pax_global_header00006660000000000000000000000064135650410070014513gustar00rootroot0000000000000052 comment=d1ee711ee996fa74abaffbdb572963f368f215a9 google-cloud-go-0.49.0/000077500000000000000000000000001356504100700145705ustar00rootroot00000000000000google-cloud-go-0.49.0/CHANGES.md000066400000000000000000001247751356504100700162020ustar00rootroot00000000000000# Changes ## v0.49.0 -functions/metadata: - Handle string resources in JSON unmarshaller. - Various updates to autogenerated clients. ## v0.48.0 - Various updates to autogenerated clients ## v0.47.0 This release drops support for Go 1.9 and Go 1.10: we continue to officially support Go 1.11, Go 1.12, and Go 1.13. - Various updates to autogenerated clients. - Add cloudbuild/apiv1 client. ## v0.46.3 This is an empty release that was created solely to aid in storage's module carve-out. See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository. ## v0.46.2 This is an empty release that was created solely to aid in spanner's module carve-out. See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository. ## v0.46.1 This is an empty release that was created solely to aid in firestore's module carve-out. See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository. ## v0.46.0 - spanner: - Retry "Session not found" for read-only transactions. - Retry aborted PDMLs. - spanner/spannertest: - Fix a bug that was causing 0X-prefixed number to be parsed incorrectly. - storage: - Add HMACKeyOptions. - Remove *REGIONAL from StorageClass documentation. Using MULTI_REGIONAL, DURABLE_REDUCED_AVAILABILITY, and REGIONAL are no longer best practice StorageClasses but they are still acceptable values. - trace: - Remove cloud.google.com/go/trace. Package cloud.google.com/go/trace has been marked OBSOLETE for several years: it is now no longer provided. If you relied on this package, please vendor it or switch to using https://cloud.google.com/trace/docs/setup/go (which obsoleted it). ## v0.45.1 This is an empty release that was created solely to aid in pubsub's module carve-out. See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository. ## v0.45.0 - compute/metadata: - Add Email method. - storage: - Fix duplicated retry logic. - Add ReaderObjectAttrs.StartOffset. - Support reading last N bytes of a file when a negative range is given, such as `obj.NewRangeReader(ctx, -10, -1)`. - Add HMACKey listing functionality. - spanner/spannertest: - Support primary keys with no columns. - Fix MinInt64 parsing. - Implement deletion of key ranges. - Handle reads during a read-write transaction. - Handle returning DATE values. - pubsub: - Fix Ack/Modack request size calculation. - logging: - Add auto-detection of monitored resources on GAE Standard. ## v0.44.3 This is an empty release that was created solely to aid in bigtable's module carve-out. See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository. ## v0.44.2 This is an empty release that was created solely to aid in bigquery's module carve-out. See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository. ## v0.44.1 This is an empty release that was created solely to aid in datastore's module carve-out. See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository. ## v0.44.0 - datastore: - Interface elements whose underlying types are supported, are now supported. - Reduce time to initial retry from 1s to 100ms. - firestore: - Add Increment transformation. - storage: - Allow emulator with STORAGE_EMULATOR_HOST. - Add methods for HMAC key management. - pubsub: - Add PublishCount and PublishLatency measurements. - Add DefaultPublishViews and DefaultSubscribeViews for convenience of importing all views. - Add add Subscription.PushConfig.AuthenticationMethod. - spanner: - Allow emulator usage with SPANNER_EMULATOR_HOST. - Add cloud.google.com/go/spanner/spannertest, a spanner emulator. - Add cloud.google.com/go/spanner/spansql which contains types and a parser for the Cloud Spanner SQL dialect. - asset: - Add apiv1p2beta1 client. ## v0.43.0 This is an empty release that was created solely to aid in logging's module carve-out. See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository. ## v0.42.0 - bigtable: - Add an admin method to update an instance and clusters. - Fix bttest regex matching behavior for alternations (things like `|a`). - Expose BlockAllFilter filter. - bigquery: - Add Routines API support. - storage: - Add read-only Bucket.LocationType. - logging: - Add TraceSampled to Entry. - Fix to properly extract {Trace, Span}Id from X-Cloud-Trace-Context. - pubsub: - Add Cloud Key Management to TopicConfig. - Change ExpirationPolicy to optional.Duration. - automl: - Add apiv1beta1 client. - iam: - Fix compilation problem with iam/credentials/apiv1. ## v0.41.0 - bigtable: - Check results from PredicateFilter in bttest, which fixes certain false matches. - profiler: - debugLog checks user defined logging options before logging. - spanner: - PartitionedUpdates respect query parameters. - StartInstance allows specifying cloud API access scopes. - bigquery: - Use empty slice instead of nil for ValueSaver, fixing an issue with zero-length, repeated, nested fields causing panics. - firestore: - Return same number of snapshots as doc refs (in the form of duplicate records) during GetAll. - replay: - Change references to IPv4 addresses to localhost, making replay compatible with IPv6. ## v0.40.0 - all: - Update to protobuf-golang v1.3.1. - datastore: - Attempt to decode GAE-encoded keys if initial decoding attempt fails. - Support integer time conversion. - pubsub: - Add PublishSettings.BundlerByteLimit. If users receive pubsub.ErrOverflow, this value should be adjusted higher. - Use IPv6 compatible target in testutil. - bigtable: - Fix Latin-1 regexp filters in bttest, allowing \C. - Expose PassAllFilter. - profiler: - Add log messages for slow path in start. - Fix start to allow retry until success. - firestore: - Add admin client. - containeranalysis: - Add apiv1 client. - grafeas: - Add apiv1 client. ## 0.39.0 - bigtable: - Implement DeleteInstance in bttest. - Return an error on invalid ReadRowsRequest.RowRange key ranges in bttest. - bigquery: - Move RequirePartitionFilter outside of TimePartioning. - Expose models API. - firestore: - Allow array values in create and update calls. - Add CollectionGroup method. - pubsub: - Add ExpirationPolicy to Subscription. - storage: - Add V4 signing. - rpcreplay: - Match streams by first sent request. This further improves rpcreplay's ability to distinguish streams. - httpreplay: - Set up Man-In-The-Middle config only once. This should improve proxy creation when multiple proxies are used in a single process. - Remove error on empty Content-Type, allowing requests with no Content-Type header but a non-empty body. - all: - Fix an edge case bug in auto-generated library pagination by properly propagating pagetoken. ## 0.38.0 This update includes a substantial reduction in our transitive dependency list by way of updating to opencensus@v0.21.0. - spanner: - Error implements GRPCStatus, allowing status.Convert. - bigtable: - Fix a bug in bttest that prevents single column queries returning results that match other filters. - Remove verbose retry logging. - logging: - Ensure RequestUrl has proper UTF-8, removing the need for users to wrap and rune replace manually. - recaptchaenterprise: - Add v1beta1 client. - phishingprotection: - Add v1beta1 client. ## 0.37.4 This patch releases re-builds the go.sum. This was not possible in the previous release. - firestore: - Add sentinel value DetectProjectID for auto-detecting project ID. - Add OpenCensus tracing for public methods. - Marked stable. All future changes come with a backwards compatibility guarantee. - Removed firestore/apiv1beta1. All users relying on this low-level library should migrate to firestore/apiv1. Note that most users should use the high-level firestore package instead. - pubsub: - Allow large messages in synchronous pull case. - Cap bundler byte limit. This should prevent OOM conditions when there are a very large number of message publishes occurring. - storage: - Add ETag to BucketAttrs and ObjectAttrs. - datastore: - Removed some non-sensical OpenCensus traces. - webrisk: - Add v1 client. - asset: - Add v1 client. - cloudtasks: - Add v2 client. ## 0.37.3 This patch release removes github.com/golang/lint from the transitive dependency list, resolving `go get -u` problems. Note: this release intentionally has a broken go.sum. Please use v0.37.4. ## 0.37.2 This patch release is mostly intended to bring in v0.3.0 of google.golang.org/api, which fixes a GCF deployment issue. Note: we had to-date accidentally marked Redis as stable. In this release, we've fixed it by downgrading its documentation to alpha, as it is in other languages and docs. - all: - Document context in generated libraries. ## 0.37.1 Small go.mod version bumps to bring in v0.2.0 of google.golang.org/api, which introduces a new oauth2 url. ## 0.37.0 - spanner: - Add BatchDML method. - Reduced initial time between retries. - bigquery: - Produce better error messages for InferSchema. - Add logical type control for avro loads. - Add support for the GEOGRAPHY type. - datastore: - Add sentinel value DetectProjectID for auto-detecting project ID. - Allow flatten tag on struct pointers. - Fixed a bug that caused queries to panic with invalid queries. Instead they will now return an error. - profiler: - Add ability to override GCE zone and instance. - pubsub: - BEHAVIOR CHANGE: Refactor error code retry logic. RPCs should now more consistently retry specific error codes based on whether they're idempotent or non-idempotent. - httpreplay: Fixed a bug when a non-GET request had a zero-length body causing the Content-Length header to be dropped. - iot: - Add new apiv1 client. - securitycenter: - Add new apiv1 client. - cloudscheduler: - Add new apiv1 client. ## 0.36.0 - spanner: - Reduce minimum retry backoff from 1s to 100ms. This makes time between retries much faster and should improve latency. - storage: - Add support for Bucket Policy Only. - kms: - Add ResourceIAM helper method. - Deprecate KeyRingIAM and CryptoKeyIAM. Please use ResourceIAM. - firestore: - Switch from v1beta1 API to v1 API. - Allow emulator with FIRESTORE_EMULATOR_HOST. - bigquery: - Add NumLongTermBytes to Table. - Add TotalBytesProcessedAccuracy to QueryStatistics. - irm: - Add new v1alpha2 client. - talent: - Add new v4beta1 client. - rpcreplay: - Fix connection to work with grpc >= 1.17. - It is now required for an actual gRPC server to be running for Dial to succeed. ## 0.35.1 - spanner: - Adds OpenCensus views back to public API. ## v0.35.0 - all: - Add go.mod and go.sum. - Switch usage of gax-go to gax-go/v2. - bigquery: - Fix bug where time partitioning could not be removed from a table. - Fix panic that occurred with empty query parameters. - bttest: - Fix bug where deleted rows were returned by ReadRows. - bigtable/emulator: - Configure max message size to 256 MiB. - firestore: - Allow non-transactional queries in transactions. - Allow StartAt/EndBefore on direct children at any depth. - QuerySnapshotIterator.Stop may be called in an error state. - Fix bug the prevented reset of transaction write state in between retries. - functions/metadata: - Make Metadata.Resource a pointer. - logging: - Make SpanID available in logging.Entry. - metadata: - Wrap !200 error code in a typed err. - profiler: - Add function to check if function name is within a particular file in the profile. - Set parent field in create profile request. - Return kubernetes client to start cluster, so client can be used to poll cluster. - Add function for checking if filename is in profile. - pubsub: - Fix bug where messages expired without an initial modack in synchronous=true mode. - Receive does not retry ResourceExhausted errors. - spanner: - client.Close now cancels existing requests and should be much faster for large amounts of sessions. - Correctly allow MinOpened sessions to be spun up. ## v0.34.0 - functions/metadata: - Switch to using JSON in context. - Make Resource a value. - vision: Fix ProductSearch return type. - datastore: Add an example for how to handle MultiError. ## v0.33.1 - compute: Removes an erroneously added go.mod. - logging: Populate source location in fromLogEntry. ## v0.33.0 - bttest: - Add support for apply_label_transformer. - expr: - Add expr library. - firestore: - Support retrieval of missing documents. - kms: - Add IAM methods. - pubsub: - Clarify extension documentation. - scheduler: - Add v1beta1 client. - vision: - Add product search helper. - Add new product search client. ## v0.32.0 Note: This release is the last to support Go 1.6 and 1.8. - bigquery: - Add support for removing an expiration. - Ignore NeverExpire in Table.Create. - Validate table expiration time. - cbt: - Add note about not supporting arbitrary bytes. - datastore: - Align key checks. - firestore: - Return an error when using Start/End without providing values. - pubsub: - Add pstest Close method. - Clarify MaxExtension documentation. - securitycenter: - Add v1beta1 client. - spanner: - Allow nil in mutations. - Improve doc of SessionPoolConfig.MaxOpened. - Increase session deletion timeout from 5s to 15s. ## v0.31.0 - bigtable: - Group mutations across multiple requests. - bigquery: - Link to bigquery troubleshooting errors page in bigquery.Error comment. - cbt: - Fix go generate command. - Document usage of both maxage + maxversions. - datastore: - Passing nil keys results in ErrInvalidKey. - firestore: - Clarify what Document.DataTo does with untouched struct fields. - profile: - Validate service name in agent. - pubsub: - Fix deadlock with pstest and ctx.Cancel. - Fix a possible deadlock in pstest. - trace: - Update doc URL with new fragment. Special thanks to @fastest963 for going above and beyond helping us to debug hard-to-reproduce Pub/Sub issues. ## v0.30.0 - spanner: DML support added. See https://godoc.org/cloud.google.com/go/spanner#hdr-DML_and_Partitioned_DML for more information. - bigtable: bttest supports row sample filter. - functions: metadata package added for accessing Cloud Functions resource metadata. ## v0.29.0 - bigtable: - Add retry to all idempotent RPCs. - cbt supports complex GC policies. - Emulator supports arbitrary bytes in regex filters. - firestore: Add ArrayUnion and ArrayRemove. - logging: Add the ContextFunc option to supply the context used for asynchronous RPCs. - profiler: Ignore NotDefinedError when fetching the instance name - pubsub: - BEHAVIOR CHANGE: Receive doesn't retry if an RPC returns codes.Cancelled. - BEHAVIOR CHANGE: Receive retries on Unavailable intead of returning. - Fix deadlock. - Restore Ack/Nack/Modacks metrics. - Improve context handling in iterator. - Implement synchronous mode for Receive. - pstest: add Pull. - spanner: Add a metric for the number of sessions currently opened. - storage: - Canceling the context releases all resources. - Add additional RetentionPolicy attributes. - vision/apiv1: Add LocalizeObjects method. ## v0.28.0 - bigtable: - Emulator returns Unimplemented for snapshot RPCs. - bigquery: - Support zero-length repeated, nested fields. - cloud assets: - Add v1beta client. - datastore: - Don't nil out transaction ID on retry. - firestore: - BREAKING CHANGE: When watching a query with Query.Snapshots, QuerySnapshotIterator.Next returns a QuerySnapshot which contains read time, result size, change list and the DocumentIterator (previously, QuerySnapshotIterator.Next returned just the DocumentIterator). See: https://godoc.org/cloud.google.com/go/firestore#Query.Snapshots. - Add array-contains operator. - IAM: - Add iam/credentials/apiv1 client. - pubsub: - Canceling the context passed to Subscription.Receive causes Receive to return when processing finishes on all messages currently in progress, even if new messages are arriving. - redis: - Add redis/apiv1 client. - storage: - Add Reader.Attrs. - Deprecate several Reader getter methods: please use Reader.Attrs for these instead. - Add ObjectHandle.Bucket and ObjectHandle.Object methods. ## v0.27.0 - bigquery: - Allow modification of encryption configuration and partitioning options to a table via the Update call. - Add a SchemaFromJSON function that converts a JSON table schema. - bigtable: - Restore cbt count functionality. - containeranalysis: - Add v1beta client. - spanner: - Fix a case where an iterator might not be closed correctly. - storage: - Add ServiceAccount method https://godoc.org/cloud.google.com/go/storage#Client.ServiceAccount. - Add a method to Reader that returns the parsed value of the Last-Modified header. ## v0.26.0 - bigquery: - Support filtering listed jobs by min/max creation time. - Support data clustering (https://godoc.org/cloud.google.com/go/bigquery#Clustering). - Include job creator email in Job struct. - bigtable: - Add `RowSampleFilter`. - emulator: BREAKING BEHAVIOR CHANGE: Regexps in row, family, column and value filters must match the entire target string to succeed. Previously, the emulator was succeeding on partial matches. NOTE: As of this release, this change only affects the emulator when run from this repo (bigtable/cmd/emulator/cbtemulator.go). The version launched from `gcloud` will be updated in a subsequent `gcloud` release. - dataproc: Add apiv1beta2 client. - datastore: Save non-nil pointer fields on omitempty. - logging: populate Entry.Trace from the HTTP X-Cloud-Trace-Context header. - logging/logadmin: Support writer_identity and include_children. - pubsub: - Support labels on topics and subscriptions. - Support message storage policy for topics. - Use the distribution of ack times to determine when to extend ack deadlines. The only user-visible effect of this change should be that programs that call only `Subscription.Receive` need no IAM permissions other than `Pub/Sub Subscriber`. - storage: - Support predefined ACLs. - Support additional ACL fields other than Entity and Role. - Support bucket websites. - Support bucket logging. ## v0.25.0 - Added [Code of Conduct](https://github.com/googleapis/google-cloud-go/blob/master/CODE_OF_CONDUCT.md) - bigtable: - cbt: Support a GC policy of "never". - errorreporting: - Support User. - Close now calls Flush. - Use OnError (previously ignored). - Pass through the RPC error as-is to OnError. - httpreplay: A tool for recording and replaying HTTP requests (for the bigquery and storage clients in this repo). - kms: v1 client added - logging: add SourceLocation to Entry. - storage: improve CRC checking on read. ## v0.24.0 - bigquery: Support for the NUMERIC type. - bigtable: - cbt: Optionally specify columns for read/lookup - Support instance-level administration. - oslogin: New client for the OS Login API. - pubsub: - The package is now stable. There will be no further breaking changes. - Internal changes to improve Subscription.Receive behavior. - storage: Support updating bucket lifecycle config. - spanner: Support struct-typed parameter bindings. - texttospeech: New client for the Text-to-Speech API. ## v0.23.0 - bigquery: Add DDL stats to query statistics. - bigtable: - cbt: Add cells-per-column limit for row lookup. - cbt: Make it possible to combine read filters. - dlp: v2beta2 client removed. Use the v2 client instead. - firestore, spanner: Fix compilation errors due to protobuf changes. ## v0.22.0 - bigtable: - cbt: Support cells per column limit for row read. - bttest: Correctly handle empty RowSet. - Fix ReadModifyWrite operation in emulator. - Fix API path in GetCluster. - bigquery: - BEHAVIOR CHANGE: Retry on 503 status code. - Add dataset.DeleteWithContents. - Add SchemaUpdateOptions for query jobs. - Add Timeline to QueryStatistics. - Add more stats to ExplainQueryStage. - Support Parquet data format. - datastore: - Support omitempty for times. - dlp: - **BREAKING CHANGE:** Remove v1beta1 client. Please migrate to the v2 client, which is now out of beta. - Add v2 client. - firestore: - BEHAVIOR CHANGE: Treat set({}, MergeAll) as valid. - iam: - Support JWT signing via SignJwt callopt. - profiler: - BEHAVIOR CHANGE: PollForSerialOutput returns an error when context.Done. - BEHAVIOR CHANGE: Increase the initial backoff to 1 minute. - Avoid returning empty serial port output. - pubsub: - BEHAVIOR CHANGE: Don't backoff during next retryable error once stream is healthy. - BEHAVIOR CHANGE: Don't backoff on EOF. - pstest: Support Acknowledge and ModifyAckDeadline RPCs. - redis: - Add v1 beta Redis client. - spanner: - Support SessionLabels. - speech: - Add api v1 beta1 client. - storage: - BEHAVIOR CHANGE: Retry reads when retryable error occurs. - Fix delete of object in requester-pays bucket. - Support KMS integration. ## v0.21.0 - bigquery: - Add OpenCensus tracing. - firestore: - **BREAKING CHANGE:** If a document does not exist, return a DocumentSnapshot whose Exists method returns false. DocumentRef.Get and Transaction.Get return the non-nil DocumentSnapshot in addition to a NotFound error. **DocumentRef.GetAll and Transaction.GetAll return a non-nil DocumentSnapshot instead of nil.** - Add DocumentIterator.Stop. **Call Stop whenever you are done with a DocumentIterator.** - Added Query.Snapshots and DocumentRef.Snapshots, which provide realtime notification of updates. See https://cloud.google.com/firestore/docs/query-data/listen. - Canceling an RPC now always returns a grpc.Status with codes.Canceled. - spanner: - Add `CommitTimestamp`, which supports inserting the commit timestamp of a transaction into a column. ## v0.20.0 - bigquery: Support SchemaUpdateOptions for load jobs. - bigtable: - Add SampleRowKeys. - cbt: Support union, intersection GCPolicy. - Retry admin RPCS. - Add trace spans to retries. - datastore: Add OpenCensus tracing. - firestore: - Fix queries involving Null and NaN. - Allow Timestamp protobuffers for time values. - logging: Add a WriteTimeout option. - spanner: Support Batch API. - storage: Add OpenCensus tracing. ## v0.19.0 - bigquery: - Support customer-managed encryption keys. - bigtable: - Improved emulator support. - Support GetCluster. - datastore: - Add general mutations. - Support pointer struct fields. - Support transaction options. - firestore: - Add Transaction.GetAll. - Support document cursors. - logging: - Support concurrent RPCs to the service. - Support per-entry resources. - profiler: - Add config options to disable heap and thread profiling. - Read the project ID from $GOOGLE_CLOUD_PROJECT when it's set. - pubsub: - BEHAVIOR CHANGE: Release flow control after ack/nack (instead of after the callback returns). - Add SubscriptionInProject. - Add OpenCensus instrumentation for streaming pull. - storage: - Support CORS. ## v0.18.0 - bigquery: - Marked stable. - Schema inference of nullable fields supported. - Added TimePartitioning to QueryConfig. - firestore: Data provided to DocumentRef.Set with a Merge option can contain Delete sentinels. - logging: Clients can accept parent resources other than projects. - pubsub: - pubsub/pstest: A lighweight fake for pubsub. Experimental; feedback welcome. - Support updating more subscription metadata: AckDeadline, RetainAckedMessages and RetentionDuration. - oslogin/apiv1beta: New client for the Cloud OS Login API. - rpcreplay: A package for recording and replaying gRPC traffic. - spanner: - Add a ReadWithOptions that supports a row limit, as well as an index. - Support query plan and execution statistics. - Added [OpenCensus](http://opencensus.io) support. - storage: Clarify checksum validation for gzipped files (it is not validated when the file is served uncompressed). ## v0.17.0 - firestore BREAKING CHANGES: - Remove UpdateMap and UpdateStruct; rename UpdatePaths to Update. Change `docref.UpdateMap(ctx, map[string]interface{}{"a.b", 1})` to `docref.Update(ctx, []firestore.Update{{Path: "a.b", Value: 1}})` Change `docref.UpdateStruct(ctx, []string{"Field"}, aStruct)` to `docref.Update(ctx, []firestore.Update{{Path: "Field", Value: aStruct.Field}})` - Rename MergePaths to Merge; require args to be FieldPaths - A value stored as an integer can be read into a floating-point field, and vice versa. - bigtable/cmd/cbt: - Support deleting a column. - Add regex option for row read. - spanner: Mark stable. - storage: - Add Reader.ContentEncoding method. - Fix handling of SignedURL headers. - bigquery: - If Uploader.Put is called with no rows, it returns nil without making a call. - Schema inference supports the "nullable" option in struct tags for non-required fields. - TimePartitioning supports "Field". ## v0.16.0 - Other bigquery changes: - `JobIterator.Next` returns `*Job`; removed `JobInfo` (BREAKING CHANGE). - UseStandardSQL is deprecated; set UseLegacySQL to true if you need Legacy SQL. - Uploader.Put will generate a random insert ID if you do not provide one. - Support time partitioning for load jobs. - Support dry-run queries. - A `Job` remembers its last retrieved status. - Support retrieving job configuration. - Support labels for jobs and tables. - Support dataset access lists. - Improve support for external data sources, including data from Bigtable and Google Sheets, and tables with external data. - Support updating a table's view configuration. - Fix uploading civil times with nanoseconds. - storage: - Support PubSub notifications. - Support Requester Pays buckets. - profiler: Support goroutine and mutex profile types. ## v0.15.0 - firestore: beta release. See the [announcement](https://firebase.googleblog.com/2017/10/introducing-cloud-firestore.html). - errorreporting: The existing package has been redesigned. - errors: This package has been removed. Use errorreporting. ## v0.14.0 - bigquery BREAKING CHANGES: - Standard SQL is the default for queries and views. - `Table.Create` takes `TableMetadata` as a second argument, instead of options. - `Dataset.Create` takes `DatasetMetadata` as a second argument. - `DatasetMetadata` field `ID` renamed to `FullID` - `TableMetadata` field `ID` renamed to `FullID` - Other bigquery changes: - The client will append a random suffix to a provided job ID if you set `AddJobIDSuffix` to true in a job config. - Listing jobs is supported. - Better retry logic. - vision, language, speech: clients are now stable - monitoring: client is now beta - profiler: - Rename InstanceName to Instance, ZoneName to Zone - Auto-detect service name and version on AppEngine. ## v0.13.0 - bigquery: UseLegacySQL options for CreateTable and QueryConfig. Use these options to continue using Legacy SQL after the client switches its default to Standard SQL. - bigquery: Support for updating dataset labels. - bigquery: Set DatasetIterator.ProjectID to list datasets in a project other than the client's. DatasetsInProject is no longer needed and is deprecated. - bigtable: Fail ListInstances when any zones fail. - spanner: support decoding of slices of basic types (e.g. []string, []int64, etc.) - logging/logadmin: UpdateSink no longer creates a sink if it is missing (actually a change to the underlying service, not the client) - profiler: Service and ServiceVersion replace Target in Config. ## v0.12.0 - pubsub: Subscription.Receive now uses streaming pull. - pubsub: add Client.TopicInProject to access topics in a different project than the client. - errors: renamed errorreporting. The errors package will be removed shortly. - datastore: improved retry behavior. - bigquery: support updates to dataset metadata, with etags. - bigquery: add etag support to Table.Update (BREAKING: etag argument added). - bigquery: generate all job IDs on the client. - storage: support bucket lifecycle configurations. ## v0.11.0 - Clients for spanner, pubsub and video are now in beta. - New client for DLP. - spanner: performance and testing improvements. - storage: requester-pays buckets are supported. - storage, profiler, bigtable, bigquery: bug fixes and other minor improvements. - pubsub: bug fixes and other minor improvements ## v0.10.0 - pubsub: Subscription.ModifyPushConfig replaced with Subscription.Update. - pubsub: Subscription.Receive now runs concurrently for higher throughput. - vision: cloud.google.com/go/vision is deprecated. Use cloud.google.com/go/vision/apiv1 instead. - translation: now stable. - trace: several changes to the surface. See the link below. ### Code changes required from v0.9.0 - pubsub: Replace ``` sub.ModifyPushConfig(ctx, pubsub.PushConfig{Endpoint: "https://example.com/push"}) ``` with ``` sub.Update(ctx, pubsub.SubscriptionConfigToUpdate{ PushConfig: &pubsub.PushConfig{Endpoint: "https://example.com/push"}, }) ``` - trace: traceGRPCServerInterceptor will be provided from *trace.Client. Given an initialized `*trace.Client` named `tc`, instead of ``` s := grpc.NewServer(grpc.UnaryInterceptor(trace.GRPCServerInterceptor(tc))) ``` write ``` s := grpc.NewServer(grpc.UnaryInterceptor(tc.GRPCServerInterceptor())) ``` - trace trace.GRPCClientInterceptor will also provided from *trace.Client. Instead of ``` conn, err := grpc.Dial(srv.Addr, grpc.WithUnaryInterceptor(trace.GRPCClientInterceptor())) ``` write ``` conn, err := grpc.Dial(srv.Addr, grpc.WithUnaryInterceptor(tc.GRPCClientInterceptor())) ``` - trace: We removed the deprecated `trace.EnableGRPCTracing`. Use the gRPC interceptor as a dial option as shown below when initializing Cloud package clients: ``` c, err := pubsub.NewClient(ctx, "project-id", option.WithGRPCDialOption(grpc.WithUnaryInterceptor(tc.GRPCClientInterceptor()))) if err != nil { ... } ``` ## v0.9.0 - Breaking changes to some autogenerated clients. - rpcreplay package added. ## v0.8.0 - profiler package added. - storage: - Retry Objects.Insert call. - Add ProgressFunc to WRiter. - pubsub: breaking changes: - Publish is now asynchronous ([announcement](https://groups.google.com/d/topic/google-api-go-announce/aaqRDIQ3rvU/discussion)). - Subscription.Pull replaced by Subscription.Receive, which takes a callback ([announcement](https://groups.google.com/d/topic/google-api-go-announce/8pt6oetAdKc/discussion)). - Message.Done replaced with Message.Ack and Message.Nack. ## v0.7.0 - Release of a client library for Spanner. See the [blog post](https://cloudplatform.googleblog.com/2017/02/introducing-Cloud-Spanner-a-global-database-service-for-mission-critical-applications.html). Note that although the Spanner service is beta, the Go client library is alpha. ## v0.6.0 - Beta release of BigQuery, DataStore, Logging and Storage. See the [blog post](https://cloudplatform.googleblog.com/2016/12/announcing-new-google-cloud-client.html). - bigquery: - struct support. Read a row directly into a struct with `RowIterator.Next`, and upload a row directly from a struct with `Uploader.Put`. You can also use field tags. See the [package documentation][cloud-bigquery-ref] for details. - The `ValueList` type was removed. It is no longer necessary. Instead of ```go var v ValueList ... it.Next(&v) .. ``` use ```go var v []Value ... it.Next(&v) ... ``` - Previously, repeatedly calling `RowIterator.Next` on the same `[]Value` or `ValueList` would append to the slice. Now each call resets the size to zero first. - Schema inference will infer the SQL type BYTES for a struct field of type []byte. Previously it inferred STRING. - The types `uint`, `uint64` and `uintptr` are no longer supported in schema inference. BigQuery's integer type is INT64, and those types may hold values that are not correctly represented in a 64-bit signed integer. ## v0.5.0 - bigquery: - The SQL types DATE, TIME and DATETIME are now supported. They correspond to the `Date`, `Time` and `DateTime` types in the new `cloud.google.com/go/civil` package. - Support for query parameters. - Support deleting a dataset. - Values from INTEGER columns will now be returned as int64, not int. This will avoid errors arising from large values on 32-bit systems. - datastore: - Nested Go structs encoded as Entity values, instead of a flattened list of the embedded struct's fields. This means that you may now have twice-nested slices, eg. ```go type State struct { Cities []struct{ Populations []int } } ``` See [the announcement](https://groups.google.com/forum/#!topic/google-api-go-announce/79jtrdeuJAg) for more details. - Contexts no longer hold namespaces; instead you must set a key's namespace explicitly. Also, key functions have been changed and renamed. - The WithNamespace function has been removed. To specify a namespace in a Query, use the Query.Namespace method: ```go q := datastore.NewQuery("Kind").Namespace("ns") ``` - All the fields of Key are exported. That means you can construct any Key with a struct literal: ```go k := &Key{Kind: "Kind", ID: 37, Namespace: "ns"} ``` - As a result of the above, the Key methods Kind, ID, d.Name, Parent, SetParent and Namespace have been removed. - `NewIncompleteKey` has been removed, replaced by `IncompleteKey`. Replace ```go NewIncompleteKey(ctx, kind, parent) ``` with ```go IncompleteKey(kind, parent) ``` and if you do use namespaces, make sure you set the namespace on the returned key. - `NewKey` has been removed, replaced by `NameKey` and `IDKey`. Replace ```go NewKey(ctx, kind, name, 0, parent) NewKey(ctx, kind, "", id, parent) ``` with ```go NameKey(kind, name, parent) IDKey(kind, id, parent) ``` and if you do use namespaces, make sure you set the namespace on the returned key. - The `Done` variable has been removed. Replace `datastore.Done` with `iterator.Done`, from the package `google.golang.org/api/iterator`. - The `Client.Close` method will have a return type of error. It will return the result of closing the underlying gRPC connection. - See [the announcement](https://groups.google.com/forum/#!topic/google-api-go-announce/hqXtM_4Ix-0) for more details. ## v0.4.0 - bigquery: -`NewGCSReference` is now a function, not a method on `Client`. - `Table.LoaderFrom` now accepts a `ReaderSource`, enabling loading data into a table from a file or any `io.Reader`. * Client.Table and Client.OpenTable have been removed. Replace ```go client.OpenTable("project", "dataset", "table") ``` with ```go client.DatasetInProject("project", "dataset").Table("table") ``` * Client.CreateTable has been removed. Replace ```go client.CreateTable(ctx, "project", "dataset", "table") ``` with ```go client.DatasetInProject("project", "dataset").Table("table").Create(ctx) ``` * Dataset.ListTables have been replaced with Dataset.Tables. Replace ```go tables, err := ds.ListTables(ctx) ``` with ```go it := ds.Tables(ctx) for { table, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: use table. } ``` * Client.Read has been replaced with Job.Read, Table.Read and Query.Read. Replace ```go it, err := client.Read(ctx, job) ``` with ```go it, err := job.Read(ctx) ``` and similarly for reading from tables or queries. * The iterator returned from the Read methods is now named RowIterator. Its behavior is closer to the other iterators in these libraries. It no longer supports the Schema method; see the next item. Replace ```go for it.Next(ctx) { var vals ValueList if err := it.Get(&vals); err != nil { // TODO: Handle error. } // TODO: use vals. } if err := it.Err(); err != nil { // TODO: Handle error. } ``` with ``` for { var vals ValueList err := it.Next(&vals) if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: use vals. } ``` Instead of the `RecordsPerRequest(n)` option, write ```go it.PageInfo().MaxSize = n ``` Instead of the `StartIndex(i)` option, write ```go it.StartIndex = i ``` * ValueLoader.Load now takes a Schema in addition to a slice of Values. Replace ```go func (vl *myValueLoader) Load(v []bigquery.Value) ``` with ```go func (vl *myValueLoader) Load(v []bigquery.Value, s bigquery.Schema) ``` * Table.Patch is replace by Table.Update. Replace ```go p := table.Patch() p.Description("new description") metadata, err := p.Apply(ctx) ``` with ```go metadata, err := table.Update(ctx, bigquery.TableMetadataToUpdate{ Description: "new description", }) ``` * Client.Copy is replaced by separate methods for each of its four functions. All options have been replaced by struct fields. * To load data from Google Cloud Storage into a table, use Table.LoaderFrom. Replace ```go client.Copy(ctx, table, gcsRef) ``` with ```go table.LoaderFrom(gcsRef).Run(ctx) ``` Instead of passing options to Copy, set fields on the Loader: ```go loader := table.LoaderFrom(gcsRef) loader.WriteDisposition = bigquery.WriteTruncate ``` * To extract data from a table into Google Cloud Storage, use Table.ExtractorTo. Set fields on the returned Extractor instead of passing options. Replace ```go client.Copy(ctx, gcsRef, table) ``` with ```go table.ExtractorTo(gcsRef).Run(ctx) ``` * To copy data into a table from one or more other tables, use Table.CopierFrom. Set fields on the returned Copier instead of passing options. Replace ```go client.Copy(ctx, dstTable, srcTable) ``` with ```go dst.Table.CopierFrom(srcTable).Run(ctx) ``` * To start a query job, create a Query and call its Run method. Set fields on the query instead of passing options. Replace ```go client.Copy(ctx, table, query) ``` with ```go query.Run(ctx) ``` * Table.NewUploader has been renamed to Table.Uploader. Instead of options, configure an Uploader by setting its fields. Replace ```go u := table.NewUploader(bigquery.UploadIgnoreUnknownValues()) ``` with ```go u := table.NewUploader(bigquery.UploadIgnoreUnknownValues()) u.IgnoreUnknownValues = true ``` - pubsub: remove `pubsub.Done`. Use `iterator.Done` instead, where `iterator` is the package `google.golang.org/api/iterator`. ## v0.3.0 - storage: * AdminClient replaced by methods on Client. Replace ```go adminClient.CreateBucket(ctx, bucketName, attrs) ``` with ```go client.Bucket(bucketName).Create(ctx, projectID, attrs) ``` * BucketHandle.List replaced by BucketHandle.Objects. Replace ```go for query != nil { objs, err := bucket.List(d.ctx, query) if err != nil { ... } query = objs.Next for _, obj := range objs.Results { fmt.Println(obj) } } ``` with ```go iter := bucket.Objects(d.ctx, query) for { obj, err := iter.Next() if err == iterator.Done { break } if err != nil { ... } fmt.Println(obj) } ``` (The `iterator` package is at `google.golang.org/api/iterator`.) Replace `Query.Cursor` with `ObjectIterator.PageInfo().Token`. Replace `Query.MaxResults` with `ObjectIterator.PageInfo().MaxSize`. * ObjectHandle.CopyTo replaced by ObjectHandle.CopierFrom. Replace ```go attrs, err := src.CopyTo(ctx, dst, nil) ``` with ```go attrs, err := dst.CopierFrom(src).Run(ctx) ``` Replace ```go attrs, err := src.CopyTo(ctx, dst, &storage.ObjectAttrs{ContextType: "text/html"}) ``` with ```go c := dst.CopierFrom(src) c.ContextType = "text/html" attrs, err := c.Run(ctx) ``` * ObjectHandle.ComposeFrom replaced by ObjectHandle.ComposerFrom. Replace ```go attrs, err := dst.ComposeFrom(ctx, []*storage.ObjectHandle{src1, src2}, nil) ``` with ```go attrs, err := dst.ComposerFrom(src1, src2).Run(ctx) ``` * ObjectHandle.Update's ObjectAttrs argument replaced by ObjectAttrsToUpdate. Replace ```go attrs, err := obj.Update(ctx, &storage.ObjectAttrs{ContextType: "text/html"}) ``` with ```go attrs, err := obj.Update(ctx, storage.ObjectAttrsToUpdate{ContextType: "text/html"}) ``` * ObjectHandle.WithConditions replaced by ObjectHandle.If. Replace ```go obj.WithConditions(storage.Generation(gen), storage.IfMetaGenerationMatch(mgen)) ``` with ```go obj.Generation(gen).If(storage.Conditions{MetagenerationMatch: mgen}) ``` Replace ```go obj.WithConditions(storage.IfGenerationMatch(0)) ``` with ```go obj.If(storage.Conditions{DoesNotExist: true}) ``` * `storage.Done` replaced by `iterator.Done` (from package `google.golang.org/api/iterator`). - Package preview/logging deleted. Use logging instead. ## v0.2.0 - Logging client replaced with preview version (see below). - New clients for some of Google's Machine Learning APIs: Vision, Speech, and Natural Language. - Preview version of a new [Stackdriver Logging][cloud-logging] client in [`cloud.google.com/go/preview/logging`](https://godoc.org/cloud.google.com/go/preview/logging). This client uses gRPC as its transport layer, and supports log reading, sinks and metrics. It will replace the current client at `cloud.google.com/go/logging` shortly. google-cloud-go-0.49.0/CODE_OF_CONDUCT.md000066400000000000000000000036761356504100700174030ustar00rootroot00000000000000# Contributor Code of Conduct As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality. Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery * Personal attacks * Trolling or insulting/derogatory comments * Public or private harassment * Publishing other's private information, such as physical or electronic addresses, without explicit permission * Other unethical or unprofessional conduct. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team. This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers. This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/) google-cloud-go-0.49.0/CONTRIBUTING.md000066400000000000000000000303041356504100700170210ustar00rootroot00000000000000# Contributing 1. [Install Go](https://golang.org/dl/). 1. Ensure that your `GOBIN` directory (by default `$(go env GOPATH)/bin`) is in your `PATH`. 1. Check it's working by running `go version`. * If it doesn't work, check the install location, usually `/usr/local/go`, is on your `PATH`. 1. Sign one of the [contributor license agreements](#contributor-license-agreements) below. 1. Run `go get golang.org/x/review/git-codereview && go install golang.org/x/review/git-codereview` to install the code reviewing tool. 1. Ensure it's working by running `git codereview` (check your `PATH` if not). 1. If you would like, you may want to set up aliases for `git-codereview`, such that `git codereview change` becomes `git change`. See the [godoc](https://godoc.org/golang.org/x/review/git-codereview) for details. * Should you run into issues with the `git-codereview` tool, please note that all error messages will assume that you have set up these aliases. 1. Change to a directory of your choosing and clone the repo. ``` cd ~/code git clone https://code.googlesource.com/gocloud ``` * If you have already checked out the source, make sure that the remote `git` `origin` is https://code.googlesource.com/gocloud: ``` git remote -v # ... git remote set-url origin https://code.googlesource.com/gocloud ``` * The project uses [Go Modules](https://blog.golang.org/using-go-modules) for dependency management See [`gopls`](https://github.com/golang/go/wiki/gopls) for making your editor work with modules. 1. Change to the project directory: ``` cd ~/code/gocloud ``` 1. Make sure your `git` auth is configured correctly by visiting https://code.googlesource.com, clicking "Generate Password" at the top-right, and following the directions. Otherwise, `git codereview mail` in the next step will fail. 1. Now you are ready to make changes. Don't create a new branch or make commits in the traditional way. Use the following`git codereview` commands to create a commit and create a Gerrit CL: ``` git codereview change # Use this instead of git checkout -b # Make changes. git add ... git codereview change # Use this instead of git commit git codereview mail # If this fails, the error message will contain instructions to fix it. ``` * This will create a new `git` branch for you to develop on. Once your change is merged, you can delete this branch. 1. As you make changes for code review, ammend the commit and re-mail the change: ``` # Make more changes. git add ... git codereview change git codereview mail ``` * **Warning**: do not change the `Change-Id` at the bottom of the commit message - it's how Gerrit knows which change this is (or if it's new). * When you fixes issues from code review, respond to each code review message then click **Reply** at the top of the page. * Each new mailed amendment will create a new patch set for your change in Gerrit. Patch sets can be compared and reviewed. * **Note**: if your change includes a breaking change, our breaking change detector will cause CI/CD to fail. If your breaking change is acceptable in some way, add a `BREAKING_CHANGE_ACCEPTABLE=` line to the commit message to cause the detector not to be run and to make it clear why that is acceptable. 1. Finally, add reviewers to your CL when it's ready for review. Reviewers will not be added automatically. If you're not sure who to add for your code review, add deklerk@, tbp@, cbro@, and codyoss@. ## Integration Tests In addition to the unit tests, you may run the integration test suite. These directions describe setting up your environment to run integration tests for _all_ packages: note that many of these instructions may be redundant if you intend only to run integration tests on a single package. #### GCP Setup To run the integrations tests, creation and configuration of two projects in the Google Developers Console is required: one specifically for Firestore integration tests, and another for all other integration tests. We'll refer to these projects as "general project" and "Firestore project". After creating each project, you must [create a service account](https://developers.google.com/identity/protocols/OAuth2ServiceAccount#creatinganaccount) for each project. Ensure the project-level **Owner** [IAM role](console.cloud.google.com/iam-admin/iam/project) role is added to each service account. During the creation of the service account, you should download the JSON credential file for use later. Next, ensure the following APIs are enabled in the general project: - BigQuery API - BigQuery Data Transfer API - Cloud Dataproc API - Cloud Dataproc Control API Private - Cloud Datastore API - Cloud Firestore API - Cloud Key Management Service (KMS) API - Cloud Natural Language API - Cloud OS Login API - Cloud Pub/Sub API - Cloud Resource Manager API - Cloud Spanner API - Cloud Speech API - Cloud Translation API - Cloud Video Intelligence API - Cloud Vision API - Compute Engine API - Compute Engine Instance Group Manager API - Container Registry API - Firebase Rules API - Google Cloud APIs - Google Cloud Deployment Manager V2 API - Google Cloud SQL - Google Cloud Storage - Google Cloud Storage JSON API - Google Compute Engine Instance Group Updater API - Google Compute Engine Instance Groups API - Kubernetes Engine API - Stackdriver Error Reporting API Next, create a Datastore database in the general project, and a Firestore database in the Firestore project. Finally, in the general project, create an API key for the translate API: - Go to GCP Developer Console. - Navigate to APIs & Services > Credentials. - Click Create Credentials > API Key. - Save this key for use in `GCLOUD_TESTS_API_KEY` as described below. #### Local Setup Once the two projects are created and configured, set the following environment variables: - `GCLOUD_TESTS_GOLANG_PROJECT_ID`: Developers Console project's ID (e.g. bamboo-shift-455) for the general project. - `GCLOUD_TESTS_GOLANG_KEY`: The path to the JSON key file of the general project's service account. - `GCLOUD_TESTS_GOLANG_FIRESTORE_PROJECT_ID`: Developers Console project's ID (e.g. doorway-cliff-677) for the Firestore project. - `GCLOUD_TESTS_GOLANG_FIRESTORE_KEY`: The path to the JSON key file of the Firestore project's service account. - `GCLOUD_TESTS_GOLANG_KEYRING`: The full name of the keyring for the tests, in the form "projects/P/locations/L/keyRings/R". The creation of this is described below. - `GCLOUD_TESTS_API_KEY`: API key for using the Translate API. - `GCLOUD_TESTS_GOLANG_ZONE`: Compute Engine zone. Install the [gcloud command-line tool][gcloudcli] to your machine and use it to create some resources used in integration tests. From the project's root directory: ``` sh # Sets the default project in your env. $ gcloud config set project $GCLOUD_TESTS_GOLANG_PROJECT_ID # Authenticates the gcloud tool with your account. $ gcloud auth login # Create the indexes used in the datastore integration tests. $ gcloud datastore indexes create datastore/testdata/index.yaml # Creates a Google Cloud storage bucket with the same name as your test project, # and with the Stackdriver Logging service account as owner, for the sink # integration tests in logging. $ gsutil mb gs://$GCLOUD_TESTS_GOLANG_PROJECT_ID $ gsutil acl ch -g cloud-logs@google.com:O gs://$GCLOUD_TESTS_GOLANG_PROJECT_ID # Creates a PubSub topic for integration tests of storage notifications. $ gcloud beta pubsub topics create go-storage-notification-test # Next, go to the Pub/Sub dashboard in GCP console. Authorize the user # "service-@gs-project-accounts.iam.gserviceaccount.com" # as a publisher to that topic. # Creates a Spanner instance for the spanner integration tests. $ gcloud beta spanner instances create go-integration-test --config regional-us-central1 --nodes 10 --description 'Instance for go client test' # NOTE: Spanner instances are priced by the node-hour, so you may want to # delete the instance after testing with 'gcloud beta spanner instances delete'. $ export MY_KEYRING=some-keyring-name $ export MY_LOCATION=global # Creates a KMS keyring, in the same location as the default location for your # project's buckets. $ gcloud kms keyrings create $MY_KEYRING --location $MY_LOCATION # Creates two keys in the keyring, named key1 and key2. $ gcloud kms keys create key1 --keyring $MY_KEYRING --location $MY_LOCATION --purpose encryption $ gcloud kms keys create key2 --keyring $MY_KEYRING --location $MY_LOCATION --purpose encryption # Sets the GCLOUD_TESTS_GOLANG_KEYRING environment variable. $ export GCLOUD_TESTS_GOLANG_KEYRING=projects/$GCLOUD_TESTS_GOLANG_PROJECT_ID/locations/$MY_LOCATION/keyRings/$MY_KEYRING # Authorizes Google Cloud Storage to encrypt and decrypt using key1. gsutil kms authorize -p $GCLOUD_TESTS_GOLANG_PROJECT_ID -k $GCLOUD_TESTS_GOLANG_KEYRING/cryptoKeys/key1 ``` #### Running Once you've done the necessary setup, you can run the integration tests by running: ``` sh $ go test -v cloud.google.com/go/... ``` #### Replay Some packages can record the RPCs during integration tests to a file for subsequent replay. To record, pass the `-record` flag to `go test`. The recording will be saved to the _package_`.replay` file. To replay integration tests from a saved recording, the replay file must be present, the `-short` flag must be passed to `go test`, and the `GCLOUD_TESTS_GOLANG_ENABLE_REPLAY` environment variable must have a non-empty value. ## Contributor License Agreements Before we can accept your pull requests you'll need to sign a Contributor License Agreement (CLA): - **If you are an individual writing original source code** and **you own the intellectual property**, then you'll need to sign an [individual CLA][indvcla]. - **If you work for a company that wants to allow you to contribute your work**, then you'll need to sign a [corporate CLA][corpcla]. You can sign these electronically (just scroll to the bottom). After that, we'll be able to accept your pull requests. ## Contributor Code of Conduct As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality. Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery * Personal attacks * Trolling or insulting/derogatory comments * Public or private harassment * Publishing other's private information, such as physical or electronic addresses, without explicit permission * Other unethical or unprofessional conduct. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team. This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers. This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/) [gcloudcli]: https://developers.google.com/cloud/sdk/gcloud/ [indvcla]: https://developers.google.com/open-source/cla/individual [corpcla]: https://developers.google.com/open-source/cla/corporate google-cloud-go-0.49.0/LICENSE000066400000000000000000000261361356504100700156050ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. google-cloud-go-0.49.0/README.md000066400000000000000000000301761356504100700160560ustar00rootroot00000000000000# Google Cloud Client Libraries for Go [![GoDoc](https://godoc.org/cloud.google.com/go?status.svg)](https://godoc.org/cloud.google.com/go) Go packages for [Google Cloud Platform](https://cloud.google.com) services. ``` go import "cloud.google.com/go" ``` To install the packages on your system, *do not clone the repo*. Instead: 1. Change to your project directory: ``` cd /my/cloud/project ``` 1. Get the package you want to use. Some products have their own module, so it's best to `go get` the package(s) you want to use: ``` $ go get cloud.google.com/go/firestore # Replace with the package you want to use. ``` **NOTE:** Some of these packages are under development, and may occasionally make backwards-incompatible changes. **NOTE:** Github repo is a mirror of [https://code.googlesource.com/gocloud](https://code.googlesource.com/gocloud). ## Supported APIs Google API | Status | Package ------------------------------------------------|--------------|----------------------------------------------------------- [Asset][cloud-asset] | alpha | [`cloud.google.com/go/asset/v1beta`](https://godoc.org/cloud.google.com/go/asset/v1beta) [Automl][cloud-automl] | stable | [`cloud.google.com/go/automl/apiv1`](https://godoc.org/cloud.google.com/go/automl/apiv1) [BigQuery][cloud-bigquery] | stable | [`cloud.google.com/go/bigquery`](https://godoc.org/cloud.google.com/go/bigquery) [Bigtable][cloud-bigtable] | stable | [`cloud.google.com/go/bigtable`](https://godoc.org/cloud.google.com/go/bigtable) [Cloudbuild][cloud-build] | alpha | [`cloud.google.com/go/cloudbuild/apiv1`](https://godoc.org/cloud.google.com/go/cloudbuild/apiv1) [Cloudtasks][cloud-tasks] | stable | [`cloud.google.com/go/cloudtasks/apiv2`](https://godoc.org/cloud.google.com/go/cloudtasks/apiv2) [Container][cloud-container] | stable | [`cloud.google.com/go/container/apiv1`](https://godoc.org/cloud.google.com/go/container/apiv1) [ContainerAnalysis][cloud-containeranalysis] | beta | [`cloud.google.com/go/containeranalysis/apiv1`](https://godoc.org/cloud.google.com/go/containeranalysis/apiv1) [Dataproc][cloud-dataproc] | stable | [`cloud.google.com/go/dataproc/apiv1`](https://godoc.org/cloud.google.com/go/dataproc/apiv1) [Datastore][cloud-datastore] | stable | [`cloud.google.com/go/datastore`](https://godoc.org/cloud.google.com/go/datastore) [Debugger][cloud-debugger] | alpha | [`cloud.google.com/go/debugger/apiv2`](https://godoc.org/cloud.google.com/go/debugger/apiv2) [Dialogflow][cloud-dialogflow] | alpha | [`cloud.google.com/go/dialogflow/apiv2`](https://godoc.org/cloud.google.com/go/dialogflow/apiv2) [Data Loss Prevention][cloud-dlp] | alpha | [`cloud.google.com/go/dlp/apiv2`](https://godoc.org/cloud.google.com/go/dlp/apiv2) [ErrorReporting][cloud-errors] | alpha | [`cloud.google.com/go/errorreporting`](https://godoc.org/cloud.google.com/go/errorreporting) [Firestore][cloud-firestore] | stable | [`cloud.google.com/go/firestore`](https://godoc.org/cloud.google.com/go/firestore) [IAM][cloud-iam] | stable | [`cloud.google.com/go/iam`](https://godoc.org/cloud.google.com/go/iam) [IoT][cloud-iot] | alpha | [`cloud.google.com/iot/apiv1`](https://godoc.org/cloud.google.com/iot/apiv1) [IRM][cloud-irm] | alpha | [`cloud.google.com/irm/apiv1alpha2`](https://godoc.org/cloud.google.com/irm/apiv1alpha2) [KMS][cloud-kms] | stable | [`cloud.google.com/go/kms`](https://godoc.org/cloud.google.com/go/kms) [Natural Language][cloud-natural-language] | stable | [`cloud.google.com/go/language/apiv1`](https://godoc.org/cloud.google.com/go/language/apiv1) [Logging][cloud-logging] | stable | [`cloud.google.com/go/logging`](https://godoc.org/cloud.google.com/go/logging) [Memorystore][cloud-memorystore] | alpha | [`cloud.google.com/go/redis/apiv1`](https://godoc.org/cloud.google.com/go/redis/apiv1) [Monitoring][cloud-monitoring] | alpha | [`cloud.google.com/go/monitoring/apiv3`](https://godoc.org/cloud.google.com/go/monitoring/apiv3) [OS Login][cloud-oslogin] | alpha | [`cloud.google.com/go/oslogin/apiv1`](https://godoc.org/cloud.google.com/go/oslogin/apiv1) [Pub/Sub][cloud-pubsub] | stable | [`cloud.google.com/go/pubsub`](https://godoc.org/cloud.google.com/go/pubsub) [Phishing Protection][cloud-phishingprotection] | alpha | [`cloud.google.com/go/phishingprotection/apiv1beta1`](https://godoc.org/cloud.google.com/go/phishingprotection/apiv1beta1) [reCAPTCHA Enterprise][cloud-recaptcha] | alpha | [`cloud.google.com/go/recaptchaenterprise/apiv1beta1`](https://godoc.org/cloud.google.com/go/recaptchaenterprise/apiv1beta1) [Recommender][cloud-recommender] | beta | [`cloud.google.com/go/recommender/apiv1beta1`](https://godoc.org/cloud.google.com/go/recommender/apiv1beta1) [Scheduler][cloud-scheduler] | stable | [`cloud.google.com/go/scheduler/apiv1`](https://godoc.org/cloud.google.com/go/scheduler/apiv1) [Securitycenter][cloud-securitycenter] | alpha | [`cloud.google.com/go/securitycenter/apiv1`](https://godoc.org/cloud.google.com/go/securitycenter/apiv1) [Spanner][cloud-spanner] | stable | [`cloud.google.com/go/spanner`](https://godoc.org/cloud.google.com/go/spanner) [Speech][cloud-speech] | stable | [`cloud.google.com/go/speech/apiv1`](https://godoc.org/cloud.google.com/go/speech/apiv1) [Storage][cloud-storage] | stable | [`cloud.google.com/go/storage`](https://godoc.org/cloud.google.com/go/storage) [Talent][cloud-talent] | alpha | [`cloud.google.com/go/talent/apiv4beta1`](https://godoc.org/cloud.google.com/go/talent/apiv4beta1) [Text To Speech][cloud-texttospeech] | alpha | [`cloud.google.com/go/texttospeech/apiv1`](https://godoc.org/cloud.google.com/go/texttospeech/apiv1) [Trace][cloud-trace] | alpha | [`cloud.google.com/go/trace/apiv2`](https://godoc.org/cloud.google.com/go/trace/apiv2) [Translate][cloud-translate] | stable | [`cloud.google.com/go/translate`](https://godoc.org/cloud.google.com/go/translate) [Video Intelligence][cloud-video] | alpha | [`cloud.google.com/go/videointelligence/apiv1beta1`](https://godoc.org/cloud.google.com/go/videointelligence/apiv1beta1) [Vision][cloud-vision] | stable | [`cloud.google.com/go/vision/apiv1`](https://godoc.org/cloud.google.com/go/vision/apiv1) [Webrisk][cloud-webrisk] | alpha | [`cloud.google.com/go/webrisk/apiv1beta1`](https://godoc.org/cloud.google.com/go/webrisk/apiv1beta1) > **Alpha status**: the API is still being actively developed. As a > result, it might change in backward-incompatible ways and is not recommended > for production use. > > **Beta status**: the API is largely complete, but still has outstanding > features and bugs to be addressed. There may be minor backwards-incompatible > changes where necessary. > > **Stable status**: the API is mature and ready for production use. We will > continue addressing bugs and feature requests. Documentation and examples are available at [godoc.org/cloud.google.com/go](https://godoc.org/cloud.google.com/go) ## Go Versions Supported We support the two most recent major versions of Go. If Google App Engine uses an older version, we support that as well. ## Authorization By default, each API will use [Google Application Default Credentials](https://developers.google.com/identity/protocols/application-default-credentials) for authorization credentials used in calling the API endpoints. This will allow your application to run in many environments without requiring explicit configuration. [snip]:# (auth) ```go client, err := storage.NewClient(ctx) ``` To authorize using a [JSON key file](https://cloud.google.com/iam/docs/managing-service-account-keys), pass [`option.WithCredentialsFile`](https://godoc.org/google.golang.org/api/option#WithCredentialsFile) to the `NewClient` function of the desired package. For example: [snip]:# (auth-JSON) ```go client, err := storage.NewClient(ctx, option.WithCredentialsFile("path/to/keyfile.json")) ``` You can exert more control over authorization by using the [`golang.org/x/oauth2`](https://godoc.org/golang.org/x/oauth2) package to create an `oauth2.TokenSource`. Then pass [`option.WithTokenSource`](https://godoc.org/google.golang.org/api/option#WithTokenSource) to the `NewClient` function: [snip]:# (auth-ts) ```go tokenSource := ... client, err := storage.NewClient(ctx, option.WithTokenSource(tokenSource)) ``` ## Contributing Contributions are welcome. Please, see the [CONTRIBUTING](https://github.com/GoogleCloudPlatform/google-cloud-go/blob/master/CONTRIBUTING.md) document for details. We're using Gerrit for our code reviews. Please don't open pull requests against this repo, new pull requests will be automatically closed. Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms. See [Contributor Code of Conduct](https://github.com/GoogleCloudPlatform/google-cloud-go/blob/master/CONTRIBUTING.md#contributor-code-of-conduct) for more information. [cloud-asset]: https://cloud.google.com/security-command-center/docs/how-to-asset-inventory [cloud-automl]: https://cloud.google.com/automl [cloud-build]: https://cloud.google.com/cloud-build/ [cloud-bigquery]: https://cloud.google.com/bigquery/ [cloud-bigtable]: https://cloud.google.com/bigtable/ [cloud-container]: https://cloud.google.com/containers/ [cloud-containeranalysis]: https://cloud.google.com/container-registry/docs/container-analysis [cloud-dataproc]: https://cloud.google.com/dataproc/ [cloud-datastore]: https://cloud.google.com/datastore/ [cloud-dialogflow]: https://cloud.google.com/dialogflow-enterprise/ [cloud-debugger]: https://cloud.google.com/debugger/ [cloud-dlp]: https://cloud.google.com/dlp/ [cloud-errors]: https://cloud.google.com/error-reporting/ [cloud-firestore]: https://cloud.google.com/firestore/ [cloud-iam]: https://cloud.google.com/iam/ [cloud-iot]: https://cloud.google.com/iot-core/ [cloud-irm]: https://cloud.google.com/incident-response/docs/concepts [cloud-kms]: https://cloud.google.com/kms/ [cloud-pubsub]: https://cloud.google.com/pubsub/ [cloud-storage]: https://cloud.google.com/storage/ [cloud-language]: https://cloud.google.com/natural-language [cloud-logging]: https://cloud.google.com/logging/ [cloud-natural-language]: https://cloud.google.com/natural-language/ [cloud-memorystore]: https://cloud.google.com/memorystore/ [cloud-monitoring]: https://cloud.google.com/monitoring/ [cloud-oslogin]: https://cloud.google.com/compute/docs/oslogin/rest [cloud-phishingprotection]: https://cloud.google.com/phishing-protection/ [cloud-securitycenter]: https://cloud.google.com/security-command-center/ [cloud-scheduler]: https://cloud.google.com/scheduler [cloud-spanner]: https://cloud.google.com/spanner/ [cloud-speech]: https://cloud.google.com/speech [cloud-talent]: https://cloud.google.com/solutions/talent-solution/ [cloud-tasks]: https://cloud.google.com/tasks/ [cloud-texttospeech]: https://cloud.google.com/texttospeech/ [cloud-talent]: https://cloud.google.com/solutions/talent-solution/ [cloud-trace]: https://cloud.google.com/trace/ [cloud-translate]: https://cloud.google.com/translate [cloud-recaptcha]: https://cloud.google.com/recaptcha-enterprise/ [cloud-recommender]: https://cloud.google.com/recommendations/ [cloud-video]: https://cloud.google.com/video-intelligence/ [cloud-vision]: https://cloud.google.com/vision [cloud-webrisk]: https://cloud.google.com/web-risk/ google-cloud-go-0.49.0/RELEASING.md000066400000000000000000000140311356504100700164220ustar00rootroot00000000000000# Setup from scratch 1. [Install Go](https://golang.org/dl/). 1. Ensure that your `GOBIN` directory (by default `$(go env GOPATH)/bin`) is in your `PATH`. 1. Check it's working by running `go version`. * If it doesn't work, check the install location, usually `/usr/local/go`, is on your `PATH`. 1. Sign one of the [contributor license agreements](#contributor-license-agreements) below. 1. Run `go get golang.org/x/review/git-codereview && go install golang.org/x/review/git-codereview` to install the code reviewing tool. 1. Ensure it's working by running `git codereview` (check your `PATH` if not). 1. If you would like, you may want to set up aliases for `git-codereview`, such that `git codereview change` becomes `git change`. See the [godoc](https://godoc.org/golang.org/x/review/git-codereview) for details. * Should you run into issues with the `git-codereview` tool, please note that all error messages will assume that you have set up these aliases. 1. Change to a directory of your choosing and clone the repo. ``` cd ~/code git clone https://code.googlesource.com/gocloud ``` * If you have already checked out the source, make sure that the remote `git` `origin` is https://code.googlesource.com/gocloud: ``` git remote -v # ... git remote set-url origin https://code.googlesource.com/gocloud ``` * The project uses [Go Modules](https://blog.golang.org/using-go-modules) for dependency management See [`gopls`](https://github.com/golang/go/wiki/gopls) for making your editor work with modules. 1. Change to the project directory and add the github remote: ``` cd ~/code/gocloud git remote add github https://github.com/googleapis/google-cloud-go ``` 1. Make sure your `git` auth is configured correctly by visiting https://code.googlesource.com, clicking "Generate Password" at the top-right, and following the directions. Otherwise, `git codereview mail` in the next step will fail. # Which module to release? The Go client libraries have several modules. Each module does not strictly correspond to a single library - they correspond to trees of directories. If a file needs to be released, you must release the closest ancestor module. To see all modules: ``` $ cat `find . -name go.mod` | grep module module cloud.google.com/go module cloud.google.com/go/bigtable module cloud.google.com/go/firestore module cloud.google.com/go/bigquery module cloud.google.com/go/storage module cloud.google.com/go/datastore module cloud.google.com/go/pubsub module cloud.google.com/go/spanner module cloud.google.com/go/logging ``` The `cloud.google.com/go` is the repository root module. Each other module is a submodule. So, if you need to release a change in `bigtable/bttest/inmem.go`, the closest ancestor module is `cloud.google.com/go/bigtable` - so you should release a new version of the `cloud.google.com/go/bigtable` submodule. If you need to release a change in `asset/apiv1/asset_client.go`, the closest ancestor module is `cloud.google.com/go` - so you should release a new version of the `cloud.google.com/go` repository root module. Note: releasing `cloud.google.com/go` has no impact on any of the submodules, and vice-versa. They are released entirely independently. # How to release `cloud.google.com/go` 1. Navigate to `~/code/gocloud/` and switch to master. 1. `git pull` 1. Run `git tag -l | grep -v beta | grep -v alpha` to see all existing releases. The current latest tag `$CV` is the largest tag. It should look something like `vX.Y.Z` (note: ignore all `LIB/vX.Y.Z` tags - these are tags for a specific library, not the module root). We'll call the current version `$CV` and the new version `$NV`. 1. On master, run `git log $CV...` to list all the changes since the last release. NOTE: You must manually visually parse out changes to submodules [1] (the `git log` is going to show you things in submodules, which are not going to be part of your release). 1. Edit `CHANGES.md` to include a summary of the changes. 1. `cd internal/version && go generate && cd -` 1. Mail the CL: `git add -A && git change && git mail` 1. Wait for the CL to be submitted. Once it's submitted, and without submitting any other CLs in the meantime: a. Switch to master. b. `git pull` c. Tag the repo with the next version: `git tag $NV`. d. Push the tag to both remotes: `git push origin $NV` `git push github $NV` 1. Update [the releases page](https://github.com/googleapis/google-cloud-go/releases) with the new release, copying the contents of `CHANGES.md`. # How to release a submodule We have several submodules, including `cloud.google.com/go/logging`, `cloud.google.com/go/datastore`, and so on. To release a submodule: (these instructions assume we're releasing `cloud.google.com/go/datastore` - adjust accordingly) 1. Navigate to `~/code/gocloud/` and switch to master. 1. `git pull` 1. Run `git tag -l | grep datastore | grep -v beta | grep -v alpha` to see all existing releases. The current latest tag `$CV` is the largest tag. It should look something like `datastore/vX.Y.Z`. We'll call the current version `$CV` and the new version `$NV`. 1. On master, run `git log $CV.. -- datastore/` to list all the changes to the submodule directory since the last release. 1. Edit `datastore/CHANGES.md` to include a summary of the changes. 1. `cd internal/version && go generate && cd -` 1. Mail the CL: `git add -A && git change && git mail` 1. Wait for the CL to be submitted. Once it's submitted, and without submitting any other CLs in the meantime: a. Switch to master. b. `git pull` c. Tag the repo with the next version: `git tag $NV`. d. Push the tag to both remotes: `git push origin $NV` `git push github $NV` 1. Update [the releases page](https://github.com/googleapis/google-cloud-go/releases) with the new release, copying the contents of `datastore/CHANGES.md`. # Appendix 1: This should get better as submodule tooling matures. google-cloud-go-0.49.0/asset/000077500000000000000000000000001356504100700157075ustar00rootroot00000000000000google-cloud-go-0.49.0/asset/apiv1/000077500000000000000000000000001356504100700167275ustar00rootroot00000000000000google-cloud-go-0.49.0/asset/apiv1/.repo-metadata.json000066400000000000000000000006541356504100700224300ustar00rootroot00000000000000{ "name": "asset", "name_pretty": "Cloud Asset Inventory API", "product_documentation": "https://cloud.google.com/resource-manager", "client_documentation": "https://godoc.org/cloud.google.com/go/asset/apiv1", "release_level": "alpha", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go/asset", "api_id": "cloudasset.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/asset/apiv1/asset_client.go000066400000000000000000000226141356504100700217400ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go_gapic. DO NOT EDIT. package asset import ( "context" "fmt" "math" "net/url" "time" "cloud.google.com/go/longrunning" lroauto "cloud.google.com/go/longrunning/autogen" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" "google.golang.org/api/transport" assetpb "google.golang.org/genproto/googleapis/cloud/asset/v1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // CallOptions contains the retry settings for each method of Client. type CallOptions struct { ExportAssets []gax.CallOption BatchGetAssetsHistory []gax.CallOption } func defaultClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("cloudasset.googleapis.com:443"), option.WithGRPCDialOption(grpc.WithDisableServiceConfig()), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultCallOptions() *CallOptions { return &CallOptions{ ExportAssets: []gax.CallOption{}, BatchGetAssetsHistory: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, } } // Client is a client for interacting with Cloud Asset API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. client assetpb.AssetServiceClient // LROClient is used internally to handle longrunning operations. // It is exposed so that its CallOptions can be modified if required. // Users should not Close this client. LROClient *lroauto.OperationsClient // The call options for this service. CallOptions *CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewClient creates a new asset service client. // // Asset service definition. func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultClientOptions(), opts...)...) if err != nil { return nil, err } c := &Client{ conn: conn, CallOptions: defaultCallOptions(), client: assetpb.NewAssetServiceClient(conn), } c.setGoogleClientInfo() c.LROClient, err = lroauto.NewOperationsClient(ctx, option.WithGRPCConn(conn)) if err != nil { // This error "should not happen", since we are just reusing old connection // and never actually need to dial. // If this does happen, we could leak conn. However, we cannot close conn: // If the user invoked the function with option.WithGRPCConn, // we would close a connection that's still in use. // TODO(pongad): investigate error conditions. return nil, err } return c, nil } // Connection returns the client's connection to the API service. func (c *Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *Client) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *Client) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // ExportAssets exports assets with time and resource types to a given Cloud Storage // location. The output format is newline-delimited JSON. // This API implements the [google.longrunning.Operation][google.longrunning.Operation] API allowing you // to keep track of the export. func (c *Client) ExportAssets(ctx context.Context, req *assetpb.ExportAssetsRequest, opts ...gax.CallOption) (*ExportAssetsOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ExportAssets[0:len(c.CallOptions.ExportAssets):len(c.CallOptions.ExportAssets)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ExportAssets(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &ExportAssetsOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // BatchGetAssetsHistory batch gets the update history of assets that overlap a time window. // For RESOURCE content, this API outputs history with asset in both // non-delete or deleted status. // For IAM_POLICY content, this API outputs history when the asset and its // attached IAM POLICY both exist. This can create gaps in the output history. // If a specified asset does not exist, this API returns an INVALID_ARGUMENT // error. func (c *Client) BatchGetAssetsHistory(ctx context.Context, req *assetpb.BatchGetAssetsHistoryRequest, opts ...gax.CallOption) (*assetpb.BatchGetAssetsHistoryResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.BatchGetAssetsHistory[0:len(c.CallOptions.BatchGetAssetsHistory):len(c.CallOptions.BatchGetAssetsHistory)], opts...) var resp *assetpb.BatchGetAssetsHistoryResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.BatchGetAssetsHistory(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ExportAssetsOperation manages a long-running operation from ExportAssets. type ExportAssetsOperation struct { lro *longrunning.Operation } // ExportAssetsOperation returns a new ExportAssetsOperation from a given name. // The name must be that of a previously created ExportAssetsOperation, possibly from a different process. func (c *Client) ExportAssetsOperation(name string) *ExportAssetsOperation { return &ExportAssetsOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *ExportAssetsOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*assetpb.ExportAssetsResponse, error) { var resp assetpb.ExportAssetsResponse if err := op.lro.WaitWithInterval(ctx, &resp, time.Minute, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *ExportAssetsOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*assetpb.ExportAssetsResponse, error) { var resp assetpb.ExportAssetsResponse if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *ExportAssetsOperation) Metadata() (*assetpb.ExportAssetsRequest, error) { var meta assetpb.ExportAssetsRequest if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *ExportAssetsOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *ExportAssetsOperation) Name() string { return op.lro.Name() } google-cloud-go-0.49.0/asset/apiv1/asset_client_example_test.go000066400000000000000000000035351356504100700245130ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go_gapic. DO NOT EDIT. package asset_test import ( "context" asset "cloud.google.com/go/asset/apiv1" assetpb "google.golang.org/genproto/googleapis/cloud/asset/v1" ) func ExampleNewClient() { ctx := context.Background() c, err := asset.NewClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleClient_ExportAssets() { // import assetpb "google.golang.org/genproto/googleapis/cloud/asset/v1" ctx := context.Background() c, err := asset.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &assetpb.ExportAssetsRequest{ // TODO: Fill request struct fields. } op, err := c.ExportAssets(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_BatchGetAssetsHistory() { // import assetpb "google.golang.org/genproto/googleapis/cloud/asset/v1" ctx := context.Background() c, err := asset.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &assetpb.BatchGetAssetsHistoryRequest{ // TODO: Fill request struct fields. } resp, err := c.BatchGetAssetsHistory(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/asset/apiv1/doc.go000066400000000000000000000053341356504100700200300ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go_gapic. DO NOT EDIT. // Package asset is an auto-generated package for the // Cloud Asset API. // // The cloud asset API manages the history and inventory of cloud resources. // // NOTE: This package is in alpha. It is not stable, and is likely to change. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package asset // import "cloud.google.com/go/asset/apiv1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) const versionClient = "20191115" func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return !strings.ContainsRune("0123456789.", r) } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } google-cloud-go-0.49.0/asset/apiv1/mock_test.go000066400000000000000000000160621356504100700212530ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package asset import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" "google.golang.org/api/option" assetpb "google.golang.org/genproto/googleapis/cloud/asset/v1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockAssetServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. assetpb.AssetServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockAssetServer) ExportAssets(ctx context.Context, req *assetpb.ExportAssetsRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockAssetServer) BatchGetAssetsHistory(ctx context.Context, req *assetpb.BatchGetAssetsHistoryRequest) (*assetpb.BatchGetAssetsHistoryResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*assetpb.BatchGetAssetsHistoryResponse), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockAsset mockAssetServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() assetpb.RegisterAssetServiceServer(serv, &mockAsset) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestAssetServiceExportAssets(t *testing.T) { var expectedResponse *assetpb.ExportAssetsResponse = &assetpb.ExportAssetsResponse{} mockAsset.err = nil mockAsset.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockAsset.resps = append(mockAsset.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var parent string = "parent-995424086" var outputConfig *assetpb.OutputConfig = &assetpb.OutputConfig{} var request = &assetpb.ExportAssetsRequest{ Parent: parent, OutputConfig: outputConfig, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.ExportAssets(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockAsset.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAssetServiceExportAssetsError(t *testing.T) { errCode := codes.PermissionDenied mockAsset.err = nil mockAsset.resps = append(mockAsset.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var parent string = "parent-995424086" var outputConfig *assetpb.OutputConfig = &assetpb.OutputConfig{} var request = &assetpb.ExportAssetsRequest{ Parent: parent, OutputConfig: outputConfig, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.ExportAssets(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAssetServiceBatchGetAssetsHistory(t *testing.T) { var expectedResponse *assetpb.BatchGetAssetsHistoryResponse = &assetpb.BatchGetAssetsHistoryResponse{} mockAsset.err = nil mockAsset.reqs = nil mockAsset.resps = append(mockAsset.resps[:0], expectedResponse) var parent string = "parent-995424086" var contentType assetpb.ContentType = assetpb.ContentType_CONTENT_TYPE_UNSPECIFIED var readTimeWindow *assetpb.TimeWindow = &assetpb.TimeWindow{} var request = &assetpb.BatchGetAssetsHistoryRequest{ Parent: parent, ContentType: contentType, ReadTimeWindow: readTimeWindow, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.BatchGetAssetsHistory(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockAsset.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAssetServiceBatchGetAssetsHistoryError(t *testing.T) { errCode := codes.PermissionDenied mockAsset.err = gstatus.Error(errCode, "test error") var parent string = "parent-995424086" var contentType assetpb.ContentType = assetpb.ContentType_CONTENT_TYPE_UNSPECIFIED var readTimeWindow *assetpb.TimeWindow = &assetpb.TimeWindow{} var request = &assetpb.BatchGetAssetsHistoryRequest{ Parent: parent, ContentType: contentType, ReadTimeWindow: readTimeWindow, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.BatchGetAssetsHistory(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/asset/apiv1beta1/000077500000000000000000000000001356504100700176445ustar00rootroot00000000000000google-cloud-go-0.49.0/asset/apiv1beta1/.repo-metadata.json000066400000000000000000000006521356504100700233430ustar00rootroot00000000000000{ "name": "asset", "name_pretty": "Cloud Asset Inventory API", "product_documentation": "https://cloud.google.com/resource-manager", "client_documentation": "https://godoc.org/cloud.google.com/go/asset/apiv1beta1", "release_level": "beta", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "cloudasset.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/asset/apiv1beta1/asset_client.go000066400000000000000000000226151356504100700226560ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package asset import ( "context" "fmt" "math" "net/url" "time" "cloud.google.com/go/longrunning" lroauto "cloud.google.com/go/longrunning/autogen" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" "google.golang.org/api/transport" assetpb "google.golang.org/genproto/googleapis/cloud/asset/v1beta1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // CallOptions contains the retry settings for each method of Client. type CallOptions struct { ExportAssets []gax.CallOption BatchGetAssetsHistory []gax.CallOption } func defaultClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("cloudasset.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultCallOptions() *CallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &CallOptions{ ExportAssets: retry[[2]string{"default", "non_idempotent"}], BatchGetAssetsHistory: retry[[2]string{"default", "idempotent"}], } } // Client is a client for interacting with Cloud Asset API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. client assetpb.AssetServiceClient // LROClient is used internally to handle longrunning operations. // It is exposed so that its CallOptions can be modified if required. // Users should not Close this client. LROClient *lroauto.OperationsClient // The call options for this service. CallOptions *CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewClient creates a new asset service client. // // Asset service definition. func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultClientOptions(), opts...)...) if err != nil { return nil, err } c := &Client{ conn: conn, CallOptions: defaultCallOptions(), client: assetpb.NewAssetServiceClient(conn), } c.setGoogleClientInfo() c.LROClient, err = lroauto.NewOperationsClient(ctx, option.WithGRPCConn(conn)) if err != nil { // This error "should not happen", since we are just reusing old connection // and never actually need to dial. // If this does happen, we could leak conn. However, we cannot close conn: // If the user invoked the function with option.WithGRPCConn, // we would close a connection that's still in use. // TODO(pongad): investigate error conditions. return nil, err } return c, nil } // Connection returns the client's connection to the API service. func (c *Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *Client) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *Client) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // ExportAssets exports assets with time and resource types to a given Cloud Storage // location. The output format is newline-delimited JSON. // This API implements the // [google.longrunning.Operation][google.longrunning.Operation] API allowing // you to keep track of the export. func (c *Client) ExportAssets(ctx context.Context, req *assetpb.ExportAssetsRequest, opts ...gax.CallOption) (*ExportAssetsOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ExportAssets[0:len(c.CallOptions.ExportAssets):len(c.CallOptions.ExportAssets)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ExportAssets(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &ExportAssetsOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // BatchGetAssetsHistory batch gets the update history of assets that overlap a time window. // For RESOURCE content, this API outputs history with asset in both // non-delete or deleted status. // For IAM_POLICY content, this API outputs history when the asset and its // attached IAM POLICY both exist. This can create gaps in the output history. func (c *Client) BatchGetAssetsHistory(ctx context.Context, req *assetpb.BatchGetAssetsHistoryRequest, opts ...gax.CallOption) (*assetpb.BatchGetAssetsHistoryResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.BatchGetAssetsHistory[0:len(c.CallOptions.BatchGetAssetsHistory):len(c.CallOptions.BatchGetAssetsHistory)], opts...) var resp *assetpb.BatchGetAssetsHistoryResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.BatchGetAssetsHistory(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ExportAssetsOperation manages a long-running operation from ExportAssets. type ExportAssetsOperation struct { lro *longrunning.Operation } // ExportAssetsOperation returns a new ExportAssetsOperation from a given name. // The name must be that of a previously created ExportAssetsOperation, possibly from a different process. func (c *Client) ExportAssetsOperation(name string) *ExportAssetsOperation { return &ExportAssetsOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *ExportAssetsOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*assetpb.ExportAssetsResponse, error) { var resp assetpb.ExportAssetsResponse if err := op.lro.WaitWithInterval(ctx, &resp, 5000*time.Millisecond, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *ExportAssetsOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*assetpb.ExportAssetsResponse, error) { var resp assetpb.ExportAssetsResponse if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *ExportAssetsOperation) Metadata() (*assetpb.ExportAssetsRequest, error) { var meta assetpb.ExportAssetsRequest if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *ExportAssetsOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *ExportAssetsOperation) Name() string { return op.lro.Name() } google-cloud-go-0.49.0/asset/apiv1beta1/asset_client_example_test.go000066400000000000000000000033151356504100700254240ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package asset_test import ( "context" asset "cloud.google.com/go/asset/apiv1beta1" assetpb "google.golang.org/genproto/googleapis/cloud/asset/v1beta1" ) func ExampleNewClient() { ctx := context.Background() c, err := asset.NewClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleClient_ExportAssets() { ctx := context.Background() c, err := asset.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &assetpb.ExportAssetsRequest{ // TODO: Fill request struct fields. } op, err := c.ExportAssets(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_BatchGetAssetsHistory() { ctx := context.Background() c, err := asset.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &assetpb.BatchGetAssetsHistoryRequest{ // TODO: Fill request struct fields. } resp, err := c.BatchGetAssetsHistory(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/asset/apiv1beta1/doc.go000066400000000000000000000053401356504100700207420ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package asset is an auto-generated package for the // Cloud Asset API. // // NOTE: This package is in beta. It is not stable, and may be subject to changes. // // The cloud asset API manages the history and inventory of cloud resources. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package asset // import "cloud.google.com/go/asset/apiv1beta1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "UNKNOWN" google-cloud-go-0.49.0/asset/apiv1beta1/mock_test.go000066400000000000000000000163231356504100700221700ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package asset import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" "google.golang.org/api/option" assetpb "google.golang.org/genproto/googleapis/cloud/asset/v1beta1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockAssetServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. assetpb.AssetServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockAssetServer) ExportAssets(ctx context.Context, req *assetpb.ExportAssetsRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockAssetServer) BatchGetAssetsHistory(ctx context.Context, req *assetpb.BatchGetAssetsHistoryRequest) (*assetpb.BatchGetAssetsHistoryResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*assetpb.BatchGetAssetsHistoryResponse), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockAsset mockAssetServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() assetpb.RegisterAssetServiceServer(serv, &mockAsset) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestAssetServiceExportAssets(t *testing.T) { var expectedResponse *assetpb.ExportAssetsResponse = &assetpb.ExportAssetsResponse{} mockAsset.err = nil mockAsset.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockAsset.resps = append(mockAsset.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var outputConfig *assetpb.OutputConfig = &assetpb.OutputConfig{} var request = &assetpb.ExportAssetsRequest{ Parent: formattedParent, OutputConfig: outputConfig, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.ExportAssets(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockAsset.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAssetServiceExportAssetsError(t *testing.T) { errCode := codes.PermissionDenied mockAsset.err = nil mockAsset.resps = append(mockAsset.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var outputConfig *assetpb.OutputConfig = &assetpb.OutputConfig{} var request = &assetpb.ExportAssetsRequest{ Parent: formattedParent, OutputConfig: outputConfig, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.ExportAssets(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAssetServiceBatchGetAssetsHistory(t *testing.T) { var expectedResponse *assetpb.BatchGetAssetsHistoryResponse = &assetpb.BatchGetAssetsHistoryResponse{} mockAsset.err = nil mockAsset.reqs = nil mockAsset.resps = append(mockAsset.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var contentType assetpb.ContentType = assetpb.ContentType_CONTENT_TYPE_UNSPECIFIED var readTimeWindow *assetpb.TimeWindow = &assetpb.TimeWindow{} var request = &assetpb.BatchGetAssetsHistoryRequest{ Parent: formattedParent, ContentType: contentType, ReadTimeWindow: readTimeWindow, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.BatchGetAssetsHistory(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockAsset.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAssetServiceBatchGetAssetsHistoryError(t *testing.T) { errCode := codes.PermissionDenied mockAsset.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var contentType assetpb.ContentType = assetpb.ContentType_CONTENT_TYPE_UNSPECIFIED var readTimeWindow *assetpb.TimeWindow = &assetpb.TimeWindow{} var request = &assetpb.BatchGetAssetsHistoryRequest{ Parent: formattedParent, ContentType: contentType, ReadTimeWindow: readTimeWindow, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.BatchGetAssetsHistory(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/asset/apiv1p2beta1/000077500000000000000000000000001356504100700201065ustar00rootroot00000000000000google-cloud-go-0.49.0/asset/apiv1p2beta1/.repo-metadata.json000066400000000000000000000006541356504100700236070ustar00rootroot00000000000000{ "name": "asset", "name_pretty": "Cloud Asset Inventory API", "product_documentation": "https://cloud.google.com/resource-manager", "client_documentation": "https://godoc.org/cloud.google.com/go/asset/apiv1p2beta1", "release_level": "beta", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "cloudasset.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/asset/apiv1p2beta1/asset_client.go000066400000000000000000000327121356504100700231170ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package asset import ( "context" "fmt" "math" "net/url" "time" "cloud.google.com/go/longrunning" lroauto "cloud.google.com/go/longrunning/autogen" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" "google.golang.org/api/transport" assetpb "google.golang.org/genproto/googleapis/cloud/asset/v1p2beta1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // CallOptions contains the retry settings for each method of Client. type CallOptions struct { ExportAssets []gax.CallOption BatchGetAssetsHistory []gax.CallOption CreateFeed []gax.CallOption GetFeed []gax.CallOption ListFeeds []gax.CallOption UpdateFeed []gax.CallOption DeleteFeed []gax.CallOption } func defaultClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("cloudasset.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultCallOptions() *CallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &CallOptions{ ExportAssets: retry[[2]string{"default", "non_idempotent"}], BatchGetAssetsHistory: retry[[2]string{"default", "idempotent"}], CreateFeed: retry[[2]string{"default", "non_idempotent"}], GetFeed: retry[[2]string{"default", "idempotent"}], ListFeeds: retry[[2]string{"default", "idempotent"}], UpdateFeed: retry[[2]string{"default", "non_idempotent"}], DeleteFeed: retry[[2]string{"default", "idempotent"}], } } // Client is a client for interacting with Cloud Asset API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. client assetpb.AssetServiceClient // LROClient is used internally to handle longrunning operations. // It is exposed so that its CallOptions can be modified if required. // Users should not Close this client. LROClient *lroauto.OperationsClient // The call options for this service. CallOptions *CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewClient creates a new asset service client. // // Asset service definition. func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultClientOptions(), opts...)...) if err != nil { return nil, err } c := &Client{ conn: conn, CallOptions: defaultCallOptions(), client: assetpb.NewAssetServiceClient(conn), } c.setGoogleClientInfo() c.LROClient, err = lroauto.NewOperationsClient(ctx, option.WithGRPCConn(conn)) if err != nil { // This error "should not happen", since we are just reusing old connection // and never actually need to dial. // If this does happen, we could leak conn. However, we cannot close conn: // If the user invoked the function with option.WithGRPCConn, // we would close a connection that's still in use. // TODO(pongad): investigate error conditions. return nil, err } return c, nil } // Connection returns the client's connection to the API service. func (c *Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *Client) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *Client) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // ExportAssets exports assets with time and resource types to a given Cloud Storage // location. The output format is newline-delimited JSON. // This API implements the [google.longrunning.Operation][google.longrunning.Operation] API allowing you // to keep track of the export. func (c *Client) ExportAssets(ctx context.Context, req *assetpb.ExportAssetsRequest, opts ...gax.CallOption) (*ExportAssetsOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ExportAssets[0:len(c.CallOptions.ExportAssets):len(c.CallOptions.ExportAssets)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ExportAssets(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &ExportAssetsOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // BatchGetAssetsHistory batch gets the update history of assets that overlap a time window. // For RESOURCE content, this API outputs history with asset in both // non-delete or deleted status. // For IAM_POLICY content, this API outputs history when the asset and its // attached IAM POLICY both exist. This can create gaps in the output history. func (c *Client) BatchGetAssetsHistory(ctx context.Context, req *assetpb.BatchGetAssetsHistoryRequest, opts ...gax.CallOption) (*assetpb.BatchGetAssetsHistoryResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.BatchGetAssetsHistory[0:len(c.CallOptions.BatchGetAssetsHistory):len(c.CallOptions.BatchGetAssetsHistory)], opts...) var resp *assetpb.BatchGetAssetsHistoryResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.BatchGetAssetsHistory(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateFeed creates a feed in a parent project/folder/organization to listen to its // asset updates. func (c *Client) CreateFeed(ctx context.Context, req *assetpb.CreateFeedRequest, opts ...gax.CallOption) (*assetpb.Feed, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateFeed[0:len(c.CallOptions.CreateFeed):len(c.CallOptions.CreateFeed)], opts...) var resp *assetpb.Feed err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CreateFeed(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetFeed gets details about an asset feed. func (c *Client) GetFeed(ctx context.Context, req *assetpb.GetFeedRequest, opts ...gax.CallOption) (*assetpb.Feed, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetFeed[0:len(c.CallOptions.GetFeed):len(c.CallOptions.GetFeed)], opts...) var resp *assetpb.Feed err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetFeed(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListFeeds lists all asset feeds in a parent project/folder/organization. func (c *Client) ListFeeds(ctx context.Context, req *assetpb.ListFeedsRequest, opts ...gax.CallOption) (*assetpb.ListFeedsResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListFeeds[0:len(c.CallOptions.ListFeeds):len(c.CallOptions.ListFeeds)], opts...) var resp *assetpb.ListFeedsResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListFeeds(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateFeed updates an asset feed configuration. func (c *Client) UpdateFeed(ctx context.Context, req *assetpb.UpdateFeedRequest, opts ...gax.CallOption) (*assetpb.Feed, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "feed.name", url.QueryEscape(req.GetFeed().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateFeed[0:len(c.CallOptions.UpdateFeed):len(c.CallOptions.UpdateFeed)], opts...) var resp *assetpb.Feed err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.UpdateFeed(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteFeed deletes an asset feed. func (c *Client) DeleteFeed(ctx context.Context, req *assetpb.DeleteFeedRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteFeed[0:len(c.CallOptions.DeleteFeed):len(c.CallOptions.DeleteFeed)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.client.DeleteFeed(ctx, req, settings.GRPC...) return err }, opts...) return err } // ExportAssetsOperation manages a long-running operation from ExportAssets. type ExportAssetsOperation struct { lro *longrunning.Operation } // ExportAssetsOperation returns a new ExportAssetsOperation from a given name. // The name must be that of a previously created ExportAssetsOperation, possibly from a different process. func (c *Client) ExportAssetsOperation(name string) *ExportAssetsOperation { return &ExportAssetsOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *ExportAssetsOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*assetpb.ExportAssetsResponse, error) { var resp assetpb.ExportAssetsResponse if err := op.lro.WaitWithInterval(ctx, &resp, 5000*time.Millisecond, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *ExportAssetsOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*assetpb.ExportAssetsResponse, error) { var resp assetpb.ExportAssetsResponse if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *ExportAssetsOperation) Metadata() (*assetpb.ExportAssetsRequest, error) { var meta assetpb.ExportAssetsRequest if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *ExportAssetsOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *ExportAssetsOperation) Name() string { return op.lro.Name() } google-cloud-go-0.49.0/asset/apiv1p2beta1/asset_client_example_test.go000066400000000000000000000064461356504100700256760ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package asset_test import ( "context" asset "cloud.google.com/go/asset/apiv1p2beta1" assetpb "google.golang.org/genproto/googleapis/cloud/asset/v1p2beta1" ) func ExampleNewClient() { ctx := context.Background() c, err := asset.NewClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleClient_ExportAssets() { ctx := context.Background() c, err := asset.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &assetpb.ExportAssetsRequest{ // TODO: Fill request struct fields. } op, err := c.ExportAssets(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_BatchGetAssetsHistory() { ctx := context.Background() c, err := asset.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &assetpb.BatchGetAssetsHistoryRequest{ // TODO: Fill request struct fields. } resp, err := c.BatchGetAssetsHistory(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_CreateFeed() { ctx := context.Background() c, err := asset.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &assetpb.CreateFeedRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateFeed(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_GetFeed() { ctx := context.Background() c, err := asset.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &assetpb.GetFeedRequest{ // TODO: Fill request struct fields. } resp, err := c.GetFeed(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ListFeeds() { ctx := context.Background() c, err := asset.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &assetpb.ListFeedsRequest{ // TODO: Fill request struct fields. } resp, err := c.ListFeeds(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_UpdateFeed() { ctx := context.Background() c, err := asset.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &assetpb.UpdateFeedRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateFeed(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_DeleteFeed() { ctx := context.Background() c, err := asset.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &assetpb.DeleteFeedRequest{ // TODO: Fill request struct fields. } err = c.DeleteFeed(ctx, req) if err != nil { // TODO: Handle error. } } google-cloud-go-0.49.0/asset/apiv1p2beta1/doc.go000066400000000000000000000053431356504100700212070ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package asset is an auto-generated package for the // Cloud Asset API. // // NOTE: This package is in beta. It is not stable, and may be subject to changes. // // The cloud asset API manages the history and inventory of cloud resources. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package asset // import "cloud.google.com/go/asset/apiv1p2beta1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191115" google-cloud-go-0.49.0/asset/apiv1p2beta1/mock_test.go000066400000000000000000000407431356504100700224350ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package asset import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" "google.golang.org/api/option" assetpb "google.golang.org/genproto/googleapis/cloud/asset/v1p2beta1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" field_maskpb "google.golang.org/genproto/protobuf/field_mask" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockAssetServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. assetpb.AssetServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockAssetServer) ExportAssets(ctx context.Context, req *assetpb.ExportAssetsRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockAssetServer) BatchGetAssetsHistory(ctx context.Context, req *assetpb.BatchGetAssetsHistoryRequest) (*assetpb.BatchGetAssetsHistoryResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*assetpb.BatchGetAssetsHistoryResponse), nil } func (s *mockAssetServer) CreateFeed(ctx context.Context, req *assetpb.CreateFeedRequest) (*assetpb.Feed, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*assetpb.Feed), nil } func (s *mockAssetServer) GetFeed(ctx context.Context, req *assetpb.GetFeedRequest) (*assetpb.Feed, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*assetpb.Feed), nil } func (s *mockAssetServer) ListFeeds(ctx context.Context, req *assetpb.ListFeedsRequest) (*assetpb.ListFeedsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*assetpb.ListFeedsResponse), nil } func (s *mockAssetServer) UpdateFeed(ctx context.Context, req *assetpb.UpdateFeedRequest) (*assetpb.Feed, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*assetpb.Feed), nil } func (s *mockAssetServer) DeleteFeed(ctx context.Context, req *assetpb.DeleteFeedRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockAsset mockAssetServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() assetpb.RegisterAssetServiceServer(serv, &mockAsset) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestAssetServiceExportAssets(t *testing.T) { var expectedResponse *assetpb.ExportAssetsResponse = &assetpb.ExportAssetsResponse{} mockAsset.err = nil mockAsset.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockAsset.resps = append(mockAsset.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var parent string = "parent-995424086" var outputConfig *assetpb.OutputConfig = &assetpb.OutputConfig{} var request = &assetpb.ExportAssetsRequest{ Parent: parent, OutputConfig: outputConfig, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.ExportAssets(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockAsset.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAssetServiceExportAssetsError(t *testing.T) { errCode := codes.PermissionDenied mockAsset.err = nil mockAsset.resps = append(mockAsset.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var parent string = "parent-995424086" var outputConfig *assetpb.OutputConfig = &assetpb.OutputConfig{} var request = &assetpb.ExportAssetsRequest{ Parent: parent, OutputConfig: outputConfig, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.ExportAssets(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAssetServiceBatchGetAssetsHistory(t *testing.T) { var expectedResponse *assetpb.BatchGetAssetsHistoryResponse = &assetpb.BatchGetAssetsHistoryResponse{} mockAsset.err = nil mockAsset.reqs = nil mockAsset.resps = append(mockAsset.resps[:0], expectedResponse) var parent string = "parent-995424086" var assetNames []string = nil var contentType assetpb.ContentType = assetpb.ContentType_CONTENT_TYPE_UNSPECIFIED var request = &assetpb.BatchGetAssetsHistoryRequest{ Parent: parent, AssetNames: assetNames, ContentType: contentType, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.BatchGetAssetsHistory(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockAsset.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAssetServiceBatchGetAssetsHistoryError(t *testing.T) { errCode := codes.PermissionDenied mockAsset.err = gstatus.Error(errCode, "test error") var parent string = "parent-995424086" var assetNames []string = nil var contentType assetpb.ContentType = assetpb.ContentType_CONTENT_TYPE_UNSPECIFIED var request = &assetpb.BatchGetAssetsHistoryRequest{ Parent: parent, AssetNames: assetNames, ContentType: contentType, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.BatchGetAssetsHistory(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAssetServiceCreateFeed(t *testing.T) { var name string = "name3373707" var expectedResponse = &assetpb.Feed{ Name: name, } mockAsset.err = nil mockAsset.reqs = nil mockAsset.resps = append(mockAsset.resps[:0], expectedResponse) var parent string = "parent-995424086" var feedId string = "feedId-976011428" var feed *assetpb.Feed = &assetpb.Feed{} var request = &assetpb.CreateFeedRequest{ Parent: parent, FeedId: feedId, Feed: feed, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateFeed(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockAsset.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAssetServiceCreateFeedError(t *testing.T) { errCode := codes.PermissionDenied mockAsset.err = gstatus.Error(errCode, "test error") var parent string = "parent-995424086" var feedId string = "feedId-976011428" var feed *assetpb.Feed = &assetpb.Feed{} var request = &assetpb.CreateFeedRequest{ Parent: parent, FeedId: feedId, Feed: feed, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateFeed(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAssetServiceGetFeed(t *testing.T) { var name2 string = "name2-1052831874" var expectedResponse = &assetpb.Feed{ Name: name2, } mockAsset.err = nil mockAsset.reqs = nil mockAsset.resps = append(mockAsset.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/feeds/%s", "[PROJECT]", "[FEED]") var request = &assetpb.GetFeedRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetFeed(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockAsset.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAssetServiceGetFeedError(t *testing.T) { errCode := codes.PermissionDenied mockAsset.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/feeds/%s", "[PROJECT]", "[FEED]") var request = &assetpb.GetFeedRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetFeed(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAssetServiceListFeeds(t *testing.T) { var expectedResponse *assetpb.ListFeedsResponse = &assetpb.ListFeedsResponse{} mockAsset.err = nil mockAsset.reqs = nil mockAsset.resps = append(mockAsset.resps[:0], expectedResponse) var parent string = "parent-995424086" var request = &assetpb.ListFeedsRequest{ Parent: parent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListFeeds(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockAsset.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAssetServiceListFeedsError(t *testing.T) { errCode := codes.PermissionDenied mockAsset.err = gstatus.Error(errCode, "test error") var parent string = "parent-995424086" var request = &assetpb.ListFeedsRequest{ Parent: parent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListFeeds(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAssetServiceUpdateFeed(t *testing.T) { var name string = "name3373707" var expectedResponse = &assetpb.Feed{ Name: name, } mockAsset.err = nil mockAsset.reqs = nil mockAsset.resps = append(mockAsset.resps[:0], expectedResponse) var feed *assetpb.Feed = &assetpb.Feed{} var updateMask *field_maskpb.FieldMask = &field_maskpb.FieldMask{} var request = &assetpb.UpdateFeedRequest{ Feed: feed, UpdateMask: updateMask, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateFeed(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockAsset.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAssetServiceUpdateFeedError(t *testing.T) { errCode := codes.PermissionDenied mockAsset.err = gstatus.Error(errCode, "test error") var feed *assetpb.Feed = &assetpb.Feed{} var updateMask *field_maskpb.FieldMask = &field_maskpb.FieldMask{} var request = &assetpb.UpdateFeedRequest{ Feed: feed, UpdateMask: updateMask, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateFeed(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAssetServiceDeleteFeed(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockAsset.err = nil mockAsset.reqs = nil mockAsset.resps = append(mockAsset.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/feeds/%s", "[PROJECT]", "[FEED]") var request = &assetpb.DeleteFeedRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteFeed(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockAsset.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestAssetServiceDeleteFeedError(t *testing.T) { errCode := codes.PermissionDenied mockAsset.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/feeds/%s", "[PROJECT]", "[FEED]") var request = &assetpb.DeleteFeedRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteFeed(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } google-cloud-go-0.49.0/asset/v1beta1/000077500000000000000000000000001356504100700171525ustar00rootroot00000000000000google-cloud-go-0.49.0/asset/v1beta1/.repo-metadata.json000066400000000000000000000006501356504100700226470ustar00rootroot00000000000000{ "name": "asset", "name_pretty": "Cloud Asset Inventory API", "product_documentation": "https://cloud.google.com/resource-manager", "client_documentation": "https://godoc.org/cloud.google.com/go/asset/v1beta1", "release_level": "alpha", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "cloudasset.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/asset/v1beta1/asset_client.go000066400000000000000000000220221356504100700221540ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // AUTO-GENERATED CODE. DO NOT EDIT. package asset import ( "context" "time" "cloud.google.com/go/longrunning" lroauto "cloud.google.com/go/longrunning/autogen" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" "google.golang.org/api/transport" assetpb "google.golang.org/genproto/googleapis/cloud/asset/v1beta1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // CallOptions contains the retry settings for each method of Client. type CallOptions struct { ExportAssets []gax.CallOption BatchGetAssetsHistory []gax.CallOption } func defaultClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("cloudasset.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), } } func defaultCallOptions() *CallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &CallOptions{ ExportAssets: retry[[2]string{"default", "non_idempotent"}], BatchGetAssetsHistory: retry[[2]string{"default", "idempotent"}], } } // Client is a client for interacting with Cloud Asset API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. client assetpb.AssetServiceClient // LROClient is used internally to handle longrunning operations. // It is exposed so that its CallOptions can be modified if required. // Users should not Close this client. LROClient *lroauto.OperationsClient // The call options for this service. CallOptions *CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewClient creates a new asset service client. // // Asset service definition. func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultClientOptions(), opts...)...) if err != nil { return nil, err } c := &Client{ conn: conn, CallOptions: defaultCallOptions(), client: assetpb.NewAssetServiceClient(conn), } c.setGoogleClientInfo() c.LROClient, err = lroauto.NewOperationsClient(ctx, option.WithGRPCConn(conn)) if err != nil { // This error "should not happen", since we are just reusing old connection // and never actually need to dial. // If this does happen, we could leak conn. However, we cannot close conn: // If the user invoked the function with option.WithGRPCConn, // we would close a connection that's still in use. // TODO(pongad): investigate error conditions. return nil, err } return c, nil } // Connection returns the client's connection to the API service. func (c *Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *Client) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *Client) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // ExportAssets exports assets with time and resource types to a given Cloud Storage // location. The output format is newline-delimited JSON. // This API implements the [google.longrunning.Operation][google.longrunning.Operation] API allowing you // to keep track of the export. func (c *Client) ExportAssets(ctx context.Context, req *assetpb.ExportAssetsRequest, opts ...gax.CallOption) (*ExportAssetsOperation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.ExportAssets[0:len(c.CallOptions.ExportAssets):len(c.CallOptions.ExportAssets)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ExportAssets(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &ExportAssetsOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // BatchGetAssetsHistory batch gets the update history of assets that overlap a time window. // For RESOURCE content, this API outputs history with asset in both // non-delete or deleted status. // For IAM_POLICY content, this API outputs history when the asset and its // attached IAM POLICY both exist. This can create gaps in the output history. func (c *Client) BatchGetAssetsHistory(ctx context.Context, req *assetpb.BatchGetAssetsHistoryRequest, opts ...gax.CallOption) (*assetpb.BatchGetAssetsHistoryResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.BatchGetAssetsHistory[0:len(c.CallOptions.BatchGetAssetsHistory):len(c.CallOptions.BatchGetAssetsHistory)], opts...) var resp *assetpb.BatchGetAssetsHistoryResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.BatchGetAssetsHistory(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ExportAssetsOperation manages a long-running operation from ExportAssets. type ExportAssetsOperation struct { lro *longrunning.Operation } // ExportAssetsOperation returns a new ExportAssetsOperation from a given name. // The name must be that of a previously created ExportAssetsOperation, possibly from a different process. func (c *Client) ExportAssetsOperation(name string) *ExportAssetsOperation { return &ExportAssetsOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *ExportAssetsOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*assetpb.ExportAssetsResponse, error) { var resp assetpb.ExportAssetsResponse if err := op.lro.WaitWithInterval(ctx, &resp, 5000*time.Millisecond, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *ExportAssetsOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*assetpb.ExportAssetsResponse, error) { var resp assetpb.ExportAssetsResponse if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *ExportAssetsOperation) Metadata() (*assetpb.ExportAssetsRequest, error) { var meta assetpb.ExportAssetsRequest if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *ExportAssetsOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *ExportAssetsOperation) Name() string { return op.lro.Name() } google-cloud-go-0.49.0/asset/v1beta1/asset_client_example_test.go000066400000000000000000000032741356504100700247360ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // AUTO-GENERATED CODE. DO NOT EDIT. package asset_test import ( "context" asset "cloud.google.com/go/asset/v1beta1" assetpb "google.golang.org/genproto/googleapis/cloud/asset/v1beta1" ) func ExampleNewClient() { ctx := context.Background() c, err := asset.NewClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleClient_ExportAssets() { ctx := context.Background() c, err := asset.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &assetpb.ExportAssetsRequest{ // TODO: Fill request struct fields. } op, err := c.ExportAssets(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_BatchGetAssetsHistory() { ctx := context.Background() c, err := asset.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &assetpb.BatchGetAssetsHistoryRequest{ // TODO: Fill request struct fields. } resp, err := c.BatchGetAssetsHistory(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/asset/v1beta1/doc.go000066400000000000000000000044471356504100700202570ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // AUTO-GENERATED CODE. DO NOT EDIT. // Package asset is an auto-generated package for the // Cloud Asset API. // // NOTE: This package is in alpha. It is not stable, and is likely to change. // // The cloud asset API manages the history and inventory of cloud resources. package asset // import "cloud.google.com/go/asset/v1beta1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20190910" google-cloud-go-0.49.0/asset/v1beta1/mock_test.go000066400000000000000000000163051356504100700214760ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // AUTO-GENERATED CODE. DO NOT EDIT. package asset import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" "google.golang.org/api/option" assetpb "google.golang.org/genproto/googleapis/cloud/asset/v1beta1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockAssetServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. assetpb.AssetServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockAssetServer) ExportAssets(ctx context.Context, req *assetpb.ExportAssetsRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockAssetServer) BatchGetAssetsHistory(ctx context.Context, req *assetpb.BatchGetAssetsHistoryRequest) (*assetpb.BatchGetAssetsHistoryResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*assetpb.BatchGetAssetsHistoryResponse), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockAsset mockAssetServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() assetpb.RegisterAssetServiceServer(serv, &mockAsset) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestAssetServiceExportAssets(t *testing.T) { var expectedResponse *assetpb.ExportAssetsResponse = &assetpb.ExportAssetsResponse{} mockAsset.err = nil mockAsset.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockAsset.resps = append(mockAsset.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var outputConfig *assetpb.OutputConfig = &assetpb.OutputConfig{} var request = &assetpb.ExportAssetsRequest{ Parent: formattedParent, OutputConfig: outputConfig, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.ExportAssets(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockAsset.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAssetServiceExportAssetsError(t *testing.T) { errCode := codes.PermissionDenied mockAsset.err = nil mockAsset.resps = append(mockAsset.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var outputConfig *assetpb.OutputConfig = &assetpb.OutputConfig{} var request = &assetpb.ExportAssetsRequest{ Parent: formattedParent, OutputConfig: outputConfig, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.ExportAssets(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAssetServiceBatchGetAssetsHistory(t *testing.T) { var expectedResponse *assetpb.BatchGetAssetsHistoryResponse = &assetpb.BatchGetAssetsHistoryResponse{} mockAsset.err = nil mockAsset.reqs = nil mockAsset.resps = append(mockAsset.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var contentType assetpb.ContentType = assetpb.ContentType_CONTENT_TYPE_UNSPECIFIED var readTimeWindow *assetpb.TimeWindow = &assetpb.TimeWindow{} var request = &assetpb.BatchGetAssetsHistoryRequest{ Parent: formattedParent, ContentType: contentType, ReadTimeWindow: readTimeWindow, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.BatchGetAssetsHistory(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockAsset.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAssetServiceBatchGetAssetsHistoryError(t *testing.T) { errCode := codes.PermissionDenied mockAsset.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var contentType assetpb.ContentType = assetpb.ContentType_CONTENT_TYPE_UNSPECIFIED var readTimeWindow *assetpb.TimeWindow = &assetpb.TimeWindow{} var request = &assetpb.BatchGetAssetsHistoryRequest{ Parent: formattedParent, ContentType: contentType, ReadTimeWindow: readTimeWindow, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.BatchGetAssetsHistory(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/automl/000077500000000000000000000000001356504100700160715ustar00rootroot00000000000000google-cloud-go-0.49.0/automl/apiv1/000077500000000000000000000000001356504100700171115ustar00rootroot00000000000000google-cloud-go-0.49.0/automl/apiv1/auto_ml_client.go000066400000000000000000001445721356504100700224530ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package automl import ( "context" "fmt" "math" "net/url" "time" "cloud.google.com/go/longrunning" lroauto "cloud.google.com/go/longrunning/autogen" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" automlpb "google.golang.org/genproto/googleapis/cloud/automl/v1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // CallOptions contains the retry settings for each method of Client. type CallOptions struct { CreateDataset []gax.CallOption UpdateDataset []gax.CallOption GetDataset []gax.CallOption ListDatasets []gax.CallOption DeleteDataset []gax.CallOption ImportData []gax.CallOption ExportData []gax.CallOption GetAnnotationSpec []gax.CallOption CreateModel []gax.CallOption GetModel []gax.CallOption UpdateModel []gax.CallOption ListModels []gax.CallOption DeleteModel []gax.CallOption DeployModel []gax.CallOption UndeployModel []gax.CallOption ExportModel []gax.CallOption GetModelEvaluation []gax.CallOption ListModelEvaluations []gax.CallOption } func defaultClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("automl.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultCallOptions() *CallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &CallOptions{ CreateDataset: retry[[2]string{"default", "non_idempotent"}], UpdateDataset: retry[[2]string{"default", "non_idempotent"}], GetDataset: retry[[2]string{"default", "idempotent"}], ListDatasets: retry[[2]string{"default", "idempotent"}], DeleteDataset: retry[[2]string{"default", "idempotent"}], ImportData: retry[[2]string{"default", "non_idempotent"}], ExportData: retry[[2]string{"default", "non_idempotent"}], GetAnnotationSpec: retry[[2]string{"default", "idempotent"}], CreateModel: retry[[2]string{"default", "non_idempotent"}], GetModel: retry[[2]string{"default", "idempotent"}], UpdateModel: retry[[2]string{"default", "non_idempotent"}], ListModels: retry[[2]string{"default", "idempotent"}], DeleteModel: retry[[2]string{"default", "idempotent"}], DeployModel: retry[[2]string{"default", "non_idempotent"}], UndeployModel: retry[[2]string{"default", "non_idempotent"}], ExportModel: retry[[2]string{"default", "non_idempotent"}], GetModelEvaluation: retry[[2]string{"default", "idempotent"}], ListModelEvaluations: retry[[2]string{"default", "idempotent"}], } } // Client is a client for interacting with Cloud AutoML API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. client automlpb.AutoMlClient // LROClient is used internally to handle longrunning operations. // It is exposed so that its CallOptions can be modified if required. // Users should not Close this client. LROClient *lroauto.OperationsClient // The call options for this service. CallOptions *CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewClient creates a new auto ml client. // // AutoML Server API. // // The resource names are assigned by the server. // The server never reuses names that it has created after the resources with // those names are deleted. // // An ID of a resource is the last element of the item's resource name. For // projects/{project_id}/locations/{location_id}/datasets/{dataset_id}, then // the id for the item is {dataset_id}. // // Currently the only supported location_id is "us-central1". // // On any input that is documented to expect a string parameter in // snake_case or kebab-case, either of those cases is accepted. func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultClientOptions(), opts...)...) if err != nil { return nil, err } c := &Client{ conn: conn, CallOptions: defaultCallOptions(), client: automlpb.NewAutoMlClient(conn), } c.setGoogleClientInfo() c.LROClient, err = lroauto.NewOperationsClient(ctx, option.WithGRPCConn(conn)) if err != nil { // This error "should not happen", since we are just reusing old connection // and never actually need to dial. // If this does happen, we could leak conn. However, we cannot close conn: // If the user invoked the function with option.WithGRPCConn, // we would close a connection that's still in use. // TODO(pongad): investigate error conditions. return nil, err } return c, nil } // Connection returns the client's connection to the API service. func (c *Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *Client) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *Client) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // CreateDataset creates a dataset. func (c *Client) CreateDataset(ctx context.Context, req *automlpb.CreateDatasetRequest, opts ...gax.CallOption) (*CreateDatasetOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateDataset[0:len(c.CallOptions.CreateDataset):len(c.CallOptions.CreateDataset)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CreateDataset(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &CreateDatasetOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // UpdateDataset updates a dataset. func (c *Client) UpdateDataset(ctx context.Context, req *automlpb.UpdateDatasetRequest, opts ...gax.CallOption) (*automlpb.Dataset, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "dataset.name", url.QueryEscape(req.GetDataset().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateDataset[0:len(c.CallOptions.UpdateDataset):len(c.CallOptions.UpdateDataset)], opts...) var resp *automlpb.Dataset err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.UpdateDataset(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetDataset gets a dataset. func (c *Client) GetDataset(ctx context.Context, req *automlpb.GetDatasetRequest, opts ...gax.CallOption) (*automlpb.Dataset, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetDataset[0:len(c.CallOptions.GetDataset):len(c.CallOptions.GetDataset)], opts...) var resp *automlpb.Dataset err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetDataset(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListDatasets lists datasets in a project. func (c *Client) ListDatasets(ctx context.Context, req *automlpb.ListDatasetsRequest, opts ...gax.CallOption) *DatasetIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListDatasets[0:len(c.CallOptions.ListDatasets):len(c.CallOptions.ListDatasets)], opts...) it := &DatasetIterator{} req = proto.Clone(req).(*automlpb.ListDatasetsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*automlpb.Dataset, string, error) { var resp *automlpb.ListDatasetsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListDatasets(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Datasets, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // DeleteDataset deletes a dataset and all of its contents. // Returns empty response in the // [response][google.longrunning.Operation.response] field when it completes, // and delete_details in the // [metadata][google.longrunning.Operation.metadata] field. func (c *Client) DeleteDataset(ctx context.Context, req *automlpb.DeleteDatasetRequest, opts ...gax.CallOption) (*DeleteDatasetOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteDataset[0:len(c.CallOptions.DeleteDataset):len(c.CallOptions.DeleteDataset)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.DeleteDataset(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &DeleteDatasetOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // ImportData imports data into a dataset. func (c *Client) ImportData(ctx context.Context, req *automlpb.ImportDataRequest, opts ...gax.CallOption) (*ImportDataOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ImportData[0:len(c.CallOptions.ImportData):len(c.CallOptions.ImportData)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ImportData(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &ImportDataOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // ExportData exports dataset's data to the provided output location. // Returns an empty response in the // [response][google.longrunning.Operation.response] field when it completes. func (c *Client) ExportData(ctx context.Context, req *automlpb.ExportDataRequest, opts ...gax.CallOption) (*ExportDataOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ExportData[0:len(c.CallOptions.ExportData):len(c.CallOptions.ExportData)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ExportData(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &ExportDataOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // GetAnnotationSpec gets an annotation spec. func (c *Client) GetAnnotationSpec(ctx context.Context, req *automlpb.GetAnnotationSpecRequest, opts ...gax.CallOption) (*automlpb.AnnotationSpec, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetAnnotationSpec[0:len(c.CallOptions.GetAnnotationSpec):len(c.CallOptions.GetAnnotationSpec)], opts...) var resp *automlpb.AnnotationSpec err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetAnnotationSpec(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateModel creates a model. // Returns a Model in the [response][google.longrunning.Operation.response] // field when it completes. // When you create a model, several model evaluations are created for it: // a global evaluation, and one evaluation for each annotation spec. func (c *Client) CreateModel(ctx context.Context, req *automlpb.CreateModelRequest, opts ...gax.CallOption) (*CreateModelOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateModel[0:len(c.CallOptions.CreateModel):len(c.CallOptions.CreateModel)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CreateModel(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &CreateModelOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // GetModel gets a model. func (c *Client) GetModel(ctx context.Context, req *automlpb.GetModelRequest, opts ...gax.CallOption) (*automlpb.Model, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetModel[0:len(c.CallOptions.GetModel):len(c.CallOptions.GetModel)], opts...) var resp *automlpb.Model err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetModel(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateModel updates a model. func (c *Client) UpdateModel(ctx context.Context, req *automlpb.UpdateModelRequest, opts ...gax.CallOption) (*automlpb.Model, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "model.name", url.QueryEscape(req.GetModel().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateModel[0:len(c.CallOptions.UpdateModel):len(c.CallOptions.UpdateModel)], opts...) var resp *automlpb.Model err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.UpdateModel(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListModels lists models. func (c *Client) ListModels(ctx context.Context, req *automlpb.ListModelsRequest, opts ...gax.CallOption) *ModelIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListModels[0:len(c.CallOptions.ListModels):len(c.CallOptions.ListModels)], opts...) it := &ModelIterator{} req = proto.Clone(req).(*automlpb.ListModelsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*automlpb.Model, string, error) { var resp *automlpb.ListModelsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListModels(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Model, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // DeleteModel deletes a model. // Returns google.protobuf.Empty in the // [response][google.longrunning.Operation.response] field when it completes, // and delete_details in the // [metadata][google.longrunning.Operation.metadata] field. func (c *Client) DeleteModel(ctx context.Context, req *automlpb.DeleteModelRequest, opts ...gax.CallOption) (*DeleteModelOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteModel[0:len(c.CallOptions.DeleteModel):len(c.CallOptions.DeleteModel)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.DeleteModel(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &DeleteModelOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // DeployModel deploys a model. If a model is already deployed, deploying it with the // same parameters has no effect. Deploying with different parametrs // (as e.g. changing // // [node_number][google.cloud.automl.v1.ImageObjectDetectionModelDeploymentMetadata.node_number]) // will reset the deployment state without pausing the model's availability. // // Only applicable for Text Classification, Image Object Detection; all other // domains manage deployment automatically. // // Returns an empty response in the // [response][google.longrunning.Operation.response] field when it completes. func (c *Client) DeployModel(ctx context.Context, req *automlpb.DeployModelRequest, opts ...gax.CallOption) (*DeployModelOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeployModel[0:len(c.CallOptions.DeployModel):len(c.CallOptions.DeployModel)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.DeployModel(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &DeployModelOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // UndeployModel undeploys a model. If the model is not deployed this method has no effect. // // Only applicable for Text Classification, Image Object Detection; // all other domains manage deployment automatically. // // Returns an empty response in the // [response][google.longrunning.Operation.response] field when it completes. func (c *Client) UndeployModel(ctx context.Context, req *automlpb.UndeployModelRequest, opts ...gax.CallOption) (*UndeployModelOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UndeployModel[0:len(c.CallOptions.UndeployModel):len(c.CallOptions.UndeployModel)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.UndeployModel(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &UndeployModelOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // ExportModel exports a trained, "export-able", model to a user specified Google Cloud // Storage location. A model is considered export-able if and only if it has // an export format defined for it in // [ModelExportOutputConfig][google.cloud.automl.v1.ModelExportOutputConfig]. // // Returns an empty response in the // [response][google.longrunning.Operation.response] field when it completes. func (c *Client) ExportModel(ctx context.Context, req *automlpb.ExportModelRequest, opts ...gax.CallOption) (*ExportModelOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ExportModel[0:len(c.CallOptions.ExportModel):len(c.CallOptions.ExportModel)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ExportModel(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &ExportModelOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // GetModelEvaluation gets a model evaluation. func (c *Client) GetModelEvaluation(ctx context.Context, req *automlpb.GetModelEvaluationRequest, opts ...gax.CallOption) (*automlpb.ModelEvaluation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetModelEvaluation[0:len(c.CallOptions.GetModelEvaluation):len(c.CallOptions.GetModelEvaluation)], opts...) var resp *automlpb.ModelEvaluation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetModelEvaluation(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListModelEvaluations lists model evaluations. func (c *Client) ListModelEvaluations(ctx context.Context, req *automlpb.ListModelEvaluationsRequest, opts ...gax.CallOption) *ModelEvaluationIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListModelEvaluations[0:len(c.CallOptions.ListModelEvaluations):len(c.CallOptions.ListModelEvaluations)], opts...) it := &ModelEvaluationIterator{} req = proto.Clone(req).(*automlpb.ListModelEvaluationsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*automlpb.ModelEvaluation, string, error) { var resp *automlpb.ListModelEvaluationsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListModelEvaluations(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.ModelEvaluation, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // DatasetIterator manages a stream of *automlpb.Dataset. type DatasetIterator struct { items []*automlpb.Dataset pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*automlpb.Dataset, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *DatasetIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *DatasetIterator) Next() (*automlpb.Dataset, error) { var item *automlpb.Dataset if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *DatasetIterator) bufLen() int { return len(it.items) } func (it *DatasetIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // ModelEvaluationIterator manages a stream of *automlpb.ModelEvaluation. type ModelEvaluationIterator struct { items []*automlpb.ModelEvaluation pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*automlpb.ModelEvaluation, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *ModelEvaluationIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *ModelEvaluationIterator) Next() (*automlpb.ModelEvaluation, error) { var item *automlpb.ModelEvaluation if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *ModelEvaluationIterator) bufLen() int { return len(it.items) } func (it *ModelEvaluationIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // ModelIterator manages a stream of *automlpb.Model. type ModelIterator struct { items []*automlpb.Model pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*automlpb.Model, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *ModelIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *ModelIterator) Next() (*automlpb.Model, error) { var item *automlpb.Model if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *ModelIterator) bufLen() int { return len(it.items) } func (it *ModelIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // CreateDatasetOperation manages a long-running operation from CreateDataset. type CreateDatasetOperation struct { lro *longrunning.Operation } // CreateDatasetOperation returns a new CreateDatasetOperation from a given name. // The name must be that of a previously created CreateDatasetOperation, possibly from a different process. func (c *Client) CreateDatasetOperation(name string) *CreateDatasetOperation { return &CreateDatasetOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *CreateDatasetOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*automlpb.Dataset, error) { var resp automlpb.Dataset if err := op.lro.WaitWithInterval(ctx, &resp, 5000*time.Millisecond, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *CreateDatasetOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*automlpb.Dataset, error) { var resp automlpb.Dataset if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *CreateDatasetOperation) Metadata() (*automlpb.OperationMetadata, error) { var meta automlpb.OperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *CreateDatasetOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *CreateDatasetOperation) Name() string { return op.lro.Name() } // CreateModelOperation manages a long-running operation from CreateModel. type CreateModelOperation struct { lro *longrunning.Operation } // CreateModelOperation returns a new CreateModelOperation from a given name. // The name must be that of a previously created CreateModelOperation, possibly from a different process. func (c *Client) CreateModelOperation(name string) *CreateModelOperation { return &CreateModelOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *CreateModelOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*automlpb.Model, error) { var resp automlpb.Model if err := op.lro.WaitWithInterval(ctx, &resp, 5000*time.Millisecond, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *CreateModelOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*automlpb.Model, error) { var resp automlpb.Model if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *CreateModelOperation) Metadata() (*automlpb.OperationMetadata, error) { var meta automlpb.OperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *CreateModelOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *CreateModelOperation) Name() string { return op.lro.Name() } // DeleteDatasetOperation manages a long-running operation from DeleteDataset. type DeleteDatasetOperation struct { lro *longrunning.Operation } // DeleteDatasetOperation returns a new DeleteDatasetOperation from a given name. // The name must be that of a previously created DeleteDatasetOperation, possibly from a different process. func (c *Client) DeleteDatasetOperation(name string) *DeleteDatasetOperation { return &DeleteDatasetOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning any error encountered. // // See documentation of Poll for error-handling information. func (op *DeleteDatasetOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { return op.lro.WaitWithInterval(ctx, nil, 5000*time.Millisecond, opts...) } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, op.Done will return true. func (op *DeleteDatasetOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Poll(ctx, nil, opts...) } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *DeleteDatasetOperation) Metadata() (*automlpb.OperationMetadata, error) { var meta automlpb.OperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *DeleteDatasetOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *DeleteDatasetOperation) Name() string { return op.lro.Name() } // DeleteModelOperation manages a long-running operation from DeleteModel. type DeleteModelOperation struct { lro *longrunning.Operation } // DeleteModelOperation returns a new DeleteModelOperation from a given name. // The name must be that of a previously created DeleteModelOperation, possibly from a different process. func (c *Client) DeleteModelOperation(name string) *DeleteModelOperation { return &DeleteModelOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning any error encountered. // // See documentation of Poll for error-handling information. func (op *DeleteModelOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { return op.lro.WaitWithInterval(ctx, nil, 5000*time.Millisecond, opts...) } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, op.Done will return true. func (op *DeleteModelOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Poll(ctx, nil, opts...) } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *DeleteModelOperation) Metadata() (*automlpb.OperationMetadata, error) { var meta automlpb.OperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *DeleteModelOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *DeleteModelOperation) Name() string { return op.lro.Name() } // DeployModelOperation manages a long-running operation from DeployModel. type DeployModelOperation struct { lro *longrunning.Operation } // DeployModelOperation returns a new DeployModelOperation from a given name. // The name must be that of a previously created DeployModelOperation, possibly from a different process. func (c *Client) DeployModelOperation(name string) *DeployModelOperation { return &DeployModelOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning any error encountered. // // See documentation of Poll for error-handling information. func (op *DeployModelOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { return op.lro.WaitWithInterval(ctx, nil, 5000*time.Millisecond, opts...) } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, op.Done will return true. func (op *DeployModelOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Poll(ctx, nil, opts...) } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *DeployModelOperation) Metadata() (*automlpb.OperationMetadata, error) { var meta automlpb.OperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *DeployModelOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *DeployModelOperation) Name() string { return op.lro.Name() } // ExportDataOperation manages a long-running operation from ExportData. type ExportDataOperation struct { lro *longrunning.Operation } // ExportDataOperation returns a new ExportDataOperation from a given name. // The name must be that of a previously created ExportDataOperation, possibly from a different process. func (c *Client) ExportDataOperation(name string) *ExportDataOperation { return &ExportDataOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning any error encountered. // // See documentation of Poll for error-handling information. func (op *ExportDataOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { return op.lro.WaitWithInterval(ctx, nil, 5000*time.Millisecond, opts...) } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, op.Done will return true. func (op *ExportDataOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Poll(ctx, nil, opts...) } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *ExportDataOperation) Metadata() (*automlpb.OperationMetadata, error) { var meta automlpb.OperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *ExportDataOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *ExportDataOperation) Name() string { return op.lro.Name() } // ExportModelOperation manages a long-running operation from ExportModel. type ExportModelOperation struct { lro *longrunning.Operation } // ExportModelOperation returns a new ExportModelOperation from a given name. // The name must be that of a previously created ExportModelOperation, possibly from a different process. func (c *Client) ExportModelOperation(name string) *ExportModelOperation { return &ExportModelOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning any error encountered. // // See documentation of Poll for error-handling information. func (op *ExportModelOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { return op.lro.WaitWithInterval(ctx, nil, 5000*time.Millisecond, opts...) } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, op.Done will return true. func (op *ExportModelOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Poll(ctx, nil, opts...) } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *ExportModelOperation) Metadata() (*automlpb.OperationMetadata, error) { var meta automlpb.OperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *ExportModelOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *ExportModelOperation) Name() string { return op.lro.Name() } // ImportDataOperation manages a long-running operation from ImportData. type ImportDataOperation struct { lro *longrunning.Operation } // ImportDataOperation returns a new ImportDataOperation from a given name. // The name must be that of a previously created ImportDataOperation, possibly from a different process. func (c *Client) ImportDataOperation(name string) *ImportDataOperation { return &ImportDataOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning any error encountered. // // See documentation of Poll for error-handling information. func (op *ImportDataOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { return op.lro.WaitWithInterval(ctx, nil, 5000*time.Millisecond, opts...) } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, op.Done will return true. func (op *ImportDataOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Poll(ctx, nil, opts...) } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *ImportDataOperation) Metadata() (*automlpb.OperationMetadata, error) { var meta automlpb.OperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *ImportDataOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *ImportDataOperation) Name() string { return op.lro.Name() } // UndeployModelOperation manages a long-running operation from UndeployModel. type UndeployModelOperation struct { lro *longrunning.Operation } // UndeployModelOperation returns a new UndeployModelOperation from a given name. // The name must be that of a previously created UndeployModelOperation, possibly from a different process. func (c *Client) UndeployModelOperation(name string) *UndeployModelOperation { return &UndeployModelOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning any error encountered. // // See documentation of Poll for error-handling information. func (op *UndeployModelOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { return op.lro.WaitWithInterval(ctx, nil, 5000*time.Millisecond, opts...) } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, op.Done will return true. func (op *UndeployModelOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Poll(ctx, nil, opts...) } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *UndeployModelOperation) Metadata() (*automlpb.OperationMetadata, error) { var meta automlpb.OperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *UndeployModelOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *UndeployModelOperation) Name() string { return op.lro.Name() } google-cloud-go-0.49.0/automl/apiv1/auto_ml_client_example_test.go000066400000000000000000000167061356504100700252220ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package automl_test import ( "context" automl "cloud.google.com/go/automl/apiv1" "google.golang.org/api/iterator" automlpb "google.golang.org/genproto/googleapis/cloud/automl/v1" ) func ExampleNewClient() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleClient_CreateDataset() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.CreateDatasetRequest{ // TODO: Fill request struct fields. } op, err := c.CreateDataset(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_UpdateDataset() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.UpdateDatasetRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateDataset(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_GetDataset() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.GetDatasetRequest{ // TODO: Fill request struct fields. } resp, err := c.GetDataset(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ListDatasets() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.ListDatasetsRequest{ // TODO: Fill request struct fields. } it := c.ListDatasets(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_DeleteDataset() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.DeleteDatasetRequest{ // TODO: Fill request struct fields. } op, err := c.DeleteDataset(ctx, req) if err != nil { // TODO: Handle error. } err = op.Wait(ctx) // TODO: Handle error. } func ExampleClient_ImportData() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.ImportDataRequest{ // TODO: Fill request struct fields. } op, err := c.ImportData(ctx, req) if err != nil { // TODO: Handle error. } err = op.Wait(ctx) // TODO: Handle error. } func ExampleClient_ExportData() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.ExportDataRequest{ // TODO: Fill request struct fields. } op, err := c.ExportData(ctx, req) if err != nil { // TODO: Handle error. } err = op.Wait(ctx) // TODO: Handle error. } func ExampleClient_GetAnnotationSpec() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.GetAnnotationSpecRequest{ // TODO: Fill request struct fields. } resp, err := c.GetAnnotationSpec(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_CreateModel() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.CreateModelRequest{ // TODO: Fill request struct fields. } op, err := c.CreateModel(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_GetModel() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.GetModelRequest{ // TODO: Fill request struct fields. } resp, err := c.GetModel(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_UpdateModel() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.UpdateModelRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateModel(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ListModels() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.ListModelsRequest{ // TODO: Fill request struct fields. } it := c.ListModels(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_DeleteModel() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.DeleteModelRequest{ // TODO: Fill request struct fields. } op, err := c.DeleteModel(ctx, req) if err != nil { // TODO: Handle error. } err = op.Wait(ctx) // TODO: Handle error. } func ExampleClient_DeployModel() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.DeployModelRequest{ // TODO: Fill request struct fields. } op, err := c.DeployModel(ctx, req) if err != nil { // TODO: Handle error. } err = op.Wait(ctx) // TODO: Handle error. } func ExampleClient_UndeployModel() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.UndeployModelRequest{ // TODO: Fill request struct fields. } op, err := c.UndeployModel(ctx, req) if err != nil { // TODO: Handle error. } err = op.Wait(ctx) // TODO: Handle error. } func ExampleClient_ExportModel() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.ExportModelRequest{ // TODO: Fill request struct fields. } op, err := c.ExportModel(ctx, req) if err != nil { // TODO: Handle error. } err = op.Wait(ctx) // TODO: Handle error. } func ExampleClient_GetModelEvaluation() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.GetModelEvaluationRequest{ // TODO: Fill request struct fields. } resp, err := c.GetModelEvaluation(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ListModelEvaluations() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.ListModelEvaluationsRequest{ // TODO: Fill request struct fields. } it := c.ListModelEvaluations(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } google-cloud-go-0.49.0/automl/apiv1/doc.go000066400000000000000000000052501356504100700202070ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package automl is an auto-generated package for the // Cloud AutoML API. // // Train high-quality custom machine learning models with minimum effort and // machine learning expertise. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package automl // import "cloud.google.com/go/automl/apiv1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191108" google-cloud-go-0.49.0/automl/apiv1/mock_test.go000066400000000000000000001477701356504100700214500ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package automl import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" "google.golang.org/api/option" automlpb "google.golang.org/genproto/googleapis/cloud/automl/v1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" field_maskpb "google.golang.org/genproto/protobuf/field_mask" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockAutoMlServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. automlpb.AutoMlServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockAutoMlServer) CreateDataset(ctx context.Context, req *automlpb.CreateDatasetRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockAutoMlServer) GetDataset(ctx context.Context, req *automlpb.GetDatasetRequest) (*automlpb.Dataset, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*automlpb.Dataset), nil } func (s *mockAutoMlServer) ListDatasets(ctx context.Context, req *automlpb.ListDatasetsRequest) (*automlpb.ListDatasetsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*automlpb.ListDatasetsResponse), nil } func (s *mockAutoMlServer) UpdateDataset(ctx context.Context, req *automlpb.UpdateDatasetRequest) (*automlpb.Dataset, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*automlpb.Dataset), nil } func (s *mockAutoMlServer) DeleteDataset(ctx context.Context, req *automlpb.DeleteDatasetRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockAutoMlServer) ImportData(ctx context.Context, req *automlpb.ImportDataRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockAutoMlServer) ExportData(ctx context.Context, req *automlpb.ExportDataRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockAutoMlServer) GetAnnotationSpec(ctx context.Context, req *automlpb.GetAnnotationSpecRequest) (*automlpb.AnnotationSpec, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*automlpb.AnnotationSpec), nil } func (s *mockAutoMlServer) CreateModel(ctx context.Context, req *automlpb.CreateModelRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockAutoMlServer) GetModel(ctx context.Context, req *automlpb.GetModelRequest) (*automlpb.Model, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*automlpb.Model), nil } func (s *mockAutoMlServer) ListModels(ctx context.Context, req *automlpb.ListModelsRequest) (*automlpb.ListModelsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*automlpb.ListModelsResponse), nil } func (s *mockAutoMlServer) DeleteModel(ctx context.Context, req *automlpb.DeleteModelRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockAutoMlServer) UpdateModel(ctx context.Context, req *automlpb.UpdateModelRequest) (*automlpb.Model, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*automlpb.Model), nil } func (s *mockAutoMlServer) DeployModel(ctx context.Context, req *automlpb.DeployModelRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockAutoMlServer) UndeployModel(ctx context.Context, req *automlpb.UndeployModelRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockAutoMlServer) ExportModel(ctx context.Context, req *automlpb.ExportModelRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockAutoMlServer) GetModelEvaluation(ctx context.Context, req *automlpb.GetModelEvaluationRequest) (*automlpb.ModelEvaluation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*automlpb.ModelEvaluation), nil } func (s *mockAutoMlServer) ListModelEvaluations(ctx context.Context, req *automlpb.ListModelEvaluationsRequest) (*automlpb.ListModelEvaluationsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*automlpb.ListModelEvaluationsResponse), nil } type mockPredictionServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. automlpb.PredictionServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockPredictionServer) Predict(ctx context.Context, req *automlpb.PredictRequest) (*automlpb.PredictResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*automlpb.PredictResponse), nil } func (s *mockPredictionServer) BatchPredict(ctx context.Context, req *automlpb.BatchPredictRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockAutoMl mockAutoMlServer mockPrediction mockPredictionServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() automlpb.RegisterAutoMlServer(serv, &mockAutoMl) automlpb.RegisterPredictionServiceServer(serv, &mockPrediction) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestAutoMlCreateDataset(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var description string = "description-1724546052" var exampleCount int32 = 1517063674 var etag string = "etag3123477" var expectedResponse = &automlpb.Dataset{ Name: name, DisplayName: displayName, Description: description, ExampleCount: exampleCount, Etag: etag, } mockAutoMl.err = nil mockAutoMl.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockAutoMl.resps = append(mockAutoMl.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var dataset *automlpb.Dataset = &automlpb.Dataset{} var request = &automlpb.CreateDatasetRequest{ Parent: formattedParent, Dataset: dataset, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.CreateDataset(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAutoMlCreateDatasetError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var dataset *automlpb.Dataset = &automlpb.Dataset{} var request = &automlpb.CreateDatasetRequest{ Parent: formattedParent, Dataset: dataset, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.CreateDataset(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAutoMlUpdateDataset(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var description string = "description-1724546052" var exampleCount int32 = 1517063674 var etag string = "etag3123477" var expectedResponse = &automlpb.Dataset{ Name: name, DisplayName: displayName, Description: description, ExampleCount: exampleCount, Etag: etag, } mockAutoMl.err = nil mockAutoMl.reqs = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], expectedResponse) var dataset *automlpb.Dataset = &automlpb.Dataset{} var updateMask *field_maskpb.FieldMask = &field_maskpb.FieldMask{} var request = &automlpb.UpdateDatasetRequest{ Dataset: dataset, UpdateMask: updateMask, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateDataset(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAutoMlUpdateDatasetError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = gstatus.Error(errCode, "test error") var dataset *automlpb.Dataset = &automlpb.Dataset{} var updateMask *field_maskpb.FieldMask = &field_maskpb.FieldMask{} var request = &automlpb.UpdateDatasetRequest{ Dataset: dataset, UpdateMask: updateMask, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateDataset(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAutoMlGetDataset(t *testing.T) { var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var description string = "description-1724546052" var exampleCount int32 = 1517063674 var etag string = "etag3123477" var expectedResponse = &automlpb.Dataset{ Name: name2, DisplayName: displayName, Description: description, ExampleCount: exampleCount, Etag: etag, } mockAutoMl.err = nil mockAutoMl.reqs = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/datasets/%s", "[PROJECT]", "[LOCATION]", "[DATASET]") var request = &automlpb.GetDatasetRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetDataset(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAutoMlGetDatasetError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/datasets/%s", "[PROJECT]", "[LOCATION]", "[DATASET]") var request = &automlpb.GetDatasetRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetDataset(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAutoMlListDatasets(t *testing.T) { var nextPageToken string = "" var datasetsElement *automlpb.Dataset = &automlpb.Dataset{} var datasets = []*automlpb.Dataset{datasetsElement} var expectedResponse = &automlpb.ListDatasetsResponse{ NextPageToken: nextPageToken, Datasets: datasets, } mockAutoMl.err = nil mockAutoMl.reqs = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &automlpb.ListDatasetsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListDatasets(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Datasets[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAutoMlListDatasetsError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &automlpb.ListDatasetsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListDatasets(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAutoMlDeleteDataset(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockAutoMl.err = nil mockAutoMl.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockAutoMl.resps = append(mockAutoMl.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/datasets/%s", "[PROJECT]", "[LOCATION]", "[DATASET]") var request = &automlpb.DeleteDatasetRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.DeleteDataset(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestAutoMlDeleteDatasetError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/datasets/%s", "[PROJECT]", "[LOCATION]", "[DATASET]") var request = &automlpb.DeleteDatasetRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.DeleteDataset(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestAutoMlImportData(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockAutoMl.err = nil mockAutoMl.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockAutoMl.resps = append(mockAutoMl.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/datasets/%s", "[PROJECT]", "[LOCATION]", "[DATASET]") var inputConfig *automlpb.InputConfig = &automlpb.InputConfig{} var request = &automlpb.ImportDataRequest{ Name: formattedName, InputConfig: inputConfig, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.ImportData(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestAutoMlImportDataError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/datasets/%s", "[PROJECT]", "[LOCATION]", "[DATASET]") var inputConfig *automlpb.InputConfig = &automlpb.InputConfig{} var request = &automlpb.ImportDataRequest{ Name: formattedName, InputConfig: inputConfig, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.ImportData(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestAutoMlExportData(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockAutoMl.err = nil mockAutoMl.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockAutoMl.resps = append(mockAutoMl.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/datasets/%s", "[PROJECT]", "[LOCATION]", "[DATASET]") var outputConfig *automlpb.OutputConfig = &automlpb.OutputConfig{} var request = &automlpb.ExportDataRequest{ Name: formattedName, OutputConfig: outputConfig, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.ExportData(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestAutoMlExportDataError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/datasets/%s", "[PROJECT]", "[LOCATION]", "[DATASET]") var outputConfig *automlpb.OutputConfig = &automlpb.OutputConfig{} var request = &automlpb.ExportDataRequest{ Name: formattedName, OutputConfig: outputConfig, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.ExportData(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestAutoMlGetAnnotationSpec(t *testing.T) { var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var exampleCount int32 = 1517063674 var expectedResponse = &automlpb.AnnotationSpec{ Name: name2, DisplayName: displayName, ExampleCount: exampleCount, } mockAutoMl.err = nil mockAutoMl.reqs = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/datasets/%s/annotationSpecs/%s", "[PROJECT]", "[LOCATION]", "[DATASET]", "[ANNOTATION_SPEC]") var request = &automlpb.GetAnnotationSpecRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetAnnotationSpec(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAutoMlGetAnnotationSpecError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/datasets/%s/annotationSpecs/%s", "[PROJECT]", "[LOCATION]", "[DATASET]", "[ANNOTATION_SPEC]") var request = &automlpb.GetAnnotationSpecRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetAnnotationSpec(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAutoMlCreateModel(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var datasetId string = "datasetId-2115646910" var etag string = "etag3123477" var expectedResponse = &automlpb.Model{ Name: name, DisplayName: displayName, DatasetId: datasetId, Etag: etag, } mockAutoMl.err = nil mockAutoMl.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockAutoMl.resps = append(mockAutoMl.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var model *automlpb.Model = &automlpb.Model{} var request = &automlpb.CreateModelRequest{ Parent: formattedParent, Model: model, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.CreateModel(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAutoMlCreateModelError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var model *automlpb.Model = &automlpb.Model{} var request = &automlpb.CreateModelRequest{ Parent: formattedParent, Model: model, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.CreateModel(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAutoMlGetModel(t *testing.T) { var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var datasetId string = "datasetId-2115646910" var etag string = "etag3123477" var expectedResponse = &automlpb.Model{ Name: name2, DisplayName: displayName, DatasetId: datasetId, Etag: etag, } mockAutoMl.err = nil mockAutoMl.reqs = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/models/%s", "[PROJECT]", "[LOCATION]", "[MODEL]") var request = &automlpb.GetModelRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetModel(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAutoMlGetModelError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/models/%s", "[PROJECT]", "[LOCATION]", "[MODEL]") var request = &automlpb.GetModelRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetModel(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAutoMlUpdateModel(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var datasetId string = "datasetId-2115646910" var etag string = "etag3123477" var expectedResponse = &automlpb.Model{ Name: name, DisplayName: displayName, DatasetId: datasetId, Etag: etag, } mockAutoMl.err = nil mockAutoMl.reqs = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], expectedResponse) var model *automlpb.Model = &automlpb.Model{} var updateMask *field_maskpb.FieldMask = &field_maskpb.FieldMask{} var request = &automlpb.UpdateModelRequest{ Model: model, UpdateMask: updateMask, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateModel(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAutoMlUpdateModelError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = gstatus.Error(errCode, "test error") var model *automlpb.Model = &automlpb.Model{} var updateMask *field_maskpb.FieldMask = &field_maskpb.FieldMask{} var request = &automlpb.UpdateModelRequest{ Model: model, UpdateMask: updateMask, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateModel(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAutoMlListModels(t *testing.T) { var nextPageToken string = "" var modelElement *automlpb.Model = &automlpb.Model{} var model = []*automlpb.Model{modelElement} var expectedResponse = &automlpb.ListModelsResponse{ NextPageToken: nextPageToken, Model: model, } mockAutoMl.err = nil mockAutoMl.reqs = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &automlpb.ListModelsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListModels(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Model[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAutoMlListModelsError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &automlpb.ListModelsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListModels(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAutoMlDeleteModel(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockAutoMl.err = nil mockAutoMl.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockAutoMl.resps = append(mockAutoMl.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/models/%s", "[PROJECT]", "[LOCATION]", "[MODEL]") var request = &automlpb.DeleteModelRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.DeleteModel(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestAutoMlDeleteModelError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/models/%s", "[PROJECT]", "[LOCATION]", "[MODEL]") var request = &automlpb.DeleteModelRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.DeleteModel(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestAutoMlDeployModel(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockAutoMl.err = nil mockAutoMl.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockAutoMl.resps = append(mockAutoMl.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/models/%s", "[PROJECT]", "[LOCATION]", "[MODEL]") var request = &automlpb.DeployModelRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.DeployModel(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestAutoMlDeployModelError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/models/%s", "[PROJECT]", "[LOCATION]", "[MODEL]") var request = &automlpb.DeployModelRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.DeployModel(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestAutoMlUndeployModel(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockAutoMl.err = nil mockAutoMl.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockAutoMl.resps = append(mockAutoMl.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/models/%s", "[PROJECT]", "[LOCATION]", "[MODEL]") var request = &automlpb.UndeployModelRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.UndeployModel(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestAutoMlUndeployModelError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/models/%s", "[PROJECT]", "[LOCATION]", "[MODEL]") var request = &automlpb.UndeployModelRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.UndeployModel(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestAutoMlExportModel(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockAutoMl.err = nil mockAutoMl.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockAutoMl.resps = append(mockAutoMl.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/models/%s", "[PROJECT]", "[LOCATION]", "[MODEL]") var outputConfig *automlpb.ModelExportOutputConfig = &automlpb.ModelExportOutputConfig{} var request = &automlpb.ExportModelRequest{ Name: formattedName, OutputConfig: outputConfig, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.ExportModel(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestAutoMlExportModelError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/models/%s", "[PROJECT]", "[LOCATION]", "[MODEL]") var outputConfig *automlpb.ModelExportOutputConfig = &automlpb.ModelExportOutputConfig{} var request = &automlpb.ExportModelRequest{ Name: formattedName, OutputConfig: outputConfig, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.ExportModel(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestAutoMlGetModelEvaluation(t *testing.T) { var name2 string = "name2-1052831874" var annotationSpecId string = "annotationSpecId60690191" var displayName string = "displayName1615086568" var evaluatedExampleCount int32 = 277565350 var expectedResponse = &automlpb.ModelEvaluation{ Name: name2, AnnotationSpecId: annotationSpecId, DisplayName: displayName, EvaluatedExampleCount: evaluatedExampleCount, } mockAutoMl.err = nil mockAutoMl.reqs = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/models/%s/modelEvaluations/%s", "[PROJECT]", "[LOCATION]", "[MODEL]", "[MODEL_EVALUATION]") var request = &automlpb.GetModelEvaluationRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetModelEvaluation(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAutoMlGetModelEvaluationError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/models/%s/modelEvaluations/%s", "[PROJECT]", "[LOCATION]", "[MODEL]", "[MODEL_EVALUATION]") var request = &automlpb.GetModelEvaluationRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetModelEvaluation(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAutoMlListModelEvaluations(t *testing.T) { var nextPageToken string = "" var modelEvaluationElement *automlpb.ModelEvaluation = &automlpb.ModelEvaluation{} var modelEvaluation = []*automlpb.ModelEvaluation{modelEvaluationElement} var expectedResponse = &automlpb.ListModelEvaluationsResponse{ NextPageToken: nextPageToken, ModelEvaluation: modelEvaluation, } mockAutoMl.err = nil mockAutoMl.reqs = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/models/%s", "[PROJECT]", "[LOCATION]", "[MODEL]") var filter string = "filter-1274492040" var request = &automlpb.ListModelEvaluationsRequest{ Parent: formattedParent, Filter: filter, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListModelEvaluations(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.ModelEvaluation[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAutoMlListModelEvaluationsError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/models/%s", "[PROJECT]", "[LOCATION]", "[MODEL]") var filter string = "filter-1274492040" var request = &automlpb.ListModelEvaluationsRequest{ Parent: formattedParent, Filter: filter, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListModelEvaluations(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestPredictionServicePredict(t *testing.T) { var expectedResponse *automlpb.PredictResponse = &automlpb.PredictResponse{} mockPrediction.err = nil mockPrediction.reqs = nil mockPrediction.resps = append(mockPrediction.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/models/%s", "[PROJECT]", "[LOCATION]", "[MODEL]") var payload *automlpb.ExamplePayload = &automlpb.ExamplePayload{} var request = &automlpb.PredictRequest{ Name: formattedName, Payload: payload, } c, err := NewPredictionClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Predict(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockPrediction.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestPredictionServicePredictError(t *testing.T) { errCode := codes.PermissionDenied mockPrediction.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/models/%s", "[PROJECT]", "[LOCATION]", "[MODEL]") var payload *automlpb.ExamplePayload = &automlpb.ExamplePayload{} var request = &automlpb.PredictRequest{ Name: formattedName, Payload: payload, } c, err := NewPredictionClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Predict(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestPredictionServiceBatchPredict(t *testing.T) { var expectedResponse *automlpb.BatchPredictResult = &automlpb.BatchPredictResult{} mockPrediction.err = nil mockPrediction.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockPrediction.resps = append(mockPrediction.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/models/%s", "[PROJECT]", "[LOCATION]", "[MODEL]") var inputConfig *automlpb.BatchPredictInputConfig = &automlpb.BatchPredictInputConfig{} var outputConfig *automlpb.BatchPredictOutputConfig = &automlpb.BatchPredictOutputConfig{} var request = &automlpb.BatchPredictRequest{ Name: formattedName, InputConfig: inputConfig, OutputConfig: outputConfig, } c, err := NewPredictionClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.BatchPredict(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockPrediction.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestPredictionServiceBatchPredictError(t *testing.T) { errCode := codes.PermissionDenied mockPrediction.err = nil mockPrediction.resps = append(mockPrediction.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/models/%s", "[PROJECT]", "[LOCATION]", "[MODEL]") var inputConfig *automlpb.BatchPredictInputConfig = &automlpb.BatchPredictInputConfig{} var outputConfig *automlpb.BatchPredictOutputConfig = &automlpb.BatchPredictOutputConfig{} var request = &automlpb.BatchPredictRequest{ Name: formattedName, InputConfig: inputConfig, OutputConfig: outputConfig, } c, err := NewPredictionClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.BatchPredict(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/automl/apiv1/prediction_client.go000066400000000000000000000241031356504100700231360ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package automl import ( "context" "fmt" "math" "net/url" "time" "cloud.google.com/go/longrunning" lroauto "cloud.google.com/go/longrunning/autogen" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" "google.golang.org/api/transport" automlpb "google.golang.org/genproto/googleapis/cloud/automl/v1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" "google.golang.org/grpc" "google.golang.org/grpc/metadata" ) // PredictionCallOptions contains the retry settings for each method of PredictionClient. type PredictionCallOptions struct { Predict []gax.CallOption BatchPredict []gax.CallOption } func defaultPredictionClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("automl.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultPredictionCallOptions() *PredictionCallOptions { retry := map[[2]string][]gax.CallOption{} return &PredictionCallOptions{ Predict: retry[[2]string{"default", "non_idempotent"}], BatchPredict: retry[[2]string{"default", "non_idempotent"}], } } // PredictionClient is a client for interacting with Cloud AutoML API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type PredictionClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. predictionClient automlpb.PredictionServiceClient // LROClient is used internally to handle longrunning operations. // It is exposed so that its CallOptions can be modified if required. // Users should not Close this client. LROClient *lroauto.OperationsClient // The call options for this service. CallOptions *PredictionCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewPredictionClient creates a new prediction service client. // // AutoML Prediction API. // // On any input that is documented to expect a string parameter in // snake_case or kebab-case, either of those cases is accepted. func NewPredictionClient(ctx context.Context, opts ...option.ClientOption) (*PredictionClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultPredictionClientOptions(), opts...)...) if err != nil { return nil, err } c := &PredictionClient{ conn: conn, CallOptions: defaultPredictionCallOptions(), predictionClient: automlpb.NewPredictionServiceClient(conn), } c.setGoogleClientInfo() c.LROClient, err = lroauto.NewOperationsClient(ctx, option.WithGRPCConn(conn)) if err != nil { // This error "should not happen", since we are just reusing old connection // and never actually need to dial. // If this does happen, we could leak conn. However, we cannot close conn: // If the user invoked the function with option.WithGRPCConn, // we would close a connection that's still in use. // TODO(pongad): investigate error conditions. return nil, err } return c, nil } // Connection returns the client's connection to the API service. func (c *PredictionClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *PredictionClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *PredictionClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // Predict perform an online prediction. The prediction result will be directly // returned in the response. // Available for following ML problems, and their expected request payloads: // // Image Classification - Image in .JPEG, .GIF or .PNG format, image_bytes // up to 30MB. // // Image Object Detection - Image in .JPEG, .GIF or .PNG format, image_bytes // up to 30MB. // // Text Classification - TextSnippet, content up to 60,000 characters, // UTF-8 encoded. // // Text Extraction - TextSnippet, content up to 30,000 characters, // UTF-8 NFC encoded. // // Translation - TextSnippet, content up to 25,000 characters, UTF-8 // encoded. // // Text Sentiment - TextSnippet, content up 500 characters, UTF-8 // encoded. func (c *PredictionClient) Predict(ctx context.Context, req *automlpb.PredictRequest, opts ...gax.CallOption) (*automlpb.PredictResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.Predict[0:len(c.CallOptions.Predict):len(c.CallOptions.Predict)], opts...) var resp *automlpb.PredictResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.predictionClient.Predict(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // BatchPredict perform a batch prediction. Unlike the online // [Predict][google.cloud.automl.v1.PredictionService.Predict], batch // prediction result won't be immediately available in the response. Instead, // a long running operation object is returned. User can poll the operation // result via [GetOperation][google.longrunning.Operations.GetOperation] // method. Once the operation is done, // [BatchPredictResult][google.cloud.automl.v1.BatchPredictResult] is returned // in the [response][google.longrunning.Operation.response] field. Available // for following ML problems: // // Image Classification // // Image Object Detection // // Text Extraction func (c *PredictionClient) BatchPredict(ctx context.Context, req *automlpb.BatchPredictRequest, opts ...gax.CallOption) (*BatchPredictOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.BatchPredict[0:len(c.CallOptions.BatchPredict):len(c.CallOptions.BatchPredict)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.predictionClient.BatchPredict(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &BatchPredictOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // BatchPredictOperation manages a long-running operation from BatchPredict. type BatchPredictOperation struct { lro *longrunning.Operation } // BatchPredictOperation returns a new BatchPredictOperation from a given name. // The name must be that of a previously created BatchPredictOperation, possibly from a different process. func (c *PredictionClient) BatchPredictOperation(name string) *BatchPredictOperation { return &BatchPredictOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *BatchPredictOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*automlpb.BatchPredictResult, error) { var resp automlpb.BatchPredictResult if err := op.lro.WaitWithInterval(ctx, &resp, 5000*time.Millisecond, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *BatchPredictOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*automlpb.BatchPredictResult, error) { var resp automlpb.BatchPredictResult if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *BatchPredictOperation) Metadata() (*automlpb.OperationMetadata, error) { var meta automlpb.OperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *BatchPredictOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *BatchPredictOperation) Name() string { return op.lro.Name() } google-cloud-go-0.49.0/automl/apiv1/prediction_client_example_test.go000066400000000000000000000033371356504100700257160ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package automl_test import ( "context" automl "cloud.google.com/go/automl/apiv1" automlpb "google.golang.org/genproto/googleapis/cloud/automl/v1" ) func ExampleNewPredictionClient() { ctx := context.Background() c, err := automl.NewPredictionClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExamplePredictionClient_Predict() { ctx := context.Background() c, err := automl.NewPredictionClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.PredictRequest{ // TODO: Fill request struct fields. } resp, err := c.Predict(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExamplePredictionClient_BatchPredict() { ctx := context.Background() c, err := automl.NewPredictionClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.BatchPredictRequest{ // TODO: Fill request struct fields. } op, err := c.BatchPredict(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/automl/apiv1beta1/000077500000000000000000000000001356504100700200265ustar00rootroot00000000000000google-cloud-go-0.49.0/automl/apiv1beta1/.repo-metadata.json000066400000000000000000000006211356504100700235210ustar00rootroot00000000000000{ "name": "automl", "name_pretty": "Cloud AutoML", "product_documentation": "https://cloud.google.com/automl", "client_documentation": "https://godoc.org/cloud.google.com/go/automl/apiv1beta1", "release_level": "beta", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "automl.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/automl/apiv1beta1/auto_ml_client.go000066400000000000000000001711461356504100700233650ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package automl import ( "context" "fmt" "math" "net/url" "time" "cloud.google.com/go/longrunning" lroauto "cloud.google.com/go/longrunning/autogen" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" automlpb "google.golang.org/genproto/googleapis/cloud/automl/v1beta1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // CallOptions contains the retry settings for each method of Client. type CallOptions struct { CreateDataset []gax.CallOption UpdateDataset []gax.CallOption GetDataset []gax.CallOption ListDatasets []gax.CallOption DeleteDataset []gax.CallOption ImportData []gax.CallOption ExportData []gax.CallOption CreateModel []gax.CallOption GetModel []gax.CallOption ListModels []gax.CallOption DeleteModel []gax.CallOption DeployModel []gax.CallOption UndeployModel []gax.CallOption GetModelEvaluation []gax.CallOption ExportModel []gax.CallOption ExportEvaluatedExamples []gax.CallOption ListModelEvaluations []gax.CallOption GetAnnotationSpec []gax.CallOption GetTableSpec []gax.CallOption ListTableSpecs []gax.CallOption UpdateTableSpec []gax.CallOption GetColumnSpec []gax.CallOption ListColumnSpecs []gax.CallOption UpdateColumnSpec []gax.CallOption } func defaultClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("automl.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultCallOptions() *CallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &CallOptions{ CreateDataset: retry[[2]string{"default", "non_idempotent"}], UpdateDataset: retry[[2]string{"default", "non_idempotent"}], GetDataset: retry[[2]string{"default", "idempotent"}], ListDatasets: retry[[2]string{"default", "idempotent"}], DeleteDataset: retry[[2]string{"default", "idempotent"}], ImportData: retry[[2]string{"default", "non_idempotent"}], ExportData: retry[[2]string{"default", "non_idempotent"}], CreateModel: retry[[2]string{"default", "non_idempotent"}], GetModel: retry[[2]string{"default", "idempotent"}], ListModels: retry[[2]string{"default", "idempotent"}], DeleteModel: retry[[2]string{"default", "idempotent"}], DeployModel: retry[[2]string{"default", "non_idempotent"}], UndeployModel: retry[[2]string{"default", "non_idempotent"}], GetModelEvaluation: retry[[2]string{"default", "idempotent"}], ExportModel: retry[[2]string{"default", "non_idempotent"}], ExportEvaluatedExamples: retry[[2]string{"default", "non_idempotent"}], ListModelEvaluations: retry[[2]string{"default", "non_idempotent"}], GetAnnotationSpec: retry[[2]string{"default", "idempotent"}], GetTableSpec: retry[[2]string{"default", "idempotent"}], ListTableSpecs: retry[[2]string{"default", "idempotent"}], UpdateTableSpec: retry[[2]string{"default", "non_idempotent"}], GetColumnSpec: retry[[2]string{"default", "idempotent"}], ListColumnSpecs: retry[[2]string{"default", "idempotent"}], UpdateColumnSpec: retry[[2]string{"default", "non_idempotent"}], } } // Client is a client for interacting with Cloud AutoML API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. client automlpb.AutoMlClient // LROClient is used internally to handle longrunning operations. // It is exposed so that its CallOptions can be modified if required. // Users should not Close this client. LROClient *lroauto.OperationsClient // The call options for this service. CallOptions *CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewClient creates a new auto ml client. // // AutoML Server API. // // The resource names are assigned by the server. // The server never reuses names that it has created after the resources with // those names are deleted. // // An ID of a resource is the last element of the item's resource name. For // projects/{project_id}/locations/{location_id}/datasets/{dataset_id}, then // the id for the item is {dataset_id}. // // Currently the only supported location_id is "us-central1". // // On any input that is documented to expect a string parameter in // snake_case or kebab-case, either of those cases is accepted. func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultClientOptions(), opts...)...) if err != nil { return nil, err } c := &Client{ conn: conn, CallOptions: defaultCallOptions(), client: automlpb.NewAutoMlClient(conn), } c.setGoogleClientInfo() c.LROClient, err = lroauto.NewOperationsClient(ctx, option.WithGRPCConn(conn)) if err != nil { // This error "should not happen", since we are just reusing old connection // and never actually need to dial. // If this does happen, we could leak conn. However, we cannot close conn: // If the user invoked the function with option.WithGRPCConn, // we would close a connection that's still in use. // TODO(pongad): investigate error conditions. return nil, err } return c, nil } // Connection returns the client's connection to the API service. func (c *Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *Client) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *Client) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // CreateDataset creates a dataset. func (c *Client) CreateDataset(ctx context.Context, req *automlpb.CreateDatasetRequest, opts ...gax.CallOption) (*automlpb.Dataset, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateDataset[0:len(c.CallOptions.CreateDataset):len(c.CallOptions.CreateDataset)], opts...) var resp *automlpb.Dataset err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CreateDataset(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateDataset updates a dataset. func (c *Client) UpdateDataset(ctx context.Context, req *automlpb.UpdateDatasetRequest, opts ...gax.CallOption) (*automlpb.Dataset, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "dataset.name", url.QueryEscape(req.GetDataset().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateDataset[0:len(c.CallOptions.UpdateDataset):len(c.CallOptions.UpdateDataset)], opts...) var resp *automlpb.Dataset err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.UpdateDataset(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetDataset gets a dataset. func (c *Client) GetDataset(ctx context.Context, req *automlpb.GetDatasetRequest, opts ...gax.CallOption) (*automlpb.Dataset, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetDataset[0:len(c.CallOptions.GetDataset):len(c.CallOptions.GetDataset)], opts...) var resp *automlpb.Dataset err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetDataset(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListDatasets lists datasets in a project. func (c *Client) ListDatasets(ctx context.Context, req *automlpb.ListDatasetsRequest, opts ...gax.CallOption) *DatasetIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListDatasets[0:len(c.CallOptions.ListDatasets):len(c.CallOptions.ListDatasets)], opts...) it := &DatasetIterator{} req = proto.Clone(req).(*automlpb.ListDatasetsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*automlpb.Dataset, string, error) { var resp *automlpb.ListDatasetsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListDatasets(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Datasets, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // DeleteDataset deletes a dataset and all of its contents. // Returns empty response in the // [response][google.longrunning.Operation.response] field when it completes, // and delete_details in the // [metadata][google.longrunning.Operation.metadata] field. func (c *Client) DeleteDataset(ctx context.Context, req *automlpb.DeleteDatasetRequest, opts ...gax.CallOption) (*DeleteDatasetOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteDataset[0:len(c.CallOptions.DeleteDataset):len(c.CallOptions.DeleteDataset)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.DeleteDataset(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &DeleteDatasetOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // ImportData imports data into a dataset. // For Tables this method can only be called on an empty Dataset. // // For Tables: // // A // [schema_inference_version][google.cloud.automl.v1beta1.InputConfig.params] // parameter must be explicitly set. // Returns an empty response in the // [response][google.longrunning.Operation.response] field when it completes. func (c *Client) ImportData(ctx context.Context, req *automlpb.ImportDataRequest, opts ...gax.CallOption) (*ImportDataOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ImportData[0:len(c.CallOptions.ImportData):len(c.CallOptions.ImportData)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ImportData(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &ImportDataOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // ExportData exports dataset's data to the provided output location. // Returns an empty response in the // [response][google.longrunning.Operation.response] field when it completes. func (c *Client) ExportData(ctx context.Context, req *automlpb.ExportDataRequest, opts ...gax.CallOption) (*ExportDataOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ExportData[0:len(c.CallOptions.ExportData):len(c.CallOptions.ExportData)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ExportData(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &ExportDataOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // CreateModel creates a model. // Returns a Model in the [response][google.longrunning.Operation.response] // field when it completes. // When you create a model, several model evaluations are created for it: // a global evaluation, and one evaluation for each annotation spec. func (c *Client) CreateModel(ctx context.Context, req *automlpb.CreateModelRequest, opts ...gax.CallOption) (*CreateModelOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateModel[0:len(c.CallOptions.CreateModel):len(c.CallOptions.CreateModel)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CreateModel(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &CreateModelOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // GetModel gets a model. func (c *Client) GetModel(ctx context.Context, req *automlpb.GetModelRequest, opts ...gax.CallOption) (*automlpb.Model, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetModel[0:len(c.CallOptions.GetModel):len(c.CallOptions.GetModel)], opts...) var resp *automlpb.Model err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetModel(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListModels lists models. func (c *Client) ListModels(ctx context.Context, req *automlpb.ListModelsRequest, opts ...gax.CallOption) *ModelIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListModels[0:len(c.CallOptions.ListModels):len(c.CallOptions.ListModels)], opts...) it := &ModelIterator{} req = proto.Clone(req).(*automlpb.ListModelsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*automlpb.Model, string, error) { var resp *automlpb.ListModelsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListModels(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Model, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // DeleteModel deletes a model. // Returns google.protobuf.Empty in the // [response][google.longrunning.Operation.response] field when it completes, // and delete_details in the // [metadata][google.longrunning.Operation.metadata] field. func (c *Client) DeleteModel(ctx context.Context, req *automlpb.DeleteModelRequest, opts ...gax.CallOption) (*DeleteModelOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteModel[0:len(c.CallOptions.DeleteModel):len(c.CallOptions.DeleteModel)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.DeleteModel(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &DeleteModelOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // DeployModel deploys a model. If a model is already deployed, deploying it with the // same parameters has no effect. Deploying with different parametrs // (as e.g. changing // // [node_number][google.cloud.automl.v1beta1.ImageObjectDetectionModelDeploymentMetadata.node_number]) // will reset the deployment state without pausing the model's availability. // // Only applicable for Text Classification, Image Object Detection and Tables; all other domains manage deployment automatically. // // Returns an empty response in the // [response][google.longrunning.Operation.response] field when it completes. func (c *Client) DeployModel(ctx context.Context, req *automlpb.DeployModelRequest, opts ...gax.CallOption) (*DeployModelOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeployModel[0:len(c.CallOptions.DeployModel):len(c.CallOptions.DeployModel)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.DeployModel(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &DeployModelOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // UndeployModel undeploys a model. If the model is not deployed this method has no effect. // // Only applicable for Text Classification, Image Object Detection and Tables; // all other domains manage deployment automatically. // // Returns an empty response in the // [response][google.longrunning.Operation.response] field when it completes. func (c *Client) UndeployModel(ctx context.Context, req *automlpb.UndeployModelRequest, opts ...gax.CallOption) (*UndeployModelOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UndeployModel[0:len(c.CallOptions.UndeployModel):len(c.CallOptions.UndeployModel)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.UndeployModel(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &UndeployModelOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // GetModelEvaluation gets a model evaluation. func (c *Client) GetModelEvaluation(ctx context.Context, req *automlpb.GetModelEvaluationRequest, opts ...gax.CallOption) (*automlpb.ModelEvaluation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetModelEvaluation[0:len(c.CallOptions.GetModelEvaluation):len(c.CallOptions.GetModelEvaluation)], opts...) var resp *automlpb.ModelEvaluation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetModelEvaluation(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ExportModel exports a trained, "export-able", model to a user specified Google Cloud // Storage location. A model is considered export-able if and only if it has // an export format defined for it in // // [ModelExportOutputConfig][google.cloud.automl.v1beta1.ModelExportOutputConfig]. // // Returns an empty response in the // [response][google.longrunning.Operation.response] field when it completes. func (c *Client) ExportModel(ctx context.Context, req *automlpb.ExportModelRequest, opts ...gax.CallOption) (*ExportModelOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ExportModel[0:len(c.CallOptions.ExportModel):len(c.CallOptions.ExportModel)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ExportModel(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &ExportModelOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // ExportEvaluatedExamples exports examples on which the model was evaluated (i.e. which were in the // TEST set of the dataset the model was created from), together with their // ground truth annotations and the annotations created (predicted) by the // model. // The examples, ground truth and predictions are exported in the state // they were at the moment the model was evaluated. // // This export is available only for 30 days since the model evaluation is // created. // // Currently only available for Tables. // // Returns an empty response in the // [response][google.longrunning.Operation.response] field when it completes. func (c *Client) ExportEvaluatedExamples(ctx context.Context, req *automlpb.ExportEvaluatedExamplesRequest, opts ...gax.CallOption) (*ExportEvaluatedExamplesOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ExportEvaluatedExamples[0:len(c.CallOptions.ExportEvaluatedExamples):len(c.CallOptions.ExportEvaluatedExamples)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ExportEvaluatedExamples(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &ExportEvaluatedExamplesOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // ListModelEvaluations lists model evaluations. func (c *Client) ListModelEvaluations(ctx context.Context, req *automlpb.ListModelEvaluationsRequest, opts ...gax.CallOption) *ModelEvaluationIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListModelEvaluations[0:len(c.CallOptions.ListModelEvaluations):len(c.CallOptions.ListModelEvaluations)], opts...) it := &ModelEvaluationIterator{} req = proto.Clone(req).(*automlpb.ListModelEvaluationsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*automlpb.ModelEvaluation, string, error) { var resp *automlpb.ListModelEvaluationsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListModelEvaluations(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.ModelEvaluation, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetAnnotationSpec gets an annotation spec. func (c *Client) GetAnnotationSpec(ctx context.Context, req *automlpb.GetAnnotationSpecRequest, opts ...gax.CallOption) (*automlpb.AnnotationSpec, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetAnnotationSpec[0:len(c.CallOptions.GetAnnotationSpec):len(c.CallOptions.GetAnnotationSpec)], opts...) var resp *automlpb.AnnotationSpec err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetAnnotationSpec(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetTableSpec gets a table spec. func (c *Client) GetTableSpec(ctx context.Context, req *automlpb.GetTableSpecRequest, opts ...gax.CallOption) (*automlpb.TableSpec, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetTableSpec[0:len(c.CallOptions.GetTableSpec):len(c.CallOptions.GetTableSpec)], opts...) var resp *automlpb.TableSpec err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetTableSpec(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListTableSpecs lists table specs in a dataset. func (c *Client) ListTableSpecs(ctx context.Context, req *automlpb.ListTableSpecsRequest, opts ...gax.CallOption) *TableSpecIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListTableSpecs[0:len(c.CallOptions.ListTableSpecs):len(c.CallOptions.ListTableSpecs)], opts...) it := &TableSpecIterator{} req = proto.Clone(req).(*automlpb.ListTableSpecsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*automlpb.TableSpec, string, error) { var resp *automlpb.ListTableSpecsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListTableSpecs(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.TableSpecs, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // UpdateTableSpec updates a table spec. func (c *Client) UpdateTableSpec(ctx context.Context, req *automlpb.UpdateTableSpecRequest, opts ...gax.CallOption) (*automlpb.TableSpec, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "table_spec.name", url.QueryEscape(req.GetTableSpec().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateTableSpec[0:len(c.CallOptions.UpdateTableSpec):len(c.CallOptions.UpdateTableSpec)], opts...) var resp *automlpb.TableSpec err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.UpdateTableSpec(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetColumnSpec gets a column spec. func (c *Client) GetColumnSpec(ctx context.Context, req *automlpb.GetColumnSpecRequest, opts ...gax.CallOption) (*automlpb.ColumnSpec, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetColumnSpec[0:len(c.CallOptions.GetColumnSpec):len(c.CallOptions.GetColumnSpec)], opts...) var resp *automlpb.ColumnSpec err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetColumnSpec(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListColumnSpecs lists column specs in a table spec. func (c *Client) ListColumnSpecs(ctx context.Context, req *automlpb.ListColumnSpecsRequest, opts ...gax.CallOption) *ColumnSpecIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListColumnSpecs[0:len(c.CallOptions.ListColumnSpecs):len(c.CallOptions.ListColumnSpecs)], opts...) it := &ColumnSpecIterator{} req = proto.Clone(req).(*automlpb.ListColumnSpecsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*automlpb.ColumnSpec, string, error) { var resp *automlpb.ListColumnSpecsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListColumnSpecs(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.ColumnSpecs, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // UpdateColumnSpec updates a column spec. func (c *Client) UpdateColumnSpec(ctx context.Context, req *automlpb.UpdateColumnSpecRequest, opts ...gax.CallOption) (*automlpb.ColumnSpec, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "column_spec.name", url.QueryEscape(req.GetColumnSpec().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateColumnSpec[0:len(c.CallOptions.UpdateColumnSpec):len(c.CallOptions.UpdateColumnSpec)], opts...) var resp *automlpb.ColumnSpec err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.UpdateColumnSpec(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ColumnSpecIterator manages a stream of *automlpb.ColumnSpec. type ColumnSpecIterator struct { items []*automlpb.ColumnSpec pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*automlpb.ColumnSpec, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *ColumnSpecIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *ColumnSpecIterator) Next() (*automlpb.ColumnSpec, error) { var item *automlpb.ColumnSpec if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *ColumnSpecIterator) bufLen() int { return len(it.items) } func (it *ColumnSpecIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // DatasetIterator manages a stream of *automlpb.Dataset. type DatasetIterator struct { items []*automlpb.Dataset pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*automlpb.Dataset, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *DatasetIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *DatasetIterator) Next() (*automlpb.Dataset, error) { var item *automlpb.Dataset if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *DatasetIterator) bufLen() int { return len(it.items) } func (it *DatasetIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // ModelEvaluationIterator manages a stream of *automlpb.ModelEvaluation. type ModelEvaluationIterator struct { items []*automlpb.ModelEvaluation pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*automlpb.ModelEvaluation, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *ModelEvaluationIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *ModelEvaluationIterator) Next() (*automlpb.ModelEvaluation, error) { var item *automlpb.ModelEvaluation if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *ModelEvaluationIterator) bufLen() int { return len(it.items) } func (it *ModelEvaluationIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // ModelIterator manages a stream of *automlpb.Model. type ModelIterator struct { items []*automlpb.Model pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*automlpb.Model, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *ModelIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *ModelIterator) Next() (*automlpb.Model, error) { var item *automlpb.Model if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *ModelIterator) bufLen() int { return len(it.items) } func (it *ModelIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // TableSpecIterator manages a stream of *automlpb.TableSpec. type TableSpecIterator struct { items []*automlpb.TableSpec pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*automlpb.TableSpec, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *TableSpecIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *TableSpecIterator) Next() (*automlpb.TableSpec, error) { var item *automlpb.TableSpec if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *TableSpecIterator) bufLen() int { return len(it.items) } func (it *TableSpecIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // CreateModelOperation manages a long-running operation from CreateModel. type CreateModelOperation struct { lro *longrunning.Operation } // CreateModelOperation returns a new CreateModelOperation from a given name. // The name must be that of a previously created CreateModelOperation, possibly from a different process. func (c *Client) CreateModelOperation(name string) *CreateModelOperation { return &CreateModelOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *CreateModelOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*automlpb.Model, error) { var resp automlpb.Model if err := op.lro.WaitWithInterval(ctx, &resp, 5000*time.Millisecond, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *CreateModelOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*automlpb.Model, error) { var resp automlpb.Model if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *CreateModelOperation) Metadata() (*automlpb.OperationMetadata, error) { var meta automlpb.OperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *CreateModelOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *CreateModelOperation) Name() string { return op.lro.Name() } // DeleteDatasetOperation manages a long-running operation from DeleteDataset. type DeleteDatasetOperation struct { lro *longrunning.Operation } // DeleteDatasetOperation returns a new DeleteDatasetOperation from a given name. // The name must be that of a previously created DeleteDatasetOperation, possibly from a different process. func (c *Client) DeleteDatasetOperation(name string) *DeleteDatasetOperation { return &DeleteDatasetOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning any error encountered. // // See documentation of Poll for error-handling information. func (op *DeleteDatasetOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { return op.lro.WaitWithInterval(ctx, nil, 5000*time.Millisecond, opts...) } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, op.Done will return true. func (op *DeleteDatasetOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Poll(ctx, nil, opts...) } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *DeleteDatasetOperation) Metadata() (*automlpb.OperationMetadata, error) { var meta automlpb.OperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *DeleteDatasetOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *DeleteDatasetOperation) Name() string { return op.lro.Name() } // DeleteModelOperation manages a long-running operation from DeleteModel. type DeleteModelOperation struct { lro *longrunning.Operation } // DeleteModelOperation returns a new DeleteModelOperation from a given name. // The name must be that of a previously created DeleteModelOperation, possibly from a different process. func (c *Client) DeleteModelOperation(name string) *DeleteModelOperation { return &DeleteModelOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning any error encountered. // // See documentation of Poll for error-handling information. func (op *DeleteModelOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { return op.lro.WaitWithInterval(ctx, nil, 5000*time.Millisecond, opts...) } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, op.Done will return true. func (op *DeleteModelOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Poll(ctx, nil, opts...) } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *DeleteModelOperation) Metadata() (*automlpb.OperationMetadata, error) { var meta automlpb.OperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *DeleteModelOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *DeleteModelOperation) Name() string { return op.lro.Name() } // DeployModelOperation manages a long-running operation from DeployModel. type DeployModelOperation struct { lro *longrunning.Operation } // DeployModelOperation returns a new DeployModelOperation from a given name. // The name must be that of a previously created DeployModelOperation, possibly from a different process. func (c *Client) DeployModelOperation(name string) *DeployModelOperation { return &DeployModelOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning any error encountered. // // See documentation of Poll for error-handling information. func (op *DeployModelOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { return op.lro.WaitWithInterval(ctx, nil, 5000*time.Millisecond, opts...) } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, op.Done will return true. func (op *DeployModelOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Poll(ctx, nil, opts...) } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *DeployModelOperation) Metadata() (*automlpb.OperationMetadata, error) { var meta automlpb.OperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *DeployModelOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *DeployModelOperation) Name() string { return op.lro.Name() } // ExportDataOperation manages a long-running operation from ExportData. type ExportDataOperation struct { lro *longrunning.Operation } // ExportDataOperation returns a new ExportDataOperation from a given name. // The name must be that of a previously created ExportDataOperation, possibly from a different process. func (c *Client) ExportDataOperation(name string) *ExportDataOperation { return &ExportDataOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning any error encountered. // // See documentation of Poll for error-handling information. func (op *ExportDataOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { return op.lro.WaitWithInterval(ctx, nil, 5000*time.Millisecond, opts...) } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, op.Done will return true. func (op *ExportDataOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Poll(ctx, nil, opts...) } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *ExportDataOperation) Metadata() (*automlpb.OperationMetadata, error) { var meta automlpb.OperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *ExportDataOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *ExportDataOperation) Name() string { return op.lro.Name() } // ExportEvaluatedExamplesOperation manages a long-running operation from ExportEvaluatedExamples. type ExportEvaluatedExamplesOperation struct { lro *longrunning.Operation } // ExportEvaluatedExamplesOperation returns a new ExportEvaluatedExamplesOperation from a given name. // The name must be that of a previously created ExportEvaluatedExamplesOperation, possibly from a different process. func (c *Client) ExportEvaluatedExamplesOperation(name string) *ExportEvaluatedExamplesOperation { return &ExportEvaluatedExamplesOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning any error encountered. // // See documentation of Poll for error-handling information. func (op *ExportEvaluatedExamplesOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { return op.lro.WaitWithInterval(ctx, nil, 5000*time.Millisecond, opts...) } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, op.Done will return true. func (op *ExportEvaluatedExamplesOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Poll(ctx, nil, opts...) } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *ExportEvaluatedExamplesOperation) Metadata() (*automlpb.OperationMetadata, error) { var meta automlpb.OperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *ExportEvaluatedExamplesOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *ExportEvaluatedExamplesOperation) Name() string { return op.lro.Name() } // ExportModelOperation manages a long-running operation from ExportModel. type ExportModelOperation struct { lro *longrunning.Operation } // ExportModelOperation returns a new ExportModelOperation from a given name. // The name must be that of a previously created ExportModelOperation, possibly from a different process. func (c *Client) ExportModelOperation(name string) *ExportModelOperation { return &ExportModelOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning any error encountered. // // See documentation of Poll for error-handling information. func (op *ExportModelOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { return op.lro.WaitWithInterval(ctx, nil, 5000*time.Millisecond, opts...) } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, op.Done will return true. func (op *ExportModelOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Poll(ctx, nil, opts...) } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *ExportModelOperation) Metadata() (*automlpb.OperationMetadata, error) { var meta automlpb.OperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *ExportModelOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *ExportModelOperation) Name() string { return op.lro.Name() } // ImportDataOperation manages a long-running operation from ImportData. type ImportDataOperation struct { lro *longrunning.Operation } // ImportDataOperation returns a new ImportDataOperation from a given name. // The name must be that of a previously created ImportDataOperation, possibly from a different process. func (c *Client) ImportDataOperation(name string) *ImportDataOperation { return &ImportDataOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning any error encountered. // // See documentation of Poll for error-handling information. func (op *ImportDataOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { return op.lro.WaitWithInterval(ctx, nil, 5000*time.Millisecond, opts...) } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, op.Done will return true. func (op *ImportDataOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Poll(ctx, nil, opts...) } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *ImportDataOperation) Metadata() (*automlpb.OperationMetadata, error) { var meta automlpb.OperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *ImportDataOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *ImportDataOperation) Name() string { return op.lro.Name() } // UndeployModelOperation manages a long-running operation from UndeployModel. type UndeployModelOperation struct { lro *longrunning.Operation } // UndeployModelOperation returns a new UndeployModelOperation from a given name. // The name must be that of a previously created UndeployModelOperation, possibly from a different process. func (c *Client) UndeployModelOperation(name string) *UndeployModelOperation { return &UndeployModelOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning any error encountered. // // See documentation of Poll for error-handling information. func (op *UndeployModelOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { return op.lro.WaitWithInterval(ctx, nil, 5000*time.Millisecond, opts...) } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, op.Done will return true. func (op *UndeployModelOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Poll(ctx, nil, opts...) } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *UndeployModelOperation) Metadata() (*automlpb.OperationMetadata, error) { var meta automlpb.OperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *UndeployModelOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *UndeployModelOperation) Name() string { return op.lro.Name() } google-cloud-go-0.49.0/automl/apiv1beta1/auto_ml_client_example_test.go000066400000000000000000000231711356504100700261310ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package automl_test import ( "context" automl "cloud.google.com/go/automl/apiv1beta1" "google.golang.org/api/iterator" automlpb "google.golang.org/genproto/googleapis/cloud/automl/v1beta1" ) func ExampleNewClient() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleClient_CreateDataset() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.CreateDatasetRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateDataset(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_UpdateDataset() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.UpdateDatasetRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateDataset(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_GetDataset() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.GetDatasetRequest{ // TODO: Fill request struct fields. } resp, err := c.GetDataset(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ListDatasets() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.ListDatasetsRequest{ // TODO: Fill request struct fields. } it := c.ListDatasets(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_DeleteDataset() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.DeleteDatasetRequest{ // TODO: Fill request struct fields. } op, err := c.DeleteDataset(ctx, req) if err != nil { // TODO: Handle error. } err = op.Wait(ctx) // TODO: Handle error. } func ExampleClient_ImportData() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.ImportDataRequest{ // TODO: Fill request struct fields. } op, err := c.ImportData(ctx, req) if err != nil { // TODO: Handle error. } err = op.Wait(ctx) // TODO: Handle error. } func ExampleClient_ExportData() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.ExportDataRequest{ // TODO: Fill request struct fields. } op, err := c.ExportData(ctx, req) if err != nil { // TODO: Handle error. } err = op.Wait(ctx) // TODO: Handle error. } func ExampleClient_CreateModel() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.CreateModelRequest{ // TODO: Fill request struct fields. } op, err := c.CreateModel(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_GetModel() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.GetModelRequest{ // TODO: Fill request struct fields. } resp, err := c.GetModel(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ListModels() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.ListModelsRequest{ // TODO: Fill request struct fields. } it := c.ListModels(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_DeleteModel() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.DeleteModelRequest{ // TODO: Fill request struct fields. } op, err := c.DeleteModel(ctx, req) if err != nil { // TODO: Handle error. } err = op.Wait(ctx) // TODO: Handle error. } func ExampleClient_DeployModel() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.DeployModelRequest{ // TODO: Fill request struct fields. } op, err := c.DeployModel(ctx, req) if err != nil { // TODO: Handle error. } err = op.Wait(ctx) // TODO: Handle error. } func ExampleClient_UndeployModel() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.UndeployModelRequest{ // TODO: Fill request struct fields. } op, err := c.UndeployModel(ctx, req) if err != nil { // TODO: Handle error. } err = op.Wait(ctx) // TODO: Handle error. } func ExampleClient_GetModelEvaluation() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.GetModelEvaluationRequest{ // TODO: Fill request struct fields. } resp, err := c.GetModelEvaluation(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ExportModel() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.ExportModelRequest{ // TODO: Fill request struct fields. } op, err := c.ExportModel(ctx, req) if err != nil { // TODO: Handle error. } err = op.Wait(ctx) // TODO: Handle error. } func ExampleClient_ExportEvaluatedExamples() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.ExportEvaluatedExamplesRequest{ // TODO: Fill request struct fields. } op, err := c.ExportEvaluatedExamples(ctx, req) if err != nil { // TODO: Handle error. } err = op.Wait(ctx) // TODO: Handle error. } func ExampleClient_ListModelEvaluations() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.ListModelEvaluationsRequest{ // TODO: Fill request struct fields. } it := c.ListModelEvaluations(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_GetAnnotationSpec() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.GetAnnotationSpecRequest{ // TODO: Fill request struct fields. } resp, err := c.GetAnnotationSpec(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_GetTableSpec() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.GetTableSpecRequest{ // TODO: Fill request struct fields. } resp, err := c.GetTableSpec(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ListTableSpecs() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.ListTableSpecsRequest{ // TODO: Fill request struct fields. } it := c.ListTableSpecs(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_UpdateTableSpec() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.UpdateTableSpecRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateTableSpec(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_GetColumnSpec() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.GetColumnSpecRequest{ // TODO: Fill request struct fields. } resp, err := c.GetColumnSpec(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ListColumnSpecs() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.ListColumnSpecsRequest{ // TODO: Fill request struct fields. } it := c.ListColumnSpecs(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_UpdateColumnSpec() { ctx := context.Background() c, err := automl.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.UpdateColumnSpecRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateColumnSpec(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/automl/apiv1beta1/doc.go000066400000000000000000000054041356504100700211250ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package automl is an auto-generated package for the // Cloud AutoML API. // // NOTE: This package is in beta. It is not stable, and may be subject to changes. // // Train high-quality custom machine learning models with minimum effort and // machine learning expertise. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package automl // import "cloud.google.com/go/automl/apiv1beta1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191115" google-cloud-go-0.49.0/automl/apiv1beta1/mock_test.go000066400000000000000000002025571356504100700223600ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package automl import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" "google.golang.org/api/option" automlpb "google.golang.org/genproto/googleapis/cloud/automl/v1beta1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockAutoMlServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. automlpb.AutoMlServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockAutoMlServer) CreateDataset(ctx context.Context, req *automlpb.CreateDatasetRequest) (*automlpb.Dataset, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*automlpb.Dataset), nil } func (s *mockAutoMlServer) GetDataset(ctx context.Context, req *automlpb.GetDatasetRequest) (*automlpb.Dataset, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*automlpb.Dataset), nil } func (s *mockAutoMlServer) ListDatasets(ctx context.Context, req *automlpb.ListDatasetsRequest) (*automlpb.ListDatasetsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*automlpb.ListDatasetsResponse), nil } func (s *mockAutoMlServer) UpdateDataset(ctx context.Context, req *automlpb.UpdateDatasetRequest) (*automlpb.Dataset, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*automlpb.Dataset), nil } func (s *mockAutoMlServer) DeleteDataset(ctx context.Context, req *automlpb.DeleteDatasetRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockAutoMlServer) ImportData(ctx context.Context, req *automlpb.ImportDataRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockAutoMlServer) ExportData(ctx context.Context, req *automlpb.ExportDataRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockAutoMlServer) GetAnnotationSpec(ctx context.Context, req *automlpb.GetAnnotationSpecRequest) (*automlpb.AnnotationSpec, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*automlpb.AnnotationSpec), nil } func (s *mockAutoMlServer) GetTableSpec(ctx context.Context, req *automlpb.GetTableSpecRequest) (*automlpb.TableSpec, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*automlpb.TableSpec), nil } func (s *mockAutoMlServer) ListTableSpecs(ctx context.Context, req *automlpb.ListTableSpecsRequest) (*automlpb.ListTableSpecsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*automlpb.ListTableSpecsResponse), nil } func (s *mockAutoMlServer) UpdateTableSpec(ctx context.Context, req *automlpb.UpdateTableSpecRequest) (*automlpb.TableSpec, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*automlpb.TableSpec), nil } func (s *mockAutoMlServer) GetColumnSpec(ctx context.Context, req *automlpb.GetColumnSpecRequest) (*automlpb.ColumnSpec, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*automlpb.ColumnSpec), nil } func (s *mockAutoMlServer) ListColumnSpecs(ctx context.Context, req *automlpb.ListColumnSpecsRequest) (*automlpb.ListColumnSpecsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*automlpb.ListColumnSpecsResponse), nil } func (s *mockAutoMlServer) UpdateColumnSpec(ctx context.Context, req *automlpb.UpdateColumnSpecRequest) (*automlpb.ColumnSpec, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*automlpb.ColumnSpec), nil } func (s *mockAutoMlServer) CreateModel(ctx context.Context, req *automlpb.CreateModelRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockAutoMlServer) GetModel(ctx context.Context, req *automlpb.GetModelRequest) (*automlpb.Model, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*automlpb.Model), nil } func (s *mockAutoMlServer) ListModels(ctx context.Context, req *automlpb.ListModelsRequest) (*automlpb.ListModelsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*automlpb.ListModelsResponse), nil } func (s *mockAutoMlServer) DeleteModel(ctx context.Context, req *automlpb.DeleteModelRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockAutoMlServer) DeployModel(ctx context.Context, req *automlpb.DeployModelRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockAutoMlServer) UndeployModel(ctx context.Context, req *automlpb.UndeployModelRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockAutoMlServer) ExportModel(ctx context.Context, req *automlpb.ExportModelRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockAutoMlServer) ExportEvaluatedExamples(ctx context.Context, req *automlpb.ExportEvaluatedExamplesRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockAutoMlServer) GetModelEvaluation(ctx context.Context, req *automlpb.GetModelEvaluationRequest) (*automlpb.ModelEvaluation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*automlpb.ModelEvaluation), nil } func (s *mockAutoMlServer) ListModelEvaluations(ctx context.Context, req *automlpb.ListModelEvaluationsRequest) (*automlpb.ListModelEvaluationsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*automlpb.ListModelEvaluationsResponse), nil } type mockPredictionServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. automlpb.PredictionServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockPredictionServer) Predict(ctx context.Context, req *automlpb.PredictRequest) (*automlpb.PredictResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*automlpb.PredictResponse), nil } func (s *mockPredictionServer) BatchPredict(ctx context.Context, req *automlpb.BatchPredictRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockAutoMl mockAutoMlServer mockPrediction mockPredictionServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() automlpb.RegisterAutoMlServer(serv, &mockAutoMl) automlpb.RegisterPredictionServiceServer(serv, &mockPrediction) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestAutoMlCreateDataset(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var description string = "description-1724546052" var exampleCount int32 = 1517063674 var etag string = "etag3123477" var expectedResponse = &automlpb.Dataset{ Name: name, DisplayName: displayName, Description: description, ExampleCount: exampleCount, Etag: etag, } mockAutoMl.err = nil mockAutoMl.reqs = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var dataset *automlpb.Dataset = &automlpb.Dataset{} var request = &automlpb.CreateDatasetRequest{ Parent: formattedParent, Dataset: dataset, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateDataset(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAutoMlCreateDatasetError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var dataset *automlpb.Dataset = &automlpb.Dataset{} var request = &automlpb.CreateDatasetRequest{ Parent: formattedParent, Dataset: dataset, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateDataset(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAutoMlUpdateDataset(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var description string = "description-1724546052" var exampleCount int32 = 1517063674 var etag string = "etag3123477" var expectedResponse = &automlpb.Dataset{ Name: name, DisplayName: displayName, Description: description, ExampleCount: exampleCount, Etag: etag, } mockAutoMl.err = nil mockAutoMl.reqs = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], expectedResponse) var dataset *automlpb.Dataset = &automlpb.Dataset{} var request = &automlpb.UpdateDatasetRequest{ Dataset: dataset, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateDataset(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAutoMlUpdateDatasetError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = gstatus.Error(errCode, "test error") var dataset *automlpb.Dataset = &automlpb.Dataset{} var request = &automlpb.UpdateDatasetRequest{ Dataset: dataset, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateDataset(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAutoMlGetDataset(t *testing.T) { var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var description string = "description-1724546052" var exampleCount int32 = 1517063674 var etag string = "etag3123477" var expectedResponse = &automlpb.Dataset{ Name: name2, DisplayName: displayName, Description: description, ExampleCount: exampleCount, Etag: etag, } mockAutoMl.err = nil mockAutoMl.reqs = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/datasets/%s", "[PROJECT]", "[LOCATION]", "[DATASET]") var request = &automlpb.GetDatasetRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetDataset(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAutoMlGetDatasetError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/datasets/%s", "[PROJECT]", "[LOCATION]", "[DATASET]") var request = &automlpb.GetDatasetRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetDataset(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAutoMlListDatasets(t *testing.T) { var nextPageToken string = "" var datasetsElement *automlpb.Dataset = &automlpb.Dataset{} var datasets = []*automlpb.Dataset{datasetsElement} var expectedResponse = &automlpb.ListDatasetsResponse{ NextPageToken: nextPageToken, Datasets: datasets, } mockAutoMl.err = nil mockAutoMl.reqs = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &automlpb.ListDatasetsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListDatasets(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Datasets[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAutoMlListDatasetsError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &automlpb.ListDatasetsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListDatasets(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAutoMlDeleteDataset(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockAutoMl.err = nil mockAutoMl.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockAutoMl.resps = append(mockAutoMl.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/datasets/%s", "[PROJECT]", "[LOCATION]", "[DATASET]") var request = &automlpb.DeleteDatasetRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.DeleteDataset(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestAutoMlDeleteDatasetError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/datasets/%s", "[PROJECT]", "[LOCATION]", "[DATASET]") var request = &automlpb.DeleteDatasetRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.DeleteDataset(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestAutoMlImportData(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockAutoMl.err = nil mockAutoMl.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockAutoMl.resps = append(mockAutoMl.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/datasets/%s", "[PROJECT]", "[LOCATION]", "[DATASET]") var inputConfig *automlpb.InputConfig = &automlpb.InputConfig{} var request = &automlpb.ImportDataRequest{ Name: formattedName, InputConfig: inputConfig, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.ImportData(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestAutoMlImportDataError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/datasets/%s", "[PROJECT]", "[LOCATION]", "[DATASET]") var inputConfig *automlpb.InputConfig = &automlpb.InputConfig{} var request = &automlpb.ImportDataRequest{ Name: formattedName, InputConfig: inputConfig, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.ImportData(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestAutoMlExportData(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockAutoMl.err = nil mockAutoMl.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockAutoMl.resps = append(mockAutoMl.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/datasets/%s", "[PROJECT]", "[LOCATION]", "[DATASET]") var outputConfig *automlpb.OutputConfig = &automlpb.OutputConfig{} var request = &automlpb.ExportDataRequest{ Name: formattedName, OutputConfig: outputConfig, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.ExportData(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestAutoMlExportDataError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/datasets/%s", "[PROJECT]", "[LOCATION]", "[DATASET]") var outputConfig *automlpb.OutputConfig = &automlpb.OutputConfig{} var request = &automlpb.ExportDataRequest{ Name: formattedName, OutputConfig: outputConfig, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.ExportData(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestAutoMlCreateModel(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var datasetId string = "datasetId-2115646910" var expectedResponse = &automlpb.Model{ Name: name, DisplayName: displayName, DatasetId: datasetId, } mockAutoMl.err = nil mockAutoMl.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockAutoMl.resps = append(mockAutoMl.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var model *automlpb.Model = &automlpb.Model{} var request = &automlpb.CreateModelRequest{ Parent: formattedParent, Model: model, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.CreateModel(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAutoMlCreateModelError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var model *automlpb.Model = &automlpb.Model{} var request = &automlpb.CreateModelRequest{ Parent: formattedParent, Model: model, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.CreateModel(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAutoMlGetModel(t *testing.T) { var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var datasetId string = "datasetId-2115646910" var expectedResponse = &automlpb.Model{ Name: name2, DisplayName: displayName, DatasetId: datasetId, } mockAutoMl.err = nil mockAutoMl.reqs = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/models/%s", "[PROJECT]", "[LOCATION]", "[MODEL]") var request = &automlpb.GetModelRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetModel(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAutoMlGetModelError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/models/%s", "[PROJECT]", "[LOCATION]", "[MODEL]") var request = &automlpb.GetModelRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetModel(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAutoMlListModels(t *testing.T) { var nextPageToken string = "" var modelElement *automlpb.Model = &automlpb.Model{} var model = []*automlpb.Model{modelElement} var expectedResponse = &automlpb.ListModelsResponse{ NextPageToken: nextPageToken, Model: model, } mockAutoMl.err = nil mockAutoMl.reqs = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &automlpb.ListModelsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListModels(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Model[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAutoMlListModelsError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &automlpb.ListModelsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListModels(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAutoMlDeleteModel(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockAutoMl.err = nil mockAutoMl.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockAutoMl.resps = append(mockAutoMl.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/models/%s", "[PROJECT]", "[LOCATION]", "[MODEL]") var request = &automlpb.DeleteModelRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.DeleteModel(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestAutoMlDeleteModelError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/models/%s", "[PROJECT]", "[LOCATION]", "[MODEL]") var request = &automlpb.DeleteModelRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.DeleteModel(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestAutoMlDeployModel(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockAutoMl.err = nil mockAutoMl.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockAutoMl.resps = append(mockAutoMl.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/models/%s", "[PROJECT]", "[LOCATION]", "[MODEL]") var request = &automlpb.DeployModelRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.DeployModel(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestAutoMlDeployModelError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/models/%s", "[PROJECT]", "[LOCATION]", "[MODEL]") var request = &automlpb.DeployModelRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.DeployModel(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestAutoMlUndeployModel(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockAutoMl.err = nil mockAutoMl.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockAutoMl.resps = append(mockAutoMl.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/models/%s", "[PROJECT]", "[LOCATION]", "[MODEL]") var request = &automlpb.UndeployModelRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.UndeployModel(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestAutoMlUndeployModelError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/models/%s", "[PROJECT]", "[LOCATION]", "[MODEL]") var request = &automlpb.UndeployModelRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.UndeployModel(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestAutoMlGetModelEvaluation(t *testing.T) { var name2 string = "name2-1052831874" var annotationSpecId string = "annotationSpecId60690191" var displayName string = "displayName1615086568" var evaluatedExampleCount int32 = 277565350 var expectedResponse = &automlpb.ModelEvaluation{ Name: name2, AnnotationSpecId: annotationSpecId, DisplayName: displayName, EvaluatedExampleCount: evaluatedExampleCount, } mockAutoMl.err = nil mockAutoMl.reqs = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/models/%s/modelEvaluations/%s", "[PROJECT]", "[LOCATION]", "[MODEL]", "[MODEL_EVALUATION]") var request = &automlpb.GetModelEvaluationRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetModelEvaluation(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAutoMlGetModelEvaluationError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/models/%s/modelEvaluations/%s", "[PROJECT]", "[LOCATION]", "[MODEL]", "[MODEL_EVALUATION]") var request = &automlpb.GetModelEvaluationRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetModelEvaluation(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAutoMlExportModel(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockAutoMl.err = nil mockAutoMl.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockAutoMl.resps = append(mockAutoMl.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/models/%s", "[PROJECT]", "[LOCATION]", "[MODEL]") var outputConfig *automlpb.ModelExportOutputConfig = &automlpb.ModelExportOutputConfig{} var request = &automlpb.ExportModelRequest{ Name: formattedName, OutputConfig: outputConfig, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.ExportModel(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestAutoMlExportModelError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/models/%s", "[PROJECT]", "[LOCATION]", "[MODEL]") var outputConfig *automlpb.ModelExportOutputConfig = &automlpb.ModelExportOutputConfig{} var request = &automlpb.ExportModelRequest{ Name: formattedName, OutputConfig: outputConfig, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.ExportModel(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestAutoMlExportEvaluatedExamples(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockAutoMl.err = nil mockAutoMl.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockAutoMl.resps = append(mockAutoMl.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/models/%s", "[PROJECT]", "[LOCATION]", "[MODEL]") var outputConfig *automlpb.ExportEvaluatedExamplesOutputConfig = &automlpb.ExportEvaluatedExamplesOutputConfig{} var request = &automlpb.ExportEvaluatedExamplesRequest{ Name: formattedName, OutputConfig: outputConfig, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.ExportEvaluatedExamples(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestAutoMlExportEvaluatedExamplesError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/models/%s", "[PROJECT]", "[LOCATION]", "[MODEL]") var outputConfig *automlpb.ExportEvaluatedExamplesOutputConfig = &automlpb.ExportEvaluatedExamplesOutputConfig{} var request = &automlpb.ExportEvaluatedExamplesRequest{ Name: formattedName, OutputConfig: outputConfig, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.ExportEvaluatedExamples(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestAutoMlListModelEvaluations(t *testing.T) { var nextPageToken string = "" var modelEvaluationElement *automlpb.ModelEvaluation = &automlpb.ModelEvaluation{} var modelEvaluation = []*automlpb.ModelEvaluation{modelEvaluationElement} var expectedResponse = &automlpb.ListModelEvaluationsResponse{ NextPageToken: nextPageToken, ModelEvaluation: modelEvaluation, } mockAutoMl.err = nil mockAutoMl.reqs = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/models/%s", "[PROJECT]", "[LOCATION]", "[MODEL]") var request = &automlpb.ListModelEvaluationsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListModelEvaluations(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.ModelEvaluation[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAutoMlListModelEvaluationsError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/models/%s", "[PROJECT]", "[LOCATION]", "[MODEL]") var request = &automlpb.ListModelEvaluationsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListModelEvaluations(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAutoMlGetAnnotationSpec(t *testing.T) { var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var exampleCount int32 = 1517063674 var expectedResponse = &automlpb.AnnotationSpec{ Name: name2, DisplayName: displayName, ExampleCount: exampleCount, } mockAutoMl.err = nil mockAutoMl.reqs = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/datasets/%s/annotationSpecs/%s", "[PROJECT]", "[LOCATION]", "[DATASET]", "[ANNOTATION_SPEC]") var request = &automlpb.GetAnnotationSpecRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetAnnotationSpec(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAutoMlGetAnnotationSpecError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/datasets/%s/annotationSpecs/%s", "[PROJECT]", "[LOCATION]", "[DATASET]", "[ANNOTATION_SPEC]") var request = &automlpb.GetAnnotationSpecRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetAnnotationSpec(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAutoMlGetTableSpec(t *testing.T) { var name2 string = "name2-1052831874" var timeColumnSpecId string = "timeColumnSpecId1558734824" var rowCount int64 = 1340416618 var validRowCount int64 = 406068761 var columnCount int64 = 122671386 var etag string = "etag3123477" var expectedResponse = &automlpb.TableSpec{ Name: name2, TimeColumnSpecId: timeColumnSpecId, RowCount: rowCount, ValidRowCount: validRowCount, ColumnCount: columnCount, Etag: etag, } mockAutoMl.err = nil mockAutoMl.reqs = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/datasets/%s/tableSpecs/%s", "[PROJECT]", "[LOCATION]", "[DATASET]", "[TABLE_SPEC]") var request = &automlpb.GetTableSpecRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetTableSpec(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAutoMlGetTableSpecError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/datasets/%s/tableSpecs/%s", "[PROJECT]", "[LOCATION]", "[DATASET]", "[TABLE_SPEC]") var request = &automlpb.GetTableSpecRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetTableSpec(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAutoMlListTableSpecs(t *testing.T) { var nextPageToken string = "" var tableSpecsElement *automlpb.TableSpec = &automlpb.TableSpec{} var tableSpecs = []*automlpb.TableSpec{tableSpecsElement} var expectedResponse = &automlpb.ListTableSpecsResponse{ NextPageToken: nextPageToken, TableSpecs: tableSpecs, } mockAutoMl.err = nil mockAutoMl.reqs = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/datasets/%s", "[PROJECT]", "[LOCATION]", "[DATASET]") var request = &automlpb.ListTableSpecsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListTableSpecs(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.TableSpecs[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAutoMlListTableSpecsError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/datasets/%s", "[PROJECT]", "[LOCATION]", "[DATASET]") var request = &automlpb.ListTableSpecsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListTableSpecs(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAutoMlUpdateTableSpec(t *testing.T) { var name string = "name3373707" var timeColumnSpecId string = "timeColumnSpecId1558734824" var rowCount int64 = 1340416618 var validRowCount int64 = 406068761 var columnCount int64 = 122671386 var etag string = "etag3123477" var expectedResponse = &automlpb.TableSpec{ Name: name, TimeColumnSpecId: timeColumnSpecId, RowCount: rowCount, ValidRowCount: validRowCount, ColumnCount: columnCount, Etag: etag, } mockAutoMl.err = nil mockAutoMl.reqs = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], expectedResponse) var tableSpec *automlpb.TableSpec = &automlpb.TableSpec{} var request = &automlpb.UpdateTableSpecRequest{ TableSpec: tableSpec, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateTableSpec(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAutoMlUpdateTableSpecError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = gstatus.Error(errCode, "test error") var tableSpec *automlpb.TableSpec = &automlpb.TableSpec{} var request = &automlpb.UpdateTableSpecRequest{ TableSpec: tableSpec, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateTableSpec(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAutoMlGetColumnSpec(t *testing.T) { var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var etag string = "etag3123477" var expectedResponse = &automlpb.ColumnSpec{ Name: name2, DisplayName: displayName, Etag: etag, } mockAutoMl.err = nil mockAutoMl.reqs = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/datasets/%s/tableSpecs/%s/columnSpecs/%s", "[PROJECT]", "[LOCATION]", "[DATASET]", "[TABLE_SPEC]", "[COLUMN_SPEC]") var request = &automlpb.GetColumnSpecRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetColumnSpec(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAutoMlGetColumnSpecError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/datasets/%s/tableSpecs/%s/columnSpecs/%s", "[PROJECT]", "[LOCATION]", "[DATASET]", "[TABLE_SPEC]", "[COLUMN_SPEC]") var request = &automlpb.GetColumnSpecRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetColumnSpec(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAutoMlListColumnSpecs(t *testing.T) { var nextPageToken string = "" var columnSpecsElement *automlpb.ColumnSpec = &automlpb.ColumnSpec{} var columnSpecs = []*automlpb.ColumnSpec{columnSpecsElement} var expectedResponse = &automlpb.ListColumnSpecsResponse{ NextPageToken: nextPageToken, ColumnSpecs: columnSpecs, } mockAutoMl.err = nil mockAutoMl.reqs = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/datasets/%s/tableSpecs/%s", "[PROJECT]", "[LOCATION]", "[DATASET]", "[TABLE_SPEC]") var request = &automlpb.ListColumnSpecsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListColumnSpecs(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.ColumnSpecs[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAutoMlListColumnSpecsError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/datasets/%s/tableSpecs/%s", "[PROJECT]", "[LOCATION]", "[DATASET]", "[TABLE_SPEC]") var request = &automlpb.ListColumnSpecsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListColumnSpecs(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAutoMlUpdateColumnSpec(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var etag string = "etag3123477" var expectedResponse = &automlpb.ColumnSpec{ Name: name, DisplayName: displayName, Etag: etag, } mockAutoMl.err = nil mockAutoMl.reqs = nil mockAutoMl.resps = append(mockAutoMl.resps[:0], expectedResponse) var columnSpec *automlpb.ColumnSpec = &automlpb.ColumnSpec{} var request = &automlpb.UpdateColumnSpecRequest{ ColumnSpec: columnSpec, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateColumnSpec(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockAutoMl.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAutoMlUpdateColumnSpecError(t *testing.T) { errCode := codes.PermissionDenied mockAutoMl.err = gstatus.Error(errCode, "test error") var columnSpec *automlpb.ColumnSpec = &automlpb.ColumnSpec{} var request = &automlpb.UpdateColumnSpecRequest{ ColumnSpec: columnSpec, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateColumnSpec(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestPredictionServicePredict(t *testing.T) { var expectedResponse *automlpb.PredictResponse = &automlpb.PredictResponse{} mockPrediction.err = nil mockPrediction.reqs = nil mockPrediction.resps = append(mockPrediction.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/models/%s", "[PROJECT]", "[LOCATION]", "[MODEL]") var payload *automlpb.ExamplePayload = &automlpb.ExamplePayload{} var request = &automlpb.PredictRequest{ Name: formattedName, Payload: payload, } c, err := NewPredictionClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Predict(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockPrediction.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestPredictionServicePredictError(t *testing.T) { errCode := codes.PermissionDenied mockPrediction.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/models/%s", "[PROJECT]", "[LOCATION]", "[MODEL]") var payload *automlpb.ExamplePayload = &automlpb.ExamplePayload{} var request = &automlpb.PredictRequest{ Name: formattedName, Payload: payload, } c, err := NewPredictionClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Predict(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestPredictionServiceBatchPredict(t *testing.T) { var expectedResponse *automlpb.BatchPredictResult = &automlpb.BatchPredictResult{} mockPrediction.err = nil mockPrediction.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockPrediction.resps = append(mockPrediction.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/models/%s", "[PROJECT]", "[LOCATION]", "[MODEL]") var inputConfig *automlpb.BatchPredictInputConfig = &automlpb.BatchPredictInputConfig{} var outputConfig *automlpb.BatchPredictOutputConfig = &automlpb.BatchPredictOutputConfig{} var request = &automlpb.BatchPredictRequest{ Name: formattedName, InputConfig: inputConfig, OutputConfig: outputConfig, } c, err := NewPredictionClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.BatchPredict(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockPrediction.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestPredictionServiceBatchPredictError(t *testing.T) { errCode := codes.PermissionDenied mockPrediction.err = nil mockPrediction.resps = append(mockPrediction.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/models/%s", "[PROJECT]", "[LOCATION]", "[MODEL]") var inputConfig *automlpb.BatchPredictInputConfig = &automlpb.BatchPredictInputConfig{} var outputConfig *automlpb.BatchPredictOutputConfig = &automlpb.BatchPredictOutputConfig{} var request = &automlpb.BatchPredictRequest{ Name: formattedName, InputConfig: inputConfig, OutputConfig: outputConfig, } c, err := NewPredictionClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.BatchPredict(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/automl/apiv1beta1/prediction_client.go000066400000000000000000000245521356504100700240630ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package automl import ( "context" "fmt" "math" "net/url" "time" "cloud.google.com/go/longrunning" lroauto "cloud.google.com/go/longrunning/autogen" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" "google.golang.org/api/transport" automlpb "google.golang.org/genproto/googleapis/cloud/automl/v1beta1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" "google.golang.org/grpc" "google.golang.org/grpc/metadata" ) // PredictionCallOptions contains the retry settings for each method of PredictionClient. type PredictionCallOptions struct { Predict []gax.CallOption BatchPredict []gax.CallOption } func defaultPredictionClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("automl.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultPredictionCallOptions() *PredictionCallOptions { retry := map[[2]string][]gax.CallOption{} return &PredictionCallOptions{ Predict: retry[[2]string{"default", "non_idempotent"}], BatchPredict: retry[[2]string{"default", "non_idempotent"}], } } // PredictionClient is a client for interacting with Cloud AutoML API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type PredictionClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. predictionClient automlpb.PredictionServiceClient // LROClient is used internally to handle longrunning operations. // It is exposed so that its CallOptions can be modified if required. // Users should not Close this client. LROClient *lroauto.OperationsClient // The call options for this service. CallOptions *PredictionCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewPredictionClient creates a new prediction service client. // // AutoML Prediction API. // // On any input that is documented to expect a string parameter in // snake_case or kebab-case, either of those cases is accepted. func NewPredictionClient(ctx context.Context, opts ...option.ClientOption) (*PredictionClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultPredictionClientOptions(), opts...)...) if err != nil { return nil, err } c := &PredictionClient{ conn: conn, CallOptions: defaultPredictionCallOptions(), predictionClient: automlpb.NewPredictionServiceClient(conn), } c.setGoogleClientInfo() c.LROClient, err = lroauto.NewOperationsClient(ctx, option.WithGRPCConn(conn)) if err != nil { // This error "should not happen", since we are just reusing old connection // and never actually need to dial. // If this does happen, we could leak conn. However, we cannot close conn: // If the user invoked the function with option.WithGRPCConn, // we would close a connection that's still in use. // TODO(pongad): investigate error conditions. return nil, err } return c, nil } // Connection returns the client's connection to the API service. func (c *PredictionClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *PredictionClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *PredictionClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // Predict perform an online prediction. The prediction result will be directly // returned in the response. // Available for following ML problems, and their expected request payloads: // // Image Classification - Image in .JPEG, .GIF or .PNG format, image_bytes // up to 30MB. // // Image Object Detection - Image in .JPEG, .GIF or .PNG format, image_bytes // up to 30MB. // // Text Classification - TextSnippet, content up to 60,000 characters, // UTF-8 encoded. // // Text Extraction - TextSnippet, content up to 30,000 characters, // UTF-8 NFC encoded. // // Translation - TextSnippet, content up to 25,000 characters, UTF-8 // encoded. // // Tables - Row, with column values matching the columns of the model, // up to 5MB. Not available for FORECASTING // // [prediction_type][google.cloud.automl.v1beta1.TablesModelMetadata.prediction_type]. // // Text Sentiment - TextSnippet, content up 500 characters, UTF-8 // encoded. func (c *PredictionClient) Predict(ctx context.Context, req *automlpb.PredictRequest, opts ...gax.CallOption) (*automlpb.PredictResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.Predict[0:len(c.CallOptions.Predict):len(c.CallOptions.Predict)], opts...) var resp *automlpb.PredictResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.predictionClient.Predict(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // BatchPredict perform a batch prediction. Unlike the online // [Predict][google.cloud.automl.v1beta1.PredictionService.Predict], batch // prediction result won't be immediately available in the response. Instead, // a long running operation object is returned. User can poll the operation // result via [GetOperation][google.longrunning.Operations.GetOperation] // method. Once the operation is done, // [BatchPredictResult][google.cloud.automl.v1beta1.BatchPredictResult] is // returned in the [response][google.longrunning.Operation.response] field. // Available for following ML problems: // // Image Classification // // Image Object Detection // // Video Classification // // Video Object Tracking * Text Extraction // // Tables func (c *PredictionClient) BatchPredict(ctx context.Context, req *automlpb.BatchPredictRequest, opts ...gax.CallOption) (*BatchPredictOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.BatchPredict[0:len(c.CallOptions.BatchPredict):len(c.CallOptions.BatchPredict)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.predictionClient.BatchPredict(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &BatchPredictOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // BatchPredictOperation manages a long-running operation from BatchPredict. type BatchPredictOperation struct { lro *longrunning.Operation } // BatchPredictOperation returns a new BatchPredictOperation from a given name. // The name must be that of a previously created BatchPredictOperation, possibly from a different process. func (c *PredictionClient) BatchPredictOperation(name string) *BatchPredictOperation { return &BatchPredictOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *BatchPredictOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*automlpb.BatchPredictResult, error) { var resp automlpb.BatchPredictResult if err := op.lro.WaitWithInterval(ctx, &resp, 5000*time.Millisecond, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *BatchPredictOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*automlpb.BatchPredictResult, error) { var resp automlpb.BatchPredictResult if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *BatchPredictOperation) Metadata() (*automlpb.OperationMetadata, error) { var meta automlpb.OperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *BatchPredictOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *BatchPredictOperation) Name() string { return op.lro.Name() } google-cloud-go-0.49.0/automl/apiv1beta1/prediction_client_example_test.go000066400000000000000000000033511356504100700266270ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package automl_test import ( "context" automl "cloud.google.com/go/automl/apiv1beta1" automlpb "google.golang.org/genproto/googleapis/cloud/automl/v1beta1" ) func ExampleNewPredictionClient() { ctx := context.Background() c, err := automl.NewPredictionClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExamplePredictionClient_Predict() { ctx := context.Background() c, err := automl.NewPredictionClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.PredictRequest{ // TODO: Fill request struct fields. } resp, err := c.Predict(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExamplePredictionClient_BatchPredict() { ctx := context.Background() c, err := automl.NewPredictionClient(ctx) if err != nil { // TODO: Handle error. } req := &automlpb.BatchPredictRequest{ // TODO: Fill request struct fields. } op, err := c.BatchPredict(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/bigquery/000077500000000000000000000000001356504100700164175ustar00rootroot00000000000000google-cloud-go-0.49.0/bigquery/.repo-metadata.json000066400000000000000000000006051356504100700221140ustar00rootroot00000000000000{ "name": "bigquery", "name_pretty": "BigQuery", "product_documentation": "https://cloud.google.com/bigquery", "client_documentation": "https://godoc.org/cloud.google.com/go/bigquery", "release_level": "ga", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go/bigquery", "api_id": "bigquery:v2", "requires_billing": true } google-cloud-go-0.49.0/bigquery/CHANGES.md000066400000000000000000000023661356504100700200200ustar00rootroot00000000000000# Changes ## v1.3.0 * Add Description field for Routine entities. * Add support for iamMember entities on dataset ACLs. * Address issue when constructing a Pager from a RowIterator that referenced a result with zero result rows. * Add support for integer range partitioning, which affects table creation directly and via query/load jobs. * Add opt-out support for streaming inserts via experimental `NoDedupeID` sentinel. ## v1.2.0 * Adds support for scripting feature, which includes script statistics and the ability to list jobs run as part of a script query. * Updates default endpoint for BigQuery from www.googleapis.com to bigquery.googleapis.com. ## v1.1.0 * Added support for specifying default `EncryptionConfig` settings on the dataset. * Added support for `EncyptionConfig` as part of an ML model. * Added `Relax()` to make all fields within a `Schema` nullable. * Added a `UseAvroLogicalTypes` option when defining an avro extract job. ## v1.0.1 This patch release is a small fix to the go.mod to point to the post-carve out cloud.google.com/go. ## v1.0.0 This is the first tag to carve out bigquery as its own module. See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository. google-cloud-go-0.49.0/bigquery/README.md000066400000000000000000000022371356504100700177020ustar00rootroot00000000000000## BigQuery [![GoDoc](https://godoc.org/cloud.google.com/go/bigquery?status.svg)](https://godoc.org/cloud.google.com/go/bigquery) - [About BigQuery](https://cloud.google.com/bigquery/) - [API documentation](https://cloud.google.com/bigquery/docs) - [Go client documentation](https://godoc.org/cloud.google.com/go/bigquery) - [Complete sample programs](https://github.com/GoogleCloudPlatform/golang-samples/tree/master/bigquery) ### Example Usage First create a `bigquery.Client` to use throughout your application: [snip]:# (bq-1) ```go c, err := bigquery.NewClient(ctx, "my-project-ID") if err != nil { // TODO: Handle error. } ``` Then use that client to interact with the API: [snip]:# (bq-2) ```go // Construct a query. q := c.Query(` SELECT year, SUM(number) FROM [bigquery-public-data:usa_names.usa_1910_2013] WHERE name = "William" GROUP BY year ORDER BY year `) // Execute the query. it, err := q.Read(ctx) if err != nil { // TODO: Handle error. } // Iterate through the results. for { var values []bigquery.Value err := it.Next(&values) if err == iterator.Done { break } if err != nil { // TODO: Handle error. } fmt.Println(values) } ```google-cloud-go-0.49.0/bigquery/benchmarks/000077500000000000000000000000001356504100700205345ustar00rootroot00000000000000google-cloud-go-0.49.0/bigquery/benchmarks/README.md000066400000000000000000000003731356504100700220160ustar00rootroot00000000000000# BigQuery Benchmark This directory contains benchmarks for BigQuery client. ## Usage `go run bench.go -- queries.json` BigQuery service caches requests so the benchmark should be run at least twice, disregarding the first result. google-cloud-go-0.49.0/bigquery/benchmarks/bench.go000066400000000000000000000035351356504100700221500ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //+build ignore package main import ( "context" "encoding/json" "flag" "io/ioutil" "log" "time" "cloud.google.com/go/bigquery" "google.golang.org/api/iterator" ) func main() { flag.Parse() ctx := context.Background() c, err := bigquery.NewClient(ctx, flag.Arg(0)) if err != nil { log.Fatal(err) } queriesJSON, err := ioutil.ReadFile(flag.Arg(1)) if err != nil { log.Fatal(err) } var queries []string if err := json.Unmarshal(queriesJSON, &queries); err != nil { log.Fatal(err) } for _, q := range queries { doQuery(ctx, c, q) } } func doQuery(ctx context.Context, c *bigquery.Client, qt string) { startTime := time.Now() q := c.Query(qt) it, err := q.Read(ctx) if err != nil { log.Fatal(err) } numRows, numCols := 0, 0 var firstByte time.Duration for { var values []bigquery.Value err := it.Next(&values) if err == iterator.Done { break } if err != nil { log.Fatal(err) } if numRows == 0 { numCols = len(values) firstByte = time.Since(startTime) } else if numCols != len(values) { log.Fatalf("got %d columns, want %d", len(values), numCols) } numRows++ } log.Printf("query %q: %d rows, %d cols, first byte %f sec, total %f sec", qt, numRows, numCols, firstByte.Seconds(), time.Since(startTime).Seconds()) } google-cloud-go-0.49.0/bigquery/benchmarks/queries.json000066400000000000000000000013401356504100700231020ustar00rootroot00000000000000[ "SELECT * FROM `nyc-tlc.yellow.trips` LIMIT 10000", "SELECT * FROM `nyc-tlc.yellow.trips` LIMIT 100000", "SELECT * FROM `nyc-tlc.yellow.trips` LIMIT 1000000", "SELECT title FROM `bigquery-public-data.samples.wikipedia` ORDER BY title LIMIT 1000", "SELECT title, id, timestamp, contributor_ip FROM `bigquery-public-data.samples.wikipedia` WHERE title like 'Blo%' ORDER BY id", "SELECT * FROM `bigquery-public-data.baseball.games_post_wide` ORDER BY gameId", "SELECT * FROM `bigquery-public-data.samples.github_nested` WHERE repository.has_downloads ORDER BY repository.created_at LIMIT 10000", "SELECT repo_name, path FROM `bigquery-public-data.github_repos.files` WHERE path LIKE '%.java' ORDER BY id LIMIT 1000000" ] google-cloud-go-0.49.0/bigquery/bigquery.go000066400000000000000000000114111356504100700205730ustar00rootroot00000000000000// Copyright 2015 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "context" "fmt" "io" "net/http" "time" "cloud.google.com/go/internal" "cloud.google.com/go/internal/version" gax "github.com/googleapis/gax-go/v2" bq "google.golang.org/api/bigquery/v2" "google.golang.org/api/googleapi" "google.golang.org/api/option" ) const ( // Scope is the Oauth2 scope for the service. // For relevant BigQuery scopes, see: // https://developers.google.com/identity/protocols/googlescopes#bigqueryv2 Scope = "https://www.googleapis.com/auth/bigquery" userAgentPrefix = "gcloud-golang-bigquery" ) var xGoogHeader = fmt.Sprintf("gl-go/%s gccl/%s", version.Go(), version.Repo) func setClientHeader(headers http.Header) { headers.Set("x-goog-api-client", xGoogHeader) } // Client may be used to perform BigQuery operations. type Client struct { // Location, if set, will be used as the default location for all subsequent // dataset creation and job operations. A location specified directly in one of // those operations will override this value. Location string projectID string bqs *bq.Service } // NewClient constructs a new Client which can perform BigQuery operations. // Operations performed via the client are billed to the specified GCP project. func NewClient(ctx context.Context, projectID string, opts ...option.ClientOption) (*Client, error) { o := []option.ClientOption{ option.WithScopes(Scope), option.WithUserAgent(fmt.Sprintf("%s/%s", userAgentPrefix, version.Repo)), } o = append(o, opts...) bqs, err := bq.NewService(ctx, o...) if err != nil { return nil, fmt.Errorf("bigquery: constructing client: %v", err) } c := &Client{ projectID: projectID, bqs: bqs, } return c, nil } // Close closes any resources held by the client. // Close should be called when the client is no longer needed. // It need not be called at program exit. func (c *Client) Close() error { return nil } // Calls the Jobs.Insert RPC and returns a Job. func (c *Client) insertJob(ctx context.Context, job *bq.Job, media io.Reader) (*Job, error) { call := c.bqs.Jobs.Insert(c.projectID, job).Context(ctx) setClientHeader(call.Header()) if media != nil { call.Media(media) } var res *bq.Job var err error invoke := func() error { res, err = call.Do() return err } // A job with a client-generated ID can be retried; the presence of the // ID makes the insert operation idempotent. // We don't retry if there is media, because it is an io.Reader. We'd // have to read the contents and keep it in memory, and that could be expensive. // TODO(jba): Look into retrying if media != nil. if job.JobReference != nil && media == nil { err = runWithRetry(ctx, invoke) } else { err = invoke() } if err != nil { return nil, err } return bqToJob(res, c) } // Convert a number of milliseconds since the Unix epoch to a time.Time. // Treat an input of zero specially: convert it to the zero time, // rather than the start of the epoch. func unixMillisToTime(m int64) time.Time { if m == 0 { return time.Time{} } return time.Unix(0, m*1e6) } // runWithRetry calls the function until it returns nil or a non-retryable error, or // the context is done. // See the similar function in ../storage/invoke.go. The main difference is the // reason for retrying. func runWithRetry(ctx context.Context, call func() error) error { // These parameters match the suggestions in https://cloud.google.com/bigquery/sla. backoff := gax.Backoff{ Initial: 1 * time.Second, Max: 32 * time.Second, Multiplier: 2, } return internal.Retry(ctx, backoff, func() (stop bool, err error) { err = call() if err == nil { return true, nil } return !retryableError(err), err }) } // This is the correct definition of retryable according to the BigQuery team. It // also considers 502 ("Bad Gateway") and 503 ("Service Unavailable") errors // retryable; these are returned by systems between the client and the BigQuery // service. func retryableError(err error) bool { e, ok := err.(*googleapi.Error) if !ok { return false } var reason string if len(e.Errors) > 0 { reason = e.Errors[0].Reason } return e.Code == http.StatusServiceUnavailable || e.Code == http.StatusBadGateway || reason == "backendError" || reason == "rateLimitExceeded" } google-cloud-go-0.49.0/bigquery/bigquery.replay000066400000000000000000035007211356504100700214740ustar00rootroot00000000000000{ "Initial": "IjIwMTktMTAtMjhUMTg6MzU6MDYuNTkwMDkzNjU5WiI=", "Version": "0.2", "Converter": { "ClearHeaders": [ "^X-Goog-.*Encryption-Key$" ], "RemoveRequestHeaders": [ "^Authorization$", "^Proxy-Authorization$", "^Connection$", "^Content-Type$", "^Date$", "^Host$", "^Transfer-Encoding$", "^Via$", "^X-Forwarded-.*$", "^X-Cloud-Trace-Context$", "^X-Goog-Api-Client$", "^X-Google-.*$", "^X-Gfe-.*$" ], "RemoveResponseHeaders": [ "^X-Google-.*$", "^X-Gfe-.*$" ], "ClearParams": null, "RemoveParams": null }, "Entries": [ { "ID": "05a0f97b61e4f9bc", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "74" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJkYXRhc2V0UmVmZXJlbmNlIjp7ImRhdGFzZXRJZCI6ImRhdGFzZXRfMjAxOTEwMjhfNjY5MDY1OTAwOTM2NTlfMDAwMSJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:07 GMT" ], "Etag": [ "gs3AYtwXmh7aF/dUsSnjCA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42RbWvCMBSF/0v2VZu0vtQWhLnNDWEvUBU3xpCYXmu0TbokVUT870ulyj6o+Clwcs65T252aMVFjEI048lvAWp7F1NDNRhUQ2BoYm8S3eh9mc1ntvDpM47HeiiWj71u1zp4mdQLmabbjIp6DJmsG9AmrEqmHnEDl3idabsdkHYrICRo2GNKCHFtXkM6f+ViZVsWxuQ6xPjI4SRSJinQnGuHyeyk47WHcyWXwIzGZ0bjarTGNzJUtgjmoEAwQOHuqA3K591YUzENLmwE7WuIMgZao/B7h5RM7SA0iQajflQuIgfGafqiZJFbvSqbKG5AaZs9JT4m71cCHxtxwV9oUA/bfkZ5atWSqK7kTJr7M6wOp5mT2MCaM7DQshCm/IP/vVG/93QFJAIaH0h+aogpoIZLMeJZmXRbvud1fJ/4zWbTFqRUmzcZ8zmH+JJFskODvRoP0f4PCVPOULQCAAA=" } }, { "ID": "f0be3768141a8a07", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "210" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJleHBpcmF0aW9uVGltZSI6IjE1NzIyODg2MDcwMDAiLCJzY2hlbWEiOnsiZmllbGRzIjpbeyJuYW1lIjoicmVjIiwidHlwZSI6IlJFQ09SRCJ9XX0sInRhYmxlUmVmZXJlbmNlIjp7ImRhdGFzZXRJZCI6ImRhdGFzZXRfMjAxOTEwMjhfNjY5MDY1OTAwOTM2NTlfMDAwMSIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QiLCJ0YWJsZUlkIjoidF9iYWQifX0K" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:07 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6WOMQvCMBCF9/6KI7NDBye3YqsUtEJRFxFJm6MNpI3kUkFK/7tJzODudHz37r17cwLA0Bht2AZmBw5bLdDROk1X38WARLzzO7aTqAQYbEES2PcToS62pzqHZrLQc4JRA7U9DpxFcwgn570Fhvjl7+AQIPTA5ej9ndINV7+aQU46aHJ8cSUFi9oS5j32I8vt5PuxsrpmhzJ/ZPX+ciyqs79fkiX5AH4fDhokAQAA" } }, { "ID": "007350d4f29cb23a", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "366" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJleHBpcmF0aW9uVGltZSI6IjE1NzIyODgzMDcwMDAiLCJzY2hlbWEiOnsiZmllbGRzIjpbeyJuYW1lIjoibmFtZSIsInR5cGUiOiJTVFJJTkcifSx7Im1vZGUiOiJSRVBFQVRFRCIsIm5hbWUiOiJudW1zIiwidHlwZSI6IklOVEVHRVIifSx7ImZpZWxkcyI6W3sibmFtZSI6ImJvb2wiLCJ0eXBlIjoiQk9PTEVBTiJ9XSwibmFtZSI6InJlYyIsInR5cGUiOiJSRUNPUkQifV19LCJ0YWJsZVJlZmVyZW5jZSI6eyJkYXRhc2V0SWQiOiJkYXRhc2V0XzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDEiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0IiwidGFibGVJZCI6InRhYmxlXzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDEifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:08 GMT" ], "Etag": [ "xGHJs5vCc0GIeyRFDLpKQA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42Q3U7CQBCF32W9RXapgZYmXIBURCtoqVfGkKUdykrbrd1VaQjv7rSCNf6F7MVmzpwz82W2ZC3SkNhkIaLnF8iLE80XMZAGAc0j1DejyyvVfj0P2GgMhXcxdLPru36vhw5R5tRKxnGR8PQ0hESealDaDrnmCvTcYK1uixnWvNPpsk67y1j3DL85Y6zVrPb8a8EVCuKlK9I1LlppnSmb0gNoM5IyioFnQjUDmXzq9NWgWS6fINCK/kJH93SKHoNJK0xFj6KtTB4sIYc0AGJvyR5k/MelMLOHqBzHAB3WVIEjqHZ4xGAFCS9xlgLiUBH7YUtSniDhx4cji6ysZr43nowwU/dfElX3xxPfGTkeCokMS8Fzbp2+7wy/RnII6oTnnE+9IdY/Vy+kjGvjYDp1nf6E7B7xNcq9gwJPhB1GqtKVaeRD/l325NuhCnLgWsjUF9X8Vts0DMs0mWkZ5dlgk4n8p8E6YyZeCg0xV/pGhgJRw+8zLNYxali/P3CdMiGDaiBK9zOyewcC/my7TQMAAA==" } }, { "ID": "f84d1553f81296b8", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "311" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJ0YWJsZVJlZmVyZW5jZSI6eyJkYXRhc2V0SWQiOiJkYXRhc2V0XzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDEiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0IiwidGFibGVJZCI6InRfdmlld19zdGFuZGFyZHNxbCJ9LCJ2aWV3Ijp7InF1ZXJ5IjoiU0VMRUNUIEFQUFJPWF9DT1VOVF9ESVNUSU5DVChuYW1lKSBGUk9NIGBzaG9sbHltYW4tZGVtby10ZXN0LmRhdGFzZXRfMjAxOTEwMjhfNjY5MDY1OTAwOTM2NTlfMDAwMS50YWJsZV8yMDE5MTAyOF82NjkwNjU5MDA5MzY1OV8wMDAxYCIsInVzZUxlZ2FjeVNxbCI6ZmFsc2V9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:08 GMT" ], "Etag": [ "1a06HZtgBjvaM+E52VYphA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42SXY+aQBSG/4qZ3rRpVwY2KpLshVrakqBuELdfadhZOODsDjMsM7ohxv/eA9E2aW3jFTnv+XrOO+zJE5cZ8cgDL563UDevDHsQQN4RMKxA3WZ0+OmbKaaPOzZ/6w+cu6/VZnJzgxW87dMbJURTMnmVQamuDGjjZcwwDSZxqD22qeMmw+GYDgdjSsfX+EkopXbfJDsOL4k2TGaszvSzwJEaRB5y+YSDN8ZU2rOsE1i/UKoQwCqu+6kqf+nWzrGqWj1CarR1hsY60mjrEiyrO19bZ+m6XAQ51CBTIN6eHBcH/3ACe45Lu4pLAE5ruoYzFAc0Kd1Aydr1OQeRaeJ93xPJSiQiOU3aCU3VBsEi9j/6EQqlylphsQ7DyTT0yeEHzpHbctogJiYo6cJQySKG+k85Ui+nKK2BGa5kzLt19mDkOO5oRF3bdTEtmDZzlXEEy/4qubYHv9nuAv8zRu197SXdU6K88kN/Fvcmt7fR8ksyW64XcfI+WMXBYha/bm980/sQLee9+zNu9y/771p3/1tyj1xbDSEULG1W6LmXM6EBHRMq7a5H0PWKHH4CKQGoMj0DAAA=" } }, { "ID": "73dcf15f72046f29", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/t_view_standardsql?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:08 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6uuBQBDv6ajAgAAAA==" } }, { "ID": "8f7c14edaa1ce301", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0001?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:08 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6uuBQBDv6ajAgAAAA==" } }, { "ID": "de3d3e08c604b81c", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "366" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJleHBpcmF0aW9uVGltZSI6IjE1NzIyODgzMDcwMDAiLCJzY2hlbWEiOnsiZmllbGRzIjpbeyJuYW1lIjoibmFtZSIsInR5cGUiOiJTVFJJTkcifSx7Im1vZGUiOiJSRVBFQVRFRCIsIm5hbWUiOiJudW1zIiwidHlwZSI6IklOVEVHRVIifSx7ImZpZWxkcyI6W3sibmFtZSI6ImJvb2wiLCJ0eXBlIjoiQk9PTEVBTiJ9XSwibmFtZSI6InJlYyIsInR5cGUiOiJSRUNPUkQifV19LCJ0YWJsZVJlZmVyZW5jZSI6eyJkYXRhc2V0SWQiOiJkYXRhc2V0XzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDEiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0IiwidGFibGVJZCI6InRhYmxlXzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDIifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:08 GMT" ], "Etag": [ "Sqn5ZaQqM5uZ6kSzqV4eAw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42R3U7CQBCF32W9RXYpAm0TLkAbQ8KPttULjSFLO5SVtlu6i4qEd3dawRpRQ3qxmTPnzHyZbslSpCGxyUxEqzXkmzPNZzGQGgHNI9S9Vdp64LerUWv90F5676v7C+i9drvoEEVOLWQcbxKenoeQyHMNStsh11yBnhqsYTWYYU7bbYu1WxZjVhOfKWOsUS/3/GcxcIWCeD4U6RIXLbTOlE3pAbQeSRnFwDOh6oFMvnT6YtAsl88QaEV/oaN7OkVPwaQlpqIn0ZYmF+aQQxoAsbdkDzL441KY2UOUjlOADmvKwAlUOzxisICEFzhzAXGoiP24JSlPkPDzwZGbrKg83x2MrzFT9deJqvqDse9cOy4KiQwLwXVunJ7vXH2P5BBUCde5nLhXWB+vnkkZV8b+ZDJ0emOye8KvVuztb/BE2GGkLIcyjXzIf8qufD1UQQ5cC5n6opzfaHUMw+x0mGk2i78Db5nIjw1mk3XwUmiIudIjGQpEDY9mWAarYP1ef+gUCRmUA1G688juAygkJNdNAwAA" } }, { "ID": "25e7e6880f82d40d", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0002?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:09 GMT" ], "Etag": [ "Sqn5ZaQqM5uZ6kSzqV4eAw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42R3U7CQBCF32W9RXYpAm0TLkAbQ8KPttULjSFLO5SVtlu6i4qEd3dawRpRQ3qxmTPnzHyZbslSpCGxyUxEqzXkmzPNZzGQGgHNI9S9Vdp64LerUWv90F5676v7C+i9drvoEEVOLWQcbxKenoeQyHMNStsh11yBnhqsYTWYYU7bbYu1WxZjVhOfKWOsUS/3/GcxcIWCeD4U6RIXLbTOlE3pAbQeSRnFwDOh6oFMvnT6YtAsl88QaEV/oaN7OkVPwaQlpqIn0ZYmF+aQQxoAsbdkDzL441KY2UOUjlOADmvKwAlUOzxisICEFzhzAXGoiP24JSlPkPDzwZGbrKg83x2MrzFT9deJqvqDse9cOy4KiQwLwXVunJ7vXH2P5BBUCde5nLhXWB+vnkkZV8b+ZDJ0emOye8KvVuztb/BE2GGkLIcyjXzIf8qufD1UQQ5cC5n6opzfaHUMw+x0mGk2i78Db5nIjw1mk3XwUmiIudIjGQpEDY9mWAarYP1ef+gUCRmUA1G688juAygkJNdNAwAA" } }, { "ID": "949d602f771a3353", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "302" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJleHBpcmF0aW9uVGltZSI6IjE1NzIyODgzMDcwMDAiLCJzY2hlbWEiOnsiZmllbGRzIjpbeyJuYW1lIjoibmFtZSIsInR5cGUiOiJTVFJJTkcifSx7Im5hbWUiOiJkYXRlIiwidHlwZSI6IkRBVEUifV19LCJ0YWJsZVJlZmVyZW5jZSI6eyJkYXRhc2V0SWQiOiJkYXRhc2V0XzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDEiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0IiwidGFibGVJZCI6InRfbWV0YWRhdGFfcGFydGl0aW9uX25vY2x1c3Rlcl8wIn0sInRpbWVQYXJ0aXRpb25pbmciOnsidHlwZSI6IkRBWSJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:09 GMT" ], "Etag": [ "/9ZgIqtBre0gTvY495t1AA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42Sy07DMBBF/8VsoXZS+kgkFq1AqFJBqIRFQSgyyTQ1JHawp0BV9d8Zh7YgHqIra8Z37j0eecWelM5ZzB5U8bwAuzxA+VACO2SAsqA+j26L0TMOLYgieZkeRx0MBoOTE1IoP+fmpiyXldRHOVTmCMFhnEuUDjANRRAFIuyn3W4kup1IiKhNRyqECFqYVhThpWktLSpURqfaZOXCIdhUUICDcjZW+oli5oi1iznfYrYKY4oSZK1cKzPVrs9fQl5b8wgZOv4LG9+wOb4PJG+W4fgerI1yAjOwoDNg8YptMEZ/bIlmNgiNYh+cbUwz8C/TmhaYzaGSHmamoMwdi+9WTMuK+D4OMlzWvrpOJqPLc5rZ3ZPzl/vTQXLG1vfkiaqCq22g0oV334mmPlUvquGSnkgdvxkqx0YXCdjv7Yl53VaZBekNE9WEB51eGPZ7PRGF4th/xrda2Z+Cflv0aDEkKKXDC5Mremf+w6Mdis+XJIPh+MxPmKwxpNbNNVu/A063LnIJAwAA" } }, { "ID": "56b227398f0c30ea", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/t_metadata_partition_nocluster_0?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:09 GMT" ], "Etag": [ "/9ZgIqtBre0gTvY495t1AA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42Sy07DMBBF/8VsoXZS+kgkFq1AqFJBqIRFQSgyyTQ1JHawp0BV9d8Zh7YgHqIra8Z37j0eecWelM5ZzB5U8bwAuzxA+VACO2SAsqA+j26L0TMOLYgieZkeRx0MBoOTE1IoP+fmpiyXldRHOVTmCMFhnEuUDjANRRAFIuyn3W4kup1IiKhNRyqECFqYVhThpWktLSpURqfaZOXCIdhUUICDcjZW+oli5oi1iznfYrYKY4oSZK1cKzPVrs9fQl5b8wgZOv4LG9+wOb4PJG+W4fgerI1yAjOwoDNg8YptMEZ/bIlmNgiNYh+cbUwz8C/TmhaYzaGSHmamoMwdi+9WTMuK+D4OMlzWvrpOJqPLc5rZ3ZPzl/vTQXLG1vfkiaqCq22g0oV334mmPlUvquGSnkgdvxkqx0YXCdjv7Yl53VaZBekNE9WEB51eGPZ7PRGF4th/xrda2Z+Cflv0aDEkKKXDC5Mremf+w6Mdis+XJIPh+MxPmKwxpNbNNVu/A063LnIJAwAA" } }, { "ID": "4176229c3cdc06af", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "333" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjbHVzdGVyaW5nIjp7ImZpZWxkcyI6WyJuYW1lIl19LCJleHBpcmF0aW9uVGltZSI6IjE1NzIyODgzMDcwMDAiLCJzY2hlbWEiOnsiZmllbGRzIjpbeyJuYW1lIjoibmFtZSIsInR5cGUiOiJTVFJJTkcifSx7Im5hbWUiOiJkYXRlIiwidHlwZSI6IkRBVEUifV19LCJ0YWJsZVJlZmVyZW5jZSI6eyJkYXRhc2V0SWQiOiJkYXRhc2V0XzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDEiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0IiwidGFibGVJZCI6InRfbWV0YWRhdGFfcGFydGl0aW9uX2NsdXN0ZXJfMCJ9LCJ0aW1lUGFydGl0aW9uaW5nIjp7InR5cGUiOiJEQVkifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:09 GMT" ], "Etag": [ "yedqPy1Zkhz/hCIcO9Y15w==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42SXU/CMBSG/0u9FdrNwNgSLlCJIcGP4LxAQ5a6HbbK1o61qJPw3z0dHxo/oldNT9/znue86ZoshExIQB5FulxBVR8Z/pgDOSZgeIr1GpLlTe3cL7I3mp2N4mt/6nRe+n1UCNunM5XndcFlK4FCtQxoEyTccA0mcpnjO8ztRd2uz7odnzH/BI+IMea0TVTgCCuNSl4ZYYSSUZyvtIEqYmivIZ+PhVzgkMyYUgeU7iHbqVJpDrwUuh2r4lCnzy4tK/UEsdH0BzK6I9P0P4i0iULTP0kb3QTmUIGMgQRrsoMY/ZIQ9uwAGsV/YPZjmoY/iDYYXpxBwS3KXECeaBI8rInkBdJtD7SrS3u7DSejqwvsObyj76f380E4JJsZehpRwM1+nJCpdT+IpnaqXBWnNS6IFZsLXsdKpiFUX8sT9bK/xRVwaxiKZrjT8Vy353nM77qu/Yavpai+C3onzMNYUJBzbS5VInDP5JuH5/Y+NgkHp+Oh7VBxY4ilu1tLsA1ut9Ehr20cs83mHReJFo8kAwAA" } }, { "ID": "935482881ea36a18", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/t_metadata_partition_cluster_0?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:09 GMT" ], "Etag": [ "yedqPy1Zkhz/hCIcO9Y15w==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42SXU/CMBSG/0u9FdrNwNgSLlCJIcGP4LxAQ5a6HbbK1o61qJPw3z0dHxo/oldNT9/znue86ZoshExIQB5FulxBVR8Z/pgDOSZgeIr1GpLlTe3cL7I3mp2N4mt/6nRe+n1UCNunM5XndcFlK4FCtQxoEyTccA0mcpnjO8ztRd2uz7odnzH/BI+IMea0TVTgCCuNSl4ZYYSSUZyvtIEqYmivIZ+PhVzgkMyYUgeU7iHbqVJpDrwUuh2r4lCnzy4tK/UEsdH0BzK6I9P0P4i0iULTP0kb3QTmUIGMgQRrsoMY/ZIQ9uwAGsV/YPZjmoY/iDYYXpxBwS3KXECeaBI8rInkBdJtD7SrS3u7DSejqwvsObyj76f380E4JJsZehpRwM1+nJCpdT+IpnaqXBWnNS6IFZsLXsdKpiFUX8sT9bK/xRVwaxiKZrjT8Vy353nM77qu/Yavpai+C3onzMNYUJBzbS5VInDP5JuH5/Y+NgkHp+Oh7VBxY4ilu1tLsA1ut9Ehr20cs83mHReJFo8kAwAA" } }, { "ID": "0afa71eb8a71812c", "Request": { "Method": "PATCH", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/t_metadata_partition_nocluster_0?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "32" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJyZXF1aXJlUGFydGl0aW9uRmlsdGVyIjp0cnVlfQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:10 GMT" ], "Etag": [ "hMOSCWlX5GKYUPYQ/XU40w==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42SX0/bMBTFv4t5XWsnpX8SiYcCpUIrG2tTjWpCkUluU4NjB9uBVRXffddZWyZgok+Rr8859+ejbMiDUDmJyZ0oHmsw6yPH7ySQLwQcL3C+uvo+O/spb7rjr4v59eIHvZkfs+eTE1QI77MrLeW65KqVQ6lbDqyLc+64BZeGLIgCFg7SXi9ivW7EWNTBT8oYC9ouLXGFl6YVN044oVWqdCZr68CkDBdYkMuJUA8ew7nKxpTuMNuF1oUEXgnbznS5n9OnkFZG30PmLP2AjW7ZLD0EkjZlWHoAa6OcwhIMqAxIvCFbjMv/tISeLUKjOARnt6YxfMr0ggVmKyi5h1kKkLkl8a8NUbxEvr8fDFxX/jRLppffxujZ32PyP/fnw2REXm4x04kSrncLhSp8+l60QIeBx1qYV82FkAhEYmdqQL+qy9M1FoB63xseJ1oVCZi346l+3p0yA9xHJaJBC7r9MBz0+ywK2bH/VX9XwrwXDDqsj7WhQHLrrnQusIX8TUbAOmH0+s5keDoZeYfOmkAczWefPeoPApFHpEUDAAA=" } }, { "ID": "a904db128d354ce7", "Request": { "Method": "PATCH", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/t_metadata_partition_nocluster_0?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "32" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJyZXF1aXJlUGFydGl0aW9uRmlsdGVyIjp0cnVlfQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:10 GMT" ], "Etag": [ "SZfujLFgKyd7haukqhQKlw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42SQU/jMBCF/4u5Qu2kS9NE4gBaQIiCoA0HWK0ik0wTU8dObQeIKv4749CWFbsreoo8fu/N56esyEKogiTkUZTLFky35/ijBLJPwPES57OHefs0OSsvuyKqeLtYVreX8uXoCBXC+2ylpexqrg4KqPWBA+uSgjtuwWUhC+KAheNsNIrZ6DBmLB7iJ2OMBQOX1bjCS7OGGyec0CpTOpetdWAyhgssyPlEqAWuqZxrbELpBnNQal1K4I2wg1zX2zl9Dmlj9BPkztJ/sNE1m6W7QNK+DEt3YO2VU5iDAZUDSVZkjXHxn5bQs0boFbvgbNb0hm+Z3rDAvIKae5i5AFlYkvxaEcVr5Pv4YGDX+NMsnV5cn6Nne4/Jf9z/PE5PydtvzHSihpvNQqFKn74V3aPDwLIV5lNzJiQCkcSZFtCv2vqkwwJQ73vD40SrMgXzdTzVL5tTboD7qFT0aMFhFIbjKGJxyH74X/W1EeZvwXjIIqwNBZJbd6ULgS0UXzICFg2Hn+9Mj08mp96h8z4QR3ez7x71DqGtDHhFAwAA" } }, { "ID": "dea634411117aae5", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "324" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJleHBpcmF0aW9uVGltZSI6IjE1NzIyODgzMDcwMDAiLCJzY2hlbWEiOnsiZmllbGRzIjpbeyJuYW1lIjoibmFtZSIsInR5cGUiOiJTVFJJTkcifSx7Im5hbWUiOiJkYXRlIiwidHlwZSI6IkRBVEUifV19LCJ0YWJsZVJlZmVyZW5jZSI6eyJkYXRhc2V0SWQiOiJkYXRhc2V0XzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDEiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0IiwidGFibGVJZCI6InRfbWV0YWRhdGFfcGFydGl0aW9uX25vY2x1c3Rlcl8xIn0sInRpbWVQYXJ0aXRpb25pbmciOnsiZXhwaXJhdGlvbk1zIjoiMTAwMCIsInR5cGUiOiJEQVkifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:10 GMT" ], "Etag": [ "R5OBB6v5jqD4cvp5U45csA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42SXU/CMBSG/0u9VdpNxtgSLyASY4IfwXFhjFlqdxiFrZ1rQQnhv3s6Ab8jV835et/nnHRN5lJlJCZPMn9eQL06svypAHJMwPIc86Pgpt/vLIPZ83lbLKtg3A6E6Z2dYYd0c2aqi2JVcnWSQalPLBgbZ9xyAzb1mRd5zO+mnU7EOkHEWHSKT8oY81o2LdHCtaYVr620UqtUaVEsjIU69dDAQDEZSjVHm6m1lYkp3WG2cq3zAnglTUvocp+nS59WtZ6BsIb+wka3bIYeAkmbYxh6AGvTOYIJ1KAEkHhNthiXf1wJZ7YITcchODubZuBfpg0eUEyh5A5mIqHIDIkf1kTxEvneHxRcVS66S0aX1xc4s6+j8qf6eS8ZkM0jalpZwu3OUKrcqe+b7t3Hea1kzV31Cg2Jh+SORS3K/goXxxQjTTjUKk+g/p4e6ZddJGpohBLZIHlB6PvdMPRYNwi/OH1p6J6y0Jkek4Ibe6UzidtnPzQiP/zYL+n1hwM3oUUjiKnxHdm8AYs0pW0fAwAA" } }, { "ID": "18a74cb64db8020c", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/t_metadata_partition_nocluster_1?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:11 GMT" ], "Etag": [ "R5OBB6v5jqD4cvp5U45csA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42SXU/CMBSG/0u9VdpNxtgSLyASY4IfwXFhjFlqdxiFrZ1rQQnhv3s6Ab8jV835et/nnHRN5lJlJCZPMn9eQL06svypAHJMwPIc86Pgpt/vLIPZ83lbLKtg3A6E6Z2dYYd0c2aqi2JVcnWSQalPLBgbZ9xyAzb1mRd5zO+mnU7EOkHEWHSKT8oY81o2LdHCtaYVr620UqtUaVEsjIU69dDAQDEZSjVHm6m1lYkp3WG2cq3zAnglTUvocp+nS59WtZ6BsIb+wka3bIYeAkmbYxh6AGvTOYIJ1KAEkHhNthiXf1wJZ7YITcchODubZuBfpg0eUEyh5A5mIqHIDIkf1kTxEvneHxRcVS66S0aX1xc4s6+j8qf6eS8ZkM0jalpZwu3OUKrcqe+b7t3Hea1kzV31Cg2Jh+SORS3K/goXxxQjTTjUKk+g/p4e6ZddJGpohBLZIHlB6PvdMPRYNwi/OH1p6J6y0Jkek4Ibe6UzidtnPzQiP/zYL+n1hwM3oUUjiKnxHdm8AYs0pW0fAwAA" } }, { "ID": "72c3f8f5da79ab24", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "355" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjbHVzdGVyaW5nIjp7ImZpZWxkcyI6WyJuYW1lIl19LCJleHBpcmF0aW9uVGltZSI6IjE1NzIyODgzMDcwMDAiLCJzY2hlbWEiOnsiZmllbGRzIjpbeyJuYW1lIjoibmFtZSIsInR5cGUiOiJTVFJJTkcifSx7Im5hbWUiOiJkYXRlIiwidHlwZSI6IkRBVEUifV19LCJ0YWJsZVJlZmVyZW5jZSI6eyJkYXRhc2V0SWQiOiJkYXRhc2V0XzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDEiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0IiwidGFibGVJZCI6InRfbWV0YWRhdGFfcGFydGl0aW9uX2NsdXN0ZXJfMSJ9LCJ0aW1lUGFydGl0aW9uaW5nIjp7ImV4cGlyYXRpb25NcyI6IjEwMDAiLCJ0eXBlIjoiREFZIn19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:11 GMT" ], "Etag": [ "8m4hqWfphAvrKD22YeJv8A==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42Sa0/bMBSG/4v5CvUl0KaR+FAEQmxlmkqmCU0oMslpYojtYLvdqqr/fcfpZWMXwSfr3N73OUdek2dlKpKRR1W/LMCtjoJ8bIEcEwiyxnyqT5uXr/OumSzdx0sh7uHDMp2cn2OHinO+sW270tKcVKDtSQAfskoG6SEUgvExZyIthsMxG56NGRsn+BSMMT4IhUaL2Fp00gUVlDVF2S58AFdwlPfQzqfKPKNJE0LnM0r3kIPa2roF2Sk/KK0+5OlS0M7ZJyiDp/8gozsyT9+DSPtTePomad83gzk4MCWQbE12EDf/uRDO7AD6jvfA7G36gTeINni8sgEtI8pcQVt5kn1bEyM10m0flFt1MbrLZzefrnHmUEfd3+qXk/yKbB5QMygNn/d2ytRR/dB0H7/Mj045Gau3aEg4ckcWs9AXK1wbU4z04dSaOgf3Z3pmv++j0kEvlKseiZ+NhEhHI86FSF45vWpIEzaKpseklT7c2krh9tVfGknCf+2XTy6mV3HClr0gpr7cRYLtOXd7Hq64PdLDZvMTDj8byDoDAAA=" } }, { "ID": "636377dfb40ad235", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/t_metadata_partition_cluster_1?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:11 GMT" ], "Etag": [ "8m4hqWfphAvrKD22YeJv8A==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42Sa0/bMBSG/4v5CvUl0KaR+FAEQmxlmkqmCU0oMslpYojtYLvdqqr/fcfpZWMXwSfr3N73OUdek2dlKpKRR1W/LMCtjoJ8bIEcEwiyxnyqT5uXr/OumSzdx0sh7uHDMp2cn2OHinO+sW270tKcVKDtSQAfskoG6SEUgvExZyIthsMxG56NGRsn+BSMMT4IhUaL2Fp00gUVlDVF2S58AFdwlPfQzqfKPKNJE0LnM0r3kIPa2roF2Sk/KK0+5OlS0M7ZJyiDp/8gozsyT9+DSPtTePomad83gzk4MCWQbE12EDf/uRDO7AD6jvfA7G36gTeINni8sgEtI8pcQVt5kn1bEyM10m0flFt1MbrLZzefrnHmUEfd3+qXk/yKbB5QMygNn/d2ytRR/dB0H7/Mj045Gau3aEg4ckcWs9AXK1wbU4z04dSaOgf3Z3pmv++j0kEvlKseiZ+NhEhHI86FSF45vWpIEzaKpseklT7c2krh9tVfGknCf+2XTy6mV3HClr0gpr7cRYLtOXd7Hq64PdLDZvMTDj8byDoDAAA=" } }, { "ID": "99b89f6b096e557d", "Request": { "Method": "PATCH", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/t_metadata_partition_nocluster_1?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "32" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJyZXF1aXJlUGFydGl0aW9uRmlsdGVyIjp0cnVlfQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:12 GMT" ], "Etag": [ "ors7Ie/+Jrme10hRIhQsSg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42SW2/aMBTHv4v7uIKdIAhE6kOrXsREpw2yh2maIjc5JC6+pLazDaF+9x2H21q1Kk+Rj/+Xn4+yISuhS5KSB1E9tWDXZ54/SCDnBDyvcG6sS6ZAP322CiJWz6f1N7eoLi5QIYLP1UbKteK6V4IyPQ/OpyX33IHPYxZNIhaP89FowkbDCWOTAX5yxljU97nCiiDNG2698MLoXJtCts6DzSMscCCXM6FXWFN737iU0j1mvzKmksAb4fqFUYc5/R3TxppHKLyjb7DRHZujp0DSbhmOnsDaKeewBAu6AJJuyA5j+s6W0LND6BSn4OxrOsOHTM+4wKIGxQPMUoAsHUl/bojmCvm2HwxcN+G0yObTL3foOdxj8n/315fZDXn+hZleKPi6LxS6CukH0Y/w4/xthOXh9h4LSYTkOLXw1Ap7dN4KiZgk9bYFTNWtulrjWtAQ1HicGV1lYF+P5+bP/lRY6Goy0QFHwySOx0kSsfEwecHxQjAesGSLJLnz96YUuJvydUbMBvHx9dnl1ewmOEzRBeLo++KjR/0DU9+2oFsDAAA=" } }, { "ID": "162574a9830d41af", "Request": { "Method": "PATCH", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/t_metadata_partition_nocluster_1?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "32" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJyZXF1aXJlUGFydGl0aW9uRmlsdGVyIjp0cnVlfQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:12 GMT" ], "Etag": [ "X62OLE2TahFdIQbWC+Rx3A==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42S207jMBCG38VcArWT0qaNxEXZLahSOWwJghVaRW4yTQ2OHWwHWlW8+45DWxbEil5FHv+Hz6OsyKNQOYnJVBRPNZjlnuNTCeSAgOMFzu+64eV4GCZ8fpqPfk1vf+xPFu3B8TEqhPfZuZZyWXJ1mEOpDx1YF+fccQsuDVnQD1jYS7vdPut2+oz12/hJGWNBy6UlVnhpWnHjhBNapUpnsrYOTBpggQU5Gwv1iDVz5yobU7rBbBVaFxJ4JWwr0+V2Tp9DWhn9AJmz9As2umazdBdI2izD0h1YG+UEZmBAZUDiFVljjP6zJfSsERrFLjibmsbwLdMrLjCbQ8k9zEyAzC2J71dE8RL53j4YuKz86TqZjC7O0LO9x+R/7n8OkiF5/YOZTpRwtSkUqvDpW9Fv/+MsKmG4vz3HQhIgOU4NPNXCvDtPhURMEjtTA6aqujxZ4lrQ4NV4HGtVJGA+jyf6ZXPKDDQ1iWiAg04Uhr0oClivE33g+CDotVn0hiS5dec6F7ib/HNGeNQ+en99MjgZD71DZ00gjm6uv3vUX6/OeGpbAwAA" } }, { "ID": "7dbfbda208b1c486", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "332" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJleHBpcmF0aW9uVGltZSI6IjE1NzIyODgzMDcwMDAiLCJzY2hlbWEiOnsiZmllbGRzIjpbeyJuYW1lIjoibmFtZSIsInR5cGUiOiJTVFJJTkcifSx7Im5hbWUiOiJkYXRlIiwidHlwZSI6IkRBVEUifV19LCJ0YWJsZVJlZmVyZW5jZSI6eyJkYXRhc2V0SWQiOiJkYXRhc2V0XzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDEiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0IiwidGFibGVJZCI6InRfbWV0YWRhdGFfcGFydGl0aW9uX25vY2x1c3Rlcl8yIn0sInRpbWVQYXJ0aXRpb25pbmciOnsicmVxdWlyZVBhcnRpdGlvbkZpbHRlciI6dHJ1ZSwidHlwZSI6IkRBWSJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:12 GMT" ], "Etag": [ "zH3uptlELKNbbZuQe4DlHg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42SUU/bMBSF/4v3OmonpU0TiQcQ3UAUtJXwANMUucltanDsYN/AStX/zk1oyzQ2rU+Wr88598tRVuxBmYIlbKbKxwbc8hPKmQb2mQHKkuYvZ/2mRj2eXFzNZnfNdzg81Wfl0REpVOvzC6v1spLmoIDKHiB4TAqJ0gNmoQjiQISjbDiMxXAQCxH36ciEEEEPs4pWtNKslg4VKmsyY3PdeASXhbTAg55PlHmgNQvE2iecbzF7pbWlBlkr38tttZvzp5DXzt5Djp7/hY1v2DzfB5J3ZXi+B2unnMIcHJgcWLJiG4zzf7REng1Cp9gHZ7umM/yXaU0F5guoZAszV6ALz5IfK2ZkRXxvBwUu6/Z2nU7Pr76SZ/dOyb+9nx6nY7b+SZmoKvi2XahM2abvRLfkcPDYKPeu+aI0AbEEXQPkN011sqQCSC9Yd51YU6bg/hxP7fP2ljuQbVSqOrRgEIXhKIqCcHAYtb/qr1q5j4JRX0RUGwm09HhpC0UtFB8yhkH8/p3p8clk3Dps3gXS6OaarV8BptmUvCcDAAA=" } }, { "ID": "d6b7e7a4d1020e41", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/t_metadata_partition_nocluster_2?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:12 GMT" ], "Etag": [ "zH3uptlELKNbbZuQe4DlHg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42S0U/bMBDG/xfvFWonpU0TiQcQ3UAUBCV7GNMUuck1NTh2sC9Aqfjfd8nagsYm+mTd+fu++/nkFbtXpmAJm6nyoQG3/IJypoHtMUBZUv/ltN/UqMeT88vZ7La5hoMTfVoeHpJCtT6/sFovK2n2C6jsPoLHpJAoPWAWiiAORDjKhsNYDAexEHGfjkwIEfQwq2hEK81q6VChsiYzNteNR3BZSAM86PlEmXsas0CsfcL5BrNXWltqkLXyvdxW2z5/DHnt7B3k6Pk/2PiazfNdIHm3DM93YO2UU5iDA5MDS1ZsjXH2ny2RZ43QKXbB2YzpDJ8yvdIC8wVUsoWZK9CFZ8nPFTOyIr4/BwUu67a6Sadnl9/Is72n5Hf3J0fpmL3+okxUFVxtBipTtulb0Q9yOHholHvTfFWagFiCrgHym6Y6XtICSC9YV06sKVNwf7en9mlT5Q5kG5WqDi0YRGE4iqIgHBxE7Vd9rpX7KBj1RURrI4GWHi9soWgLxYeMYRC/vTM9Op6MW4fNu0Bqfb/57FG/AcvAUy5FAwAA" } }, { "ID": "b7a1a05804c4db09", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "363" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjbHVzdGVyaW5nIjp7ImZpZWxkcyI6WyJuYW1lIl19LCJleHBpcmF0aW9uVGltZSI6IjE1NzIyODgzMDcwMDAiLCJzY2hlbWEiOnsiZmllbGRzIjpbeyJuYW1lIjoibmFtZSIsInR5cGUiOiJTVFJJTkcifSx7Im5hbWUiOiJkYXRlIiwidHlwZSI6IkRBVEUifV19LCJ0YWJsZVJlZmVyZW5jZSI6eyJkYXRhc2V0SWQiOiJkYXRhc2V0XzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDEiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0IiwidGFibGVJZCI6InRfbWV0YWRhdGFfcGFydGl0aW9uX2NsdXN0ZXJfMiJ9LCJ0aW1lUGFydGl0aW9uaW5nIjp7InJlcXVpcmVQYXJ0aXRpb25GaWx0ZXIiOnRydWUsInR5cGUiOiJEQVkifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:13 GMT" ], "Etag": [ "9HsBS6c1OUU7Wi7IObMI+w==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42S3U7jMBCF38VcstROKpomUi+oloVKZUFtqtUKochNpqnBsYPtLFRV351x+gNiQXAVeXzOmc9HWZMHoQqSkLkoHxswqyPH5xLIDwKOlziPL+1w2suD69ks+iOi0fX8anT8NBigQnifXWopVxVXJwVU+sSBdUnBHbfgspAFccDCftbrxax3GjMWd/GTMcaCjssqXOGlWc2NE05oleWysQ5MFmK8BbkYC/WAS5bO1TahdA/ZKbUuJfBa2E6uq8Oc/gtpbfQ95M7SD8jojszS7yDStgpLvyRtdRNYgAGVA0nWZAcx+qQh9OwAWsV3YPZrWsMXRBssL19CxT3KQoAsLElu10TxCum2H4xb1f40TSej3xfoOdxj7pv7n2fpOdncYaYTFdzs1wlV+vSD6C86DDw2wrxqfgmJQCRxpgH0q6YarvD5qGekPY61KlMw78cT/bQ/5Qa4j0pFixacRmHYj6IgjFnf/6TPtTD/C/pdFmFpKJDcuitdCGyheJ/Rxapf35meDcfn3qHzNhBHs6kn2Na6e++hzW1Zd5vNCx0B1uxCAwAA" } }, { "ID": "d5bc9af784dd4fc8", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/t_metadata_partition_cluster_2?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:13 GMT" ], "Etag": [ "9HsBS6c1OUU7Wi7IObMI+w==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42SXW/aMBSG/4t32YGdoBISiYuisRWJrhUETdM0RSY5BLeOndrOWoT47z0OH53YR3tl+fg973nOK2/Jg1AFSchSlI8NmM0Hx5cSyEcCjpdYj6/taN7Pg9vFIvomosnt8mZy8TQcokL4PrvWUm4qrjoFVLrjwLqk4I5bcFnIgjhg4SDr92PWv4wZi3t4ZIyxoOuyCkd4aVZz44QTWmW5bKwDk4Vob0GupkI94JC1c7VNKD1CdkutSwm8Frab6+pUp79CWht9D7mz9C9k9EBm6XsQaRuFpW+StroZrMCAyoEkW3KAmPwjIew5ALSK98Acx7QNbxDtMLx8DRX3KCsBsrAk+bElildItz/QblP72zydTb5+wZ7TO/r+9v7pKh2T3U/0dKKCu+M4oUrvfhJ9xw4Dj40wr5rPQiIQSZxpAPtVU402uD7qGWmvU63KFMx5eaafjrfcAPdWqWjRgssoDAdRFIQxG/hP+lwL86dg0GMRhoYCya270YXAFIpzjx5G/bpnejWajn2HzltDLC3mnmAf62HfU5r7sHws/936BaLlN9NgAwAA" } }, { "ID": "9affe0731b3a4f40", "Request": { "Method": "PATCH", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/t_metadata_partition_nocluster_2?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "33" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJyZXF1aXJlUGFydGl0aW9uRmlsdGVyIjpmYWxzZX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:13 GMT" ], "Etag": [ "5sU7NtKUea+MywanKU3aAw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42S3U7jMBCF38V7CdROummaSFwULawQBaE2vVghFJlkmhocO9judqOq78442xbEj+hVNOMz53wzypo8CVWSlDyI6nkJpv3h+IMEckzA8Qr7kZ3FN+5qBvzoul1xdTXr89Hq9BQVws/ZhZayrbk6KaHWJw6sS0vuuAWXhyxIAhYO88EgYYMoYSzp4ydnjAU9l9cY4aV5w40TTmiVK13IpXVg8hADLMj5WKgnjFk419iU0h1mr9K6ksAbYXuFrvd9+jekjdGPUDhLP2GjWzZLD4Gk3TEsPYC1U05gDgZUASRdky3G5RdXwpktQqc4BGcX0w18y7TBAxYLqLmHmQuQpSXp3ZooXiPf/w8ato2vptnk8uY3zuzf0fnN+69Rdk429+jpRA23u0ChKu++F/3xqWpZn7W4InYY6cqxVlUG5n17ole7qjDAvWEmuvAgisNwGMdBGP2M/c/4rxHmo2DYZzEeBgWSW3etS4F7lu89+lGYvG6Sjc7G535CF50htmZTrA08L4V5Xe1CSLwjSedcWti8ALU4j3EoAwAA" } }, { "ID": "9ef1fdbea03d3c74", "Request": { "Method": "PATCH", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/t_metadata_partition_nocluster_2?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "33" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJyZXF1aXJlUGFydGl0aW9uRmlsdGVyIjpmYWxzZX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:13 GMT" ], "Etag": [ "5sU7NtKUea+MywanKU3aAw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42S3U7jMBCF38V7CdROummaSFwULawQBaE2vVghFJlkmhocO9judqOq78442xbEj+hVNOMz53wzypo8CVWSlDyI6nkJpv3h+IMEckzA8Qr7kZ3FN+5qBvzoul1xdTXr89Hq9BQVws/ZhZayrbk6KaHWJw6sS0vuuAWXhyxIAhYO88EgYYMoYSzp4ydnjAU9l9cY4aV5w40TTmiVK13IpXVg8hADLMj5WKgnjFk419iU0h1mr9K6ksAbYXuFrvd9+jekjdGPUDhLP2GjWzZLD4Gk3TEsPYC1U05gDgZUASRdky3G5RdXwpktQqc4BGcX0w18y7TBAxYLqLmHmQuQpSXp3ZooXiPf/w8ato2vptnk8uY3zuzf0fnN+69Rdk429+jpRA23u0ChKu++F/3xqWpZn7W4InYY6cqxVlUG5n17ole7qjDAvWEmuvAgisNwGMdBGP2M/c/4rxHmo2DYZzEeBgWSW3etS4F7lu89+lGYvG6Sjc7G535CF50htmZTrA08L4V5Xe1CSLwjSedcWti8ALU4j3EoAwAA" } }, { "ID": "a0b285c02b2703d5", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "369" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJleHBpcmF0aW9uVGltZSI6IjE1NzIyODgzMDcwMDAiLCJzY2hlbWEiOnsiZmllbGRzIjpbeyJuYW1lIjoibmFtZSIsInR5cGUiOiJTVFJJTkcifSx7Im5hbWUiOiJkYXRlIiwidHlwZSI6IkRBVEUifV19LCJ0YWJsZVJlZmVyZW5jZSI6eyJkYXRhc2V0SWQiOiJkYXRhc2V0XzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDEiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0IiwidGFibGVJZCI6InRfbWV0YWRhdGFfcGFydGl0aW9uX25vY2x1c3Rlcl8zIn0sInRpbWVQYXJ0aXRpb25pbmciOnsiZXhwaXJhdGlvbk1zIjoiMTAwMCIsImZpZWxkIjoiZGF0ZSIsInJlcXVpcmVQYXJ0aXRpb25GaWx0ZXIiOnRydWUsInR5cGUiOiJEQVkifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:14 GMT" ], "Etag": [ "jPXOPS5eOIfOz/1rTfnDYQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42Sa2/TMBSG/4v5ymo7pZdE2odNG6hSR0sbpE0TirzkJPXm2JntAKXqf+c464VNIPrJOpf3fR8deUOepC5IQh5k9dyCXb/z4kEBeU/Aiwr7j/Pb2Xw5gNmknP2i3Kalvrr7cn6OGzLo3Moota6FPiugNmcenE8K4YUDn0WMx5xF42w4jNlwEDMW9/HJGGO857MaI8Jq1gjrpZdGZ9rkqnUebNbHAAeqnEr9hDEr7xuXULrH7FXGVApEI10vN/WhT79HtLHmEXLv6F/Y6I7N0VMgaXcMR09g7TYXUIIFnQNJNmSHMfnHlVCzQ+g2TsHZx3SC/zJt8YD5CmoRYEoJqnAkud8QLWrke3nQcN2EapkuJp8/oeYwR+c/5lcX6TXZfkNPL2uY7wOlroL7YekufJyfjbQiTG8wkHAkx24HcLS18NxKezT6KBVSk8TbFjBEt/XlGq+EgiDGcmp0lYJ9216YH/sqt9ClprLj54NRFI1HI96PB/wV1quFcZ+NXgiVcP7GFBJJi7ceH1jEj8dILy6n10Fh8s4QW1+XZPsbGqa4hkwDAAA=" } }, { "ID": "b0491c13f2cfcb3e", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/t_metadata_partition_nocluster_3?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:14 GMT" ], "Etag": [ "jPXOPS5eOIfOz/1rTfnDYQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42Sa0/bMBSG/4v3ddR2ul4SiQ8g2FSprF2bSUNoikxykhocO9jORlfx33ccegG0iX6yzuV93ydH2ZB7qQuSkFtZPbRg1x+8uFVAPhLwosL+3fzHbL4cwGxSzv5QbtNSX1x/Oz3FDRl0bmWUWtdCnxRQmxMPzieF8MKBzyLGY86icTYcxmw4iBmL+/hkjDHe81mNEWE1a4T10kujM21y1ToPNutjgANVTqW+x5iV941LKN1h9ipjKgWika6Xm3rfp78i2lhzB7l39B9sdMvm6DGQtDuGo0ewdpsLKMGCzoEkG7LFmPznSqjZInQbx+DsYjrBu0xPeMB8BbUIMKUEVTiS3GyIFjXyPT9ouG5CtUwXk69fULOfo/OL+cVZekmefqKnlzXMd4FSV8F9v3QdfpzHRloRplcYSDiSY7cDONhaeGilPRh9lgqpSeJtCxii2/p8jVdCQRBjOTW6SsG+bS/M712VW+hSU9nx88EoisajEe/HA/4K69XCuM9Gz4RKOH9lComkxVuPTyzih2OkZ+fTy6AweWeIre/L9z7qLzM78v1qAwAA" } }, { "ID": "00a9957de4c2948b", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "400" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjbHVzdGVyaW5nIjp7ImZpZWxkcyI6WyJuYW1lIl19LCJleHBpcmF0aW9uVGltZSI6IjE1NzIyODgzMDcwMDAiLCJzY2hlbWEiOnsiZmllbGRzIjpbeyJuYW1lIjoibmFtZSIsInR5cGUiOiJTVFJJTkcifSx7Im5hbWUiOiJkYXRlIiwidHlwZSI6IkRBVEUifV19LCJ0YWJsZVJlZmVyZW5jZSI6eyJkYXRhc2V0SWQiOiJkYXRhc2V0XzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDEiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0IiwidGFibGVJZCI6InRfbWV0YWRhdGFfcGFydGl0aW9uX2NsdXN0ZXJfMyJ9LCJ0aW1lUGFydGl0aW9uaW5nIjp7ImV4cGlyYXRpb25NcyI6IjEwMDAiLCJmaWVsZCI6ImRhdGUiLCJyZXF1aXJlUGFydGl0aW9uRmlsdGVyIjp0cnVlLCJ0eXBlIjoiREFZIn19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:14 GMT" ], "Etag": [ "0T5ZkW3wj1HKjwQqST7u3Q==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42SXW/TMBiF/4u5ZbWTrE0TaRebGDDRIdYGTQNNkZe8Td06cWo7lKrqf+e1+8X40HZlvV/nPDryhixEU5KUPIlq2YFev7H8SQJ5S8DyCvss639b3EerefDx03x1t5xkcRfdXVzghnB3ZqakXNe8OSuhVmcWjE1LbrkBm4csSAIWDvPBIGGDfsJYEuGTM8aCns1rtHCrecu1FVaoJi9kZyzoPEJ5A3I6Es0CTWbWtial9ADZq5SqJPBWmF6h6mOf/ghpq9UcCmvoP8jonszQ1yBSH4WhL5L6vTFMQUNTAEk3ZA9x85+E8GYP4DdeA3Ow8QcvEG0xvGIGNXcoUwGyNCT9viENr5Fu96DcunXVJBvffP6AN8c56v42f3eZXZPtI2paUcOXg51oKqd+XHpwX+ZnKzR301s0JAFyY9cDnGQ1LDuhT0LvhURqklrdAZo0XX21xozc1yO+HKmmykD/2R6r1aEqNHjXTHj+oB+H4TCOg/OIRc+wni0MIxbvCCU39laVAknLvzTOw+QURnZ5Nbp2F6rwgtj6OnEEu+z3oRwj3yX6uN3+AjVBonZnAwAA" } }, { "ID": "a029148b82625564", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/t_metadata_partition_cluster_3?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:14 GMT" ], "Etag": [ "0T5ZkW3wj1HKjwQqST7u3Q==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42SXU/bMBiF/4u5HbWT0KaJxAVosKGVabSZpjFNkUnepm4dO7WddVXFf9/r9Av2BVeW349zHh95QxZClSQlD6JatmDWJ44/SCBvCDheYZ1l/fvFl2g1D95/mK/ulpMsbqO783OcEH7PzrSU65qr0xJqferAurTkjltweciCJGDhMB8MEjboJ4wlER45YyzoubxGCz+aN9w44YRWeSFb68DkEcpbkNORUAs0mTnX2JTSPWSv0rqSwBthe4WuD3X6I6SN0XMonKV/IaM7Mktfg0i7KCx9kbSbG8MUDKgCSLohO4ibfySEOzuAbuI1MHubbuEFokcMr5hBzT3KVIAsLUm/bYjiNdJtD5RbN/42ycY3H9/hzqGPuk/6by+yK/L4HTWdqOHT3k6oyqsfhr76L/OzEYb77i0akgC5sdoBHGUNLFthjkLXQiI1SZ1pAU1UW1+uMSP/9Uh3HWlVZWB+L4/1an8rDHSumej4g34chsM4Ds4iFj3DejYwjFi8JZTcultdCiQt/9A4C5NjGNnF5ejKb+iiE8TS54kn2Ga/C+UQ+TZRn91/X/0LAme45YUDAAA=" } }, { "ID": "7ba557d43113b6f5", "Request": { "Method": "PATCH", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/t_metadata_partition_nocluster_3?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "33" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJyZXF1aXJlUGFydGl0aW9uRmlsdGVyIjpmYWxzZX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:15 GMT" ], "Etag": [ "jXlEkPcyZpPt/vdyy8xxIw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42SW0/jMBCF/4v3damdRL0kEg8gyqpSWVUlSAtoFZlkmpo6drBdaFT1v+84NOWiRfQpmpkz53weZUtWQhUkIQ+ifFqDaX44/iCB/CTgeIn9xz9yvJrlzV09c/S5aJrRZjN5OT1FhfB7dqmlbCquTgqo9IkD65KCO27BZSEL4oCFo2wwiNmgHzMWR/jJGGNBz2UVRnhpVnPjhBNaZUrncm0dmCzCAAtyMRVqhTFL52qbUNph9kqtSwm8FraX6+rQp88hrY1+hNxZ+h82umez9BhI2h7D0iNYW+UcFmBA5UCSLdljTL64Eu7sEVrFMThdTLvwLdMOD5gvoeIeZiFAFpYk91uieIV8rx80bGpfXafzye9fuHOYo/O7+cVZOia7v+jpRAWzLlCo0rsfRLf+x9nUwnA/vcJAEiA5dluAzhZt1Lo6b/AO2PJjLKdalSmYz+25fumq3EDrm4qWMOgPw3A0HAZR3A8+BH8QjCI2fGWQ3LorXQhkKT579FkUvT03PTufjv2GzltDbN1cY23gaS3M2/svhcRjk2TBpYXdP6DSilNNAwAA" } }, { "ID": "0455d09eee791c07", "Request": { "Method": "PATCH", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/t_metadata_partition_nocluster_3?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "33" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJyZXF1aXJlUGFydGl0aW9uRmlsdGVyIjpmYWxzZX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:15 GMT" ], "Etag": [ "jXlEkPcyZpPt/vdyy8xxIw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42SW0/jMBCF/4v3damdRL0kEg8gyqpSWVUlSAtoFZlkmpo6drBdaFT1v+84NOWiRfQpmpkz53weZUtWQhUkIQ+ifFqDaX44/iCB/CTgeIn9xz9yvJrlzV09c/S5aJrRZjN5OT1FhfB7dqmlbCquTgqo9IkD65KCO27BZSEL4oCFo2wwiNmgHzMWR/jJGGNBz2UVRnhpVnPjhBNaZUrncm0dmCzCAAtyMRVqhTFL52qbUNph9kqtSwm8FraX6+rQp88hrY1+hNxZ+h82umez9BhI2h7D0iNYW+UcFmBA5UCSLdljTL64Eu7sEVrFMThdTLvwLdMOD5gvoeIeZiFAFpYk91uieIV8rx80bGpfXafzye9fuHOYo/O7+cVZOia7v+jpRAWzLlCo0rsfRLf+x9nUwnA/vcJAEiA5dluAzhZt1Lo6b/AO2PJjLKdalSmYz+25fumq3EDrm4qWMOgPw3A0HAZR3A8+BH8QjCI2fGWQ3LorXQhkKT579FkUvT03PTufjv2GzltDbN1cY23gaS3M2/svhcRjk2TBpYXdP6DSilNNAwAA" } }, { "ID": "16579c8f7469ad6f", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/t_metadata_partition_nocluster_3?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:15 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6uuBQBDv6ajAgAAAA==" } }, { "ID": "7ea0df705f752418", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/t_metadata_partition_nocluster_2?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:15 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6uuBQBDv6ajAgAAAA==" } }, { "ID": "f6fb6ad58a1f3be9", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/t_metadata_partition_nocluster_1?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:15 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6uuBQBDv6ajAgAAAA==" } }, { "ID": "3305dfab8cd99722", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/t_metadata_partition_nocluster_0?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:16 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6uuBQBDv6ajAgAAAA==" } }, { "ID": "946d03804e0c508e", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0002?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:16 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6uuBQBDv6ajAgAAAA==" } }, { "ID": "f3548433f3d748dd", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "246" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJleHBpcmF0aW9uVGltZSI6IjE1NzIyODgzMDcwMDAiLCJ0YWJsZVJlZmVyZW5jZSI6eyJkYXRhc2V0SWQiOiJkYXRhc2V0XzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDEiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0IiwidGFibGVJZCI6InRhYmxlXzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDMifSwidGltZVBhcnRpdGlvbmluZyI6eyJleHBpcmF0aW9uTXMiOiI4NjQwMDAwMCIsInR5cGUiOiJEQVkifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:16 GMT" ], "Etag": [ "aYCSY0ris6vF95xjwQk65A==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42Ry27CMBBF/8XdAnYSkpBIXUAfUiWQWqALVsgkQzAkcWqbR4T499pWqERfijf2XN+Ze2Sf0Y6VKYrRimUfexD1naKrHFAHgaKZ1uniYbYggsng8Bz5p+3xbRf4w/t77WCmT254ntcFLbspFLyrQKo4pYpKUEuXOJFD3MEyCCIS+BEhkae3JSHE6dmc/yyejpCQr8es3OmgjVKVjDG+gvYyzrMcaMVkL+HFl44PLq4E30KiJP6FDjd0ErfBxBZT4la01jSFNQgoE0DxGTUgL3+8lO5pIKyjDdA1xja0oLroR0w2UFCNo8+KFfBKhWKK8ZKVmYFUdaVh0eNwYb79VDFBze1EanEQ9IlZZk65L0a1xtYyQbYc8zKbg/guT/nxWiUC7LC5ztWS44euOwhDJ+i73k3ajWHgkdCEdlBOpZrwlK0ZpD9m+J6xNPjz4Wj8ZDp4Ygdq6X2GLp9VTpwQ4QIAAA==" } }, { "ID": "d323529b2485cade", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0003?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:16 GMT" ], "Etag": [ "aYCSY0ris6vF95xjwQk65A==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42RXW+CMBiF/0t3q7aAgJDsQveRLNFkU3fhlanwilWgrK0fxPjf1za4xH2F3jQ9Pec9T9oz2rEyRTFasexjD6K+U3SVA+ogUDTTOl08zBZEMBkcniP/tD2+7QJ/eH+vHczk5IbneV3QsptCwbsKpIpTqqgEtXSJEznEHSyDICKBHxESeXpbEkKcnu35z+LpCgn5eszKnS7aKFXJGOMraC/jPMuBVkz2El586fjg4krwLSRK4l/ocEMncRtMbDElbkVrTVNYg4AyARSfUQPy8sdL6UwDYR1tgK41NtCC6qL9rIBXKhRTjJeszAyYqisNiB6HC/PVp4oJam4nUouDoE/MMtlyX4xqjaplguxxzMtsDuK7POXH6ykRYIfNda+WHD903UEYOkHf9W7abgwDj4SmtINyKtWEp2zNIP0xw/eMpcGfD0fjJ5PgiR2opfcZunwCsYG+D9UCAAA=" } }, { "ID": "8cac08485ab3feec", "Request": { "Method": "PATCH", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0003?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "87" ], "If-Match": [ "aYCSY0ris6vF95xjwQk65A==" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJ0aW1lUGFydGl0aW9uaW5nIjp7ImV4cGlyYXRpb25NcyI6bnVsbCwicmVxdWlyZVBhcnRpdGlvbkZpbHRlciI6ZmFsc2UsInR5cGUiOiJEQVkifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:17 GMT" ], "Etag": [ "Q8hVT33taI/7sP2nLAhDAw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42QXW+CMBSG/0t3O22BCULihcYtMWGJc27JrkyFA3RCi22dM8b/vgPTLXEf8Yr0zfvxcPZkJWRKIrIU+XoDendl+bIEck3A8hz1h37xPPc8yyc0MFNXxsNiPNwOBugQTc4Uqix3FZedFCrVsWBslHLLDdiFy5zQYW5/4fsh83shY6GHnwVjzOm2O/9ZPJwwUGaxkCscKqytTUTpCbSbK5WXwGthuomqvnT65tJaq1dIrKG/0NEjnaGXYNIW09CLaFvTDDLQIBMg0Z4cQSZ/XAozR4jWcQnQaaYNXEB1QL+oYMq1FVYoKWTegNldjYBkPHzBQg3rjdDfnjtRWtAkynhpAAvkphrtkBcDjLTPWMl8Dvpcnqnt6ZVo4E3XHMdRcnqB6/aDwPFv3OZU8F4L/dPQ91iA2GgoubH3KhWZgPS8I3Bcv7nD5z/Mh6P4tkmopC1E6emRHD4AnT+vw9oCAAA=" } }, { "ID": "bfd4ce24c91cd4bf", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0003?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:17 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6uuBQBDv6ajAgAAAA==" } }, { "ID": "1152dee9028a6971", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "112" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJkYXRhc2V0UmVmZXJlbmNlIjp7ImRhdGFzZXRJZCI6ImRhdGFzZXRfMjAxOTEwMjhfNjY5MDY1OTAwOTM2NTlfMDAwMiJ9LCJmcmllbmRseU5hbWUiOiJuYW1lIiwibG9jYXRpb24iOiJFVSJ9Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:18 GMT" ], "Etag": [ "em8j2Aev8yrSn6pl3yNEpA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41RW2vCMBT+L9lr7U3sDYQ5VoawKXQbPowhMT2t0TTpktRRxP++VKrsQcWnwHe+2znZoy3lOUrQipY/Dcj2IccaK9DIQqBxaSZQRRt/Aruole88qNmwnaX1ZDw2DNop1Vow1laYD3KoxECD0klvsvRdL/ZcP1oGQewGo9h146F5lq7r+kavgBWvlG+Ny1rrWiWOc+phl0KUDHBNlU1Edcadne/UUmyAaOVciHb6aOXc2aGnZVCABE4AJfsTNu3Wu9Om7zS9chF0sFAhKfCctTNcmRTEu8dCmBBQCiVfeyQF6waLbPqRZt15aiAUsxcpmtrgfcRCUg1SGcezYr6Y3RDMf/kVfqNAPrVphSkzaNdzIMVK6McLG9gUV3ZpBDtKwJQWDdfdz/z3zdLJ840iGeD82OTbQkQC1lTwD3o8hjcKfT8KQy+MQs8YMKz0m8hpQSG/RhHk6GBG6Sc6/AEaYK+sygIAAA==" } }, { "ID": "e454119731b44203", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0002?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:18 GMT" ], "Etag": [ "em8j2Aev8yrSn6pl3yNEpA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41RW2vCMBT+L9lr7U3sDYQ5VoawKXQbPowhMT2t0TTpktRRxP++VKrsQcWnwHe+2znZoy3lOUrQipY/Dcj2IccaK9DIQqBxaSZQRRt/Aruole88qNmwnaX1ZDw2DNop1Vow1laYD3KoxECD0klvsvRdL/ZcP1oGQewGo9h146F5lq7r+kavgBWvlG+Ny1rrWiWOc+phl0KUDHBNlU1Edcadne/UUmyAaOVciHb6aOXc2aGnZVCABE4AJfsTNu3Wu9Om7zS9chF0sFAhKfCctTNcmRTEu8dCmBBQCiVfeyQF6waLbPqRZt15aiAUsxcpmtrgfcRCUg1SGcezYr6Y3RDMf/kVfqNAPrVphSkzaNdzIMVK6McLG9gUV3ZpBDtKwJQWDdfdz/z3zdLJ840iGeD82OTbQkQC1lTwD3o8hjcKfT8KQy+MQs8YMKz0m8hpQSG/RhHk6GBG6Sc6/AEaYK+sygIAAA==" } }, { "ID": "8d3d9e6b3a3a89bb", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0002?alt=json\u0026deleteContents=false\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:19 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6uuBQBDv6ajAgAAAA==" } }, { "ID": "71a529607d51c3ba", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:19 GMT" ], "Etag": [ "gs3AYtwXmh7aF/dUsSnjCA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42RbWvCMBSF/0v2VZu0vtQWhLnNDWEvUBU3xpCYXmu0TbokVUT870ulyj6o+Clwcs65T252aMVFjEI048lvAWp7F1NDNRhUQ2BoYm8S3eh9mc1ntvDpM47HeiiWj71u1zp4mdQLmabbjIp6DJmsG9AmrEqmHnEDl3idabsdkHYrICRo2GNKCHFtXkM6f+ViZVsWxuQ6xPjI4SRSJinQnGuHyeyk47WHcyWXwIzGZ0bjarTGNzJUtgjmoEAwQOHuqA3K591YUzENLmwE7WuIMgZao/B7h5RM7SA0iQajflQuIgfGafqiZJFbvSqbKG5AaZs9JT4m71cCHxtxwV9oUA/bfkZ5atWSqK7kTJr7M6wOp5mT2MCaM7DQshCm/IP/vVG/93QFJAIaH0h+aogpoIZLMeJZmXRbvud1fJ/4zWbTFqRUmzcZ8zmH+JJFskODvRoP0f4PCVPOULQCAAA=" } }, { "ID": "dd0fee87e150af29", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/does_not_exist?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 404, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:19 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/62OsQ7CMAxE935FlJlKDJ06Vx3bBSaEKkNMqZTEUuxKoKr/ThIy8AFM1vnsd7dVSmkMgYJu1RZFlHcyGFVzbA7fhUNmmNNODyTqQas3repAgFEUP8natwNfG3RUC7K0hpAnTzLha2HRhZNzOGIuWasS+M+MzDLkYPEJNVu6gf31AgJT9uJrn1J0Mfc8r6UrC8jKuc54mvrxPHTpcK/26gOm62vXNAEAAA==" } }, { "ID": "ad5a63405b6cae67", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "74" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJkYXRhc2V0UmVmZXJlbmNlIjp7ImRhdGFzZXRJZCI6ImRhdGFzZXRfMjAxOTEwMjhfNjY5MDY1OTAwOTM2NTlfMDAwMyJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:20 GMT" ], "Etag": [ "BsNiNGQ6iMsm3h86/XQ0Pw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42RUWvCMBSF/0v2qm2ss2pB2GQiwtTZORyMITG91jvTpktSRcT/vlSq7EHFp8DJOed+udmTNaYRCcgC498c1O4hYoZpMKRCwLDY3nT1CEf9iY9DndRXLd/9nNC3badjHVgk9UoKsUtYWo0gkVUD2gRlydyjtXaNeq2577ep32hT2q7bY04prdu8BrF8xXRtW1bGZDpw3ROHE0sZC2AZaofL5Ky7G8/NlPwBbrR7YbRbjtbunQylLYQlKEg5kGB/0gbF8+6sKZkGVzZCDhXCOAetSfC1J0oKO4jMwsG0FxaLyIAjE30l88zqZdlMoQGlbfacGM9GNwLjbXrFn2tQ3V0vYSisWhBVlVxI83SB1UGWOLENbJCDhZZ5aoo/+N8b9p5fboCEwKIjyXeFcAXMoEynmBTJWqPpea1m06PeY7E4wbQZygiXCNE1i+THBnv18U4Of/r/Bp+0AgAA" } }, { "ID": "ff9c4499e0d0f8f2", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0003?alt=json\u0026deleteContents=false\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:20 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6uuBQBDv6ajAgAAAA==" } }, { "ID": "5216747da6c55790", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "74" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJkYXRhc2V0UmVmZXJlbmNlIjp7ImRhdGFzZXRJZCI6ImRhdGFzZXRfMjAxOTEwMjhfNjY5MDY1OTAwOTM2NTlfMDAwNCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:21 GMT" ], "Etag": [ "xEvfhxdEvTOWvagy/brMPw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42RXWvCMBiF/0t2q/3I/GpB2MbKEOYcnaMXY0hM39bMtOmStFrE/75UquxCxavAyTnnffJmh9Ysj5GPliz9LUHWdzHRRIFGHQSapOZmG1TJahsH1XwWVSSt7aWcvm/GY+NgTVKtBOd1RvJuDJnoalDab0sW2HE918GjxWDgOYO+5zjevTkWjuP0TF4BT15ZvjYtK60L5dv2kcNKhUg5kIIpi4rspNsVtgspfoBqZZ8ZbbejlX0jQ2sLIQEJOQXk747apHnejTUt0+TCRtC+gwiloBTyv3ZICm4GoSiczIOwWUQBlBH+IkVZGL0tiyTTIJXJnhKz6O1KYLbJL/hLBfKpDjLCuFEboq4US6EfzrBajGRWagIVo2CgRZnr5g/+94bB4/MVkBBIfCD57iAqgWgm8jnLmqTbH2I8Gg6xi3vYFHCi9FTELGEQX7IIemgwV58faP8HYF01VLQCAAA=" } }, { "ID": "c37fe938a3b20714", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0004/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "153" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJ0YWJsZVJlZmVyZW5jZSI6eyJkYXRhc2V0SWQiOiJkYXRhc2V0XzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDQiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0IiwidGFibGVJZCI6InRhYmxlXzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDQifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:21 GMT" ], "Etag": [ "+5BPv6XuuESE0Eks2iCBbA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42QX2+CMBTFv0v3uGlLJygkPsjCwxKXLOqSvZkKV+yEltHiQozffZdG9rB/4ant6Tk9v94zOUqVkYjsZP7eQN3eWLErgNwRsCJH/daPn0/Ba9Mk64QlR8PlQ7xbzOfokF3OHHRRtKVQowxKPbJgbJQJKwzYLWde6DE+2wZByAI/ZCy8x2XLGJuMXc+/FqwwUOyXUh2x6GBtZSJKe9BxrnVegKikGae6/NLpidOq1m+QWkN/oaNXOkOHYFKHaeggWmdawR5qUCmQ6EyuII9/TAozVwjnGALU17jAAKoLDjE9QCkQB/eqKeMWqzHMiDsutco3UH+XV/qjP6U1CCu12sgSP0U8f8r5bDrl3iSY4XUhjH3SmdxLyH5YAr+z2Lbq5M0iXiZdQqfuQZRe1uTyCfc+2hGEAgAA" } }, { "ID": "0333c5be8413e358", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0004?alt=json\u0026deleteContents=false\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:21 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/72PQQuCQBCF7/6KYc8JY5lkt6AIoTxEdYmQLQcTVhd21kOE/7119dAv6DS892b43nwCAEHGaCPW8HHCyacuyakYcTYaDTHLavDEVlrJZIFfWql3I9uwpEaHltiuyzEr5hilEc5XRZKkmCxTxHThRoGIMdQMbGuloG6hYxITwldgR7h5DVOXP+E9ptSNrNuBUin9kOo3MyRZ+8wQ6848KWsv7nza6P28T7+wlbYbfhFZft0csm2xOe0vx11+Hvb7oA++nXKyHnYBAAA=" } }, { "ID": "96d76e422e436cad", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0004?alt=json\u0026deleteContents=true\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:22 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6uuBQBDv6ajAgAAAA==" } }, { "ID": "2436c3369263bad2", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:22 GMT" ], "Etag": [ "gs3AYtwXmh7aF/dUsSnjCA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42RbWvCMBSF/0v2VZu0vtQWhLnNDWEvUBU3xpCYXmu0TbokVUT870ulyj6o+Clwcs65T252aMVFjEI048lvAWp7F1NDNRhUQ2BoYm8S3eh9mc1ntvDpM47HeiiWj71u1zp4mdQLmabbjIp6DJmsG9AmrEqmHnEDl3idabsdkHYrICRo2GNKCHFtXkM6f+ViZVsWxuQ6xPjI4SRSJinQnGuHyeyk47WHcyWXwIzGZ0bjarTGNzJUtgjmoEAwQOHuqA3K591YUzENLmwE7WuIMgZao/B7h5RM7SA0iQajflQuIgfGafqiZJFbvSqbKG5AaZs9JT4m71cCHxtxwV9oUA/bfkZ5atWSqK7kTJr7M6wOp5mT2MCaM7DQshCm/IP/vVG/93QFJAIaH0h+aogpoIZLMeJZmXRbvud1fJ/4zWbTFqRUmzcZ8zmH+JJFskODvRoP0f4PCVPOULQCAAA=" } }, { "ID": "a7e5815df464a0e7", "Request": { "Method": "PATCH", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "41" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJkZXNjcmlwdGlvbiI6ImQyIiwiZnJpZW5kbHlOYW1lIjoibjIifQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:23 GMT" ], "Etag": [ "YzOg8uDabREdMsJ19QQPCA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41RW2vCMBj9L9mr2rReWxjsogzH1Nk5ZIwhMf2smWnSJanDif99iXQyhhOfAifnlpMtWjGRoAjNWfpRgNpcJMQQDQZVEBiS2puXr1HaKbpkHveSgb73w/H48fb68tIymFPqpeR8kxFRTSCTVQPaRKXJLMB+6OOgM2u1QtxqhhiHdXvMMMa+1WvgiwcmVtZlaUyuI8/76VFLpUw5kJzpGpXZAffWgZcr+Q7UaO9ItFdGa+/MDiUthgUoEBRQtP3B+u55Z9qUnfr/LIJ2FbRQDETCN0OS2RQkApcOmiqWGyaFy3IQoRS0RtHrFinJHXMa9ye92O2VA2WE3ylZ5BYvM6eKGVDaRhwUo+nwhGD0Kf7hFxrUzaaXEcYt6opXlZxLc3XkSTVGslpqBWtGwZaWhTDuq377xr3r7okiMZBk3+StgqgC4maYsP06frMdBJ12G7cbjYY14ESbgUzYgkHyhxLUGx33BVxSUg75/IR2337Wlk/bAgAA" } }, { "ID": "da31b5eda2068596", "Request": { "Method": "PATCH", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "39" ], "If-Match": [ "gs3AYtwXmh7aF/dUsSnjCA==" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJkZXNjcmlwdGlvbiI6ImQiLCJmcmllbmRseU5hbWUiOiJuIn0K" ] }, "Response": { "StatusCode": 412, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:23 GMT" ], "Etag": [ "YzOg8uDabREdMsJ19QQPCA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6vmUlBQSi0qyi9SslKoBnKA3OT8lFQgz8TAQAcikJtaXJyYDhJTCihKTc7PS8ksyczPU0jOSE3OVkhLzMxJTdFTgioGG1YMVBsN5itATSXZILCGlPzcxMw8kPr0nPykxBxkuaLUxOJ8sBxEI7KJSlBltWA6Fuq04pLEklKQ05TcHD19XF3iA4Jcnf39XDxDPP39QFpquWq5AH1JwmMSAQAA" } }, { "ID": "faea53f38565dc75", "Request": { "Method": "PATCH", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "37" ], "If-Match": [ "YzOg8uDabREdMsJ19QQPCA==" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJkZXNjcmlwdGlvbiI6IiIsImZyaWVuZGx5TmFtZSI6IiJ9Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:24 GMT" ], "Etag": [ "yNL/q8jRoElmNa7RVFBHzQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41R3U7CMBh9l3oLrEzYYAmJElFJcMSJcmEMKd3HKHTraAtmEt7dFgcxBgxXTU7PX0+3aMmyGAVoypLVGmRxFRNNFGhUQaBJYm6KcOCsWotI9HgaEj96u+8+fj13OobBrFLNBedFSrJqDKmoalA6KE0mLq6369htTTyvjb1mG+P2tTkmGOO60SvgswHLlsZlrnWuAsc59KglQiQcSM5UjYr0iDsb18mlWADVyjkR7ZTRyrmwQ0mLYAYSMgoo2B6wvn3ehTZlp/6ZRdCugmaSQRbzIiSpSUE2GxSVLNdMZD8AoRSUQsH7FknBLWsc9Ue9yG6VA2WEP0ixzg1e5o0l0yCVsT8qhuPwH8HwMzvDXyuQ3aKXEsYNaktXpZgKfXPiOTVG0lpiBBtGwZQW60zbb/rtG/Vu7/4pEgGJ900+KohKIHaEEdsvU2/6rtvyfew3Gg1jwInSTyJmMwbxH4rb8PympQhKyhlfX9DuGxUevcnXAgAA" } }, { "ID": "bdc51f83de22e1d1", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:25 GMT" ], "Etag": [ "yNL/q8jRoElmNa7RVFBHzQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41R3U7CMBh9l3oLrEzYYAmJElFJcMSJcmEMKd3HKHTraAtmEt7dFgcxBgxXTU7PX0+3aMmyGAVoypLVGmRxFRNNFGhUQaBJYm6KcOCsWotI9HgaEj96u+8+fj13OobBrFLNBedFSrJqDKmoalA6KE0mLq6369htTTyvjb1mG+P2tTkmGOO60SvgswHLlsZlrnWuAsc59KglQiQcSM5UjYr0iDsb18mlWADVyjkR7ZTRyrmwQ0mLYAYSMgoo2B6wvn3ehTZlp/6ZRdCugmaSQRbzIiSpSUE2GxSVLNdMZD8AoRSUQsH7FknBLWsc9Ue9yG6VA2WEP0ixzg1e5o0l0yCVsT8qhuPwH8HwMzvDXyuQ3aKXEsYNaktXpZgKfXPiOTVG0lpiBBtGwZQW60zbb/rtG/Vu7/4pEgGJ900+KohKIHaEEdsvU2/6rtvyfew3Gg1jwInSTyJmMwbxH4rb8PympQhKyhlfX9DuGxUevcnXAgAA" } }, { "ID": "11b10e65685e63d0", "Request": { "Method": "PATCH", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "39" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJkZWZhdWx0VGFibGVFeHBpcmF0aW9uTXMiOiIzNjAwMDAwIn0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:25 GMT" ], "Etag": [ "82fDkwNf6G0lWINzlSWb2A==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41RYWvCMBT8L9lXtbHTVoXBHJMhbArV0Q9jSExfuzfTpktSnRP/+xKpYwwn9kvh3t29e5cdWWGRkAFZYvZRgdpeJcwwDYY0CBiW2UnPT+9Xm0kaPFARjydfYhYv/eHNjWWgU+o3KcQ2Z0UzgVw2DWgzqE0WPm3329TvLYKgT4Nun9L+tf0tKKVtq9cg0kcsVtblzZhSDzzvmKOVSZkJYCXqFpf5D+6tfa9U8h240d6J1V69WnsXZqhpEaSgoOBABrsjNnbnXWhTZxr/0wjZN0iqEIpEbCcst1uI2w2aKywNyuIIpKwSZs6WAkafJSrmZk/aTq8D6j5LYpyDttDLjigpnFUcjeejyBVaAkcmHpSsSovXoWKFBpS2GX4U03hyRjDdFP/wKw3qbjvKGQqLusuaSi6luT1xcwtZ3sqsYI0cbGhZFca95W/faDS8PxMkApYckrw2CFdwaGOOh/ra3dD3e2FIw06nYw0E0+ZJJpgiJH8ofjfsuDcSkrO66+cZ2X8DHvNmK/wCAAA=" } }, { "ID": "04e2e7bc83a46cd3", "Request": { "Method": "PATCH", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "23" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJmcmllbmRseU5hbWUiOiJ4eXoifQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:26 GMT" ], "Etag": [ "7RnTP/b60fUeA//pVhQgAg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41R0W7iMBD8F/cVsAmQFKRKR1VUIV3buxTKw+mEjLMJezh2znZ6TRH/XhulVXWiVfNiaXZmdnayJztUGZmQDRZ/azDNWcYdt+BIh4DjhZ8kqVr8oJuY5UuYUlo9bH8W0+LiwjMwKO1WS9mUXHUzKHXXgXWT1mQdsf64z6LzdRyPWTwaMzYe+GfNGOt7vQWZf0e18y5b5yo7ofQ1R6/QupDAK7Q9ocs3nD5GtDL6Dwhn6YnVtF1t6RcztLQUcjCgBJDJ/hWbh/O+aNNmmn/QCDl0SG4QVCabW176LeSpeQ7rwQqDlUOtPHYEcl5Lt+AbCbOnCg0Psxvrp4OYhc+TuBBgPfRrT4yWwW2VzhezNHRagUAur42uK4+3uVYGHRjrY7wp7la3nwju/qkP+LUFc9nMSo7So+G4rtEb7b6dOLuHvOwVXvCIAnxoXSsXfud733Q2vfokSAo8Oyb53SHCwLGNBR4b7I+SKDpPEpYMh0NvILl1NzrDHCH7jxLFo+EgULTgbdfLe3J4AVHICbv/AgAA" } }, { "ID": "666f6234d8f9226a", "Request": { "Method": "PATCH", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "34" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJkZWZhdWx0VGFibGVFeHBpcmF0aW9uTXMiOm51bGx9Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:27 GMT" ], "Etag": [ "Ju4EHHqB6coSrRM7CG640A==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41R3U7CMBh9l3oLrMyxwRISQYlgBJOB4cIYUrqPUe3W0XboJL67LRnEGDBcNTk9fz3doXeWxShES5ZsCpDlVUw0UaBRDYEmibl5KLzBcLjp+1RMZTQObu99D/e6XcNgVqnWgvMyJVk9hlTUNSgdViYLFzc7Tey2F77fwX6rg3Hn2hwLjHHT6BXw1SPL3o3LWutchY5z6NFIhEg4kJypBhXpEXe2rpNL8QZUK+dEtFNFK+fCDhUtghVIyCigcHfARvZ5F9pUnUZnFkHfNbSSDLKYlxOSmhT0WX7ZeFBUslwzkRnMAIRSUAqFLzskBbfEeTSaDSI7Vw6UEX4vRZEbvIqcS6ZBKpNwVDzNJ/8Inj6yM/xCgeyXg5QwblDbuy7FUuibEy9qMJI2EiPYMgqmtCgybX/qt2806N39UyQCEu+bvNYQlUDsCDO2H6fZCly3HQQ48DzPGHCi9FjEbMUg/kNxAy8ILEVQUs34PEXfP5i88/LaAgAA" } }, { "ID": "b135c79f00d9ca1a", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:27 GMT" ], "Etag": [ "Ju4EHHqB6coSrRM7CG640A==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41R3U7CMBh9l3oLrMyxwRISQYlgBJOB4cIYUrqPUe3W0XboJL67LRnEGDBcNTk9fz3doXeWxShES5ZsCpDlVUw0UaBRDYEmibl5KLzBcLjp+1RMZTQObu99D/e6XcNgVqnWgvMyJVk9hlTUNSgdViYLFzc7Tey2F77fwX6rg3Hn2hwLjHHT6BXw1SPL3o3LWutchY5z6NFIhEg4kJypBhXpEXe2rpNL8QZUK+dEtFNFK+fCDhUtghVIyCigcHfARvZ5F9pUnUZnFkHfNbSSDLKYlxOSmhT0WX7ZeFBUslwzkRnMAIRSUAqFLzskBbfEeTSaDSI7Vw6UEX4vRZEbvIqcS6ZBKpNwVDzNJ/8Inj6yM/xCgeyXg5QwblDbuy7FUuibEy9qMJI2EiPYMgqmtCgybX/qt2806N39UyQCEu+bvNYQlUDsCDO2H6fZCly3HQQ48DzPGHCi9FjEbMUg/kNxAy8ILEVQUs34PEXfP5i88/LaAgAA" } }, { "ID": "eb71c152631f03cd", "Request": { "Method": "PATCH", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "299" ], "If-Match": [ "Ju4EHHqB6coSrRM7CG640A==" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJhY2Nlc3MiOlt7InJvbGUiOiJXUklURVIiLCJzcGVjaWFsR3JvdXAiOiJwcm9qZWN0V3JpdGVycyJ9LHsicm9sZSI6Ik9XTkVSIiwic3BlY2lhbEdyb3VwIjoicHJvamVjdE93bmVycyJ9LHsicm9sZSI6Ik9XTkVSIiwidXNlckJ5RW1haWwiOiJ0ZXN0LXJvYm90QHNob2xseW1hbi1kZW1vLXRlc3QuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSx7InJvbGUiOiJSRUFERVIiLCJzcGVjaWFsR3JvdXAiOiJwcm9qZWN0UmVhZGVycyJ9LHsicm9sZSI6IlJFQURFUiIsInVzZXJCeUVtYWlsIjoiSm9lQGV4YW1wbGUuY29tIn1dfQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:28 GMT" ], "Etag": [ "gssiuE7itlrIEvMCm3TuRA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41RW0/CMBj9L/UVWDcugyUmoi4Go5JMDA/GkNp9zE+7dbYdMgn/3VYHUaPGpyan59bTDXnCIiURucfsuQJVH6TMMA2GtAgYltmbTGus4hCNUJN4dXmSd2dVMj48tAx0Sv0ghahzVrRTyGXbgDZRY7IIqD/yaTBcDAYjOuiPKB117bGglPpWr0EsL7B4si4PxpQ68rxdj04mZSaAlag7XOZ73FsFXqnkI3CjvR+ivSZae//s0NASWIKCggOJNjts4p73T5um0+SXRci2RZYKoUhFfcVym0LW9auLB80VlgZlYTELMM5BaxLdboiSwhHnyWQWJ26uEjgycaZkVVq8iZwrNKC0TdgrpvOrPwTTl+IXfqVBHddxzlBY1PVuK3kvzdEPL+ogyzuZFayQgy0tq8K4n/rsm8Tj0z+KJMDSb032iq9VziUcwZrlpYCPjLsW4QqYm22G73P6/TAIhmFIw16vZw0E0+ZSprhESL9RgmG/13cUyVkz/M012b4BMa3NQAwDAAA=" } }, { "ID": "802f8f50ceceb493", "Request": { "Method": "PATCH", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "249" ], "If-Match": [ "gssiuE7itlrIEvMCm3TuRA==" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJhY2Nlc3MiOlt7InJvbGUiOiJXUklURVIiLCJzcGVjaWFsR3JvdXAiOiJwcm9qZWN0V3JpdGVycyJ9LHsicm9sZSI6Ik9XTkVSIiwic3BlY2lhbEdyb3VwIjoicHJvamVjdE93bmVycyJ9LHsicm9sZSI6Ik9XTkVSIiwidXNlckJ5RW1haWwiOiJ0ZXN0LXJvYm90QHNob2xseW1hbi1kZW1vLXRlc3QuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSx7InJvbGUiOiJSRUFERVIiLCJzcGVjaWFsR3JvdXAiOiJwcm9qZWN0UmVhZGVycyJ9XX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:29 GMT" ], "Etag": [ "8RdOge1OhUaADc100cxRQA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41R3WrCMBh9l+xWbVqrtQVhDmUIm7JO8WIMielnzUybLolunfjuS6TKGCpeBU7OX052aM3yBEVowdLPDcjyLiGaKNCohkCT1Nx04mScgjteTUmvT12M6Xf80ut2DYNZpVoJzsuM5PUEMlHXoHRUmcw97IYu9jrzdjvE7VaIcdg0xxxj7Bq9Ar58YvnauKy0LlTkOMcejVSIlAMpmGpQkZ1wZ+s5hRQfQLVyzkQ7VbRybuxQ0WJYgoScAop2R2xon3ejTdVpeGERtK+hpWSQJ7wckcykoO/yx8aDopIVmoncYAYglIJSKHrbISm4Jc7i4WQQ27kKoIzwRyk2hcGryJlkGqQyCSfFeDa6Ihh/5Rf4GwXyoRxkhHGD2t51KRZC3595UYORrJEawZZRMKXFJtf2p/76xoNe/0qRGEhyaPJeQ1QCsSNM2GEctxV4XicIcOD7vjHgROlnkbAlg+QfxQubPrYUQUk14/QV7X8BxPh5rNoCAAA=" } }, { "ID": "a50d859181ddb439", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:29 GMT" ], "Etag": [ "8RdOge1OhUaADc100cxRQA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41R3WrCMBh9l+xWbVqrtQVhDmUIm7JO8WIMielnzUybLolunfjuS6TKGCpeBU7OX052aM3yBEVowdLPDcjyLiGaKNCohkCT1Nx04mScgjteTUmvT12M6Xf80ut2DYNZpVoJzsuM5PUEMlHXoHRUmcw97IYu9jrzdjvE7VaIcdg0xxxj7Bq9Ar58YvnauKy0LlTkOMcejVSIlAMpmGpQkZ1wZ+s5hRQfQLVyzkQ7VbRybuxQ0WJYgoScAop2R2xon3ejTdVpeGERtK+hpWSQJ7wckcykoO/yx8aDopIVmoncYAYglIJSKHrbISm4Jc7i4WQQ27kKoIzwRyk2hcGryJlkGqQyCSfFeDa6Ihh/5Rf4GwXyoRxkhHGD2t51KRZC3595UYORrJEawZZRMKXFJtf2p/76xoNe/0qRGEhyaPJeQ1QCsSNM2GEctxV4XicIcOD7vjHgROlnkbAlg+QfxQubPrYUQUk14/QV7X8BxPh5rNoCAAA=" } }, { "ID": "afa006c3d0ad4b33", "Request": { "Method": "PATCH", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "29" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJsYWJlbHMiOnsibGFiZWwiOiJ2YWx1ZSJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:30 GMT" ], "Etag": [ "jJzAA3MMxMe9v3HYhRxLYg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41RbWvCMBj8L9lXtbF1agVhjsnm8AU6h8gYEtPHGpc2XZI6q/jfl0iVMVT8lHC5u+eeyw59sSRELTRn0XcGMr8LiSYKNCoh0CQyL6vXbafjDQabAfhr72W6DDb9adRuGwazSrUUnOcxScohxKKsQelWYTJzcdWvYrc5q9d9XL/3MfY9c8wwxlWjV8AXfZZ8GZel1qlqOc4xRyUSIuJAUqYqVMQn3Fm7TirFCqhWzpnRTjFaOTdmKGgBLEBCQgG1dkesZ9e70abI1LvQCNqX0EIySEKeD0lspqBNvrXjQVHJUs1EYjADcDIHrmyKw82Aa8IzsAaEUlDm6WOHpODWYxL0xt3ANpkCZYQ/S5GlBi/STCTTIJXRnhSjyfCKYPSTXOBnCuRj3o0Js5HsSmUp5kI/nFm2wkhciYxgzSiY0CJLtP3Ev75Bt/N0JUgAJDwk+SwhKoHYfsbs0Fv1vuG6zUYDN2q12qEwpQciZAsG4T+Kh70athRBSdHw+xva/wJAjzHT9QIAAA==" } }, { "ID": "48e0ff121d859e9f", "Request": { "Method": "PATCH", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "26" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJsYWJlbHMiOnsibGFiZWwiOm51bGx9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:31 GMT" ], "Etag": [ "vzd7TsU8YT5pVc4MbQo+LQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41RW0vDMBj9L/HRrU27bl0LgopDBruwOh0iMrL0WxeXNjVJp93YfzeRKiIqPgVOzi0nB7RlRYpitGLZcwWyPkmJJgo0aiHQJDM3u30aztVt/37eLe9oMF7NxOlodnZmGMwq1UZwXuekaKeQi7YGpePGZOljL/Kw31/2ehHudSOMo445lhhjz+gV8PWIFVvjstG6VLHrfvRwMiEyDqRkyqEi/8Tdne+WUjwB1cr9IdptopX7zw4NLYE1SCgooPjwgQ3t8/5p03Qa/rIIOrbQWjIoUl5PSG5S0Gu9t/GgqGSlZqIwmAEIpaAUih8OSApuiYtkOB8kdq4SKCP8WoqqNHgTuZBMg1Qm4VMxXUz+EExfil/4lQJ5WQ9ywrhBbe+2FCuhz394kcNI7mRGsGMUTGlRFdr+1FffZHBx9UeRBEj63uSxhagEYkeYs/dxvG7o+/0wxGEQBMaAE6XHImVrBuk3SsfzAvsDXFDSzHh7g45vr94gK9oCAAA=" } }, { "ID": "5ee1731832c8d12e", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "366" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJleHBpcmF0aW9uVGltZSI6IjE1NzIyODgzMDcwMDAiLCJzY2hlbWEiOnsiZmllbGRzIjpbeyJuYW1lIjoibmFtZSIsInR5cGUiOiJTVFJJTkcifSx7Im1vZGUiOiJSRVBFQVRFRCIsIm5hbWUiOiJudW1zIiwidHlwZSI6IklOVEVHRVIifSx7ImZpZWxkcyI6W3sibmFtZSI6ImJvb2wiLCJ0eXBlIjoiQk9PTEVBTiJ9XSwibmFtZSI6InJlYyIsInR5cGUiOiJSRUNPUkQifV19LCJ0YWJsZVJlZmVyZW5jZSI6eyJkYXRhc2V0SWQiOiJkYXRhc2V0XzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDEiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0IiwidGFibGVJZCI6InRhYmxlXzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDUifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:31 GMT" ], "Etag": [ "hUw6Vl9tApa5+6B9jBEojQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42Q0W/aMBDG/xfvcS12EiWQSH0gq1UhMdjStC9ThUxyBFMnTmO3HUL8772k0Exlm5AfrPvu++5+uh15lFVOIrKUxdMzNNsvViwVkAsCVhSor+9eg3sV2nEt/K9BHG5irjc/r67QIducWWultqWoLnMo9aUFY6NcWGHALlzmhA5zR4sgCFngh4yFHn4Lxpgz6Pb8z+LjCgNqNZXVYwtibW0iSo+gg0LrQoGopRlkuvzQ6YtL60ZvILOG/oWOHugMPQeTdpiGnkXbmRJYQQNVBiTakQPI5B+XwswBonOcA3Rc0wXOoNrjEbM1lKLFWUlQuSHRrx2pRImE7x+O3NZtdZsmk9kNZvr+c2n6/mSW8hueoFDqvBUS/oOPU379Z6SBrE8k/Ns8ucb6dPVSa9Ub4/l8ysczsn/Ad9Hujbd4Iuww0pVTXRUpNJ/lRL8eq6wBYaWuUtnNd/yh646GQ8/xRu3Z4Hctm1PDyGNDvBQalDD2u84louYnM3zP62HTcTzlbUJn3UCU7m7J/g3mAd7CTQMAAA==" } }, { "ID": "df4b4c7baf5fcf95", "Request": { "Method": "PATCH", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0005?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "29" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJsYWJlbHMiOnsibGFiZWwiOiJ2YWx1ZSJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:32 GMT" ], "Etag": [ "7ASXQwdJXGCOW5NOB487Ew==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42QYY+aQBCG/8v2qycLHAIm90HviLGx0kOaXtI0ZoURt7ewlF3PM8b/frNUS1Pbi+HDMjPvO++TOZBnXuVkSFa8+LmFZv9Bs5UA0iOgWYF9f7R4etzlH58m9/FXbx6PbwM/2t3doYIbn9pIIfYlq25yKOWNBqWHOdNMgV461A5t6gTLwSCkAy+kNHTxWVJK7X6b857EwwgFYj3j1TMGbbSu1dCyzqD9QspCAKu56mey/N23XhyrbuQPyLSy/kFnneiUdQ2m1WIq6yraVpTAGhqoMiDDAzmBTP9zKfScIFrFNUDnmNZwBdWxRwRbgVAGp/1D3wsTWzAjlW2gZGa05iByFH07kIqVCP/rwbR9bapFmkznE/R0822puvl0nkaTKMFGKXPTSKLP0SiNHv60NJB1jiS6j5MHrC+jV1KKTjiO41k0mpPjd/x6Jne8x+vhhJK2nMmqSKH5u53I3bnKGmCayyrl7X7b8x0n8H3XdgNzUXiteXMpCFzq4xGJOaHSn2TOETW/2BG6XgebjsazyDhk1i7E1pcFOb4Bp//TKWgDAAA=" } }, { "ID": "1c4ebfa02243e306", "Request": { "Method": "PATCH", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0005?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "26" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJsYWJlbHMiOnsibGFiZWwiOm51bGx9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:32 GMT" ], "Etag": [ "F6B0udglhnhjow75plio6Q==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42Q0U/CMBDG/5f6KrQbssESH0CnIUHQMZ+MIWU7tmq3zrWohPC/e5vgjKghfWjuu++7++U25FnkMfHIQiQvKyjXJ4YvJJBTAoYnqF85Q7aKE5nm6ZN6c7uFFMq5Oz9Hh6hyOlVSrjOet2LIVMuANl7MDddg5jaz+haze3PH6TOn22es38Fvzhiz2vWe/yxdXKFBLscif8ZFqTGF9ijdg7YTpRIJvBC6HansS6evNi1K9QSR0fQXOrqj0/QYTFpjanoUbW0KYAkl5BEQb0N2IKM/LoWZHUTtOAZov6YOHEG1xSNGKWS8wlkKkLEm3sOG5DxDws8PR66LqpqFwWhyjZmmv8p00x9NQv/aD1DIVFwJgX/rD0L/8nukhKhJBP7FNLjE+nD1QinZGIfT6dgfTMj2Ed9ptXe4xhNhh5G6HKs8CaH8KQfqbV9FJXAjVB6Ker7VdW2757odq9OrzgbvhSgPDb0Oc/FSaJBcmxsVC0SNf86wz87cBjYcDMd+lVBRPRCl+xnZfgANtq4XTQMAAA==" } }, { "ID": "995fbf2a7dda2f92", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0005?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:32 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6uuBQBDv6ajAgAAAA==" } }, { "ID": "d7c755e681860cf4", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "366" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJleHBpcmF0aW9uVGltZSI6IjE1NzIyODgzMDcwMDAiLCJzY2hlbWEiOnsiZmllbGRzIjpbeyJuYW1lIjoibmFtZSIsInR5cGUiOiJTVFJJTkcifSx7Im1vZGUiOiJSRVBFQVRFRCIsIm5hbWUiOiJudW1zIiwidHlwZSI6IklOVEVHRVIifSx7ImZpZWxkcyI6W3sibmFtZSI6ImJvb2wiLCJ0eXBlIjoiQk9PTEVBTiJ9XSwibmFtZSI6InJlYyIsInR5cGUiOiJSRUNPUkQifV19LCJ0YWJsZVJlZmVyZW5jZSI6eyJkYXRhc2V0SWQiOiJkYXRhc2V0XzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDEiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0IiwidGFibGVJZCI6InRhYmxlXzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDYifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:32 GMT" ], "Etag": [ "sarVs1dSxhUPgWc9KMRosQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42S3U7CQBCF32W9RXbbCqVNvABtDJEfLVUvjCFLO5SVtlu7i0oI7+60gjWihvRiM2fOmfky6YYsRRYRl8xE/LKCYn2i+SwB0iCgeYy64sW9MqLJ++LuJn4IneuhL9Xt+Tk6RJlTC5kk65RnpxGk8lSD0m7ENVegpyYzHIOZnWm77bB2y2HMsfCZMsaMZrXnP0sbVyhI5gORLXHRQutcuZTuQZuxlHECPBeqGcr0S6evJs0L+QyhVvQXOrqjU/QYTFphKnoUbWXyYQ4FZCEQd0N2IP0/LoWZHUTlOAZov6YKHEG1xSOGC0h5iTMXkESKuI8bkvEUCT8fHLnOy2oS+P3RFWbq/ipVdb8/Crwrz0chlVEp+N6N1w28y++RAsI64XsXY/8S68PVMymT2tgbjwded0S2T/g1yr29NZ4IO4xU5UBmcQDFT9mXb/sqLIBrIbNAVPONlm2aHdu2TLt1Vv7Q77koDg0di9l4KTQkXOmhjASiRgczOpZVwwbd3sArEzKsBqJ0NyHbD4oYlfdNAwAA" } }, { "ID": "93775ac713a86d6a", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables?alt=json\u0026pageToken=\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:33 GMT" ], "Etag": [ "f+PJntftwjCWqzFVVi1pZQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/9WTa0sCQRSG/8v0MY2ZWd11F/xgF8EwqBCjQpZRjza2N2fPUib735vxQoGpJYH6aWDmOee8nIeZklcZ9YlHunI4zkBNTlB0A2jKFEmBAIqhfhuc3l5HOMC30cXD+KPebkuWPN1Vq5qY0Snxnqc/N9KINLfpSxwEk1BExT6EcREhRa8vUKSAPqfMZZRXfNt2qV12KXUtffiUUnaGfqhTGNRPhEKJMo78XpClCMqnywT3MAAFUQ+INyWJikfQw8aaubpmMXlG/CbFcsysYEuiXLOTRAchrdp588qUyhBul6SMhibjArmsPZqCngJhHlua1Les7HBecRzq2pwbDe+JVKtAxaKOTqeBxfRF74GEoG+ckEhovJPnhb3YYQdnh/3dzvft36Rm92bl650xxrl1vM74wTnjuzhTMM6k+mLqMtC9iIcqgw3uuEsrx+vOOjh31n/9t8J8yfOAsLvgkkUP/HOaLpsQey+St6daFb3GgcWdcmm7g7yjG8YoggZCqHdfzj8BzNfZuasIAAA=" } }, { "ID": "3ede34b17f792ec4", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0006?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:33 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6uuBQBDv6ajAgAAAA==" } }, { "ID": "17ee9c9f9de84e79", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "366" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJleHBpcmF0aW9uVGltZSI6IjE1NzIyODgzMDcwMDAiLCJzY2hlbWEiOnsiZmllbGRzIjpbeyJuYW1lIjoibmFtZSIsInR5cGUiOiJTVFJJTkcifSx7Im1vZGUiOiJSRVBFQVRFRCIsIm5hbWUiOiJudW1zIiwidHlwZSI6IklOVEVHRVIifSx7ImZpZWxkcyI6W3sibmFtZSI6ImJvb2wiLCJ0eXBlIjoiQk9PTEVBTiJ9XSwibmFtZSI6InJlYyIsInR5cGUiOiJSRUNPUkQifV19LCJ0YWJsZVJlZmVyZW5jZSI6eyJkYXRhc2V0SWQiOiJkYXRhc2V0XzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDEiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0IiwidGFibGVJZCI6InRhYmxlXzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDcifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:33 GMT" ], "Etag": [ "SRdCDuNO1r3eNAp+7oGKQw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42SQU/CQBCF/8t6VNltK5Q28QDSECIWLfVkDFnaoay23dpdVEL4704rWCNqSA+befPezJdJN+RZ5DFxyVwkLyso1yeaz1MgZwQ0T1CfBvHVYOVPjNICv1ec2nJ4ffd2eYkOUeXUUqbpOuP5eQyZPNegtBtzzRXomckMx2Bmd9bpOKzTdhhzLHxmjDGjVe/5z2LjCgXpYizyZ1y01LpQLqV70FYiZZICL4RqRTL70umrSYtSPkGkFf2Fju7oFD0Gk9aYih5FW5sCWEAJeQTE3ZAdyOiPS2FmB1E7jgHar6kDR1Bt8YjREjJe4SwEpLEi7sOG5DxDws8HR66LqpqGwcgfYqbprzLV9Ed+6A29AIVMxpUQeLdeL/QG3yMlRE0i8K4mwQDrw9VzKdPG2J9Mxl7PJ9tH/M6qvf01ngg7jNTlWOZJCOVPOZBv+yoqgWsh81DU8422bZpd27Ys68Kpfuj3QpSHhq7FbLwUGlKu9I2MBaLGBzMurHYDG/b6Y69KyKgeiNL9lGw/AIMyRUJNAwAA" } }, { "ID": "ac124c9b205fb704", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0007/insertAll?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "215" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJyb3dzIjpbeyJpbnNlcnRJZCI6ImEiLCJqc29uIjp7Im5hbWUiOiJhIiwibnVtcyI6WzBdLCJyZWMiOnsiYm9vbCI6dHJ1ZX19fSx7Imluc2VydElkIjoiYiIsImpzb24iOnsibmFtZSI6ImIiLCJudW1zIjpbMV0sInJlYyI6eyJib29sIjp0cnVlfX19LHsiaW5zZXJ0SWQiOiJjIiwianNvbiI6eyJuYW1lIjoiYyIsIm51bXMiOlsyXSwicmVjIjp7ImJvb2wiOnRydWV9fX1dfQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:33 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTMK04tKnHMyQlKLS7IB3KUagGmFzWCLgAAAA==" } }, { "ID": "8a3a3e932a264223", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0007/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:33 GMT" ], "Etag": [ "5qAbjVirb+RatOqJ1QsTEA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8qbFjomZYVlFiVpByWW+Bd6GQYWh7g62toCVZTklyTmBOWXFwOVGSjVAgARmFAuUwAAAA==" } }, { "ID": "44ad7d83bc7ac128", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0007?alt=json\u0026fields=schema\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:33 GMT" ], "Etag": [ "SRdCDuNO1r3eNAp+7oGKQw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWKk7OSM1NVLKqVkrLTM1JKVayiq5WykvMTVWyglA6SiWVBSBecEiQp5+7Uq0OQr40txgh7+kX4uruGgQUyM1PAQkEuQa4Ooa4uiBrKUpNRugIcnX2D3IB8jGtTsrPz0EodPL393F19FOqjQXCWgCN1fK3tQAAAA==" } }, { "ID": "d6e5c03edcae9556", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0007/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:35 GMT" ], "Etag": [ "JgR2QcJCb27Nx/hOahTsUw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8p7pQcZBSZ7OScZmftV6Gf4J2aEFIeW29oCVZTklyTmBOWXFwOVGQD5RWBmdLVSGpgsAwonKtXqgFlQvoFSbSxUBFlZSVFpKkgGIokQT0LTbkia9mQ07UYEtcfWAgDAGmPnGQEAAA==" } }, { "ID": "10bdc9b0f4fd10a5", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0007?alt=json\u0026fields=schema\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:35 GMT" ], "Etag": [ "SRdCDuNO1r3eNAp+7oGKQw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWKk7OSM1NVLKqVkrLTM1JKVayiq5WykvMTVWyglA6SiWVBSBecEiQp5+7Uq0OQr40txgh7+kX4uruGgQUyM1PAQkEuQa4Ooa4uiBrKUpNRugIcnX2D3IB8jGtTsrPz0EodPL393F19FOqjQXCWgCN1fK3tQAAAA==" } }, { "ID": "4539880260cb2197", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0007/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:35 GMT" ], "Etag": [ "JgR2QcJCb27Nx/hOahTsUw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8p7pQcZBSZ7OScZmftV6Gf4J2aEFIeW29oCVZTklyTmBOWXFwOVGQD5RWBmdLVSGpgsAwonKtXqgFlQvoFSbSxUBFlZSVFpKkgGIokQT0LTbkia9mQ07UYEtcfWAgDAGmPnGQEAAA==" } }, { "ID": "f328ec00ac6bf196", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0007?alt=json\u0026fields=schema\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:35 GMT" ], "Etag": [ "SRdCDuNO1r3eNAp+7oGKQw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWKk7OSM1NVLKqVkrLTM1JKVayiq5WykvMTVWyglA6SiWVBSBecEiQp5+7Uq0OQr40txgh7+kX4uruGgQUyM1PAQkEuQa4Ooa4uiBrKUpNRugIcnX2D3IB8jGtTsrPz0EodPL393F19FOqjQXCWgCN1fK3tQAAAA==" } }, { "ID": "61f45cfa5330d4a6", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "317" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7ImRlZmF1bHREYXRhc2V0Ijp7ImRhdGFzZXRJZCI6ImRhdGFzZXRfMjAxOTEwMjhfNjY5MDY1OTAwOTM2NTlfMDAwMSIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QifSwicXVlcnkiOiJzZWxlY3QgbmFtZSwgbnVtcywgcmVjIGZyb20gdGFibGVfMjAxOTEwMjhfNjY5MDY1OTAwOTM2NTlfMDAwNyIsInVzZUxlZ2FjeVNxbCI6ZmFsc2V9fSwiam9iUmVmZXJlbmNlIjp7ImpvYklkIjoib3VRbm1MWlpRY1gwRkN4U0dqU3czUU9DTkR0IiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:35 GMT" ], "Etag": [ "HjFq6yhHO+fcTDSBWHm4Pg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41TXU/bQBD8K5H7WIi/vyKhliYGIkWhiZ3S8mKdL2tzwb4LvjM0Qvz37jkBoZbSPtm+nZ2Z3Rs/GreMr42RUbDqroN292EjCuPIAEUqPL3YnN0Fu5uLy48lzSbpl6uLxvtanZwggukueSPqetcQfryGRhwrkGq0SoeiW/Bmdn29oN+ts/HP9HyTPriLy/F8orBTQl3OGL/F/hultnJkms/qw0qIqgayZXJIRfNybt475rYVG6BKmm+Imuhamu/IfqoFJYoJfrJK0UInoc2hIaxGE5rguBWFUJ/foB4y0gwrxN8zCoRS0XGlvSELFbxkVdf2xMbo0ei9vnrRo6LlAScNHA1418ijQQt0ULaiGShS1JA7lh3blhPlQRBbgR9bVuziI7csK0SJNTpgvBfINF6THxYx/csF6C6iiIQ9Ii8AnDAo1rFv255dBoHvR8QOvdiNabz2PYe64Fguwb7eUt9FuOBr24UojOLchzLIPa8McwIR5GEEHoRFWbhgGU+4hhaIggmTWyHZfhXGeJmcZkk+PcvnSTJJJkj+0LLfUVfLKYKy5Wo+RnQ/bkm6Wk32/vWwr0c5vL+3MxtJ/rWfJw1hAu3oK5rOs2R5Os6m35J9MGZQEbpL7zAaJaklIBzTle22uHxjsUqWP4z90RJKaIHT/7wU7Oir7/8czzlFICYVhaTCbwwBlVqm37UOA2u0HdsPHScKQ9cPPN/owa36oxb3a3kJp2aEBrg6zJQms2ScGU8HsU6+gLCIdzOfzs+x+gvv3ntPKwQAAA==" } }, { "ID": "537f1bc2805777c2", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/ouQnmLZZQcX0FCxSGjSw3QOCNDt?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:36 GMT" ], "Etag": [ "4JaijwfgkwEW+eURZNb6FA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/22RUW+CMBSF/8vd4zAxcdkDiQ+I1bkQkKLZ4rKHUi4ItpTREkeM/33FLWEPpg/tSc9377ntBU5lnYELaVl8ddj2DwWaeDhQ1J0w2m6NqjWCA2hYYZ1Pr6ysznlxOpO3R9zTQ5g+r7z53Do0P6Jk4F4gL1FkGtyPC9RMosVumwOmbwaV7OgmXFstVTbocB8E3iIgcHVGopN6JDbhjqwJHRFKtsTbkeV/pEU+EpT4EV3e6eHciZcqJUZ0EUUB8cJ7+T7tcqBSKcUcW6w5DvM2raqQm83wlPqohOglqycZSjUxqA3ciNut6uJaBodDzN+nK/87WVfJeRZHfrgcXEJxZkpVW+M+sZOBUYYJqs42LMzgTy96W3TbKo5a41B0+tvAV7IRaGwi03boAGf2Q15KA27OhMbrD53IeR7uAQAA" } }, { "ID": "96816cb3efe657dd", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anond13e8789_5ef6_44f7_ae8e_78e4e7bfb3e0/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:36 GMT" ], "Etag": [ "9xxCEEYwkv1ewcgeOLRqlg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8pbVlQ4u7pGlmeXGaaWJ6en+vsEFeak29oCVZTklyTmBOWXFwOVGQP5RWBmdLVSGpgsAwonKtXqgFlQvoFSbSxUBFlZSVFpKkgGIokQT0LTbkia9mQ07UYEtcfWAgAnKK9AGQEAAA==" } }, { "ID": "75d1f70d0cc24547", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "317" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7ImRlZmF1bHREYXRhc2V0Ijp7ImRhdGFzZXRJZCI6ImRhdGFzZXRfMjAxOTEwMjhfNjY5MDY1OTAwOTM2NTlfMDAwMSIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QifSwicXVlcnkiOiJzZWxlY3QgbmFtZSwgbnVtcywgcmVjIGZyb20gdGFibGVfMjAxOTEwMjhfNjY5MDY1OTAwOTM2NTlfMDAwNyIsInVzZUxlZ2FjeVNxbCI6ZmFsc2V9fSwiam9iUmVmZXJlbmNlIjp7ImpvYklkIjoiNHlUSUNXMUlpVjZsbFIzY3hsdkNYaXJYa2NHIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:37 GMT" ], "Etag": [ "U0IxqCCb5F6Vnn+txcTriw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41T207bQBD9lch9LMS32I4joRY5BllCkeo4QJ+s9XpsFuzdsLsGIsS/d9YJCLWU9sWXnTNzzsycfbbuGK+thVWx9n4AuftyKyrryAJNWjzdONnTfZJUwVl4yflX/UQLyR5PThDBTJa6EV236wk/rqEXxxqUXmzW09muyJIrN2OXYdflPn3qHpJrJq/v6DlmKuiaC8bvMP9G661a2PYr+7QVou2AbJmaUtG/ndsPnr2V4haoVvYHpDaqVvYntN86QYlmgp9s1ihhUCBL6AnrUIQpcCxFJfT3D0pPGemnLeIfGAVCqRi4NtqwChW8Ye0gx8LW4tkatb77MK2i5AknPRxN+NCro4kEOmmk6CeaVB2UnuPGruPNyzCMnTCIHSf28VU6jhMhRY0KGB8JCoM3xQ+DyP6yAJNFNFGwR5QVgBeFVR0HrjtzmzAMgjlxo1nsxzSug5lHffAcn2DeKGnMIlzwWVCTkLpQVhE+ZgHE5dx3vNJvKpd4NKqroLZecAwSiIYlU1uh2H4UVpKnp0VaZmflKk2X6RKLP0r2O+oqzxBU5JtVguix3YYMnV7u9Ztm37dy+P5sZi4W+dd8XgyECZRjVpStijQ/TYrsMt0b4wJaQnfre7RGQzoFCEd3FbstDt/6sUnzn9b+KIcGJHD6n0vBjDH6+eV49am5fGtDpDT+owmoMjTjrI0ZWG/kuEHkefMo8iPHNXZBsNR/xLxxLG/mNBWhB64PPa3TizQprJcD2aDeQBjE3ayy1TlGfwGfKgA4KwQAAA==" } }, { "ID": "727bfdc6907eaed6", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs/4yTICW1IiV6llR3cxlvCXirXkcG?alt=json\u0026fields=configuration%2CjobReference%2Cstatus%2Cstatistics\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:37 GMT" ], "Etag": [ "U0IxqCCb5F6Vnn+txcTriw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42S226cMBCGXwX5eiPZ5rTkLmJphBQhlWWT9AoZM6ROjb3Bpi2K9t1rs6soaqUmN7Zhvjn9M6+IazWIp3liVmiFrl/RywzT8u6BDEjgNlBshE2g5tFsggl4MEx6DCzrJLQUk4xgum2TJMNJnGGche5qMcYp2qAejBVqTdB43gc/TvrZRS17n+C7lnIZmbrqYdRX1uHei1lm4Ey0HQBNk67PYkIiMiRJHG8ZSaMszHjWxxHlIVAcMue3lrR6MaVVFPcs4QTaLnVHFEPWbkNM23DoCKM87bu4R6cN4hMwCzthjtqIsxQor4ubpmjLL21VFLti54L/msTf1ENdOqipD1Xu6LXdgc3S7s71+2bft3J5/08z4oJ8pM/JI0K7cvyIyqop6pu8Ke99AbOBO3hifNm/SHQ9MGnA4c+6a5ajEx99PRT1N3T+VcMAEyj+yaE4j9UaLU2ZP5BS3CdS1iH/LX/mj2J6/MFvHSU1v6wTOux9ImPdt1sCbnyaVWu/DGL05ZA4pXSbpmGKiV8XB0/2HxtdZXlbTh8RRlD20tO+uCvyBp0uyWbzBjmjm01VVrfO+gd2TUt28AIAAA==" } }, { "ID": "a7f698816766a65e", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/4yTICW1IiV6llR3cxlvCXirXkcG?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:37 GMT" ], "Etag": [ "/35mPTToGRSOe2xHaoijag==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/22RTW/CMAyG/4t3LdoH2w6VOECJoFLVslA2pGmHkJpSSOquSTcqxH9fyiZ1B5SD8yp+7NfOCQ5FmYEPmyL/bLBub3K0L92Fo2mUNS5UVBoED9CK3GXeDp/0Ik1pxpcJPhzngoq9yEcjl2HkDrUA/wTbAlVmwH8/QSk0OuwSPLBt1allysN45rSmrNPxKorGk4jB2euJRpueCOOUzRjvEc4WbJyy6X+kRtkTnAUJn17p4V2xtyFSPTpJkoiN42v+PtzxYE8bjlussZTYzVvVtEdpw26VZkdKtVqUgww1DSwaCxfi8vrYpmHwdh8Wr89K8aE8qq9gXdTrg+zWoUgKW1DpEldLNxlYskJx+nZmYQh/etK6oouaJBqDXdG73wYB6UqhdY5s3aAHUrgPmRcW/K1QBs8/T8bkgO4BAAA=" } }, { "ID": "05ce8bfa16bbaee1", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anon45da6c1e_b71e_45e9_8302_3fb1a2c7db5d/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:38 GMT" ], "Etag": [ "hoEQtF68hWR8Sjgk+/Q1RQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8pn5LsGlriZWWSEB1kEZ6Vna+sHGgYF2toCVZTklyTmBOWXFwOVGQP5RWBmdLVSGpgsAwonKtXqgFlQvoFSbSxUBFlZSVFpKkgGIokQT0LTbkia9mQ07UYEtcfWAgAAy5uSGQEAAA==" } }, { "ID": "00cfdf95526acab9", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs/4yTICW1IiV6llR3cxlvCXirXkcG?alt=json\u0026fields=status%2Cstatistics\u0026location=US\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:38 GMT" ], "Etag": [ "0lSl6hqGDmj6EW4bJ6khrg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41UbW/aMBD+K8jiwya1lRNeApH2oS+ZVq0MBKn6YaoikxytN8fJYqcdQvz3nW1SQkurCQHJPffcc74Xb4jSTHOleapIuCFpBfhayJjnQELiDQLfHwVBL6BeQE6Mc6XfYD71EAOZvUGG1EdEF5qJi7UGNauKFJSCDL0oIn9qqNZG1z7MBJMk/Lkhktk4C0rDzrTWZa3Rlzckm8REHQj1hn2Xwit7nxrGM+N6bs51/vRAQnrmjwaB19//Oo+JsjDx24wJ+/sRw8KWgYXLWhrO0ISkbQcXsnFwEYxDWuR4UtgH8V5sTZzglZslt91cNOP2XPF2LHr26gTezqUJPTzg7I79LsfpGI56rFcrAa5NtskIjIKjyKLkQrw0v4K0qDI1xzKgpbe33KGGBrkzlqxiyBLXEsPY7u6KIEBDNjuGmpmuzcvldDK7ieLI2qBUdrp+c2kE59H5lbHXywYiXS80o3fS6fqhrHOFD70QkzrrcpXIQieyFgKNfWtcFoXAAF/n00lHs6WABBdh7FF/lAyHYzocjCkd9/AvoZQG5H578qJt8rp1aR3I0074pTM5/x4li3h+exl/6vZNDp8PyHfz6yNUkzR+PVPZeNpJEizCA1CaFG6B7rf4wRXBVc8ZFu7oPiIGgkuwdQLBSoTsRvWGQbPIC1G47RuYUpe4c1w+3Epuq0/bvWmMHjHKlozt0txcMG+l370k9shFe3yW+ILKMYfK7sCR5FKWPsI3rkm4YkKBGbAVVCBTyGLTMDcPZVX8glRfm8DqsRBinTN5mkFenKKmuXoyppkC57F7/qjXRtoOhCX8x2iY8piZhRykjtelvfyim+gyJtsjB9vuJ3zjeGi/mv6IyHb7D65SoK3RBQAA" } }, { "ID": "01032ad8f0d10781", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0007/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:38 GMT" ], "Etag": [ "JgR2QcJCb27Nx/hOahTsUw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8p7pQcZBSZ7OScZmftV6Gf4J2aEFIeW29oCVZTklyTmBOWXFwOVGQD5RWBmdLVSGpgsAwonKtXqgFlQvoFSbSxUBFlZSVFpKkgGIokQT0LTbkia9mQ07UYEtcfWAgDAGmPnGQEAAA==" } }, { "ID": "cbee37495f0eaeba", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0007?alt=json\u0026fields=schema\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:38 GMT" ], "Etag": [ "SRdCDuNO1r3eNAp+7oGKQw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWKk7OSM1NVLKqVkrLTM1JKVayiq5WykvMTVWyglA6SiWVBSBecEiQp5+7Uq0OQr40txgh7+kX4uruGgQUyM1PAQkEuQa4Ooa4uiBrKUpNRugIcnX2D3IB8jGtTsrPz0EodPL393F19FOqjQXCWgCN1fK3tQAAAA==" } }, { "ID": "bf1bacedfc1135fb", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0007/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:38 GMT" ], "Etag": [ "JgR2QcJCb27Nx/hOahTsUw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8p7pQcZBSZ7OScZmftV6Gf4J2aEFIeW29oCVZTklyTmBOWXFwOVGQD5RWBmdLVSGpgsAwonKtXqgFlQvoFSbSxUBFlZSVFpKkgGIokQT0LTbkia9mQ07UYEtcfWAgDAGmPnGQEAAA==" } }, { "ID": "3f9e21e5ad8a6b35", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0007?alt=json\u0026fields=schema\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:38 GMT" ], "Etag": [ "SRdCDuNO1r3eNAp+7oGKQw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWKk7OSM1NVLKqVkrLTM1JKVayiq5WykvMTVWyglA6SiWVBSBecEiQp5+7Uq0OQr40txgh7+kX4uruGgQUyM1PAQkEuQa4Ooa4uiBrKUpNRugIcnX2D3IB8jGtTsrPz0EodPL393F19FOqjQXCWgCN1fK3tQAAAA==" } }, { "ID": "e0cc36762fd4ee1f", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0007/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:39 GMT" ], "Etag": [ "JgR2QcJCb27Nx/hOahTsUw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8p7pQcZBSZ7OScZmftV6Gf4J2aEFIeW29oCVZTklyTmBOWXFwOVGQD5RWBmdLVSGpgsAwonKtXqgFlQvoFSbSxUBFlZSVFpKkgGIokQT0LTbkia9mQ07UYEtcfWAgDAGmPnGQEAAA==" } }, { "ID": "892d67e651508440", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0007?alt=json\u0026fields=schema\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:39 GMT" ], "Etag": [ "SRdCDuNO1r3eNAp+7oGKQw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWKk7OSM1NVLKqVkrLTM1JKVayiq5WykvMTVWyglA6SiWVBSBecEiQp5+7Uq0OQr40txgh7+kX4uruGgQUyM1PAQkEuQa4Ooa4uiBrKUpNRugIcnX2D3IB8jGtTsrPz0EodPL393F19FOqjQXCWgCN1fK3tQAAAA==" } }, { "ID": "a9f2c96c0ac634ba", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0007?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:39 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6uuBQBDv6ajAgAAAA==" } }, { "ID": "ca1d768edd21972c", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "2077" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJleHBpcmF0aW9uVGltZSI6IjE1NzIyODgzMDcwMDAiLCJzY2hlbWEiOnsiZmllbGRzIjpbeyJtb2RlIjoiUkVRVUlSRUQiLCJuYW1lIjoiTmFtZSIsInR5cGUiOiJTVFJJTkcifSx7Im1vZGUiOiJSRVFVSVJFRCIsIm5hbWUiOiJCeXRlcyIsInR5cGUiOiJCWVRFUyJ9LHsibW9kZSI6IlJFUVVJUkVEIiwibmFtZSI6IkludGVnZXIiLCJ0eXBlIjoiSU5URUdFUiJ9LHsibW9kZSI6IlJFUVVJUkVEIiwibmFtZSI6IkZsb2F0IiwidHlwZSI6IkZMT0FUIn0seyJtb2RlIjoiUkVRVUlSRUQiLCJuYW1lIjoiQm9vbGVhbiIsInR5cGUiOiJCT09MRUFOIn0seyJtb2RlIjoiUkVRVUlSRUQiLCJuYW1lIjoiVGltZXN0YW1wIiwidHlwZSI6IlRJTUVTVEFNUCJ9LHsibW9kZSI6IlJFUVVJUkVEIiwibmFtZSI6IkRhdGUiLCJ0eXBlIjoiREFURSJ9LHsibW9kZSI6IlJFUVVJUkVEIiwibmFtZSI6IlRpbWUiLCJ0eXBlIjoiVElNRSJ9LHsibW9kZSI6IlJFUVVJUkVEIiwibmFtZSI6IkRhdGVUaW1lIiwidHlwZSI6IkRBVEVUSU1FIn0seyJtb2RlIjoiUkVRVUlSRUQiLCJuYW1lIjoiTnVtZXJpYyIsInR5cGUiOiJOVU1FUklDIn0seyJtb2RlIjoiUkVRVUlSRUQiLCJuYW1lIjoiR2VvZ3JhcGh5IiwidHlwZSI6IlNUUklORyJ9LHsibW9kZSI6IlJFUEVBVEVEIiwibmFtZSI6IlN0cmluZ0FycmF5IiwidHlwZSI6IlNUUklORyJ9LHsibW9kZSI6IlJFUEVBVEVEIiwibmFtZSI6IkludGVnZXJBcnJheSIsInR5cGUiOiJJTlRFR0VSIn0seyJtb2RlIjoiUkVQRUFURUQiLCJuYW1lIjoiRmxvYXRBcnJheSIsInR5cGUiOiJGTE9BVCJ9LHsibW9kZSI6IlJFUEVBVEVEIiwibmFtZSI6IkJvb2xlYW5BcnJheSIsInR5cGUiOiJCT09MRUFOIn0seyJtb2RlIjoiUkVQRUFURUQiLCJuYW1lIjoiVGltZXN0YW1wQXJyYXkiLCJ0eXBlIjoiVElNRVNUQU1QIn0seyJtb2RlIjoiUkVQRUFURUQiLCJuYW1lIjoiRGF0ZUFycmF5IiwidHlwZSI6IkRBVEUifSx7Im1vZGUiOiJSRVBFQVRFRCIsIm5hbWUiOiJUaW1lQXJyYXkiLCJ0eXBlIjoiVElNRSJ9LHsibW9kZSI6IlJFUEVBVEVEIiwibmFtZSI6IkRhdGVUaW1lQXJyYXkiLCJ0eXBlIjoiREFURVRJTUUifSx7Im1vZGUiOiJSRVBFQVRFRCIsIm5hbWUiOiJOdW1lcmljQXJyYXkiLCJ0eXBlIjoiTlVNRVJJQyJ9LHsibW9kZSI6IlJFUEVBVEVEIiwibmFtZSI6Ikdlb2dyYXBoeUFycmF5IiwidHlwZSI6IlNUUklORyJ9LHsiZmllbGRzIjpbeyJtb2RlIjoiUkVRVUlSRUQiLCJuYW1lIjoiU3RyaW5nIiwidHlwZSI6IlNUUklORyJ9LHsiZmllbGRzIjpbeyJtb2RlIjoiUkVRVUlSRUQiLCJuYW1lIjoiSW50ZWdlciIsInR5cGUiOiJJTlRFR0VSIn1dLCJtb2RlIjoiUkVRVUlSRUQiLCJuYW1lIjoiUmVjb3JkIiwidHlwZSI6IlJFQ09SRCJ9LHsiZmllbGRzIjpbeyJtb2RlIjoiUkVRVUlSRUQiLCJuYW1lIjoiSW50ZWdlciIsInR5cGUiOiJJTlRFR0VSIn1dLCJtb2RlIjoiUkVQRUFURUQiLCJuYW1lIjoiUmVjb3JkQXJyYXkiLCJ0eXBlIjoiUkVDT1JEIn1dLCJtb2RlIjoiUkVRVUlSRUQiLCJuYW1lIjoiUmVjb3JkIiwidHlwZSI6IlJFQ09SRCJ9LHsiZmllbGRzIjpbeyJtb2RlIjoiUkVRVUlSRUQiLCJuYW1lIjoiU3RyaW5nIiwidHlwZSI6IlNUUklORyJ9LHsiZmllbGRzIjpbeyJtb2RlIjoiUkVRVUlSRUQiLCJuYW1lIjoiSW50ZWdlciIsInR5cGUiOiJJTlRFR0VSIn1dLCJtb2RlIjoiUkVRVUlSRUQiLCJuYW1lIjoiUmVjb3JkIiwidHlwZSI6IlJFQ09SRCJ9LHsiZmllbGRzIjpbeyJtb2RlIjoiUkVRVUlSRUQiLCJuYW1lIjoiSW50ZWdlciIsInR5cGUiOiJJTlRFR0VSIn1dLCJtb2RlIjoiUkVQRUFURUQiLCJuYW1lIjoiUmVjb3JkQXJyYXkiLCJ0eXBlIjoiUkVDT1JEIn1dLCJtb2RlIjoiUkVQRUFURUQiLCJuYW1lIjoiUmVjb3JkQXJyYXkiLCJ0eXBlIjoiUkVDT1JEIn1dfSwidGFibGVSZWZlcmVuY2UiOnsiZGF0YXNldElkIjoiZGF0YXNldF8yMDE5MTAyOF82NjkwNjU5MDA5MzY1OV8wMDAxIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCIsInRhYmxlSWQiOiJ0YWJsZV8yMDE5MTAyOF82NjkwNjU5MDA5MzY1OV8wMDA4In19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:39 GMT" ], "Etag": [ "W0kLF+Aew/VCOw2KtSvzYA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/+2WUXOaQBSF/8v2sYkgxijM5AEVHaaoKWA7mU7H2cCKVGDpssZaJ/+9C0ExsEFt+tgn5u7cb8/hcljYgZUfuUABj773c43I9gOFjwECVwBR6LH1r+LKGH5U0Ub40p9upE/Uevr9oN7dsQ4/5ZIlDoJtCKNrF4X4mqKEKi6kMEF0LolNuSlK3fntrSzetmVRlFvsMhdFsdnIdOpaukwiQcHC8KMVE1pSGieKIOyNNjyMvQDB2E8aDg4P68KTJMQE/0AOTQSOOyF3lwjn2BQym4lwltusyUQLRFDkIKDsQG5Ef2NSjMlNZB3nGNrLZMAZrp7ZEJ0lCmFqZ+GjwE2A8m0HIhgyh2CSXtiW2zitLNvUJyNWh9hNa1P7PNNNbcB2ORC9LXNeIL0HW7PqCT2iyEOkYPSJrY00s54aBhjSghkaU9U+4QxjlofoyNt0amjqpJ6y/ZA9CRjGBWfrY82y1fF9PTmA9Gh2A9XWTiu9Fjm9/2sm1TjNTdYhIr5TYJPZWDP1fj01QtgjMF5uL4uDRYkfeSohsBa815h1XipKJCcaVTSLRgms5KOK5fkogZyQVNFDSEowNylVPH2SJbIcF74mR+60EgfkBacK58EpsZz0VNFDev4iCSZyMHELxtT6U3PAid0V5wB7yd9lmX2X4CWn2feKaGk8VeV8PO9X/rfa/8f85piZOojW4ct3UQEiyEoDR56NSHnZxJt95RAEqY+j7IhXQLPdkaRup9OSb27Snwn0K/ZJtaHbEjvsw84aApjQMXZ9dgduZY+2JB8dG2rPSF/9ADvZhmxpZoHnP5Sf6BD8CQAA" } }, { "ID": "3ad32e1bacd89174", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0008/insertAll?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "1350" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJyb3dzIjpbeyJpbnNlcnRJZCI6Ikt3RjJDT3FuenMwYUlOS3pKeXNQTmY3WVdkNCIsImpzb24iOnsiQm9vbGVhbiI6dHJ1ZSwiQm9vbGVhbkFycmF5IjpbdHJ1ZSxmYWxzZV0sIkJ5dGVzIjoiWW5sMFpRPT0iLCJEYXRlIjoiMjAxNi0wMy0yMCIsIkRhdGVBcnJheSI6WyIyMDE2LTAzLTIwIiwiMTk5NC0wNS0xNSJdLCJEYXRlVGltZSI6IjIwMTYtMDMtMjAgMTU6MDQ6MDUuMDAwMDA2IiwiRGF0ZVRpbWVBcnJheSI6WyIyMDE2LTAzLTIwIDE1OjA0OjA1LjAwMDAwNiIsIjE5OTQtMDUtMTUgMDE6MDI6MDQiXSwiRmxvYXQiOjMuMTQsIkZsb2F0QXJyYXkiOlsxLDEuNDFdLCJHZW9ncmFwaHkiOiJQT0lOVCgtMTIyLjM1MDIyMCA0Ny42NDkxNTQpIiwiR2VvZ3JhcGh5QXJyYXkiOlsiUE9JTlQoLTEyMi4zNTAyMjAgNDcuNjQ5MTU0KSIsIlBPSU5UKC0xMjIuMDgzNjc5MSAzNy40MjE4MjcpIl0sIkludGVnZXIiOjQyLCJJbnRlZ2VyQXJyYXkiOlsxLDJdLCJOYW1lIjoiYSIsIk51bWVyaWMiOiIwLjU3MDAwMDAwMCIsIk51bWVyaWNBcnJheSI6WyIwLjUwMDAwMDAwMCIsIjAuNjAwMDAwMDAwIl0sIlJlY29yZCI6eyJSZWNvcmQiOnsiSW50ZWdlciI6MjR9LCJSZWNvcmRBcnJheSI6W3siSW50ZWdlciI6MX0seyJJbnRlZ2VyIjoyfV0sIlN0cmluZyI6InN0cmluZyJ9LCJSZWNvcmRBcnJheSI6W3siUmVjb3JkIjp7IkludGVnZXIiOjB9LCJTdHJpbmciOiJlbXB0eSJ9LHsiUmVjb3JkIjp7IkludGVnZXIiOjF9LCJSZWNvcmRBcnJheSI6W3siSW50ZWdlciI6MX0seyJJbnRlZ2VyIjoyfV0sIlN0cmluZyI6ImZ1bGwifV0sIlN0cmluZ0FycmF5IjpbImEiLCJiIl0sIlRpbWUiOiIxNTowNDowNS4wMDAwMDYiLCJUaW1lQXJyYXkiOlsiMTU6MDQ6MDUuMDAwMDA2IiwiMDE6MDI6MDQiXSwiVGltZXN0YW1wIjoiMjAxNi0wMy0yMFQxNTowNDowNS4wMDAwMDZaIiwiVGltZXN0YW1wQXJyYXkiOlsiMjAxNi0wMy0yMFQxNTowNDowNS4wMDAwMDZaIiwiMTk5NC0wNS0xNVQwMTowMjowNFoiXX19LHsiaW5zZXJ0SWQiOiJ5YWdvZE93alBITHd5ZDlsM0hKZHZFbXZzdEMiLCJqc29uIjp7IkJvb2xlYW4iOmZhbHNlLCJCeXRlcyI6IllubDBaVEk9IiwiRGF0ZSI6IjIwMTYtMDMtMjAiLCJEYXRlVGltZSI6IjIwMTYtMDMtMjAgMTU6MDQ6MDUuMDAwMDA2IiwiRmxvYXQiOjQuMTMsIkdlb2dyYXBoeSI6IiIsIkludGVnZXIiOjI0LCJOYW1lIjoiYiIsIk51bWVyaWMiOiIwLjQ0OTkwMDAwMCIsIlJlY29yZCI6eyJSZWNvcmQiOnsiSW50ZWdlciI6MH0sIlN0cmluZyI6IiJ9LCJUaW1lIjoiMTU6MDQ6MDUuMDAwMDA2IiwiVGltZXN0YW1wIjoiMjAxNi0wMy0yMFQxNTowNDowNS4wMDAwMDZaIn19XX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:39 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTMK04tKnHMyQlKLS7IB3KUagGmFzWCLgAAAA==" } }, { "ID": "70d2cca5d44e0d9c", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0008?alt=json\u0026fields=schema\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:39 GMT" ], "Etag": [ "W0kLF+Aew/VCOw2KtSvzYA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/+3Uz2qDMADH8XfJ2SfwZmsqgRq7mB7G6CFoZgX/EbODiO++uolpk0xx3XGnksOnP4lf7EGbXHnJgNuD95wXaQvctx5UrOTABXj8cYDsmvEUU4JwcDuXdTqeCXw5IwJ9MDiz2HWSt4rsXimMlwWqJM+4UAZhCgNIltWhqJlU5nCMPLryZHVdcFbdPVsUHaGHlxXNS95KVjbKURTCmHrhaVn6TN7dne9RuL70OLL+/49m3Fh3+KPkIk8Uw+cQErRfVgGvM8Gaa7cth1iKvMo8IdgiPMHbo9uq0KQlDZN+paFBow+TTX1o0BKJSedINGwtxeTjm9Sknot90zK3vmSBtnBMPIWjWUs9Jp3r+UUJhCe1SJUhcB8R35KdY/mAffe3rdmnBrd8zS7GqHY95vJ0Pc8v/+32/zX/eM2XYfgEGv3PqmQHAAA=" } }, { "ID": "f7c0b0e8a9c60fa9", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0008/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:40 GMT" ], "Etag": [ "a468H12rjAJ6Z9aUebIkYg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/8VTXU+DMBT9K6a+uGQ0bbmUj4QHEx+cMX4FH7aFhxIZweGm0GmWZf9dhkrLgEVjjJCQc3vOvb09vWzQPF08IA9FafKyivP1sRRRFp8JKS7TQqIhiqVISl4Ad84pyx9PL/jEFfdxNJqPE98vFXIpRXa3fCtKGSnjvILTDZpV39dddbQdfqDxIiOTYOTXCwxqCJiadTATWRHXEQXLAYczsDDZPVzlE8oNYhqMKLHlEfDIAWnQJyEYwHXr8AtMw78CukuoY608VbhVSU081JWi6fGtrzwGVkMTU2W4zFf/YbFl18HN9egqODEoY9i0CGPkCGzMwaUWDGrz988XoW3Y5KhqoM1hrW0MtCVouPA5dvs1er2xueNy02aASSuryzfXBYNYBrXae/T5RT3CSupA+V6v1XZBb5nyPrS74S3+O1eki4hjctulR6aNgVGH2QNVUp/XQubpIumaeQb60LdoqrGNtGo9PJQaPz3L9U9+M10zW2VZVy79bbdh9b4DQMzT5osFAAA=" } }, { "ID": "f2262f6538de5759", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0008/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:40 GMT" ], "Etag": [ "a468H12rjAJ6Z9aUebIkYg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/8VTXU+DMBT9K6a+uGQ0bbmUj4QHEx+cMX4FH7aFhxIZweGm0GmWZf9dhkrLgEVjjJCQc3vOvb09vWzQPF08IA9FafKyivP1sRRRFp8JKS7TQqIhiqVISl4Ad84pyx9PL/jEFfdxNJqPE98vFXIpRXa3fCtKGSnjvILTDZpV39dddbQdfqDxIiOTYOTXCwxqCJiadTATWRHXEQXLAYczsDDZPVzlE8oNYhqMKLHlEfDIAWnQJyEYwHXr8AtMw78CukuoY608VbhVSU081JWi6fGtrzwGVkMTU2W4zFf/YbFl18HN9egqODEoY9i0CGPkCGzMwaUWDGrz988XoW3Y5KhqoM1hrW0MtCVouPA5dvs1er2xueNy02aASSuryzfXBYNYBrXae/T5RT3CSupA+V6v1XZBb5nyPrS74S3+O1eki4hjctulR6aNgVGH2QNVUp/XQubpIumaeQb60LdoqrGNtGo9PJQaPz3L9U9+M10zW2VZVy79bbdh9b4DQMzT5osFAAA=" } }, { "ID": "b9aa8b7ac378c11d", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0008?alt=json\u0026fields=schema\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:40 GMT" ], "Etag": [ "W0kLF+Aew/VCOw2KtSvzYA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/+3Uz2qDMADH8XfJ2SfwZmsqgRq7mB7G6CFoZgX/EbODiO++uolpk0xx3XGnksOnP4lf7EGbXHnJgNuD95wXaQvctx5UrOTABXj8cYDsmvEUU4JwcDuXdTqeCXw5IwJ9MDiz2HWSt4rsXimMlwWqJM+4UAZhCgNIltWhqJlU5nCMPLryZHVdcFbdPVsUHaGHlxXNS95KVjbKURTCmHrhaVn6TN7dne9RuL70OLL+/49m3Fh3+KPkIk8Uw+cQErRfVgGvM8Gaa7cth1iKvMo8IdgiPMHbo9uq0KQlDZN+paFBow+TTX1o0BKJSedINGwtxeTjm9Sknot90zK3vmSBtnBMPIWjWUs9Jp3r+UUJhCe1SJUhcB8R35KdY/mAffe3rdmnBrd8zS7GqHY95vJ0Pc8v/+32/zX/eM2XYfgEGv3PqmQHAAA=" } }, { "ID": "0cb1cee7003b654d", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0008?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:40 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6uuBQBDv6ajAgAAAA==" } }, { "ID": "446ee1667ae24250", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "667" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJleHBpcmF0aW9uVGltZSI6IjE1NzIyODgzMDcwMDAiLCJzY2hlbWEiOnsiZmllbGRzIjpbeyJuYW1lIjoiU3RyaW5nIiwidHlwZSI6IlNUUklORyJ9LHsibmFtZSI6IkJ5dGVzIiwidHlwZSI6IkJZVEVTIn0seyJuYW1lIjoiSW50ZWdlciIsInR5cGUiOiJJTlRFR0VSIn0seyJuYW1lIjoiRmxvYXQiLCJ0eXBlIjoiRkxPQVQifSx7Im5hbWUiOiJCb29sZWFuIiwidHlwZSI6IkJPT0xFQU4ifSx7Im5hbWUiOiJUaW1lc3RhbXAiLCJ0eXBlIjoiVElNRVNUQU1QIn0seyJuYW1lIjoiRGF0ZSIsInR5cGUiOiJEQVRFIn0seyJuYW1lIjoiVGltZSIsInR5cGUiOiJUSU1FIn0seyJuYW1lIjoiRGF0ZVRpbWUiLCJ0eXBlIjoiREFURVRJTUUifSx7Im5hbWUiOiJOdW1lcmljIiwidHlwZSI6Ik5VTUVSSUMifSx7Im5hbWUiOiJHZW9ncmFwaHkiLCJ0eXBlIjoiR0VPR1JBUEhZIn0seyJmaWVsZHMiOlt7Im5hbWUiOiJYIiwidHlwZSI6IklOVEVHRVIifV0sIm5hbWUiOiJSZWNvcmQiLCJ0eXBlIjoiUkVDT1JEIn1dfSwidGFibGVSZWZlcmVuY2UiOnsiZGF0YXNldElkIjoiZGF0YXNldF8yMDE5MTAyOF82NjkwNjU5MDA5MzY1OV8wMDAxIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCIsInRhYmxlSWQiOiJ0YWJsZV8yMDE5MTAyOF82NjkwNjU5MDA5MzY1OV8wMDA5In19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:40 GMT" ], "Etag": [ "LlogGDUyln0N6GmOz/nUhw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42TbW+bMBCA/4v3tQ0OWfOC1A+koQyJQEWI1GqaIhcuxCvYzHbWsWj/fYYmhSTdFPEB3fHc3cMZduiFshRZ6JlmP7Ygqk+KPOeArhAokum8n/PMnS2rnOFg6Bbhb4MtN6+3t5qgdZ3c8DyvCsKuUyj4tQKprJQoIkGtTNyf9LE5Xg2HEzy8mWA8GejbCmPc7zVz/odM9AgJ+dqn7EUP2ihVSsswDqK9jPMsB1JS2Ut48Z43fppGKfh3SJQ0PrAz9nbSuETTaDSlcZFtA0WwBgEsAWTt0F7E+8emdM1eoiEuETqMaQousPqjl5hsoCC1zppCnkpkfd0hRgptiBZKUJbVTauyiePIC1xd9U5MK23aAtOn2Fl0n3tMQQaiJbwgdlwn6jL3OSeqJe790I6PZnCuT5J1poSh79hBl4lpoTdGirKlYm/uLGJ7/tDlZkRBi8zs2DntctzgtPaYqOtPqWBbgKBJCwXLuRN5d13GBZ4JUm6qlnKd0I3shy9PXS6ChIu0hSLnLoxmOj4/qscPVvxNX1eIbYu3U7IQRk3oc5bFIE7TEX89RIkAoihnzetaqH8zMs3xaPQZDwdm/ff/Kqk4B8YDPNKflQZyItWcp1R7pmc9RgPcWbI99Z26gidNQ51a6i/oL5C6dZJ6BAAA" } }, { "ID": "19afe4a505946726", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0009/insertAll?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "207" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJyb3dzIjpbeyJpbnNlcnRJZCI6InJZNUFWUXpJVlF4V1JFTFFEYzdCZjFHWjJDcyIsImpzb24iOnsiQm9vbGVhbiI6bnVsbCwiQnl0ZXMiOm51bGwsIkRhdGUiOm51bGwsIkRhdGVUaW1lIjpudWxsLCJGbG9hdCI6bnVsbCwiR2VvZ3JhcGh5IjpudWxsLCJJbnRlZ2VyIjpudWxsLCJTdHJpbmciOm51bGwsIlRpbWUiOm51bGwsIlRpbWVzdGFtcCI6bnVsbH19XX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:40 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTMK04tKnHMyQlKLS7IB3KUagGmFzWCLgAAAA==" } }, { "ID": "d01641ed7408ddd6", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0009/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:41 GMT" ], "Etag": [ "nh/yC0Of4zcCB0TxUk2s5g==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8rnZehXOhv4p5lUJTs7GYRUhGYbFZum29oCVZTklyTmBOWXFwOVGQD5RWBmdLVSGpgsU7LKK83JqdUZKGYsEAIASQ+aU+gAAAA=" } }, { "ID": "994533755987eab3", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0009?alt=json\u0026fields=schema\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:41 GMT" ], "Etag": [ "LlogGDUyln0N6GmOz/nUhw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/23RwWrDMAwA0H/RuV+Qm9uonqGxi+PBytjBpFoaiOPguIcQ+u/rdpidbOgk9CSBtMDU3MhZKBb47Ki/TlC8LzBYR1BAHUM3tLCDOI8/udFCcnjsfsV+jjQlsL8YrPO6GCK1FJIQ0iBHnZtj721M4nhSzKx2eN+THbItSp2QydyYztEUrRuTMqLC2rDqnLvSRkqkZAa3U9YDtr1r8d2/VfLuKHRNQvK1Qi0OueHk22DH25wUR8U1O79ccqep8eGakMaD0uUz//uqt39O/PGMxxcmuQC34gEAAA==" } }, { "ID": "cdb966ca9b1fc949", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0009/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:41 GMT" ], "Etag": [ "nh/yC0Of4zcCB0TxUk2s5g==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8rnZehXOhv4p5lUJTs7GYRUhGYbFZum29oCVZTklyTmBOWXFwOVGQD5RWBmdLVSGpgsU7LKK83JqdUZKGYsEAIASQ+aU+gAAAA=" } }, { "ID": "30636bb05db80032", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0009?alt=json\u0026fields=schema\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:41 GMT" ], "Etag": [ "LlogGDUyln0N6GmOz/nUhw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/23RwWrDMAwA0H/RuV+Qm9uonqGxi+PBytjBpFoaiOPguIcQ+u/rdpidbOgk9CSBtMDU3MhZKBb47Ki/TlC8LzBYR1BAHUM3tLCDOI8/udFCcnjsfsV+jjQlsL8YrPO6GCK1FJIQ0iBHnZtj721M4nhSzKx2eN+THbItSp2QydyYztEUrRuTMqLC2rDqnLvSRkqkZAa3U9YDtr1r8d2/VfLuKHRNQvK1Qi0OueHk22DH25wUR8U1O79ccqep8eGakMaD0uUz//uqt39O/PGMxxcmuQC34gEAAA==" } }, { "ID": "cf7b1f678bd34d5a", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0009/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:42 GMT" ], "Etag": [ "nh/yC0Of4zcCB0TxUk2s5g==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8rnZehXOhv4p5lUJTs7GYRUhGYbFZum29oCVZTklyTmBOWXFwOVGQD5RWBmdLVSGpgsU7LKK83JqdUZKGYsEAIASQ+aU+gAAAA=" } }, { "ID": "40b537bd9ad8dcdd", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0009?alt=json\u0026fields=schema\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:41 GMT" ], "Etag": [ "LlogGDUyln0N6GmOz/nUhw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/23RwWrDMAwA0H/RuV+Qm9uonqGxi+PBytjBpFoaiOPguIcQ+u/rdpidbOgk9CSBtMDU3MhZKBb47Ki/TlC8LzBYR1BAHUM3tLCDOI8/udFCcnjsfsV+jjQlsL8YrPO6GCK1FJIQ0iBHnZtj721M4nhSzKx2eN+THbItSp2QydyYztEUrRuTMqLC2rDqnLvSRkqkZAa3U9YDtr1r8d2/VfLuKHRNQvK1Qi0OueHk22DH25wUR8U1O79ccqep8eGakMaD0uUz//uqt39O/PGMxxcmuQC34gEAAA==" } }, { "ID": "c979e263c9592f62", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0009?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:42 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6uuBQBDv6ajAgAAAA==" } }, { "ID": "fb5501deddc50357", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "667" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJleHBpcmF0aW9uVGltZSI6IjE1NzIyODgzMDcwMDAiLCJzY2hlbWEiOnsiZmllbGRzIjpbeyJuYW1lIjoiU3RyaW5nIiwidHlwZSI6IlNUUklORyJ9LHsibmFtZSI6IkJ5dGVzIiwidHlwZSI6IkJZVEVTIn0seyJuYW1lIjoiSW50ZWdlciIsInR5cGUiOiJJTlRFR0VSIn0seyJuYW1lIjoiRmxvYXQiLCJ0eXBlIjoiRkxPQVQifSx7Im5hbWUiOiJCb29sZWFuIiwidHlwZSI6IkJPT0xFQU4ifSx7Im5hbWUiOiJUaW1lc3RhbXAiLCJ0eXBlIjoiVElNRVNUQU1QIn0seyJuYW1lIjoiRGF0ZSIsInR5cGUiOiJEQVRFIn0seyJuYW1lIjoiVGltZSIsInR5cGUiOiJUSU1FIn0seyJuYW1lIjoiRGF0ZVRpbWUiLCJ0eXBlIjoiREFURVRJTUUifSx7Im5hbWUiOiJOdW1lcmljIiwidHlwZSI6Ik5VTUVSSUMifSx7Im5hbWUiOiJHZW9ncmFwaHkiLCJ0eXBlIjoiR0VPR1JBUEhZIn0seyJmaWVsZHMiOlt7Im5hbWUiOiJYIiwidHlwZSI6IklOVEVHRVIifV0sIm5hbWUiOiJSZWNvcmQiLCJ0eXBlIjoiUkVDT1JEIn1dfSwidGFibGVSZWZlcmVuY2UiOnsiZGF0YXNldElkIjoiZGF0YXNldF8yMDE5MTAyOF82NjkwNjU5MDA5MzY1OV8wMDAxIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCIsInRhYmxlSWQiOiJ0YWJsZV8yMDE5MTAyOF82NjkwNjU5MDA5MzY1OV8wMDEwIn19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:42 GMT" ], "Etag": [ "PMfCB7YDCQa3Nn7uDu/xiQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42TUW/aMBCA/4v32hInaQlE6kOAlEWCQEMqDU0TcpMjeE3szDZbEdp/n5NBE6CbUB7QHd/dfTk7e/RKWYpc9EKzH1sQu0+KvOSAbhAokun8fLoeDpzlaPhE7JA529HWeKNPDw+aoFWd3PA83xWE3aZQ8FsFUrkpUUSCWlnY7JvY6q263T7u3vcx7tv6Z4UxNjv1nP8gJtYjJOTrCWWvetBGqVK6hnEU7WScZzmQkspOwov3vPHTMkrBv0OipPGBnXGwk8Y1mkatKY2rbGsogjUIYAkgd48OIsE/NqVrDhI1cY3QcUxdcIXVb73EZAMFqXTWFPJUIvfrHjFSaEO0UIKyrGq6K+s4joJwrKveicFOmzbAYBn7i/b/AVOQgWiIIIz9sR+1mcecE9UQj5OZF5/M4FyfJGtNmc0mvhe2mZgWemOkKBsqDqb+Ivam8zY3IgoaZOTF/nmX0wbntadEVX9OhdsCBE0aKHye+lEwbDNj4Jkg5WbXUGN/No68+edlm4sg4SJtoMgfzqKRji+P6ssHK/6mnxvEtsXfU3JRdQ11OOEsi0GcpyP+6xglAoiinNWv6yLz3rGsnuPcWbbdq77+t5KKS6BnY0ffQg3kRKopT6n2TC963Nm4tWRvMPGrCp7UDXXqWd+gP2X4FNJ6BAAA" } }, { "ID": "ed2779d65db61dd9", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0010/insertAll?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "207" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJyb3dzIjpbeyJpbnNlcnRJZCI6IjdRMmZBM0QzNG9EN0o5cFNmUDZVc3I0VkEzNCIsImpzb24iOnsiQm9vbGVhbiI6bnVsbCwiQnl0ZXMiOm51bGwsIkRhdGUiOm51bGwsIkRhdGVUaW1lIjpudWxsLCJGbG9hdCI6bnVsbCwiR2VvZ3JhcGh5IjpudWxsLCJJbnRlZ2VyIjpudWxsLCJTdHJpbmciOm51bGwsIlRpbWUiOm51bGwsIlRpbWVzdGFtcCI6bnVsbH19XX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:42 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTMK04tKnHMyQlKLS7IB3KUagGmFzWCLgAAAA==" } }, { "ID": "61df195aaa5fc1bb", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0010?alt=json\u0026fields=schema\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:42 GMT" ], "Etag": [ "PMfCB7YDCQa3Nn7uDu/xiQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/23RwWrDMAwA0H/RuV+Qm9uonqGxi+PBytjBpFoaiOPguIcQ+u/rdpidbOgk9CSBtMDU3MhZKBb47Ki/TlC8LzBYR1BAHUM3tLCDOI8/udFCcnjsfsV+jjQlsL8YrPO6GCK1FJIQ0iBHnZtj721M4nhSzKx2eN+THbItSp2QydyYztEUrRuTMqLC2rDqnLvSRkqkZAa3U9YDtr1r8d2/VfLuKHRNQvK1Qi0OueHk22DH25wUR8U1O79ccqep8eGakMaD0uUz//uqt39O/PGMxxcmuQC34gEAAA==" } }, { "ID": "986acf56a18b37a1", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0010/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:42 GMT" ], "Etag": [ "wIC4LkcvUWLDDKbQ80B2PA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8qXezqb+GQnl4WG+7i4eCcFWhg4GQU42toCVZTklyTmBOWXFwOVGQD5RWBmdLVSGpgsU7LKK83JqdUZKGYsEAIAUG9l1ugAAAA=" } }, { "ID": "d530bfd23d74d044", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0010/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:43 GMT" ], "Etag": [ "wIC4LkcvUWLDDKbQ80B2PA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8qXezqb+GQnl4WG+7i4eCcFWhg4GQU42toCVZTklyTmBOWXFwOVGQD5RWBmdLVSGpgsU7LKK83JqdUZKGYsEAIAUG9l1ugAAAA=" } }, { "ID": "930383573429ad49", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0010?alt=json\u0026fields=schema\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:43 GMT" ], "Etag": [ "PMfCB7YDCQa3Nn7uDu/xiQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/23RwWrDMAwA0H/RuV+Qm9uonqGxi+PBytjBpFoaiOPguIcQ+u/rdpidbOgk9CSBtMDU3MhZKBb47Ki/TlC8LzBYR1BAHUM3tLCDOI8/udFCcnjsfsV+jjQlsL8YrPO6GCK1FJIQ0iBHnZtj721M4nhSzKx2eN+THbItSp2QydyYztEUrRuTMqLC2rDqnLvSRkqkZAa3U9YDtr1r8d2/VfLuKHRNQvK1Qi0OueHk22DH25wUR8U1O79ccqep8eGakMaD0uUz//uqt39O/PGMxxcmuQC34gEAAA==" } }, { "ID": "9eaacda204d03b05", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0010/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:43 GMT" ], "Etag": [ "wIC4LkcvUWLDDKbQ80B2PA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8qXezqb+GQnl4WG+7i4eCcFWhg4GQU42toCVZTklyTmBOWXFwOVGQD5RWBmdLVSGpgsU7LKK83JqdUZKGYsEAIAUG9l1ugAAAA=" } }, { "ID": "4b2c8e4216cfc48e", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0010?alt=json\u0026fields=schema\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:43 GMT" ], "Etag": [ "PMfCB7YDCQa3Nn7uDu/xiQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/23RwWrDMAwA0H/RuV+Qm9uonqGxi+PBytjBpFoaiOPguIcQ+u/rdpidbOgk9CSBtMDU3MhZKBb47Ki/TlC8LzBYR1BAHUM3tLCDOI8/udFCcnjsfsV+jjQlsL8YrPO6GCK1FJIQ0iBHnZtj721M4nhSzKx2eN+THbItSp2QydyYztEUrRuTMqLC2rDqnLvSRkqkZAa3U9YDtr1r8d2/VfLuKHRNQvK1Qi0OueHk22DH25wUR8U1O79ccqep8eGakMaD0uUz//uqt39O/PGMxxcmuQC34gEAAA==" } }, { "ID": "96d76d9aa89a3f61", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0010?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:43 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6uuBQBDv6ajAgAAAA==" } }, { "ID": "7b74af6b043ff349", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "667" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJleHBpcmF0aW9uVGltZSI6IjE1NzIyODgzMDcwMDAiLCJzY2hlbWEiOnsiZmllbGRzIjpbeyJuYW1lIjoiU3RyaW5nIiwidHlwZSI6IlNUUklORyJ9LHsibmFtZSI6IkJ5dGVzIiwidHlwZSI6IkJZVEVTIn0seyJuYW1lIjoiSW50ZWdlciIsInR5cGUiOiJJTlRFR0VSIn0seyJuYW1lIjoiRmxvYXQiLCJ0eXBlIjoiRkxPQVQifSx7Im5hbWUiOiJCb29sZWFuIiwidHlwZSI6IkJPT0xFQU4ifSx7Im5hbWUiOiJUaW1lc3RhbXAiLCJ0eXBlIjoiVElNRVNUQU1QIn0seyJuYW1lIjoiRGF0ZSIsInR5cGUiOiJEQVRFIn0seyJuYW1lIjoiVGltZSIsInR5cGUiOiJUSU1FIn0seyJuYW1lIjoiRGF0ZVRpbWUiLCJ0eXBlIjoiREFURVRJTUUifSx7Im5hbWUiOiJOdW1lcmljIiwidHlwZSI6Ik5VTUVSSUMifSx7Im5hbWUiOiJHZW9ncmFwaHkiLCJ0eXBlIjoiR0VPR1JBUEhZIn0seyJmaWVsZHMiOlt7Im5hbWUiOiJYIiwidHlwZSI6IklOVEVHRVIifV0sIm5hbWUiOiJSZWNvcmQiLCJ0eXBlIjoiUkVDT1JEIn1dfSwidGFibGVSZWZlcmVuY2UiOnsiZGF0YXNldElkIjoiZGF0YXNldF8yMDE5MTAyOF82NjkwNjU5MDA5MzY1OV8wMDAxIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCIsInRhYmxlSWQiOiJ0YWJsZV8yMDE5MTAyOF82NjkwNjU5MDA5MzY1OV8wMDExIn19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:43 GMT" ], "Etag": [ "l0WxJ0QYhQ6Nqv7MErhT9g==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42SbW+bMBCA/4v3tQ2GLG9I/UAaN2NKSEuoumiaIhcu4BUwtZ22UbT/PkOTQpJuiviA7nju7uHsLXpieYRs9Mji5zWIzRdFH1NAFwgUjXU+xQ9v3/HdIrnres8vvSkRSTCIr640wco6mfA03WQ0v4wg45cKpLIjqqgEtbSwOTCx1V92uwPc7QwwHrT1a4kxNlvVnP8gpqlHSEhXE5Y/6UGJUoW0DWMv2oo5j1OgBZOtkGcfeePFMgrBf0OopPGJnbGzk8Y5mkalKY2zbCvIhxUIyENA9hbtRNx/bErX7CQq4hyh/Ziq4AyrP3qJYQIZLXVWDNJIIvvnFuU004ZorgTL47LppqjiwHe9sa76IIYbbVoDw0VA5s3vbq4gBlETrheQMfGbzE3KqaqJm8nMCQ5mcK5PMm9Mmc0mxPGaTMAyvTGaFTUVuFMyD5zpbZMbUQU1MnICctzlsMFx7SFR1h9T3joDwcIa8u6nxHevm8wYeCxokWxqakxmY9+5/bZocj6EXEQ15JPrmT/S8elR/fhkxb/0c4HydfZ+SjbCqAonPI8DEMdpn7/uo1AAVYzn1e/ayOz0LKvf631td9rlHYO3golToN/GPX0LNZBSqaY8YtozOunRbVuNJTvDCSkreFg11Kl7fYP+AmFW7WF6BAAA" } }, { "ID": "dc31bfdb538f69ed", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0011/insertAll?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "344" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJyb3dzIjpbeyJpbnNlcnRJZCI6Imp0YVhyNUQyblQxcUZaTzY3SHFXSTE1VmJDNSIsImpzb24iOnsiQm9vbGVhbiI6dHJ1ZSwiQnl0ZXMiOiJBUUlEIiwiRGF0ZSI6IjIwMTYtMTEtMDUiLCJEYXRlVGltZSI6IjIwMTYtMTEtMDUgMTU6MDQ6MDUuMDAwMDA2IiwiRmxvYXQiOjIuMywiR2VvZ3JhcGh5IjoiUE9JTlQoLTEyMi4xOTg5MzkgNDcuNjY5ODY1KSIsIkludGVnZXIiOjEsIk51bWVyaWMiOiIwLjMzMDAwMDAwMCIsIlJlY29yZCI6eyJYIjo0fSwiU3RyaW5nIjoieCIsIlRpbWUiOiIxNTowNDowNS4wMDAwMDYiLCJUaW1lc3RhbXAiOiIyMDE2LTExLTA1VDA3OjUwOjIyLjAwMDAwMDAwOFoifX1dfQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:43 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTMK04tKnHMyQlKLS7IB3KUagGmFzWCLgAAAA==" } }, { "ID": "ca42cb8c1b6078e7", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0011/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:44 GMT" ], "Etag": [ "kEU0nDtnorkiHoSe7huI5g==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/3WPywrCMBBFf0XiRsGGiWnSB3QhVLAgPutKXESMtbS0WFMfSP/dqNi60GEY7p05cJk7SuJsh1y0jaNjKYtbW4ltKn2hxDg+KdRDUolI35PhCjJfZXmRxKN8Ka1DGbDI8zShciXSRX45aQy0L15yfUf71zzr9RVVvbcazAO/NqRWfUxrrYpSNohp2ZT2dWFoaCDcIMQA1nDMBdMFhuFZ/Aca/kMA0yZ8Ng0mYccgOo84tkOdlmlhzh2bs+4H+v7MRNWm0r2pHvDdH2VLAQAA" } }, { "ID": "641f5cdebbe03252", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0011?alt=json\u0026fields=schema\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:44 GMT" ], "Etag": [ "l0WxJ0QYhQ6Nqv7MErhT9g==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/23RwWrDMAwA0H/RuV+Qm9uonqGxi+PBytjBpFoaiOPguIcQ+u/rdpidbOgk9CSBtMDU3MhZKBb47Ki/TlC8LzBYR1BAHUM3tLCDOI8/udFCcnjsfsV+jjQlsL8YrPO6GCK1FJIQ0iBHnZtj721M4nhSzKx2eN+THbItSp2QydyYztEUrRuTMqLC2rDqnLvSRkqkZAa3U9YDtr1r8d2/VfLuKHRNQvK1Qi0OueHk22DH25wUR8U1O79ccqep8eGakMaD0uUz//uqt39O/PGMxxcmuQC34gEAAA==" } }, { "ID": "8d97bc62cc5076ab", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0011?alt=json\u0026fields=schema\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:44 GMT" ], "Etag": [ "l0WxJ0QYhQ6Nqv7MErhT9g==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/23RwWrDMAwA0H/RuV+Qm9uonqGxi+PBytjBpFoaiOPguIcQ+u/rdpidbOgk9CSBtMDU3MhZKBb47Ki/TlC8LzBYR1BAHUM3tLCDOI8/udFCcnjsfsV+jjQlsL8YrPO6GCK1FJIQ0iBHnZtj721M4nhSzKx2eN+THbItSp2QydyYztEUrRuTMqLC2rDqnLvSRkqkZAa3U9YDtr1r8d2/VfLuKHRNQvK1Qi0OueHk22DH25wUR8U1O79ccqep8eGakMaD0uUz//uqt39O/PGMxxcmuQC34gEAAA==" } }, { "ID": "282c22bdc2ba11d4", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0011/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:44 GMT" ], "Etag": [ "kEU0nDtnorkiHoSe7huI5g==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/3WPywrCMBBFf0XiRsGGiWnSB3QhVLAgPutKXESMtbS0WFMfSP/dqNi60GEY7p05cJk7SuJsh1y0jaNjKYtbW4ltKn2hxDg+KdRDUolI35PhCjJfZXmRxKN8Ka1DGbDI8zShciXSRX45aQy0L15yfUf71zzr9RVVvbcazAO/NqRWfUxrrYpSNohp2ZT2dWFoaCDcIMQA1nDMBdMFhuFZ/Aca/kMA0yZ8Ng0mYccgOo84tkOdlmlhzh2bs+4H+v7MRNWm0r2pHvDdH2VLAQAA" } }, { "ID": "7f78f3bc04f23a0c", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0011/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:45 GMT" ], "Etag": [ "kEU0nDtnorkiHoSe7huI5g==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/3WPywrCMBBFf0XiRsGGiWnSB3QhVLAgPutKXESMtbS0WFMfSP/dqNi60GEY7p05cJk7SuJsh1y0jaNjKYtbW4ltKn2hxDg+KdRDUolI35PhCjJfZXmRxKN8Ka1DGbDI8zShciXSRX45aQy0L15yfUf71zzr9RVVvbcazAO/NqRWfUxrrYpSNohp2ZT2dWFoaCDcIMQA1nDMBdMFhuFZ/Aca/kMA0yZ8Ng0mYccgOo84tkOdlmlhzh2bs+4H+v7MRNWm0r2pHvDdH2VLAQAA" } }, { "ID": "29d94ea00cc7cd50", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0011?alt=json\u0026fields=schema\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:45 GMT" ], "Etag": [ "l0WxJ0QYhQ6Nqv7MErhT9g==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/23RwWrDMAwA0H/RuV+Qm9uonqGxi+PBytjBpFoaiOPguIcQ+u/rdpidbOgk9CSBtMDU3MhZKBb47Ki/TlC8LzBYR1BAHUM3tLCDOI8/udFCcnjsfsV+jjQlsL8YrPO6GCK1FJIQ0iBHnZtj721M4nhSzKx2eN+THbItSp2QydyYztEUrRuTMqLC2rDqnLvSRkqkZAa3U9YDtr1r8d2/VfLuKHRNQvK1Qi0OueHk22DH25wUR8U1O79ccqep8eGakMaD0uUz//uqt39O/PGMxxcmuQC34gEAAA==" } }, { "ID": "c38f590e1aacba44", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0011?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:45 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6uuBQBDv6ajAgAAAA==" } }, { "ID": "def7df2ab3b7858c", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "366" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJleHBpcmF0aW9uVGltZSI6IjE1NzIyODgzMDcwMDAiLCJzY2hlbWEiOnsiZmllbGRzIjpbeyJuYW1lIjoibmFtZSIsInR5cGUiOiJTVFJJTkcifSx7Im1vZGUiOiJSRVBFQVRFRCIsIm5hbWUiOiJudW1zIiwidHlwZSI6IklOVEVHRVIifSx7ImZpZWxkcyI6W3sibmFtZSI6ImJvb2wiLCJ0eXBlIjoiQk9PTEVBTiJ9XSwibmFtZSI6InJlYyIsInR5cGUiOiJSRUNPUkQifV19LCJ0YWJsZVJlZmVyZW5jZSI6eyJkYXRhc2V0SWQiOiJkYXRhc2V0XzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDEiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0IiwidGFibGVJZCI6InRhYmxlXzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMTIifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:45 GMT" ], "Etag": [ "1i0CY1MkXrbTixhAJOUBRQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42S0U7CQBBF/2V9FXZbhEITHig2BoOgtSYaY8jSDmWl7dbuqhDCvzutYI2oafqwmTv3zpxMuiUrkYbEJnMRvbxCvjnRfB4DOSWgeYS6Idjwwbha3edzX6yXg8vpnePd9PvoEEVOLWUcbxKeNkJIZEOD0nbINVegZyYzegYzu7NOp8c67R5jvRY+M8aY0Sz3/GMxTFyhIF6MRbrCRUutM2VTegBtRlJGMfBMqGYgky+dvpk0y+UzBFrRX+jonk7ROpi0xFS0Fm1p8mABOaQBEHtL9iCjPy6FmT1E6agDdFhTBmpQ7fCIwRISXuAsBMShIvbjlqQ8QcLPB0dusqK69b3R5AIzVf81UVV/NPHdC9dDIZFhIXjutTvw3fPvkRyCKuG5w6l3jvXx6rmUcWV0ptOxO5iQ3RN+p8VeZ4Mnwg4jZTmWaeRD/lP25PuhCnLgWsjUF+V8o22ZZteyztqdtlX80OtM5MeGbotZeFg0xFzpKxkKRA2PZlimVcH6A2fsFgkZlANRursluw9+EJdSTQMAAA==" } }, { "ID": "003b5be24f39193c", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0012?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:45 GMT" ], "Etag": [ "1i0CY1MkXrbTixhAJOUBRQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42S0U7CQBBF/2V9FXZbhEITHig2BoOgtSYaY8jSDmWl7dbuqhDCvzutYI2oafqwmTv3zpxMuiUrkYbEJnMRvbxCvjnRfB4DOSWgeYS6Idjwwbha3edzX6yXg8vpnePd9PvoEEVOLWUcbxKeNkJIZEOD0nbINVegZyYzegYzu7NOp8c67R5jvRY+M8aY0Sz3/GMxTFyhIF6MRbrCRUutM2VTegBtRlJGMfBMqGYgky+dvpk0y+UzBFrRX+jonk7ROpi0xFS0Fm1p8mABOaQBEHtL9iCjPy6FmT1E6agDdFhTBmpQ7fCIwRISXuAsBMShIvbjlqQ8QcLPB0dusqK69b3R5AIzVf81UVV/NPHdC9dDIZFhIXjutTvw3fPvkRyCKuG5w6l3jvXx6rmUcWV0ptOxO5iQ3RN+p8VeZ4Mnwg4jZTmWaeRD/lP25PuhCnLgWsjUF+V8o22ZZteyztqdtlX80OtM5MeGbotZeFg0xFzpKxkKRA2PZlimVcH6A2fsFgkZlANRursluw9+EJdSTQMAAA==" } }, { "ID": "d00dd89cc00f0049", "Request": { "Method": "PATCH", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0012?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "78" ], "If-Match": [ "1i0CY1MkXrbTixhAJOUBRQ==" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJkZXNjcmlwdGlvbiI6Im1vcmUiLCJleHBpcmF0aW9uVGltZSI6IjE1NzIzNzQ3MDcwMDAiLCJmcmllbmRseU5hbWUiOiJtb3JlIn0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:46 GMT" ], "Etag": [ "/i1JBShzIyD2yYicBdiZdw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42SUW/aMBSF/4v3SrGTQgKR+kBGVDExmEL20FYTMvYleE3izHbXZoj/PjuDZqLdhPJg3etz7vlsZ48eRcVRhDYi//EEqvlg6KYA1ENgaG77WHif4tXu16yZ+s2dYDEX9/z55sYqhPPpnSyKpqTVFYdSXhnQJuLUUA1m7RNv7BF/tA6CMQmGY0LG13ZZE0K8fpvzH4nn2wgNxXYuqkcbtDOm1hHGJ9B+LmVeAK2F7jNZvvbxTx/XSn4HZjR+hw4f6TS+BBO3mBpfRNuKUtiCgooBivboCDL7x01ZzxGiVVwCdIppDRdQHXpoqwRUvGgWtLRQqJTKvS8HzZSojZBV19RsByV15FsBBdcoetij6o+vXWx6U7tqlaWzxa0d3+0/lbrbny2y5DZJbaOU3DXS5EsyyZLp3xYFrHOkycdlOrX12+iNlEUnjJfLeTJZoMM3+/VcbtzY27Q7BLXlXFZ5Buq8ncrnU8UUUHfyTLTzvWHo+6MwHAyDYej+/ZdaqHPBdTgISWjfwAoKqs1nyYVF5eczgoE36mCzSTxPnEMyerzrryt0+A1hq4lUeAMAAA==" } }, { "ID": "60c0b980faae6d42", "Request": { "Method": "PATCH", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0012?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "21" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJmcmllbmRseU5hbWUiOiJ4In0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:46 GMT" ], "Etag": [ "tdQ8f+rEaSgmViqeU7Navg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42SX2+bMBTFv4v3uDQYWiBB6kOyWlWkjKyE7mWaIgdfiFeDqe12RVG++2yWjCn7o4gH616fc8/PNnv0xBuGErTl1fMLqO6doVsBaITA0Mr2DXuYlO8Voeuq/syf4TFO6Wt1e2sV3Pn0TgrR1bS5YlDLKwPaJIwaqsFsAuxPfRxMNlE0xVE4xXh6bZcNxtgf9zn/kfiBjdAgyiVvnmzQzphWJ553Ah1XUlYCaMv1uJD1r773Gnitkt+gMNr7C513pNPeJZhej6m9i2h7UQYlKGgKQMkeHUEW/7gp6zlC9IpLgE4xveECqsMIlYpDw0SX0tpCoTeXCrpQvDVcNrZTS+VeXBc7qKnDLjkIplHyZY+an6Z+sdFd66p1ni3Sezt72H+p9bC/SHNyTzLbqCVzjYx8IrOc3P1uUVAMjox8WGV3tv4zeiulGITz1WpJZik6fLXfyOXOO3uVdgejvlzKpspBnbcz+f1UFQqoO3nO+/l+GAfBJI5vwiiM3Y//1nJ1LriOb2Ic2wewAkG1+SgZt6jsfEYUB+EAm8/mS+IcsqDHu35co8MP7+RIO3UDAAA=" } }, { "ID": "fc7268185c0ac1a9", "Request": { "Method": "PATCH", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0012?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "21" ], "If-Match": [ "/i1JBShzIyD2yYicBdiZdw==" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJmcmllbmRseU5hbWUiOiJ5In0K" ] }, "Response": { "StatusCode": 412, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:46 GMT" ], "Etag": [ "tdQ8f+rEaSgmViqeU7Navg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6vmUlBQSi0qyi9SslKoBnKA3OT8lFQgz8TAQAcikJtaXJyYDhJTCihKTc7PS8ksyczPU0jOSE3OVkhLzMxJTdFTgioGG1YMVBsN5itATSXZILCGlPzcxMw8kPr0nPykxBxkuaLUxOJ8sBxEI7KJSlBltWA6Fuq04pLEklKQ05TcHD19XF3iA4Jcnf39XDxDPP39QFpquWq5AH1JwmMSAQAA" } }, { "ID": "709e9c0327d9aec7", "Request": { "Method": "PATCH", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0012?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "293" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJzY2hlbWEiOnsiZmllbGRzIjpbeyJuYW1lIjoibmFtZSIsInR5cGUiOiJTVFJJTkcifSx7ImZpZWxkcyI6W3sibmFtZSI6Im5lc3RlZCIsInR5cGUiOiJCT09MRUFOIn0seyJuYW1lIjoib3RoZXIiLCJ0eXBlIjoiU1RSSU5HIn1dLCJuYW1lIjoicmVjMiIsInR5cGUiOiJSRUNPUkQifSx7Im1vZGUiOiJSRVBFQVRFRCIsIm5hbWUiOiJudW1zIiwidHlwZSI6IklOVEVHRVIifSx7ImZpZWxkcyI6W3sibmFtZSI6ImJvb2wiLCJ0eXBlIjoiQk9PTEVBTiJ9XSwibmFtZSI6InJlYyIsInR5cGUiOiJSRUNPUkQifV19fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:47 GMT" ], "Etag": [ "2k+dS8/NweEIP0snP6EXRg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41TX2/aMBD/Lt7jWuyEkpBIfYA1qpBYQCGTJlUVMskRPBI7s921EeK7185g6Wg35cm6u98/++QD2jOeoxBtWPHzCWTzSdNNCegKgaaF6bv7z/lqjONniGZLovjSi74nxe2tQTDLUztRlk1F+XUOlbjWoHSYU00V6LVLnMAh7njteQHxRgEhwdAca0KIM2h9/gNxXGOhoNzOGd8bo53WtQoxPgcdFEIUJdCaqUEmqj99/MvFtRQ/INMKf5AOn9Ip3CcmbmMq3CttC0pgCxJ4Big8oFOQ2T9eynBOIVpEn0Bnm5bQI9XxCm0lA56XTUwrEwq9WFdQmWS1ZoKbTiWk3bjKdlBRG3vLoMwVCh8OiP8mtYexbmpbrdJkFt8b7W7+VKluPovT6D5KTKMSuW0k0TKapNHdW4qErGMk0ZdFcmfq99YbIcoOOF0s5tEkRsfHv6XcXlrcPDrkH6h1WkLvQL6/6qM1tNecNmZzZkBQW84FL1KQl+1EPJ+rTAK1D52yVt8Z+a479v2bkTfy7T97qZm8BAz9G5/4Zt8GUFKlv4qcmdvklxr+0A26rOlkOo8sQ2T0tNpvK3R8BUBVLhfkAwAA" } }, { "ID": "24692315f7c847e6", "Request": { "Method": "PATCH", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0012?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "14" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJzY2hlbWEiOnt9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:47 GMT" ], "Etag": [ "2k+dS8/NweEIP0snP6EXRg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41TX2/aMBD/Lt7jWuyEkpBIfYA1qpBYQCGTJlUVMskRPBI7s921EeK7185g6Wg35cm6u98/++QD2jOeoxBtWPHzCWTzSdNNCegKgaaF6bv7z/lqjONniGZLovjSi74nxe2tQTDLUztRlk1F+XUOlbjWoHSYU00V6LVLnMAh7njteQHxRgEhwdAca0KIM2h9/gNxXGOhoNzOGd8bo53WtQoxPgcdFEIUJdCaqUEmqj99/MvFtRQ/INMKf5AOn9Ip3CcmbmMq3CttC0pgCxJ4Big8oFOQ2T9eynBOIVpEn0Bnm5bQI9XxCm0lA56XTUwrEwq9WFdQmWS1ZoKbTiWk3bjKdlBRG3vLoMwVCh8OiP8mtYexbmpbrdJkFt8b7W7+VKluPovT6D5KTKMSuW0k0TKapNHdW4qErGMk0ZdFcmfq99YbIcoOOF0s5tEkRsfHv6XcXlrcPDrkH6h1WkLvQL6/6qM1tNecNmZzZkBQW84FL1KQl+1EPJ+rTAK1D52yVt8Z+a479v2bkTfy7T97qZm8BAz9G5/4Zt8GUFKlv4qcmdvklxr+0A26rOlkOo8sQ2T0tNpvK3R8BUBVLhfkAwAA" } }, { "ID": "fb23ad8a16ca5b66", "Request": { "Method": "PATCH", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0012?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "311" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJzY2hlbWEiOnsiZmllbGRzIjpbeyJtb2RlIjoiUkVRVUlSRUQiLCJuYW1lIjoibmFtZSIsInR5cGUiOiJTVFJJTkcifSx7Im1vZGUiOiJSRVBFQVRFRCIsIm5hbWUiOiJudW1zIiwidHlwZSI6IklOVEVHRVIifSx7ImZpZWxkcyI6W3sibmFtZSI6ImJvb2wiLCJ0eXBlIjoiQk9PTEVBTiJ9XSwibmFtZSI6InJlYyIsInR5cGUiOiJSRUNPUkQifSx7ImZpZWxkcyI6W3sibmFtZSI6Im5lc3RlZCIsInR5cGUiOiJCT09MRUFOIn0seyJuYW1lIjoib3RoZXIiLCJ0eXBlIjoiU1RSSU5HIn1dLCJuYW1lIjoicmVjMiIsInR5cGUiOiJSRUNPUkQifV19fQo=" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:48 GMT" ], "Etag": [ "2k+dS8/NweEIP0snP6EXRg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/92QzU6EQBCE7zxFZ87uZkAlsjfMoiFBorh4MYb0Mi2QzE/CjJuYDe/ugBw87QN46lRVd1JfnwMARuNoRraDsxdetkaQVzecX/0aiqzFbvbY82hOgyABr21PCkEYsqCNA4Wu7eGAR0lgeyPlt0K9EaTMxpF1O4EOLbkm4mES8uiuieOEx7cJ58m1Hw3nPNy6+fzCShht4WEgKUCjIujRQtuj7nwf5UvD52gUlHVRpPdFBs5Alb3UeZXt2UqykFoP8r5oWJH/F+VCI4zCQc8wnTRHlH+zkdCaJRv0CeUg2JpNy/xYn2Uduq/5WSwv39Ii3zdp9Vg/ZeVh3p+CKfgBUCscXD4CAAA=" } }, { "ID": "94bad9152ebf96c7", "Request": { "Method": "PATCH", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0012?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "342" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJzY2hlbWEiOnsiZmllbGRzIjpbeyJuYW1lIjoibmFtZSIsInR5cGUiOiJTVFJJTkcifSx7Im1vZGUiOiJSRVBFQVRFRCIsIm5hbWUiOiJudW1zIiwidHlwZSI6IklOVEVHRVIifSx7ImZpZWxkcyI6W3sibmFtZSI6ImJvb2wiLCJ0eXBlIjoiQk9PTEVBTiJ9XSwibmFtZSI6InJlYyIsInR5cGUiOiJSRUNPUkQifSx7ImZpZWxkcyI6W3sibmFtZSI6Im5lc3RlZCIsInR5cGUiOiJCT09MRUFOIn0seyJuYW1lIjoib3RoZXIiLCJ0eXBlIjoiU1RSSU5HIn1dLCJuYW1lIjoicmVjMiIsInR5cGUiOiJSRUNPUkQifSx7Im1vZGUiOiJSRVFVSVJFRCIsIm5hbWUiOiJyZXEiLCJ0eXBlIjoiU1RSSU5HIn1dfX0K" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:48 GMT" ], "Etag": [ "2k+dS8/NweEIP0snP6EXRg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/92Qz0rEMBDG732KoScFt6RVi+1tUZEFXUR3vYiU2WZsA/mDSXZRlr67SezBkw/gafjm+4aZ3xwzgJysNTZv4RhEkL3hFNQFY2c/DUXO4RB7+aM1B8GJw3M/kkLghhxo40Gh70fY4E4SuNFI+aVQLzgps/DkfMvRoyPfVaxsSlZddXXdsPqyYaw5D6VjjJWFj+N/RMqqgGvUcR9yDpY+9sKGY94FSe7AG0AN9CmcF3oAl04s4CTZbYyf5jNSQnaB6DVpmNn/KW7C4kah0JFqkGaH8rdnCZ1JntAHlILnszel+jZ/zXn0+/i1fLV+Wd6vbrrl09324Xa9ifkpm7JvvtAZEVACAAA=" } }, { "ID": "8bb5c03e938ca416", "Request": { "Method": "PATCH", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0012?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "182" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJzY2hlbWEiOnsiZmllbGRzIjpbeyJuYW1lIjoibmFtZSIsInR5cGUiOiJTVFJJTkcifSx7Im1vZGUiOiJSRVBFQVRFRCIsIm5hbWUiOiJudW1zIiwidHlwZSI6IklOVEVHRVIifSx7ImZpZWxkcyI6W3sibmFtZSI6ImJvb2wiLCJ0eXBlIjoiQk9PTEVBTiJ9XSwibmFtZSI6InJlYyIsInR5cGUiOiJSRUNPUkQifV19fQo=" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:48 GMT" ], "Etag": [ "2k+dS8/NweEIP0snP6EXRg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/9WQT0vDQBDF7/kUw57bsokaTG8FqxS0iFYvImGaHZKF/QM7a0VKvrubNQdP3j0Nb94M/N47FwCCQvBBrOGcRJKdV5TUpZSLn4UlZuynnXgM/qQVKXjuBrIIyhOD8xEsxm6AAx4NAQ/emC+LbqnI+mUkjmuFEZliW8myKWV13dZ1I+urRsrmIo1WSlmu4vT+x0lZreBWk1EQqKtAM1jNrF0P2oGjT+BMJWbunIsT9lvWMAf8z5kyu/IWtZvQe+OPaH57gZB99rQ7odFKzN6Y5/tcDUeMH1M1Yrd/3dzvbtrN093Lw3Z/mO7HYiy+AQQhsgMaAgAA" } }, { "ID": "de4ab341ea7c116f", "Request": { "Method": "PATCH", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0012?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "260" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJzY2hlbWEiOnsiZmllbGRzIjpbeyJuYW1lIjoibmFtZSIsInR5cGUiOiJTVFJJTkcifSx7Im1vZGUiOiJSRVBFQVRFRCIsIm5hbWUiOiJudW1zIiwidHlwZSI6IklOVEVHRVIifSx7ImZpZWxkcyI6W3sibmFtZSI6ImJvb2wiLCJ0eXBlIjoiQk9PTEVBTiJ9XSwibmFtZSI6InJlYyIsInR5cGUiOiJSRUNPUkQifSx7ImZpZWxkcyI6W3sibmFtZSI6Im5lc3RlZCIsInR5cGUiOiJCT09MRUFOIn1dLCJuYW1lIjoicmVjMiIsInR5cGUiOiJSRUNPUkQifV19fQo=" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:49 GMT" ], "Etag": [ "2k+dS8/NweEIP0snP6EXRg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/9WQS0vEQBCE7/kVzZzdMIkazN4WfLCgi+jqRST0ZppkYB4wPa7Ikv/uZMzBk3dPTXV1Q311KgAEheCDWMMpiSR7ryipCynPfhaWmHGYd+Ix+KNWpOC5H8kiKE8MzkewGPsR9ngwBDx6Y74supUi61eROK4VRmSKXS2rtpL1Vdc0rWwuWynb8zQ6KWVVxvn9j5OqLuFWk1EQqK9LH0cKoBmsZtZuAO3A0SdwziaW9JmOU/i3rGHB/P9kmUB5i9rNAIPxBzS/vUDIPnvaHdFoJRZvyvN9KYgjxo+5ILHdvW7ut9fd5unu5eFmt5/vp2IqvgF1KIWvJgIAAA==" } }, { "ID": "07308d9cf03734c9", "Request": { "Method": "PATCH", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0012?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "214" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJzY2hlbWEiOnsiZmllbGRzIjpbeyJuYW1lIjoibmFtZSIsInR5cGUiOiJTVFJJTkcifSx7Im1vZGUiOiJSRVBFQVRFRCIsIm5hbWUiOiJudW1zIiwidHlwZSI6IklOVEVHRVIifSx7ImZpZWxkcyI6W3sibmFtZSI6ImJvb2wiLCJ0eXBlIjoiQk9PTEVBTiJ9XSwibmFtZSI6InJlYyIsInR5cGUiOiJSRUNPUkQifSx7Im5hbWUiOiJyZWMyIiwidHlwZSI6IlJFQ09SRCJ9XX19Cg==" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:49 GMT" ], "Etag": [ "2k+dS8/NweEIP0snP6EXRg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6WOMQvCMBCF9/6KI7NDESe3YqsIWqGoi4ikzdEG0kZyqSCl/90kZnB3Ot69e9+9KQFgaIw2bA2TE042WqBTqzRdfBc9EvHW79hWohJgsFmCJLDvJ0JVbE5VDvVooeMEgwZqOuw5i+lAJxe+BQ3xzf/kQBC653LwgFbpmqtfzyAnHTw5vLiSgkVvDvMeC5LldvQF2b68Zod9/siq3eVYlGd/Pydz8gEioPfmJgEAAA==" } }, { "ID": "b84a64376d6e8840", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0012?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:49 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6uuBQBDv6ajAgAAAA==" } }, { "ID": "36f9de46847c78f2", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "273" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJleHBpcmF0aW9uVGltZSI6IjE1NzIyODgzMDcwMDAiLCJzY2hlbWEiOnsiZmllbGRzIjpbeyJuYW1lIjoibmFtZSIsInR5cGUiOiJTVFJJTkcifSx7Im5hbWUiOiJudW1zIiwidHlwZSI6IklOVEVHRVIifV19LCJ0YWJsZVJlZmVyZW5jZSI6eyJkYXRhc2V0SWQiOiJkYXRhc2V0XzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDEiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0IiwidGFibGVJZCI6InRhYmxlXzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMTMifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:35:49 GMT" ], "Etag": [ "auan5KHKNRTv/BJ3TG/aEg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42QwW6CQBCG32V7re4CBYTEQ02ItVoPlJ6axqww4lZgKbvaEuO7d6Bak9o2nCYz8/8z38yebESREJ8sRfq2haq+0nyZAbkmoHmKdb7lhT29m87DaEdH91Y0pjxIh0NUiMan1jLL6pwXvQRy2dOgtJ9wzRXohckMz2DmYOE4HnNsjzHPwrBgjBn9ds8/EsPCFQqy1UwUG1y01rpUPqUn0H4qZZoBL4XqxzL/rtOdSctKvkKsFf2Fjh7pFO2CSVtMRTvRtqIQVlBBEQPx9+QIMvnjU+g5QrSKLkCnNa2hA9UBnxivIecNzkpAlijiP+9JwXMk/Ao4si6b7DEKJ/Mxes79ba7O/ck8CsZBSA4vOBZboxqvwDojbTqTRRpB9bMcyvdTFlfAtZBFJNrphu2a5sB1bzzbah4IH6WoLgUDi7l4OwoyrvSDTAQeklzMcEx2Ro1uR7Ogcci4HYilp0dy+AT9/pl38AIAAA==" } }, { "ID": "4f4f73da0245f272", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/upload/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7ImxhYmVscyI6eyJ0ZXN0IjoiZ28ifSwibG9hZCI6eyJkZXN0aW5hdGlvblRhYmxlIjp7ImRhdGFzZXRJZCI6ImRhdGFzZXRfMjAxOTEwMjhfNjY5MDY1OTAwOTM2NTlfMDAwMSIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QiLCJ0YWJsZUlkIjoidGFibGVfMjAxOTEwMjhfNjY5MDY1OTAwOTM2NTlfMDAxMyJ9LCJ3cml0ZURpc3Bvc2l0aW9uIjoiV1JJVEVfVFJVTkNBVEUifX0sImpvYlJlZmVyZW5jZSI6eyJqb2JJZCI6ImJhZG5zMmE2Ujk0cU1EcUdGeFJTa0JNRHIzdyIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QifX0K", "YSwwCmIsMQpjLDIK" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "902" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:01 GMT" ], "Etag": [ "\"CRkpyt4RXWzE4lvoHDbioIbWdUA/qFUD9S14fSBWTBqL6jZlkwdcMkM\"" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Uploadid": [ "AEnB2Uq2LpGScI81hWG_bxudjNkicrHFEpIvFlhk4739YxsirO_YWbC-cKOy2jllCYtPgT03q5Jtt8ud_dSchAdpB5Ib8audYg" ] }, "Body": "eyJraW5kIjoiYmlncXVlcnkjam9iIiwiZXRhZyI6IlwiQ1JrcHl0NFJYV3pFNGx2b0hEYmlvSWJXZFVBL3FGVUQ5UzE0ZlNCV1RCcUw2alpsa3dkY01rTVwiIiwiaWQiOiJzaG9sbHltYW4tZGVtby10ZXN0OlVTLmJhZG5zMmE2Ujk0cU1EcUdGeFJTa0JNRHIzdyIsInNlbGZMaW5rIjoiaHR0cHM6Ly9iaWdxdWVyeS5nb29nbGVhcGlzLmNvbS9iaWdxdWVyeS92Mi9wcm9qZWN0cy9zaG9sbHltYW4tZGVtby10ZXN0L2pvYnMvYmFkbnMyYTZSOTRxTURxR0Z4UlNrQk1EcjN3P2xvY2F0aW9uPVVTIiwiam9iUmVmZXJlbmNlIjp7InByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QiLCJqb2JJZCI6ImJhZG5zMmE2Ujk0cU1EcUdGeFJTa0JNRHIzdyIsImxvY2F0aW9uIjoiVVMifSwiY29uZmlndXJhdGlvbiI6eyJqb2JUeXBlIjoiTE9BRCIsImxvYWQiOnsic2NoZW1hIjp7ImZpZWxkcyI6W3sibmFtZSI6Im5hbWUiLCJ0eXBlIjoiU1RSSU5HIn0seyJuYW1lIjoibnVtcyIsInR5cGUiOiJJTlRFR0VSIn1dfSwiZGVzdGluYXRpb25UYWJsZSI6eyJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0IiwiZGF0YXNldElkIjoiZGF0YXNldF8yMDE5MTAyOF82NjkwNjU5MDA5MzY1OV8wMDAxIiwidGFibGVJZCI6InRhYmxlXzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMTMifSwid3JpdGVEaXNwb3NpdGlvbiI6IldSSVRFX1RSVU5DQVRFIn0sImxhYmVscyI6eyJ0ZXN0IjoiZ28ifX0sInN0YXR1cyI6eyJzdGF0ZSI6IlJVTk5JTkcifSwic3RhdGlzdGljcyI6eyJjcmVhdGlvblRpbWUiOiIxNTcyMjg3NzYwNDgzIiwic3RhcnRUaW1lIjoiMTU3MjI4Nzc2MTA2NSJ9LCJ1c2VyX2VtYWlsIjoidGVzdC1yb2JvdEBzaG9sbHltYW4tZGVtby10ZXN0LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0=" } }, { "ID": "03535bf9d1b44e09", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs/badns2a6R94qMDqGFxRSkBMDr3w?alt=json\u0026fields=status%2Cstatistics\u0026location=US\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:01 GMT" ], "Etag": [ "9fMO76bx2CXuFfOb8KaraA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWKi5JLMksLslMLlayqlZKLkoFcvPzQjJzU5WslAxNzY2MLMzNzQxMLIyVdECKi0rQ5QwNzEyVasGSJaVgU0AskJKgUD8/Tz93pdpaAIxHndZoAAAA" } }, { "ID": "3b6f714709e14694", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs/badns2a6R94qMDqGFxRSkBMDr3w?alt=json\u0026fields=status%2Cstatistics\u0026location=US\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:02 GMT" ], "Etag": [ "9fMO76bx2CXuFfOb8KaraA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWKi5JLMksLslMLlayqlZKLkoFcvPzQjJzU5WslAxNzY2MLMzNzQxMLIyVdECKi0rQ5QwNzEyVasGSJaVgU0AskJKgUD8/Tz93pdpaAIxHndZoAAAA" } }, { "ID": "2ab07b4504675cc1", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs/badns2a6R94qMDqGFxRSkBMDr3w?alt=json\u0026fields=status%2Cstatistics\u0026location=US\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:03 GMT" ], "Etag": [ "sXLavZRpATxDVKZU6SI8Ow==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/22QzWrDMBCE32XPDthybAcfQ1rIIQm46an0oFrbIlAkI60TitG7R+vS0IbcpG9m9m+CQJJ0IN0HaCfoPaavs0d9QmihqBohVk1T58tVCRmbPd1rRV5XSUOr7hUhymVSencaDHLZjotDW2RgnFTcUNthpGdtMHAwmW9g/U0/UCTqRkq4cxcm5Q38ekpGH1J12DuvmOQQMyBH0rwYRztGVVUnl8eA/jwv+RrkV5r3bQIr58EVfsrR0GLQAxptkTf+m47v//Jb9SgT5zPRON+TX1x5c9g/QYxXUiozhG8BAAA=" } }, { "ID": "90f0dd8e1fd62b02", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0013/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:03 GMT" ], "Etag": [ "3lOtnbfXMYJfQqviTcwcww==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8ob5/iX5CWlRfhGeqUFFpZlhiSXJ5eX29oCVZTklyTmBOWXF4OUAflFYGZ0tVIamCwDCicq1epAWAZKtbEgNkIuCS5niCGXDJczAsnF1gIAKKQr4bAAAAA=" } }, { "ID": "8f8e046c42df9da4", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0013?alt=json\u0026fields=schema\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:03 GMT" ], "Etag": [ "ghJrG2Y2u9RwCjWPqd/mVw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWKk7OSM1NVLKqVkrLTM1JKVayiq5WykvMTVWyglA6SiWVBSBecEiQp5+7Uq0OQr40txgh7+kX4uruGqRUG1tbCwCcp8mLWAAAAA==" } }, { "ID": "14885471cea2e09e", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0013?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:03 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6uuBQBDv6ajAgAAAA==" } }, { "ID": "546ac038ad89c85a", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "366" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJleHBpcmF0aW9uVGltZSI6IjE1NzIyODgzMDcwMDAiLCJzY2hlbWEiOnsiZmllbGRzIjpbeyJuYW1lIjoibmFtZSIsInR5cGUiOiJTVFJJTkcifSx7Im1vZGUiOiJSRVBFQVRFRCIsIm5hbWUiOiJudW1zIiwidHlwZSI6IklOVEVHRVIifSx7ImZpZWxkcyI6W3sibmFtZSI6ImJvb2wiLCJ0eXBlIjoiQk9PTEVBTiJ9XSwibmFtZSI6InJlYyIsInR5cGUiOiJSRUNPUkQifV19LCJ0YWJsZVJlZmVyZW5jZSI6eyJkYXRhc2V0SWQiOiJkYXRhc2V0XzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDEiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0IiwidGFibGVJZCI6InRhYmxlXzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMTQifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:03 GMT" ], "Etag": [ "Vrc2NOHDTr0sOMJMkvk0gg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42Q3U7CQBCF32W9VXZblJYmXoA0igFqavXGGLK0Q1lpu3V3/SGEd3dawRpRQ/ZiM2fOmfkya7IURUI8MhPp8wuo1ZHhswzIMQHDU9TvVWxPgqtBpJgOxtfj5euSpen5OTpEldMLmWWrnBcnCeTyxIA2XsIN12CmNrO6FrPdaafTZZ2zLmPdNn5TxpjVqvf8Y7FOcYWGbD4SxRIXLYwptUfpDrSVSplmwEuhW7HMv3T6atNSySeIjaa/0NEtnaaHYNIaU9ODaGtTCHNQUMRAvDXZggz/uBRmthC14xCg3Zo6cADVBo8YLyDnFc5cQJZo4j2sScFzJPz8cOSqrKrbKBxOLjHT9F9y3fSHk8i/9EMUcplUQujf+L3IH3yPKIibROhfBOEA6/3VMymzxtgPgpHfm5DNI77jam9/hSfCDiN1OZJFGoH6KYfybVfFCrgRsohEPd86c2zbdZxO23GrNryXQu0b3DZz8LBoyLg2Y5kIRE32ZrhWu4GNev2RXyVkXA9E6e6WbD4AcqnzoE0DAAA=" } }, { "ID": "83ad23a4ed32277c", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "429" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiSU5TRVJUIGRhdGFzZXRfMjAxOTEwMjhfNjY5MDY1OTAwOTM2NTlfMDAwMS50YWJsZV8yMDE5MTAyOF82NjkwNjU5MDA5MzY1OV8wMDE0IChuYW1lLCBudW1zLCByZWMpXG5cdFx0XHRcdFx0XHRWQUxVRVMgKCdhJywgWzBdLCBTVFJVQ1RcdTAwM2NCT09MXHUwMDNlKFRSVUUpKSxcblx0XHRcdFx0XHRcdFx0ICAgKCdiJywgWzFdLCBTVFJVQ1RcdTAwM2NCT09MXHUwMDNlKEZBTFNFKSksXG5cdFx0XHRcdFx0XHRcdCAgICgnYycsIFsyXSwgU1RSVUNUXHUwMDNjQk9PTFx1MDAzZShUUlVFKSkiLCJ1c2VMZWdhY3lTcWwiOmZhbHNlfX0sImpvYlJlZmVyZW5jZSI6eyJqb2JJZCI6ImIxYjBDSEdhUEVuU0hKb1d5eDRHdzd0Z0p3UiIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:04 GMT" ], "Etag": [ "4sqmJZkdp2ClS3/MPtebqQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41Ta2/aMBT9K5H3oSCFvKDQIKGNoYyCKG2T0GkbE3KMSV0SG2KnHar633eTUPZQaat8iHN9zr3HxyePaM34EnVRxOJtTrPdhzsRIR1RhWOotuQ2HX9fLzfOIAma5sWVotH2utcDBCtY8lYkyS7FvLGkqWgoKlV3FhiRHVmD8yG+8nhwPhZfd79aw4eOiscPPjAlTVYTxtfAv1VqI7um+TzdiIWIE4o3TBpEpIe6ee+Ym0zcUaKk+cJQE1RL85WxHxNBsGKC92YBSMglzRY0xSwBEUWDRiYioT690NpgODViwN8zQjEhIueq0AZdiOArFudZ2Rh1H1Gp9a8FGk0Dzw+1JVZYUrVwLNu1Leds0W67VvvUtSy3Ca+FZVm2oXCU0FcgdkurcZxSXeN5KnUto6Q+53P157npT2ZeoNVO8Imu/bB+6loQ+rNBOM8tq0k+X15OyhWtQdWr1/V/2XOlacCNCq59nPulPwmOkklBdt4aDNYtwVnGS+PC4tyFafsLHh0JVsGqfCwR7/EUKKWrJeFtf9GTDiKYyJiqLi/0/P4gHN14VWQmNMZkF2whNCucSApwyF2424B8dD3z/G+oKvl0RTPKyTuPBYxy9/Xf5jnBAIQMwyCp4BtsJLIYQzJa2cnSQo592nGcs06n3XQ7LirBmfp/r2W3C48OsS060pRytT9TFV/0tB+WywMINv3ZdDqaDmH3N7/exFxFBAAA" } }, { "ID": "2528e3efbf7c282f", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/b1b0CHGaPEnSHJoWyx4Gw7tgJwR?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:06 GMT" ], "Etag": [ "84LSdI+69VCnmMaBR4lTIg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/2VQy07DMBD8l+VIKhVR8YjUQ5taaarSFifAAXFwkk2a4keIHZWo6r+zKYcgIR/WOzuzHs8JPiudgw9pVX612HRXJbrn/sLRttJZKrXRFsEDdKIk5sNkHefR9d3ja6DVk5jziUyicjolhs32qAT4JygqlLkF//0EWigk2aV44Lq67+KER5sQzt4wb5Ud5tEmYSHjBCiT9wBnOzZL2OKvpMFsUHAWbPmC+v9Pp8bIgTjfbtdstoHzBx0PDiblWGCDOsPeed2YA2Yu6kOxeyNlp4Qe5ajMyKF1cFFcpulNOg6WodgxHS9X5q37noTHe1eujr1vaTLhKqOJ+BKTa3DGCTnvaMmuMRlai/2S8e/CwKhaoiMHrmnRg0xQlMvKgV8IaQmgeBZKzoqCvGHOzZF+CLdw/gF37PJYwQEAAA==" } }, { "ID": "806bd4526b37c2f7", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs/b1b0CHGaPEnSHJoWyx4Gw7tgJwR?alt=json\u0026fields=status%2Cstatistics\u0026location=US\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:06 GMT" ], "Etag": [ "7JIdIMolJrIzDrLmaj1ftw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/7VXf2+jNhj+KhGqdJvUq/wDA0baH7k206otl4pQnabtFLnwpmUjkGHnelXV7z7bQEMISfrHVZXeGr+/7cePnWdHKqEyqbJEOuGzk1SgP8sizlbghA5mPiGB73uU+9w5N8aV6utc7GGtgyLta5iPXa1RpRL5pycF8qYqE5ASUm2FtOa/DVRPJq8d3OSicMK/np1C2DhzhMLRdbHeKG2atT62hqncqYD4QV1Bf56byh5FpiLT1vjbvROiC4Q8l1PWkbw2mkpr4ew4TcX3E07Wwjrp1Us7meqJNirqGtRRW4M6gjFIypXuF3bKxdwNENvKV6s2Mu05tiUfcawzGsfHKjuZz9p0s22dDudqnLaZ5MNmucxhtlG6BosHreDDmvk6y/NXnFSQlFUqI71YuzNfdA4FRZNgLSqhvXKLGdnsiWk5BwXpzZDWwH9jPi5n05s/JvHEzsFaWiD+mxVpo7utVZu7VuucYTQKfxlNx79PFvM4ur2Mfzoj7Hx0Rtyfna8v56fcqXX/ID5oxRnF5mMcReM//94gRJOLiws7AKslRovfEtWto97ZqO7RqG4T1QypGaK3JGB1gsQmYEcTsIGyv0TXQytpls0KbAQxwuxoPBstFnqP7gGhRWnhoaPZeK8kgcPRZSlykAm0PIEP8AS1Qfd5wqXGIzPAmJtktiq9GvvcgYOAYuy9SrLLHIQPUAfBLgkMFzbS3yUOSt+NOQjjvtuR3h51uAeogwWui9lW7lEHH6IOTL2dP9ajDoKHuINQ6nteR/a5w/uB5EHfTB4MHWUPht5KH9FkfNVD/K/RbHoa2SQc1V21uCYHcO26fBDXeuf2cY33cY179x9z92CMe7edNXkf1PYuWsL3UIv7ri1sj7k2haMh4Po88BEmrfR4D7iYDN56h92aZOTgvYfeEbk/6NobwO1hpt5BNN4i+gTznyB90j0aGragX6orobsafE5qHeRZAbYJyMVaq+yJ8DBv36HzvKxPD8XEHKe1PjVZcX9bZEp2MGmXrp1kxlAkKvsGWzvTWTcHZuQdknxtIupdVJl5me83ffB1vdV86qLqTn/oYuIMKnusBytORPIAv2XKCZcil2CQt4QKigTSWNzlUANlXZX/QKKuTWj5UOb500oUH1NYlR91VkNbqVBCQm3RjBdEPxYxIsHC8zjyGEeIU/1vgRAy2FQmvnWwoyPm+teFWaBis7pa5ePlUpcCaVQ+yvbBqVEOKyhU/LQ2jHr9eT6JYr1zQz2/bE/Fc+2pNVezzxPn5eV/zT2XOycNAAA=" } }, { "ID": "706bb8baeeddb223", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0014/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:06 GMT" ], "Etag": [ "7AnLO5LPfaExsuI+fa5vAA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8qbO+b5+Jv6BKQlulYUl3pqpyWaljk62toCVZTklyTmBOWXFwOVGQP5RWBmdLVSGpgsA5muVKsDZkH5hkq1sVARZGVpiTnFqSApiCxCIhFNvwF2/SVFpVi1J6NpNyKoPbYWAP2nsZEaAQAA" } }, { "ID": "a3d8e2bfa9bc4202", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0014?alt=json\u0026fields=schema\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:06 GMT" ], "Etag": [ "Vrc2NOHDTr0sOMJMkvk0gg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWKk7OSM1NVLKqVkrLTM1JKVayiq5WykvMTVWyglA6SiWVBSBecEiQp5+7Uq0OQr40txgh7+kX4uruGgQUyM1PAQkEuQa4Ooa4uiBrKUpNRugIcnX2D3IB8jGtTsrPz0EodPL393F19FOqjQXCWgCN1fK3tQAAAA==" } }, { "ID": "1c5ed291f4493301", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0014?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:06 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6uuBQBDv6ajAgAAAA==" } }, { "ID": "253a4156bd4595e5", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "327" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJleHBpcmF0aW9uVGltZSI6IjE1NzIyODgzMDcwMDAiLCJzY2hlbWEiOnsiZmllbGRzIjpbeyJuYW1lIjoiZCIsInR5cGUiOiJEQVRFIn0seyJuYW1lIjoidCIsInR5cGUiOiJUSU1FIn0seyJuYW1lIjoiZHQiLCJ0eXBlIjoiREFURVRJTUUifSx7Im5hbWUiOiJ0cyIsInR5cGUiOiJUSU1FU1RBTVAifV19LCJ0YWJsZVJlZmVyZW5jZSI6eyJkYXRhc2V0SWQiOiJkYXRhc2V0XzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDEiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0IiwidGFibGVJZCI6InRhYmxlXzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMTUifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:06 GMT" ], "Etag": [ "iCEGhKL92T60QIOimIgP3w==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42SUW+CMBSF/0v3Om2BCULig25mIcPMKXtaFlPhCp1AGa1zxvjfVxp1U7eFJ9p7z7nn6w1btGRFjDw0Z8n7CqrNlaTzDNA1AkkTVWe3w/v0IXDN0CZP/iPL/WRsrXs9pWC1T6Q8yzY5LVox5LwlQUgvppIKkDOTGK5BzO7Mtl1id1xCXEt9ZoQQo61z/pEYHRUhIFsErFiqoFTKUngYH0DbCedJBrRkoh3x/FjHHyYuK/4GkRT4Fzq8pxO4CSbWmAI3otWiCSyggiIC5G3RHsT/Y1PKs4fQiiZAhxhtaEC1U0uMUshpjbNgkMUCeS9bVNAc6sh63qasj3f9cKjkx5b8boX+6KQVy1PbeV+KU+807I/GaPeqYIpVPtiot6sOQfoa8CIJoTovT/j6cIsqoJLxImR6utFxTLPrOLZ9Y7n1n/pZsupS0LWIozamBBkVcsRjpp4fX85wnB+w/UEwrB080gNV6XmKdl9gDiOeJgMAAA==" } }, { "ID": "f404fc1099480976", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0015/insertAll?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "164" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJyb3dzIjpbeyJpbnNlcnRJZCI6IjBucDBrTVZXVktNd3dEc3Npa2pFNHB0WEl5ZyIsImpzb24iOnsiZCI6IjIwMTYtMDMtMjAiLCJkdCI6IjIwMTYtMDMtMjAgMTI6MzA6MDAuMDAwMDA2IiwidCI6IjEyOjMwOjAwLjAwMDAwNiIsInRzIjoiMjAxNi0wMy0yMFQxNTowNDowNVoifX1dfQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:06 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTMK04tKnHMyQlKLS7IB3KUagGmFzWCLgAAAA==" } }, { "ID": "50aee77ed10305fb", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0015/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:06 GMT" ], "Etag": [ "4mwRyGcPntjsq9s9nnsVfw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8qb5JYHVbonB+SVZBUXWhZb5uUVh6WV29oCVZTklyTmBOWXFwOVGSjVAgDtIhrCUwAAAA==" } }, { "ID": "474e6ef7132e0375", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0015?alt=json\u0026fields=schema\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:06 GMT" ], "Etag": [ "iCEGhKL92T60QIOimIgP3w==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWKk7OSM1NVLKqVkrLTM1JKVayiq5WykvMTVWyUkpR0lEqqSwAMV0cQ1yVanXgUiUIqRBPXxSplBJUbejyJcWoeoNDHH0DlGpja2sB5wvkN44AAAA=" } }, { "ID": "8bc7f78f38dae130", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0015/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:08 GMT" ], "Etag": [ "JlGmsv2RwTxUb/iBrQsr4g==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8p75bjnFpcZBZWHVIQm6Wc6FQUWF5mk29oCVZTklyTmBOWXFwOVGQD5RWBmdLVSGpgsAwobGRia6RoY6xoZKNXqQIQMjayMDawMDPQMQMAMLo5QGoJLiaGJqYWJhZmRiake0LxYIAQA3yIimscAAAA=" } }, { "ID": "c44869640f24639a", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0015?alt=json\u0026fields=schema\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:07 GMT" ], "Etag": [ "iCEGhKL92T60QIOimIgP3w==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWKk7OSM1NVLKqVkrLTM1JKVayiq5WykvMTVWyUkpR0lEqqSwAMV0cQ1yVanXgUiUIqRBPXxSplBJUbejyJcWoeoNDHH0DlGpja2sB5wvkN44AAAA=" } }, { "ID": "20fd213e7772ef33", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "338" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiSU5TRVJUIGRhdGFzZXRfMjAxOTEwMjhfNjY5MDY1OTAwOTM2NTlfMDAwMS50YWJsZV8yMDE5MTAyOF82NjkwNjU5MDA5MzY1OV8wMDE1IChkLCB0LCBkdCwgdHMpIFZBTFVFUyAoJzIwMTYtMDMtMjAnLCAnMTI6MzA6MDAuMDAwMDA2JywgJzIwMTYtMDMtMjAgMTI6MzA6MDAuMDAwMDA2JywgJzIwMTYtMDMtMjAgMTU6MDQ6MDUnKSIsInVzZUxlZ2FjeVNxbCI6ZmFsc2V9fSwiam9iUmVmZXJlbmNlIjp7ImpvYklkIjoiMzBFdVRPVzIyQ2Z3NkRLWHRUVzJ5Q1NTZ09EIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:08 GMT" ], "Etag": [ "OdpcQIiVoACdnVyK8dgnBw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41SYW/aMBD9K5H3gVaCxAlNgEhoYzSaUBGoJNDtEzKOSd0mNo2dVlHV/75zQtmkdW0joYS79+7eu7tndM9FikK049lDxcr6y53coS5immQQXaYHej3jGzmZpmJTXw3TTHx/Go8BwQ1L3co8rwsieikrZE8zpcN1bPdxVCXLG8+b7p+Cy6ufOrnx6mkcZ8tLYCqW7+dc3AP/VuuDCh3ntbudSZnljBy4sqksTnHn0XMOpbxjVCvnjaYOqFbOO22/5pISzaUYr2OQUClWbllBeA4iTIFeKXdSf3ujtM1JYWeAf+SUEUplJbTRBlWoFHueVWVTGIXPqNH61weaLeJolVgp0UQxvfWwO3KxN9wGwQgH/gjjUR9eW4yxa2uyy9k7ENe3ztKupbtWCj+tzq3NZL6OYuusA6Sgh/s9D3e6Vsf1wj4OMbaxeQIT+gOwPsj6Ib4Isd85B38p2OeicZcYccbZcQuz/2zfsFqzDeIzxoHSWG8IHw8BvXRBBJcl1+2Ek2g1mSazTdTudc4yQuv4ATa7J7liAIfjSOoDyEfX62j1C7WhFduzkgn6SVvAaLLv3/brmQEQDg0aKQ3/YYxUmTa0ZO04eWHkuP7A84aDQTD0+j5qwKX+J3eBB5A73ZapyAom9NFTe2Po5disUicQJFfrxWK2+AHZ37Zq8xDqAwAA" } }, { "ID": "a6889bef635c5251", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/30EuTOW22Cfw6DKXtTW2yCSSgOD?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:09 GMT" ], "Etag": [ "w64RN8LDGjiWcFsF5tQ1Lw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/12Q3U7CQBCF32W8LQmgEtOEC2xBiSDQ1mBivFi201Lcn9qdpmlI392pJhq82sl+55w9O2f4KEwKPhyK/LPGqr3KkXb9EKGrFTk+SmscggdIImdlM7mJnu9W4cOp2MuFW9zSbrRqplNWOHlELcA/Q1agSh34b2cwQiPbUubUlv0YzpI5dN4voj+ULNcXKKVL239O7tIbJ7P1Frr3zoOTPUSYYYVGYl+prOwJJS3737qjVarVwgxS1HZA6Pp32PFNr4fzOtnsx+Mgaybh0ysl+3EbxHG+CVmlrBRUWMPCl5i7AFkS6r7lkG1lJTqHfcjwJzCwulRI3ICqGj2Qgnf0WBD4mVCOL0ytQ61mWcbdMI1sw1uDEXRfNqSr6JoBAAA=" } }, { "ID": "047e5d13c3a23f56", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs/30EuTOW22Cfw6DKXtTW2yCSSgOD?alt=json\u0026fields=status%2Cstatistics\u0026location=US\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:10 GMT" ], "Etag": [ "eeqHgcTRL3dBHglfyCQYdA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/81W227bOBD9FUPIY1KQlKgbsA9p42ID1HVgu+jDojAYaZyoK0tekW42CPLvnaEk25LltFgkwBoQLHLmzIU8h+KTo40ymTZZop34yUkqwGFZLLI1OLHDZSBEGAR+KFzpnJNzZY5sHgvQBkXat0QhJ5QpjcrfPxrQN1WZgNaQohdDyz9bqB4pr325yVXhxH89OYWyceaMxaPrYrM16Jq1GFvDRHcqkNKtK+jNB4LmH1RmZtTW5Y87J2bvGAt9wfww8qXkgfC4G9ROE209HH4Imqh/fwGyHhaEq5ceZKon2qjs0KGO2jrUEcghKdfYL3TKdT0vFIHc59+5taG9HrKt+SVknZOQD1XWzch3LUYuxyCy8dmtT9hBNdlOo5oFIpS+365WOUy3BquwnECLiAYt802W5zuuVJCUVapnuGDdma+YxEDRbMFGVQpRueWNbiap6RwMpDdDVpLAlgYfppObT+PF2M7BRlsy/p0VaWP7Upu2t63VOeOj+I8R98OQCjoTdiRil8WMKIM/n+ZdmheM+xfMvRBsyMWzUE+GHu6WJ2sL/Zxvz+e7Kr7OrgdqOB+dCXxcfGg/F9PRcolN3QFjy9KuJwaxYXbK4vHoQ6ly0Am04uInxBV4w+KKJCEyWsk5JbPFYLmvJbgOmYjHXb2J/6He/A42OlJbMKg2sW+RgKKvNjmkNo911eb21OYFr6g2/ttqk+xFuUn2u3qbjS+vekT/OJtOfs1sEY/qrlpeixO8DmU0zOtAHPOaH/Oa9zjM/SMW894nwrq8CWk57wosPOIsd4dJ+xKyKdsdom3QFaffp23oD9H2NKrOZVGDtGVvyNpX+kYMcPbocO6QmO9J/N/PeHGoBGQp4G1urbCRwSsX2iDPCrB1Q642aLIC8O2JYe9q87ysxeKKkLSwQZFkxd2XIjP6gIJ2tdpJSY4qMdkP2PtRV4c5kF1vkORbExE3zmR0ez1u+uQNdG95f0ikWxxgMYsMKqviwYoTldzDn5lx4pXKNRDZVlBBkUC6ULc51NzYVOV3SMw1hdb3ZZ4/rlVxkcK6vMCsdEqlyigNtUfzvsTLQsSZCJe+HzFfRoxFLv4t8UJAdDQU3wLs2wvu+PWgBSq266t1frlaYSmQzsqHQ2LDGgqzeNzQAXr9eT6eLXDnhnp+3gvhqUai5Wr6eew8P/8Etxb3cUsMAAA=" } }, { "ID": "cecec5d4e209f186", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0015/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:10 GMT" ], "Etag": [ "oGrIUjPFenpUGe38J5rMvw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8rnuxd5hmYFuKXmFYS6pxpbeJkW+ZaV29oCVZTklyTmBOWXFwOVGQD5RWBmdLVSGpgsAwobGRia6RoY6xoZKNXqQIQMjayMDawMDPQMQMAMLo5QGoJLiaGJqYWJhZmRiake0LxYkDC9rIqtBQB/LmJ8MgEAAA==" } }, { "ID": "5e34c0a7756e2031", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0015?alt=json\u0026fields=schema\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:10 GMT" ], "Etag": [ "iCEGhKL92T60QIOimIgP3w==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWKk7OSM1NVLKqVkrLTM1JKVayiq5WykvMTVWyUkpR0lEqqSwAMV0cQ1yVanXgUiUIqRBPXxSplBJUbejyJcWoeoNDHH0DlGpja2sB5wvkN44AAAA=" } }, { "ID": "548fb773b2fd966e", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0015?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:10 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6uuBQBDv6ajAgAAAA==" } }, { "ID": "680249a39c8c4b7c", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "159" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUIDEiLCJ1c2VMZWdhY3lTcWwiOmZhbHNlfX0sImpvYlJlZmVyZW5jZSI6eyJqb2JJZCI6IndoZXJFeFlobzdSSWFtanZxSTk2cXZKMkdPYSIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:10 GMT" ], "Etag": [ "TwBvc51yO4M6eQFf03UeZQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42Sb4+aQBDGv0qzfVvln4CYmPaq3IXGehGxzfWNWZYB1wMW2VVrLvfdO4ueadrrpe9g5zfzzDwzT+SR1xkZkZQXuz20p/dbkZIPBBQt8DU5fj4w1zrdD756sLjNTWcFPxbjMRJcZ8mNKMtTReteBpXoKZBqtFr2jxtow58PG+HHEa22h10UeLvDF/vunmKmhDKf8foR8zdKNXJkGC/q/UKIogTacNlnorq+GwfbaFqxBaak8YqogV1L4w3Zj6VgVHFRj1dLbGEvoV1DRXmJTegCvVakQn16pXSf06pfIH/gDChjYl8r3RtWYaLOebFvu8Jk9ES6Xn/7IMtwFk6SdxbCGdbidYcmNC1BY5eRon9YqbOoohLOxDoFsH0vzQLXsgZW7nmuO6SWPwicgAWZO7CZA7bpaI+VluiyaC1qL3AZ862hZdJswFw3TU3fznIPPEz3AjPP7dTx7Zw841AtUAVTLhsh+XkwMonDmyRcR7freRhOwykKHFv+J/U9jhBK4tV8gjQyTcsFYtqIaJ6E8c0kib6FZ/tnUFB2Wu5wATktJaAy7jA5NWgMWazC+IGcn2LIoYWa/adhmNFF3z7Bl2tAEO8BhaTCf1wQk1qm80Avile6Hcv1bXvo+77pOQ7p4Fb9FfM9HbuegK4IFdTqMtP5FMjzRWwvrxAG0bN5NL/D6C8R+8UFkQMAAA==" } }, { "ID": "6322e94355d8a56f", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/wherExYho7RIamjvqI96qvJ2GOa?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:11 GMT" ], "Etag": [ "BxdpyrM1O05FLog7gj2rLQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2P3U7CQBCF32W8hQRIlEjChTUVaypIlQtjjFna6Z+7nbI7BZqm7+4UvJo9s9+cOdPBb1ElsIB9kR0atO1NhrwdHhG6RrOTUlPlEEaArDIhvXNSt/Z1upncPoWUzbNyZsPtcimEi3M0ChYdpAXqxMHiq4NKGZSxdPIjBLf1IIL1h7/yI2kYSobGeheGD17oQ//dj6CkfYQpWqxiHNxqSyXGHAxBXU5at0ZV4wQNjRkdw2Xi8nvK0frnz5zmUaBMeTwE93eH48tstVFCaYoVF1QJuHsHWcTESkd0kqQwhX/ttWL6ZilG53AwnVwXPJKpNbIkYtvgCGIl5z4XfNX9HzXb6SFLAQAA" } }, { "ID": "94f20514082ef2dd", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anon695cc71810ad4c55bb072df6e6a17690ff2b372f/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:11 GMT" ], "Etag": [ "GWexNmViIavplSMAEOgtCg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8q7h6dW+OWGZXomlhXkBPs6uvqnlzin29oCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwvXxgIhACzXrDpuAAAA" } }, { "ID": "b865fc640bf0c6f5", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "161" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUIDEuMyIsInVzZUxlZ2FjeVNxbCI6ZmFsc2V9fSwiam9iUmVmZXJlbmNlIjp7ImpvYklkIjoic1M0UmJ3SFIzT2ZMZU8xUVpleGFhZWxxcTgxIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:11 GMT" ], "Etag": [ "zRwl3x/rzBidgYZfBQLmVg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42S226bQBCGX6Xa3tbg5WhbitrEpi2S5cgYp0purGUZyCbAYnYdx4ny7hnAsao2qXoHO98//5yeyb2oUjIhici3O2gOn+9kQr4Q0CzH16doX9iPZvN0IdL8+ia7WM7Lq/zsDAnRqtStLIpDyapBCqUcaFB6sl4ZauVEyf5nZF9mc7ikyxt4ZAyK7XZEUamgyOaiukf9rda1mpjmm7uRS5kXwGqhDC7L07v5YJl1I++Aa2W+Y2pi1Rj42PZrITnTQlZn6xWWsFPQbKBkosAi2gSDRiZSf3sntSFYaeTIPwgOjHO5q3RbG2bhsspEvmu6xGTyTLpaf/sgq2AeTONP1LARTzGbqDo4ZkkBLXhsKvxgmK2KaaagJzYJgOV7STp2KXVo5nmuO2LUd8b2mI9T17G4DdbQZqjTrUWnYpWsKHf5kGejhNEsTXji0BHYnjt0/WRs2WyYpL5neU5GXrCtBpiGmVC1VKJvjUyj4DwONuH3zSIIZsEMDfaN+JP6FYUIxdF6MUUamboRErF2FOEiDqLzaRxeBf0C5pAzflhtcQUZKxSgM24xPtQ4GLJcB9E16Z8iyKCBiv/nwFDRR/95hG/3gCBeBBopjf+4IK5am24G7aJE2ZZDXd+yRr7vU8dzSAc3+q+YNxxj7HQEbUYoodLHnvpjIC9Hs506QRjEmS3CxQ+MvgINTuXUkwMAAA==" } }, { "ID": "93dd9cfa23fa6c66", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/sS4RbwHR3OfLeO1QZexaaelqq81?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:11 GMT" ], "Etag": [ "71y9+62Z5vwbNLDmhaDsHg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/yWPy26DMBBF/2W6LJFC30XKImlaUQmFhjSbVFVlYHikNgY8KUWIf884rOwjn7lzPcBvWaXgQVzmzQnb/ipH2tpLhOYkyfBR68ogOIAkcjYf3f75+uHmcP/XxZtgrQqxNn6+WLBhkgKVAG+ArESZGvC+BqiEQh7L5j9sUF9beAvC5Sej0qnFzT4IlqvgFcbv0YGjjiPMsMUqQZtVt/qICb3bmqbQUvZKVLMUlZ4RGoLLxPS6u4vizo9uwyzA0N0e8F8IlE3z5LIldSKo1BWL+x3wItIkZKQ77glWuPCq59CPVidoDNrQ+bTgRataInEjak/oQCL4s35JE49n0/piG0kBAAA=" } }, { "ID": "86cc422f0736f093", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anon1c5c0cf8ba1fdbcb418e365057b923a0bd76264f/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:12 GMT" ], "Etag": [ "9yJIpaHjf1+w8g+bCJ9lQg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8pbVnp5FiR6ZKUZapdbpGsnOXtZ5gSm29oCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwnrGSvVxgIhAJVrFwJwAAAA" } }, { "ID": "6a28edf445146345", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "179" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUIENBU1QoMS4zICBBUyBOVU1FUklDKSIsInVzZUxlZ2FjeVNxbCI6ZmFsc2V9fSwiam9iUmVmZXJlbmNlIjp7ImpvYklkIjoiN2EyeFNUUWo2SWRScDFTT1MzZk9RN3BYbVlYIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:12 GMT" ], "Etag": [ "RYvKFUaeFArqMORStLz+eQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41TWW+bQBD+K9b2pVUbYy5jLEWtZZMK1SEyRxs/WcsykHWAJezarRvlv3fAjlW1adQ3duY75uKR3PM6I1OS8uJhB+3hzVak5AMBRQuMhuv9l6uEwtWsfbi+CSO1/PkeVpeXiOAdS96JsjxUtL7IoBIXCqSaJtHQocaPKF5tx34WNnp0E5n5zcppbqv1LTIllPmS1/fIv1OqkVNNe3YfFkIUJdCGyyET1Tmu7Q2tacUWmJLaC6YaVi21V2w/loJRxUV9mURYwk5Cu4GK8hKL6AQuWpEK9ekF6SGn1bBA/J4zoIyJXa262lCFiTrnxa7thcn0kfS1/vZBIm/pzePBfBbFb/WhORjMokGQXHuhP3+HAhnq87qnxzQtoaOe2vT/Md6ORRWVcERsUgDDGaeZa+u6pefjsW1PqO5YrukyN7Mtg5lgjEyKPNVZ9Cxai5qmLjWobpq27kzS1J6MczsfWc7YclkOlgGZO5roE4c8YaMtUAULLhsh+bFZMg+9Wext/KtN4HkLb4EG31v+J+pb6CMoDpNgjmjENC0XCOuG4wexF87msf/VO65kCQVlh+gBl5LTUgI6417jQ4ODIavEC9fkGAohhxZq9p8DQ0afff0sny8EgXgjaCQVvnFBTHY2/Qy6RfGqK0e3HcOYOI5jmLpOenCr/spZpou581l0ilBBrU49Hc+DPJ3MdvIM6v69JAj84DNmfwFzGSZ4pQMAAA==" } }, { "ID": "efbbf8c52e45de87", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/7a2xSTQj6IdRp1SOS3fOQ7pXmYX?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:12 GMT" ], "Etag": [ "9vJLN2n6Q5FhEy8pQ/afGw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2PW0/CQBCF/8v4ChEwgjbhQUjVmgq2lQRjjFna6QX3ZncQm6b/3Sn4NHtmvzlzpoWvSmfgwa4qvg9YNxcFUtQ/YnQHSY6LNdohDABJFEze/jyFq4meRtf3pd/c2OhS5A/H+ZwJl5aoBHgt5BXKzIH33oIWCnksH30yQY3txWrz7MfBkhvKZOdGGN4tQh+6j24Ae7OLMccadYq9m63NHlMK+qCuNFI2SuhhhsoMCR3BaeL0OxOT3+Q12k+DLLbjZJ1c5etoZrfqbcuUNKmgymgGNwnwIjIkZGyOnBTG8K8XDZu+1CZF57A3HZ0XLI2yEokTUX3AAaSCz32s6Ky7P1XeRQlLAQAA" } }, { "ID": "19af92fd937f8244", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anonab9a2a1335178bb586f5f047649cfe42ed908187/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:12 GMT" ], "Etag": [ "hvLBYqVtCaXte/5R5DSPIQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8pnlPk4RRaGlTgnRpSk6psGmboEB3gG2toCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwnrGSvVxgIhAFga5mdwAAAA" } }, { "ID": "c354e0039c93a7bf", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "172" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUIE5VTUVSSUMgJzAuMjUnIiwidXNlTGVnYWN5U3FsIjpmYWxzZX19LCJqb2JSZWZlcmVuY2UiOnsiam9iSWQiOiJYQkdVNHh6NExxUzhaNkRKSFpxalg5OFRNaFYiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0In19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:13 GMT" ], "Etag": [ "436CKvzFMjVpfVToxL2c8g==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41SXXOaQBT9K5ntQ16qCIKAM06bKklp1Zki2DQvzrJccA2wyK42JpP/3gsap5NJM31hlnvPuefcjydyz8uEDEnMs+0O6sOHjYjJRwKKZhg1+4Px9/3j9WyzrNJlKB6mBnOy0QgRvGHJtcjzQ0HLTgKF6CiQahgturdfbiLz4dGcbhfO3WDy7evddnPrOuFsvUSmhDyd8vIe+WulKjnUtBf1biZElgOtuOwyUZzj2t7QqlpsgCmpvSGqoWupvSP7KReMKi7KUbRACzsJ9QoKynM00RTo1CIW6vMbpbucFt0M8XvOgDImdqVqvGEVJsqUZ7u6LUyGT6T1+teDLLypNw4v5tHMC/zxxWWva1iXyEywMC9bXkjjHBrOqT//H3NtWFRRCUfEKgYw7EGcuJaum3o6GFiWQ3XbdPsucxPLNFgfjF6fIk81Ei2Llmh5kLCEgWM5eqynOrNdI9bthMXU6JtGzzR0140hAfKMHdZAFUy4rITkxy7JOPCuQm/lX6/mnjfxJijwu+avUT8DH0FhEM3HiEZMVXOBsGYq/jz0gqtx6C+94y6mkFF2WGxxGynNJaAyLjQ8VDgY8iPygl/kGAoghRpK9p8DQ0abff8eX04DgXgcKCQV/uOCmGxk2hk0i+JFY0e3bMNwbNvGj0NacK1e5/q9nom58z00FaGAUp16Ot4FeT6J7eQZhEmc2dyf32D2D7vaNkSeAwAA" } }, { "ID": "fe0ee3019698b88e", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/XBGU4xz4LqS8Z6DJHZqjX98TMhV?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:13 GMT" ], "Etag": [ "pmJcnt84JtvgqNpAvB87vQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2P3U7CQBCF32W8hQQTopWEC4pEIIVIEUIwxizbaSnuT9sdqrXpuzulXs2e2W/OnKnhKzURjOCUJvkVi+ouQdq0jxDdVZHjklnjEHqAJBImM72UhrzhksokX2eT0vcey814zISTZ9QCRjXEKarIwei9BiM08lg8+GSCqqwV691qFi6m3NA26hpBMPGDGTQfTQ8u9hRijAUaia1bVtgLSlq0Qd3ZKlVpYfoRatsndAS3idvvwX/ZDX9+h0G+9Y4Pz8v5Mb8cnry31XnPlLJSUGoNg7st8CKyJFRovzkp3MO/9is2fS2sROewNR10C6ZWZwqJE1FxxR5IwefOU+p08wcuBbyfSwEAAA==" } }, { "ID": "e0573a6f3db3f701", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anonf6dcdce8581b1f1c792b17dcba2342042199bede/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:13 GMT" ], "Etag": [ "A/8NXo6FaEm2YMDaS+G49g==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8o76lv4ReSbuSW65hpF+rokBmu7m1im29oCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwob6BmZKtXGAiEA1xSA7XEAAAA=" } }, { "ID": "bbebddcca13227b0", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "162" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUIFRSVUUiLCJ1c2VMZWdhY3lTcWwiOmZhbHNlfX0sImpvYlJlZmVyZW5jZSI6eyJqb2JJZCI6ImVGWkQ3WTQzS1Z1S1J6b0FPaUlaSUpXMGNjWiIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:13 GMT" ], "Etag": [ "jBy7bR963Bg6IV4C/toHFA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42S227aQBCGX6Xa3haMvT5gJNQSMK0bRFVjiMINWq/HzhLbS7zrVDTKu3dsCKraNOqdvfP988/pidyLKiUjkoj8oYH6+H4vE/KBgGY5vu6vjl4S+S69yt1wY08NLb/MJ+MxEqJVqTtZFMeSVb0UStnToPRoverDfDvzbm16vWmuo59y8k2E2/DrzYDzLSoVFNlCVPeov9P6oEaG8eLez6XMC2AHofpclpd349EyDrXcA9fKeMXUwKqV8Ybtx0JypoWsxusVltAoqHdQMlFgEW2CXi0TqT+9krovWNnPkX8UHBjnsql0Wxtm4bLKRN7UXWIyeiJdrb99kFWwCKbxuzhaB8inmE5UHR2zpICWPHcV/mOarYpppuBE7BIAy3OT1HdM0zYz13WcITM926c+91PHtjgFa0AZ6nRr0alYJStqWi71HQo09VNIKfPBTFzbBMfjtp8NbcfN0sxKyDP2VQPTMBPqIJU49UamUTCJg1043y2DYBbM0OBHLf6kbqIQIWx3OUUamUMtJGLtLMJlHESTaRxugtMGFpAzflw94A4yVihAZ1xjfDzgYMj3dRDdktNTBBnUUPH/HBgquujbV/hyEAjiSaCR0viPC+Kqtelm0C5KlG05puNZ1tDzPOoNXNLBtf4rNnQpxi5X0GaEEip97ul0DeT5bNaoC4RBnNkyXH7G6C/YhbGplAMAAA==" } }, { "ID": "c8c775ce119daee1", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/eFZD7Y43KVuKRzoAOiIZIJW0ccZ?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:14 GMT" ], "Etag": [ "hF5EOg7/+nwCjf5WCDdSug==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2PYU/CQAyG/0v9KESMEhISPgwYcbIwHUEixpjj1o3h7Tp3Xchc+O924Kfe23v69m0L37lNYAz7PPupsWpuMuTX7hGjqw07KSVZh9ADZJUJeVgM/Sgb3d3a0+yYDrezebKus8lECKcPWCgYt5DmaBIH448WrCpQxtLBlxDclJ2YRlHoeytpFJR0jdUmDL1p6MP589yDI+1jTLFCq7FzKys6ouagC+oOZExTKNtPsKA+o2O4TFx+cbGbj94fH5Zv9TL+JS/Kg13wvB1ovRPKkFackxVwswZZxMTKxHSSpHAP/3raiOlLRRqdw850cF0wo6I0yJKIqxp7oJWc+5TzVZ//ACZTwtdLAQAA" } }, { "ID": "895e5593f613b3f7", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anon31263953e3d9ded3a9e1b641e57c49f8456fdf2b/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:14 GMT" ], "Etag": [ "Xrf5H8p4GeP/MpXndIN69A==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8pHFKWZelgUmLinBuj7FkTkpXj6mVk62toCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwqXFJWmKtXGAiEA/0a8lXEAAAA=" } }, { "ID": "71e02ae0792f9ee3", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "163" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUICdBQkMnIiwidXNlTGVnYWN5U3FsIjpmYWxzZX19LCJqb2JSZWZlcmVuY2UiOnsiam9iSWQiOiJzcGdqMlh3TnRyc0Y4dW9RWndBc2lNSGM1cEYiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0In19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:14 GMT" ], "Etag": [ "PqKewwXdN+y9IYGWeDtt1g==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42S227aQBCGX6XaXuSiBeMTxkiopWBSK9RqjGmS3qD1euwssb3Guw5CUd69Y0NQ1SZVJS7MzvfPP6cn8sDLhIxJzLNdA/Xh/VbE5CMBRTN8/b67gv3+Ngk+HFz/7vIG5krp2WSCBG9V8l7k+aGgZS+BQvQUSDVer/qyyrbG7T5QtVyMGnH9cz+V/NtXZlcLVErI0yUvH1B/r1Qlx5r24t7PhMhyoBWXfSaK87v2aGhVLbbAlNReMdWwagy8bfspF4wqLsrJeoUlNBLqDRSU51hEm6BXi1ioz6+k7nNa9DPkHzkDyphoStXWhlmYKFOeNXWXmIyfSFfrbx9k5S29WfTuYvpldoGCBPPxssMjGufQoqe2/DfG2aqoohKOxCYGMJxhnLi2rlt6Ohza9ojqjuWaLnMT2zKYCcbApKhTrUWnoqUoB7EzNBOaMhd/4MR6PLQck0KaGjoDOzFSd5TasUmesbEaqII5l5WQ/NgcmYXeNPI2/mITeN7cm6PBvuZ/Ujehj1AUroMZ0shUNReItcPwg8gLp7PI/+EdV7CEjLLDaodLSGkuAZ1xj9GhwsGQ67UX3pHjUwgp1FCy/xwYKo7Rf57hy0UgiDeBRlLhf1wQk61NN4N2Ubxoy9FtxzBGjuNY5sAkHVyrv2KWYWDsfAZtRiigVKeejudAnk9mjTxDGMSZBX5widFfxP0B5pUDAAA=" } }, { "ID": "8670320015dae37c", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/spgj2XwNtrsF8uoQZwAsiMHc5pF?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:14 GMT" ], "Etag": [ "z4Lg4AtWFTTOlb2ey96Qyw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2PYUvDMBCG/8v5dYM5puhgHzaxblCn6zYURSRNr11rmovNlVLL/rtX66fkIc+996aDr9wmMIc4z75rrNqLDHnXXyL0tWEvhyPrEUaArDIxf2ZhNlvyS3A4PJl4iu3t9a5tFgsxvD5hqWDeQZqjSTzM3zuwqkQZSyefYnDretgfos32QbikpOftMQyXq/Aezh/nERQUR5hihVZjH+YqKlDzpu/pT2RMWyo7TrCkMaNn+JsYXl1WTF+bLVc+uKlp99Ysff641lcuEMuQVpyTFfG4B1nExMpE1EhRuIR/XrUS+lyRRu+xD50MC+6odAZZGnFV4wi0kt+ucx74/AsFQBIbSgEAAA==" } }, { "ID": "fd1727ed20e6bc69", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anon0b763dafc9fc9e7b1b6473aeff21ce5d2f98f5b3/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:14 GMT" ], "Etag": [ "BtqUgTOhmUHTXegWr7oUdg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8o7lRSGpof4Z+SGeoREpKaHF5nnh6ak29oCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwo7Ojkr1cYCIQCAg1BAcAAAAA==" } }, { "ID": "0265ddba6f22f4c5", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "178" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUIENBU1QoJ2ZvbycgQVMgQllURVMpIiwidXNlTGVnYWN5U3FsIjpmYWxzZX19LCJqb2JSZWZlcmVuY2UiOnsiam9iSWQiOiJpR3l4dGNGd0lkMHRzV2VZbjVKcVZQODBIQXkiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0In19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:15 GMT" ], "Etag": [ "2t5a75k26+WA7RHv8u6SrA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41S0W6bQBD8Fev6kFatjTkbA5asltokobKsFnAsP1nHsZCLgXO4c1Iryr93wY5VtWnUN7id2Zmd3SeyFVVKxiQR+f0e6sO7O5mQTwQ0y/GVaovZ1paOPq48O7x+cPajqPYmE0SIhqVuZVEcSlZ1UyhlV4PS42XUE1eHn5pfPgZpX6sVrCvr2/3Nd6d/7R2QqaDI5qLaIv9W650aG8aLei+XMi+A7YTqcVme340HauxqeQdcK+MVUQNdK+MN2c+F5EwLWU2WEVrYK6g3UDJRoImmQbeWidRfXmndE6zs5Yh/EBwY53Jf6cYbduGyykS+r9vGZPxEWq+/fZDIn/vTuDP1ovj9RSblRceLOl/XsR99QH6K7UXVsmOWFNAwT1MG/0i3YTHNFBwRmwSA2qMkdS3THJrZaGRZDjPtoTtwuZtaQ8oHQPsDhjzdSLQsVqFx7qQ0c/qWm4wsCn17OHTMjDrMztKEUZrYnGYumOQZ56yBaZgJtZNKHGcl09D3Yn8TXG4Wvj/zZyjwWIs/UaswQFAcLhdTRCNmVwuJsCabYBH7oTeNgxv/uJE55IwfonvcScYKBaiMa40POwyG/Fj64Zocn0LIoIaK/2dgyGirb1/ly4EgEE8EhZTGf1wQV41Mm0GzKFE2dkzLptSxbXvoDCzSgmv9V821+lg7X0XTEUqo9Gmm43WQ55PYXp1BWMTMFsHiCqu/AI8MWTekAwAA" } }, { "ID": "35aedafc33d2b22b", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/iGyxtcFwId0tsWeYn5JqVP80HAy?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:15 GMT" ], "Etag": [ "i/lUk1IxYckS0pr2nS/mCg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2P3WrCQBBG32V6GzEWCkXwwoitllBs0rRIKWXdTOKa/YnZEQ0h796JerV72DPffNtBpWwOU9ip8njCpn0okT6GS4L+pMnzUTvrEQJAEiWbaqyzarK+bGWVhnXzaNOxWZSzGRte7tEImHZQKNS5h+lPB1YY5LEi/GOD2nqAaPu5TBmNywd8z+J4HsVL6H/7AA5ul2CBDVqJQ1bduANKWg81/d5p3RphRzkaNyL0BNeJ66t6bS8kX87rPCT/jVv79Hb82jyHq3nLlnZSkHKWxSwFXkSOhE7cmXvCBO4ctRy6aZxE73EIDW8LFs7UGokbUXPCAKTgz64U3bj/BztM1StJAQAA" } }, { "ID": "c13f69754efe00f1", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anonfc8d2f8059b652e074481f28a7fdba22b7c2f9e1/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:15 GMT" ], "Etag": [ "cjTd1Ashk9AiyCldTUt9Wg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8onZ4WkGDoWZ2RbOmZWOuekhISWWIan29oCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwpH5VqWKdXGAiEAuXln13EAAAA=" } }, { "ID": "c89c51b1d5fb9507", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "189" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUIFRJTUVTVEFNUCAnMjAxNi0wMy0yMCAxNTowNDowNSciLCJ1c2VMZWdhY3lTcWwiOmZhbHNlfX0sImpvYlJlZmVyZW5jZSI6eyJqb2JJZCI6Ijk3M2ZFbFlUWkQ0RFVZMEJkbGpwVXpNNWs1TyIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:15 GMT" ], "Etag": [ "e2IXt3r3ntAXXpTjvmueCw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41SW4/SQBT+K2R82Beh12mBhChCNU0WVCgKvpDp9LQ70Ha6nYENbva/e1pYYnTd+NbO+W7n8kj2okzIkMQiuz9AfXqzkzF5S0CzDF/BDtfaqZ1Sj9frKtodiwNMHkYjRIiGpe5knp8KVnYTKGRXg9LD1bI38J00yDfRj6k7XW3MD0m+q1Y/Z3RPPyNTQZ7einKP/DutKzU0jGf3XiZllgOrhOpxWVzfjaNtVLXcAdfKeMHUwNTKeMX2XS4500KWo9USIxwU1FsomMgxRCPQrWUs9fsXpHuCFb0M8UfBgXEuD6VusqEKl2UqskPdCpPhI2mz/vZBlsFtMIk6UTgLltF49qVzY5uW1zWdrm12LDo03aFJb1AqQSdRtkIRi3NoRC4Nh/8YdMNimik4I7YxgO17cTKgluVaqedR2meW7w6cAR8k1LW5A7bpMOTpxqJlsVKWScIdb4Bs6rAU+pxT1zJN1/P8lCW+Y8acO7HleuQJW66BaZgKVUklzm2TySIYR8E2/LidB8E0mKLBQy3+RH1fhAiKFqv5BNGIqWohEdaMKZxHwWI8icJvwXk5t5Axflre43pSlitAZ9xwdKpwMOTrKlhsyPlpASnUUPL/HBgy2urrB/p8KwjEa0EjpfEfF8RVY9POoFmUKJo4FvVtu+/7PnU9Slpwrf+q0b6NteuBNIpQQKkvPZ0PhTxdzA7qCsIizmwezj9h9RdUr3uWrwMAAA==" } }, { "ID": "95fb4a7629f589e4", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/973fElYTZD4DUY0BdljpUzM5k5O?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:15 GMT" ], "Etag": [ "R2ZZ+4ZhyYKisJ8YTVrrTQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2P0U7CQBBF/2V8tCSoEJWEBypNREGhtCatMWZpp7Cw7dbdIaY0/XdnwafZO3vmzp0WDrLKYQQbuf05ommutkgr9wjRHhVZLrWuLIIHSGLLZHibpteDdNckr9K+PCTRhzHRajxmwmY7LAWMWigkqtzC6LOFSpTIY0X/mwlqaiei2SJYR5PFklulzl3rLZ7PJ/48gO6r82CvNyEWaLDK0PnVRu8xo5mLandaqaYUVS/HUvcILcF54vz7eH9XBCqJ0ulgGid9P1f7Oj4thofhO1NKZ4KkrhiM18CLSJNQof7lrHAD/9pv2HRpdIbWojPtXxY86bJWSJyIzBE9yAQf/Czpors/mhapc00BAAA=" } }, { "ID": "2c9092387bf660e1", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anonddc369ee253afe8cc541004667fad730bcc3b146/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:16 GMT" ], "Etag": [ "ZZYu21RieP64P5ZzIka7eg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8pHRUWWGhkGZaYGmJkEmEZVeWYnmqem29oCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwmbmFqYWJgZmZjqGSjVxgIhAFxk/CB5AAAA" } }, { "ID": "ea2d27a5290eda97", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "224" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUIFtUSU1FU1RBTVAgJzIwMTYtMDMtMjAgMTU6MDQ6MDUnLCBUSU1FU1RBTVAgJzIwMTYtMDMtMjAgMTU6MDQ6MDUnXSIsInVzZUxlZ2FjeVNxbCI6ZmFsc2V9fSwiam9iUmVmZXJlbmNlIjp7ImpvYklkIjoiakVyR3BVWVNHM2JmVzRlTk5Gd1ZCYTc5ZkNRIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:16 GMT" ], "Etag": [ "0Mya8IU2azX5iyMvu0m4Zg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41SXW+bQBD8K9b1IS+x+QZjyWpdm0RIMUpsnDStKus4FnIOcIQ7O3Kj/Pcu2ImqNk37BrszO3Oz+0TueZWSEUl4/rCFZv9hIxJySkDRHKv6fE+H4cqkP744fD/fbfXS/pqPx4jgLUveiaLYl7Tqp1CKvgKpRqvlYBM05/XqdnluJdmNDVF09nj9mXp+Nr1CpoQiu+DVPfLvlKrlSNNe1Ae5EHkBtOZywET5Wtd2plY3YgNMSe0NUQ1dS+0d2Y+FYFRxUY1XS7SwldCsoaS8QBPtgH4jEqE+vTF6wGk5yBG/4wwoY2JbqdYbTmGiyni+bbrBZPREOq+/fJBlcBFM4963OJwHy3gyv+ydmLrh9nWrb+o9wxnp9kh3Tk57/wB8R7UUzfCq04ppUkCrc8wk/MsuWhZVVMIBsU4ATM9NUt8xDNvIXNdxhtTwbN/ymZ86tsksMHWLIk+1Eh2LVqJivuNTn7q+5VDb9ayUpZZvJEOa6K5vZqmRALMylpBnTKUBqmDGZS0kPyRDpotgEgfr8GwdBcEsmKHAY8N/R90sQgTFi1U0RTRi6oYLhLVJhlEcLCbTOLwODvu7gJyy/fIBN5jRQgIq4xHE+xqDIVerYHFLDqUFZNBAxf4zMGR03fdv+OWcEIgHhUJS4T8uiMlWpsugXRQvWzuG45nm0PM813Rt0oEb9UfPNgzsvd5QOxFKqNTxTYdbIs9Hsa18BWETM4vC6By7PwGM5RFY0gMAAA==" } }, { "ID": "e5738af6ffd8d805", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/jErGpUYSG3bfW4eNNFwVBa79fCQ?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:16 GMT" ], "Etag": [ "819MqO5nCRR33cplwA+emA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2P3U7CQBCF32W8tCQQNEoTLgpW5AIsBTTGGLPdTkvr/pTuNE1DeHem4NXsmf3mzJkT/BUmBR+SIj82WHd3OdKmf8ToGkWOS2WNQ/AASeRMPo8mq+P7o5nH8XgsK9UG96iD6ZQJJw+oBfgnyApUqQP/+wRGaOSxbPjLBHVVL3bLVbjdBauIW9qmfSsOozDYhS9w/jl7UNokxgxrNBJ7v6q2JUpa9lHdwSrVaWEGKWo7IHQE14nrbxnWi2r/tV2Mk+zzAdfr1/ZjJp4m2XzDlLJSUGENg/st8CKyJFRsW84KI/jXs45No9pKdA570+FtwdzqSiFxIqob9EAKPvitoJs+XwA02RmKTQEAAA==" } }, { "ID": "01aa5a18e5d62863", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anonc959a9a6935a4673dcd391b8ab0692fd1bec3fcb/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:16 GMT" ], "Etag": [ "h/p+c3Kb+mBdfNyGpruFnQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8pn6BdoJxt7J2nnOqWk+VW6FxSVuuUF2toCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsg5FKhiamFiYWZkYmpnoGSrU62ARjwRAArOfkwZYAAAA=" } }, { "ID": "138fc8da4db90b35", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "200" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUICgnaGVsbG8nLCBUSU1FU1RBTVAgJzIwMTYtMDMtMjAgMTU6MDQ6MDUnKSIsInVzZUxlZ2FjeVNxbCI6ZmFsc2V9fSwiam9iUmVmZXJlbmNlIjp7ImpvYklkIjoiNkpyU1AxcVFuanJnY0lFUU8wU0lGRlp1cHBZIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:17 GMT" ], "Etag": [ "PWv7r46rU9diCHiAfULZwA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41SbW+bMBD+K5H3IZvUBEOAhEjVFqV0Y0qzNpBV7ZfImIO6BUxsp1VU9b/vIG01bV01Phnf83J+7h7JnagzMiWpKLY7UPsPtzIlRwQMK/D2/PJ+rFxfrYNMzL+JWb5eXD/Mjo8RIVqWvpFlua9YPcigkgMD2kzX8dD/ruJze3tR36qCR+HFDxpHp6fXu6a5QqaGMl+I+g75N8Y0empZL+7DQsqiBNYIPeSyer237h2rUfIWuNHWG6YWdq2td2w/l5IzI2R9vI6xhZ0GtYGKiRKbaAUGSqbSfHlDeihYNSwQfy84MM7lrjZtb6jCZZ2LYqc6YTJ9JF2vvx1IHC7CedL72L+BspT9o14SnYVxMjs77/UdavsDOho4tGd7U+pOqdf/hKoZmoq600xYWkKr9/z26B+ZtyxmmIYDYpMCOGM/zQLPtl07933PmzB77AajgAeZ5zp8BA4dMeSZ1qJjsVrWaRqkWc4D30td5ud5nrl85OfMm6TUD6g94dTzxpSSJ3y9AmbgROhGanFIgMxX4SwJN9HpZhmGJ+EJGjwo8SfqchUhKFmtl3NEI6ZRQiKsTSxaJuFqNk+in+FhTgsoGN/HW5xUzkoN6IzDTvYNBkMu1uHqihyuVpCDgpr/Z2DI6Krv7+rL2iAQFweNtMF/HBDXrU2XQTsoUbXt2N7YcSZj/OgoIB1Ymb9qju1g7XVXWkWooDbPbzrsDHl6NtvpVxAWMbNltPyK1V+y0B3IugMAAA==" } }, { "ID": "f1c09fb77760de4c", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/6JrSP1qQnjrgcIEQO0SIFFZuppY?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:17 GMT" ], "Etag": [ "+08gTPak/XohbbDj9b7H3A==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/22QyW7CMBCG38U9NqihlbogcWAJJRVLSILURRVynCEkOHawHVUR4t07DgekFvlg/+P/m+1I9rlISY8keXaoQTU3GZiVfYSga240XpUUGohDwNAMnbfucxYHdH/3LndJMi5ekqfpw6DfR4dmOygp6R3JNgeeatL7OhJBS0Bs627QYZrKitAbLcMx6lKmVi/Ws9lgOPMw8p/ctKFN94JHcegvXq/gJ+cvdX+hYn/uRfFgHlwDv/E4pJBJCFtQIBjYMSolC2DGtxvSO8l5U1LRSaGUHQPakJZofx/fVBR0DytRqIz53mrpRv5k8llX1Qe6uGTU5FKgcR1hl8RIQ3kof3BQ0g5m9bDBpIGSDLQGm9Q9FxjJsuJgsCOjanAIo7jnaW7O+vQL00g/EcQBAAA=" } }, { "ID": "04c67ce3f359af83", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anonbb9bdfc965b4a6fffd4c36fa58b069018c055700/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:17 GMT" ], "Etag": [ "DWf2CqKOtHFXTtNDtYnmcQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8q7hKcZORd6+5d4uEWElPi5lETm5SYH2toCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsU7JCYiplpObk5CvV6kB4hiamFiYWZkYmpnoGSrWxtUAUWwsAdAtlOpUAAAA=" } }, { "ID": "02d948abc01ca43f", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "199" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUIERBVEVUSU1FKFRJTUVTVEFNUCAnMjAxNi0wMy0yMCAxNTowNDowNScpIiwidXNlTGVnYWN5U3FsIjpmYWxzZX19LCJqb2JSZWZlcmVuY2UiOnsiam9iSWQiOiI5SlRJMjZZcFRZMktzWWJjTTVJT2Z1SG9mZHoiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0In19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:17 GMT" ], "Etag": [ "Yxu09UMtBTazcyaBpBfplA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41SW4+TQBT+K834sJrYAlMuhaTRXlDRtmpLNX1qhmFgZxcYlhlWu5v9756h3cboupEHAud8l3O7R9e8SlGAEp7ftKw5vLgSCXqNmCI5RHc/W9PfLtU0Jnf0QKb1NKuLyXgMCK5Z8lIUxaEkVT9lpegrJlWw3Qz8j3GE3V0d7/AnuUvo0ok+Z+0HkaV3wJSsyBa8ugb+pVK1DAzj0X2QC5EXjNRcDqgoz3HjFht1I64YVdJ4wtSAqqXxjO2bQlCiuKjG2w2U0ErW7FlJeAFFaIF+IxKh3j4hPeCkHOSAv+WUEUpFWyldG6hQUWU8b5tOGAX3qKv1tw+0CRfhLO7NJ3EYR8vwpX5t4snyS+8Cm5bbN4d9bPYsJzDtwHQuXoFoCp686iRjkhRMy51aj/4xcs0iikh2ROwTxrDnJqnvWJZtZa7rOCNiebY/9KmfOjamQ4bNIQGe0hYdi1SiMj3fc/EoSz1vRD3Lo9jFJvbdzLJMNyV25pg+SIzQAzTfMKLYnMtaSH4cAJqtQ+h0H73br8JwHs7B4EfD/0R9X0cAitfb1QzQgKkbLgCmBxat4nA9mcXRt/C4pgXLCT1sbmBRGSkkA2fYdXyoYTDo6zZc79AxtGYZa1hF/3NgwOiyz5/q49UAEO4GjKSCf1gQldqmm4FeFC91OZbjYTzy4HEtG3XgRv2V82wXcudT0YqsZJU69XQ8GfRwMmvlGQRJmNkqWr2H7C/rRtVBuQMAAA==" } }, { "ID": "e5b2b4eacfc94dfc", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/9JTI26YpTY2KsYbcM5IOfuHofdz?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:18 GMT" ], "Etag": [ "hmmfL34hyyt8dewrxChJ9A==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2PW2+CQBCF/8v0FRNrL6kkPqA1EYu9KD6QpmnWZRDsLkPZIZYS/3sH7dPsmf3mzJkOvooyBR92xf67wbq92iO/9Y81usawk1JR6RA8QFZ7IXNrs+jmNm9bfkjxWP/M8uU4mEyEcDpHq8DvICvQpA789w5KZVHGsuGnENxWvXgM4nkcrubSsZT2nedtFAXTaA6nj5MHB9qtMcMaS429XVXTATWHfVKXkzGtVeUgRUsDRsdwnjj/jpdxOLpPqjgZPblkp1d34UvWLChLf4UypBUXVAq43YAsYmJl1nSUqHAN/3raiulrTRqdw950eFkwI1sZZEnEdYMeaCX3Lgq+6NMfpLToLUwBAAA=" } }, { "ID": "b5551bcfb73c63ea", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anon0797628fd778c717c2620296f1106da4f5099c98/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:18 GMT" ], "Etag": [ "BOqxJjnumc3F2wdr/uajfw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8o7+RdWeGXlleYmG7sZlacU6ZcmZqWV29oCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwobGRia6RoY6xoZhBiaWhmYWBmYKtXGAiEAdUI0VIAAAAA=" } }, { "ID": "9aa2747173396412", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "195" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUIERBVEUoVElNRVNUQU1QICcyMDE2LTAzLTIwIDE1OjA0OjA1JykiLCJ1c2VMZWdhY3lTcWwiOmZhbHNlfX0sImpvYlJlZmVyZW5jZSI6eyJqb2JJZCI6InQ3VlpYdW5kRHdUMVRKNXZ6ZFp6MUQzd1ZvcSIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:18 GMT" ], "Etag": [ "WmLkCQFQDSsL77CDjD5qbw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41SW2/aMBT+K5X30E0a5IYJQUIbIumUiqIBgW59QY5zkpomMcQGRKv+952EFk1bV+0t8flu5/JEHkSZkD6JRbbdQXX8sJYx+UxAswxfb4vxw2h6NfXnauy6I3/t0218GAwQIWqWupd5fixY2UqgkC0NSvcX87Z2l3c/dmXiHyIruqb7x+Tu0fKdw1JukakgT8eifED+vdYb1TeMV/d2JmWWA9sI1eayOL8be9vYVHINXCvjDVMDUyvjHdsvueRMC1kOFnOMsFNQraBgIscQtUCrkrHUX9+QbgtWtDPE7wUHxrnclbrOhipclqnIdlUjTPpPpMn62weZB+NgFF34wyj4GIU3wTwa3ny/uLRNq9synZZtXli0b3b6Jr38hIIJ+omykYtYnEMt9dJ2+I9x1yymmYITYhUD2G43TjxqWR0r7XYp7THL7XiOx72EdmzugG06DHm6tmhYrJSl68RJ0jOhC7bToVaaupTx1LSAJ6mTdrjVczmlHiXP2HgFTIMv1EYqcWqejGYBdrkKr1aTIPADHw0OlfgTdTsLERTNFpMRohGzqYREWD2scBIFs+EoCpfBaUVjyBg/zre4pJTlCtAZ9xwdNzgYMl0Es5/k9DSDFCoo+X8ODBlN9f0zfb0YBOLNoJHS+I8L4qq2aWZQL0oUdRyLurbdc123Zzs90oAr/VfN8Tysnc+kVoQCSv3S0+lcyPOL2U6dQVjEmU3CyTes/gLAyr4GtQMAAA==" } }, { "ID": "a3e1a3f5ebde33bd", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/t7VZXundDwT1TJ5vzdZz1D3wVoq?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:18 GMT" ], "Etag": [ "iSWojQNy4KVHxvQuAA6DvA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2P3W6CQBBG32V6q4mkfwmJF1hMbEtMQbSNTdOsMCp02UF2wCLx3Ttor3ZP9sw333bwk5kUXNhku0ONVXuzQw77S4S21mzlKMlYhAEgq52Y2eKd8nDe3r2uZr9NWHveg99447EYNtljocDtYJuhTi24nx0YVaCMbUffYnBb9uB78VSooLSn+TIIvEkwhfPXeQA5bSLcYoUmwT6qrCjHhJ/7lnZPWreFMsMUCxoyWobLxOWVH1frj9qk/jF24pf75pSuT45/e1zRQSxNieKMjIjLBcgiJlY6oqPUBAf+edJK6FtFCVqLfejouuCJilIjSyOuahxAouSvs4yvfP4DguTA70gBAAA=" } }, { "ID": "dc2cf4102e358449", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anon73bdd80e6e23451ff75acf01ecdf3f4c187c5595/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:18 GMT" ], "Etag": [ "55aLywss8knVv/Jc8SvVMA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8qbmib6VJYXF1tk54WV6XslWwSXhfk62toCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwobGRia6RoY6xoZKNXGAiEA8IWd+XcAAAA=" } }, { "ID": "1d1c95863fae2608", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "195" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUIFRJTUUoVElNRVNUQU1QICcyMDE2LTAzLTIwIDE1OjA0OjA1JykiLCJ1c2VMZWdhY3lTcWwiOmZhbHNlfX0sImpvYlJlZmVyZW5jZSI6eyJqb2JJZCI6ImJQN2hzbXFqaVJ3QTFXRzhBVWlIOUJpTWlQbyIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:19 GMT" ], "Etag": [ "lShrfmYZ9y9u2bJHws32nQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41SWU/bQBD+K2j7QCs18RUfGwm1aeKCUYjAcYroS7Rej50NtjfxbogixH/v2AFUtRT1xVrPfMdcj+Re1BkZklQU2x00hw9rmZLPBDQrMFrOV01e3f2kB7qz08uLvXLs+ubsDBGiZamVLMtDxepeBpXsaVB6uJj302t/partWsT7kXV7HowW4oJ+E1fiWiJTQZlPRX2P/JXWGzU0jBf3fiFlUQLbCNXnsnqNGw+2sWnkGrhWxhumBlatjHdsv5SSMy1kfbaYYwk7Bc0SKiZKLKIV6DUylfrrG9J9wap+gfgHwYFxLne1bmtDFS7rXBS7phMmw0fS1frbg8zDaThOTpLoKvzYfubJ6Or65NQ2La9nOj3bPLHcoTkYmu7pJxTM0E/UnVzC0hJaqee2o3+Mu2UxzRQcEcsUwPa9NKOuZQ2s3PNcN2CWP6AO5TRzBzZ3wDYdhjzdWnQsVss6pRY1cxp4yEuzwAJ/AJmXZabpcJpbjh/YGR2wgDxh4w0wDROhNlKJY/NkHIejJFxG35ezMJyEEzTYN+JP1G0cISiJF7MxohGzaYREWDusaJaE8WicRD/C44qmUDB+mG9xSTkrFaAz7jk5bHAw5GYRxnfkGIohhwZq/p8DQ0aXff9MXy4GgXgzaKQ0/uOCuGptuhm0ixJVW47l+rYd+L4fBL5HOnCj/8pRP8Dc65m0ilBBrZ97Op4LeXo226lXECZxZrNodo7ZX0SaCe+1AwAA" } }, { "ID": "58310ba59c94e020", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/bP7hsmqjiRwA1WG8AUiH9BiMiPo?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:19 GMT" ], "Etag": [ "zjXAzkuT1Ma2p+A3NXouZA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2P0U7CQBBF/2V8FBLQB7UJD4shQtISrBCJxpilHdotu53SnYaUhn93Cj7tnuyZO3c7OJgyhQB2Jjs2WLd3GfJ7f4nRN5a9HBWVHmEAyDoT81xs1fnQrMeRfqju1eNyS82XmkzE8EmOTkPQwd6gTT0E3x2U2qGM7Ue/YnBb9bBeRDMhR2lPy00Yqmk4g8vPZQAF7WLcY41lgn1UVVOBCS/6lj4na1uny2GKjoaMnuE6cX3drZ5y746FiU9q/Pn2rDZm/jI1kVmRWJYSzYZKETcfIIuYWNuYTlITxvDP01ZCVzUl6D32oaPbgldylUWWRlw3OIBEy1/nhm98+QNS+JF4SAEAAA==" } }, { "ID": "c8af0f80e29a40e0", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anonb9190f986114bd81e74ed6dd003c9f13782d94a8/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:19 GMT" ], "Etag": [ "Dkkf1RAnz70opW6EE5Vizg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8q7ZGenGQY55lWZG+QXhJu5upqGZVal29oCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwmbWhmYWBmYKtXGAiEApv30XXUAAAA=" } }, { "ID": "dd6b02082e1c8063", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "164" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUICgxLCAyKSIsInVzZUxlZ2FjeVNxbCI6ZmFsc2V9fSwiam9iUmVmZXJlbmNlIjp7ImpvYklkIjoiZ3pKNndJcmJkS2ZveGJ1ZXpGWXlCZlBMYUZoIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:19 GMT" ], "Etag": [ "yu8qsJBhsEZ8IoFXXozS0w==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41SXW/aQBD8K9H1pZUSjL8xEmoTMJUThFowbdIXdD7W5hLbZ3znUIjy37tnCKraNOqbfTuzMzu7T+SBlyvSJwnPNg3Uu3f3IiHnBBTN8HXX9Dby+motwx+9SIxvb8V+3t0OBojgmiXXIs93BS0vVlCICwVS9RfzTra/9rZRnaxuUvEzaWA/vttdpV8mdLxGpoQ8nfDyAflrpSrZN4wX9U4mRJYDrbjsMFGc3o1Hy6hqcQ9MSeMVUQNdS+MN2Y+5YFRxUQ4Wc7TQSKiXUFCeownd4KIWiVCfXmnd4bToZIh/5AwoY6IplfaGXZgoU541dduY9J9I6/W3DzIPJ+EwPntvnp9ZH5Cxwoa8bPExTXLQ2ONc0T/y1CyqqIQDYpkAWL6XrALXNB0z9TzX7VHTdwI7YMHKdSxmg9W1KfKUlmhZtBSl6THbcgLX73q+abte13LsrpMGjudSqwfMcv2km6SMPONkNVAFIy4rIflhOjKchZdxuIzGy2kYjsIRCmxr/ifq+yxCUDxbTIeIRkxVc4EwnUY0jcPZ5TCOvoWHHUwgo2w33+AWUppLQGVcZLyrMBjydRHO7sjhaQYp1FCy/wwMGW317Tt8OQkE4lGgkFT4jwtiUsu0GehF8ULbMV3fsnq+7+vASAuu1V81z9G10x3ojlBAqY4zHe6BPB/FGnkCYREzm0bTz1j9Bej2E9mWAwAA" } }, { "ID": "50f3a6216a74e420", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/gzJ6wIrbdKfoxbuezFYyBfPLaFh?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:19 GMT" ], "Etag": [ "RVzUTXjXFXOM0fcRvj1/aQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42QTU/CQBCG/8t4LRE8eCDhIFgUrXysYDDGkO12Wlq3ndrdioXw350tBxP1YPaw+86+z3wd4C0tIuhDmCbvNVbNWYJ24R4CTa2t4aukwiB4gFYm7BRP+9Vyna3H69lDN1biI+udy8VgwA6jtphL6B8gTlFHBvovByhkjozF3Q07bFM6IfzRTFyzzilyeroKgqth4HPkN7lpQ5veNz6ZLv0bX/zBH72f2MW/sFc+HmQUCoyxwkKhm6KsKENlJ25BZktaN7ksOhHm1LFoLLRE+5vs7y53kyqM7mP6DGvcj5+bYTwP5HjLLk1K2pQKNq4euUewZKUWtOM5oZ3L6WHDSecVKTQGXdLuqcCI8lKj5Y5sVaMHSvKab1N70scvfozYs8MBAAA=" } }, { "ID": "fd013e77e0381453", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anon16c3249570671356024304f9465a28ec257b0bfc/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:20 GMT" ], "Etag": [ "SLqlZudkMQFuOVU9GJOwKQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8oH+xTmRJWmZPsGupX6h4Vaunv5l3sH2toCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsU7JCYgJV1OpAWEZKtbG1QBRbCwC1aXuHhgAAAA==" } }, { "ID": "c80528c33b995230", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "167" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUIFsxLCAyLCAzXSIsInVzZUxlZ2FjeVNxbCI6ZmFsc2V9fSwiam9iUmVmZXJlbmNlIjp7ImpvYklkIjoiV1djU3lvUmRWUk5uUWppd2VJTkJGV2ZVNkpSIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:20 GMT" ], "Etag": [ "4N3bWe4ZCd7zR9/MfzLIKg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41S226bQBD9FWv7ahtzB0tWm9qkonWRgnGstqqsZRnIOsASdp3IifLvHbBjVW0a9Yll5lzm9kRueZ2RKUl5cbeH9vBuJ1IyJKBogVErMtMNWN/nmfsY+9rX/HEZfilmM0TwjiVvRFkeKlqPMqjESIFU0/VqvNmw1UHE2XUc1Vc7/gBh9PFyk6+dzzEyJZT5kte3yL9RqpFTTXtxHxdCFCXQhssxE9U5rt0bWtOKHTAltVdMNaxaam/Yvi8Fo4qLerZeYQl7Ce0WKspLLKITGLUiFerDK9JjTqtxgfh7zoAyJva16mpDFSbqnBf7thcm0yfS1/rbg6yCZTBPBj/04cAYDsyfSMpQk9c9JaFpCR381Fr4j5F2LKqohCNimwIYrpNmvq3rlp47jm17VHct3/SZn9mWwUwwJiZFnuosehatRe1bTuroduoZeqpnJvhObuLXtajlwMRyJrrtpSZzyTM21wJVsOCyEZIfGyTzOLhIgm14uY2CYBEs0OCh5X+iNnGIoCReR3NEI6ZpuUBYN5AwSoL4Yp6E18FxDUsoKDus7nAROS0loDPuMjk0OBhytQ7ib+QYiiGHFmr2nwNDRp99+xRfrgKBeBdoJBX+44KY7Gz6GXSL4lVXjm67huG5rjeZeDbpwa36K2foHubOp9ApQgW1OvV0PAnyfDLbyzMIkzizKIw+YfYXCx4k9ZkDAAA=" } }, { "ID": "1c3ece54abcd8c06", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/WWcSyoRdVRNnQjiweINBFWfU6JR?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:20 GMT" ], "Etag": [ "PG4J5YEy3IBXcXyPsNu5fw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y1PwW7CMAz9F+8KEtPGDpU4rFvHyqEqAQZomqaQuqVdGneNKxQh/n0J7GQ/+/m95zP81KaACA519Ttg7+4q5GVoBNpBs/WlI2MRRoAsK8/M54+L6T5xD2m8UzuX22yYlqfZzDOsOmIrITpDWaMuLESfZzCyRX9WTr49g10XQJqtk3ki/KClIgxEkifP6+QVLl+XETR0EFhij0ZhUOt6alBxGoLaI2ntWmnGBbY0ZrQM14vrdrtVK0ei+BCZWTb1CdMsftuWm6dFMNOkJNdkPHGzAm/ExFILOvmkcA//OHZeNO9JobUYRCc3gxdqO43sE3E/4AiU9O++13zDlz++As5TSwEAAA==" } }, { "ID": "8652524f8148b3a4", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anon946b615b821b1d3e96f31d374a46e0460158b3c7/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:20 GMT" ], "Etag": [ "Ie3yN7mzpVfifn8XeJV/IA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8p7phpX+pnnVhWEpWWm5VlEpHqF6Xs62toCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsg5FAyVodCMsIzjJWqo0FQwCQysZEigAAAA==" } }, { "ID": "4eb32ca41d3166a0", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "177" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUIChbMSwgMl0sIDMsIFs0LCA1XSkiLCJ1c2VMZWdhY3lTcWwiOmZhbHNlfX0sImpvYlJlZmVyZW5jZSI6eyJqb2JJZCI6ImFEUXp6OFY1N2czY3RZZTJ2OWVQMlQ5VWdaZiIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:20 GMT" ], "Etag": [ "Q8WG3DwnoAg4rMvsVcgZMA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41SW2/aMBT+K8h72SQgdxIjoQ1BViFR1IZA1VYVcpyT1G0S09hQ0ar/fSdA0bR11d4Sn+92Lq/kUVQp6ZNE5E8bqHdfHmRC2gQ0y/H1Mrg6c8bPlRzmbn2+VUue35wPBwNEiIal7mVR7EpWdVIoZUeD0v3FvMvGly8vwdLzc4fra7C3FC7smC7ymwyZCopsKqpH5N9rvVZ9w3h37+ZS5gWwtVBdLsvTu7G1jXUtH4BrZXxgamBqZXxi+72QnGkhq8FijhE2CuoVlEwUGKIR6NQykfrHB9Jdwcpujvit4MA4l5tKN9lQhcsqE/mm3guT/ivZZ/3tg8zDaTiKW19vrXbLvmu3nHbr1m23vLtvSE9RXVR7csySAhriscnJP4bbsJhmCg6IVQJg+70kpZ5luVbW63lewCzfpQ7lNPVcmztgmw5Dnm4s9ixWySoNTC+xXUo9hhoppabp2BS4ZVucUotaGWSmk7rkDdusgWkYC7WWShxaJaMoHMbhavJzNQvDcThGg+da/Im6iiYIiqPFbIRoxKxrIRHWjGYyi8NoOIony/CwkCnkjO/mT7iSjBUK0Bm3Gu/W0BziIoyuyeEpggxqqPh/DgwZh7Y/Pcr3+0AgXggaKY3/uCCuGpv9DJpFibKJY3m+bQe+H5i9XkD24Fr/VfM9irXTUTSKUEKljz0djoO8Hc026gTCIs5sNpmdYfUXYfhzA6MDAAA=" } }, { "ID": "b711aea4ee87f1c3", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/aDQzz8V57g3ctYe2v9eP2T9UgZf?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:20 GMT" ], "Etag": [ "Orr0QDx8q+DZX24h8PTiFA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42RYU/CMBCG/8v50ZHg0AgkfABWlYTAmJtRjCGlu43hto61qIPw372ORBJJjOmH9r2+z931uof3JA+hC8sk3myxrC5i1DNz8FBtU61oK2SuECxAzWNyTsuyOXO+2ptLZ/5sX6/arp/c9Xs9ciixwoxDdw9RgmmooPu6h5xnSFjUXJBDV4URHhtOPYd0JkOjJ8F43B+MGUXOyUUdWlyd8NHEZ/fMO/Eec1nfZw4crN+Y/Qf2U/Yca/2r2hstC9Zy6WGEJeYCzeOLUq5R6JGZq1rJNK0ynjdCzGRDo9JQE/Utd2a7Xfvp5jZuCf2C9kcHXdvvBPE8IlcqBdeJzMkYPFKPoKXmqSc/aTxQj8PoQUVJ3VIKVApN0uaxwFBmRYqaOtLlFi0QnH7nIdFHffgG9tzpl/oBAAA=" } }, { "ID": "7db4876859f5dd56", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anond805b24995abeed9900329ec121c99191fef03d4/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:21 GMT" ], "Etag": [ "4qyaLd1DqyKRS6QBSpw7lQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8qbFFYm+qQYuhRWegcFmwU6BReUm+cE2toCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsU7JCYkJIoLpaHQjLSKk2FsY2holCVZnAVZmCVMXWggkAa3ZF1LQAAAA=" } }, { "ID": "765314c3c87caaf8", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "180" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUIFsoMSwgMiwgMyksICg0LCA1LCA2KV0iLCJ1c2VMZWdhY3lTcWwiOmZhbHNlfX0sImpvYlJlZmVyZW5jZSI6eyJqb2JJZCI6IkU2SThCeFRpZ2ZwSkx2N2l6Y1NweUNWV0tIeSIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:21 GMT" ], "Etag": [ "xqFeUDgDXJU/qy1zifgLMw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41SYU/bMBD9K5X3BaTS1E7SpJXQxtqwBbpKa1PYNE2V416CIYnT2C0ExH/fJQU0bQztW+J77967d/dAbmSxJiMSy3Szhap+d61i0iVgeIqvd5tTWE7SybezpbWp6b1M0umX2+NjRMiGpa9UltU5L47WkKsjA9qMloteMAj9j3eRTJPybLrz5L1YlPX44vL8c41MDVkylcUN8q+MKfXIsp7Ve6lSaQa8lLonVP7ybu2YVVbqGoTR1iuiFrrW1huy7zMluJGqOF4u0MJWQ7WCnMsMTTQNjioVK/PhldY9yfNeividFMCFUNvCNN6wi1BFItNt1TYmowfSev3tgyyCaTCOOj8OaLfDuh37sNs5cLodt9sZHP7EDmsUkEXLj3icQcN9mjP8R74NixuuYY9YxQDMG8TroUupQ5PBwHV9Tj1naA/FcO06TNjA+jZHnmkkWhYvVDGgzpAJ36bU6yex2/eHtuMBZZ7tQ5/7Doekz8BPyCNOWgE3MJG6VFrupyXjeXASBavwdDULgkkwQYHbSv6JupyHCIrmy9kY0YgpK6kQ1qQTzqJgfjKOwotgv5MppFzUiw1uJeGZBlTGxUZ1icGQr8tg/p3sn+aQQAWF+M/AkNFW377L5xNBIB4JCmmD/7ggoRuZNoNmUTJv7FDXY8z3PJ8yykgLrsxfNZvZWHu5i6Yj5FCYp5n290Een8S2+gWERcxsFs4+YfUXPni496YDAAA=" } }, { "ID": "b3ad492daf884cea", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/E6I8BxTigfpJLv7izcSpyCVWKHy?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:21 GMT" ], "Etag": [ "h/jBTO8OR17M3SPL5+Dg/A==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/52RUU/CMBDHv8v56AgiUQgJDwwaQSdgGfpgDCndbRS3da5FnYTv7nU8kOiLMX1o/9f/7+563cOryiPowVolbzssq7ME7YM7cDS71BraCp0bBA/QioScm+bWD2fdGW917tuLeXB1Pkqag36fHEZuMBPQ20OsMI0M9J73kIsMCYsvVuSwVeEEZ8MZH5HOdHTUczYImYv8Jld1aNU64ZNpyG4YP/HTZRAM/IDBwfuJXf4Pa/8Je6HlwVavOcZYYi7RPb4o9Ralnbi5mo1O0yoTeSPCTDcsGgs1Ud+y60nX/wxVEhe3wXtHfclFUQ0fn+7GFblSLYVVOifjckE9gtVWpFx/0HigHofTfkVJ56WWaAy6pBfHAkOdFSla6siWO/RACvqdsbJHffgGE8/kCvoBAAA=" } }, { "ID": "d531c387927462f1", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anon61492c831170fb5089347e12738e0a84aef02e8f/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:21 GMT" ], "Etag": [ "yKrQ9L28x2wEp084BYagrA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8pXehcFWvoYWVQYlbsWGFiYOEUmphc52toCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsg5FIAkB1tToQlhGcZaxUG1sL5SCrNYGrMIWzzMBqY8EQAC6z5IbEAAAA" } }, { "ID": "e599b261d68ae194", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "187" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUIFsoWzEsIDIsIDNdLCA0KSwgKFs1LCA2XSwgNyldIiwidXNlTGVnYWN5U3FsIjpmYWxzZX19LCJqb2JSZWZlcmVuY2UiOnsiam9iSWQiOiJ1VFNNNE9NdGR0U1Q3YnZ1dGg3aGRMOU1mUlUiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0In19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:21 GMT" ], "Etag": [ "BMwT73iECIV2XoQR/GSPyw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41SW0/bMBT+K5X3AlJp6lzbStXG2gxFaruRpGwTQpXjnKSGJC6xU1Qh/vtOUkDTxtCeEp/zXc7tkdyJKiUTkoj8voH68OFWJqRPQLMco5+XD7FnCX8WXJk/5GVoXETfDg/TKSJEy1JbWRSHklVnKZTyTIPSk3U0aOJoaX9d6lRHsZfsG731tulivMzCNTIVFNlCVHfI32q9UxPDeHEf5FLmBbCdUAMuy9e4sTeNXS1vgWtlvGFqYNXKeMf2YyE500JW03WEJTQK6g2UTBRYRCtwVstE6k9vSA8EKwc54veCA+NcNpVua0MVLqtM5E3dCZPJI+lq/e2HRP7Cn8W965Nr2u+Z/Z510+/Zp/3eybXT77n48E5vUChFH1F1MjFLCmglntsN/jHmlsU0U3BEbBIA03OTdOxQatPMdR1nxKhnj60xH6eObXILzKHFkKdbi47FKlk5PDWzoe16jmnZdATMzXjGbepaoyE1acaGLgNKh+QJG66BaZgLtZNKHJsms9A/j/1N8GWz8v25P0eDh1r8ifoeBgiKw/VqhmjE7GohEdYOKVjFfng+i4Mr/7iaBeSMH6J7XE7GCgXojPuNDzscDLlc++FPcgyFkEENFf/PgSGjy75/ni+XgkC8FTRSGt+4IK5am24G7aJE2ZZDHc80R543ovglHbjWf+VGzhBzr+fRKkIJlX7u6Xgm5OnZrFGvIEzizFbB6gKzvwBaSYn5rQMAAA==" } }, { "ID": "4792bc387f13bd5e", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/uTSM4OMtdtST7bvuth7hdL9MfRU?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:22 GMT" ], "Etag": [ "6jj9a6FpRzqMnoVEP04K3Q==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/32QXU/CMBSG/8vxdiSoBAIJF4BViRsfZXhjDCnbGdvs2rGeaSbhv9uOCxM1phfte/o+5+sEb5mKYQT77HCssWquDkhr9+BoaknGXqVWBsEDJHGwzn6eD0X/vuSfx0DpZ7bq9p5u1+OxdZgoxULA6ARJhjI2MHo5gRIFWizp7qyDmtIJzmZLfmd1oeOLXrFJyFzkN7lrQ7vrb3y+CNkD43/wZ+8ndvMPttj6/mTqMzi/2uNBrvccE6xQReimKCudY0RztyCTaimbQqhOjIXuEBqClmh/63AT9JYBxbQJB/v3mtJBGvvDIOFb65I6EpRpZY3bje0RSJOQXH/YOaGdy+lpY5OuKh2hMeiSdi8FZrooJZLtiKoaPYiEXfNjRhd9/gKs2EHCwwEAAA==" } }, { "ID": "bd2595cd460657fa", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anon5cd2f0467523418ea6fcfc416380121fa06ae110/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:22 GMT" ], "Etag": [ "Lve18g7HfoccPjvTqV5b2w==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8r7lKUaWqSbe6TlJycHZJWFFIaZJhmV29oCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsg5EYAkDVtToQlhGcZaxUGwtjm4DYUA6mblO4HjMkPeZgPbFgCAAVG3Zr3gAAAA==" } }, { "ID": "9b0fb3e54a2be97c", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "186" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUIEFSUkFZKFNFTEVDVCBTVFJVQ1QoWzEsIDJdKSkiLCJ1c2VMZWdhY3lTcWwiOmZhbHNlfX0sImpvYlJlZmVyZW5jZSI6eyJqb2JJZCI6IngwSnB1RU9oTnVzR3ozM3pnS0RtOUJUM0hLQiIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:22 GMT" ], "Etag": [ "saVQQ1CRTVqlBgCNeVShxA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41SW0/bMBT+K8h7AQka4tyaSmgracYKKBNp2glNU+W4J6khiUPsMAriv+8kLWjaGNqbfc53ObcnciuqFRmRVOR3LTSbDzcyJYcENMsxqtji6soM4mRxV5zmQQSL2fphfHKCCNGx1FoWxaZk1dEKSnmkQenRfDZ4OD6v2/DrOmrV2aNlPeYXk9I/TawvF6fIVFBkl6K6Rf5a61qNDOPFfZBLmRfAaqEGXJavceOeGnUjb4BrZbxhamDVynjH9mMhOdNCVifzGZbQKmiWUDJRYBGdwFEjU6k/vSE9EKwc5Ii/FxwY57KtdFcbqnBZZSJvm16YjJ5IX+tvDzILL8Mg2RvH8fh6f/eZJfE8SPa/m4d79MfBAeqs0EZUvUrC0gI6hV23039MuWMxzRRsEcsUgHpuuvId07TNzHUdZ8hMz/Ytn/srx6bcAnpsMeTpzqJnsUpWpu24Weq4MDQ96oBPmelnlNqWTR1/BalHue8xNyPP2G8DTMNEqFoqse2ZBHE4TsLl9PMyCsNJOEGDn434E/UtniIIG48CRCOmboREWDejaZSE8ThIpotwu5lLyBnfzO5wNxkrFKAzrjfZ1DgYcjUP42uyDcWQQQMV/8+BIaPPvn+dL4eCQDwVNFIa/7ggrjqbfgbdokTZlWM6HqVDzxtS27VID270XznHpZh7vY5OEUqo9K6n7WGQ551Zq15BmMSZRdPoDLO/AIeOwr6sAwAA" } }, { "ID": "dba83faa76bb4d6e", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/x0JpuEOhNusGz33zgKDm9BT3HKB?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:22 GMT" ], "Etag": [ "LBYDvCm2D6MxDSH5fmFQUg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/22Qy07DMBBF/2XYtlKgAolIXZAmNKXQR9ouEEKVm0wexY5DPIGmVf+dcbpgAfLCvuN7Zq59go+iTMCFXZF9Nli3VxnS0h4iNI0kw1ulS4PQAySRsfPZe/W/RurGv3s5+KvwNlWPy002HLLDxDkqAe4J0gJlYsB9O0EpFDKWOlt2UFtZEQWjeeSzVjq56EXwsA5s5S+57Urb6198MlsH4yD6hz+/8+rBXu8iTLHGMkYbp6r1HmOa2JeaXEvZKlH2E1S6T2gIOqK7PThPVRPM81ljxsfB4JhNfXXvrQfh1GOX1LGgQpds3KyAB5EmISP9zYGhC2i113LTRa1jNAZtU+cyYKRVJZE4EdUN9iAW/F9hQRd9/gEnATogjAEAAA==" } }, { "ID": "45f3ac1643a9832c", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anon1456fb56e81725e92a19f22434259deb72c97a6f/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:23 GMT" ], "Etag": [ "EribgkzIOJrGXAjsY6Aq3A==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8q7FmUmpWdXefp7FblHOGYVR5o5Fho72toCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsg5EYAkDVtToQlpFSbSwQgonYWgAPFC3ulgAAAA==" } }, { "ID": "d3c28e701e6a6459", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "158" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUIDEiLCJ1c2VMZWdhY3lTcWwiOnRydWV9fSwiam9iUmVmZXJlbmNlIjp7ImpvYklkIjoiTEpVc1k4MFJFcjVoV0lYMjdFWVZPaE10Vmg0IiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:23 GMT" ], "Etag": [ "jHZkLbDlzSumR3hmks37aA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42SYY+aQBCG/0qz/VpFFhAxMa1R2tJYmyJ6vX4xyzLAKrAcu1xjL/ffO6BnmvZ66TfYeWbemXfmgRxFlZApiUV210Jzen2QMXlDQLMMXw8fvx9X8bL4uWnL0MrLo7JcNp/NkBBdlsplUZxKVg0SKOVAg9LT7Wa4+rRVt5NR6DdOfhN8o65/u/uSf9a73MZMBUW6EtUR83OtazU1jCf1YSZlVgCrhRpyWV7fjXtq1I08ANfKeEbUwK6V8YLs20JypoWsZtsNttAqaPZQMlFgE12BQSNjqd89U3ooWDnMkL8XHBjnsq101xtW4bJKRdY2fWEyfSB9r799kI2/8hfRKxPhBGuJqkcjFhfQYZeRgn9Y2WUxzRSciX0MQN1xnHiOadpmOh47zoSZru1ZHvcSx6bcAjqyGObpTqLPYpWsOI9dO2E2ZSkyXmryNB2llFKXeqaJRWOXAgWLPOJQDTANS6FqqcR5MLII/Xnk74P3+7XvL/0lCvxoxJ/UTRggFIXb9QJpZOpGSMQ6I4J15IfzRRTs/LP9K8gYP23ucAG6aQGFcYXRqUZfyNetH96S81MIKTRQ8f/0CzP66MsX+HQMCOI5oJDS+I/74aqT6S3o9iTKrh3TcSmduO7EouMJ6eFG/xWzxxRj1wvoKkIJlb7MdL4E8ngRa9UVwiBatg7WHzD6C0lVV56QAwAA" } }, { "ID": "e912c77be9f5996c", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/LJUsY80REr5hWIX27EYVOhMtVh4?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:23 GMT" ], "Etag": [ "2K+htbicSr6uw/FtgSe/bQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2PW0+DQBCF/8v4KE2x8ZYmfbAGFcVqQaqNMWZZhktdWNwd0hDCf3dofZo9s9+cOdPDT1mnMIekzH9bNN1JjrQeHyHaVpHl0ujaIjiAJHImZ0+nBSWljMxlu5/eUR7hNFkvFkxYWWAlYN5DVqJKLcw/e6hFhTyWud9MUNeMwl+9efdeyI1Kp2NjFQfBzTLwYPgaHNjpJMQMDdYSR7fG6B1K8segttBKdZWoJylWekJoCQ4Th9/gMbbbazf0zEXx7n/Mrrzt5qV4pk1xzpTSUlCpawbjCHgRaRIq1HtOCmfwr5cdm74aLdFaHE3d44JbXTUKiRORadEBKfjch5KOevgDCeOELksBAAA=" } }, { "ID": "f9235a108bb6347b", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anonccb74da42af2c39f1cff0f22272911e27b72e2e3/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:23 GMT" ], "Etag": [ "RCuE/6G28BFNSkm6eGOBEA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8oHOZe66pu5G1k4ufkFZ+eapbr7O7k62toCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwvXxgIhAFmpeK9uAAAA" } }, { "ID": "42251547c3c099a3", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "160" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUIDEuMyIsInVzZUxlZ2FjeVNxbCI6dHJ1ZX19LCJqb2JSZWZlcmVuY2UiOnsiam9iSWQiOiJUQU53Q1ozeW81d0ZwcXlWUENuZlJkWHFmMnEiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0In19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:24 GMT" ], "Etag": [ "COd2B/d3ZDVQU93Dp8oIcQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42S226bQBCGX6Xa3tYcjTGWrNbFpEKy3Bpjt82NtSwD2QRYzC6xUJR374Adq4rSqHew8/3zz+mJPPAqJTOS8PzYQtN9vBcJ+URA0Rxf/e+p9VVP7dvlfrPz7GU9FSHbzOdI8F4l70RRdCWtRimUYqRAqtluq8WL9cm/tTvhnG7qY7f/4VdZlP46ZtYRlRKKbMWrB9TfKVXLma6/uGu5EHkBtOZSY6K8vuuPll434h6YkvobpjpWLfV3bD8XglHFRTXfbbGEVkJzgJLyAovoE4wakQj15Y3UGqelliP/yBlQxkRbqb42zMJElfG8bYbEZPZEhlr/+iDbYBX48QdTsxFPMRuvBjimSQE9eGkq/McwexVVVMKZOCQAljtJUs8xzbGZTSaOM6WmO/Zsj3mpM7aYDZZhU9Sp3mJQ0UpUKEyMDIx0yhzkU8P1PNPNsoxmBnONccImluGljDxjWw1QBUsuayH5uTXiR8EiDg7hzWEdBMtgiQanhr+mfkYhQnG0W/tII1M3XCDWjyJcx0G08ONwH5wXsIKcsm57xBWopgU0xiXGXY1zIZtdEP0m56cIMmigYv85L1QM0fdv8OUcEMSDQCOp8B/3w2RvM4yg3xMv+3JMx7WsqetObc8yyQA36nVsbNgGxq430GeEEip16el8C+T5YtbKK4RBHNk6XH/D6B/RT1cHkgMAAA==" } }, { "ID": "55b0259a6cc20c4e", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/TANwCZ3yo5wFpqyVPCnfRdXqf2q?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:24 GMT" ], "Etag": [ "7AnfuA91DQZFKaWiLZu6Ig==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2P0U6DQBBF/2V8bZNWo0aSPlCU2Ehqi60ajDFbGCh12QF2CCGEf3dofdo92TN37vbwm5sEHDjkWdVg3V1lyNvxEqJtNFs5SjIWYQLIKhPz3jVp4z7MH7eR/6I+8iBq7lbZYiGGjY9YKHB6SHPUiQXnqwejCpSxdPYjBnflCH7w6u4EC0pGXO+DwF0GTzB8DxM40SHEFGs0MY5ZZU0njHk11rRH0rorlJkmWNCU0TKcJ86vO3fdetFNR7etX1bd+8YzaZh8Vul1JZamWHFORsT9G8giJlY6pFZ6whz+edlJ6KamGK3FMXR2WeBRUWpkacR1gxOIlXz2OecLD39rCn+YSQEAAA==" } }, { "ID": "bc7b748aa7413711", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anonbeeb0fe0d8c5174d079917fffaf0c704bc6209dc/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:24 GMT" ], "Etag": [ "7NJewAPixiCWVFoeVMvHlA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8qb+3mlljsGZFZkOoeHueWnhvmWeeQ42toCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwnrGSvVxgIhAMqsCMxwAAAA" } }, { "ID": "b84842b0ee41d973", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "161" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUIFRSVUUiLCJ1c2VMZWdhY3lTcWwiOnRydWV9fSwiam9iUmVmZXJlbmNlIjp7ImpvYklkIjoiTUxXVGVhVURiQW0wU01xVjJNOUxUUnpYeXh6IiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:24 GMT" ], "Etag": [ "s1bQAZNws5kmhO6IjEDGtQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42SXW/aMBSG/8rk3Q5CDAkECW0IvCoSUBFCu+0GOc4hGJI4xE47WvW/7yRQNG1dtbvE53nPe76eyUHmMRmSSCbHCsrTx72KyCcChif4qu1oOf6xeNTOIdvduv6eTW/McjRCQtYqvVNpesp43oohUy0D2gzXq/Z8dh8CX0+jcdZZzY93dO7NwuDp2+nnEyo1pNuZzA+o3xlT6KFlvbq3E6WSFHghdVuo7PpuPVCrKNUehNHWG6YWVq2td2w/p0pwI1U+Wq+whEpDuYGMyxSLqBO0ShUp8+WN1G3Js3aC/IMUwIVQVW7q2jCLUPlWJlXZJCbDZ9LU+tsHWbEZm4QfwmDNkI8xncwbOuRRCjV56cr/xzRrFTdcw5nYRAC070ax59h2z966ruMMuN3veV1PeLHTo6ILtNPlqDO1RaPiucophYEbObFL3Y5ti44TC6CucOwe7QoaCeoJN446nLxgXyVwA1OpC6XluTcyCdg4ZBv/62bB2JRN0eCxlH9S94GPELa7mCCNTFFKhVg9C38RsmA8Cf07dt7ADBIuTqsj7sCUFaAxbjE8FTgXslyz4Ds5PwWwhRJy8Z/zQkUTff8IX+8BQbwINNIG/3E/Qtc2zQjqPcmsLsd2+pQO+v1Bz6EuaeDS/BVzHQ9j1yOoM0IGubn0dD4G8nIxq/QVwiCObOEvbjD6CwbD0RWTAwAA" } }, { "ID": "8b5957519d01c73e", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/MLWTeaUDbAm0SMqV2M9LTRzXyxz?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:24 GMT" ], "Etag": [ "L9IdeIlyj0I0Pc/6KSspMg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2P3U7CQBCF32W8hVi9MKEJF6AkNm4BC4iJMWa7nZbW/SndIboQ3t0peDV7Zr85c+YE37UtIIa8rvYH7MJNhfTaPzL0B02eS+usRxgAkqyYFKOkwESHJkqipbp9eFn5Nq3GYya82qGREJ+grFEXHuKPE1hpkMfK6IsJCm0vpouFmE3m3DCu6BvzjRCTqZjB+fM8gMblGZbYoVXYu7Wda1BR0gf1O6d1MNIOCzRuSOgJLhOX31Rs1yg3T/nERKt0/3afjsQ6O76H3yNT2ilJtbMMblbAi8iR1Jn74aRwB/96Gth02TmF3mNvGl0XPDrTaiRORN0BB6Akn/tc01Wf/wChp7fwSwEAAA==" } }, { "ID": "1200b533f15e864d", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anon22e86b5d626011c05dce26c51423c2bc29c6db0a/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:25 GMT" ], "Etag": [ "h5mkha42Xdz57LSnwSVPiQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8pnmOZmZySaGEWkVJma+wTnlQeHBWQG2toCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwqXFJWmKtXGAiEART5HNnEAAAA=" } }, { "ID": "0e46b355e9ca3aaf", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "162" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUICdBQkMnIiwidXNlTGVnYWN5U3FsIjp0cnVlfX0sImpvYlJlZmVyZW5jZSI6eyJqb2JJZCI6ImZCYXVteVd2NTlFdlVpZ1dESnRZME5GT0s5eCIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:25 GMT" ], "Etag": [ "KH4ockKDjHqQwOC/kNdG3w==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42SXXOaQBSG/0pne5GbKoIg4IzTGiUJ1SETxDq5cpblSFaBJeyidTL57z2gcTptmukd7Hne856vF7LjRUKGJObpcw3V8fNWxOQLAUVTfJ3dmYLtZtPt3fPD4X6i7YLktn8YjZDgjUo+iSw75rToJJCLjgKphstFd3NN6/y42luut1/ydDX9rh57wc39zP2JSgnZZs6LHeqflCrlUNPe3LupEGkGtOSyy0R+edf2hlZWYgtMSe0dUw2rltoHtl8zwajiohgtF1hCLaFaQ055hkU0CTqViIX69k7qLqd5N0V+zxlQxkRdqKY2zMJEseFpXbWJyfCFtLX+9kEW3tybRJ+uxteTKxQkmI8XLR7ROIMGPbfl/2OcjYoqKuFErGMAwx7EiWvpuqlvBgPLcqhum27fZW5imQbrg9HrU9SpxqJV0UIUcdyzHT1xHWYYVpzEiTNgrtMzHYeafQwlPYfGpg3kFRurgCqYclkKyU/NkUnojSNv7d+sA8+belM0OFT8T2oV+ghF4TKYII1MWXGBWDMMP4i8cDyJ/B/eaQVzSCk7Lp5xCaqqAY1xjdGxxLmQh6UXPpLTUwgbqKBg/zkvVLTRj6/w7SAQxJNAI6nwH/fDZGPTjqDZE8+bcnTLNgzHth2r59qkhSv1V0y3m9jlCpqMkEOhzj2droG8ns1qeYEwiCML/OAWo78AF81IaJQDAAA=" } }, { "ID": "027faea85f52fe8d", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/fBaumyWv59EvUigWDJtY0NFOK9x?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:25 GMT" ], "Etag": [ "mM/FwkxZQqtvTLHwuaoXWQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2PTW+CQBCG/8v0iik99CCJh9pqtaW0ooZ+pGlWGBDdZZAdVGL47w7a0+6Tfeadd0+wzYsEPFjl2a7GqrnJkGfdJURba7ZylFRYBAeQVSamebsdH7bH79mO9wt/cqgVfUazwUAMG6/RKPBOkOaoEwvezwkKZVDGUvdPDG7KDuaLcBo8CxtKOg6Wvv8w9EfQ/rYObGgVYooVFjF2YWVFG4x52vW0a9K6MaroJWiox2gZLhOX13SoatNE+/v+aL/Ms+jphb/cYPz+2j+KpSlWnFMh4nIOsoiJlQ7pIEXhDv552EjoR0UxWotdqHtd8Eim1MjSiKsaHYiV/HaS85XbM3BbxhpKAQAA" } }, { "ID": "4a3a1ce8de7fa983", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anonbb0781d98c225bdbd86c980488a43078d08ab47e/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:25 GMT" ], "Etag": [ "EYU8rQa2ftujQRgqoUU5Wg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8q7RoZaFAUmGqWVlGYFBqUX5oeGmoan29oCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwo7Ojkr1cYCIQDzYii+cAAAAA==" } }, { "ID": "ae49f1eb750aaf42", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "177" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUIENBU1QoJ2ZvbycgQVMgQllURVMpIiwidXNlTGVnYWN5U3FsIjp0cnVlfX0sImpvYlJlZmVyZW5jZSI6eyJqb2JJZCI6IkdBVm13RmxpUWhocmxMNnBzTVA3VlBDZ290WiIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:25 GMT" ], "Etag": [ "fq8UN9+En5F4ruTdniwaEQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41SYW/aMBD9K5X3oZu2EhJIQpCqjYFbIVFUSGDqviDHHMFtYgfbKUJV//sugVbT1lX7lvjeu/fu3T2RByHXpE9Ske0q0IcP9yolXwhYluHrZtdbTKPPVPpXXV0layn2jM4uLxEhapbZqjw/FExerKFQFxaM7S/i1vVgWeyvcjHbbnU+CUpzcxsub4eZsj+RaSDfTIR8QP7W2tL0HedFvZUpleXASmFaXBWv786j55Ra3QO3xnlD1EHXxnlH9muuOLNCyctFjBYqA3oFBRM5mqgbXGiVKvvtjdYtwYpWhvhHwYFxrippa2/YhSu5EVmlm8ak/0Qar799kJhO6DA5Gw7i5OP5Rqnzs0F89v0uofEn5K+xvZANO2FpDjXzNOX4H+nWLGaZgSNilQJ4YZCuI991u+4mCHy/x9ywG3UiHq39rsc74LU7DHm2lmhYTCoJnShlPOiBF3EObhh2wjRgURoF7a7X5m0WtCPXjTzyjHNqYBZGwpTKiOOsZDing4SuxlerKaUjOkKBvRZ/on7MxwhK5ovpENGIKbVQCKuzGU8TOh8Mk/GSHjcygYzxQ7zDnVhdAQrjVpNDibmQ2YLO78jxaQ4b0CD5f+aFjKb6/lG+3AcC8UJQyFj8x/1wU8s0EdR7EkVtx/VDz+uFYc8P2h5pwNr+XYtCrL0eRd0RCpD2NNPxOMjzSawyryAsYmTT8fQaq78Avo8reaMDAAA=" } }, { "ID": "79c8e8bb37570da0", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/GAVmwFliQhhrlL6psMP7VPCgotZ?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:25 GMT" ], "Etag": [ "d7ZSHCvz0mr21D8cTvZ/NA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2P3U7CQBBG32W8hQheiCHhAiqKSSVQfhJrjFm2Q1vc7dTdAVKbvjtT8Gr3ZM98820NP3mRwBB2efp7RFfdpcjL9hKhPxr2cpRUeIQOIKtUzGQQr2bB6a9n3UP/+UmvT/H9fDwaieF1hlbBsIZ9jibxMPysoVAWZWzf+xaDq7KFycd6uhK0lLQ434TheBJOoflqOnCgXYR7dFhobLNKRwfU/NbW9BkZU1lVdBO01GX0DNeJ6+vreGvPLyZfZpkz4WPp3xeD7SJIiWOxDGnFORUiblYgi5hYmYjO0hP68M+TSkIXjjR6j21o77YgIFsaZGnE7ogd0Eo+O8v5xs0FYU2TlEkBAAA=" } }, { "ID": "da535b357729f06a", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anone39bac68e29cce17737b6a9b960420c0a6091192/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:26 GMT" ], "Etag": [ "9FV264sQR/PbALLr3jHgtA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8pbuoUZmZkUBwbpByQ5+vgUGWd5pJc42toCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwpH5VqWKdXGAiEARWiz93EAAAA=" } }, { "ID": "793acf775966fa51", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "189" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUIFRJTUVTVEFNUCgnMjAxNi0wMy0yMCAxNTowNDowNScpIiwidXNlTGVnYWN5U3FsIjp0cnVlfX0sImpvYlJlZmVyZW5jZSI6eyJqb2JJZCI6IlBUNHpIM3JUTzZKU0pLRUdVeUd0ckpIaW9JSiIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:26 GMT" ], "Etag": [ "oj/1FZ23HfgvP9daKUPhxg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41SW0/bMBT+K8h7YJPWJnHuldCGSoAU6Lo23bS9VI5zGgxJXGwX1iH++07SUk0bQ3tLfL7buTySW9EUZEByUd6tQW3e3MicvCdgWImv8sZyTr9T93xZ3k/igl3MJ9c/yqMjRIiWpa9lVW1q1vQKqGXPgDaD+aw/ybyf567KPgWj2egiOZtvzowanQuZjpCpoVpeiuYW+dfGrPTAsp7d+6WUZQVsJXSfy3r/bt1Ta6XkDXCjrRdMLUytrVdsP1SSMyNkczSfYYS1BrWAmokKQ7QCPSVzaT6+IN0XrO6XiL8XHBjnct2YNhuqcNksRblWnTAZPJIu628fZJZcJsPsIEuvkll2fDV5e0htJ+jZbo/aB44/sL2B7R++Q60CrUTTKWUsr6BV2XWc/mPSLYsZpmGLWOQANAzyIvYdx3OWQeD7EXNCL3ZjHhe+R7kL1HYZ8kxr0bFYIxtmB5GXsyjPnTD2GKM2DXkeRr4b0yLMwbXdHLkFecKeFTADJ0KvpBbbvslwmhxnySI9XYyT5CQ5QYMHJf5EfZ2mCMqm8/EQ0YhZKSER1s4pHWfJ9HiYpV+S7XYuoWR8M7vD/Ri1BjTGDWebFc6FfJ4n029k+zSFJSho+H/OCxld9fUDfb4VBOK1oJE2+I/74bq16UbQ7knUbRzHDymNwjAKnCAgHViZv2o0iLC2P5BWEWpozK6n7aGQp53ZWu9BWMSRjdPxGVZ/AbCXVQqvAwAA" } }, { "ID": "75ac779a407ed988", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/PT4zH3rTO6JSJKEGUyGtrJHioIJ?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:26 GMT" ], "Etag": [ "imeJ7tDArqZ+RhVVqdWfuQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2PYU/CQAyG/0v9KCQYjSZL+AC6AHMojIGJxphj6+Dwbt3uuphJ+O924Kfe23v69u0RvnWZQwBbvasbdO3VDnnZPRL0jWEvpaLSI/QAWe2E1BajB34aufr9OtlvNnX+VjTL4VAIn+3RKgiOUGg0uYfg4wilsihjxeBLCG6rTqSzebhKR/OFtCzlXetlHcejcRzC6fPUgwNtEyzQYZlh51c5OmDGsy6q35MxrVVlP0dLfUbPcJ44/y7Su9/prUtf76NV9BxO1u2EXTTVNIuEMpQp1lQKuF6BLGJiZRL6kaxwA/963IrpwlGG3mNnOrgseCRbGWRJxK7BHmRKDp5qvujTHxfT5n1NAQAA" } }, { "ID": "171e54c4ce71fdb5", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anona0684ba8bb1794aa2027cb785392d7be303bc3ed/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:26 GMT" ], "Etag": [ "nHV+kQHgLgep8nrTR0DWMg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8rneYRpZwd6pPukpxZY5BWFBBm4hPum29oCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwmbmFqYWJgZmZjqGSjVxgIhAExFsul5AAAA" } }, { "ID": "c3bd9ae149a45500", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "195" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUIERBVEUoVElNRVNUQU1QKCcyMDE2LTAzLTIwIDE1OjA0OjA1JykpIiwidXNlTGVnYWN5U3FsIjp0cnVlfX0sImpvYlJlZmVyZW5jZSI6eyJqb2JJZCI6IlBXaFRoY0V1b3FpVDNQYnpzV3BpM3E2TFBaUSIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:27 GMT" ], "Etag": [ "/yQA9+xFSrt+P2WHop0dOg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41S226bQBD9lWj7kESpzR2Mpai1bNIgOa5j41rti7UsA94EWMwuad0o/94BJ1bVplF5AWbOZW6P5J6XCRmSmGe7Bur9uzsRk/cEFM0wqu1vR/7Fj6tlrS7m5vpaVHryObu8RARvWXIr8nxf0LKXQCF6CqQarpb9+XobbVnQiB2PrHn8U64rbu3c6fzbLTIl5OmUl/fI3ypVyaGmvbj3MyGyHGjFZZ+J4hjXHkytqsUdMCW1V0w1rFpqb9h+yAWjiovycrXEEhoJ9QYKynMsohXo1SIW6uMr0n1Oi36G+AfOgDImmlK1taEKE2XKs6buhMnwkXS1/vZBlsE0GEcnk1EUnEXhTbCMRjfzs1NTN9yebvVM/cRwhro91J3T83NUTNCQl51eROMcWq3nvsN/zLtlUUUlHBCbGMD03DjxHcOwjdR1HWdADc/2LZ/5iWObzAJTtyjyVGvRsWgpSjtm4A1SPRmYvpPYtp/iw3xqWL7lYghfSWrTlDxh5zVQBRMuKyH5oXsyXgTY5ia82syCYBJM0OB7zf9ErRchgqLFajZGNGKqmguEtdMKZ1GwGI2j8Etw2NEUMsr2yx1uSdUNoDHuOdpXOBdyuwoWX8khtIAUaijZf84LGV327TN9uRgE4s2gkVT4j/thsrXpRtDuiRdtOYbjmebA8waub/ikA9fq75zvYe54Jq0iFFCq554O50Kens0aeQRhEkc2C2efMPsL4rXaVrUDAAA=" } }, { "ID": "a9d7d90df292c82f", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/PWhThcEuoqiT3PbzsWpi3q6LPZQ?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:27 GMT" ], "Etag": [ "WkzS2GJv8O7v1q+QG8LxbA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2P0WrCQBBF/2X6WAWt0IrggxZJLcHGqAgtpWw2E7O6ySTZiW0U/92J9mn3sGfu3D3DweQxjCAyu7LGqnnYIS/bS4iutuzkKCh3CB1AVjsxt4fT6sl7Pw4/Xo798nHpDf2/aDIei+F0ipmC0RkSgzZ2MPo6Q64ylLGk9yMGN0ULq3U4X3jCGcUtLza+P5n6M7h8XzqwpyjEBCvMNbZhRUV71Dxve7qUrG0ylXdjzKjL6BhuE7fXYJuuUz2rqTTrQRCd3LYwg/LZDz6XYlnSig3lIm5WIIuYWNmQfqUo9OGfp42EBhVpdA7b0N59wStlhUWWRlzV2AGt5Ldvhu98uQKziqGbSgEAAA==" } }, { "ID": "28d1d90c20ebef1a", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anon4bce78f0d8295d449ffffc9a13936295393df4af/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:27 GMT" ], "Etag": [ "xBvEnnVOLs2PlnOpqfxhMQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8pXOJW55uWF+fsUGwXk5PkXFKZVZPgG2toCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwobGRia6RoY6xoZKNXGAiEAlvSoiXcAAAA=" } }, { "ID": "0a1a092c0b9c4bbd", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "195" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUIFRJTUUoVElNRVNUQU1QKCcyMDE2LTAzLTIwIDE1OjA0OjA1JykpIiwidXNlTGVnYWN5U3FsIjp0cnVlfX0sImpvYlJlZmVyZW5jZSI6eyJqb2JJZCI6ImtnbmNscVY5dW52RHlKUGl6NDdzVGNBak1rTSIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:27 GMT" ], "Etag": [ "y+hPQKE4Xztg8N4DbXaiqQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41SW2/aMBT+K5X30FYb5O4EpGpDkE3ZCmohdN0TcpyT1CWJIXY60ar/fSeBomnrqr2g4PPdzuWJrEWVkiFJRL5toN69u5cJ+UBAsxxfd+/vrq6/he7to86DmTtJbpnYXl9cIEK0LHUni2JXsqqXQil7GpQeLhf9dV7xYnszaKqHye7rlXh0fRXz0f10PUWmgiK7FNUa+Xdab9TQMF7c+7mUeQFsI1Sfy/L4bjzYxqaW98C1Ml4xNTC1Mt6w/VhIzrSQ1cVygREaBfUKSiYKDNEK9GqZSP3pFem+YGU/R/yD4MA4l02l22yowmWVibypO2EyfCJd1t8+yCK8DMfxSRxNw7P2ZxGPpldnp7Zp0Z7p9GzzxPKGpjs0vdPzc1RM0VBUnV7MkgJarUPf0T/m3bKYZgr2iFUCYPs0SQeeZblWRqnnBczy3YEz4IPUc23ugG06DHm6tehYrJIVT8AM/IDSNMuomQK1eOBSL4UMAsp9aieZ5zNnQJ6x8xqYholQG6nEvnsynoejOFxFn1ezMJyEEzT4WYs/Ud/nEYLi+XI2RjRiNrWQCGunFc3icD4ax9FNuN/RJeSM7xZb3JKuG0Bj3HO82+BcyPUynP8g+6c5Zqyh4v85L2R01bfP9OViEIg3g0ZK43/cD1etTTeCdk+ibONYnm/bge8HvutQ0oFr/VeNOh7WjmfSKkIJlT70tD8X8nwwa9QRhEUc2SyafcHqL4AYyFC1AwAA" } }, { "ID": "e00639aff7bbd5f2", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/kgnclqV9unvDyJPiz47sTcAjMkM?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:27 GMT" ], "Etag": [ "AJe2BAMA8g2yvHUlwpzARg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2P0W6CQBBF/2X6iok1TdqS+ABtUzVgLIovTdOsy4DAsovsoEHCv3fQPu2e7Jk7d3soc52AC4c8O7XYdA8Z0td4idC2iiwftdEWwQEkkbHprXDme6H3ks268yJWl/rqRdl8zoaVR6wEuD2kOarEgvvdgxYV8lg6/WWDunqE7S5arj+ZK5OMvI6DwPODDxh+BgcKc4gwxQa1xDGsbkyBkpZjT3s0SnWV0JMEKzMhtAS3idtrmWmpTvvXVp/fu9Umvz492530irAM2VJGCsqNZjHeAi8iQ0JF5sJF4RH+2e84dNMYidbiGDq9L3gzVa2QuBE1LTogBf92kdOdhz/Nt2xpSgEAAA==" } }, { "ID": "57ad65330c0b17d0", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anoncbe087866dff60de61c8465defe86c762bf57a39/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:28 GMT" ], "Etag": [ "l3d8H0EWWjSGZrFLFSnIHQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8rnGKdYeBi4hodnBbtHFbn5uAXneXoE2toCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwmbWhmYWBmYKtXGAiEAbxEwWHUAAAA=" } }, { "ID": "86a734147395b230", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "261" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUIEB2YWwiLCJxdWVyeVBhcmFtZXRlcnMiOlt7Im5hbWUiOiJ2YWwiLCJwYXJhbWV0ZXJUeXBlIjp7InR5cGUiOiJJTlQ2NCJ9LCJwYXJhbWV0ZXJWYWx1ZSI6eyJ2YWx1ZSI6IjEifX1dLCJ1c2VMZWdhY3lTcWwiOmZhbHNlfX0sImpvYlJlZmVyZW5jZSI6eyJqb2JJZCI6InhJRFRacVVDaUFKNkhBNmNCbkZldG9PS1I1NiIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:28 GMT" ], "Etag": [ "CDTm0lBumZ6odNjZuH8rGw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42SYW+bMBCG/8rkfW1DIMGESNWaJrRlq7KNkE7rNEXGHNQtYGKbdFHV/74D2m7aumqfML7nvffufPfkVlQpmZJE5NsG1P7tjUzIAQHDcrydL+JyWJw05RWV6fLmqjmfqLO7oyMkRKvS17Io9iWrDlMo5aEBbabr1eBHuIivtuu5mL2n5zPKT6pTMPLjh8ilqNRQZBeiukX9tTG1nlrWk/sglzIvgNVCD7gsn++tnWPVSt4AN9p6wdTCqrX1iu27QnJmhKyO1issodGgNlAyUWARbYJDJRNpjl9IPRCsHOTI7wQHxrlsKtPWhlm4rDKRN6pLTKb3pKv1twNZBRfBPH5zvGMF8immE1VHxywpoCUfuwr/Mc1WxQzT0BObBMDxaJL6rm2P7YxS150w2xv7I5/7qTt2+Aic4YihzrQWnYpVsqLM5zY4zKNZOnIye+iPshEM02RC6XhMHddPmDekPnnAvhQwAwuha6lF3xuZR8EsDjbh6WYZBItggQZ3SvxJfYlChOJovZwjjUythESsnUW4jINoNo/Dy6B/gQvIGd+vtvgGGSs0HPRj+8QUK8GA0mT67Z5U+IPqfoL1Uyze1934TPdtc9NxW/ozcMmKpiN2/YHY5OHhOxK4Kb2YfF4H0VfSX0WQgYKK/+eboKKLvr7oTzuHIG4dGmmD/7gDXLc23ZjbXRBdh7brOc7E8yYT23FIByvzV8yxXXLwa9HajFBCZR576hcOW+3NGv0MYRCfZRkuzzD6E5HAkEv3AwAA" } }, { "ID": "2a17f360eca5ee13", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/xIDTZqUCiAJ6HA6cBnFetoOKR56?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:28 GMT" ], "Etag": [ "bjFADPaTKgSWYpx6Rm3nuQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2P3W7CMAyF38W7BYlpWi8qcVH+RgdiUEBom6YppG4pS+LSuBpV1XdfArtyjvP5+LiFn8KkEMKxyC81Vs1DjrzxjwRtrdi6UpKxCD1AFrknz7Nosha7Rb49vJfXINFPpt4Mh46w8oRaQNhCVqBKLYSfLRih0Y1lg29HcFN6Ea9205dp4hqaUt9Y7ZfLaLScQvfV9eBMxwQzrNBI9G5lRWeUHPug9kRKNVqYfoqa+oyW4TZx+73Gk93HZT8uotdgHgVyZGbI9LZIngNHKZKCCzIO3G/BLWJioRL6dUnhEf71qHGm64okWovedHBfMCZdKmSXiKsaeyCFO3de8F13fykSBSdLAQAA" } }, { "ID": "9bb4227ca5ffd5e8", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anon6a9c1e2a76fd32f1093f3e0db866446259ba7069/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:28 GMT" ], "Etag": [ "kpceRaS9m0FwAf1HUJInPQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8pnFySnBiUGW+YauJU7phl6hHp55gUE2toCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwvXxgIhAEE5v9FuAAAA" } }, { "ID": "d8077e6a53eeaf2f", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "265" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUIEB2YWwiLCJxdWVyeVBhcmFtZXRlcnMiOlt7Im5hbWUiOiJ2YWwiLCJwYXJhbWV0ZXJUeXBlIjp7InR5cGUiOiJGTE9BVDY0In0sInBhcmFtZXRlclZhbHVlIjp7InZhbHVlIjoiMS4zIn19XSwidXNlTGVnYWN5U3FsIjpmYWxzZX19LCJqb2JSZWZlcmVuY2UiOnsiam9iSWQiOiJIZ3RqeTBNNEpwYTJ6UE5scmxRbTdLRjB1OU4iLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0In19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:28 GMT" ], "Etag": [ "FTtwBPtW+4jcMdWej7jDZA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42Sb2+bMBDGv8rkvVwb/gQCRIrWLCFbtpS1CWm1TVNkzEGdAqbYpMqqfvcd0GTT1lV7hfH97p678/NAbnkRkyGJeHpXQ7V/vRUROSGgaIq3s1Ddv7tQ12+sLTuPr2HrbKdfx6MRErzJkjciy/Y5LU5jyMWpAqmG61XvQ6q2e/3c+lhS88dFkFXZZe58mum1F2CmhCxZ8OIW82+UKuVQ0w7qvVSINANactljIj/eaztTKyuxBaak9oyohl1L7QXZt5lgVHFRjNYrbKGWUG0gpzzDJpoCp5WIhDp7pnSP07yXIr/jDChjoi5U0xtWYaJIeFpXbWEyfCBtr78dyMpf+JPw1dmOZsjHWI4XLR3SKIOGfJpq/o9tNllUUQkdsYkATGcQxZ5tGJaRDAa27VLDsby+x7zYtkzWB1PvU8xTjUSbRQtsNB5QJ3H1RE8sakQJWJaTOGbfMiwasyRJXM+1YssmjzhXBVTBlMtSSN7NRiZLfxz6m/lsE/j+1J+iwH3F/6Sul3OEwuU6mCCNTFlxgVizi3kQ+svxJJxf+d0LLCClbL+6wzdIaCbhpFvbBa1oDgoqSYbfHkiBP5jdbbA8xMJ92a5PtV8yW3wehwOraf6IXNGsbplddyBGr08eH78jg27pCpDLtb/8QrqrJSRQQcH+810wo42+bPaD7xBE56GQVPiPPmCykWlX3fiBt1MatmOaruO47sCzSQtX6q+Yq+vk5JfZmoqQQ6GeZupMh6N2YrU8QhjEpwnmwXuM/gTvwFPa+wMAAA==" } }, { "ID": "ef5cba75941827f1", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/Hgtjy0M4Jpa2zPNlrlQm7KF0u9N?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:29 GMT" ], "Etag": [ "9Dlos3T948RudU5fIirOZQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2P0U6DQBBF/2V8pQlqjULSh1ZtWkXaYnnRGLOFgYK7DO4OMdj03x1an3ZP9syduwf4qpocQthV5XeHtr8okTfDJUHXaXZytNQ4BA+QVSlm8KDJXW+D8V3S5elNsazs6m0zmYjhsj0aBeEBigp17iB8P0CjDMpY4X+KwX07wDxaTbeChvIB4zSKprPoEY4fRw9q2iVYoMUmwyGrtVRjxsuhptuT1r1RzShHQyNGx3CaOL0uSq57/2X81Kqr33Wsrd6Y2+e53wWxWJoyxRU1IqavIIuYWOmEfqQnXMI/z3oJXVvK0DkcQv3zgnsyrUaWRmw79CBT8tlFxWc+/gHGMk6USQEAAA==" } }, { "ID": "22264fd1286e963f", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anonfd6a7f80f0f4a1bfe447f723414adcfff8984d45/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:29 GMT" ], "Etag": [ "fmPDaAW+FhkH9eGHuJzpGg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8qn5Qa4JDqGa7tlZHtYprp7lHpVFbin29oCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwnrGSvVxgIhAFOxj1ZwAAAA" } }, { "ID": "8061fbc4bd29c3bd", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "273" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUIEB2YWwiLCJxdWVyeVBhcmFtZXRlcnMiOlt7Im5hbWUiOiJ2YWwiLCJwYXJhbWV0ZXJUeXBlIjp7InR5cGUiOiJOVU1FUklDIn0sInBhcmFtZXRlclZhbHVlIjp7InZhbHVlIjoiMS4zMDAwMDAwMDAifX1dLCJ1c2VMZWdhY3lTcWwiOmZhbHNlfX0sImpvYlJlZmVyZW5jZSI6eyJqb2JJZCI6ImpnbUhTQkJsNnBZRmczZk9tWmNXV3dZSWpoRiIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:29 GMT" ], "Etag": [ "1oVlbEdkfdoUw9Y/M0u3NQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42Sa2+bMBSG/8rkfU1DuIdI1dqmdENq6UpIq2yaImMO1Clgik2iqOp/3wHSbtq6anzB9nnec38iD7xKyYwkPH9sodl/3IiEjAgomuOrLm6LxE8fslQsd95Ku5q0ZnhzfIwE71TyXhTFvqTVUQqlOFIg1Wy5GG/y8svi7Kxw6tVFbmbX5Td2d7dbBZv7C1RKKLJLXj2g/l6pWs407SX6OBciL4DWXI6ZKF/fta2h1Y3YAFNSeyOohllL7Z2wnwrBqOKiOl4uMIVWQrOGkvICk+gcHDUiEerkDddjTstxjvyWM6CMibZSXW7ohYkq43nb9I7J7In0uf52IAv/0p/HH062tEA+RXe86umYJgV05KGq4B/d7FRUUQkDsU4ADNdJUs/WdUvPHMe2p1R3Lc/0mJfalsFMMCYmRZ3qQvQqWomK2WBa5tQ1TcuyPErdiW45ujM17YwmmaXbLmTM9hzyjHU1QBWcc1kLyYfayDzyT2N/HVysQ98/988xwK7hf1J3UYBQHC3DOdLI1A0XiHW9CMLYj07ncXDrDxO4hJyy/eIRZ5DRQsJoaNtX2tASFDSSzL4/kQovqB46WL/Y4n3dt0/1fxIur/womHfJvyK3tGh7ZjsciD42J4ePPD//QBa3ZnBEbpZ+tCLDUwQZNFCx/5wPKnrr+0v/sn8I4gZiIKnwjvvAZBemb3m3F7yvFsdhGFPXnXqGo5MebtRfNtOdkNGvpes8QgmVOtQ0LB+WOgRr5SuERhxRGISf0foTzoFAMQMEAAA=" } }, { "ID": "8cdcf94b53ee6ddd", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/jgmHSBBl6pYFg3fOmZcWWwYIjhF?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:29 GMT" ], "Etag": [ "3MQ3YIqcZ2Yc6vRl1FcFeA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2P3WrCQBCF32V6G0EreBHwwojBQGxrRCSWUtbN5K+72ZidVELIu3diejV7Zr85c6aHn6JKwIVbkd1bbLqXDOk4PiK0rSLLpTaVRXAASWRMLg/HZRzc5fU1lqvfSC186eNmvWbCyhy1ALeHtECVWHA/e6iERh5L599MUFeP4u182EXBlhvaJFMjDDdeuIPha3CgNLcIU2ywkji61Y0pUVIwBrW5UarTopolqM2M0BI8J56/Zab3J89Tqzr2s2X6rq/ycnnEQZn7TCkjBRWmYvB8Al5EhoSKzIOTwgL+tdex6UdjJFqLo+l8WrA1ulZInIiaFh2Qgs/dFzTp4Q+exbZmSwEAAA==" } }, { "ID": "88a1b354e410eca1", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anonc5e34387334449aa7014616835fabf4157efc596/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:29 GMT" ], "Etag": [ "c9XTRKCuV7q/0DR2N8afjA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8onW0aEBHk7l4aZF+obuAQZ+VkkpmU52toCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwnrGSvVxgIhAIkXbdhwAAAA" } }, { "ID": "3b512c73727b1a3c", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "263" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUIEB2YWwiLCJxdWVyeVBhcmFtZXRlcnMiOlt7Im5hbWUiOiJ2YWwiLCJwYXJhbWV0ZXJUeXBlIjp7InR5cGUiOiJCT09MIn0sInBhcmFtZXRlclZhbHVlIjp7InZhbHVlIjoidHJ1ZSJ9fV0sInVzZUxlZ2FjeVNxbCI6ZmFsc2V9fSwiam9iUmVmZXJlbmNlIjp7ImpvYklkIjoiTWdYNWgwSHpteVlpSFVIVnhkbm9UdFpzNnRpIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:29 GMT" ], "Etag": [ "nHk9tTrK51ZxbyVFbEI8vg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41Sa2/TMBT9K8h8bZslTdqk0sRGl9GI0kGbFjaEKse5Sb0ldma7ZWXqf+cm2QaCMfHJj3vOPfdx7skNFykZkYTnt1tQ+9fXMiEdAobm+CsmN4GJ1XvPvrpL9qvzJIz8XX58jAhes/RGFsW+pKKbQim7BrQZLRe9D/kXb3M0+VHuL/lkOVndpULG5koPDEemhiKbcnGD/I0xlR5Z1qN6L5cyL4BWXPeYLJ/+rZ1jVUpeAzPaekbUwqq19YLsm0IyargUx8sFlrDVoNZQUl5gEXWCrpKJNCfPpO5xWvZyxO84A8qY3ApT14ZZmBQZz7eqSUxG96Sp9bcLWYTTcBy/OtnRAvEppuOiQcc0KaBGPnQV/WOaNYsaqqFFrBMAZzhI0sCzbdfOBgPP86k9dIN+wILUcx3WB+eoT5FnaomGRYUUQcb6RxkEWQau4yWua7s+GwyYzTKa2czxXT9NEuqSA/algBo447qSmre9kfE8PI3DdXS+noXhWXiGAt8V/xP1eR4hKJ4vZ2NEI6ZSXCKsnkU0i8P56TiOVmG7gSnklO0Xt7iDjBYaOu3YPlJFSzCgNBl9vScCH8huJ1g9xuJ91YzPNCd5e3ExrSt/iq9osW0Au/ZCjMLjcPiGIPRKSyefluH8krRfc8hAgWD/uRVkNNGXrf7oOgSi71BIG3yjC5iuZZpB127gTY+2N3Qcfzj0A98JSANW5q9Y4AxJ55fV6oxQgjAPPbWWw1Zbsa1+AmEQFzOLZu8w+hMHdwIk+QMAAA==" } }, { "ID": "25a24c100d1c987e", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/MgX5h0HzmyYiHUHVxdnoTtZs6ti?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:30 GMT" ], "Etag": [ "cMe4UxitIviAQT4MMAgf2Q==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2P3W7CMAyF38W7BYlNbBeVuCgTUpFaGIxO+9E0hdQtYUncNWajQ333ubAr5zifj49P8Gl8ARFsTfV1wKa9qpBX/WON4WA5SKnJB4QBIKtKSJ3hOD8ann+beLUZZ1lclTeryUSIoHfoFEQnKA3aIkD0dgKvHMpYOfoQgtu6F9PlMp3FC2k4KvrGIk/TeJrOoHvvBrCn7RpLbNBr7N3qhvaoed4HDTuytnXKDwt0NGQMDOeJ829WPd/uRsmva19MkidPx8LThl/DHRuhLGnFhryA+SPIIiZWdk0/khSu4V9PWzF9aEhjCNibji4L7snVFlkScXPAAWgl5yaGL7r7Aw78YW5LAQAA" } }, { "ID": "9843d83857eafa00", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anon9fc30fe9ffe425b44148c66c1cfaf1c2848dbba4/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:30 GMT" ], "Etag": [ "dxSHkKOAd4KsqW0FQm4mZg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8qnVAR7ZHv7O6aYeBcXhhu4Beaa5Eal29oCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwqXFJWmKtXGAiEA9xmoHHEAAAA=" } }, { "ID": "adc08435ff40d901", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "264" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUIEB2YWwiLCJxdWVyeVBhcmFtZXRlcnMiOlt7Im5hbWUiOiJ2YWwiLCJwYXJhbWV0ZXJUeXBlIjp7InR5cGUiOiJTVFJJTkcifSwicGFyYW1ldGVyVmFsdWUiOnsidmFsdWUiOiJBQkMifX1dLCJ1c2VMZWdhY3lTcWwiOmZhbHNlfX0sImpvYlJlZmVyZW5jZSI6eyJqb2JJZCI6IjdHNFM3clM1VlNoZVBqNzhlNU5oYW50QXdTZCIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:30 GMT" ], "Etag": [ "X0/LHROGCcSjAGN6gTif/w==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42Sb2+bMBDGv8rkvW1DQvgTIlVrlrIsUsQ6IN2maYqMOYhTsKntpIqqfPcd0HbT1lV7hfH9nnvuzvdAbrnIyZRkvLzbgzq+3cmMnBEwtMTbr0Nr9TH+tJizZDdbRF6Z8sK6v7hAgrcqvZVVdaypOM+hlucGtJmuk4G/cBJfJe5NsoXrnT8BN9pSYWb3SY5KDVWx4uIW9VtjGj21rCf3QSllWQFtuB4wWT/fWwfbapTcATPaesHUwqq19Yrtu0oyargUF+sES9hrUBuoKa+wiDbBuZKZNJcvpB5wWg9K5A+cAWVM7oVpa8MsTIqCl3vVJSbTB9LV+tuBJOEqnKdvLg+0Qj7HdFx0dEqzClrysavlP6bZqqihGnpikwHYvpflgTsaOaPC81x3Qke+E4wDFuSuY7Mx2MMxRZ1pLToVFVJ4OXV9h7pj6jFwAi+bOMU4CNzctQPHoRNgwwwy3yEn7EsBNXDFdSM173sj8zicpeFm+WETheFVeIUG94r/SX2Jlwil8TqaI41Mo7hErJ3FMkrDeDZPlzdh/wIrKCk7Jnf4BgWtNJz1Y7umitZgQGky/f5ABP6gup9g8xRLj003PtN9SZLGy2jR1v5M3NBq3yGH/kBm7+fkdPqBDC5Lryef12H8jfRXMRSgQLD/fBZUdNHXd/1p7RDExUMjbfAf14Dp1qabdLsOvGty5Pq2PfH9YOg6HulgZf6K+Z5Pzn7tWpsRahDmsad+57DV3myvnyEM4stE3aROPwHXrpdr+gMAAA==" } }, { "ID": "3ca3a29ac933fd51", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/7G4S7rS5VShePj78e5NhantAwSd?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:30 GMT" ], "Etag": [ "w2RCs+V11RWRgVPCk4AvJg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2P3WqDQBBG32V6WQOxJKQIuTBS0hQRuzbJRSllo+NPsu5ad6yI5N07Jr3aPeyZb74d4VLpDDw4VcVPh+3wUCC9TxeBtlNk+WiMtggOIMmCzf5JBPbx4LriKIpDHFwW/u9bsV6zYdMSawneCHmFKrPgfY6gZY08ls+/2aChmSD5ELtoy1ybbOJoH4b+JnyB69fVgbM5CcyxRZ3iFNa05owp7aaetjRKDbXUswxrMyO0BLeJ2+tqu0hWbbI8JCXG59UzLqNSavL7JGNLmVRSZTSL+wR4ERmSSpiei4IL/7wZODRuTYrW4hQ6vy8ITN0oJG5EbYcOpJJ/+1rRna9/F8V9qEoBAAA=" } }, { "ID": "2ba376fa2c915191", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anon6da574a53a6ce496b84f3995d52944a8ec0beb74/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:31 GMT" ], "Etag": [ "pXPF0HaBC9nGh4B2h1toxQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8oXRAS4GXgkOjlb5rlnmDgZZRiW5FcE2toCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwo7Ojkr1cYCIQDOHZWmcAAAAA==" } }, { "ID": "291a7059bc437e0c", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "264" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUIEB2YWwiLCJxdWVyeVBhcmFtZXRlcnMiOlt7Im5hbWUiOiJ2YWwiLCJwYXJhbWV0ZXJUeXBlIjp7InR5cGUiOiJCWVRFUyJ9LCJwYXJhbWV0ZXJWYWx1ZSI6eyJ2YWx1ZSI6IlptOXYifX1dLCJ1c2VMZWdhY3lTcWwiOmZhbHNlfX0sImpvYlJlZmVyZW5jZSI6eyJqb2JJZCI6IjBFRVVUaTBwT0VZaldCNW1wV1JheEJ1c1h3biIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:31 GMT" ], "Etag": [ "VQTSvfZeAuxFJfzX06AffQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42Sa2+bMBSG/8rkfW1CICGESNWapu6UKUpXQnqbpsiYA3UKNsUmbVb1v+8AbTZtXbVPvpznPfcncidkTMYkEul9BeXu40ZF5ICAYSn+XpyHy21yA5Pq8fRL8uOqN5wkyfnhIRKiVulblWW7nMlODLnqGNBmvFp2e5SuQtErzuj15vLYzYvLgD0eV/rqQaJSQ5bMhbxD/a0xhR5b1mv0bqpUmgErhO5yle//ra1jFaXaADfaeiOohVlr652wnzLFmRFKHq6WmEKloVxDzkSGSdQOOqWKlDl6w3VXsLybIr8VHBjnqpKmzg29cCUTkVZl45iMn0iT628XsqRzOg0/HG1ZhnyM7oRs6JBFGdTkS1Wzf3SzVjHDNLTEOgJwvGEU+65tD+xkOHTdEbO9gd/3uR+7A4f3wen1GepMHaJRMamkN4y9QeRG4PV9xxv5dhxH0B/a8ShxeBInwNEBA588Y10lMAMnQhdKi7Y2Mg3oJKTr2el6QekJPcEAD6X4k7oMZgiFwWoxRRqZohQKsboXs0VIg8k0nF3QdgJzSBnfLe9xBgnLNBy0bfvKSpaDgVKT8bcnIvGB6raDxast3BVN+0xzkuPrkC7r1PfABcuqhti2F3KT+1vy/PwdIVyWVk/OVzS4Ju1XAAmUIPl/jgUVjfX9XX9dOwRXTYLa4BvXgOs6TNPpeh1EU6Tteo4z8jzftj2fNHBp/rL1bYcc/Nq12iPkIM1LTe3OYaltsErvITTiZBazxWe0/gRH4cGL+gMAAA==" } }, { "ID": "0b6cb470a6ff49df", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/0EEUTi0pOEYjWB5mpWRaxBusXwn?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:31 GMT" ], "Etag": [ "o5M+5xutMzmwl/SRISxabg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2PTU+DQBCG/8t4lEY8cCHpQQyJTVo/oKQ2xpgFphTc3UF2SIuE/+7Qetp9ss+88+4I37UtIYS8rn567IabCvltviToes1OjpasQ/AAWVViUrC5Dc49b37NSd+lySo9q7xaLsVwxRGNgnCEQ426dBB+jGCVQRk7+F9i8NDOEO23cSpoqJzxOVuvH6J1DNPn5EFDeYIH7NAWOGe1HTVY8Gqu6Y6k9WCUXZRoaMHoGC4Tl1c/jrNt7bcv8b7ZRYFpd4k6R717P1mxNBWKa7IiZinIIiZWOqGT9IR7+OdokNDXjgp0Di+h1wWPZFqNLI2469GDQslnn2q+8vQHCZ2xXUkBAAA=" } }, { "ID": "47ae4302fd9a13a6", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anon76d74b5be73927891ddbe361d8f2cfdfec9c9ae9/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:31 GMT" ], "Etag": [ "6zjPuiNZCcmMgaPqh+EexA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8qbVWUFlGb6RTkn5/qmJwYUZmi7plY42toCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwpH5VqWKdXGAiEAHvgGyHEAAAA=" } }, { "ID": "0a9e2d776e9ff105", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "289" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUIEB2YWwiLCJxdWVyeVBhcmFtZXRlcnMiOlt7Im5hbWUiOiJ2YWwiLCJwYXJhbWV0ZXJUeXBlIjp7InR5cGUiOiJUSU1FU1RBTVAifSwicGFyYW1ldGVyVmFsdWUiOnsidmFsdWUiOiIyMDE2LTAzLTIwIDE1OjA0OjA1KzAwOjAwIn19XSwidXNlTGVnYWN5U3FsIjpmYWxzZX19LCJqb2JSZWZlcmVuY2UiOnsiam9iSWQiOiJtWkFCSmhHaE5PQ3RYUW02bFNZVW5Tcm9GVG8iLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0In19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:32 GMT" ], "Etag": [ "tRJgAEsltOZCoP6L9dKPFA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41TW0/bMBT+K8h7HG3sXJtIaHQloEApJUnZYJoq13VTQxKH2O1UVfz3nSTAJsTQnmL7fJdzyx49iHKJArQQ2eOG17tP93KBDhHXNINXHZ9nw1Dl+upuJKfu2F9eTE+HR0eAEA1LrWWe7wpa9pa8kD3NlQ5mSb+4G349X5+tJ1cj/f26cPPkdlYmtTxNJTAVz1djUT4Af611pQLDeHHvZ1JmOaeVUH0mi9d3Y2saVS3vOdPKeMfUgKyV8YHtl1wyqoUsj2YJpLBRvJ7zgoq8KRIEerVcSH38jnRf0KKfAX4rGKeMyU2pm9xAhclyJbJN3QqjYI/aXP86oCQch6P04HhLc8AvQU6ULTqli5w3yOeqon90s2FRTRXvEPMF56bnLpa+Q4hNVq7rOANKPNu3fOYvHdtkFjexRYGnG4uWRUtZuhYZ2K5pOtwjFsM2sSkxfX+AvUaDMUKoRZi/Qk9QV82p5idCVVKJrjY0isNhGs6j0/kkDE/CEzD4VYu3qG9xBKA0nk1GgAZMVQsJsKYX0SQN4+EojW7CbgJjnlG2Sx5hBiuaK37YtW1Ka1pwzWuFgh97VMIF2F0Hq5dYuqva9un2i9LoMkzS4eW0Sf8VdEPzTYvadgdkYuL2sNUz8QFxAmwH2PmMcYAxenr6CUzYok4YXc/C+BZ1TzFf8ZqX7D/nBYw2+vFP8LKPAISNBCOl4Q77wVRj046g2RPRVk8czzQHnucT38WoBdf6bczEno8O/yxho8gLXurnmrplhFI7s416BUEQRjaJJmcQ/Q0apn1ZEwQAAA==" } }, { "ID": "cf3ea2b10249c734", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/mZABJhGhNOCtXQm6lSYUnSroFTo?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:32 GMT" ], "Etag": [ "wEb4r8g8wAqbe+ZOJubdww==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2P3WrCQBCF32V6WQULpYjgRSK2VfxNFFpLKZtkTGJ3d+LuhBDEd+9EezV7Zr85c+YCv6XNYARJmZ9rdO1DjrztHhH6WrOXUpH1CD1AVrmQzTR5dsN82ATnBB8P63mdZE0zHgvh0wKNgtEFjiXqzMPo6wJWGZSx4+BHCG6rTuxmy2m8C5YbaRnKutZqv1gE4WIK1+9rD06URHhEhzbFzq9ydMKUZ11UX5DWrVG2n6GhPqNnuE3cfs0hCOfFW7FaT/hja150/Lm3saPXHQmlKVVckhVwH4MsYmKlI2okKzzBvw5bMd04StF77EwH9wUTMpVGlkTsauxBquTg95Lv+voHlDT19U0BAAA=" } }, { "ID": "9b9a03a9846584be", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anon631846225e713c0414a12998076655cc11a31c9f/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:32 GMT" ], "Etag": [ "PJzSqkZmDjY51CeDabfgeA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8oHeFUFF2ZH5bpkRZoaOgMVJKWlpzra2gJVlOSXJOYE5ZcXA5UZAvlFYGZ0tVIamCwDCZuYWphYmBmZmOoZKNXGAiEAlmZrgXkAAAA=" } }, { "ID": "97470ee9856725b8", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "374" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUIEB2YWwiLCJxdWVyeVBhcmFtZXRlcnMiOlt7Im5hbWUiOiJ2YWwiLCJwYXJhbWV0ZXJUeXBlIjp7ImFycmF5VHlwZSI6eyJ0eXBlIjoiVElNRVNUQU1QIn0sInR5cGUiOiJBUlJBWSJ9LCJwYXJhbWV0ZXJWYWx1ZSI6eyJhcnJheVZhbHVlcyI6W3sidmFsdWUiOiIyMDE2LTAzLTIwIDE1OjA0OjA1KzAwOjAwIn0seyJ2YWx1ZSI6IjIwMTYtMDMtMjAgMTU6MDQ6MDUrMDA6MDAifV19fV0sInVzZUxlZ2FjeVNxbCI6ZmFsc2V9fSwiam9iUmVmZXJlbmNlIjp7ImpvYklkIjoiamZQcnRyckp1ZG0wbWxnRXF2ckJXbUFiSzczIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:32 GMT" ], "Etag": [ "Ua8fssOygsr4QpDmAGK2+g==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41Tf0/bMBT8Ksj7E9rmV5smEhpZm6EO6CBNQWiaKid5CYYkTm23U4X63ffiAEKMIaRIiX13757PL4/kgdUZ8UnCivUGxO7LPU/IEQFFC9xd0nEu5c9dIYVz1Uyr4PTMOiyOj5HBWpW842W5q2jdy6DiPQVS+ctF/z6/FEqIH5usMqqyCNdb8e2mCpIz10alhDI/Z/UD6u+UaqQ/GDy79wvOixJow2Q/5dXL/mBrDRrB7yFVcvCO6QC7loMPbL+WPKWK8fp4ucAWNhLECirKSmyiLdATPOHq5J3SfUarfoH8LUuBpinf1KrtDaukvM5ZsRG6MPEfie711QdZhOfhJD442dIS+RmWY7VmxzQpoWU+nWr2nzRbFVVUQsdYJQCWO0oyb2iajpmPRsPhmJqu49le6mVDx0ptsAybok61FlpFa16nrkk9IxmN08y0wLU8xzassWWPaOaMEhibjmPaWQ5kj+cSQBVMmWy4ZN3ZyCQKgzhczb6v5mE4Dado8Eewt6ybaIakOFrOJ8hGTiMYR1qbxWweh1EwiWfXYXcD51DQdLdY4x3ktJRw1MV2SQWtQIGQxP/1SGpcoLpLsHnG4l2j41P6TYIoCm4Rp0LQ3Rssnl2Eizi4uCT7/asK17TcaJrW6FVnuO0AYhnmqGfYPcs4MIe+4fjG8NAwfMPAiD7F+r3H54jgaHYdkatlGN2SbiuCHATU6SeHABUa/fjPeh7y9s9dtEZS4RqHLpWtjb7XdviYjtQcupY1dl3Pcl2HaLJQ/2Bjjb1MdlsRKqjV05m6CdfRttBGvpAQxDmYz+aniP4F7Ftol2gEAAA=" } }, { "ID": "2c05b964dcd7b199", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/jfPrtrrJudm0mlgEqvrBWmAbK73?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:33 GMT" ], "Etag": [ "83dkhuH3Ku7WZ0KbVzyuHA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2P3U7DMAyF38XcdlLRLoYq7aKDShvVpNIVJoEQSlv3b0nTJQ6oTH133I0r5zifj48vcGr7EgLI2/rs0Ix3NdLL/EjROkmWy6B7i+ABkqiZfFiWp8Ztl7FbHd/9OH/7Hd02XK+ZsEWDSkBwgapFWVoIPi7QC4U8VvlfTNA4zCLb7aNDFu4Tbildzq00SqIwi55g+pw86HSeYoUG+wJnv8HoDgvazVFto6UclegXJSq9ILQE14nrb1clhox5dqXylayj87fZHFWYx6slU1IXglrdM/h6AF5EmoRM9Q9nhXv415uRTROjC7QWZ1P/tuBRq0EicSIyDj0oBB+8bemmpz/bzJrMTQEAAA==" } }, { "ID": "0abf637163c0e021", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anonc71a90b68cd12e72943028236ad46be814413dfe/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:33 GMT" ], "Etag": [ "qV6Ty3CsePmRIjlSQFwLWg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8oXhpmFVBo7F6cG5AZ5ZuUEB7qV+4Sn29oCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsg5FKhiamFiYWZkYmpnoGSrU62ARjwRAA2mrJiJYAAAA=" } }, { "ID": "531f33a22b0b1228", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "289" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUIEB2YWwiLCJxdWVyeVBhcmFtZXRlcnMiOlt7Im5hbWUiOiJ2YWwiLCJwYXJhbWV0ZXJUeXBlIjp7InR5cGUiOiJEQVRFVElNRSJ9LCJwYXJhbWV0ZXJWYWx1ZSI6eyJ2YWx1ZSI6IjIwMTYtMDMtMjAgMTU6MDQ6MDUuMDAwMDAzIn19XSwidXNlTGVnYWN5U3FsIjpmYWxzZX19LCJqb2JSZWZlcmVuY2UiOnsiam9iSWQiOiJ0RUhoNXBSakJQUjNWQ0lDS082WHlHc1dTcmsiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0In19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:33 GMT" ], "Etag": [ "RXC7X9hj/Ft5Q+5/2gKyFQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41Ta2+bMBT9K5X3cU14GgJStHaEdqhd1hDSdpqmyBhDnAKm2MkUVf3vu0DbTVtXjS/Y955zz335Ad3xOkM+Snlxv2Pt4d1WpOgYMUUKsMa3gXvrbbbamcKL91gzi4vD2WI6BQTvWHIjyvJQkXqUsUqMFJPKXy3HKvy0wU28/XgVW9dBFFx8cW4P5/Jm2d4BU7Iyv+T1HfA3SjXS17Rn9XEhRFEy0nA5pqJ6sWt7U2tasWVUSe0VUQ2yltobsh9KQYniop6ulpDCTrJ2zSrCS0iiCzBqRSrUySuhx5xU4wLwe04ZoVTsatXlBlGoqHNe7No+MPIfUJ/rbwe0DC/DIDk62ZMS8BmE43WPTkhasg75VFX0j252LKKIZANinTJmuk6aedgwbCN3HIwnxHBtz/Kol2HbpBYzdYsAT3USPYvUonb1zLUc1zYJNXHm5baNU+aAhTguBLWc1LJyOsHoEepqGVFsxmUjJB9qQ0EcnibhOjpbz8NwFs5A4EfL/0TdxBGAkng1DwANmKblAmBdL6J5EsanQRJdh8MELllB6GF5DzPISSnZ8dC2K9KSiinWSuR/e0A1XIA9dLB59iWHpm+f6v9oBmpJ9Dnssn/BXJNy14P2wwGZuuGMdGtk6kcG9nXb1/FY7z4LPT5+Byps0RAYLVZh/BUNppjlrGU1/c95AaP3vv0InvcRgLCRICQV3GE/qOxk+hF0e8L76g3smubEdT3LdCaoB7fqL5/lYXT8awm7iKxitXqqaVhGKHUQ28kXUPfSV/N5ND8H70+MoY2fEwQAAA==" } }, { "ID": "eb0bcbc6d2d530a6", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/tEHh5pRjBPR3VCICKO6XyGsWSrk?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:33 GMT" ], "Etag": [ "nx1vnOWlIZlpLTw4I5vkpw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2PQU/CQBCF/8t4hQSieCDhQGsjjVWwFDEaY5btFArb3bU7pTaE/+4seJp9s9+8eXOCQ6lzGMOm3P40WHc3W6RX/0jRNYocF2u0Q+gBktgyqX+HRz1fq/hD2SRr7+LR8WDbyYQJJ3dYCRifoChR5Q7GnyfQokIeKwbfTFBnvXiYZlEWP0fcqUzuOy+rJJkGSQTnr3MP9maTYoE1aoneztZmj5Jin9TtjFJdJXQ/x8r0CR3BZeLyS9FsN7LpPlikt29hHD7N79+7R7de1gemlJGCSqMZXC2BF5EhoVLTclQYwr8OOjZd1Eaic+hNB9cFoamsQuJEVDfYAyn43llJV33+A4RNWM5MAQAA" } }, { "ID": "b9a271f14e108d65", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anon70d736742ac25d9f445be6367a67bee36b33fc85/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:33 GMT" ], "Etag": [ "fxmspMvMESqTkEM0r+XTCg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8qnVeQWF/iW+boGF4Zku/oaFGlHhDin29oCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwobGRia6RoY6xoZhBiaWhmYWBmY6hmAgLFSbSwQAgA/ounPhwAAAA==" } }, { "ID": "ff0899ea448a3ea5", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "269" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUIEB2YWwiLCJxdWVyeVBhcmFtZXRlcnMiOlt7Im5hbWUiOiJ2YWwiLCJwYXJhbWV0ZXJUeXBlIjp7InR5cGUiOiJEQVRFIn0sInBhcmFtZXRlclZhbHVlIjp7InZhbHVlIjoiMjAxNi0wMy0yMCJ9fV0sInVzZUxlZ2FjeVNxbCI6ZmFsc2V9fSwiam9iUmVmZXJlbmNlIjp7ImpvYklkIjoiQTJEbjVaZEc1aFowSUhZUmFETEhWUjloRVBHIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:33 GMT" ], "Etag": [ "nXLLlyvkavk2JcTUG++7jw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42SYW+bMBCG/8rkfWwTAgQIkaq1SljKFEUdId3aaYqMOYgbsCl2UkVV/vsOaLtq66p9wvieu/fu/D6SLRcpGZOE5/c7qA8f72RCTglomuOt+D6fF4f9lu631hcWr2YnJ97dw9kZErzJUhtZFIeSil4KpexpUHq8WvYvrKlwbtOZs7kdhJc3EZ3OL68jfxNczTBTQZHNudhi/kbrSo0N41m9n0uZF0ArrvpMli/3xt4yqlreAdPKeEPUwK6V8Y7sp0IyqrkUZ6sltrBTUK+hpLzAJpoCvVomUp+/UbrPadnPkd9zBpQxuRO66Q2rMCkynu/qtjAZP5K211cHsgzmwST+cL6nBfIpluOipWOaFNCQT1OF/9hmk0U1VdAR6wTA8twk9R3THJqZ6zrOiJre0Ld95qfO0GI2WAObYp5uJNosKqSgpjtiziiz0yGktk+9lPq+n4BjppRZbpIxJ7PczCRHnKsGqmHKVSUV72Yjkyi4iIN1+Hm9CIJpMEWBh5r/SX2LQoTiaLWYII1MVXOJWLOLcBEH0cUkDq+D7gXmkFN2WN7jG2S0UHDare2K1rQEDbUi4x+PROAPZncbrJ5j8aFq16fbL5k2asdX8Wta7Fpg3x2INTDd3sDuWQNyPP5EFB3TFSFfV0F0Q7qrCDKoQbD/fBvMaKPvG/7Zewii+1BIafxHLzDVyLTrbjzB20lNx7Oskef59sgakRau9V8x3x6Q09+GaypCCUI/zdQZD0ftxHbqBcIgPs8iXMww+gswia9k/wMAAA==" } }, { "ID": "7248799baf41dd7c", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/A2Dn5ZdG5hZ0IHYRaDLHVR9hEPG?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:34 GMT" ], "Etag": [ "YJwb4caWBuH1VqWhai1ccQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2P3W6CQBBG32V6qwk09aIkXkAxYkMapVWjTdMsy/Bjl11khxhCfPcO6tXuyZ755tsB/iqdgQdpVZw7bPunAmkzXhK0nSLLR2O0RZgAkijYPLxf0hcp9kEXubvzvhSVK+VmPmfDyhJrAd4AeYUqs+B9D6BFjTyWO79sUN+MEPpfC6baZCN9bOPYD+IFXH+uEziZNMEcW9QSx6imNSeUtBpb2tIo1ddCTzOszZTQEtwmbq/+c6hnx2w5K4/OKjokIoyjXfJaLtZLtpSRgiqjWdx+Ai8iQ0Il5sI1wYUHBz2Hrlsj0VocQ537gjdTNwqJG1Hb4QSk4L9GFd35+g+lhsOHSAEAAA==" } }, { "ID": "98a9ea63df2755dd", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anona168c58f3d4ed39a7da999be51dac26bfc5f26f1/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:34 GMT" ], "Etag": [ "vOyD2fkNLNp00/0rQoTvWA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8qX+Ve6GKVl+/n4FRgY6BsUBeaHlIU72toCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwobGRia6RoY6xoZKNXGAiEAFeEMeHcAAAA=" } }, { "ID": "eafe3b51c0cf5dca", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "274" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUIEB2YWwiLCJxdWVyeVBhcmFtZXRlcnMiOlt7Im5hbWUiOiJ2YWwiLCJwYXJhbWV0ZXJUeXBlIjp7InR5cGUiOiJUSU1FIn0sInBhcmFtZXRlclZhbHVlIjp7InZhbHVlIjoiMTU6MDQ6MDUuMDAwMDAzIn19XSwidXNlTGVnYWN5U3FsIjpmYWxzZX19LCJqb2JSZWZlcmVuY2UiOnsiam9iSWQiOiJ2WG81VkNXdkxtOHFSazhWMHRiVWpDQWxFNWoiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0In19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:34 GMT" ], "Etag": [ "GMRSv6/xOoU06NMVKRtBFA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41S226bQBD9lWr7mpiLuRikqHEdEqE6Toux06qqrAEPZB1gCbumtaL8ewdI0qpNo/LC7s45c+Zy7tktr7bMZwnP7/bYHN7uRMKOGCrI6fXiMlq2jvbjSqx0Z3G5/hCp9+fTkxNC8I4lb0RRHEqojrdYimOFUvmr5aj9LOz17Lqdl5O76Hay1lWy2s2mRWDviCmxyOa8uiX+jVK19DXtSX2UC5EXCDWXo1SUz+9aa2p1I3aYKqm9IKpR1VJ7RfZdIVJQXFQnqyWVsJfYbLAEXlARXYLjRiRCnb6QesShHOWEb3mKkKZiX6muNsqSiirj+b7pEzP/nvW1/nZgy2AezOI3py0UhN9SOl716BiSAjvkY1fhP6bZsUCBxAGxSRBN10m2nm0YlpE5jm1PwHAtb+yl3ta2zHSMpj4G4qlOomdBJSrXRMuCBJOtk1lg6oltJKbnjD0bHEhN3dZhkliQsQfqq0FQeMZlLSQfemOzKJjGwSY83yyC4Cw4I4HvDf8TdR2FBIqj1WJGaMLUDRcE62YRLuIgms7icB0MG5hjDulheUc7yKCQeDSM7SM0UKLCRjL/6z2r6ELsYYL1Uyw+1P34VP9ncXgZdJU/x9dQ7HtAOxyYYfu65ev2SO++MXt4+EZ4ss2QiX1aBdEXNjxFmGGDVfqfCyJGH33d9U8GJCBZkISkojsZIpWdTD/zzhi8HMp1TXPiup7l6BPWgxv1V8zVDXb0y3VdRiyxUo89De6jVgexvXwGUZB2tAgXFxT9CVQdw8UEBAAA" } }, { "ID": "169ee25ff277e0be", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/vXo5VCWvLm8qRk8V0tbUjCAlE5j?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:34 GMT" ], "Etag": [ "hLnzuafks7Zo8lfk6yriow==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2P3U4CMRBG32W8hWS9QDckXAAhkWQ1ugoajTGlO/vbdpbtLGQlvLtT8Ko96Zlvvp6gqVwGU9hVxb7HbrgpkF/CJUXfG/ZytOQ8wgiQVSFmmbjfXuWNv/+k2OTN3dBVdJzNxPC6RKtgeoK8QpN5mH6dwCmLMpZHP2Lw0AZ4Wz+uhCxlgZ42STJfJCs4f59HUNMuxRw7dBpDVNtRjZrXoaUvyZjBKjfO0NKY0TNcJi6vhw+abJfvh8TG+7SJtxHvNvVyblaTWixDWnFFTsTNK8giJlYmpaPUhFv458Ugoc8dafQeQ2h0XbAk2xpkacRdjyPQSv76UPGVz39p3CSrSAEAAA==" } }, { "ID": "e73c60e3687e7b60", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anon72e44abebd6f4a20b51b296395a6ac2050a8b4af/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:35 GMT" ], "Etag": [ "uaAZrbCrIaQIoDoJ+VKp8g==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8qXJjpGFSU5F3kmBnrmu+R7aYd5F1ik29oCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwmbWhmYWBmY6hmAgLFSbSwQAgCWElj9fAAAAA==" } }, { "ID": "46f7f4728a747204", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "936" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUIEB2YWwiLCJxdWVyeVBhcmFtZXRlcnMiOlt7Im5hbWUiOiJ2YWwiLCJwYXJhbWV0ZXJUeXBlIjp7InN0cnVjdFR5cGVzIjpbeyJuYW1lIjoiVGltZXN0YW1wIiwidHlwZSI6eyJ0eXBlIjoiVElNRVNUQU1QIn19LHsibmFtZSI6IlN0cmluZ0FycmF5IiwidHlwZSI6eyJhcnJheVR5cGUiOnsidHlwZSI6IlNUUklORyJ9LCJ0eXBlIjoiQVJSQVkifX0seyJuYW1lIjoiU3ViU3RydWN0IiwidHlwZSI6eyJzdHJ1Y3RUeXBlcyI6W3sibmFtZSI6IlN0cmluZyIsInR5cGUiOnsidHlwZSI6IlNUUklORyJ9fV0sInR5cGUiOiJTVFJVQ1QifX0seyJuYW1lIjoiU3ViU3RydWN0QXJyYXkiLCJ0eXBlIjp7ImFycmF5VHlwZSI6eyJzdHJ1Y3RUeXBlcyI6W3sibmFtZSI6IlN0cmluZyIsInR5cGUiOnsidHlwZSI6IlNUUklORyJ9fV0sInR5cGUiOiJTVFJVQ1QifSwidHlwZSI6IkFSUkFZIn19XSwidHlwZSI6IlNUUlVDVCJ9LCJwYXJhbWV0ZXJWYWx1ZSI6eyJzdHJ1Y3RWYWx1ZXMiOnsiU3RyaW5nQXJyYXkiOnsiYXJyYXlWYWx1ZXMiOlt7InZhbHVlIjoiYSJ9LHsidmFsdWUiOiJiIn1dfSwiU3ViU3RydWN0Ijp7InN0cnVjdFZhbHVlcyI6eyJTdHJpbmciOnsidmFsdWUiOiJjIn19fSwiU3ViU3RydWN0QXJyYXkiOnsiYXJyYXlWYWx1ZXMiOlt7InN0cnVjdFZhbHVlcyI6eyJTdHJpbmciOnsidmFsdWUiOiJkIn19fSx7InN0cnVjdFZhbHVlcyI6eyJTdHJpbmciOnsidmFsdWUiOiJlIn19fV19LCJUaW1lc3RhbXAiOnsidmFsdWUiOiIyMDE2LTAzLTIwIDE1OjA0OjA1KzAwOjAwIn19fX1dLCJ1c2VMZWdhY3lTcWwiOmZhbHNlfX0sImpvYlJlZmVyZW5jZSI6eyJqb2JJZCI6InR4ckZBOGJGeWdiakxkeDZOTVg5S3VGa1VQbSIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:35 GMT" ], "Etag": [ "vGfUgrpbmydQEq+rnQ4C1Q==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6VUa0/iQBT9K2b2owJtoRSamJVgMWSVSFvcNZsNmU6ndbQvp1NWYvjve2cKiIK62f1A4M4959wn9xk9sCxENgpY/FhRvvxynwfoBFGBY3hdXESzmBdBugynzuMxz6adoT49PQUEk6zyLk+SZYqzRkjTvCFoKeyZ1xRPfDToBaNlHNxfhk/dydWP/rdq9DC7ToFZ0iS6ZNkD8O+EKEq71dpEb8Z5HicUF6xskjzdvrcWRqvg+T0lomwdCNqCrMvWB2G/JjnBguXZ6cyDFKqS8jlNMUsgCSnQ4HmQi7MD0k2G02YM+AUjFBOSV5mQuYEKybOIxRVXwsh+RirXnR/Icy6doX90tsAJ4EOQY5lC+zhIqESuqxq/003JwgKXtEbMA0oNqxuEfVPXO3rU7ZpmD+tWp9/uk35odgzSpobWxsATMoRi4SzPAsuMIiOyjJ5BzA4J9a6Fu6HZ65hWP6Ltfog7UtJCK6iLUyzoOSuLvGR1bWjoOgPfmY9H84njnDvnEOA3Z29R390xgHx3NhkCGjAFZznAZC/GE99xB0N/fOPUE7ikMSZL7xFmEOGkpCd1264xxykVlJfI/vmMMjDkJqoOFhufvyxU+4T6Rh6EHPpytwSviJDeV2yfpdBMnBayL6+p/vjK8fzB1TVarU62BE9wlsUDzvFynzJw3cEtPGPp3s9kPLkArV2xKvBUXvtSnyVe53GQV4f5dTDQvyX+35nAZ2dGNzipFLJWVGYp7d3mgqmy2Xgh4KLmIYxkaRsrQEr9pZfvCstfGxZRk3jbmANBP5cK10P9HEnRuhUva7fjNTS929DaDUM70k1b69iaeaxptqZJlqLBMauHg6Yzx71F9ZNLI8ppRv7ybABDeT++xZuzCEA4jCs5fbDhTBFVm7oE8lwxtQO6aRlGz7Lg+rQNtSqYiz2fYUnf9hZKRZrSTKxrqm+i/LcpV1VuQeCEyzGp1+kPnswsIpoGAAA=" } }, { "ID": "dc9687f441d2fdc8", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/txrFA8bFygbjLdx6NMX9KuFkUPm?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:35 GMT" ], "Etag": [ "N2sJBMS5YHkEHBaILy1pIg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6WSUU+DMBSF/0t9xWQz0eiSPcDGHAqIhSUaY0yBO8ZGKbYljiz77142M+KcLxoe4JTz3XPSdkNWeZmSAYnz7L0G2ZxloB/bDwqqLrTCVyVKBcQgoFmGTv9C3VleePk8XdlTizlu06+cbDhEh0oWwBkZbMg8hyJVZPCyISXjgNi894YO3VStoPbogY5Rc5G22p+5rmm5Nq78JKOcg9KMVx0fOZ4dRqYXnBixNQ5kqGVeZqaUrOnYMKKOf9uB1A5sM7LH38A6RrZO9B8r74N/z+zKvp5KPWp8HH1o/N/o9jHIUsQU5iChTKA9u0qKJSTaaa+FWoiiaDgrz1Pg4lzjQZAdsfur13JiXseTJouXbrq+8r2nm/t6spoFHF2FSJjORYnGWYi7S7TQrKDiA/uSPvnSVoNDAykSUAraob19wEjwqgCNjXBLwCAJw8s1zfVebz8B5wAJ8LkCAAA=" } }, { "ID": "8b98df71cc20f03d", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anonb75ff2f7282c54cd167a6d584579fe39da451147/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:35 GMT" ], "Etag": [ "3tKwmoVejW2WF57RGiO40g==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8obl3iX5+aHpWaFG4W7mZoHuWf6mxik29oCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsU7JCYioZmphamFiYGZmY6hko1eqABaFSiTC+UpJSbSyUjaw3GSSMogdZNgVJFlk8FSweCyMAVWdpk/MAAAA=" } }, { "ID": "35059da6526c8895", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "827" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUIEB2YWwuVGltZXN0YW1wLCBAdmFsLlN1YlN0cnVjdC5TdHJpbmciLCJxdWVyeVBhcmFtZXRlcnMiOlt7Im5hbWUiOiJ2YWwiLCJwYXJhbWV0ZXJUeXBlIjp7InN0cnVjdFR5cGVzIjpbeyJuYW1lIjoiVGltZXN0YW1wIiwidHlwZSI6eyJ0eXBlIjoiVElNRVNUQU1QIn19LHsibmFtZSI6IlN0cmluZ0FycmF5IiwidHlwZSI6eyJhcnJheVR5cGUiOnsidHlwZSI6IlNUUklORyJ9LCJ0eXBlIjoiQVJSQVkifX0seyJuYW1lIjoiU3ViU3RydWN0IiwidHlwZSI6eyJzdHJ1Y3RUeXBlcyI6W3sibmFtZSI6IlN0cmluZyIsInR5cGUiOnsidHlwZSI6IlNUUklORyJ9fV0sInR5cGUiOiJTVFJVQ1QifX0seyJuYW1lIjoiU3ViU3RydWN0QXJyYXkiLCJ0eXBlIjp7ImFycmF5VHlwZSI6eyJzdHJ1Y3RUeXBlcyI6W3sibmFtZSI6IlN0cmluZyIsInR5cGUiOnsidHlwZSI6IlNUUklORyJ9fV0sInR5cGUiOiJTVFJVQ1QifSwidHlwZSI6IkFSUkFZIn19XSwidHlwZSI6IlNUUlVDVCJ9LCJwYXJhbWV0ZXJWYWx1ZSI6eyJzdHJ1Y3RWYWx1ZXMiOnsiU3RyaW5nQXJyYXkiOnt9LCJTdWJTdHJ1Y3QiOnsic3RydWN0VmFsdWVzIjp7IlN0cmluZyI6eyJ2YWx1ZSI6ImEifX19LCJTdWJTdHJ1Y3RBcnJheSI6e30sIlRpbWVzdGFtcCI6eyJ2YWx1ZSI6IjIwMTYtMDMtMjAgMTU6MDQ6MDUrMDA6MDAifX19fV0sInVzZUxlZ2FjeVNxbCI6ZmFsc2V9fSwiam9iUmVmZXJlbmNlIjp7ImpvYklkIjoicmhEQXlSM1RVWHdDZEpXeUZYYXlJNEZvRlRrIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:36 GMT" ], "Etag": [ "JElTrp2vPaTxLLvpcXstmQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6VUa2/aMBT9K5X3cTzyIECQqhVBmKgoakPoQ9OEHMekbpM4dQxdVPHfd+0USgfrpu1D5Nj3nHNf9n1BjyyLUA+FLH5aUVF+euAhqiEqcQyn514SiNxaX+Lgx2SyzsltIdOr01NAMMUq7nmSlCnO6hFNeV3SQvbms4a4H/ZL3w7mt8+D6PymHN3ictwa8VHwCMyCJssJyx6Bfy9lXvSaza33Rsx5nFCcs6JBeLo7b66tZi74AyWyaB5x2oSoi+YHbr8knGDJeHY6n0EIq4KKBU0xSyAIJVAXPOTy7Ih0g+G0EQN+zQjFhPBVJlVsoEJ4tmTxSmhh1HtBOta9HzTzJt4gODlb46QRsBTkcJrXqv1sFc6kWBHZgIVlMQhGAGCZlgtwmFAl9Zr2+DflViwscUErxCKk1Oq0w8h1TLNlLtttx+lis9NybZe4kdOyiE0tw8bAk8qFZuGMZ8QgtGu7ZmgTHNrYse2uhd1lm4RL2sI4Ch3Dsa0wQhtIXFAs6ZAVOS9YlTwa+F4/8Bbj0WLqeUNvCA6eBfsVdeOPART48+kA0IDJBeMAU8UaTwPP7w+C8bVXtWhCY0zK2RM0aYmTgtaqul5igVMqqShQ79sLymADbCipktvagjLX5ZN6RTNwOQjU5dMlV9Z37F1zVF3eU4PxhTcL+heXaLOp7QhVz/pC4PKQ0vf9/h0cY2U+jGQ8/Qpa+2Lbq3Ao9afAd3fnkFe5+X7U0b8F/t+RwLfXo2ucrDSyUtTbQu3f6nHMWPmBv3XFR1hXc6+HezbLMNt1w65bxonp9IxWz3A+G0bPMBRHhwOjo8oUXc09/w5VRz5dUkEz8pdvEBja+vHk2w4hAMIY2qhSwh7ePNGZ6Wel3j7TBTWdjmV1Ox3X6UK4Gizkgc3tmqj2NnmUIk1pJl9zqiaQurratCp2IDDCM5xWvfkJXIDUAggGAAA=" } }, { "ID": "db2be932f840a045", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/rhDAyR3TUXwCdJWyFXayI4FoFTk?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:36 GMT" ], "Etag": [ "7onp6EW68MtfjjprqRc5kA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/22QT08CMRDFv8t4XRKNioaEw4Kga4Dg7hJIjIfSHZYu/Uc7hDSE724XjF48tfP6fjNveoKd0BX0YC3q/QFduKmRPtpLjv4gycfDGu0REkBidXQ+GW27o2X3eUqbprFun/PHXdrvR4fnW1QMeifYCJSVh97nCTRTGLFSKPTElI0+CvYiZdNRUabTeZSUqVpptphM0sFkBOfklyzICV3/YUWZZ7PX/5ivcwKNWee4QYeaY5vEOtMgp6xd0m+NlEEx3alQmQ7FQHAhLq9u+5KG/L5crI7D6n0ZxisWsoexGZe76JKGMxJGR+OiiPGADDGZm2PcEu7gpx6E2HTuDEfvsW16ex0wNMpKpJiI3AET4Cx+1Zuga33+BkHFTECHAQAA" } }, { "ID": "cf21212b95aa8abf", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anonc0ce8391b3cab3a53382a9f6cbfe4aadb50532bd/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:36 GMT" ], "Etag": [ "lhvxDnPw0Fo0dy3jEk+n/g==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8rnZJRVuOQFlBu45RukVBpnuWZr5+mn29oCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwmbmFqYWJgZmZjqGSjV6kAEE5VqY4EQAFx01huDAAAA" } }, { "ID": "33a25680f232b5ee", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "233" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7ImRyeVJ1biI6dHJ1ZSwicXVlcnkiOnsicXVlcnkiOiJTRUxFQ1Qgd29yZCBmcm9tIGBiaWdxdWVyeS1wdWJsaWMtZGF0YS5zYW1wbGVzLnNoYWtlc3BlYXJlYCBMSU1JVCAxMCIsInVzZUxlZ2FjeVNxbCI6ZmFsc2V9fSwiam9iUmVmZXJlbmNlIjp7ImpvYklkIjoiVVF4cmQzWHR4VFMySEpZUjkwWDk5MVdDek5rIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:36 GMT" ], "Etag": [ "C93D59g1oAOUTK6HSr3mbA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41T72+bMBD9VyL2tUn4EUiJVG1pwlY0lnaEbJqmKTXmIG4BU9u0iqr+7zuTpGurTNs37Hv33vnd49G4ZXVmTIyUFXctiO27G54aJwYoUuDtzHfmrl9YfHq5Sj57F0vhVOn07AwRTHfJDS/LbUXqfgYV7yuQarJaDrAsocwjVt8iaKNUIyfD4UFiUHBelEAaJgeUV8/3w3t72Ah+A1TJ4RHmIY4mh+9LTolivD5bLVGnlSDWUBFWopJG9QVPufpwpH/ASDUoEH/PKBBKeVsrPQCyUF7nrGhFR2xMHo1uoBcfxjKIglnSe+Ai6+WCV73rw9j9pk1LRvsZUWQgSdWUIAdyQ25BNkAEXPei8EuY9CwThTKcg9WdTELSErTE/s3hXwzVXUgtYYdYpwD22Esz37WskZV7nuueEms88h2f+pk7sqkDtukQ7FNaousiNa/d7JR4JqGmiU3UdfOxiySu55rEG5nguVk6ym0zNZ7QEAFEwZzJhku2M8WYxcE0Cdbhx/UiCObBHAUeBHuL+h6HCEri1WKGaMQ0gnGEaRPDRRLE01kSfgt2q4ugIHS7vMPl5aSUgMqZ2MYtEinRwomBK0+2DdpkfF0F8Q89Gl7FkIOAmv6nfYfEIAAzgxRS4RkXQaUm6N6qF8IqLWS5Y9s+HY99z/F8bSJXpDzfIteV4BSkBK1kOY7tjxysP0flX8A/9XNWll1RR4ISuoELpvYWnBji8LqsiwjO+PP1K48l701K9jl8lYEXmTSefqELqFsRPXnOoMx2OjXpTNA5180775dJHC4+4bnimT4vVlE0PY8CpNm7CRXUar+p3a9y3LkppfiXUR2GqziYhUvk2FO03TI6MqzOLxe69BuyKSAMoAQAAA==" } }, { "ID": "91c39d7c74c6a9ac", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "711" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiXG5cdC0tIERlY2xhcmUgYSB2YXJpYWJsZSB0byBob2xkIG5hbWVzIGFzIGFuIGFycmF5LlxuXHRERUNMQVJFIHRvcF9uYW1lcyBBUlJBWVx1MDAzY1NUUklOR1x1MDAzZTtcblx0LS0gQnVpbGQgYW4gYXJyYXkgb2YgdGhlIHRvcCAxMDAgbmFtZXMgZnJvbSB0aGUgeWVhciAyMDE3LlxuXHRTRVQgdG9wX25hbWVzID0gKFxuXHQgIFNFTEVDVCBBUlJBWV9BR0cobmFtZSBPUkRFUiBCWSBudW1iZXIgREVTQyBMSU1JVCAxMDApXG5cdCAgRlJPTSBgYmlncXVlcnktcHVibGljLWRhdGFgLnVzYV9uYW1lcy51c2FfMTkxMF9jdXJyZW50XG5cdCAgV0hFUkUgeWVhciA9IDIwMTdcblx0KTtcblx0LS0gV2hpY2ggbmFtZXMgYXBwZWFyIGFzIHdvcmRzIGluIFNoYWtlc3BlYXJlJ3MgcGxheXM/XG5cdFNFTEVDVFxuXHQgIG5hbWUgQVMgc2hha2VzcGVhcmVfbmFtZVxuXHRGUk9NIFVOTkVTVCh0b3BfbmFtZXMpIEFTIG5hbWVcblx0V0hFUkUgbmFtZSBJTiAoXG5cdCAgU0VMRUNUIHdvcmRcblx0ICBGUk9NIGBiaWdxdWVyeS1wdWJsaWMtZGF0YWAuc2FtcGxlcy5zaGFrZXNwZWFyZVxuXHQpO1xuXHQiLCJ1c2VMZWdhY3lTcWwiOmZhbHNlfX0sImpvYlJlZmVyZW5jZSI6eyJqb2JJZCI6InloQ0lIZlE3Qk1DZFRybWtQVzRWTVNPVUlGSCIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:37 GMT" ], "Etag": [ "0TgKaIUR5jswYPUNAEZANg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/4VTbU/bMBD+K1b2YSDR9GWwQqeKhTZARFsgL6BOSMV13dQ0iYPtgCLEf9/ZaQraGFPywb577p7nzncv1pplC6tnzVn8WFBRfnngc2vPogrHYG2F8QX2Iv/gQT5Pr6KJ4/5yJnG/Dwimo+SKJ0mZ4qyxoClvKCpVLwrscjXwzpfX3ZPxYBGKdH11u38zDi4j7/QcIiVNliOWrSF+pVQue81mzW7HnMcJxTmTNuHp1t586jRzwR8oUbL5AWkTVMvmJ7THCSdYMZ71owAkFJKKGU0xS0CETtAQfM7Vzw9S2wyndgz4J0YoJoQXmdLaIAvh2ZLFhTCJrd6LZbS+O1h32Z1qNNCQkgQLijB6woLheUKR4gi4FijDKZUIw58hLAQubR0zdAcjx3cBlc8qhOP7zvSuaLW+kSD0vcmZOdMfG4aTgkGyOgfiS6RWmiRH7VZrQ7IUPDXmkmKBOq1213AFbviOp492tBGhwB25g7DinTlnZzvajy79oeujkynKinROBRq6wQCNvLEXaqLdKvTUvxyj+/rtGnkxTxhpLLDC93YhccVkTu2jdmtGCiFopqrY23MX6jYK+0ajNu/WZd6uGFnVPctzjYLWPXOxkIhlKFjhNZXaTL9KlCe4lMdVibqWisCU4QRIvmGNIO01wqPJxA3CnW1LdjW6RlTyTA5v8kertIz/N0DiNE+g/Hf8byXCUOWCccGUnh5vErq+Mwi9G7ea2RGNMSmDR5jaJU4kfd2zYPDDMqeAvo5cf2pVJp8uKfSUUD2Mm8Xx/rGwlokw3s/3tl4hAMISAZFUcJeKEalpiKDGHbJUy2kfdDudw2736Pvh/qFlwEL95YMPfNu90RlpCsOwqSkY+N5VaL1uyAq5BYHTh5eCRQDvb7hqkLvGBAAA" } }, { "ID": "8ea9728555391751", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/yhCIHfQ7BMCdTrmkPW4VMSOUIFH?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:40 GMT" ], "Etag": [ "AG6V181pQnvs8nraQiGJ9g==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2OS2+CQBSF/8vtVheIoUjiQkiLNGgF1C6aphnh8pB50JmxDSH+9w60q/s657tngLbhBXhwaaqvG8r+oUKdjE2K6ka1MqUTXCHMADWpjHITOmfLtbqEfyuXS5I04cuqWq+NQuU1MgLeAGWDtFDgvQ/ACUNjUzVpDQuJxM9pNQPdd+MlO6bRPjQzE8U4709xvPHjJ7h/3GdwFZcUS5TIcxzJnRRXzHVUTExBac8InxfIxFyj0jA5pmtfB9G2TB79XVAcJWsPb8vzLns9Rc9bo6IiJ7oR3AhPGZhHWmhCU/FjUoPtwv/C7w31IEWOSuFItZb2ynacxeLvUyBYR1GbaFre8P4LCaf5JFABAAA=" } }, { "ID": "d41a0c97d8bf2538", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs/yhCIHfQ7BMCdTrmkPW4VMSOUIFH?alt=json\u0026fields=status%2Cstatistics\u0026location=US\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:40 GMT" ], "Etag": [ "AqO2IhLIdCfeR4N7J3xGEg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/4WQzQ6CMAyA36VnD7ghGx5BD5qoRHgBhSYuGUxZORDCu7uhxhhNTE/t96V/A1g6kbKkSgvLAcoWXWqaQtUIS5gvBGNSiDiSoYSZl1v6Yi4cw6b6JDIIAsYdIUMnnfSENmtNidZi5a2QxzyKGHPGrcO29/P/q28jUVo/cSgCHkr5wrk2tHP3AGfisTVhjQ0V/dXvl6fHTVbA+Ntuujq9KF1tzdkXmfd8h2560NTLlVeH/RrG8Q7AcM1sQAEAAA==" } }, { "ID": "f035b8e7c491adb6", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?allUsers=false\u0026alt=json\u0026pageToken=\u0026parentJobId=yhCIHfQ7BMCdTrmkPW4VMSOUIFH\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:41 GMT" ], "Etag": [ "0JlHaFzTGLbfPR8XTgQtaw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/+1Z6W/bOBb/VwRtP6RAGlC35EGBdRylccZHKinNFNtAQ0u0rVaWXB1JvEX+930kfelwjmIWM7uYfAhk8h18x++Rj/whkgLPxI6ILuMLfP5v78NgMr1yzN+82ccC379/Lx6L36IkBIpJNPtekmz1j6/pZBDlBczAVy52/vVDjChBPk/jeLXAybuQLNJ3BcmLzrV7kgdZtCx8oPUtGUkmNnTFCkNNnmpkEigTYsiGGk6noUV8qV0dV+WQKclIEhCx80NcZulXEhT9A4o5B599pf44DXARpQmwXrvi47GYF7gAneLZeGSL/CeYHwU5XUeQEUbtRQtKI2mGLJuGYVmyZHLirGjMqTJVRJKwOaOpMFOkBY5PV2DIVZYGJM8JNQTBDHMJ1XuYZDdzGsXxdjjAwZxcRIXYKbKSrK1akKTwVku6Btce2D2P2rvE4OXicu2+1bzXv5h+NE6HvdDLFt+ubtRPQ3d83T+/oPYx57oVl5A7HJfMKb/yULpe17OH9sjjDgm+nWd4QXjmMAcNogSWIElrf/XSuFyA/y3mo/WkwX5spiQEhpKHYrvwL8mXQhASkCt0XSGf428kXxKwxKdjdPbcGQ+F69HIdr2jIl2y8fwtpd5Q3FzYjs1l9EfCERfJxQv3aRbyASbn9016vluWkzgK3oW4wL+f5HixjEl+sqefMr0VH28fwbNBmkyjWZmt8+vHLpzrj/8NY47FECAWJTzx8SR+ISKp2JxwCn9CiGzok9DSJEmVprquaSaWDNVSrMAKNVUOFCIjBdOMpioYF07SJESWpIeqgieaaQUacMihKSuBbhlIDxVdCScaDvQpTWWGTnIW5cs0j9ag7jk2pKPfP/dHtn1mn4GC+yyqU904fSDynOtRD6iBZplFKZDRIPVHnu10e17/E50oczIgMxys3O+x2JniOCdrnF5hmucFyXiq01gA9zZcIoMap+AgBFhzMHYdp/sZ5nGW4VVtzvWc/uiD+Pi4x/4JEMdoGAP7xXXe8QnRXiwwOGQ3MIyqv0cpnlcGxnF0V6Nx0+W8NtTP8YTEcXWwocwlEwwJg5PK6CDCiypfMa+RDHFRzMl9ZewMJxGJK0OXOIBNosZI0spINyYPOAlJ9rTZl2VcX2fdVack+YoXUfK8IxoWtnjQXkTxqjLSA+F1QemstqiW8FziVUiSmr5pjWhQBjivOiZqcLWGi2qsee8M38HOXxEGpQRH1eh0cZZWRXXv8DPROlvFNfUj3MyOKJjjRipQZFUcHEdfa0H+FAUFgBk/R9dNinmarOqBxsHTUW4xr5HFN7A31/maadyb4yxOCzh+VOSHWT04LaBoSaMhztNXY7AZ5Ms0ry6omWbdJMxqFlOu5bzuyyZoGpDsJrOaae1YbpSdZi404d7ETAuyWqpnM/Nay0ITXPYdiVfPY7lZhtoyZlAmdZPrKdREUhtGB+U3Ug9N9BLUuAFkKCmK50qFs6pX/0ZJc/GirPnUxQnUoVlaS6SkWQuaZfSKJCROl+Q57/fmGZxdoTDXVtzI8u6CxNR6epTb7uYky9LsZJpmCwA5CX12vvWLDEObcnh/3+3hNUGQsDme/RTryzQ/c7K47vFDelYGrDGonFxiehI/XlNvueA0pKuV9QT8kP4CymkUE/bZoG0xc9uYHSaG0LT5hTc6PmsYXuXZLL33g7RMnmLbWHULB7IwWzllsj0FQs9JO7y0LIbgSFGWNMtUTJU3p+u+6+O17XzetJkla6AqDecjO2FmPllQzMLxEc7S77J0khb/bDlln0CFOJkB/V0UEBywtZ8EKa8aL+zSZcnSTUNTNF2dyqquyjKxwsBEMjGCCTEVH/13u/QX6f9junRDV4xDXbphylp7l26qZrXR3m/BJVWxFF2X5f1unbcDtBDvwclFqCP0k2VJ/RBt+nS2FpYuO31IU/hKauOyRO8R7nFUONS87t1M7KATWTV0yULb/wonGeZsXpT1fZ4hfniSh81zHvBhuNMj8YGNVAlp+ySMbUvChXASSEawmOwv2NyObqQxjOxTrpe5T8mFMkrWv+1LRIqJLE3e/JfWJBvxVZ617IM8XBHlyefldBqTcVnAEljkqW9U02ydc5f79y8ZCaDrzh1wCIzoSDYlTdqN34CugtB0lta1Bnhjlh35epBaDlstCa/aZjflQ+yNh1cD2+MgIEtewddwhdaX9rt5OdlMiW/kDs3HY+GN0knKxYRk8Cl1VtDuAyW7H2i7Hjgpc8zbWPYlWRLygzKjN0fAxi8fyPcSx0dvpGNBRpLxVrylRWi9ku6HD479gbfW1eUgofNecC+6zpnPNisfSI/eyMLYObMd4fQzLFQ4s92eMOgP+54gIVSVzDr3plQY8caCTzfoGUHIT1mggPN2r967SOoIPIQbTEqHMGlJ7ZhULMpKQ+NSVUw/Em+bOFUkVTY1Y/e/ilNFacHpQR6epIynilNUxSlqoBRVUYraMYpqBULSG6Cto3uDq6c4uU6tFcN6/a+GYqMVxYe5uC7jEI4l9BM4/msgGG2Q2pLeL4CcxCDnjMdeBXFoB7nXA06qAU7aBxyAgV4gwpGZhE9uoEBD2KmTeoDEeAkkDG+6JG92YBcaZDamyDS2S4BklMyuk4g5Fu27fTMoi3QJjBsiUbA7vyfu0Q+urnnTLqmqgRS+I0xow5bMvAgaC7oXtq12dyu/PjJmm+NTyC5Weez3j1Ftxbh2t7otzZW700aZpj44/ArQ6ts/+mXA/u3KsV23Px49/TSg1V4GZG3vacA69DJQvfTepTa7FN/mNt/06hn+/PX44Q2Q8/I9kO6jwnu2Ab7uJYBfUwuePbwSzq9HPQ+cBGiiTQe0JCQLgNGPEuhHEhz7/tEDN/BLiZAS8FaGfRP2KnD08PaXL8naE09I+Su67O0vf/KLg66bCgqQ4utTlfiqhgJ/YlrED4mGDW2iGhqS/+9fG/6+8/j7zuMn7zwsy5D+lDuP28f/AGojk2LgIAAA" } }, { "ID": "d821c0f7903cbf6b", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "272" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJleHBpcmF0aW9uVGltZSI6IjE1NzIyODgzMDcwMDAiLCJzY2hlbWEiOnsiZmllbGRzIjpbeyJuYW1lIjoibmFtZSIsInR5cGUiOiJTVFJJTkcifSx7Im5hbWUiOiJudW0iLCJ0eXBlIjoiSU5URUdFUiJ9XX0sInRhYmxlUmVmZXJlbmNlIjp7ImRhdGFzZXRJZCI6ImRhdGFzZXRfMjAxOTEwMjhfNjY5MDY1OTAwOTM2NTlfMDAwMSIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QiLCJ0YWJsZUlkIjoidGFibGVfMjAxOTEwMjhfNjY5MDY1OTAwOTM2NTlfMDAxNiJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:41 GMT" ], "Etag": [ "lx1UaOxunlsjqNJkyvIxCA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42SUWvCMBDHv0v2Ok1SUWvBBx0iDudA69MYEtuzRtOmNtFZxO++a6cT5jb6FO5//7v73ZET2cokJB5Zymi3hyx/sGKpgDwSsCJCXR35XLwe94kym93keZsfRsenXreLDlnUmbVWKo9FUgsh1jULxnqhsMKAXTiMdzhz3EWr1WGtZoexTgOfBWOM18s5/1h4C0cYUKuxTLY4aG1tajxKr6D1SOtIgUilqQc6/tbpwaFppjcQWEN/oaMXOkOrYNIS09BKtKVpCivIIAmAeCdyARn9cSmsuUCUjipA1zFlQQWqMx4xWEMsCpyVBBUa4r2dSCJiJPx6sGWeFtHMn44mQ6y55ffxLT2a+IPhYErO79gVM/0cl0CdkTIc6yTyIfspT/XHNQoyEFbqxJdlc95sO47bdhlnbqP4csdUZvcGt8HauDoalDD2RYcS9wjvenDu3FD9Xn88KCp0UDZEaT4j508CGiX17wIAAA==" } }, { "ID": "73a490efd4070511", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "298" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiSU5TRVJUIGRhdGFzZXRfMjAxOTEwMjhfNjY5MDY1OTAwOTM2NTlfMDAwMS50YWJsZV8yMDE5MTAyOF82NjkwNjU5MDA5MzY1OV8wMDE2IChuYW1lLCBudW0pXG5cdFx0ICAgICAgICAgICAgICAgIFZBTFVFUyAoJ2EnLCAxKSwgKCdiJywgMiksICgnYycsIDMpIiwidXNlTGVnYWN5U3FsIjpmYWxzZX19LCJqb2JSZWZlcmVuY2UiOnsiam9iSWQiOiJISmIzYVhpenZpOXU4cmhoeDVBakw0V2tGWVoiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0In19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:41 GMT" ], "Etag": [ "K9+lCo/1Y1GNWEmLF0NT5A==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41S227aQBD9FWv7kKCCbwSDkVCLIielRZYKJikVElovg1li7xLvGpVG+feObYKqNqXhhfHOOXPOXJ7IAxcr0icxTx4LyA/vtjImTQKaJvj6xX+fXkvLmTu34X2QjW/sMOoMBwNE8JKlNjJNDxkVrRVksqVB6f5san76HLfpN/5zz/2il282PzrD7fjq/uFm/h2ZCtL1mIsH5G+03qm+Zb2om4mUSQp0x5XJZHZ6t/autcvlFphW1iuiFrpW1hnZD6lkVHMpBrMpWigU5EvIKE/RRFmglctY6o+vlDY5zcwE8XvOgDImC6FLb1iFSbHmSZFXhUn/iVRefwvIKJwGk8hYUU0V6KVrO75ju72l5/m21/Ft22/j39K2bcfUNE7hDMTxjEtBM2gaosgaC7HQC2388bsbjmfB1Li8oBdNw2k0MYoxcquIYdRuoO8VtsVF5ToqRUvHx+mO/rHVklU3USHe0hBSqpYqwv+bI89NNMFlznU9uSiYDK+j0V1Q72sMCWWH6SNubE1TBQjHpUeHHdonX2fBZE7qpwmsIQfB3tgWMqrs+Zt9OR8E4gGhkNL4jWNkqpRhOdTj5Flpx+l0XbfX7dmO63mkAuf6r9xVu4u5082UFSEDoY891bdDno9ihTqBMDmZheEovMXsL2wZWfrCAwAA" } }, { "ID": "16bc24eaa6d416e2", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/HJb3aXizvi9u8rhhx5AjL4WkFYZ?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:44 GMT" ], "Etag": [ "StvP13MfFXywrsSOVDXYSw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/0VPy07CQBT9l+u2JBo00SYsUF41itiigsbF0N62AzOdOnML1Kb/7i0uWN3HeeScBnaySMCHjcx+KrT1RYb02i0hukqR41GawiF4gCQyZka0X1z1n9PJqj5YF728j1br6DAYMMPFOWoBfgOpRJU48L8aKIRGlp2GB1SX3RUtw2A+hdY745U+w8F8OZ6OQ2i/Ww+2ZhNiihaLGDvv0potxhR0sV1ulKq1KHoJatMjdAQnxQmdPW76YiV/9/KuurV5frwZbp+uP3aT9SezlIkFSVMw8S3iKECGhLqv2WRhTYzOYWdy+W/4YHSpkDgB2Qo9iAWXnUkCPxXK8YMLjLQapilnwyQ0B64PfWj/AFcikQ9jAQAA" } }, { "ID": "b56a11fa465cad17", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs/HJb3aXizvi9u8rhhx5AjL4WkFYZ?alt=json\u0026fields=status%2Cstatistics\u0026location=US\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:44 GMT" ], "Etag": [ "Uq90DVYFtVFjwA6j6epTXA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/7VWXU/jOBT9K1WENC+w8kc+7EjzwEBXi7SdorajeRihyiS3kNk06cbusAjx3/faaWiahtKR4Kmx7z0+17fn2H7ytFEm0yZLtBc/eUkFOCyLWbYEL/ZoEDEmIkEoC0Pv1CZXZi/m8whjUKTdiE8ExYgpjcq/PBrQ11WZgNaQYhbByL9rqB4tr/u4zlXhxT+evEK5daaExIOrYrU2mJo1GFfDSO9UEDC/rqA7zwXOP6jMTOy2zn/deTH5gxDBQt8PmSBS0ogHQVgnjbTL8GgbNFL/vQFyGQ6E3UtbTPVEsyppJ9SrNgn1CjYhKZe4X9gpl3MSRCKgjMswlD5jL2nN0n4H2dR8CFlzWuRDlb3N6JLafFvUAbYNasul79eLRQ7jtcEqnCZsgPVGpqssz1+0UkFSVqmeYMN2Z74jhwFUjsdxcqUqhajc6UZv/he76RwMpNd9UWuBtR1cjEfXfw9nQzcHK+3E+E9WpJvYtzq0vm2i3gklg/jz4JP6hIETSu2AejfPp2/hWI27dTjmcOwYHK9xicNxh+M7uO+Tq54qTwcntsez8WA+x+3eASHz0nUawQ7+4jkaDy5KlYNOoLEd7bcdIzLssx3jTFqo7fHUkrkiiHfzXlbsE1rLif6HOdGnnDFOfeLLQIRRJPacGLzixMjneB6FAROSBeG+D2WfD7GjhPmR5FwIn8ko7NiQyj4f1hRUCu5HFIm7NuTBO/qQH+3DgBw0YkCOdeJkeH7ZEfifk/HobWWzeFDvqtE1e0XXjEa9uvYl3dc13dc17WiY7auYdi4P9mHXBz2gvU19vF+0h5CbsnmfbHcNzUPRkW0k+mT7Oqrmcqhe2ZIPVO073R49mn05lHfES7fi/f0znbWVj6oEfNctFRbe+/jCGORZAa5OyNUKQ07wgRDNq22al7U5mEWs0BJZcfetyIxuCc71ppm0LVGJyX7BNs1upU1AaUj2GAQJ6JEcATuChIXUf3+Sm82KKAWT2Zfyfltffe1uI1/a0rzFARYzy6By50JvxYlK7uGvzHjxQuUarHwXUEGRQDpTtznUaltV5U9IzJVdWt+Xef64VMVZCsvyDFntuZcqozTUGZvvOSNUUsLEHC9TEgaSEMnxZ04Icc93u74DuK8D6TR0DSrWy8tlfr5YYCmQTsoHvXGXtQosoTCzx5U9kq++ToeTGf5zfXt+3lrrqUZi5HL8deg9P/8PRf2Ik7cMAAA=" } }, { "ID": "c3cb40688d39d8a3", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "389" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7ImV4dHJhY3QiOnsiZGVzdGluYXRpb25Gb3JtYXQiOiJDU1YiLCJkZXN0aW5hdGlvblVyaXMiOlsiZ3M6Ly9zaG9sbHltYW4tZGVtby10ZXN0L2JxLXRlc3QtdGFibGVfMjAxOTEwMjhfNjY5MDY1OTAwOTM2NTlfMDAxNi5jc3YiXSwic291cmNlVGFibGUiOnsiZGF0YXNldElkIjoiZGF0YXNldF8yMDE5MTAyOF82NjkwNjU5MDA5MzY1OV8wMDAxIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCIsInRhYmxlSWQiOiJ0YWJsZV8yMDE5MTAyOF82NjkwNjU5MDA5MzY1OV8wMDE2In19fSwiam9iUmVmZXJlbmNlIjp7ImpvYklkIjoiSkkwbkNkUms1dUFENE8ydGpIVTRVeFZQRzgxIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:44 GMT" ], "Etag": [ "/9v6gMxQA4aEy5pYLCmfrw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/61S0W7aMBT9F+91JE4GIYmENsS6jqljGyRVp2pCjjGpIbFT22Ggin/vtQuTtjK6hz35+t5zzzk58QNac7FAKSp4ed8ytXu1kgV6jZghJXT9ZBOVn7ffhl1yses1369G9VL9HAwAwe2WvpNVtauJ6CxYLTuGaZPmM+/TGIvRYrrutcP33S+hWX3Mu/n2+utlHMCmZtXyios17N8Z0+jU94/qXillWTHScO1RWf/q+5vQb5RcMWq0f0LUB9faPyP7tpKUGC7FIJ+BhVYzNWc14RWYsAQdJQtp3p2g9jipvRLwG04ZoVS2wlhvwEKlWPKyVY4YpQ+IbY0i1NhSy1ZRlpGiYvZ6MD/+S2hAtiCGaPaEONTzEAdJgMN4HkUJjnoJxskbOOYYYxuksexuwVVn4EGE9iABSlw4t7nisFba7E/FWdy7s/Myr0f1Bv1JrVF6+9/If/zG/kGqmkDCaDS7tt8EPz7bNZAxurjJpsNRdmhO2ZIpJug/pg8bbnr+5R4fEQDhGYGQNnAHb1RbGaqYG2e8toaCXj8M436MuxGOkQMr82zWx/jI1DoWW1nINJ9MxpNLtN8/ApaOOW6lAwAA" } }, { "ID": "e9b0b15fd08cbecd", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs/JI0nCdRk5uAD4O2tjHU4UxVPG81?alt=json\u0026fields=status%2Cstatistics\u0026location=US\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:44 GMT" ], "Etag": [ "/9v6gMxQA4aEy5pYLCmfrw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWKi5JLMksLslMLlayqlZKLkoFcvPzQjJzU5WslAxNzY2MLMwtDEzMDCyUdECKi0ow5MwNDJRqwZIlpWBTQCyQkqBQPz9PP3el2loAZuTgdWgAAAA=" } }, { "ID": "0244d20d8817220d", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs/JI0nCdRk5uAD4O2tjHU4UxVPG81?alt=json\u0026fields=status%2Cstatistics\u0026location=US\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:45 GMT" ], "Etag": [ "/9v6gMxQA4aEy5pYLCmfrw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWKi5JLMksLslMLlayqlZKLkoFcvPzQjJzU5WslAxNzY2MLMwtDEzMDCyUdECKi0ow5MwNDJRqwZIlpWBTQCyQkqBQPz9PP3el2loAZuTgdWgAAAA=" } }, { "ID": "14475bebfc9e4837", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs/JI0nCdRk5uAD4O2tjHU4UxVPG81?alt=json\u0026fields=status%2Cstatistics\u0026location=US\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:45 GMT" ], "Etag": [ "LAShRajm9MLk6iSygk76pQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWKi5JLMksLslMLlayqlZKLkoFcvPzQjJzU5WslAxNzY2MLMwtDEzMDCyUdECKi0ow5MwNDIByyfm5BTmpIM1BICOUrAz0TGvBWkpKwWaDWCCNQaF+fp5+7kq1tQCA6jeufgAAAA==" } }, { "ID": "d807e5db8203c367", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs/JI0nCdRk5uAD4O2tjHU4UxVPG81?alt=json\u0026fields=status%2Cstatistics\u0026location=US\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:48 GMT" ], "Etag": [ "1fvX/kW8+O++3NtPczhbhg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/21Qu67CMAz9F89FSinQ0pGXxABIXJgQQ9QaFCkkVeIiUJV/v05ZuBc228fnYXfgSZLypCoPZQeVQ26tOagbQgnpOB8Oi7wQo4koIInLjj6wXAjG0NT/kfG0mDBS2VujMcruoziUKW8/yMmKomeNbG9626NTK6VxbltDnOcEKZwTUKZpafYk5BFkGYQEyJLUP9rSJs6mImMbhx7d/aXj5ZWTnDowso9U40W2mgaNalArg/GWd3Y4/+Gv62+c0D+A2v5TsYrKi912CSH8AmMQp2lJAQAA" } }, { "ID": "a0e766714ed10443", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "451" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUICogRlJPTSBjc3YiLCJ0YWJsZURlZmluaXRpb25zIjp7ImNzdiI6eyJjc3ZPcHRpb25zIjp7ImZpZWxkRGVsaW1pdGVyIjoiLCIsInNraXBMZWFkaW5nUm93cyI6IjEifSwic2NoZW1hIjp7ImZpZWxkcyI6W3sibmFtZSI6Im5hbWUiLCJ0eXBlIjoiU1RSSU5HIn0seyJuYW1lIjoibnVtIiwidHlwZSI6IklOVEVHRVIifV19LCJzb3VyY2VGb3JtYXQiOiJDU1YiLCJzb3VyY2VVcmlzIjpbImdzOi8vc2hvbGx5bWFuLWRlbW8tdGVzdC9icS10ZXN0LXRhYmxlXzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMTYuY3N2Il19fSwidXNlTGVnYWN5U3FsIjpmYWxzZX19LCJqb2JSZWZlcmVuY2UiOnsiam9iSWQiOiJ2cGh1Y1lCOWhDNWlUSTFEVUkzQWVtOGFYUzgiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0In19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:49 GMT" ], "Etag": [ "rFoh4jm3dD32JbvK3npiOQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41T72/aMBD9Vyrv21QgPwgkSNXWQaiyMqqG0K2aqshxnOA2iVPboUIV//vOCaXT1lXji4nv3bu753fP6IFVKZqghOWPDRW7D/c8QaeIKpzDrZjzzfC+tNOZbX1Ntpd2VbOr67MzQDCdJTe8KHYlrnopLXlPUakm61V/W28acvvF20wdFgXmbB3Y57R08Y+VC5mSFtmCVQ+Qv1GqlpPB4KV6P+c8LyiumewTXh7vB1trUAt+T4mSgzeKDqBrOXin7KeCE6wYr87WK2ihkVTEtMSsgCY0QU/whKvPb1D3GS77OeC3jFBMCG8qpXsDFsKrjOWNaInR5Bm1vf72B638hT+NTj6ezMOrbydEbiErBVJWtTkRTgqq8YfZgn9oqrOwwpJ2iDih1BqPktRzTHNoZqOR47jYHA892yNe6gwtYlPLsDHkKV2izcIVtEscb2xYRpwZjhMP7cSNPcPAsTu2XJzhJHXTDO1hMkGxojMmay5ZNx2ahv555MfBPF76/syfAfmTYH+ivocBgKJwvZwCGjC1YBxgWo1gGfnh+TQKbvzuDRY0x2S3eoRXyHAh6aHdGc1Y1RJKLY6WDQ7JG0HoWjC4/IlybZu3nJA8tmevZYotw/RMw3Lj0cgzRg4M69lwxIZhjvqa+A78SDZgBV0iY7RINf0zqnAJL9Md0Nau1l+rKAyWFyDQa7wpX8N6vgs/RPs7kLBrd85FiZVWb3WjHSO3V/VxsLbcjBasBBkFgE71djywekFxyqo85E+AQybaw+8UgcejrtD12g9vUXcV0owKWpH/9BFktNH3V/RlWwAI+6KnUfANviXdi2h7aP+yVgTTGVuWO3YNz7QN1IKF+itmWybEjiuiGWlJK3WYqVsVtD8Ua+QRBEGw07JVfv8La8KkwbEEAAA=" } }, { "ID": "eb1ea54f8b1d9635", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/vphucYB9hC5iTI1DUI3Aem8aXS8?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:50 GMT" ], "Etag": [ "nxLdGvELu0X51a1jS2hoMg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/22QTWvCQBCG/8v0GqFRBBvwoDbYQCptoqCUHtbNmMTu7qTZiW0Q/3t3bcFLTzMv8z7zdYaP2hQQwb4uPzts+7sS+dUnGdpOsXWhIWMRAkAWpXOa77RYnuK0u9+OQxEe82FFz+V06hxWVqgFRGc41KgKC9HbGYzQ6DEfAuC+8SpfZ8lq6bSmwuvVJk1n8zSGS3AjOn0DktU6XsbZf8T7JYAj7TM8YItGop/ftHREyYk/zVakVK+FGRSoacBoGa7EtXpqqk7u5g/VYlyvk/Bxk4xmqCdim0+cS5EUXJNxxk3ulgMmFiqjL3cbjOBPz3vX9KUlidaibxoOfycsSDcK2a3EbYcBSOE+9FQzRAehLF5+AHL/Qu5/AQAA" } }, { "ID": "b31be1c84d590c29", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anonfc597020_f055_43b8_900a_8728afabd8df/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:50 GMT" ], "Etag": [ "J1d+8bL5TCVRVrD4oDAKYw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8p7GaZoWyT5mIY4hwWFFbmY5Ls4ekeW29oCVZTklyTmBOWXFwOVGQP5RWBmdLVSGpgsA5muVKsDYRkp1caC2Ai5RLicIYZcMlzOGCQXWwsAn0oY6LAAAAA=" } }, { "ID": "2448ca961dc642a7", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "556" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJleHBpcmF0aW9uVGltZSI6IjE1NzIyODgzMDcwMDAiLCJleHRlcm5hbERhdGFDb25maWd1cmF0aW9uIjp7ImNzdk9wdGlvbnMiOnsiZmllbGREZWxpbWl0ZXIiOiIsIiwic2tpcExlYWRpbmdSb3dzIjoiMSJ9LCJzY2hlbWEiOnsiZmllbGRzIjpbeyJuYW1lIjoibmFtZSIsInR5cGUiOiJTVFJJTkcifSx7Im5hbWUiOiJudW0iLCJ0eXBlIjoiSU5URUdFUiJ9XX0sInNvdXJjZUZvcm1hdCI6IkNTViIsInNvdXJjZVVyaXMiOlsiZ3M6Ly9zaG9sbHltYW4tZGVtby10ZXN0L2JxLXRlc3QtdGFibGVfMjAxOTEwMjhfNjY5MDY1OTAwOTM2NTlfMDAxNi5jc3YiXX0sInNjaGVtYSI6eyJmaWVsZHMiOlt7Im5hbWUiOiJuYW1lIiwidHlwZSI6IlNUUklORyJ9LHsibmFtZSI6Im51bSIsInR5cGUiOiJJTlRFR0VSIn1dfSwidGFibGVSZWZlcmVuY2UiOnsiZGF0YXNldElkIjoiZGF0YXNldF8yMDE5MTAyOF82NjkwNjU5MDA5MzY1OV8wMDAxIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCIsInRhYmxlSWQiOiJ0YWJsZV8yMDE5MTAyOF82NjkwNjU5MDA5MzY1OV8wMDE3In19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:50 GMT" ], "Etag": [ "CpCiKYaxKmdPFI2QP3QIuA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42TYW/aMBCG/4v3FYgT1ACR+qGjtIrKWBvSqdNUIZMcwcOxU9vQIsR/3zkNRWq7jU+W7967e+6NsyMrLnMSkTkvntagt18smwsgLQKWFRgfVkN+85O93JT57VUc3N127+L1xfk5KrirM0slxLZksp1DqdoWjI1yZpkBOwuoP/Bp0J+F4YCGZwNKB108ZpRSv1PP+YfE7+EIA2Ix5nKFg5bWVibyvANop1CqEMAqbjqZKt/i3ibwKq1+Q2aN9wmd19AZ7xRMr8Y03km0tSiBBWiQGZBoRxqQ+C9OYU0DUStOATqMqQtOoNqjidkSSuZwFhxEbkj0a0ckK5Hw9cCW28rdpmkST66x5phfl8d0PElH16OE7B+xK2a+bnEJjFNSX8dKFino9+FEPR9umQZmuZIpr5v7Z70g6Pf6Dt75By8V1x8F/S7t4eooEMzYbyrnuEf+oUfXD4+oo4d0lEwuxnVXC1oycYnuDpVc8GL9OsQ5YtRaZ3CvuXOFFO6BffZm5k/12f6v4WEnMxvy2GoaXyldMut+o+kPt7/ZfK/caPP2NS5B8JIjIYpa7sWveDUGlnNZNMb5ZI92C5U10OR+SvZ/AF7QcQe4AwAA" } }, { "ID": "6f2fc31083e53cca", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "236" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUICogRlJPTSBkYXRhc2V0XzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDEudGFibGVfMjAxOTEwMjhfNjY5MDY1OTAwOTM2NTlfMDAxNyIsInVzZUxlZ2FjeVNxbCI6ZmFsc2V9fSwiam9iUmVmZXJlbmNlIjp7ImpvYklkIjoib1I1MHdnWUd0ZHI4Q1k0b20ySXZ2TTVWd1JpIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:50 GMT" ], "Etag": [ "ASjDhj92AAEgxMpVIRAoOw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41SXW+bQBD8K9H1raoNBxwflqLWskmElDgqxqn8hA5Y43OAI9zZrhXlv3fBSVS1adQnYHdmZ5jdJ/IgmoJMSCbKxz10p087mZEvBDQvsTpd7ubbXWBNp2H587a9j+KpvDteXiJC9Cy1lVV1qnkzKqCWIw1KT1bLsYyZeSzX17ro/NnakbUVHQ637P4YC2QqqDY3onlA/lbrVk0M41V9XEpZVsBboca5rN/qxsEy2k7uINfKeEfUQNfK+ED2ayVzroVsLldLtLBX0KVQc1GhiX7AqJOZ1N/eGT0WvB6XiD+IHHiey32je284JZfNRpT7bhhMJk9k8PrbC1mGN+Esufh8cRXf3V4UXHMFOrVMGlDT8lPXDUyXBaYZ2PhITdOkY82zCj6AUA+VCzQmmkE36fG95ks+0T/20rPO+gMizQAsz82KgFHq0I3rMuZz6jmBHeRBwRwrt8EybY68wdLA4o1s7CJjSHPSDfXc1LGpk2YWdVPmgO/ZbsYK3yfPmE4HXMNcqFYqcU6IzOJwmoRpdJUuwnAeznH4sRN/on7EEYKSeLWYIRoxbSckwvpEo0USxtNZEt2H5z3eQMnz0/IRN7nhlQJUxmNITi2GQr6vwnhNzqUYNtBBk/9nWMgYuh/f8utZIRAPC4WUxm9cTq56mSGDfkmi7u1Q5lmW7/nUdJhDBnCn/+oxL8De2y31E6GGRr/80/mmyPOL2F69gbCJmS2ixTV2fwFhic3E2gMAAA==" } }, { "ID": "2f8027403a19d1c3", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/oR50wgYGtdr8CY4om2IvvM5VwRi?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:51 GMT" ], "Etag": [ "DxRabi0owJ4KP4G8paI66w==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/22QTU/CQBCG/8t4LQkiENKEg2BTq0hwARNiPCzttCzudmp3Sm1I/7tbNOHiaebNvM98neFT5Qn4sFfZV4Vlc5Mhv3aJQFtpti4UlFsED5Bl5pwP30LuVZ/qp+HzahhOChmNx/V06hw2PqCR4J8hVagTC/77GXJp0GGX4AE3RafWGxEtQ6cNJZ1ebheL+9kigNa7EpW5AtFyE4SB+I/4aD040l5giiXmMXbzi5KOGHPUnWYPpHVjZN5L0FCP0TJciEuVxKhfZ7uQk3Iy3w3JDKLT6WX0VgvlXJpiyYpyZ9yu3XLAxFILqt1tcAd/eta4pquSYrQWu6a3g98JczKFRnYrcVmhB7F0H3pUDH4qtcX2B3sdNuF/AQAA" } }, { "ID": "1e2eaf6b1918c6e7", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anon3db5bd94_f176_4314_b216_54e8736b5d88/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:51 GMT" ], "Etag": [ "4j12MRVv3xOz3coQxRWq6w==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8qbZBka+QaFlRlX+FcZJ+cHVgSFF5qV29oCVZTklyTmBOWXFwOVGQP5RWBmdLVSGpgsA5muVKsDYRkp1caC2Ai5RLicIYZcMlzOGCQXWwsAg8Vx0bAAAAA=" } }, { "ID": "7026c07edca1695e", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0017?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:51 GMT" ], "Etag": [ "CpCiKYaxKmdPFI2QP3QIuA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42TYW/aMBCG/4v3FYgT1ACR+qGjtIrKWBvSqdNUIZMcwcOxU9vQIsR/3zkNRWq7jU+W7967e+6NsyMrLnMSkTkvntagt18smwsgLQKWFRgfVkN+85O93JT57VUc3N127+L1xfk5KrirM0slxLZksp1DqdoWjI1yZpkBOwuoP/Bp0J+F4YCGZwNKB108ZpRSv1PP+YfE7+EIA2Ix5nKFg5bWVibyvANop1CqEMAqbjqZKt/i3ibwKq1+Q2aN9wmd19AZ7xRMr8Y03km0tSiBBWiQGZBoRxqQ+C9OYU0DUStOATqMqQtOoNqjidkSSuZwFhxEbkj0a0ckK5Hw9cCW28rdpmkST66x5phfl8d0PElH16OE7B+xK2a+bnEJjFNSX8dKFino9+FEPR9umQZmuZIpr5v7Z70g6Pf6Dt75By8V1x8F/S7t4eooEMzYbyrnuEf+oUfXD4+oo4d0lEwuxnVXC1oycYnuDpVc8GL9OsQ5YtRaZ3CvuXOFFO6BffZm5k/12f6v4WEnMxvy2GoaXyldMut+o+kPt7/ZfK/caPP2NS5B8JIjIYpa7sWveDUGlnNZNMb5ZI92C5U10OR+SvZ/AF7QcQe4AwAA" } }, { "ID": "e97e3aa755c88575", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/shollyman-demo-test/o/bq-test-table_20191028_66906590093659_0016.csv?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Mon, 28 Oct 2019 18:36:52 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Uploadid": [ "AEnB2UqiWfcy5JSDn0peycZ-pq80XYA9xgPaFfnXMl9juv2sZEdN6UZwvV56nFdaqFnACUVRwWLOD8Ey7FwCkusdFZczRTtn_D8XRj6Km944atJ7yRzugJM" ] }, "Body": "" } }, { "ID": "6807fd7b35129d13", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0016?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:52 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6uuBQBDv6ajAgAAAA==" } }, { "ID": "19daa71025199c7f", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "366" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJleHBpcmF0aW9uVGltZSI6IjE1NzIyODgzMDcwMDAiLCJzY2hlbWEiOnsiZmllbGRzIjpbeyJuYW1lIjoibmFtZSIsInR5cGUiOiJTVFJJTkcifSx7Im1vZGUiOiJSRVBFQVRFRCIsIm5hbWUiOiJudW1zIiwidHlwZSI6IklOVEVHRVIifSx7ImZpZWxkcyI6W3sibmFtZSI6ImJvb2wiLCJ0eXBlIjoiQk9PTEVBTiJ9XSwibmFtZSI6InJlYyIsInR5cGUiOiJSRUNPUkQifV19LCJ0YWJsZVJlZmVyZW5jZSI6eyJkYXRhc2V0SWQiOiJkYXRhc2V0XzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDEiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0IiwidGFibGVJZCI6InRhYmxlXzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMTgifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:52 GMT" ], "Etag": [ "BNEF5WsGLdGY5cUQAQtE0A==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42S3U7CQBCF32W9VXZbBUoTL4quhKSC1BpjjCFLO5TVtlu76w8hvLvTCtaIGtKLzZw5Z+bLpCvyJPOYuGQmk+cXKJcHRsxSIIcEjEhQ74/4RftWD/x4cNeObibexHDmnZ6iQ1Y5vVBpusxEfhRDpo4MaOPGwggNZmozq2cx25l2Oj3WafcY6x3jM2WMWa16zz8Wy8EVGtK5L/MnXLQwptAupVvQVqJUkoIopG5FKvvS6atNi1I9QmQ0/YWObug03QeT1pia7kVbmwKYQwl5BMRdkQ3I8I9LYWYDUTv2AdquqQN7UK3xiNECMlHhzCWksSbu/YrkIkPCzwdHLouqug6D4WiAmab/kummPxyFfMADFDIVV0LAr7gX8vPvkRKiJhHws3FwjvXu6plSaWPsj8c+90Zk/YDfYbW3v8QTYYeRuvRVnoRQ/pQD9batohKEkSoPZT3fandt2+k6lm2fdKof+r2Q5a7BOWZdPCwaUqHNpYolosa7MxyrgQ29vs+rhIrqgSjdXJP1B/nb0HFNAwAA" } }, { "ID": "6d7c1016f011922d", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0018/insertAll?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "105" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJyb3dzIjpbeyJpbnNlcnRJZCI6IlBVUktIQThKWjh0bTVuSkQ1ZkpIVVhCZmhJcSIsImpzb24iOnsibmFtZSI6bnVsbCwibnVtcyI6W10sInJlYyI6eyJib29sIjpudWxsfX19XX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:52 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTMK04tKnHMyQlKLS7IB3KUagGmFzWCLgAAAA==" } }, { "ID": "e370c7a558c19ce2", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0018/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:52 GMT" ], "Etag": [ "OnHzgA3+l3ESC+Sx6N2oFA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8r753lUpTsaa+cYuwY7awdXmPkZ5bs52toCVZTklyTmBOWXFwOVGSjVAgCmwRjgUwAAAA==" } }, { "ID": "f383c4982718616e", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0018?alt=json\u0026fields=schema\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:52 GMT" ], "Etag": [ "BNEF5WsGLdGY5cUQAQtE0A==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWKk7OSM1NVLKqVkrLTM1JKVayiq5WykvMTVWyglA6SiWVBSBecEiQp5+7Uq0OQr40txgh7+kX4uruGgQUyM1PAQkEuQa4Ooa4uiBrKUpNRugIcnX2D3IB8jGtTsrPz0EodPL393F19FOqjQXCWgCN1fK3tQAAAA==" } }, { "ID": "365d79896ad9ed62", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0018/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:53 GMT" ], "Etag": [ "nCZ+muwhAbUbUWE2zKcV4A==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8rnOUdp55aWZzgmhSaFhrsaVXknh5k42toCVZTklyTmBOWXFwOVGQD5RWBmdLVSGpgsU7LKK83JqdUBM6NjoQx06dhaIIqtBQBvgOV7kQAAAA==" } }, { "ID": "b8656343ef3e6714", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0018?alt=json\u0026fields=schema\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:53 GMT" ], "Etag": [ "BNEF5WsGLdGY5cUQAQtE0A==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWKk7OSM1NVLKqVkrLTM1JKVayiq5WykvMTVWyglA6SiWVBSBecEiQp5+7Uq0OQr40txgh7+kX4uruGgQUyM1PAQkEuQa4Ooa4uiBrKUpNRugIcnX2D3IB8jGtTsrPz0EodPL393F19FOqjQXCWgCN1fK3tQAAAA==" } }, { "ID": "f456a1ff29c84278", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "306" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7ImRlZmF1bHREYXRhc2V0Ijp7ImRhdGFzZXRJZCI6ImRhdGFzZXRfMjAxOTEwMjhfNjY5MDY1OTAwOTM2NTlfMDAwMSIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QifSwicXVlcnkiOiJzZWxlY3QgbmFtZSBmcm9tIHRhYmxlXzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMTgiLCJ1c2VMZWdhY3lTcWwiOmZhbHNlfX0sImpvYlJlZmVyZW5jZSI6eyJqb2JJZCI6IkdUYmtiWGxjSjNZVXVMQ3gxZHk0Y0RCRlU0MCIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:54 GMT" ], "Etag": [ "+GAmcoPW3jua6evKKlP1VQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41TXU/bQBD8K+j62BKfv+1IqKWJQSlRBIkD5ck6n9fmwPYF35k2Qvz37jkBoZbSPtm+nZmd3Rs/kjvRFmRMclHd99BtP9zKnHwioFmFpx9Pjxsuz6/c254F8HB2Vp/blxdHR4gQhqVuZF1vG9YeFtDIQw1Kj9er0Wma3+Xfa/7NvV7388lPu9h6fPr1ZO1RZCqoy7lo75B/o/VGjS3rufuokrKqgW2EGnHZvJxbD4616eQtcK2sN5pa6FpZ77T9XEvOtJDt0XqFFnoFXQYNEzWaMAKHncyl/vKG9EiwZlQh/kFwYJzLvtXGG6pw2Zai6rtBmIwfyeD11YsZFS0ftKyBg7KTzYFmeQ2ZQ+3Ypk6UBUFMAz+mNHbxkVFqR6hbYFvRDqqpwRvF/fSzv2zdsJhmCnaILAdwwiAvYt+2PbsMAt+PmB16sRvzuPA9h7vgUJchb7A0sFgr26IoAXgMmVtGbubFYZzFfu5klPuhH0GIxIA84ewdMA1ToTZSid38ZLJMjtMkm51kiySZJlMU/9GJ31FXyxmC0uV6MUH0MG7J+lpPd/7NsK9H2b+/szNqo8i/9vNkIEKiHXMvs0WaLI8n6ewy2aVhDhXj29U95qFktQKEY6TS7QaXTy7WyfKa7I6WUEIHLf/PS0HGUH3/j3gOJwIxnthIafzGEHBl2gy7NmEQjbFj+6HjRGFkezQMyADu9B81h5oovSTSKEIDrd7PtErmySQlT/tmvXoBYRHvZjFbnGL1F4aeSQEgBAAA" } }, { "ID": "9b2d48dffcd0caa1", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/GTbkbXlcJ3YUuLCx1dy4cDBFU40?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:54 GMT" ], "Etag": [ "4ycYBFDlOo4/UbZf1jjWtw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y1P0U6DQBD8l/WVxjbyRNIHaW2tIVVpiVbjw3EsFHp3i9ySSgj/7oE+zU52dma2h0tpMgggLYvvFpvupkB+HYcYbavYOqjJWAQPkEXhlH4nT+FmrZ7Jv03Sj3xRVW98XS6dwsozagFBD3mJKrMQfPZghEZ3NoEH3NUjOxzj3X7ruKZs5Pskiu7D6AGGr8GDitIYc2zQSBzd6oYqlLwbi9ozKdVpYWYZapoxWobpYtpuj+klfVfy6e6UtNHqZ5F1vlyHm8SfO5UiKbgk44TJAVwQEwsV09U1hQX887Bzpi8NSbQWR9P5X8CKdK2QXSNuWvRACvfuY8kQ5EJZHH4BgoM0VEwBAAA=" } }, { "ID": "c43448bf0ff8e50e", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anonddfeec9e_3f83_4979_95b2_0c5758e72c36/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:55 GMT" ], "Etag": [ "JL8cJwenC9svu+inOTD5Kg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8p7+Vgke5Wn5jlbFpeVamfm+Ye4mHqn29oCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsU7LKK83JqY0FQgBW4/RhbwAAAA==" } }, { "ID": "bb3d39d5fa0cc00e", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0018?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:55 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6uuBQBDv6ajAgAAAA==" } }, { "ID": "74f0637283ab5fc1", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "217" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5Ijoic2VsZWN0IHdvcmQgZnJvbSBbYmlncXVlcnktcHVibGljLWRhdGE6c2FtcGxlcy5zaGFrZXNwZWFyZV0gbGltaXQgMSIsInVzZUxlZ2FjeVNxbCI6dHJ1ZX19LCJqb2JSZWZlcmVuY2UiOnsiam9iSWQiOiJndlBHYVA4cjJrVU52OUd3NllraE1IazN5M3MiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0In19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:55 GMT" ], "Etag": [ "X73OV5Tv0r9QFoPVRlG7+g==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41S72/aMBD9V1D2cYM0zg8IUrVVNGVIHWtD6FZNE7KdS3BJ4tR2QKjq/74ztNW0ddW+RI7v3b3n9+7B2Ygmd8YOE+V9B2r/7k4y54MDhpZ4+33of70Js+2Jiq8v5NVNWk2H78vTU0QI26XXsqr2NW36OdSyb0Cb8XIxKLdXU3o1UmSznG/j6S663ay/fN74e19jp4aquBTNBvvXxrR67LrP7INSyrIC2go94LJ+uXe3xG2VvANutPsKqYuqtfsG7cdKcmqEbE6XC5TQaVArqKmoUIQd0FeSSfPpldEDQetBifit4EA5l11jrDacwmVTiLJTh8HO+ME5aP3tYJ+Kkns7qfJeoWTd+/H8on7bsUrwfk4NHWtatxXogV7TDegWqIKfvUrUwvQ85MlRhmgOLBllFViGJzdm/0jBduFkDUfEigGQYcTyOPS8wCuiKAxH1BsGsR/zOA8Dwn0gJz7FPmMpDl20kY0XMMZOgggIhaDwaRgzQhiP8RMFPivIiOQ5cN95RD8UUAPnQrdSi6MnziRNzrJkNbtYzZPkPDlHgp0Sf6K+pTMEZelyPkE0YlolJMKsh7N5lqRnk2x2kxyTu4SS8v3iHrMzqgMkxvSzfYu+ONfLJL11jlcpFKCg4f/pF3Ycqm8v7/MeIRA3CYm0wX/Mh2tLc7DA5iRqK8cLh4SMhiMv9IlNEsHK/FULoghrL8tjJ0INjXl60yK5TCaZ8/hE1ukXEBbRsvlsPsXqLwpYrH3LAwAA" } }, { "ID": "52618b87671a91bb", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/gvPGaP8r2kUNv9Gw6YkhMHk3y3s?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:55 GMT" ], "Etag": [ "V4KEpQbJglN3jc319Ba0fg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2P3U7CQBBG32W8hQSsMULChRgCaG1KsSbGeLFsp7/bTt0daBrCuzsFr3ZP9sw3356hKpoE5nAost8j2v4uQ94Nlwjd0bCTo6XGIYwAWWVifj68rdrd4TUzgVdqbzpbqkmaLRZiOJ1jrWB+hrRAkziYf5+hUTXKWEc2EYX7dqD9R7QN1sI1JQMHse8/L/0VXH4uIyjpEGGKFhuNQ1prqUTN26Goy8mYvlbNOMGaxoyO4Tpxfc1O4VqFT/a+ioPTbN09flX5+6byes+JZUgrLqgRMd6DLGJiZSLqpClM4Z+XvYSGljQ6h0Po5LbgherWIEsjtkccgVby3U3BN778AdROBytLAQAA" } }, { "ID": "f2e93786cf940883", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "218" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5Ijoic2VsZWN0IHdvcmQgZnJvbSBbYmlncXVlcnktcHVibGljLWRhdGE6c2FtcGxlcy5zaGFrZXNwZWFyZV0gbGltaXQgMSIsInVzZUxlZ2FjeVNxbCI6ZmFsc2V9fSwiam9iUmVmZXJlbmNlIjp7ImpvYklkIjoiandjbWN3VU9RZGYzampJZ2F3ZllhNndReUtwIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:56 GMT" ], "Etag": [ "HOI3lzRokig7ymOOsO8yfQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/91S607bMBR+Fcv7SxNaNCiRqm3aKq0aouptEirVOHVOUre+BNuhZIh333EKu2iMB5iUH/E53/kux37gO2lynvG1LG9rdM2brV3zI44BSqp+Ho9O1Pep3cnyrNHjsR/3m2IyGBBCxim/sUo1GkwnR207AX3IFrNkuxda7BfjSV6cbLejEvbFFZzuJ82XiiY9quJCmh3Nb0KofJamz+pJaW2pECrpE2H1z3p610srZ7cogk9fEE3JtU9fkX2nrIAgrRksZmSh9ui+oQapyEQk6Di7tuH9C9SJBJ2UhL+TAkEIW5sQvRGLsKaQZe1aYp498Nbrbz8xKllme+tyVjir2fI5Uaeq10qKTg4BMg+6UugTv4Ed+grB4YopqWVgXdKpnLROhkg4upwPpx8+zkdfh4cYF1iCaGa3FKQA5fHxiNMu5k2FhJ4shtMrfihNsUCHRmD097TL0T/ukLcTbff1q3zeKgFpryTkA519kMJHGeGwbc+ljna6b896vf5Zv3t6fHzOW7ALf/d6p/EBmvzFzpNG3fKjc9ZN0dcqxCOp+daLNHegZD5pb+EPl7dPJY3eQxnpZ40JcM9aqowtDN5XtBnM2TVfXnMGgS27Wbe/StioYGEjPaMPWIC1QiZzNEEWEt0RQy+gQoIgM6CR7WXYsBuqJ2XCblp8Ehs3jB7MBh0hwbDlr8YqielaI5Ru+V/kWR2uKxr7NL4c8sfHHz+eSg9yBAAA" } }, { "ID": "b7d9391f6792a10f", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/jwcmcwUOQdf3jjIgawfYa6wQyKp?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:56 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/9WQwWrDMBBE7/6KRecgEuih+BZoKYY20DbpxTH1xt44AllypU0bE/zvlRVDc+gPBARiZp7Q7J4TAEHOWSdSOAcRZGVrCupuPp9djJa8x2b0xHtvGE8QX6SwMXTqqGKqYSvyrQBkyBfp4r6QkO2BD8pDOAiMO02gajKs9orcDMhX2FFACAy2BD+KD1AGXzYSysjLMSjBYYBcINFA/hcUUkz1Yhkf2uVRwzTHDVSPFWvbojJjw0bbHerrzBF6GzNlvlGr+vVIrr8mtK2Q1YX5+i9Y910cv0MXvmZyYmKGeBfTEj0jH8climz1sXzOHj6Xb0+bl8fVeuSHZEh+AVVsNvkrAgAA" } }, { "ID": "217f01f654f99eb5", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "218" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5Ijoic2VsZWN0IHdvcmQgZnJvbSBbYmlncXVlcnktcHVibGljLWRhdGE6c2FtcGxlcy5zaGFrZXNwZWFyZV0gbGltaXQgMSIsInVzZUxlZ2FjeVNxbCI6ZmFsc2V9fSwiam9iUmVmZXJlbmNlIjp7ImpvYklkIjoiQXVqOFdTYklGZzhzT2FXMXRLSE12aHBhdUpQIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:56 GMT" ], "Etag": [ "GuDFYbMm+EaIyFjg7wr/WQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/91S607bMBR+Fcv7OZqolUa7SGhDo2zduKy3IVSqceKcJC6OndpOoUK8+44D3UVjPMCk/IjP+c53OfY9v5E64wlPZbFu0G5frUzK9zh6KKj6sTk6vkxPq9dDGG2PV0X/1sYX44MDQsgw5Uqj1LYC3cmwMh2PzifzaXTYrAYX03R0XAzcOVx0/ZdPp5uyhubzV5p0qPITqW9ovvS+dkkc79SjwphCIdTSRcJUP+vxphfX1qxQeBc/IxqTaxe/IPtOGQFeGn0wn5KFxqH9jhVIRSYCQcea1Pj3z1BHEqqoIPxGCgQhTKN98EYswuhcFo1tiXlyz1uvv/2EqGSZ3Rqbsdyaii12iTp1kyopOhl4SBxUtUIXuRJu0NUIFpdMyUp61iWd2kpjpQ+Eo7PZcHL4YTb6NnyMcYIFiO10TUFyUA4f9jjtYratkdDj+XByyR9LE8zRohYY/D3tcvSPO+TtRNt9+Sp3WyUg7ZWEnKez81K4ICMstu2ZrIKd7pt+rzfoD7r7vf193oKt/7vXfxseoM6e7TxpNC0/WmvsBF2jfDiSmmu9SL0BJbNxewt/uFw/lSp0DopAP91qD3espUrYXONdTZvBjF3xxRVn4Nmim3QHy4iNcuZL6Rh9wDykCpnMUHuZS7R7DJ2AGgmCTEOF7Fb6kl1TPSoidt3io9C4ZvRgSrSEBM0WvxrLKKRrjVC6xX+RZ/l4XcHY0fnZkD88/ACS32T0cgQAAA==" } }, { "ID": "0d4f35a94931296e", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/Auj8WSbIFg8sOaW1tKHMvhpauJP?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:56 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/9WQwWrDMBBE7/6KRecgEuih+BZoKYY20DbpxTH1xt44AllypU0bE/zvlRVDc+gPBARiZp7Q7J4TAEHOWSdSOAcRZGVrCupuPp9djJa8x2b0xHtvGE8QX6SwMXTqqGKqYSvyrQBkyBfp4r6QkO2BD8pDOAiMO02gajKs9orcDMhX2FFACAy2BD+KD1AGXzYSysjLMSjBYYBcINFA/hcUUkz1Yhkf2uVRwzTHDVSPFWvbojJjw0bbHerrzBF6GzNlvlGr+vVIrr8mtK2Q1YX5+i9Y910cv0MXvmZyYmKGeBfTEj0jH8climz1sXzOHj6Xb0+bl8fVeuSHZEh+AVVsNvkrAgAA" } }, { "ID": "05d1a03037919769", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "217" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5Ijoic2VsZWN0IHdvcmQgZnJvbSBgYmlncXVlcnktcHVibGljLWRhdGEuc2FtcGxlcy5zaGFrZXNwZWFyZWAgbGltaXQgMSIsInVzZUxlZ2FjeVNxbCI6dHJ1ZX19LCJqb2JSZWZlcmVuY2UiOnsiam9iSWQiOiJBeFJaeG1EU2pHcjhhazk2dzNqUTgwQWpYc04iLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0In19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:56 GMT" ], "Etag": [ "q+pKf6Cx7KHbgpJ/XzZNKg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/+1Sa28SQRT9K5v1i8bubkELlIQoaYkiBMPL1NbGzs5eloF5LDOzFGz4795ZWNNGbPS732bu45xzz70P/pLJxG/6MUtXOejti4WK/RMfLEkxunqd9Wa1i0299zFOs0/R1Y/rQS9ttbCCuS4zV5xvBZFBAkIFFoxtTsdhezO63ojL8eKDbpDlee3+zWLYOG0vrswAOw3wWZ/JJfbPrc1MM4pK9jBVKuVAMmZCqsSveLSuRplWC6DWREdII1Rtomdo33FFiWVKtqZjlJAb0N9BEMZRhAMItIqVfX8EOmREhCnWrxkFQqnKpXXaEIUqOWNprgtgv/ngF1ofPdyoKNm7VzrxZloJ766cKMjymDMaJMSS0BCRcTChmZMlmAyIhjuPM8GsV0GeTDOlmXWA3cGkM2pfTLpfOvsx+pASuh2vcBCrc9id+GjFZJsBFg+nndFXfx8awQw0SApO3sHK7h9W6BcdRfb5TZamYiHaikTG4t9YRo2joRqK9IQJJ6dyVq9WG/VGpfb2/NQvirX9LXdWcTmQydHMgSMv8EFrpUdgcm7dF9lMoYXJNeF4n08E/r3z2CfAGJI6+u4ey7Mk5uBJIqD5D0v8Jm8meuvlhsnUQ+EyIXgJ42Hfe1mePuUqTw53//TmE0VNpMu9RWV7YFY8Aol6EDR4HH11GzqDClvQoJv/luwtud0fjdN++XnQ8Xe7nxVTqh/3BAAA" } }, { "ID": "a5019c8a6c744397", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/AxRZxmDSjGr8ak96w3jQ80AjXsN?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:56 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/92QQUsDMRCF7/srwp4U3KQHT3srKFKoBbV6qcXOJmMazCbbTFYoZf+72XQL/Q2ehvde5pFvTgVjJYbgQ1mzUxJJSq8wqfvZ7O5stEgEevTKhfsFaxSL0FhkDlqs2a4x+tBjOFZd31gjKwUROEHbWSROe/hB6hAC7j7dZh2OrCfjNKMITkFQ7O1lyW72MXZUCyGt7xXX3muLXPpWXMqF8pJEwG8M6CSKy3pFByvQpf+k0uravd3yciLIhJQANlmzCfV/0GUK5VswboTQ1jdgr7OAQD5n5gxYTtmQ53Y6UmqPPeU7rD7my8XD1/z16f35cbUe3w/FUPwBjqyvuS4CAAA=" } }, { "ID": "c88f844ac82188ae", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "218" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5Ijoic2VsZWN0IHdvcmQgZnJvbSBgYmlncXVlcnktcHVibGljLWRhdGEuc2FtcGxlcy5zaGFrZXNwZWFyZWAgbGltaXQgMSIsInVzZUxlZ2FjeVNxbCI6ZmFsc2V9fSwiam9iUmVmZXJlbmNlIjp7ImpvYklkIjoib1N0aGp4UU10cFlSb0xRVWxGWDN1a1ZoY2Q0IiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:57 GMT" ], "Etag": [ "Bk69o6oiPAZo3pY3wYd0pg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41SXW/aQBD8K+j6Wmz8DUhRmxKnQqKoGJOWvpDzeW0ObJ9zdw5FUf5714agqk2jvtm3Mzuzs/tE9rxKyZgkPH9oQB7f7URC3hPQNMfXT3t/JHzBv17/EE69dg7rdFDnV1eI4C1LbUVRHEta9VMoRV+D0uPV0hBLvd39XHzR9ToSs8WquP3uNPu7LUtdZCooshmv9sjfal2rsWm+qBu5EHkBtObKYKK8vJuPtllLsQOmlfmKqImulfmG7IdCMKq5qK5WS7TQKJAbKCkv0ETboC9FIvTHV1obnJZGjvhHzoAyJppKt96wCxNVxvNGdo3J+Il0Xn/7aEdFy72DkGkvk6Ls3b9M1K+bpOCsn1JNDUXLugBlqC3dg6qBSrjvFbzkumehToo2eNWpxDQpoFU4pzH9xxZaFnZWcEJsEgA78JN05FmWa2W+73lDagXuyBmxUeq5NnPAHjgUebqV6Fi0EtUA/MQeuH4aZK7jZXYyAieA1AInGVgD2w6cYeC6QUaeMQ8JVMMNV7VQ/JQJmUThdRxuprebeRjehDcocJD8T9S3aIqgOFrNJ4hGTC25QFib4XQeh9H1JJ7ehafNzSCn7Lh8wN1ltFCAyrj++FhjMGSxCqM1OT1FkIGEiv1nYMjoqm9f78shIRBPCYWUxn9cEFOtTJdBuyhetnYsL7DtYTC0/MDySQeW+q/a0PKwdrmetiOUUOnzTMtwFk5i8nwWa9QFhEXMbD6df8bqL+hoVmfMAwAA" } }, { "ID": "6a0a5ced86b911e8", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/oSthjxQMtpYRoLQUlFX3ukVhcd4?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:57 GMT" ], "Etag": [ "7ydy5G4pgswmGn4VZcQr4A==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2PXU8CMRBF/8v4ConGNSYkPIDRlWQl7iLEj/hQ2mE/aDtrOxvcEP67s+BTe9Izd26PsK+9gQls6/Knw9Bflcj5cCkwdpajHC35iDACZFWKed+b/i5N2jIeXOqTzafOQzKbTsWIukKnYHKEXY3WRJh8HcErhzJ2oGBE4b4daPVWLJapsCMz8HKdZbN59gin79MIGtoWuMOAXuOQ1gZqUPNiKBorsrZ3yo8NOhozRobzxPmVVlw1v/kLtx8FZfnaPr3fdvtNpU0iliWtuCYv4noFsoiJlS3oIE3hBv553kvoayCNMeIQen1Z8ECutcjSiEOHI9BKvvtc84VPf3onWkxLAQAA" } }, { "ID": "d5f7cb5b525894ab", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "218" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5Ijoic2VsZWN0IHdvcmQgZnJvbSBgYmlncXVlcnktcHVibGljLWRhdGEuc2FtcGxlcy5zaGFrZXNwZWFyZWAgbGltaXQgMSIsInVzZUxlZ2FjeVNxbCI6ZmFsc2V9fSwiam9iUmVmZXJlbmNlIjp7ImpvYklkIjoiTnRObHdjNnUzQWhvUTdIeGgwWjJEcE0xU2t4IiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:57 GMT" ], "Etag": [ "IUHNop7Qw2WQ5e4CIrS8Iw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41SXW/aQBD8K+j6Wmz8DUioReA2llJLgGnUvpDzeW0u2D7n7hyCovz3rg2JqjaN+mbfzuzMzu4TOfA6I1OS8uK+BXn6cCdS8pGApgW+RturWDTB6mjfrDxwF5HcjKPjbIYI3rHUXpTlqaL1MINKDDUoPd1ujFjH5ZH5rTPfi1Vw9bgf/bSXzTdrc3hEpoIyv+b1Afl7rRs1Nc0XdaMQoiiBNlwZTFSv7+aDbTZS3AHTynxD1ETXynxH9lMpGNVc1LPtBi20CuQOKspLNNE1GEqRCv35jdYGp5VRIP6BM6CMibbWnTfswkSd86KVfWMyfSK9198+ulHR8uAoZDbIpagGty8TDZs2LTkbZlRTQ9GqKUEZak8PoBqgEm4HJa+4Hliok6ENXvcqCU1L6BQuaUT/2ELHws4KzohdCmAHfppNPMtyrdz3PW9MrcCdOBM2yTzXZg7YI4ciT3cSPYvWoh6Bn9oj18+C3HW83E4n4ASQWeCkI2tk24EzDlw3yMkz5iGBalhy1QjFz5mQxTqcJ+Eu+rKLw3AZLlHgKPmfqJt1hKBkvY0XiEZMI7lAWJdhFCfher5Iou/heXPXUFB22tzj7nJaKkBlXH9yajAYstqG6x/k/LSGHCTU7D8DQ0Zfff96Xw4JgXhKKKQ0/uOCmOpk+gy6RfGqs2N5gW2Pg7EVOMGY9GCp/6p5Ex9rr9fTdYQKan2ZaRNeh4uEPF/EWvUKwiJmFkfxV6z+AtKVAE3MAwAA" } }, { "ID": "8a1dffe8652e2abe", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/NtNlwc6u3AhoQ7Hxh0Z2DpM1Skx?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:58 GMT" ], "Etag": [ "J7IuKE5wg9PbtrdujlXuDQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2P0U7CQBBF/2V8hQQ0SmzCAwgRtDZQJDEaH5bt0Ba2nbo7m9I0/DtT8Gn3ZM/cudvCMS8TCGCXp38ebXOXIq+7S4zOG3ZyVFQ6hB4gq1TMt9HSv88f6/R5tWOb+IP58rP1eCyG0xkWCoIW9jmaxEHw00KpCpSxmmwiCjdVR5vPeBm9CheUdBxtw3AyDedw/j334EC7GPdosdTYpVWWDqh52RV1GRnTFKrsJ1hQn9ExXCeurxFHptZP/mGS0Xq0OGWD7/tZ9THcHE9iGdKKcypF3G5AFjGxMjHV0hSG8M/TRkJXljQ6h13o4LbghYrKIEsjth57oJV8d5Hzjc8X4VUu4UsBAAA=" } }, { "ID": "9d0b2861bc3d934f", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "366" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJleHBpcmF0aW9uVGltZSI6IjE1NzIyODgzMDcwMDAiLCJzY2hlbWEiOnsiZmllbGRzIjpbeyJuYW1lIjoibmFtZSIsInR5cGUiOiJTVFJJTkcifSx7Im1vZGUiOiJSRVBFQVRFRCIsIm5hbWUiOiJudW1zIiwidHlwZSI6IklOVEVHRVIifSx7ImZpZWxkcyI6W3sibmFtZSI6ImJvb2wiLCJ0eXBlIjoiQk9PTEVBTiJ9XSwibmFtZSI6InJlYyIsInR5cGUiOiJSRUNPUkQifV19LCJ0YWJsZVJlZmVyZW5jZSI6eyJkYXRhc2V0SWQiOiJkYXRhc2V0XzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDEiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0IiwidGFibGVJZCI6InRhYmxlXzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMTkifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:58 GMT" ], "Etag": [ "pxZTK0i42E7Y/YDIRyKAYg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42SW4/aMBCF/4v7CtgJl1ykfYBirRAUqmz2gVYrZJIhuJvEaWxaIsR/30kKTVW2FcqDNWfOmfk0yom8yjwmPtnK5PsByuqDEdsUSIeAEQnqxfFLOGdyYHNnTdfTWVDNx+vk4QEdss7pvUrTKhN5N4ZMdQ1o48fCCA1mYzPLs5jtbkYjj42GHmNeH58NY8zqNXv+Y7E8XKEh3S1k/oqL9sYU2qf0CtpLlEpSEIXUvUhlv3X6w6ZFqb5BZDR9h45e6DS9B5M2mJreRduYAthBCXkExD+RC8jsH5fCzAWicdwDdF3TBO6gOuMRoz1kosbZSUhjTfyvJ5KLDAl/PTiyKurqKQxmy0fMtP1Dptv+bBnyRx6gkKm4FgL+mY9DPv0zUkLUJgL+cRVMsb5dvVUqbY2T1WrBx0tyfsGvU++dVHgi7DDSlAuVJyGUf8uB+nmtohKEkSoPZTPfGjq27Tqu5VrOoP6hj4Usbw1unzl4WDSkQptPKpaIGt/MsK1+CxuOJwteJ1TUDETp+Ymc3wCZcxW1TQMAAA==" } }, { "ID": "9d43a1b74286b21f", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "226" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJ0YWJsZVJlZmVyZW5jZSI6eyJkYXRhc2V0SWQiOiJkYXRhc2V0XzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDEiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0IiwidGFibGVJZCI6InRfdmlld18wIn0sInZpZXciOnsicXVlcnkiOiJTRUxFQ1Qgd29yZCBmcm9tIFtiaWdxdWVyeS1wdWJsaWMtZGF0YTpzYW1wbGVzLnNoYWtlc3BlYXJlXSIsInVzZUxlZ2FjeVNxbCI6dHJ1ZX19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:58 GMT" ], "Etag": [ "+qYcgJVq8LWs7UopTGBiDA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42RUWvbMBSF/0rQHrfEstMktqEP62pKhjeo47SUUowi3zhqZMux5AYT8t93ZZKutBv0SZyre+/5jnQgW1HlJCQrUexaaLovhq0kkG8EDCuw/nX3wIufdzs/vtezparTmytx/f3yEjuEndMbJWVXsmqYQ6mGBrQJc2aYBpN51A1c6vnZdBrQ6SSgNBjjkVFK3ZHJXgTsM4qLNMh1LKotrtsYU+vQcc44o0KpQgKrhR5xVb7WnRfPqRv1DNxo5x8MzolBO5+BcfrQ2nnD1FcSWEMDFQcSHsjJbv6f1Dhzsuo7PmN7tukHXr2P+CB8AyWzpmsBMtckfDyQipXIQfaqye1gV1u1SJP57xvUpcqtTqLb5TyJrsnxCfdUbXnVIRxe2EwoY1UVKTTvy4nanxVvgBmhqlT0du5k5nn+zHf98WSM15Jp80vlAsHyDy0Xs+Av2t08ukdlU9kk/bdZ4iiOfqQDG2OwblQ5eDz/6bBuV1LwoX26ULOyxi8Z6Q3bgq6BNfCE21oNMRSMd4udJKFpWsCYUvEeGbcvF+T4ByKRxMzUAgAA" } }, { "ID": "436b8a54244551c3", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/t_view_0?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:58 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6uuBQBDv6ajAgAAAA==" } }, { "ID": "e67506591a5733d1", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "227" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJ0YWJsZVJlZmVyZW5jZSI6eyJkYXRhc2V0SWQiOiJkYXRhc2V0XzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDEiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0IiwidGFibGVJZCI6InRfdmlld18xIn0sInZpZXciOnsicXVlcnkiOiJTRUxFQ1Qgd29yZCBmcm9tIFtiaWdxdWVyeS1wdWJsaWMtZGF0YTpzYW1wbGVzLnNoYWtlc3BlYXJlXSIsInVzZUxlZ2FjeVNxbCI6ZmFsc2V9fQo=" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:58 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/9WQwWrDMBBE7/6KRecgEuih+BZoKYY20DbpxTH1xt44AllypU0bE/zvlRVDc+gPBARiZp7Q7J4TAEHOWSdSOAcRZGVrCupuPp9djJa8x2b0xHtvGE8QX6SwMXTqqGKqYSvyrQBkyBfp4r6QkO2BD8pDOAiMO02gajKs9orcDMhX2FFACAy2BD+KD1AGXzYSysjLMSjBYYBcINFA/hcUUkz1Yhkf2uVRwzTHDVSPFWvbojJjw0bbHerrzBF6GzNlvlGr+vVIrr8mtK2Q1YX5+i9Y910cv0MXvmZyYmKGeBfTEj0jH8climz1sXzOHj6Xb0+bl8fVeuSHZEh+AVVsNvkrAgAA" } }, { "ID": "4d42ed2d58302eac", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/t_view_1?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 404, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:58 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/72PwW7CQAxE7/mK1Z6hclIaNTkjjsmFniq0Ml0XkDaxFDtFCOXf2Wxz4As4jWbG0jzfM2MsDQMPtjb3aKL9YU/RbWCz+g86EsHTnNmG1fzy2Pva7PEYyMiZQ7h12K89dbxWEq09KgqpKyCvcig+XVlWUH5UANV7FAcA+Zu6vwtdXW6XkQQhceM7ebPQvAwgDXnu8NLPO6fARwzP3UAonLqedTcj2KWckh6WR0RRR0ms7d7t2q9mOx9O2ZQ9ADSd8r1uAQAA" } }, { "ID": "6f03df53ad536142", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "227" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJ0YWJsZVJlZmVyZW5jZSI6eyJkYXRhc2V0SWQiOiJkYXRhc2V0XzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDEiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0IiwidGFibGVJZCI6InRfdmlld18yIn0sInZpZXciOnsicXVlcnkiOiJTRUxFQ1Qgd29yZCBmcm9tIFtiaWdxdWVyeS1wdWJsaWMtZGF0YTpzYW1wbGVzLnNoYWtlc3BlYXJlXSIsInVzZUxlZ2FjeVNxbCI6ZmFsc2V9fQo=" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:59 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/9WQwWrDMBBE7/6KRecgEuih+BZoKYY20DbpxTH1xt44AllypU0bE/zvlRVDc+gPBARiZp7Q7J4TAEHOWSdSOAcRZGVrCupuPp9djJa8x2b0xHtvGE8QX6SwMXTqqGKqYSvyrQBkyBfp4r6QkO2BD8pDOAiMO02gajKs9orcDMhX2FFACAy2BD+KD1AGXzYSysjLMSjBYYBcINFA/hcUUkz1Yhkf2uVRwzTHDVSPFWvbojJjw0bbHerrzBF6GzNlvlGr+vVIrr8mtK2Q1YX5+i9Y910cv0MXvmZyYmKGeBfTEj0jH8climz1sXzOHj6Xb0+bl8fVeuSHZEh+AVVsNvkrAgAA" } }, { "ID": "c1d50d0d7bfeccf9", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/t_view_2?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 404, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:59 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/72PzYrCQBCE73mKYc66dKIbTM7iUS96EhnanfYHJmlIt4pI3t3JbA4+gaeiqhrq61dmjKWu487W5hVNtH/sKbo5zCf/QUMieB4yu2Y1J761vjZbPAYycuEQng22U08NT5VEa4+KQuoKyKscioUrywrK3wqgmkVxAJD/qLtf6eEKO44kCIkb++TNSPM1gDTkucFrO+ycAx8xfHYdoXDqWtbVgGDHsk96GB8RRb1JYt1s3WqzWy+Hwz7rszcBPx/MbgEAAA==" } }, { "ID": "99480a915206a471", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/t_view_3?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 404, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:59 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/72PwYrCQBBE7/mKYc4qnahhk7N4jBf3tCxD6/RGYZKGdKuI5N93MuawX7Cnoqoa6vUrM8bSMPBga/OKJtoze4puA5vFO+hIBNspsw2r+eFb72tzxFMgIxcO4dlhv/TU8VJJtPaoKKSugLzKofhwZVlBua0AqnUUBwD5St39Sg+3tvNIgpC48ZW8mWn+DSANee7w2k87beAThr/dQCicup51PyHYuRyTfs+PiKLeJLEejm5/+Gx20+GYjdkvLaOUVW4BAAA=" } }, { "ID": "6eadd20692bbf5fe", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "226" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJ0YWJsZVJlZmVyZW5jZSI6eyJkYXRhc2V0SWQiOiJkYXRhc2V0XzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDEiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0IiwidGFibGVJZCI6InRfdmlld180In0sInZpZXciOnsicXVlcnkiOiJTRUxFQ1Qgd29yZCBmcm9tIGBiaWdxdWVyeS1wdWJsaWMtZGF0YS5zYW1wbGVzLnNoYWtlc3BlYXJlYCIsInVzZUxlZ2FjeVNxbCI6dHJ1ZX19Cg==" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:59 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/92QQUsDMRCF7/srwp4U3KQHT3srKFKoBbV6qcXOJmMazCbbTFYoZf+72XQL/Q2ehvde5pFvTgVjJYbgQ1mzUxJJSq8wqfvZ7O5stEgEevTKhfsFaxSL0FhkDlqs2a4x+tBjOFZd31gjKwUROEHbWSROe/hB6hAC7j7dZh2OrCfjNKMITkFQ7O1lyW72MXZUCyGt7xXX3muLXPpWXMqF8pJEwG8M6CSKy3pFByvQpf+k0uravd3yciLIhJQANlmzCfV/0GUK5VswboTQ1jdgr7OAQD5n5gxYTtmQ53Y6UmqPPeU7rD7my8XD1/z16f35cbUe3w/FUPwBjqyvuS4CAAA=" } }, { "ID": "bd3421b0c3910834", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/t_view_4?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 404, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:59 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/72PzYrCQBCE73mKYc66dDQbTM7iUS96EhnanfYHJmlIt4pI3t3JbA4+gaeiqhrq61dmjKWu487W5hVNtH/sKboCisl/0JAInofMrlnNiW+tr80Wj4GMXDiEZ4Pt1FPDUyXR2qOikLoZ5FUOs4UrywrK3wqgmkdxAJD/qLtf6eEKO44kCIkb++TNSPM1gDTkucFrO+ycAx8xfHYdoXDqWtbVgGDHsk96GB8RRb1JYt1s3WqzWy+Hwz7rszdre8QvbgEAAA==" } }, { "ID": "67649221d810896a", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "227" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJ0YWJsZVJlZmVyZW5jZSI6eyJkYXRhc2V0SWQiOiJkYXRhc2V0XzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDEiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0IiwidGFibGVJZCI6InRfdmlld181In0sInZpZXciOnsicXVlcnkiOiJTRUxFQ1Qgd29yZCBmcm9tIGBiaWdxdWVyeS1wdWJsaWMtZGF0YS5zYW1wbGVzLnNoYWtlc3BlYXJlYCIsInVzZUxlZ2FjeVNxbCI6ZmFsc2V9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:59 GMT" ], "Etag": [ "AayGkjmb0HWH04d30mJUJA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42RW0/jMBCF/0rlfd3GTqCXROKhrCooyvLQCzysVsGNJ6mpHYfYpYqq/nfGUcuudkHiKTqTmTnfGR/IVlaCJGQty5cdNO03x9cKyHcCjpdYn/D2Zvus1+z28ZZdigum71Z3k6sr7JB+zm6MUq3mVV+ANn0H1iWCO27BZREL45BF42w4jNlwEDMWX+AnY4yFgcteJeyzAS6yoIpUVltct3GutgmlZ5ygNKZUwGtpg9zo9zp9jWjdmGfInaUfMNATg6VfgaFdaEv/YuoqcyiggSoHkhzIyW72SWqcOVl1HV+xPdt0A+/eRzxIvgHNvWkhQQlLkl8HUnGNHGRvGuEH29qrxXI+u79BrY3w+n6VppPrdEqOv3FPtdPXLcLhD0Y6mZqqXELzb3lu9meVN8CdNNVSdnbhYBRF49E4jIehv4vi1v00QiKY+K9lFF7+QXuYTR9R+VQ+SfdsnniaTn8sez5Gr2iM7j2d37Rf79ZK5n1/usByXeOTBHbDt2Br4A084badhRRKnreLF0WSgisLmFOZvGPG9asFOb4Bhlx+/NUCAAA=" } }, { "ID": "42ab895aa873c3e5", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/t_view_5?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:36:59 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6uuBQBDv6ajAgAAAA==" } }, { "ID": "9fa5bd2794888bb6", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "227" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJ0YWJsZVJlZmVyZW5jZSI6eyJkYXRhc2V0SWQiOiJkYXRhc2V0XzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDEiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0IiwidGFibGVJZCI6InRfdmlld182In0sInZpZXciOnsicXVlcnkiOiJTRUxFQ1Qgd29yZCBmcm9tIGBiaWdxdWVyeS1wdWJsaWMtZGF0YS5zYW1wbGVzLnNoYWtlc3BlYXJlYCIsInVzZUxlZ2FjeVNxbCI6ZmFsc2V9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:00 GMT" ], "Etag": [ "Yjxnnay3Cv7KElkpCkyZfw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42RX2/aMBTFvwryXkfshPEnkfrQoqhCy/oAdNNWTalJboIbx05jA40Q333XEXRVtUl9ss71vff8jn0klVA5ichGlM87aLtPlm8kkM8ELC+x/vPpRSnejeb76ddYVs286n4Vh6sr7BBuzmy1lF3N1TCHWg8tGBvl3HIDNg2YH/osmKWTScgm45CxcIRHyhjzPZvuBRzSCS4yIItEqArXba1tTETpBccrtS4l8EYYL9P1a53uA9q0+gkya+g/GOiZwdCPwNA+tKFvmPrKEgpoQWVAoiM52y3+kxpnzlZ9x0dsLzb9wKv3CR8k20LNnWkhQOaGRA9HoniNHOSg29wNdo1Tq/VycXeLuta503f3SXJ9k8Tk9Bv3qF190yEcXjDSy0Srcg3t+/JSHy4qa4FbodVa9Hb+eBoEs+nMD8PZF7yW3NhvOhcIlr9rCVgwGv9F+76If6ByqVyS/tsccZzE8/XAxRgUra4Hj5c/HTa7jRTZ0D2dZ3jd4Jd4ZssrMA3wFh5x285AAiXPutWzJFHBpQHMKXXWM+P6+xU5/QETr3kl1QIAAA==" } }, { "ID": "1b0f287462dd84a6", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/t_view_6?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:00 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6uuBQBDv6ajAgAAAA==" } }, { "ID": "dfce3a3b888918af", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/t_view_7?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 404, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:00 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/72PvY7CQAyE+zzFams4OcAFkhpRhoarEFoZ1vxIm1iKHU4nlHe/zV6KewKq0cxYms+vzBhLXcedrcwrmmgv7Cm6Faxmf0FDIngbM1uzmiv3ra/MAc+BjNw5hJ8G27mnhudKopVHRSF1C8jLHBYbVxQlFJ8lQLmM4gAg/1D3fNC3W9tpJEFI3DgmbyaatwGkIc8NPtpx5xb4jOF/1xEKp65l3Y0IdiqHpKfpEVHUXhLr/uB2+696Ox4O2ZD9Al7ZKV5uAQAA" } }, { "ID": "daac2b78d5b82095", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0019?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:00 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6uuBQBDv6ajAgAAAA==" } }, { "ID": "e620ab3008a70dfd", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?allUsers=false\u0026alt=json\u0026pageToken=\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:01 GMT" ], "Etag": [ "UDEdqWFU40uhL7e9V31qtQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/+19CVPjSJr2X3GwE1FV+1F03gcTE7sGDJgbH1zVFe5UKoUFvvABmI76719KsgHbkoBue2zPAhWFrTzevJ73zEz9uWK66nplfaW8lXPvzrfLBPSqB9zIMwzvuqf/+tfK6sqt33BtDse/vuuZdv+/bprOgd/p2pSGeeyeqGtTat6ahs0CKUdIcM4xB+y72b7a4pcE75/19gtPzeyxn7/K750Dra9sWVtLZ2X9x58rflB5p9qs1fp11fjumnrze9d0uuvl4tpR96j2oFkPZ6vNU777WAVXaKt1CIu3j/ENiyouGM+0TUOblfU/V1rt5o3R3XwCmahEmJpOrdbUqus3g36Wiyu/Vlc6XdW1FFa2jo9yK9FXOyy+7gRUdduEuUt+3byMjIB2aESUud2dSKOS2TTTcCdSGOI2pdvsqtpG3zb7pN3UptMxQbOBTQkHIKCbnOUlZcOv1Z4fa6WrZtfvrqx32z0z6FXdNLqlfitoQzF3kNssrfyyHdbNhudf99qDYfjzhergw0rH1OxQZx6abTfjtZv1zB/Dyfne6jk1X393VVetdVS9VTOdtU5V3ZpOy6i2+SNT8+t+NwNtk1w7LX4jGj7l1N45i0HNHRPlqDjGIM4cV1IICfQYo1QoyInEUkuXEqSxQQCrYFwCEmEp1Wg2gGEOAoS53COYesiRBnPjQoMdAAFCHAtOCPeCBRDOsdnyO61mxx8sjc1CLlvKVfLblaNcbiu3ZQk8tP3xXOeFvM1UKpSPNm1um6fV9ps2WzCG+aNSrpDdLOXPgoRexxyYa6X7xbvayrqnah3zK1yxg+k5LecKl8PV2AuX3si6/BVW0a6YuvJtBSvBYH1vN51m939jhnHNV/W1a5v/3tdGad3sNbprulm31aQDtVnsVm8eTw+7rctC8+C0XNu+wL3bs6p2yQyAmk5tOkBlHLIkoDIBaTxQmcDsE6ifQF1YoGYfC1eP9a3izU5bqFvJHvDNqQDZm4vO0QyAmk7tLaCadrvZLphOr9YNyNpJ7ISZ/ca9qtlOjtTw/gVsy9Ut3qzeEkxiVFcmXFyZhqqb9Q9g4ffGj1K7n+l1/MZ1xra+4SoLqOLpQeZrtdttddZ/+03Xmj137brZvK6ZYIZ+G1b+m9vUnd/aw4H9bVj8e+eu9ptp2PbYSr+/fvrt59pwlN7Bv4gEifyLQpDAv4KUfyMHeSecAo73Fpo+V0vsagmHJdK0P4ckGJKfq/NhvL0bcV508tvXonOszmF3f/fwvtpSvb2TWTDeVGp/k/GehixgpJq7waOXdVHsN7rqMRNWtZ4pW1OxZZtu3MzvKz9+X8mobuYHXIfi51om72W6Vb+Tsf/UYBn5rtVrfM837dWM6WjVMjZLtLoyD363mvnDPl+7Xsv8EeZfCxL+yFhuVTVtm1M1Mj9eEj7ENRFL1voQlwlcM0j5a1zzRxxU1mOg8vPjXPNdSsh/4lyn8Lwl7M+cGNbNg67rh/Lxqevhm5v8tXrwLhV7OO3vt2bAsNKpfTKsRIYFgExkWAAl+JPClE+GtTBz/cmwpsCwru9PdtSJaKPb8tG93Hlgl7fVw91b3MedGTCsdGrT8UFRjGASuClhCeCmRKKl9EH9JdYyTx8UJI7jAMIMUoZ4WFHpIORoaf9jBDseEsh1jcbz8UG9x2ieB053Ss6tc1HTe/iy3DvYfIRun+itjSD2NAOcplObDk4J4IlWA0FAxOPUAvidQZ3ww0lNNUIJEbDZAGsArGeOe91WL+iuPywUNuKwM0IIs0ETxp5TgIMlp/xuIehX9v56ZR2sQTH6i6Ish50wfQW9LnKoHlOLhOlhETt07isq0YNhneB1hqjOYYaohpD5NOu2r+Z1Uwkd/cXPuYY107GCgwanFYwo0iEYX+jBwZNh3RCO5AnLveSJqgnzdKo9z6uZaLLCqQ5SYhOKrdf8tm205Y6dgh2JQYnBk3NLoxvFXAOGoNrKlqrlG7aaYd1Bf2rGKgEncalDFrCyeXx4cpArRYvdtCIlZABCy54CntTpOcOklX/A9XD9ra5sF44PIw2iggCUECBRYUwCRqXVSbH9UwEAipWfAT8YVBiysoka7YPScaZSsW26NgBUmtGi/vnrZ6BKBPy9bkHpxgsqC6qa3zBhs01NtWxSuMoJEkNwFWvNASJIALiWBYLfuC43/HA0wOuxGj6EoRYTlrbD1w1ZcYqQfKf4dOwXS7lkVa1wpcS17kXEhtpwMOMDvueG8i2aoI9JuMHnlHkCcES4vWNan7W8GPEf17OPqASh6hmqBO9oyHxVANf1jNHSVLAncIVILiuSOqgCNOVUGG4LsimLf9d4yho/W1H7g87+hbl+a3x+LX+oq1mg4OH6cqfrtsXmJWnWUf7+/pCePRT8WcSkU6lNR88AVlQl6RmAJnknoZ35RG4F0RQVDcAJiFM0gAhjUROKBuSMcECFQJgiSeCoosHiFI2kIpG0ZZOKxhpH1iCyYGCAC4IhpqOqB+aTukdymYhMWCZGHYGUCYa41aukAFgiOKGOiHh1JK1gRFK8rY7Qd6gjNFEdIejD+giO00fwXPSR1cw/0HqjVx/qJe/hgmtvChf+DuUloDwbBSbE85ggDTePzViBgaPeg2cNxrIfQTl7hyITtnI5FBn+MUXG9uxdikxUQea/M1NdjfNVdbDrUFuMVDzLhCuWLZKKgyCrUGIEx8yhrhCfu21GVJD7VrWnLzdkdZP6pTzcKudx1tSFuiiKGagg6dSmooIACXHSthK7UkN35aQKAiQHydvipqmCAEkIi1FBgF3tI/rEQGIDOfoLx5wdI/6RgbBOLjPQDiaUEDimcozkGMrpEQUDxysYCI7+Tvo7xjWTQZvTCkYk+aSCEeglo79oXOWY1DjSCr14Vv4PqCC6cz9P9QG/bER9Fl9hxGDRtYewkdNSHl4kWDAdHxH17J0B0lFJH1CZr5T2NLXcFoGKByi1UtoRFatEqIrgSChPOa5w57kndtDcLeP5jWhZhdLGDlsgopu9tjblth+C4zrY/RUzVL85d+Hf729qTGwtBKGddLua6iog4fmm5nZey5aBO7M7WA6lQv5oJxTsw/QQ0oPkoH87uYJdSYEADZu73WxbeAajVzwLVm7n/rj13LGQ3JYJw1XBarcZbLlbv3Vg+ZfFQKH5MMDbr1+LqMDs5UFj0y3c0l52ixyj7s1umZQfz052BJyBApNObToKDGEg6QAOIBzE74sFVAr2wihttaHAC7mXeey2lY78cC+4t4t426+ZzWCkw9UMg3XoN16JO4wnuY4EkUQLpiqqJ4rwvyzXgffve8tvRYzf9uV16YDHvSofmU3jZeI426t+RAv7L7Ku6dtoISceHVtbbFrsYbzqafOeV7WPsIoRuOcuSgHbnD/gd/ccrC78p3tf9kS7Wn2k2ZsDcn67fXk1A8CnU5sO4GHylk4ASejKiwE8ASHP+VvB2VC7fMNeseoxibNXIMUizl4BAjFr4iBr0UjIMaVs1GCBcQZLcqFBkHLSbTqd+CzAGFAuKERYWogQhCYMFhJvsKSWjGiSOIslrtyIyTJaKoXaiM1CpmizvHry77FZgrRyjO0BMuv/ynxRX2zCPyAMvsARiyWhHIrKOWE5FJZD7ymHo3I6LIfDcvjvW0irrzAH1zObTWWtA22GsIPxsENAxroJEEaB1zWU08WAWNgIEPDx6UAxbqG9QiKZGRIJxAhhSACRVDDOxXu3SgBOsOVHjCIhEWWTOJTxngNrhBAuMRaCIMnZ+N4JGYfDiASUAhMeRJPGYYjn4zugIBWIFPwN70FoNr65stG4+wslrGsEeey6JhJOrms4ua7HYnAQTa7isZhblGUmixamrL1B+8YdZUMf1JurNiw5sWxHAY2ZGFu2XMQt2+RSA9+aSFq2YEk9XgOmPLJ44cvi/ThPR9PxelExuesHgXd7vVZXrAXk35uXbEFXXhOAkIEJCtY+hO+kQdE7iCAGyfSJ/Ns3NA1avByBQBYOUKNX36rXsp4Xbp8feGfwyqTbMH9UzBVi3IZhn9/lOIxqmFJskGW+Rj5o24Fvvzd+7/7ezYz9nGUPyrli5qtV+FYz8Nuq/eTYTyj8pO0n/G0qrssZ2f/LHgrs6Lbf6lZsuyrS9lUozrB0XYo8ahyNHcMRJ67nudJUZuFb+yj9aRjfXEoEE7xtNo3EhwuDFEpS2dHsTzCsDgasONJNc69qvbCj+9H0FEvZUu4wd1SKOqlvt9sWhhFHCzt9EEopCAdjsNms9ep2TGXY70EiD78Mk6DVjbrmsfvcmADOmWhPZLaYeXUMohI8C1JDMVw+OsoVS1+7zVb4vPMtyD3Mcb6bK+SiOvJHma9RlYPQRXAAI3oQ1hN7ePuPuNPbQaFvgSv8A4GSBe/MnDeTAgmZS7ByqJCa2hLIFQhrFsTPXcyCHRhKs/nGbyJ/lwrWede0R0Ipz9M1UEfDHBGw/hxGULKFQvYyUE/abdUfSxsGX369Kn5mERfmCQuE3yKa91HCSq5eVyH3HT449Ee/HzVVdeTBcc2/H8tTbLaqY4/yHeWYWm304QSxonGUXTCqMfL0wEqJ0XLBObnRVqput2oeRp5tqYZvaiOP9pS2jH+soGmOPMnWzKNquFYHS+32Xq823s7xodowjRtV9xtvD8RED2NGMFf3a/2RJ5u28vGKmtdjjYqZnj3Vd01jjJ43lumgp1VndGD8iVKx0xVQHBu9LXVvpflIZZaVBBrCyDPVbo5Wlb1Xb8zWVr82Rv5ITa4OX1fVxFIIkDUywDX/ZmySz3zdtWBWb+XLNrrVZqM/PtFKp89yTPcmVvF5YBSMlZtcxptV1bZKc9eM1u+2xycnBhQxy+gwPDX7QQxOTvJeszPaoMlllm247bEeB6Va1fGxnATNBCSzjeuxrsVjeYLtTK6FSbhPYiYGWTHcc3LlxbKFSXDl7k2t/zaWJ9lQ3Io56DXGuzy+hCaRFIfRg96tGZ8a/z2oKWq7Qk23+xarKPTHuf8ESyuqem9sTIuqYfnQdXNsITUmecEkGz0xDVNrtsxbo79ZbVvd1TLmsRZPrPJs4E5RkSr3LM3D0+RrXhiztMZwJdRvK0GQ2KTI9xcZPlbR8LT6Xyj6PspvaBblzUhJb/d0qOyPaC6DSHp3tJTVhhgZaY+OlPR35PT8mhnZWpLWzWdjKznzz1+x4xIZL5XQYPjQyLabD5XQek0pNuxVsNnFbfcLvcazFhjY19Zqa/YGPjZIpcCCrCy25Y2gZIJTTBnxEGEEISNdLQAyXDtG4MosTiB/lP50LG9r3vMky5sLFHt/JZeCiJStfQRLzBh6537dt8Pflh6geDJeYZ8jOBJ4GO5/JZxBCZ7/x2NHk+OODCWWGZxNnjwzNLZdFwI6Eb8Y268bZYmJYExG2URCwFtMRChEQoA72MyMhv+PHwJKCG8nlHkjuI2IiI9cpAUoGEAC0oU4q4yGG3NxsDHXCS44+Qdc71tzfxi7iL2ortdRkRkbfgrckhXda1vkB6s5cj6Yu56qfQ0CGQhA/m0k5JHd2SnkdrJJgfPibrawVQmFVcVm/foPlDkubOUKmY1L29DMVq64mTnIH+ZLGQjAt7eDKWF4453R8dEYYmxsPMCkhPGYxO+NjWNIkKD85f+xXfVx2+oTy7zaEj+j0Pgog4Ds3aHxtJKJ1wjYcmz8ZzzMGIvi5FIvW/jjrxoAfwHHi4FgMB5lBHFRxkTIRXtcCsfHpRHEgRfIfRxwcAxw8N2hy9cCNDGEyV520D9HlTB678UF6G/s3H/dupgN/IRwgCOJkB73i1r78bBfHDMe860+s+YR3+kEm/7IRv+ote/y9ucuTgq5YjF/fJTu7qdj3n5EX7n7ZZK3f9SR/bJcQ0f383qNBNn4qn3b5Z0s1KKykVwLZGPmX6FQ+5h3P3I9Z0q5w5PMdvlos2QHySIkMCSsmWHa2has+A1rYzRUrVL5+hh18PceAFhH5kn42YSe/q+P3/75e2MwEim1LOKQffvnnKMIjAkMNMAV5hFTIRToiiOkqbiGKk4dwilA//ERhE8/xqcf4y/6MaTkcBH9GP3qZn7XO+Ubh5tuqV2/PTknZ4fF43J+e3cGXot0atPxUTBBEncHMPsb56MQAACUcp9JnI/ib+s7sRrDuH6xWcifJOoXVgZtVv2auxe+9mgFvW+PUCBQvn/PbBldU22TUZl71fbDSzu7zYydPjeMgncyyv5rZEKGsRaU2cptHmStbHpmp0nS9p8DChs927bnOjJNL7wC1BYPROWASHQhk30cSrxA3oW0irnSKzr/yiyiTB5287zq6+pwzFpB3D8YumDPQCfjNzLFl+0AXzqZVk31O/8TdXHxty6EXVyi/QvLvp+rXd3K9gu4VL542HT3zvvbF6qfJ9vN7dLtDLhxOrXpcGMqQMLVDjZNioS9WgyEvuSFv212ALL/tTbdWtAHW1m9tRp9L/acYqhPrdk/1q6dM4w00EZgCR2slYMVxVggJT2mHc8QpSyIAMXIcRdVibdDmq7Dpaqwz5MzqUSW8oeWtWYPT0Y0wGjOsoHgmizyUWPheSnEqrCpDX9eOymqbwyhv9bwv92SUBme3GUV1TjcZvXnq/GIS4zorL8EklU4mq/m8FWalcbsO8DfEchAug7IOqD/D4B1y3R+DZqzcEy++9jezgpnu3/t3By4j+zo8ELu97Zvyyf1GTD5dGpTYvIQo0QmjziKZ/IUy2Vj8nPm4Q6nnoc8jgTSlGgXMq6YSwWhXHoGS1eRoEr+ycM/efjMefirwU3ZSDu6+8mJ7jj5IP/XEf8fG5gYom9X5Q4m9e2cZmUwFP8pYuf+oknPNs/vD+rirnArzkDXKd9sZms5ejMDsZNObTpiJ/nWFZvGQYJtQXiKp+dT7MSIHY4MIcoxjss8ohBwKHSQZFZ8K6Y0AhQo4RC1sCcI0sVOIDtWYlneEOxDhK+B4AevLCjAs2irQa/cHVq9Avndy4LaOtg9K8hq7mRnBgBPpzYdgFsTNRHgWOLYa5WCFJp+7vQT4GMAV5AJTYWHXWJcLBV3lZTSMRS6Ft/M8TT1EPPgcgJ8K6CWCvAXab6o2O7mdqu0VbjZOCngs8385v4xu+jvdM6L7Vk4BtOpTQnbiCVjO7IM47BNPoX3B4U3cDlmnCCLZOpKjxDqGIYDy5HbSjFzMPa0oMuL7bcFeIy2vuCy/MY7aXfb7b2eWwf12nXu7r69cV7POvsczwDv6dSmg3fEecJrJmya4CQe70iCpXjt3OLgXXOoJHCsQHchMhxJggESCDPlEuYYAQmB2PXMcuI9zfkx4gT6wFnfFFt+9V25fi4oE6lfZTf2qjvVo+PN7sVpndWKl+VGsd3cLjVnwETSqU2HiQQvT0lkIiD+XTU2BYJ3vhPvk4kMdvthKAhDiBoOsQYEEgWRlALwoA6tIVQYarnEFv+AUXxQa3j28S0k3kEuVy75oHWcu7w536D11nlBPW70OhcPjRngPZ3alPAOecKLqG0ahgmBJYjJp9LwMSOBuZw41jDg2CpqQkLXdaxpAF3hIe1ZbUHbCpSRy4n3jctSrpiO9au6vF9UWPMdUuTtIj0rVs3JDReGHlVVo5t9KLozgHU6tenAGlCScHuyTeMs9vbkIEUmv+/lE9ZxYtxVlBNFsWLaEMkcQTwsJXWDt9wRJYwGjnGs7bWUsH5+q0IKrrMbm4sK68PrC1oFu0/1/qW/W949e3QbzVL3qsO6s3iTZDq1qcBaSIGSpLWQEsXD2qbQd16K/gnrCNbS0xh4RnqeIYg61qAnQjOmofaUBzUSRLiOo5YU1hvHxwfpoA4mc1FRfXNd3y1ubNRY63L7GnvH9St9fv5wmb+pbs/CcZdKbUqoRgwmohrz+CCckAR8BuE+5rijBhMsOMaEEKkUB5AwyASmnnI8YkfWBK9hmvaLn/9NqD4qH+YK+c03Au1rGAx+FhXfu9fdmz44JHsthZ5Ojmrt2mmd72+DnjyaAb7TqU0H34KFwbZYfAsR/+6iIAXN+zbVJcO35zLFPQE84BEFg133hHsc4cC55mrP86z+RFyypIG47YPjbHge8g18LyquH/Nbpau78qaf3WO7WaY3Gtum2zzeL1A2A1ynU5sSriFK2pRtwQvjA+wBrD/l9seMbCU1NEhx5rkYeRBI7GEDXEew8BUOVDpWlrMl9Z0NTjmnonpRMX173dC1uzPZa9xv9fdO/CfCOyWdvTm8PZwBptOpTQfTnOAkx5ngDCdgmjMmlwjTQXjm63OM5uuXmDjMl2/zvlVbOwYIbiHueh4DrmFQC8Koa9eOYJoz5HiUKzwn1AeTsYiIPDmvlqo612ve+SV84jx1zls+vmMHJ1enM0BkOrXpIJJJmOjzYlIm+Lw4QMsUoQp2WS08IomjDRcecAWS1LUmtFWpPS0VDC5kQMFpM+x6c9ulvrCILJGnXdwuHbO94t5+bqfc3+m293b9Zn5vFohMpTYlRMKkV3PatGjTaQwi7QpZpo2lb4FxzlhUgAniKOE4kEuiFAKIa4cLC0LkcsdggB1bdk6HzRcVizvZs/rDds0/rVbbtQPW6hye8LOTzetmdxavyU2nNh0sUgYSbVDKkqSj/btMB4M3s8XS1y9es/kluJQl3Gwwb/wZbI1OzYRBUmsDOcfcsXaqIxkgCGigGJAQyjnd2Lao+PM2VK/eP7+nMndf9q/Pt/a6l+Bo+3hfPs4Af+nUpoQ/IJPu6xbULosE/EG5TPslv2Q3Nr/MGXCOA7iArhQaIeq4jmuNQCkAEUIRbJNcIJRD+Jx2XS8q4A4PzktGlbecbB0UD+/O0KE8KBWeLvqPTzMAXDq16QCOUJSofBJG4zco25TlUj4L5dyc8YaQEcyhrlXoAYQaUFcbxDSFBGGNHG3lHnMdoD7x9hpvpezRw+YV7jfpw3brrm+1vYZXcC/uPHQ3A7ylU5sO3qw9kbg5gYCEE8I2hS2T+yUIm81ZvBnjAM8AV1iIceICHryW2vM85QHNAXE0Q0C6+hNur+F2sFfuXApQyLVp9Tx/gXju8uy4etg9q5IZwC2d2pTglnxoV2DC4vfj2xSxTOINzju0oB0LMUWQ8mwe6UHtecBDCHFkjTZbqcORQQZ/gm0kgA/2Wr3ccfWo19l5wvjpen+rLjdKeHd/YwZgS6c2HbAhwnAS2BBNAhuiYpl2yYcHOr8OvkTXV339EbwB5+fcAwqQUOY5lBkBOaJGIgWlhSHBBFHpGotCLbma64tzFxGIvVLxkBwfdt1uscSd+163yqvugTz0CuUZADGd2nSAaKc/0YsJBU1QMqEQy7Sv/UcEu9UM/rmaId9WM19/0NUMs1/4t59zRiLVLvIAYZwG2+WEsaDTniaQYQEggp4CTBkIwScSR5CYY3mx8Vjyr73W3sE99590sdXfPDvf3+3PAInp1KaERASTkYgRTkAiJsskEn98HQAxACFZzQQwnDsEGSQSaYEh5MAKRSAkJtxAxLEwQAmijAeQEZ/CcBSCauv06UmcUX6NdffSoHtpTlBJlq+vvBlAMJ3adCAIWLIJCHiShxPwlFeALh4EByqoxeBq5kcAwZ/zVkZdAaiDiJRU2TpcKQHASBptOaKWEkroWQBid55nvhYRf+fnuthvFtyzwlHj9MZ/MPmjje1zr8z2CjPAXzq1KeEPiMTjGgDBhO0tAC3VIctnVXTOqJOEOQxSRyDoQBcbyTxs/3KiCDNWIQWQCgfreV64vYiou37aYw/5tuPue81Hp2eeti/7G97JgdquzgB16dSmgrrgruEk1HHJSPzG6/B9U0uEulDvnLegg0xjK+coB4xDHGwgIhgQL5gAhYTRiHIHON6cQg0LCznnhFc79bsbv/CQhec7Ilv2d+WGf+ifzOKur3Rq04GcEDwplM6F5PGCjgd60RJBbvSsQ2YhN3M6Vr0EnhTMlnNcAQ0nxmWuG7z2TXoQc4FcSZT4ROTolb387Oqi13C3HkqwtEfvn9yrJ7iFH86aswi2p1ObEiIRTjL9gkh8vOnHBUFiiRA5etZhMRHJseNag9AwgzCh0PM4VdoD0GjXwx7RUHBNqZznUeJFRKTcK+URu2yVLtF+59LRhzR/7PV2m547i+1m6dSmg0jOYNKluvYn9HrGINL+LNP+6uEdz4uOSsAlZ0h4ruV5mkOuEUMAWZMRQsBcRTwKpK3iU06OopLttYsn8O60cdO+1vnc6TEo5re3r3qt1uUMUJlObUqoBDjpTCDnKOHWSptClklz/fqlamq15pfVzILD0nGk43paMuoQxTzPc4nGzFNUOIBJAIUG1Fqbn8HDsYuscu2dVvmyuIMd75yYo6Pth7MNxaW3OYujuunUpgNLhliisGQExr8uyqaQZToM8eMNNL4J13m7XLWkUknFJKaKMI5d7QZvrRUqQCvyXOgYjT3tfMJ1VLfl2MvVLktXW2SrfAk23NpNq/x0SG/p8Sx021Rq04ErTXG52sWUIEWp1bmWCK5vgHHOWHRdKymlLU2x8ozQmhIIAGGMe8rlGDhaYweSeV5Jt4hY9Hf6j129/ZB3Qbdzbi4bdO/u7ESA3ews9t2kU5sOFonAiVgkMmEHnE3hy6TRLuA5Xk8LF3kCUOkwigzghAjoIaG45zoKIccamZ4083wx2yICsNO6vkEXD0fddmdb9JqnVw/Zjn+4q2lrFpewplObEgAxSNoLbtcEShCGhCzVxrdFOMgLHM6wq6y9aP8Z7kCHEY6V8TwEtaEWjVJ41JnT4YuFRZzZvtrilwTvn/X2C0/N7LGfv8rvnQOtZ3F1RTq16SAOc5AYfsSCxW81tSlyma5FXYCTvBii4E3C2GBXusbFyoozizloKNdEeiI4hOF66P+cvffz1/8HcD1BVEf1AAA=" } }, { "ID": "5ba1e040186a509d", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "72" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJkYXRhc2V0UmVmZXJlbmNlIjp7ImRhdGFzZXRJZCI6InRva3lvIn0sImxvY2F0aW9uIjoiYXNpYS1ub3J0aGVhc3QxIn0K" ] }, "Response": { "StatusCode": 409, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:02 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/62OsQrCQBBE+3zFcbUBCxvTBZJCsDIWioisuSUG77KS3YAh5N+9nFf4AVbLzCxvZkqU0tj31OtMTV54WZNBrzbr7eprOGSGZvF0bnsEM6ry3bJwpgoQYBTFD7J2dNClBh2lgiyZ0HMkHRmhgz3iErSKZf/iB44hB223YBpLd7C/mccyhcwML9vWIKhjOod7jUNZQAYOW/aHMi/Ot/K0q47V8j0nc/IBXE/GKzIBAAA=" } }, { "ID": "3f51c74fed4229c4", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/tokyo?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:03 GMT" ], "Etag": [ "jQy5ZIFyGuC20r9/b3P8NA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/32Q0WrCMBSG3yW7tY12KrMgzG1OCptuRRA2dhHTY42mOV2SOor47qbSyi7U23P+7z9fsidboRISkqVIfwvQ5V3CLDNgSYuAZanbbD7L3lf0Wk6K56CtB3R5//EwHQ2HLiEq0qxRyjJjyksgQ8+CsaHFbYkuYECu3oTautja2tyElDaH/BQxlcByYXyO2XlOdwHNNW6AW0MvdNNa0NDmSD2IYQUaFAcS7ptZVAk2ubo1uiJNDi3COAdjSPi9JxqlayKLOJqP4+opOXDB5ERjkbt5XbbQwoI2jj0Ts8X0BjD7U1fyhQH9VI4zJmQl7Yw8jUu0jxdcfcEyP3XATnBw0lgoW/3i/954PHq5IRIDS04mPy3CNTArUM1FVpGdXtBt9/uDzqAb9F2BZMa+YyJWApJrEeSnBrdiRjBPobZrcFyHHI565pKMZAIAAA==" } }, { "ID": "631f39fb888f780a", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/tokyo/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "242" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJleHBpcmF0aW9uVGltZSI6IjE1NzIyODgzMDcwMDAiLCJzY2hlbWEiOnsiZmllbGRzIjpbeyJuYW1lIjoibmFtZSIsInR5cGUiOiJTVFJJTkcifSx7Im5hbWUiOiJudW1zIiwidHlwZSI6IklOVEVHRVIifV19LCJ0YWJsZVJlZmVyZW5jZSI6eyJkYXRhc2V0SWQiOiJ0b2t5byIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QiLCJ0YWJsZUlkIjoidGFibGVfMjAxOTEwMjhfNjY5MDY1OTAwOTM2NTlfMDAyMCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:03 GMT" ], "Etag": [ "+bJ8klHWphVhtHWFgb1OYg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42SW0/CQBCF/8v6qNBtCb0lPEiCgEFMsJEYY8i2Hdq17W7trpeG8N+dFpBENPq0mTMz3znTdEMyLmLik5AnL69Q1WeahTmQCwKaJaifh9dulk+WZXqf6snyKgnN24dkMMAJ3uypVOZ5XTDRiaGQHQ1K+1pmtey2oJVFTc+klruybY/afY9Sr4fPilKLIkNBvp5xkSEp1bpUvmEcknQTKZMcWMlVN5LFl268WUZZyWeItDJ+sDdippkCbLY5jDaHMv4Vpx1awBoqEBEQf0P2TtNfbsWdvV070ToeODvlb9stfoYohYI1fmsOeayI/7ghghUYYfcgsi6b6i5YTOdj3Dn2Xwt17E/nwWg8WpDtE2KxNawxJurNdVjOpEgCqL7LC/l+qKIKmOZSBLylm33HslzHtXq25zW/xUfJq9MBt0cdSpv9nCl9I2OOh8QnDKdvHqMGl8PZqNmQUQtEiSnOOkJWOgXEmGT7CVEHXgygAgAA" } }, { "ID": "48e52d277c16733d", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/upload/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7ImxvYWQiOnsiZGVzdGluYXRpb25UYWJsZSI6eyJkYXRhc2V0SWQiOiJ0b2t5byIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QiLCJ0YWJsZUlkIjoidGFibGVfMjAxOTEwMjhfNjY5MDY1OTAwOTM2NTlfMDAyMCJ9fX0sImpvYlJlZmVyZW5jZSI6eyJqb2JJZCI6IkU2VXEzQ0tFSUF2eWd3a1ZhSmtKeUdGM0tTYiIsImxvY2F0aW9uIjoiYXNpYS1ub3J0aGVhc3QxIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCJ9fQo=", "YSwwCmIsMQpjLDIK" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "851" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:06 GMT" ], "Etag": [ "\"CRkpyt4RXWzE4lvoHDbioIbWdUA/xmHnQLYqH_Wlyye14GtMpmSxHzU\"" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Uploadid": [ "AEnB2UrzKSoGj78wjQVTKbY4hO-qYtcaD40Eki4F3p4LJ4N61G8LmDShmPvDmIL4XTVICJlF5i5PlUabE4elpixSO0ncEQGhVOkuR0wFbGSzr4EXZ2dY3jU" ] }, "Body": "eyJraW5kIjoiYmlncXVlcnkjam9iIiwiZXRhZyI6IlwiQ1JrcHl0NFJYV3pFNGx2b0hEYmlvSWJXZFVBL3htSG5RTFlxSF9XbHl5ZTE0R3RNcG1TeEh6VVwiIiwiaWQiOiJzaG9sbHltYW4tZGVtby10ZXN0OmFzaWEtbm9ydGhlYXN0MS5FNlVxM0NLRUlBdnlnd2tWYUprSnlHRjNLU2IiLCJzZWxmTGluayI6Imh0dHBzOi8vYmlncXVlcnkuZ29vZ2xlYXBpcy5jb20vYmlncXVlcnkvdjIvcHJvamVjdHMvc2hvbGx5bWFuLWRlbW8tdGVzdC9qb2JzL0U2VXEzQ0tFSUF2eWd3a1ZhSmtKeUdGM0tTYj9sb2NhdGlvbj1hc2lhLW5vcnRoZWFzdDEiLCJqb2JSZWZlcmVuY2UiOnsicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCIsImpvYklkIjoiRTZVcTNDS0VJQXZ5Z3drVmFKa0p5R0YzS1NiIiwibG9jYXRpb24iOiJhc2lhLW5vcnRoZWFzdDEifSwiY29uZmlndXJhdGlvbiI6eyJqb2JUeXBlIjoiTE9BRCIsImxvYWQiOnsic2NoZW1hIjp7ImZpZWxkcyI6W3sibmFtZSI6Im5hbWUiLCJ0eXBlIjoiU1RSSU5HIn0seyJuYW1lIjoibnVtcyIsInR5cGUiOiJJTlRFR0VSIn1dfSwiZGVzdGluYXRpb25UYWJsZSI6eyJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0IiwiZGF0YXNldElkIjoidG9reW8iLCJ0YWJsZUlkIjoidGFibGVfMjAxOTEwMjhfNjY5MDY1OTAwOTM2NTlfMDAyMCJ9fX0sInN0YXR1cyI6eyJzdGF0ZSI6IlJVTk5JTkcifSwic3RhdGlzdGljcyI6eyJjcmVhdGlvblRpbWUiOiIxNTcyMjg3ODI1Nzg1Iiwic3RhcnRUaW1lIjoiMTU3MjI4NzgyNjM4MiJ9LCJ1c2VyX2VtYWlsIjoidGVzdC1yb2JvdEBzaG9sbHltYW4tZGVtby10ZXN0LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0=" } }, { "ID": "3c720ce75409fd7b", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs/E6Uq3CKEIAvygwkVaJkJyGF3KSb?alt=json\u0026fields=configuration%2CjobReference%2Cstatus%2Cstatistics\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 404, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:06 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/7WOsQrCMBiE9z5FyGxBsDh0E23FFtpB6yIiqYlVmubHJFVK6bubxAy+gNPP3f3cd2OAEGZSgsQxGo0w8gqUGRXNo9nX6JhSpLEeLkCjG/SCxiiDGqk7cD50RISUdRBqpnScLKvnYp0nu9VraN7tkWRtNmzTRb6vsS90QGX6Tk4jT/4LzJVS6MhD2M6GQ034byYZUeAyATq1OOzDyd2zH6000b1yu8rDJS2rYmMfp2AKPmIs+VVGAQAA" } }, { "ID": "97a660ea20cdc134", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs/E6Uq3CKEIAvygwkVaJkJyGF3KSb?alt=json\u0026fields=configuration%2CjobReference%2Cstatus%2Cstatistics\u0026location=US\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 404, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:06 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/7WOQQuCQBSE7/6KZc8ZgdLBW1RGCnowu0TEmpuFq498ayHif29320N/oNNjZh7zzegQQnnXQUcDMiqh5BVKrpS/8Gdfo+GIrNIeTUCSG/RtGZAICoJ3EGJoWOuWvAFXcpRBns23y/zprePtfvUaqnd9ZFEdDbvQi7OC2k7DRFV5MppY+L94preEhj1aXVsJKJj4zTrOEEzWggw1kdpwMvdsd6NkskczLT1cwjRPNvpxcibnAzE69qpMAQAA" } }, { "ID": "7cdcc164620922ff", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs/E6Uq3CKEIAvygwkVaJkJyGF3KSb?alt=json\u0026fields=configuration%2CjobReference%2Cstatus%2Cstatistics\u0026location=asia-northeast1\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:07 GMT" ], "Etag": [ "lyWpxws/2QMsU18iWvctrg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41STU/jMBD9Lz63kpMoadIbLKEqsEVKy15WqHKTaWvq2Fl7Aoqq/Hc8CQsse+E04/fefPjZZ1YavZeH1gqURrP5mSkjKoquPEItKNtLUJVj899npkUNbD6GCcOuodN6UyxXC9ZPPvi2dh/8crXJF3nB+sd+wipwKPUwbSN2CmhAY80TlLj0c5k7GqW6WuhpBbWZopf7TpVA4WBUoDl1hrpT+YhQtg15kAU8TLdJkvEkzjjPIh+2nIec9X70k9ltxo3u7i+u2IgUsAcLuvzmIr5iYPPk4U/04zZfXjx3h5fTL3FzuukW19HteudVypRvfjLhpJhqY/EIwmFAUx160rtQOppZWhjdkIN1QTwLw3SWhvEsjdkgtviVS6I09Bzo6iszC+JkWGB8RKmbFq+lAkciT7wDlx2OIDUyLXq4MC+ERO/AX01E0E5UBZTG0k9gnO6BBoVaK4M/CcpIZMGBfR7u8+DEAT5/mgr2olU4bWQDSmr6QO5Tcf/4T/ng8n8lb+61g3OUUeOr+1XuH/gVzSBnc8wCAAA=" } }, { "ID": "ba6c7c6be72a9d8a", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs/E6Uq3CKEIAvygwkVaJkJyGF3KSb?alt=json\u0026fields=status%2Cstatistics\u0026location=asia-northeast1\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:08 GMT" ], "Etag": [ "lyWpxws/2QMsU18iWvctrg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/22QTQvCMAyG/0vOCroxNz2KCh5U8OMkHuoapVDb0WaKjP53m4mi4q193g+SNOBJkPKkSg+jBkqH8WvNVl0QRtDP8iQp8iLJ8iKDDpsd/WqDtEiihkb+Knk/G0RFWyG5XJmqppnS6NkUhTcY3+kJucjWFPHa3pikb/DypIyOQq6xtE4y6UHoAFkSeqMtLRgN2eTQo7u2++y8OMfR9g0Y0c4o8SRqTd1KVaiVQV7uIxwOX/G5/BcJ7UGobi/HLy6erJZTCOEBT5K5PVkBAAA=" } }, { "ID": "86bf3e07b40bf422", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs/E6Uq3CKEIAvygwkVaJkJyGF3KSb/cancel?alt=json\u0026fields=\u0026location=asia-northeast1\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "0" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:08 GMT" ], "Etag": [ "lyWpxws/2QMsU18iWvctrg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41S227iMBD9F+8rkJsIAQmtui1F9EK1AdqHVYVMMgQXx05jBzZC+ff1JKUXtlvtk+0zZ2bOHM+BbJmIyYCsWPJcQF5+e5Krcyoi4CGoTAoFpEUMRgaHz6gmCJomBuXlQ/Z7ryz3561aOAF72EU6T4ZDw2CYpTaS8zKloh1DKtsalB5QxWhbyFxvgCrtdEb+4tk7vx5NznZlst/e06vtVTm+9K5n2EgBX98wsTXFNlpnamBZRymdRMqEA82Y6kQyfcWtnWtluXyCSCvrEwWWGUFZX7T9zmVENZNieKLV6ImkWLOkyOs4+sMljfFU0QZSirc1Ax4rMvh1IIKmYJTXR4voMsPXbB5OpmNStd7iRare4pPpfDQehaR6rFokNoKZqLvN6YoDNngZbvIPh02lmGqqoGFouS0lVsf0BsHb0rWdvmO7wdL3+7bf7dt23zPH0rZdm1RVvQDzRtHN3dkFaZAQ1pCDWZX/E2Iy6ujXn3z02xBPHTddlTZB40KksGeUQ+MGq61zuj3XDXqB2+0FXVKTc30a873AxaUV8Wmk53T9WkDziUxkhb5kHBSScIuPwI9SNyAWkoU2cCj3iHivwJHjIbSicQiRzHETiI1zaKkpn3GpbxHqIykHBfmunmehaALvlyaGNS24bmcsA84ELpB6l1w9fkivXf4r5cW9onYOb1j44m46Mh9c/QE0RaazBwQAAA==" } }, { "ID": "24f68961550a6945", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "234" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUICogRlJPTSB0b2t5by50YWJsZV8yMDE5MTAyOF82NjkwNjU5MDA5MzY1OV8wMDIwIiwidXNlTGVnYWN5U3FsIjpmYWxzZX19LCJqb2JSZWZlcmVuY2UiOnsiam9iSWQiOiJSNW5CZ1ZueFBGZWZIVVdBWURNcWFUOXg2UWwiLCJsb2NhdGlvbiI6ImFzaWEtbm9ydGhlYXN0MSIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:10 GMT" ], "Etag": [ "OrgyU/g97aXX5QqqN+vvFw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41SXU/bQBD8K+j61jbxV2znIqGWJk4bCUwxDh9P1tlemyv2XeK7BCLEf++eA6iiFPXJ1u7szNzsPpBbLkoyITmv1xvodh9+yZx8JqBZjdXTrt4trZqG7OrKP1uv40/b7fzu8BAR3EypG9k0u5aJQQmtHGhQesIUZwMhO30DTGlnmPjiW30h7n/OofqxvDy6np2sWUrvg7MGaRQ01TEXt0h2o/VKTSzr2cqwlrJugK24GhayfalbW9dadfIXFFpZbziw8AnKekf2SyMLprkUh6+8op+Ngi6DlvEGHRm2QSdzqb++oTPkrB3WiN/yAlhRyI3QxiiyFFJUvN50vQqZPJDe+B8/5Dw6jqbpwceDeXJ6cqDl7U4ONcsbyFzboY7tjrMgoHbgU9umHn4y23ZtpC5RmYueODV4Q/qUxuIfKzFTTDMFe0RmQ1mVLoRebo8czwlsGozysV061IOq8kdeTisXezjXW+qnmJACKIAbOv44oIHjjCFnENijkhaVO/KqEMLQD5zCrcgjRtAB0zDjaiUV38dApkl0lEbZYp7FUTSLZihw1/HXqMtkgaA0WcZTRCNm1XGJMBPbIk6j5GiaLi6i/bKOoWbF7nyN66pYowCVcf3pboXBkLNllFyTfSmBCjoQxX8GhhN99/3rfT4kk8+rU0JVpbGJ2yqU0ewDMVvjrfHm+KHrjsOxS/2ROTwEd/qvHg097L1cj2GEFoR+euD+isjjk9hGvYCM9WUcL+Lv2P0N2CWYbuYDAAA=" } }, { "ID": "da5a1aff2d195bc0", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/R5nBgVnxPFefHUWAYDMqaT9x6Ql?alt=json\u0026location=asia-northeast1\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:10 GMT" ], "Etag": [ "esJ5K4XKAwibt61hOFrYow==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/22QzW7CMBCE32V7DQdEQWokDtDyVyiFFNqiqgeTbBJT2xvsjSBCvDsOrcSlp/Vo59PM+gQ/0iQQwlZm+xJtdZchL+tHhK5U7PwoyDiEAJBF5p3ontvT+89p7yC33Gnmr0O7oUO36x0uzlELCE+QSlSJg/DrBEZo9Nh1BMBVUau3VTSZj7zWlNR6vp7Nev3ZAM7BjSi1uxGT+WowGkT/Id/nAHa0jTBFiybGukBhaYcxT+rbXE5KVVqYRoKaGoyO4Upct1Hb9LN3c1wMMR2vP3qbp5e9WD0cO0vlXYpiwZKMNwonRcOQ5RyF46avCkwsVEQHfym04E/3K5+wsBSjc1gntFq/cY+kC4Xs+7EtMYBY+P8aS4YwFcrh+QKvQZsSjQEAAA==" } }, { "ID": "831ec5d31c4b6ea7", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_0edfd2e73b0413160964b80d193eff543b9f2b04/tables/anone9ee27158696118ebae604d9cf243f7e77561c2f/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:11 GMT" ], "Etag": [ "/o/kZYpxDmoS1f6gNLc8Mw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8rr5+tnR0UWVLjk5gcbppml+/kkW/iW29oCVZTklyTmBOWXFwOVGQP5RWBmdLVSGpgsAwonKtXqQFgGSrWxIDZCLgkuZ4ghlwyXMwLJxdYCAMuw+s+wAAAA" } }, { "ID": "09074aeb9313113a", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "389" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7ImNvcHkiOnsiZGVzdGluYXRpb25UYWJsZSI6eyJkYXRhc2V0SWQiOiJ0b2t5byIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QiLCJ0YWJsZUlkIjoidGFibGVfMjAxOTEwMjhfNjY5MDY1OTAwOTM2NTlfMDAyMSJ9LCJzb3VyY2VUYWJsZXMiOlt7ImRhdGFzZXRJZCI6InRva3lvIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCIsInRhYmxlSWQiOiJ0YWJsZV8yMDE5MTAyOF82NjkwNjU5MDA5MzY1OV8wMDIwIn1dfX0sImpvYlJlZmVyZW5jZSI6eyJqb2JJZCI6IllOSGZ0bHhZc2xPdG1SR0lUMXRtbTRrN09uRSIsImxvY2F0aW9uIjoiYXNpYS1ub3J0aGVhc3QxIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:12 GMT" ], "Etag": [ "6SBcDB56SppJ5NMfqb0l+g==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/7VSy27bMBD8F+bYWKKUWLYFGC3yQOqilQvHORhFYVA0JTPmQyFXQQXD/96l3OSQpEEvPZGYHc7M7nJPdtJsSE5KWT+0wnUn97Ykp0QAqxHNbi/41cUwu22aL8PiW/VQUvWhnk6RIcMrv7VKdZqZwUZoOwDhIWdesoGxDraCeUiiVfG5AvVr5dUc9OJmtkxA6/PdaG6uUcYLVX2VZodiW4DG53H8FCWqra2VYI30Ebf6GY8f07hx9l5w8PEbCWJswcfv2H5UljOQ1kxfZMU8rRduLTSTChMFtYGzpYVPb/hEkumoRv6j5IJxblsDISiqcGsqWbeudyH5HoGmC6e3reNiyUolPMl/7MmfRmZ/mSZqbRgwL44MsLvOIgZB4IiE2zqlySSh6XidZROaDSeUTs7wWFOaUnL4iSKoJU0fpzcPWf67dUIOh1OC21h2DTqSy/n3FTkiC1EJJwz/xyD4oq++/5ee1orEl4tFVw9YxClw3y/EieM0pA7RkuEoTcej8Vl6TinpyQ5e18bPSm2vEm6Bsrgrillxg/3+Bvn3Q1ZRAwAA" } }, { "ID": "967c41c59669a7cf", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "387" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7ImV4dHJhY3QiOnsiZGVzdGluYXRpb25Gb3JtYXQiOiJDU1YiLCJkZXN0aW5hdGlvblVyaXMiOlsiZ3M6Ly9zaG9sbHltYW4tZGVtby10ZXN0L2JxLXRlc3QtdGFibGVfMjAxOTEwMjhfNjY5MDY1OTAwOTM2NTlfMDAyMC5jc3YiXSwic291cmNlVGFibGUiOnsiZGF0YXNldElkIjoidG9reW8iLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0IiwidGFibGVJZCI6InRhYmxlXzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMjAifX19LCJqb2JSZWZlcmVuY2UiOnsiam9iSWQiOiJFTlcyQmE2RVZBbEd3RlgycjdkSUF4SnU3V0YiLCJsb2NhdGlvbiI6ImFzaWEtbm9ydGhlYXN0MSIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:13 GMT" ], "Etag": [ "WIC1y6tbfvxlfMjMGAeaiA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/62Sb2/aMBDGv4v3dvnfBoiEuhQBYlp5wdJSqZqQYy7BkMTUdihRxXffOS2TRmm3F31l5/zc75673DPZ8GpJIpLy/LEG2XxZi5R8JaBpjtH5ZOA1oU6z3b7IbtY34xgoj/t9VHCTpVaiKJqSVtYSSmFpUDqiilOrElKvgCrt2cPp3L+m4fAuLsZPo3tfdpaTeP+97sxHiFFQZD94tUHYSuutihznaMXOhcgLoFuubCbKP3Fn5ztbKdbAtHLOOHCwBeV8UPaqEIxqLqr+iVf0UyuQCygpL9CRoVlSpEJ/O1PH5rS0c9TvOAPKmKgrbYwihYkq43kt2yokeiaw15Iyba5K1JJBQtMCzOdrJ5N3xomwJdVUwYtCi00jMKZN+kvE3Ba+6/U81+8uwrDnhpc91+0FeCxc13fJARmI4lVr51ZyTMvNpM8NL31sT+vfXJupHTlFKxI9fBr811/0kZAlxRGSwc870xP+5qTZ4hDJ8D6ZxYPkNTiDDCRU7D/Hixnt68d7elwZFJ4uDVZVGh/RKFOmJpPQahNeGnfeZcf3u51uEPiBWTEUS/3m7eIiOJLqlmJuRjK7nU4n0zE5HH4DIw4ffK0DAAA=" } }, { "ID": "9c60fb43e6feb7cb", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/shollyman-demo-test/o/bq-test-table_20191028_66906590093659_0020.csv?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 404, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "263" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:13 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Uploadid": [ "AEnB2Uo178pkItYH0gtI_l6a_PIVICS-ooYmWEWX15rkmmT5aKj0nROMYOzIzWiAES5yuABuYVomOS1NHZcWho0Z8YRvtdzU9HfsG9nsBpgj21g1zrnPslw" ] }, "Body": "eyJlcnJvciI6eyJjb2RlIjo0MDQsIm1lc3NhZ2UiOiJObyBzdWNoIG9iamVjdDogc2hvbGx5bWFuLWRlbW8tdGVzdC9icS10ZXN0LXRhYmxlXzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMjAuY3N2IiwiZXJyb3JzIjpbeyJtZXNzYWdlIjoiTm8gc3VjaCBvYmplY3Q6IHNob2xseW1hbi1kZW1vLXRlc3QvYnEtdGVzdC10YWJsZV8yMDE5MTAyOF82NjkwNjU5MDA5MzY1OV8wMDIwLmNzdiIsImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6Im5vdEZvdW5kIn1dfX0=" } }, { "ID": "f0df3e818409c079", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/tokyo/tables/table_20191028_66906590093659_0020?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:14 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6uuBQBDv6ajAgAAAA==" } }, { "ID": "4eb2caa9980de20d", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "72" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJkYXRhc2V0UmVmZXJlbmNlIjp7ImRhdGFzZXRJZCI6InRva3lvIn0sImxvY2F0aW9uIjoiYXNpYS1ub3J0aGVhc3QxIn0K" ] }, "Response": { "StatusCode": 409, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:14 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/62OsQrCQBBE+3zFcbUBCxvTBZJCsDIWioisuSUG77KS3YAh5N+9nFf4AVbLzCxvZkqU0tj31OtMTV54WZNBrzbr7eprOGSGZvF0bnsEM6ry3bJwpgoQYBTFD7J2dNClBh2lgiyZ0HMkHRmhgz3iErSKZf/iB44hB223YBpLd7C/mccyhcwML9vWIKhjOod7jUNZQAYOW/aHMi/Ot/K0q47V8j0nc/IBXE/GKzIBAAA=" } }, { "ID": "6b94036560ff0def", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/tokyo?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:15 GMT" ], "Etag": [ "jQy5ZIFyGuC20r9/b3P8NA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/32Q0WrCMBSG3yW7tY12KrMgzG1OCptuRRA2dhHTY42mOV2SOor47qbSyi7U23P+7z9fsidboRISkqVIfwvQ5V3CLDNgSYuAZanbbD7L3lf0Wk6K56CtB3R5//EwHQ2HLiEq0qxRyjJjyksgQ8+CsaHFbYkuYECu3oTautja2tyElDaH/BQxlcByYXyO2XlOdwHNNW6AW0MvdNNa0NDmSD2IYQUaFAcS7ptZVAk2ubo1uiJNDi3COAdjSPi9JxqlayKLOJqP4+opOXDB5ERjkbt5XbbQwoI2jj0Ts8X0BjD7U1fyhQH9VI4zJmQl7Yw8jUu0jxdcfcEyP3XATnBw0lgoW/3i/954PHq5IRIDS04mPy3CNTArUM1FVpGdXtBt9/uDzqAb9F2BZMa+YyJWApJrEeSnBrdiRjBPobZrcFyHHI565pKMZAIAAA==" } }, { "ID": "db7aaa7371ad5160", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/tokyo/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "242" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJleHBpcmF0aW9uVGltZSI6IjE1NzIyODgzMDcwMDAiLCJzY2hlbWEiOnsiZmllbGRzIjpbeyJuYW1lIjoibmFtZSIsInR5cGUiOiJTVFJJTkcifSx7Im5hbWUiOiJudW1zIiwidHlwZSI6IklOVEVHRVIifV19LCJ0YWJsZVJlZmVyZW5jZSI6eyJkYXRhc2V0SWQiOiJ0b2t5byIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QiLCJ0YWJsZUlkIjoidGFibGVfMjAxOTEwMjhfNjY5MDY1OTAwOTM2NTlfMDAyMiJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:16 GMT" ], "Etag": [ "D8VQY/7H2OBqWwpgapMqNg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42SX0/CMBTFv0t9FVo6/owlPEgkSAIYcdEYY0jZLltlW8da1IXw3b0rIIlo9Km55977O6dNt2Qls5B4ZCGj9QaK8sKIRQLkkoAREerX7sPdE+3c8Nv++vE9j0Q+WU+jXg8nZLWnY5UkZSqyWgipqhnQxjNqVaq6Bc05a3QbjLvzdrvL2q0uY10HjzljnCNDQ7Icy2yFpNiYXHuUHpPUI6WiBEQudT1Q6ZdO3zjNC/UKgdH0B3saCiM0YNPmoDaHpv+KY4dmsIQCsgCItyUHp9Evd8Wdg52dsI5Hzl7523aHzxDEkIrKbykhCTXxnrckEylG2B+ILPOquvdno+kQd079TapP/dHUHwwHM7J7QSy2+iXGRJ0RW45VFvlQfJdn6v1YBQUII1XmS0tvtDqcux3XaTvcrb7FRy6L8wHXYR3Gqv1EaDNRocSLhGeMZqt5iupf9ceDakMFFoiS0FLUMlWYGBDTILtPYepYRKACAAA=" } }, { "ID": "63ab22d1d098a54c", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/upload/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7ImxvYWQiOnsiZGVzdGluYXRpb25UYWJsZSI6eyJkYXRhc2V0SWQiOiJ0b2t5byIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QiLCJ0YWJsZUlkIjoidGFibGVfMjAxOTEwMjhfNjY5MDY1OTAwOTM2NTlfMDAyMiJ9fX0sImpvYlJlZmVyZW5jZSI6eyJqb2JJZCI6ImE3QXZzbjRoOFM5aUpTRHlsOU1YZGRDazV0OSIsImxvY2F0aW9uIjoiYXNpYS1ub3J0aGVhc3QxIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCJ9fQo=", "YSwwCmIsMQpjLDIK" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "851" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:19 GMT" ], "Etag": [ "\"CRkpyt4RXWzE4lvoHDbioIbWdUA/YskItLki7RmhlqMqcQW0-cwgQX0\"" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Uploadid": [ "AEnB2UpoBPFra7uyxcm-jPvR-nJL1pjekw763k23sVHosbcuT02x24hn9UUKYz8IBWUniyEMnE98yXWxluVR_hRnbQZlXIwECw" ] }, "Body": "eyJraW5kIjoiYmlncXVlcnkjam9iIiwiZXRhZyI6IlwiQ1JrcHl0NFJYV3pFNGx2b0hEYmlvSWJXZFVBL1lza0l0TGtpN1JtaGxxTXFjUVcwLWN3Z1FYMFwiIiwiaWQiOiJzaG9sbHltYW4tZGVtby10ZXN0OmFzaWEtbm9ydGhlYXN0MS5hN0F2c240aDhTOWlKU0R5bDlNWGRkQ2s1dDkiLCJzZWxmTGluayI6Imh0dHBzOi8vYmlncXVlcnkuZ29vZ2xlYXBpcy5jb20vYmlncXVlcnkvdjIvcHJvamVjdHMvc2hvbGx5bWFuLWRlbW8tdGVzdC9qb2JzL2E3QXZzbjRoOFM5aUpTRHlsOU1YZGRDazV0OT9sb2NhdGlvbj1hc2lhLW5vcnRoZWFzdDEiLCJqb2JSZWZlcmVuY2UiOnsicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCIsImpvYklkIjoiYTdBdnNuNGg4UzlpSlNEeWw5TVhkZENrNXQ5IiwibG9jYXRpb24iOiJhc2lhLW5vcnRoZWFzdDEifSwiY29uZmlndXJhdGlvbiI6eyJqb2JUeXBlIjoiTE9BRCIsImxvYWQiOnsic2NoZW1hIjp7ImZpZWxkcyI6W3sibmFtZSI6Im5hbWUiLCJ0eXBlIjoiU1RSSU5HIn0seyJuYW1lIjoibnVtcyIsInR5cGUiOiJJTlRFR0VSIn1dfSwiZGVzdGluYXRpb25UYWJsZSI6eyJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0IiwiZGF0YXNldElkIjoidG9reW8iLCJ0YWJsZUlkIjoidGFibGVfMjAxOTEwMjhfNjY5MDY1OTAwOTM2NTlfMDAyMiJ9fX0sInN0YXR1cyI6eyJzdGF0ZSI6IlJVTk5JTkcifSwic3RhdGlzdGljcyI6eyJjcmVhdGlvblRpbWUiOiIxNTcyMjg3ODM4MzQxIiwic3RhcnRUaW1lIjoiMTU3MjI4NzgzODg3OCJ9LCJ1c2VyX2VtYWlsIjoidGVzdC1yb2JvdEBzaG9sbHltYW4tZGVtby10ZXN0LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0=" } }, { "ID": "ad1b952ae18f592c", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs/a7Avsn4h8S9iJSDyl9MXddCk5t9?alt=json\u0026fields=configuration%2CjobReference%2Cstatus%2Cstatistics\u0026location=asia-northeast1\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:19 GMT" ], "Etag": [ "mDmiAoRARmgRZd3i12V0Qw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41R0WrCMBT9l/tcIa1aG99kiji2DmoHgzEkJrdrNE2kiYMi/fcl7YYPe9lL7k3OuedcTm7Aja7k57VlThoNyxsow0SoltfYsNBVEpWwsHy/gWYNwnIsEbjuEm77stjlW+ijO35t7B3f5eVmuymg/+gjEGid1INbyY4Kg8GlNSfkbud9wdZGqa5heiKwMRPn6V5JMMcsjgxnzp0J6mF8fAndISExjUmSHdKUknROCaFTXw6EJAn03vpkjuW40dPLag3jS4EVtqj5PxfxEwPKFqsvq2d1tqfycb/uFH1+E+LhPHfUs5ThP3kCs5JNtGldjcy6OLha50GfArfBk7c4piGH6OL5IkmyRTbNprMYBnLr/mD++FW6DiqhC5TiNc+Hz+i/AW/HFlTbAQAA" } }, { "ID": "a721756572a9b7b1", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs/a7Avsn4h8S9iJSDyl9MXddCk5t9?alt=json\u0026fields=configuration%2CjobReference%2Cstatus%2Cstatistics\u0026location=US\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 404, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:19 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/7WOQQuCQBSE7/6KZc8ZHYzSWyQehPRgQhARa7uptLsP9q2BiP893Tz0Bzo9ZuYx3wweIVQYA4ZGZJjEJB/AxaSCTbD6Gkogsnr2aAaWPKHTPCIpVAQbkLJXTPtcKPCtQBuVxZrtDm/UQbMvwjYt4l6Gpwvnx9fWhnTpdEycKq9OkwX+L57r5aBYq+faWkLF5G9mBENwmQabzES6hKO7t2U3WmY7dNPy8z3JyyyeH0dv9D6Jj6QuTAEAAA==" } }, { "ID": "c7e6d1aaeb25de4e", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs/a7Avsn4h8S9iJSDyl9MXddCk5t9?alt=json\u0026fields=configuration%2CjobReference%2Cstatus%2Cstatistics\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 404, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:19 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/7WOQQuCQBSE7/6KZc8JHYzSWyQehPRgQRARa7uptLsP9q2BiP89d/PQH+j0mJnHfDMGhFBhDBiakHEWs3wAF7OK1tHqayiByBrn0QIseUKveUJyqAm2IOWgmA65UBBagTZh2/0bddTuqrjLq3SQ8fHC+eG1sTFdCj0Q576r12Qh/wXmSzko1mnX2UiomfzNjGAIPtNgM4ejSzj5e1tGo2W2R7+rPN2z8lyk7nEKpuADCKibOEYBAAA=" } }, { "ID": "e4089fd3705d633d", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs/a7Avsn4h8S9iJSDyl9MXddCk5t9?alt=json\u0026fields=status%2Cstatistics\u0026location=asia-northeast1\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:20 GMT" ], "Etag": [ "cXKNPdBt6srWqAlr8KNNSg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/22QQYvCMBCF/8ucK9hGadejqOBBBXVPyx5iM0ogJiWZKlLy3zdTUVZ3L2HyvTePmekgkCQdSNcBJh3UHtPX2b0+I0wgH5dFUZWVqMQoh4zNnv5o6UkaWvWufIxFmRTjpOJwbZuWFtpgYFMSnmB6ozssEnUtJbx1VybiCR4ewegg1RZr5xWTIcQMyJE0O+NoxajkII8B/aXf5zPIUxrtqwMr+xkVHmVraNDoBo22yMv9ao7fL+1L9V9L7A9CbX85rjh4tlnPIcYf/DDKBFkBAAA=" } }, { "ID": "0cc49f47eb6e9d1f", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs/a7Avsn4h8S9iJSDyl9MXddCk5t9/cancel?alt=json\u0026fields=\u0026location=asia-northeast1\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "0" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:21 GMT" ], "Etag": [ "cXKNPdBt6srWqAlr8KNNSg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41Sa2/aMBT9L95XICEpjyChiRZWsbbpFJhWaaqQiS/BxbHT2KGKUP77fJPSdrSr9iV2zrmPc4/vgey4ZGRE1jx5LCAvvzyo9QWVMYgIdKakBtIiFiOjw0ehlgRDE4vGd1fhD3Zu+jr/9TgR+fAqDBfJeGwjOGbprRKiTKlsM0hV24A2I6o5bUuVmy1QbbodOpjstTzbDhcB/76YliK4uWPsYtczgS2jQWyuudzZYltjMj1ynKOUTqJUIoBmXHdilb7gzt5zslw9QGy084ECx46gnU/afhUqpoYrOT7RavXESm54UuQ1j/4IRRmeOt5CSvG24SCYJqPfByJpClZ5fbSIKTP8WyyjeXhJqtYrX6T6lZ+Hy9nlLCLVfdUizArmsu62pGsB2OB5uPk/HLaVGDVUQxNh1K5UWB3TGwRvK8/tBl3XG676/cDt9wLXDXx7rFzX80hV1QuwbBRd306mpEEi2EAOdlX+T4jNqNnPH/noNwaeOG67amNJ60KssWecQ+MGr63r9gaeNxwM/aF/hu9jg3PzjrMfXFrJTpmg5w9qAc0jcpkV5hsXoDEIt/gInJemAT2LqsJYOFJPiPgvwDHGR2hNWQSxynETiItzGGWoWAhlbhAaYKEcNOT7ep6fmibwdmkYbGghTDvjGQgucYH0m+Tq/q/02uV3Kc/uFbVzeMPC09twZh+4+gMsEqMdBwQAAA==" } }, { "ID": "54ebe33ec6730813", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "234" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiU0VMRUNUICogRlJPTSB0b2t5by50YWJsZV8yMDE5MTAyOF82NjkwNjU5MDA5MzY1OV8wMDIyIiwidXNlTGVnYWN5U3FsIjpmYWxzZX19LCJqb2JSZWZlcmVuY2UiOnsiam9iSWQiOiJMSklsN2g4cnYxU2RpUE9PZGJpdmdvOVduQzAiLCJsb2NhdGlvbiI6ImFzaWEtbm9ydGhlYXN0MSIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:22 GMT" ], "Etag": [ "JJHM0DwAkWUUvLIFppsJCw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/61VbW/iOBD+Kyi3n04tOAnkBam669JUSwWlB/Sq06lCTjKAt8HOxoYuqvjvN3YSCi1b7UqnfqCZeWbmmVe/WE+Mp1bXitni2xqK7W9fRWydWaDoAqU3N1+G5Or58unh/n4z6F/nubzpPV9cIIJpK7kUWbZdUX6ewkqcK5CqSyWj51wUaglUKrs5uOln/jIoNvYkZXejURqzzUKED7xH0I2EbD5g/AmdLZXKZbfVqqk0F0IsMqA5k81ErPby1sZp5YX4ComSrRMMWpiCbH0Q9o9MJFQxwS/ecEU+awnFDFaUZchIezsvRCzUnyfiNBldNReI37AEaJKINVeaKHpJBJ+zxbowUazui2WIH/xjTaJB1Js2fm9cj0fDhhJPW9FUNM5g5hA7tIkTzDwvJF4nJCR08WdGiOOg6xQjM24cTzVeO62q0f9BS7QVVVRCiZgRSOepA74bk7bt2h4JvXYckNQOXZjPO203DucO6tDOUDJWlAvu2HECPkk8z++EaUwTCEjsprTtuonjJ0AISdNOSq0dlqAAquCKyVxIVpbB6o2jy2k061/PbqPoKrrCAM8Fe4t6GPcRNB3f3/YQjZi8YAJhumz922k0vuxN+39HZbMGsKDJdvIN2zWnmQSMjO2fbnMsjPXXfTT+xypFY5hDATz5yYKhhdF+PL31IOn6vBkljCoVKrFbidQxTUF019hKc7M7vuMEftC2Pc+1DLhQ73S+p3sOPH2rcdqBp/sjFM0+b5H0XSESkBI0aVc7PB65u4wiy39fLE6Nowkh3cZorfK1qpeZ1CyG8ohD4Polh2O549qhbiBlaqwTu9zgxSClYCjNl3G5Bwzp9wOA+TIArEv66sEuBbWHtt85hBirPaT0UUJw8TAXOKDSJMRzkW4Qtn3XQ8L2HlV7d98YlhQ/NCxjuvXoHsdzbNJxDm0rVB3PPjLbR/uxWRlNm8nlej7PoGyZ6bhO3TmpmeQsyyDd1zcRRSrHWLKKeSV5wBgKeCXMaUHRKutzdCOrqDrtDBSkd6e0esDX+qM3Gt4NIrOsUkEuzaRVLwvuvF50uY5rlfXJ7uoxPGt8crp8vZKo/rUz+Lg72/s35+JdAO0bhdNRYzZDmgu8TTNRjvvjDv9woHEzV3ii0tPrg0rIGAeTCmQ0R51ZgI6/X7xJJsplcQJd6Bx3hPHFPWemQuSwfrVQl40mim3gFaaTOYzg287/HeGx8odtVObOHiVMPr4kr6rP9VzZpB1gIbRhjDLkNGVQmNU8xTuhyRK+MFUdaT2B1TVOzSNWDsyvPWNmWI6eqJ8YHF0IPbWwAq6qV6J8ivXBfk999zrkL6UhKq5Gt5G12/0Hm+5KQzwJAAA=" } }, { "ID": "e106eb4528cc39db", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/LJIl7h8rv1SdiPOOdbivgo9WnC0?alt=json\u0026location=asia-northeast1\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:23 GMT" ], "Etag": [ "gMUxIUPc4JEHu8sRsQ9Bww==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/22QzWvCQBDF/5fpNULFQjXgoUrQSOpHVHooPazJmKzdj3Rnog3i/95NWvDS0+xj3o/3Zq/wKU0OIRxk8VWjax4K5E37SJFqxeRHZQ0hBIAsCu8sXvff8X6dPS2ieT2klDajyeUyHnsHZSVqAeEVjhJVThC+X8EIjR7rRgDcVK3a7tJ4OfNa27zVy32SvEySCG7Bnag13Yl4uYtmUfof8nEL4GQPKR7RocmwLVA5e8KM4/Y2Kq1SjRaml6O2PUZi6Ihumyxi9VwO3bm/zeV6tcoP8lzY0ZuZPnqXsplgaY03CpKiZ6zjEgVx31cFtixUai/+UhjAn540PmHtbIZE2CYMBr9xU6srhez7sasxgEz4/5pLhvAoFOHtB1qW6/+NAQAA" } }, { "ID": "38b4da3f076c225f", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_0edfd2e73b0413160964b80d193eff543b9f2b04/tables/anon21bce70c66759dbace80b3da433c27ce000dd5da/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:24 GMT" ], "Etag": [ "XDOQq9TANTgTh6JbIYVV3Q==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8pHuPgHFlqGOPqFpIdkmHkleUaGhRkH2toCVZTklyTmBOWXFwOVGQP5RWBmdLVSGpgsAwonKtXqQFgGSrWxIDZCLgkuZ4ghlwyXMwLJxdYCAMT08miwAAAA" } }, { "ID": "0b243cf889d26577", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "389" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7ImNvcHkiOnsiZGVzdGluYXRpb25UYWJsZSI6eyJkYXRhc2V0SWQiOiJ0b2t5byIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QiLCJ0YWJsZUlkIjoidGFibGVfMjAxOTEwMjhfNjY5MDY1OTAwOTM2NTlfMDAyMyJ9LCJzb3VyY2VUYWJsZXMiOlt7ImRhdGFzZXRJZCI6InRva3lvIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCIsInRhYmxlSWQiOiJ0YWJsZV8yMDE5MTAyOF82NjkwNjU5MDA5MzY1OV8wMDIyIn1dfX0sImpvYlJlZmVyZW5jZSI6eyJqb2JJZCI6InhnZHRMM2dYU0NOQkZzZTVmV3lJUTVxTEV5MiIsImxvY2F0aW9uIjoiYXNpYS1ub3J0aGVhc3QxIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:24 GMT" ], "Etag": [ "s/3U35Jk4x2N5CqcJTzCYg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/7VSXW/aMBT9L95ryYdDgERCq4a2iQpla0e1VlOFjLkYl8QOtlM1Q/z3Xoeyh7ar9rInW+cen3Puvd6TrVQrkpOlFLsGTPvhXi/JGQHHBKI2TK6T9GLbf6RFOtnxi/nvya0Yj5Eh/Su70WXZVkz1VlDpngPrcmYl6ylt3AaYdXHwKFZuloibH5Pi0xcL6fpnO71Md7PPLUUZC+V6JtUWxTbO1TYPw1OUQGgtSmC1tAHX1R88fKBhbfQ9cGfDNxKE2IIN37H9WGrOnNRq/CIr5mksmAVUTJaYyKv1jF5qd/6GTyBZFQjkP0gOjHPdKOeDogrXai1FYzoXku8RqFt/Wt0YDnO2LMGS/NeePDcy/cs0UWvFHLNwZDi9bTVizgscEX9b0CjO4oiOFoNBFg3SLIqyBI9FFFFKDncoglpSdXE6c5/lv1sn5HA4I7iNeVujI5l8+35LjsgVrMGA4v8YBF901ff/0mmtSHy5WHS1Dos4BW67hRg4TkNWPlqcDikdDUf9/iAeko5s3OtaFp2Umk7F3zzl6roopsVX7PcJ36lGllEDAAA=" } }, { "ID": "25e2498acc5a3272", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "387" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7ImV4dHJhY3QiOnsiZGVzdGluYXRpb25Gb3JtYXQiOiJDU1YiLCJkZXN0aW5hdGlvblVyaXMiOlsiZ3M6Ly9zaG9sbHltYW4tZGVtby10ZXN0L2JxLXRlc3QtdGFibGVfMjAxOTEwMjhfNjY5MDY1OTAwOTM2NTlfMDAyMi5jc3YiXSwic291cmNlVGFibGUiOnsiZGF0YXNldElkIjoidG9reW8iLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0IiwidGFibGVJZCI6InRhYmxlXzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMjIifX19LCJqb2JSZWZlcmVuY2UiOnsiam9iSWQiOiJmRWNMS09qaXNtbXlyWmdja3lNcU0zb3MxY3IiLCJsb2NhdGlvbiI6ImFzaWEtbm9ydGhlYXN0MSIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:25 GMT" ], "Etag": [ "Oc6ii0yVq3kOXLEK0C/f1Q==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/62Sb2/aMBDGv4v3dkmcUP5FQtuE2FSVgsbSqto0IcdcgiHJge2gRhXffee0TBpj3V7slS/n5373+HJPbKuqFYtZqvJ9Dbp5s8GUvWVgRU7ZuewpxZv7fWc7f5hObvg4yMLPoxEplKsyayyKphSVt4ISPQvGxsIo4VWo7RqEsaGfTeT0Zr5Rpiwb/TWX2+Z2f9tBE0pNGANFNlXVlmBra3cmDoKTFT9HzAsQO2V8ieXPfHCIgp3GDUhrggsOAnqCCV5p+65AKazCanTmlfzUBvQSSqEKcuRonsYU7fsLfXwlSj8n/UFJEFJiXVlnlCgSq0zltW67sPiJwaPVQloXGqy1hESkBbjPl5dc/2GcBFsJKww8KyxuG6ScdeXPGRctIx4OQx4Nlr3ekPe6Q86HHTqWnEcROxKDUKpq7dxpRWW5m/Sl4aX79vT+zvWlObBztGHxt/8G//4L/SPqUtAI2fjLvXsT/eak2dEQ2eQhWXwYJy/JBWSgoZL/OF6qaG9f39PTypDwfGmoq7F0SUalcT2lhlabqNK5C7v9KBr0B1fdqM9ZK9b2t7urQedEqluKi5xkcTebXc8+sePxBwHDfButAwAA" } }, { "ID": "00795b336d1cb6db", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/shollyman-demo-test/o/bq-test-table_20191028_66906590093659_0022.csv?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 404, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "263" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:25 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Uploadid": [ "AEnB2Uoiqp6WJaYWzofk2bQElccI6vK-cpV5Imql7uPEcOwRp0cqg31IF4qngoWai6LCTXvp41gQ-_fRo_BMOvPyN7d9DHgRUBYc_-pwqTIPpt3YZtirupI" ] }, "Body": "eyJlcnJvciI6eyJjb2RlIjo0MDQsIm1lc3NhZ2UiOiJObyBzdWNoIG9iamVjdDogc2hvbGx5bWFuLWRlbW8tdGVzdC9icS10ZXN0LXRhYmxlXzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMjIuY3N2IiwiZXJyb3JzIjpbeyJtZXNzYWdlIjoiTm8gc3VjaCBvYmplY3Q6IHNob2xseW1hbi1kZW1vLXRlc3QvYnEtdGVzdC10YWJsZV8yMDE5MTAyOF82NjkwNjU5MDA5MzY1OV8wMDIyLmNzdiIsImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6Im5vdEZvdW5kIn1dfX0=" } }, { "ID": "ab39375fa85f00de", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/tokyo/tables/table_20191028_66906590093659_0022?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:26 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6uuBQBDv6ajAgAAAA==" } }, { "ID": "b2ddd272cf682063", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "238" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJleHBpcmF0aW9uVGltZSI6IjE1NzIyODgzMDcwMDAiLCJzY2hlbWEiOnsiZmllbGRzIjpbeyJuYW1lIjoibiIsInR5cGUiOiJOVU1FUklDIn1dfSwidGFibGVSZWZlcmVuY2UiOnsiZGF0YXNldElkIjoiZGF0YXNldF8yMDE5MTAyOF82NjkwNjU5MDA5MzY1OV8wMDAxIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCIsInRhYmxlSWQiOiJ0YWJsZV8yMDE5MTAyOF82NjkwNjU5MDA5MzY1OV8wMDI0In19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:26 GMT" ], "Etag": [ "VCJ3jzIwFvLeC1eviigbWg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42SX0/CMBTFv0t9FdptsH8JD0IwwQwfEPTBGFK2yyhs7VwLOAnfna4BTUTNntp7cs69v970gDaMJyhEC5a+b6GsbhRdZIBuESiaav158OCsP0f7+10EAwt2jKWLl7TX0w5W5+RKZFmVU95KIBctBVKFCVVUgprbxAosYvtz1w2I2w0ICRx9zAkhVtvM+cdid/QICdkyYnyjB62UKmSI8QW0nQqRZkALJtuxyL90vLNxUYo1xEriX+jwmU7iJpjYYErciNaYJrCEEngMKDygM8joj03pzBnCOJoAXcaYQAOqo15ivIKc1jhLBlkiUfh6QJzmmhDxul9V1NfH2Xg4GQ3Q8U1n+DbvVxpR6wSZMhI8nUL5U56I/aWKS6CKCT5lprXV9Wzb9/yO67he/aE+ClZeG3yHePph2pBRqcYiYZoyuerRIe436vSuHw3rhIhNQy3NntDxBKgcG+jNAgAA" } }, { "ID": "c25c2e90ac29b7ab", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0024/insertAll?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "121" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJyb3dzIjpbeyJpbnNlcnRJZCI6InNoUUFxZm9lMDNRQ1ByZloxc0w4eEtLRGNkciIsImpzb24iOnsibiI6IjEwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwLjAwMDAwMDAwMCJ9fV19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:26 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42MuwoCMRBFf2UZ20XWNp3oFim0WLASi4kZQzBONA9RFv/dYQVtvdPMOXDvCGfPFhQY726V0nNW0ARaY0HNmVJZhjBQvkYBaMFPrk8ppgxqP4qw9ADVtUA/mQhzZBn1fMfgrRRDPGLxk2RBS6Y6zacoLHihnNGRgP40mu1u0w961QhVUs2i+zPz7wevg9wb8ASitOAAAAA=" } }, { "ID": "e1cb068c3ff76b8e", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/tables/table_20191028_66906590093659_0024?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:26 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6uuBQBDv6ajAgAAAA==" } }, { "ID": "5dc84b71847cf7d7", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "167" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiYmxhaCBibGFoIGJyb2tlbiIsInVzZUxlZ2FjeVNxbCI6ZmFsc2V9fSwiam9iUmVmZXJlbmNlIjp7ImpvYklkIjoienQ0QkZLa256NmhGa1ZKVEVQU3h2WURFSGVqIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:26 GMT" ], "Etag": [ "HZMdEQeqbQppZ01jSgJgEw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/72SW2/aMBiG/0rk3ZZkoLagSGinpipd1w0SKvWkyXG+GBPHDrbDSCv++2xDp01jvdxNFH+H933yOs+oYqJAMcoZXbWgujdLmaMjBAZTW724+1IkU1jl06a5e9tfpvSSJj/GYzvB3JZeSM67GoteAbXsGdAmnqfhkzn+eP65Ek+ni/Pq5jJLvqWb9e1ZcgFLu6mBl1dMVHZ/YUyj4yh6cQ+plJQDbpgOiax/1aP1IGqUXAIxOjpgGllqHb1i+45Lgg2TYjxPLUKrQX2HGjNuIZxAT8lcmvcHpEOG65Da+TUjgAmRrTCOzaoQKUpGW+WFUfyMPOtvLyjneBHsHkpWIOxSo5hUzLju5DpLZh8+ZZObZMd0BRSTLl1ZqhJzDdsjZD8s6xqw09N5MrtFu9IMSlAgCDizfTCTf1wI8hu++/q9vERkB21I1kgbe9aGEe1siALfzljtcPonw8FgNBwdnw6HA+SHlfm7Nzpxf5MoDnb2Hq3XB6WkmoFuuXFH66Y9CxNrzFkx9ZH+Qbnal2rQGlMnn3bC4E3gpeJgLmDT2GSgCFgBwrCSgQoe/K08oACb4L4f9x8dht+wGPf/1/hxF4BTOPt6naDt9ie0p50qkQMAAA==" } }, { "ID": "08a3931fd8e63d0d", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/zt4BFKknz6hFkVJTEPSxvYDEHej?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:26 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/61PvQrCMBDe+xRHZgcFp24FRQoqqK2LFjmbUwNpUpNULKXvbhs7dHB0Or7fu2sCAEbGaMNCaDrQwVxz6tB8Op18iYKsxXvPsUOtHL7BJ0JIFb1Lyh1xEJyUEzdBBs7sKvFxZoAOTrNwlrGhx6dsV3PyGIaF/9zhu7guUKi+6i71FeVYM4RWe02oF0rBdxWZeuyQOkcnvp7nLyGpS39niQYLcmTY4Gn9zIZvrUNX9d+yeHuM1vHiEu1X6Wa5TXp/G7TBB3+aYz19AQAA" } }, { "ID": "037ba80101748cf9", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "507" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiXG5cdFx0Q1JFQVRFIE1PREVMIGBzaG9sbHltYW4tZGVtby10ZXN0LmRhdGFzZXRfMjAxOTEwMjhfNjY5MDY1OTAwOTM2NTlfMDAwMS5tb2RlbF8yMDE5MTAyOF82NjkwNjU5MDA5MzY1OV8wMDAxYFxuXHRcdE9QVElPTlMgKFxuXHRcdFx0bW9kZWxfdHlwZT0nbGluZWFyX3JlZycsXG5cdFx0XHRtYXhfaXRlcmF0aW9uPTEsXG5cdFx0XHRsZWFybl9yYXRlPTAuNCxcblx0XHRcdGxlYXJuX3JhdGVfc3RyYXRlZ3k9J2NvbnN0YW50J1xuXHRcdCkgQVMgKFxuXHRcdFx0U0VMRUNUICdhJyBBUyBmMSwgMi4wIEFTIGxhYmVsXG5cdFx0XHRVTklPTiBBTExcblx0XHRcdFNFTEVDVCAnYicgQVMgZjEsIDMuOCBBUyBsYWJlbFxuXHRcdCkiLCJ1c2VMZWdhY3lTcWwiOmZhbHNlfX0sImpvYlJlZmVyZW5jZSI6eyJqb2JJZCI6IjJKQ1kwbjFMUWVOTUgzNzVuOXM5NlRydjBFayIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:27 GMT" ], "Etag": [ "Sbv6TksWcTHiS+tCdkhiVA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41TbU/bMBD+K1H2oUMreQPaplK0VV20dQphNCkTUqXgpNdgmtjFdqtViP++cwIVYh3jk+2757l7fC8P5oqyhTk0c1reb0DsPtzx3OyaoEiJ1iTf9tKV/FWk32nySY0Xq1t6NQoCRFDNkre8qnY1YccLqPmxAqmGs8TyfoyvHeZGlxCffz/pnzFf+r1UbJ1whUwJ1TKibIX8W6XWcmjbz9mtkvOyArKm0ip4vbfbW89eC34HhZL2gaQ2qpb2G2k/V7wginIWzBKUsJEgMqgJrVCEDnAseM7VlwOhLUpqq0T8lhZAioJvmNLaMErB2ZKWG9EENocPZqP1xcWcs7maq/E0HKWhcX7xNYyMm0M5FkQRCSrzHNd3HW+Q9Xq+0zvzHcc/wSNzHMe1ar6A6k3ITZvv4mc6uYgT42P7nKuWqXZrCDoVZUBEJqDsdPd+8jujCtqPBO7ejp0QLEMzBI51esCcSaWPchd0sBhSEaY6LerIGL0QkIRROE6NDulo89LtGp7l6GtFcqieUbMYZRujKHpNy/e0E2vwinaEjVhgDSlr1Kckr0C34GlcJv8YU81qi94g3tMApCgdvSH8vxnmYxdFUC6o0qMwidNwOhqnk6uwHcAISlLsknscwSWpJCAcpzjFJiH6chZOr83WNIUlCGDFO7+FjMb79hI+7wMCcSMwETZPUSxjIXWaQkBbTlprOe5Z3/MG/cFpv60DgoX62+f30LdfAh0RamDq6U/tGmTNGpiPTyk3cg9FyHQWx5P4G3r/AN85IDuZBAAA" } }, { "ID": "4768ba8622cb9b2e", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/2JCY0n1LQeNMH375n9s96Trv0Ek?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:37 GMT" ], "Etag": [ "pcxo4Hkib3GG9z+RBIypTw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/yWNyw6CMBRE/6Uu1QTFRyBxozGgURMQFy5LuWKh9FZaH0j8dyuuZpI5J9OSksuM+CTl+e0OddPLwUS/EoO+C6NtKJQayICAobklFXvhJCx56gaB9+7Hy02jkudiYYkC0xguUINkQPyWqBoLYGbzO9BXFKKpqBxmUOHQgDZ/o1vH29XZkaNdBId96M6n0tPeLKkfzrq0lEBGDUdpwdORfDpthZUSYOzPhQoNny+eToOdygAAAA==" } }, { "ID": "4757002d0fa2bba1", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/2JCY0n1LQeNMH375n9s96Trv0Ek?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:38 GMT" ], "Etag": [ "niNAoZehTSAO9vVoA98g0A==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/yWOXU/CQBBF/8v4WpKqEW0THgoxQaIoXybytiyXdmG7U3enJA3hv7uVp7nJnDl3LnQybk857Uz528J3dyVk0YclQmslxNGwC6CEIKqMpDPzgreo1qviMzt/c5G9lGkxGkXiyLslDvBwGpRfqPF8hJa3viBUbG1XKzfYo+aBIMjt4n/7MJv8pO7+fYH5x/Tx+cllIRuu/Tl9PUXKslZi2EVws6JrQsKi7LiLki/PGiGgl6Q34YTrxkLiB+JbJKSVrjA1QvlB2YDrHxR4hKL0AAAA" } }, { "ID": "95e1257270239ff5", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs/2JCY0n1LQeNMH375n9s96Trv0Ek?alt=json\u0026fields=status%2Cstatistics\u0026location=US\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:38 GMT" ], "Etag": [ "HRm7ADrqvWPGSVogti5ulw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/7VVy27bMBD8F54TgKRelG9NIqAF4lpo1VMRGIy0jllQj1JUAMPwv3cpRnESOe2h8UnkzuzMcgmu9qS30qreqrIniz0pDeC2bQpVA1kQFiWci0SECaWMXDiysXMsjRGDpnqDRCIQAhHbWqmvdhb63LQl9D1UyKKI/B7A7JzvuMi1bMji5540ctTJDXQ+AalqyhlrWPavKuAs9RW8ikeMx7HPsIMDrlfL/DYrMnK4eDYpjFTNpM9O6k86M/0oTei/9LNHqQdpYbLgpy2epGYWIohCl7EdNhsNq8F2gx1beezGW+87lMELrdG0Otl1xECrBsZeg5YdQt41pNN1fdetr9BFOixLNQ8/GmWnUNnWnQZ0eBmUpVWPcIy4NrzUD0RyVn0eRdEHGrCZQciSj+wQnxlEIhRnNUjCJDirQRoH5z0Bw9fIZw6cCh7+j8vdk2KOT1O5ETh/Nu+OsSNypbR+Dt/jBmspFBiyYO9VXMpyC5+VJYuN1D34Jw01NLbYdW6CXH/LPhXZerm6yW6RX1V61YEZx3QOZtOaenT0NE8opHkAW8h7DW664hT9BaX94mj9ttV6V8vmsoK6vcSarcuRVvbgGU/rNacsZZSLdRynNI5SStMAP2vq/wXWqY8JdVuB/jv9cDh9/MNxgu39wRG6WX3FMXb4AwaWhuucBgAA" } }, { "ID": "b87f4e2da67db5fe", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/models/model_20191028_66906590093659_0001?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:38 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/31SbW+bQAz+L/c5mQ5IeInUDzRlKVpCOqDatGlC1+AwpoPL7o62aZT/Ph+hVVpF48sZ+7Ef+7EPBDSryIxYO7hr1Pc4TZ6dl9todf1tlSyqqysyIo0ogaewBQntBsjsQHZS/IGNjktMVL8F5/uGteMSGjHWoDTmlEwzBSfEYBc2tQKL2n7hugF1pwGlgYNPQSm1Xmn6hN76P/w4IhsJTNeizesGzABTz7Z9z596AXWwHGdKr0RZb2soP0J8x7VfGfP9zsSWcRKFaZFGizTKsnidYFxLVrd1W6Vdq8js5+HNsd4ZYmWkaNhzrEGywUHMJFwoNZRdRWFSZF/vwzS6KZbrLDNhYLJNmcY4/TTBfyuFquNM1i99GXSj077gbOo2BY7/j3AnRSVBKVODWiPyxGSTaSY1mW0ZVzAiyML3mRY7MtOygzPeDOfQUO2xv/k6yfIwybEtgUM1A9sZ4jrM57fFIg1v4ijJi5som+NrFoD0HdcnZeq2hOe+x7I7ibEyajhOv4tX3Zbi1LBr+/Tss6yPohx/Yf+PjHenUqBlvenlltBP/d7ZAGvDByV4pyGSUkhTY/qOglJv1OOyvx2TUL7BLrRyBluK6g1JnanjB5Y38T3PRYNODLSsL3DTyXtux0W1hpImbtsTN7AcbLE3aHBEOZXZ3nCp5vbHFh3bfm75M8eb2R5u2f5BjDBbvPtOwhw5m+EwW9anbc316f7yDv37BfeC/ixP42RBjiabswfgF3J32Fu90VAWPeJyoc/LdZi7k6GS2AynSe4zcvwHomKWvksEAAA=" } }, { "ID": "69125c36d9b9f7f9", "Request": { "Method": "PATCH", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/models/model_20191028_66906590093659_0001?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "81" ], "If-Match": [ "1pePmsXIRNx3zHEMBWMNGg==" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJkZXNjcmlwdGlvbiI6Im5ldyIsImV4cGlyYXRpb25UaW1lIjoiMTU3MjM3NDI1ODgxOSIsImZyaWVuZGx5TmFtZSI6ImZyaWVuZGx5In0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:39 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/31TXW+bMBT9L35OJvMNkfrAUtZFS8kK9GGbJuSGC3NlPmpMmyzKf981oVVaRePF9r3n3nN8fDkQUKwiC8J/2Lt0U943ztPjwx29/+5Ylbq7uiIzUrcFiARKkNBsgSwOpJPtI2zVqsDC/k8rxL5mzbyAup0r6BXWFEyxHk6IaZ+b1AgMavq56wbUdQJKAwuXnFJqvNKMBePu//DjjGwlMMXbJuM1iiKG45mm7/mOF1AL2wnWq9u24CWH4iPED1z7lTHbdzq3XsVRmORJdJNEabraxJhXkvGGN1UyND1Z/Dq8BTadJu61FTXbrRRINgWIvolo+35qexuFcZ7e3YdJdJ2vN2mq08BkkzCFefrJxrORQDUIJvnfsQ2GMWheCNa8SUDg+Rm+y7aS0Pe6BzVm5IXJOlVMKrIomehhRpBF7FPVdmSh5ABnvCneQ0G1R33LTZxmYZyhrBYvVU9sZ4jPYbb8mt8k4fUqirP8OkqXuOoHQPpBqJMzvClgN2oshpMZt9oNyxrf4tW3dXsS7Jo+PfsM46Mpx9+o/5mJ4dQKlOTb0W4J463fB2tgTfjQt2JQEEnZSt3DeUdBqTcbcenTwCQUb7ALUs5g67Z6Q1LLsfzA8Gzf81zcUFtDC36Bm9rvuS0X3Zpa6rxp2m5gWChx3NDgiHb2+vWmSdWzPzfo3PQzw19Y3sL08JXNn0QbU+LcDxKWyFlPg9mwsazU06fGyTuM6zd8F4ynWbKKb8hRVwv2AOJCbYfa+FZBkY+Iy42+rDdhhv/O2KmAfit5d5pO0sAL1pSSQ1OIfTwJmo6YgV3H5ccf1vJs0/F9IyDHf/Z8lJ2KBAAA" } }, { "ID": "8e506a3363d098fe", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/models?alt=json\u0026pageToken=\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:39 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/32OwQqCQBCG32XOCqOm7nrrICGUgXqLkMUdyVBX3L2I+O6Z1qVDp/lgvn/+maFTkloN0W3eMaOaRuorgmiGYVRPqkwiIQL9UG07daK3JXXKNqQNWCCFEZp248Oliw530GVlEHAMfI7IvXWUiOiska1mC2z0X18sqEYSplF90XTrU+D4oeuykPkhR2891wptLko2dUPyV2E8OHwbi2l4785JGh+zMotPWZznyTWF5b68AAuE2UUHAQAA" } }, { "ID": "e9a81ef08854dd2e", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/models/model_20191028_66906590093659_0001?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:39 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6uuBQBDv6ajAgAAAA==" } }, { "ID": "1671095c16c0bfd8", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/models/model_20191028_66906590093659_0001?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 404, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:39 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/82PMQ+CMBCFd35F01nMgUiE2bAJi07GkGormrRcwpXBEP67bWVwcna6vHvvct+bIsa4GgYceMkmJ5y8oVROZZCtPgujiETnd7xGy+449rJkBxfTjB6o9cuIPpbKYGwV2VIKK0jZNoWkSCDdtXleQL4tAIqNGy0AJGvjz39G+PI+4JH7fg6aLZx/gBYQJBrx7D1Bp/Eq9Lc3KEEYvB5t5eH4Ys5hXpaKZIUdKbRojm3VnOq9D87RHL0B/Mu5Z6IBAAA=" } }, { "ID": "34d694d29ddf7f9b", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/routines?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "292" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJhcmd1bWVudHMiOlt7ImRhdGFUeXBlIjp7InR5cGVLaW5kIjoiSU5UNjQifSwibmFtZSI6IngifV0sImRlZmluaXRpb25Cb2R5IjoieCAqIDMiLCJsYW5ndWFnZSI6IlNRTCIsInJvdXRpbmVSZWZlcmVuY2UiOnsiZGF0YXNldElkIjoiZGF0YXNldF8yMDE5MTAyOF82NjkwNjU5MDA5MzY1OV8wMDAxIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCIsInJvdXRpbmVJZCI6InJvdXRpbmVfMjAxOTEwMjhfNjY5MDY1OTAwOTM2NTlfMDAwMSJ9LCJyb3V0aW5lVHlwZSI6IlNDQUxBUl9GVU5DVElPTiJ9Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:39 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/32PT2uDQBDFv0qYY2lg1fgXcoiBFok1JLGHthRZdLTb6m7QFRTxu3c10p7a0zxm3m/mzQAoaQEexC+GIP6X3T0Sn7525BIejuK03cI91KKVjOMZc6yRpwjeANdafGIqg0yhzYcoy76ifJ1hJdYSG6mojEra4M2x6EQnmqsR3UksyyWW6RLiGqokhBDt99CMLPp/ZPxh4v6qcsFlvwt35+ThOdrHwTFSO9MaqWSCx6yaDJpp67pjO6a7sQ01Lmkjn0TGcobZnxZetLSY159C1aB10VbIZQPe2wCczlS3vHwLMoBU9cD49EoQxdYGxvFdOTBnnE15fJH1E7a6WxkwfgPK8JBKhwEAAA==" } }, { "ID": "52d137124d3ddadd", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "447" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiXG5cdFx0Q1JFQVRFIEZVTkNUSU9OIGBzaG9sbHltYW4tZGVtby10ZXN0LmRhdGFzZXRfMjAxOTEwMjhfNjY5MDY1OTAwOTM2NTlfMDAwMS5yb3V0aW5lXzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDJgKFxuXHRcdFx0YXJyIEFSUkFZXHUwMDNjU1RSVUNUXHUwMDNjbmFtZSBTVFJJTkcsIHZhbCBJTlQ2NFx1MDAzZVx1MDAzZVxuXHRcdCAgKSBBUyAoXG5cdFx0XHQgIChTRUxFQ1QgU1VNKElGKGVsZW0ubmFtZSA9IFwiZm9vXCIsZWxlbS52YWwsbnVsbCkpIEZST00gVU5ORVNUKGFycikgQVMgZWxlbSlcblx0XHQgICkiLCJ1c2VMZWdhY3lTcWwiOmZhbHNlfX0sImpvYlJlZmVyZW5jZSI6eyJqb2JJZCI6InJ6Tks1S0thcE8zbmVsbDU3WWVwbUZhWVg0QiIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:39 GMT" ], "Etag": [ "Mty5paeXKV0PUAfAa0c6sA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/31Sa2+bQBD8K6frF1tyAJNAbEtWSy1cWXZIyyOKJSTnQtbkEuDI3RHJjfLfu+CHKjXNFzh2Z2eG23mjz7x6oBN6z/OXBuTuy5O4pwMKmuVYvdI7p2Zwu7yxfibe1mNW5ipvOkUEb6fUoyiKXcmqswcoxZkGpSdJZMjfwdJZLll9fV5BUTiXa6jLOVvfXnzHSQXFdsWrZ5x/1LpWE9M8qhu5EHkBrObKyER5qpuvtllL8QSZVuYHoia6VuYnsl8LkTHNRTVNIrTQKJAbKBkv0ERLcCbFvdDfPqA2OCuNHPGvPAOWZaKpdOsNWTJRbXneyI6YTt5o5/WvA02rVKd6Fvpe7JN5EszixXVA7j6SeWCaKdAb2xqOh5Y92rju2HKdsWWNz/G1sSxraEjRaF7BZyD7rrdXTTWTknhh6K3TxrLOsygOk1m8P1esBIKFRfBjQF5ZQRZB7F50PTg8OxJC+sSLyImSkF7kr/xZTKLkqreY96CA0ujYpiSlWyFSOuhqSDqomqLo98k8vL4iSRD4UdxDTx1ji+mfNPAya8mF5Lq9NfTihx7e1Y2/39UKcpbtohfc1pYVCt4HFBce72pA9K/ED9d0XwphCxKqDNolHAKz+E9QaTfRdT/P6zE6CMTwoJDS+K00z1Qrk0no2jEvWztD59K2R5cjZ+y4Lu3AUv/Tc+0L7J3y0jJCCZU+/NM+MZtjYuj7QbVRJzSiQrxTXCB2/wDqwd9hxwMAAA==" } }, { "ID": "1afeedbce09a7bd1", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/rzNK5KKapO3nell57YepmFaYX4B?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:39 GMT" ], "Etag": [ "KK1s4mbAhpJgHow1z/lxmg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/yWOXUsDMRBF/8v4ukWLLcJCH2xBqgE/KoJ9zKa32a1JJiaz6Lb0v5u1T3Nhzpw7J/rqwo5qajr73SMNVxbyNoYNcu8klxE5ZFBFEG0LqdQ0z3xz38Ynu+af6fHa/Xq7WBTiwM0GeyQEA6pPFBMfYORxLMgtOzd4HSY7eJ4Islwu/rfp+KzmSun4chvg3Pxui+gf9PZztiyUY6Ol41DAj3c6VyQs2i2HInlNbJAzRsnNRbhiHx2kfCCpR0VGmxbrTqjea5dx/gM00fSa9AAAAA==" } }, { "ID": "620b59aae4367517", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs/rzNK5KKapO3nell57YepmFaYX4B?alt=json\u0026fields=status%2Cstatistics\u0026location=US\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:39 GMT" ], "Etag": [ "kkYL1Hr2AMbmSHaxi93JyQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/32RQVODMBCF/0vOdiagUOBmax17EJiKZybCto0TSE2WA9Ppf3cTGD0wekqy73u7ecmVWRQoLcrGsuzKGgN01H0lO2AZC6J1GCbrJEqjOGZ3Dja40OLwgTTo26WSJqSgRqE2I4ItjW7AWmiJ4qR8DWBGN9cjJTWXbvqC+7vDr7KRSv2UP+gg+1MlwbAsmLE3pfHVzkQjmjO8SGTZUSgLPhtCBz1W48Wl2B52j9Wufn7Pt9W+yMnStqq4gPEPVII5atP5gRM5AZUwJ8CDHlD24JJdjP6EBvcOtGet1NiJftVCp1d0aXQugcLCRMz7OuRBGvAwqeM45XGUcp7e01JzzgOymKm/t8z7/ywhu92Wb3CbMg/+4316Kj8V+Y7ob/G5Zy0YAgAA" } }, { "ID": "6039e321d7b9f17d", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/routines/routine_20191028_66906590093659_0002?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:40 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/32Qb0/CMBCHv8rSV5AMU4ZMRsKLSYBMYejWkRg1pLJjzozWdB26kH13b5NgjH/25pr2ee5+twMBzRMyJDdR74le7XurcjXjKyjfFzfsLRmNiEmULHQqIIAtKBAbIMMDeVXyBTbai1HNn2WWlTsuOjHsZEdDrtGKueY5fBLH89qiXadLrcHath1q9x1KnR6WNaW0+zWoUY7n/xSLVCeHla+Yi4Rjd+4G62nkj5m39LHnRgHXqRQs3dVAt39hWYOLQd+xBw4+ZzzXCxmn2xTiPxGRFDxp2t/O8YKrpNiB0DkZ3h+I4I3FlTou/RnlQDTW61TUy7hB4N41puLlJIPa/gULWRCNGXK5VsXmRGC2LP42rClmo/5s4fkzUlXmCd7z7HfW85l9juhjhd8jhodtKtL6Z13KuESgFU7mkzEzwmjR8qYtwOBndVNjZDyQrZQPxGzucIIpiixrt41psFwYke9PQtbCbduGGxo10ybVB42Tk9drAgAA" } }, { "ID": "97366e446d40d857", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/routines/routine_20191028_66906590093659_0002?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:40 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6uuBQBDv6ajAgAAAA==" } }, { "ID": "477418610767222e", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "289" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5IjoiXG5cdFx0Q1JFQVRFIEZVTkNUSU9OIGBzaG9sbHltYW4tZGVtby10ZXN0LmRhdGFzZXRfMjAxOTEwMjhfNjY5MDY1OTAwOTM2NTlfMDAwMS5yb3V0aW5lXzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDNgKHggSU5UNjQpIEFTICh4ICogMyk7IiwidXNlTGVnYWN5U3FsIjpmYWxzZX19LCJqb2JSZWZlcmVuY2UiOnsiam9iSWQiOiJ6OEpnZ0IwZzZCZXFhOFpJQmhnVTBSbWljMUQiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0In19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:40 GMT" ], "Etag": [ "Amn3GQrlbksaVntI4dJwLQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/31Sa2/aMBT9K5H3ZZ1KEkIbHhPaoGNVKpSJQCptQqLGXIxLYoPtdGNV//tuwkOTxviU+J5z7zm+x69kLeSCdMhc8G0BevfuWc3JNQFLOVZ7uWzcj3Q2Xxv6KG10s3j4ORx1u8gQZZdZqSzb5VTWFpCrmgVjO+nY/d164Lzv87APW9r6EfVXPPWTXLD6F+w0kC2HQq6xf2XtxnQ876jucqV4BnQjjMtUfqp7L4G30eoZmDXeGVEPXRvvguynTDFqhZLddIwWCgN6BjkVGZooB9S0miv7+cxoV9Dc5ch/EQwoY6qQtvSGU5iSS8ELXQ0mnVdSef3rh0zl1E7tXTLoTQbO1zS+m0TfYufpnMyCWmrAzgK/3q77QWsWhm0/vG37fruBn5nv+3VXq8IKCZdIjaf3v5wonoQ3V05v7ODhg9O4+oh2N1ooLWzpC/FB0kM3j4P9NobAKduNt7iPJc0MvF0TXOlktwFkj9JB8p3sSwksQYNkUF7zEEn0n6dAqo4KvfwijuEgEeNBIWPxbKxgppRhGip4IvLSTv22GQStZiv0gzAgFVnbf7BGs43YKZFyIuQg7eFO+0xmx0zI20G1MCc2spI0jqP4HtE/LwEbLCkDAAA=" } }, { "ID": "5cba0e3ee24aecfe", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/z8JggB0g6Beqa8ZIBhgU0Rmic1D?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:40 GMT" ], "Etag": [ "Cuem33Jpkuy0ZJR1C7QpJg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/yWOy27CMBBF/2W6DVIQUosisUm6KFmVIDbsjLk4Br+wx4uA+Pc6ZTVXmjPnzpNu2p2poZNW94w4fSjwbg4DUjacygjeJVBFYKEK2WXY1aoPtzzVx35Ydl+70KvNphBXfxpwQYSToOZJIforJG/ngjR6YyYr3OIM6xeMxO+L/+1j3SvV1uqzxV2sj9t2VId6sFouvwtlvBSsvSvgYU+vitizMO1UJL/RS6SEWVK/hZ23wYDLBxwzKpJCjvjRTM1FmITXH2A4nq/0AAAA" } }, { "ID": "5ce510f3f0fbff4b", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs/z8JggB0g6Beqa8ZIBhgU0Rmic1D?alt=json\u0026fields=status%2Cstatistics\u0026location=US\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:40 GMT" ], "Etag": [ "k4V0noqkLssnU4MtvzQxYQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/32RzW7CMBCE38XnIjlJyd+t0FTlUEA0PUdusoArJ07t5RAh3r1rJ2oPUTnZ3vlm12NfmUWB0qKsLcuvrDZAR92VsgWWs2CZhGGapDEP45A9ONjgTIuSjDTompnymEakoEahVgOC3Rtdg7XQEMVJ+b6AGdxcj+ypuXTTZ9z/Hf6UlVTqt/xJB9mdSgmG5cGEvSuNb3YialGf4VUiy49CWfDZEFrosBx6l2J9KJ7Konr52K7LzW5LlqZRux6Mf6A9mKM2rR84kiNQCnMCPOgLyg5cst7oL6hx40B71koNregWDbR6QZdG5xIoLIzEtK9CHmQBD9MqjjMeLzPOs4iWinMekMWM/b1l2t+zROx2m7/Bbcx88R/v01P5ebctiP4BP1RJ7xgCAAA=" } }, { "ID": "235c0d2d211f8b25", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/routines/routine_20191028_66906590093659_0003?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:40 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/32PT2uDQBDFv0qYY2lg1cR/kEMMtEisIYk9tKXI4o52W90NuoIi+e5djbSn9jTDzPvNvDcAKlqAD8mLJUnw5XSPJKCvHTlH+4M8bjZwD7VsFRd4whxrFBmCP8Cllp+YqZBptPmQZdlXVCwZVnKpsFGaYlTRBm+KuU9NYngGMd3Utj1irz1CPEuXlBBi/D6akLn/D7Hg+sMk/UX7gvNuG21P6cNzvEvCQ6xvZjVSxaVIeDUKjLVjmq7j2mRle3pd0kY9ScZzjuxPiShaWkznj5Ee0LpoKxSqAf9tAEEnqpsj34wMoHTdczFGCePEXsH1+q4VmHPBRz+BZP2ILe4WOsc3XIfztIcBAAA=" } }, { "ID": "9075067d8edb4779", "Request": { "Method": "PUT", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/routines/routine_20191028_66906590093659_0003?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "275" ], "If-Match": [ "TY3o0Bk7xG0BaZx0SLKOoQ==" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJhcmd1bWVudHMiOlt7ImRhdGFUeXBlIjp7InR5cGVLaW5kIjoiSU5UNjQifSwibmFtZSI6IngifV0sImRlZmluaXRpb25Cb2R5IjoieCAqIDQiLCJyb3V0aW5lUmVmZXJlbmNlIjp7ImRhdGFzZXRJZCI6ImRhdGFzZXRfMjAxOTEwMjhfNjY5MDY1OTAwOTM2NTlfMDAwMSIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QiLCJyb3V0aW5lSWQiOiJyb3V0aW5lXzIwMTkxMDI4XzY2OTA2NTkwMDkzNjU5XzAwMDMifSwicm91dGluZVR5cGUiOiJTQ0FMQVJfRlVOQ1RJT04ifQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:41 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/32PUU+DMBDHv8pyj8bFAhsDkj2wJSbEiTpxmhhDGnpgDbQLLehC+O4WRjTxwae79H6/6/86QE0LCKCUbdKqUG0OV/fWc3t4YTpmn+s1XEItG80F7jHHGkWGEHRwrOUHZjpiRlXvsixPFRVzhpWca1TaWIxqqvBMTH1qE8u3iO2lrusTd+kT4jumpIQQ6/ejUZn6/xQH+h8nOR1NLnjchrtwn14/xdskuovNzqxGqrkUCa8GwFqubNtbeS5ZuL4Zl1TpW8l4zpH9RSziOSMiioYW4/qHnXmgddFUKLSC4LUDQUfrazr5HKQDbeoNF8MpUZy4C+j7N0NgzgUf8mwkOw3a7GJmZt8wXF9mhwEAAA==" } }, { "ID": "8a2e2fac0c38b971", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/routines?alt=json\u0026pageToken=\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:41 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/82QTU/CQBCG/8ueJc62dNttwqEl0RBrEaj4FdNsukuttl3SXSqk4b+zIuJFuXjxNJPM+8xMng41cqWLWijkP3VIaJYjHyUPtoTwzV1fQsge1zCLrsZyMhigs6/4VCxEI+pMIL9Dy0a+ikyPuEHViyzLTcXqHheV7GmhtKE400yJz8ShTy3AFIPlpYRQIA4FoLYpKQDg70N75NCfRrZHJtkszV9oNgyiYJpe3MbDZDSOzc6sEUwXsk6K6iOAHdeyPNdzaN+1zbhkSl9LXiwKwX+N1PmK5fv1k8jcPDorZZu0KlDh/PwG37Xze65j/v6vndl/cEagT+hpZwSD95Oz5+0OlUhz+3YCAAA=" } }, { "ID": "e13d401715a561c8", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/routines/routine_20191028_66906590093659_0003?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:41 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6uuBQBDv6ajAgAAAA==" } }, { "ID": "e4dd1a46f1234a7a", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001/routines/routine_20191028_66906590093659_0003?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 404, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:41 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/82PPQvCMBCG9/6KkFnlarXYztKxgugkUqKJtdDmIHcdpPS/m8YOTs5Ox/vB8bxDJIQ0zqGTuRi88PKO2ni1gc3iY3SGSNWTJ0tk8cDe6lwcsefGGkFPbNtXp+xSmw6XbIhzrViR4WoNcRbDelelaQbpNgPIEn8qAIhX7vPgVymRM0JAJE9wCVrMrH+CFzA0dqqxE0Xd4k2135kzijBkFrmYAOUcjuFe55nEinsKSw6nqjicy/1UHKMxegNhQiAVqgEAAA==" } }, { "ID": "8adbdf84843bcc6f", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "159" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5Ijoic2VsZWN0ICoiLCJ1c2VMZWdhY3lTcWwiOmZhbHNlfX0sImpvYlJlZmVyZW5jZSI6eyJqb2JJZCI6IkRwWEtGWFhtWlVhbzhQV3I1SllGRUttc3RLSCIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:41 GMT" ], "Etag": [ "TJFyguOqY4toGVdiTWQ25A==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/7WSUW/aMBSF/0rkvVUlEQgoioS2qg0bhZURQgurqsk4l+A2joPtIEUV/33Xhk6bRvvWt/jec893fJ0X8syLlIRkxbNtBar+9CRX5JyAoRlWk5tBnVWT7bJt5Ne7lCf301bnst9HBbdTeiPzvBa0aKQgZMOANuF85l+Xi9FgsRA/51T2ftyrzs1yEI2ENqNvOKkhX4958YzzG2NKHQbBK93PpMxyoCXXPpPiTz3YtYJSySdgRgcnoAGm1sE72M+5ZNRwWfTnM4xQaVC/QFCeYwhr0FByJc2XE9Y+p8LPUL/jDChjsiqMzYYuTBZrnlXKGZPwhbisf33Yq2Jk7wzFpeJScWOrw9skii+vkuFddMgyhoyyerbFNGuaa9ifE7xQUpeA6uk8ipfkUIphDQoKBhZyXMjwjYcgbsJ133+P19WgEJeDIG3wrA1n2mKYAtdOuLBxmp2LVqt30es2O+0ucWJl/ut1m237FxXpyc6RUTl/UEqqGHSVG3tEmnZZeLGjOU+nbpX/pNweSwK0ppm1n0Xj6CrxzjxRaeNt6A486g3iyXeP5RQX7FHjPTTD3qNFOyCiHz4e9ni4qJ26ntxGZL//DTH3B41xAwAA" } }, { "ID": "316717e4273bab60", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "245" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5Ijoic2VsZWN0ID8iLCJxdWVyeVBhcmFtZXRlcnMiOlt7InBhcmFtZXRlclR5cGUiOnsidHlwZSI6IklOVDY0In0sInBhcmFtZXRlclZhbHVlIjp7InZhbHVlIjoiMCJ9fV0sInVzZUxlZ2FjeVNxbCI6ZmFsc2V9fSwiam9iUmVmZXJlbmNlIjp7ImpvYklkIjoiejlwVER3ZzRnTlROek0zYWRKeGlHbVRORzVNIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:41 GMT" ], "Etag": [ "OgdnoOlMODr6yiw7pBWiOQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42Sa0/bMBSG/8rkfYWmuTeVEGNtVnWi6WhT0DRNleOcBkMSB9sFCuK/7zih1bQxtE++nOc992dyy+ucDEnGi7styN3HG5GRIwKaFvg7L/JazMvZfCyDHX8Im89XfH5xcoIENyp1LcpyV9H6OIdKHGtQerha9p6iJh0/FF6RpMnTzKX510c+qdJk4s9QqaDcnPP6FvXXWjdqaFn76L1CiKIE2nDVY6I6/Fv3jtVIcQNMK+uNoBZmrax3wp6WglHNRX2yWmIKWwVyDRXlJSZhHBxLkQn96Q3XPU6rXoH8PWdAGRPbWpvc0AsT9YYXW9k6JsNn0ub628WUiil/OEU4R1+8btGUZiUY7LWk6T9aaVRUUwUdsc4AnDDI8si3bc/eBIHvD6gdepEbsSj3PYe54PRdijptQrQqWovaZzmLMrvvAwDzHWABi6Kw77lZnrkbN0Bx5nhORl6wKAlUw5irRijeFUZGi/gsjdfTL+skjsfxGAM8SP4ndbWYIpQuVskIaWQayQViphHTJI0XZ6N0ehl37T+HgrLd8g4HsKGlgqOuZ9+opBVokIoMf2CD9s9017Qd0+1p3AWeyfYAXNJy2xL33YX0ycvLTyRwMzoxuVjFi++k+1rABiTU7D/HgIrW+v5i73cMQdwyDKQ0vnHsTJkwbWfN+Hll0rH90HEG4SCww7BPWljqv2yD1nZYLOMRKqj1a03L+DwepVhqF2yrDhAacRLJNJmg9RddCWOH5wMAAA==" } }, { "ID": "c99e94535ba41e17", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/z9pTDwg4gNTNzM3adJxiGmTNG5M?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:42 GMT" ], "Etag": [ "LbyKDm5FvmsnkgRrw6rGjw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2P3U6DQBCF32W8bZMarYkkvbAWsUqJIr0yxiwwUOj+4O4g0oZ379B6NXtmvzlz5gj7SufgQVqVPy3a/qpEeh8fMbpWkuPSGO0QJoAkSibDtH9dqfnTr3J6X8a2u7NB3S0WTLhsh0qAd4SiQpk78D6PoIVCHitm30xQ34xiHSV+4MfcUCYfG9E2DB+WoQ/D1zCB2qQxFmhRZzi6NdbUmNF6DOp2RspeCT3NUZkpoSM4T5x/D/dNsurK2zJKosPmRuQvf1WgkiiYb5iSJhNUGc3g9gN4ERkSMjYdJ4Vr+NfLnk3frMnQORxNZ5cFj0Y1EokTkW1xApngc58ruujhBKhp5XtLAQAA" } }, { "ID": "ac670c5662853bfb", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anon5cdc9b105eeec52ec6c997043bdb3f369d5b242b/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:42 GMT" ], "Etag": [ "dfs/+fs8YpkRHn6kxjDxbQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8qnpBXra6cVW0QWZAd55JllV2S5VCQF2toCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwobKNXGAiEAMtIS024AAAA=" } }, { "ID": "28d87f66ae8946ca", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "250" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5Ijoic2VsZWN0ID8iLCJxdWVyeVBhcmFtZXRlcnMiOlt7InBhcmFtZXRlclR5cGUiOnsidHlwZSI6IkZMT0FUNjQifSwicGFyYW1ldGVyVmFsdWUiOnsidmFsdWUiOiIzLjE0In19XSwidXNlTGVnYWN5U3FsIjpmYWxzZX19LCJqb2JSZWZlcmVuY2UiOnsiam9iSWQiOiJEdjRxU042VmdiTjJpWHg5enFqQzRxbzQ3dGciLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0In19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:42 GMT" ], "Etag": [ "xhvKtM68dwQxbEg/K3lyAg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42Sb2/aMBDGv8rkvQVC/pAQJNQhSCdUlq0Q2KZpQo5zBLdJDLFDYVW/+85JYdPWVXsVx/e7e5473yO550VCBiTm6b6C8vT2TsSkRUDRFG+P28ON+uD2k4fbYxykxo2dnUbpcIgE11lyK7LslNOinUAu2gqkGiwXncnB2S9Cd5XGocW/HP0f+7uxsxeOp1LMlJBtZry4x/ytUjs5MIyzeicVIs2A7rjsMJFf7o2DZexKcQdMSeMFUQNdS+MV2atMMKq4KIbLBVqoJJRryCnP0IQu0C5FLNS7F0p3OM07KfIHzoAyJqpCaW9YhYliw9OqrAuTwSOpvf520K2i5TdXCCdYixc1GtE4A409tzT9xyh1FlVUQkOsYwDLc+PE75mmY25ct9frU9NzfNtnftJzLGaD1bUp5iktUWfRQhRgU9p3fc8F17UpbGLqgO13uwzsmNmmYyVml8V+jzxhUyVQBRMud0LypjEyngejKFhPr9dhEEyCCQo8lPxP6vN8ilA0X4ZjpJHZlVwgpgcxDaNgPhpH01XQjH8GKWWnxR4fYEMzCa1mZp9oSXNQUEoy+IYDOv9Gp109MVV/yfXs4yhyHe33gqxoVtXMoTkQu2Mi8fQdIVyPpgK5XQbzr6S5msMGSijYf74FZtTR17f7vGgI4qqhkFT4j2/PpJapx6t3gOfajtnzLKvv9V3Lth1Sw6X6K+Z4XdL6tV26IuRQqOeeFsEsGEfYaiNWyQuEQXyOcBq+x+hPw7MSI+wDAAA=" } }, { "ID": "df394cccb2e83e93", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/Dv4qSN6VgbN2iXx9zqjC4qo47tg?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:42 GMT" ], "Etag": [ "fdDFGh+OcfnKA9RsMLJCOA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2PXU+DMBSG/8vxUpZMQzRbsgvGnF+4KXPGxBhTyoExSw/Qg4qE/267edU+6XPe87aHz0KnMIWkyOsWm+4kR35ylxhNq9jYoyJtEDxAFrk1s3SxvN6drmWm74NJbB6iu3AdzGbWMHKHpYBpD1mBKjUwfetBixLd2PjDGtxVDpbROni2WFLqcLWNomAeXcHwPniwpyTGDBvUEl1W1dAeJd+6mmZHSnWl0KMUSxoxGobDxOF18eXXm9XFS56szovXn8lvvQ/9mvxLzq2lSAouSFtxuwG7iImFiunb9oQz+Od5Z0MfG5JoDLrQ8XFBSGWlkG0jblr0QAr72ZuCjzz8AZTDEwNJAQAA" } }, { "ID": "42e1e9d0078e82e8", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anone3aa86976e663aefba4e3900ce3bc3142d10cb95/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:42 GMT" ], "Etag": [ "6G3ETqhMUXE4N6CJHyQNKA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8qbuRu7hhRm+IZGuJr4mTl7eVQG+nk72toCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwob6xmaKNXGAiEAAG+0AXEAAAA=" } }, { "ID": "ceb84ea26565e6d5", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "257" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5Ijoic2VsZWN0ID8iLCJxdWVyeVBhcmFtZXRlcnMiOlt7InBhcmFtZXRlclR5cGUiOnsidHlwZSI6IkZMT0FUNjQifSwicGFyYW1ldGVyVmFsdWUiOnsidmFsdWUiOiIzLjE0MTU5ZS04NyJ9fV0sInVzZUxlZ2FjeVNxbCI6ZmFsc2V9fSwiam9iUmVmZXJlbmNlIjp7ImpvYklkIjoicHpzUFNWTU8zanJLMXR4U3c0TGNCcHJrSGJJIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:43 GMT" ], "Etag": [ "52Ky6KiDmyL87vuYGnJB6A==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42Sb0/bMBDGv8rkvaUN+dukEmKlDSyjFNamTGiaKse9BkMSB9sp6xDffecE2IQY2qs459/dc/f4Hsgtr9ZkSDKe3zUgdx9vREb2CGiaY9R3TnfBKZ+Uu2k42DZXJ9WXo2B0cIAEN1nqWhTFrqRVbw2l6GlQerhc9Otf6mJxeXbu3shTW/9c3HtTdlTL289ZgpkKis2UV7eYf611rYaW9azez4XIC6A1V30mype4tXWsWoobYFpZb4ha2LWy3pE9LASjmovqYLnAFhoFcgUl5QU2YQr0pMiE/vRG6T6nZT9HfssZUMZEU2nTG1ZhotrwvJFtYTJ8IG2vfx3MqNjyh0OE11iLVy2a0qwAgz2NlPzDSpNFNVXQEasMwBkE2TrybduzN0Hg+yG1B17kRixa+57DXHD2XYp52ki0WbQSVRgxNwgz2wPqekHmOJSFzLcx6G8gg4CBbwfMj8gjDiWBaphwVQvFu8HIeB6P0niVHK9mcTyJJyhwL/lr6ts8QSidL2djpJGpJReIGSOSWRrPR+M0uYw7+6eQU7Zb3OEDbGihYK/z7IJKWoIGqcjwOxr0/Jvu6tYx3X7J8fR8lAae6fcFuaRF0zLb7kDcPrrkR9ALB+Tx8QeyuCVdIfJ1Gc+vSBeawwYkVOw/nwQz2tv3l/x53xDEjUMhpfEfV4ApI9O6bFaBl6Yd2x84TjgIAydyHdLCUr++c/f9gOz9WTJTEUqo9NNMi3gaj1MctRNr1AuEl/gqs2R2gre/AVTdEZnzAwAA" } }, { "ID": "f0dc5676d261c77a", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/pzsPSVMO3jrK1txSw4LcBprkHbI?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:43 GMT" ], "Etag": [ "vSxCivvoLKuE1+Z6LRgyRQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2PwU7CQBCG32U8CglE46EJB0owEFaBVjxojFm2Q2nZduruFKik7+4UPO1+2W/++fcCh6xMIIBtlv7U6Jq7FHndXSL0tWUvR0WlR+gBsk7FPMbnSXY8klrU0+H9x5OK0iZaj0ZieLPHQkNwgV2GNvEQfF6g1AXK2G7wLQY3VQfPajl+Eywo6fB1o9Q4VFNov9oe5LSNcIcOS4NdVuUoR8Pzrqbfk7VNoct+ggX1GT3DdeL6Wv36Vfz+snzI3WLI5/j0qExYucNsOxfLktGcUSniJgZZxMTaRnSSnjCEfw4bCV05Mug9dqGD24IJFZVFlkbsauyB0fLZWcY3bv8AJFZus0kBAAA=" } }, { "ID": "3b0d4ef089d65577", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anon89c368b14ea346b22ac8c51c365febe6ce516c59/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:43 GMT" ], "Etag": [ "7PubGjvdf7J1AirLErbhDQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8qbB5QmuWeVpaSZexk6Zhb5uBYlZbgE2toCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwob6xmaGJpapupamCvVxgIhAG+nuKt4AAAA" } }, { "ID": "e9dcf6d0f52720d2", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "247" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5Ijoic2VsZWN0ID8iLCJxdWVyeVBhcmFtZXRlcnMiOlt7InBhcmFtZXRlclR5cGUiOnsidHlwZSI6IkJPT0wifSwicGFyYW1ldGVyVmFsdWUiOnsidmFsdWUiOiJ0cnVlIn19XSwidXNlTGVnYWN5U3FsIjpmYWxzZX19LCJqb2JSZWZlcmVuY2UiOnsiam9iSWQiOiJJaXc0bzhWUnpjVmtVS2lIOTdPMkNkSHN3T1MiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0In19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:43 GMT" ], "Etag": [ "rnSK0CGdpG15Ticas/Lj6g==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41Sa0/bMBT9K5P3FRqS1klTqWKsZBBRtVuadpqmqXKc22BI4mC7RQXx33edQDdtDO2TH/ece859PJJbUedkRDJR3G1B7d/fyIwcETCswF9VL65OJhd5c+HSVHCmnemNX4zHiBCWpa9lWe4rVh/nUMljA9qMloteLO4HcrhKHvjqdnklLsNg7k3yS30/XyBTQ7mZivoW+dfGNHrkOC/qvULKogTWCN3jsjr8OzvPaZS8AW6084qog66184bsaSk5M0LW46W1sNWg1lAxUaIJm+BYyUyaD6+k7glW9QrE7wQHxrnc1sZ6wyxc1htRbFWbmIweSev1t4stFS2/O0VwjrlE3UJTlpVgYc8lxf9opWUxwzR0iHUG4AV+lofUdQfuxvcpHTI3GIT9kIc5HXi8D95JnyHPWImWxWpZQ+hzP/f67maYh5xSn+Z+PwupN8zzk8DlfoYJvAElT1iUAmbgXOhGatEVRiZJdJZG6/jTehZF59E5Ctwr8SfqaxIjKE2WswmiEdMoIRFmGxHP0ig5m6TxKuraP4WC8f3iDgewYaWGo65nn5liFRhQmoy+Y4Nenum+aTtm2pN8nM+n1uwhvmLltgXsugsxCo+npx8Iwt3o6OTLMkq+ke4rgQ0oqPl/DgIZbfTt1X7ZMgTinqGQNvjGwXNtZdre2gUQlbXj0sDzhsHQ71MakBaszF8x3w/J0a/Vshmhgto817SIptEkxVI7sa0+gDCIs5jFswuM/gSDiuoR6QMAAA==" } }, { "ID": "033dfb8e09d9b11c", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/Iiw4o8VRzcVkUKiH97O2CdHswOS?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:43 GMT" ], "Etag": [ "d9r3ZI4WMa4H6ZNUIvwyUw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2PYU/CQAyG/0v9CgkqUVnCB0ZItjiZjgwTjDHHrcDBbZ274jKX/Xc78FPv7T19+7aFkyky8GBr9t9nrJqbPfJb/0jQnS07KSUVDmEAyGovZDap7jfh+P1FjYOHzTINf+omradTIZw+YK7Aa2Fn0GYOvI8WCpWjjO1GX0JwU/bCj+NoMVtKI6esbyzTKJr50QK6z24AR9omuMMKC429W1nRETWHfVB3IGubXBXDDHMaMjqGy8TlNzT1mJ7Wya9en9JnE0we47t5Frg6XgllSSs2VAiYrkAWMbGyCdWSFG7hX/uNmL5WpNE57E1H1wVzykuLLIm4OuMAtJJzA8NX3f0B1Pbe/UsBAAA=" } }, { "ID": "1eb7964ae18d8062", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anone96c6d231f8d9c5565d63b9528dd071c6b9c9245/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:44 GMT" ], "Etag": [ "IGDPWgAC0eakMCDJ9TeWBA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8p7ursEhKc7OhukJmb7Ort4WYakhjs52toCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwqXFJWmKtXGAiEAmSRo0HEAAAA=" } }, { "ID": "bd2f1741f905b30e", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "251" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5Ijoic2VsZWN0ID8iLCJxdWVyeVBhcmFtZXRlcnMiOlt7InBhcmFtZXRlclR5cGUiOnsidHlwZSI6IlNUUklORyJ9LCJwYXJhbWV0ZXJWYWx1ZSI6eyJ2YWx1ZSI6InN0cmluZyJ9fV0sInVzZUxlZ2FjeVNxbCI6ZmFsc2V9fSwiam9iUmVmZXJlbmNlIjp7ImpvYklkIjoiQThGZUJuYW5TNFQ5Z094em8yc1MxUmN2MVljIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:44 GMT" ], "Etag": [ "XX2vI7bt2p1Sh4qp5WhlcQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42SbW+bMBDHv8rkvW1CTHgIkaouS+mEVKUrkD5omiJjLsQt2BQ72bIq330HtN20ddVeYezf3f3vf/dI7oXMyZRkonjYQrN/f6cyckTAsAJvb27sXeRnxq5psnEeavd6U/LL42MkRBulN6os9xWTgxwqNTCgzXSZDGeTM/gomUycNCguvv9Qtk5ozHf0lmOkhnJ9LuQ9xm+MqfXUsp6rDwulihJYLfSQq+rl3trZVt2oO+BGW68UtVC1tt4oe1IqzoxQ8niZoISthmYFFRMlimgTDBqVKfPhldRDwaphgfxOcGCcq600rTbMwpVci2LbdInJ9JF0Wn87tK2i5HcnCOeYS8gOTVlWQos9tRT9w8o2ihmmoSdWGYDte1keuJQ6dO15rjth1HeCccCD3HVsPgZ7NGYYZ9oSXRSTSrq+59o5jGCUscBdB6N8ZPsuBUpdCDwY5d6EjaljkwM21QAzcCp0rbToGyPzOJyl4So6Wy3C8DQ8xQLfGvEndR1HCKXxcjFHGpm6EQqx1ohokYbxbJ5GV2Fv/zkUjO+TBxzAmpUajnrPPrOGVWCg0WT6BQ16/k33deeY6b4kSeNo8amV+0JcsXLbIbv+QLRphCzI4fAVMdyPPgW5XIbxLemvYlhDA5L/5zAwont9e72fNw1B3DUspA3+4/C5bst0/rZLIKpWDnV92574E88ZU0o6uDF/vbmuR45+rVebESqQ5qmnJDwP5ym22hfb6hcIH3Eei86sw0/+fhLM7QMAAA==" } }, { "ID": "eb6784278199d22d", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/A8FeBnanS4T9gOxzo2sS1Rcv1Yc?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:44 GMT" ], "Etag": [ "XKZtdaHFWojxxzTBRxDSYg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2P0U7CQBBF/2V8LQk1PmgTHqiKEAlqW4JojFm201Lc7tTuVFsI/+4UfNo92TN37h7gq7ApBLAp8u8G6+4iR37pLxG6xrCToyLrEDxAVrmYr49vnKrpZEW7tt0nYdTexet8NBLD6S2WCoIDZAWa1EHwfgCrSpSxbPgpBndVD3ESzRYPwiWlPS+W8/k4nN/D8ePowY42EWZYo9XYh1U17VDzrO/ptmRMVyo7SLGkAaNjOE2cXsfXEwytsvFVcpM/tXu6dLEf6R9/rcUypBUXZEVcxiCLmFiZiH6lKPjwz2Enoc81aXQO+9DhecEtlZVBlkZcN+iBVvLbacFnPv4BibpFQkoBAAA=" } }, { "ID": "3a80594727294c0a", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anon57652de0e0ba95f90d02751e115e96e0d68a3142/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:44 GMT" ], "Etag": [ "2ITuz9xbiw1Fxkdn/YEewQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8obeYaUVllWJGWWG7pVZKfk6Ue6ppYH2toCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwoXlxRl5qUr1cYCIQAdNVoGcwAAAA==" } }, { "ID": "1d6a5a8722c61bd1", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "256" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5Ijoic2VsZWN0ID8iLCJxdWVyeVBhcmFtZXRlcnMiOlt7InBhcmFtZXRlclR5cGUiOnsidHlwZSI6IlNUUklORyJ9LCJwYXJhbWV0ZXJWYWx1ZSI6eyJ2YWx1ZSI6IuaXpeacrOiqnlxuIn19XSwidXNlTGVnYWN5U3FsIjpmYWxzZX19LCJqb2JSZWZlcmVuY2UiOnsiam9iSWQiOiJ3U1k5MUZ2azA5VjhNZzJ6dDY2RmkxMmRYZW8iLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0In19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:45 GMT" ], "Etag": [ "XUNQSSAeNuOd8/3KmyMVmQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42S227TQBCGXwUtt218SHyKVJUqdVFEa4jthFaAovV67G5re1PvOlWo8hzcIO64QTxXxWMwttuCoFRceT37zcw//84NueRVSsYk4flVA/Xm+YVIyA4BRXOMns6DWRQdQNC8Tl1t+KrcnCzK2d4eErzNkueiKDYlrXZTKMWuAqnG82hwHZ15xtH6UvcW7kluflS2fcQNMz0FgZkSiuyYV5eYf67USo417b77IBciL4CuuBwwUT7EtbWprWpxAUxJ7ZGmGqqW2hNt9wvBqOKi2ptHKKGRUC+hpLxAEW2B3VokQr14pPSA03KQI7/mDChjoqlUqw2rMFFlPG/qrjAZ35BO62+HdlSU/Gwf4RRr8apDY5oU0GJ3I03/YWWbRRWV0BPLBMB07CT1LMMYGZltW5ZLDWfkDT3mpdbIZEMw9SHFPNW26LJohSotliVe5uqWrtvMdbMRODQzPdehaeZ6pucMKUaAbHGoGqiCQy5XQvJ+MDIJ/YPYX06PloHvH/qH2OC65n9Sb8MpQnE4DyZII7OquUCsNWIaxH54MImnC7+3/xhyyjbRFT5ARgsJO71nb2hNS1BQSzJ+hwbd/8abVeeY6r4kisNp8LKV+0AsaNF0yLo/kNtPX28/f//x7cv7imy3H5DFJenrkNncD89IHwohgxoq9p8vghnd7dM7fr9uCOLCYSOp8B83gMm2TWdyuwm8bOUYlmOaruPalm7qpINr9dedOTLIzq8daytCCZW6mynyj/1JjKP2zRr5AOElPkrQObb9CaibHybyAwAA" } }, { "ID": "9fd8cba5ecbe7aff", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/wSY91Fvk09V8Mg2zt66Fi12dXeo?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:45 GMT" ], "Etag": [ "S75HcD2KUVNUrpSxG2lEcA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2P3U6DQBBG32W8bRMgsVqSXrTav4hEQRqNMWa7DJR2YZCdWrHpuzu0Xu2e7Jlvvj3CrqhS8GFd5F97bNqrHPm5u0Ro94atHDVVFqEHyCoXM765Xuh77yFZhUlTxz9zz0z1eDQSw+oNlgr8I2QFmtSC/36ESpUoY5nzKQa3dQfxS7QM58IlpR2HSRCMJ8EUTh+nHmxpHWGGDVYau7C6oS1qXnY97YaMaUtV9VMsqc9oGc4T59dD/DZ0Z987Z7i6fcy9Xx4MZoXrpa9IYhnSiguqRExikEVMrExEBykKLvzzpJXQp4Y0WotdqHNZcEdlbZClETd77IFW8ttFwRc+/QHM2ESSSgEAAA==" } }, { "ID": "1dfe86fb412e5d45", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anonf5cfb9f805006c88f4e7af2987adf892973ae7ae/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:45 GMT" ], "Etag": [ "nFyPFSjFz36pttjcTH4rTw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8rnuVUGuAVnuVUZmxWUlGQlh3iYFIWU29oCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwo/m7702Zw1L1bNi8lTqo0FQgCiIFuaeAAAAA==" } }, { "ID": "3aca071600273f7f", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "249" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5Ijoic2VsZWN0ID8iLCJxdWVyeVBhcmFtZXRlcnMiOlt7InBhcmFtZXRlclR5cGUiOnsidHlwZSI6IkZMT0FUNjQifSwicGFyYW1ldGVyVmFsdWUiOnsidmFsdWUiOiJOYU4ifX1dLCJ1c2VMZWdhY3lTcWwiOmZhbHNlfX0sImpvYlJlZmVyZW5jZSI6eyJqb2JJZCI6IkhiVnZ0UlVwbWFoOXB6YzFaZnEyS1pvU2pUNiIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:45 GMT" ], "Etag": [ "/5DrsJqNS426puyR5Em9vQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41TXW+bMBT9K5P3moZAAoRIVVcldMsWsZWQTus0RcZcqFvAxDaZsir/fdfQdtPWVXvC9j3nnnM/uCd3vM7IjKS82LUgD69vRUoGBDQt8NVyF1K930XrieM17SF2wyrYX56eIoIblroRZXmoaH2SQSVONCg926yH79KrvY43TUVvguYHs6/znfPhWqxvEw+ZCsp8xes75N9o3aiZZT2qDwshihJow9WQierp3do7ViPFLTCtrGdELXStrBdkz0rBqOaiPt2s0UKrQG6horxEEybBiRSp0G+eST3ktBoWiN9zBpQx0dbaeMMsTNQ5L1rZJSaze9J5/e1gSkXLr84QnGEuXnfQhKYlGNhDSct/tNKwqKYKesQ2BXB8L80C17Yndu55rjultj8JxgELMnfisDE4ozFFnjYSHYvWoma5m/ojL0+RyKapn+dZPvVGNB8FjutNshGMc9f1UnLEoiRQDQuuGqF4XxiZx+F5Em6XF9soDBfhAgW+S/4n6nO8RFASb6I5ohHTSC4QZhqxjJIwPp8ny6uwb/8KCsoO6x0OIKelgkHfs09U0go0SEVmX7FBj9fk0HQd092XXKw+nifexPh9glzRsu0w+/5AIhqR4/EbYnA7+gTkchPGX0j/FEMOEmr2n6NARhd9ebkf9wyBuGkopDTecfRMGZmuu2YFeGXs2K7vOFN/6rme0/0amkr9V8y3p2Twa7lMRqig1g81rcNVOE+w1F6sVU8gDOI0omX0FqM/AVxSNkDrAwAA" } }, { "ID": "141fd4e0949a0ea6", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/HbVvtRUpmah9pzc1Zfq2KZoSjT6?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:45 GMT" ], "Etag": [ "7Z0eX2rb688XdOtAWdpbHw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2P0U7CQBBF/2V8LUnhAZGEBzAajI1ooUJqjNlup1Dc7SzdqaQS/t0p+LR7smfu3D3Bd1nlMIas3B4arNubLfJbd4nRN4a9HI4qjxAAstqKeZuGuBnU2XA02uQLnq5zl82Pk4kYXu/QKhifoCjR5B7GHyeolEUZK8IvMbh1HTxGi+lK0FLe4UsSRdNZ9ADnz3MAe8piLLDGSmOX5Wrao+anrqbfkTGtVVUvR0s9Rs9wmbi8zrP3H44TZ9Xuzv3qflocBs8pLferoViGtOKSKhGTJcgiJlYmpqP0hD7886yV0NeaNHqPXWh4XXBP1hlkacR1gwFoJZ+dl3zl8x+6ZdKNSQEAAA==" } }, { "ID": "b62e30b52589d2a0", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anoncf5b706fb511c8b7ffdf860af092564d0e3f556b/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:46 GMT" ], "Etag": [ "EH4aInn5/mHkqkXkJkWJvQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8q7epgkeublmernemQXZkdke2WHe5UF2toCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwr7Jfop1cYCIQDnvX3ScAAAAA==" } }, { "ID": "0d50ddff4a24f40d", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "248" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5Ijoic2VsZWN0ID8iLCJxdWVyeVBhcmFtZXRlcnMiOlt7InBhcmFtZXRlclR5cGUiOnsidHlwZSI6IkJZVEVTIn0sInBhcmFtZXRlclZhbHVlIjp7InZhbHVlIjoiWm05diJ9fV0sInVzZUxlZ2FjeVNxbCI6ZmFsc2V9fSwiam9iUmVmZXJlbmNlIjp7ImpvYklkIjoiRllKdk5HNWdnczFKSEVWcE5YWTJKWW5KdXJVIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:46 GMT" ], "Etag": [ "q/ngh69U5Eo6PfzhwVWn/Q==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42Sb0/bMBDGv8rkvYXmT5uEVEKMlcBaoQjapKybpspxLqkhsdPYKSqI775LAmzaGNqrOL7fc/fc+R7JHRcpGZOE59sG6v3HW5mQAwKa5ni7NUS+cf3YCaR7lT1s7pc3wrg+PkaCtyq1kUWxL6k4TKGUhxqUHseLwflqtgsvnDxX1uxLsKzCryt7thKzpo5RqaDILrm4Q/1G60qNDeOl+iCXMi+AVlwNmCxf742dbVS1vAWmlfFGUQNdK+OdsieFZFRzKY7jBVpoFNRrKCkv0ESb4LCWidSf3kg94LQc5MjvOAPKmGyEbr1hFiZFxvOm7hKT8SPpvP52aFtFyx9OEE4xFxcdGtGkgBZ7bmn6j1G2Kqqpgp5YJwC25yap71jWyMpc13GOqOWN/KHP/NQZ2WwItjmkqNNtiU5FhRTWcJiYFFxmU2tkMt/2zNT3Td+z08xzHM9mqWWlpkOesKkaqIYzriqpeN8YmcyD0yhYT8/XYRCcBWdY4L7mf1I38ylC0TwOJ0gjU9VcItYOYhpGwfx0Ek2XQT/+S8gp2y+2+AAZLRQc9DO7ojUtQUOtyPg7DujlN9pX3cR09yWfV1GwaN2+AktaNB2x6w/kW+nvyNPTD4RwOXo9uY6D+Yr0V3PIoAbB/vMlUNFF39/tlzVDMO4MKo3/+PJMtWW64bYbwMvWjoWjt4+8I9cdWUPSwbX+K+Y4Jjn4tVttRihB6OeeFsFlMImw1b5Yo14hDOJjhNPwAqM/AYBVyprqAwAA" } }, { "ID": "777ca49850c24317", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/FYJvNG5ggs1JHEVpNXY2JYnJurU?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:46 GMT" ], "Etag": [ "yBCmfQSFidfY3dma46B+Ag==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2PXU+DQBBF/8v4KE1avx5I+lAaaiWEWLBGYozZwkCp+4HsoCGE/+5s69PuyZ65c3eEr0aX4MOhqb977IarGmnnLinaXpLlozXaIniAJGo2h2Ctql22acoqvy2VuHsIrlf1csmGLY6oBPgjVA3K0oL/PoIWCnmsmn+yQUPrIMhfwoxRmdJhso/jVRCHMH1MHpzMIcUKO9QFuqy2Mycs6MnVtEcj5aCEnpWozIzQEpwnzq+bPPpJHu/r2i6ibfjaJm/5TZTrqO/2bElTCGqMZnGfAS8iQ0Km5pd7wgL+ORg49LkzBVqLLnR+WbA2qpVI3Ii6Hj0oBH9229CFpz+eZ4fVSQEAAA==" } }, { "ID": "68c52d68561ba0df", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anon133b0ae6c2a140c9270d990972df75572cd11d05/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:46 GMT" ], "Etag": [ "CaV/GP4jm7dGZFPz0rvytA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8o7J4bpuweYZOWap7hHuQVUGRSVVZY42toCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwpH5VqWKdXGAiEAMmXWL3EAAAA=" } }, { "ID": "9c783876e1a632de", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "280" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5Ijoic2VsZWN0ID8iLCJxdWVyeVBhcmFtZXRlcnMiOlt7InBhcmFtZXRlclR5cGUiOnsidHlwZSI6IlRJTUVTVEFNUCJ9LCJwYXJhbWV0ZXJWYWx1ZSI6eyJ2YWx1ZSI6IjIwMTYtMDMtMjAgMDQ6MjI6MDkuMDAwMDA1LTAxOjAyIn19XSwidXNlTGVnYWN5U3FsIjpmYWxzZX19LCJqb2JSZWZlcmVuY2UiOnsiam9iSWQiOiJlcmhuV0FqS01zeGZ4amx1blNLTWxuVGtGSVUiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0In19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:47 GMT" ], "Etag": [ "OdFGoJY4HjINitFTUhajNw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42SbVObQBDHv4pzfWsCXHgIzDg2E4mlGrQJ0XE6ncwBC7kIXOQONeP43buA2k5rnfKGe/jtf/+7t0/kllcp8UjM87sG6v2nrYjJIQHFcjy9SGen4uuN+WUbhFzNotWGbcOHoyMkeBslN6Io9iWrBimUYqBAKm+1HEK9qa4n27O5fMwet0VTLc/mRRXdzoIVRkoosnNe3WL8Rqmd9DTtNfswFyIvgO24HCaifDvX7qm2q8UWEiW1d5Jq6FpqH6Q9LkTCFBfV0WqJFhoJ9RpKxgs00QoMahEL9fkd6SFn5TBH/p4nwJJENJVqvaFKIqqM503dCRPviXRef1u0paLlg2OEU9TiVYdGLC6gxV5KCv7RyjaKKSahJ9YxAHXsOHUtwzCNzLYta8wMx3RHbuKmlkmTEVB9xDBOtSm6KFaJSnecmDrUNFydwdhN0pRSG3Rqmm6GPDjUTnUrzcgzFlUDU3DC5U5I3hdGpgt/EvnrYLYOff/EP8EEDzX/k7peBAhFi1U4RRqZXc0FYm0jgjDyF5NpFFz5ffvPIWfJfnmHD5CxQsJh37NLVrMSFNSSeN+xQa/baL/rOqa6P4mCub+MJvPL1vEbdMWKpqPu+wWhumEP9NGA6ge66VHq6e5Qbz9roBueTsnz8w8UwOHp9cm3lb+4If3RAjKooUr+86Uworv9ePZfxxBBHERMJBXucTIS2abpmt9OCC9bO4blUDp2xraj2yPSwbX6685wXXL4a/ZaRSihUi81Lf1zfxphqX2yRr5BeImPFQbhKd7+BC/EJx0KBAAA" } }, { "ID": "4b76180ec26dc5a6", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/erhnWAjKMsxfxjlunSKMlnTkFIU?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:47 GMT" ], "Etag": [ "op0qqgtP2KZZ0jRaC84isg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2PQWuDQBCF/8v0asCWHkogBxNSKonFqqGQUspGR6NZd9QdaUT87x2Tnmbf7Ddv3oxwKU0GSziVRdtjNzwUyB/zI0Lba7ZSGjIWwQFkVQhJjdu2BYdPu+PRrSK1eXkubbFaCWHTM9YKliPkJerMwvJrBKNqlLHc/RGCh2YWiR9s48QLQmnVlM2t98N+7633W5i+JwcqOkWYY4cmxdmv6ajClP05qj2T1kOtzCLDmhaMluE2cfvF7mw+vWoX2Gt+rXRv4l2gTXJ59Q9CaUoVl2QEPMQgi5hY6Yh+JSs8wr9eD2IadpSitTibuvcFG6objSyJuOvRgVTJwW8l3/X0B6W+6J9NAQAA" } }, { "ID": "9204e64f1a600549", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anon077b2724190ae89cdd226e02449f03ae726d05df/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:47 GMT" ], "Etag": [ "2vTjAisyRxOoiCPpaObdbw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8oblYVkOWYWVwZV+OdnOgcUJPonpSSV29oCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwmbmFqYmBqamFjqGYCAqVJtLBACAL6otWd+AAAA" } }, { "ID": "de999681674d1380", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "253" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5Ijoic2VsZWN0ID8iLCJxdWVyeVBhcmFtZXRlcnMiOlt7InBhcmFtZXRlclR5cGUiOnsidHlwZSI6IkRBVEUifSwicGFyYW1ldGVyVmFsdWUiOnsidmFsdWUiOiIyMDE2LTAzLTIwIn19XSwidXNlTGVnYWN5U3FsIjpmYWxzZX19LCJqb2JSZWZlcmVuY2UiOnsiam9iSWQiOiJCTGVNTmc3TGNRdXJ0cGptTzJEajdsSWdvckEiLCJwcm9qZWN0SWQiOiJzaG9sbHltYW4tZGVtby10ZXN0In19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:47 GMT" ], "Etag": [ "wZHkEwfVm6XkpSye0G5Lvg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42SbW/aMBDHv8rkvS3kAfIAEuo6yLpIjK0QuidNyDiX1JDEqe1QoYrvvnPSdtPWVXsVx/e7///ufPdkz6uUjMmW57cNyOPrndiSMwKa5nh79+39PrrLrkv/y75eHcG+9OaHfDJBgpssdSOK4ljSqpdCKXoalB6vV/23c/iwyIM5u2qkrnflR3e2C4o4F/ICMxUU2ZxXe8y/0bpWY8t6dO/nQuQF0JqrPhPl0711cK1aih0wraxnTC2sWlkv2J4XglHNRTVZr7CERoHcQEl5gUUYgZ4UW6HfPCPd57Ts58gfOAPKmGgqbWpDFSaqjOeNbIXJ+J60tf52MK1iya/OEU5Ri1ctmtBtAQZ7aCn+xyhNFtVUQUdstgBu4G/Tkec4Qyfzfc8LqRMMR4MRG6Xe0GUDcO0BxTxtLNosWomKOmHK/MwNUsoy8NLQGw5TSu1sZA9t1/do6qOO7ZMTNiWBaphxVQvFu8bIdBldJNEmfrdZRNEsmqHBneR/Up+XMULJcr2YIo1MLblAzAwiXiTR8mKaxNdRN/455JQdV7f4ABktFJx1M/tEJS1Bg1Rk/B0H9PibHOt2Yrr9kpkxwGKf4te0aFrg0B2Iazt+zx70XJucTj8QxQ3pRMjVOlp+Jd3VEjKQULH/fA7MaKMvL/jjriGI24ZGSuM/Pj9TxqadsFkDXppyHC9w3TAI/cAPR6SFpf4rFroBOfu1YEYRSqj0Q0+raB5NE2y1M2vUE4RBfJFFvLjE6E9jHObz7wMAAA==" } }, { "ID": "ae3a3c935168c5fd", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/BLeMNg7LcQurtpjmO2Dj7lIgorA?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:48 GMT" ], "Etag": [ "a1d8PYRwV5s642MU6v2DNw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2PYWvCMBCG/8vtq4KWTYfghzqFCdVpN4UxxojpWdslvS65Tkrxv++i+5Q85Ln33nTwXVQZTOBQ5D8NuvYuR96GS4q+MezlqKnyCD1AVrmYapg9bt7T8/7Bj+6j1W70G83X5+lUDK9PaBVMOjgWaDIPk48OKmVRxo6DLzG4rQPM47eFkKUs0HqXJPEsWcDl89KDkg4pHtFhpTFE1Y5K1LwMLf2JjGmtqvoZWuozeobrxPV1luBqnY8TvW0c16V9iebl2CxzcrFYhrTigioRd68gi5hYmZTOUhOG8M+zVkI3jjR6jyF0cFvwRLY2yNKIXYM90Er++lzwjS9/IU5vs0gBAAA=" } }, { "ID": "2db372002cf69148", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anona18dc6f27dacfe5d8544daa0f9040265ad6a1706/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:48 GMT" ], "Etag": [ "SI1WtCiNYH0KjoxWRPHj3A==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8oHexqGlzhn+kV6GHhn5VeEBwV4ZBk72toCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwobGRia6RoY6xoZKNXGAiEA1ogQMncAAAA=" } }, { "ID": "f7b59c3c368b47f7", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "258" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5Ijoic2VsZWN0ID8iLCJxdWVyeVBhcmFtZXRlcnMiOlt7InBhcmFtZXRlclR5cGUiOnsidHlwZSI6IlRJTUUifSwicGFyYW1ldGVyVmFsdWUiOnsidmFsdWUiOiIwNDowNTowNi43ODkwMDAifX1dLCJ1c2VMZWdhY3lTcWwiOmZhbHNlfX0sImpvYlJlZmVyZW5jZSI6eyJqb2JJZCI6IkZMZjNNV3JVdFR6eHhxYjZxbUNQaGVKVFQ0ZSIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:48 GMT" ], "Etag": [ "/eamq+Z1P+lH7koIPFEUow==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42S207bQBCGX6XaXgLx+RBLEUXBtK5ClCYOqK2qaGyPzYLtTbwbIKC8e8c20KqlqFde73wz/z+z88hueJ2xgCW82Gyx2b2/Fgk7ZKigoFsNodocfDNmB+Un70ZEs7NwKe5GIyJ4myWvRFnuKqiPMqzEkUKpguVicDbJrfPLZqnih/v7TeJuqvHsCj/HsY2UKbHMJ7y+ofwrpdYy0LRn9UEhRFEirLkcpKJ6udduTW3diGtMldReEdXItdTekD0uRQqKi3q0XJCFrcRmhRXwkky0BY4akQj14ZXSAw7VoCD+lqcIaSq2tWq9UZVU1Dkvtk1XmAWPrPP626FtlSy/OyY4o1q87tAYkhJb7Kml6B+jbLNAgcSeWCWIpucm2dAxDNvIXddxfDA8e2gN02Hm2GZqoalbQHmqleiyoCaXPvieDWjbjm+5rpXlOWSQ2WDmVp74FsDQQje12J6aahAUnnK5FpL3jbHxPDyJw1V0tpqG4Wl4SgJ3Df+TupxHBMXz5XRMNDHrhgvC2kFE0zicn4zj6CLsxz/BAtLdYkMPkEMp8bCf2QwaqFBhI1nwnQb0/Bvv1t3EVPdlcXQetmZf4hdQbjvgtj8w3Q50J9DdgecPdV1n+/0P4mlN+krsyzKcf2X91RxzbLBO//NNKKOLvr3lzwtHIK0cCUlF/7QDqWxlujG3u8Cr1o7heKbpe77rm47NOrhRf8Us22CHv7asrYgV1uqpp0U4CccxtdqLbeULREF6lmk0/UjRnwVKSIb0AwAA" } }, { "ID": "ccd6a624de32dec8", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/FLf3MWrUtTzxxqb6qmCPheJTT4e?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:48 GMT" ], "Etag": [ "4tS78Ms3S5OdtBN/1xms/Q==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2PW2+CQBCF/8v0FaNGewmJD8XY1AasckkfmqZZYLjYXRbYIYUS/ru72qeZL3PmzJkRfsoqBRviMm86bIe7HOlkGh9Vx0npUstKIViAxHKtXFPw+OSpVXD/npJzmC97oeanzUYrVFKgYGCPkJXIUwX25wgVE6jXssW3VtBQGwj33k6TkKmhQ+S6z467g+lrsuAsYx8zbLFK0FjVrTxjQnuTUhWS80GwapaikDNCRXDduE5f3GzlfbQRhX9938QPjdgeC3wLw7WJz2XCqJSVFkYB6EMkiXFf/uqYsIR/dgZtemxlgkqhMV3cDmylqDmSTkRthxYkTP/6WtKNpwvctdvMSAEAAA==" } }, { "ID": "14880fbb90b88854", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anonf8a874ae44583663dffadad4a2f3fb83aa93e6c3/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:48 GMT" ], "Etag": [ "iv2flgpb4yyWt1UzFZv8bg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8pnlhml5aQXJJlUVoaXGIZWuUWVWSSl29oCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwobmFgZmFoZmOmZW1gaGBgo1cYCIQB0TlNMfAAAAA==" } }, { "ID": "ba95cad8a9ef6029", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "273" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5Ijoic2VsZWN0ID8iLCJxdWVyeVBhcmFtZXRlcnMiOlt7InBhcmFtZXRlclR5cGUiOnsidHlwZSI6IkRBVEVUSU1FIn0sInBhcmFtZXRlclZhbHVlIjp7InZhbHVlIjoiMjAxNi0wMy0yMCAwNDowNTowNi43ODkwMDAifX1dLCJ1c2VMZWdhY3lTcWwiOmZhbHNlfX0sImpvYlJlZmVyZW5jZSI6eyJqb2JJZCI6IktFZjRlZ1JNdjFqS2VSRDJQd1p0czVEZHZiOSIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:49 GMT" ], "Etag": [ "E2psafbc3yLBxCGDUBEq8Q==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42S207bQBCGXwVtb0l8jg8SohC7yCJE4DhUbVVF6/XYLNhe492ERoh379gGWrUU9cLyHr5//pnZeSR3vMlJQDJe3m+h23+4FRk5JKBoiaeR2UpaZMzaL05/zM/C9Wl0710dHSHBe5W8EVW1r2kzyaEWEwVSBevV9DwqbCiTi51xew5JaF4+fFXSCfNd5qNSQlUseHOH+hulWhlo2ov7tBSirIC2XE6ZqF/PtZ2ptZ24Baak9oaphllL7R3b40owqrhojtYrTGErodtATXmFSfQBJp3IhPr4Rugpp/W0RH7HGVDGxLZRfW4YhYmm4OW2GwKT4JEMuf626EvFlA+OEc4xFm8GNKVZBT32XFL8j1b2KqqohJHYZACmO8ty3zEM2yhmM8fxqOHavuUzP3dsk1lg6hZFneotBhVtRJPnvm64BfWYwZhreYbnQuG6jm35tm2YnlMUJvUNhzxhUR1QBSGXrZB8LIzMk+gkjTbxp80yisIoRIOHjv9JfU5ihNJkvZwjjUzbcYFY34h4mUbJyTyNr6Ox/QsoKduv7vEBClpJOBx7dkk7WoOCTpLgGzboZZvu26FjaviTEA3S+CLqE35lrmm1HaDduCCmbswmujUx9QPdDnQn0GdT1/N1XSdPT99RilMzBiZX6yj5QsajBArooGH/+USoGG7fH/qX+UMQJxCNpMI9jgSTvc3Q9X40eN2nYziuaXquN8PPIQPcqb/ufMckh7+Gro8INTTquaZVtIjmKZY6mm3lK4SX+ErLeHmGtz8Bwx8PmQMEAAA=" } }, { "ID": "290b7dec67c34355", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/KEf4egRMv1jKeRD2PwZts5Ddvb9?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:49 GMT" ], "Etag": [ "BO8WwweiRez7+ICfwrsOoA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2PUU+DUAyF/0t9lCWb0agke4BBIhlzE7eYaIy5QGHghSK3jOCy/27ZfOo9vV9PT4/wXdQp2BAX+U+H7XCVI7+MjwhNp9lIaag2CBYgq1xId/3w1vdYRPh7fx0ssr41a3LmcyFMssdKgX2ErECdGrA/jlCrCmUsm34JwUMzCs/Z+ttg5UunonTsPO/C0HFDH06fJwtKiiPMsMU6wdGuaanEhIMxqdmT1kOl6kmKFU0YDcN54vy79LNbzKPVYVYuMfJuNv07mzsvPcSPQmlKFBdUC7h7BVnExEpH1EtUmMG/dgcx3bSUoDE4mk4vCxZUNRpZEnHboQWJknufCr7o0x8pMNKQTAEAAA==" } }, { "ID": "482384a3bee9aff6", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anondd9017fa8c1cc738187ef775439441285ff2a915/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:49 GMT" ], "Etag": [ "8xIW1L1AcIicBvQK0SAnVg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8pbVHiGG/oYOiZ7ZiY7lQV6GwQ75oWl29oCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwobGRia6RoY6xoZhBiYWBmYWhmY6ZlbWBoYGCjVxgIhAAAd5DOHAAAA" } }, { "ID": "613164480ed4514d", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "258" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5Ijoic2VsZWN0ID8iLCJxdWVyeVBhcmFtZXRlcnMiOlt7InBhcmFtZXRlclR5cGUiOnsidHlwZSI6Ik5VTUVSSUMifSwicGFyYW1ldGVyVmFsdWUiOnsidmFsdWUiOiIxMi4zNDUwMDAwMDAifX1dLCJ1c2VMZWdhY3lTcWwiOmZhbHNlfX0sImpvYlJlZmVyZW5jZSI6eyJqb2JJZCI6IlVtT2xReVBHZDVLUHBHRzJjZDZxYUhzOU56MyIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:49 GMT" ], "Etag": [ "x3FaYZpmTw/m8gzaNTK3aw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42SbU/bMBDHv8rkvYWGPDeVEEMldBEsgzRlYtNUXZ1LMCRxGruwgvjuuyTApo2h5U1s3+/uf08P7EbUGZuwlSjWG2y376/liu0w1FDQ6w/7GC6/NlV6Z1Tj4h7i9MSGu/19IkTnpa5kWW4rqHczrOSuRqUni/loUX0uz7dns8w9OWtmM4tn3ho+qiC+t8lTYZmfivqG/K+0btTEMJ7VR4WURYnQCDXisnp5N24to2nlNXKtjFdEDcpaGW/IHpSSgxay3l/MKYWNwnaJFYiSkugC7LZyJfWHV0KPBFSjgvhbwRE4l5tad7lRFC7rXBSbtg/MJg+sz/W3Q1cqpfzugOCMYom6R1NYldhhTyVF/2hl5wUaFA7EcoVo+d4qC1zTdMzc81x3DKbvBHbAg8x1LG6jtWcD+elOoveCWtZ7jgdOboFr25Zng8XRCxzft2wzB9fJue8HvhkgZ49UVIug8UioRioxFMamSXiYhsvoeBmH4VF4RAJ3rfiT+pJEBKXJIp4STUzTCklY14goTsPkcJpGF+HQ/lMsgG/naxpADqXCnaFnZ9BChRpbxSbfqEHP13Tb9B3T/Z/Fi09hEk27fF+QCyg3PXM7HJhpjWzH3es/9vj4nWBakyESO1+EySUbnhLMscWa/+dMyKO3vr3lzwvXgfNOSGm60w5w1cn0be52QVR9rq5vWWN/7AX22Gc93Oq/bDRptvNry7qIWGGtn2qah6fhNKVSB7GNeoHISGOJo3hG1p+hKNMS9AMAAA==" } }, { "ID": "fcf5248f146a8be2", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/UmOlQyPGd5KPpGG2cd6qaHs9Nz3?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:49 GMT" ], "Etag": [ "gIcnw4kr4r7TtuRvuNehjQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2PW0+DQBCF/8v4SpOqVSNJH2zTUCIiYPtkjNkuw617obuDDRL+u0vr0+yZ/ebMmQGOtcrBh0Ndnjo0/U2JlE6PDG0nyLrSamURPEBipSPLkKvz4mgW5mlHXfbTxVg16XLpCMsrlAz8AYoaRW7B/xxAMYlurJh/O4L6dhLx/m2ThWvXkDq/NqLoZRVtYPwaPWj0IcMCDSqOk1trdIOcwimorbQQvWRqlqPUM0JLcJm4/O7lu0j7JMgfXpM2CO54/nhiW/sc/947SmjOqNZqAj/ALSJNTGT67JLCLfzrVe9ME6M5WouT6fy6YK1lK5BcIjIdesCZO3db01WPf9pKNMVLAQAA" } }, { "ID": "dbb048b78aa9573a", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anon046a4f2a533263a2ce69477231fa54fc779719ec/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:49 GMT" ], "Etag": [ "0SCxdxaANP3IcQ1I9V2PxQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8obBDtXpFQkOvoFGHsmBxp6WoYZBVQE2toCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsAwkb6RmbmCrVxgIhAJV6c2tzAAAA" } }, { "ID": "9ed7cafc86ec95bc", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "263" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5Ijoic2VsZWN0ID8iLCJxdWVyeVBhcmFtZXRlcnMiOlt7InBhcmFtZXRlclR5cGUiOnsiYXJyYXlUeXBlIjp7InR5cGUiOiJJTlQ2NCJ9LCJ0eXBlIjoiQVJSQVkifSwicGFyYW1ldGVyVmFsdWUiOnt9fV0sInVzZUxlZ2FjeVNxbCI6ZmFsc2V9fSwiam9iUmVmZXJlbmNlIjp7ImpvYklkIjoiSk90RnRKV0c4NktnY2d0YXZnbzVuOHNUNHA3IiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:50 GMT" ], "Etag": [ "odipY6sJFwYRkyt6qicd0w==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41S70/bMBD9VybvKzS/naYSYlUJqAyVLU2HqmmqHOcSDEkcbLeoQv3fd0mATYihfUp89+7eu3f3RO5Fk5MJyUT5sAW1/3wnM3JEwLASozIX7Zrqy/PHdXK/N/RB8Nx+PDlBhOiq9K2sqn3NmuMcanlsQJvJajm6vDbn5vLmYky/lrw0bFfKoBnr1G9DrNRQFVeiucf6W2NaPbGsF/ZRKWVZAWuFHnFZv8atnWu1St4BN9p6h9RC1dr6gPa0kpwZIZuT1RIlbDWoDdRMVCiia3CsZCbNl3dajwSrRyXid4ID41xuG9Npwy5cNoUot6pvTCZPpNf61083Kkr+dIrgHHuJpoemLKuggz2PNP+HlV0VM0zDgNhkAG5IszwKHMd3CkqDYMyc0I+8iEd54LvcA9f2GNaZjqKvYo1s/CKICg+cKAsDyhwvcBm1C9/OPNf3qRvlBRvbNqXkgEMpYAbOhG6lFsNgZJbE0zTezM83izg+i8+Q4FGJt6ibZI6gNFktZohGTKuERFhnxHyRxsl0ls5/xIP9V1Ayvl8+4AIKVmk4Gjz7xhSrwYDSZPITDXp5pvu2d8z0XzJNkukaGzGl2P5NDqmoTw6Hwy+cBu9iSJPvqzhZkyGUQAEKGv6fS8CKPvvxWb9cGALxxpBIG3zj0rnuaHpfu+WLupPjBKHrjsMxjSKPkh6szJtcaNt+RI7+nFXXEWpozPNMy/gqnqU460C21a8gTOIeFvPFBWZ/AwFvqFflAwAA" } }, { "ID": "8dd499b60c26fdfd", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/JOtFtJWG86Kgcgtavgo5n8sT4p7?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:50 GMT" ], "Etag": [ "kBb2q/TXQouTqfW3v5aFiw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2P3U7CQBCF32W8hYg/KGnChWhBMFGoNZgYY5btdClsd0p3Cmka3p0peDV7Zr85c6aBbeYSCGCVmV2FZX1lkBftI0JfWfZSCnIeoQPIygi5Ha1ud9fx94KqeJcu7/Z9Nc4Ow6EQXq8xVxA0kGZoEw/BTwNO5Shjae9PCK6LVkzf43ASRtLIKWkbUTgPn+LwBY6/xw5saBVhiiU6ja1bUdIGNU/boH5N1ta5ct0Ec+oyeobzxPl39sFjni0ng4c3ow2rvaG+G/j4vngUypJWnJET8OsTZBETKxvRQZLCDfzrUS2m85I0eo+tae+y4JnywiJLIi4r7IBWcu5rxhd9PAEztHpkSwEAAA==" } }, { "ID": "f09f28a519a32404", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anon4f59f3e19b756a1352a60f40b3244629dfa80066/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:50 GMT" ], "Etag": [ "XMGvErQA4Dp2KEqRxois0Q==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8pH+LqXuRYFOpq4FBh5uxYGVeRnFhsE2toCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsA5KxtSAIABJyG7JtAAAA" } }, { "ID": "b62f7db097175712", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "263" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5Ijoic2VsZWN0ID8iLCJxdWVyeVBhcmFtZXRlcnMiOlt7InBhcmFtZXRlclR5cGUiOnsiYXJyYXlUeXBlIjp7InR5cGUiOiJJTlQ2NCJ9LCJ0eXBlIjoiQVJSQVkifSwicGFyYW1ldGVyVmFsdWUiOnt9fV0sInVzZUxlZ2FjeVNxbCI6ZmFsc2V9fSwiam9iUmVmZXJlbmNlIjp7ImpvYklkIjoiOWF3YWYxOG9tdlFVc0VmNzg2cktQOFRDUmhiIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:50 GMT" ], "Etag": [ "TYR97vVaSU1rY96U1YKOTg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41S207bQBD9lWr7CvElvkZCNErcKgIFcGyqqKqisTN2Fmxv2N0ERSj/3rENtKIU9cnemTPnzJmZJ3bPmzUbsYyXDzuUh893ImMnDDWUFE2Wcejvb2GRWnIZeqm1vLhKyrMzQvC2Sm1EVR1qaE7XWItTjUqP0sUghEcorEDU+5tURYUfePLiOkgm8ablVlgVl7y5p/qN1ls1MowX9UEpRFkhbLka5KJ+jRt729hKcYe5VsY7ogZ1rYwPZM8rkYPmojlLF9TCTqFcYQ28oiZaglMpMqG/vEM94FAPSsLveY6Q52LX6LY3YslFU/ByJztiNnpiXa9//LRWqeVP5wReExdvOmgCWYUt7NnS7B+jbKtAg8IescoQbd/L1qFrWY5VeJ7rBmD5TjgM83DtOnY+RNscAtXpVqKrgkY0TuGGxRCtMPNdD6yha4NnFo6ZDW3H8exwXUBgmp7HjmRKImiccrUVivfG2CSOxkm0mn1dzaNoGk1J4FHyt6jv8YxASZzOJ4QmzFZyQbB2ELN5EsXjSTK7jfrxX2IJ+WHxQAsooFJ40s/sGiTUqFEqNvpBA3p5JodtNzHdfdk4jsdLIgIp4fAmR1Kew47H409yQ3fRp9lNGsVL1odiLFBik//nEqiiy3581i8XRkC6MRJSmt609Fy1Mt1c2+Xzum3Hcn3bDvzAN73AZB1Y6r9yPjk5+X1WLSPW2OhnT4voMpok5LUX26lXECVpD/PZ/BtlfwE5ViJK5QMAAA==" } }, { "ID": "2771beb89e47e29d", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/9awaf18omvQUsEf786rKP8TCRhb?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:51 GMT" ], "Etag": [ "FbDhsCoKhszX5g/h5bhc0w==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2PQU/DMAyF/4u5bqI7DEqlHaArME1CXdkkJIRQmrpNR1KXxqMq0/477sbJec7n5+cjfNVNARHkdfV9wG64qpA34yNDf7DspbTUeIQJIKtKyMd8aXxMa+N/3+bVtZnnRgf9YiGE1wadgugIZY228BC9H6FRDmWsDD6F4KEdxeplmzwlmTQcFWMjS9Lkfpss4fRxmsCe8gxL7LDROLq1He1R82oM6g1ZOzjVTAt0NGX0DOeJ8++d6lU5C8n9bHY+KW/Dm26dhts4M7lQlrTimhoBd68gi5hY2Yx6SQoz+NcPg5imHWn0HkfT4LIgJtdaZEnE3QEnoJWc+1zzRZ/+ABdSCCJLAQAA" } }, { "ID": "e1eacc9e1eae0fd9", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anon4f59f3e19b756a1352a60f40b3244629dfa80066/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:51 GMT" ], "Etag": [ "XMGvErQA4Dp2KEqRxois0Q==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8pH+LqXuRYFOpq4FBh5uxYGVeRnFhsE2toCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsA5KxtSAIABJyG7JtAAAA" } }, { "ID": "52443880e5aa7f66", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "306" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5Ijoic2VsZWN0ID8iLCJxdWVyeVBhcmFtZXRlcnMiOlt7InBhcmFtZXRlclR5cGUiOnsiYXJyYXlUeXBlIjp7InR5cGUiOiJJTlQ2NCJ9LCJ0eXBlIjoiQVJSQVkifSwicGFyYW1ldGVyVmFsdWUiOnsiYXJyYXlWYWx1ZXMiOlt7InZhbHVlIjoiMSJ9LHsidmFsdWUiOiIyIn1dfX1dLCJ1c2VMZWdhY3lTcWwiOmZhbHNlfX0sImpvYlJlZmVyZW5jZSI6eyJqb2JJZCI6IlZVNUpFZlF1djZtbTExRG5yQ0NUZG1wSW9oMCIsInByb2plY3RJZCI6InNob2xseW1hbi1kZW1vLXRlc3QifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:51 GMT" ], "Etag": [ "DFxiWD3VE5yL5v2SaXc84g==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41TbW+bMBD+K5P3NQ3lxSREqroooRNTFK2EpKumKTLGELeAqW2yRVX++w7TplPXVZOQ4HzPy935eET3vM7QBKW8eGiZPHy8EykaIKZJAafzq1/8Zu5uQnxY4L2zIt/o2CsuLgDBO5baibI8VKQ+y1glzjRTerJeDTdr/CXMr9u9X1W2Pa/lbJZkVROJ3TkwFSvzBa/vgb/TulETy3p2HxZCFCUjDVdDKqrTubV3rEaKO0a1st4wtaBqZb1je1kKSjQX9cV6BSW0isktqwgvoYhO4EyKVOhPb0gPOamGBeD3nDJCqWhr3dUGKlTUOS9aaYTR5BGZWv/46FqFkj9cAjgDLV4baELSknWwp5aif4yyYxFNFOsR25QxZ+SnWYBt27Nz38d4TOyRF7gBDTLsOdRlzrlLgKc7C8MitahJ5nlOnnk48M49lrvYxzRPM2o7eEzHbmpj28U0wOgITUlGNJtz1QjF+8bQLA6nSbiNrrbLMJyHczD4Kflr1E0cASiJ18sZoAHTSC4A1g0iWiZhPJ0l0Sbsx79gBaGH1QNcQE5KxQb9zL4SSSqmmVRo8h0G9Bwmh8ZMTJs3msbx9BaEiJTk8CoHVr6HjtDKib0hZWsgBm+iXn/fJ5ANnb9EDjr+OMIzQLBWvTq6XofxLeqPYpYzyWr6n3cIDJN9/694XlAAwoqCkdIQw85Q1dmYa+l2h1emYDxynPFoPLLtwEcGLPVfOSfw0OBlKztFVrFaP/W0ChfhLDGj6lKtOoEgCde4jJafIfsbTHDNciQEAAA=" } }, { "ID": "3a3480f8d2c037db", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/VU5JEfQuv6mm11DnrCCTdmpIoh0?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:51 GMT" ], "Etag": [ "P7gJM2ZXkJanhvgVvKeKLA==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2P3U7CQBCF32W8haQ1UZMmXCA02qKmVCBGY8zSTn9gd6d2p5iG8O5MwavZM/vNmTNH2Nc2hwC2dfnbYdvflMjL4ZGi6zQ7KQ1ZhzACZFUKmTyU8evt58c+VrY6lJvDAhcv08lECJdVaBQERyhq1LmD4OsIVhmUscL7EYL7ZhDR2yp8ClNpGMqHRhom4XQVzuH0fRrBjrYpFtiizXBwa1raYcbRENRVpHVvlB3naGjM6BguE5ffzfouDotld7g3xvfntp3NVrlpIqo8oTRlimuyAq7fQRYxsdIp/UlS8OFfP/ZimrSUoXM4mHrXBTMyjUaWRNx2OIJMybnPNV/16Qzg0yrpSwEAAA==" } }, { "ID": "030c304dc9962fb7", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anonad442fd459404ef3565cfbdc1258c83b15135c95/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:51 GMT" ], "Etag": [ "keCPj8S1SB83nf2ROL+02Q==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8pnpzoHZFkEGwY7WRjnpRkF+ftoGxgF2toCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsg5FAyVodCMtIqTYWDAEND7H5gAAAAA==" } }, { "ID": "5c4e2ebd964638e4", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "320" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5Ijoic2VsZWN0ID8iLCJxdWVyeVBhcmFtZXRlcnMiOlt7InBhcmFtZXRlclR5cGUiOnsiYXJyYXlUeXBlIjp7InR5cGUiOiJJTlQ2NCJ9LCJ0eXBlIjoiQVJSQVkifSwicGFyYW1ldGVyVmFsdWUiOnsiYXJyYXlWYWx1ZXMiOlt7InZhbHVlIjoiMSJ9LHsidmFsdWUiOiIyIn0seyJ2YWx1ZSI6IjMifV19fV0sInVzZUxlZ2FjeVNxbCI6ZmFsc2V9fSwiam9iUmVmZXJlbmNlIjp7ImpvYklkIjoiMTZNM245N2s1RGZFRk5mNHpJVkRBZnZZYzJBIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:51 GMT" ], "Etag": [ "X7KE3isjmU5IxoYG2YFYfw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41TbU/bMBD+K5P3Fdomad4qIVa1AUVj1ZambNU0VY57DoYkLrZb1iH++y4OdBtjaFKk5HzPy935ck9uRLMmI1KI8nYLav/2WhbkiIChJZ5+Cd8nntDX9cJPv8vlubs8W/K7kxNEiJalr2RV7WvaHK+hlscGtBkt5j0n+OA1cXjjT3lyNuPDH+nldMx3S+aOkamh4heiuUH+lTEbPer3n9x7pZRlBXQjdI/J+nDe37n9jZLXwIzuv2Dax6p1/xXb00oyaoRsThZzLGGrQa2gpqLCIlqBYyULad69IN0TtO6ViN8JBpQxuW1MWxuqMNlwUW6VFSaje2Jr/e2jbRVLfnOK4DVqicZCc1pU0MIeW0r/McqWRQ3V0CFWBYAbBsU69h1n6PAg8P2IOuEw9mIWr/2hyzxwBx5FnmktLIs2soliHkaRx8OQh5RGPvdh4HHqUAhicHxWDAbOgBUeecCmFFADU6E3UouuMTLJknGerNKz1SxJpskUDe6UeI76nKUIyrPFbIJoxGyUkAhrB5HO8iQbT/L0MunGfwElZfv5LV4Ap5WGo25mH6miNRhQmoy+4oCewny/sRMz9k3GWTZeohBViu6f5dAqGJIHbOXAvqTV1kIs3kad/q5LEAc7/xW5f0Q4lW8P+BwRXLLOi3xaJNmSdEcZcFDQsP+8UWTY7Ov/yNO6IhAXFo20wRg3iOnWxl5Su0mituX7oetGYRQ6QTwkFqzMX7nIbXOHHW0VoYbGPPY0Ty6SSW4H16a2+gDCJF7qLJ2dY/Yn2kbchDIEAAA=" } }, { "ID": "5a47e386a7eae691", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/16M3n97k5DfEFNf4zIVDAfvYc2A?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:52 GMT" ], "Etag": [ "xGEDkgBfSBl/3L2yU+MS8g==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/y2Pb0/CMBDGv8v50hER/EvCi+EqLhGCG5gYY0zprmPQtXO9iXPhu9uCr3rP3e957trBrtAZjGBd5F8N1u1ZjvTiiwRto8i6pzLaIgSAxHNH/kxZtMsnMp2oi+HzoF2dz9K7fDx2hBUbLDmMOpAFqszC6L0DzUt0Ntn/dAS1lRfxfMmmLHGN0mS+kbAFC5csgsPHIYCtWScosUYt0KdVtdmioNgfajdGqbbkupdhaXqEluDoOE4vb2ZDfX+7u44ke5zLq9/4NQrl95sYhI5SRnAqjHbgKgW3iAxxlZi99Vb415PWhS5qI9Ba9KH904IHU1YKyV1EdYMBCO6++1TQSR/+AAfbSLNLAQAA" } }, { "ID": "986beca3fe39d9fd", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anon89f7883f77f7aa85f5e03fa1ae69e15cb0010cb3/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:52 GMT" ], "Etag": [ "LHZFxu922mSUaKCBjDxSrw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8r7eES5VZRaGhnlBocmejs7ZblUBBeV29oCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsg5FAyVodCMsIzjJWqo0FQwAcBa/eigAAAA==" } }, { "ID": "bb7f4edc4eb2d02d", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "479" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5Ijoic2VsZWN0ID8iLCJxdWVyeVBhcmFtZXRlcnMiOlt7InBhcmFtZXRlclR5cGUiOnsic3RydWN0VHlwZXMiOlt7Im5hbWUiOiJBIiwidHlwZSI6eyJ0eXBlIjoiSU5UNjQifX0seyJuYW1lIjoiQiIsInR5cGUiOnsic3RydWN0VHlwZXMiOlt7Im5hbWUiOiJEIiwidHlwZSI6eyJ0eXBlIjoiU1RSSU5HIn19XSwidHlwZSI6IlNUUlVDVCJ9fSx7Im5hbWUiOiJDIiwidHlwZSI6eyJ0eXBlIjoiQk9PTCJ9fV0sInR5cGUiOiJTVFJVQ1QifSwicGFyYW1ldGVyVmFsdWUiOnsic3RydWN0VmFsdWVzIjp7IkEiOnsidmFsdWUiOiIwIn0sIkIiOnt9LCJDIjp7InZhbHVlIjoiZmFsc2UifX19fV0sInVzZUxlZ2FjeVNxbCI6ZmFsc2V9fSwiam9iUmVmZXJlbmNlIjp7ImpvYklkIjoiRXR4eWtHaVdRNjc3Wm8xOUdZMHk5TnpvYkxkIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:52 GMT" ], "Etag": [ "Zl+mHqWn77oDgku5vunTDg==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/41TbW/aMBD+K5P3cZS8E4JUdRSyDgnRFUKrdpqQk1xSlySmscPGKv77zk7ftnbdvhDse57n7h7f3ZE1q1IyIDHLbxuod+9veEw6BCTN8faq+FB+vr2ofJ+P83XjbZsqGueHh4hgiiWueVHsSlodpFDyAwlCDpaLbih/7NYn7OKs5/tX3ApOLs1dMPvJ42mKTAFFNmXVGvnXUm7EwDAesndzzvMC6IaJbsLLx3tjaxubmt9AIoXxSlIDqxbGG2mPCp5QyXh1uFxgCY2AegUlZQUWoQQOah5z+fEV6S6jZTdH/JYlQJOEN5VUtaFKwquM5U2thcngjuhan/1RrWLJ744QnKIWqzQ0onEBCnbf0uQvVioWlVRAi1jFALbfi9PAsyzXyno9z+tTy3cDJ0iC1HPtxAHbdCjypEqhWbTilR+Dmbl9sFw3Nk3LzijYlgWpk/V8x+uDGYCdBrFP9thUDVTCmIkNF6xtjIzm4TAKV5NPq1kYjsMxJvhesz9RF/MJgqL5cjZCNGI2NeMIU0ZMZlE4H46iyXnY2j+FnCa7xS0+QEYLAZ3Wsy+0piVIqAUZfEWDHo7RbqMdk/pLFphlFKlZknWTSBVtCRXCMT5UFvxOwQp6LtnvO4+g45egf+mOX6VMZico/O259ugl8Pj0dKphnae2zmnRaEybTx+FOg/Vz7aNElO9y+j5jbYMxVo5HP7WH3K2DOeXpL2aQwY1VMl/ThoydPTt3X1YIwTiIu2VUXjGyU502Xp41IQz7YLl+bbd9/u+7TmudpXW8kWs5zik87Q7ShFKqOR9T4twGuKb7O+TNeIRhEEctllr/y+vvPbYygQAAA==" } }, { "ID": "4f13da0ba6e72fdb", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/EtxykGiWQ677Zo19GY0y9NzobLd?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:52 GMT" ], "Etag": [ "2tMOGKxq63ABYb80uEfdKw==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/52R3W6CQBCF32V6qwm2iVYTL0AJNVKoq6axTdPwMygKLLJDFI3v3kGb2qRe9Wr3zJ5vzu7sETZxFkIP/Hi5LbGo7pZIk3ojUJUJKV5ymSmEBiB5S3be07Nrjffb9oNuLPxHrTSjcLzr99mhghWmHvSOEMWYhAp670fIvBQZi7RPdlCV10KYA1cMWacyrLUzt23dsE2u/CX1KzdyZqZlihvgqfHjN/6ZM7xy05kYOdatmI9fQYMrYLiuberObYIZWEtfYIQFZgHWA8oLucaARvXs1UomSZV6WTPEVDYJFcGZOJ+atK82Vvw6aXc6b7LVtRZa1XUO0rdDdiUy8CiWGRvnU54CkCQvEXLHT4MWfGuj4qYvhQxQKaybapeAgUzzBIlvREWJDQg8/sGnmC769AUxgzMlHgIAAA==" } }, { "ID": "d43a86b182fa0a5a", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anon7be0f48e144b0012fae211ed3f67358e09e2d9b7/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:53 GMT" ], "Etag": [ "V7Aakxx6AhoQyiqKGgo/ZQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8qHmTsmZldUmDlm5AdWZhZ6u6fn60cF2toCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsU7JCYioZKNXqgFl5pTk5UKZSWmJOcapSbWwtEMXWAgCp0n0BlQAAAA==" } }, { "ID": "da88ba321321ed32", "Request": { "Method": "POST", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/jobs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "512" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb25maWd1cmF0aW9uIjp7InF1ZXJ5Ijp7InF1ZXJ5Ijoic2VsZWN0ID8iLCJxdWVyeVBhcmFtZXRlcnMiOlt7InBhcmFtZXRlclR5cGUiOnsic3RydWN0VHlwZXMiOlt7Im5hbWUiOiJBIiwidHlwZSI6eyJ0eXBlIjoiSU5UNjQifX0seyJuYW1lIjoiQiIsInR5cGUiOnsic3RydWN0VHlwZXMiOlt7Im5hbWUiOiJEIiwidHlwZSI6eyJ0eXBlIjoiU1RSSU5HIn19XSwidHlwZSI6IlNUUlVDVCJ9fSx7Im5hbWUiOiJDIiwidHlwZSI6eyJ0eXBlIjoiQk9PTCJ9fV0sInR5cGUiOiJTVFJVQ1QifSwicGFyYW1ldGVyVmFsdWUiOnsic3RydWN0VmFsdWVzIjp7IkEiOnsidmFsdWUiOiIxIn0sIkIiOnsic3RydWN0VmFsdWVzIjp7IkQiOnsidmFsdWUiOiJzIn19fSwiQyI6eyJ2YWx1ZSI6InRydWUifX19fV0sInVzZUxlZ2FjeVNxbCI6ZmFsc2V9fSwiam9iUmVmZXJlbmNlIjp7ImpvYklkIjoiNDlXczlTWnZFblJxUHFueDVaV2ViWm93emJkIiwicHJvamVjdElkIjoic2hvbGx5bWFuLWRlbW8tdGVzdCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:53 GMT" ], "Etag": [ "hbSgf88BeEZ4A822HbEonQ==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/42Ta2/aMBSG/8rkfaWQhIQkSFXHJduQEG25tBrThJxwkroNNsQOLav47zt2emEr6/aF4HOec3vt80juGF+SNolZtimh2H28FTGpEVA0Q+tNPMnSIOhCNHc7geN8jSPBL09PkWA6St6IPN+tKD9ZwkqcKJCqPZvU3fBahpP5NuLjzcWGP3jza4jn4v5nvMRICXk6ZPxO51dqLduNxnP1eiZElgNdM1lPxOrF3tg6jXUhbiFRsnGkaAO7lo13yp7lIqGKCX46m2ALpYRiASvKcmxCJzgpRCzUpyOp64yu6hnyW5YATRJRcqV7wyyJ4CnLysIkJu1HYno9+KNHxZY/nCG8xFyMG3RK4xw09jTS4C9S6iiqqISKWMQAjt+Kl6Fn266dtlqeF1Dbd8NmmIRLz3WSJjhWk2Kc0iVMFOWCW02rBS0rjK2mTy2PNm3fomFge5AmduoGfsv2IYQl2eNQBVAFfSbXQrJqMNIbR51ptBh8XoyiqB/1scB9wf6krscDhKbj2aiHNDLrggnEtBCD0TQad3rTwVVUyT+EjCa7yQYvIKW5hFql2QUt6AoUFJK0v6NAz8fpbm0UU+ZLJlilN9VvSRVlorS3CuCIo7+jJfg9BDtouWS/r71A3bfQv/L2j4YMRl8w8Y/D3L23YPf8fGiw2utYVzQvDVPVM0epzx39s628xNb30j2G9Q8xidkR7B3akAdtNmVxSSodyeUsGn8jlWkMKRTAk/98kRhhvO/v+PO6IYgLt9eC4hk3IDF9m0emN4EZtWzPd5zAD/ym5btGfVqoNz7bC0ntdcd0RlgBV08zTaJhhHe3fypWyhcInfgoR9U1/QIw/X/t8gQAAA==" } }, { "ID": "408a63203fe397cd", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/queries/49Ws9SZvEnRqPqnx5ZWebZowzbd?alt=json\u0026location=US\u0026maxResults=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:53 GMT" ], "Etag": [ "JJEbugGSziw3aFKmS0o17g==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/52RUU/CMBSF/8v1FRKIGgMJDwwqgsvADkKCMabbLmPYtWPtxEH479yBERN58qk9t+e7p73dw0eiImhDkMSbAvPyJkb7Um04mkJaQ0umlUGoAVoRk3M0YkERD/xdsr0Vj8+p39DNh7jTIYcJV5gKaO9hmaCMDLRf96BEioQtG+/ksGVWCc56Y94nneqo0t7MdbuOy6jyl+xeuKE3ZQPGr4CH2o/f+WdO/8L5Uz70Btdi3n4F9S6AMx67rOtdJ4iBtQ44LjFHFWI1oCzXawztsJq9WWkpy1SoeoSprls0Fk7E6fSuNTctf/HJFN9MNurrfjHHYKG3uyAil9ShsIlWZJz5NAWw2grJ9ZaeBk341k5JTSe5DtEYrJo2zgE9nWYSLd3I5gXWIBT0g0+JPevDEaR8u+weAgAA" } }, { "ID": "d92e7008dce6c785", "Request": { "Method": "GET", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/_bee276bd951141f66558a174939c9d542c3e203a/tables/anon0306e609b037a05a3170a9815efc1f487617e9ed/data?alt=json\u0026prettyPrint=false\u0026startIndex=0", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:53 GMT" ], "Etag": [ "VTPvXen4e+jVq/SXL1Lb7Q==" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6tWys7MS1GyUkrKTC8sTS2qVC5JTMpJdUksSfTJLC5R0lFKLUlMB8qHhQSURaTmmaRqZ4UV6gdH+Bj6JJkH2toCVZTklyTmBOWXFwOVGQL5RWBmdLVSGpgsU7JCYgJV1OpgCBYr1cbWQsWVSopKU8H8WCAEAFj4RHChAAAA" } }, { "ID": "9a3be072efb53ccb", "Request": { "Method": "DELETE", "URL": "https://bigquery.googleapis.com/bigquery/v2/projects/shollyman-demo-test/datasets/dataset_20191028_66906590093659_0001?alt=json\u0026deleteContents=true\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Cache-Control": [ "private" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Mon, 28 Oct 2019 18:37:54 GMT" ], "Server": [ "ESF" ], "Vary": [ "Origin", "X-Origin", "Referer" ], "X-Content-Type-Options": [ "nosniff" ], "X-Frame-Options": [ "SAMEORIGIN" ], "X-Xss-Protection": [ "0" ] }, "Body": "H4sIAAAAAAAC/6uuBQBDv6ajAgAAAA==" } } ] }google-cloud-go-0.49.0/bigquery/copy.go000066400000000000000000000063361356504100700177300ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "context" bq "google.golang.org/api/bigquery/v2" ) // CopyConfig holds the configuration for a copy job. type CopyConfig struct { // Srcs are the tables from which data will be copied. Srcs []*Table // Dst is the table into which the data will be copied. Dst *Table // CreateDisposition specifies the circumstances under which the destination table will be created. // The default is CreateIfNeeded. CreateDisposition TableCreateDisposition // WriteDisposition specifies how existing data in the destination table is treated. // The default is WriteEmpty. WriteDisposition TableWriteDisposition // The labels associated with this job. Labels map[string]string // Custom encryption configuration (e.g., Cloud KMS keys). DestinationEncryptionConfig *EncryptionConfig } func (c *CopyConfig) toBQ() *bq.JobConfiguration { var ts []*bq.TableReference for _, t := range c.Srcs { ts = append(ts, t.toBQ()) } return &bq.JobConfiguration{ Labels: c.Labels, Copy: &bq.JobConfigurationTableCopy{ CreateDisposition: string(c.CreateDisposition), WriteDisposition: string(c.WriteDisposition), DestinationTable: c.Dst.toBQ(), DestinationEncryptionConfiguration: c.DestinationEncryptionConfig.toBQ(), SourceTables: ts, }, } } func bqToCopyConfig(q *bq.JobConfiguration, c *Client) *CopyConfig { cc := &CopyConfig{ Labels: q.Labels, CreateDisposition: TableCreateDisposition(q.Copy.CreateDisposition), WriteDisposition: TableWriteDisposition(q.Copy.WriteDisposition), Dst: bqToTable(q.Copy.DestinationTable, c), DestinationEncryptionConfig: bqToEncryptionConfig(q.Copy.DestinationEncryptionConfiguration), } for _, t := range q.Copy.SourceTables { cc.Srcs = append(cc.Srcs, bqToTable(t, c)) } return cc } // A Copier copies data into a BigQuery table from one or more BigQuery tables. type Copier struct { JobIDConfig CopyConfig c *Client } // CopierFrom returns a Copier which can be used to copy data into a // BigQuery table from one or more BigQuery tables. // The returned Copier may optionally be further configured before its Run method is called. func (t *Table) CopierFrom(srcs ...*Table) *Copier { return &Copier{ c: t.c, CopyConfig: CopyConfig{ Srcs: srcs, Dst: t, }, } } // Run initiates a copy job. func (c *Copier) Run(ctx context.Context) (*Job, error) { return c.c.insertJob(ctx, c.newJob(), nil) } func (c *Copier) newJob() *bq.Job { return &bq.Job{ JobReference: c.JobIDConfig.createJobRef(c.c), Configuration: c.CopyConfig.toBQ(), } } google-cloud-go-0.49.0/bigquery/copy_test.go000066400000000000000000000077231356504100700207700ustar00rootroot00000000000000// Copyright 2015 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "testing" "cloud.google.com/go/internal/testutil" "github.com/google/go-cmp/cmp/cmpopts" bq "google.golang.org/api/bigquery/v2" ) func defaultCopyJob() *bq.Job { return &bq.Job{ JobReference: &bq.JobReference{JobId: "RANDOM", ProjectId: "client-project-id"}, Configuration: &bq.JobConfiguration{ Copy: &bq.JobConfigurationTableCopy{ DestinationTable: &bq.TableReference{ ProjectId: "d-project-id", DatasetId: "d-dataset-id", TableId: "d-table-id", }, SourceTables: []*bq.TableReference{ { ProjectId: "s-project-id", DatasetId: "s-dataset-id", TableId: "s-table-id", }, }, }, }, } } func TestCopy(t *testing.T) { defer fixRandomID("RANDOM")() testCases := []struct { dst *Table srcs []*Table jobID string location string config CopyConfig want *bq.Job }{ { dst: &Table{ ProjectID: "d-project-id", DatasetID: "d-dataset-id", TableID: "d-table-id", }, srcs: []*Table{ { ProjectID: "s-project-id", DatasetID: "s-dataset-id", TableID: "s-table-id", }, }, want: defaultCopyJob(), }, { dst: &Table{ ProjectID: "d-project-id", DatasetID: "d-dataset-id", TableID: "d-table-id", }, srcs: []*Table{ { ProjectID: "s-project-id", DatasetID: "s-dataset-id", TableID: "s-table-id", }, }, config: CopyConfig{ CreateDisposition: CreateNever, WriteDisposition: WriteTruncate, DestinationEncryptionConfig: &EncryptionConfig{KMSKeyName: "keyName"}, Labels: map[string]string{"a": "b"}, }, want: func() *bq.Job { j := defaultCopyJob() j.Configuration.Labels = map[string]string{"a": "b"} j.Configuration.Copy.CreateDisposition = "CREATE_NEVER" j.Configuration.Copy.WriteDisposition = "WRITE_TRUNCATE" j.Configuration.Copy.DestinationEncryptionConfiguration = &bq.EncryptionConfiguration{KmsKeyName: "keyName"} return j }(), }, { dst: &Table{ ProjectID: "d-project-id", DatasetID: "d-dataset-id", TableID: "d-table-id", }, srcs: []*Table{ { ProjectID: "s-project-id", DatasetID: "s-dataset-id", TableID: "s-table-id", }, }, jobID: "job-id", want: func() *bq.Job { j := defaultCopyJob() j.JobReference.JobId = "job-id" return j }(), }, { dst: &Table{ ProjectID: "d-project-id", DatasetID: "d-dataset-id", TableID: "d-table-id", }, srcs: []*Table{ { ProjectID: "s-project-id", DatasetID: "s-dataset-id", TableID: "s-table-id", }, }, location: "asia-northeast1", want: func() *bq.Job { j := defaultCopyJob() j.JobReference.Location = "asia-northeast1" return j }(), }, } c := &Client{projectID: "client-project-id"} for i, tc := range testCases { tc.dst.c = c copier := tc.dst.CopierFrom(tc.srcs...) copier.JobID = tc.jobID copier.Location = tc.location tc.config.Srcs = tc.srcs tc.config.Dst = tc.dst copier.CopyConfig = tc.config got := copier.newJob() checkJob(t, i, got, tc.want) jc, err := bqToJobConfig(got.Configuration, c) if err != nil { t.Fatalf("#%d: %v", i, err) } diff := testutil.Diff(jc.(*CopyConfig), &copier.CopyConfig, cmpopts.IgnoreUnexported(Table{})) if diff != "" { t.Errorf("#%d: (got=-, want=+:\n%s", i, diff) } } } google-cloud-go-0.49.0/bigquery/dataset.go000066400000000000000000000532511356504100700204010ustar00rootroot00000000000000// Copyright 2015 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "context" "errors" "fmt" "time" "cloud.google.com/go/internal/optional" "cloud.google.com/go/internal/trace" bq "google.golang.org/api/bigquery/v2" "google.golang.org/api/iterator" ) // Dataset is a reference to a BigQuery dataset. type Dataset struct { ProjectID string DatasetID string c *Client } // DatasetMetadata contains information about a BigQuery dataset. type DatasetMetadata struct { // These fields can be set when creating a dataset. Name string // The user-friendly name for this dataset. Description string // The user-friendly description of this dataset. Location string // The geo location of the dataset. DefaultTableExpiration time.Duration // The default expiration time for new tables. Labels map[string]string // User-provided labels. Access []*AccessEntry // Access permissions. DefaultEncryptionConfig *EncryptionConfig // These fields are read-only. CreationTime time.Time LastModifiedTime time.Time // When the dataset or any of its tables were modified. FullID string // The full dataset ID in the form projectID:datasetID. // ETag is the ETag obtained when reading metadata. Pass it to Dataset.Update to // ensure that the metadata hasn't changed since it was read. ETag string } // DatasetMetadataToUpdate is used when updating a dataset's metadata. // Only non-nil fields will be updated. type DatasetMetadataToUpdate struct { Description optional.String // The user-friendly description of this table. Name optional.String // The user-friendly name for this dataset. // DefaultTableExpiration is the default expiration time for new tables. // If set to time.Duration(0), new tables never expire. DefaultTableExpiration optional.Duration // DefaultEncryptionConfig defines CMEK settings for new resources created // in the dataset. DefaultEncryptionConfig *EncryptionConfig // The entire access list. It is not possible to replace individual entries. Access []*AccessEntry labelUpdater } // Dataset creates a handle to a BigQuery dataset in the client's project. func (c *Client) Dataset(id string) *Dataset { return c.DatasetInProject(c.projectID, id) } // DatasetInProject creates a handle to a BigQuery dataset in the specified project. func (c *Client) DatasetInProject(projectID, datasetID string) *Dataset { return &Dataset{ ProjectID: projectID, DatasetID: datasetID, c: c, } } // Create creates a dataset in the BigQuery service. An error will be returned if the // dataset already exists. Pass in a DatasetMetadata value to configure the dataset. func (d *Dataset) Create(ctx context.Context, md *DatasetMetadata) (err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Dataset.Create") defer func() { trace.EndSpan(ctx, err) }() ds, err := md.toBQ() if err != nil { return err } ds.DatasetReference = &bq.DatasetReference{DatasetId: d.DatasetID} // Use Client.Location as a default. if ds.Location == "" { ds.Location = d.c.Location } call := d.c.bqs.Datasets.Insert(d.ProjectID, ds).Context(ctx) setClientHeader(call.Header()) _, err = call.Do() return err } func (dm *DatasetMetadata) toBQ() (*bq.Dataset, error) { ds := &bq.Dataset{} if dm == nil { return ds, nil } ds.FriendlyName = dm.Name ds.Description = dm.Description ds.Location = dm.Location ds.DefaultTableExpirationMs = int64(dm.DefaultTableExpiration / time.Millisecond) ds.Labels = dm.Labels var err error ds.Access, err = accessListToBQ(dm.Access) if err != nil { return nil, err } if !dm.CreationTime.IsZero() { return nil, errors.New("bigquery: Dataset.CreationTime is not writable") } if !dm.LastModifiedTime.IsZero() { return nil, errors.New("bigquery: Dataset.LastModifiedTime is not writable") } if dm.FullID != "" { return nil, errors.New("bigquery: Dataset.FullID is not writable") } if dm.ETag != "" { return nil, errors.New("bigquery: Dataset.ETag is not writable") } if dm.DefaultEncryptionConfig != nil { ds.DefaultEncryptionConfiguration = dm.DefaultEncryptionConfig.toBQ() } return ds, nil } func accessListToBQ(a []*AccessEntry) ([]*bq.DatasetAccess, error) { var q []*bq.DatasetAccess for _, e := range a { a, err := e.toBQ() if err != nil { return nil, err } q = append(q, a) } return q, nil } // Delete deletes the dataset. Delete will fail if the dataset is not empty. func (d *Dataset) Delete(ctx context.Context) (err error) { return d.deleteInternal(ctx, false) } // DeleteWithContents deletes the dataset, as well as contained resources. func (d *Dataset) DeleteWithContents(ctx context.Context) (err error) { return d.deleteInternal(ctx, true) } func (d *Dataset) deleteInternal(ctx context.Context, deleteContents bool) (err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Dataset.Delete") defer func() { trace.EndSpan(ctx, err) }() call := d.c.bqs.Datasets.Delete(d.ProjectID, d.DatasetID).Context(ctx).DeleteContents(deleteContents) setClientHeader(call.Header()) return call.Do() } // Metadata fetches the metadata for the dataset. func (d *Dataset) Metadata(ctx context.Context) (md *DatasetMetadata, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Dataset.Metadata") defer func() { trace.EndSpan(ctx, err) }() call := d.c.bqs.Datasets.Get(d.ProjectID, d.DatasetID).Context(ctx) setClientHeader(call.Header()) var ds *bq.Dataset if err := runWithRetry(ctx, func() (err error) { ds, err = call.Do() return err }); err != nil { return nil, err } return bqToDatasetMetadata(ds) } func bqToDatasetMetadata(d *bq.Dataset) (*DatasetMetadata, error) { dm := &DatasetMetadata{ CreationTime: unixMillisToTime(d.CreationTime), LastModifiedTime: unixMillisToTime(d.LastModifiedTime), DefaultTableExpiration: time.Duration(d.DefaultTableExpirationMs) * time.Millisecond, DefaultEncryptionConfig: bqToEncryptionConfig(d.DefaultEncryptionConfiguration), Description: d.Description, Name: d.FriendlyName, FullID: d.Id, Location: d.Location, Labels: d.Labels, ETag: d.Etag, } for _, a := range d.Access { e, err := bqToAccessEntry(a, nil) if err != nil { return nil, err } dm.Access = append(dm.Access, e) } return dm, nil } // Update modifies specific Dataset metadata fields. // To perform a read-modify-write that protects against intervening reads, // set the etag argument to the DatasetMetadata.ETag field from the read. // Pass the empty string for etag for a "blind write" that will always succeed. func (d *Dataset) Update(ctx context.Context, dm DatasetMetadataToUpdate, etag string) (md *DatasetMetadata, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Dataset.Update") defer func() { trace.EndSpan(ctx, err) }() ds, err := dm.toBQ() if err != nil { return nil, err } call := d.c.bqs.Datasets.Patch(d.ProjectID, d.DatasetID, ds).Context(ctx) setClientHeader(call.Header()) if etag != "" { call.Header().Set("If-Match", etag) } var ds2 *bq.Dataset if err := runWithRetry(ctx, func() (err error) { ds2, err = call.Do() return err }); err != nil { return nil, err } return bqToDatasetMetadata(ds2) } func (dm *DatasetMetadataToUpdate) toBQ() (*bq.Dataset, error) { ds := &bq.Dataset{} forceSend := func(field string) { ds.ForceSendFields = append(ds.ForceSendFields, field) } if dm.Description != nil { ds.Description = optional.ToString(dm.Description) forceSend("Description") } if dm.Name != nil { ds.FriendlyName = optional.ToString(dm.Name) forceSend("FriendlyName") } if dm.DefaultTableExpiration != nil { dur := optional.ToDuration(dm.DefaultTableExpiration) if dur == 0 { // Send a null to delete the field. ds.NullFields = append(ds.NullFields, "DefaultTableExpirationMs") } else { ds.DefaultTableExpirationMs = int64(dur / time.Millisecond) } } if dm.DefaultEncryptionConfig != nil { ds.DefaultEncryptionConfiguration = dm.DefaultEncryptionConfig.toBQ() ds.DefaultEncryptionConfiguration.ForceSendFields = []string{"KmsKeyName"} } if dm.Access != nil { var err error ds.Access, err = accessListToBQ(dm.Access) if err != nil { return nil, err } if len(ds.Access) == 0 { ds.NullFields = append(ds.NullFields, "Access") } } labels, forces, nulls := dm.update() ds.Labels = labels ds.ForceSendFields = append(ds.ForceSendFields, forces...) ds.NullFields = append(ds.NullFields, nulls...) return ds, nil } // Table creates a handle to a BigQuery table in the dataset. // To determine if a table exists, call Table.Metadata. // If the table does not already exist, use Table.Create to create it. func (d *Dataset) Table(tableID string) *Table { return &Table{ProjectID: d.ProjectID, DatasetID: d.DatasetID, TableID: tableID, c: d.c} } // Tables returns an iterator over the tables in the Dataset. func (d *Dataset) Tables(ctx context.Context) *TableIterator { it := &TableIterator{ ctx: ctx, dataset: d, } it.pageInfo, it.nextFunc = iterator.NewPageInfo( it.fetch, func() int { return len(it.tables) }, func() interface{} { b := it.tables; it.tables = nil; return b }) return it } // A TableIterator is an iterator over Tables. type TableIterator struct { ctx context.Context dataset *Dataset tables []*Table pageInfo *iterator.PageInfo nextFunc func() error } // Next returns the next result. Its second return value is Done if there are // no more results. Once Next returns Done, all subsequent calls will return // Done. func (it *TableIterator) Next() (*Table, error) { if err := it.nextFunc(); err != nil { return nil, err } t := it.tables[0] it.tables = it.tables[1:] return t, nil } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *TableIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // listTables exists to aid testing. var listTables = func(it *TableIterator, pageSize int, pageToken string) (*bq.TableList, error) { call := it.dataset.c.bqs.Tables.List(it.dataset.ProjectID, it.dataset.DatasetID). PageToken(pageToken). Context(it.ctx) setClientHeader(call.Header()) if pageSize > 0 { call.MaxResults(int64(pageSize)) } var res *bq.TableList err := runWithRetry(it.ctx, func() (err error) { res, err = call.Do() return err }) return res, err } func (it *TableIterator) fetch(pageSize int, pageToken string) (string, error) { res, err := listTables(it, pageSize, pageToken) if err != nil { return "", err } for _, t := range res.Tables { it.tables = append(it.tables, bqToTable(t.TableReference, it.dataset.c)) } return res.NextPageToken, nil } func bqToTable(tr *bq.TableReference, c *Client) *Table { if tr == nil { return nil } return &Table{ ProjectID: tr.ProjectId, DatasetID: tr.DatasetId, TableID: tr.TableId, c: c, } } // Model creates a handle to a BigQuery model in the dataset. // To determine if a model exists, call Model.Metadata. // If the model does not already exist, you can create it via execution // of a CREATE MODEL query. func (d *Dataset) Model(modelID string) *Model { return &Model{ProjectID: d.ProjectID, DatasetID: d.DatasetID, ModelID: modelID, c: d.c} } // Models returns an iterator over the models in the Dataset. func (d *Dataset) Models(ctx context.Context) *ModelIterator { it := &ModelIterator{ ctx: ctx, dataset: d, } it.pageInfo, it.nextFunc = iterator.NewPageInfo( it.fetch, func() int { return len(it.models) }, func() interface{} { b := it.models; it.models = nil; return b }) return it } // A ModelIterator is an iterator over Models. type ModelIterator struct { ctx context.Context dataset *Dataset models []*Model pageInfo *iterator.PageInfo nextFunc func() error } // Next returns the next result. Its second return value is Done if there are // no more results. Once Next returns Done, all subsequent calls will return // Done. func (it *ModelIterator) Next() (*Model, error) { if err := it.nextFunc(); err != nil { return nil, err } t := it.models[0] it.models = it.models[1:] return t, nil } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *ModelIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // listTables exists to aid testing. var listModels = func(it *ModelIterator, pageSize int, pageToken string) (*bq.ListModelsResponse, error) { call := it.dataset.c.bqs.Models.List(it.dataset.ProjectID, it.dataset.DatasetID). PageToken(pageToken). Context(it.ctx) setClientHeader(call.Header()) if pageSize > 0 { call.MaxResults(int64(pageSize)) } var res *bq.ListModelsResponse err := runWithRetry(it.ctx, func() (err error) { res, err = call.Do() return err }) return res, err } func (it *ModelIterator) fetch(pageSize int, pageToken string) (string, error) { res, err := listModels(it, pageSize, pageToken) if err != nil { return "", err } for _, t := range res.Models { it.models = append(it.models, bqToModel(t.ModelReference, it.dataset.c)) } return res.NextPageToken, nil } func bqToModel(mr *bq.ModelReference, c *Client) *Model { if mr == nil { return nil } return &Model{ ProjectID: mr.ProjectId, DatasetID: mr.DatasetId, ModelID: mr.ModelId, c: c, } } // Routine creates a handle to a BigQuery routine in the dataset. // To determine if a routine exists, call Routine.Metadata. func (d *Dataset) Routine(routineID string) *Routine { return &Routine{ ProjectID: d.ProjectID, DatasetID: d.DatasetID, RoutineID: routineID, c: d.c} } // Routines returns an iterator over the routines in the Dataset. func (d *Dataset) Routines(ctx context.Context) *RoutineIterator { it := &RoutineIterator{ ctx: ctx, dataset: d, } it.pageInfo, it.nextFunc = iterator.NewPageInfo( it.fetch, func() int { return len(it.routines) }, func() interface{} { b := it.routines; it.routines = nil; return b }) return it } // A RoutineIterator is an iterator over Routines. type RoutineIterator struct { ctx context.Context dataset *Dataset routines []*Routine pageInfo *iterator.PageInfo nextFunc func() error } // Next returns the next result. Its second return value is Done if there are // no more results. Once Next returns Done, all subsequent calls will return // Done. func (it *RoutineIterator) Next() (*Routine, error) { if err := it.nextFunc(); err != nil { return nil, err } t := it.routines[0] it.routines = it.routines[1:] return t, nil } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *RoutineIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // listRoutines exists to aid testing. var listRoutines = func(it *RoutineIterator, pageSize int, pageToken string) (*bq.ListRoutinesResponse, error) { call := it.dataset.c.bqs.Routines.List(it.dataset.ProjectID, it.dataset.DatasetID). PageToken(pageToken). Context(it.ctx) setClientHeader(call.Header()) if pageSize > 0 { call.MaxResults(int64(pageSize)) } var res *bq.ListRoutinesResponse err := runWithRetry(it.ctx, func() (err error) { res, err = call.Do() return err }) return res, err } func (it *RoutineIterator) fetch(pageSize int, pageToken string) (string, error) { res, err := listRoutines(it, pageSize, pageToken) if err != nil { return "", err } for _, t := range res.Routines { it.routines = append(it.routines, bqToRoutine(t.RoutineReference, it.dataset.c)) } return res.NextPageToken, nil } func bqToRoutine(mr *bq.RoutineReference, c *Client) *Routine { if mr == nil { return nil } return &Routine{ ProjectID: mr.ProjectId, DatasetID: mr.DatasetId, RoutineID: mr.RoutineId, c: c, } } // Datasets returns an iterator over the datasets in a project. // The Client's project is used by default, but that can be // changed by setting ProjectID on the returned iterator before calling Next. func (c *Client) Datasets(ctx context.Context) *DatasetIterator { return c.DatasetsInProject(ctx, c.projectID) } // DatasetsInProject returns an iterator over the datasets in the provided project. // // Deprecated: call Client.Datasets, then set ProjectID on the returned iterator. func (c *Client) DatasetsInProject(ctx context.Context, projectID string) *DatasetIterator { it := &DatasetIterator{ ctx: ctx, c: c, ProjectID: projectID, } it.pageInfo, it.nextFunc = iterator.NewPageInfo( it.fetch, func() int { return len(it.items) }, func() interface{} { b := it.items; it.items = nil; return b }) return it } // DatasetIterator iterates over the datasets in a project. type DatasetIterator struct { // ListHidden causes hidden datasets to be listed when set to true. // Set before the first call to Next. ListHidden bool // Filter restricts the datasets returned by label. The filter syntax is described in // https://cloud.google.com/bigquery/docs/labeling-datasets#filtering_datasets_using_labels // Set before the first call to Next. Filter string // The project ID of the listed datasets. // Set before the first call to Next. ProjectID string ctx context.Context c *Client pageInfo *iterator.PageInfo nextFunc func() error items []*Dataset } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *DatasetIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next Dataset. Its second return value is iterator.Done if // there are no more results. Once Next returns Done, all subsequent calls will // return Done. func (it *DatasetIterator) Next() (*Dataset, error) { if err := it.nextFunc(); err != nil { return nil, err } item := it.items[0] it.items = it.items[1:] return item, nil } // for testing var listDatasets = func(it *DatasetIterator, pageSize int, pageToken string) (*bq.DatasetList, error) { call := it.c.bqs.Datasets.List(it.ProjectID). Context(it.ctx). PageToken(pageToken). All(it.ListHidden) setClientHeader(call.Header()) if pageSize > 0 { call.MaxResults(int64(pageSize)) } if it.Filter != "" { call.Filter(it.Filter) } var res *bq.DatasetList err := runWithRetry(it.ctx, func() (err error) { res, err = call.Do() return err }) return res, err } func (it *DatasetIterator) fetch(pageSize int, pageToken string) (string, error) { res, err := listDatasets(it, pageSize, pageToken) if err != nil { return "", err } for _, d := range res.Datasets { it.items = append(it.items, &Dataset{ ProjectID: d.DatasetReference.ProjectId, DatasetID: d.DatasetReference.DatasetId, c: it.c, }) } return res.NextPageToken, nil } // An AccessEntry describes the permissions that an entity has on a dataset. type AccessEntry struct { Role AccessRole // The role of the entity EntityType EntityType // The type of entity Entity string // The entity (individual or group) granted access View *Table // The view granted access (EntityType must be ViewEntity) } // AccessRole is the level of access to grant to a dataset. type AccessRole string const ( // OwnerRole is the OWNER AccessRole. OwnerRole AccessRole = "OWNER" // ReaderRole is the READER AccessRole. ReaderRole AccessRole = "READER" // WriterRole is the WRITER AccessRole. WriterRole AccessRole = "WRITER" ) // EntityType is the type of entity in an AccessEntry. type EntityType int const ( // DomainEntity is a domain (e.g. "example.com"). DomainEntity EntityType = iota + 1 // GroupEmailEntity is an email address of a Google Group. GroupEmailEntity // UserEmailEntity is an email address of an individual user. UserEmailEntity // SpecialGroupEntity is a special group: one of projectOwners, projectReaders, projectWriters or // allAuthenticatedUsers. SpecialGroupEntity // ViewEntity is a BigQuery view. ViewEntity // IAMMemberEntity represents entities present in IAM but not represented using // the other entity types. IAMMemberEntity ) func (e *AccessEntry) toBQ() (*bq.DatasetAccess, error) { q := &bq.DatasetAccess{Role: string(e.Role)} switch e.EntityType { case DomainEntity: q.Domain = e.Entity case GroupEmailEntity: q.GroupByEmail = e.Entity case UserEmailEntity: q.UserByEmail = e.Entity case SpecialGroupEntity: q.SpecialGroup = e.Entity case ViewEntity: q.View = e.View.toBQ() case IAMMemberEntity: q.IamMember = e.Entity default: return nil, fmt.Errorf("bigquery: unknown entity type %d", e.EntityType) } return q, nil } func bqToAccessEntry(q *bq.DatasetAccess, c *Client) (*AccessEntry, error) { e := &AccessEntry{Role: AccessRole(q.Role)} switch { case q.Domain != "": e.Entity = q.Domain e.EntityType = DomainEntity case q.GroupByEmail != "": e.Entity = q.GroupByEmail e.EntityType = GroupEmailEntity case q.UserByEmail != "": e.Entity = q.UserByEmail e.EntityType = UserEmailEntity case q.SpecialGroup != "": e.Entity = q.SpecialGroup e.EntityType = SpecialGroupEntity case q.View != nil: e.View = c.DatasetInProject(q.View.ProjectId, q.View.DatasetId).Table(q.View.TableId) e.EntityType = ViewEntity case q.IamMember != "": e.Entity = q.IamMember e.EntityType = IAMMemberEntity default: return nil, errors.New("bigquery: invalid access value") } return e, nil } google-cloud-go-0.49.0/bigquery/dataset_test.go000066400000000000000000000337501356504100700214420ustar00rootroot00000000000000// Copyright 2015 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "context" "errors" "fmt" "strconv" "testing" "time" "cloud.google.com/go/internal/testutil" "github.com/google/go-cmp/cmp" bq "google.golang.org/api/bigquery/v2" itest "google.golang.org/api/iterator/testing" ) // readServiceStub services read requests by returning data from an in-memory list of values. type listTablesStub struct { expectedProject, expectedDataset string tables []*bq.TableListTables } func (s *listTablesStub) listTables(it *TableIterator, pageSize int, pageToken string) (*bq.TableList, error) { if it.dataset.ProjectID != s.expectedProject { return nil, fmt.Errorf("wrong project id: %q", it.dataset.ProjectID) } if it.dataset.DatasetID != s.expectedDataset { return nil, fmt.Errorf("wrong dataset id: %q", it.dataset.DatasetID) } const maxPageSize = 2 if pageSize <= 0 || pageSize > maxPageSize { pageSize = maxPageSize } start := 0 if pageToken != "" { var err error start, err = strconv.Atoi(pageToken) if err != nil { return nil, err } } end := start + pageSize if end > len(s.tables) { end = len(s.tables) } nextPageToken := "" if end < len(s.tables) { nextPageToken = strconv.Itoa(end) } return &bq.TableList{ Tables: s.tables[start:end], NextPageToken: nextPageToken, }, nil } func TestTables(t *testing.T) { c := &Client{projectID: "p1"} inTables := []*bq.TableListTables{ {TableReference: &bq.TableReference{ProjectId: "p1", DatasetId: "d1", TableId: "t1"}}, {TableReference: &bq.TableReference{ProjectId: "p1", DatasetId: "d1", TableId: "t2"}}, {TableReference: &bq.TableReference{ProjectId: "p1", DatasetId: "d1", TableId: "t3"}}, } outTables := []*Table{ {ProjectID: "p1", DatasetID: "d1", TableID: "t1", c: c}, {ProjectID: "p1", DatasetID: "d1", TableID: "t2", c: c}, {ProjectID: "p1", DatasetID: "d1", TableID: "t3", c: c}, } lts := &listTablesStub{ expectedProject: "p1", expectedDataset: "d1", tables: inTables, } old := listTables listTables = lts.listTables // cannot use t.Parallel with this test defer func() { listTables = old }() msg, ok := itest.TestIterator(outTables, func() interface{} { return c.Dataset("d1").Tables(context.Background()) }, func(it interface{}) (interface{}, error) { return it.(*TableIterator).Next() }) if !ok { t.Error(msg) } } // listModelsStub services list requests by returning data from an in-memory list of values. type listModelsStub struct { expectedProject, expectedDataset string models []*bq.Model } func (s *listModelsStub) listModels(it *ModelIterator, pageSize int, pageToken string) (*bq.ListModelsResponse, error) { if it.dataset.ProjectID != s.expectedProject { return nil, errors.New("wrong project id") } if it.dataset.DatasetID != s.expectedDataset { return nil, errors.New("wrong dataset id") } const maxPageSize = 2 if pageSize <= 0 || pageSize > maxPageSize { pageSize = maxPageSize } start := 0 if pageToken != "" { var err error start, err = strconv.Atoi(pageToken) if err != nil { return nil, err } } end := start + pageSize if end > len(s.models) { end = len(s.models) } nextPageToken := "" if end < len(s.models) { nextPageToken = strconv.Itoa(end) } return &bq.ListModelsResponse{ Models: s.models[start:end], NextPageToken: nextPageToken, }, nil } func TestModels(t *testing.T) { c := &Client{projectID: "p1"} inModels := []*bq.Model{ {ModelReference: &bq.ModelReference{ProjectId: "p1", DatasetId: "d1", ModelId: "m1"}}, {ModelReference: &bq.ModelReference{ProjectId: "p1", DatasetId: "d1", ModelId: "m2"}}, {ModelReference: &bq.ModelReference{ProjectId: "p1", DatasetId: "d1", ModelId: "m3"}}, } outModels := []*Model{ {ProjectID: "p1", DatasetID: "d1", ModelID: "m1", c: c}, {ProjectID: "p1", DatasetID: "d1", ModelID: "m2", c: c}, {ProjectID: "p1", DatasetID: "d1", ModelID: "m3", c: c}, } lms := &listModelsStub{ expectedProject: "p1", expectedDataset: "d1", models: inModels, } old := listModels listModels = lms.listModels // cannot use t.Parallel with this test defer func() { listModels = old }() msg, ok := itest.TestIterator(outModels, func() interface{} { return c.Dataset("d1").Models(context.Background()) }, func(it interface{}) (interface{}, error) { return it.(*ModelIterator).Next() }) if !ok { t.Error(msg) } } // listRoutinesStub services list requests by returning data from an in-memory list of values. type listRoutinesStub struct { routines []*bq.Routine } func (s *listRoutinesStub) listRoutines(it *RoutineIterator, pageSize int, pageToken string) (*bq.ListRoutinesResponse, error) { const maxPageSize = 2 if pageSize <= 0 || pageSize > maxPageSize { pageSize = maxPageSize } start := 0 if pageToken != "" { var err error start, err = strconv.Atoi(pageToken) if err != nil { return nil, err } } end := start + pageSize if end > len(s.routines) { end = len(s.routines) } nextPageToken := "" if end < len(s.routines) { nextPageToken = strconv.Itoa(end) } return &bq.ListRoutinesResponse{ Routines: s.routines[start:end], NextPageToken: nextPageToken, }, nil } func TestRoutines(t *testing.T) { c := &Client{projectID: "p1"} inRoutines := []*bq.Routine{ {RoutineReference: &bq.RoutineReference{ProjectId: "p1", DatasetId: "d1", RoutineId: "r1"}}, {RoutineReference: &bq.RoutineReference{ProjectId: "p1", DatasetId: "d1", RoutineId: "r2"}}, {RoutineReference: &bq.RoutineReference{ProjectId: "p1", DatasetId: "d1", RoutineId: "r3"}}, } outRoutines := []*Routine{ {ProjectID: "p1", DatasetID: "d1", RoutineID: "r1", c: c}, {ProjectID: "p1", DatasetID: "d1", RoutineID: "r2", c: c}, {ProjectID: "p1", DatasetID: "d1", RoutineID: "r3", c: c}, } lms := &listRoutinesStub{ routines: inRoutines, } old := listRoutines listRoutines = lms.listRoutines // cannot use t.Parallel with this test defer func() { listRoutines = old }() msg, ok := itest.TestIterator(outRoutines, func() interface{} { return c.Dataset("d1").Routines(context.Background()) }, func(it interface{}) (interface{}, error) { return it.(*RoutineIterator).Next() }) if !ok { t.Error(msg) } } type listDatasetsStub struct { expectedProject string datasets []*bq.DatasetListDatasets hidden map[*bq.DatasetListDatasets]bool } func (s *listDatasetsStub) listDatasets(it *DatasetIterator, pageSize int, pageToken string) (*bq.DatasetList, error) { const maxPageSize = 2 if pageSize <= 0 || pageSize > maxPageSize { pageSize = maxPageSize } if it.Filter != "" { return nil, errors.New("filter not supported") } if it.ProjectID != s.expectedProject { return nil, errors.New("bad project ID") } start := 0 if pageToken != "" { var err error start, err = strconv.Atoi(pageToken) if err != nil { return nil, err } } var ( i int result []*bq.DatasetListDatasets nextPageToken string ) for i = start; len(result) < pageSize && i < len(s.datasets); i++ { if s.hidden[s.datasets[i]] && !it.ListHidden { continue } result = append(result, s.datasets[i]) } if i < len(s.datasets) { nextPageToken = strconv.Itoa(i) } return &bq.DatasetList{ Datasets: result, NextPageToken: nextPageToken, }, nil } func TestDatasets(t *testing.T) { client := &Client{projectID: "p"} inDatasets := []*bq.DatasetListDatasets{ {DatasetReference: &bq.DatasetReference{ProjectId: "p", DatasetId: "a"}}, {DatasetReference: &bq.DatasetReference{ProjectId: "p", DatasetId: "b"}}, {DatasetReference: &bq.DatasetReference{ProjectId: "p", DatasetId: "hidden"}}, {DatasetReference: &bq.DatasetReference{ProjectId: "p", DatasetId: "c"}}, } outDatasets := []*Dataset{ {"p", "a", client}, {"p", "b", client}, {"p", "hidden", client}, {"p", "c", client}, } lds := &listDatasetsStub{ expectedProject: "p", datasets: inDatasets, hidden: map[*bq.DatasetListDatasets]bool{inDatasets[2]: true}, } old := listDatasets listDatasets = lds.listDatasets // cannot use t.Parallel with this test defer func() { listDatasets = old }() msg, ok := itest.TestIterator(outDatasets, func() interface{} { it := client.Datasets(context.Background()); it.ListHidden = true; return it }, func(it interface{}) (interface{}, error) { return it.(*DatasetIterator).Next() }) if !ok { t.Fatalf("ListHidden=true: %s", msg) } msg, ok = itest.TestIterator([]*Dataset{outDatasets[0], outDatasets[1], outDatasets[3]}, func() interface{} { it := client.Datasets(context.Background()); it.ListHidden = false; return it }, func(it interface{}) (interface{}, error) { return it.(*DatasetIterator).Next() }) if !ok { t.Fatalf("ListHidden=false: %s", msg) } } func TestDatasetToBQ(t *testing.T) { for _, test := range []struct { in *DatasetMetadata want *bq.Dataset }{ {nil, &bq.Dataset{}}, {&DatasetMetadata{Name: "name"}, &bq.Dataset{FriendlyName: "name"}}, {&DatasetMetadata{ Name: "name", Description: "desc", DefaultTableExpiration: time.Hour, DefaultEncryptionConfig: &EncryptionConfig{ KMSKeyName: "some_key", }, Location: "EU", Labels: map[string]string{"x": "y"}, Access: []*AccessEntry{{Role: OwnerRole, Entity: "example.com", EntityType: DomainEntity}}, }, &bq.Dataset{ FriendlyName: "name", Description: "desc", DefaultTableExpirationMs: 60 * 60 * 1000, DefaultEncryptionConfiguration: &bq.EncryptionConfiguration{ KmsKeyName: "some_key", }, Location: "EU", Labels: map[string]string{"x": "y"}, Access: []*bq.DatasetAccess{{Role: "OWNER", Domain: "example.com"}}, }}, } { got, err := test.in.toBQ() if err != nil { t.Fatal(err) } if !testutil.Equal(got, test.want) { t.Errorf("%v:\ngot %+v\nwant %+v", test.in, got, test.want) } } // Check that non-writeable fields are unset. aTime := time.Date(2017, 1, 26, 0, 0, 0, 0, time.Local) for _, dm := range []*DatasetMetadata{ {CreationTime: aTime}, {LastModifiedTime: aTime}, {FullID: "x"}, {ETag: "e"}, } { if _, err := dm.toBQ(); err == nil { t.Errorf("%+v: got nil, want error", dm) } } } func TestBQToDatasetMetadata(t *testing.T) { cTime := time.Date(2017, 1, 26, 0, 0, 0, 0, time.Local) cMillis := cTime.UnixNano() / 1e6 mTime := time.Date(2017, 10, 31, 0, 0, 0, 0, time.Local) mMillis := mTime.UnixNano() / 1e6 q := &bq.Dataset{ CreationTime: cMillis, LastModifiedTime: mMillis, FriendlyName: "name", Description: "desc", DefaultTableExpirationMs: 60 * 60 * 1000, DefaultEncryptionConfiguration: &bq.EncryptionConfiguration{ KmsKeyName: "some_key", }, Location: "EU", Labels: map[string]string{"x": "y"}, Access: []*bq.DatasetAccess{ {Role: "READER", UserByEmail: "joe@example.com"}, {Role: "WRITER", GroupByEmail: "users@example.com"}, }, Etag: "etag", } want := &DatasetMetadata{ CreationTime: cTime, LastModifiedTime: mTime, Name: "name", Description: "desc", DefaultTableExpiration: time.Hour, DefaultEncryptionConfig: &EncryptionConfig{ KMSKeyName: "some_key", }, Location: "EU", Labels: map[string]string{"x": "y"}, Access: []*AccessEntry{ {Role: ReaderRole, Entity: "joe@example.com", EntityType: UserEmailEntity}, {Role: WriterRole, Entity: "users@example.com", EntityType: GroupEmailEntity}, }, ETag: "etag", } got, err := bqToDatasetMetadata(q) if err != nil { t.Fatal(err) } if diff := testutil.Diff(got, want); diff != "" { t.Errorf("-got, +want:\n%s", diff) } } func TestDatasetMetadataToUpdateToBQ(t *testing.T) { dm := DatasetMetadataToUpdate{ Description: "desc", Name: "name", DefaultTableExpiration: time.Hour, DefaultEncryptionConfig: &EncryptionConfig{ KMSKeyName: "some_key", }, } dm.SetLabel("label", "value") dm.DeleteLabel("del") got, err := dm.toBQ() if err != nil { t.Fatal(err) } want := &bq.Dataset{ Description: "desc", FriendlyName: "name", DefaultTableExpirationMs: 60 * 60 * 1000, DefaultEncryptionConfiguration: &bq.EncryptionConfiguration{ KmsKeyName: "some_key", ForceSendFields: []string{"KmsKeyName"}, }, Labels: map[string]string{"label": "value"}, ForceSendFields: []string{"Description", "FriendlyName"}, NullFields: []string{"Labels.del"}, } if diff := testutil.Diff(got, want); diff != "" { t.Errorf("-got, +want:\n%s", diff) } } func TestConvertAccessEntry(t *testing.T) { c := &Client{projectID: "pid"} for _, e := range []*AccessEntry{ {Role: ReaderRole, Entity: "e", EntityType: DomainEntity}, {Role: WriterRole, Entity: "e", EntityType: GroupEmailEntity}, {Role: OwnerRole, Entity: "e", EntityType: UserEmailEntity}, {Role: ReaderRole, Entity: "e", EntityType: SpecialGroupEntity}, {Role: ReaderRole, Entity: "e", EntityType: IAMMemberEntity}, {Role: ReaderRole, EntityType: ViewEntity, View: &Table{ProjectID: "p", DatasetID: "d", TableID: "t", c: c}}, } { q, err := e.toBQ() if err != nil { t.Fatal(err) } got, err := bqToAccessEntry(q, c) if err != nil { t.Fatal(err) } if diff := testutil.Diff(got, e, cmp.AllowUnexported(Table{}, Client{})); diff != "" { t.Errorf("got=-, want=+:\n%s", diff) } } e := &AccessEntry{Role: ReaderRole, Entity: "e"} if _, err := e.toBQ(); err == nil { t.Error("got nil, want error") } if _, err := bqToAccessEntry(&bq.DatasetAccess{Role: "WRITER"}, nil); err == nil { t.Error("got nil, want error") } } google-cloud-go-0.49.0/bigquery/datatransfer/000077500000000000000000000000001356504100700210755ustar00rootroot00000000000000google-cloud-go-0.49.0/bigquery/datatransfer/apiv1/000077500000000000000000000000001356504100700221155ustar00rootroot00000000000000google-cloud-go-0.49.0/bigquery/datatransfer/apiv1/.repo-metadata.json000066400000000000000000000007251356504100700256150ustar00rootroot00000000000000{ "name": "datatransfer", "name_pretty": "Google Bigquery Data Transfer Service", "product_documentation": "https://cloud.google.com/bigquery/transfer/", "client_documentation": "https://godoc.org/cloud.google.com/go/bigquery/datatransfer/apiv1", "release_level": "alpha", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "bigquerydatatransfer.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/bigquery/datatransfer/apiv1/ListDataSources_smoke_test.go000066400000000000000000000033241356504100700277540ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package datatransfer import ( "context" "fmt" "strconv" "testing" "time" "cloud.google.com/go/internal/testutil" "google.golang.org/api/iterator" "google.golang.org/api/option" datatransferpb "google.golang.org/genproto/googleapis/cloud/bigquery/datatransfer/v1" ) var _ = fmt.Sprintf var _ = iterator.Done var _ = strconv.FormatUint var _ = time.Now func TestDataTransferServiceSmoke(t *testing.T) { if testing.Short() { t.Skip("skipping smoke test in short mode") } ctx := context.Background() ts := testutil.TokenSource(ctx, DefaultAuthScopes()...) if ts == nil { t.Skip("Integration tests skipped. See CONTRIBUTING.md for details") } projectId := testutil.ProjID() _ = projectId c, err := NewClient(ctx, option.WithTokenSource(ts)) if err != nil { t.Fatal(err) } var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", projectId, "us-central1") var request = &datatransferpb.ListDataSourcesRequest{ Parent: formattedParent, } iter := c.ListDataSources(ctx, request) if _, err := iter.Next(); err != nil && err != iterator.Done { t.Error(err) } } google-cloud-go-0.49.0/bigquery/datatransfer/apiv1/data_transfer_client.go000066400000000000000000000643231356504100700266270ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package datatransfer import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" datatransferpb "google.golang.org/genproto/googleapis/cloud/bigquery/datatransfer/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // CallOptions contains the retry settings for each method of Client. type CallOptions struct { GetDataSource []gax.CallOption ListDataSources []gax.CallOption CreateTransferConfig []gax.CallOption UpdateTransferConfig []gax.CallOption DeleteTransferConfig []gax.CallOption GetTransferConfig []gax.CallOption ListTransferConfigs []gax.CallOption ScheduleTransferRuns []gax.CallOption GetTransferRun []gax.CallOption DeleteTransferRun []gax.CallOption ListTransferRuns []gax.CallOption ListTransferLogs []gax.CallOption CheckValidCreds []gax.CallOption StartManualTransferRuns []gax.CallOption } func defaultClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("bigquerydatatransfer.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultCallOptions() *CallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &CallOptions{ GetDataSource: retry[[2]string{"default", "idempotent"}], ListDataSources: retry[[2]string{"default", "idempotent"}], CreateTransferConfig: retry[[2]string{"default", "non_idempotent"}], UpdateTransferConfig: retry[[2]string{"default", "non_idempotent"}], DeleteTransferConfig: retry[[2]string{"default", "idempotent"}], GetTransferConfig: retry[[2]string{"default", "idempotent"}], ListTransferConfigs: retry[[2]string{"default", "idempotent"}], ScheduleTransferRuns: retry[[2]string{"default", "non_idempotent"}], GetTransferRun: retry[[2]string{"default", "idempotent"}], DeleteTransferRun: retry[[2]string{"default", "idempotent"}], ListTransferRuns: retry[[2]string{"default", "idempotent"}], ListTransferLogs: retry[[2]string{"default", "idempotent"}], CheckValidCreds: retry[[2]string{"default", "idempotent"}], StartManualTransferRuns: retry[[2]string{"default", "non_idempotent"}], } } // Client is a client for interacting with BigQuery Data Transfer API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. client datatransferpb.DataTransferServiceClient // The call options for this service. CallOptions *CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewClient creates a new data transfer service client. // // The Google BigQuery Data Transfer Service API enables BigQuery users to // configure the transfer of their data from other Google Products into // BigQuery. This service contains methods that are end user exposed. It backs // up the frontend. func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultClientOptions(), opts...)...) if err != nil { return nil, err } c := &Client{ conn: conn, CallOptions: defaultCallOptions(), client: datatransferpb.NewDataTransferServiceClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *Client) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *Client) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // GetDataSource retrieves a supported data source and returns its settings, // which can be used for UI rendering. func (c *Client) GetDataSource(ctx context.Context, req *datatransferpb.GetDataSourceRequest, opts ...gax.CallOption) (*datatransferpb.DataSource, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetDataSource[0:len(c.CallOptions.GetDataSource):len(c.CallOptions.GetDataSource)], opts...) var resp *datatransferpb.DataSource err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetDataSource(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListDataSources lists supported data sources and returns their settings, // which can be used for UI rendering. func (c *Client) ListDataSources(ctx context.Context, req *datatransferpb.ListDataSourcesRequest, opts ...gax.CallOption) *DataSourceIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListDataSources[0:len(c.CallOptions.ListDataSources):len(c.CallOptions.ListDataSources)], opts...) it := &DataSourceIterator{} req = proto.Clone(req).(*datatransferpb.ListDataSourcesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*datatransferpb.DataSource, string, error) { var resp *datatransferpb.ListDataSourcesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListDataSources(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.DataSources, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // CreateTransferConfig creates a new data transfer configuration. func (c *Client) CreateTransferConfig(ctx context.Context, req *datatransferpb.CreateTransferConfigRequest, opts ...gax.CallOption) (*datatransferpb.TransferConfig, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateTransferConfig[0:len(c.CallOptions.CreateTransferConfig):len(c.CallOptions.CreateTransferConfig)], opts...) var resp *datatransferpb.TransferConfig err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CreateTransferConfig(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateTransferConfig updates a data transfer configuration. // All fields must be set, even if they are not updated. func (c *Client) UpdateTransferConfig(ctx context.Context, req *datatransferpb.UpdateTransferConfigRequest, opts ...gax.CallOption) (*datatransferpb.TransferConfig, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "transfer_config.name", url.QueryEscape(req.GetTransferConfig().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateTransferConfig[0:len(c.CallOptions.UpdateTransferConfig):len(c.CallOptions.UpdateTransferConfig)], opts...) var resp *datatransferpb.TransferConfig err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.UpdateTransferConfig(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteTransferConfig deletes a data transfer configuration, // including any associated transfer runs and logs. func (c *Client) DeleteTransferConfig(ctx context.Context, req *datatransferpb.DeleteTransferConfigRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteTransferConfig[0:len(c.CallOptions.DeleteTransferConfig):len(c.CallOptions.DeleteTransferConfig)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.client.DeleteTransferConfig(ctx, req, settings.GRPC...) return err }, opts...) return err } // GetTransferConfig returns information about a data transfer config. func (c *Client) GetTransferConfig(ctx context.Context, req *datatransferpb.GetTransferConfigRequest, opts ...gax.CallOption) (*datatransferpb.TransferConfig, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetTransferConfig[0:len(c.CallOptions.GetTransferConfig):len(c.CallOptions.GetTransferConfig)], opts...) var resp *datatransferpb.TransferConfig err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetTransferConfig(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListTransferConfigs returns information about all data transfers in the project. func (c *Client) ListTransferConfigs(ctx context.Context, req *datatransferpb.ListTransferConfigsRequest, opts ...gax.CallOption) *TransferConfigIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListTransferConfigs[0:len(c.CallOptions.ListTransferConfigs):len(c.CallOptions.ListTransferConfigs)], opts...) it := &TransferConfigIterator{} req = proto.Clone(req).(*datatransferpb.ListTransferConfigsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*datatransferpb.TransferConfig, string, error) { var resp *datatransferpb.ListTransferConfigsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListTransferConfigs(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.TransferConfigs, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // ScheduleTransferRuns creates transfer runs for a time range [start_time, end_time]. // For each date - or whatever granularity the data source supports - in the // range, one transfer run is created. // Note that runs are created per UTC time in the time range. // DEPRECATED: use StartManualTransferRuns instead. func (c *Client) ScheduleTransferRuns(ctx context.Context, req *datatransferpb.ScheduleTransferRunsRequest, opts ...gax.CallOption) (*datatransferpb.ScheduleTransferRunsResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ScheduleTransferRuns[0:len(c.CallOptions.ScheduleTransferRuns):len(c.CallOptions.ScheduleTransferRuns)], opts...) var resp *datatransferpb.ScheduleTransferRunsResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ScheduleTransferRuns(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetTransferRun returns information about the particular transfer run. func (c *Client) GetTransferRun(ctx context.Context, req *datatransferpb.GetTransferRunRequest, opts ...gax.CallOption) (*datatransferpb.TransferRun, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetTransferRun[0:len(c.CallOptions.GetTransferRun):len(c.CallOptions.GetTransferRun)], opts...) var resp *datatransferpb.TransferRun err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetTransferRun(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteTransferRun deletes the specified transfer run. func (c *Client) DeleteTransferRun(ctx context.Context, req *datatransferpb.DeleteTransferRunRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteTransferRun[0:len(c.CallOptions.DeleteTransferRun):len(c.CallOptions.DeleteTransferRun)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.client.DeleteTransferRun(ctx, req, settings.GRPC...) return err }, opts...) return err } // ListTransferRuns returns information about running and completed jobs. func (c *Client) ListTransferRuns(ctx context.Context, req *datatransferpb.ListTransferRunsRequest, opts ...gax.CallOption) *TransferRunIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListTransferRuns[0:len(c.CallOptions.ListTransferRuns):len(c.CallOptions.ListTransferRuns)], opts...) it := &TransferRunIterator{} req = proto.Clone(req).(*datatransferpb.ListTransferRunsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*datatransferpb.TransferRun, string, error) { var resp *datatransferpb.ListTransferRunsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListTransferRuns(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.TransferRuns, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // ListTransferLogs returns user facing log messages for the data transfer run. func (c *Client) ListTransferLogs(ctx context.Context, req *datatransferpb.ListTransferLogsRequest, opts ...gax.CallOption) *TransferMessageIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListTransferLogs[0:len(c.CallOptions.ListTransferLogs):len(c.CallOptions.ListTransferLogs)], opts...) it := &TransferMessageIterator{} req = proto.Clone(req).(*datatransferpb.ListTransferLogsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*datatransferpb.TransferMessage, string, error) { var resp *datatransferpb.ListTransferLogsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListTransferLogs(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.TransferMessages, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // CheckValidCreds returns true if valid credentials exist for the given data source and // requesting user. // Some data sources doesn't support service account, so we need to talk to // them on behalf of the end user. This API just checks whether we have OAuth // token for the particular user, which is a pre-requisite before user can // create a transfer config. func (c *Client) CheckValidCreds(ctx context.Context, req *datatransferpb.CheckValidCredsRequest, opts ...gax.CallOption) (*datatransferpb.CheckValidCredsResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CheckValidCreds[0:len(c.CallOptions.CheckValidCreds):len(c.CallOptions.CheckValidCreds)], opts...) var resp *datatransferpb.CheckValidCredsResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CheckValidCreds(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // StartManualTransferRuns start manual transfer runs to be executed now with schedule_time equal to // current time. The transfer runs can be created for a time range where the // run_time is between start_time (inclusive) and end_time (exclusive), or for // a specific run_time. func (c *Client) StartManualTransferRuns(ctx context.Context, req *datatransferpb.StartManualTransferRunsRequest, opts ...gax.CallOption) (*datatransferpb.StartManualTransferRunsResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.StartManualTransferRuns[0:len(c.CallOptions.StartManualTransferRuns):len(c.CallOptions.StartManualTransferRuns)], opts...) var resp *datatransferpb.StartManualTransferRunsResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.StartManualTransferRuns(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DataSourceIterator manages a stream of *datatransferpb.DataSource. type DataSourceIterator struct { items []*datatransferpb.DataSource pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*datatransferpb.DataSource, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *DataSourceIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *DataSourceIterator) Next() (*datatransferpb.DataSource, error) { var item *datatransferpb.DataSource if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *DataSourceIterator) bufLen() int { return len(it.items) } func (it *DataSourceIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // TransferConfigIterator manages a stream of *datatransferpb.TransferConfig. type TransferConfigIterator struct { items []*datatransferpb.TransferConfig pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*datatransferpb.TransferConfig, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *TransferConfigIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *TransferConfigIterator) Next() (*datatransferpb.TransferConfig, error) { var item *datatransferpb.TransferConfig if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *TransferConfigIterator) bufLen() int { return len(it.items) } func (it *TransferConfigIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // TransferMessageIterator manages a stream of *datatransferpb.TransferMessage. type TransferMessageIterator struct { items []*datatransferpb.TransferMessage pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*datatransferpb.TransferMessage, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *TransferMessageIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *TransferMessageIterator) Next() (*datatransferpb.TransferMessage, error) { var item *datatransferpb.TransferMessage if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *TransferMessageIterator) bufLen() int { return len(it.items) } func (it *TransferMessageIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // TransferRunIterator manages a stream of *datatransferpb.TransferRun. type TransferRunIterator struct { items []*datatransferpb.TransferRun pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*datatransferpb.TransferRun, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *TransferRunIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *TransferRunIterator) Next() (*datatransferpb.TransferRun, error) { var item *datatransferpb.TransferRun if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *TransferRunIterator) bufLen() int { return len(it.items) } func (it *TransferRunIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/bigquery/datatransfer/apiv1/data_transfer_client_example_test.go000066400000000000000000000144701356504100700313770ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package datatransfer_test import ( "context" datatransfer "cloud.google.com/go/bigquery/datatransfer/apiv1" "google.golang.org/api/iterator" datatransferpb "google.golang.org/genproto/googleapis/cloud/bigquery/datatransfer/v1" ) func ExampleNewClient() { ctx := context.Background() c, err := datatransfer.NewClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleClient_GetDataSource() { ctx := context.Background() c, err := datatransfer.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &datatransferpb.GetDataSourceRequest{ // TODO: Fill request struct fields. } resp, err := c.GetDataSource(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ListDataSources() { ctx := context.Background() c, err := datatransfer.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &datatransferpb.ListDataSourcesRequest{ // TODO: Fill request struct fields. } it := c.ListDataSources(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_CreateTransferConfig() { ctx := context.Background() c, err := datatransfer.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &datatransferpb.CreateTransferConfigRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateTransferConfig(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_UpdateTransferConfig() { ctx := context.Background() c, err := datatransfer.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &datatransferpb.UpdateTransferConfigRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateTransferConfig(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_DeleteTransferConfig() { ctx := context.Background() c, err := datatransfer.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &datatransferpb.DeleteTransferConfigRequest{ // TODO: Fill request struct fields. } err = c.DeleteTransferConfig(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleClient_GetTransferConfig() { ctx := context.Background() c, err := datatransfer.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &datatransferpb.GetTransferConfigRequest{ // TODO: Fill request struct fields. } resp, err := c.GetTransferConfig(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ListTransferConfigs() { ctx := context.Background() c, err := datatransfer.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &datatransferpb.ListTransferConfigsRequest{ // TODO: Fill request struct fields. } it := c.ListTransferConfigs(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_ScheduleTransferRuns() { ctx := context.Background() c, err := datatransfer.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &datatransferpb.ScheduleTransferRunsRequest{ // TODO: Fill request struct fields. } resp, err := c.ScheduleTransferRuns(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_GetTransferRun() { ctx := context.Background() c, err := datatransfer.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &datatransferpb.GetTransferRunRequest{ // TODO: Fill request struct fields. } resp, err := c.GetTransferRun(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_DeleteTransferRun() { ctx := context.Background() c, err := datatransfer.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &datatransferpb.DeleteTransferRunRequest{ // TODO: Fill request struct fields. } err = c.DeleteTransferRun(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleClient_ListTransferRuns() { ctx := context.Background() c, err := datatransfer.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &datatransferpb.ListTransferRunsRequest{ // TODO: Fill request struct fields. } it := c.ListTransferRuns(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_ListTransferLogs() { ctx := context.Background() c, err := datatransfer.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &datatransferpb.ListTransferLogsRequest{ // TODO: Fill request struct fields. } it := c.ListTransferLogs(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_CheckValidCreds() { ctx := context.Background() c, err := datatransfer.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &datatransferpb.CheckValidCredsRequest{ // TODO: Fill request struct fields. } resp, err := c.CheckValidCreds(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_StartManualTransferRuns() { ctx := context.Background() c, err := datatransfer.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &datatransferpb.StartManualTransferRunsRequest{ // TODO: Fill request struct fields. } resp, err := c.StartManualTransferRuns(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/bigquery/datatransfer/apiv1/doc.go000066400000000000000000000054451356504100700232210ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package datatransfer is an auto-generated package for the // BigQuery Data Transfer API. // // NOTE: This package is in alpha. It is not stable, and is likely to change. // // Schedule queries or transfer external data from SaaS applications to // Google // BigQuery on a regular basis. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package datatransfer // import "cloud.google.com/go/bigquery/datatransfer/apiv1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191115" google-cloud-go-0.49.0/bigquery/datatransfer/apiv1/mock_test.go000066400000000000000000001130601356504100700244350ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package datatransfer import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" timestamppb "github.com/golang/protobuf/ptypes/timestamp" "google.golang.org/api/option" datatransferpb "google.golang.org/genproto/googleapis/cloud/bigquery/datatransfer/v1" field_maskpb "google.golang.org/genproto/protobuf/field_mask" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockDataTransferServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. datatransferpb.DataTransferServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockDataTransferServer) GetDataSource(ctx context.Context, req *datatransferpb.GetDataSourceRequest) (*datatransferpb.DataSource, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*datatransferpb.DataSource), nil } func (s *mockDataTransferServer) ListDataSources(ctx context.Context, req *datatransferpb.ListDataSourcesRequest) (*datatransferpb.ListDataSourcesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*datatransferpb.ListDataSourcesResponse), nil } func (s *mockDataTransferServer) CreateTransferConfig(ctx context.Context, req *datatransferpb.CreateTransferConfigRequest) (*datatransferpb.TransferConfig, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*datatransferpb.TransferConfig), nil } func (s *mockDataTransferServer) UpdateTransferConfig(ctx context.Context, req *datatransferpb.UpdateTransferConfigRequest) (*datatransferpb.TransferConfig, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*datatransferpb.TransferConfig), nil } func (s *mockDataTransferServer) DeleteTransferConfig(ctx context.Context, req *datatransferpb.DeleteTransferConfigRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockDataTransferServer) GetTransferConfig(ctx context.Context, req *datatransferpb.GetTransferConfigRequest) (*datatransferpb.TransferConfig, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*datatransferpb.TransferConfig), nil } func (s *mockDataTransferServer) ListTransferConfigs(ctx context.Context, req *datatransferpb.ListTransferConfigsRequest) (*datatransferpb.ListTransferConfigsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*datatransferpb.ListTransferConfigsResponse), nil } func (s *mockDataTransferServer) ScheduleTransferRuns(ctx context.Context, req *datatransferpb.ScheduleTransferRunsRequest) (*datatransferpb.ScheduleTransferRunsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*datatransferpb.ScheduleTransferRunsResponse), nil } func (s *mockDataTransferServer) StartManualTransferRuns(ctx context.Context, req *datatransferpb.StartManualTransferRunsRequest) (*datatransferpb.StartManualTransferRunsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*datatransferpb.StartManualTransferRunsResponse), nil } func (s *mockDataTransferServer) GetTransferRun(ctx context.Context, req *datatransferpb.GetTransferRunRequest) (*datatransferpb.TransferRun, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*datatransferpb.TransferRun), nil } func (s *mockDataTransferServer) DeleteTransferRun(ctx context.Context, req *datatransferpb.DeleteTransferRunRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockDataTransferServer) ListTransferRuns(ctx context.Context, req *datatransferpb.ListTransferRunsRequest) (*datatransferpb.ListTransferRunsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*datatransferpb.ListTransferRunsResponse), nil } func (s *mockDataTransferServer) ListTransferLogs(ctx context.Context, req *datatransferpb.ListTransferLogsRequest) (*datatransferpb.ListTransferLogsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*datatransferpb.ListTransferLogsResponse), nil } func (s *mockDataTransferServer) CheckValidCreds(ctx context.Context, req *datatransferpb.CheckValidCredsRequest) (*datatransferpb.CheckValidCredsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*datatransferpb.CheckValidCredsResponse), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockDataTransfer mockDataTransferServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() datatransferpb.RegisterDataTransferServiceServer(serv, &mockDataTransfer) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestDataTransferServiceGetDataSource(t *testing.T) { var name2 string = "name2-1052831874" var dataSourceId string = "dataSourceId-1015796374" var displayName string = "displayName1615086568" var description string = "description-1724546052" var clientId string = "clientId-1904089585" var supportsMultipleTransfers bool = true var updateDeadlineSeconds int32 = 991471694 var defaultSchedule string = "defaultSchedule-800168235" var supportsCustomSchedule bool = true var helpUrl string = "helpUrl-789431439" var defaultDataRefreshWindowDays int32 = 1804935157 var manualRunsDisabled bool = true var expectedResponse = &datatransferpb.DataSource{ Name: name2, DataSourceId: dataSourceId, DisplayName: displayName, Description: description, ClientId: clientId, SupportsMultipleTransfers: supportsMultipleTransfers, UpdateDeadlineSeconds: updateDeadlineSeconds, DefaultSchedule: defaultSchedule, SupportsCustomSchedule: supportsCustomSchedule, HelpUrl: helpUrl, DefaultDataRefreshWindowDays: defaultDataRefreshWindowDays, ManualRunsDisabled: manualRunsDisabled, } mockDataTransfer.err = nil mockDataTransfer.reqs = nil mockDataTransfer.resps = append(mockDataTransfer.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/dataSources/%s", "[PROJECT]", "[DATA_SOURCE]") var request = &datatransferpb.GetDataSourceRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetDataSource(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDataTransfer.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDataTransferServiceGetDataSourceError(t *testing.T) { errCode := codes.PermissionDenied mockDataTransfer.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/dataSources/%s", "[PROJECT]", "[DATA_SOURCE]") var request = &datatransferpb.GetDataSourceRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetDataSource(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDataTransferServiceListDataSources(t *testing.T) { var nextPageToken string = "" var dataSourcesElement *datatransferpb.DataSource = &datatransferpb.DataSource{} var dataSources = []*datatransferpb.DataSource{dataSourcesElement} var expectedResponse = &datatransferpb.ListDataSourcesResponse{ NextPageToken: nextPageToken, DataSources: dataSources, } mockDataTransfer.err = nil mockDataTransfer.reqs = nil mockDataTransfer.resps = append(mockDataTransfer.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &datatransferpb.ListDataSourcesRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListDataSources(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockDataTransfer.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.DataSources[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDataTransferServiceListDataSourcesError(t *testing.T) { errCode := codes.PermissionDenied mockDataTransfer.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &datatransferpb.ListDataSourcesRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListDataSources(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDataTransferServiceCreateTransferConfig(t *testing.T) { var name string = "name3373707" var destinationDatasetId string = "destinationDatasetId1541564179" var displayName string = "displayName1615086568" var dataSourceId string = "dataSourceId-1015796374" var schedule string = "schedule-697920873" var dataRefreshWindowDays int32 = 327632845 var disabled bool = true var userId int64 = 147132913 var datasetRegion string = "datasetRegion959248539" var expectedResponse = &datatransferpb.TransferConfig{ Name: name, Destination: &datatransferpb.TransferConfig_DestinationDatasetId{ DestinationDatasetId: destinationDatasetId, }, DisplayName: displayName, DataSourceId: dataSourceId, Schedule: schedule, DataRefreshWindowDays: dataRefreshWindowDays, Disabled: disabled, UserId: userId, DatasetRegion: datasetRegion, } mockDataTransfer.err = nil mockDataTransfer.reqs = nil mockDataTransfer.resps = append(mockDataTransfer.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var transferConfig *datatransferpb.TransferConfig = &datatransferpb.TransferConfig{} var request = &datatransferpb.CreateTransferConfigRequest{ Parent: formattedParent, TransferConfig: transferConfig, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateTransferConfig(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDataTransfer.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDataTransferServiceCreateTransferConfigError(t *testing.T) { errCode := codes.PermissionDenied mockDataTransfer.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var transferConfig *datatransferpb.TransferConfig = &datatransferpb.TransferConfig{} var request = &datatransferpb.CreateTransferConfigRequest{ Parent: formattedParent, TransferConfig: transferConfig, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateTransferConfig(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDataTransferServiceUpdateTransferConfig(t *testing.T) { var name string = "name3373707" var destinationDatasetId string = "destinationDatasetId1541564179" var displayName string = "displayName1615086568" var dataSourceId string = "dataSourceId-1015796374" var schedule string = "schedule-697920873" var dataRefreshWindowDays int32 = 327632845 var disabled bool = true var userId int64 = 147132913 var datasetRegion string = "datasetRegion959248539" var expectedResponse = &datatransferpb.TransferConfig{ Name: name, Destination: &datatransferpb.TransferConfig_DestinationDatasetId{ DestinationDatasetId: destinationDatasetId, }, DisplayName: displayName, DataSourceId: dataSourceId, Schedule: schedule, DataRefreshWindowDays: dataRefreshWindowDays, Disabled: disabled, UserId: userId, DatasetRegion: datasetRegion, } mockDataTransfer.err = nil mockDataTransfer.reqs = nil mockDataTransfer.resps = append(mockDataTransfer.resps[:0], expectedResponse) var transferConfig *datatransferpb.TransferConfig = &datatransferpb.TransferConfig{} var updateMask *field_maskpb.FieldMask = &field_maskpb.FieldMask{} var request = &datatransferpb.UpdateTransferConfigRequest{ TransferConfig: transferConfig, UpdateMask: updateMask, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateTransferConfig(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDataTransfer.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDataTransferServiceUpdateTransferConfigError(t *testing.T) { errCode := codes.PermissionDenied mockDataTransfer.err = gstatus.Error(errCode, "test error") var transferConfig *datatransferpb.TransferConfig = &datatransferpb.TransferConfig{} var updateMask *field_maskpb.FieldMask = &field_maskpb.FieldMask{} var request = &datatransferpb.UpdateTransferConfigRequest{ TransferConfig: transferConfig, UpdateMask: updateMask, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateTransferConfig(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDataTransferServiceDeleteTransferConfig(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockDataTransfer.err = nil mockDataTransfer.reqs = nil mockDataTransfer.resps = append(mockDataTransfer.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/transferConfigs/%s", "[PROJECT]", "[TRANSFER_CONFIG]") var request = &datatransferpb.DeleteTransferConfigRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteTransferConfig(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDataTransfer.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestDataTransferServiceDeleteTransferConfigError(t *testing.T) { errCode := codes.PermissionDenied mockDataTransfer.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/transferConfigs/%s", "[PROJECT]", "[TRANSFER_CONFIG]") var request = &datatransferpb.DeleteTransferConfigRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteTransferConfig(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestDataTransferServiceGetTransferConfig(t *testing.T) { var name2 string = "name2-1052831874" var destinationDatasetId string = "destinationDatasetId1541564179" var displayName string = "displayName1615086568" var dataSourceId string = "dataSourceId-1015796374" var schedule string = "schedule-697920873" var dataRefreshWindowDays int32 = 327632845 var disabled bool = true var userId int64 = 147132913 var datasetRegion string = "datasetRegion959248539" var expectedResponse = &datatransferpb.TransferConfig{ Name: name2, Destination: &datatransferpb.TransferConfig_DestinationDatasetId{ DestinationDatasetId: destinationDatasetId, }, DisplayName: displayName, DataSourceId: dataSourceId, Schedule: schedule, DataRefreshWindowDays: dataRefreshWindowDays, Disabled: disabled, UserId: userId, DatasetRegion: datasetRegion, } mockDataTransfer.err = nil mockDataTransfer.reqs = nil mockDataTransfer.resps = append(mockDataTransfer.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/transferConfigs/%s", "[PROJECT]", "[TRANSFER_CONFIG]") var request = &datatransferpb.GetTransferConfigRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetTransferConfig(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDataTransfer.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDataTransferServiceGetTransferConfigError(t *testing.T) { errCode := codes.PermissionDenied mockDataTransfer.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/transferConfigs/%s", "[PROJECT]", "[TRANSFER_CONFIG]") var request = &datatransferpb.GetTransferConfigRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetTransferConfig(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDataTransferServiceListTransferConfigs(t *testing.T) { var nextPageToken string = "" var transferConfigsElement *datatransferpb.TransferConfig = &datatransferpb.TransferConfig{} var transferConfigs = []*datatransferpb.TransferConfig{transferConfigsElement} var expectedResponse = &datatransferpb.ListTransferConfigsResponse{ NextPageToken: nextPageToken, TransferConfigs: transferConfigs, } mockDataTransfer.err = nil mockDataTransfer.reqs = nil mockDataTransfer.resps = append(mockDataTransfer.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &datatransferpb.ListTransferConfigsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListTransferConfigs(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockDataTransfer.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.TransferConfigs[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDataTransferServiceListTransferConfigsError(t *testing.T) { errCode := codes.PermissionDenied mockDataTransfer.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &datatransferpb.ListTransferConfigsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListTransferConfigs(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDataTransferServiceScheduleTransferRuns(t *testing.T) { var expectedResponse *datatransferpb.ScheduleTransferRunsResponse = &datatransferpb.ScheduleTransferRunsResponse{} mockDataTransfer.err = nil mockDataTransfer.reqs = nil mockDataTransfer.resps = append(mockDataTransfer.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/transferConfigs/%s", "[PROJECT]", "[TRANSFER_CONFIG]") var startTime *timestamppb.Timestamp = ×tamppb.Timestamp{} var endTime *timestamppb.Timestamp = ×tamppb.Timestamp{} var request = &datatransferpb.ScheduleTransferRunsRequest{ Parent: formattedParent, StartTime: startTime, EndTime: endTime, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ScheduleTransferRuns(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDataTransfer.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDataTransferServiceScheduleTransferRunsError(t *testing.T) { errCode := codes.PermissionDenied mockDataTransfer.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/transferConfigs/%s", "[PROJECT]", "[TRANSFER_CONFIG]") var startTime *timestamppb.Timestamp = ×tamppb.Timestamp{} var endTime *timestamppb.Timestamp = ×tamppb.Timestamp{} var request = &datatransferpb.ScheduleTransferRunsRequest{ Parent: formattedParent, StartTime: startTime, EndTime: endTime, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ScheduleTransferRuns(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDataTransferServiceGetTransferRun(t *testing.T) { var name2 string = "name2-1052831874" var destinationDatasetId string = "destinationDatasetId1541564179" var dataSourceId string = "dataSourceId-1015796374" var userId int64 = 147132913 var schedule string = "schedule-697920873" var expectedResponse = &datatransferpb.TransferRun{ Name: name2, Destination: &datatransferpb.TransferRun_DestinationDatasetId{ DestinationDatasetId: destinationDatasetId, }, DataSourceId: dataSourceId, UserId: userId, Schedule: schedule, } mockDataTransfer.err = nil mockDataTransfer.reqs = nil mockDataTransfer.resps = append(mockDataTransfer.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/transferConfigs/%s/runs/%s", "[PROJECT]", "[TRANSFER_CONFIG]", "[RUN]") var request = &datatransferpb.GetTransferRunRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetTransferRun(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDataTransfer.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDataTransferServiceGetTransferRunError(t *testing.T) { errCode := codes.PermissionDenied mockDataTransfer.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/transferConfigs/%s/runs/%s", "[PROJECT]", "[TRANSFER_CONFIG]", "[RUN]") var request = &datatransferpb.GetTransferRunRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetTransferRun(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDataTransferServiceDeleteTransferRun(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockDataTransfer.err = nil mockDataTransfer.reqs = nil mockDataTransfer.resps = append(mockDataTransfer.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/transferConfigs/%s/runs/%s", "[PROJECT]", "[TRANSFER_CONFIG]", "[RUN]") var request = &datatransferpb.DeleteTransferRunRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteTransferRun(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDataTransfer.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestDataTransferServiceDeleteTransferRunError(t *testing.T) { errCode := codes.PermissionDenied mockDataTransfer.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/transferConfigs/%s/runs/%s", "[PROJECT]", "[TRANSFER_CONFIG]", "[RUN]") var request = &datatransferpb.DeleteTransferRunRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteTransferRun(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestDataTransferServiceListTransferRuns(t *testing.T) { var nextPageToken string = "" var transferRunsElement *datatransferpb.TransferRun = &datatransferpb.TransferRun{} var transferRuns = []*datatransferpb.TransferRun{transferRunsElement} var expectedResponse = &datatransferpb.ListTransferRunsResponse{ NextPageToken: nextPageToken, TransferRuns: transferRuns, } mockDataTransfer.err = nil mockDataTransfer.reqs = nil mockDataTransfer.resps = append(mockDataTransfer.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/transferConfigs/%s", "[PROJECT]", "[TRANSFER_CONFIG]") var request = &datatransferpb.ListTransferRunsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListTransferRuns(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockDataTransfer.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.TransferRuns[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDataTransferServiceListTransferRunsError(t *testing.T) { errCode := codes.PermissionDenied mockDataTransfer.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/transferConfigs/%s", "[PROJECT]", "[TRANSFER_CONFIG]") var request = &datatransferpb.ListTransferRunsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListTransferRuns(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDataTransferServiceListTransferLogs(t *testing.T) { var nextPageToken string = "" var transferMessagesElement *datatransferpb.TransferMessage = &datatransferpb.TransferMessage{} var transferMessages = []*datatransferpb.TransferMessage{transferMessagesElement} var expectedResponse = &datatransferpb.ListTransferLogsResponse{ NextPageToken: nextPageToken, TransferMessages: transferMessages, } mockDataTransfer.err = nil mockDataTransfer.reqs = nil mockDataTransfer.resps = append(mockDataTransfer.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/transferConfigs/%s/runs/%s", "[PROJECT]", "[TRANSFER_CONFIG]", "[RUN]") var request = &datatransferpb.ListTransferLogsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListTransferLogs(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockDataTransfer.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.TransferMessages[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDataTransferServiceListTransferLogsError(t *testing.T) { errCode := codes.PermissionDenied mockDataTransfer.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/transferConfigs/%s/runs/%s", "[PROJECT]", "[TRANSFER_CONFIG]", "[RUN]") var request = &datatransferpb.ListTransferLogsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListTransferLogs(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDataTransferServiceCheckValidCreds(t *testing.T) { var hasValidCreds bool = false var expectedResponse = &datatransferpb.CheckValidCredsResponse{ HasValidCreds: hasValidCreds, } mockDataTransfer.err = nil mockDataTransfer.reqs = nil mockDataTransfer.resps = append(mockDataTransfer.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/dataSources/%s", "[PROJECT]", "[DATA_SOURCE]") var request = &datatransferpb.CheckValidCredsRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CheckValidCreds(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDataTransfer.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDataTransferServiceCheckValidCredsError(t *testing.T) { errCode := codes.PermissionDenied mockDataTransfer.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/dataSources/%s", "[PROJECT]", "[DATA_SOURCE]") var request = &datatransferpb.CheckValidCredsRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CheckValidCreds(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDataTransferServiceStartManualTransferRuns(t *testing.T) { var expectedResponse *datatransferpb.StartManualTransferRunsResponse = &datatransferpb.StartManualTransferRunsResponse{} mockDataTransfer.err = nil mockDataTransfer.reqs = nil mockDataTransfer.resps = append(mockDataTransfer.resps[:0], expectedResponse) var request *datatransferpb.StartManualTransferRunsRequest = &datatransferpb.StartManualTransferRunsRequest{} c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.StartManualTransferRuns(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDataTransfer.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDataTransferServiceStartManualTransferRunsError(t *testing.T) { errCode := codes.PermissionDenied mockDataTransfer.err = gstatus.Error(errCode, "test error") var request *datatransferpb.StartManualTransferRunsRequest = &datatransferpb.StartManualTransferRunsRequest{} c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.StartManualTransferRuns(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/bigquery/datatransfer/apiv1/path_funcs.go000066400000000000000000000064621356504100700246060ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package datatransfer // ProjectPath returns the path for the project resource. // // Deprecated: Use // fmt.Sprintf("projects/%s", project) // instead. func ProjectPath(project string) string { return "" + "projects/" + project + "" } // LocationPath returns the path for the location resource. // // Deprecated: Use // fmt.Sprintf("projects/%s/locations/%s", project, location) // instead. func LocationPath(project, location string) string { return "" + "projects/" + project + "/locations/" + location + "" } // LocationDataSourcePath returns the path for the location data source resource. // // Deprecated: Use // fmt.Sprintf("projects/%s/locations/%s/dataSources/%s", project, location, dataSource) // instead. func LocationDataSourcePath(project, location, dataSource string) string { return "" + "projects/" + project + "/locations/" + location + "/dataSources/" + dataSource + "" } // LocationTransferConfigPath returns the path for the location transfer config resource. // // Deprecated: Use // fmt.Sprintf("projects/%s/locations/%s/transferConfigs/%s", project, location, transferConfig) // instead. func LocationTransferConfigPath(project, location, transferConfig string) string { return "" + "projects/" + project + "/locations/" + location + "/transferConfigs/" + transferConfig + "" } // LocationRunPath returns the path for the location run resource. // // Deprecated: Use // fmt.Sprintf("projects/%s/locations/%s/transferConfigs/%s/runs/%s", project, location, transferConfig, run) // instead. func LocationRunPath(project, location, transferConfig, run string) string { return "" + "projects/" + project + "/locations/" + location + "/transferConfigs/" + transferConfig + "/runs/" + run + "" } // DataSourcePath returns the path for the data source resource. // // Deprecated: Use // fmt.Sprintf("projects/%s/dataSources/%s", project, dataSource) // instead. func DataSourcePath(project, dataSource string) string { return "" + "projects/" + project + "/dataSources/" + dataSource + "" } // TransferConfigPath returns the path for the transfer config resource. // // Deprecated: Use // fmt.Sprintf("projects/%s/transferConfigs/%s", project, transferConfig) // instead. func TransferConfigPath(project, transferConfig string) string { return "" + "projects/" + project + "/transferConfigs/" + transferConfig + "" } // RunPath returns the path for the run resource. // // Deprecated: Use // fmt.Sprintf("projects/%s/transferConfigs/%s/runs/%s", project, transferConfig, run) // instead. func RunPath(project, transferConfig, run string) string { return "" + "projects/" + project + "/transferConfigs/" + transferConfig + "/runs/" + run + "" } google-cloud-go-0.49.0/bigquery/doc.go000066400000000000000000000227721356504100700175250ustar00rootroot00000000000000// Copyright 2015 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. /* Package bigquery provides a client for the BigQuery service. The following assumes a basic familiarity with BigQuery concepts. See https://cloud.google.com/bigquery/docs. See https://godoc.org/cloud.google.com/go for authentication, timeouts, connection pooling and similar aspects of this package. Creating a Client To start working with this package, create a client: ctx := context.Background() client, err := bigquery.NewClient(ctx, projectID) if err != nil { // TODO: Handle error. } Querying To query existing tables, create a Query and call its Read method: q := client.Query(` SELECT year, SUM(number) as num FROM ` + "`bigquery-public-data.usa_names.usa_1910_2013`" + ` WHERE name = "William" GROUP BY year ORDER BY year `) it, err := q.Read(ctx) if err != nil { // TODO: Handle error. } Then iterate through the resulting rows. You can store a row using anything that implements the ValueLoader interface, or with a slice or map of bigquery.Value. A slice is simplest: for { var values []bigquery.Value err := it.Next(&values) if err == iterator.Done { break } if err != nil { // TODO: Handle error. } fmt.Println(values) } You can also use a struct whose exported fields match the query: type Count struct { Year int Num int } for { var c Count err := it.Next(&c) if err == iterator.Done { break } if err != nil { // TODO: Handle error. } fmt.Println(c) } You can also start the query running and get the results later. Create the query as above, but call Run instead of Read. This returns a Job, which represents an asynchronous operation. job, err := q.Run(ctx) if err != nil { // TODO: Handle error. } Get the job's ID, a printable string. You can save this string to retrieve the results at a later time, even in another process. jobID := job.ID() fmt.Printf("The job ID is %s\n", jobID) To retrieve the job's results from the ID, first look up the Job: job, err = client.JobFromID(ctx, jobID) if err != nil { // TODO: Handle error. } Use the Job.Read method to obtain an iterator, and loop over the rows. Query.Read is just a convenience method that combines Query.Run and Job.Read. it, err = job.Read(ctx) if err != nil { // TODO: Handle error. } // Proceed with iteration as above. Datasets and Tables You can refer to datasets in the client's project with the Dataset method, and in other projects with the DatasetInProject method: myDataset := client.Dataset("my_dataset") yourDataset := client.DatasetInProject("your-project-id", "your_dataset") These methods create references to datasets, not the datasets themselves. You can have a dataset reference even if the dataset doesn't exist yet. Use Dataset.Create to create a dataset from a reference: if err := myDataset.Create(ctx, nil); err != nil { // TODO: Handle error. } You can refer to tables with Dataset.Table. Like bigquery.Dataset, bigquery.Table is a reference to an object in BigQuery that may or may not exist. table := myDataset.Table("my_table") You can create, delete and update the metadata of tables with methods on Table. For instance, you could create a temporary table with: err = myDataset.Table("temp").Create(ctx, &bigquery.TableMetadata{ ExpirationTime: time.Now().Add(1*time.Hour)}) if err != nil { // TODO: Handle error. } We'll see how to create a table with a schema in the next section. Schemas There are two ways to construct schemas with this package. You can build a schema by hand, like so: schema1 := bigquery.Schema{ {Name: "Name", Required: true, Type: bigquery.StringFieldType}, {Name: "Grades", Repeated: true, Type: bigquery.IntegerFieldType}, {Name: "Optional", Required: false, Type: bigquery.IntegerFieldType}, } Or you can infer the schema from a struct: type student struct { Name string Grades []int Optional bigquery.NullInt64 } schema2, err := bigquery.InferSchema(student{}) if err != nil { // TODO: Handle error. } // schema1 and schema2 are identical. Struct inference supports tags like those of the encoding/json package, so you can change names, ignore fields, or mark a field as nullable (non-required). Fields declared as one of the Null types (NullInt64, NullFloat64, NullString, NullBool, NullTimestamp, NullDate, NullTime, NullDateTime, and NullGeography) are automatically inferred as nullable, so the "nullable" tag is only needed for []byte, *big.Rat and pointer-to-struct fields. type student2 struct { Name string `bigquery:"full_name"` Grades []int Secret string `bigquery:"-"` Optional []byte `bigquery:",nullable" } schema3, err := bigquery.InferSchema(student2{}) if err != nil { // TODO: Handle error. } // schema3 has required fields "full_name" and "Grade", and nullable BYTES field "Optional". Having constructed a schema, you can create a table with it like so: if err := table.Create(ctx, &bigquery.TableMetadata{Schema: schema1}); err != nil { // TODO: Handle error. } Copying You can copy one or more tables to another table. Begin by constructing a Copier describing the copy. Then set any desired copy options, and finally call Run to get a Job: copier := myDataset.Table("dest").CopierFrom(myDataset.Table("src")) copier.WriteDisposition = bigquery.WriteTruncate job, err = copier.Run(ctx) if err != nil { // TODO: Handle error. } You can chain the call to Run if you don't want to set options: job, err = myDataset.Table("dest").CopierFrom(myDataset.Table("src")).Run(ctx) if err != nil { // TODO: Handle error. } You can wait for your job to complete: status, err := job.Wait(ctx) if err != nil { // TODO: Handle error. } Job.Wait polls with exponential backoff. You can also poll yourself, if you wish: for { status, err := job.Status(ctx) if err != nil { // TODO: Handle error. } if status.Done() { if status.Err() != nil { log.Fatalf("Job failed with error %v", status.Err()) } break } time.Sleep(pollInterval) } Loading and Uploading There are two ways to populate a table with this package: load the data from a Google Cloud Storage object, or upload rows directly from your program. For loading, first create a GCSReference, configuring it if desired. Then make a Loader, optionally configure it as well, and call its Run method. gcsRef := bigquery.NewGCSReference("gs://my-bucket/my-object") gcsRef.AllowJaggedRows = true loader := myDataset.Table("dest").LoaderFrom(gcsRef) loader.CreateDisposition = bigquery.CreateNever job, err = loader.Run(ctx) // Poll the job for completion if desired, as above. To upload, first define a type that implements the ValueSaver interface, which has a single method named Save. Then create an Uploader, and call its Put method with a slice of values. u := table.Uploader() // Item implements the ValueSaver interface. items := []*Item{ {Name: "n1", Size: 32.6, Count: 7}, {Name: "n2", Size: 4, Count: 2}, {Name: "n3", Size: 101.5, Count: 1}, } if err := u.Put(ctx, items); err != nil { // TODO: Handle error. } You can also upload a struct that doesn't implement ValueSaver. Use the StructSaver type to specify the schema and insert ID by hand, or just supply the struct or struct pointer directly and the schema will be inferred: type Item2 struct { Name string Size float64 Count int } // Item implements the ValueSaver interface. items2 := []*Item2{ {Name: "n1", Size: 32.6, Count: 7}, {Name: "n2", Size: 4, Count: 2}, {Name: "n3", Size: 101.5, Count: 1}, } if err := u.Put(ctx, items2); err != nil { // TODO: Handle error. } Extracting If you've been following so far, extracting data from a BigQuery table into a Google Cloud Storage object will feel familiar. First create an Extractor, then optionally configure it, and lastly call its Run method. extractor := table.ExtractorTo(gcsRef) extractor.DisableHeader = true job, err = extractor.Run(ctx) // Poll the job for completion if desired, as above. Errors Errors returned by this client are often of the type [`googleapi.Error`](https://godoc.org/google.golang.org/api/googleapi#Error). These errors can be introspected for more information by type asserting to the richer `googleapi.Error` type. For example: if e, ok := err.(*googleapi.Error); ok { if e.Code = 409 { ... } } */ package bigquery // import "cloud.google.com/go/bigquery" google-cloud-go-0.49.0/bigquery/error.go000066400000000000000000000045601356504100700201040ustar00rootroot00000000000000// Copyright 2015 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "fmt" bq "google.golang.org/api/bigquery/v2" ) // An Error contains detailed information about a failed bigquery operation. // Detailed description of possible Reasons can be found here: https://cloud.google.com/bigquery/troubleshooting-errors. type Error struct { // Mirrors bq.ErrorProto, but drops DebugInfo Location, Message, Reason string } func (e Error) Error() string { return fmt.Sprintf("{Location: %q; Message: %q; Reason: %q}", e.Location, e.Message, e.Reason) } func bqToError(ep *bq.ErrorProto) *Error { if ep == nil { return nil } return &Error{ Location: ep.Location, Message: ep.Message, Reason: ep.Reason, } } // A MultiError contains multiple related errors. type MultiError []error func (m MultiError) Error() string { switch len(m) { case 0: return "(0 errors)" case 1: return m[0].Error() case 2: return m[0].Error() + " (and 1 other error)" } return fmt.Sprintf("%s (and %d other errors)", m[0].Error(), len(m)-1) } // RowInsertionError contains all errors that occurred when attempting to insert a row. type RowInsertionError struct { InsertID string // The InsertID associated with the affected row. RowIndex int // The 0-based index of the affected row in the batch of rows being inserted. Errors MultiError } func (e *RowInsertionError) Error() string { errFmt := "insertion of row [insertID: %q; insertIndex: %v] failed with error: %s" return fmt.Sprintf(errFmt, e.InsertID, e.RowIndex, e.Errors.Error()) } // PutMultiError contains an error for each row which was not successfully inserted // into a BigQuery table. type PutMultiError []RowInsertionError func (pme PutMultiError) Error() string { plural := "s" if len(pme) == 1 { plural = "" } return fmt.Sprintf("%v row insertion%s failed", len(pme), plural) } google-cloud-go-0.49.0/bigquery/error_test.go000066400000000000000000000052101356504100700211340ustar00rootroot00000000000000// Copyright 2015 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "errors" "strings" "testing" "cloud.google.com/go/internal/testutil" bq "google.golang.org/api/bigquery/v2" ) func rowInsertionError(msg string) RowInsertionError { return RowInsertionError{Errors: []error{errors.New(msg)}} } func TestPutMultiErrorString(t *testing.T) { testCases := []struct { errs PutMultiError want string }{ { errs: PutMultiError{}, want: "0 row insertions failed", }, { errs: PutMultiError{rowInsertionError("a")}, want: "1 row insertion failed", }, { errs: PutMultiError{rowInsertionError("a"), rowInsertionError("b")}, want: "2 row insertions failed", }, } for _, tc := range testCases { if tc.errs.Error() != tc.want { t.Errorf("PutMultiError string: got:\n%v\nwant:\n%v", tc.errs.Error(), tc.want) } } } func TestMultiErrorString(t *testing.T) { testCases := []struct { errs MultiError want string }{ { errs: MultiError{}, want: "(0 errors)", }, { errs: MultiError{errors.New("a")}, want: "a", }, { errs: MultiError{errors.New("a"), errors.New("b")}, want: "a (and 1 other error)", }, { errs: MultiError{errors.New("a"), errors.New("b"), errors.New("c")}, want: "a (and 2 other errors)", }, } for _, tc := range testCases { if tc.errs.Error() != tc.want { t.Errorf("PutMultiError string: got:\n%v\nwant:\n%v", tc.errs.Error(), tc.want) } } } func TestErrorFromErrorProto(t *testing.T) { for _, test := range []struct { in *bq.ErrorProto want *Error }{ {nil, nil}, { in: &bq.ErrorProto{Location: "L", Message: "M", Reason: "R"}, want: &Error{Location: "L", Message: "M", Reason: "R"}, }, } { if got := bqToError(test.in); !testutil.Equal(got, test.want) { t.Errorf("%v: got %v, want %v", test.in, got, test.want) } } } func TestErrorString(t *testing.T) { e := &Error{Location: "", Message: "", Reason: ""} got := e.Error() if !strings.Contains(got, "") || !strings.Contains(got, "") || !strings.Contains(got, "") { t.Errorf(`got %q, expected to see "", "" and ""`, got) } } google-cloud-go-0.49.0/bigquery/examples_test.go000066400000000000000000000503071356504100700216300ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery_test import ( "context" "fmt" "os" "time" "cloud.google.com/go/bigquery" "google.golang.org/api/iterator" ) func ExampleNewClient() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } _ = client // TODO: Use client. } func ExampleClient_Dataset() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } ds := client.Dataset("my_dataset") fmt.Println(ds) } func ExampleClient_DatasetInProject() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } ds := client.DatasetInProject("their-project-id", "their-dataset") fmt.Println(ds) } func ExampleClient_Datasets() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } it := client.Datasets(ctx) _ = it // TODO: iterate using Next or iterator.Pager. } func ExampleClient_DatasetsInProject() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } it := client.DatasetsInProject(ctx, "their-project-id") _ = it // TODO: iterate using Next or iterator.Pager. } func getJobID() string { return "" } func ExampleClient_JobFromID() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } jobID := getJobID() // Get a job ID using Job.ID, the console or elsewhere. job, err := client.JobFromID(ctx, jobID) if err != nil { // TODO: Handle error. } fmt.Println(job.LastStatus()) // Display the job's status. } func ExampleClient_Jobs() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } it := client.Jobs(ctx) it.State = bigquery.Running // list only running jobs. _ = it // TODO: iterate using Next or iterator.Pager. } func ExampleNewGCSReference() { gcsRef := bigquery.NewGCSReference("gs://my-bucket/my-object") fmt.Println(gcsRef) } func ExampleClient_Query() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } q := client.Query("select name, num from t1") q.DefaultProjectID = "project-id" // TODO: set other options on the Query. // TODO: Call Query.Run or Query.Read. } func ExampleClient_Query_parameters() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } q := client.Query("select num from t1 where name = @user") q.Parameters = []bigquery.QueryParameter{ {Name: "user", Value: "Elizabeth"}, } // TODO: set other options on the Query. // TODO: Call Query.Run or Query.Read. } // This example demonstrates how to run a query job on a table // with a customer-managed encryption key. The same // applies to load and copy jobs as well. func ExampleClient_Query_encryptionKey() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } q := client.Query("select name, num from t1") // TODO: Replace this key with a key you have created in Cloud KMS. keyName := "projects/P/locations/L/keyRings/R/cryptoKeys/K" q.DestinationEncryptionConfig = &bigquery.EncryptionConfig{KMSKeyName: keyName} // TODO: set other options on the Query. // TODO: Call Query.Run or Query.Read. } func ExampleQuery_Read() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } q := client.Query("select name, num from t1") it, err := q.Read(ctx) if err != nil { // TODO: Handle error. } _ = it // TODO: iterate using Next or iterator.Pager. } func ExampleRowIterator_Next() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } q := client.Query("select name, num from t1") it, err := q.Read(ctx) if err != nil { // TODO: Handle error. } for { var row []bigquery.Value err := it.Next(&row) if err == iterator.Done { break } if err != nil { // TODO: Handle error. } fmt.Println(row) } } func ExampleRowIterator_Next_struct() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } type score struct { Name string Num int } q := client.Query("select name, num from t1") it, err := q.Read(ctx) if err != nil { // TODO: Handle error. } for { var s score err := it.Next(&s) if err == iterator.Done { break } if err != nil { // TODO: Handle error. } fmt.Println(s) } } func ExampleJob_Read() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } q := client.Query("select name, num from t1") // Call Query.Run to get a Job, then call Read on the job. // Note: Query.Read is a shorthand for this. job, err := q.Run(ctx) if err != nil { // TODO: Handle error. } it, err := job.Read(ctx) if err != nil { // TODO: Handle error. } _ = it // TODO: iterate using Next or iterator.Pager. } func ExampleJob_Wait() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } ds := client.Dataset("my_dataset") job, err := ds.Table("t1").CopierFrom(ds.Table("t2")).Run(ctx) if err != nil { // TODO: Handle error. } status, err := job.Wait(ctx) if err != nil { // TODO: Handle error. } if status.Err() != nil { // TODO: Handle error. } } func ExampleJob_Config() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } ds := client.Dataset("my_dataset") job, err := ds.Table("t1").CopierFrom(ds.Table("t2")).Run(ctx) if err != nil { // TODO: Handle error. } jc, err := job.Config() if err != nil { // TODO: Handle error. } copyConfig := jc.(*bigquery.CopyConfig) fmt.Println(copyConfig.Dst, copyConfig.CreateDisposition) } func ExampleDataset_Create() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } ds := client.Dataset("my_dataset") if err := ds.Create(ctx, &bigquery.DatasetMetadata{Location: "EU"}); err != nil { // TODO: Handle error. } } func ExampleDataset_Delete() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } if err := client.Dataset("my_dataset").Delete(ctx); err != nil { // TODO: Handle error. } } func ExampleDataset_Metadata() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } md, err := client.Dataset("my_dataset").Metadata(ctx) if err != nil { // TODO: Handle error. } fmt.Println(md) } // This example illustrates how to perform a read-modify-write sequence on dataset // metadata. Passing the metadata's ETag to the Update call ensures that the call // will fail if the metadata was changed since the read. func ExampleDataset_Update_readModifyWrite() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } ds := client.Dataset("my_dataset") md, err := ds.Metadata(ctx) if err != nil { // TODO: Handle error. } md2, err := ds.Update(ctx, bigquery.DatasetMetadataToUpdate{Name: "new " + md.Name}, md.ETag) if err != nil { // TODO: Handle error. } fmt.Println(md2) } // To perform a blind write, ignoring the existing state (and possibly overwriting // other updates), pass the empty string as the etag. func ExampleDataset_Update_blindWrite() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } md, err := client.Dataset("my_dataset").Update(ctx, bigquery.DatasetMetadataToUpdate{Name: "blind"}, "") if err != nil { // TODO: Handle error. } fmt.Println(md) } func ExampleDataset_Table() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } // Table creates a reference to the table. It does not create the actual // table in BigQuery; to do so, use Table.Create. t := client.Dataset("my_dataset").Table("my_table") fmt.Println(t) } func ExampleDataset_Tables() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } it := client.Dataset("my_dataset").Tables(ctx) _ = it // TODO: iterate using Next or iterator.Pager. } func ExampleDatasetIterator_Next() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } it := client.Datasets(ctx) for { ds, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } fmt.Println(ds) } } func ExampleInferSchema() { type Item struct { Name string Size float64 Count int } schema, err := bigquery.InferSchema(Item{}) if err != nil { fmt.Println(err) // TODO: Handle error. } for _, fs := range schema { fmt.Println(fs.Name, fs.Type) } // Output: // Name STRING // Size FLOAT // Count INTEGER } func ExampleInferSchema_tags() { type Item struct { Name string Size float64 Count int `bigquery:"number"` Secret []byte `bigquery:"-"` Optional bigquery.NullBool OptBytes []byte `bigquery:",nullable"` } schema, err := bigquery.InferSchema(Item{}) if err != nil { fmt.Println(err) // TODO: Handle error. } for _, fs := range schema { fmt.Println(fs.Name, fs.Type, fs.Required) } // Output: // Name STRING true // Size FLOAT true // number INTEGER true // Optional BOOLEAN false // OptBytes BYTES false } func ExampleTable_Create() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } t := client.Dataset("my_dataset").Table("new-table") if err := t.Create(ctx, nil); err != nil { // TODO: Handle error. } } // Initialize a new table by passing TableMetadata to Table.Create. func ExampleTable_Create_initialize() { ctx := context.Background() // Infer table schema from a Go type. schema, err := bigquery.InferSchema(Item{}) if err != nil { // TODO: Handle error. } client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } t := client.Dataset("my_dataset").Table("new-table") if err := t.Create(ctx, &bigquery.TableMetadata{ Name: "My New Table", Schema: schema, ExpirationTime: time.Now().Add(24 * time.Hour), }); err != nil { // TODO: Handle error. } } // This example demonstrates how to create a table with // a customer-managed encryption key. func ExampleTable_Create_encryptionKey() { ctx := context.Background() // Infer table schema from a Go type. schema, err := bigquery.InferSchema(Item{}) if err != nil { // TODO: Handle error. } client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } t := client.Dataset("my_dataset").Table("new-table") // TODO: Replace this key with a key you have created in Cloud KMS. keyName := "projects/P/locations/L/keyRings/R/cryptoKeys/K" if err := t.Create(ctx, &bigquery.TableMetadata{ Name: "My New Table", Schema: schema, EncryptionConfig: &bigquery.EncryptionConfig{KMSKeyName: keyName}, }); err != nil { // TODO: Handle error. } } func ExampleTable_Delete() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } if err := client.Dataset("my_dataset").Table("my_table").Delete(ctx); err != nil { // TODO: Handle error. } } func ExampleTable_Metadata() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } md, err := client.Dataset("my_dataset").Table("my_table").Metadata(ctx) if err != nil { // TODO: Handle error. } fmt.Println(md) } func ExampleTable_Inserter() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } ins := client.Dataset("my_dataset").Table("my_table").Inserter() _ = ins // TODO: Use ins. } func ExampleTable_Inserter_options() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } ins := client.Dataset("my_dataset").Table("my_table").Inserter() ins.SkipInvalidRows = true ins.IgnoreUnknownValues = true _ = ins // TODO: Use ins. } func ExampleTable_CopierFrom() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } ds := client.Dataset("my_dataset") c := ds.Table("combined").CopierFrom(ds.Table("t1"), ds.Table("t2")) c.WriteDisposition = bigquery.WriteTruncate // TODO: set other options on the Copier. job, err := c.Run(ctx) if err != nil { // TODO: Handle error. } status, err := job.Wait(ctx) if err != nil { // TODO: Handle error. } if status.Err() != nil { // TODO: Handle error. } } func ExampleTable_ExtractorTo() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } gcsRef := bigquery.NewGCSReference("gs://my-bucket/my-object") gcsRef.FieldDelimiter = ":" // TODO: set other options on the GCSReference. ds := client.Dataset("my_dataset") extractor := ds.Table("my_table").ExtractorTo(gcsRef) extractor.DisableHeader = true // TODO: set other options on the Extractor. job, err := extractor.Run(ctx) if err != nil { // TODO: Handle error. } status, err := job.Wait(ctx) if err != nil { // TODO: Handle error. } if status.Err() != nil { // TODO: Handle error. } } func ExampleTable_LoaderFrom() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } gcsRef := bigquery.NewGCSReference("gs://my-bucket/my-object") gcsRef.AllowJaggedRows = true gcsRef.MaxBadRecords = 5 gcsRef.Schema = schema // TODO: set other options on the GCSReference. ds := client.Dataset("my_dataset") loader := ds.Table("my_table").LoaderFrom(gcsRef) loader.CreateDisposition = bigquery.CreateNever // TODO: set other options on the Loader. job, err := loader.Run(ctx) if err != nil { // TODO: Handle error. } status, err := job.Wait(ctx) if err != nil { // TODO: Handle error. } if status.Err() != nil { // TODO: Handle error. } } func ExampleTable_LoaderFrom_reader() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } f, err := os.Open("data.csv") if err != nil { // TODO: Handle error. } rs := bigquery.NewReaderSource(f) rs.AllowJaggedRows = true rs.MaxBadRecords = 5 rs.Schema = schema // TODO: set other options on the GCSReference. ds := client.Dataset("my_dataset") loader := ds.Table("my_table").LoaderFrom(rs) loader.CreateDisposition = bigquery.CreateNever // TODO: set other options on the Loader. job, err := loader.Run(ctx) if err != nil { // TODO: Handle error. } status, err := job.Wait(ctx) if err != nil { // TODO: Handle error. } if status.Err() != nil { // TODO: Handle error. } } func ExampleTable_Read() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } it := client.Dataset("my_dataset").Table("my_table").Read(ctx) _ = it // TODO: iterate using Next or iterator.Pager. } // This example illustrates how to perform a read-modify-write sequence on table // metadata. Passing the metadata's ETag to the Update call ensures that the call // will fail if the metadata was changed since the read. func ExampleTable_Update_readModifyWrite() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } t := client.Dataset("my_dataset").Table("my_table") md, err := t.Metadata(ctx) if err != nil { // TODO: Handle error. } md2, err := t.Update(ctx, bigquery.TableMetadataToUpdate{Name: "new " + md.Name}, md.ETag) if err != nil { // TODO: Handle error. } fmt.Println(md2) } // To perform a blind write, ignoring the existing state (and possibly overwriting // other updates), pass the empty string as the etag. func ExampleTable_Update_blindWrite() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } t := client.Dataset("my_dataset").Table("my_table") tm, err := t.Update(ctx, bigquery.TableMetadataToUpdate{ Description: "my favorite table", }, "") if err != nil { // TODO: Handle error. } fmt.Println(tm) } func ExampleTableIterator_Next() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } it := client.Dataset("my_dataset").Tables(ctx) for { t, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } fmt.Println(t) } } type Item struct { Name string Size float64 Count int } // Save implements the ValueSaver interface. func (i *Item) Save() (map[string]bigquery.Value, string, error) { return map[string]bigquery.Value{ "Name": i.Name, "Size": i.Size, "Count": i.Count, }, "", nil } func ExampleInserter_Put() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } ins := client.Dataset("my_dataset").Table("my_table").Inserter() // Item implements the ValueSaver interface. items := []*Item{ {Name: "n1", Size: 32.6, Count: 7}, {Name: "n2", Size: 4, Count: 2}, {Name: "n3", Size: 101.5, Count: 1}, } if err := ins.Put(ctx, items); err != nil { // TODO: Handle error. } } var schema bigquery.Schema func ExampleInserter_Put_structSaver() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } ins := client.Dataset("my_dataset").Table("my_table").Inserter() type score struct { Name string Num int } // Assume schema holds the table's schema. savers := []*bigquery.StructSaver{ {Struct: score{Name: "n1", Num: 12}, Schema: schema, InsertID: "id1"}, {Struct: score{Name: "n2", Num: 31}, Schema: schema, InsertID: "id2"}, {Struct: score{Name: "n3", Num: 7}, Schema: schema, InsertID: "id3"}, } if err := ins.Put(ctx, savers); err != nil { // TODO: Handle error. } } func ExampleInserter_Put_struct() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } ins := client.Dataset("my_dataset").Table("my_table").Inserter() type score struct { Name string Num int } scores := []score{ {Name: "n1", Num: 12}, {Name: "n2", Num: 31}, {Name: "n3", Num: 7}, } // Schema is inferred from the score type. if err := ins.Put(ctx, scores); err != nil { // TODO: Handle error. } } func ExampleInserter_Put_valuesSaver() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } ins := client.Dataset("my_dataset").Table("my_table").Inserter() var vss []*bigquery.ValuesSaver for i, name := range []string{"n1", "n2", "n3"} { // Assume schema holds the table's schema. vss = append(vss, &bigquery.ValuesSaver{ Schema: schema, InsertID: name, Row: []bigquery.Value{name, int64(i)}, }) } if err := ins.Put(ctx, vss); err != nil { // TODO: Handle error. } } google-cloud-go-0.49.0/bigquery/external.go000066400000000000000000000321551356504100700205760ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "encoding/base64" "unicode/utf8" bq "google.golang.org/api/bigquery/v2" ) // DataFormat describes the format of BigQuery table data. type DataFormat string // Constants describing the format of BigQuery table data. const ( CSV DataFormat = "CSV" Avro DataFormat = "AVRO" JSON DataFormat = "NEWLINE_DELIMITED_JSON" DatastoreBackup DataFormat = "DATASTORE_BACKUP" GoogleSheets DataFormat = "GOOGLE_SHEETS" Bigtable DataFormat = "BIGTABLE" Parquet DataFormat = "PARQUET" ORC DataFormat = "ORC" ) // ExternalData is a table which is stored outside of BigQuery. It is implemented by // *ExternalDataConfig. // GCSReference also implements it, for backwards compatibility. type ExternalData interface { toBQ() bq.ExternalDataConfiguration } // ExternalDataConfig describes data external to BigQuery that can be used // in queries and to create external tables. type ExternalDataConfig struct { // The format of the data. Required. SourceFormat DataFormat // The fully-qualified URIs that point to your // data in Google Cloud. Required. // // For Google Cloud Storage URIs, each URI can contain one '*' wildcard character // and it must come after the 'bucket' name. Size limits related to load jobs // apply to external data sources. // // For Google Cloud Bigtable URIs, exactly one URI can be specified and it has be // a fully specified and valid HTTPS URL for a Google Cloud Bigtable table. // // For Google Cloud Datastore backups, exactly one URI can be specified. Also, // the '*' wildcard character is not allowed. SourceURIs []string // The schema of the data. Required for CSV and JSON; disallowed for the // other formats. Schema Schema // Try to detect schema and format options automatically. // Any option specified explicitly will be honored. AutoDetect bool // The compression type of the data. Compression Compression // IgnoreUnknownValues causes values not matching the schema to be // tolerated. Unknown values are ignored. For CSV this ignores extra values // at the end of a line. For JSON this ignores named values that do not // match any column name. If this field is not set, records containing // unknown values are treated as bad records. The MaxBadRecords field can // be used to customize how bad records are handled. IgnoreUnknownValues bool // MaxBadRecords is the maximum number of bad records that will be ignored // when reading data. MaxBadRecords int64 // Additional options for CSV, GoogleSheets and Bigtable formats. Options ExternalDataConfigOptions } func (e *ExternalDataConfig) toBQ() bq.ExternalDataConfiguration { q := bq.ExternalDataConfiguration{ SourceFormat: string(e.SourceFormat), SourceUris: e.SourceURIs, Autodetect: e.AutoDetect, Compression: string(e.Compression), IgnoreUnknownValues: e.IgnoreUnknownValues, MaxBadRecords: e.MaxBadRecords, } if e.Schema != nil { q.Schema = e.Schema.toBQ() } if e.Options != nil { e.Options.populateExternalDataConfig(&q) } return q } func bqToExternalDataConfig(q *bq.ExternalDataConfiguration) (*ExternalDataConfig, error) { e := &ExternalDataConfig{ SourceFormat: DataFormat(q.SourceFormat), SourceURIs: q.SourceUris, AutoDetect: q.Autodetect, Compression: Compression(q.Compression), IgnoreUnknownValues: q.IgnoreUnknownValues, MaxBadRecords: q.MaxBadRecords, Schema: bqToSchema(q.Schema), } switch { case q.CsvOptions != nil: e.Options = bqToCSVOptions(q.CsvOptions) case q.GoogleSheetsOptions != nil: e.Options = bqToGoogleSheetsOptions(q.GoogleSheetsOptions) case q.BigtableOptions != nil: var err error e.Options, err = bqToBigtableOptions(q.BigtableOptions) if err != nil { return nil, err } } return e, nil } // ExternalDataConfigOptions are additional options for external data configurations. // This interface is implemented by CSVOptions, GoogleSheetsOptions and BigtableOptions. type ExternalDataConfigOptions interface { populateExternalDataConfig(*bq.ExternalDataConfiguration) } // CSVOptions are additional options for CSV external data sources. type CSVOptions struct { // AllowJaggedRows causes missing trailing optional columns to be tolerated // when reading CSV data. Missing values are treated as nulls. AllowJaggedRows bool // AllowQuotedNewlines sets whether quoted data sections containing // newlines are allowed when reading CSV data. AllowQuotedNewlines bool // Encoding is the character encoding of data to be read. Encoding Encoding // FieldDelimiter is the separator for fields in a CSV file, used when // reading or exporting data. The default is ",". FieldDelimiter string // Quote is the value used to quote data sections in a CSV file. The // default quotation character is the double quote ("), which is used if // both Quote and ForceZeroQuote are unset. // To specify that no character should be interpreted as a quotation // character, set ForceZeroQuote to true. // Only used when reading data. Quote string ForceZeroQuote bool // The number of rows at the top of a CSV file that BigQuery will skip when // reading data. SkipLeadingRows int64 } func (o *CSVOptions) populateExternalDataConfig(c *bq.ExternalDataConfiguration) { c.CsvOptions = &bq.CsvOptions{ AllowJaggedRows: o.AllowJaggedRows, AllowQuotedNewlines: o.AllowQuotedNewlines, Encoding: string(o.Encoding), FieldDelimiter: o.FieldDelimiter, Quote: o.quote(), SkipLeadingRows: o.SkipLeadingRows, } } // quote returns the CSV quote character, or nil if unset. func (o *CSVOptions) quote() *string { if o.ForceZeroQuote { quote := "" return "e } if o.Quote == "" { return nil } return &o.Quote } func (o *CSVOptions) setQuote(ps *string) { if ps != nil { o.Quote = *ps if o.Quote == "" { o.ForceZeroQuote = true } } } func bqToCSVOptions(q *bq.CsvOptions) *CSVOptions { o := &CSVOptions{ AllowJaggedRows: q.AllowJaggedRows, AllowQuotedNewlines: q.AllowQuotedNewlines, Encoding: Encoding(q.Encoding), FieldDelimiter: q.FieldDelimiter, SkipLeadingRows: q.SkipLeadingRows, } o.setQuote(q.Quote) return o } // GoogleSheetsOptions are additional options for GoogleSheets external data sources. type GoogleSheetsOptions struct { // The number of rows at the top of a sheet that BigQuery will skip when // reading data. SkipLeadingRows int64 // Optionally specifies a more specific range of cells to include. // Typical format: sheet_name!top_left_cell_id:bottom_right_cell_id // // Example: sheet1!A1:B20 Range string } func (o *GoogleSheetsOptions) populateExternalDataConfig(c *bq.ExternalDataConfiguration) { c.GoogleSheetsOptions = &bq.GoogleSheetsOptions{ SkipLeadingRows: o.SkipLeadingRows, Range: o.Range, } } func bqToGoogleSheetsOptions(q *bq.GoogleSheetsOptions) *GoogleSheetsOptions { return &GoogleSheetsOptions{ SkipLeadingRows: q.SkipLeadingRows, Range: q.Range, } } // BigtableOptions are additional options for Bigtable external data sources. type BigtableOptions struct { // A list of column families to expose in the table schema along with their // types. If omitted, all column families are present in the table schema and // their values are read as BYTES. ColumnFamilies []*BigtableColumnFamily // If true, then the column families that are not specified in columnFamilies // list are not exposed in the table schema. Otherwise, they are read with BYTES // type values. The default is false. IgnoreUnspecifiedColumnFamilies bool // If true, then the rowkey column families will be read and converted to string. // Otherwise they are read with BYTES type values and users need to manually cast // them with CAST if necessary. The default is false. ReadRowkeyAsString bool } func (o *BigtableOptions) populateExternalDataConfig(c *bq.ExternalDataConfiguration) { q := &bq.BigtableOptions{ IgnoreUnspecifiedColumnFamilies: o.IgnoreUnspecifiedColumnFamilies, ReadRowkeyAsString: o.ReadRowkeyAsString, } for _, f := range o.ColumnFamilies { q.ColumnFamilies = append(q.ColumnFamilies, f.toBQ()) } c.BigtableOptions = q } func bqToBigtableOptions(q *bq.BigtableOptions) (*BigtableOptions, error) { b := &BigtableOptions{ IgnoreUnspecifiedColumnFamilies: q.IgnoreUnspecifiedColumnFamilies, ReadRowkeyAsString: q.ReadRowkeyAsString, } for _, f := range q.ColumnFamilies { f2, err := bqToBigtableColumnFamily(f) if err != nil { return nil, err } b.ColumnFamilies = append(b.ColumnFamilies, f2) } return b, nil } // BigtableColumnFamily describes how BigQuery should access a Bigtable column family. type BigtableColumnFamily struct { // Identifier of the column family. FamilyID string // Lists of columns that should be exposed as individual fields as opposed to a // list of (column name, value) pairs. All columns whose qualifier matches a // qualifier in this list can be accessed as .. Other columns can be accessed as // a list through .Column field. Columns []*BigtableColumn // The encoding of the values when the type is not STRING. Acceptable encoding values are: // - TEXT - indicates values are alphanumeric text strings. // - BINARY - indicates values are encoded using HBase Bytes.toBytes family of functions. // This can be overridden for a specific column by listing that column in 'columns' and // specifying an encoding for it. Encoding string // If true, only the latest version of values are exposed for all columns in this // column family. This can be overridden for a specific column by listing that // column in 'columns' and specifying a different setting for that column. OnlyReadLatest bool // The type to convert the value in cells of this // column family. The values are expected to be encoded using HBase // Bytes.toBytes function when using the BINARY encoding value. // Following BigQuery types are allowed (case-sensitive): // BYTES STRING INTEGER FLOAT BOOLEAN. // The default type is BYTES. This can be overridden for a specific column by // listing that column in 'columns' and specifying a type for it. Type string } func (b *BigtableColumnFamily) toBQ() *bq.BigtableColumnFamily { q := &bq.BigtableColumnFamily{ FamilyId: b.FamilyID, Encoding: b.Encoding, OnlyReadLatest: b.OnlyReadLatest, Type: b.Type, } for _, col := range b.Columns { q.Columns = append(q.Columns, col.toBQ()) } return q } func bqToBigtableColumnFamily(q *bq.BigtableColumnFamily) (*BigtableColumnFamily, error) { b := &BigtableColumnFamily{ FamilyID: q.FamilyId, Encoding: q.Encoding, OnlyReadLatest: q.OnlyReadLatest, Type: q.Type, } for _, col := range q.Columns { c, err := bqToBigtableColumn(col) if err != nil { return nil, err } b.Columns = append(b.Columns, c) } return b, nil } // BigtableColumn describes how BigQuery should access a Bigtable column. type BigtableColumn struct { // Qualifier of the column. Columns in the parent column family that have this // exact qualifier are exposed as . field. The column field name is the // same as the column qualifier. Qualifier string // If the qualifier is not a valid BigQuery field identifier i.e. does not match // [a-zA-Z][a-zA-Z0-9_]*, a valid identifier must be provided as the column field // name and is used as field name in queries. FieldName string // If true, only the latest version of values are exposed for this column. // See BigtableColumnFamily.OnlyReadLatest. OnlyReadLatest bool // The encoding of the values when the type is not STRING. // See BigtableColumnFamily.Encoding Encoding string // The type to convert the value in cells of this column. // See BigtableColumnFamily.Type Type string } func (b *BigtableColumn) toBQ() *bq.BigtableColumn { q := &bq.BigtableColumn{ FieldName: b.FieldName, OnlyReadLatest: b.OnlyReadLatest, Encoding: b.Encoding, Type: b.Type, } if utf8.ValidString(b.Qualifier) { q.QualifierString = b.Qualifier } else { q.QualifierEncoded = base64.RawStdEncoding.EncodeToString([]byte(b.Qualifier)) } return q } func bqToBigtableColumn(q *bq.BigtableColumn) (*BigtableColumn, error) { b := &BigtableColumn{ FieldName: q.FieldName, OnlyReadLatest: q.OnlyReadLatest, Encoding: q.Encoding, Type: q.Type, } if q.QualifierString != "" { b.Qualifier = q.QualifierString } else { bytes, err := base64.RawStdEncoding.DecodeString(q.QualifierEncoded) if err != nil { return nil, err } b.Qualifier = string(bytes) } return b, nil } google-cloud-go-0.49.0/bigquery/external_test.go000066400000000000000000000073171356504100700216370ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "testing" "cloud.google.com/go/internal/pretty" "cloud.google.com/go/internal/testutil" ) func TestExternalDataConfig(t *testing.T) { // Round-trip of ExternalDataConfig to underlying representation. for i, want := range []*ExternalDataConfig{ { SourceFormat: CSV, SourceURIs: []string{"uri"}, Schema: Schema{{Name: "n", Type: IntegerFieldType}}, AutoDetect: true, Compression: Gzip, IgnoreUnknownValues: true, MaxBadRecords: 17, Options: &CSVOptions{ AllowJaggedRows: true, AllowQuotedNewlines: true, Encoding: UTF_8, FieldDelimiter: "f", Quote: "q", SkipLeadingRows: 3, }, }, { SourceFormat: GoogleSheets, Options: &GoogleSheetsOptions{ SkipLeadingRows: 4, Range: "sheet1!A1:Z10", }, }, { SourceFormat: Bigtable, Options: &BigtableOptions{ IgnoreUnspecifiedColumnFamilies: true, ReadRowkeyAsString: true, ColumnFamilies: []*BigtableColumnFamily{ { FamilyID: "f1", Encoding: "TEXT", OnlyReadLatest: true, Type: "FLOAT", Columns: []*BigtableColumn{ { Qualifier: "valid-utf-8", FieldName: "fn", OnlyReadLatest: true, Encoding: "BINARY", Type: "STRING", }, }, }, }, }, }, } { q := want.toBQ() got, err := bqToExternalDataConfig(&q) if err != nil { t.Fatal(err) } if diff := testutil.Diff(got, want); diff != "" { t.Errorf("#%d: got=-, want=+:\n%s", i, diff) } } } func TestQuote(t *testing.T) { ptr := func(s string) *string { return &s } for _, test := range []struct { quote string force bool want *string }{ {"", false, nil}, {"", true, ptr("")}, {"-", false, ptr("-")}, {"-", true, ptr("")}, } { o := CSVOptions{ Quote: test.quote, ForceZeroQuote: test.force, } got := o.quote() if (got == nil) != (test.want == nil) { t.Errorf("%+v\ngot %v\nwant %v", test, pretty.Value(got), pretty.Value(test.want)) } if got != nil && test.want != nil && *got != *test.want { t.Errorf("%+v: got %q, want %q", test, *got, *test.want) } } } func TestQualifier(t *testing.T) { b := BigtableColumn{Qualifier: "a"} q := b.toBQ() if q.QualifierString != b.Qualifier || q.QualifierEncoded != "" { t.Errorf("got (%q, %q), want (%q, %q)", q.QualifierString, q.QualifierEncoded, b.Qualifier, "") } b2, err := bqToBigtableColumn(q) if err != nil { t.Fatal(err) } if got, want := b2.Qualifier, b.Qualifier; got != want { t.Errorf("got %q, want %q", got, want) } const ( invalidUTF8 = "\xDF\xFF" invalidEncoded = "3/8" ) b = BigtableColumn{Qualifier: invalidUTF8} q = b.toBQ() if q.QualifierString != "" || q.QualifierEncoded != invalidEncoded { t.Errorf("got (%q, %q), want (%q, %q)", q.QualifierString, "", b.Qualifier, invalidEncoded) } b2, err = bqToBigtableColumn(q) if err != nil { t.Fatal(err) } if got, want := b2.Qualifier, b.Qualifier; got != want { t.Errorf("got %q, want %q", got, want) } } google-cloud-go-0.49.0/bigquery/extract.go000066400000000000000000000067241356504100700204310ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "context" "cloud.google.com/go/internal/trace" bq "google.golang.org/api/bigquery/v2" ) // ExtractConfig holds the configuration for an extract job. type ExtractConfig struct { // Src is the table from which data will be extracted. Src *Table // Dst is the destination into which the data will be extracted. Dst *GCSReference // DisableHeader disables the printing of a header row in exported data. DisableHeader bool // The labels associated with this job. Labels map[string]string // For Avro-based extracts, controls whether logical type annotations are generated. // // Example: With this enabled, writing a BigQuery TIMESTAMP column will result in // an integer column annotated with the appropriate timestamp-micros/millis annotation // in the resulting Avro files. UseAvroLogicalTypes bool } func (e *ExtractConfig) toBQ() *bq.JobConfiguration { var printHeader *bool if e.DisableHeader { f := false printHeader = &f } return &bq.JobConfiguration{ Labels: e.Labels, Extract: &bq.JobConfigurationExtract{ DestinationUris: append([]string{}, e.Dst.URIs...), Compression: string(e.Dst.Compression), DestinationFormat: string(e.Dst.DestinationFormat), FieldDelimiter: e.Dst.FieldDelimiter, SourceTable: e.Src.toBQ(), PrintHeader: printHeader, UseAvroLogicalTypes: e.UseAvroLogicalTypes, }, } } func bqToExtractConfig(q *bq.JobConfiguration, c *Client) *ExtractConfig { qe := q.Extract return &ExtractConfig{ Labels: q.Labels, Dst: &GCSReference{ URIs: qe.DestinationUris, Compression: Compression(qe.Compression), DestinationFormat: DataFormat(qe.DestinationFormat), FileConfig: FileConfig{ CSVOptions: CSVOptions{ FieldDelimiter: qe.FieldDelimiter, }, }, }, DisableHeader: qe.PrintHeader != nil && !*qe.PrintHeader, Src: bqToTable(qe.SourceTable, c), UseAvroLogicalTypes: qe.UseAvroLogicalTypes, } } // An Extractor extracts data from a BigQuery table into Google Cloud Storage. type Extractor struct { JobIDConfig ExtractConfig c *Client } // ExtractorTo returns an Extractor which can be used to extract data from a // BigQuery table into Google Cloud Storage. // The returned Extractor may optionally be further configured before its Run method is called. func (t *Table) ExtractorTo(dst *GCSReference) *Extractor { return &Extractor{ c: t.c, ExtractConfig: ExtractConfig{ Src: t, Dst: dst, }, } } // Run initiates an extract job. func (e *Extractor) Run(ctx context.Context) (j *Job, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Extractor.Run") defer func() { trace.EndSpan(ctx, err) }() return e.c.insertJob(ctx, e.newJob(), nil) } func (e *Extractor) newJob() *bq.Job { return &bq.Job{ JobReference: e.JobIDConfig.createJobRef(e.c), Configuration: e.ExtractConfig.toBQ(), } } google-cloud-go-0.49.0/bigquery/extract_test.go000066400000000000000000000064131356504100700214630ustar00rootroot00000000000000// Copyright 2015 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "testing" "cloud.google.com/go/internal/testutil" "github.com/google/go-cmp/cmp" bq "google.golang.org/api/bigquery/v2" ) func defaultExtractJob() *bq.Job { return &bq.Job{ JobReference: &bq.JobReference{JobId: "RANDOM", ProjectId: "client-project-id"}, Configuration: &bq.JobConfiguration{ Extract: &bq.JobConfigurationExtract{ SourceTable: &bq.TableReference{ ProjectId: "client-project-id", DatasetId: "dataset-id", TableId: "table-id", }, DestinationUris: []string{"uri"}, }, }, } } func defaultGCS() *GCSReference { return &GCSReference{ URIs: []string{"uri"}, } } func TestExtract(t *testing.T) { defer fixRandomID("RANDOM")() c := &Client{ projectID: "client-project-id", } testCases := []struct { dst *GCSReference src *Table config ExtractConfig want *bq.Job }{ { dst: defaultGCS(), src: c.Dataset("dataset-id").Table("table-id"), want: defaultExtractJob(), }, { dst: defaultGCS(), src: c.Dataset("dataset-id").Table("table-id"), config: ExtractConfig{ DisableHeader: true, Labels: map[string]string{"a": "b"}, }, want: func() *bq.Job { j := defaultExtractJob() j.Configuration.Labels = map[string]string{"a": "b"} f := false j.Configuration.Extract.PrintHeader = &f return j }(), }, { dst: func() *GCSReference { g := NewGCSReference("uri") g.Compression = Gzip g.DestinationFormat = JSON g.FieldDelimiter = "\t" return g }(), src: c.Dataset("dataset-id").Table("table-id"), want: func() *bq.Job { j := defaultExtractJob() j.Configuration.Extract.Compression = "GZIP" j.Configuration.Extract.DestinationFormat = "NEWLINE_DELIMITED_JSON" j.Configuration.Extract.FieldDelimiter = "\t" return j }(), }, { dst: func() *GCSReference { g := NewGCSReference("uri") g.DestinationFormat = Avro return g }(), src: c.Dataset("dataset-id").Table("table-id"), config: ExtractConfig{ UseAvroLogicalTypes: true, }, want: func() *bq.Job { j := defaultExtractJob() j.Configuration.Extract.UseAvroLogicalTypes = true j.Configuration.Extract.DestinationFormat = "AVRO" return j }(), }, } for i, tc := range testCases { ext := tc.src.ExtractorTo(tc.dst) tc.config.Src = ext.Src tc.config.Dst = ext.Dst ext.ExtractConfig = tc.config got := ext.newJob() checkJob(t, i, got, tc.want) jc, err := bqToJobConfig(got.Configuration, c) if err != nil { t.Fatalf("#%d: %v", i, err) } diff := testutil.Diff(jc, &ext.ExtractConfig, cmp.AllowUnexported(Table{}, Client{})) if diff != "" { t.Errorf("#%d: (got=-, want=+:\n%s", i, diff) } } } google-cloud-go-0.49.0/bigquery/file.go000066400000000000000000000112611356504100700176660ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "io" bq "google.golang.org/api/bigquery/v2" ) // A ReaderSource is a source for a load operation that gets // data from an io.Reader. // // When a ReaderSource is part of a LoadConfig obtained via Job.Config, // its internal io.Reader will be nil, so it cannot be used for a // subsequent load operation. type ReaderSource struct { r io.Reader FileConfig } // NewReaderSource creates a ReaderSource from an io.Reader. You may // optionally configure properties on the ReaderSource that describe the // data being read, before passing it to Table.LoaderFrom. func NewReaderSource(r io.Reader) *ReaderSource { return &ReaderSource{r: r} } func (r *ReaderSource) populateLoadConfig(lc *bq.JobConfigurationLoad) io.Reader { r.FileConfig.populateLoadConfig(lc) return r.r } // FileConfig contains configuration options that pertain to files, typically // text files that require interpretation to be used as a BigQuery table. A // file may live in Google Cloud Storage (see GCSReference), or it may be // loaded into a table via the Table.LoaderFromReader. type FileConfig struct { // SourceFormat is the format of the data to be read. // Allowed values are: Avro, CSV, DatastoreBackup, JSON, ORC, and Parquet. The default is CSV. SourceFormat DataFormat // Indicates if we should automatically infer the options and // schema for CSV and JSON sources. AutoDetect bool // MaxBadRecords is the maximum number of bad records that will be ignored // when reading data. MaxBadRecords int64 // IgnoreUnknownValues causes values not matching the schema to be // tolerated. Unknown values are ignored. For CSV this ignores extra values // at the end of a line. For JSON this ignores named values that do not // match any column name. If this field is not set, records containing // unknown values are treated as bad records. The MaxBadRecords field can // be used to customize how bad records are handled. IgnoreUnknownValues bool // Schema describes the data. It is required when reading CSV or JSON data, // unless the data is being loaded into a table that already exists. Schema Schema // Additional options for CSV files. CSVOptions } func (fc *FileConfig) populateLoadConfig(conf *bq.JobConfigurationLoad) { conf.SkipLeadingRows = fc.SkipLeadingRows conf.SourceFormat = string(fc.SourceFormat) conf.Autodetect = fc.AutoDetect conf.AllowJaggedRows = fc.AllowJaggedRows conf.AllowQuotedNewlines = fc.AllowQuotedNewlines conf.Encoding = string(fc.Encoding) conf.FieldDelimiter = fc.FieldDelimiter conf.IgnoreUnknownValues = fc.IgnoreUnknownValues conf.MaxBadRecords = fc.MaxBadRecords if fc.Schema != nil { conf.Schema = fc.Schema.toBQ() } conf.Quote = fc.quote() } func bqPopulateFileConfig(conf *bq.JobConfigurationLoad, fc *FileConfig) { fc.SourceFormat = DataFormat(conf.SourceFormat) fc.AutoDetect = conf.Autodetect fc.MaxBadRecords = conf.MaxBadRecords fc.IgnoreUnknownValues = conf.IgnoreUnknownValues fc.Schema = bqToSchema(conf.Schema) fc.SkipLeadingRows = conf.SkipLeadingRows fc.AllowJaggedRows = conf.AllowJaggedRows fc.AllowQuotedNewlines = conf.AllowQuotedNewlines fc.Encoding = Encoding(conf.Encoding) fc.FieldDelimiter = conf.FieldDelimiter fc.CSVOptions.setQuote(conf.Quote) } func (fc *FileConfig) populateExternalDataConfig(conf *bq.ExternalDataConfiguration) { format := fc.SourceFormat if format == "" { // Format must be explicitly set for external data sources. format = CSV } conf.Autodetect = fc.AutoDetect conf.IgnoreUnknownValues = fc.IgnoreUnknownValues conf.MaxBadRecords = fc.MaxBadRecords conf.SourceFormat = string(format) if fc.Schema != nil { conf.Schema = fc.Schema.toBQ() } if format == CSV { fc.CSVOptions.populateExternalDataConfig(conf) } } // Encoding specifies the character encoding of data to be loaded into BigQuery. // See https://cloud.google.com/bigquery/docs/reference/v2/jobs#configuration.load.encoding // for more details about how this is used. type Encoding string const ( // UTF_8 specifies the UTF-8 encoding type. UTF_8 Encoding = "UTF-8" // ISO_8859_1 specifies the ISO-8859-1 encoding type. ISO_8859_1 Encoding = "ISO-8859-1" ) google-cloud-go-0.49.0/bigquery/file_test.go000066400000000000000000000050401356504100700207230ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "testing" "cloud.google.com/go/internal/pretty" "cloud.google.com/go/internal/testutil" bq "google.golang.org/api/bigquery/v2" ) var ( hyphen = "-" fc = FileConfig{ SourceFormat: CSV, AutoDetect: true, MaxBadRecords: 7, IgnoreUnknownValues: true, Schema: Schema{ stringFieldSchema(), nestedFieldSchema(), }, CSVOptions: CSVOptions{ Quote: hyphen, FieldDelimiter: "\t", SkipLeadingRows: 8, AllowJaggedRows: true, AllowQuotedNewlines: true, Encoding: UTF_8, }, } ) func TestFileConfigPopulateLoadConfig(t *testing.T) { want := &bq.JobConfigurationLoad{ SourceFormat: "CSV", FieldDelimiter: "\t", SkipLeadingRows: 8, AllowJaggedRows: true, AllowQuotedNewlines: true, Autodetect: true, Encoding: "UTF-8", MaxBadRecords: 7, IgnoreUnknownValues: true, Schema: &bq.TableSchema{ Fields: []*bq.TableFieldSchema{ bqStringFieldSchema(), bqNestedFieldSchema(), }}, Quote: &hyphen, } got := &bq.JobConfigurationLoad{} fc.populateLoadConfig(got) if !testutil.Equal(got, want) { t.Errorf("got:\n%v\nwant:\n%v", pretty.Value(got), pretty.Value(want)) } } func TestFileConfigPopulateExternalDataConfig(t *testing.T) { got := &bq.ExternalDataConfiguration{} fc.populateExternalDataConfig(got) want := &bq.ExternalDataConfiguration{ SourceFormat: "CSV", Autodetect: true, MaxBadRecords: 7, IgnoreUnknownValues: true, Schema: &bq.TableSchema{ Fields: []*bq.TableFieldSchema{ bqStringFieldSchema(), bqNestedFieldSchema(), }}, CsvOptions: &bq.CsvOptions{ AllowJaggedRows: true, AllowQuotedNewlines: true, Encoding: "UTF-8", FieldDelimiter: "\t", Quote: &hyphen, SkipLeadingRows: 8, }, } if diff := testutil.Diff(got, want); diff != "" { t.Errorf("got=-, want=+:\n%s", diff) } } google-cloud-go-0.49.0/bigquery/gcs.go000066400000000000000000000053301356504100700175230ustar00rootroot00000000000000// Copyright 2015 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "io" bq "google.golang.org/api/bigquery/v2" ) // GCSReference is a reference to one or more Google Cloud Storage objects, which together constitute // an input or output to a BigQuery operation. type GCSReference struct { // URIs refer to Google Cloud Storage objects. URIs []string FileConfig // DestinationFormat is the format to use when writing exported files. // Allowed values are: CSV, Avro, JSON. The default is CSV. // CSV is not supported for tables with nested or repeated fields. DestinationFormat DataFormat // Compression specifies the type of compression to apply when writing data // to Google Cloud Storage, or using this GCSReference as an ExternalData // source with CSV or JSON SourceFormat. Default is None. Compression Compression } // NewGCSReference constructs a reference to one or more Google Cloud Storage objects, which together constitute a data source or destination. // In the simple case, a single URI in the form gs://bucket/object may refer to a single GCS object. // Data may also be split into mutiple files, if multiple URIs or URIs containing wildcards are provided. // Each URI may contain one '*' wildcard character, which (if present) must come after the bucket name. // For more information about the treatment of wildcards and multiple URIs, // see https://cloud.google.com/bigquery/exporting-data-from-bigquery#exportingmultiple func NewGCSReference(uri ...string) *GCSReference { return &GCSReference{URIs: uri} } // Compression is the type of compression to apply when writing data to Google Cloud Storage. type Compression string const ( // None specifies no compression. None Compression = "NONE" // Gzip specifies gzip compression. Gzip Compression = "GZIP" ) func (gcs *GCSReference) populateLoadConfig(lc *bq.JobConfigurationLoad) io.Reader { lc.SourceUris = gcs.URIs gcs.FileConfig.populateLoadConfig(lc) return nil } func (gcs *GCSReference) toBQ() bq.ExternalDataConfiguration { conf := bq.ExternalDataConfiguration{ Compression: string(gcs.Compression), SourceUris: append([]string{}, gcs.URIs...), } gcs.FileConfig.populateExternalDataConfig(&conf) return conf } google-cloud-go-0.49.0/bigquery/go.mod000066400000000000000000000010531356504100700175240ustar00rootroot00000000000000module cloud.google.com/go/bigquery go 1.11 require ( cloud.google.com/go v0.46.3 cloud.google.com/go/storage v1.0.0 github.com/golang/protobuf v1.3.2 github.com/google/go-cmp v0.3.0 github.com/googleapis/gax-go/v2 v2.0.5 golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136 // indirect golang.org/x/lint v0.0.0-20190930215403-16217165b5de // indirect golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2 // indirect google.golang.org/api v0.14.0 google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9 google.golang.org/grpc v1.21.1 ) google-cloud-go-0.49.0/bigquery/go.sum000066400000000000000000000420721356504100700175570ustar00rootroot00000000000000cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2 h1:yH/xNMI6CEel8IuF+gaXLvg2N1JZ6pOMkkr25uH8+2k= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3 h1:AVXDdKsrtX33oR9fbCMu/+c1o8Ofjq6Ku/MInaLVg5Y= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/datastore v1.0.0 h1:Kt+gOPPp2LEPWp8CSfxhsM8ik9CcyE/gYu+0r+RnZvM= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/pubsub v1.0.1 h1:W9tAK3E57P75u0XLLR82LZyw8VpAnhmyTOxW9qzmyj8= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/storage v1.0.0 h1:VV2nUM3wwLLGh9lSABFgZMjInyUbJeaRSE64WuAIQ+4= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024 h1:rBMNdlhTLzJjJSDIjNEXX1Pz3Hmwmz91v+zycvx9PJc= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522 h1:OeRHuibLsmZkFj773W4LcfAGsSxJgfPONhr8cmO+eLA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979 h1:Agxu5KLo8o7Bb634SVDnhIfpTvxmzUwhbYAzBvXt6h4= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136 h1:A1gGSx58LAGVHUUsOf7IiR0u8Xb6W51gRwfDBhkdcaw= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422 h1:QzoH/1pFpZguR8NrRHLcO6jKqfv2zpuSqZLgdm7ZmjI= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac h1:8R1esu+8QioDxo4E4mX6bFztO+dMTM49DNAaWfO5OeY= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0 h1:HyfiK1WMnHj5FXFXatD+Qs1A/xC2Run6RzeW1SyHxpc= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0 h1:Dh6fw+p6FyRl5x/FvNswO1ji0lIGzm3KP8Y9VkS9PTE= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff h1:On1qIo75ByTwFJ4/W2bIqHcwJ9XAqtSWUs8GwRrIhtc= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2 h1:EtTFh6h4SAKemS+CURDMTDIANuduG5zKEXShyy18bGA= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0 h1:VGGbLNyPF7dvYHhcUGYBBGCRDDK0RRJAI6KCvo0CL+E= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.14.0 h1:uMf5uLi4eQMRrMKhCplNik4U4H8Z6C1br3zOtAa/aDE= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64 h1:iKtrH9Y8mcbADOP0YFaEMth7OfuHY9xHOwNj4znpM1A= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51 h1:Ex1mq5jaJof+kRnYi3SlYJ8KKa9Ao3NHyIT5XJ1gF6U= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9 h1:6XzpBoANz1NqMNfDXzc2QmHmbb1vyMsvRfoP5rM+K1I= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1 h1:j6XxA85m/6txkUCHvzlV5f+HBNl/1r5cZ2A/3IEFOO8= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a h1:LJwr7TCTghdatWv40WobzlKXc9c4s8oGa7QKJUtHhWA= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= google-cloud-go-0.49.0/bigquery/go_mod_tidy_hack.go000066400000000000000000000016271356504100700222370ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // This file, and the cloud.google.com/go import, won't actually become part of // the resultant binary. // +build modhack package bigquery // Necessary for safely adding multi-module repo. See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository import _ "cloud.google.com/go" google-cloud-go-0.49.0/bigquery/inserter.go000066400000000000000000000166521356504100700206130ustar00rootroot00000000000000// Copyright 2015 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "context" "errors" "fmt" "reflect" "cloud.google.com/go/internal/trace" bq "google.golang.org/api/bigquery/v2" ) // NoDedupeID indicates a streaming insert row wants to opt out of best-effort // deduplication. // It is EXPERIMENTAL and subject to change or removal without notice. const NoDedupeID = "NoDedupeID" // An Inserter does streaming inserts into a BigQuery table. // It is safe for concurrent use. type Inserter struct { t *Table // SkipInvalidRows causes rows containing invalid data to be silently // ignored. The default value is false, which causes the entire request to // fail if there is an attempt to insert an invalid row. SkipInvalidRows bool // IgnoreUnknownValues causes values not matching the schema to be ignored. // The default value is false, which causes records containing such values // to be treated as invalid records. IgnoreUnknownValues bool // A TableTemplateSuffix allows Inserters to create tables automatically. // // Experimental: this option is experimental and may be modified or removed in future versions, // regardless of any other documented package stability guarantees. In general, // the BigQuery team recommends the use of partitioned tables over sharding // tables by suffix. // // When you specify a suffix, the table you upload data to // will be used as a template for creating a new table, with the same schema, // called + . // // More information is available at // https://cloud.google.com/bigquery/streaming-data-into-bigquery#template-tables TableTemplateSuffix string } // Inserter returns an Inserter that can be used to append rows to t. // The returned Inserter may optionally be further configured before its Put method is called. // // To stream rows into a date-partitioned table at a particular date, add the // $yyyymmdd suffix to the table name when constructing the Table. func (t *Table) Inserter() *Inserter { return &Inserter{t: t} } // Uploader calls Inserter. // Deprecated: use Table.Inserter instead. func (t *Table) Uploader() *Inserter { return t.Inserter() } // Put uploads one or more rows to the BigQuery service. // // If src is ValueSaver, then its Save method is called to produce a row for uploading. // // If src is a struct or pointer to a struct, then a schema is inferred from it // and used to create a StructSaver. The InsertID of the StructSaver will be // empty. // // If src is a slice of ValueSavers, structs, or struct pointers, then each // element of the slice is treated as above, and multiple rows are uploaded. // // Put returns a PutMultiError if one or more rows failed to be uploaded. // The PutMultiError contains a RowInsertionError for each failed row. // // Put will retry on temporary errors (see // https://cloud.google.com/bigquery/troubleshooting-errors). This can result // in duplicate rows if you do not use insert IDs. Also, if the error persists, // the call will run indefinitely. Pass a context with a timeout to prevent // hanging calls. func (u *Inserter) Put(ctx context.Context, src interface{}) (err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Inserter.Put") defer func() { trace.EndSpan(ctx, err) }() savers, err := valueSavers(src) if err != nil { return err } return u.putMulti(ctx, savers) } func valueSavers(src interface{}) ([]ValueSaver, error) { saver, ok, err := toValueSaver(src) if err != nil { return nil, err } if ok { return []ValueSaver{saver}, nil } srcVal := reflect.ValueOf(src) if srcVal.Kind() != reflect.Slice { return nil, fmt.Errorf("%T is not a ValueSaver, struct, struct pointer, or slice", src) } var savers []ValueSaver for i := 0; i < srcVal.Len(); i++ { s := srcVal.Index(i).Interface() saver, ok, err := toValueSaver(s) if err != nil { return nil, err } if !ok { return nil, fmt.Errorf("src[%d] has type %T, which is not a ValueSaver, struct or struct pointer", i, s) } savers = append(savers, saver) } return savers, nil } // Make a ValueSaver from x, which must implement ValueSaver already // or be a struct or pointer to struct. func toValueSaver(x interface{}) (ValueSaver, bool, error) { if _, ok := x.(StructSaver); ok { return nil, false, errors.New("bigquery: use &StructSaver, not StructSaver") } var insertID string // Handle StructSavers specially so we can infer the schema if necessary. if ss, ok := x.(*StructSaver); ok && ss.Schema == nil { x = ss.Struct insertID = ss.InsertID // Fall through so we can infer the schema. } if saver, ok := x.(ValueSaver); ok { return saver, ok, nil } v := reflect.ValueOf(x) // Support Put with []interface{} if v.Kind() == reflect.Interface { v = v.Elem() } if v.Kind() == reflect.Ptr { v = v.Elem() } if v.Kind() != reflect.Struct { return nil, false, nil } schema, err := inferSchemaReflectCached(v.Type()) if err != nil { return nil, false, err } return &StructSaver{ Struct: x, InsertID: insertID, Schema: schema, }, true, nil } func (u *Inserter) putMulti(ctx context.Context, src []ValueSaver) error { req, err := u.newInsertRequest(src) if err != nil { return err } if req == nil { return nil } call := u.t.c.bqs.Tabledata.InsertAll(u.t.ProjectID, u.t.DatasetID, u.t.TableID, req) call = call.Context(ctx) setClientHeader(call.Header()) var res *bq.TableDataInsertAllResponse err = runWithRetry(ctx, func() (err error) { res, err = call.Do() return err }) if err != nil { return err } return handleInsertErrors(res.InsertErrors, req.Rows) } func (u *Inserter) newInsertRequest(savers []ValueSaver) (*bq.TableDataInsertAllRequest, error) { if savers == nil { // If there are no rows, do nothing. return nil, nil } req := &bq.TableDataInsertAllRequest{ TemplateSuffix: u.TableTemplateSuffix, IgnoreUnknownValues: u.IgnoreUnknownValues, SkipInvalidRows: u.SkipInvalidRows, } for _, saver := range savers { row, insertID, err := saver.Save() if err != nil { return nil, err } if insertID == NoDedupeID { insertID = "" } else if insertID == "" { insertID = randomIDFn() } m := make(map[string]bq.JsonValue) for k, v := range row { m[k] = bq.JsonValue(v) } req.Rows = append(req.Rows, &bq.TableDataInsertAllRequestRows{ InsertId: insertID, Json: m, }) } return req, nil } func handleInsertErrors(ierrs []*bq.TableDataInsertAllResponseInsertErrors, rows []*bq.TableDataInsertAllRequestRows) error { if len(ierrs) == 0 { return nil } var errs PutMultiError for _, e := range ierrs { if int(e.Index) > len(rows) { return fmt.Errorf("internal error: unexpected row index: %v", e.Index) } rie := RowInsertionError{ InsertID: rows[e.Index].InsertId, RowIndex: int(e.Index), } for _, errp := range e.Errors { rie.Errors = append(rie.Errors, bqToError(errp)) } errs = append(errs, rie) } return errs } // Uploader is an obsolete name for Inserter. type Uploader = Inserter google-cloud-go-0.49.0/bigquery/inserter_test.go000066400000000000000000000131161356504100700216420ustar00rootroot00000000000000// Copyright 2015 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "errors" "strconv" "testing" "cloud.google.com/go/internal/pretty" "cloud.google.com/go/internal/testutil" "github.com/google/go-cmp/cmp" bq "google.golang.org/api/bigquery/v2" ) type testSaver struct { row map[string]Value insertID string err error } func (ts testSaver) Save() (map[string]Value, string, error) { return ts.row, ts.insertID, ts.err } func TestNewInsertRequest(t *testing.T) { prev := randomIDFn n := 0 randomIDFn = func() string { n++; return strconv.Itoa(n) } defer func() { randomIDFn = prev }() tests := []struct { ul *Uploader savers []ValueSaver req *bq.TableDataInsertAllRequest }{ { ul: &Uploader{}, savers: nil, req: nil, }, { ul: &Uploader{}, savers: []ValueSaver{ testSaver{row: map[string]Value{"one": 1}}, testSaver{row: map[string]Value{"two": 2}}, testSaver{insertID: NoDedupeID, row: map[string]Value{"three": 3}}, }, req: &bq.TableDataInsertAllRequest{ Rows: []*bq.TableDataInsertAllRequestRows{ {InsertId: "1", Json: map[string]bq.JsonValue{"one": 1}}, {InsertId: "2", Json: map[string]bq.JsonValue{"two": 2}}, {InsertId: "", Json: map[string]bq.JsonValue{"three": 3}}, }, }, }, { ul: &Uploader{ TableTemplateSuffix: "suffix", IgnoreUnknownValues: true, SkipInvalidRows: true, }, savers: []ValueSaver{ testSaver{insertID: "a", row: map[string]Value{"one": 1}}, testSaver{insertID: "", row: map[string]Value{"two": 2}}, }, req: &bq.TableDataInsertAllRequest{ Rows: []*bq.TableDataInsertAllRequestRows{ {InsertId: "a", Json: map[string]bq.JsonValue{"one": 1}}, {InsertId: "3", Json: map[string]bq.JsonValue{"two": 2}}, }, TemplateSuffix: "suffix", SkipInvalidRows: true, IgnoreUnknownValues: true, }, }, } for i, tc := range tests { got, err := tc.ul.newInsertRequest(tc.savers) if err != nil { t.Fatal(err) } want := tc.req if !testutil.Equal(got, want) { t.Errorf("%d: %#v: got %#v, want %#v", i, tc.ul, got, want) } } } func TestNewInsertRequestErrors(t *testing.T) { var u Uploader _, err := u.newInsertRequest([]ValueSaver{testSaver{err: errors.New("bang")}}) if err == nil { t.Error("got nil, want error") } } func TestHandleInsertErrors(t *testing.T) { rows := []*bq.TableDataInsertAllRequestRows{ {InsertId: "a"}, {InsertId: "b"}, } for _, test := range []struct { in []*bq.TableDataInsertAllResponseInsertErrors want error }{ { in: nil, want: nil, }, { in: []*bq.TableDataInsertAllResponseInsertErrors{{Index: 1}}, want: PutMultiError{RowInsertionError{InsertID: "b", RowIndex: 1}}, }, { in: []*bq.TableDataInsertAllResponseInsertErrors{{Index: 1}}, want: PutMultiError{RowInsertionError{InsertID: "b", RowIndex: 1}}, }, { in: []*bq.TableDataInsertAllResponseInsertErrors{ {Errors: []*bq.ErrorProto{{Message: "m0"}}, Index: 0}, {Errors: []*bq.ErrorProto{{Message: "m1"}}, Index: 1}, }, want: PutMultiError{ RowInsertionError{InsertID: "a", RowIndex: 0, Errors: []error{&Error{Message: "m0"}}}, RowInsertionError{InsertID: "b", RowIndex: 1, Errors: []error{&Error{Message: "m1"}}}, }, }, } { got := handleInsertErrors(test.in, rows) if !testutil.Equal(got, test.want) { t.Errorf("%#v:\ngot\n%#v\nwant\n%#v", test.in, got, test.want) } } } func TestValueSavers(t *testing.T) { ts := &testSaver{} type T struct{ I int } schema, err := InferSchema(T{}) if err != nil { t.Fatal(err) } for _, test := range []struct { in interface{} want []ValueSaver }{ {[]interface{}(nil), nil}, {[]interface{}{}, nil}, {ts, []ValueSaver{ts}}, {T{I: 1}, []ValueSaver{&StructSaver{Schema: schema, Struct: T{I: 1}}}}, {[]ValueSaver{ts, ts}, []ValueSaver{ts, ts}}, {[]interface{}{ts, ts}, []ValueSaver{ts, ts}}, {[]T{{I: 1}, {I: 2}}, []ValueSaver{ &StructSaver{Schema: schema, Struct: T{I: 1}}, &StructSaver{Schema: schema, Struct: T{I: 2}}, }}, {[]interface{}{T{I: 1}, &T{I: 2}}, []ValueSaver{ &StructSaver{Schema: schema, Struct: T{I: 1}}, &StructSaver{Schema: schema, Struct: &T{I: 2}}, }}, {&StructSaver{Struct: T{I: 3}, InsertID: "foo"}, []ValueSaver{ &StructSaver{Schema: schema, Struct: T{I: 3}, InsertID: "foo"}, }}, } { got, err := valueSavers(test.in) if err != nil { t.Fatal(err) } if !testutil.Equal(got, test.want, cmp.AllowUnexported(testSaver{})) { t.Errorf("%+v: got %v, want %v", test.in, pretty.Value(got), pretty.Value(test.want)) } // Make sure Save is successful. for i, vs := range got { _, _, err := vs.Save() if err != nil { t.Fatalf("%+v, #%d: got error %v, want nil", test.in, i, err) } } } } func TestValueSaversErrors(t *testing.T) { inputs := []interface{}{ nil, 1, []int{1, 2}, []interface{}{ testSaver{row: map[string]Value{"one": 1}, insertID: "a"}, 1, }, StructSaver{}, } for _, in := range inputs { if _, err := valueSavers(in); err == nil { t.Errorf("%#v: got nil, want error", in) } } } google-cloud-go-0.49.0/bigquery/integration_test.go000066400000000000000000002145011356504100700223330ustar00rootroot00000000000000// Copyright 2015 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "context" "encoding/json" "errors" "flag" "fmt" "log" "math/big" "net/http" "os" "sort" "strings" "testing" "time" "cloud.google.com/go/civil" "cloud.google.com/go/httpreplay" "cloud.google.com/go/internal" "cloud.google.com/go/internal/pretty" "cloud.google.com/go/internal/testutil" "cloud.google.com/go/internal/uid" "cloud.google.com/go/storage" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/googleapi" "google.golang.org/api/iterator" "google.golang.org/api/option" ) const replayFilename = "bigquery.replay" var record = flag.Bool("record", false, "record RPCs") var ( client *Client storageClient *storage.Client dataset *Dataset schema = Schema{ {Name: "name", Type: StringFieldType}, {Name: "nums", Type: IntegerFieldType, Repeated: true}, {Name: "rec", Type: RecordFieldType, Schema: Schema{ {Name: "bool", Type: BooleanFieldType}, }}, } testTableExpiration time.Time datasetIDs, tableIDs, modelIDs, routineIDs *uid.Space ) // Note: integration tests cannot be run in parallel, because TestIntegration_Location // modifies the client. func TestMain(m *testing.M) { cleanup := initIntegrationTest() r := m.Run() cleanup() os.Exit(r) } func getClient(t *testing.T) *Client { if client == nil { t.Skip("Integration tests skipped") } return client } var grpcHeadersChecker = testutil.DefaultHeadersEnforcer() // If integration tests will be run, create a unique dataset for them. // Return a cleanup function. func initIntegrationTest() func() { ctx := context.Background() flag.Parse() // needed for testing.Short() projID := testutil.ProjID() switch { case testing.Short() && *record: log.Fatal("cannot combine -short and -record") return func() {} case testing.Short() && httpreplay.Supported() && testutil.CanReplay(replayFilename) && projID != "": // go test -short with a replay file will replay the integration tests if the // environment variables are set. log.Printf("replaying from %s", replayFilename) httpreplay.DebugHeaders() replayer, err := httpreplay.NewReplayer(replayFilename) if err != nil { log.Fatal(err) } var t time.Time if err := json.Unmarshal(replayer.Initial(), &t); err != nil { log.Fatal(err) } hc, err := replayer.Client(ctx) // no creds needed if err != nil { log.Fatal(err) } client, err = NewClient(ctx, projID, option.WithHTTPClient(hc)) if err != nil { log.Fatal(err) } storageClient, err = storage.NewClient(ctx, option.WithHTTPClient(hc)) if err != nil { log.Fatal(err) } cleanup := initTestState(client, t) return func() { cleanup() _ = replayer.Close() // No actionable error returned. } case testing.Short(): // go test -short without a replay file skips the integration tests. if testutil.CanReplay(replayFilename) && projID != "" { log.Print("replay not supported for Go versions before 1.8") } client = nil storageClient = nil return func() {} default: // Run integration tests against a real backend. ts := testutil.TokenSource(ctx, Scope) if ts == nil { log.Println("Integration tests skipped. See CONTRIBUTING.md for details") return func() {} } bqOpts := []option.ClientOption{option.WithTokenSource(ts)} sOpts := []option.ClientOption{option.WithTokenSource(testutil.TokenSource(ctx, storage.ScopeFullControl))} cleanup := func() {} now := time.Now().UTC() if *record { if !httpreplay.Supported() { log.Print("record not supported for Go versions before 1.8") } else { nowBytes, err := json.Marshal(now) if err != nil { log.Fatal(err) } recorder, err := httpreplay.NewRecorder(replayFilename, nowBytes) if err != nil { log.Fatalf("could not record: %v", err) } log.Printf("recording to %s", replayFilename) hc, err := recorder.Client(ctx, bqOpts...) if err != nil { log.Fatal(err) } bqOpts = append(bqOpts, option.WithHTTPClient(hc)) hc, err = recorder.Client(ctx, sOpts...) if err != nil { log.Fatal(err) } sOpts = append(sOpts, option.WithHTTPClient(hc)) cleanup = func() { if err := recorder.Close(); err != nil { log.Printf("saving recording: %v", err) } } } } else { // When we're not recording, do http header checking. // We can't check universally because option.WithHTTPClient is // incompatible with gRPC options. bqOpts = append(bqOpts, grpcHeadersChecker.CallOptions()...) sOpts = append(sOpts, grpcHeadersChecker.CallOptions()...) } var err error client, err = NewClient(ctx, projID, bqOpts...) if err != nil { log.Fatalf("NewClient: %v", err) } storageClient, err = storage.NewClient(ctx, sOpts...) if err != nil { log.Fatalf("storage.NewClient: %v", err) } c := initTestState(client, now) return func() { c(); cleanup() } } } func initTestState(client *Client, t time.Time) func() { // BigQuery does not accept hyphens in dataset or table IDs, so we create IDs // with underscores. ctx := context.Background() opts := &uid.Options{Sep: '_', Time: t} datasetIDs = uid.NewSpace("dataset", opts) tableIDs = uid.NewSpace("table", opts) modelIDs = uid.NewSpace("model", opts) routineIDs = uid.NewSpace("routine", opts) testTableExpiration = t.Add(10 * time.Minute).Round(time.Second) // For replayability, seed the random source with t. Seed(t.UnixNano()) dataset = client.Dataset(datasetIDs.New()) if err := dataset.Create(ctx, nil); err != nil { log.Fatalf("creating dataset %s: %v", dataset.DatasetID, err) } return func() { if err := dataset.DeleteWithContents(ctx); err != nil { log.Printf("could not delete %s", dataset.DatasetID) } } } func TestIntegration_TableCreate(t *testing.T) { // Check that creating a record field with an empty schema is an error. if client == nil { t.Skip("Integration tests skipped") } table := dataset.Table("t_bad") schema := Schema{ {Name: "rec", Type: RecordFieldType, Schema: Schema{}}, } err := table.Create(context.Background(), &TableMetadata{ Schema: schema, ExpirationTime: testTableExpiration.Add(5 * time.Minute), }) if err == nil { t.Fatal("want error, got nil") } if !hasStatusCode(err, http.StatusBadRequest) { t.Fatalf("want a 400 error, got %v", err) } } func TestIntegration_TableCreateView(t *testing.T) { if client == nil { t.Skip("Integration tests skipped") } ctx := context.Background() table := newTable(t, schema) defer table.Delete(ctx) // Test that standard SQL views work. view := dataset.Table("t_view_standardsql") query := fmt.Sprintf("SELECT APPROX_COUNT_DISTINCT(name) FROM `%s.%s.%s`", dataset.ProjectID, dataset.DatasetID, table.TableID) err := view.Create(context.Background(), &TableMetadata{ ViewQuery: query, UseStandardSQL: true, }) if err != nil { t.Fatalf("table.create: Did not expect an error, got: %v", err) } if err := view.Delete(ctx); err != nil { t.Fatal(err) } } func TestIntegration_TableMetadata(t *testing.T) { if client == nil { t.Skip("Integration tests skipped") } ctx := context.Background() table := newTable(t, schema) defer table.Delete(ctx) // Check table metadata. md, err := table.Metadata(ctx) if err != nil { t.Fatal(err) } // TODO(jba): check md more thorougly. if got, want := md.FullID, fmt.Sprintf("%s:%s.%s", dataset.ProjectID, dataset.DatasetID, table.TableID); got != want { t.Errorf("metadata.FullID: got %q, want %q", got, want) } if got, want := md.Type, RegularTable; got != want { t.Errorf("metadata.Type: got %v, want %v", got, want) } if got, want := md.ExpirationTime, testTableExpiration; !got.Equal(want) { t.Errorf("metadata.Type: got %v, want %v", got, want) } // Check that timePartitioning is nil by default if md.TimePartitioning != nil { t.Errorf("metadata.TimePartitioning: got %v, want %v", md.TimePartitioning, nil) } // Create tables that have time partitioning partitionCases := []struct { timePartitioning TimePartitioning wantExpiration time.Duration wantField string wantPruneFilter bool }{ {TimePartitioning{}, time.Duration(0), "", false}, {TimePartitioning{Expiration: time.Second}, time.Second, "", false}, {TimePartitioning{RequirePartitionFilter: true}, time.Duration(0), "", true}, { TimePartitioning{ Expiration: time.Second, Field: "date", RequirePartitionFilter: true, }, time.Second, "date", true}, } schema2 := Schema{ {Name: "name", Type: StringFieldType}, {Name: "date", Type: DateFieldType}, } clustering := &Clustering{ Fields: []string{"name"}, } // Currently, clustering depends on partitioning. Interleave testing of the two features. for i, c := range partitionCases { table := dataset.Table(fmt.Sprintf("t_metadata_partition_nocluster_%v", i)) clusterTable := dataset.Table(fmt.Sprintf("t_metadata_partition_cluster_%v", i)) // Create unclustered, partitioned variant and get metadata. err = table.Create(context.Background(), &TableMetadata{ Schema: schema2, TimePartitioning: &c.timePartitioning, ExpirationTime: testTableExpiration, }) if err != nil { t.Fatal(err) } defer table.Delete(ctx) md, err := table.Metadata(ctx) if err != nil { t.Fatal(err) } // Created clustered table and get metadata. err = clusterTable.Create(context.Background(), &TableMetadata{ Schema: schema2, TimePartitioning: &c.timePartitioning, ExpirationTime: testTableExpiration, Clustering: clustering, }) if err != nil { t.Fatal(err) } clusterMD, err := clusterTable.Metadata(ctx) if err != nil { t.Fatal(err) } for _, v := range []*TableMetadata{md, clusterMD} { got := v.TimePartitioning want := &TimePartitioning{ Expiration: c.wantExpiration, Field: c.wantField, RequirePartitionFilter: c.wantPruneFilter, } if !testutil.Equal(got, want) { t.Errorf("metadata.TimePartitioning: got %v, want %v", got, want) } // Manipulate RequirePartitionFilter at the table level. mdUpdate := TableMetadataToUpdate{ RequirePartitionFilter: !want.RequirePartitionFilter, } newmd, err := table.Update(ctx, mdUpdate, "") if err != nil { t.Errorf("failed to invert RequirePartitionFilter on %s: %v", table.FullyQualifiedName(), err) } if newmd.RequirePartitionFilter == want.RequirePartitionFilter { t.Errorf("inverting table-level RequirePartitionFilter on %s failed, want %t got %t", table.FullyQualifiedName(), !want.RequirePartitionFilter, newmd.RequirePartitionFilter) } // Also verify that the clone of RequirePartitionFilter in the TimePartitioning message is consistent. if newmd.RequirePartitionFilter != newmd.TimePartitioning.RequirePartitionFilter { t.Errorf("inconsistent RequirePartitionFilter. Table: %t, TimePartitioning: %t", newmd.RequirePartitionFilter, newmd.TimePartitioning.RequirePartitionFilter) } } if md.Clustering != nil { t.Errorf("metadata.Clustering was not nil on unclustered table %s", table.TableID) } got := clusterMD.Clustering want := clustering if clusterMD.Clustering != clustering { if !testutil.Equal(got, want) { t.Errorf("metadata.Clustering: got %v, want %v", got, want) } } } } func TestIntegration_RangePartitioning(t *testing.T) { if client == nil { t.Skip("Integration tests skipped") } ctx := context.Background() table := dataset.Table(tableIDs.New()) schema := Schema{ {Name: "name", Type: StringFieldType}, {Name: "somevalue", Type: IntegerFieldType}, } wantedRange := &RangePartitioningRange{ Start: 10, End: 135, Interval: 25, } wantedPartitioning := &RangePartitioning{ Field: "somevalue", Range: wantedRange, } err := table.Create(context.Background(), &TableMetadata{ Schema: schema, RangePartitioning: wantedPartitioning, }) if err != nil { t.Fatal(err) } defer table.Delete(ctx) md, err := table.Metadata(ctx) if err != nil { t.Fatal(err) } if md.RangePartitioning == nil { t.Fatal("expected range partitioning, got nil") } got := md.RangePartitioning.Field if wantedPartitioning.Field != got { t.Errorf("RangePartitioning Field: got %v, want %v", got, wantedPartitioning.Field) } if md.RangePartitioning.Range == nil { t.Fatal("expected a range definition, got nil") } gotInt64 := md.RangePartitioning.Range.Start if gotInt64 != wantedRange.Start { t.Errorf("Range.Start: got %v, wanted %v", gotInt64, wantedRange.Start) } gotInt64 = md.RangePartitioning.Range.End if gotInt64 != wantedRange.End { t.Errorf("Range.End: got %v, wanted %v", gotInt64, wantedRange.End) } gotInt64 = md.RangePartitioning.Range.Interval if gotInt64 != wantedRange.Interval { t.Errorf("Range.Interval: got %v, wanted %v", gotInt64, wantedRange.Interval) } } func TestIntegration_RemoveTimePartitioning(t *testing.T) { if client == nil { t.Skip("Integration tests skipped") } ctx := context.Background() table := dataset.Table(tableIDs.New()) want := 24 * time.Hour err := table.Create(ctx, &TableMetadata{ ExpirationTime: testTableExpiration, TimePartitioning: &TimePartitioning{ Expiration: want, }, }) if err != nil { t.Fatal(err) } defer table.Delete(ctx) md, err := table.Metadata(ctx) if err != nil { t.Fatal(err) } if got := md.TimePartitioning.Expiration; got != want { t.Fatalf("TimeParitioning expiration want = %v, got = %v", want, got) } // Remove time partitioning expiration md, err = table.Update(context.Background(), TableMetadataToUpdate{ TimePartitioning: &TimePartitioning{Expiration: 0}, }, md.ETag) if err != nil { t.Fatal(err) } want = time.Duration(0) if got := md.TimePartitioning.Expiration; got != want { t.Fatalf("TimeParitioning expiration want = %v, got = %v", want, got) } } func TestIntegration_DatasetCreate(t *testing.T) { if client == nil { t.Skip("Integration tests skipped") } ctx := context.Background() ds := client.Dataset(datasetIDs.New()) wmd := &DatasetMetadata{Name: "name", Location: "EU"} err := ds.Create(ctx, wmd) if err != nil { t.Fatal(err) } gmd, err := ds.Metadata(ctx) if err != nil { t.Fatal(err) } if got, want := gmd.Name, wmd.Name; got != want { t.Errorf("name: got %q, want %q", got, want) } if got, want := gmd.Location, wmd.Location; got != want { t.Errorf("location: got %q, want %q", got, want) } if err := ds.Delete(ctx); err != nil { t.Fatalf("deleting dataset %v: %v", ds, err) } } func TestIntegration_DatasetMetadata(t *testing.T) { if client == nil { t.Skip("Integration tests skipped") } ctx := context.Background() md, err := dataset.Metadata(ctx) if err != nil { t.Fatal(err) } if got, want := md.FullID, fmt.Sprintf("%s:%s", dataset.ProjectID, dataset.DatasetID); got != want { t.Errorf("FullID: got %q, want %q", got, want) } jan2016 := time.Date(2016, 1, 1, 0, 0, 0, 0, time.UTC) if md.CreationTime.Before(jan2016) { t.Errorf("CreationTime: got %s, want > 2016-1-1", md.CreationTime) } if md.LastModifiedTime.Before(jan2016) { t.Errorf("LastModifiedTime: got %s, want > 2016-1-1", md.LastModifiedTime) } // Verify that we get a NotFound for a nonexistent dataset. _, err = client.Dataset("does_not_exist").Metadata(ctx) if err == nil || !hasStatusCode(err, http.StatusNotFound) { t.Errorf("got %v, want NotFound error", err) } } func TestIntegration_DatasetDelete(t *testing.T) { if client == nil { t.Skip("Integration tests skipped") } ctx := context.Background() ds := client.Dataset(datasetIDs.New()) if err := ds.Create(ctx, nil); err != nil { t.Fatalf("creating dataset %s: %v", ds.DatasetID, err) } if err := ds.Delete(ctx); err != nil { t.Fatalf("deleting dataset %s: %v", ds.DatasetID, err) } } func TestIntegration_DatasetDeleteWithContents(t *testing.T) { if client == nil { t.Skip("Integration tests skipped") } ctx := context.Background() ds := client.Dataset(datasetIDs.New()) if err := ds.Create(ctx, nil); err != nil { t.Fatalf("creating dataset %s: %v", ds.DatasetID, err) } table := ds.Table(tableIDs.New()) if err := table.Create(ctx, nil); err != nil { t.Fatalf("creating table %s in dataset %s: %v", table.TableID, table.DatasetID, err) } // We expect failure here if err := ds.Delete(ctx); err == nil { t.Fatalf("non-recursive delete of dataset %s succeeded unexpectedly.", ds.DatasetID) } if err := ds.DeleteWithContents(ctx); err != nil { t.Fatalf("deleting recursively dataset %s: %v", ds.DatasetID, err) } } func TestIntegration_DatasetUpdateETags(t *testing.T) { if client == nil { t.Skip("Integration tests skipped") } check := func(md *DatasetMetadata, wantDesc, wantName string) { if md.Description != wantDesc { t.Errorf("description: got %q, want %q", md.Description, wantDesc) } if md.Name != wantName { t.Errorf("name: got %q, want %q", md.Name, wantName) } } ctx := context.Background() md, err := dataset.Metadata(ctx) if err != nil { t.Fatal(err) } if md.ETag == "" { t.Fatal("empty ETag") } // Write without ETag succeeds. desc := md.Description + "d2" name := md.Name + "n2" md2, err := dataset.Update(ctx, DatasetMetadataToUpdate{Description: desc, Name: name}, "") if err != nil { t.Fatal(err) } check(md2, desc, name) // Write with original ETag fails because of intervening write. _, err = dataset.Update(ctx, DatasetMetadataToUpdate{Description: "d", Name: "n"}, md.ETag) if err == nil { t.Fatal("got nil, want error") } // Write with most recent ETag succeeds. md3, err := dataset.Update(ctx, DatasetMetadataToUpdate{Description: "", Name: ""}, md2.ETag) if err != nil { t.Fatal(err) } check(md3, "", "") } func TestIntegration_DatasetUpdateDefaultExpiration(t *testing.T) { if client == nil { t.Skip("Integration tests skipped") } ctx := context.Background() _, err := dataset.Metadata(ctx) if err != nil { t.Fatal(err) } // Set the default expiration time. md, err := dataset.Update(ctx, DatasetMetadataToUpdate{DefaultTableExpiration: time.Hour}, "") if err != nil { t.Fatal(err) } if md.DefaultTableExpiration != time.Hour { t.Fatalf("got %s, want 1h", md.DefaultTableExpiration) } // Omitting DefaultTableExpiration doesn't change it. md, err = dataset.Update(ctx, DatasetMetadataToUpdate{Name: "xyz"}, "") if err != nil { t.Fatal(err) } if md.DefaultTableExpiration != time.Hour { t.Fatalf("got %s, want 1h", md.DefaultTableExpiration) } // Setting it to 0 deletes it (which looks like a 0 duration). md, err = dataset.Update(ctx, DatasetMetadataToUpdate{DefaultTableExpiration: time.Duration(0)}, "") if err != nil { t.Fatal(err) } if md.DefaultTableExpiration != 0 { t.Fatalf("got %s, want 0", md.DefaultTableExpiration) } } func TestIntegration_DatasetUpdateAccess(t *testing.T) { if client == nil { t.Skip("Integration tests skipped") } ctx := context.Background() md, err := dataset.Metadata(ctx) if err != nil { t.Fatal(err) } origAccess := append([]*AccessEntry(nil), md.Access...) newEntries := []*AccessEntry{ { Role: ReaderRole, Entity: "Joe@example.com", EntityType: UserEmailEntity, }, { Role: ReaderRole, Entity: "allUsers", EntityType: IAMMemberEntity, }, } newAccess := append(md.Access, newEntries...) dm := DatasetMetadataToUpdate{Access: newAccess} md, err = dataset.Update(ctx, dm, md.ETag) if err != nil { t.Fatal(err) } defer func() { _, err := dataset.Update(ctx, DatasetMetadataToUpdate{Access: origAccess}, md.ETag) if err != nil { t.Log("could not restore dataset access list") } }() for _, v := range md.Access { fmt.Printf("md %+v\n", v) } for _, v := range newAccess { fmt.Printf("newAccess %+v\n", v) } if diff := testutil.Diff(md.Access, newAccess, cmpopts.SortSlices(lessAccessEntries)); diff != "" { t.Fatalf("got=-, want=+:\n%s", diff) } } // Comparison function for AccessEntries to enable order insensitive equality checking. func lessAccessEntries(x, y *AccessEntry) bool { if x.Entity < y.Entity { return true } if x.Entity > y.Entity { return false } if x.EntityType < y.EntityType { return true } if x.EntityType > y.EntityType { return false } if x.Role < y.Role { return true } if x.Role > y.Role { return false } if x.View == nil { return y.View != nil } return false } func TestIntegration_DatasetUpdateLabels(t *testing.T) { if client == nil { t.Skip("Integration tests skipped") } ctx := context.Background() _, err := dataset.Metadata(ctx) if err != nil { t.Fatal(err) } var dm DatasetMetadataToUpdate dm.SetLabel("label", "value") md, err := dataset.Update(ctx, dm, "") if err != nil { t.Fatal(err) } if got, want := md.Labels["label"], "value"; got != want { t.Errorf("got %q, want %q", got, want) } dm = DatasetMetadataToUpdate{} dm.DeleteLabel("label") md, err = dataset.Update(ctx, dm, "") if err != nil { t.Fatal(err) } if _, ok := md.Labels["label"]; ok { t.Error("label still present after deletion") } } func TestIntegration_TableUpdateLabels(t *testing.T) { if client == nil { t.Skip("Integration tests skipped") } ctx := context.Background() table := newTable(t, schema) defer table.Delete(ctx) var tm TableMetadataToUpdate tm.SetLabel("label", "value") md, err := table.Update(ctx, tm, "") if err != nil { t.Fatal(err) } if got, want := md.Labels["label"], "value"; got != want { t.Errorf("got %q, want %q", got, want) } tm = TableMetadataToUpdate{} tm.DeleteLabel("label") md, err = table.Update(ctx, tm, "") if err != nil { t.Fatal(err) } if _, ok := md.Labels["label"]; ok { t.Error("label still present after deletion") } } func TestIntegration_Tables(t *testing.T) { if client == nil { t.Skip("Integration tests skipped") } ctx := context.Background() table := newTable(t, schema) defer table.Delete(ctx) wantName := table.FullyQualifiedName() // This test is flaky due to eventual consistency. ctx, cancel := context.WithTimeout(ctx, 10*time.Second) defer cancel() err := internal.Retry(ctx, gax.Backoff{}, func() (stop bool, err error) { // Iterate over tables in the dataset. it := dataset.Tables(ctx) var tableNames []string for { tbl, err := it.Next() if err == iterator.Done { break } if err != nil { return false, err } tableNames = append(tableNames, tbl.FullyQualifiedName()) } // Other tests may be running with this dataset, so there might be more // than just our table in the list. So don't try for an exact match; just // make sure that our table is there somewhere. for _, tn := range tableNames { if tn == wantName { return true, nil } } return false, fmt.Errorf("got %v\nwant %s in the list", tableNames, wantName) }) if err != nil { t.Fatal(err) } } func TestIntegration_SimpleRowResults(t *testing.T) { if client == nil { t.Skip("Integration tests skipped") } ctx := context.Background() testCases := []struct { description string query string want [][]Value }{ { description: "literals", query: "select 17 as foo", want: [][]Value{{int64(17)}}, }, { description: "empty results", query: "SELECT * FROM (select 17 as foo) where false", want: [][]Value{}, }, { // Note: currently CTAS returns the rows due to the destination table reference, // but it's not clear that it should. // https://github.com/googleapis/google-cloud-go/issues/1467 for followup. description: "ctas ddl", query: fmt.Sprintf("CREATE TABLE %s.%s AS SELECT 17 as foo", dataset.DatasetID, tableIDs.New()), want: [][]Value{{int64(17)}}, }, } for _, tc := range testCases { curCase := tc t.Run(curCase.description, func(t *testing.T) { t.Parallel() q := client.Query(curCase.query) it, err := q.Read(ctx) if err != nil { t.Fatalf("%s read error: %v", curCase.description, err) } checkReadAndTotalRows(t, curCase.description, it, curCase.want) }) } } func TestIntegration_InsertAndRead(t *testing.T) { if client == nil { t.Skip("Integration tests skipped") } ctx := context.Background() table := newTable(t, schema) defer table.Delete(ctx) // Populate the table. ins := table.Inserter() var ( wantRows [][]Value saverRows []*ValuesSaver ) for i, name := range []string{"a", "b", "c"} { row := []Value{name, []Value{int64(i)}, []Value{true}} wantRows = append(wantRows, row) saverRows = append(saverRows, &ValuesSaver{ Schema: schema, InsertID: name, Row: row, }) } if err := ins.Put(ctx, saverRows); err != nil { t.Fatal(putError(err)) } // Wait until the data has been uploaded. This can take a few seconds, according // to https://cloud.google.com/bigquery/streaming-data-into-bigquery. if err := waitForRow(ctx, table); err != nil { t.Fatal(err) } // Read the table. checkRead(t, "upload", table.Read(ctx), wantRows) // Query the table. q := client.Query(fmt.Sprintf("select name, nums, rec from %s", table.TableID)) q.DefaultProjectID = dataset.ProjectID q.DefaultDatasetID = dataset.DatasetID rit, err := q.Read(ctx) if err != nil { t.Fatal(err) } checkRead(t, "query", rit, wantRows) // Query the long way. job1, err := q.Run(ctx) if err != nil { t.Fatal(err) } if job1.LastStatus() == nil { t.Error("no LastStatus") } job2, err := client.JobFromID(ctx, job1.ID()) if err != nil { t.Fatal(err) } if job2.LastStatus() == nil { t.Error("no LastStatus") } rit, err = job2.Read(ctx) if err != nil { t.Fatal(err) } checkRead(t, "job.Read", rit, wantRows) // Get statistics. jobStatus, err := job2.Status(ctx) if err != nil { t.Fatal(err) } if jobStatus.Statistics == nil { t.Fatal("jobStatus missing statistics") } if _, ok := jobStatus.Statistics.Details.(*QueryStatistics); !ok { t.Errorf("expected QueryStatistics, got %T", jobStatus.Statistics.Details) } // Test reading directly into a []Value. valueLists, schema, _, err := readAll(table.Read(ctx)) if err != nil { t.Fatal(err) } it := table.Read(ctx) for i, vl := range valueLists { var got []Value if err := it.Next(&got); err != nil { t.Fatal(err) } if !testutil.Equal(it.Schema, schema) { t.Fatalf("got schema %v, want %v", it.Schema, schema) } want := []Value(vl) if !testutil.Equal(got, want) { t.Errorf("%d: got %v, want %v", i, got, want) } } // Test reading into a map. it = table.Read(ctx) for _, vl := range valueLists { var vm map[string]Value if err := it.Next(&vm); err != nil { t.Fatal(err) } if got, want := len(vm), len(vl); got != want { t.Fatalf("valueMap len: got %d, want %d", got, want) } // With maps, structs become nested maps. vl[2] = map[string]Value{"bool": vl[2].([]Value)[0]} for i, v := range vl { if got, want := vm[schema[i].Name], v; !testutil.Equal(got, want) { t.Errorf("%d, name=%s: got %#v, want %#v", i, schema[i].Name, got, want) } } } } type SubSubTestStruct struct { Integer int64 } type SubTestStruct struct { String string Record SubSubTestStruct RecordArray []SubSubTestStruct } type TestStruct struct { Name string Bytes []byte Integer int64 Float float64 Boolean bool Timestamp time.Time Date civil.Date Time civil.Time DateTime civil.DateTime Numeric *big.Rat Geography string StringArray []string IntegerArray []int64 FloatArray []float64 BooleanArray []bool TimestampArray []time.Time DateArray []civil.Date TimeArray []civil.Time DateTimeArray []civil.DateTime NumericArray []*big.Rat GeographyArray []string Record SubTestStruct RecordArray []SubTestStruct } // Round times to the microsecond for comparison purposes. var roundToMicros = cmp.Transformer("RoundToMicros", func(t time.Time) time.Time { return t.Round(time.Microsecond) }) func TestIntegration_InsertAndReadStructs(t *testing.T) { if client == nil { t.Skip("Integration tests skipped") } schema, err := InferSchema(TestStruct{}) if err != nil { t.Fatal(err) } ctx := context.Background() table := newTable(t, schema) defer table.Delete(ctx) d := civil.Date{Year: 2016, Month: 3, Day: 20} tm := civil.Time{Hour: 15, Minute: 4, Second: 5, Nanosecond: 6000} ts := time.Date(2016, 3, 20, 15, 4, 5, 6000, time.UTC) dtm := civil.DateTime{Date: d, Time: tm} d2 := civil.Date{Year: 1994, Month: 5, Day: 15} tm2 := civil.Time{Hour: 1, Minute: 2, Second: 4, Nanosecond: 0} ts2 := time.Date(1994, 5, 15, 1, 2, 4, 0, time.UTC) dtm2 := civil.DateTime{Date: d2, Time: tm2} g := "POINT(-122.350220 47.649154)" g2 := "POINT(-122.0836791 37.421827)" // Populate the table. ins := table.Inserter() want := []*TestStruct{ { "a", []byte("byte"), 42, 3.14, true, ts, d, tm, dtm, big.NewRat(57, 100), g, []string{"a", "b"}, []int64{1, 2}, []float64{1, 1.41}, []bool{true, false}, []time.Time{ts, ts2}, []civil.Date{d, d2}, []civil.Time{tm, tm2}, []civil.DateTime{dtm, dtm2}, []*big.Rat{big.NewRat(1, 2), big.NewRat(3, 5)}, []string{g, g2}, SubTestStruct{ "string", SubSubTestStruct{24}, []SubSubTestStruct{{1}, {2}}, }, []SubTestStruct{ {String: "empty"}, { "full", SubSubTestStruct{1}, []SubSubTestStruct{{1}, {2}}, }, }, }, { Name: "b", Bytes: []byte("byte2"), Integer: 24, Float: 4.13, Boolean: false, Timestamp: ts, Date: d, Time: tm, DateTime: dtm, Numeric: big.NewRat(4499, 10000), }, } var savers []*StructSaver for _, s := range want { savers = append(savers, &StructSaver{Schema: schema, Struct: s}) } if err := ins.Put(ctx, savers); err != nil { t.Fatal(putError(err)) } // Wait until the data has been uploaded. This can take a few seconds, according // to https://cloud.google.com/bigquery/streaming-data-into-bigquery. if err := waitForRow(ctx, table); err != nil { t.Fatal(err) } // Test iteration with structs. it := table.Read(ctx) var got []*TestStruct for { var g TestStruct err := it.Next(&g) if err == iterator.Done { break } if err != nil { t.Fatal(err) } got = append(got, &g) } sort.Sort(byName(got)) // BigQuery does not elide nils. It reports an error for nil fields. for i, g := range got { if i >= len(want) { t.Errorf("%d: got %v, past end of want", i, pretty.Value(g)) } else if diff := testutil.Diff(g, want[i], roundToMicros); diff != "" { t.Errorf("%d: got=-, want=+:\n%s", i, diff) } } } type byName []*TestStruct func (b byName) Len() int { return len(b) } func (b byName) Swap(i, j int) { b[i], b[j] = b[j], b[i] } func (b byName) Less(i, j int) bool { return b[i].Name < b[j].Name } func TestIntegration_InsertAndReadNullable(t *testing.T) { if client == nil { t.Skip("Integration tests skipped") } ctm := civil.Time{Hour: 15, Minute: 4, Second: 5, Nanosecond: 6000} cdt := civil.DateTime{Date: testDate, Time: ctm} rat := big.NewRat(33, 100) geo := "POINT(-122.198939 47.669865)" // Nil fields in the struct. testInsertAndReadNullable(t, testStructNullable{}, make([]Value, len(testStructNullableSchema))) // Explicitly invalidate the Null* types within the struct. testInsertAndReadNullable(t, testStructNullable{ String: NullString{Valid: false}, Integer: NullInt64{Valid: false}, Float: NullFloat64{Valid: false}, Boolean: NullBool{Valid: false}, Timestamp: NullTimestamp{Valid: false}, Date: NullDate{Valid: false}, Time: NullTime{Valid: false}, DateTime: NullDateTime{Valid: false}, Geography: NullGeography{Valid: false}, }, make([]Value, len(testStructNullableSchema))) // Populate the struct with values. testInsertAndReadNullable(t, testStructNullable{ String: NullString{"x", true}, Bytes: []byte{1, 2, 3}, Integer: NullInt64{1, true}, Float: NullFloat64{2.3, true}, Boolean: NullBool{true, true}, Timestamp: NullTimestamp{testTimestamp, true}, Date: NullDate{testDate, true}, Time: NullTime{ctm, true}, DateTime: NullDateTime{cdt, true}, Numeric: rat, Geography: NullGeography{geo, true}, Record: &subNullable{X: NullInt64{4, true}}, }, []Value{"x", []byte{1, 2, 3}, int64(1), 2.3, true, testTimestamp, testDate, ctm, cdt, rat, geo, []Value{int64(4)}}) } func testInsertAndReadNullable(t *testing.T, ts testStructNullable, wantRow []Value) { ctx := context.Background() table := newTable(t, testStructNullableSchema) defer table.Delete(ctx) // Populate the table. ins := table.Inserter() if err := ins.Put(ctx, []*StructSaver{{Schema: testStructNullableSchema, Struct: ts}}); err != nil { t.Fatal(putError(err)) } // Wait until the data has been uploaded. This can take a few seconds, according // to https://cloud.google.com/bigquery/streaming-data-into-bigquery. if err := waitForRow(ctx, table); err != nil { t.Fatal(err) } // Read into a []Value. iter := table.Read(ctx) gotRows, _, _, err := readAll(iter) if err != nil { t.Fatal(err) } if len(gotRows) != 1 { t.Fatalf("got %d rows, want 1", len(gotRows)) } if diff := testutil.Diff(gotRows[0], wantRow, roundToMicros); diff != "" { t.Error(diff) } // Read into a struct. want := ts var sn testStructNullable it := table.Read(ctx) if err := it.Next(&sn); err != nil { t.Fatal(err) } if diff := testutil.Diff(sn, want, roundToMicros); diff != "" { t.Error(diff) } } func TestIntegration_TableUpdate(t *testing.T) { if client == nil { t.Skip("Integration tests skipped") } ctx := context.Background() table := newTable(t, schema) defer table.Delete(ctx) // Test Update of non-schema fields. tm, err := table.Metadata(ctx) if err != nil { t.Fatal(err) } wantDescription := tm.Description + "more" wantName := tm.Name + "more" wantExpiration := tm.ExpirationTime.Add(time.Hour * 24) got, err := table.Update(ctx, TableMetadataToUpdate{ Description: wantDescription, Name: wantName, ExpirationTime: wantExpiration, }, tm.ETag) if err != nil { t.Fatal(err) } if got.Description != wantDescription { t.Errorf("Description: got %q, want %q", got.Description, wantDescription) } if got.Name != wantName { t.Errorf("Name: got %q, want %q", got.Name, wantName) } if got.ExpirationTime != wantExpiration { t.Errorf("ExpirationTime: got %q, want %q", got.ExpirationTime, wantExpiration) } if !testutil.Equal(got.Schema, schema) { t.Errorf("Schema: got %v, want %v", pretty.Value(got.Schema), pretty.Value(schema)) } // Blind write succeeds. _, err = table.Update(ctx, TableMetadataToUpdate{Name: "x"}, "") if err != nil { t.Fatal(err) } // Write with old etag fails. _, err = table.Update(ctx, TableMetadataToUpdate{Name: "y"}, got.ETag) if err == nil { t.Fatal("Update with old ETag succeeded, wanted failure") } // Test schema update. // Columns can be added. schema2 is the same as schema, except for the // added column in the middle. nested := Schema{ {Name: "nested", Type: BooleanFieldType}, {Name: "other", Type: StringFieldType}, } schema2 := Schema{ schema[0], {Name: "rec2", Type: RecordFieldType, Schema: nested}, schema[1], schema[2], } got, err = table.Update(ctx, TableMetadataToUpdate{Schema: schema2}, "") if err != nil { t.Fatal(err) } // Wherever you add the column, it appears at the end. schema3 := Schema{schema2[0], schema2[2], schema2[3], schema2[1]} if !testutil.Equal(got.Schema, schema3) { t.Errorf("add field:\ngot %v\nwant %v", pretty.Value(got.Schema), pretty.Value(schema3)) } // Updating with the empty schema succeeds, but is a no-op. got, err = table.Update(ctx, TableMetadataToUpdate{Schema: Schema{}}, "") if err != nil { t.Fatal(err) } if !testutil.Equal(got.Schema, schema3) { t.Errorf("empty schema:\ngot %v\nwant %v", pretty.Value(got.Schema), pretty.Value(schema3)) } // Error cases when updating schema. for _, test := range []struct { desc string fields Schema }{ {"change from optional to required", Schema{ {Name: "name", Type: StringFieldType, Required: true}, schema3[1], schema3[2], schema3[3], }}, {"add a required field", Schema{ schema3[0], schema3[1], schema3[2], schema3[3], {Name: "req", Type: StringFieldType, Required: true}, }}, {"remove a field", Schema{schema3[0], schema3[1], schema3[2]}}, {"remove a nested field", Schema{ schema3[0], schema3[1], schema3[2], {Name: "rec2", Type: RecordFieldType, Schema: Schema{nested[0]}}}}, {"remove all nested fields", Schema{ schema3[0], schema3[1], schema3[2], {Name: "rec2", Type: RecordFieldType, Schema: Schema{}}}}, } { _, err = table.Update(ctx, TableMetadataToUpdate{Schema: Schema(test.fields)}, "") if err == nil { t.Errorf("%s: want error, got nil", test.desc) } else if !hasStatusCode(err, 400) { t.Errorf("%s: want 400, got %v", test.desc, err) } } } func TestIntegration_Load(t *testing.T) { if client == nil { t.Skip("Integration tests skipped") } ctx := context.Background() // CSV data can't be loaded into a repeated field, so we use a different schema. table := newTable(t, Schema{ {Name: "name", Type: StringFieldType}, {Name: "nums", Type: IntegerFieldType}, }) defer table.Delete(ctx) // Load the table from a reader. r := strings.NewReader("a,0\nb,1\nc,2\n") wantRows := [][]Value{ {"a", int64(0)}, {"b", int64(1)}, {"c", int64(2)}, } rs := NewReaderSource(r) loader := table.LoaderFrom(rs) loader.WriteDisposition = WriteTruncate loader.Labels = map[string]string{"test": "go"} job, err := loader.Run(ctx) if err != nil { t.Fatal(err) } if job.LastStatus() == nil { t.Error("no LastStatus") } conf, err := job.Config() if err != nil { t.Fatal(err) } config, ok := conf.(*LoadConfig) if !ok { t.Fatalf("got %T, want LoadConfig", conf) } diff := testutil.Diff(config, &loader.LoadConfig, cmp.AllowUnexported(Table{}), cmpopts.IgnoreUnexported(Client{}, ReaderSource{}), // returned schema is at top level, not in the config cmpopts.IgnoreFields(FileConfig{}, "Schema")) if diff != "" { t.Errorf("got=-, want=+:\n%s", diff) } if err := wait(ctx, job); err != nil { t.Fatal(err) } checkReadAndTotalRows(t, "reader load", table.Read(ctx), wantRows) } func TestIntegration_DML(t *testing.T) { if client == nil { t.Skip("Integration tests skipped") } ctx := context.Background() table := newTable(t, schema) defer table.Delete(ctx) sql := fmt.Sprintf(`INSERT %s.%s (name, nums, rec) VALUES ('a', [0], STRUCT(TRUE)), ('b', [1], STRUCT(FALSE)), ('c', [2], STRUCT(TRUE))`, table.DatasetID, table.TableID) if err := runQueryJob(ctx, sql); err != nil { t.Fatal(err) } wantRows := [][]Value{ {"a", []Value{int64(0)}, []Value{true}}, {"b", []Value{int64(1)}, []Value{false}}, {"c", []Value{int64(2)}, []Value{true}}, } checkRead(t, "DML", table.Read(ctx), wantRows) } // runQueryJob is useful for running queries where no row data is returned (DDL/DML). func runQueryJob(ctx context.Context, sql string) error { return internal.Retry(ctx, gax.Backoff{}, func() (stop bool, err error) { job, err := client.Query(sql).Run(ctx) if err != nil { if e, ok := err.(*googleapi.Error); ok && e.Code < 500 { return true, err // fail on 4xx } return false, err } _, err = job.Wait(ctx) if err != nil { if e, ok := err.(*googleapi.Error); ok && e.Code < 500 { return true, err // fail on 4xx } return false, err } return true, nil }) } func TestIntegration_TimeTypes(t *testing.T) { if client == nil { t.Skip("Integration tests skipped") } ctx := context.Background() dtSchema := Schema{ {Name: "d", Type: DateFieldType}, {Name: "t", Type: TimeFieldType}, {Name: "dt", Type: DateTimeFieldType}, {Name: "ts", Type: TimestampFieldType}, } table := newTable(t, dtSchema) defer table.Delete(ctx) d := civil.Date{Year: 2016, Month: 3, Day: 20} tm := civil.Time{Hour: 12, Minute: 30, Second: 0, Nanosecond: 6000} dtm := civil.DateTime{Date: d, Time: tm} ts := time.Date(2016, 3, 20, 15, 04, 05, 0, time.UTC) wantRows := [][]Value{ {d, tm, dtm, ts}, } ins := table.Inserter() if err := ins.Put(ctx, []*ValuesSaver{ {Schema: dtSchema, Row: wantRows[0]}, }); err != nil { t.Fatal(putError(err)) } if err := waitForRow(ctx, table); err != nil { t.Fatal(err) } // SQL wants DATETIMEs with a space between date and time, but the service // returns them in RFC3339 form, with a "T" between. query := fmt.Sprintf("INSERT %s.%s (d, t, dt, ts) "+ "VALUES ('%s', '%s', '%s', '%s')", table.DatasetID, table.TableID, d, CivilTimeString(tm), CivilDateTimeString(dtm), ts.Format("2006-01-02 15:04:05")) if err := runQueryJob(ctx, query); err != nil { t.Fatal(err) } wantRows = append(wantRows, wantRows[0]) checkRead(t, "TimeTypes", table.Read(ctx), wantRows) } func TestIntegration_StandardQuery(t *testing.T) { if client == nil { t.Skip("Integration tests skipped") } ctx := context.Background() d := civil.Date{Year: 2016, Month: 3, Day: 20} tm := civil.Time{Hour: 15, Minute: 04, Second: 05, Nanosecond: 0} ts := time.Date(2016, 3, 20, 15, 04, 05, 0, time.UTC) dtm := ts.Format("2006-01-02 15:04:05") // Constructs Value slices made up of int64s. ints := func(args ...int) []Value { vals := make([]Value, len(args)) for i, arg := range args { vals[i] = int64(arg) } return vals } testCases := []struct { query string wantRow []Value }{ {"SELECT 1", ints(1)}, {"SELECT 1.3", []Value{1.3}}, {"SELECT CAST(1.3 AS NUMERIC)", []Value{big.NewRat(13, 10)}}, {"SELECT NUMERIC '0.25'", []Value{big.NewRat(1, 4)}}, {"SELECT TRUE", []Value{true}}, {"SELECT 'ABC'", []Value{"ABC"}}, {"SELECT CAST('foo' AS BYTES)", []Value{[]byte("foo")}}, {fmt.Sprintf("SELECT TIMESTAMP '%s'", dtm), []Value{ts}}, {fmt.Sprintf("SELECT [TIMESTAMP '%s', TIMESTAMP '%s']", dtm, dtm), []Value{[]Value{ts, ts}}}, {fmt.Sprintf("SELECT ('hello', TIMESTAMP '%s')", dtm), []Value{[]Value{"hello", ts}}}, {fmt.Sprintf("SELECT DATETIME(TIMESTAMP '%s')", dtm), []Value{civil.DateTime{Date: d, Time: tm}}}, {fmt.Sprintf("SELECT DATE(TIMESTAMP '%s')", dtm), []Value{d}}, {fmt.Sprintf("SELECT TIME(TIMESTAMP '%s')", dtm), []Value{tm}}, {"SELECT (1, 2)", []Value{ints(1, 2)}}, {"SELECT [1, 2, 3]", []Value{ints(1, 2, 3)}}, {"SELECT ([1, 2], 3, [4, 5])", []Value{[]Value{ints(1, 2), int64(3), ints(4, 5)}}}, {"SELECT [(1, 2, 3), (4, 5, 6)]", []Value{[]Value{ints(1, 2, 3), ints(4, 5, 6)}}}, {"SELECT [([1, 2, 3], 4), ([5, 6], 7)]", []Value{[]Value{[]Value{ints(1, 2, 3), int64(4)}, []Value{ints(5, 6), int64(7)}}}}, {"SELECT ARRAY(SELECT STRUCT([1, 2]))", []Value{[]Value{[]Value{ints(1, 2)}}}}, } for _, c := range testCases { q := client.Query(c.query) it, err := q.Read(ctx) if err != nil { t.Fatal(err) } checkRead(t, "StandardQuery", it, [][]Value{c.wantRow}) } } func TestIntegration_LegacyQuery(t *testing.T) { if client == nil { t.Skip("Integration tests skipped") } ctx := context.Background() ts := time.Date(2016, 3, 20, 15, 04, 05, 0, time.UTC) dtm := ts.Format("2006-01-02 15:04:05") testCases := []struct { query string wantRow []Value }{ {"SELECT 1", []Value{int64(1)}}, {"SELECT 1.3", []Value{1.3}}, {"SELECT TRUE", []Value{true}}, {"SELECT 'ABC'", []Value{"ABC"}}, {"SELECT CAST('foo' AS BYTES)", []Value{[]byte("foo")}}, {fmt.Sprintf("SELECT TIMESTAMP('%s')", dtm), []Value{ts}}, {fmt.Sprintf("SELECT DATE(TIMESTAMP('%s'))", dtm), []Value{"2016-03-20"}}, {fmt.Sprintf("SELECT TIME(TIMESTAMP('%s'))", dtm), []Value{"15:04:05"}}, } for _, c := range testCases { q := client.Query(c.query) q.UseLegacySQL = true it, err := q.Read(ctx) if err != nil { t.Fatal(err) } checkRead(t, "LegacyQuery", it, [][]Value{c.wantRow}) } } func TestIntegration_QueryParameters(t *testing.T) { if client == nil { t.Skip("Integration tests skipped") } ctx := context.Background() d := civil.Date{Year: 2016, Month: 3, Day: 20} tm := civil.Time{Hour: 15, Minute: 04, Second: 05, Nanosecond: 3008} rtm := tm rtm.Nanosecond = 3000 // round to microseconds dtm := civil.DateTime{Date: d, Time: tm} ts := time.Date(2016, 3, 20, 15, 04, 05, 0, time.UTC) rat := big.NewRat(13, 10) type ss struct { String string } type s struct { Timestamp time.Time StringArray []string SubStruct ss SubStructArray []ss } testCases := []struct { query string parameters []QueryParameter wantRow []Value wantConfig interface{} }{ { "SELECT @val", []QueryParameter{{"val", 1}}, []Value{int64(1)}, int64(1), }, { "SELECT @val", []QueryParameter{{"val", 1.3}}, []Value{1.3}, 1.3, }, { "SELECT @val", []QueryParameter{{"val", rat}}, []Value{rat}, rat, }, { "SELECT @val", []QueryParameter{{"val", true}}, []Value{true}, true, }, { "SELECT @val", []QueryParameter{{"val", "ABC"}}, []Value{"ABC"}, "ABC", }, { "SELECT @val", []QueryParameter{{"val", []byte("foo")}}, []Value{[]byte("foo")}, []byte("foo"), }, { "SELECT @val", []QueryParameter{{"val", ts}}, []Value{ts}, ts, }, { "SELECT @val", []QueryParameter{{"val", []time.Time{ts, ts}}}, []Value{[]Value{ts, ts}}, []interface{}{ts, ts}, }, { "SELECT @val", []QueryParameter{{"val", dtm}}, []Value{civil.DateTime{Date: d, Time: rtm}}, civil.DateTime{Date: d, Time: rtm}, }, { "SELECT @val", []QueryParameter{{"val", d}}, []Value{d}, d, }, { "SELECT @val", []QueryParameter{{"val", tm}}, []Value{rtm}, rtm, }, { "SELECT @val", []QueryParameter{{"val", s{ts, []string{"a", "b"}, ss{"c"}, []ss{{"d"}, {"e"}}}}}, []Value{[]Value{ts, []Value{"a", "b"}, []Value{"c"}, []Value{[]Value{"d"}, []Value{"e"}}}}, map[string]interface{}{ "Timestamp": ts, "StringArray": []interface{}{"a", "b"}, "SubStruct": map[string]interface{}{"String": "c"}, "SubStructArray": []interface{}{ map[string]interface{}{"String": "d"}, map[string]interface{}{"String": "e"}, }, }, }, { "SELECT @val.Timestamp, @val.SubStruct.String", []QueryParameter{{"val", s{Timestamp: ts, SubStruct: ss{"a"}}}}, []Value{ts, "a"}, map[string]interface{}{ "Timestamp": ts, "SubStruct": map[string]interface{}{"String": "a"}, "StringArray": nil, "SubStructArray": nil, }, }, } for _, c := range testCases { q := client.Query(c.query) q.Parameters = c.parameters job, err := q.Run(ctx) if err != nil { t.Fatal(err) } if job.LastStatus() == nil { t.Error("no LastStatus") } it, err := job.Read(ctx) if err != nil { t.Fatal(err) } checkRead(t, "QueryParameters", it, [][]Value{c.wantRow}) config, err := job.Config() if err != nil { t.Fatal(err) } got := config.(*QueryConfig).Parameters[0].Value if !testutil.Equal(got, c.wantConfig) { t.Errorf("param %[1]v (%[1]T): config:\ngot %[2]v (%[2]T)\nwant %[3]v (%[3]T)", c.parameters[0].Value, got, c.wantConfig) } } } func TestIntegration_QueryDryRun(t *testing.T) { if client == nil { t.Skip("Integration tests skipped") } ctx := context.Background() q := client.Query("SELECT word from " + stdName + " LIMIT 10") q.DryRun = true job, err := q.Run(ctx) if err != nil { t.Fatal(err) } s := job.LastStatus() if s.State != Done { t.Errorf("state is %v, expected Done", s.State) } if s.Statistics == nil { t.Fatal("no statistics") } if s.Statistics.Details.(*QueryStatistics).Schema == nil { t.Fatal("no schema") } if s.Statistics.Details.(*QueryStatistics).TotalBytesProcessedAccuracy == "" { t.Fatal("no cost accuracy") } } func TestIntegration_Scripting(t *testing.T) { if client == nil { t.Skip("Integration tests skipped") } ctx := context.Background() sql := ` -- Declare a variable to hold names as an array. DECLARE top_names ARRAY; -- Build an array of the top 100 names from the year 2017. SET top_names = ( SELECT ARRAY_AGG(name ORDER BY number DESC LIMIT 100) FROM ` + "`bigquery-public-data`" + `.usa_names.usa_1910_current WHERE year = 2017 ); -- Which names appear as words in Shakespeare's plays? SELECT name AS shakespeare_name FROM UNNEST(top_names) AS name WHERE name IN ( SELECT word FROM ` + "`bigquery-public-data`" + `.samples.shakespeare ); ` q := client.Query(sql) job, err := q.Run(ctx) if err != nil { t.Fatalf("failed to run parent job: %v", err) } status, err := job.Wait(ctx) if err != nil { t.Fatalf("failed to wait for completion: %v", err) } if status.Err() != nil { t.Fatalf("job terminated with error: %v", err) } queryStats, ok := status.Statistics.Details.(*QueryStatistics) if !ok { t.Fatalf("failed to fetch query statistics") } want := "SCRIPT" if queryStats.StatementType != want { t.Errorf("statement type mismatch. got %s want %s", queryStats.StatementType, want) } if status.Statistics.NumChildJobs <= 0 { t.Errorf("expected script to indicate nonzero child jobs, got %d", status.Statistics.NumChildJobs) } // Ensure child jobs are present. var childJobs []*Job it := job.Children(ctx) for { job, err := it.Next() if err == iterator.Done { break } if err != nil { t.Fatal(err) } childJobs = append(childJobs, job) } if len(childJobs) == 0 { t.Fatal("Script had no child jobs.") } for _, cj := range childJobs { cStatus := cj.LastStatus() if cStatus.Statistics.ParentJobID != job.ID() { t.Errorf("child job %q doesn't indicate parent. got %q, want %q", cj.ID(), cStatus.Statistics.ParentJobID, job.ID()) } if cStatus.Statistics.ScriptStatistics == nil { t.Errorf("child job %q doesn't have script statistics present", cj.ID()) } if cStatus.Statistics.ScriptStatistics.EvaluationKind == "" { t.Errorf("child job %q didn't indicate evaluation kind", cj.ID()) } } } func TestIntegration_ExtractExternal(t *testing.T) { // Create a table, extract it to GCS, then query it externally. if client == nil { t.Skip("Integration tests skipped") } ctx := context.Background() schema := Schema{ {Name: "name", Type: StringFieldType}, {Name: "num", Type: IntegerFieldType}, } table := newTable(t, schema) defer table.Delete(ctx) // Insert table data. sql := fmt.Sprintf(`INSERT %s.%s (name, num) VALUES ('a', 1), ('b', 2), ('c', 3)`, table.DatasetID, table.TableID) if err := runQueryJob(ctx, sql); err != nil { t.Fatal(err) } // Extract to a GCS object as CSV. bucketName := testutil.ProjID() objectName := fmt.Sprintf("bq-test-%s.csv", table.TableID) uri := fmt.Sprintf("gs://%s/%s", bucketName, objectName) defer storageClient.Bucket(bucketName).Object(objectName).Delete(ctx) gr := NewGCSReference(uri) gr.DestinationFormat = CSV e := table.ExtractorTo(gr) job, err := e.Run(ctx) if err != nil { t.Fatal(err) } conf, err := job.Config() if err != nil { t.Fatal(err) } config, ok := conf.(*ExtractConfig) if !ok { t.Fatalf("got %T, want ExtractConfig", conf) } diff := testutil.Diff(config, &e.ExtractConfig, cmp.AllowUnexported(Table{}), cmpopts.IgnoreUnexported(Client{})) if diff != "" { t.Errorf("got=-, want=+:\n%s", diff) } if err := wait(ctx, job); err != nil { t.Fatal(err) } edc := &ExternalDataConfig{ SourceFormat: CSV, SourceURIs: []string{uri}, Schema: schema, Options: &CSVOptions{ SkipLeadingRows: 1, // This is the default. Since we use edc as an expectation later on, // let's just be explicit. FieldDelimiter: ",", }, } // Query that CSV file directly. q := client.Query("SELECT * FROM csv") q.TableDefinitions = map[string]ExternalData{"csv": edc} wantRows := [][]Value{ {"a", int64(1)}, {"b", int64(2)}, {"c", int64(3)}, } iter, err := q.Read(ctx) if err != nil { t.Fatal(err) } checkReadAndTotalRows(t, "external query", iter, wantRows) // Make a table pointing to the file, and query it. // BigQuery does not allow a Table.Read on an external table. table = dataset.Table(tableIDs.New()) err = table.Create(context.Background(), &TableMetadata{ Schema: schema, ExpirationTime: testTableExpiration, ExternalDataConfig: edc, }) if err != nil { t.Fatal(err) } q = client.Query(fmt.Sprintf("SELECT * FROM %s.%s", table.DatasetID, table.TableID)) iter, err = q.Read(ctx) if err != nil { t.Fatal(err) } checkReadAndTotalRows(t, "external table", iter, wantRows) // While we're here, check that the table metadata is correct. md, err := table.Metadata(ctx) if err != nil { t.Fatal(err) } // One difference: since BigQuery returns the schema as part of the ordinary // table metadata, it does not populate ExternalDataConfig.Schema. md.ExternalDataConfig.Schema = md.Schema if diff := testutil.Diff(md.ExternalDataConfig, edc); diff != "" { t.Errorf("got=-, want=+\n%s", diff) } } func TestIntegration_ReadNullIntoStruct(t *testing.T) { // Reading a null into a struct field should return an error (not panic). if client == nil { t.Skip("Integration tests skipped") } ctx := context.Background() table := newTable(t, schema) defer table.Delete(ctx) ins := table.Inserter() row := &ValuesSaver{ Schema: schema, Row: []Value{nil, []Value{}, []Value{nil}}, } if err := ins.Put(ctx, []*ValuesSaver{row}); err != nil { t.Fatal(putError(err)) } if err := waitForRow(ctx, table); err != nil { t.Fatal(err) } q := client.Query(fmt.Sprintf("select name from %s", table.TableID)) q.DefaultProjectID = dataset.ProjectID q.DefaultDatasetID = dataset.DatasetID it, err := q.Read(ctx) if err != nil { t.Fatal(err) } type S struct{ Name string } var s S if err := it.Next(&s); err == nil { t.Fatal("got nil, want error") } } const ( stdName = "`bigquery-public-data.samples.shakespeare`" legacyName = "[bigquery-public-data:samples.shakespeare]" ) // These tests exploit the fact that the two SQL versions have different syntaxes for // fully-qualified table names. var useLegacySQLTests = []struct { t string // name of table std, legacy bool // use standard/legacy SQL err bool // do we expect an error? }{ {t: legacyName, std: false, legacy: true, err: false}, {t: legacyName, std: true, legacy: false, err: true}, {t: legacyName, std: false, legacy: false, err: true}, // standard SQL is default {t: legacyName, std: true, legacy: true, err: true}, {t: stdName, std: false, legacy: true, err: true}, {t: stdName, std: true, legacy: false, err: false}, {t: stdName, std: false, legacy: false, err: false}, // standard SQL is default {t: stdName, std: true, legacy: true, err: true}, } func TestIntegration_QueryUseLegacySQL(t *testing.T) { // Test the UseLegacySQL and UseStandardSQL options for queries. if client == nil { t.Skip("Integration tests skipped") } ctx := context.Background() for _, test := range useLegacySQLTests { q := client.Query(fmt.Sprintf("select word from %s limit 1", test.t)) q.UseStandardSQL = test.std q.UseLegacySQL = test.legacy _, err := q.Read(ctx) gotErr := err != nil if gotErr && !test.err { t.Errorf("%+v:\nunexpected error: %v", test, err) } else if !gotErr && test.err { t.Errorf("%+v:\nsucceeded, but want error", test) } } } func TestIntegration_TableUseLegacySQL(t *testing.T) { // Test UseLegacySQL and UseStandardSQL for Table.Create. if client == nil { t.Skip("Integration tests skipped") } ctx := context.Background() table := newTable(t, schema) defer table.Delete(ctx) for i, test := range useLegacySQLTests { view := dataset.Table(fmt.Sprintf("t_view_%d", i)) tm := &TableMetadata{ ViewQuery: fmt.Sprintf("SELECT word from %s", test.t), UseStandardSQL: test.std, UseLegacySQL: test.legacy, } err := view.Create(ctx, tm) gotErr := err != nil if gotErr && !test.err { t.Errorf("%+v:\nunexpected error: %v", test, err) } else if !gotErr && test.err { t.Errorf("%+v:\nsucceeded, but want error", test) } _ = view.Delete(ctx) } } func TestIntegration_ListJobs(t *testing.T) { // It's difficult to test the list of jobs, because we can't easily // control what's in it. Also, there are many jobs in the test project, // and it takes considerable time to list them all. if client == nil { t.Skip("Integration tests skipped") } ctx := context.Background() // About all we can do is list a few jobs. const max = 20 var jobs []*Job it := client.Jobs(ctx) for { job, err := it.Next() if err == iterator.Done { break } if err != nil { t.Fatal(err) } jobs = append(jobs, job) if len(jobs) >= max { break } } // We expect that there is at least one job in the last few months. if len(jobs) == 0 { t.Fatal("did not get any jobs") } } const tokyo = "asia-northeast1" func TestIntegration_Location(t *testing.T) { if client == nil { t.Skip("Integration tests skipped") } client.Location = "" testLocation(t, tokyo) client.Location = tokyo defer func() { client.Location = "" }() testLocation(t, "") } func testLocation(t *testing.T, loc string) { ctx := context.Background() tokyoDataset := client.Dataset("tokyo") err := tokyoDataset.Create(ctx, &DatasetMetadata{Location: loc}) if err != nil && !hasStatusCode(err, 409) { // 409 = already exists t.Fatal(err) } md, err := tokyoDataset.Metadata(ctx) if err != nil { t.Fatal(err) } if md.Location != tokyo { t.Fatalf("dataset location: got %s, want %s", md.Location, tokyo) } table := tokyoDataset.Table(tableIDs.New()) err = table.Create(context.Background(), &TableMetadata{ Schema: Schema{ {Name: "name", Type: StringFieldType}, {Name: "nums", Type: IntegerFieldType}, }, ExpirationTime: testTableExpiration, }) if err != nil { t.Fatal(err) } defer table.Delete(ctx) loader := table.LoaderFrom(NewReaderSource(strings.NewReader("a,0\nb,1\nc,2\n"))) loader.Location = loc job, err := loader.Run(ctx) if err != nil { t.Fatal("loader.Run", err) } if job.Location() != tokyo { t.Fatalf("job location: got %s, want %s", job.Location(), tokyo) } _, err = client.JobFromID(ctx, job.ID()) if client.Location == "" && err == nil { t.Error("JobFromID with Tokyo job, no client location: want error, got nil") } if client.Location != "" && err != nil { t.Errorf("JobFromID with Tokyo job, with client location: want nil, got %v", err) } _, err = client.JobFromIDLocation(ctx, job.ID(), "US") if err == nil { t.Error("JobFromIDLocation with US: want error, got nil") } job2, err := client.JobFromIDLocation(ctx, job.ID(), loc) if loc == tokyo && err != nil { t.Errorf("loc=tokyo: %v", err) } if loc == "" && err == nil { t.Error("loc empty: got nil, want error") } if job2 != nil && (job2.ID() != job.ID() || job2.Location() != tokyo) { t.Errorf("got id %s loc %s, want id%s loc %s", job2.ID(), job2.Location(), job.ID(), tokyo) } if err := wait(ctx, job); err != nil { t.Fatal(err) } // Cancel should succeed even if the job is done. if err := job.Cancel(ctx); err != nil { t.Fatal(err) } q := client.Query(fmt.Sprintf("SELECT * FROM %s.%s", table.DatasetID, table.TableID)) q.Location = loc iter, err := q.Read(ctx) if err != nil { t.Fatal(err) } wantRows := [][]Value{ {"a", int64(0)}, {"b", int64(1)}, {"c", int64(2)}, } checkRead(t, "location", iter, wantRows) table2 := tokyoDataset.Table(tableIDs.New()) copier := table2.CopierFrom(table) copier.Location = loc if _, err := copier.Run(ctx); err != nil { t.Fatal(err) } bucketName := testutil.ProjID() objectName := fmt.Sprintf("bq-test-%s.csv", table.TableID) uri := fmt.Sprintf("gs://%s/%s", bucketName, objectName) defer storageClient.Bucket(bucketName).Object(objectName).Delete(ctx) gr := NewGCSReference(uri) gr.DestinationFormat = CSV e := table.ExtractorTo(gr) e.Location = loc if _, err := e.Run(ctx); err != nil { t.Fatal(err) } } func TestIntegration_NumericErrors(t *testing.T) { // Verify that the service returns an error for a big.Rat that's too large. if client == nil { t.Skip("Integration tests skipped") } ctx := context.Background() schema := Schema{{Name: "n", Type: NumericFieldType}} table := newTable(t, schema) defer table.Delete(ctx) tooBigRat := &big.Rat{} if _, ok := tooBigRat.SetString("1e40"); !ok { t.Fatal("big.Rat.SetString failed") } ins := table.Inserter() err := ins.Put(ctx, []*ValuesSaver{{Schema: schema, Row: []Value{tooBigRat}}}) if err == nil { t.Fatal("got nil, want error") } } func TestIntegration_QueryErrors(t *testing.T) { // Verify that a bad query returns an appropriate error. if client == nil { t.Skip("Integration tests skipped") } ctx := context.Background() q := client.Query("blah blah broken") _, err := q.Read(ctx) const want = "invalidQuery" if !strings.Contains(err.Error(), want) { t.Fatalf("got %q, want substring %q", err, want) } } func TestIntegration_ModelLifecycle(t *testing.T) { if client == nil { t.Skip("Integration tests skipped") } ctx := context.Background() // Create a model via a CREATE MODEL query modelID := modelIDs.New() model := dataset.Model(modelID) modelRef := fmt.Sprintf("%s.%s.%s", dataset.ProjectID, dataset.DatasetID, modelID) sql := fmt.Sprintf(` CREATE MODEL `+"`%s`"+` OPTIONS ( model_type='linear_reg', max_iteration=1, learn_rate=0.4, learn_rate_strategy='constant' ) AS ( SELECT 'a' AS f1, 2.0 AS label UNION ALL SELECT 'b' AS f1, 3.8 AS label )`, modelRef) if err := runQueryJob(ctx, sql); err != nil { t.Fatal(err) } defer model.Delete(ctx) // Get the model metadata. curMeta, err := model.Metadata(ctx) if err != nil { t.Fatalf("couldn't get metadata: %v", err) } want := "LINEAR_REGRESSION" if curMeta.Type != want { t.Errorf("Model type mismatch. Want %s got %s", curMeta.Type, want) } // Ensure training metadata is available. runs := curMeta.RawTrainingRuns() if runs == nil { t.Errorf("training runs unpopulated.") } labelCols, err := curMeta.RawLabelColumns() if err != nil { t.Fatalf("failed to get label cols: %v", err) } if labelCols == nil { t.Errorf("label column information unpopulated.") } featureCols, err := curMeta.RawFeatureColumns() if err != nil { t.Fatalf("failed to get feature cols: %v", err) } if featureCols == nil { t.Errorf("feature column information unpopulated.") } // Update mutable fields via API. expiry := time.Now().Add(24 * time.Hour).Truncate(time.Millisecond) upd := ModelMetadataToUpdate{ Description: "new", Name: "friendly", ExpirationTime: expiry, } newMeta, err := model.Update(ctx, upd, curMeta.ETag) if err != nil { t.Fatalf("failed to update: %v", err) } want = "new" if newMeta.Description != want { t.Fatalf("Description not updated. got %s want %s", newMeta.Description, want) } want = "friendly" if newMeta.Name != want { t.Fatalf("Description not updated. got %s want %s", newMeta.Description, want) } if newMeta.ExpirationTime != expiry { t.Fatalf("ExpirationTime not updated. got %v want %v", newMeta.ExpirationTime, expiry) } // Ensure presence when enumerating the model list. it := dataset.Models(ctx) seen := false for { mdl, err := it.Next() if err == iterator.Done { break } if err != nil { t.Fatal(err) } if mdl.ModelID == modelID { seen = true } } if !seen { t.Fatal("model not listed in dataset") } // Delete the model. if err := model.Delete(ctx); err != nil { t.Fatalf("failed to delete model: %v", err) } } func TestIntegration_RoutineScalarUDF(t *testing.T) { if client == nil { t.Skip("Integration tests skipped") } ctx := context.Background() // Create a scalar UDF routine via API. routineID := routineIDs.New() routine := dataset.Routine(routineID) err := routine.Create(ctx, &RoutineMetadata{ Type: "SCALAR_FUNCTION", Language: "SQL", Body: "x * 3", Arguments: []*RoutineArgument{ { Name: "x", DataType: &StandardSQLDataType{ TypeKind: "INT64", }, }, }, }) if err != nil { t.Fatalf("Create: %v", err) } } func TestIntegration_RoutineComplexTypes(t *testing.T) { if client == nil { t.Skip("Integration tests skipped") } ctx := context.Background() routineID := routineIDs.New() routine := dataset.Routine(routineID) sql := fmt.Sprintf(` CREATE FUNCTION `+"`%s`("+` arr ARRAY> ) AS ( (SELECT SUM(IF(elem.name = "foo",elem.val,null)) FROM UNNEST(arr) AS elem) )`, routine.FullyQualifiedName()) if err := runQueryJob(ctx, sql); err != nil { t.Fatal(err) } defer routine.Delete(ctx) meta, err := routine.Metadata(ctx) if err != nil { t.Fatalf("Metadata: %v", err) } if meta.Type != "SCALAR_FUNCTION" { t.Fatalf("routine type mismatch, got %s want SCALAR_FUNCTION", meta.Type) } if meta.Language != "SQL" { t.Fatalf("language type mismatch, got %s want SQL", meta.Language) } want := []*RoutineArgument{ { Name: "arr", DataType: &StandardSQLDataType{ TypeKind: "ARRAY", ArrayElementType: &StandardSQLDataType{ TypeKind: "STRUCT", StructType: &StandardSQLStructType{ Fields: []*StandardSQLField{ { Name: "name", Type: &StandardSQLDataType{ TypeKind: "STRING", }, }, { Name: "val", Type: &StandardSQLDataType{ TypeKind: "INT64", }, }, }, }, }, }, }, } if diff := testutil.Diff(meta.Arguments, want); diff != "" { t.Fatalf("%+v: -got, +want:\n%s", meta.Arguments, diff) } } func TestIntegration_RoutineLifecycle(t *testing.T) { if client == nil { t.Skip("Integration tests skipped") } ctx := context.Background() // Create a scalar UDF routine via a CREATE FUNCTION query routineID := routineIDs.New() routine := dataset.Routine(routineID) sql := fmt.Sprintf(` CREATE FUNCTION `+"`%s`"+`(x INT64) AS (x * 3);`, routine.FullyQualifiedName()) if err := runQueryJob(ctx, sql); err != nil { t.Fatal(err) } defer routine.Delete(ctx) // Get the routine metadata. curMeta, err := routine.Metadata(ctx) if err != nil { t.Fatalf("couldn't get metadata: %v", err) } want := "SCALAR_FUNCTION" if curMeta.Type != want { t.Errorf("Routine type mismatch. got %s want %s", curMeta.Type, want) } want = "SQL" if curMeta.Language != want { t.Errorf("Language mismatch. got %s want %s", curMeta.Language, want) } // Perform an update to change the routine body and description. want = "x * 4" wantDescription := "an updated description" // during beta, update doesn't allow partial updates. Provide all fields. newMeta, err := routine.Update(ctx, &RoutineMetadataToUpdate{ Body: want, Arguments: curMeta.Arguments, Description: wantDescription, ReturnType: curMeta.ReturnType, Type: curMeta.Type, }, curMeta.ETag) if err != nil { t.Fatalf("Update: %v", err) } if newMeta.Body != want { t.Fatalf("Update body failed. want %s got %s", want, newMeta.Body) } if newMeta.Description != wantDescription { t.Fatalf("Update description failed. want %s got %s", wantDescription, newMeta.Description) } // Ensure presence when enumerating the model list. it := dataset.Routines(ctx) seen := false for { r, err := it.Next() if err == iterator.Done { break } if err != nil { t.Fatal(err) } if r.RoutineID == routineID { seen = true } } if !seen { t.Fatal("routine not listed in dataset") } // Delete the model. if err := routine.Delete(ctx); err != nil { t.Fatalf("failed to delete routine: %v", err) } } // Creates a new, temporary table with a unique name and the given schema. func newTable(t *testing.T, s Schema) *Table { table := dataset.Table(tableIDs.New()) err := table.Create(context.Background(), &TableMetadata{ Schema: s, ExpirationTime: testTableExpiration, }) if err != nil { t.Fatal(err) } return table } func checkRead(t *testing.T, msg string, it *RowIterator, want [][]Value) { if msg2, ok := compareRead(it, want, false); !ok { t.Errorf("%s: %s", msg, msg2) } } func checkReadAndTotalRows(t *testing.T, msg string, it *RowIterator, want [][]Value) { if msg2, ok := compareRead(it, want, true); !ok { t.Errorf("%s: %s", msg, msg2) } } func compareRead(it *RowIterator, want [][]Value, compareTotalRows bool) (msg string, ok bool) { got, _, totalRows, err := readAll(it) if err != nil { return err.Error(), false } if len(got) != len(want) { return fmt.Sprintf("got %d rows, want %d", len(got), len(want)), false } if compareTotalRows && len(got) != int(totalRows) { return fmt.Sprintf("got %d rows, but totalRows = %d", len(got), totalRows), false } sort.Sort(byCol0(got)) for i, r := range got { gotRow := []Value(r) wantRow := want[i] if !testutil.Equal(gotRow, wantRow) { return fmt.Sprintf("#%d: got %#v, want %#v", i, gotRow, wantRow), false } } return "", true } func readAll(it *RowIterator) ([][]Value, Schema, uint64, error) { var ( rows [][]Value schema Schema totalRows uint64 ) for { var vals []Value err := it.Next(&vals) if err == iterator.Done { return rows, schema, totalRows, nil } if err != nil { return nil, nil, 0, err } rows = append(rows, vals) schema = it.Schema totalRows = it.TotalRows } } type byCol0 [][]Value func (b byCol0) Len() int { return len(b) } func (b byCol0) Swap(i, j int) { b[i], b[j] = b[j], b[i] } func (b byCol0) Less(i, j int) bool { switch a := b[i][0].(type) { case string: return a < b[j][0].(string) case civil.Date: return a.Before(b[j][0].(civil.Date)) default: panic("unknown type") } } func hasStatusCode(err error, code int) bool { if e, ok := err.(*googleapi.Error); ok && e.Code == code { return true } return false } // wait polls the job until it is complete or an error is returned. func wait(ctx context.Context, job *Job) error { status, err := job.Wait(ctx) if err != nil { return err } if status.Err() != nil { return fmt.Errorf("job status error: %#v", status.Err()) } if status.Statistics == nil { return errors.New("nil Statistics") } if status.Statistics.EndTime.IsZero() { return errors.New("EndTime is zero") } if status.Statistics.Details == nil { return errors.New("nil Statistics.Details") } return nil } // waitForRow polls the table until it contains a row. // TODO(jba): use internal.Retry. func waitForRow(ctx context.Context, table *Table) error { for { it := table.Read(ctx) var v []Value err := it.Next(&v) if err == nil { return nil } if err != iterator.Done { return err } time.Sleep(1 * time.Second) } } func putError(err error) string { pme, ok := err.(PutMultiError) if !ok { return err.Error() } var msgs []string for _, err := range pme { msgs = append(msgs, err.Error()) } return strings.Join(msgs, "\n") } google-cloud-go-0.49.0/bigquery/iterator.go000066400000000000000000000153361356504100700206070ustar00rootroot00000000000000// Copyright 2015 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "context" "fmt" "reflect" bq "google.golang.org/api/bigquery/v2" "google.golang.org/api/iterator" ) // Construct a RowIterator. // If pf is nil, there are no rows in the result set. func newRowIterator(ctx context.Context, t *Table, pf pageFetcher) *RowIterator { it := &RowIterator{ ctx: ctx, table: t, pf: pf, } if pf != nil { it.pageInfo, it.nextFunc = iterator.NewPageInfo( it.fetch, func() int { return len(it.rows) }, func() interface{} { r := it.rows; it.rows = nil; return r }) } return it } // A RowIterator provides access to the result of a BigQuery lookup. type RowIterator struct { ctx context.Context table *Table pf pageFetcher pageInfo *iterator.PageInfo nextFunc func() error // StartIndex can be set before the first call to Next. If PageInfo().Token // is also set, StartIndex is ignored. StartIndex uint64 // The schema of the table. Available after the first call to Next. Schema Schema // The total number of rows in the result. Available after the first call to Next. // May be zero just after rows were inserted. TotalRows uint64 rows [][]Value structLoader structLoader // used to populate a pointer to a struct } // Next loads the next row into dst. Its return value is iterator.Done if there // are no more results. Once Next returns iterator.Done, all subsequent calls // will return iterator.Done. // // dst may implement ValueLoader, or may be a *[]Value, *map[string]Value, or struct pointer. // // If dst is a *[]Value, it will be set to new []Value whose i'th element // will be populated with the i'th column of the row. // // If dst is a *map[string]Value, a new map will be created if dst is nil. Then // for each schema column name, the map key of that name will be set to the column's // value. STRUCT types (RECORD types or nested schemas) become nested maps. // // If dst is pointer to a struct, each column in the schema will be matched // with an exported field of the struct that has the same name, ignoring case. // Unmatched schema columns and struct fields will be ignored. // // Each BigQuery column type corresponds to one or more Go types; a matching struct // field must be of the correct type. The correspondences are: // // STRING string // BOOL bool // INTEGER int, int8, int16, int32, int64, uint8, uint16, uint32 // FLOAT float32, float64 // BYTES []byte // TIMESTAMP time.Time // DATE civil.Date // TIME civil.Time // DATETIME civil.DateTime // // A repeated field corresponds to a slice or array of the element type. A STRUCT // type (RECORD or nested schema) corresponds to a nested struct or struct pointer. // All calls to Next on the same iterator must use the same struct type. // // It is an error to attempt to read a BigQuery NULL value into a struct field, // unless the field is of type []byte or is one of the special Null types: NullInt64, // NullFloat64, NullBool, NullString, NullTimestamp, NullDate, NullTime or // NullDateTime. You can also use a *[]Value or *map[string]Value to read from a // table with NULLs. func (it *RowIterator) Next(dst interface{}) error { if it.pf == nil { // There are no rows in the result set. return iterator.Done } var vl ValueLoader switch dst := dst.(type) { case ValueLoader: vl = dst case *[]Value: vl = (*valueList)(dst) case *map[string]Value: vl = (*valueMap)(dst) default: if !isStructPtr(dst) { return fmt.Errorf("bigquery: cannot convert %T to ValueLoader (need pointer to []Value, map[string]Value, or struct)", dst) } } if err := it.nextFunc(); err != nil { return err } row := it.rows[0] it.rows = it.rows[1:] if vl == nil { // This can only happen if dst is a pointer to a struct. We couldn't // set vl above because we need the schema. if err := it.structLoader.set(dst, it.Schema); err != nil { return err } vl = &it.structLoader } return vl.Load(row, it.Schema) } func isStructPtr(x interface{}) bool { t := reflect.TypeOf(x) return t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Struct } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *RowIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } func (it *RowIterator) fetch(pageSize int, pageToken string) (string, error) { res, err := it.pf(it.ctx, it.table, it.Schema, it.StartIndex, int64(pageSize), pageToken) if err != nil { return "", err } it.rows = append(it.rows, res.rows...) it.Schema = res.schema it.TotalRows = res.totalRows return res.pageToken, nil } // A pageFetcher returns a page of rows from a destination table. type pageFetcher func(ctx context.Context, _ *Table, _ Schema, startIndex uint64, pageSize int64, pageToken string) (*fetchPageResult, error) type fetchPageResult struct { pageToken string rows [][]Value totalRows uint64 schema Schema } // fetchPage gets a page of rows from t. func fetchPage(ctx context.Context, t *Table, schema Schema, startIndex uint64, pageSize int64, pageToken string) (*fetchPageResult, error) { // Fetch the table schema in the background, if necessary. errc := make(chan error, 1) if schema != nil { errc <- nil } else { go func() { var bqt *bq.Table err := runWithRetry(ctx, func() (err error) { bqt, err = t.c.bqs.Tables.Get(t.ProjectID, t.DatasetID, t.TableID). Fields("schema"). Context(ctx). Do() return err }) if err == nil && bqt.Schema != nil { schema = bqToSchema(bqt.Schema) } errc <- err }() } call := t.c.bqs.Tabledata.List(t.ProjectID, t.DatasetID, t.TableID) setClientHeader(call.Header()) if pageToken != "" { call.PageToken(pageToken) } else { call.StartIndex(startIndex) } if pageSize > 0 { call.MaxResults(pageSize) } var res *bq.TableDataList err := runWithRetry(ctx, func() (err error) { res, err = call.Context(ctx).Do() return err }) if err != nil { return nil, err } err = <-errc if err != nil { return nil, err } rows, err := convertRows(res.Rows, schema) if err != nil { return nil, err } return &fetchPageResult{ pageToken: res.PageToken, rows: rows, totalRows: uint64(res.TotalRows), schema: schema, }, nil } google-cloud-go-0.49.0/bigquery/iterator_test.go000066400000000000000000000215511356504100700216420ustar00rootroot00000000000000// Copyright 2015 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "context" "errors" "fmt" "testing" "cloud.google.com/go/internal/testutil" "google.golang.org/api/iterator" ) type fetchResponse struct { result *fetchPageResult // The result to return. err error // The error to return. } // pageFetcherStub services fetch requests by returning data from an in-memory list of values. type pageFetcherStub struct { fetchResponses map[string]fetchResponse err error } func (pf *pageFetcherStub) fetchPage(ctx context.Context, _ *Table, _ Schema, _ uint64, _ int64, pageToken string) (*fetchPageResult, error) { call, ok := pf.fetchResponses[pageToken] if !ok { pf.err = fmt.Errorf("Unexpected page token: %q", pageToken) } return call.result, call.err } func TestIterator(t *testing.T) { var ( iiSchema = Schema{ {Type: IntegerFieldType}, {Type: IntegerFieldType}, } siSchema = Schema{ {Type: StringFieldType}, {Type: IntegerFieldType}, } ) fetchFailure := errors.New("fetch failure") testCases := []struct { desc string pageToken string fetchResponses map[string]fetchResponse want [][]Value wantErr error wantSchema Schema wantTotalRows uint64 }{ { desc: "Iteration over single empty page", fetchResponses: map[string]fetchResponse{ "": { result: &fetchPageResult{ pageToken: "", rows: [][]Value{}, schema: Schema{}, }, }, }, want: [][]Value{}, wantSchema: Schema{}, }, { desc: "Iteration over single page", fetchResponses: map[string]fetchResponse{ "": { result: &fetchPageResult{ pageToken: "", rows: [][]Value{{1, 2}, {11, 12}}, schema: iiSchema, totalRows: 4, }, }, }, want: [][]Value{{1, 2}, {11, 12}}, wantSchema: iiSchema, wantTotalRows: 4, }, { desc: "Iteration over single page with different schema", fetchResponses: map[string]fetchResponse{ "": { result: &fetchPageResult{ pageToken: "", rows: [][]Value{{"1", 2}, {"11", 12}}, schema: siSchema, }, }, }, want: [][]Value{{"1", 2}, {"11", 12}}, wantSchema: siSchema, }, { desc: "Iteration over two pages", fetchResponses: map[string]fetchResponse{ "": { result: &fetchPageResult{ pageToken: "a", rows: [][]Value{{1, 2}, {11, 12}}, schema: iiSchema, totalRows: 4, }, }, "a": { result: &fetchPageResult{ pageToken: "", rows: [][]Value{{101, 102}, {111, 112}}, schema: iiSchema, totalRows: 4, }, }, }, want: [][]Value{{1, 2}, {11, 12}, {101, 102}, {111, 112}}, wantSchema: iiSchema, wantTotalRows: 4, }, { desc: "Server response includes empty page", fetchResponses: map[string]fetchResponse{ "": { result: &fetchPageResult{ pageToken: "a", rows: [][]Value{{1, 2}, {11, 12}}, schema: iiSchema, }, }, "a": { result: &fetchPageResult{ pageToken: "b", rows: [][]Value{}, schema: iiSchema, }, }, "b": { result: &fetchPageResult{ pageToken: "", rows: [][]Value{{101, 102}, {111, 112}}, schema: iiSchema, }, }, }, want: [][]Value{{1, 2}, {11, 12}, {101, 102}, {111, 112}}, wantSchema: iiSchema, }, { desc: "Fetch error", fetchResponses: map[string]fetchResponse{ "": { result: &fetchPageResult{ pageToken: "a", rows: [][]Value{{1, 2}, {11, 12}}, schema: iiSchema, }, }, "a": { // We returns some data from this fetch, but also an error. // So the end result should include only data from the previous fetch. err: fetchFailure, result: &fetchPageResult{ pageToken: "b", rows: [][]Value{{101, 102}, {111, 112}}, schema: iiSchema, }, }, }, want: [][]Value{{1, 2}, {11, 12}}, wantErr: fetchFailure, wantSchema: iiSchema, }, { desc: "Skip over an entire page", pageToken: "a", fetchResponses: map[string]fetchResponse{ "": { result: &fetchPageResult{ pageToken: "a", rows: [][]Value{{1, 2}, {11, 12}}, schema: iiSchema, }, }, "a": { result: &fetchPageResult{ pageToken: "", rows: [][]Value{{101, 102}, {111, 112}}, schema: iiSchema, }, }, }, want: [][]Value{{101, 102}, {111, 112}}, wantSchema: iiSchema, }, { desc: "Skip beyond all data", pageToken: "b", fetchResponses: map[string]fetchResponse{ "": { result: &fetchPageResult{ pageToken: "a", rows: [][]Value{{1, 2}, {11, 12}}, schema: iiSchema, }, }, "a": { result: &fetchPageResult{ pageToken: "b", rows: [][]Value{{101, 102}, {111, 112}}, schema: iiSchema, }, }, "b": { result: &fetchPageResult{}, }, }, // In this test case, Next will return false on its first call, // so we won't even attempt to call Get. want: [][]Value{}, wantSchema: Schema{}, }, } for _, tc := range testCases { pf := &pageFetcherStub{ fetchResponses: tc.fetchResponses, } it := newRowIterator(context.Background(), nil, pf.fetchPage) it.PageInfo().Token = tc.pageToken values, schema, totalRows, err := consumeRowIterator(it) if err != tc.wantErr { t.Fatalf("%s: got %v, want %v", tc.desc, err, tc.wantErr) } if (len(values) != 0 || len(tc.want) != 0) && !testutil.Equal(values, tc.want) { t.Errorf("%s: values:\ngot: %v\nwant:%v", tc.desc, values, tc.want) } if (len(schema) != 0 || len(tc.wantSchema) != 0) && !testutil.Equal(schema, tc.wantSchema) { t.Errorf("%s: iterator.Schema:\ngot: %v\nwant: %v", tc.desc, schema, tc.wantSchema) } if totalRows != tc.wantTotalRows { t.Errorf("%s: totalRows: got %d, want %d", tc.desc, totalRows, tc.wantTotalRows) } } } // consumeRowIterator reads the schema and all values from a RowIterator and returns them. func consumeRowIterator(it *RowIterator) ([][]Value, Schema, uint64, error) { var ( got [][]Value schema Schema totalRows uint64 ) for { var vls []Value err := it.Next(&vls) if err == iterator.Done { return got, schema, totalRows, nil } if err != nil { return got, schema, totalRows, err } got = append(got, vls) schema = it.Schema totalRows = it.TotalRows } } func TestNextDuringErrorState(t *testing.T) { pf := &pageFetcherStub{ fetchResponses: map[string]fetchResponse{ "": {err: errors.New("bang")}, }, } it := newRowIterator(context.Background(), nil, pf.fetchPage) var vals []Value if err := it.Next(&vals); err == nil { t.Errorf("Expected error after calling Next") } if err := it.Next(&vals); err == nil { t.Errorf("Expected error calling Next again when iterator has a non-nil error.") } } func TestNextAfterFinished(t *testing.T) { testCases := []struct { fetchResponses map[string]fetchResponse want [][]Value }{ { fetchResponses: map[string]fetchResponse{ "": { result: &fetchPageResult{ pageToken: "", rows: [][]Value{{1, 2}, {11, 12}}, }, }, }, want: [][]Value{{1, 2}, {11, 12}}, }, { fetchResponses: map[string]fetchResponse{ "": { result: &fetchPageResult{ pageToken: "", rows: [][]Value{}, }, }, }, want: [][]Value{}, }, } for _, tc := range testCases { pf := &pageFetcherStub{ fetchResponses: tc.fetchResponses, } it := newRowIterator(context.Background(), nil, pf.fetchPage) values, _, _, err := consumeRowIterator(it) if err != nil { t.Fatal(err) } if (len(values) != 0 || len(tc.want) != 0) && !testutil.Equal(values, tc.want) { t.Errorf("values: got:\n%v\nwant:\n%v", values, tc.want) } // Try calling Get again. var vals []Value if err := it.Next(&vals); err != iterator.Done { t.Errorf("Expected Done calling Next when there are no more values") } } } func TestIteratorNextTypes(t *testing.T) { it := newRowIterator(context.Background(), nil, nil) for _, v := range []interface{}{3, "s", []int{}, &[]int{}, map[string]Value{}, &map[string]interface{}{}, struct{}{}, } { if err := it.Next(v); err == nil { t.Errorf("%v: want error, got nil", v) } } } google-cloud-go-0.49.0/bigquery/job.go000066400000000000000000000703251356504100700175270ustar00rootroot00000000000000// Copyright 2015 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "context" "errors" "fmt" "time" "cloud.google.com/go/internal" "cloud.google.com/go/internal/trace" gax "github.com/googleapis/gax-go/v2" bq "google.golang.org/api/bigquery/v2" "google.golang.org/api/googleapi" "google.golang.org/api/iterator" ) // A Job represents an operation which has been submitted to BigQuery for processing. type Job struct { c *Client projectID string jobID string location string email string config *bq.JobConfiguration lastStatus *JobStatus } // JobFromID creates a Job which refers to an existing BigQuery job. The job // need not have been created by this package. For example, the job may have // been created in the BigQuery console. // // For jobs whose location is other than "US" or "EU", set Client.Location or use // JobFromIDLocation. func (c *Client) JobFromID(ctx context.Context, id string) (*Job, error) { return c.JobFromIDLocation(ctx, id, c.Location) } // JobFromIDLocation creates a Job which refers to an existing BigQuery job. The job // need not have been created by this package (for example, it may have // been created in the BigQuery console), but it must exist in the specified location. func (c *Client) JobFromIDLocation(ctx context.Context, id, location string) (j *Job, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.JobFromIDLocation") defer func() { trace.EndSpan(ctx, err) }() bqjob, err := c.getJobInternal(ctx, id, location, "configuration", "jobReference", "status", "statistics") if err != nil { return nil, err } return bqToJob(bqjob, c) } // ID returns the job's ID. func (j *Job) ID() string { return j.jobID } // Location returns the job's location. func (j *Job) Location() string { return j.location } // Email returns the email of the job's creator. func (j *Job) Email() string { return j.email } // State is one of a sequence of states that a Job progresses through as it is processed. type State int const ( // StateUnspecified is the default JobIterator state. StateUnspecified State = iota // Pending is a state that describes that the job is pending. Pending // Running is a state that describes that the job is running. Running // Done is a state that describes that the job is done. Done ) // JobStatus contains the current State of a job, and errors encountered while processing that job. type JobStatus struct { State State err error // All errors encountered during the running of the job. // Not all Errors are fatal, so errors here do not necessarily mean that the job has completed or was unsuccessful. Errors []*Error // Statistics about the job. Statistics *JobStatistics } // JobConfig contains configuration information for a job. It is implemented by // *CopyConfig, *ExtractConfig, *LoadConfig and *QueryConfig. type JobConfig interface { isJobConfig() } func (*CopyConfig) isJobConfig() {} func (*ExtractConfig) isJobConfig() {} func (*LoadConfig) isJobConfig() {} func (*QueryConfig) isJobConfig() {} // Config returns the configuration information for j. func (j *Job) Config() (JobConfig, error) { return bqToJobConfig(j.config, j.c) } // Children returns a job iterator for enumerating child jobs // of the current job. Currently only scripts, a form of query job, // will create child jobs. func (j *Job) Children(ctx context.Context) *JobIterator { it := j.c.Jobs(ctx) it.ParentJobID = j.ID() return it } func bqToJobConfig(q *bq.JobConfiguration, c *Client) (JobConfig, error) { switch { case q == nil: return nil, nil case q.Copy != nil: return bqToCopyConfig(q, c), nil case q.Extract != nil: return bqToExtractConfig(q, c), nil case q.Load != nil: return bqToLoadConfig(q, c), nil case q.Query != nil: return bqToQueryConfig(q, c) default: return nil, nil } } // JobIDConfig describes how to create an ID for a job. type JobIDConfig struct { // JobID is the ID to use for the job. If empty, a random job ID will be generated. JobID string // If AddJobIDSuffix is true, then a random string will be appended to JobID. AddJobIDSuffix bool // Location is the location for the job. Location string } // createJobRef creates a JobReference. func (j *JobIDConfig) createJobRef(c *Client) *bq.JobReference { // We don't check whether projectID is empty; the server will return an // error when it encounters the resulting JobReference. loc := j.Location if loc == "" { // Use Client.Location as a default. loc = c.Location } jr := &bq.JobReference{ProjectId: c.projectID, Location: loc} if j.JobID == "" { jr.JobId = randomIDFn() } else if j.AddJobIDSuffix { jr.JobId = j.JobID + "-" + randomIDFn() } else { jr.JobId = j.JobID } return jr } // Done reports whether the job has completed. // After Done returns true, the Err method will return an error if the job completed unsuccessfully. func (s *JobStatus) Done() bool { return s.State == Done } // Err returns the error that caused the job to complete unsuccessfully (if any). func (s *JobStatus) Err() error { return s.err } // Status retrieves the current status of the job from BigQuery. It fails if the Status could not be determined. func (j *Job) Status(ctx context.Context) (js *JobStatus, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Job.Status") defer func() { trace.EndSpan(ctx, err) }() bqjob, err := j.c.getJobInternal(ctx, j.jobID, j.location, "status", "statistics") if err != nil { return nil, err } if err := j.setStatus(bqjob.Status); err != nil { return nil, err } j.setStatistics(bqjob.Statistics, j.c) return j.lastStatus, nil } // LastStatus returns the most recently retrieved status of the job. The status is // retrieved when a new job is created, or when JobFromID or Job.Status is called. // Call Job.Status to get the most up-to-date information about a job. func (j *Job) LastStatus() *JobStatus { return j.lastStatus } // Cancel requests that a job be cancelled. This method returns without waiting for // cancellation to take effect. To check whether the job has terminated, use Job.Status. // Cancelled jobs may still incur costs. func (j *Job) Cancel(ctx context.Context) error { // Jobs.Cancel returns a job entity, but the only relevant piece of // data it may contain (the status of the job) is unreliable. From the // docs: "This call will return immediately, and the client will need // to poll for the job status to see if the cancel completed // successfully". So it would be misleading to return a status. call := j.c.bqs.Jobs.Cancel(j.projectID, j.jobID). Location(j.location). Fields(). // We don't need any of the response data. Context(ctx) setClientHeader(call.Header()) return runWithRetry(ctx, func() error { _, err := call.Do() return err }) } // Wait blocks until the job or the context is done. It returns the final status // of the job. // If an error occurs while retrieving the status, Wait returns that error. But // Wait returns nil if the status was retrieved successfully, even if // status.Err() != nil. So callers must check both errors. See the example. func (j *Job) Wait(ctx context.Context) (js *JobStatus, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Job.Wait") defer func() { trace.EndSpan(ctx, err) }() if j.isQuery() { // We can avoid polling for query jobs. if _, _, err := j.waitForQuery(ctx, j.projectID); err != nil { return nil, err } // Note: extra RPC even if you just want to wait for the query to finish. js, err := j.Status(ctx) if err != nil { return nil, err } return js, nil } // Non-query jobs must poll. err = internal.Retry(ctx, gax.Backoff{}, func() (stop bool, err error) { js, err = j.Status(ctx) if err != nil { return true, err } if js.Done() { return true, nil } return false, nil }) if err != nil { return nil, err } return js, nil } // Read fetches the results of a query job. // If j is not a query job, Read returns an error. func (j *Job) Read(ctx context.Context) (ri *RowIterator, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Job.Read") defer func() { trace.EndSpan(ctx, err) }() return j.read(ctx, j.waitForQuery, fetchPage) } func (j *Job) read(ctx context.Context, waitForQuery func(context.Context, string) (Schema, uint64, error), pf pageFetcher) (*RowIterator, error) { if !j.isQuery() { return nil, errors.New("bigquery: cannot read from a non-query job") } destTable := j.config.Query.DestinationTable // The destination table should only be nil if there was a query error. projectID := j.projectID if destTable != nil && projectID != destTable.ProjectId { return nil, fmt.Errorf("bigquery: job project ID is %q, but destination table's is %q", projectID, destTable.ProjectId) } schema, totalRows, err := waitForQuery(ctx, projectID) if err != nil { return nil, err } if destTable == nil { return nil, errors.New("bigquery: query job missing destination table") } dt := bqToTable(destTable, j.c) it := newRowIterator(ctx, dt, pf) it.Schema = schema it.TotalRows = totalRows return it, nil } // waitForQuery waits for the query job to complete and returns its schema. It also // returns the total number of rows in the result set. func (j *Job) waitForQuery(ctx context.Context, projectID string) (Schema, uint64, error) { // Use GetQueryResults only to wait for completion, not to read results. call := j.c.bqs.Jobs.GetQueryResults(projectID, j.jobID).Location(j.location).Context(ctx).MaxResults(0) setClientHeader(call.Header()) backoff := gax.Backoff{ Initial: 1 * time.Second, Multiplier: 2, Max: 60 * time.Second, } var res *bq.GetQueryResultsResponse err := internal.Retry(ctx, backoff, func() (stop bool, err error) { res, err = call.Do() if err != nil { return !retryableError(err), err } if !res.JobComplete { // GetQueryResults may return early without error; retry. return false, nil } return true, nil }) if err != nil { return nil, 0, err } return bqToSchema(res.Schema), res.TotalRows, nil } // JobStatistics contains statistics about a job. type JobStatistics struct { CreationTime time.Time StartTime time.Time EndTime time.Time TotalBytesProcessed int64 Details Statistics // NumChildJobs indicates the number of child jobs run as part of a script. NumChildJobs int64 // ParentJobID indicates the origin job for jobs run as part of a script. ParentJobID string // ScriptStatistics includes information run as part of a child job within // a script. ScriptStatistics *ScriptStatistics } // Statistics is one of ExtractStatistics, LoadStatistics or QueryStatistics. type Statistics interface { implementsStatistics() } // ExtractStatistics contains statistics about an extract job. type ExtractStatistics struct { // The number of files per destination URI or URI pattern specified in the // extract configuration. These values will be in the same order as the // URIs specified in the 'destinationUris' field. DestinationURIFileCounts []int64 } // LoadStatistics contains statistics about a load job. type LoadStatistics struct { // The number of bytes of source data in a load job. InputFileBytes int64 // The number of source files in a load job. InputFiles int64 // Size of the loaded data in bytes. Note that while a load job is in the // running state, this value may change. OutputBytes int64 // The number of rows imported in a load job. Note that while an import job is // in the running state, this value may change. OutputRows int64 } // QueryStatistics contains statistics about a query job. type QueryStatistics struct { // Billing tier for the job. BillingTier int64 // Whether the query result was fetched from the query cache. CacheHit bool // The type of query statement, if valid. StatementType string // Total bytes billed for the job. TotalBytesBilled int64 // Total bytes processed for the job. TotalBytesProcessed int64 // For dry run queries, indicates how accurate the TotalBytesProcessed value is. // When indicated, values include: // UNKNOWN: accuracy of the estimate is unknown. // PRECISE: estimate is precise. // LOWER_BOUND: estimate is lower bound of what the query would cost. // UPPER_BOUND: estiamte is upper bound of what the query would cost. TotalBytesProcessedAccuracy string // Describes execution plan for the query. QueryPlan []*ExplainQueryStage // The number of rows affected by a DML statement. Present only for DML // statements INSERT, UPDATE or DELETE. NumDMLAffectedRows int64 // Describes a timeline of job execution. Timeline []*QueryTimelineSample // ReferencedTables: [Output-only] Referenced tables for // the job. Queries that reference more than 50 tables will not have a // complete list. ReferencedTables []*Table // The schema of the results. Present only for successful dry run of // non-legacy SQL queries. Schema Schema // Slot-milliseconds consumed by this query job. SlotMillis int64 // Standard SQL: list of undeclared query parameter names detected during a // dry run validation. UndeclaredQueryParameterNames []string // DDL target table. DDLTargetTable *Table // DDL Operation performed on the target table. Used to report how the // query impacted the DDL target table. DDLOperationPerformed string // The DDL target table, present only for CREATE/DROP FUNCTION/PROCEDURE queries. DDLTargetRoutine *Routine } // ExplainQueryStage describes one stage of a query. type ExplainQueryStage struct { // CompletedParallelInputs: Number of parallel input segments completed. CompletedParallelInputs int64 // ComputeAvg: Duration the average shard spent on CPU-bound tasks. ComputeAvg time.Duration // ComputeMax: Duration the slowest shard spent on CPU-bound tasks. ComputeMax time.Duration // Relative amount of the total time the average shard spent on CPU-bound tasks. ComputeRatioAvg float64 // Relative amount of the total time the slowest shard spent on CPU-bound tasks. ComputeRatioMax float64 // EndTime: Stage end time. EndTime time.Time // Unique ID for stage within plan. ID int64 // InputStages: IDs for stages that are inputs to this stage. InputStages []int64 // Human-readable name for stage. Name string // ParallelInputs: Number of parallel input segments to be processed. ParallelInputs int64 // ReadAvg: Duration the average shard spent reading input. ReadAvg time.Duration // ReadMax: Duration the slowest shard spent reading input. ReadMax time.Duration // Relative amount of the total time the average shard spent reading input. ReadRatioAvg float64 // Relative amount of the total time the slowest shard spent reading input. ReadRatioMax float64 // Number of records read into the stage. RecordsRead int64 // Number of records written by the stage. RecordsWritten int64 // ShuffleOutputBytes: Total number of bytes written to shuffle. ShuffleOutputBytes int64 // ShuffleOutputBytesSpilled: Total number of bytes written to shuffle // and spilled to disk. ShuffleOutputBytesSpilled int64 // StartTime: Stage start time. StartTime time.Time // Current status for the stage. Status string // List of operations within the stage in dependency order (approximately // chronological). Steps []*ExplainQueryStep // WaitAvg: Duration the average shard spent waiting to be scheduled. WaitAvg time.Duration // WaitMax: Duration the slowest shard spent waiting to be scheduled. WaitMax time.Duration // Relative amount of the total time the average shard spent waiting to be scheduled. WaitRatioAvg float64 // Relative amount of the total time the slowest shard spent waiting to be scheduled. WaitRatioMax float64 // WriteAvg: Duration the average shard spent on writing output. WriteAvg time.Duration // WriteMax: Duration the slowest shard spent on writing output. WriteMax time.Duration // Relative amount of the total time the average shard spent on writing output. WriteRatioAvg float64 // Relative amount of the total time the slowest shard spent on writing output. WriteRatioMax float64 } // ExplainQueryStep describes one step of a query stage. type ExplainQueryStep struct { // Machine-readable operation type. Kind string // Human-readable stage descriptions. Substeps []string } // QueryTimelineSample represents a sample of execution statistics at a point in time. type QueryTimelineSample struct { // Total number of units currently being processed by workers, represented as largest value since last sample. ActiveUnits int64 // Total parallel units of work completed by this query. CompletedUnits int64 // Time elapsed since start of query execution. Elapsed time.Duration // Total parallel units of work remaining for the active stages. PendingUnits int64 // Cumulative slot-milliseconds consumed by the query. SlotMillis int64 } // ScriptStatistics report information about script-based query jobs. type ScriptStatistics struct { EvaluationKind string StackFrames []*ScriptStackFrame } func bqToScriptStatistics(bs *bq.ScriptStatistics) *ScriptStatistics { if bs == nil { return nil } ss := &ScriptStatistics{ EvaluationKind: bs.EvaluationKind, } for _, f := range bs.StackFrames { ss.StackFrames = append(ss.StackFrames, bqToScriptStackFrame(f)) } return ss } // ScriptStackFrame represents the location of the statement/expression being evaluated. // // Line and column numbers are defined as follows: // // - Line and column numbers start with one. That is, line 1 column 1 denotes // the start of the script. // - When inside a stored procedure, all line/column numbers are relative // to the procedure body, not the script in which the procedure was defined. // - Start/end positions exclude leading/trailing comments and whitespace. // The end position always ends with a ";", when present. // - Multi-byte Unicode characters are treated as just one column. // - If the original script (or procedure definition) contains TAB characters, // a tab "snaps" the indentation forward to the nearest multiple of 8 // characters, plus 1. For example, a TAB on column 1, 2, 3, 4, 5, 6 , or 8 // will advance the next character to column 9. A TAB on column 9, 10, 11, // 12, 13, 14, 15, or 16 will advance the next character to column 17. type ScriptStackFrame struct { StartLine int64 StartColumn int64 EndLine int64 EndColumn int64 // Name of the active procedure. Empty if in a top-level script. ProcedureID string // Text of the current statement/expression. Text string } func bqToScriptStackFrame(bsf *bq.ScriptStackFrame) *ScriptStackFrame { if bsf == nil { return nil } return &ScriptStackFrame{ StartLine: bsf.StartLine, StartColumn: bsf.StartColumn, EndLine: bsf.EndLine, EndColumn: bsf.EndColumn, ProcedureID: bsf.ProcedureId, Text: bsf.Text, } } func (*ExtractStatistics) implementsStatistics() {} func (*LoadStatistics) implementsStatistics() {} func (*QueryStatistics) implementsStatistics() {} // Jobs lists jobs within a project. func (c *Client) Jobs(ctx context.Context) *JobIterator { it := &JobIterator{ ctx: ctx, c: c, ProjectID: c.projectID, } it.pageInfo, it.nextFunc = iterator.NewPageInfo( it.fetch, func() int { return len(it.items) }, func() interface{} { b := it.items; it.items = nil; return b }) return it } // JobIterator iterates over jobs in a project. type JobIterator struct { ProjectID string // Project ID of the jobs to list. Default is the client's project. AllUsers bool // Whether to list jobs owned by all users in the project, or just the current caller. State State // List only jobs in the given state. Defaults to all states. MinCreationTime time.Time // List only jobs created after this time. MaxCreationTime time.Time // List only jobs created before this time. ParentJobID string // List only jobs that are children of a given scripting job. ctx context.Context c *Client pageInfo *iterator.PageInfo nextFunc func() error items []*Job } // PageInfo is a getter for the JobIterator's PageInfo. func (it *JobIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next Job. Its second return value is iterator.Done if // there are no more results. Once Next returns Done, all subsequent calls will // return Done. func (it *JobIterator) Next() (*Job, error) { if err := it.nextFunc(); err != nil { return nil, err } item := it.items[0] it.items = it.items[1:] return item, nil } func (it *JobIterator) fetch(pageSize int, pageToken string) (string, error) { var st string switch it.State { case StateUnspecified: st = "" case Pending: st = "pending" case Running: st = "running" case Done: st = "done" default: return "", fmt.Errorf("bigquery: invalid value for JobIterator.State: %d", it.State) } req := it.c.bqs.Jobs.List(it.ProjectID). Context(it.ctx). PageToken(pageToken). Projection("full"). AllUsers(it.AllUsers) if st != "" { req.StateFilter(st) } if !it.MinCreationTime.IsZero() { req.MinCreationTime(uint64(it.MinCreationTime.UnixNano() / 1e6)) } if !it.MaxCreationTime.IsZero() { req.MaxCreationTime(uint64(it.MaxCreationTime.UnixNano() / 1e6)) } setClientHeader(req.Header()) if pageSize > 0 { req.MaxResults(int64(pageSize)) } if it.ParentJobID != "" { req.ParentJobId(it.ParentJobID) } res, err := req.Do() if err != nil { return "", err } for _, j := range res.Jobs { job, err := convertListedJob(j, it.c) if err != nil { return "", err } it.items = append(it.items, job) } return res.NextPageToken, nil } func convertListedJob(j *bq.JobListJobs, c *Client) (*Job, error) { return bqToJob2(j.JobReference, j.Configuration, j.Status, j.Statistics, j.UserEmail, c) } func (c *Client) getJobInternal(ctx context.Context, jobID, location string, fields ...googleapi.Field) (*bq.Job, error) { var job *bq.Job call := c.bqs.Jobs.Get(c.projectID, jobID).Context(ctx) if location != "" { call = call.Location(location) } if len(fields) > 0 { call = call.Fields(fields...) } setClientHeader(call.Header()) err := runWithRetry(ctx, func() (err error) { job, err = call.Do() return err }) if err != nil { return nil, err } return job, nil } func bqToJob(q *bq.Job, c *Client) (*Job, error) { return bqToJob2(q.JobReference, q.Configuration, q.Status, q.Statistics, q.UserEmail, c) } func bqToJob2(qr *bq.JobReference, qc *bq.JobConfiguration, qs *bq.JobStatus, qt *bq.JobStatistics, email string, c *Client) (*Job, error) { j := &Job{ projectID: qr.ProjectId, jobID: qr.JobId, location: qr.Location, c: c, email: email, } j.setConfig(qc) if err := j.setStatus(qs); err != nil { return nil, err } j.setStatistics(qt, c) return j, nil } func (j *Job) setConfig(config *bq.JobConfiguration) { if config == nil { return } j.config = config } func (j *Job) isQuery() bool { return j.config != nil && j.config.Query != nil } var stateMap = map[string]State{"PENDING": Pending, "RUNNING": Running, "DONE": Done} func (j *Job) setStatus(qs *bq.JobStatus) error { if qs == nil { return nil } state, ok := stateMap[qs.State] if !ok { return fmt.Errorf("unexpected job state: %v", qs.State) } j.lastStatus = &JobStatus{ State: state, err: nil, } if err := bqToError(qs.ErrorResult); state == Done && err != nil { j.lastStatus.err = err } for _, ep := range qs.Errors { j.lastStatus.Errors = append(j.lastStatus.Errors, bqToError(ep)) } return nil } func (j *Job) setStatistics(s *bq.JobStatistics, c *Client) { if s == nil || j.lastStatus == nil { return } js := &JobStatistics{ CreationTime: unixMillisToTime(s.CreationTime), StartTime: unixMillisToTime(s.StartTime), EndTime: unixMillisToTime(s.EndTime), TotalBytesProcessed: s.TotalBytesProcessed, NumChildJobs: s.NumChildJobs, ParentJobID: s.ParentJobId, ScriptStatistics: bqToScriptStatistics(s.ScriptStatistics), } switch { case s.Extract != nil: js.Details = &ExtractStatistics{ DestinationURIFileCounts: []int64(s.Extract.DestinationUriFileCounts), } case s.Load != nil: js.Details = &LoadStatistics{ InputFileBytes: s.Load.InputFileBytes, InputFiles: s.Load.InputFiles, OutputBytes: s.Load.OutputBytes, OutputRows: s.Load.OutputRows, } case s.Query != nil: var names []string for _, qp := range s.Query.UndeclaredQueryParameters { names = append(names, qp.Name) } var tables []*Table for _, tr := range s.Query.ReferencedTables { tables = append(tables, bqToTable(tr, c)) } js.Details = &QueryStatistics{ BillingTier: s.Query.BillingTier, CacheHit: s.Query.CacheHit, DDLTargetTable: bqToTable(s.Query.DdlTargetTable, c), DDLOperationPerformed: s.Query.DdlOperationPerformed, DDLTargetRoutine: bqToRoutine(s.Query.DdlTargetRoutine, c), StatementType: s.Query.StatementType, TotalBytesBilled: s.Query.TotalBytesBilled, TotalBytesProcessed: s.Query.TotalBytesProcessed, TotalBytesProcessedAccuracy: s.Query.TotalBytesProcessedAccuracy, NumDMLAffectedRows: s.Query.NumDmlAffectedRows, QueryPlan: queryPlanFromProto(s.Query.QueryPlan), Schema: bqToSchema(s.Query.Schema), SlotMillis: s.Query.TotalSlotMs, Timeline: timelineFromProto(s.Query.Timeline), ReferencedTables: tables, UndeclaredQueryParameterNames: names, } } j.lastStatus.Statistics = js } func queryPlanFromProto(stages []*bq.ExplainQueryStage) []*ExplainQueryStage { var res []*ExplainQueryStage for _, s := range stages { var steps []*ExplainQueryStep for _, p := range s.Steps { steps = append(steps, &ExplainQueryStep{ Kind: p.Kind, Substeps: p.Substeps, }) } res = append(res, &ExplainQueryStage{ CompletedParallelInputs: s.CompletedParallelInputs, ComputeAvg: time.Duration(s.ComputeMsAvg) * time.Millisecond, ComputeMax: time.Duration(s.ComputeMsMax) * time.Millisecond, ComputeRatioAvg: s.ComputeRatioAvg, ComputeRatioMax: s.ComputeRatioMax, EndTime: time.Unix(0, s.EndMs*1e6), ID: s.Id, InputStages: s.InputStages, Name: s.Name, ParallelInputs: s.ParallelInputs, ReadAvg: time.Duration(s.ReadMsAvg) * time.Millisecond, ReadMax: time.Duration(s.ReadMsMax) * time.Millisecond, ReadRatioAvg: s.ReadRatioAvg, ReadRatioMax: s.ReadRatioMax, RecordsRead: s.RecordsRead, RecordsWritten: s.RecordsWritten, ShuffleOutputBytes: s.ShuffleOutputBytes, ShuffleOutputBytesSpilled: s.ShuffleOutputBytesSpilled, StartTime: time.Unix(0, s.StartMs*1e6), Status: s.Status, Steps: steps, WaitAvg: time.Duration(s.WaitMsAvg) * time.Millisecond, WaitMax: time.Duration(s.WaitMsMax) * time.Millisecond, WaitRatioAvg: s.WaitRatioAvg, WaitRatioMax: s.WaitRatioMax, WriteAvg: time.Duration(s.WriteMsAvg) * time.Millisecond, WriteMax: time.Duration(s.WriteMsMax) * time.Millisecond, WriteRatioAvg: s.WriteRatioAvg, WriteRatioMax: s.WriteRatioMax, }) } return res } func timelineFromProto(timeline []*bq.QueryTimelineSample) []*QueryTimelineSample { var res []*QueryTimelineSample for _, s := range timeline { res = append(res, &QueryTimelineSample{ ActiveUnits: s.ActiveUnits, CompletedUnits: s.CompletedUnits, Elapsed: time.Duration(s.ElapsedMs) * time.Millisecond, PendingUnits: s.PendingUnits, SlotMillis: s.TotalSlotMs, }) } return res } google-cloud-go-0.49.0/bigquery/job_test.go000066400000000000000000000046461356504100700205710ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "testing" "cloud.google.com/go/internal/testutil" bq "google.golang.org/api/bigquery/v2" ) func TestCreateJobRef(t *testing.T) { defer fixRandomID("RANDOM")() cNoLoc := &Client{projectID: "projectID"} cLoc := &Client{projectID: "projectID", Location: "defaultLoc"} for _, test := range []struct { in JobIDConfig client *Client want *bq.JobReference }{ { in: JobIDConfig{JobID: "foo"}, want: &bq.JobReference{JobId: "foo"}, }, { in: JobIDConfig{}, want: &bq.JobReference{JobId: "RANDOM"}, }, { in: JobIDConfig{AddJobIDSuffix: true}, want: &bq.JobReference{JobId: "RANDOM"}, }, { in: JobIDConfig{JobID: "foo", AddJobIDSuffix: true}, want: &bq.JobReference{JobId: "foo-RANDOM"}, }, { in: JobIDConfig{JobID: "foo", Location: "loc"}, want: &bq.JobReference{JobId: "foo", Location: "loc"}, }, { in: JobIDConfig{JobID: "foo"}, client: cLoc, want: &bq.JobReference{JobId: "foo", Location: "defaultLoc"}, }, { in: JobIDConfig{JobID: "foo", Location: "loc"}, client: cLoc, want: &bq.JobReference{JobId: "foo", Location: "loc"}, }, } { client := test.client if client == nil { client = cNoLoc } got := test.in.createJobRef(client) test.want.ProjectId = "projectID" if !testutil.Equal(got, test.want) { t.Errorf("%+v: got %+v, want %+v", test.in, got, test.want) } } } func fixRandomID(s string) func() { prev := randomIDFn randomIDFn = func() string { return s } return func() { randomIDFn = prev } } func checkJob(t *testing.T, i int, got, want *bq.Job) { if got.JobReference == nil { t.Errorf("#%d: empty job reference", i) return } if got.JobReference.JobId == "" { t.Errorf("#%d: empty job ID", i) return } d := testutil.Diff(got, want) if d != "" { t.Errorf("#%d: (got=-, want=+) %s", i, d) } } google-cloud-go-0.49.0/bigquery/load.go000066400000000000000000000123771356504100700176770ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "context" "io" "cloud.google.com/go/internal/trace" bq "google.golang.org/api/bigquery/v2" ) // LoadConfig holds the configuration for a load job. type LoadConfig struct { // Src is the source from which data will be loaded. Src LoadSource // Dst is the table into which the data will be loaded. Dst *Table // CreateDisposition specifies the circumstances under which the destination table will be created. // The default is CreateIfNeeded. CreateDisposition TableCreateDisposition // WriteDisposition specifies how existing data in the destination table is treated. // The default is WriteAppend. WriteDisposition TableWriteDisposition // The labels associated with this job. Labels map[string]string // If non-nil, the destination table is partitioned by time. TimePartitioning *TimePartitioning // If non-nil, the destination table is partitioned by integer range. RangePartitioning *RangePartitioning // Clustering specifies the data clustering configuration for the destination table. Clustering *Clustering // Custom encryption configuration (e.g., Cloud KMS keys). DestinationEncryptionConfig *EncryptionConfig // Allows the schema of the destination table to be updated as a side effect of // the load job. SchemaUpdateOptions []string // For Avro-based loads, controls whether logical type annotations are used. // See https://cloud.google.com/bigquery/docs/loading-data-cloud-storage-avro#logical_types // for additional information. UseAvroLogicalTypes bool } func (l *LoadConfig) toBQ() (*bq.JobConfiguration, io.Reader) { config := &bq.JobConfiguration{ Labels: l.Labels, Load: &bq.JobConfigurationLoad{ CreateDisposition: string(l.CreateDisposition), WriteDisposition: string(l.WriteDisposition), DestinationTable: l.Dst.toBQ(), TimePartitioning: l.TimePartitioning.toBQ(), RangePartitioning: l.RangePartitioning.toBQ(), Clustering: l.Clustering.toBQ(), DestinationEncryptionConfiguration: l.DestinationEncryptionConfig.toBQ(), SchemaUpdateOptions: l.SchemaUpdateOptions, UseAvroLogicalTypes: l.UseAvroLogicalTypes, }, } media := l.Src.populateLoadConfig(config.Load) return config, media } func bqToLoadConfig(q *bq.JobConfiguration, c *Client) *LoadConfig { lc := &LoadConfig{ Labels: q.Labels, CreateDisposition: TableCreateDisposition(q.Load.CreateDisposition), WriteDisposition: TableWriteDisposition(q.Load.WriteDisposition), Dst: bqToTable(q.Load.DestinationTable, c), TimePartitioning: bqToTimePartitioning(q.Load.TimePartitioning), RangePartitioning: bqToRangePartitioning(q.Load.RangePartitioning), Clustering: bqToClustering(q.Load.Clustering), DestinationEncryptionConfig: bqToEncryptionConfig(q.Load.DestinationEncryptionConfiguration), SchemaUpdateOptions: q.Load.SchemaUpdateOptions, UseAvroLogicalTypes: q.Load.UseAvroLogicalTypes, } var fc *FileConfig if len(q.Load.SourceUris) == 0 { s := NewReaderSource(nil) fc = &s.FileConfig lc.Src = s } else { s := NewGCSReference(q.Load.SourceUris...) fc = &s.FileConfig lc.Src = s } bqPopulateFileConfig(q.Load, fc) return lc } // A Loader loads data from Google Cloud Storage into a BigQuery table. type Loader struct { JobIDConfig LoadConfig c *Client } // A LoadSource represents a source of data that can be loaded into // a BigQuery table. // // This package defines two LoadSources: GCSReference, for Google Cloud Storage // objects, and ReaderSource, for data read from an io.Reader. type LoadSource interface { // populates config, returns media populateLoadConfig(*bq.JobConfigurationLoad) io.Reader } // LoaderFrom returns a Loader which can be used to load data into a BigQuery table. // The returned Loader may optionally be further configured before its Run method is called. // See GCSReference and ReaderSource for additional configuration options that // affect loading. func (t *Table) LoaderFrom(src LoadSource) *Loader { return &Loader{ c: t.c, LoadConfig: LoadConfig{ Src: src, Dst: t, }, } } // Run initiates a load job. func (l *Loader) Run(ctx context.Context) (j *Job, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Load.Run") defer func() { trace.EndSpan(ctx, err) }() job, media := l.newJob() return l.c.insertJob(ctx, job, media) } func (l *Loader) newJob() (*bq.Job, io.Reader) { config, media := l.LoadConfig.toBQ() return &bq.Job{ JobReference: l.JobIDConfig.createJobRef(l.c), Configuration: config, }, media } google-cloud-go-0.49.0/bigquery/load_test.go000066400000000000000000000217701356504100700207330ustar00rootroot00000000000000// Copyright 2015 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "strings" "testing" "time" "cloud.google.com/go/internal/testutil" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" bq "google.golang.org/api/bigquery/v2" ) func defaultLoadJob() *bq.Job { return &bq.Job{ JobReference: &bq.JobReference{JobId: "RANDOM", ProjectId: "client-project-id"}, Configuration: &bq.JobConfiguration{ Load: &bq.JobConfigurationLoad{ DestinationTable: &bq.TableReference{ ProjectId: "client-project-id", DatasetId: "dataset-id", TableId: "table-id", }, SourceUris: []string{"uri"}, }, }, } } func stringFieldSchema() *FieldSchema { return &FieldSchema{Name: "fieldname", Type: StringFieldType} } func nestedFieldSchema() *FieldSchema { return &FieldSchema{ Name: "nested", Type: RecordFieldType, Schema: Schema{stringFieldSchema()}, } } func bqStringFieldSchema() *bq.TableFieldSchema { return &bq.TableFieldSchema{ Name: "fieldname", Type: "STRING", } } func bqNestedFieldSchema() *bq.TableFieldSchema { return &bq.TableFieldSchema{ Name: "nested", Type: "RECORD", Fields: []*bq.TableFieldSchema{bqStringFieldSchema()}, } } func TestLoad(t *testing.T) { defer fixRandomID("RANDOM")() c := &Client{projectID: "client-project-id"} testCases := []struct { dst *Table src LoadSource jobID string location string config LoadConfig want *bq.Job }{ { dst: c.Dataset("dataset-id").Table("table-id"), src: NewGCSReference("uri"), want: defaultLoadJob(), }, { dst: c.Dataset("dataset-id").Table("table-id"), src: NewGCSReference("uri"), location: "loc", want: func() *bq.Job { j := defaultLoadJob() j.JobReference.Location = "loc" return j }(), }, { dst: c.Dataset("dataset-id").Table("table-id"), jobID: "ajob", config: LoadConfig{ CreateDisposition: CreateNever, WriteDisposition: WriteTruncate, Labels: map[string]string{"a": "b"}, TimePartitioning: &TimePartitioning{Expiration: 1234 * time.Millisecond}, Clustering: &Clustering{Fields: []string{"cfield1"}}, DestinationEncryptionConfig: &EncryptionConfig{KMSKeyName: "keyName"}, SchemaUpdateOptions: []string{"ALLOW_FIELD_ADDITION"}, }, src: NewGCSReference("uri"), want: func() *bq.Job { j := defaultLoadJob() j.Configuration.Labels = map[string]string{"a": "b"} j.Configuration.Load.CreateDisposition = "CREATE_NEVER" j.Configuration.Load.WriteDisposition = "WRITE_TRUNCATE" j.Configuration.Load.TimePartitioning = &bq.TimePartitioning{ Type: "DAY", ExpirationMs: 1234, } j.Configuration.Load.Clustering = &bq.Clustering{ Fields: []string{"cfield1"}, } j.Configuration.Load.DestinationEncryptionConfiguration = &bq.EncryptionConfiguration{KmsKeyName: "keyName"} j.JobReference = &bq.JobReference{ JobId: "ajob", ProjectId: "client-project-id", } j.Configuration.Load.SchemaUpdateOptions = []string{"ALLOW_FIELD_ADDITION"} return j }(), }, { dst: c.Dataset("dataset-id").Table("table-id"), src: func() *GCSReference { g := NewGCSReference("uri") g.MaxBadRecords = 1 g.AllowJaggedRows = true g.AllowQuotedNewlines = true g.IgnoreUnknownValues = true return g }(), want: func() *bq.Job { j := defaultLoadJob() j.Configuration.Load.MaxBadRecords = 1 j.Configuration.Load.AllowJaggedRows = true j.Configuration.Load.AllowQuotedNewlines = true j.Configuration.Load.IgnoreUnknownValues = true return j }(), }, { dst: c.Dataset("dataset-id").Table("table-id"), src: func() *GCSReference { g := NewGCSReference("uri") g.Schema = Schema{ stringFieldSchema(), nestedFieldSchema(), } return g }(), want: func() *bq.Job { j := defaultLoadJob() j.Configuration.Load.Schema = &bq.TableSchema{ Fields: []*bq.TableFieldSchema{ bqStringFieldSchema(), bqNestedFieldSchema(), }} return j }(), }, { dst: c.Dataset("dataset-id").Table("table-id"), src: func() *GCSReference { g := NewGCSReference("uri") g.SkipLeadingRows = 1 g.SourceFormat = JSON g.Encoding = UTF_8 g.FieldDelimiter = "\t" g.Quote = "-" return g }(), want: func() *bq.Job { j := defaultLoadJob() j.Configuration.Load.SkipLeadingRows = 1 j.Configuration.Load.SourceFormat = "NEWLINE_DELIMITED_JSON" j.Configuration.Load.Encoding = "UTF-8" j.Configuration.Load.FieldDelimiter = "\t" hyphen := "-" j.Configuration.Load.Quote = &hyphen return j }(), }, { dst: c.Dataset("dataset-id").Table("table-id"), src: NewGCSReference("uri"), want: func() *bq.Job { j := defaultLoadJob() // Quote is left unset in GCSReference, so should be nil here. j.Configuration.Load.Quote = nil return j }(), }, { dst: c.Dataset("dataset-id").Table("table-id"), src: func() *GCSReference { g := NewGCSReference("uri") g.ForceZeroQuote = true return g }(), want: func() *bq.Job { j := defaultLoadJob() empty := "" j.Configuration.Load.Quote = &empty return j }(), }, { dst: c.Dataset("dataset-id").Table("table-id"), src: func() *ReaderSource { r := NewReaderSource(strings.NewReader("foo")) r.SkipLeadingRows = 1 r.SourceFormat = JSON r.Encoding = UTF_8 r.FieldDelimiter = "\t" r.Quote = "-" return r }(), want: func() *bq.Job { j := defaultLoadJob() j.Configuration.Load.SourceUris = nil j.Configuration.Load.SkipLeadingRows = 1 j.Configuration.Load.SourceFormat = "NEWLINE_DELIMITED_JSON" j.Configuration.Load.Encoding = "UTF-8" j.Configuration.Load.FieldDelimiter = "\t" hyphen := "-" j.Configuration.Load.Quote = &hyphen return j }(), }, { dst: c.Dataset("dataset-id").Table("table-id"), src: func() *GCSReference { g := NewGCSReference("uri") g.SourceFormat = Avro return g }(), config: LoadConfig{ UseAvroLogicalTypes: true, }, want: func() *bq.Job { j := defaultLoadJob() j.Configuration.Load.SourceFormat = "AVRO" j.Configuration.Load.UseAvroLogicalTypes = true return j }(), }, { dst: c.Dataset("dataset-id").Table("table-id"), src: func() *ReaderSource { r := NewReaderSource(strings.NewReader("foo")) r.SourceFormat = Avro return r }(), config: LoadConfig{ UseAvroLogicalTypes: true, }, want: func() *bq.Job { j := defaultLoadJob() j.Configuration.Load.SourceUris = nil j.Configuration.Load.SourceFormat = "AVRO" j.Configuration.Load.UseAvroLogicalTypes = true return j }(), }, { dst: c.Dataset("dataset-id").Table("table-id"), src: func() *ReaderSource { r := NewReaderSource(strings.NewReader("foo")) return r }(), config: LoadConfig{ TimePartitioning: &TimePartitioning{ Field: "somefield", }, }, want: func() *bq.Job { j := defaultLoadJob() j.Configuration.Load.SourceUris = nil j.Configuration.Load.TimePartitioning = &bq.TimePartitioning{ Field: "somefield", Type: "DAY", } return j }(), }, { dst: c.Dataset("dataset-id").Table("table-id"), src: func() *ReaderSource { r := NewReaderSource(strings.NewReader("foo")) return r }(), config: LoadConfig{ RangePartitioning: &RangePartitioning{ Field: "somefield", Range: &RangePartitioningRange{ Start: 1, End: 2, Interval: 3, }, }, }, want: func() *bq.Job { j := defaultLoadJob() j.Configuration.Load.SourceUris = nil j.Configuration.Load.RangePartitioning = &bq.RangePartitioning{ Field: "somefield", Range: &bq.RangePartitioningRange{ Start: 1, End: 2, Interval: 3, }, } return j }(), }, } for i, tc := range testCases { loader := tc.dst.LoaderFrom(tc.src) loader.JobID = tc.jobID loader.Location = tc.location tc.config.Src = tc.src tc.config.Dst = tc.dst loader.LoadConfig = tc.config got, _ := loader.newJob() checkJob(t, i, got, tc.want) jc, err := bqToJobConfig(got.Configuration, c) if err != nil { t.Fatalf("#%d: %v", i, err) } diff := testutil.Diff(jc.(*LoadConfig), &loader.LoadConfig, cmp.AllowUnexported(Table{}, Client{}), cmpopts.IgnoreUnexported(ReaderSource{})) if diff != "" { t.Errorf("#%d: (got=-, want=+:\n%s", i, diff) } } } google-cloud-go-0.49.0/bigquery/model.go000066400000000000000000000204741356504100700200550ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "context" "fmt" "time" "cloud.google.com/go/internal/optional" "cloud.google.com/go/internal/trace" bq "google.golang.org/api/bigquery/v2" ) // Model represent a reference to a BigQuery ML model. // Within the API, models are used largely for communicating // statistical information about a given model, as creation of models is only // supported via BigQuery queries (e.g. CREATE MODEL .. AS ..). // // For more info, see documentation for Bigquery ML, // see: https://cloud.google.com/bigquery/docs/bigqueryml type Model struct { ProjectID string DatasetID string // ModelID must contain only letters (a-z, A-Z), numbers (0-9), or underscores (_). // The maximum length is 1,024 characters. ModelID string c *Client } // FullyQualifiedName returns the ID of the model in projectID:datasetID.modelid format. func (m *Model) FullyQualifiedName() string { return fmt.Sprintf("%s:%s.%s", m.ProjectID, m.DatasetID, m.ModelID) } // Metadata fetches the metadata for a model, which includes ML training statistics. func (m *Model) Metadata(ctx context.Context) (mm *ModelMetadata, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Model.Metadata") defer func() { trace.EndSpan(ctx, err) }() req := m.c.bqs.Models.Get(m.ProjectID, m.DatasetID, m.ModelID).Context(ctx) setClientHeader(req.Header()) var model *bq.Model err = runWithRetry(ctx, func() (err error) { model, err = req.Do() return err }) if err != nil { return nil, err } return bqToModelMetadata(model) } // Update updates mutable fields in an ML model. func (m *Model) Update(ctx context.Context, mm ModelMetadataToUpdate, etag string) (md *ModelMetadata, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Model.Update") defer func() { trace.EndSpan(ctx, err) }() bqm, err := mm.toBQ() if err != nil { return nil, err } call := m.c.bqs.Models.Patch(m.ProjectID, m.DatasetID, m.ModelID, bqm).Context(ctx) setClientHeader(call.Header()) if etag != "" { call.Header().Set("If-Match", etag) } var res *bq.Model if err := runWithRetry(ctx, func() (err error) { res, err = call.Do() return err }); err != nil { return nil, err } return bqToModelMetadata(res) } // Delete deletes an ML model. func (m *Model) Delete(ctx context.Context) (err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Model.Delete") defer func() { trace.EndSpan(ctx, err) }() req := m.c.bqs.Models.Delete(m.ProjectID, m.DatasetID, m.ModelID).Context(ctx) setClientHeader(req.Header()) return req.Do() } // ModelMetadata represents information about a BigQuery ML model. type ModelMetadata struct { // The user-friendly description of the model. Description string // The user-friendly name of the model. Name string // The type of the model. Possible values include: // "LINEAR_REGRESSION" - a linear regression model // "LOGISTIC_REGRESSION" - a logistic regression model // "KMEANS" - a k-means clustering model Type string // The creation time of the model. CreationTime time.Time // The last modified time of the model. LastModifiedTime time.Time // The expiration time of the model. ExpirationTime time.Time // The geographic location where the model resides. This value is // inherited from the encapsulating dataset. Location string // Custom encryption configuration (e.g., Cloud KMS keys). EncryptionConfig *EncryptionConfig // The input feature columns used to train the model. featureColumns []*bq.StandardSqlField // The label columns used to train the model. Output // from the model will have a "predicted_" prefix for these columns. labelColumns []*bq.StandardSqlField // Information for all training runs, ordered by increasing start times. trainingRuns []*bq.TrainingRun Labels map[string]string // ETag is the ETag obtained when reading metadata. Pass it to Model.Update // to ensure that the metadata hasn't changed since it was read. ETag string } // TrainingRun represents information about a single training run for a BigQuery ML model. // Experimental: This information may be modified or removed in future versions of this package. type TrainingRun bq.TrainingRun // RawTrainingRuns exposes the underlying training run stats for a model using types from // "google.golang.org/api/bigquery/v2", which are subject to change without warning. // It is EXPERIMENTAL and subject to change or removal without notice. func (mm *ModelMetadata) RawTrainingRuns() []*TrainingRun { if mm.trainingRuns == nil { return nil } var runs []*TrainingRun for _, v := range mm.trainingRuns { r := TrainingRun(*v) runs = append(runs, &r) } return runs } // RawLabelColumns exposes the underlying label columns used to train an ML model and uses types from // "google.golang.org/api/bigquery/v2", which are subject to change without warning. // It is EXPERIMENTAL and subject to change or removal without notice. func (mm *ModelMetadata) RawLabelColumns() ([]*StandardSQLField, error) { return bqToModelCols(mm.labelColumns) } // RawFeatureColumns exposes the underlying feature columns used to train an ML model and uses types from // "google.golang.org/api/bigquery/v2", which are subject to change without warning. // It is EXPERIMENTAL and subject to change or removal without notice. func (mm *ModelMetadata) RawFeatureColumns() ([]*StandardSQLField, error) { return bqToModelCols(mm.featureColumns) } func bqToModelCols(s []*bq.StandardSqlField) ([]*StandardSQLField, error) { if s == nil { return nil, nil } var cols []*StandardSQLField for _, v := range s { c, err := bqToStandardSQLField(v) if err != nil { return nil, err } cols = append(cols, c) } return cols, nil } func bqToModelMetadata(m *bq.Model) (*ModelMetadata, error) { md := &ModelMetadata{ Description: m.Description, Name: m.FriendlyName, Type: m.ModelType, Location: m.Location, Labels: m.Labels, ExpirationTime: unixMillisToTime(m.ExpirationTime), CreationTime: unixMillisToTime(m.CreationTime), LastModifiedTime: unixMillisToTime(m.LastModifiedTime), EncryptionConfig: bqToEncryptionConfig(m.EncryptionConfiguration), featureColumns: m.FeatureColumns, labelColumns: m.LabelColumns, trainingRuns: m.TrainingRuns, ETag: m.Etag, } return md, nil } // ModelMetadataToUpdate is used when updating an ML model's metadata. // Only non-nil fields will be updated. type ModelMetadataToUpdate struct { // The user-friendly description of this model. Description optional.String // The user-friendly name of this model. Name optional.String // The time when this model expires. To remove a model's expiration, // set ExpirationTime to NeverExpire. The zero value is ignored. ExpirationTime time.Time // The model's encryption configuration. EncryptionConfig *EncryptionConfig labelUpdater } func (mm *ModelMetadataToUpdate) toBQ() (*bq.Model, error) { m := &bq.Model{} forceSend := func(field string) { m.ForceSendFields = append(m.ForceSendFields, field) } if mm.Description != nil { m.Description = optional.ToString(mm.Description) forceSend("Description") } if mm.Name != nil { m.FriendlyName = optional.ToString(mm.Name) forceSend("FriendlyName") } if mm.EncryptionConfig != nil { m.EncryptionConfiguration = mm.EncryptionConfig.toBQ() } if !validExpiration(mm.ExpirationTime) { return nil, invalidTimeError(mm.ExpirationTime) } if mm.ExpirationTime == NeverExpire { m.NullFields = append(m.NullFields, "ExpirationTime") } else if !mm.ExpirationTime.IsZero() { m.ExpirationTime = mm.ExpirationTime.UnixNano() / 1e6 forceSend("ExpirationTime") } labels, forces, nulls := mm.update() m.Labels = labels m.ForceSendFields = append(m.ForceSendFields, forces...) m.NullFields = append(m.NullFields, nulls...) return m, nil } google-cloud-go-0.49.0/bigquery/model_test.go000066400000000000000000000063331356504100700211120ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "testing" "time" "cloud.google.com/go/internal/testutil" "github.com/google/go-cmp/cmp/cmpopts" bq "google.golang.org/api/bigquery/v2" ) func TestBQToModelMetadata(t *testing.T) { aTime := time.Date(2019, 3, 14, 0, 0, 0, 0, time.Local) aTimeMillis := aTime.UnixNano() / 1e6 for _, test := range []struct { in *bq.Model want *ModelMetadata }{ {&bq.Model{}, &ModelMetadata{}}, { &bq.Model{ CreationTime: aTimeMillis, Description: "desc", Etag: "etag", ExpirationTime: aTimeMillis, EncryptionConfiguration: &bq.EncryptionConfiguration{KmsKeyName: "keyName"}, FriendlyName: "fname", LastModifiedTime: aTimeMillis, Location: "loc", Labels: map[string]string{"a": "b"}, }, &ModelMetadata{ CreationTime: aTime.Truncate(time.Millisecond), Description: "desc", ETag: "etag", ExpirationTime: aTime.Truncate(time.Millisecond), Name: "fname", LastModifiedTime: aTime.Truncate(time.Millisecond), EncryptionConfig: &EncryptionConfig{KMSKeyName: "keyName"}, Location: "loc", Labels: map[string]string{"a": "b"}, }, }, } { got, err := bqToModelMetadata(test.in) if err != nil { t.Fatal(err) } if diff := testutil.Diff(got, test.want, cmpopts.IgnoreUnexported(ModelMetadata{})); diff != "" { t.Errorf("%+v:\n, -got, +want:\n%s", test.in, diff) } } } func TestModelMetadataUpdateToBQ(t *testing.T) { aTime := time.Date(2019, 3, 14, 0, 0, 0, 0, time.Local) aTimeMillis := aTime.UnixNano() / 1e6 for _, test := range []struct { in ModelMetadataToUpdate want *bq.Model }{ { ModelMetadataToUpdate{}, &bq.Model{}, }, { ModelMetadataToUpdate{ Description: "d", Name: "n", }, &bq.Model{ Description: "d", FriendlyName: "n", ForceSendFields: []string{"Description", "FriendlyName"}, }, }, { ModelMetadataToUpdate{ ExpirationTime: aTime, }, &bq.Model{ ExpirationTime: aTimeMillis, ForceSendFields: []string{"ExpirationTime"}, }, }, { ModelMetadataToUpdate{ labelUpdater: labelUpdater{ setLabels: map[string]string{"L": "V"}, deleteLabels: map[string]bool{"D": true}, }, }, &bq.Model{ Labels: map[string]string{"L": "V"}, NullFields: []string{"Labels.D"}, }, }, } { got, err := test.in.toBQ() if err != nil { t.Fatalf("%+v: %v", test.in, err) } if diff := testutil.Diff(got, test.want); diff != "" { t.Errorf("%+v:\n-got, +want:\n%s", test.in, diff) } } } google-cloud-go-0.49.0/bigquery/nulls.go000066400000000000000000000203101356504100700200770ustar00rootroot00000000000000// Copyright 2015 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "bytes" "encoding/json" "fmt" "reflect" "strconv" "time" "cloud.google.com/go/civil" ) // NullInt64 represents a BigQuery INT64 that may be NULL. type NullInt64 struct { Int64 int64 Valid bool // Valid is true if Int64 is not NULL. } func (n NullInt64) String() string { return nullstr(n.Valid, n.Int64) } // NullString represents a BigQuery STRING that may be NULL. type NullString struct { StringVal string Valid bool // Valid is true if StringVal is not NULL. } func (n NullString) String() string { return nullstr(n.Valid, n.StringVal) } // NullGeography represents a BigQuery GEOGRAPHY string that may be NULL. type NullGeography struct { GeographyVal string Valid bool // Valid is true if GeographyVal is not NULL. } func (n NullGeography) String() string { return nullstr(n.Valid, n.GeographyVal) } // NullFloat64 represents a BigQuery FLOAT64 that may be NULL. type NullFloat64 struct { Float64 float64 Valid bool // Valid is true if Float64 is not NULL. } func (n NullFloat64) String() string { return nullstr(n.Valid, n.Float64) } // NullBool represents a BigQuery BOOL that may be NULL. type NullBool struct { Bool bool Valid bool // Valid is true if Bool is not NULL. } func (n NullBool) String() string { return nullstr(n.Valid, n.Bool) } // NullTimestamp represents a BigQuery TIMESTAMP that may be null. type NullTimestamp struct { Timestamp time.Time Valid bool // Valid is true if Time is not NULL. } func (n NullTimestamp) String() string { return nullstr(n.Valid, n.Timestamp) } // NullDate represents a BigQuery DATE that may be null. type NullDate struct { Date civil.Date Valid bool // Valid is true if Date is not NULL. } func (n NullDate) String() string { return nullstr(n.Valid, n.Date) } // NullTime represents a BigQuery TIME that may be null. type NullTime struct { Time civil.Time Valid bool // Valid is true if Time is not NULL. } func (n NullTime) String() string { if !n.Valid { return "" } return CivilTimeString(n.Time) } // NullDateTime represents a BigQuery DATETIME that may be null. type NullDateTime struct { DateTime civil.DateTime Valid bool // Valid is true if DateTime is not NULL. } func (n NullDateTime) String() string { if !n.Valid { return "" } return CivilDateTimeString(n.DateTime) } // MarshalJSON converts the NullInt64 to JSON. func (n NullInt64) MarshalJSON() ([]byte, error) { return nulljson(n.Valid, n.Int64) } // MarshalJSON converts the NullFloat64 to JSON. func (n NullFloat64) MarshalJSON() ([]byte, error) { return nulljson(n.Valid, n.Float64) } // MarshalJSON converts the NullBool to JSON. func (n NullBool) MarshalJSON() ([]byte, error) { return nulljson(n.Valid, n.Bool) } // MarshalJSON converts the NullString to JSON. func (n NullString) MarshalJSON() ([]byte, error) { return nulljson(n.Valid, n.StringVal) } // MarshalJSON converts the NullGeography to JSON. func (n NullGeography) MarshalJSON() ([]byte, error) { return nulljson(n.Valid, n.GeographyVal) } // MarshalJSON converts the NullTimestamp to JSON. func (n NullTimestamp) MarshalJSON() ([]byte, error) { return nulljson(n.Valid, n.Timestamp) } // MarshalJSON converts the NullDate to JSON. func (n NullDate) MarshalJSON() ([]byte, error) { return nulljson(n.Valid, n.Date) } // MarshalJSON converts the NullTime to JSON. func (n NullTime) MarshalJSON() ([]byte, error) { if !n.Valid { return jsonNull, nil } return []byte(`"` + CivilTimeString(n.Time) + `"`), nil } // MarshalJSON converts the NullDateTime to JSON. func (n NullDateTime) MarshalJSON() ([]byte, error) { if !n.Valid { return jsonNull, nil } return []byte(`"` + CivilDateTimeString(n.DateTime) + `"`), nil } func nullstr(valid bool, v interface{}) string { if !valid { return "NULL" } return fmt.Sprint(v) } var jsonNull = []byte("null") func nulljson(valid bool, v interface{}) ([]byte, error) { if !valid { return jsonNull, nil } return json.Marshal(v) } // UnmarshalJSON converts JSON into a NullInt64. func (n *NullInt64) UnmarshalJSON(b []byte) error { n.Valid = false n.Int64 = 0 if bytes.Equal(b, jsonNull) { return nil } if err := json.Unmarshal(b, &n.Int64); err != nil { return err } n.Valid = true return nil } // UnmarshalJSON converts JSON into a NullFloat64. func (n *NullFloat64) UnmarshalJSON(b []byte) error { n.Valid = false n.Float64 = 0 if bytes.Equal(b, jsonNull) { return nil } if err := json.Unmarshal(b, &n.Float64); err != nil { return err } n.Valid = true return nil } // UnmarshalJSON converts JSON into a NullBool. func (n *NullBool) UnmarshalJSON(b []byte) error { n.Valid = false n.Bool = false if bytes.Equal(b, jsonNull) { return nil } if err := json.Unmarshal(b, &n.Bool); err != nil { return err } n.Valid = true return nil } // UnmarshalJSON converts JSON into a NullString. func (n *NullString) UnmarshalJSON(b []byte) error { n.Valid = false n.StringVal = "" if bytes.Equal(b, jsonNull) { return nil } if err := json.Unmarshal(b, &n.StringVal); err != nil { return err } n.Valid = true return nil } // UnmarshalJSON converts JSON into a NullGeography. func (n *NullGeography) UnmarshalJSON(b []byte) error { n.Valid = false n.GeographyVal = "" if bytes.Equal(b, jsonNull) { return nil } if err := json.Unmarshal(b, &n.GeographyVal); err != nil { return err } n.Valid = true return nil } // UnmarshalJSON converts JSON into a NullTimestamp. func (n *NullTimestamp) UnmarshalJSON(b []byte) error { n.Valid = false n.Timestamp = time.Time{} if bytes.Equal(b, jsonNull) { return nil } if err := json.Unmarshal(b, &n.Timestamp); err != nil { return err } n.Valid = true return nil } // UnmarshalJSON converts JSON into a NullDate. func (n *NullDate) UnmarshalJSON(b []byte) error { n.Valid = false n.Date = civil.Date{} if bytes.Equal(b, jsonNull) { return nil } if err := json.Unmarshal(b, &n.Date); err != nil { return err } n.Valid = true return nil } // UnmarshalJSON converts JSON into a NullTime. func (n *NullTime) UnmarshalJSON(b []byte) error { n.Valid = false n.Time = civil.Time{} if bytes.Equal(b, jsonNull) { return nil } s, err := strconv.Unquote(string(b)) if err != nil { return err } t, err := civil.ParseTime(s) if err != nil { return err } n.Time = t n.Valid = true return nil } // UnmarshalJSON converts JSON into a NullDateTime. func (n *NullDateTime) UnmarshalJSON(b []byte) error { n.Valid = false n.DateTime = civil.DateTime{} if bytes.Equal(b, jsonNull) { return nil } s, err := strconv.Unquote(string(b)) if err != nil { return err } dt, err := parseCivilDateTime(s) if err != nil { return err } n.DateTime = dt n.Valid = true return nil } var ( typeOfNullInt64 = reflect.TypeOf(NullInt64{}) typeOfNullFloat64 = reflect.TypeOf(NullFloat64{}) typeOfNullBool = reflect.TypeOf(NullBool{}) typeOfNullString = reflect.TypeOf(NullString{}) typeOfNullGeography = reflect.TypeOf(NullGeography{}) typeOfNullTimestamp = reflect.TypeOf(NullTimestamp{}) typeOfNullDate = reflect.TypeOf(NullDate{}) typeOfNullTime = reflect.TypeOf(NullTime{}) typeOfNullDateTime = reflect.TypeOf(NullDateTime{}) ) func nullableFieldType(t reflect.Type) FieldType { switch t { case typeOfNullInt64: return IntegerFieldType case typeOfNullFloat64: return FloatFieldType case typeOfNullBool: return BooleanFieldType case typeOfNullString: return StringFieldType case typeOfNullGeography: return GeographyFieldType case typeOfNullTimestamp: return TimestampFieldType case typeOfNullDate: return DateFieldType case typeOfNullTime: return TimeFieldType case typeOfNullDateTime: return DateTimeFieldType default: return "" } } google-cloud-go-0.49.0/bigquery/nulls_test.go000066400000000000000000000045541356504100700211520ustar00rootroot00000000000000// Copyright 2015 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "encoding/json" "reflect" "testing" "cloud.google.com/go/civil" "cloud.google.com/go/internal/testutil" ) var ( nullsTestTime = civil.Time{Hour: 7, Minute: 50, Second: 22, Nanosecond: 1000} nullsTestDateTime = civil.DateTime{Date: civil.Date{Year: 2016, Month: 11, Day: 5}, Time: nullsTestTime} ) func TestNullsJSON(t *testing.T) { for _, test := range []struct { in interface{} want string }{ {&NullInt64{Valid: true, Int64: 3}, `3`}, {&NullFloat64{Valid: true, Float64: 3.14}, `3.14`}, {&NullBool{Valid: true, Bool: true}, `true`}, {&NullString{Valid: true, StringVal: "foo"}, `"foo"`}, {&NullGeography{Valid: true, GeographyVal: "ST_GEOPOINT(47.649154, -122.350220)"}, `"ST_GEOPOINT(47.649154, -122.350220)"`}, {&NullTimestamp{Valid: true, Timestamp: testTimestamp}, `"2016-11-05T07:50:22.000000008Z"`}, {&NullDate{Valid: true, Date: testDate}, `"2016-11-05"`}, {&NullTime{Valid: true, Time: nullsTestTime}, `"07:50:22.000001"`}, {&NullDateTime{Valid: true, DateTime: nullsTestDateTime}, `"2016-11-05 07:50:22.000001"`}, {&NullInt64{}, `null`}, {&NullFloat64{}, `null`}, {&NullBool{}, `null`}, {&NullString{}, `null`}, {&NullGeography{}, `null`}, {&NullTimestamp{}, `null`}, {&NullDate{}, `null`}, {&NullTime{}, `null`}, {&NullDateTime{}, `null`}, } { bytes, err := json.Marshal(test.in) if err != nil { t.Fatal(err) } if got, want := string(bytes), test.want; got != want { t.Errorf("%#v: got %s, want %s", test.in, got, want) } typ := reflect.Indirect(reflect.ValueOf(test.in)).Type() value := reflect.New(typ).Interface() err = json.Unmarshal(bytes, value) if err != nil { t.Fatal(err) } if !testutil.Equal(value, test.in) { t.Errorf("%#v: got %#v, want %#v", test.in, value, test.in) } } } google-cloud-go-0.49.0/bigquery/oc_test.go000066400000000000000000000020441356504100700204060ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "context" "testing" "cloud.google.com/go/internal/testutil" ) func TestOCTracing(t *testing.T) { ctx := context.Background() client := getClient(t) defer client.Close() te := testutil.NewTestExporter() defer te.Unregister() q := client.Query("select *") q.Run(ctx) // Doesn't matter if we get an error; span should be created either way if len(te.Spans) == 0 { t.Fatalf("Expected some spans to be created, but got %d", 0) } } google-cloud-go-0.49.0/bigquery/params.go000066400000000000000000000251071356504100700202360ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "encoding/base64" "errors" "fmt" "math/big" "reflect" "regexp" "time" "cloud.google.com/go/civil" "cloud.google.com/go/internal/fields" bq "google.golang.org/api/bigquery/v2" ) var ( // See https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#timestamp-type. timestampFormat = "2006-01-02 15:04:05.999999-07:00" // See https://cloud.google.com/bigquery/docs/reference/rest/v2/tables#schema.fields.name validFieldName = regexp.MustCompile("^[a-zA-Z_][a-zA-Z0-9_]{0,127}$") ) const nullableTagOption = "nullable" func bqTagParser(t reflect.StructTag) (name string, keep bool, other interface{}, err error) { name, keep, opts, err := fields.ParseStandardTag("bigquery", t) if err != nil { return "", false, nil, err } if name != "" && !validFieldName.MatchString(name) { return "", false, nil, invalidFieldNameError(name) } for _, opt := range opts { if opt != nullableTagOption { return "", false, nil, fmt.Errorf( "bigquery: invalid tag option %q. The only valid option is %q", opt, nullableTagOption) } } return name, keep, opts, nil } type invalidFieldNameError string func (e invalidFieldNameError) Error() string { return fmt.Sprintf("bigquery: invalid name %q of field in struct", string(e)) } var fieldCache = fields.NewCache(bqTagParser, nil, nil) var ( int64ParamType = &bq.QueryParameterType{Type: "INT64"} float64ParamType = &bq.QueryParameterType{Type: "FLOAT64"} boolParamType = &bq.QueryParameterType{Type: "BOOL"} stringParamType = &bq.QueryParameterType{Type: "STRING"} bytesParamType = &bq.QueryParameterType{Type: "BYTES"} dateParamType = &bq.QueryParameterType{Type: "DATE"} timeParamType = &bq.QueryParameterType{Type: "TIME"} dateTimeParamType = &bq.QueryParameterType{Type: "DATETIME"} timestampParamType = &bq.QueryParameterType{Type: "TIMESTAMP"} numericParamType = &bq.QueryParameterType{Type: "NUMERIC"} ) var ( typeOfDate = reflect.TypeOf(civil.Date{}) typeOfTime = reflect.TypeOf(civil.Time{}) typeOfDateTime = reflect.TypeOf(civil.DateTime{}) typeOfGoTime = reflect.TypeOf(time.Time{}) typeOfRat = reflect.TypeOf(&big.Rat{}) ) // A QueryParameter is a parameter to a query. type QueryParameter struct { // Name is used for named parameter mode. // It must match the name in the query case-insensitively. Name string // Value is the value of the parameter. // // When you create a QueryParameter to send to BigQuery, the following Go types // are supported, with their corresponding Bigquery types: // int, int8, int16, int32, int64, uint8, uint16, uint32: INT64 // Note that uint, uint64 and uintptr are not supported, because // they may contain values that cannot fit into a 64-bit signed integer. // float32, float64: FLOAT64 // bool: BOOL // string: STRING // []byte: BYTES // time.Time: TIMESTAMP // *big.Rat: NUMERIC // Arrays and slices of the above. // Structs of the above. Only the exported fields are used. // // BigQuery does not support params of type GEOGRAPHY. For users wishing // to parameterize Geography values, use string parameters and cast in the // SQL query, e.g. `SELECT ST_GeogFromText(@string_param) as geo` // // When a QueryParameter is returned inside a QueryConfig from a call to // Job.Config: // Integers are of type int64. // Floating-point values are of type float64. // Arrays are of type []interface{}, regardless of the array element type. // Structs are of type map[string]interface{}. Value interface{} } func (p QueryParameter) toBQ() (*bq.QueryParameter, error) { pv, err := paramValue(reflect.ValueOf(p.Value)) if err != nil { return nil, err } pt, err := paramType(reflect.TypeOf(p.Value)) if err != nil { return nil, err } return &bq.QueryParameter{ Name: p.Name, ParameterValue: &pv, ParameterType: pt, }, nil } func paramType(t reflect.Type) (*bq.QueryParameterType, error) { if t == nil { return nil, errors.New("bigquery: nil parameter") } switch t { case typeOfDate: return dateParamType, nil case typeOfTime: return timeParamType, nil case typeOfDateTime: return dateTimeParamType, nil case typeOfGoTime: return timestampParamType, nil case typeOfRat: return numericParamType, nil } switch t.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint8, reflect.Uint16, reflect.Uint32: return int64ParamType, nil case reflect.Float32, reflect.Float64: return float64ParamType, nil case reflect.Bool: return boolParamType, nil case reflect.String: return stringParamType, nil case reflect.Slice: if t.Elem().Kind() == reflect.Uint8 { return bytesParamType, nil } fallthrough case reflect.Array: et, err := paramType(t.Elem()) if err != nil { return nil, err } return &bq.QueryParameterType{Type: "ARRAY", ArrayType: et}, nil case reflect.Ptr: if t.Elem().Kind() != reflect.Struct { break } t = t.Elem() fallthrough case reflect.Struct: var fts []*bq.QueryParameterTypeStructTypes fields, err := fieldCache.Fields(t) if err != nil { return nil, err } for _, f := range fields { pt, err := paramType(f.Type) if err != nil { return nil, err } fts = append(fts, &bq.QueryParameterTypeStructTypes{ Name: f.Name, Type: pt, }) } return &bq.QueryParameterType{Type: "STRUCT", StructTypes: fts}, nil } return nil, fmt.Errorf("bigquery: Go type %s cannot be represented as a parameter type", t) } func paramValue(v reflect.Value) (bq.QueryParameterValue, error) { var res bq.QueryParameterValue if !v.IsValid() { return res, errors.New("bigquery: nil parameter") } t := v.Type() switch t { case typeOfDate: res.Value = v.Interface().(civil.Date).String() return res, nil case typeOfTime: // civil.Time has nanosecond resolution, but BigQuery TIME only microsecond. // (If we send nanoseconds, then when we try to read the result we get "query job // missing destination table"). res.Value = CivilTimeString(v.Interface().(civil.Time)) return res, nil case typeOfDateTime: res.Value = CivilDateTimeString(v.Interface().(civil.DateTime)) return res, nil case typeOfGoTime: res.Value = v.Interface().(time.Time).Format(timestampFormat) return res, nil case typeOfRat: res.Value = NumericString(v.Interface().(*big.Rat)) return res, nil } switch t.Kind() { case reflect.Slice: if t.Elem().Kind() == reflect.Uint8 { res.Value = base64.StdEncoding.EncodeToString(v.Interface().([]byte)) return res, nil } fallthrough case reflect.Array: var vals []*bq.QueryParameterValue for i := 0; i < v.Len(); i++ { val, err := paramValue(v.Index(i)) if err != nil { return bq.QueryParameterValue{}, err } vals = append(vals, &val) } return bq.QueryParameterValue{ArrayValues: vals}, nil case reflect.Ptr: if t.Elem().Kind() != reflect.Struct { return res, fmt.Errorf("bigquery: Go type %s cannot be represented as a parameter value", t) } t = t.Elem() v = v.Elem() if !v.IsValid() { // nil pointer becomes empty value return res, nil } fallthrough case reflect.Struct: fields, err := fieldCache.Fields(t) if err != nil { return bq.QueryParameterValue{}, err } res.StructValues = map[string]bq.QueryParameterValue{} for _, f := range fields { fv := v.FieldByIndex(f.Index) fp, err := paramValue(fv) if err != nil { return bq.QueryParameterValue{}, err } res.StructValues[f.Name] = fp } return res, nil } // None of the above: assume a scalar type. (If it's not a valid type, // paramType will catch the error.) res.Value = fmt.Sprint(v.Interface()) // Ensure empty string values are sent. if res.Value == "" { res.ForceSendFields = append(res.ForceSendFields, "Value") } return res, nil } func bqToQueryParameter(q *bq.QueryParameter) (QueryParameter, error) { p := QueryParameter{Name: q.Name} val, err := convertParamValue(q.ParameterValue, q.ParameterType) if err != nil { return QueryParameter{}, err } p.Value = val return p, nil } var paramTypeToFieldType = map[string]FieldType{ int64ParamType.Type: IntegerFieldType, float64ParamType.Type: FloatFieldType, boolParamType.Type: BooleanFieldType, stringParamType.Type: StringFieldType, bytesParamType.Type: BytesFieldType, dateParamType.Type: DateFieldType, timeParamType.Type: TimeFieldType, numericParamType.Type: NumericFieldType, } // Convert a parameter value from the service to a Go value. This is similar to, but // not quite the same as, converting data values. func convertParamValue(qval *bq.QueryParameterValue, qtype *bq.QueryParameterType) (interface{}, error) { switch qtype.Type { case "ARRAY": if qval == nil { return []interface{}(nil), nil } return convertParamArray(qval.ArrayValues, qtype.ArrayType) case "STRUCT": if qval == nil { return map[string]interface{}(nil), nil } return convertParamStruct(qval.StructValues, qtype.StructTypes) case "TIMESTAMP": return time.Parse(timestampFormat, qval.Value) case "DATETIME": return parseCivilDateTime(qval.Value) default: return convertBasicType(qval.Value, paramTypeToFieldType[qtype.Type]) } } // convertParamArray converts a query parameter array value to a Go value. It // always returns a []interface{}. func convertParamArray(elVals []*bq.QueryParameterValue, elType *bq.QueryParameterType) ([]interface{}, error) { var vals []interface{} for _, el := range elVals { val, err := convertParamValue(el, elType) if err != nil { return nil, err } vals = append(vals, val) } return vals, nil } // convertParamStruct converts a query parameter struct value into a Go value. It // always returns a map[string]interface{}. func convertParamStruct(sVals map[string]bq.QueryParameterValue, sTypes []*bq.QueryParameterTypeStructTypes) (map[string]interface{}, error) { vals := map[string]interface{}{} for _, st := range sTypes { if sv, ok := sVals[st.Name]; ok { val, err := convertParamValue(&sv, st.Type) if err != nil { return nil, err } vals[st.Name] = val } else { vals[st.Name] = nil } } return vals, nil } google-cloud-go-0.49.0/bigquery/params_test.go000066400000000000000000000230011356504100700212640ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "context" "errors" "math" "math/big" "reflect" "testing" "time" "cloud.google.com/go/civil" "cloud.google.com/go/internal/testutil" "github.com/google/go-cmp/cmp" bq "google.golang.org/api/bigquery/v2" ) var scalarTests = []struct { val interface{} // The Go value wantVal string // paramValue's desired output wantType *bq.QueryParameterType // paramType's desired output }{ {int64(0), "0", int64ParamType}, {3.14, "3.14", float64ParamType}, {3.14159e-87, "3.14159e-87", float64ParamType}, {true, "true", boolParamType}, {"string", "string", stringParamType}, {"\u65e5\u672c\u8a9e\n", "\u65e5\u672c\u8a9e\n", stringParamType}, {math.NaN(), "NaN", float64ParamType}, {[]byte("foo"), "Zm9v", bytesParamType}, // base64 encoding of "foo" {time.Date(2016, 3, 20, 4, 22, 9, 5000, time.FixedZone("neg1-2", -3720)), "2016-03-20 04:22:09.000005-01:02", timestampParamType}, {civil.Date{Year: 2016, Month: 3, Day: 20}, "2016-03-20", dateParamType}, {civil.Time{Hour: 4, Minute: 5, Second: 6, Nanosecond: 789000000}, "04:05:06.789000", timeParamType}, {civil.DateTime{Date: civil.Date{Year: 2016, Month: 3, Day: 20}, Time: civil.Time{Hour: 4, Minute: 5, Second: 6, Nanosecond: 789000000}}, "2016-03-20 04:05:06.789000", dateTimeParamType}, {big.NewRat(12345, 1000), "12.345000000", numericParamType}, } type ( S1 struct { A int B *S2 C bool } S2 struct { D string } ) var ( s1 = S1{ A: 1, B: &S2{D: "s"}, C: true, } s1ParamType = &bq.QueryParameterType{ Type: "STRUCT", StructTypes: []*bq.QueryParameterTypeStructTypes{ {Name: "A", Type: int64ParamType}, {Name: "B", Type: &bq.QueryParameterType{ Type: "STRUCT", StructTypes: []*bq.QueryParameterTypeStructTypes{ {Name: "D", Type: stringParamType}, }, }}, {Name: "C", Type: boolParamType}, }, } s1ParamValue = bq.QueryParameterValue{ StructValues: map[string]bq.QueryParameterValue{ "A": sval("1"), "B": { StructValues: map[string]bq.QueryParameterValue{ "D": sval("s"), }, }, "C": sval("true"), }, } s1ParamReturnValue = map[string]interface{}{ "A": int64(1), "B": map[string]interface{}{"D": "s"}, "C": true, } ) func sval(s string) bq.QueryParameterValue { return bq.QueryParameterValue{Value: s} } func TestParamValueScalar(t *testing.T) { for _, test := range scalarTests { got, err := paramValue(reflect.ValueOf(test.val)) if err != nil { t.Errorf("%v: got %v, want nil", test.val, err) continue } want := sval(test.wantVal) if !testutil.Equal(got, want) { t.Errorf("%v:\ngot %+v\nwant %+v", test.val, got, want) } } } func TestParamValueArray(t *testing.T) { qpv := bq.QueryParameterValue{ArrayValues: []*bq.QueryParameterValue{ {Value: "1"}, {Value: "2"}, }, } for _, test := range []struct { val interface{} want bq.QueryParameterValue }{ {[]int(nil), bq.QueryParameterValue{}}, {[]int{}, bq.QueryParameterValue{}}, {[]int{1, 2}, qpv}, {[2]int{1, 2}, qpv}, } { got, err := paramValue(reflect.ValueOf(test.val)) if err != nil { t.Fatal(err) } if !testutil.Equal(got, test.want) { t.Errorf("%#v:\ngot %+v\nwant %+v", test.val, got, test.want) } } } func TestParamValueStruct(t *testing.T) { got, err := paramValue(reflect.ValueOf(s1)) if err != nil { t.Fatal(err) } if !testutil.Equal(got, s1ParamValue) { t.Errorf("got %+v\nwant %+v", got, s1ParamValue) } } func TestParamValueErrors(t *testing.T) { // paramValue lets a few invalid types through, but paramType catches them. // Since we never call one without the other that's fine. for _, val := range []interface{}{nil, new([]int)} { _, err := paramValue(reflect.ValueOf(val)) if err == nil { t.Errorf("%v (%T): got nil, want error", val, val) } } } func TestParamType(t *testing.T) { for _, test := range scalarTests { got, err := paramType(reflect.TypeOf(test.val)) if err != nil { t.Fatal(err) } if !testutil.Equal(got, test.wantType) { t.Errorf("%v (%T): got %v, want %v", test.val, test.val, got, test.wantType) } } for _, test := range []struct { val interface{} want *bq.QueryParameterType }{ {uint32(32767), int64ParamType}, {[]byte("foo"), bytesParamType}, {[]int{}, &bq.QueryParameterType{Type: "ARRAY", ArrayType: int64ParamType}}, {[3]bool{}, &bq.QueryParameterType{Type: "ARRAY", ArrayType: boolParamType}}, {S1{}, s1ParamType}, } { got, err := paramType(reflect.TypeOf(test.val)) if err != nil { t.Fatal(err) } if !testutil.Equal(got, test.want) { t.Errorf("%v (%T): got %v, want %v", test.val, test.val, got, test.want) } } } func TestParamTypeErrors(t *testing.T) { for _, val := range []interface{}{ nil, uint(0), new([]int), make(chan int), } { _, err := paramType(reflect.TypeOf(val)) if err == nil { t.Errorf("%v (%T): got nil, want error", val, val) } } } func TestConvertParamValue(t *testing.T) { // Scalars. for _, test := range scalarTests { pval, err := paramValue(reflect.ValueOf(test.val)) if err != nil { t.Fatal(err) } ptype, err := paramType(reflect.TypeOf(test.val)) if err != nil { t.Fatal(err) } got, err := convertParamValue(&pval, ptype) if err != nil { t.Fatalf("convertParamValue(%+v, %+v): %v", pval, ptype, err) } if !testutil.Equal(got, test.val) { t.Errorf("%#v: got %#v", test.val, got) } } // Arrays. for _, test := range []struct { pval *bq.QueryParameterValue want []interface{} }{ { &bq.QueryParameterValue{}, nil, }, { &bq.QueryParameterValue{ ArrayValues: []*bq.QueryParameterValue{{Value: "1"}, {Value: "2"}}, }, []interface{}{int64(1), int64(2)}, }, } { ptype := &bq.QueryParameterType{Type: "ARRAY", ArrayType: int64ParamType} got, err := convertParamValue(test.pval, ptype) if err != nil { t.Fatalf("%+v: %v", test.pval, err) } if !testutil.Equal(got, test.want) { t.Errorf("%+v: got %+v, want %+v", test.pval, got, test.want) } } // Structs. got, err := convertParamValue(&s1ParamValue, s1ParamType) if err != nil { t.Fatal(err) } if !testutil.Equal(got, s1ParamReturnValue) { t.Errorf("got %+v, want %+v", got, s1ParamReturnValue) } } func TestIntegration_ScalarParam(t *testing.T) { roundToMicros := cmp.Transformer("RoundToMicros", func(t time.Time) time.Time { return t.Round(time.Microsecond) }) c := getClient(t) for _, test := range scalarTests { gotData, gotParam, err := paramRoundTrip(c, test.val) if err != nil { t.Fatal(err) } if !testutil.Equal(gotData, test.val, roundToMicros) { t.Errorf("\ngot %#v (%T)\nwant %#v (%T)", gotData, gotData, test.val, test.val) } if !testutil.Equal(gotParam, test.val, roundToMicros) { t.Errorf("\ngot %#v (%T)\nwant %#v (%T)", gotParam, gotParam, test.val, test.val) } } } func TestIntegration_OtherParam(t *testing.T) { c := getClient(t) for _, test := range []struct { val interface{} wantData interface{} wantParam interface{} }{ {[]int(nil), []Value(nil), []interface{}(nil)}, {[]int{}, []Value(nil), []interface{}(nil)}, { []int{1, 2}, []Value{int64(1), int64(2)}, []interface{}{int64(1), int64(2)}, }, { [3]int{1, 2, 3}, []Value{int64(1), int64(2), int64(3)}, []interface{}{int64(1), int64(2), int64(3)}, }, { S1{}, []Value{int64(0), nil, false}, map[string]interface{}{ "A": int64(0), "B": nil, "C": false, }, }, { s1, []Value{int64(1), []Value{"s"}, true}, s1ParamReturnValue, }, } { gotData, gotParam, err := paramRoundTrip(c, test.val) if err != nil { t.Fatal(err) } if !testutil.Equal(gotData, test.wantData) { t.Errorf("%#v:\ngot %#v (%T)\nwant %#v (%T)", test.val, gotData, gotData, test.wantData, test.wantData) } if !testutil.Equal(gotParam, test.wantParam) { t.Errorf("%#v:\ngot %#v (%T)\nwant %#v (%T)", test.val, gotParam, gotParam, test.wantParam, test.wantParam) } } } // paramRoundTrip passes x as a query parameter to BigQuery. It returns // the resulting data value from running the query and the parameter value from // the returned job configuration. func paramRoundTrip(c *Client, x interface{}) (data Value, param interface{}, err error) { ctx := context.Background() q := c.Query("select ?") q.Parameters = []QueryParameter{{Value: x}} job, err := q.Run(ctx) if err != nil { return nil, nil, err } it, err := job.Read(ctx) if err != nil { return nil, nil, err } var val []Value err = it.Next(&val) if err != nil { return nil, nil, err } if len(val) != 1 { return nil, nil, errors.New("wrong number of values") } conf, err := job.Config() if err != nil { return nil, nil, err } return val[0], conf.(*QueryConfig).Parameters[0].Value, nil } func TestQueryParameter_toBQ(t *testing.T) { in := QueryParameter{Name: "name", Value: ""} want := []string{"Value"} q, err := in.toBQ() if err != nil { t.Fatalf("expected no error, got %v", err) } got := q.ParameterValue.ForceSendFields if !cmp.Equal(want, got) { t.Fatalf("want %v, got %v", want, got) } } google-cloud-go-0.49.0/bigquery/query.go000066400000000000000000000275461356504100700201310ustar00rootroot00000000000000// Copyright 2015 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "context" "errors" "cloud.google.com/go/internal/trace" bq "google.golang.org/api/bigquery/v2" ) // QueryConfig holds the configuration for a query job. type QueryConfig struct { // Dst is the table into which the results of the query will be written. // If this field is nil, a temporary table will be created. Dst *Table // The query to execute. See https://cloud.google.com/bigquery/query-reference for details. Q string // DefaultProjectID and DefaultDatasetID specify the dataset to use for unqualified table names in the query. // If DefaultProjectID is set, DefaultDatasetID must also be set. DefaultProjectID string DefaultDatasetID string // TableDefinitions describes data sources outside of BigQuery. // The map keys may be used as table names in the query string. // // When a QueryConfig is returned from Job.Config, the map values // are always of type *ExternalDataConfig. TableDefinitions map[string]ExternalData // CreateDisposition specifies the circumstances under which the destination table will be created. // The default is CreateIfNeeded. CreateDisposition TableCreateDisposition // WriteDisposition specifies how existing data in the destination table is treated. // The default is WriteEmpty. WriteDisposition TableWriteDisposition // DisableQueryCache prevents results being fetched from the query cache. // If this field is false, results are fetched from the cache if they are available. // The query cache is a best-effort cache that is flushed whenever tables in the query are modified. // Cached results are only available when TableID is unspecified in the query's destination Table. // For more information, see https://cloud.google.com/bigquery/querying-data#querycaching DisableQueryCache bool // DisableFlattenedResults prevents results being flattened. // If this field is false, results from nested and repeated fields are flattened. // DisableFlattenedResults implies AllowLargeResults // For more information, see https://cloud.google.com/bigquery/docs/data#nested DisableFlattenedResults bool // AllowLargeResults allows the query to produce arbitrarily large result tables. // The destination must be a table. // When using this option, queries will take longer to execute, even if the result set is small. // For additional limitations, see https://cloud.google.com/bigquery/querying-data#largequeryresults AllowLargeResults bool // Priority specifies the priority with which to schedule the query. // The default priority is InteractivePriority. // For more information, see https://cloud.google.com/bigquery/querying-data#batchqueries Priority QueryPriority // MaxBillingTier sets the maximum billing tier for a Query. // Queries that have resource usage beyond this tier will fail (without // incurring a charge). If this field is zero, the project default will be used. MaxBillingTier int // MaxBytesBilled limits the number of bytes billed for // this job. Queries that would exceed this limit will fail (without incurring // a charge). // If this field is less than 1, the project default will be // used. MaxBytesBilled int64 // UseStandardSQL causes the query to use standard SQL. The default. // Deprecated: use UseLegacySQL. UseStandardSQL bool // UseLegacySQL causes the query to use legacy SQL. UseLegacySQL bool // Parameters is a list of query parameters. The presence of parameters // implies the use of standard SQL. // If the query uses positional syntax ("?"), then no parameter may have a name. // If the query uses named syntax ("@p"), then all parameters must have names. // It is illegal to mix positional and named syntax. Parameters []QueryParameter // TimePartitioning specifies time-based partitioning // for the destination table. TimePartitioning *TimePartitioning // RangePartitioning specifies integer range-based partitioning // for the destination table. RangePartitioning *RangePartitioning // Clustering specifies the data clustering configuration for the destination table. Clustering *Clustering // The labels associated with this job. Labels map[string]string // If true, don't actually run this job. A valid query will return a mostly // empty response with some processing statistics, while an invalid query will // return the same error it would if it wasn't a dry run. // // Query.Read will fail with dry-run queries. Call Query.Run instead, and then // call LastStatus on the returned job to get statistics. Calling Status on a // dry-run job will fail. DryRun bool // Custom encryption configuration (e.g., Cloud KMS keys). DestinationEncryptionConfig *EncryptionConfig // Allows the schema of the destination table to be updated as a side effect of // the query job. SchemaUpdateOptions []string } func (qc *QueryConfig) toBQ() (*bq.JobConfiguration, error) { qconf := &bq.JobConfigurationQuery{ Query: qc.Q, CreateDisposition: string(qc.CreateDisposition), WriteDisposition: string(qc.WriteDisposition), AllowLargeResults: qc.AllowLargeResults, Priority: string(qc.Priority), MaximumBytesBilled: qc.MaxBytesBilled, TimePartitioning: qc.TimePartitioning.toBQ(), RangePartitioning: qc.RangePartitioning.toBQ(), Clustering: qc.Clustering.toBQ(), DestinationEncryptionConfiguration: qc.DestinationEncryptionConfig.toBQ(), SchemaUpdateOptions: qc.SchemaUpdateOptions, } if len(qc.TableDefinitions) > 0 { qconf.TableDefinitions = make(map[string]bq.ExternalDataConfiguration) } for name, data := range qc.TableDefinitions { qconf.TableDefinitions[name] = data.toBQ() } if qc.DefaultProjectID != "" || qc.DefaultDatasetID != "" { qconf.DefaultDataset = &bq.DatasetReference{ DatasetId: qc.DefaultDatasetID, ProjectId: qc.DefaultProjectID, } } if tier := int64(qc.MaxBillingTier); tier > 0 { qconf.MaximumBillingTier = &tier } f := false if qc.DisableQueryCache { qconf.UseQueryCache = &f } if qc.DisableFlattenedResults { qconf.FlattenResults = &f // DisableFlattenResults implies AllowLargeResults. qconf.AllowLargeResults = true } if qc.UseStandardSQL && qc.UseLegacySQL { return nil, errors.New("bigquery: cannot provide both UseStandardSQL and UseLegacySQL") } if len(qc.Parameters) > 0 && qc.UseLegacySQL { return nil, errors.New("bigquery: cannot provide both Parameters (implying standard SQL) and UseLegacySQL") } ptrue := true pfalse := false if qc.UseLegacySQL { qconf.UseLegacySql = &ptrue } else { qconf.UseLegacySql = &pfalse } if qc.Dst != nil && !qc.Dst.implicitTable() { qconf.DestinationTable = qc.Dst.toBQ() } for _, p := range qc.Parameters { qp, err := p.toBQ() if err != nil { return nil, err } qconf.QueryParameters = append(qconf.QueryParameters, qp) } return &bq.JobConfiguration{ Labels: qc.Labels, DryRun: qc.DryRun, Query: qconf, }, nil } func bqToQueryConfig(q *bq.JobConfiguration, c *Client) (*QueryConfig, error) { qq := q.Query qc := &QueryConfig{ Labels: q.Labels, DryRun: q.DryRun, Q: qq.Query, CreateDisposition: TableCreateDisposition(qq.CreateDisposition), WriteDisposition: TableWriteDisposition(qq.WriteDisposition), AllowLargeResults: qq.AllowLargeResults, Priority: QueryPriority(qq.Priority), MaxBytesBilled: qq.MaximumBytesBilled, UseLegacySQL: qq.UseLegacySql == nil || *qq.UseLegacySql, TimePartitioning: bqToTimePartitioning(qq.TimePartitioning), RangePartitioning: bqToRangePartitioning(qq.RangePartitioning), Clustering: bqToClustering(qq.Clustering), DestinationEncryptionConfig: bqToEncryptionConfig(qq.DestinationEncryptionConfiguration), SchemaUpdateOptions: qq.SchemaUpdateOptions, } qc.UseStandardSQL = !qc.UseLegacySQL if len(qq.TableDefinitions) > 0 { qc.TableDefinitions = make(map[string]ExternalData) } for name, qedc := range qq.TableDefinitions { edc, err := bqToExternalDataConfig(&qedc) if err != nil { return nil, err } qc.TableDefinitions[name] = edc } if qq.DefaultDataset != nil { qc.DefaultProjectID = qq.DefaultDataset.ProjectId qc.DefaultDatasetID = qq.DefaultDataset.DatasetId } if qq.MaximumBillingTier != nil { qc.MaxBillingTier = int(*qq.MaximumBillingTier) } if qq.UseQueryCache != nil && !*qq.UseQueryCache { qc.DisableQueryCache = true } if qq.FlattenResults != nil && !*qq.FlattenResults { qc.DisableFlattenedResults = true } if qq.DestinationTable != nil { qc.Dst = bqToTable(qq.DestinationTable, c) } for _, qp := range qq.QueryParameters { p, err := bqToQueryParameter(qp) if err != nil { return nil, err } qc.Parameters = append(qc.Parameters, p) } return qc, nil } // QueryPriority specifies a priority with which a query is to be executed. type QueryPriority string const ( // BatchPriority specifies that the query should be scheduled with the // batch priority. BigQuery queues each batch query on your behalf, and // starts the query as soon as idle resources are available, usually within // a few minutes. If BigQuery hasn't started the query within 24 hours, // BigQuery changes the job priority to interactive. Batch queries don't // count towards your concurrent rate limit, which can make it easier to // start many queries at once. // // More information can be found at https://cloud.google.com/bigquery/docs/running-queries#batchqueries. BatchPriority QueryPriority = "BATCH" // InteractivePriority specifies that the query should be scheduled with // interactive priority, which means that the query is executed as soon as // possible. Interactive queries count towards your concurrent rate limit // and your daily limit. It is the default priority with which queries get // executed. // // More information can be found at https://cloud.google.com/bigquery/docs/running-queries#queries. InteractivePriority QueryPriority = "INTERACTIVE" ) // A Query queries data from a BigQuery table. Use Client.Query to create a Query. type Query struct { JobIDConfig QueryConfig client *Client } // Query creates a query with string q. // The returned Query may optionally be further configured before its Run method is called. func (c *Client) Query(q string) *Query { return &Query{ client: c, QueryConfig: QueryConfig{Q: q}, } } // Run initiates a query job. func (q *Query) Run(ctx context.Context) (j *Job, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Query.Run") defer func() { trace.EndSpan(ctx, err) }() job, err := q.newJob() if err != nil { return nil, err } j, err = q.client.insertJob(ctx, job, nil) if err != nil { return nil, err } return j, nil } func (q *Query) newJob() (*bq.Job, error) { config, err := q.QueryConfig.toBQ() if err != nil { return nil, err } return &bq.Job{ JobReference: q.JobIDConfig.createJobRef(q.client), Configuration: config, }, nil } // Read submits a query for execution and returns the results via a RowIterator. // It is a shorthand for Query.Run followed by Job.Read. func (q *Query) Read(ctx context.Context) (*RowIterator, error) { job, err := q.Run(ctx) if err != nil { return nil, err } return job.Read(ctx) } google-cloud-go-0.49.0/bigquery/query_test.go000066400000000000000000000303141356504100700211530ustar00rootroot00000000000000// Copyright 2015 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "testing" "time" "cloud.google.com/go/internal/testutil" "github.com/google/go-cmp/cmp" bq "google.golang.org/api/bigquery/v2" ) func defaultQueryJob() *bq.Job { pfalse := false return &bq.Job{ JobReference: &bq.JobReference{JobId: "RANDOM", ProjectId: "client-project-id"}, Configuration: &bq.JobConfiguration{ Query: &bq.JobConfigurationQuery{ DestinationTable: &bq.TableReference{ ProjectId: "client-project-id", DatasetId: "dataset-id", TableId: "table-id", }, Query: "query string", DefaultDataset: &bq.DatasetReference{ ProjectId: "def-project-id", DatasetId: "def-dataset-id", }, UseLegacySql: &pfalse, }, }, } } var defaultQuery = &QueryConfig{ Q: "query string", DefaultProjectID: "def-project-id", DefaultDatasetID: "def-dataset-id", } func TestQuery(t *testing.T) { defer fixRandomID("RANDOM")() c := &Client{ projectID: "client-project-id", } testCases := []struct { dst *Table src *QueryConfig jobIDConfig JobIDConfig want *bq.Job }{ { dst: c.Dataset("dataset-id").Table("table-id"), src: defaultQuery, want: defaultQueryJob(), }, { dst: c.Dataset("dataset-id").Table("table-id"), src: &QueryConfig{ Q: "query string", Labels: map[string]string{"a": "b"}, DryRun: true, }, want: func() *bq.Job { j := defaultQueryJob() j.Configuration.Labels = map[string]string{"a": "b"} j.Configuration.DryRun = true j.Configuration.Query.DefaultDataset = nil return j }(), }, { dst: c.Dataset("dataset-id").Table("table-id"), jobIDConfig: JobIDConfig{JobID: "jobID", AddJobIDSuffix: true}, src: &QueryConfig{Q: "query string"}, want: func() *bq.Job { j := defaultQueryJob() j.Configuration.Query.DefaultDataset = nil j.JobReference.JobId = "jobID-RANDOM" return j }(), }, { dst: &Table{}, src: defaultQuery, want: func() *bq.Job { j := defaultQueryJob() j.Configuration.Query.DestinationTable = nil return j }(), }, { dst: c.Dataset("dataset-id").Table("table-id"), src: &QueryConfig{ Q: "query string", TableDefinitions: map[string]ExternalData{ "atable": func() *GCSReference { g := NewGCSReference("uri") g.AllowJaggedRows = true g.AllowQuotedNewlines = true g.Compression = Gzip g.Encoding = UTF_8 g.FieldDelimiter = ";" g.IgnoreUnknownValues = true g.MaxBadRecords = 1 g.Quote = "'" g.SkipLeadingRows = 2 g.Schema = Schema{{Name: "name", Type: StringFieldType}} return g }(), }, }, want: func() *bq.Job { j := defaultQueryJob() j.Configuration.Query.DefaultDataset = nil td := make(map[string]bq.ExternalDataConfiguration) quote := "'" td["atable"] = bq.ExternalDataConfiguration{ Compression: "GZIP", IgnoreUnknownValues: true, MaxBadRecords: 1, SourceFormat: "CSV", // must be explicitly set. SourceUris: []string{"uri"}, CsvOptions: &bq.CsvOptions{ AllowJaggedRows: true, AllowQuotedNewlines: true, Encoding: "UTF-8", FieldDelimiter: ";", SkipLeadingRows: 2, Quote: "e, }, Schema: &bq.TableSchema{ Fields: []*bq.TableFieldSchema{ {Name: "name", Type: "STRING"}, }, }, } j.Configuration.Query.TableDefinitions = td return j }(), }, { dst: &Table{ ProjectID: "project-id", DatasetID: "dataset-id", TableID: "table-id", }, src: &QueryConfig{ Q: "query string", DefaultProjectID: "def-project-id", DefaultDatasetID: "def-dataset-id", CreateDisposition: CreateNever, WriteDisposition: WriteTruncate, }, want: func() *bq.Job { j := defaultQueryJob() j.Configuration.Query.DestinationTable.ProjectId = "project-id" j.Configuration.Query.WriteDisposition = "WRITE_TRUNCATE" j.Configuration.Query.CreateDisposition = "CREATE_NEVER" return j }(), }, { dst: c.Dataset("dataset-id").Table("table-id"), src: &QueryConfig{ Q: "query string", DefaultProjectID: "def-project-id", DefaultDatasetID: "def-dataset-id", DisableQueryCache: true, }, want: func() *bq.Job { j := defaultQueryJob() f := false j.Configuration.Query.UseQueryCache = &f return j }(), }, { dst: c.Dataset("dataset-id").Table("table-id"), src: &QueryConfig{ Q: "query string", DefaultProjectID: "def-project-id", DefaultDatasetID: "def-dataset-id", AllowLargeResults: true, }, want: func() *bq.Job { j := defaultQueryJob() j.Configuration.Query.AllowLargeResults = true return j }(), }, { dst: c.Dataset("dataset-id").Table("table-id"), src: &QueryConfig{ Q: "query string", DefaultProjectID: "def-project-id", DefaultDatasetID: "def-dataset-id", DisableFlattenedResults: true, }, want: func() *bq.Job { j := defaultQueryJob() f := false j.Configuration.Query.FlattenResults = &f j.Configuration.Query.AllowLargeResults = true return j }(), }, { dst: c.Dataset("dataset-id").Table("table-id"), src: &QueryConfig{ Q: "query string", DefaultProjectID: "def-project-id", DefaultDatasetID: "def-dataset-id", Priority: QueryPriority("low"), }, want: func() *bq.Job { j := defaultQueryJob() j.Configuration.Query.Priority = "low" return j }(), }, { dst: c.Dataset("dataset-id").Table("table-id"), src: &QueryConfig{ Q: "query string", DefaultProjectID: "def-project-id", DefaultDatasetID: "def-dataset-id", MaxBillingTier: 3, MaxBytesBilled: 5, }, want: func() *bq.Job { j := defaultQueryJob() tier := int64(3) j.Configuration.Query.MaximumBillingTier = &tier j.Configuration.Query.MaximumBytesBilled = 5 return j }(), }, { dst: c.Dataset("dataset-id").Table("table-id"), src: &QueryConfig{ Q: "query string", DefaultProjectID: "def-project-id", DefaultDatasetID: "def-dataset-id", UseStandardSQL: true, }, want: defaultQueryJob(), }, { dst: c.Dataset("dataset-id").Table("table-id"), src: &QueryConfig{ Q: "query string", DefaultProjectID: "def-project-id", DefaultDatasetID: "def-dataset-id", UseLegacySQL: true, }, want: func() *bq.Job { j := defaultQueryJob() ptrue := true j.Configuration.Query.UseLegacySql = &ptrue j.Configuration.Query.ForceSendFields = nil return j }(), }, { dst: c.Dataset("dataset-id").Table("table-id"), src: &QueryConfig{ Q: "query string", DefaultProjectID: "def-project-id", DefaultDatasetID: "def-dataset-id", TimePartitioning: &TimePartitioning{}, }, want: func() *bq.Job { j := defaultQueryJob() j.Configuration.Query.ForceSendFields = nil j.Configuration.Query.TimePartitioning = &bq.TimePartitioning{ Type: "DAY", } return j }(), }, { dst: c.Dataset("dataset-id").Table("table-id"), src: &QueryConfig{ Q: "query string", DefaultProjectID: "def-project-id", DefaultDatasetID: "def-dataset-id", RangePartitioning: &RangePartitioning{ Field: "foo", Range: &RangePartitioningRange{ Start: 1, End: 2, Interval: 3, }, }, }, want: func() *bq.Job { j := defaultQueryJob() j.Configuration.Query.ForceSendFields = nil j.Configuration.Query.RangePartitioning = &bq.RangePartitioning{ Field: "foo", Range: &bq.RangePartitioningRange{ Start: 1, End: 2, Interval: 3, }, } return j }(), }, } for i, tc := range testCases { query := c.Query("") query.JobIDConfig = tc.jobIDConfig query.QueryConfig = *tc.src query.Dst = tc.dst got, err := query.newJob() if err != nil { t.Errorf("#%d: err calling query: %v", i, err) continue } checkJob(t, i, got, tc.want) // Round-trip. jc, err := bqToJobConfig(got.Configuration, c) if err != nil { t.Fatalf("#%d: %v", i, err) } wantConfig := query.QueryConfig // We set AllowLargeResults to true when DisableFlattenedResults is true. if wantConfig.DisableFlattenedResults { wantConfig.AllowLargeResults = true } // A QueryConfig with neither UseXXXSQL field set is equivalent // to one where UseStandardSQL = true. if !wantConfig.UseLegacySQL && !wantConfig.UseStandardSQL { wantConfig.UseStandardSQL = true } // Treat nil and empty tables the same, and ignore the client. tableEqual := func(t1, t2 *Table) bool { if t1 == nil { t1 = &Table{} } if t2 == nil { t2 = &Table{} } return t1.ProjectID == t2.ProjectID && t1.DatasetID == t2.DatasetID && t1.TableID == t2.TableID } // A table definition that is a GCSReference round-trips as an ExternalDataConfig. // TODO(jba): see if there is a way to express this with a transformer. gcsRefToEDC := func(g *GCSReference) *ExternalDataConfig { q := g.toBQ() e, _ := bqToExternalDataConfig(&q) return e } externalDataEqual := func(e1, e2 ExternalData) bool { if r, ok := e1.(*GCSReference); ok { e1 = gcsRefToEDC(r) } if r, ok := e2.(*GCSReference); ok { e2 = gcsRefToEDC(r) } return cmp.Equal(e1, e2) } diff := testutil.Diff(jc.(*QueryConfig), &wantConfig, cmp.Comparer(tableEqual), cmp.Comparer(externalDataEqual), ) if diff != "" { t.Errorf("#%d: (got=-, want=+:\n%s", i, diff) } } } func TestConfiguringQuery(t *testing.T) { c := &Client{ projectID: "project-id", } query := c.Query("q") query.JobID = "ajob" query.DefaultProjectID = "def-project-id" query.DefaultDatasetID = "def-dataset-id" query.TimePartitioning = &TimePartitioning{Expiration: 1234 * time.Second, Field: "f"} query.Clustering = &Clustering{ Fields: []string{"cfield1"}, } query.DestinationEncryptionConfig = &EncryptionConfig{KMSKeyName: "keyName"} query.SchemaUpdateOptions = []string{"ALLOW_FIELD_ADDITION"} // Note: Other configuration fields are tested in other tests above. // A lot of that can be consolidated once Client.Copy is gone. pfalse := false want := &bq.Job{ Configuration: &bq.JobConfiguration{ Query: &bq.JobConfigurationQuery{ Query: "q", DefaultDataset: &bq.DatasetReference{ ProjectId: "def-project-id", DatasetId: "def-dataset-id", }, UseLegacySql: &pfalse, TimePartitioning: &bq.TimePartitioning{ExpirationMs: 1234000, Field: "f", Type: "DAY"}, Clustering: &bq.Clustering{Fields: []string{"cfield1"}}, DestinationEncryptionConfiguration: &bq.EncryptionConfiguration{KmsKeyName: "keyName"}, SchemaUpdateOptions: []string{"ALLOW_FIELD_ADDITION"}, }, }, JobReference: &bq.JobReference{ JobId: "ajob", ProjectId: "project-id", }, } got, err := query.newJob() if err != nil { t.Fatalf("err calling Query.newJob: %v", err) } if diff := testutil.Diff(got, want); diff != "" { t.Errorf("querying: -got +want:\n%s", diff) } } func TestQueryLegacySQL(t *testing.T) { c := &Client{projectID: "project-id"} q := c.Query("q") q.UseStandardSQL = true q.UseLegacySQL = true _, err := q.newJob() if err == nil { t.Error("UseStandardSQL and UseLegacySQL: got nil, want error") } q = c.Query("q") q.Parameters = []QueryParameter{{Name: "p", Value: 3}} q.UseLegacySQL = true _, err = q.newJob() if err == nil { t.Error("Parameters and UseLegacySQL: got nil, want error") } } google-cloud-go-0.49.0/bigquery/random.go000066400000000000000000000030631356504100700202300ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "math/rand" "os" "sync" "time" ) // Support for random values (typically job IDs and insert IDs). const alphanum = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" var ( rngMu sync.Mutex rng = rand.New(rand.NewSource(time.Now().UnixNano() ^ int64(os.Getpid()))) ) // For testing. var randomIDFn = randomID // As of August 2017, the BigQuery service uses 27 alphanumeric characters for // suffixes. const randomIDLen = 27 func randomID() string { // This is used for both job IDs and insert IDs. var b [randomIDLen]byte rngMu.Lock() for i := 0; i < len(b); i++ { b[i] = alphanum[rng.Intn(len(alphanum))] } rngMu.Unlock() return string(b[:]) } // Seed seeds this package's random number generator, used for generating job and // insert IDs. Use Seed to obtain repeatable, deterministic behavior from bigquery // clients. Seed should be called before any clients are created. func Seed(s int64) { rng = rand.New(rand.NewSource(s)) } google-cloud-go-0.49.0/bigquery/read_test.go000066400000000000000000000147731356504100700207340ustar00rootroot00000000000000// Copyright 2015 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "context" "errors" "testing" "cloud.google.com/go/internal/testutil" "github.com/google/go-cmp/cmp" bq "google.golang.org/api/bigquery/v2" "google.golang.org/api/iterator" ) type pageFetcherArgs struct { table *Table schema Schema startIndex uint64 pageSize int64 pageToken string } // pageFetcherReadStub services read requests by returning data from an in-memory list of values. type pageFetcherReadStub struct { // values and pageTokens are used as sources of data to return in response to calls to readTabledata or readQuery. values [][][]Value // contains pages / rows / columns. pageTokens map[string]string // maps incoming page token to returned page token. // arguments are recorded for later inspection. calls []pageFetcherArgs } func (s *pageFetcherReadStub) fetchPage(ctx context.Context, t *Table, schema Schema, startIndex uint64, pageSize int64, pageToken string) (*fetchPageResult, error) { s.calls = append(s.calls, pageFetcherArgs{t, schema, startIndex, pageSize, pageToken}) result := &fetchPageResult{ pageToken: s.pageTokens[pageToken], rows: s.values[0], } s.values = s.values[1:] return result, nil } func waitForQueryStub(context.Context, string) (Schema, uint64, error) { return nil, 1, nil } func TestRead(t *testing.T) { // The data for the service stub to return is populated for each test case in the testCases for loop. ctx := context.Background() c := &Client{projectID: "project-id"} pf := &pageFetcherReadStub{} queryJob := &Job{ projectID: "project-id", jobID: "job-id", c: c, config: &bq.JobConfiguration{ Query: &bq.JobConfigurationQuery{ DestinationTable: &bq.TableReference{ ProjectId: "project-id", DatasetId: "dataset-id", TableId: "table-id", }, }, }, } for _, readFunc := range []func() *RowIterator{ func() *RowIterator { return c.Dataset("dataset-id").Table("table-id").read(ctx, pf.fetchPage) }, func() *RowIterator { it, err := queryJob.read(ctx, waitForQueryStub, pf.fetchPage) if err != nil { t.Fatal(err) } return it }, } { testCases := []struct { data [][][]Value pageTokens map[string]string want [][]Value }{ { data: [][][]Value{{{1, 2}, {11, 12}}, {{30, 40}, {31, 41}}}, pageTokens: map[string]string{"": "a", "a": ""}, want: [][]Value{{1, 2}, {11, 12}, {30, 40}, {31, 41}}, }, { data: [][][]Value{{{1, 2}, {11, 12}}, {{30, 40}, {31, 41}}}, pageTokens: map[string]string{"": ""}, // no more pages after first one. want: [][]Value{{1, 2}, {11, 12}}, }, } for _, tc := range testCases { pf.values = tc.data pf.pageTokens = tc.pageTokens if got, ok := collectValues(t, readFunc()); ok { if !testutil.Equal(got, tc.want) { t.Errorf("reading: got:\n%v\nwant:\n%v", got, tc.want) } } } } } func collectValues(t *testing.T, it *RowIterator) ([][]Value, bool) { var got [][]Value for { var vals []Value err := it.Next(&vals) if err == iterator.Done { break } if err != nil { t.Errorf("err calling Next: %v", err) return nil, false } got = append(got, vals) } return got, true } func TestNoMoreValues(t *testing.T) { c := &Client{projectID: "project-id"} pf := &pageFetcherReadStub{ values: [][][]Value{{{1, 2}, {11, 12}}}, } it := c.Dataset("dataset-id").Table("table-id").read(context.Background(), pf.fetchPage) var vals []Value // We expect to retrieve two values and then fail on the next attempt. if err := it.Next(&vals); err != nil { t.Fatalf("Next: got: %v: want: nil", err) } if err := it.Next(&vals); err != nil { t.Fatalf("Next: got: %v: want: nil", err) } if err := it.Next(&vals); err != iterator.Done { t.Fatalf("Next: got: %v: want: iterator.Done", err) } } var errBang = errors.New("bang") func errorFetchPage(context.Context, *Table, Schema, uint64, int64, string) (*fetchPageResult, error) { return nil, errBang } func TestReadError(t *testing.T) { // test that service read errors are propagated back to the caller. c := &Client{projectID: "project-id"} it := c.Dataset("dataset-id").Table("table-id").read(context.Background(), errorFetchPage) var vals []Value if err := it.Next(&vals); err != errBang { t.Fatalf("Get: got: %v: want: %v", err, errBang) } } func TestReadTabledataOptions(t *testing.T) { // test that read options are propagated. s := &pageFetcherReadStub{ values: [][][]Value{{{1, 2}}}, } c := &Client{projectID: "project-id"} tr := c.Dataset("dataset-id").Table("table-id") it := tr.read(context.Background(), s.fetchPage) it.PageInfo().MaxSize = 5 var vals []Value if err := it.Next(&vals); err != nil { t.Fatal(err) } want := []pageFetcherArgs{{ table: tr, pageSize: 5, pageToken: "", }} if diff := testutil.Diff(s.calls, want, cmp.AllowUnexported(pageFetcherArgs{}, pageFetcherReadStub{}, Table{}, Client{})); diff != "" { t.Errorf("reading (got=-, want=+):\n%s", diff) } } func TestReadQueryOptions(t *testing.T) { // test that read options are propagated. c := &Client{projectID: "project-id"} pf := &pageFetcherReadStub{ values: [][][]Value{{{1, 2}}}, } tr := &bq.TableReference{ ProjectId: "project-id", DatasetId: "dataset-id", TableId: "table-id", } queryJob := &Job{ projectID: "project-id", jobID: "job-id", c: c, config: &bq.JobConfiguration{ Query: &bq.JobConfigurationQuery{DestinationTable: tr}, }, } it, err := queryJob.read(context.Background(), waitForQueryStub, pf.fetchPage) if err != nil { t.Fatalf("err calling Read: %v", err) } it.PageInfo().MaxSize = 5 var vals []Value if err := it.Next(&vals); err != nil { t.Fatalf("Next: got: %v: want: nil", err) } want := []pageFetcherArgs{{ table: bqToTable(tr, c), pageSize: 5, pageToken: "", }} if !testutil.Equal(pf.calls, want, cmp.AllowUnexported(pageFetcherArgs{}, Table{}, Client{})) { t.Errorf("reading: got:\n%v\nwant:\n%v", pf.calls, want) } } google-cloud-go-0.49.0/bigquery/routine.go000066400000000000000000000232241356504100700204360ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "context" "errors" "fmt" "time" "cloud.google.com/go/internal/optional" "cloud.google.com/go/internal/trace" bq "google.golang.org/api/bigquery/v2" ) // Routine represents a reference to a BigQuery routine. There are multiple // types of routines including stored procedures and scalar user-defined functions (UDFs). // For more information, see the BigQuery documentation at https://cloud.google.com/bigquery/docs/ type Routine struct { ProjectID string DatasetID string RoutineID string c *Client } // FullyQualifiedName returns an identifer for the routine in project.dataset.routine format. func (r *Routine) FullyQualifiedName() string { return fmt.Sprintf("%s.%s.%s", r.ProjectID, r.DatasetID, r.RoutineID) } // Create creates a Routine in the BigQuery service. // Pass in a RoutineMetadata to define the routine. func (r *Routine) Create(ctx context.Context, rm *RoutineMetadata) (err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Routine.Create") defer func() { trace.EndSpan(ctx, err) }() routine, err := rm.toBQ() if err != nil { return err } routine.RoutineReference = &bq.RoutineReference{ ProjectId: r.ProjectID, DatasetId: r.DatasetID, RoutineId: r.RoutineID, } req := r.c.bqs.Routines.Insert(r.ProjectID, r.DatasetID, routine).Context(ctx) setClientHeader(req.Header()) _, err = req.Do() return err } // Metadata fetches the metadata for a given Routine. func (r *Routine) Metadata(ctx context.Context) (rm *RoutineMetadata, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Routine.Metadata") defer func() { trace.EndSpan(ctx, err) }() req := r.c.bqs.Routines.Get(r.ProjectID, r.DatasetID, r.RoutineID).Context(ctx) setClientHeader(req.Header()) var routine *bq.Routine err = runWithRetry(ctx, func() (err error) { routine, err = req.Do() return err }) if err != nil { return nil, err } return bqToRoutineMetadata(routine) } // Update modifies properties of a Routine using the API. func (r *Routine) Update(ctx context.Context, upd *RoutineMetadataToUpdate, etag string) (rm *RoutineMetadata, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Routine.Update") defer func() { trace.EndSpan(ctx, err) }() bqr, err := upd.toBQ() if err != nil { return nil, err } //TODO: remove when routines update supports partial requests. bqr.RoutineReference = &bq.RoutineReference{ ProjectId: r.ProjectID, DatasetId: r.DatasetID, RoutineId: r.RoutineID, } call := r.c.bqs.Routines.Update(r.ProjectID, r.DatasetID, r.RoutineID, bqr).Context(ctx) setClientHeader(call.Header()) if etag != "" { call.Header().Set("If-Match", etag) } var res *bq.Routine if err := runWithRetry(ctx, func() (err error) { res, err = call.Do() return err }); err != nil { return nil, err } return bqToRoutineMetadata(res) } // Delete removes a Routine from a dataset. func (r *Routine) Delete(ctx context.Context) (err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Model.Delete") defer func() { trace.EndSpan(ctx, err) }() req := r.c.bqs.Routines.Delete(r.ProjectID, r.DatasetID, r.RoutineID).Context(ctx) setClientHeader(req.Header()) return req.Do() } // RoutineMetadata represents details of a given BigQuery Routine. type RoutineMetadata struct { ETag string // Type indicates the type of routine, such as SCALAR_FUNCTION or PROCEDURE. Type string CreationTime time.Time Description string LastModifiedTime time.Time // Language of the routine, such as SQL or JAVASCRIPT. Language string // The list of arguments for the the routine. Arguments []*RoutineArgument ReturnType *StandardSQLDataType // For javascript routines, this indicates the paths for imported libraries. ImportedLibraries []string // Body contains the routine's body. // For functions, Body is the expression in the AS clause. // // For SQL functions, it is the substring inside the parentheses of a CREATE // FUNCTION statement. // // For JAVASCRIPT function, it is the evaluated string in the AS clause of // a CREATE FUNCTION statement. Body string } func (rm *RoutineMetadata) toBQ() (*bq.Routine, error) { r := &bq.Routine{} if rm == nil { return r, nil } r.Description = rm.Description r.Language = rm.Language r.RoutineType = rm.Type r.DefinitionBody = rm.Body var args []*bq.Argument for _, v := range rm.Arguments { bqa, err := v.toBQ() if err != nil { return nil, err } args = append(args, bqa) } r.Arguments = args r.ImportedLibraries = rm.ImportedLibraries if !rm.CreationTime.IsZero() { return nil, errors.New("cannot set CreationTime on create") } if !rm.LastModifiedTime.IsZero() { return nil, errors.New("cannot set LastModifiedTime on create") } if rm.ETag != "" { return nil, errors.New("cannot set ETag on create") } return r, nil } // RoutineArgument represents an argument supplied to a routine such as a UDF or // stored procedured. type RoutineArgument struct { // The name of this argument. Can be absent for function return argument. Name string // Kind indicates the kind of argument represented. // Possible values: // ARGUMENT_KIND_UNSPECIFIED // FIXED_TYPE - The argument is a variable with fully specified // type, which can be a struct or an array, but not a table. // ANY_TYPE - The argument is any type, including struct or array, // but not a table. Kind string // Mode is optional, and indicates whether an argument is input or output. // Mode can only be set for procedures. // // Possible values: // MODE_UNSPECIFIED // IN - The argument is input-only. // OUT - The argument is output-only. // INOUT - The argument is both an input and an output. Mode string // DataType provides typing information. Unnecessary for ANY_TYPE Kind // arguments. DataType *StandardSQLDataType } func (ra *RoutineArgument) toBQ() (*bq.Argument, error) { if ra == nil { return nil, nil } a := &bq.Argument{ Name: ra.Name, ArgumentKind: ra.Kind, Mode: ra.Mode, } if ra.DataType != nil { dt, err := ra.DataType.toBQ() if err != nil { return nil, err } a.DataType = dt } return a, nil } func bqToRoutineArgument(bqa *bq.Argument) (*RoutineArgument, error) { arg := &RoutineArgument{ Name: bqa.Name, Kind: bqa.ArgumentKind, Mode: bqa.Mode, } dt, err := bqToStandardSQLDataType(bqa.DataType) if err != nil { return nil, err } arg.DataType = dt return arg, nil } func bqToArgs(in []*bq.Argument) ([]*RoutineArgument, error) { var out []*RoutineArgument for _, a := range in { arg, err := bqToRoutineArgument(a) if err != nil { return nil, err } out = append(out, arg) } return out, nil } func routineArgumentsToBQ(in []*RoutineArgument) ([]*bq.Argument, error) { var out []*bq.Argument for _, inarg := range in { arg, err := inarg.toBQ() if err != nil { return nil, err } out = append(out, arg) } return out, nil } // RoutineMetadataToUpdate governs updating a routine. type RoutineMetadataToUpdate struct { Arguments []*RoutineArgument Description optional.String Type optional.String Language optional.String Body optional.String ImportedLibraries []string ReturnType *StandardSQLDataType } func (rm *RoutineMetadataToUpdate) toBQ() (*bq.Routine, error) { r := &bq.Routine{} forceSend := func(field string) { r.ForceSendFields = append(r.ForceSendFields, field) } nullField := func(field string) { r.NullFields = append(r.NullFields, field) } if rm.Description != nil { r.Description = optional.ToString(rm.Description) forceSend("Description") } if rm.Arguments != nil { if len(rm.Arguments) == 0 { nullField("Arguments") } else { args, err := routineArgumentsToBQ(rm.Arguments) if err != nil { return nil, err } r.Arguments = args forceSend("Arguments") } } if rm.Type != nil { r.RoutineType = optional.ToString(rm.Type) forceSend("RoutineType") } if rm.Language != nil { r.Language = optional.ToString(rm.Language) forceSend("Language") } if rm.Body != nil { r.DefinitionBody = optional.ToString(rm.Body) forceSend("DefinitionBody") } if rm.ImportedLibraries != nil { if len(rm.ImportedLibraries) == 0 { nullField("ImportedLibraries") } else { r.ImportedLibraries = rm.ImportedLibraries forceSend("ImportedLibraries") } } if rm.ReturnType != nil { dt, err := rm.ReturnType.toBQ() if err != nil { return nil, err } r.ReturnType = dt forceSend("ReturnType") } return r, nil } func bqToRoutineMetadata(r *bq.Routine) (*RoutineMetadata, error) { meta := &RoutineMetadata{ ETag: r.Etag, Type: r.RoutineType, CreationTime: unixMillisToTime(r.CreationTime), Description: r.Description, LastModifiedTime: unixMillisToTime(r.LastModifiedTime), Language: r.Language, ImportedLibraries: r.ImportedLibraries, Body: r.DefinitionBody, } args, err := bqToArgs(r.Arguments) if err != nil { return nil, err } meta.Arguments = args ret, err := bqToStandardSQLDataType(r.ReturnType) if err != nil { return nil, err } meta.ReturnType = ret return meta, nil } google-cloud-go-0.49.0/bigquery/routine_test.go000066400000000000000000000100341356504100700214700ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "fmt" "testing" "time" "cloud.google.com/go/internal/testutil" bq "google.golang.org/api/bigquery/v2" ) func testRoutineConversion(t *testing.T, conversion string, in interface{}, want interface{}) { var got interface{} var err error switch conversion { case "ToRoutineMetadata": input, ok := in.(*bq.Routine) if !ok { t.Fatalf("failed input type conversion (bq.Routine): %v", in) } got, err = bqToRoutineMetadata(input) case "FromRoutineMetadataToUpdate": input, ok := in.(*RoutineMetadataToUpdate) if !ok { t.Fatalf("failed input type conversion: %v", in) } got, err = input.toBQ() case "ToRoutineArgument": input, ok := in.(*bq.Argument) if !ok { t.Fatalf("failed input type conversion: %v", in) } got, err = bqToRoutineArgument(input) case "FromRoutineArgument": input, ok := in.(*RoutineArgument) if !ok { t.Fatalf("failed input type conversion: %v", in) } got, err = input.toBQ() default: t.Fatalf("invalid comparison: %s", conversion) } if err != nil { t.Fatalf("failed conversion function for %q", conversion) } if diff := testutil.Diff(got, want); diff != "" { t.Fatalf("%+v: -got, +want:\n%s", in, diff) } } func TestRoutineTypeConversions(t *testing.T) { aTime := time.Date(2019, 3, 14, 0, 0, 0, 0, time.Local) aTimeMillis := aTime.UnixNano() / 1e6 tests := []struct { name string conversion string in interface{} want interface{} }{ {"empty", "ToRoutineMetadata", &bq.Routine{}, &RoutineMetadata{}}, {"basic", "ToRoutineMetadata", &bq.Routine{ CreationTime: aTimeMillis, LastModifiedTime: aTimeMillis, DefinitionBody: "body", Description: "desc", Etag: "etag", RoutineType: "type", Language: "lang", }, &RoutineMetadata{ CreationTime: aTime, LastModifiedTime: aTime, Description: "desc", Body: "body", ETag: "etag", Type: "type", Language: "lang", }}, {"body_and_libs", "FromRoutineMetadataToUpdate", &RoutineMetadataToUpdate{ Body: "body", ImportedLibraries: []string{"foo", "bar"}, }, &bq.Routine{ DefinitionBody: "body", ImportedLibraries: []string{"foo", "bar"}, ForceSendFields: []string{"DefinitionBody", "ImportedLibraries"}, }}, {"null_fields", "FromRoutineMetadataToUpdate", &RoutineMetadataToUpdate{ Type: "type", Arguments: []*RoutineArgument{}, ImportedLibraries: []string{}, }, &bq.Routine{ RoutineType: "type", ForceSendFields: []string{"RoutineType"}, NullFields: []string{"Arguments", "ImportedLibraries"}, }}, {"empty", "ToRoutineArgument", &bq.Argument{}, &RoutineArgument{}}, {"basic", "ToRoutineArgument", &bq.Argument{ Name: "foo", ArgumentKind: "bar", Mode: "baz", }, &RoutineArgument{ Name: "foo", Kind: "bar", Mode: "baz", }}, {"empty", "FromRoutineArgument", &RoutineArgument{}, &bq.Argument{}, }, {"basic", "FromRoutineArgument", &RoutineArgument{ Name: "foo", Kind: "bar", Mode: "baz", }, &bq.Argument{ Name: "foo", ArgumentKind: "bar", Mode: "baz", }}, } for _, test := range tests { t.Run(fmt.Sprintf("%s/%s", test.conversion, test.name), func(t *testing.T) { t.Parallel() testRoutineConversion(t, test.conversion, test.in, test.want) }) } } google-cloud-go-0.49.0/bigquery/schema.go000066400000000000000000000372311356504100700202140ustar00rootroot00000000000000// Copyright 2015 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "encoding/json" "errors" "fmt" "reflect" "sync" bq "google.golang.org/api/bigquery/v2" ) // Schema describes the fields in a table or query result. type Schema []*FieldSchema // Relax returns a version of the schema where no fields are marked // as Required. func (s Schema) Relax() Schema { var out Schema for _, v := range s { relaxed := &FieldSchema{ Name: v.Name, Description: v.Description, Repeated: v.Repeated, Required: false, Type: v.Type, Schema: v.Schema.Relax(), } out = append(out, relaxed) } return out } // FieldSchema describes a single field. type FieldSchema struct { // The field name. // Must contain only letters (a-z, A-Z), numbers (0-9), or underscores (_), // and must start with a letter or underscore. // The maximum length is 128 characters. Name string // A description of the field. The maximum length is 16,384 characters. Description string // Whether the field may contain multiple values. Repeated bool // Whether the field is required. Ignored if Repeated is true. Required bool // The field data type. If Type is Record, then this field contains a nested schema, // which is described by Schema. Type FieldType // Describes the nested schema if Type is set to Record. Schema Schema } func (fs *FieldSchema) toBQ() *bq.TableFieldSchema { tfs := &bq.TableFieldSchema{ Description: fs.Description, Name: fs.Name, Type: string(fs.Type), } if fs.Repeated { tfs.Mode = "REPEATED" } else if fs.Required { tfs.Mode = "REQUIRED" } // else leave as default, which is interpreted as NULLABLE. for _, f := range fs.Schema { tfs.Fields = append(tfs.Fields, f.toBQ()) } return tfs } func (s Schema) toBQ() *bq.TableSchema { var fields []*bq.TableFieldSchema for _, f := range s { fields = append(fields, f.toBQ()) } return &bq.TableSchema{Fields: fields} } func bqToFieldSchema(tfs *bq.TableFieldSchema) *FieldSchema { fs := &FieldSchema{ Description: tfs.Description, Name: tfs.Name, Repeated: tfs.Mode == "REPEATED", Required: tfs.Mode == "REQUIRED", Type: FieldType(tfs.Type), } for _, f := range tfs.Fields { fs.Schema = append(fs.Schema, bqToFieldSchema(f)) } return fs } func bqToSchema(ts *bq.TableSchema) Schema { if ts == nil { return nil } var s Schema for _, f := range ts.Fields { s = append(s, bqToFieldSchema(f)) } return s } // FieldType is the type of field. type FieldType string const ( // StringFieldType is a string field type. StringFieldType FieldType = "STRING" // BytesFieldType is a bytes field type. BytesFieldType FieldType = "BYTES" // IntegerFieldType is a integer field type. IntegerFieldType FieldType = "INTEGER" // FloatFieldType is a float field type. FloatFieldType FieldType = "FLOAT" // BooleanFieldType is a boolean field type. BooleanFieldType FieldType = "BOOLEAN" // TimestampFieldType is a timestamp field type. TimestampFieldType FieldType = "TIMESTAMP" // RecordFieldType is a record field type. It is typically used to create columns with repeated or nested data. RecordFieldType FieldType = "RECORD" // DateFieldType is a date field type. DateFieldType FieldType = "DATE" // TimeFieldType is a time field type. TimeFieldType FieldType = "TIME" // DateTimeFieldType is a datetime field type. DateTimeFieldType FieldType = "DATETIME" // NumericFieldType is a numeric field type. Numeric types include integer types, floating point types and the // NUMERIC data type. NumericFieldType FieldType = "NUMERIC" // GeographyFieldType is a string field type. Geography types represent a set of points // on the Earth's surface, represented in Well Known Text (WKT) format. GeographyFieldType FieldType = "GEOGRAPHY" ) var ( errEmptyJSONSchema = errors.New("bigquery: empty JSON schema") fieldTypes = map[FieldType]bool{ StringFieldType: true, BytesFieldType: true, IntegerFieldType: true, FloatFieldType: true, BooleanFieldType: true, TimestampFieldType: true, RecordFieldType: true, DateFieldType: true, TimeFieldType: true, DateTimeFieldType: true, NumericFieldType: true, GeographyFieldType: true, } ) var typeOfByteSlice = reflect.TypeOf([]byte{}) // InferSchema tries to derive a BigQuery schema from the supplied struct value. // Each exported struct field is mapped to a field in the schema. // // The following BigQuery types are inferred from the corresponding Go types. // (This is the same mapping as that used for RowIterator.Next.) Fields inferred // from these types are marked required (non-nullable). // // STRING string // BOOL bool // INTEGER int, int8, int16, int32, int64, uint8, uint16, uint32 // FLOAT float32, float64 // BYTES []byte // TIMESTAMP time.Time // DATE civil.Date // TIME civil.Time // DATETIME civil.DateTime // NUMERIC *big.Rat // // The big.Rat type supports numbers of arbitrary size and precision. Values // will be rounded to 9 digits after the decimal point before being transmitted // to BigQuery. See https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#numeric-type // for more on NUMERIC. // // A Go slice or array type is inferred to be a BigQuery repeated field of the // element type. The element type must be one of the above listed types. // // Due to lack of unique native Go type for GEOGRAPHY, there is no schema // inference to GEOGRAPHY at this time. // // Nullable fields are inferred from the NullXXX types, declared in this package: // // STRING NullString // BOOL NullBool // INTEGER NullInt64 // FLOAT NullFloat64 // TIMESTAMP NullTimestamp // DATE NullDate // TIME NullTime // DATETIME NullDateTime // GEOGRAPHY NullGeography // // For a nullable BYTES field, use the type []byte and tag the field "nullable" (see below). // For a nullable NUMERIC field, use the type *big.Rat and tag the field "nullable". // // A struct field that is of struct type is inferred to be a required field of type // RECORD with a schema inferred recursively. For backwards compatibility, a field of // type pointer to struct is also inferred to be required. To get a nullable RECORD // field, use the "nullable" tag (see below). // // InferSchema returns an error if any of the examined fields is of type uint, // uint64, uintptr, map, interface, complex64, complex128, func, or chan. Future // versions may handle these cases without error. // // Recursively defined structs are also disallowed. // // Struct fields may be tagged in a way similar to the encoding/json package. // A tag of the form // bigquery:"name" // uses "name" instead of the struct field name as the BigQuery field name. // A tag of the form // bigquery:"-" // omits the field from the inferred schema. // The "nullable" option marks the field as nullable (not required). It is only // needed for []byte, *big.Rat and pointer-to-struct fields, and cannot appear on other // fields. In this example, the Go name of the field is retained: // bigquery:",nullable" func InferSchema(st interface{}) (Schema, error) { return inferSchemaReflectCached(reflect.TypeOf(st)) } var schemaCache sync.Map type cacheVal struct { schema Schema err error } func inferSchemaReflectCached(t reflect.Type) (Schema, error) { var cv cacheVal v, ok := schemaCache.Load(t) if ok { cv = v.(cacheVal) } else { s, err := inferSchemaReflect(t) cv = cacheVal{s, err} schemaCache.Store(t, cv) } return cv.schema, cv.err } func inferSchemaReflect(t reflect.Type) (Schema, error) { rec, err := hasRecursiveType(t, nil) if err != nil { return nil, err } if rec { return nil, fmt.Errorf("bigquery: schema inference for recursive type %s", t) } return inferStruct(t) } func inferStruct(t reflect.Type) (Schema, error) { switch t.Kind() { case reflect.Ptr: if t.Elem().Kind() != reflect.Struct { return nil, noStructError{t} } t = t.Elem() fallthrough case reflect.Struct: return inferFields(t) default: return nil, noStructError{t} } } // inferFieldSchema infers the FieldSchema for a Go type func inferFieldSchema(fieldName string, rt reflect.Type, nullable bool) (*FieldSchema, error) { // Only []byte and struct pointers can be tagged nullable. if nullable && !(rt == typeOfByteSlice || rt.Kind() == reflect.Ptr && rt.Elem().Kind() == reflect.Struct) { return nil, badNullableError{fieldName, rt} } switch rt { case typeOfByteSlice: return &FieldSchema{Required: !nullable, Type: BytesFieldType}, nil case typeOfGoTime: return &FieldSchema{Required: true, Type: TimestampFieldType}, nil case typeOfDate: return &FieldSchema{Required: true, Type: DateFieldType}, nil case typeOfTime: return &FieldSchema{Required: true, Type: TimeFieldType}, nil case typeOfDateTime: return &FieldSchema{Required: true, Type: DateTimeFieldType}, nil case typeOfRat: return &FieldSchema{Required: !nullable, Type: NumericFieldType}, nil } if ft := nullableFieldType(rt); ft != "" { return &FieldSchema{Required: false, Type: ft}, nil } if isSupportedIntType(rt) || isSupportedUintType(rt) { return &FieldSchema{Required: true, Type: IntegerFieldType}, nil } switch rt.Kind() { case reflect.Slice, reflect.Array: et := rt.Elem() if et != typeOfByteSlice && (et.Kind() == reflect.Slice || et.Kind() == reflect.Array) { // Multi dimensional slices/arrays are not supported by BigQuery return nil, unsupportedFieldTypeError{fieldName, rt} } if nullableFieldType(et) != "" { // Repeated nullable types are not supported by BigQuery. return nil, unsupportedFieldTypeError{fieldName, rt} } f, err := inferFieldSchema(fieldName, et, false) if err != nil { return nil, err } f.Repeated = true f.Required = false return f, nil case reflect.Ptr: if rt.Elem().Kind() != reflect.Struct { return nil, unsupportedFieldTypeError{fieldName, rt} } fallthrough case reflect.Struct: nested, err := inferStruct(rt) if err != nil { return nil, err } return &FieldSchema{Required: !nullable, Type: RecordFieldType, Schema: nested}, nil case reflect.String: return &FieldSchema{Required: !nullable, Type: StringFieldType}, nil case reflect.Bool: return &FieldSchema{Required: !nullable, Type: BooleanFieldType}, nil case reflect.Float32, reflect.Float64: return &FieldSchema{Required: !nullable, Type: FloatFieldType}, nil default: return nil, unsupportedFieldTypeError{fieldName, rt} } } // inferFields extracts all exported field types from struct type. func inferFields(rt reflect.Type) (Schema, error) { var s Schema fields, err := fieldCache.Fields(rt) if err != nil { return nil, err } for _, field := range fields { var nullable bool for _, opt := range field.ParsedTag.([]string) { if opt == nullableTagOption { nullable = true break } } f, err := inferFieldSchema(field.Name, field.Type, nullable) if err != nil { return nil, err } f.Name = field.Name s = append(s, f) } return s, nil } // isSupportedIntType reports whether t is an int type that can be properly // represented by the BigQuery INTEGER/INT64 type. func isSupportedIntType(t reflect.Type) bool { switch t.Kind() { case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: return true default: return false } } // isSupportedIntType reports whether t is a uint type that can be properly // represented by the BigQuery INTEGER/INT64 type. func isSupportedUintType(t reflect.Type) bool { switch t.Kind() { case reflect.Uint8, reflect.Uint16, reflect.Uint32: return true default: return false } } // typeList is a linked list of reflect.Types. type typeList struct { t reflect.Type next *typeList } func (l *typeList) has(t reflect.Type) bool { for l != nil { if l.t == t { return true } l = l.next } return false } // hasRecursiveType reports whether t or any type inside t refers to itself, directly or indirectly, // via exported fields. (Schema inference ignores unexported fields.) func hasRecursiveType(t reflect.Type, seen *typeList) (bool, error) { for t.Kind() == reflect.Ptr || t.Kind() == reflect.Slice || t.Kind() == reflect.Array { t = t.Elem() } if t.Kind() != reflect.Struct { return false, nil } if seen.has(t) { return true, nil } fields, err := fieldCache.Fields(t) if err != nil { return false, err } seen = &typeList{t, seen} // Because seen is a linked list, additions to it from one field's // recursive call will not affect the value for subsequent fields' calls. for _, field := range fields { ok, err := hasRecursiveType(field.Type, seen) if err != nil { return false, err } if ok { return true, nil } } return false, nil } // bigQuerySchemaJSONField is an individual field in a JSON BigQuery table schema definition // (as generated by https://github.com/GoogleCloudPlatform/protoc-gen-bq-schema). type bigQueryJSONField struct { Description string `json:"description"` Fields []bigQueryJSONField `json:"fields"` Mode string `json:"mode"` Name string `json:"name"` Type string `json:"type"` } // convertSchemaFromJSON generates a Schema: func convertSchemaFromJSON(fs []bigQueryJSONField) (Schema, error) { convertedSchema := Schema{} for _, f := range fs { convertedFieldSchema := &FieldSchema{ Description: f.Description, Name: f.Name, Required: f.Mode == "REQUIRED", Repeated: f.Mode == "REPEATED", } if len(f.Fields) > 0 { convertedNestedFieldSchema, err := convertSchemaFromJSON(f.Fields) if err != nil { return nil, err } convertedFieldSchema.Schema = convertedNestedFieldSchema } // Check that the field-type (string) maps to a known FieldType: if _, ok := fieldTypes[FieldType(f.Type)]; !ok { return nil, fmt.Errorf("unknown field type (%v)", f.Type) } convertedFieldSchema.Type = FieldType(f.Type) convertedSchema = append(convertedSchema, convertedFieldSchema) } return convertedSchema, nil } // SchemaFromJSON takes a JSON BigQuery table schema definition // (as generated by https://github.com/GoogleCloudPlatform/protoc-gen-bq-schema) // and returns a fully-populated Schema. func SchemaFromJSON(schemaJSON []byte) (Schema, error) { var bigQuerySchema []bigQueryJSONField // Make sure we actually have some content: if len(schemaJSON) == 0 { return nil, errEmptyJSONSchema } if err := json.Unmarshal(schemaJSON, &bigQuerySchema); err != nil { return nil, err } return convertSchemaFromJSON(bigQuerySchema) } type noStructError struct { typ reflect.Type } func (e noStructError) Error() string { return fmt.Sprintf("bigquery: can only infer schema from struct or pointer to struct, not %s", e.typ) } type badNullableError struct { name string typ reflect.Type } func (e badNullableError) Error() string { return fmt.Sprintf(`bigquery: field %q of type %s: use "nullable" only for []byte and struct pointers; for all other types, use a NullXXX type`, e.name, e.typ) } type unsupportedFieldTypeError struct { name string typ reflect.Type } func (e unsupportedFieldTypeError) Error() string { return fmt.Sprintf("bigquery: field %q: type %s is not supported", e.name, e.typ) } google-cloud-go-0.49.0/bigquery/schema_test.go000066400000000000000000000632551356504100700212600ustar00rootroot00000000000000// Copyright 2015 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "fmt" "math/big" "reflect" "testing" "time" "cloud.google.com/go/civil" "cloud.google.com/go/internal/pretty" "cloud.google.com/go/internal/testutil" bq "google.golang.org/api/bigquery/v2" ) func (fs *FieldSchema) GoString() string { if fs == nil { return "" } return fmt.Sprintf("{Name:%s Description:%s Repeated:%t Required:%t Type:%s Schema:%s}", fs.Name, fs.Description, fs.Repeated, fs.Required, fs.Type, fmt.Sprintf("%#v", fs.Schema), ) } func bqTableFieldSchema(desc, name, typ, mode string) *bq.TableFieldSchema { return &bq.TableFieldSchema{ Description: desc, Name: name, Mode: mode, Type: typ, } } func fieldSchema(desc, name, typ string, repeated, required bool) *FieldSchema { return &FieldSchema{ Description: desc, Name: name, Repeated: repeated, Required: required, Type: FieldType(typ), } } func TestRelaxSchema(t *testing.T) { testCases := []struct { in Schema expected Schema }{ { Schema{ &FieldSchema{ Description: "a relaxed schema", Required: false, Type: StringFieldType, }, }, Schema{ &FieldSchema{ Description: "a relaxed schema", Required: false, Type: StringFieldType, }, }, }, { Schema{ &FieldSchema{ Description: "a required string", Required: true, Type: StringFieldType, }, &FieldSchema{ Description: "a required integer", Required: true, Type: IntegerFieldType, }, }, Schema{ &FieldSchema{ Description: "a required string", Required: false, Type: StringFieldType, }, &FieldSchema{ Description: "a required integer", Required: false, Type: IntegerFieldType, }, }, }, { Schema{ &FieldSchema{ Description: "An outer schema wrapping a nested schema", Name: "outer", Required: true, Type: RecordFieldType, Schema: Schema{ { Description: "inner field", Name: "inner", Type: StringFieldType, Required: true, }, }, }, }, Schema{ &FieldSchema{ Description: "An outer schema wrapping a nested schema", Name: "outer", Required: false, Type: "RECORD", Schema: Schema{ { Description: "inner field", Name: "inner", Type: "STRING", Required: false, }, }, }, }, }, } for _, tc := range testCases { converted := tc.in.Relax() if !testutil.Equal(converted, tc.expected) { t.Errorf("relaxing schema: got:\n%v\nwant:\n%v", pretty.Value(converted), pretty.Value(tc.expected)) } } } func TestSchemaConversion(t *testing.T) { testCases := []struct { schema Schema bqSchema *bq.TableSchema }{ { // required bqSchema: &bq.TableSchema{ Fields: []*bq.TableFieldSchema{ bqTableFieldSchema("desc", "name", "STRING", "REQUIRED"), }, }, schema: Schema{ fieldSchema("desc", "name", "STRING", false, true), }, }, { // repeated bqSchema: &bq.TableSchema{ Fields: []*bq.TableFieldSchema{ bqTableFieldSchema("desc", "name", "STRING", "REPEATED"), }, }, schema: Schema{ fieldSchema("desc", "name", "STRING", true, false), }, }, { // nullable, string bqSchema: &bq.TableSchema{ Fields: []*bq.TableFieldSchema{ bqTableFieldSchema("desc", "name", "STRING", ""), }, }, schema: Schema{ fieldSchema("desc", "name", "STRING", false, false), }, }, { // integer bqSchema: &bq.TableSchema{ Fields: []*bq.TableFieldSchema{ bqTableFieldSchema("desc", "name", "INTEGER", ""), }, }, schema: Schema{ fieldSchema("desc", "name", "INTEGER", false, false), }, }, { // float bqSchema: &bq.TableSchema{ Fields: []*bq.TableFieldSchema{ bqTableFieldSchema("desc", "name", "FLOAT", ""), }, }, schema: Schema{ fieldSchema("desc", "name", "FLOAT", false, false), }, }, { // boolean bqSchema: &bq.TableSchema{ Fields: []*bq.TableFieldSchema{ bqTableFieldSchema("desc", "name", "BOOLEAN", ""), }, }, schema: Schema{ fieldSchema("desc", "name", "BOOLEAN", false, false), }, }, { // timestamp bqSchema: &bq.TableSchema{ Fields: []*bq.TableFieldSchema{ bqTableFieldSchema("desc", "name", "TIMESTAMP", ""), }, }, schema: Schema{ fieldSchema("desc", "name", "TIMESTAMP", false, false), }, }, { // civil times bqSchema: &bq.TableSchema{ Fields: []*bq.TableFieldSchema{ bqTableFieldSchema("desc", "f1", "TIME", ""), bqTableFieldSchema("desc", "f2", "DATE", ""), bqTableFieldSchema("desc", "f3", "DATETIME", ""), }, }, schema: Schema{ fieldSchema("desc", "f1", "TIME", false, false), fieldSchema("desc", "f2", "DATE", false, false), fieldSchema("desc", "f3", "DATETIME", false, false), }, }, { // numeric bqSchema: &bq.TableSchema{ Fields: []*bq.TableFieldSchema{ bqTableFieldSchema("desc", "n", "NUMERIC", ""), }, }, schema: Schema{ fieldSchema("desc", "n", "NUMERIC", false, false), }, }, { bqSchema: &bq.TableSchema{ Fields: []*bq.TableFieldSchema{ bqTableFieldSchema("geo", "g", "GEOGRAPHY", ""), }, }, schema: Schema{ fieldSchema("geo", "g", "GEOGRAPHY", false, false), }, }, { // nested bqSchema: &bq.TableSchema{ Fields: []*bq.TableFieldSchema{ { Description: "An outer schema wrapping a nested schema", Name: "outer", Mode: "REQUIRED", Type: "RECORD", Fields: []*bq.TableFieldSchema{ bqTableFieldSchema("inner field", "inner", "STRING", ""), }, }, }, }, schema: Schema{ &FieldSchema{ Description: "An outer schema wrapping a nested schema", Name: "outer", Required: true, Type: "RECORD", Schema: Schema{ { Description: "inner field", Name: "inner", Type: "STRING", }, }, }, }, }, } for _, tc := range testCases { bqSchema := tc.schema.toBQ() if !testutil.Equal(bqSchema, tc.bqSchema) { t.Errorf("converting to TableSchema: got:\n%v\nwant:\n%v", pretty.Value(bqSchema), pretty.Value(tc.bqSchema)) } schema := bqToSchema(tc.bqSchema) if !testutil.Equal(schema, tc.schema) { t.Errorf("converting to Schema: got:\n%v\nwant:\n%v", schema, tc.schema) } } } type allStrings struct { String string ByteSlice []byte } type allSignedIntegers struct { Int64 int64 Int32 int32 Int16 int16 Int8 int8 Int int } type allUnsignedIntegers struct { Uint32 uint32 Uint16 uint16 Uint8 uint8 } type allFloat struct { Float64 float64 Float32 float32 // NOTE: Complex32 and Complex64 are unsupported by BigQuery } type allBoolean struct { Bool bool } type allTime struct { Timestamp time.Time Time civil.Time Date civil.Date DateTime civil.DateTime } type allNumeric struct { Numeric *big.Rat } func reqField(name, typ string) *FieldSchema { return &FieldSchema{ Name: name, Type: FieldType(typ), Required: true, } } func optField(name, typ string) *FieldSchema { return &FieldSchema{ Name: name, Type: FieldType(typ), Required: false, } } func TestSimpleInference(t *testing.T) { testCases := []struct { in interface{} want Schema }{ { in: allSignedIntegers{}, want: Schema{ reqField("Int64", "INTEGER"), reqField("Int32", "INTEGER"), reqField("Int16", "INTEGER"), reqField("Int8", "INTEGER"), reqField("Int", "INTEGER"), }, }, { in: allUnsignedIntegers{}, want: Schema{ reqField("Uint32", "INTEGER"), reqField("Uint16", "INTEGER"), reqField("Uint8", "INTEGER"), }, }, { in: allFloat{}, want: Schema{ reqField("Float64", "FLOAT"), reqField("Float32", "FLOAT"), }, }, { in: allBoolean{}, want: Schema{ reqField("Bool", "BOOLEAN"), }, }, { in: &allBoolean{}, want: Schema{ reqField("Bool", "BOOLEAN"), }, }, { in: allTime{}, want: Schema{ reqField("Timestamp", "TIMESTAMP"), reqField("Time", "TIME"), reqField("Date", "DATE"), reqField("DateTime", "DATETIME"), }, }, { in: &allNumeric{}, want: Schema{ reqField("Numeric", "NUMERIC"), }, }, { in: allStrings{}, want: Schema{ reqField("String", "STRING"), reqField("ByteSlice", "BYTES"), }, }, } for _, tc := range testCases { got, err := InferSchema(tc.in) if err != nil { t.Fatalf("%T: error inferring TableSchema: %v", tc.in, err) } if !testutil.Equal(got, tc.want) { t.Errorf("%T: inferring TableSchema: got:\n%#v\nwant:\n%#v", tc.in, pretty.Value(got), pretty.Value(tc.want)) } } } type containsNested struct { NotNested int Nested struct { Inside int } } type containsDoubleNested struct { NotNested int Nested struct { InsideNested struct { Inside int } } } type ptrNested struct { Ptr *struct{ Inside int } } type dup struct { // more than one field of the same struct type A, B allBoolean } func TestNestedInference(t *testing.T) { testCases := []struct { in interface{} want Schema }{ { in: containsNested{}, want: Schema{ reqField("NotNested", "INTEGER"), &FieldSchema{ Name: "Nested", Required: true, Type: "RECORD", Schema: Schema{reqField("Inside", "INTEGER")}, }, }, }, { in: containsDoubleNested{}, want: Schema{ reqField("NotNested", "INTEGER"), &FieldSchema{ Name: "Nested", Required: true, Type: "RECORD", Schema: Schema{ { Name: "InsideNested", Required: true, Type: "RECORD", Schema: Schema{reqField("Inside", "INTEGER")}, }, }, }, }, }, { in: ptrNested{}, want: Schema{ &FieldSchema{ Name: "Ptr", Required: true, Type: "RECORD", Schema: Schema{reqField("Inside", "INTEGER")}, }, }, }, { in: dup{}, want: Schema{ &FieldSchema{ Name: "A", Required: true, Type: "RECORD", Schema: Schema{reqField("Bool", "BOOLEAN")}, }, &FieldSchema{ Name: "B", Required: true, Type: "RECORD", Schema: Schema{reqField("Bool", "BOOLEAN")}, }, }, }, } for _, tc := range testCases { got, err := InferSchema(tc.in) if err != nil { t.Fatalf("%T: error inferring TableSchema: %v", tc.in, err) } if !testutil.Equal(got, tc.want) { t.Errorf("%T: inferring TableSchema: got:\n%#v\nwant:\n%#v", tc.in, pretty.Value(got), pretty.Value(tc.want)) } } } type repeated struct { NotRepeated []byte RepeatedByteSlice [][]byte Slice []int Array [5]bool } type nestedRepeated struct { NotRepeated int Repeated []struct { Inside int } RepeatedPtr []*struct{ Inside int } } func repField(name, typ string) *FieldSchema { return &FieldSchema{ Name: name, Type: FieldType(typ), Repeated: true, } } func TestRepeatedInference(t *testing.T) { testCases := []struct { in interface{} want Schema }{ { in: repeated{}, want: Schema{ reqField("NotRepeated", "BYTES"), repField("RepeatedByteSlice", "BYTES"), repField("Slice", "INTEGER"), repField("Array", "BOOLEAN"), }, }, { in: nestedRepeated{}, want: Schema{ reqField("NotRepeated", "INTEGER"), { Name: "Repeated", Repeated: true, Type: "RECORD", Schema: Schema{reqField("Inside", "INTEGER")}, }, { Name: "RepeatedPtr", Repeated: true, Type: "RECORD", Schema: Schema{reqField("Inside", "INTEGER")}, }, }, }, } for i, tc := range testCases { got, err := InferSchema(tc.in) if err != nil { t.Fatalf("%d: error inferring TableSchema: %v", i, err) } if !testutil.Equal(got, tc.want) { t.Errorf("%d: inferring TableSchema: got:\n%#v\nwant:\n%#v", i, pretty.Value(got), pretty.Value(tc.want)) } } } type allNulls struct { A NullInt64 B NullFloat64 C NullBool D NullString E NullTimestamp F NullTime G NullDate H NullDateTime I NullGeography } func TestNullInference(t *testing.T) { got, err := InferSchema(allNulls{}) if err != nil { t.Fatal(err) } want := Schema{ optField("A", "INTEGER"), optField("B", "FLOAT"), optField("C", "BOOLEAN"), optField("D", "STRING"), optField("E", "TIMESTAMP"), optField("F", "TIME"), optField("G", "DATE"), optField("H", "DATETIME"), optField("I", "GEOGRAPHY"), } if diff := testutil.Diff(got, want); diff != "" { t.Error(diff) } } type Embedded struct { Embedded int } type embedded struct { Embedded2 int } type nestedEmbedded struct { Embedded embedded } func TestEmbeddedInference(t *testing.T) { got, err := InferSchema(nestedEmbedded{}) if err != nil { t.Fatal(err) } want := Schema{ reqField("Embedded", "INTEGER"), reqField("Embedded2", "INTEGER"), } if !testutil.Equal(got, want) { t.Errorf("got %v, want %v", pretty.Value(got), pretty.Value(want)) } } func TestRecursiveInference(t *testing.T) { type List struct { Val int Next *List } _, err := InferSchema(List{}) if err == nil { t.Fatal("got nil, want error") } } type withTags struct { NoTag int ExcludeTag int `bigquery:"-"` SimpleTag int `bigquery:"simple_tag"` UnderscoreTag int `bigquery:"_id"` MixedCase int `bigquery:"MIXEDcase"` Nullable []byte `bigquery:",nullable"` NullNumeric *big.Rat `bigquery:",nullable"` } type withTagsNested struct { Nested withTags `bigquery:"nested"` NestedAnonymous struct { ExcludeTag int `bigquery:"-"` Inside int `bigquery:"inside"` } `bigquery:"anon"` PNested *struct{ X int } // not nullable, for backwards compatibility PNestedNullable *struct{ X int } `bigquery:",nullable"` } type withTagsRepeated struct { Repeated []withTags `bigquery:"repeated"` RepeatedAnonymous []struct { ExcludeTag int `bigquery:"-"` Inside int `bigquery:"inside"` } `bigquery:"anon"` } type withTagsEmbedded struct { withTags } var withTagsSchema = Schema{ reqField("NoTag", "INTEGER"), reqField("simple_tag", "INTEGER"), reqField("_id", "INTEGER"), reqField("MIXEDcase", "INTEGER"), optField("Nullable", "BYTES"), optField("NullNumeric", "NUMERIC"), } func TestTagInference(t *testing.T) { testCases := []struct { in interface{} want Schema }{ { in: withTags{}, want: withTagsSchema, }, { in: withTagsNested{}, want: Schema{ &FieldSchema{ Name: "nested", Required: true, Type: "RECORD", Schema: withTagsSchema, }, &FieldSchema{ Name: "anon", Required: true, Type: "RECORD", Schema: Schema{reqField("inside", "INTEGER")}, }, &FieldSchema{ Name: "PNested", Required: true, Type: "RECORD", Schema: Schema{reqField("X", "INTEGER")}, }, &FieldSchema{ Name: "PNestedNullable", Required: false, Type: "RECORD", Schema: Schema{reqField("X", "INTEGER")}, }, }, }, { in: withTagsRepeated{}, want: Schema{ &FieldSchema{ Name: "repeated", Repeated: true, Type: "RECORD", Schema: withTagsSchema, }, &FieldSchema{ Name: "anon", Repeated: true, Type: "RECORD", Schema: Schema{reqField("inside", "INTEGER")}, }, }, }, { in: withTagsEmbedded{}, want: withTagsSchema, }, } for i, tc := range testCases { got, err := InferSchema(tc.in) if err != nil { t.Fatalf("%d: error inferring TableSchema: %v", i, err) } if !testutil.Equal(got, tc.want) { t.Errorf("%d: inferring TableSchema: got:\n%#v\nwant:\n%#v", i, pretty.Value(got), pretty.Value(tc.want)) } } } func TestTagInferenceErrors(t *testing.T) { testCases := []interface{}{ struct { LongTag int `bigquery:"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxy"` }{}, struct { UnsupporedStartChar int `bigquery:"øab"` }{}, struct { UnsupportedEndChar int `bigquery:"abø"` }{}, struct { UnsupportedMiddleChar int `bigquery:"aøb"` }{}, struct { StartInt int `bigquery:"1abc"` }{}, struct { Hyphens int `bigquery:"a-b"` }{}, } for i, tc := range testCases { _, got := InferSchema(tc) if _, ok := got.(invalidFieldNameError); !ok { t.Errorf("%d: inferring TableSchema: got:\n%#v\nwant invalidFieldNameError", i, got) } } _, err := InferSchema(struct { X int `bigquery:",optional"` }{}) if err == nil { t.Error("got nil, want error") } } func TestSchemaErrors(t *testing.T) { testCases := []struct { in interface{} want interface{} }{ { in: []byte{}, want: noStructError{}, }, { in: new(int), want: noStructError{}, }, { in: struct{ Uint uint }{}, want: unsupportedFieldTypeError{}, }, { in: struct{ Uint64 uint64 }{}, want: unsupportedFieldTypeError{}, }, { in: struct{ Uintptr uintptr }{}, want: unsupportedFieldTypeError{}, }, { in: struct{ Complex complex64 }{}, want: unsupportedFieldTypeError{}, }, { in: struct{ Map map[string]int }{}, want: unsupportedFieldTypeError{}, }, { in: struct{ Chan chan bool }{}, want: unsupportedFieldTypeError{}, }, { in: struct{ Ptr *int }{}, want: unsupportedFieldTypeError{}, }, { in: struct{ Interface interface{} }{}, want: unsupportedFieldTypeError{}, }, { in: struct{ MultiDimensional [][]int }{}, want: unsupportedFieldTypeError{}, }, { in: struct{ MultiDimensional [][][]byte }{}, want: unsupportedFieldTypeError{}, }, { in: struct{ SliceOfPointer []*int }{}, want: unsupportedFieldTypeError{}, }, { in: struct{ SliceOfNull []NullInt64 }{}, want: unsupportedFieldTypeError{}, }, { in: struct{ ChanSlice []chan bool }{}, want: unsupportedFieldTypeError{}, }, { in: struct{ NestedChan struct{ Chan []chan bool } }{}, want: unsupportedFieldTypeError{}, }, { in: struct { X int `bigquery:",nullable"` }{}, want: badNullableError{}, }, { in: struct { X bool `bigquery:",nullable"` }{}, want: badNullableError{}, }, { in: struct { X struct{ N int } `bigquery:",nullable"` }{}, want: badNullableError{}, }, { in: struct { X []int `bigquery:",nullable"` }{}, want: badNullableError{}, }, { in: struct{ X *[]byte }{}, want: unsupportedFieldTypeError{}, }, { in: struct{ X *[]int }{}, want: unsupportedFieldTypeError{}, }, { in: struct{ X *int }{}, want: unsupportedFieldTypeError{}, }, } for _, tc := range testCases { _, got := InferSchema(tc.in) if reflect.TypeOf(got) != reflect.TypeOf(tc.want) { t.Errorf("%#v: got:\n%#v\nwant type %T", tc.in, got, tc.want) } } } func TestHasRecursiveType(t *testing.T) { type ( nonStruct int nonRec struct{ A string } dup struct{ A, B nonRec } rec struct { A int B *rec } recUnexported struct { A int } hasRec struct { A int R *rec } recSlicePointer struct { A []*recSlicePointer } ) for _, test := range []struct { in interface{} want bool }{ {nonStruct(0), false}, {nonRec{}, false}, {dup{}, false}, {rec{}, true}, {recUnexported{}, false}, {hasRec{}, true}, {&recSlicePointer{}, true}, } { got, err := hasRecursiveType(reflect.TypeOf(test.in), nil) if err != nil { t.Fatal(err) } if got != test.want { t.Errorf("%T: got %t, want %t", test.in, got, test.want) } } } func TestSchemaFromJSON(t *testing.T) { testCasesExpectingSuccess := []struct { bqSchemaJSON []byte description string expectedSchema Schema }{ { description: "Flat table with a mixture of NULLABLE and REQUIRED fields", bqSchemaJSON: []byte(` [ {"name":"flat_string","type":"STRING","mode":"NULLABLE","description":"Flat nullable string"}, {"name":"flat_bytes","type":"BYTES","mode":"REQUIRED","description":"Flat required BYTES"}, {"name":"flat_integer","type":"INTEGER","mode":"NULLABLE","description":"Flat nullable INTEGER"}, {"name":"flat_float","type":"FLOAT","mode":"REQUIRED","description":"Flat required FLOAT"}, {"name":"flat_boolean","type":"BOOLEAN","mode":"NULLABLE","description":"Flat nullable BOOLEAN"}, {"name":"flat_timestamp","type":"TIMESTAMP","mode":"REQUIRED","description":"Flat required TIMESTAMP"}, {"name":"flat_date","type":"DATE","mode":"NULLABLE","description":"Flat required DATE"}, {"name":"flat_time","type":"TIME","mode":"REQUIRED","description":"Flat nullable TIME"}, {"name":"flat_datetime","type":"DATETIME","mode":"NULLABLE","description":"Flat required DATETIME"}, {"name":"flat_numeric","type":"NUMERIC","mode":"REQUIRED","description":"Flat nullable NUMERIC"}, {"name":"flat_geography","type":"GEOGRAPHY","mode":"REQUIRED","description":"Flat required GEOGRAPHY"} ]`), expectedSchema: Schema{ fieldSchema("Flat nullable string", "flat_string", "STRING", false, false), fieldSchema("Flat required BYTES", "flat_bytes", "BYTES", false, true), fieldSchema("Flat nullable INTEGER", "flat_integer", "INTEGER", false, false), fieldSchema("Flat required FLOAT", "flat_float", "FLOAT", false, true), fieldSchema("Flat nullable BOOLEAN", "flat_boolean", "BOOLEAN", false, false), fieldSchema("Flat required TIMESTAMP", "flat_timestamp", "TIMESTAMP", false, true), fieldSchema("Flat required DATE", "flat_date", "DATE", false, false), fieldSchema("Flat nullable TIME", "flat_time", "TIME", false, true), fieldSchema("Flat required DATETIME", "flat_datetime", "DATETIME", false, false), fieldSchema("Flat nullable NUMERIC", "flat_numeric", "NUMERIC", false, true), fieldSchema("Flat required GEOGRAPHY", "flat_geography", "GEOGRAPHY", false, true), }, }, { description: "Table with a nested RECORD", bqSchemaJSON: []byte(` [ {"name":"flat_string","type":"STRING","mode":"NULLABLE","description":"Flat nullable string"}, {"name":"nested_record","type":"RECORD","mode":"NULLABLE","description":"Nested nullable RECORD","fields":[{"name":"record_field_1","type":"STRING","mode":"NULLABLE","description":"First nested record field"},{"name":"record_field_2","type":"INTEGER","mode":"REQUIRED","description":"Second nested record field"}]} ]`), expectedSchema: Schema{ fieldSchema("Flat nullable string", "flat_string", "STRING", false, false), &FieldSchema{ Description: "Nested nullable RECORD", Name: "nested_record", Required: false, Type: "RECORD", Schema: Schema{ { Description: "First nested record field", Name: "record_field_1", Required: false, Type: "STRING", }, { Description: "Second nested record field", Name: "record_field_2", Required: true, Type: "INTEGER", }, }, }, }, }, { description: "Table with a repeated RECORD", bqSchemaJSON: []byte(` [ {"name":"flat_string","type":"STRING","mode":"NULLABLE","description":"Flat nullable string"}, {"name":"nested_record","type":"RECORD","mode":"REPEATED","description":"Nested nullable RECORD","fields":[{"name":"record_field_1","type":"STRING","mode":"NULLABLE","description":"First nested record field"},{"name":"record_field_2","type":"INTEGER","mode":"REQUIRED","description":"Second nested record field"}]} ]`), expectedSchema: Schema{ fieldSchema("Flat nullable string", "flat_string", "STRING", false, false), &FieldSchema{ Description: "Nested nullable RECORD", Name: "nested_record", Repeated: true, Required: false, Type: "RECORD", Schema: Schema{ { Description: "First nested record field", Name: "record_field_1", Required: false, Type: "STRING", }, { Description: "Second nested record field", Name: "record_field_2", Required: true, Type: "INTEGER", }, }, }, }, }, } for _, tc := range testCasesExpectingSuccess { convertedSchema, err := SchemaFromJSON(tc.bqSchemaJSON) if err != nil { t.Errorf("encountered an error when converting JSON table schema (%s): %v", tc.description, err) continue } if !testutil.Equal(convertedSchema, tc.expectedSchema) { t.Errorf("generated JSON table schema (%s) differs from the expected schema", tc.description) } } testCasesExpectingFailure := []struct { bqSchemaJSON []byte description string }{ { description: "Schema with invalid JSON", bqSchemaJSON: []byte(`This is not JSON`), }, { description: "Schema with unknown field type", bqSchemaJSON: []byte(`[{"name":"strange_type","type":"STRANGE","description":"This type should not exist"}]`), }, { description: "Schema with zero length", bqSchemaJSON: []byte(``), }, } for _, tc := range testCasesExpectingFailure { _, err := SchemaFromJSON(tc.bqSchemaJSON) if err == nil { t.Errorf("converting this schema should have returned an error (%s): %v", tc.description, err) continue } } } google-cloud-go-0.49.0/bigquery/standardsql.go000066400000000000000000000106501356504100700212700ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "fmt" bq "google.golang.org/api/bigquery/v2" ) // StandardSQLDataType conveys type information using the Standard SQL type // system. type StandardSQLDataType struct { // ArrayElementType indicates the type of an array's elements, when the // TypeKind is ARRAY. ArrayElementType *StandardSQLDataType // StructType indicates the struct definition (fields), when the // TypeKind is STRUCT. StructType *StandardSQLStructType // The top-level type of this type definition. // Can be any standard SQL data type. For more information about BigQuery // data types, see // https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types // // Additional information is available in the REST documentation: // https://cloud.google.com/bigquery/docs/reference/rest/v2/StandardSqlDataType TypeKind string } func (ssdt *StandardSQLDataType) toBQ() (*bq.StandardSqlDataType, error) { if ssdt == nil { return nil, nil } bqdt := &bq.StandardSqlDataType{ TypeKind: ssdt.TypeKind, } if ssdt.ArrayElementType != nil { dt, err := ssdt.ArrayElementType.toBQ() if err != nil { return nil, err } bqdt.ArrayElementType = dt } if ssdt.StructType != nil { dt, err := ssdt.StructType.toBQ() if err != nil { return nil, err } bqdt.StructType = dt } return bqdt, nil } func bqToStandardSQLDataType(bqdt *bq.StandardSqlDataType) (*StandardSQLDataType, error) { if bqdt == nil { return nil, nil } ssdt := &StandardSQLDataType{ TypeKind: bqdt.TypeKind, } if bqdt.ArrayElementType != nil { dt, err := bqToStandardSQLDataType(bqdt.ArrayElementType) if err != nil { return nil, err } ssdt.ArrayElementType = dt } if bqdt.StructType != nil { st, err := bqToStandardSQLStructType(bqdt.StructType) if err != nil { return nil, err } ssdt.StructType = st } return ssdt, nil } // StandardSQLField represents a field using the Standard SQL data type system. type StandardSQLField struct { // The name of this field. Can be absent for struct fields. Name string // Data type for the field. Type *StandardSQLDataType } func (ssf *StandardSQLField) toBQ() (*bq.StandardSqlField, error) { if ssf == nil { return nil, nil } bqf := &bq.StandardSqlField{ Name: ssf.Name, } if ssf.Type != nil { dt, err := ssf.Type.toBQ() if err != nil { return nil, err } bqf.Type = dt } return bqf, nil } func bqToStandardSQLField(bqf *bq.StandardSqlField) (*StandardSQLField, error) { if bqf == nil { return nil, nil } t, err := bqToStandardSQLDataType(bqf.Type) if err != nil { return nil, err } return &StandardSQLField{ Name: bqf.Name, Type: t, }, nil } // StandardSQLStructType represents a structure type, which is a list of Standard SQL fields. // For more information, see: // https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#struct-type type StandardSQLStructType struct { Fields []*StandardSQLField } func (ssst *StandardSQLStructType) toBQ() (*bq.StandardSqlStructType, error) { if ssst == nil { return nil, nil } fields, err := standardSQLStructFieldsToBQ(ssst.Fields) if err != nil { return nil, err } return &bq.StandardSqlStructType{ Fields: fields, }, nil } func bqToStandardSQLStructType(bqst *bq.StandardSqlStructType) (*StandardSQLStructType, error) { if bqst == nil { return nil, nil } var fields []*StandardSQLField for _, v := range bqst.Fields { f, err := bqToStandardSQLField(v) if err != nil { return nil, err } fields = append(fields, f) } return &StandardSQLStructType{ Fields: fields, }, nil } func standardSQLStructFieldsToBQ(fields []*StandardSQLField) ([]*bq.StandardSqlField, error) { var bqFields []*bq.StandardSqlField for _, v := range fields { bqf, err := v.toBQ() if err != nil { return nil, fmt.Errorf("error converting struct fields: %v", err) } bqFields = append(bqFields, bqf) } return bqFields, nil } google-cloud-go-0.49.0/bigquery/standardsql_test.go000066400000000000000000000055641356504100700223370ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "testing" "cloud.google.com/go/internal/testutil" bq "google.golang.org/api/bigquery/v2" ) func TestBQToStandardSQLDataType(t *testing.T) { for _, test := range []struct { in *bq.StandardSqlDataType want *StandardSQLDataType }{ {&bq.StandardSqlDataType{}, &StandardSQLDataType{}}, { &bq.StandardSqlDataType{ TypeKind: "INT64", }, &StandardSQLDataType{ TypeKind: "INT64", }, }, { &bq.StandardSqlDataType{ TypeKind: "ARRAY", ArrayElementType: &bq.StandardSqlDataType{ TypeKind: "INT64", }, }, &StandardSQLDataType{ TypeKind: "ARRAY", ArrayElementType: &StandardSQLDataType{ TypeKind: "INT64", }, }, }, } { got, err := bqToStandardSQLDataType(test.in) if err != nil { t.Fatal(err) } if diff := testutil.Diff(got, test.want); diff != "" { t.Errorf("%+v: -got, +want:\n%s", test.in, diff) } } } func TestBQToStandardSQLField(t *testing.T) { for _, test := range []struct { in *bq.StandardSqlField want *StandardSQLField }{ {&bq.StandardSqlField{}, &StandardSQLField{}}, { &bq.StandardSqlField{ Name: "foo", Type: &bq.StandardSqlDataType{ TypeKind: "NUMERIC", }, }, &StandardSQLField{ Name: "foo", Type: &StandardSQLDataType{ TypeKind: "NUMERIC", }, }, }, } { got, err := bqToStandardSQLField(test.in) if err != nil { t.Fatal(err) } if diff := testutil.Diff(got, test.want); diff != "" { t.Errorf("%+v: -got, +want:\n%s", test.in, diff) } } } func TestBQToStandardSQLStructType(t *testing.T) { for _, test := range []struct { in *bq.StandardSqlStructType want *StandardSQLStructType }{ {&bq.StandardSqlStructType{}, &StandardSQLStructType{}}, { &bq.StandardSqlStructType{ Fields: []*bq.StandardSqlField{ { Name: "foo", Type: &bq.StandardSqlDataType{ TypeKind: "STRING", }, }, }, }, &StandardSQLStructType{ Fields: []*StandardSQLField{ { Name: "foo", Type: &StandardSQLDataType{ TypeKind: "STRING", }, }, }, }, }, } { got, err := bqToStandardSQLStructType(test.in) if err != nil { t.Fatal(err) } if diff := testutil.Diff(got, test.want); diff != "" { t.Errorf("%+v: -got, +want:\n%s", test.in, diff) } } } google-cloud-go-0.49.0/bigquery/storage/000077500000000000000000000000001356504100700200635ustar00rootroot00000000000000google-cloud-go-0.49.0/bigquery/storage/apiv1beta1/000077500000000000000000000000001356504100700220205ustar00rootroot00000000000000google-cloud-go-0.49.0/bigquery/storage/apiv1beta1/.repo-metadata.json000066400000000000000000000007061356504100700255170ustar00rootroot00000000000000{ "name": "storage", "name_pretty": "BigQuery Storage API", "product_documentation": "https://cloud.google.com/bigquery/docs/reference/storage", "client_documentation": "https://godoc.org/cloud.google.com/go/bigquery/storage/apiv1beta1", "release_level": "beta", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "bigquerystorage.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/bigquery/storage/apiv1beta1/big_query_storage_client.go000066400000000000000000000276141356504100700274310ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package storage import ( "context" "fmt" "math" "net/url" "time" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" "google.golang.org/api/transport" storagepb "google.golang.org/genproto/googleapis/cloud/bigquery/storage/v1beta1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // BigQueryStorageCallOptions contains the retry settings for each method of BigQueryStorageClient. type BigQueryStorageCallOptions struct { CreateReadSession []gax.CallOption ReadRows []gax.CallOption BatchCreateReadSessionStreams []gax.CallOption FinalizeStream []gax.CallOption SplitReadStream []gax.CallOption } func defaultBigQueryStorageClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("bigquerystorage.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultBigQueryStorageCallOptions() *BigQueryStorageCallOptions { retry := map[[2]string][]gax.CallOption{ {"create_read_session", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, {"read_rows", "unary_streaming"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &BigQueryStorageCallOptions{ CreateReadSession: retry[[2]string{"create_read_session", "idempotent"}], ReadRows: retry[[2]string{"read_rows", "unary_streaming"}], BatchCreateReadSessionStreams: retry[[2]string{"default", "idempotent"}], FinalizeStream: retry[[2]string{"default", "idempotent"}], SplitReadStream: retry[[2]string{"default", "idempotent"}], } } // BigQueryStorageClient is a client for interacting with BigQuery Storage API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type BigQueryStorageClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. bigQueryStorageClient storagepb.BigQueryStorageClient // The call options for this service. CallOptions *BigQueryStorageCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewBigQueryStorageClient creates a new big query storage client. // // BigQuery storage API. // // The BigQuery storage API can be used to read data stored in BigQuery. func NewBigQueryStorageClient(ctx context.Context, opts ...option.ClientOption) (*BigQueryStorageClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultBigQueryStorageClientOptions(), opts...)...) if err != nil { return nil, err } c := &BigQueryStorageClient{ conn: conn, CallOptions: defaultBigQueryStorageCallOptions(), bigQueryStorageClient: storagepb.NewBigQueryStorageClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *BigQueryStorageClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *BigQueryStorageClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *BigQueryStorageClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // CreateReadSession creates a new read session. A read session divides the contents of a // BigQuery table into one or more streams, which can then be used to read // data from the table. The read session also specifies properties of the // data to be read, such as a list of columns or a push-down filter describing // the rows to be returned. // // A particular row can be read by at most one stream. When the caller has // reached the end of each stream in the session, then all the data in the // table has been read. // // Read sessions automatically expire 24 hours after they are created and do // not require manual clean-up by the caller. func (c *BigQueryStorageClient) CreateReadSession(ctx context.Context, req *storagepb.CreateReadSessionRequest, opts ...gax.CallOption) (*storagepb.ReadSession, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v&%s=%v", "table_reference.project_id", url.QueryEscape(req.GetTableReference().GetProjectId()), "table_reference.dataset_id", url.QueryEscape(req.GetTableReference().GetDatasetId()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateReadSession[0:len(c.CallOptions.CreateReadSession):len(c.CallOptions.CreateReadSession)], opts...) var resp *storagepb.ReadSession err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.bigQueryStorageClient.CreateReadSession(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ReadRows reads rows from the table in the format prescribed by the read session. // Each response contains one or more table rows, up to a maximum of 10 MiB // per response; read requests which attempt to read individual rows larger // than this will fail. // // Each request also returns a set of stream statistics reflecting the // estimated total number of rows in the read stream. This number is computed // based on the total table size and the number of active streams in the read // session, and may change as other streams continue to read data. func (c *BigQueryStorageClient) ReadRows(ctx context.Context, req *storagepb.ReadRowsRequest, opts ...gax.CallOption) (storagepb.BigQueryStorage_ReadRowsClient, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "read_position.stream.name", url.QueryEscape(req.GetReadPosition().GetStream().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ReadRows[0:len(c.CallOptions.ReadRows):len(c.CallOptions.ReadRows)], opts...) var resp storagepb.BigQueryStorage_ReadRowsClient err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.bigQueryStorageClient.ReadRows(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // BatchCreateReadSessionStreams creates additional streams for a ReadSession. This API can be used to // dynamically adjust the parallelism of a batch processing task upwards by // adding additional workers. func (c *BigQueryStorageClient) BatchCreateReadSessionStreams(ctx context.Context, req *storagepb.BatchCreateReadSessionStreamsRequest, opts ...gax.CallOption) (*storagepb.BatchCreateReadSessionStreamsResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "session.name", url.QueryEscape(req.GetSession().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.BatchCreateReadSessionStreams[0:len(c.CallOptions.BatchCreateReadSessionStreams):len(c.CallOptions.BatchCreateReadSessionStreams)], opts...) var resp *storagepb.BatchCreateReadSessionStreamsResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.bigQueryStorageClient.BatchCreateReadSessionStreams(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // FinalizeStream triggers the graceful termination of a single stream in a ReadSession. This // API can be used to dynamically adjust the parallelism of a batch processing // task downwards without losing data. // // This API does not delete the stream -- it remains visible in the // ReadSession, and any data processed by the stream is not released to other // streams. However, no additional data will be assigned to the stream once // this call completes. Callers must continue reading data on the stream until // the end of the stream is reached so that data which has already been // assigned to the stream will be processed. // // This method will return an error if there are no other live streams // in the Session, or if SplitReadStream() has been called on the given // Stream. func (c *BigQueryStorageClient) FinalizeStream(ctx context.Context, req *storagepb.FinalizeStreamRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "stream.name", url.QueryEscape(req.GetStream().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.FinalizeStream[0:len(c.CallOptions.FinalizeStream):len(c.CallOptions.FinalizeStream)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.bigQueryStorageClient.FinalizeStream(ctx, req, settings.GRPC...) return err }, opts...) return err } // SplitReadStream splits a given read stream into two Streams. These streams are referred to // as the primary and the residual of the split. The original stream can still // be read from in the same manner as before. Both of the returned streams can // also be read from, and the total rows return by both child streams will be // the same as the rows read from the original stream. // // Moreover, the two child streams will be allocated back to back in the // original Stream. Concretely, it is guaranteed that for streams Original, // Primary, and Residual, that Original[0-j] = Primary[0-j] and // Original[j-n] = Residual[0-m] once the streams have been read to // completion. // // This method is guaranteed to be idempotent. func (c *BigQueryStorageClient) SplitReadStream(ctx context.Context, req *storagepb.SplitReadStreamRequest, opts ...gax.CallOption) (*storagepb.SplitReadStreamResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "original_stream.name", url.QueryEscape(req.GetOriginalStream().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.SplitReadStream[0:len(c.CallOptions.SplitReadStream):len(c.CallOptions.SplitReadStream)], opts...) var resp *storagepb.SplitReadStreamResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.bigQueryStorageClient.SplitReadStream(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } google-cloud-go-0.49.0/bigquery/storage/apiv1beta1/big_query_storage_client_example_test.go000066400000000000000000000057601356504100700322010ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package storage_test import ( "context" "io" storage "cloud.google.com/go/bigquery/storage/apiv1beta1" storagepb "google.golang.org/genproto/googleapis/cloud/bigquery/storage/v1beta1" ) func ExampleNewBigQueryStorageClient() { ctx := context.Background() c, err := storage.NewBigQueryStorageClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleBigQueryStorageClient_CreateReadSession() { ctx := context.Background() c, err := storage.NewBigQueryStorageClient(ctx) if err != nil { // TODO: Handle error. } req := &storagepb.CreateReadSessionRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateReadSession(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleBigQueryStorageClient_ReadRows() { ctx := context.Background() c, err := storage.NewBigQueryStorageClient(ctx) if err != nil { // TODO: Handle error. } req := &storagepb.ReadRowsRequest{ // TODO: Fill request struct fields. } stream, err := c.ReadRows(ctx, req) if err != nil { // TODO: Handle error. } for { resp, err := stream.Recv() if err == io.EOF { break } if err != nil { // TODO: handle error. } // TODO: Use resp. _ = resp } } func ExampleBigQueryStorageClient_BatchCreateReadSessionStreams() { ctx := context.Background() c, err := storage.NewBigQueryStorageClient(ctx) if err != nil { // TODO: Handle error. } req := &storagepb.BatchCreateReadSessionStreamsRequest{ // TODO: Fill request struct fields. } resp, err := c.BatchCreateReadSessionStreams(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleBigQueryStorageClient_FinalizeStream() { ctx := context.Background() c, err := storage.NewBigQueryStorageClient(ctx) if err != nil { // TODO: Handle error. } req := &storagepb.FinalizeStreamRequest{ // TODO: Fill request struct fields. } err = c.FinalizeStream(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleBigQueryStorageClient_SplitReadStream() { ctx := context.Background() c, err := storage.NewBigQueryStorageClient(ctx) if err != nil { // TODO: Handle error. } req := &storagepb.SplitReadStreamRequest{ // TODO: Fill request struct fields. } resp, err := c.SplitReadStream(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/bigquery/storage/apiv1beta1/doc.go000066400000000000000000000054151356504100700231210ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package storage is an auto-generated package for the // BigQuery Storage API. // // NOTE: This package is in beta. It is not stable, and may be subject to changes. // // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package storage // import "cloud.google.com/go/bigquery/storage/apiv1beta1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/bigquery", "https://www.googleapis.com/auth/bigquery.readonly", "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191115" google-cloud-go-0.49.0/bigquery/storage/apiv1beta1/mock_test.go000066400000000000000000000314271356504100700243460ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package storage import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" "google.golang.org/api/option" storagepb "google.golang.org/genproto/googleapis/cloud/bigquery/storage/v1beta1" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockBigQueryStorageServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. storagepb.BigQueryStorageServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockBigQueryStorageServer) CreateReadSession(ctx context.Context, req *storagepb.CreateReadSessionRequest) (*storagepb.ReadSession, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*storagepb.ReadSession), nil } func (s *mockBigQueryStorageServer) ReadRows(req *storagepb.ReadRowsRequest, stream storagepb.BigQueryStorage_ReadRowsServer) error { md, _ := metadata.FromIncomingContext(stream.Context()) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return s.err } for _, v := range s.resps { if err := stream.Send(v.(*storagepb.ReadRowsResponse)); err != nil { return err } } return nil } func (s *mockBigQueryStorageServer) BatchCreateReadSessionStreams(ctx context.Context, req *storagepb.BatchCreateReadSessionStreamsRequest) (*storagepb.BatchCreateReadSessionStreamsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*storagepb.BatchCreateReadSessionStreamsResponse), nil } func (s *mockBigQueryStorageServer) FinalizeStream(ctx context.Context, req *storagepb.FinalizeStreamRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockBigQueryStorageServer) SplitReadStream(ctx context.Context, req *storagepb.SplitReadStreamRequest) (*storagepb.SplitReadStreamResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*storagepb.SplitReadStreamResponse), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockBigQueryStorage mockBigQueryStorageServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() storagepb.RegisterBigQueryStorageServer(serv, &mockBigQueryStorage) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestBigQueryStorageCreateReadSession(t *testing.T) { var name string = "name3373707" var expectedResponse = &storagepb.ReadSession{ Name: name, } mockBigQueryStorage.err = nil mockBigQueryStorage.reqs = nil mockBigQueryStorage.resps = append(mockBigQueryStorage.resps[:0], expectedResponse) var tableReference *storagepb.TableReference = &storagepb.TableReference{} var parent string = "parent-995424086" var request = &storagepb.CreateReadSessionRequest{ TableReference: tableReference, Parent: parent, } c, err := NewBigQueryStorageClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateReadSession(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockBigQueryStorage.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestBigQueryStorageCreateReadSessionError(t *testing.T) { errCode := codes.PermissionDenied mockBigQueryStorage.err = gstatus.Error(errCode, "test error") var tableReference *storagepb.TableReference = &storagepb.TableReference{} var parent string = "parent-995424086" var request = &storagepb.CreateReadSessionRequest{ TableReference: tableReference, Parent: parent, } c, err := NewBigQueryStorageClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateReadSession(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestBigQueryStorageReadRows(t *testing.T) { var rowCount int64 = 1340416618 var expectedResponse = &storagepb.ReadRowsResponse{ RowCount: rowCount, } mockBigQueryStorage.err = nil mockBigQueryStorage.reqs = nil mockBigQueryStorage.resps = append(mockBigQueryStorage.resps[:0], expectedResponse) var readPosition *storagepb.StreamPosition = &storagepb.StreamPosition{} var request = &storagepb.ReadRowsRequest{ ReadPosition: readPosition, } c, err := NewBigQueryStorageClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } stream, err := c.ReadRows(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := stream.Recv() if err != nil { t.Fatal(err) } if want, got := request, mockBigQueryStorage.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestBigQueryStorageReadRowsError(t *testing.T) { errCode := codes.PermissionDenied mockBigQueryStorage.err = gstatus.Error(errCode, "test error") var readPosition *storagepb.StreamPosition = &storagepb.StreamPosition{} var request = &storagepb.ReadRowsRequest{ ReadPosition: readPosition, } c, err := NewBigQueryStorageClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } stream, err := c.ReadRows(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := stream.Recv() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestBigQueryStorageBatchCreateReadSessionStreams(t *testing.T) { var expectedResponse *storagepb.BatchCreateReadSessionStreamsResponse = &storagepb.BatchCreateReadSessionStreamsResponse{} mockBigQueryStorage.err = nil mockBigQueryStorage.reqs = nil mockBigQueryStorage.resps = append(mockBigQueryStorage.resps[:0], expectedResponse) var session *storagepb.ReadSession = &storagepb.ReadSession{} var requestedStreams int32 = 1017221410 var request = &storagepb.BatchCreateReadSessionStreamsRequest{ Session: session, RequestedStreams: requestedStreams, } c, err := NewBigQueryStorageClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.BatchCreateReadSessionStreams(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockBigQueryStorage.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestBigQueryStorageBatchCreateReadSessionStreamsError(t *testing.T) { errCode := codes.PermissionDenied mockBigQueryStorage.err = gstatus.Error(errCode, "test error") var session *storagepb.ReadSession = &storagepb.ReadSession{} var requestedStreams int32 = 1017221410 var request = &storagepb.BatchCreateReadSessionStreamsRequest{ Session: session, RequestedStreams: requestedStreams, } c, err := NewBigQueryStorageClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.BatchCreateReadSessionStreams(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestBigQueryStorageFinalizeStream(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockBigQueryStorage.err = nil mockBigQueryStorage.reqs = nil mockBigQueryStorage.resps = append(mockBigQueryStorage.resps[:0], expectedResponse) var stream *storagepb.Stream = &storagepb.Stream{} var request = &storagepb.FinalizeStreamRequest{ Stream: stream, } c, err := NewBigQueryStorageClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.FinalizeStream(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockBigQueryStorage.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestBigQueryStorageFinalizeStreamError(t *testing.T) { errCode := codes.PermissionDenied mockBigQueryStorage.err = gstatus.Error(errCode, "test error") var stream *storagepb.Stream = &storagepb.Stream{} var request = &storagepb.FinalizeStreamRequest{ Stream: stream, } c, err := NewBigQueryStorageClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.FinalizeStream(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestBigQueryStorageSplitReadStream(t *testing.T) { var expectedResponse *storagepb.SplitReadStreamResponse = &storagepb.SplitReadStreamResponse{} mockBigQueryStorage.err = nil mockBigQueryStorage.reqs = nil mockBigQueryStorage.resps = append(mockBigQueryStorage.resps[:0], expectedResponse) var originalStream *storagepb.Stream = &storagepb.Stream{} var request = &storagepb.SplitReadStreamRequest{ OriginalStream: originalStream, } c, err := NewBigQueryStorageClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SplitReadStream(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockBigQueryStorage.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestBigQueryStorageSplitReadStreamError(t *testing.T) { errCode := codes.PermissionDenied mockBigQueryStorage.err = gstatus.Error(errCode, "test error") var originalStream *storagepb.Stream = &storagepb.Stream{} var request = &storagepb.SplitReadStreamRequest{ OriginalStream: originalStream, } c, err := NewBigQueryStorageClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SplitReadStream(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/bigquery/table.go000066400000000000000000000545051356504100700200460ustar00rootroot00000000000000// Copyright 2015 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "context" "errors" "fmt" "time" "cloud.google.com/go/internal/optional" "cloud.google.com/go/internal/trace" bq "google.golang.org/api/bigquery/v2" ) // A Table is a reference to a BigQuery table. type Table struct { // ProjectID, DatasetID and TableID may be omitted if the Table is the destination for a query. // In this case the result will be stored in an ephemeral table. ProjectID string DatasetID string // TableID must contain only letters (a-z, A-Z), numbers (0-9), or underscores (_). // The maximum length is 1,024 characters. TableID string c *Client } // TableMetadata contains information about a BigQuery table. type TableMetadata struct { // The following fields can be set when creating a table. // The user-friendly name for the table. Name string // The user-friendly description of the table. Description string // The table schema. If provided on create, ViewQuery must be empty. Schema Schema // The query to use for a view. If provided on create, Schema must be nil. ViewQuery string // Use Legacy SQL for the view query. // At most one of UseLegacySQL and UseStandardSQL can be true. UseLegacySQL bool // Use Standard SQL for the view query. The default. // At most one of UseLegacySQL and UseStandardSQL can be true. // Deprecated: use UseLegacySQL. UseStandardSQL bool // If non-nil, the table is partitioned by time. Only one of // time partitioning or range partitioning can be specified. TimePartitioning *TimePartitioning // It non-nil, the table is partitioned by integer range. Only one of // time partitioning or range partitioning can be specified. RangePartitioning *RangePartitioning // If set to true, queries that reference this table must specify a // partition filter (e.g. a WHERE clause) that can be used to eliminate // partitions. Used to prevent unintentional full data scans on large // partitioned tables. RequirePartitionFilter bool // Clustering specifies the data clustering configuration for the table. Clustering *Clustering // The time when this table expires. If set, this table will expire at the // specified time. Expired tables will be deleted and their storage // reclaimed. The zero value is ignored. ExpirationTime time.Time // User-provided labels. Labels map[string]string // Information about a table stored outside of BigQuery. ExternalDataConfig *ExternalDataConfig // Custom encryption configuration (e.g., Cloud KMS keys). EncryptionConfig *EncryptionConfig // All the fields below are read-only. FullID string // An opaque ID uniquely identifying the table. Type TableType CreationTime time.Time LastModifiedTime time.Time // The size of the table in bytes. // This does not include data that is being buffered during a streaming insert. NumBytes int64 // The number of bytes in the table considered "long-term storage" for reduced // billing purposes. See https://cloud.google.com/bigquery/pricing#long-term-storage // for more information. NumLongTermBytes int64 // The number of rows of data in this table. // This does not include data that is being buffered during a streaming insert. NumRows uint64 // Contains information regarding this table's streaming buffer, if one is // present. This field will be nil if the table is not being streamed to or if // there is no data in the streaming buffer. StreamingBuffer *StreamingBuffer // ETag is the ETag obtained when reading metadata. Pass it to Table.Update to // ensure that the metadata hasn't changed since it was read. ETag string } // TableCreateDisposition specifies the circumstances under which destination table will be created. // Default is CreateIfNeeded. type TableCreateDisposition string const ( // CreateIfNeeded will create the table if it does not already exist. // Tables are created atomically on successful completion of a job. CreateIfNeeded TableCreateDisposition = "CREATE_IF_NEEDED" // CreateNever ensures the table must already exist and will not be // automatically created. CreateNever TableCreateDisposition = "CREATE_NEVER" ) // TableWriteDisposition specifies how existing data in a destination table is treated. // Default is WriteAppend. type TableWriteDisposition string const ( // WriteAppend will append to any existing data in the destination table. // Data is appended atomically on successful completion of a job. WriteAppend TableWriteDisposition = "WRITE_APPEND" // WriteTruncate overrides the existing data in the destination table. // Data is overwritten atomically on successful completion of a job. WriteTruncate TableWriteDisposition = "WRITE_TRUNCATE" // WriteEmpty fails writes if the destination table already contains data. WriteEmpty TableWriteDisposition = "WRITE_EMPTY" ) // TableType is the type of table. type TableType string const ( // RegularTable is a regular table. RegularTable TableType = "TABLE" // ViewTable is a table type describing that the table is view. See more // information at https://cloud.google.com/bigquery/docs/views. ViewTable TableType = "VIEW" // ExternalTable is a table type describing that the table is an external // table (also known as a federated data source). See more information at // https://cloud.google.com/bigquery/external-data-sources. ExternalTable TableType = "EXTERNAL" ) // TimePartitioning describes the time-based date partitioning on a table. // For more information see: https://cloud.google.com/bigquery/docs/creating-partitioned-tables. type TimePartitioning struct { // The amount of time to keep the storage for a partition. // If the duration is empty (0), the data in the partitions do not expire. Expiration time.Duration // If empty, the table is partitioned by pseudo column '_PARTITIONTIME'; if set, the // table is partitioned by this field. The field must be a top-level TIMESTAMP or // DATE field. Its mode must be NULLABLE or REQUIRED. Field string // If set to true, queries that reference this table must specify a // partition filter (e.g. a WHERE clause) that can be used to eliminate // partitions. Used to prevent unintentional full data scans on large // partitioned tables. // DEPRECATED: use the top-level RequirePartitionFilter in TableMetadata. RequirePartitionFilter bool } func (p *TimePartitioning) toBQ() *bq.TimePartitioning { if p == nil { return nil } return &bq.TimePartitioning{ Type: "DAY", ExpirationMs: int64(p.Expiration / time.Millisecond), Field: p.Field, RequirePartitionFilter: p.RequirePartitionFilter, } } func bqToTimePartitioning(q *bq.TimePartitioning) *TimePartitioning { if q == nil { return nil } return &TimePartitioning{ Expiration: time.Duration(q.ExpirationMs) * time.Millisecond, Field: q.Field, RequirePartitionFilter: q.RequirePartitionFilter, } } // RangePartitioning indicates an integer-range based storage organization strategy. type RangePartitioning struct { // The field by which the table is partitioned. // This field must be a top-level field, and must be typed as an // INTEGER/INT64. Field string // The details of how partitions are mapped onto the integer range. Range *RangePartitioningRange } // RangePartitioningRange defines the boundaries and width of partitioned values. type RangePartitioningRange struct { // The start value of defined range of values, inclusive of the specified value. Start int64 // The end of the defined range of values, exclusive of the defined value. End int64 // The width of each interval range. Interval int64 } func (rp *RangePartitioning) toBQ() *bq.RangePartitioning { if rp == nil { return nil } return &bq.RangePartitioning{ Field: rp.Field, Range: rp.Range.toBQ(), } } func bqToRangePartitioning(q *bq.RangePartitioning) *RangePartitioning { if q == nil { return nil } return &RangePartitioning{ Field: q.Field, Range: bqToRangePartitioningRange(q.Range), } } func bqToRangePartitioningRange(br *bq.RangePartitioningRange) *RangePartitioningRange { if br == nil { return nil } return &RangePartitioningRange{ Start: br.Start, End: br.End, Interval: br.Interval, } } func (rpr *RangePartitioningRange) toBQ() *bq.RangePartitioningRange { if rpr == nil { return nil } return &bq.RangePartitioningRange{ Start: rpr.Start, End: rpr.End, Interval: rpr.Interval, } } // Clustering governs the organization of data within a partitioned table. // For more information, see https://cloud.google.com/bigquery/docs/clustered-tables type Clustering struct { Fields []string } func (c *Clustering) toBQ() *bq.Clustering { if c == nil { return nil } return &bq.Clustering{ Fields: c.Fields, } } func bqToClustering(q *bq.Clustering) *Clustering { if q == nil { return nil } return &Clustering{ Fields: q.Fields, } } // EncryptionConfig configures customer-managed encryption on tables and ML models. type EncryptionConfig struct { // Describes the Cloud KMS encryption key that will be used to protect // destination BigQuery table. The BigQuery Service Account associated with your // project requires access to this encryption key. KMSKeyName string } func (e *EncryptionConfig) toBQ() *bq.EncryptionConfiguration { if e == nil { return nil } return &bq.EncryptionConfiguration{ KmsKeyName: e.KMSKeyName, } } func bqToEncryptionConfig(q *bq.EncryptionConfiguration) *EncryptionConfig { if q == nil { return nil } return &EncryptionConfig{ KMSKeyName: q.KmsKeyName, } } // StreamingBuffer holds information about the streaming buffer. type StreamingBuffer struct { // A lower-bound estimate of the number of bytes currently in the streaming // buffer. EstimatedBytes uint64 // A lower-bound estimate of the number of rows currently in the streaming // buffer. EstimatedRows uint64 // The time of the oldest entry in the streaming buffer. OldestEntryTime time.Time } func (t *Table) toBQ() *bq.TableReference { return &bq.TableReference{ ProjectId: t.ProjectID, DatasetId: t.DatasetID, TableId: t.TableID, } } // FullyQualifiedName returns the ID of the table in projectID:datasetID.tableID format. func (t *Table) FullyQualifiedName() string { return fmt.Sprintf("%s:%s.%s", t.ProjectID, t.DatasetID, t.TableID) } // implicitTable reports whether Table is an empty placeholder, which signifies that a new table should be created with an auto-generated Table ID. func (t *Table) implicitTable() bool { return t.ProjectID == "" && t.DatasetID == "" && t.TableID == "" } // Create creates a table in the BigQuery service. // Pass in a TableMetadata value to configure the table. // If tm.View.Query is non-empty, the created table will be of type VIEW. // If no ExpirationTime is specified, the table will never expire. // After table creation, a view can be modified only if its table was initially created // with a view. func (t *Table) Create(ctx context.Context, tm *TableMetadata) (err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Table.Create") defer func() { trace.EndSpan(ctx, err) }() table, err := tm.toBQ() if err != nil { return err } table.TableReference = &bq.TableReference{ ProjectId: t.ProjectID, DatasetId: t.DatasetID, TableId: t.TableID, } req := t.c.bqs.Tables.Insert(t.ProjectID, t.DatasetID, table).Context(ctx) setClientHeader(req.Header()) _, err = req.Do() return err } func (tm *TableMetadata) toBQ() (*bq.Table, error) { t := &bq.Table{} if tm == nil { return t, nil } if tm.Schema != nil && tm.ViewQuery != "" { return nil, errors.New("bigquery: provide Schema or ViewQuery, not both") } t.FriendlyName = tm.Name t.Description = tm.Description t.Labels = tm.Labels if tm.Schema != nil { t.Schema = tm.Schema.toBQ() } if tm.ViewQuery != "" { if tm.UseStandardSQL && tm.UseLegacySQL { return nil, errors.New("bigquery: cannot provide both UseStandardSQL and UseLegacySQL") } t.View = &bq.ViewDefinition{Query: tm.ViewQuery} if tm.UseLegacySQL { t.View.UseLegacySql = true } else { t.View.UseLegacySql = false t.View.ForceSendFields = append(t.View.ForceSendFields, "UseLegacySql") } } else if tm.UseLegacySQL || tm.UseStandardSQL { return nil, errors.New("bigquery: UseLegacy/StandardSQL requires ViewQuery") } t.TimePartitioning = tm.TimePartitioning.toBQ() t.RangePartitioning = tm.RangePartitioning.toBQ() t.Clustering = tm.Clustering.toBQ() t.RequirePartitionFilter = tm.RequirePartitionFilter if !validExpiration(tm.ExpirationTime) { return nil, fmt.Errorf("invalid expiration time: %v.\n"+ "Valid expiration times are after 1678 and before 2262", tm.ExpirationTime) } if !tm.ExpirationTime.IsZero() && tm.ExpirationTime != NeverExpire { t.ExpirationTime = tm.ExpirationTime.UnixNano() / 1e6 } if tm.ExternalDataConfig != nil { edc := tm.ExternalDataConfig.toBQ() t.ExternalDataConfiguration = &edc } t.EncryptionConfiguration = tm.EncryptionConfig.toBQ() if tm.FullID != "" { return nil, errors.New("cannot set FullID on create") } if tm.Type != "" { return nil, errors.New("cannot set Type on create") } if !tm.CreationTime.IsZero() { return nil, errors.New("cannot set CreationTime on create") } if !tm.LastModifiedTime.IsZero() { return nil, errors.New("cannot set LastModifiedTime on create") } if tm.NumBytes != 0 { return nil, errors.New("cannot set NumBytes on create") } if tm.NumLongTermBytes != 0 { return nil, errors.New("cannot set NumLongTermBytes on create") } if tm.NumRows != 0 { return nil, errors.New("cannot set NumRows on create") } if tm.StreamingBuffer != nil { return nil, errors.New("cannot set StreamingBuffer on create") } if tm.ETag != "" { return nil, errors.New("cannot set ETag on create") } return t, nil } // Metadata fetches the metadata for the table. func (t *Table) Metadata(ctx context.Context) (md *TableMetadata, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Table.Metadata") defer func() { trace.EndSpan(ctx, err) }() req := t.c.bqs.Tables.Get(t.ProjectID, t.DatasetID, t.TableID).Context(ctx) setClientHeader(req.Header()) var table *bq.Table err = runWithRetry(ctx, func() (err error) { table, err = req.Do() return err }) if err != nil { return nil, err } return bqToTableMetadata(table) } func bqToTableMetadata(t *bq.Table) (*TableMetadata, error) { md := &TableMetadata{ Description: t.Description, Name: t.FriendlyName, Type: TableType(t.Type), FullID: t.Id, Labels: t.Labels, NumBytes: t.NumBytes, NumLongTermBytes: t.NumLongTermBytes, NumRows: t.NumRows, ExpirationTime: unixMillisToTime(t.ExpirationTime), CreationTime: unixMillisToTime(t.CreationTime), LastModifiedTime: unixMillisToTime(int64(t.LastModifiedTime)), ETag: t.Etag, EncryptionConfig: bqToEncryptionConfig(t.EncryptionConfiguration), RequirePartitionFilter: t.RequirePartitionFilter, } if t.Schema != nil { md.Schema = bqToSchema(t.Schema) } if t.View != nil { md.ViewQuery = t.View.Query md.UseLegacySQL = t.View.UseLegacySql } md.TimePartitioning = bqToTimePartitioning(t.TimePartitioning) md.RangePartitioning = bqToRangePartitioning(t.RangePartitioning) md.Clustering = bqToClustering(t.Clustering) if t.StreamingBuffer != nil { md.StreamingBuffer = &StreamingBuffer{ EstimatedBytes: t.StreamingBuffer.EstimatedBytes, EstimatedRows: t.StreamingBuffer.EstimatedRows, OldestEntryTime: unixMillisToTime(int64(t.StreamingBuffer.OldestEntryTime)), } } if t.ExternalDataConfiguration != nil { edc, err := bqToExternalDataConfig(t.ExternalDataConfiguration) if err != nil { return nil, err } md.ExternalDataConfig = edc } return md, nil } // Delete deletes the table. func (t *Table) Delete(ctx context.Context) (err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Table.Delete") defer func() { trace.EndSpan(ctx, err) }() req := t.c.bqs.Tables.Delete(t.ProjectID, t.DatasetID, t.TableID).Context(ctx) setClientHeader(req.Header()) return req.Do() } // Read fetches the contents of the table. func (t *Table) Read(ctx context.Context) *RowIterator { return t.read(ctx, fetchPage) } func (t *Table) read(ctx context.Context, pf pageFetcher) *RowIterator { return newRowIterator(ctx, t, pf) } // NeverExpire is a sentinel value used to remove a table'e expiration time. var NeverExpire = time.Time{}.Add(-1) // Update modifies specific Table metadata fields. func (t *Table) Update(ctx context.Context, tm TableMetadataToUpdate, etag string) (md *TableMetadata, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Table.Update") defer func() { trace.EndSpan(ctx, err) }() bqt, err := tm.toBQ() if err != nil { return nil, err } call := t.c.bqs.Tables.Patch(t.ProjectID, t.DatasetID, t.TableID, bqt).Context(ctx) setClientHeader(call.Header()) if etag != "" { call.Header().Set("If-Match", etag) } var res *bq.Table if err := runWithRetry(ctx, func() (err error) { res, err = call.Do() return err }); err != nil { return nil, err } return bqToTableMetadata(res) } func (tm *TableMetadataToUpdate) toBQ() (*bq.Table, error) { t := &bq.Table{} forceSend := func(field string) { t.ForceSendFields = append(t.ForceSendFields, field) } if tm.Description != nil { t.Description = optional.ToString(tm.Description) forceSend("Description") } if tm.Name != nil { t.FriendlyName = optional.ToString(tm.Name) forceSend("FriendlyName") } if tm.Schema != nil { t.Schema = tm.Schema.toBQ() forceSend("Schema") } if tm.EncryptionConfig != nil { t.EncryptionConfiguration = tm.EncryptionConfig.toBQ() } if !validExpiration(tm.ExpirationTime) { return nil, invalidTimeError(tm.ExpirationTime) } if tm.ExpirationTime == NeverExpire { t.NullFields = append(t.NullFields, "ExpirationTime") } else if !tm.ExpirationTime.IsZero() { t.ExpirationTime = tm.ExpirationTime.UnixNano() / 1e6 forceSend("ExpirationTime") } if tm.TimePartitioning != nil { t.TimePartitioning = tm.TimePartitioning.toBQ() t.TimePartitioning.ForceSendFields = []string{"RequirePartitionFilter"} if tm.TimePartitioning.Expiration == 0 { t.TimePartitioning.NullFields = []string{"ExpirationMs"} } } if tm.RequirePartitionFilter != nil { t.RequirePartitionFilter = optional.ToBool(tm.RequirePartitionFilter) forceSend("RequirePartitionFilter") } if tm.ViewQuery != nil { t.View = &bq.ViewDefinition{ Query: optional.ToString(tm.ViewQuery), ForceSendFields: []string{"Query"}, } } if tm.UseLegacySQL != nil { if t.View == nil { t.View = &bq.ViewDefinition{} } t.View.UseLegacySql = optional.ToBool(tm.UseLegacySQL) t.View.ForceSendFields = append(t.View.ForceSendFields, "UseLegacySql") } labels, forces, nulls := tm.update() t.Labels = labels t.ForceSendFields = append(t.ForceSendFields, forces...) t.NullFields = append(t.NullFields, nulls...) return t, nil } // validExpiration ensures a specified time is either the sentinel NeverExpire, // the zero value, or within the defined range of UnixNano. Internal // represetations of expiration times are based upon Time.UnixNano. Any time // before 1678 or after 2262 cannot be represented by an int64 and is therefore // undefined and invalid. See https://godoc.org/time#Time.UnixNano. func validExpiration(t time.Time) bool { return t == NeverExpire || t.IsZero() || time.Unix(0, t.UnixNano()).Equal(t) } // invalidTimeError emits a consistent error message for failures of the // validExpiration function. func invalidTimeError(t time.Time) error { return fmt.Errorf("invalid expiration time %v. "+ "Valid expiration times are after 1678 and before 2262", t) } // TableMetadataToUpdate is used when updating a table's metadata. // Only non-nil fields will be updated. type TableMetadataToUpdate struct { // The user-friendly description of this table. Description optional.String // The user-friendly name for this table. Name optional.String // The table's schema. // When updating a schema, you can add columns but not remove them. Schema Schema // The table's encryption configuration. EncryptionConfig *EncryptionConfig // The time when this table expires. To remove a table's expiration, // set ExpirationTime to NeverExpire. The zero value is ignored. ExpirationTime time.Time // The query to use for a view. ViewQuery optional.String // Use Legacy SQL for the view query. UseLegacySQL optional.Bool // TimePartitioning allows modification of certain aspects of partition // configuration such as partition expiration and whether partition // filtration is required at query time. When calling Update, ensure // that all mutable fields of TimePartitioning are populated. TimePartitioning *TimePartitioning // RequirePartitionFilter governs whether the table enforces partition // elimination when referenced in a query. RequirePartitionFilter optional.Bool labelUpdater } // labelUpdater contains common code for updating labels. type labelUpdater struct { setLabels map[string]string deleteLabels map[string]bool } // SetLabel causes a label to be added or modified on a call to Update. func (u *labelUpdater) SetLabel(name, value string) { if u.setLabels == nil { u.setLabels = map[string]string{} } u.setLabels[name] = value } // DeleteLabel causes a label to be deleted on a call to Update. func (u *labelUpdater) DeleteLabel(name string) { if u.deleteLabels == nil { u.deleteLabels = map[string]bool{} } u.deleteLabels[name] = true } func (u *labelUpdater) update() (labels map[string]string, forces, nulls []string) { if u.setLabels == nil && u.deleteLabels == nil { return nil, nil, nil } labels = map[string]string{} for k, v := range u.setLabels { labels[k] = v } if len(labels) == 0 && len(u.deleteLabels) > 0 { forces = []string{"Labels"} } for l := range u.deleteLabels { nulls = append(nulls, "Labels."+l) } return labels, forces, nulls } google-cloud-go-0.49.0/bigquery/table_test.go000066400000000000000000000265071356504100700211060ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "testing" "time" "cloud.google.com/go/internal/testutil" bq "google.golang.org/api/bigquery/v2" ) func TestBQToTableMetadata(t *testing.T) { aTime := time.Date(2017, 1, 26, 0, 0, 0, 0, time.Local) aTimeMillis := aTime.UnixNano() / 1e6 for _, test := range []struct { in *bq.Table want *TableMetadata }{ {&bq.Table{}, &TableMetadata{}}, // test minimal case { &bq.Table{ CreationTime: aTimeMillis, Description: "desc", Etag: "etag", ExpirationTime: aTimeMillis, FriendlyName: "fname", Id: "id", LastModifiedTime: uint64(aTimeMillis), Location: "loc", NumBytes: 123, NumLongTermBytes: 23, NumRows: 7, StreamingBuffer: &bq.Streamingbuffer{ EstimatedBytes: 11, EstimatedRows: 3, OldestEntryTime: uint64(aTimeMillis), }, TimePartitioning: &bq.TimePartitioning{ ExpirationMs: 7890, Type: "DAY", Field: "pfield", }, Clustering: &bq.Clustering{ Fields: []string{"cfield1", "cfield2"}, }, RequirePartitionFilter: true, EncryptionConfiguration: &bq.EncryptionConfiguration{KmsKeyName: "keyName"}, Type: "EXTERNAL", View: &bq.ViewDefinition{Query: "view-query"}, Labels: map[string]string{"a": "b"}, ExternalDataConfiguration: &bq.ExternalDataConfiguration{ SourceFormat: "GOOGLE_SHEETS", }, }, &TableMetadata{ Description: "desc", Name: "fname", ViewQuery: "view-query", FullID: "id", Type: ExternalTable, Labels: map[string]string{"a": "b"}, ExternalDataConfig: &ExternalDataConfig{SourceFormat: GoogleSheets}, ExpirationTime: aTime.Truncate(time.Millisecond), CreationTime: aTime.Truncate(time.Millisecond), LastModifiedTime: aTime.Truncate(time.Millisecond), NumBytes: 123, NumLongTermBytes: 23, NumRows: 7, TimePartitioning: &TimePartitioning{ Expiration: 7890 * time.Millisecond, Field: "pfield", }, Clustering: &Clustering{ Fields: []string{"cfield1", "cfield2"}, }, RequirePartitionFilter: true, StreamingBuffer: &StreamingBuffer{ EstimatedBytes: 11, EstimatedRows: 3, OldestEntryTime: aTime, }, EncryptionConfig: &EncryptionConfig{KMSKeyName: "keyName"}, ETag: "etag", }, }, } { got, err := bqToTableMetadata(test.in) if err != nil { t.Fatal(err) } if diff := testutil.Diff(got, test.want); diff != "" { t.Errorf("%+v:\n, -got, +want:\n%s", test.in, diff) } } } func TestTableMetadataToBQ(t *testing.T) { aTime := time.Date(2017, 1, 26, 0, 0, 0, 0, time.Local) aTimeMillis := aTime.UnixNano() / 1e6 sc := Schema{fieldSchema("desc", "name", "STRING", false, true)} for _, test := range []struct { in *TableMetadata want *bq.Table }{ {nil, &bq.Table{}}, {&TableMetadata{}, &bq.Table{}}, { &TableMetadata{ Name: "n", Description: "d", Schema: sc, ExpirationTime: aTime, Labels: map[string]string{"a": "b"}, ExternalDataConfig: &ExternalDataConfig{SourceFormat: Bigtable}, EncryptionConfig: &EncryptionConfig{KMSKeyName: "keyName"}, }, &bq.Table{ FriendlyName: "n", Description: "d", Schema: &bq.TableSchema{ Fields: []*bq.TableFieldSchema{ bqTableFieldSchema("desc", "name", "STRING", "REQUIRED"), }, }, ExpirationTime: aTimeMillis, Labels: map[string]string{"a": "b"}, ExternalDataConfiguration: &bq.ExternalDataConfiguration{SourceFormat: "BIGTABLE"}, EncryptionConfiguration: &bq.EncryptionConfiguration{KmsKeyName: "keyName"}, }, }, { &TableMetadata{ViewQuery: "q"}, &bq.Table{ View: &bq.ViewDefinition{ Query: "q", UseLegacySql: false, ForceSendFields: []string{"UseLegacySql"}, }, }, }, { &TableMetadata{ ViewQuery: "q", UseLegacySQL: true, TimePartitioning: &TimePartitioning{}, RequirePartitionFilter: true, }, &bq.Table{ View: &bq.ViewDefinition{ Query: "q", UseLegacySql: true, }, TimePartitioning: &bq.TimePartitioning{ Type: "DAY", ExpirationMs: 0, }, RequirePartitionFilter: true, }, }, { &TableMetadata{ ViewQuery: "q", UseStandardSQL: true, TimePartitioning: &TimePartitioning{ Expiration: time.Second, Field: "ofDreams", }, Clustering: &Clustering{ Fields: []string{"cfield1"}, }, }, &bq.Table{ View: &bq.ViewDefinition{ Query: "q", UseLegacySql: false, ForceSendFields: []string{"UseLegacySql"}, }, TimePartitioning: &bq.TimePartitioning{ Type: "DAY", ExpirationMs: 1000, Field: "ofDreams", }, Clustering: &bq.Clustering{ Fields: []string{"cfield1"}, }, }, }, { &TableMetadata{ RangePartitioning: &RangePartitioning{ Field: "ofNumbers", Range: &RangePartitioningRange{ Start: 1, End: 100, Interval: 5, }, }, Clustering: &Clustering{ Fields: []string{"cfield1"}, }, }, &bq.Table{ RangePartitioning: &bq.RangePartitioning{ Field: "ofNumbers", Range: &bq.RangePartitioningRange{ Start: 1, End: 100, Interval: 5, }, }, Clustering: &bq.Clustering{ Fields: []string{"cfield1"}, }, }, }, { &TableMetadata{ExpirationTime: NeverExpire}, &bq.Table{ExpirationTime: 0}, }, } { got, err := test.in.toBQ() if err != nil { t.Fatalf("%+v: %v", test.in, err) } if diff := testutil.Diff(got, test.want); diff != "" { t.Errorf("%+v:\n-got, +want:\n%s", test.in, diff) } } // Errors for _, in := range []*TableMetadata{ {Schema: sc, ViewQuery: "q"}, // can't have both schema and query {UseLegacySQL: true}, // UseLegacySQL without query {UseStandardSQL: true}, // UseStandardSQL without query // read-only fields {FullID: "x"}, {Type: "x"}, {CreationTime: aTime}, {LastModifiedTime: aTime}, {NumBytes: 1}, {NumLongTermBytes: 1}, {NumRows: 1}, {StreamingBuffer: &StreamingBuffer{}}, {ETag: "x"}, // expiration time outside allowable range is invalid // See https://godoc.org/time#Time.UnixNano {ExpirationTime: time.Date(1677, 9, 21, 0, 12, 43, 145224192, time.UTC).Add(-1)}, {ExpirationTime: time.Date(2262, 04, 11, 23, 47, 16, 854775807, time.UTC).Add(1)}, } { _, err := in.toBQ() if err == nil { t.Errorf("%+v: got nil, want error", in) } } } func TestTableMetadataToUpdateToBQ(t *testing.T) { aTime := time.Date(2017, 1, 26, 0, 0, 0, 0, time.Local) for _, test := range []struct { tm TableMetadataToUpdate want *bq.Table }{ { tm: TableMetadataToUpdate{}, want: &bq.Table{}, }, { tm: TableMetadataToUpdate{ Description: "d", Name: "n", }, want: &bq.Table{ Description: "d", FriendlyName: "n", ForceSendFields: []string{"Description", "FriendlyName"}, }, }, { tm: TableMetadataToUpdate{ Schema: Schema{fieldSchema("desc", "name", "STRING", false, true)}, ExpirationTime: aTime, }, want: &bq.Table{ Schema: &bq.TableSchema{ Fields: []*bq.TableFieldSchema{ bqTableFieldSchema("desc", "name", "STRING", "REQUIRED"), }, }, ExpirationTime: aTime.UnixNano() / 1e6, ForceSendFields: []string{"Schema", "ExpirationTime"}, }, }, { tm: TableMetadataToUpdate{ViewQuery: "q"}, want: &bq.Table{ View: &bq.ViewDefinition{Query: "q", ForceSendFields: []string{"Query"}}, }, }, { tm: TableMetadataToUpdate{UseLegacySQL: false}, want: &bq.Table{ View: &bq.ViewDefinition{ UseLegacySql: false, ForceSendFields: []string{"UseLegacySql"}, }, }, }, { tm: TableMetadataToUpdate{ViewQuery: "q", UseLegacySQL: true}, want: &bq.Table{ View: &bq.ViewDefinition{ Query: "q", UseLegacySql: true, ForceSendFields: []string{"Query", "UseLegacySql"}, }, }, }, { tm: func() (tm TableMetadataToUpdate) { tm.SetLabel("L", "V") tm.DeleteLabel("D") return tm }(), want: &bq.Table{ Labels: map[string]string{"L": "V"}, NullFields: []string{"Labels.D"}, }, }, { tm: TableMetadataToUpdate{ExpirationTime: NeverExpire}, want: &bq.Table{ NullFields: []string{"ExpirationTime"}, }, }, { tm: TableMetadataToUpdate{TimePartitioning: &TimePartitioning{Expiration: 0}}, want: &bq.Table{ TimePartitioning: &bq.TimePartitioning{ Type: "DAY", ForceSendFields: []string{"RequirePartitionFilter"}, NullFields: []string{"ExpirationMs"}, }, }, }, { tm: TableMetadataToUpdate{TimePartitioning: &TimePartitioning{Expiration: time.Duration(time.Hour)}}, want: &bq.Table{ TimePartitioning: &bq.TimePartitioning{ ExpirationMs: 3600000, Type: "DAY", ForceSendFields: []string{"RequirePartitionFilter"}, }, }, }, { tm: TableMetadataToUpdate{RequirePartitionFilter: false}, want: &bq.Table{ RequirePartitionFilter: false, ForceSendFields: []string{"RequirePartitionFilter"}, }, }, { tm: TableMetadataToUpdate{RequirePartitionFilter: true}, want: &bq.Table{ RequirePartitionFilter: true, ForceSendFields: []string{"RequirePartitionFilter"}, }, }, } { got, _ := test.tm.toBQ() if !testutil.Equal(got, test.want) { t.Errorf("%+v:\ngot %+v\nwant %+v", test.tm, got, test.want) } } } func TestTableMetadataToUpdateToBQErrors(t *testing.T) { // See https://godoc.org/time#Time.UnixNano start := time.Date(1677, 9, 21, 0, 12, 43, 145224192, time.UTC) end := time.Date(2262, 04, 11, 23, 47, 16, 854775807, time.UTC) for _, test := range []struct { desc string aTime time.Time wantErr bool }{ {desc: "ignored zero value", aTime: time.Time{}, wantErr: false}, {desc: "earliest valid time", aTime: start, wantErr: false}, {desc: "latested valid time", aTime: end, wantErr: false}, {desc: "invalid times before 1678", aTime: start.Add(-1), wantErr: true}, {desc: "invalid times after 2262", aTime: end.Add(1), wantErr: true}, {desc: "valid times after 1678", aTime: start.Add(1), wantErr: false}, {desc: "valid times before 2262", aTime: end.Add(-1), wantErr: false}, } { tm := &TableMetadataToUpdate{ExpirationTime: test.aTime} _, err := tm.toBQ() if test.wantErr && err == nil { t.Errorf("[%s] got no error, want error", test.desc) } if !test.wantErr && err != nil { t.Errorf("[%s] got error, want no error", test.desc) } } } google-cloud-go-0.49.0/bigquery/value.go000066400000000000000000000577421356504100700201010ustar00rootroot00000000000000// Copyright 2015 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "encoding/base64" "errors" "fmt" "math" "math/big" "reflect" "strconv" "strings" "time" "cloud.google.com/go/civil" bq "google.golang.org/api/bigquery/v2" ) // Value stores the contents of a single cell from a BigQuery result. type Value interface{} // ValueLoader stores a slice of Values representing a result row from a Read operation. // See RowIterator.Next for more information. type ValueLoader interface { Load(v []Value, s Schema) error } // valueList converts a []Value to implement ValueLoader. type valueList []Value // Load stores a sequence of values in a valueList. // It resets the slice length to zero, then appends each value to it. func (vs *valueList) Load(v []Value, _ Schema) error { *vs = append((*vs)[:0], v...) return nil } // valueMap converts a map[string]Value to implement ValueLoader. type valueMap map[string]Value // Load stores a sequence of values in a valueMap. func (vm *valueMap) Load(v []Value, s Schema) error { if *vm == nil { *vm = map[string]Value{} } loadMap(*vm, v, s) return nil } func loadMap(m map[string]Value, vals []Value, s Schema) { for i, f := range s { val := vals[i] var v interface{} switch { case val == nil: v = val case f.Schema == nil: v = val case !f.Repeated: m2 := map[string]Value{} loadMap(m2, val.([]Value), f.Schema) v = m2 default: // repeated and nested sval := val.([]Value) vs := make([]Value, len(sval)) for j, e := range sval { m2 := map[string]Value{} loadMap(m2, e.([]Value), f.Schema) vs[j] = m2 } v = vs } m[f.Name] = v } } type structLoader struct { typ reflect.Type // type of struct err error ops []structLoaderOp vstructp reflect.Value // pointer to current struct value; changed by set } // A setFunc is a function that sets a struct field or slice/array // element to a value. type setFunc func(v reflect.Value, val interface{}) error // A structLoaderOp instructs the loader to set a struct field to a row value. type structLoaderOp struct { fieldIndex []int valueIndex int setFunc setFunc repeated bool } var errNoNulls = errors.New("bigquery: NULL values cannot be read into structs") func setAny(v reflect.Value, x interface{}) error { if x == nil { return errNoNulls } v.Set(reflect.ValueOf(x)) return nil } func setInt(v reflect.Value, x interface{}) error { if x == nil { return errNoNulls } xx := x.(int64) if v.OverflowInt(xx) { return fmt.Errorf("bigquery: value %v overflows struct field of type %v", xx, v.Type()) } v.SetInt(xx) return nil } func setUint(v reflect.Value, x interface{}) error { if x == nil { return errNoNulls } xx := x.(int64) if xx < 0 || v.OverflowUint(uint64(xx)) { return fmt.Errorf("bigquery: value %v overflows struct field of type %v", xx, v.Type()) } v.SetUint(uint64(xx)) return nil } func setFloat(v reflect.Value, x interface{}) error { if x == nil { return errNoNulls } xx := x.(float64) if v.OverflowFloat(xx) { return fmt.Errorf("bigquery: value %v overflows struct field of type %v", xx, v.Type()) } v.SetFloat(xx) return nil } func setBool(v reflect.Value, x interface{}) error { if x == nil { return errNoNulls } v.SetBool(x.(bool)) return nil } func setString(v reflect.Value, x interface{}) error { if x == nil { return errNoNulls } v.SetString(x.(string)) return nil } func setGeography(v reflect.Value, x interface{}) error { if x == nil { return errNoNulls } v.SetString(x.(string)) return nil } func setBytes(v reflect.Value, x interface{}) error { if x == nil { v.SetBytes(nil) } else { v.SetBytes(x.([]byte)) } return nil } func setNull(v reflect.Value, x interface{}, build func() interface{}) error { if x == nil { v.Set(reflect.Zero(v.Type())) } else { n := build() v.Set(reflect.ValueOf(n)) } return nil } // set remembers a value for the next call to Load. The value must be // a pointer to a struct. (This is checked in RowIterator.Next.) func (sl *structLoader) set(structp interface{}, schema Schema) error { if sl.err != nil { return sl.err } sl.vstructp = reflect.ValueOf(structp) typ := sl.vstructp.Type().Elem() if sl.typ == nil { // First call: remember the type and compile the schema. sl.typ = typ ops, err := compileToOps(typ, schema) if err != nil { sl.err = err return err } sl.ops = ops } else if sl.typ != typ { return fmt.Errorf("bigquery: struct type changed from %s to %s", sl.typ, typ) } return nil } // compileToOps produces a sequence of operations that will set the fields of a // value of structType to the contents of a row with schema. func compileToOps(structType reflect.Type, schema Schema) ([]structLoaderOp, error) { var ops []structLoaderOp fields, err := fieldCache.Fields(structType) if err != nil { return nil, err } for i, schemaField := range schema { // Look for an exported struct field with the same name as the schema // field, ignoring case (BigQuery column names are case-insensitive, // and we want to act like encoding/json anyway). structField := fields.Match(schemaField.Name) if structField == nil { // Ignore schema fields with no corresponding struct field. continue } op := structLoaderOp{ fieldIndex: structField.Index, valueIndex: i, } t := structField.Type if schemaField.Repeated { if t.Kind() != reflect.Slice && t.Kind() != reflect.Array { return nil, fmt.Errorf("bigquery: repeated schema field %s requires slice or array, but struct field %s has type %s", schemaField.Name, structField.Name, t) } t = t.Elem() op.repeated = true } if schemaField.Type == RecordFieldType { // Field can be a struct or a pointer to a struct. if t.Kind() == reflect.Ptr { t = t.Elem() } if t.Kind() != reflect.Struct { return nil, fmt.Errorf("bigquery: field %s has type %s, expected struct or *struct", structField.Name, structField.Type) } nested, err := compileToOps(t, schemaField.Schema) if err != nil { return nil, err } op.setFunc = func(v reflect.Value, val interface{}) error { return setNested(nested, v, val) } } else { op.setFunc = determineSetFunc(t, schemaField.Type) if op.setFunc == nil { return nil, fmt.Errorf("bigquery: schema field %s of type %s is not assignable to struct field %s of type %s", schemaField.Name, schemaField.Type, structField.Name, t) } } ops = append(ops, op) } return ops, nil } // determineSetFunc chooses the best function for setting a field of type ftype // to a value whose schema field type is stype. It returns nil if stype // is not assignable to ftype. // determineSetFunc considers only basic types. See compileToOps for // handling of repetition and nesting. func determineSetFunc(ftype reflect.Type, stype FieldType) setFunc { switch stype { case StringFieldType: if ftype.Kind() == reflect.String { return setString } if ftype == typeOfNullString { return func(v reflect.Value, x interface{}) error { return setNull(v, x, func() interface{} { return NullString{StringVal: x.(string), Valid: true} }) } } case GeographyFieldType: if ftype.Kind() == reflect.String { return setGeography } if ftype == typeOfNullGeography { return func(v reflect.Value, x interface{}) error { return setNull(v, x, func() interface{} { return NullGeography{GeographyVal: x.(string), Valid: true} }) } } case BytesFieldType: if ftype == typeOfByteSlice { return setBytes } case IntegerFieldType: if isSupportedUintType(ftype) { return setUint } else if isSupportedIntType(ftype) { return setInt } if ftype == typeOfNullInt64 { return func(v reflect.Value, x interface{}) error { return setNull(v, x, func() interface{} { return NullInt64{Int64: x.(int64), Valid: true} }) } } case FloatFieldType: switch ftype.Kind() { case reflect.Float32, reflect.Float64: return setFloat } if ftype == typeOfNullFloat64 { return func(v reflect.Value, x interface{}) error { return setNull(v, x, func() interface{} { return NullFloat64{Float64: x.(float64), Valid: true} }) } } case BooleanFieldType: if ftype.Kind() == reflect.Bool { return setBool } if ftype == typeOfNullBool { return func(v reflect.Value, x interface{}) error { return setNull(v, x, func() interface{} { return NullBool{Bool: x.(bool), Valid: true} }) } } case TimestampFieldType: if ftype == typeOfGoTime { return setAny } if ftype == typeOfNullTimestamp { return func(v reflect.Value, x interface{}) error { return setNull(v, x, func() interface{} { return NullTimestamp{Timestamp: x.(time.Time), Valid: true} }) } } case DateFieldType: if ftype == typeOfDate { return setAny } if ftype == typeOfNullDate { return func(v reflect.Value, x interface{}) error { return setNull(v, x, func() interface{} { return NullDate{Date: x.(civil.Date), Valid: true} }) } } case TimeFieldType: if ftype == typeOfTime { return setAny } if ftype == typeOfNullTime { return func(v reflect.Value, x interface{}) error { return setNull(v, x, func() interface{} { return NullTime{Time: x.(civil.Time), Valid: true} }) } } case DateTimeFieldType: if ftype == typeOfDateTime { return setAny } if ftype == typeOfNullDateTime { return func(v reflect.Value, x interface{}) error { return setNull(v, x, func() interface{} { return NullDateTime{DateTime: x.(civil.DateTime), Valid: true} }) } } case NumericFieldType: if ftype == typeOfRat { return func(v reflect.Value, x interface{}) error { return setNull(v, x, func() interface{} { return x.(*big.Rat) }) } } } return nil } func (sl *structLoader) Load(values []Value, _ Schema) error { if sl.err != nil { return sl.err } return runOps(sl.ops, sl.vstructp.Elem(), values) } // runOps executes a sequence of ops, setting the fields of vstruct to the // supplied values. func runOps(ops []structLoaderOp, vstruct reflect.Value, values []Value) error { for _, op := range ops { field := vstruct.FieldByIndex(op.fieldIndex) var err error if op.repeated { err = setRepeated(field, values[op.valueIndex].([]Value), op.setFunc) } else { err = op.setFunc(field, values[op.valueIndex]) } if err != nil { return err } } return nil } func setNested(ops []structLoaderOp, v reflect.Value, val interface{}) error { // v is either a struct or a pointer to a struct. if v.Kind() == reflect.Ptr { // If the value is nil, set the pointer to nil. if val == nil { v.Set(reflect.Zero(v.Type())) return nil } // If the pointer is nil, set it to a zero struct value. if v.IsNil() { v.Set(reflect.New(v.Type().Elem())) } v = v.Elem() } return runOps(ops, v, val.([]Value)) } func setRepeated(field reflect.Value, vslice []Value, setElem setFunc) error { vlen := len(vslice) var flen int switch field.Type().Kind() { case reflect.Slice: // Make a slice of the right size, avoiding allocation if possible. switch { case field.Len() < vlen: field.Set(reflect.MakeSlice(field.Type(), vlen, vlen)) case field.Len() > vlen: field.SetLen(vlen) } flen = vlen case reflect.Array: flen = field.Len() if flen > vlen { // Set extra elements to their zero value. z := reflect.Zero(field.Type().Elem()) for i := vlen; i < flen; i++ { field.Index(i).Set(z) } } default: return fmt.Errorf("bigquery: impossible field type %s", field.Type()) } for i, val := range vslice { if i < flen { // avoid writing past the end of a short array if err := setElem(field.Index(i), val); err != nil { return err } } } return nil } // A ValueSaver returns a row of data to be inserted into a table. type ValueSaver interface { // Save returns a row to be inserted into a BigQuery table, represented // as a map from field name to Value. // If insertID is non-empty, BigQuery will use it to de-duplicate // insertions of this row on a best-effort basis. Save() (row map[string]Value, insertID string, err error) } // ValuesSaver implements ValueSaver for a slice of Values. type ValuesSaver struct { Schema Schema // If non-empty, BigQuery will use InsertID to de-duplicate insertions // of this row on a best-effort basis. InsertID string Row []Value } // Save implements ValueSaver. func (vls *ValuesSaver) Save() (map[string]Value, string, error) { m, err := valuesToMap(vls.Row, vls.Schema) return m, vls.InsertID, err } func valuesToMap(vs []Value, schema Schema) (map[string]Value, error) { if len(vs) != len(schema) { return nil, errors.New("schema does not match length of row to be inserted") } m := make(map[string]Value) for i, fieldSchema := range schema { if vs[i] == nil { m[fieldSchema.Name] = nil continue } if fieldSchema.Type != RecordFieldType { m[fieldSchema.Name] = toUploadValue(vs[i], fieldSchema) continue } // Nested record, possibly repeated. vals, ok := vs[i].([]Value) if !ok { return nil, errors.New("nested record is not a []Value") } if !fieldSchema.Repeated { value, err := valuesToMap(vals, fieldSchema.Schema) if err != nil { return nil, err } m[fieldSchema.Name] = value continue } // A repeated nested field is converted into a slice of maps. maps := []Value{} for _, v := range vals { sv, ok := v.([]Value) if !ok { return nil, errors.New("nested record in slice is not a []Value") } value, err := valuesToMap(sv, fieldSchema.Schema) if err != nil { return nil, err } maps = append(maps, value) } m[fieldSchema.Name] = maps } return m, nil } // StructSaver implements ValueSaver for a struct. // The struct is converted to a map of values by using the values of struct // fields corresponding to schema fields. Additional and missing // fields are ignored, as are nested struct pointers that are nil. type StructSaver struct { // Schema determines what fields of the struct are uploaded. It should // match the table's schema. // Schema is optional for StructSavers that are passed to Uploader.Put. Schema Schema // If non-empty, BigQuery will use InsertID to de-duplicate insertions // of this row on a best-effort basis. InsertID string // Struct should be a struct or a pointer to a struct. Struct interface{} } // Save implements ValueSaver. func (ss *StructSaver) Save() (row map[string]Value, insertID string, err error) { vstruct := reflect.ValueOf(ss.Struct) row, err = structToMap(vstruct, ss.Schema) if err != nil { return nil, "", err } return row, ss.InsertID, nil } func structToMap(vstruct reflect.Value, schema Schema) (map[string]Value, error) { if vstruct.Kind() == reflect.Ptr { vstruct = vstruct.Elem() } if !vstruct.IsValid() { return nil, nil } m := map[string]Value{} if vstruct.Kind() != reflect.Struct { return nil, fmt.Errorf("bigquery: type is %s, need struct or struct pointer", vstruct.Type()) } fields, err := fieldCache.Fields(vstruct.Type()) if err != nil { return nil, err } for _, schemaField := range schema { // Look for an exported struct field with the same name as the schema // field, ignoring case. structField := fields.Match(schemaField.Name) if structField == nil { continue } val, err := structFieldToUploadValue(vstruct.FieldByIndex(structField.Index), schemaField) if err != nil { return nil, err } // Add the value to the map, unless it is nil. if val != nil { m[schemaField.Name] = val } } return m, nil } // structFieldToUploadValue converts a struct field to a value suitable for ValueSaver.Save, using // the schemaField as a guide. // structFieldToUploadValue is careful to return a true nil interface{} when needed, so its // caller can easily identify a nil value. func structFieldToUploadValue(vfield reflect.Value, schemaField *FieldSchema) (interface{}, error) { if schemaField.Repeated && (vfield.Kind() != reflect.Slice && vfield.Kind() != reflect.Array) { return nil, fmt.Errorf("bigquery: repeated schema field %s requires slice or array, but value has type %s", schemaField.Name, vfield.Type()) } // A non-nested field can be represented by its Go value, except for some types. if schemaField.Type != RecordFieldType { return toUploadValueReflect(vfield, schemaField), nil } // A non-repeated nested field is converted into a map[string]Value. if !schemaField.Repeated { m, err := structToMap(vfield, schemaField.Schema) if err != nil { return nil, err } if m == nil { return nil, nil } return m, nil } // A repeated nested field is converted into a slice of maps. // If the field is zero-length (but not nil), we return a zero-length []Value. if vfield.IsNil() { return nil, nil } vals := []Value{} for i := 0; i < vfield.Len(); i++ { m, err := structToMap(vfield.Index(i), schemaField.Schema) if err != nil { return nil, err } vals = append(vals, m) } return vals, nil } func toUploadValue(val interface{}, fs *FieldSchema) interface{} { if fs.Type == TimeFieldType || fs.Type == DateTimeFieldType || fs.Type == NumericFieldType { return toUploadValueReflect(reflect.ValueOf(val), fs) } return val } func toUploadValueReflect(v reflect.Value, fs *FieldSchema) interface{} { switch fs.Type { case TimeFieldType: if v.Type() == typeOfNullTime { return v.Interface() } return formatUploadValue(v, fs, func(v reflect.Value) string { return CivilTimeString(v.Interface().(civil.Time)) }) case DateTimeFieldType: if v.Type() == typeOfNullDateTime { return v.Interface() } return formatUploadValue(v, fs, func(v reflect.Value) string { return CivilDateTimeString(v.Interface().(civil.DateTime)) }) case NumericFieldType: if r, ok := v.Interface().(*big.Rat); ok && r == nil { return nil } return formatUploadValue(v, fs, func(v reflect.Value) string { return NumericString(v.Interface().(*big.Rat)) }) default: if !fs.Repeated || v.Len() > 0 { return v.Interface() } // The service treats a null repeated field as an error. Return // nil to omit the field entirely. return nil } } func formatUploadValue(v reflect.Value, fs *FieldSchema, cvt func(reflect.Value) string) interface{} { if !fs.Repeated { return cvt(v) } if v.Len() == 0 { return nil } s := make([]string, v.Len()) for i := 0; i < v.Len(); i++ { s[i] = cvt(v.Index(i)) } return s } // CivilTimeString returns a string representing a civil.Time in a format compatible // with BigQuery SQL. It rounds the time to the nearest microsecond and returns a // string with six digits of sub-second precision. // // Use CivilTimeString when using civil.Time in DML, for example in INSERT // statements. func CivilTimeString(t civil.Time) string { if t.Nanosecond == 0 { return t.String() } micro := (t.Nanosecond + 500) / 1000 // round to nearest microsecond t.Nanosecond = 0 return t.String() + fmt.Sprintf(".%06d", micro) } // CivilDateTimeString returns a string representing a civil.DateTime in a format compatible // with BigQuery SQL. It separate the date and time with a space, and formats the time // with CivilTimeString. // // Use CivilDateTimeString when using civil.DateTime in DML, for example in INSERT // statements. func CivilDateTimeString(dt civil.DateTime) string { return dt.Date.String() + " " + CivilTimeString(dt.Time) } // parseCivilDateTime parses a date-time represented in a BigQuery SQL // compatible format and returns a civil.DateTime. func parseCivilDateTime(s string) (civil.DateTime, error) { parts := strings.Fields(s) if len(parts) != 2 { return civil.DateTime{}, fmt.Errorf("bigquery: bad DATETIME value %q", s) } return civil.ParseDateTime(parts[0] + "T" + parts[1]) } const ( // NumericPrecisionDigits is the maximum number of digits in a NUMERIC value. NumericPrecisionDigits = 38 // NumericScaleDigits is the maximum number of digits after the decimal point in a NUMERIC value. NumericScaleDigits = 9 ) // NumericString returns a string representing a *big.Rat in a format compatible // with BigQuery SQL. It returns a floating-point literal with 9 digits // after the decimal point. func NumericString(r *big.Rat) string { return r.FloatString(NumericScaleDigits) } // convertRows converts a series of TableRows into a series of Value slices. // schema is used to interpret the data from rows; its length must match the // length of each row. func convertRows(rows []*bq.TableRow, schema Schema) ([][]Value, error) { var rs [][]Value for _, r := range rows { row, err := convertRow(r, schema) if err != nil { return nil, err } rs = append(rs, row) } return rs, nil } func convertRow(r *bq.TableRow, schema Schema) ([]Value, error) { if len(schema) != len(r.F) { return nil, errors.New("schema length does not match row length") } var values []Value for i, cell := range r.F { fs := schema[i] v, err := convertValue(cell.V, fs.Type, fs.Schema) if err != nil { return nil, err } values = append(values, v) } return values, nil } func convertValue(val interface{}, typ FieldType, schema Schema) (Value, error) { switch val := val.(type) { case nil: return nil, nil case []interface{}: return convertRepeatedRecord(val, typ, schema) case map[string]interface{}: return convertNestedRecord(val, schema) case string: return convertBasicType(val, typ) default: return nil, fmt.Errorf("got value %v; expected a value of type %s", val, typ) } } func convertRepeatedRecord(vals []interface{}, typ FieldType, schema Schema) (Value, error) { var values []Value for _, cell := range vals { // each cell contains a single entry, keyed by "v" val := cell.(map[string]interface{})["v"] v, err := convertValue(val, typ, schema) if err != nil { return nil, err } values = append(values, v) } return values, nil } func convertNestedRecord(val map[string]interface{}, schema Schema) (Value, error) { // convertNestedRecord is similar to convertRow, as a record has the same structure as a row. // Nested records are wrapped in a map with a single key, "f". record := val["f"].([]interface{}) if len(record) != len(schema) { return nil, errors.New("schema length does not match record length") } var values []Value for i, cell := range record { // each cell contains a single entry, keyed by "v" val := cell.(map[string]interface{})["v"] fs := schema[i] v, err := convertValue(val, fs.Type, fs.Schema) if err != nil { return nil, err } values = append(values, v) } return values, nil } // convertBasicType returns val as an interface with a concrete type specified by typ. func convertBasicType(val string, typ FieldType) (Value, error) { switch typ { case StringFieldType: return val, nil case BytesFieldType: return base64.StdEncoding.DecodeString(val) case IntegerFieldType: return strconv.ParseInt(val, 10, 64) case FloatFieldType: return strconv.ParseFloat(val, 64) case BooleanFieldType: return strconv.ParseBool(val) case TimestampFieldType: f, err := strconv.ParseFloat(val, 64) if err != nil { return nil, err } secs := math.Trunc(f) // Timestamps in BigQuery have microsecond precision, so we must // return a round number of microseconds. micros := math.Trunc((f-secs)*1e6 + 0.5) return Value(time.Unix(int64(secs), int64(micros)*1000).UTC()), nil case DateFieldType: return civil.ParseDate(val) case TimeFieldType: return civil.ParseTime(val) case DateTimeFieldType: return civil.ParseDateTime(val) case NumericFieldType: r, ok := (&big.Rat{}).SetString(val) if !ok { return nil, fmt.Errorf("bigquery: invalid NUMERIC value %q", val) } return Value(r), nil case GeographyFieldType: return val, nil default: return nil, fmt.Errorf("unrecognized type: %s", typ) } } google-cloud-go-0.49.0/bigquery/value_test.go000066400000000000000000001023651356504100700211300ustar00rootroot00000000000000// Copyright 2015 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bigquery import ( "encoding/base64" "fmt" "math" "math/big" "testing" "time" "cloud.google.com/go/civil" "cloud.google.com/go/internal/testutil" "github.com/google/go-cmp/cmp" bq "google.golang.org/api/bigquery/v2" ) func TestConvertBasicValues(t *testing.T) { schema := Schema{ {Type: StringFieldType}, {Type: IntegerFieldType}, {Type: FloatFieldType}, {Type: BooleanFieldType}, {Type: BytesFieldType}, {Type: NumericFieldType}, {Type: GeographyFieldType}, } row := &bq.TableRow{ F: []*bq.TableCell{ {V: "a"}, {V: "1"}, {V: "1.2"}, {V: "true"}, {V: base64.StdEncoding.EncodeToString([]byte("foo"))}, {V: "123.123456789"}, {V: testGeography}, }, } got, err := convertRow(row, schema) if err != nil { t.Fatalf("error converting: %v", err) } want := []Value{"a", int64(1), 1.2, true, []byte("foo"), big.NewRat(123123456789, 1e9), testGeography} if !testutil.Equal(got, want) { t.Errorf("converting basic values: got:\n%v\nwant:\n%v", got, want) } } func TestConvertTime(t *testing.T) { schema := Schema{ {Type: TimestampFieldType}, {Type: DateFieldType}, {Type: TimeFieldType}, {Type: DateTimeFieldType}, } ts := testTimestamp.Round(time.Millisecond) row := &bq.TableRow{ F: []*bq.TableCell{ {V: fmt.Sprintf("%.10f", float64(ts.UnixNano())/1e9)}, {V: testDate.String()}, {V: testTime.String()}, {V: testDateTime.String()}, }, } got, err := convertRow(row, schema) if err != nil { t.Fatalf("error converting: %v", err) } want := []Value{ts, testDate, testTime, testDateTime} for i, g := range got { w := want[i] if !testutil.Equal(g, w) { t.Errorf("#%d: got:\n%v\nwant:\n%v", i, g, w) } } if got[0].(time.Time).Location() != time.UTC { t.Errorf("expected time zone UTC: got:\n%v", got) } } func TestConvertSmallTimes(t *testing.T) { for _, year := range []int{1600, 1066, 1} { want := time.Date(year, time.January, 1, 0, 0, 0, 0, time.UTC) s := fmt.Sprintf("%.10f", float64(want.Unix())) got, err := convertBasicType(s, TimestampFieldType) if err != nil { t.Fatal(err) } if !got.(time.Time).Equal(want) { t.Errorf("got %v, want %v", got, want) } } } func TestConvertTimePrecision(t *testing.T) { tcs := []struct { // Internally, BigQuery stores timestamps as microsecond-precision // floats. bq float64 want time.Time }{ { bq: 1555593697.154358, want: time.Unix(1555593697, 154358*1000), }, { bq: 1555593697.154359, want: time.Unix(1555593697, 154359*1000), }, { bq: 1555593697.154360, want: time.Unix(1555593697, 154360*1000), }, } for _, tc := range tcs { bqS := fmt.Sprintf("%.6f", tc.bq) t.Run(bqS, func(t *testing.T) { got, err := convertBasicType(bqS, TimestampFieldType) if err != nil { t.Fatalf("convertBasicType failed: %v", err) } gotT, ok := got.(time.Time) if !ok { t.Fatalf("got a %T from convertBasicType, want a time.Time; got = %v", got, got) } if !gotT.Equal(tc.want) { t.Errorf("got %v from convertBasicType, want %v", gotT, tc.want) } }) } } func TestConvertNullValues(t *testing.T) { schema := Schema{{Type: StringFieldType}} row := &bq.TableRow{ F: []*bq.TableCell{ {V: nil}, }, } got, err := convertRow(row, schema) if err != nil { t.Fatalf("error converting: %v", err) } want := []Value{nil} if !testutil.Equal(got, want) { t.Errorf("converting null values: got:\n%v\nwant:\n%v", got, want) } } func TestBasicRepetition(t *testing.T) { schema := Schema{ {Type: IntegerFieldType, Repeated: true}, } row := &bq.TableRow{ F: []*bq.TableCell{ { V: []interface{}{ map[string]interface{}{ "v": "1", }, map[string]interface{}{ "v": "2", }, map[string]interface{}{ "v": "3", }, }, }, }, } got, err := convertRow(row, schema) if err != nil { t.Fatalf("error converting: %v", err) } want := []Value{[]Value{int64(1), int64(2), int64(3)}} if !testutil.Equal(got, want) { t.Errorf("converting basic repeated values: got:\n%v\nwant:\n%v", got, want) } } func TestNestedRecordContainingRepetition(t *testing.T) { schema := Schema{ { Type: RecordFieldType, Schema: Schema{ {Type: IntegerFieldType, Repeated: true}, }, }, } row := &bq.TableRow{ F: []*bq.TableCell{ { V: map[string]interface{}{ "f": []interface{}{ map[string]interface{}{ "v": []interface{}{ map[string]interface{}{"v": "1"}, map[string]interface{}{"v": "2"}, map[string]interface{}{"v": "3"}, }, }, }, }, }, }, } got, err := convertRow(row, schema) if err != nil { t.Fatalf("error converting: %v", err) } want := []Value{[]Value{[]Value{int64(1), int64(2), int64(3)}}} if !testutil.Equal(got, want) { t.Errorf("converting basic repeated values: got:\n%v\nwant:\n%v", got, want) } } func TestRepeatedRecordContainingRepetition(t *testing.T) { schema := Schema{ { Type: RecordFieldType, Repeated: true, Schema: Schema{ {Type: IntegerFieldType, Repeated: true}, }, }, } row := &bq.TableRow{F: []*bq.TableCell{ { V: []interface{}{ // repeated records. map[string]interface{}{ // first record. "v": map[string]interface{}{ // pointless single-key-map wrapper. "f": []interface{}{ // list of record fields. map[string]interface{}{ // only record (repeated ints) "v": []interface{}{ // pointless wrapper. map[string]interface{}{ "v": "1", }, map[string]interface{}{ "v": "2", }, map[string]interface{}{ "v": "3", }, }, }, }, }, }, map[string]interface{}{ // second record. "v": map[string]interface{}{ "f": []interface{}{ map[string]interface{}{ "v": []interface{}{ map[string]interface{}{ "v": "4", }, map[string]interface{}{ "v": "5", }, map[string]interface{}{ "v": "6", }, }, }, }, }, }, }, }, }} got, err := convertRow(row, schema) if err != nil { t.Fatalf("error converting: %v", err) } want := []Value{ // the row is a list of length 1, containing an entry for the repeated record. []Value{ // the repeated record is a list of length 2, containing an entry for each repetition. []Value{ // the record is a list of length 1, containing an entry for the repeated integer field. []Value{int64(1), int64(2), int64(3)}, // the repeated integer field is a list of length 3. }, []Value{ // second record []Value{int64(4), int64(5), int64(6)}, }, }, } if !testutil.Equal(got, want) { t.Errorf("converting repeated records with repeated values: got:\n%v\nwant:\n%v", got, want) } } func TestRepeatedRecordContainingRecord(t *testing.T) { schema := Schema{ { Type: RecordFieldType, Repeated: true, Schema: Schema{ { Type: StringFieldType, }, { Type: RecordFieldType, Schema: Schema{ {Type: IntegerFieldType}, {Type: StringFieldType}, }, }, }, }, } row := &bq.TableRow{F: []*bq.TableCell{ { V: []interface{}{ // repeated records. map[string]interface{}{ // first record. "v": map[string]interface{}{ // pointless single-key-map wrapper. "f": []interface{}{ // list of record fields. map[string]interface{}{ // first record field (name) "v": "first repeated record", }, map[string]interface{}{ // second record field (nested record). "v": map[string]interface{}{ // pointless single-key-map wrapper. "f": []interface{}{ // nested record fields map[string]interface{}{ "v": "1", }, map[string]interface{}{ "v": "two", }, }, }, }, }, }, }, map[string]interface{}{ // second record. "v": map[string]interface{}{ "f": []interface{}{ map[string]interface{}{ "v": "second repeated record", }, map[string]interface{}{ "v": map[string]interface{}{ "f": []interface{}{ map[string]interface{}{ "v": "3", }, map[string]interface{}{ "v": "four", }, }, }, }, }, }, }, }, }, }} got, err := convertRow(row, schema) if err != nil { t.Fatalf("error converting: %v", err) } // TODO: test with flattenresults. want := []Value{ // the row is a list of length 1, containing an entry for the repeated record. []Value{ // the repeated record is a list of length 2, containing an entry for each repetition. []Value{ // record contains a string followed by a nested record. "first repeated record", []Value{ int64(1), "two", }, }, []Value{ // second record. "second repeated record", []Value{ int64(3), "four", }, }, }, } if !testutil.Equal(got, want) { t.Errorf("converting repeated records containing record : got:\n%v\nwant:\n%v", got, want) } } func TestConvertRowErrors(t *testing.T) { // mismatched lengths if _, err := convertRow(&bq.TableRow{F: []*bq.TableCell{{V: ""}}}, Schema{}); err == nil { t.Error("got nil, want error") } v3 := map[string]interface{}{"v": 3} for _, test := range []struct { value interface{} fs FieldSchema }{ {3, FieldSchema{Type: IntegerFieldType}}, // not a string {[]interface{}{v3}, // not a string, repeated FieldSchema{Type: IntegerFieldType, Repeated: true}}, {map[string]interface{}{"f": []interface{}{v3}}, // not a string, nested FieldSchema{Type: RecordFieldType, Schema: Schema{{Type: IntegerFieldType}}}}, {map[string]interface{}{"f": []interface{}{v3}}, // wrong length, nested FieldSchema{Type: RecordFieldType, Schema: Schema{}}}, } { _, err := convertRow( &bq.TableRow{F: []*bq.TableCell{{V: test.value}}}, Schema{&test.fs}) if err == nil { t.Errorf("value %v, fs %v: got nil, want error", test.value, test.fs) } } // bad field type if _, err := convertBasicType("", FieldType("BAD")); err == nil { t.Error("got nil, want error") } } func TestValuesSaverConvertsToMap(t *testing.T) { testCases := []struct { vs ValuesSaver wantInsertID string wantRow map[string]Value }{ { vs: ValuesSaver{ Schema: Schema{ {Name: "intField", Type: IntegerFieldType}, {Name: "strField", Type: StringFieldType}, {Name: "dtField", Type: DateTimeFieldType}, {Name: "nField", Type: NumericFieldType}, {Name: "geoField", Type: GeographyFieldType}, }, InsertID: "iid", Row: []Value{1, "a", civil.DateTime{ Date: civil.Date{Year: 1, Month: 2, Day: 3}, Time: civil.Time{Hour: 4, Minute: 5, Second: 6, Nanosecond: 7000}}, big.NewRat(123456789000, 1e9), testGeography, }, }, wantInsertID: "iid", wantRow: map[string]Value{ "intField": 1, "strField": "a", "dtField": "0001-02-03 04:05:06.000007", "nField": "123.456789000", "geoField": testGeography, }, }, { vs: ValuesSaver{ Schema: Schema{ {Name: "intField", Type: IntegerFieldType}, { Name: "recordField", Type: RecordFieldType, Schema: Schema{ {Name: "nestedInt", Type: IntegerFieldType, Repeated: true}, }, }, }, InsertID: "iid", Row: []Value{1, []Value{[]Value{2, 3}}}, }, wantInsertID: "iid", wantRow: map[string]Value{ "intField": 1, "recordField": map[string]Value{ "nestedInt": []Value{2, 3}, }, }, }, { // repeated nested field vs: ValuesSaver{ Schema: Schema{ { Name: "records", Type: RecordFieldType, Schema: Schema{ {Name: "x", Type: IntegerFieldType}, {Name: "y", Type: IntegerFieldType}, }, Repeated: true, }, }, InsertID: "iid", Row: []Value{ // a row is a []Value []Value{ // repeated field's value is a []Value []Value{1, 2}, // first record of the repeated field []Value{3, 4}, // second record }, }, }, wantInsertID: "iid", wantRow: map[string]Value{ "records": []Value{ map[string]Value{"x": 1, "y": 2}, map[string]Value{"x": 3, "y": 4}, }, }, }, { // zero-length repeated nested field vs: ValuesSaver{ Schema: Schema{ { Name: "records", Type: RecordFieldType, Schema: Schema{ {Name: "x", Type: IntegerFieldType}, {Name: "y", Type: IntegerFieldType}, }, Repeated: true, }, }, InsertID: "iid", Row: []Value{ // a row is a []Value []Value{}, // repeated field's value is a []Value, and non-nil }, }, wantInsertID: "iid", wantRow: map[string]Value{ "records": []Value{}, }, }, } for _, tc := range testCases { gotRow, gotInsertID, err := tc.vs.Save() if err != nil { t.Errorf("Expected successful save; got: %v", err) continue } if !testutil.Equal(gotRow, tc.wantRow) { t.Errorf("%v row:\ngot:\n%+v\nwant:\n%+v", tc.vs, gotRow, tc.wantRow) } if !testutil.Equal(gotInsertID, tc.wantInsertID) { t.Errorf("%v ID:\ngot:\n%+v\nwant:\n%+v", tc.vs, gotInsertID, tc.wantInsertID) } } } func TestValuesToMapErrors(t *testing.T) { for _, test := range []struct { values []Value schema Schema }{ { // mismatched length []Value{1}, Schema{}, }, { // nested record not a slice []Value{1}, Schema{{Type: RecordFieldType}}, }, { // nested record mismatched length []Value{[]Value{1}}, Schema{{Type: RecordFieldType}}, }, { // nested repeated record not a slice []Value{[]Value{1}}, Schema{{Type: RecordFieldType, Repeated: true}}, }, { // nested repeated record mismatched length []Value{[]Value{[]Value{1}}}, Schema{{Type: RecordFieldType, Repeated: true}}, }, } { _, err := valuesToMap(test.values, test.schema) if err == nil { t.Errorf("%v, %v: got nil, want error", test.values, test.schema) } } } func TestStructSaver(t *testing.T) { schema := Schema{ {Name: "s", Type: StringFieldType}, {Name: "r", Type: IntegerFieldType, Repeated: true}, {Name: "t", Type: TimeFieldType}, {Name: "tr", Type: TimeFieldType, Repeated: true}, {Name: "nested", Type: RecordFieldType, Schema: Schema{ {Name: "b", Type: BooleanFieldType}, }}, {Name: "rnested", Type: RecordFieldType, Repeated: true, Schema: Schema{ {Name: "b", Type: BooleanFieldType}, }}, {Name: "p", Type: IntegerFieldType, Required: false}, {Name: "n", Type: NumericFieldType, Required: false}, {Name: "nr", Type: NumericFieldType, Repeated: true}, {Name: "g", Type: GeographyFieldType, Required: false}, {Name: "gr", Type: GeographyFieldType, Repeated: true}, } type ( N struct{ B bool } T struct { S string R []int T civil.Time TR []civil.Time Nested *N Rnested []*N P NullInt64 N *big.Rat NR []*big.Rat G NullGeography GR []string // Repeated Geography } ) check := func(msg string, in interface{}, want map[string]Value) { ss := StructSaver{ Schema: schema, InsertID: "iid", Struct: in, } got, gotIID, err := ss.Save() if err != nil { t.Fatalf("%s: %v", msg, err) } if wantIID := "iid"; gotIID != wantIID { t.Errorf("%s: InsertID: got %q, want %q", msg, gotIID, wantIID) } if diff := testutil.Diff(got, want); diff != "" { t.Errorf("%s: %s", msg, diff) } } ct1 := civil.Time{Hour: 1, Minute: 2, Second: 3, Nanosecond: 4000} ct2 := civil.Time{Hour: 5, Minute: 6, Second: 7, Nanosecond: 8000} in := T{ S: "x", R: []int{1, 2}, T: ct1, TR: []civil.Time{ct1, ct2}, Nested: &N{B: true}, Rnested: []*N{{true}, {false}}, P: NullInt64{Valid: true, Int64: 17}, N: big.NewRat(123456, 1000), NR: []*big.Rat{big.NewRat(3, 1), big.NewRat(56789, 1e5)}, G: NullGeography{Valid: true, GeographyVal: "POINT(-122.350220 47.649154)"}, GR: []string{"POINT(-122.350220 47.649154)", "POINT(-122.198939 47.669865)"}, } want := map[string]Value{ "s": "x", "r": []int{1, 2}, "t": "01:02:03.000004", "tr": []string{"01:02:03.000004", "05:06:07.000008"}, "nested": map[string]Value{"b": true}, "rnested": []Value{map[string]Value{"b": true}, map[string]Value{"b": false}}, "p": NullInt64{Valid: true, Int64: 17}, "n": "123.456000000", "nr": []string{"3.000000000", "0.567890000"}, "g": NullGeography{Valid: true, GeographyVal: "POINT(-122.350220 47.649154)"}, "gr": []string{"POINT(-122.350220 47.649154)", "POINT(-122.198939 47.669865)"}, } check("all values", in, want) check("all values, ptr", &in, want) check("empty struct", T{}, map[string]Value{"s": "", "t": "00:00:00", "p": NullInt64{}, "g": NullGeography{}}) // Missing and extra fields ignored. type T2 struct { S string // missing R, Nested, RNested Extra int } check("missing and extra", T2{S: "x"}, map[string]Value{"s": "x"}) check("nils in slice", T{Rnested: []*N{{true}, nil, {false}}}, map[string]Value{ "s": "", "t": "00:00:00", "p": NullInt64{}, "g": NullGeography{}, "rnested": []Value{map[string]Value{"b": true}, map[string]Value(nil), map[string]Value{"b": false}}, }) check("zero-length repeated", T{Rnested: []*N{}}, map[string]Value{ "rnested": []Value{}, "s": "", "t": "00:00:00", "p": NullInt64{}, "g": NullGeography{}, }) } func TestStructSaverErrors(t *testing.T) { type ( badField struct { I int `bigquery:"@"` } badR struct{ R int } badRN struct{ R []int } ) for i, test := range []struct { inputStruct interface{} schema Schema }{ {0, nil}, // not a struct {&badField{}, nil}, // bad field name {&badR{}, Schema{{Name: "r", Repeated: true}}}, // repeated field has bad type {&badR{}, Schema{{Name: "r", Type: RecordFieldType}}}, // nested field has bad type {&badRN{[]int{0}}, // nested repeated field has bad type Schema{{Name: "r", Type: RecordFieldType, Repeated: true}}}, } { ss := &StructSaver{Struct: test.inputStruct, Schema: test.schema} _, _, err := ss.Save() if err == nil { t.Errorf("#%d, %v, %v: got nil, want error", i, test.inputStruct, test.schema) } } } func TestNumericString(t *testing.T) { for _, test := range []struct { in *big.Rat want string }{ {big.NewRat(2, 3), "0.666666667"}, // round to 9 places {big.NewRat(1, 2), "0.500000000"}, {big.NewRat(1, 2*1e8), "0.000000005"}, {big.NewRat(5, 1e10), "0.000000001"}, // round up the 5 in the 10th decimal place {big.NewRat(-5, 1e10), "-0.000000001"}, // round half away from zero } { got := NumericString(test.in) if got != test.want { t.Errorf("%v: got %q, want %q", test.in, got, test.want) } } } func TestConvertRows(t *testing.T) { schema := Schema{ {Type: StringFieldType}, {Type: IntegerFieldType}, {Type: FloatFieldType}, {Type: BooleanFieldType}, {Type: GeographyFieldType}, } rows := []*bq.TableRow{ {F: []*bq.TableCell{ {V: "a"}, {V: "1"}, {V: "1.2"}, {V: "true"}, {V: "POINT(-122.350220 47.649154)"}, }}, {F: []*bq.TableCell{ {V: "b"}, {V: "2"}, {V: "2.2"}, {V: "false"}, {V: "POINT(-122.198939 47.669865)"}, }}, } want := [][]Value{ {"a", int64(1), 1.2, true, "POINT(-122.350220 47.649154)"}, {"b", int64(2), 2.2, false, "POINT(-122.198939 47.669865)"}, } got, err := convertRows(rows, schema) if err != nil { t.Fatalf("got %v, want nil", err) } if !testutil.Equal(got, want) { t.Errorf("\ngot %v\nwant %v", got, want) } rows[0].F[0].V = 1 _, err = convertRows(rows, schema) if err == nil { t.Error("got nil, want error") } } func TestValueList(t *testing.T) { schema := Schema{ {Name: "s", Type: StringFieldType}, {Name: "i", Type: IntegerFieldType}, {Name: "f", Type: FloatFieldType}, {Name: "b", Type: BooleanFieldType}, } want := []Value{"x", 7, 3.14, true} var got []Value vl := (*valueList)(&got) if err := vl.Load(want, schema); err != nil { t.Fatal(err) } if !testutil.Equal(got, want) { t.Errorf("got %+v, want %+v", got, want) } // Load truncates, not appends. // https://github.com/googleapis/google-cloud-go/issues/437 if err := vl.Load(want, schema); err != nil { t.Fatal(err) } if !testutil.Equal(got, want) { t.Errorf("got %+v, want %+v", got, want) } } func TestValueMap(t *testing.T) { ns := Schema{ {Name: "x", Type: IntegerFieldType}, {Name: "y", Type: IntegerFieldType}, } schema := Schema{ {Name: "s", Type: StringFieldType}, {Name: "i", Type: IntegerFieldType}, {Name: "f", Type: FloatFieldType}, {Name: "b", Type: BooleanFieldType}, {Name: "n", Type: RecordFieldType, Schema: ns}, {Name: "rn", Type: RecordFieldType, Schema: ns, Repeated: true}, } in := []Value{"x", 7, 3.14, true, []Value{1, 2}, []Value{[]Value{3, 4}, []Value{5, 6}}, } var vm valueMap if err := vm.Load(in, schema); err != nil { t.Fatal(err) } want := map[string]Value{ "s": "x", "i": 7, "f": 3.14, "b": true, "n": map[string]Value{"x": 1, "y": 2}, "rn": []Value{ map[string]Value{"x": 3, "y": 4}, map[string]Value{"x": 5, "y": 6}, }, } if !testutil.Equal(vm, valueMap(want)) { t.Errorf("got\n%+v\nwant\n%+v", vm, want) } in = make([]Value, len(schema)) want = map[string]Value{ "s": nil, "i": nil, "f": nil, "b": nil, "n": nil, "rn": nil, } var vm2 valueMap if err := vm2.Load(in, schema); err != nil { t.Fatal(err) } if !testutil.Equal(vm2, valueMap(want)) { t.Errorf("got\n%+v\nwant\n%+v", vm2, want) } } var ( // For testing StructLoader schema2 = Schema{ {Name: "s", Type: StringFieldType}, {Name: "s2", Type: StringFieldType}, {Name: "by", Type: BytesFieldType}, {Name: "I", Type: IntegerFieldType}, {Name: "U", Type: IntegerFieldType}, {Name: "F", Type: FloatFieldType}, {Name: "B", Type: BooleanFieldType}, {Name: "TS", Type: TimestampFieldType}, {Name: "D", Type: DateFieldType}, {Name: "T", Type: TimeFieldType}, {Name: "DT", Type: DateTimeFieldType}, {Name: "N", Type: NumericFieldType}, {Name: "G", Type: GeographyFieldType}, {Name: "nested", Type: RecordFieldType, Schema: Schema{ {Name: "nestS", Type: StringFieldType}, {Name: "nestI", Type: IntegerFieldType}, }}, {Name: "t", Type: StringFieldType}, } testTimestamp = time.Date(2016, 11, 5, 7, 50, 22, 8, time.UTC) testDate = civil.Date{Year: 2016, Month: 11, Day: 5} testTime = civil.Time{Hour: 7, Minute: 50, Second: 22, Nanosecond: 8} testDateTime = civil.DateTime{Date: testDate, Time: testTime} testNumeric = big.NewRat(123, 456) // testGeography is a WKT string representing a single point. testGeography = "POINT(-122.350220 47.649154)" testValues = []Value{"x", "y", []byte{1, 2, 3}, int64(7), int64(8), 3.14, true, testTimestamp, testDate, testTime, testDateTime, testNumeric, testGeography, []Value{"nested", int64(17)}, "z"} ) type testStruct1 struct { B bool I int U uint16 times S string S2 String By []byte F float64 N *big.Rat G string Nested nested Tagged string `bigquery:"t"` } type String string type nested struct { NestS string NestI int } type times struct { TS time.Time T civil.Time D civil.Date DT civil.DateTime } func TestStructLoader(t *testing.T) { var ts1 testStruct1 mustLoad(t, &ts1, schema2, testValues) // Note: the schema field named "s" gets matched to the exported struct // field "S", not the unexported "s". want := &testStruct1{ B: true, I: 7, U: 8, F: 3.14, times: times{TS: testTimestamp, T: testTime, D: testDate, DT: testDateTime}, S: "x", S2: "y", By: []byte{1, 2, 3}, N: big.NewRat(123, 456), G: testGeography, Nested: nested{NestS: "nested", NestI: 17}, Tagged: "z", } if diff := testutil.Diff(&ts1, want, cmp.AllowUnexported(testStruct1{})); diff != "" { t.Error(diff) } // Test pointers to nested structs. type nestedPtr struct{ Nested *nested } var np nestedPtr mustLoad(t, &np, schema2, testValues) want2 := &nestedPtr{Nested: &nested{NestS: "nested", NestI: 17}} if diff := testutil.Diff(&np, want2); diff != "" { t.Error(diff) } // Existing values should be reused. nst := &nested{NestS: "x", NestI: -10} np = nestedPtr{Nested: nst} mustLoad(t, &np, schema2, testValues) if diff := testutil.Diff(&np, want2); diff != "" { t.Error(diff) } if np.Nested != nst { t.Error("nested struct pointers not equal") } } type repStruct struct { Nums []int ShortNums [2]int // to test truncation LongNums [5]int // to test padding with zeroes Nested []*nested } var ( repSchema = Schema{ {Name: "nums", Type: IntegerFieldType, Repeated: true}, {Name: "shortNums", Type: IntegerFieldType, Repeated: true}, {Name: "longNums", Type: IntegerFieldType, Repeated: true}, {Name: "nested", Type: RecordFieldType, Repeated: true, Schema: Schema{ {Name: "nestS", Type: StringFieldType}, {Name: "nestI", Type: IntegerFieldType}, }}, } v123 = []Value{int64(1), int64(2), int64(3)} repValues = []Value{v123, v123, v123, []Value{ []Value{"x", int64(1)}, []Value{"y", int64(2)}, }, } ) func TestStructLoaderRepeated(t *testing.T) { var r1 repStruct mustLoad(t, &r1, repSchema, repValues) want := repStruct{ Nums: []int{1, 2, 3}, ShortNums: [...]int{1, 2}, // extra values discarded LongNums: [...]int{1, 2, 3, 0, 0}, Nested: []*nested{{"x", 1}, {"y", 2}}, } if diff := testutil.Diff(r1, want); diff != "" { t.Error(diff) } r2 := repStruct{ Nums: []int{-1, -2, -3, -4, -5}, // truncated to zero and appended to LongNums: [...]int{-1, -2, -3, -4, -5}, // unset elements are zeroed } mustLoad(t, &r2, repSchema, repValues) if diff := testutil.Diff(r2, want); diff != "" { t.Error(diff) } if got, want := cap(r2.Nums), 5; got != want { t.Errorf("cap(r2.Nums) = %d, want %d", got, want) } // Short slice case. r3 := repStruct{Nums: []int{-1}} mustLoad(t, &r3, repSchema, repValues) if diff := testutil.Diff(r3, want); diff != "" { t.Error(diff) } if got, want := cap(r3.Nums), 3; got != want { t.Errorf("cap(r3.Nums) = %d, want %d", got, want) } } type testStructNullable struct { String NullString Bytes []byte Integer NullInt64 Float NullFloat64 Boolean NullBool Timestamp NullTimestamp Date NullDate Time NullTime DateTime NullDateTime Numeric *big.Rat Geography NullGeography Record *subNullable } type subNullable struct { X NullInt64 } var testStructNullableSchema = Schema{ {Name: "String", Type: StringFieldType, Required: false}, {Name: "Bytes", Type: BytesFieldType, Required: false}, {Name: "Integer", Type: IntegerFieldType, Required: false}, {Name: "Float", Type: FloatFieldType, Required: false}, {Name: "Boolean", Type: BooleanFieldType, Required: false}, {Name: "Timestamp", Type: TimestampFieldType, Required: false}, {Name: "Date", Type: DateFieldType, Required: false}, {Name: "Time", Type: TimeFieldType, Required: false}, {Name: "DateTime", Type: DateTimeFieldType, Required: false}, {Name: "Numeric", Type: NumericFieldType, Required: false}, {Name: "Geography", Type: GeographyFieldType, Required: false}, {Name: "Record", Type: RecordFieldType, Required: false, Schema: Schema{ {Name: "X", Type: IntegerFieldType, Required: false}, }}, } func TestStructLoaderNullable(t *testing.T) { var ts testStructNullable nilVals := make([]Value, len(testStructNullableSchema)) mustLoad(t, &ts, testStructNullableSchema, nilVals) want := testStructNullable{} if diff := testutil.Diff(ts, want); diff != "" { t.Error(diff) } nonnilVals := []Value{"x", []byte{1, 2, 3}, int64(1), 2.3, true, testTimestamp, testDate, testTime, testDateTime, big.NewRat(1, 2), testGeography, []Value{int64(4)}} // All ts fields are nil. Loading non-nil values will cause them all to // be allocated. mustLoad(t, &ts, testStructNullableSchema, nonnilVals) want = testStructNullable{ String: NullString{StringVal: "x", Valid: true}, Bytes: []byte{1, 2, 3}, Integer: NullInt64{Int64: 1, Valid: true}, Float: NullFloat64{Float64: 2.3, Valid: true}, Boolean: NullBool{Bool: true, Valid: true}, Timestamp: NullTimestamp{Timestamp: testTimestamp, Valid: true}, Date: NullDate{Date: testDate, Valid: true}, Time: NullTime{Time: testTime, Valid: true}, DateTime: NullDateTime{DateTime: testDateTime, Valid: true}, Numeric: big.NewRat(1, 2), Geography: NullGeography{GeographyVal: testGeography, Valid: true}, Record: &subNullable{X: NullInt64{Int64: 4, Valid: true}}, } if diff := testutil.Diff(ts, want); diff != "" { t.Error(diff) } // Struct pointers are reused, byte slices are not. want = ts want.Bytes = []byte{17} vals2 := []Value{nil, []byte{17}, nil, nil, nil, nil, nil, nil, nil, nil, nil, []Value{int64(7)}} mustLoad(t, &ts, testStructNullableSchema, vals2) if ts.Record != want.Record { t.Error("record pointers not identical") } } func TestStructLoaderOverflow(t *testing.T) { type S struct { I int16 U uint16 F float32 } schema := Schema{ {Name: "I", Type: IntegerFieldType}, {Name: "U", Type: IntegerFieldType}, {Name: "F", Type: FloatFieldType}, } var s S z64 := int64(0) for _, vals := range [][]Value{ {int64(math.MaxInt16 + 1), z64, 0}, {z64, int64(math.MaxInt32), 0}, {z64, int64(-1), 0}, {z64, z64, math.MaxFloat32 * 2}, } { if err := load(&s, schema, vals); err == nil { t.Errorf("%+v: got nil, want error", vals) } } } func TestStructLoaderFieldOverlap(t *testing.T) { // It's OK if the struct has fields that the schema does not, and vice versa. type S1 struct { I int X [][]int // not in the schema; does not even correspond to a valid BigQuery type // many schema fields missing } var s1 S1 if err := load(&s1, schema2, testValues); err != nil { t.Fatal(err) } want1 := S1{I: 7} if diff := testutil.Diff(s1, want1); diff != "" { t.Error(diff) } // It's even valid to have no overlapping fields at all. type S2 struct{ Z int } var s2 S2 mustLoad(t, &s2, schema2, testValues) want2 := S2{} if diff := testutil.Diff(s2, want2); diff != "" { t.Error(diff) } } func TestStructLoaderErrors(t *testing.T) { check := func(sp interface{}) { var sl structLoader err := sl.set(sp, schema2) if err == nil { t.Errorf("%T: got nil, want error", sp) } } type bad1 struct{ F int32 } // wrong type for FLOAT column check(&bad1{}) type bad2 struct{ I uint } // unsupported integer type check(&bad2{}) type bad3 struct { I int `bigquery:"@"` } // bad field name check(&bad3{}) type bad4 struct{ Nested int } // non-struct for nested field check(&bad4{}) type bad5 struct{ Nested struct{ NestS int } } // bad nested struct check(&bad5{}) bad6 := &struct{ Nums int }{} // non-slice for repeated field sl := structLoader{} err := sl.set(bad6, repSchema) if err == nil { t.Errorf("%T: got nil, want error", bad6) } // sl.set's error is sticky, even with good input. err2 := sl.set(&repStruct{}, repSchema) if err2 != err { t.Errorf("%v != %v, expected equal", err2, err) } // sl.Load is similarly sticky err2 = sl.Load(nil, nil) if err2 != err { t.Errorf("%v != %v, expected equal", err2, err) } // Null values. schema := Schema{ {Name: "i", Type: IntegerFieldType}, {Name: "f", Type: FloatFieldType}, {Name: "b", Type: BooleanFieldType}, {Name: "s", Type: StringFieldType}, {Name: "d", Type: DateFieldType}, {Name: "r", Type: RecordFieldType, Schema: Schema{{Name: "X", Type: IntegerFieldType}}}, } type s struct { I int F float64 B bool S string D civil.Date } vals := []Value{int64(0), 0.0, false, "", testDate} mustLoad(t, &s{}, schema, vals) for i, e := range vals { vals[i] = nil got := load(&s{}, schema, vals) if got != errNoNulls { t.Errorf("#%d: got %v, want %v", i, got, errNoNulls) } vals[i] = e } // Using more than one struct type with the same structLoader. type different struct { B bool I int times S string Nums []int } sl = structLoader{} if err := sl.set(&testStruct1{}, schema2); err != nil { t.Fatal(err) } err = sl.set(&different{}, schema2) if err == nil { t.Error("different struct types: got nil, want error") } } func mustLoad(t *testing.T, pval interface{}, schema Schema, vals []Value) { if err := load(pval, schema, vals); err != nil { t.Fatalf("loading: %v", err) } } func load(pval interface{}, schema Schema, vals []Value) error { var sl structLoader if err := sl.set(pval, schema); err != nil { return err } return sl.Load(vals, nil) } func BenchmarkStructLoader_NoCompile(b *testing.B) { benchmarkStructLoader(b, false) } func BenchmarkStructLoader_Compile(b *testing.B) { benchmarkStructLoader(b, true) } func benchmarkStructLoader(b *testing.B, compile bool) { var ts1 testStruct1 for i := 0; i < b.N; i++ { var sl structLoader for j := 0; j < 10; j++ { if err := load(&ts1, schema2, testValues); err != nil { b.Fatal(err) } if !compile { sl.typ = nil } } } } google-cloud-go-0.49.0/bigtable/000077500000000000000000000000001356504100700163415ustar00rootroot00000000000000google-cloud-go-0.49.0/bigtable/.repo-metadata.json000066400000000000000000000006331356504100700220370ustar00rootroot00000000000000{ "name": "bigtable", "name_pretty": "Cloud Bigtable API", "product_documentation": "https://cloud.google.com/bigtable", "client_documentation": "https://godoc.org/cloud.google.com/go/bigtable", "release_level": "ga", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go/bigtable", "api_id": "bigtable.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/bigtable/CHANGES.md000066400000000000000000000007261356504100700177400ustar00rootroot00000000000000# Changes ## v1.1.0 * Add support to cbt tool to drop all rows from a table. * Adds a method to update an instance with clusters. * Adds StorageType to ClusterInfo. * Add support for the `-auth-token` flag to cbt tool. * Adds support for Table-level IAM, including some bug fixes. ## v1.0.0 This is the first tag to carve out bigtable as its own module. See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository. google-cloud-go-0.49.0/bigtable/admin.go000066400000000000000000001365201356504100700177670ustar00rootroot00000000000000/* Copyright 2015 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package bigtable import ( "container/list" "context" "errors" "fmt" "math" "regexp" "strings" "time" btopt "cloud.google.com/go/bigtable/internal/option" "cloud.google.com/go/iam" "cloud.google.com/go/internal/optional" "cloud.google.com/go/longrunning" lroauto "cloud.google.com/go/longrunning/autogen" "github.com/golang/protobuf/ptypes" durpb "github.com/golang/protobuf/ptypes/duration" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/cloudresourcemanager/v1" "google.golang.org/api/iterator" "google.golang.org/api/option" gtransport "google.golang.org/api/transport/grpc" btapb "google.golang.org/genproto/googleapis/bigtable/admin/v2" "google.golang.org/genproto/protobuf/field_mask" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" ) const adminAddr = "bigtableadmin.googleapis.com:443" // AdminClient is a client type for performing admin operations within a specific instance. type AdminClient struct { conn *grpc.ClientConn tClient btapb.BigtableTableAdminClient lroClient *lroauto.OperationsClient project, instance string // Metadata to be sent with each request. md metadata.MD } // NewAdminClient creates a new AdminClient for a given project and instance. func NewAdminClient(ctx context.Context, project, instance string, opts ...option.ClientOption) (*AdminClient, error) { o, err := btopt.DefaultClientOptions(adminAddr, AdminScope, clientUserAgent) if err != nil { return nil, err } // Add gRPC client interceptors to supply Google client information. No external interceptors are passed. o = append(o, btopt.ClientInterceptorOptions(nil, nil)...) // Need to add scopes for long running operations (for create table & snapshots) o = append(o, option.WithScopes(cloudresourcemanager.CloudPlatformScope)) o = append(o, opts...) conn, err := gtransport.Dial(ctx, o...) if err != nil { return nil, fmt.Errorf("dialing: %v", err) } lroClient, err := lroauto.NewOperationsClient(ctx, option.WithGRPCConn(conn)) if err != nil { // This error "should not happen", since we are just reusing old connection // and never actually need to dial. // If this does happen, we could leak conn. However, we cannot close conn: // If the user invoked the function with option.WithGRPCConn, // we would close a connection that's still in use. // TODO(pongad): investigate error conditions. return nil, err } return &AdminClient{ conn: conn, tClient: btapb.NewBigtableTableAdminClient(conn), lroClient: lroClient, project: project, instance: instance, md: metadata.Pairs(resourcePrefixHeader, fmt.Sprintf("projects/%s/instances/%s", project, instance)), }, nil } // Close closes the AdminClient. func (ac *AdminClient) Close() error { return ac.conn.Close() } func (ac *AdminClient) instancePrefix() string { return fmt.Sprintf("projects/%s/instances/%s", ac.project, ac.instance) } // Tables returns a list of the tables in the instance. func (ac *AdminClient) Tables(ctx context.Context) ([]string, error) { ctx = mergeOutgoingMetadata(ctx, ac.md) prefix := ac.instancePrefix() req := &btapb.ListTablesRequest{ Parent: prefix, } var res *btapb.ListTablesResponse err := gax.Invoke(ctx, func(ctx context.Context, _ gax.CallSettings) error { var err error res, err = ac.tClient.ListTables(ctx, req) return err }, retryOptions...) if err != nil { return nil, err } names := make([]string, 0, len(res.Tables)) for _, tbl := range res.Tables { names = append(names, strings.TrimPrefix(tbl.Name, prefix+"/tables/")) } return names, nil } // TableConf contains all of the information necessary to create a table with column families. type TableConf struct { TableID string SplitKeys []string // Families is a map from family name to GCPolicy Families map[string]GCPolicy } // CreateTable creates a new table in the instance. // This method may return before the table's creation is complete. func (ac *AdminClient) CreateTable(ctx context.Context, table string) error { return ac.CreateTableFromConf(ctx, &TableConf{TableID: table}) } // CreatePresplitTable creates a new table in the instance. // The list of row keys will be used to initially split the table into multiple tablets. // Given two split keys, "s1" and "s2", three tablets will be created, // spanning the key ranges: [, s1), [s1, s2), [s2, ). // This method may return before the table's creation is complete. func (ac *AdminClient) CreatePresplitTable(ctx context.Context, table string, splitKeys []string) error { return ac.CreateTableFromConf(ctx, &TableConf{TableID: table, SplitKeys: splitKeys}) } // CreateTableFromConf creates a new table in the instance from the given configuration. func (ac *AdminClient) CreateTableFromConf(ctx context.Context, conf *TableConf) error { ctx = mergeOutgoingMetadata(ctx, ac.md) var reqSplits []*btapb.CreateTableRequest_Split for _, split := range conf.SplitKeys { reqSplits = append(reqSplits, &btapb.CreateTableRequest_Split{Key: []byte(split)}) } var tbl btapb.Table if conf.Families != nil { tbl.ColumnFamilies = make(map[string]*btapb.ColumnFamily) for fam, policy := range conf.Families { tbl.ColumnFamilies[fam] = &btapb.ColumnFamily{GcRule: policy.proto()} } } prefix := ac.instancePrefix() req := &btapb.CreateTableRequest{ Parent: prefix, TableId: conf.TableID, Table: &tbl, InitialSplits: reqSplits, } _, err := ac.tClient.CreateTable(ctx, req) return err } // CreateColumnFamily creates a new column family in a table. func (ac *AdminClient) CreateColumnFamily(ctx context.Context, table, family string) error { // TODO(dsymonds): Permit specifying gcexpr and any other family settings. ctx = mergeOutgoingMetadata(ctx, ac.md) prefix := ac.instancePrefix() req := &btapb.ModifyColumnFamiliesRequest{ Name: prefix + "/tables/" + table, Modifications: []*btapb.ModifyColumnFamiliesRequest_Modification{{ Id: family, Mod: &btapb.ModifyColumnFamiliesRequest_Modification_Create{Create: &btapb.ColumnFamily{}}, }}, } _, err := ac.tClient.ModifyColumnFamilies(ctx, req) return err } // DeleteTable deletes a table and all of its data. func (ac *AdminClient) DeleteTable(ctx context.Context, table string) error { ctx = mergeOutgoingMetadata(ctx, ac.md) prefix := ac.instancePrefix() req := &btapb.DeleteTableRequest{ Name: prefix + "/tables/" + table, } _, err := ac.tClient.DeleteTable(ctx, req) return err } // DeleteColumnFamily deletes a column family in a table and all of its data. func (ac *AdminClient) DeleteColumnFamily(ctx context.Context, table, family string) error { ctx = mergeOutgoingMetadata(ctx, ac.md) prefix := ac.instancePrefix() req := &btapb.ModifyColumnFamiliesRequest{ Name: prefix + "/tables/" + table, Modifications: []*btapb.ModifyColumnFamiliesRequest_Modification{{ Id: family, Mod: &btapb.ModifyColumnFamiliesRequest_Modification_Drop{Drop: true}, }}, } _, err := ac.tClient.ModifyColumnFamilies(ctx, req) return err } // TableInfo represents information about a table. type TableInfo struct { // DEPRECATED - This field is deprecated. Please use FamilyInfos instead. Families []string FamilyInfos []FamilyInfo } // FamilyInfo represents information about a column family. type FamilyInfo struct { Name string GCPolicy string } // TableInfo retrieves information about a table. func (ac *AdminClient) TableInfo(ctx context.Context, table string) (*TableInfo, error) { ctx = mergeOutgoingMetadata(ctx, ac.md) prefix := ac.instancePrefix() req := &btapb.GetTableRequest{ Name: prefix + "/tables/" + table, } var res *btapb.Table err := gax.Invoke(ctx, func(ctx context.Context, _ gax.CallSettings) error { var err error res, err = ac.tClient.GetTable(ctx, req) return err }, retryOptions...) if err != nil { return nil, err } ti := &TableInfo{} for name, fam := range res.ColumnFamilies { ti.Families = append(ti.Families, name) ti.FamilyInfos = append(ti.FamilyInfos, FamilyInfo{Name: name, GCPolicy: GCRuleToString(fam.GcRule)}) } return ti, nil } // SetGCPolicy specifies which cells in a column family should be garbage collected. // GC executes opportunistically in the background; table reads may return data // matching the GC policy. func (ac *AdminClient) SetGCPolicy(ctx context.Context, table, family string, policy GCPolicy) error { ctx = mergeOutgoingMetadata(ctx, ac.md) prefix := ac.instancePrefix() req := &btapb.ModifyColumnFamiliesRequest{ Name: prefix + "/tables/" + table, Modifications: []*btapb.ModifyColumnFamiliesRequest_Modification{{ Id: family, Mod: &btapb.ModifyColumnFamiliesRequest_Modification_Update{Update: &btapb.ColumnFamily{GcRule: policy.proto()}}, }}, } _, err := ac.tClient.ModifyColumnFamilies(ctx, req) return err } // DropRowRange permanently deletes a row range from the specified table. func (ac *AdminClient) DropRowRange(ctx context.Context, table, rowKeyPrefix string) error { ctx = mergeOutgoingMetadata(ctx, ac.md) prefix := ac.instancePrefix() req := &btapb.DropRowRangeRequest{ Name: prefix + "/tables/" + table, Target: &btapb.DropRowRangeRequest_RowKeyPrefix{RowKeyPrefix: []byte(rowKeyPrefix)}, } _, err := ac.tClient.DropRowRange(ctx, req) return err } // DropAllRows permanently deletes all rows from the specified table. func (ac *AdminClient) DropAllRows(ctx context.Context, table string) error { ctx = mergeOutgoingMetadata(ctx, ac.md) prefix := ac.instancePrefix() req := &btapb.DropRowRangeRequest{ Name: prefix + "/tables/" + table, Target: &btapb.DropRowRangeRequest_DeleteAllDataFromTable{DeleteAllDataFromTable: true}, } _, err := ac.tClient.DropRowRange(ctx, req) return err } // CreateTableFromSnapshot creates a table from snapshot. // The table will be created in the same cluster as the snapshot. // // This is a private alpha release of Cloud Bigtable snapshots. This feature // is not currently available to most Cloud Bigtable customers. This feature // might be changed in backward-incompatible ways and is not recommended for // production use. It is not subject to any SLA or deprecation policy. func (ac *AdminClient) CreateTableFromSnapshot(ctx context.Context, table, cluster, snapshot string) error { ctx = mergeOutgoingMetadata(ctx, ac.md) prefix := ac.instancePrefix() snapshotPath := prefix + "/clusters/" + cluster + "/snapshots/" + snapshot req := &btapb.CreateTableFromSnapshotRequest{ Parent: prefix, TableId: table, SourceSnapshot: snapshotPath, } op, err := ac.tClient.CreateTableFromSnapshot(ctx, req) if err != nil { return err } resp := btapb.Table{} return longrunning.InternalNewOperation(ac.lroClient, op).Wait(ctx, &resp) } // DefaultSnapshotDuration is the default TTL for a snapshot. const DefaultSnapshotDuration time.Duration = 0 // SnapshotTable creates a new snapshot in the specified cluster from the // specified source table. Setting the TTL to `DefaultSnapshotDuration` will // use the server side default for the duration. // // This is a private alpha release of Cloud Bigtable snapshots. This feature // is not currently available to most Cloud Bigtable customers. This feature // might be changed in backward-incompatible ways and is not recommended for // production use. It is not subject to any SLA or deprecation policy. func (ac *AdminClient) SnapshotTable(ctx context.Context, table, cluster, snapshot string, ttl time.Duration) error { ctx = mergeOutgoingMetadata(ctx, ac.md) prefix := ac.instancePrefix() var ttlProto *durpb.Duration if ttl > 0 { ttlProto = ptypes.DurationProto(ttl) } req := &btapb.SnapshotTableRequest{ Name: prefix + "/tables/" + table, Cluster: prefix + "/clusters/" + cluster, SnapshotId: snapshot, Ttl: ttlProto, } op, err := ac.tClient.SnapshotTable(ctx, req) if err != nil { return err } resp := btapb.Snapshot{} return longrunning.InternalNewOperation(ac.lroClient, op).Wait(ctx, &resp) } // Snapshots returns a SnapshotIterator for iterating over the snapshots in a cluster. // To list snapshots across all of the clusters in the instance specify "-" as the cluster. // // This is a private alpha release of Cloud Bigtable snapshots. This feature is not // currently available to most Cloud Bigtable customers. This feature might be // changed in backward-incompatible ways and is not recommended for production use. // It is not subject to any SLA or deprecation policy. func (ac *AdminClient) Snapshots(ctx context.Context, cluster string) *SnapshotIterator { ctx = mergeOutgoingMetadata(ctx, ac.md) prefix := ac.instancePrefix() clusterPath := prefix + "/clusters/" + cluster it := &SnapshotIterator{} req := &btapb.ListSnapshotsRequest{ Parent: clusterPath, } fetch := func(pageSize int, pageToken string) (string, error) { req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } var resp *btapb.ListSnapshotsResponse err := gax.Invoke(ctx, func(ctx context.Context, _ gax.CallSettings) error { var err error resp, err = ac.tClient.ListSnapshots(ctx, req) return err }, retryOptions...) if err != nil { return "", err } for _, s := range resp.Snapshots { snapshotInfo, err := newSnapshotInfo(s) if err != nil { return "", fmt.Errorf("failed to parse snapshot proto %v", err) } it.items = append(it.items, snapshotInfo) } return resp.NextPageToken, nil } bufLen := func() int { return len(it.items) } takeBuf := func() interface{} { b := it.items; it.items = nil; return b } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, bufLen, takeBuf) return it } func newSnapshotInfo(snapshot *btapb.Snapshot) (*SnapshotInfo, error) { nameParts := strings.Split(snapshot.Name, "/") name := nameParts[len(nameParts)-1] tablePathParts := strings.Split(snapshot.SourceTable.Name, "/") tableID := tablePathParts[len(tablePathParts)-1] createTime, err := ptypes.Timestamp(snapshot.CreateTime) if err != nil { return nil, fmt.Errorf("invalid createTime: %v", err) } deleteTime, err := ptypes.Timestamp(snapshot.DeleteTime) if err != nil { return nil, fmt.Errorf("invalid deleteTime: %v", err) } return &SnapshotInfo{ Name: name, SourceTable: tableID, DataSize: snapshot.DataSizeBytes, CreateTime: createTime, DeleteTime: deleteTime, }, nil } // SnapshotIterator is an EntryIterator that iterates over log entries. // // This is a private alpha release of Cloud Bigtable snapshots. This feature // is not currently available to most Cloud Bigtable customers. This feature // might be changed in backward-incompatible ways and is not recommended for // production use. It is not subject to any SLA or deprecation policy. type SnapshotIterator struct { items []*SnapshotInfo pageInfo *iterator.PageInfo nextFunc func() error } // PageInfo supports pagination. See https://godoc.org/google.golang.org/api/iterator package for details. func (it *SnapshotIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done // (https://godoc.org/google.golang.org/api/iterator) if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *SnapshotIterator) Next() (*SnapshotInfo, error) { if err := it.nextFunc(); err != nil { return nil, err } item := it.items[0] it.items = it.items[1:] return item, nil } // SnapshotInfo contains snapshot metadata. type SnapshotInfo struct { Name string SourceTable string DataSize int64 CreateTime time.Time DeleteTime time.Time } // SnapshotInfo gets snapshot metadata. // // This is a private alpha release of Cloud Bigtable snapshots. This feature // is not currently available to most Cloud Bigtable customers. This feature // might be changed in backward-incompatible ways and is not recommended for // production use. It is not subject to any SLA or deprecation policy. func (ac *AdminClient) SnapshotInfo(ctx context.Context, cluster, snapshot string) (*SnapshotInfo, error) { ctx = mergeOutgoingMetadata(ctx, ac.md) prefix := ac.instancePrefix() clusterPath := prefix + "/clusters/" + cluster snapshotPath := clusterPath + "/snapshots/" + snapshot req := &btapb.GetSnapshotRequest{ Name: snapshotPath, } var resp *btapb.Snapshot err := gax.Invoke(ctx, func(ctx context.Context, _ gax.CallSettings) error { var err error resp, err = ac.tClient.GetSnapshot(ctx, req) return err }, retryOptions...) if err != nil { return nil, err } return newSnapshotInfo(resp) } // DeleteSnapshot deletes a snapshot in a cluster. // // This is a private alpha release of Cloud Bigtable snapshots. This feature // is not currently available to most Cloud Bigtable customers. This feature // might be changed in backward-incompatible ways and is not recommended for // production use. It is not subject to any SLA or deprecation policy. func (ac *AdminClient) DeleteSnapshot(ctx context.Context, cluster, snapshot string) error { ctx = mergeOutgoingMetadata(ctx, ac.md) prefix := ac.instancePrefix() clusterPath := prefix + "/clusters/" + cluster snapshotPath := clusterPath + "/snapshots/" + snapshot req := &btapb.DeleteSnapshotRequest{ Name: snapshotPath, } _, err := ac.tClient.DeleteSnapshot(ctx, req) return err } // getConsistencyToken gets the consistency token for a table. func (ac *AdminClient) getConsistencyToken(ctx context.Context, tableName string) (string, error) { req := &btapb.GenerateConsistencyTokenRequest{ Name: tableName, } resp, err := ac.tClient.GenerateConsistencyToken(ctx, req) if err != nil { return "", err } return resp.GetConsistencyToken(), nil } // isConsistent checks if a token is consistent for a table. func (ac *AdminClient) isConsistent(ctx context.Context, tableName, token string) (bool, error) { req := &btapb.CheckConsistencyRequest{ Name: tableName, ConsistencyToken: token, } var resp *btapb.CheckConsistencyResponse // Retry calls on retryable errors to avoid losing the token gathered before. err := gax.Invoke(ctx, func(ctx context.Context, _ gax.CallSettings) error { var err error resp, err = ac.tClient.CheckConsistency(ctx, req) return err }, retryOptions...) if err != nil { return false, err } return resp.GetConsistent(), nil } // WaitForReplication waits until all the writes committed before the call started have been propagated to all the clusters in the instance via replication. func (ac *AdminClient) WaitForReplication(ctx context.Context, table string) error { ctx = mergeOutgoingMetadata(ctx, ac.md) // Get the token. prefix := ac.instancePrefix() tableName := prefix + "/tables/" + table token, err := ac.getConsistencyToken(ctx, tableName) if err != nil { return err } // Periodically check if the token is consistent. timer := time.NewTicker(time.Second * 10) defer timer.Stop() for { consistent, err := ac.isConsistent(ctx, tableName, token) if err != nil { return err } if consistent { return nil } // Sleep for a bit or until the ctx is cancelled. select { case <-ctx.Done(): return ctx.Err() case <-timer.C: } } } // TableIAM creates an IAM client specific to a given Instance and Table within the configured project. func (ac *AdminClient) TableIAM(tableID string) *iam.Handle { return iam.InternalNewHandleGRPCClient(ac.tClient, "projects/"+ac.project+"/instances/"+ac.instance+"/tables/"+tableID) } const instanceAdminAddr = "bigtableadmin.googleapis.com:443" // InstanceAdminClient is a client type for performing admin operations on instances. // These operations can be substantially more dangerous than those provided by AdminClient. type InstanceAdminClient struct { conn *grpc.ClientConn iClient btapb.BigtableInstanceAdminClient lroClient *lroauto.OperationsClient project string // Metadata to be sent with each request. md metadata.MD } // NewInstanceAdminClient creates a new InstanceAdminClient for a given project. func NewInstanceAdminClient(ctx context.Context, project string, opts ...option.ClientOption) (*InstanceAdminClient, error) { o, err := btopt.DefaultClientOptions(instanceAdminAddr, InstanceAdminScope, clientUserAgent) if err != nil { return nil, err } // Add gRPC client interceptors to supply Google client information. No external interceptors are passed. o = append(o, btopt.ClientInterceptorOptions(nil, nil)...) o = append(o, opts...) conn, err := gtransport.Dial(ctx, o...) if err != nil { return nil, fmt.Errorf("dialing: %v", err) } lroClient, err := lroauto.NewOperationsClient(ctx, option.WithGRPCConn(conn)) if err != nil { // This error "should not happen", since we are just reusing old connection // and never actually need to dial. // If this does happen, we could leak conn. However, we cannot close conn: // If the user invoked the function with option.WithGRPCConn, // we would close a connection that's still in use. // TODO(pongad): investigate error conditions. return nil, err } return &InstanceAdminClient{ conn: conn, iClient: btapb.NewBigtableInstanceAdminClient(conn), lroClient: lroClient, project: project, md: metadata.Pairs(resourcePrefixHeader, "projects/"+project), }, nil } // Close closes the InstanceAdminClient. func (iac *InstanceAdminClient) Close() error { return iac.conn.Close() } // StorageType is the type of storage used for all tables in an instance type StorageType int const ( SSD StorageType = iota HDD ) func (st StorageType) proto() btapb.StorageType { if st == HDD { return btapb.StorageType_HDD } return btapb.StorageType_SSD } func storageTypeFromProto(st btapb.StorageType) StorageType { if st == btapb.StorageType_HDD { return HDD } return SSD } // InstanceType is the type of the instance type InstanceType int32 const ( // UNSPECIFIED instance types default to PRODUCTION UNSPECIFIED InstanceType = InstanceType(btapb.Instance_TYPE_UNSPECIFIED) PRODUCTION = InstanceType(btapb.Instance_PRODUCTION) DEVELOPMENT = InstanceType(btapb.Instance_DEVELOPMENT) ) // InstanceInfo represents information about an instance type InstanceInfo struct { Name string // name of the instance DisplayName string // display name for UIs InstanceType InstanceType } // InstanceConf contains the information necessary to create an Instance type InstanceConf struct { InstanceId, DisplayName, ClusterId, Zone string // NumNodes must not be specified for DEVELOPMENT instance types NumNodes int32 StorageType StorageType InstanceType InstanceType } // InstanceWithClustersConfig contains the information necessary to create an Instance type InstanceWithClustersConfig struct { InstanceID, DisplayName string Clusters []ClusterConfig InstanceType InstanceType } var instanceNameRegexp = regexp.MustCompile(`^projects/([^/]+)/instances/([a-z][-a-z0-9]*)$`) // CreateInstance creates a new instance in the project. // This method will return when the instance has been created or when an error occurs. func (iac *InstanceAdminClient) CreateInstance(ctx context.Context, conf *InstanceConf) error { ctx = mergeOutgoingMetadata(ctx, iac.md) newConfig := InstanceWithClustersConfig{ InstanceID: conf.InstanceId, DisplayName: conf.DisplayName, InstanceType: conf.InstanceType, Clusters: []ClusterConfig{ { InstanceID: conf.InstanceId, ClusterID: conf.ClusterId, Zone: conf.Zone, NumNodes: conf.NumNodes, StorageType: conf.StorageType, }, }, } return iac.CreateInstanceWithClusters(ctx, &newConfig) } // CreateInstanceWithClusters creates a new instance with configured clusters in the project. // This method will return when the instance has been created or when an error occurs. func (iac *InstanceAdminClient) CreateInstanceWithClusters(ctx context.Context, conf *InstanceWithClustersConfig) error { ctx = mergeOutgoingMetadata(ctx, iac.md) clusters := make(map[string]*btapb.Cluster) for _, cluster := range conf.Clusters { clusters[cluster.ClusterID] = cluster.proto(iac.project) } req := &btapb.CreateInstanceRequest{ Parent: "projects/" + iac.project, InstanceId: conf.InstanceID, Instance: &btapb.Instance{DisplayName: conf.DisplayName, Type: btapb.Instance_Type(conf.InstanceType)}, Clusters: clusters, } lro, err := iac.iClient.CreateInstance(ctx, req) if err != nil { return err } resp := btapb.Instance{} return longrunning.InternalNewOperation(iac.lroClient, lro).Wait(ctx, &resp) } // updateInstance updates a single instance based on config fields that operate // at an instance level: DisplayName and InstanceType. func (iac *InstanceAdminClient) updateInstance(ctx context.Context, conf *InstanceWithClustersConfig) (updated bool, err error) { if conf.InstanceID == "" { return false, errors.New("InstanceID is required") } // Update the instance, if necessary mask := &field_mask.FieldMask{} ireq := &btapb.PartialUpdateInstanceRequest{ Instance: &btapb.Instance{ Name: "projects/" + iac.project + "/instances/" + conf.InstanceID, }, UpdateMask: mask, } if conf.DisplayName != "" { ireq.Instance.DisplayName = conf.DisplayName mask.Paths = append(mask.Paths, "display_name") } if btapb.Instance_Type(conf.InstanceType) != btapb.Instance_TYPE_UNSPECIFIED { ireq.Instance.Type = btapb.Instance_Type(conf.InstanceType) mask.Paths = append(mask.Paths, "type") } if len(mask.Paths) == 0 { return false, nil } lro, err := iac.iClient.PartialUpdateInstance(ctx, ireq) if err != nil { return false, err } err = longrunning.InternalNewOperation(iac.lroClient, lro).Wait(ctx, nil) if err != nil { return false, err } return true, nil } // UpdateInstanceWithClusters updates an instance and its clusters. Updateable // fields are instance display name, instance type and cluster size. // The provided InstanceWithClustersConfig is used as follows: // - InstanceID is required // - DisplayName and InstanceType are updated only if they are not empty // - ClusterID is required for any provided cluster // - All other cluster fields are ignored except for NumNodes, which if set will be updated // // This method may return an error after partially succeeding, for example if the instance is updated // but a cluster update fails. If an error is returned, InstanceInfo and Clusters may be called to // determine the current state. func (iac *InstanceAdminClient) UpdateInstanceWithClusters(ctx context.Context, conf *InstanceWithClustersConfig) error { ctx = mergeOutgoingMetadata(ctx, iac.md) for _, cluster := range conf.Clusters { if cluster.ClusterID == "" { return errors.New("ClusterID is required for every cluster") } } updatedInstance, err := iac.updateInstance(ctx, conf) if err != nil { return err } // Update any clusters for _, cluster := range conf.Clusters { err := iac.UpdateCluster(ctx, conf.InstanceID, cluster.ClusterID, cluster.NumNodes) if err != nil { if updatedInstance { // We updated the instance, so note that in the error message. return fmt.Errorf("UpdateCluster %q failed %v; however UpdateInstance succeeded", cluster.ClusterID, err) } return err } } return nil } // DeleteInstance deletes an instance from the project. func (iac *InstanceAdminClient) DeleteInstance(ctx context.Context, instanceID string) error { ctx = mergeOutgoingMetadata(ctx, iac.md) req := &btapb.DeleteInstanceRequest{Name: "projects/" + iac.project + "/instances/" + instanceID} _, err := iac.iClient.DeleteInstance(ctx, req) return err } // Instances returns a list of instances in the project. func (iac *InstanceAdminClient) Instances(ctx context.Context) ([]*InstanceInfo, error) { ctx = mergeOutgoingMetadata(ctx, iac.md) req := &btapb.ListInstancesRequest{ Parent: "projects/" + iac.project, } var res *btapb.ListInstancesResponse err := gax.Invoke(ctx, func(ctx context.Context, _ gax.CallSettings) error { var err error res, err = iac.iClient.ListInstances(ctx, req) return err }, retryOptions...) if err != nil { return nil, err } if len(res.FailedLocations) > 0 { // We don't have a good way to return a partial result in the face of some zones being unavailable. // Fail the entire request. return nil, status.Errorf(codes.Unavailable, "Failed locations: %v", res.FailedLocations) } var is []*InstanceInfo for _, i := range res.Instances { m := instanceNameRegexp.FindStringSubmatch(i.Name) if m == nil { return nil, fmt.Errorf("malformed instance name %q", i.Name) } is = append(is, &InstanceInfo{ Name: m[2], DisplayName: i.DisplayName, InstanceType: InstanceType(i.Type), }) } return is, nil } // InstanceInfo returns information about an instance. func (iac *InstanceAdminClient) InstanceInfo(ctx context.Context, instanceID string) (*InstanceInfo, error) { ctx = mergeOutgoingMetadata(ctx, iac.md) req := &btapb.GetInstanceRequest{ Name: "projects/" + iac.project + "/instances/" + instanceID, } var res *btapb.Instance err := gax.Invoke(ctx, func(ctx context.Context, _ gax.CallSettings) error { var err error res, err = iac.iClient.GetInstance(ctx, req) return err }, retryOptions...) if err != nil { return nil, err } m := instanceNameRegexp.FindStringSubmatch(res.Name) if m == nil { return nil, fmt.Errorf("malformed instance name %q", res.Name) } return &InstanceInfo{ Name: m[2], DisplayName: res.DisplayName, InstanceType: InstanceType(res.Type), }, nil } // ClusterConfig contains the information necessary to create a cluster type ClusterConfig struct { InstanceID, ClusterID, Zone string NumNodes int32 StorageType StorageType } func (cc *ClusterConfig) proto(project string) *btapb.Cluster { return &btapb.Cluster{ ServeNodes: cc.NumNodes, DefaultStorageType: cc.StorageType.proto(), Location: "projects/" + project + "/locations/" + cc.Zone, } } // ClusterInfo represents information about a cluster. type ClusterInfo struct { Name string // name of the cluster Zone string // GCP zone of the cluster (e.g. "us-central1-a") ServeNodes int // number of allocated serve nodes State string // state of the cluster StorageType StorageType // the storage type of the cluster } // CreateCluster creates a new cluster in an instance. // This method will return when the cluster has been created or when an error occurs. func (iac *InstanceAdminClient) CreateCluster(ctx context.Context, conf *ClusterConfig) error { ctx = mergeOutgoingMetadata(ctx, iac.md) req := &btapb.CreateClusterRequest{ Parent: "projects/" + iac.project + "/instances/" + conf.InstanceID, ClusterId: conf.ClusterID, Cluster: conf.proto(iac.project), } lro, err := iac.iClient.CreateCluster(ctx, req) if err != nil { return err } resp := btapb.Cluster{} return longrunning.InternalNewOperation(iac.lroClient, lro).Wait(ctx, &resp) } // DeleteCluster deletes a cluster from an instance. func (iac *InstanceAdminClient) DeleteCluster(ctx context.Context, instanceID, clusterID string) error { ctx = mergeOutgoingMetadata(ctx, iac.md) req := &btapb.DeleteClusterRequest{Name: "projects/" + iac.project + "/instances/" + instanceID + "/clusters/" + clusterID} _, err := iac.iClient.DeleteCluster(ctx, req) return err } // UpdateCluster updates attributes of a cluster func (iac *InstanceAdminClient) UpdateCluster(ctx context.Context, instanceID, clusterID string, serveNodes int32) error { ctx = mergeOutgoingMetadata(ctx, iac.md) cluster := &btapb.Cluster{ Name: "projects/" + iac.project + "/instances/" + instanceID + "/clusters/" + clusterID, ServeNodes: serveNodes} lro, err := iac.iClient.UpdateCluster(ctx, cluster) if err != nil { return err } return longrunning.InternalNewOperation(iac.lroClient, lro).Wait(ctx, nil) } // Clusters lists the clusters in an instance. func (iac *InstanceAdminClient) Clusters(ctx context.Context, instanceID string) ([]*ClusterInfo, error) { ctx = mergeOutgoingMetadata(ctx, iac.md) req := &btapb.ListClustersRequest{Parent: "projects/" + iac.project + "/instances/" + instanceID} var res *btapb.ListClustersResponse err := gax.Invoke(ctx, func(ctx context.Context, _ gax.CallSettings) error { var err error res, err = iac.iClient.ListClusters(ctx, req) return err }, retryOptions...) if err != nil { return nil, err } // TODO(garyelliott): Deal with failed_locations. var cis []*ClusterInfo for _, c := range res.Clusters { nameParts := strings.Split(c.Name, "/") locParts := strings.Split(c.Location, "/") cis = append(cis, &ClusterInfo{ Name: nameParts[len(nameParts)-1], Zone: locParts[len(locParts)-1], ServeNodes: int(c.ServeNodes), State: c.State.String(), StorageType: storageTypeFromProto(c.DefaultStorageType), }) } return cis, nil } // GetCluster fetches a cluster in an instance func (iac *InstanceAdminClient) GetCluster(ctx context.Context, instanceID, clusterID string) (*ClusterInfo, error) { ctx = mergeOutgoingMetadata(ctx, iac.md) req := &btapb.GetClusterRequest{Name: "projects/" + iac.project + "/instances/" + instanceID + "/clusters/" + clusterID} var c *btapb.Cluster err := gax.Invoke(ctx, func(ctx context.Context, _ gax.CallSettings) error { var err error c, err = iac.iClient.GetCluster(ctx, req) return err }, retryOptions...) if err != nil { return nil, err } nameParts := strings.Split(c.Name, "/") locParts := strings.Split(c.Location, "/") cis := &ClusterInfo{ Name: nameParts[len(nameParts)-1], Zone: locParts[len(locParts)-1], ServeNodes: int(c.ServeNodes), State: c.State.String(), StorageType: storageTypeFromProto(c.DefaultStorageType), } return cis, nil } // InstanceIAM returns the instance's IAM handle. func (iac *InstanceAdminClient) InstanceIAM(instanceID string) *iam.Handle { return iam.InternalNewHandleGRPCClient(iac.iClient, "projects/"+iac.project+"/instances/"+instanceID) } // Routing policies. const ( // MultiClusterRouting is a policy that allows read/write requests to be // routed to any cluster in the instance. Requests will will fail over to // another cluster in the event of transient errors or delays. Choosing // this option sacrifices read-your-writes consistency to improve // availability. MultiClusterRouting = "multi_cluster_routing_use_any" // SingleClusterRouting is a policy that unconditionally routes all // read/write requests to a specific cluster. This option preserves // read-your-writes consistency, but does not improve availability. SingleClusterRouting = "single_cluster_routing" ) // ProfileConf contains the information necessary to create an profile type ProfileConf struct { Name string ProfileID string InstanceID string Etag string Description string RoutingPolicy string ClusterID string AllowTransactionalWrites bool // If true, warnings are ignored IgnoreWarnings bool } // ProfileIterator iterates over profiles. type ProfileIterator struct { items []*btapb.AppProfile pageInfo *iterator.PageInfo nextFunc func() error } // ProfileAttrsToUpdate define addrs to update during an Update call. If unset, no fields will be replaced. type ProfileAttrsToUpdate struct { // If set, updates the description. Description optional.String //If set, updates the routing policy. RoutingPolicy optional.String //If RoutingPolicy is updated to SingleClusterRouting, set these fields as well. ClusterID string AllowTransactionalWrites bool // If true, warnings are ignored IgnoreWarnings bool } // GetFieldMaskPath returns the field mask path. func (p *ProfileAttrsToUpdate) GetFieldMaskPath() []string { path := make([]string, 0) if p.Description != nil { path = append(path, "description") } if p.RoutingPolicy != nil { path = append(path, optional.ToString(p.RoutingPolicy)) } return path } // PageInfo supports pagination. See https://godoc.org/google.golang.org/api/iterator package for details. func (it *ProfileIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done // (https://godoc.org/google.golang.org/api/iterator) if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *ProfileIterator) Next() (*btapb.AppProfile, error) { if err := it.nextFunc(); err != nil { return nil, err } item := it.items[0] it.items = it.items[1:] return item, nil } // CreateAppProfile creates an app profile within an instance. func (iac *InstanceAdminClient) CreateAppProfile(ctx context.Context, profile ProfileConf) (*btapb.AppProfile, error) { ctx = mergeOutgoingMetadata(ctx, iac.md) parent := "projects/" + iac.project + "/instances/" + profile.InstanceID appProfile := &btapb.AppProfile{ Etag: profile.Etag, Description: profile.Description, } if profile.RoutingPolicy == "" { return nil, errors.New("invalid routing policy") } switch profile.RoutingPolicy { case MultiClusterRouting: appProfile.RoutingPolicy = &btapb.AppProfile_MultiClusterRoutingUseAny_{ MultiClusterRoutingUseAny: &btapb.AppProfile_MultiClusterRoutingUseAny{}, } case SingleClusterRouting: appProfile.RoutingPolicy = &btapb.AppProfile_SingleClusterRouting_{ SingleClusterRouting: &btapb.AppProfile_SingleClusterRouting{ ClusterId: profile.ClusterID, AllowTransactionalWrites: profile.AllowTransactionalWrites, }, } default: return nil, errors.New("invalid routing policy") } return iac.iClient.CreateAppProfile(ctx, &btapb.CreateAppProfileRequest{ Parent: parent, AppProfile: appProfile, AppProfileId: profile.ProfileID, IgnoreWarnings: profile.IgnoreWarnings, }) } // GetAppProfile gets information about an app profile. func (iac *InstanceAdminClient) GetAppProfile(ctx context.Context, instanceID, name string) (*btapb.AppProfile, error) { ctx = mergeOutgoingMetadata(ctx, iac.md) profileRequest := &btapb.GetAppProfileRequest{ Name: "projects/" + iac.project + "/instances/" + instanceID + "/appProfiles/" + name, } var ap *btapb.AppProfile err := gax.Invoke(ctx, func(ctx context.Context, _ gax.CallSettings) error { var err error ap, err = iac.iClient.GetAppProfile(ctx, profileRequest) return err }, retryOptions...) if err != nil { return nil, err } return ap, err } // ListAppProfiles lists information about app profiles in an instance. func (iac *InstanceAdminClient) ListAppProfiles(ctx context.Context, instanceID string) *ProfileIterator { ctx = mergeOutgoingMetadata(ctx, iac.md) listRequest := &btapb.ListAppProfilesRequest{ Parent: "projects/" + iac.project + "/instances/" + instanceID, } pit := &ProfileIterator{} fetch := func(pageSize int, pageToken string) (string, error) { listRequest.PageToken = pageToken var profileRes *btapb.ListAppProfilesResponse err := gax.Invoke(ctx, func(ctx context.Context, _ gax.CallSettings) error { var err error profileRes, err = iac.iClient.ListAppProfiles(ctx, listRequest) return err }, retryOptions...) if err != nil { return "", err } pit.items = append(pit.items, profileRes.AppProfiles...) return profileRes.NextPageToken, nil } bufLen := func() int { return len(pit.items) } takeBuf := func() interface{} { b := pit.items; pit.items = nil; return b } pit.pageInfo, pit.nextFunc = iterator.NewPageInfo(fetch, bufLen, takeBuf) return pit } // UpdateAppProfile updates an app profile within an instance. // updateAttrs should be set. If unset, all fields will be replaced. func (iac *InstanceAdminClient) UpdateAppProfile(ctx context.Context, instanceID, profileID string, updateAttrs ProfileAttrsToUpdate) error { ctx = mergeOutgoingMetadata(ctx, iac.md) profile := &btapb.AppProfile{ Name: "projects/" + iac.project + "/instances/" + instanceID + "/appProfiles/" + profileID, } if updateAttrs.Description != nil { profile.Description = optional.ToString(updateAttrs.Description) } if updateAttrs.RoutingPolicy != nil { switch optional.ToString(updateAttrs.RoutingPolicy) { case MultiClusterRouting: profile.RoutingPolicy = &btapb.AppProfile_MultiClusterRoutingUseAny_{ MultiClusterRoutingUseAny: &btapb.AppProfile_MultiClusterRoutingUseAny{}, } case SingleClusterRouting: profile.RoutingPolicy = &btapb.AppProfile_SingleClusterRouting_{ SingleClusterRouting: &btapb.AppProfile_SingleClusterRouting{ ClusterId: updateAttrs.ClusterID, AllowTransactionalWrites: updateAttrs.AllowTransactionalWrites, }, } default: return errors.New("invalid routing policy") } } patchRequest := &btapb.UpdateAppProfileRequest{ AppProfile: profile, UpdateMask: &field_mask.FieldMask{ Paths: updateAttrs.GetFieldMaskPath(), }, IgnoreWarnings: updateAttrs.IgnoreWarnings, } updateRequest, err := iac.iClient.UpdateAppProfile(ctx, patchRequest) if err != nil { return err } return longrunning.InternalNewOperation(iac.lroClient, updateRequest).Wait(ctx, nil) } // DeleteAppProfile deletes an app profile from an instance. func (iac *InstanceAdminClient) DeleteAppProfile(ctx context.Context, instanceID, name string) error { ctx = mergeOutgoingMetadata(ctx, iac.md) deleteProfileRequest := &btapb.DeleteAppProfileRequest{ Name: "projects/" + iac.project + "/instances/" + instanceID + "/appProfiles/" + name, IgnoreWarnings: true, } _, err := iac.iClient.DeleteAppProfile(ctx, deleteProfileRequest) return err } // UpdateInstanceResults contains information about the // changes made after invoking UpdateInstanceAndSyncClusters. type UpdateInstanceResults struct { InstanceUpdated bool CreatedClusters []string DeletedClusters []string UpdatedClusters []string } func (r *UpdateInstanceResults) String() string { return fmt.Sprintf("Instance updated? %v Clusters added:%v Clusters deleted:%v Clusters updated:%v", r.InstanceUpdated, r.CreatedClusters, r.DeletedClusters, r.UpdatedClusters) } func max(x, y int) int { if x > y { return x } return y } // UpdateInstanceAndSyncClusters updates an instance and its clusters, and will synchronize the // clusters in the instance with the provided clusters, creating and deleting them as necessary. // The provided InstanceWithClustersConfig is used as follows: // - InstanceID is required // - DisplayName and InstanceType are updated only if they are not empty // - ClusterID is required for any provided cluster // - Any cluster present in conf.Clusters but not part of the instance will be created using CreateCluster // and the given ClusterConfig. // - Any cluster missing from conf.Clusters but present in the instance will be removed from the instance // using DeleteCluster. // - Any cluster in conf.Clusters that also exists in the instance will be updated to contain the // provided number of nodes if set. // // This method may return an error after partially succeeding, for example if the instance is updated // but a cluster update fails. If an error is returned, InstanceInfo and Clusters may be called to // determine the current state. The return UpdateInstanceResults will describe the work done by the // method, whether partial or complete. func UpdateInstanceAndSyncClusters(ctx context.Context, iac *InstanceAdminClient, conf *InstanceWithClustersConfig) (*UpdateInstanceResults, error) { ctx = mergeOutgoingMetadata(ctx, iac.md) // First fetch the existing clusters so we know what to remove, add or update. existingClusters, err := iac.Clusters(ctx, conf.InstanceID) if err != nil { return nil, err } updatedInstance, err := iac.updateInstance(ctx, conf) if err != nil { return nil, err } results := &UpdateInstanceResults{InstanceUpdated: updatedInstance} existingClusterNames := make(map[string]bool) for _, cluster := range existingClusters { existingClusterNames[cluster.Name] = true } // Synchronize clusters that were passed in with the existing clusters in the instance. // First update any cluster we encounter that already exists in the instance. // Collect the clusters that we will create and delete so that we can minimize disruption // of the instance. clustersToCreate := list.New() clustersToDelete := list.New() for _, cluster := range conf.Clusters { _, clusterExists := existingClusterNames[cluster.ClusterID] if !clusterExists { // The cluster doesn't exist yet, so we must create it. clustersToCreate.PushBack(cluster) continue } delete(existingClusterNames, cluster.ClusterID) if cluster.NumNodes <= 0 { // We only synchronize clusters with a valid number of nodes. continue } // We simply want to update this cluster err = iac.UpdateCluster(ctx, conf.InstanceID, cluster.ClusterID, cluster.NumNodes) if err != nil { return results, fmt.Errorf("UpdateCluster %q failed %v; Progress: %v", cluster.ClusterID, err, results) } results.UpdatedClusters = append(results.UpdatedClusters, cluster.ClusterID) } // Any cluster left in existingClusterNames was NOT in the given config and should be deleted. for clusterToDelete := range existingClusterNames { clustersToDelete.PushBack(clusterToDelete) } // Now that we have the clusters that we need to create and delete, we do so keeping the following // in mind: // - Don't delete the last cluster in the instance, as that will result in an error. // - Attempt to offset each deletion with a creation before another deletion, so that instance // capacity is never reduced more than necessary. // Note that there is a limit on number of clusters in an instance which we are not aware of here, // so delete a cluster before adding one (as long as there are > 1 clusters left) so that we are // less likely to exceed the maximum number of clusters. numExistingClusters := len(existingClusters) nextCreation := clustersToCreate.Front() nextDeletion := clustersToDelete.Front() for { // We are done when both lists are empty. if nextCreation == nil && nextDeletion == nil { break } // If there is more than one existing cluster, we always want to delete first if possible. // If there are no more creations left, always go ahead with the deletion. if (numExistingClusters > 1 && nextDeletion != nil) || nextCreation == nil { clusterToDelete := nextDeletion.Value.(string) err = iac.DeleteCluster(ctx, conf.InstanceID, clusterToDelete) if err != nil { return results, fmt.Errorf("DeleteCluster %q failed %v; Progress: %v", clusterToDelete, err, results) } results.DeletedClusters = append(results.DeletedClusters, clusterToDelete) numExistingClusters-- nextDeletion = nextDeletion.Next() } // Now create a new cluster if required. if nextCreation != nil { clusterToCreate := nextCreation.Value.(ClusterConfig) // Assume the cluster config is well formed and rely on the underlying call to error out. // Make sure to set the InstanceID, though, since we know what it must be. clusterToCreate.InstanceID = conf.InstanceID err = iac.CreateCluster(ctx, &clusterToCreate) if err != nil { return results, fmt.Errorf("CreateCluster %v failed %v; Progress: %v", clusterToCreate, err, results) } results.CreatedClusters = append(results.CreatedClusters, clusterToCreate.ClusterID) numExistingClusters++ nextCreation = nextCreation.Next() } } return results, nil } google-cloud-go-0.49.0/bigtable/bigtable.go000066400000000000000000000674541356504100700204610ustar00rootroot00000000000000/* Copyright 2015 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package bigtable // import "cloud.google.com/go/bigtable" import ( "context" "errors" "fmt" "io" "strconv" "time" btopt "cloud.google.com/go/bigtable/internal/option" "cloud.google.com/go/internal/trace" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" gtransport "google.golang.org/api/transport/grpc" btpb "google.golang.org/genproto/googleapis/bigtable/v2" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" ) const prodAddr = "bigtable.googleapis.com:443" // Client is a client for reading and writing data to tables in an instance. // // A Client is safe to use concurrently, except for its Close method. type Client struct { conn *grpc.ClientConn client btpb.BigtableClient project, instance string appProfile string } // ClientConfig has configurations for the client. type ClientConfig struct { // The id of the app profile to associate with all data operations sent from this client. // If unspecified, the default app profile for the instance will be used. AppProfile string } // NewClient creates a new Client for a given project and instance. // The default ClientConfig will be used. func NewClient(ctx context.Context, project, instance string, opts ...option.ClientOption) (*Client, error) { return NewClientWithConfig(ctx, project, instance, ClientConfig{}, opts...) } // NewClientWithConfig creates a new client with the given config. func NewClientWithConfig(ctx context.Context, project, instance string, config ClientConfig, opts ...option.ClientOption) (*Client, error) { o, err := btopt.DefaultClientOptions(prodAddr, Scope, clientUserAgent) if err != nil { return nil, err } // Add gRPC client interceptors to supply Google client information. No external interceptors are passed. o = append(o, btopt.ClientInterceptorOptions(nil, nil)...) // Default to a small connection pool that can be overridden. o = append(o, option.WithGRPCConnectionPool(4), // Set the max size to correspond to server-side limits. option.WithGRPCDialOption(grpc.WithDefaultCallOptions(grpc.MaxCallSendMsgSize(1<<28), grpc.MaxCallRecvMsgSize(1<<28))), // TODO(grpc/grpc-go#1388) using connection pool without WithBlock // can cause RPCs to fail randomly. We can delete this after the issue is fixed. option.WithGRPCDialOption(grpc.WithBlock())) o = append(o, opts...) conn, err := gtransport.Dial(ctx, o...) if err != nil { return nil, fmt.Errorf("dialing: %v", err) } return &Client{ conn: conn, client: btpb.NewBigtableClient(conn), project: project, instance: instance, appProfile: config.AppProfile, }, nil } // Close closes the Client. func (c *Client) Close() error { return c.conn.Close() } var ( idempotentRetryCodes = []codes.Code{codes.DeadlineExceeded, codes.Unavailable, codes.Aborted} isIdempotentRetryCode = make(map[codes.Code]bool) retryOptions = []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes(idempotentRetryCodes, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 2 * time.Second, Multiplier: 1.2, }) }), } ) func init() { for _, code := range idempotentRetryCodes { isIdempotentRetryCode[code] = true } } func (c *Client) fullTableName(table string) string { return fmt.Sprintf("projects/%s/instances/%s/tables/%s", c.project, c.instance, table) } // mergeOutgoingMetadata returns a context populated by the existing outgoing // metadata merged with the provided mds. func mergeOutgoingMetadata(ctx context.Context, mds ...metadata.MD) context.Context { ctxMD, _ := metadata.FromOutgoingContext(ctx) // The ordering matters, hence why ctxMD comes first. allMDs := append([]metadata.MD{ctxMD}, mds...) return metadata.NewOutgoingContext(ctx, metadata.Join(allMDs...)) } // A Table refers to a table. // // A Table is safe to use concurrently. type Table struct { c *Client table string // Metadata to be sent with each request. md metadata.MD } // Open opens a table. func (c *Client) Open(table string) *Table { return &Table{ c: c, table: table, md: metadata.Pairs(resourcePrefixHeader, c.fullTableName(table)), } } // TODO(dsymonds): Read method that returns a sequence of ReadItems. // ReadRows reads rows from a table. f is called for each row. // If f returns false, the stream is shut down and ReadRows returns. // f owns its argument, and f is called serially in order by row key. // // By default, the yielded rows will contain all values in all cells. // Use RowFilter to limit the cells returned. func (t *Table) ReadRows(ctx context.Context, arg RowSet, f func(Row) bool, opts ...ReadOption) (err error) { ctx = mergeOutgoingMetadata(ctx, t.md) ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigtable.ReadRows") defer func() { trace.EndSpan(ctx, err) }() var prevRowKey string attrMap := make(map[string]interface{}) err = gax.Invoke(ctx, func(ctx context.Context, _ gax.CallSettings) error { if !arg.valid() { // Empty row set, no need to make an API call. // NOTE: we must return early if arg == RowList{} because reading // an empty RowList from bigtable returns all rows from that table. return nil } req := &btpb.ReadRowsRequest{ TableName: t.c.fullTableName(t.table), AppProfileId: t.c.appProfile, Rows: arg.proto(), } for _, opt := range opts { opt.set(req) } ctx, cancel := context.WithCancel(ctx) // for aborting the stream defer cancel() startTime := time.Now() stream, err := t.c.client.ReadRows(ctx, req) if err != nil { return err } cr := newChunkReader() for { res, err := stream.Recv() if err == io.EOF { break } if err != nil { // Reset arg for next Invoke call. arg = arg.retainRowsAfter(prevRowKey) attrMap["rowKey"] = prevRowKey attrMap["error"] = err.Error() attrMap["time_secs"] = time.Since(startTime).Seconds() trace.TracePrintf(ctx, attrMap, "Retry details in ReadRows") return err } attrMap["time_secs"] = time.Since(startTime).Seconds() attrMap["rowCount"] = len(res.Chunks) trace.TracePrintf(ctx, attrMap, "Details in ReadRows") for _, cc := range res.Chunks { row, err := cr.Process(cc) if err != nil { // No need to prepare for a retry, this is an unretryable error. return err } if row == nil { continue } prevRowKey = row.Key() if !f(row) { // Cancel and drain stream. cancel() for { if _, err := stream.Recv(); err != nil { // The stream has ended. We don't return an error // because the caller has intentionally interrupted the scan. return nil } } } } if err := cr.Close(); err != nil { // No need to prepare for a retry, this is an unretryable error. return err } } return err }, retryOptions...) return err } // ReadRow is a convenience implementation of a single-row reader. // A missing row will return a zero-length map and a nil error. func (t *Table) ReadRow(ctx context.Context, row string, opts ...ReadOption) (Row, error) { var r Row err := t.ReadRows(ctx, SingleRow(row), func(rr Row) bool { r = rr return true }, opts...) return r, err } // decodeFamilyProto adds the cell data from f to the given row. func decodeFamilyProto(r Row, row string, f *btpb.Family) { fam := f.Name // does not have colon for _, col := range f.Columns { for _, cell := range col.Cells { ri := ReadItem{ Row: row, Column: fam + ":" + string(col.Qualifier), Timestamp: Timestamp(cell.TimestampMicros), Value: cell.Value, } r[fam] = append(r[fam], ri) } } } // RowSet is a set of rows to be read. It is satisfied by RowList, RowRange and RowRangeList. // The serialized size of the RowSet must be no larger than 1MiB. type RowSet interface { proto() *btpb.RowSet // retainRowsAfter returns a new RowSet that does not include the // given row key or any row key lexicographically less than it. retainRowsAfter(lastRowKey string) RowSet // Valid reports whether this set can cover at least one row. valid() bool } // RowList is a sequence of row keys. type RowList []string func (r RowList) proto() *btpb.RowSet { keys := make([][]byte, len(r)) for i, row := range r { keys[i] = []byte(row) } return &btpb.RowSet{RowKeys: keys} } func (r RowList) retainRowsAfter(lastRowKey string) RowSet { var retryKeys RowList for _, key := range r { if key > lastRowKey { retryKeys = append(retryKeys, key) } } return retryKeys } func (r RowList) valid() bool { return len(r) > 0 } // A RowRange is a half-open interval [Start, Limit) encompassing // all the rows with keys at least as large as Start, and less than Limit. // (Bigtable string comparison is the same as Go's.) // A RowRange can be unbounded, encompassing all keys at least as large as Start. type RowRange struct { start string limit string } // NewRange returns the new RowRange [begin, end). func NewRange(begin, end string) RowRange { return RowRange{ start: begin, limit: end, } } // Unbounded tests whether a RowRange is unbounded. func (r RowRange) Unbounded() bool { return r.limit == "" } // Contains says whether the RowRange contains the key. func (r RowRange) Contains(row string) bool { return r.start <= row && (r.limit == "" || r.limit > row) } // String provides a printable description of a RowRange. func (r RowRange) String() string { a := strconv.Quote(r.start) if r.Unbounded() { return fmt.Sprintf("[%s,∞)", a) } return fmt.Sprintf("[%s,%q)", a, r.limit) } func (r RowRange) proto() *btpb.RowSet { rr := &btpb.RowRange{ StartKey: &btpb.RowRange_StartKeyClosed{StartKeyClosed: []byte(r.start)}, } if !r.Unbounded() { rr.EndKey = &btpb.RowRange_EndKeyOpen{EndKeyOpen: []byte(r.limit)} } return &btpb.RowSet{RowRanges: []*btpb.RowRange{rr}} } func (r RowRange) retainRowsAfter(lastRowKey string) RowSet { if lastRowKey == "" || lastRowKey < r.start { return r } // Set the beginning of the range to the row after the last scanned. start := lastRowKey + "\x00" if r.Unbounded() { return InfiniteRange(start) } return NewRange(start, r.limit) } func (r RowRange) valid() bool { return r.Unbounded() || r.start < r.limit } // RowRangeList is a sequence of RowRanges representing the union of the ranges. type RowRangeList []RowRange func (r RowRangeList) proto() *btpb.RowSet { ranges := make([]*btpb.RowRange, len(r)) for i, rr := range r { // RowRange.proto() returns a RowSet with a single element RowRange array ranges[i] = rr.proto().RowRanges[0] } return &btpb.RowSet{RowRanges: ranges} } func (r RowRangeList) retainRowsAfter(lastRowKey string) RowSet { if lastRowKey == "" { return r } // Return a list of any range that has not yet been completely processed var ranges RowRangeList for _, rr := range r { retained := rr.retainRowsAfter(lastRowKey) if retained.valid() { ranges = append(ranges, retained.(RowRange)) } } return ranges } func (r RowRangeList) valid() bool { for _, rr := range r { if rr.valid() { return true } } return false } // SingleRow returns a RowSet for reading a single row. func SingleRow(row string) RowSet { return RowList{row} } // PrefixRange returns a RowRange consisting of all keys starting with the prefix. func PrefixRange(prefix string) RowRange { return RowRange{ start: prefix, limit: prefixSuccessor(prefix), } } // InfiniteRange returns the RowRange consisting of all keys at least as // large as start. func InfiniteRange(start string) RowRange { return RowRange{ start: start, limit: "", } } // prefixSuccessor returns the lexically smallest string greater than the // prefix, if it exists, or "" otherwise. In either case, it is the string // needed for the Limit of a RowRange. func prefixSuccessor(prefix string) string { if prefix == "" { return "" // infinite range } n := len(prefix) for n--; n >= 0 && prefix[n] == '\xff'; n-- { } if n == -1 { return "" } ans := []byte(prefix[:n]) ans = append(ans, prefix[n]+1) return string(ans) } // A ReadOption is an optional argument to ReadRows. type ReadOption interface { set(req *btpb.ReadRowsRequest) } // RowFilter returns a ReadOption that applies f to the contents of read rows. // // If multiple RowFilters are provided, only the last is used. To combine filters, // use ChainFilters or InterleaveFilters instead. func RowFilter(f Filter) ReadOption { return rowFilter{f} } type rowFilter struct{ f Filter } func (rf rowFilter) set(req *btpb.ReadRowsRequest) { req.Filter = rf.f.proto() } // LimitRows returns a ReadOption that will limit the number of rows to be read. func LimitRows(limit int64) ReadOption { return limitRows{limit} } type limitRows struct{ limit int64 } func (lr limitRows) set(req *btpb.ReadRowsRequest) { req.RowsLimit = lr.limit } // mutationsAreRetryable returns true if all mutations are idempotent // and therefore retryable. A mutation is idempotent iff all cell timestamps // have an explicit timestamp set and do not rely on the timestamp being set on the server. func mutationsAreRetryable(muts []*btpb.Mutation) bool { serverTime := int64(ServerTime) for _, mut := range muts { setCell := mut.GetSetCell() if setCell != nil && setCell.TimestampMicros == serverTime { return false } } return true } const maxMutations = 100000 // Apply mutates a row atomically. A mutation must contain at least one // operation and at most 100000 operations. func (t *Table) Apply(ctx context.Context, row string, m *Mutation, opts ...ApplyOption) (err error) { ctx = mergeOutgoingMetadata(ctx, t.md) ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigtable/Apply") defer func() { trace.EndSpan(ctx, err) }() after := func(res proto.Message) { for _, o := range opts { o.after(res) } } var callOptions []gax.CallOption if m.cond == nil { req := &btpb.MutateRowRequest{ TableName: t.c.fullTableName(t.table), AppProfileId: t.c.appProfile, RowKey: []byte(row), Mutations: m.ops, } if mutationsAreRetryable(m.ops) { callOptions = retryOptions } var res *btpb.MutateRowResponse err := gax.Invoke(ctx, func(ctx context.Context, _ gax.CallSettings) error { var err error res, err = t.c.client.MutateRow(ctx, req) return err }, callOptions...) if err == nil { after(res) } return err } req := &btpb.CheckAndMutateRowRequest{ TableName: t.c.fullTableName(t.table), AppProfileId: t.c.appProfile, RowKey: []byte(row), PredicateFilter: m.cond.proto(), } if m.mtrue != nil { if m.mtrue.cond != nil { return errors.New("bigtable: conditional mutations cannot be nested") } req.TrueMutations = m.mtrue.ops } if m.mfalse != nil { if m.mfalse.cond != nil { return errors.New("bigtable: conditional mutations cannot be nested") } req.FalseMutations = m.mfalse.ops } if mutationsAreRetryable(req.TrueMutations) && mutationsAreRetryable(req.FalseMutations) { callOptions = retryOptions } var cmRes *btpb.CheckAndMutateRowResponse err = gax.Invoke(ctx, func(ctx context.Context, _ gax.CallSettings) error { var err error cmRes, err = t.c.client.CheckAndMutateRow(ctx, req) return err }, callOptions...) if err == nil { after(cmRes) } return err } // An ApplyOption is an optional argument to Apply. type ApplyOption interface { after(res proto.Message) } type applyAfterFunc func(res proto.Message) func (a applyAfterFunc) after(res proto.Message) { a(res) } // GetCondMutationResult returns an ApplyOption that reports whether the conditional // mutation's condition matched. func GetCondMutationResult(matched *bool) ApplyOption { return applyAfterFunc(func(res proto.Message) { if res, ok := res.(*btpb.CheckAndMutateRowResponse); ok { *matched = res.PredicateMatched } }) } // Mutation represents a set of changes for a single row of a table. type Mutation struct { ops []*btpb.Mutation // for conditional mutations cond Filter mtrue, mfalse *Mutation } // NewMutation returns a new mutation. func NewMutation() *Mutation { return new(Mutation) } // NewCondMutation returns a conditional mutation. // The given row filter determines which mutation is applied: // If the filter matches any cell in the row, mtrue is applied; // otherwise, mfalse is applied. // Either given mutation may be nil. // // The application of a ReadModifyWrite is atomic; concurrent ReadModifyWrites will // be executed serially by the server. func NewCondMutation(cond Filter, mtrue, mfalse *Mutation) *Mutation { return &Mutation{cond: cond, mtrue: mtrue, mfalse: mfalse} } // Set sets a value in a specified column, with the given timestamp. // The timestamp will be truncated to millisecond granularity. // A timestamp of ServerTime means to use the server timestamp. func (m *Mutation) Set(family, column string, ts Timestamp, value []byte) { m.ops = append(m.ops, &btpb.Mutation{Mutation: &btpb.Mutation_SetCell_{SetCell: &btpb.Mutation_SetCell{ FamilyName: family, ColumnQualifier: []byte(column), TimestampMicros: int64(ts.TruncateToMilliseconds()), Value: value, }}}) } // DeleteCellsInColumn will delete all the cells whose columns are family:column. func (m *Mutation) DeleteCellsInColumn(family, column string) { m.ops = append(m.ops, &btpb.Mutation{Mutation: &btpb.Mutation_DeleteFromColumn_{DeleteFromColumn: &btpb.Mutation_DeleteFromColumn{ FamilyName: family, ColumnQualifier: []byte(column), }}}) } // DeleteTimestampRange deletes all cells whose columns are family:column // and whose timestamps are in the half-open interval [start, end). // If end is zero, it will be interpreted as infinity. // The timestamps will be truncated to millisecond granularity. func (m *Mutation) DeleteTimestampRange(family, column string, start, end Timestamp) { m.ops = append(m.ops, &btpb.Mutation{Mutation: &btpb.Mutation_DeleteFromColumn_{DeleteFromColumn: &btpb.Mutation_DeleteFromColumn{ FamilyName: family, ColumnQualifier: []byte(column), TimeRange: &btpb.TimestampRange{ StartTimestampMicros: int64(start.TruncateToMilliseconds()), EndTimestampMicros: int64(end.TruncateToMilliseconds()), }, }}}) } // DeleteCellsInFamily will delete all the cells whose columns are family:*. func (m *Mutation) DeleteCellsInFamily(family string) { m.ops = append(m.ops, &btpb.Mutation{Mutation: &btpb.Mutation_DeleteFromFamily_{DeleteFromFamily: &btpb.Mutation_DeleteFromFamily{ FamilyName: family, }}}) } // DeleteRow deletes the entire row. func (m *Mutation) DeleteRow() { m.ops = append(m.ops, &btpb.Mutation{Mutation: &btpb.Mutation_DeleteFromRow_{DeleteFromRow: &btpb.Mutation_DeleteFromRow{}}}) } // entryErr is a container that combines an entry with the error that was returned for it. // Err may be nil if no error was returned for the Entry, or if the Entry has not yet been processed. type entryErr struct { Entry *btpb.MutateRowsRequest_Entry Err error } // ApplyBulk applies multiple Mutations, up to a maximum of 100,000. // Each mutation is individually applied atomically, // but the set of mutations may be applied in any order. // // Two types of failures may occur. If the entire process // fails, (nil, err) will be returned. If specific mutations // fail to apply, ([]err, nil) will be returned, and the errors // will correspond to the relevant rowKeys/muts arguments. // // Conditional mutations cannot be applied in bulk and providing one will result in an error. func (t *Table) ApplyBulk(ctx context.Context, rowKeys []string, muts []*Mutation, opts ...ApplyOption) (errs []error, err error) { ctx = mergeOutgoingMetadata(ctx, t.md) ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigtable/ApplyBulk") defer func() { trace.EndSpan(ctx, err) }() if len(rowKeys) != len(muts) { return nil, fmt.Errorf("mismatched rowKeys and mutation array lengths: %d, %d", len(rowKeys), len(muts)) } origEntries := make([]*entryErr, len(rowKeys)) for i, key := range rowKeys { mut := muts[i] if mut.cond != nil { return nil, errors.New("conditional mutations cannot be applied in bulk") } origEntries[i] = &entryErr{Entry: &btpb.MutateRowsRequest_Entry{RowKey: []byte(key), Mutations: mut.ops}} } for _, group := range groupEntries(origEntries, maxMutations) { attrMap := make(map[string]interface{}) err = gax.Invoke(ctx, func(ctx context.Context, _ gax.CallSettings) error { attrMap["rowCount"] = len(group) trace.TracePrintf(ctx, attrMap, "Row count in ApplyBulk") err := t.doApplyBulk(ctx, group, opts...) if err != nil { // We want to retry the entire request with the current group return err } group = t.getApplyBulkRetries(group) if len(group) > 0 && len(idempotentRetryCodes) > 0 { // We have at least one mutation that needs to be retried. // Return an arbitrary error that is retryable according to callOptions. return status.Errorf(idempotentRetryCodes[0], "Synthetic error: partial failure of ApplyBulk") } return nil }, retryOptions...) if err != nil { return nil, err } } // All the errors are accumulated into an array and returned, interspersed with nils for successful // entries. The absence of any errors means we should return nil. var foundErr bool for _, entry := range origEntries { if entry.Err != nil { foundErr = true } errs = append(errs, entry.Err) } if foundErr { return errs, nil } return nil, nil } // getApplyBulkRetries returns the entries that need to be retried func (t *Table) getApplyBulkRetries(entries []*entryErr) []*entryErr { var retryEntries []*entryErr for _, entry := range entries { err := entry.Err if err != nil && isIdempotentRetryCode[status.Code(err)] && mutationsAreRetryable(entry.Entry.Mutations) { // There was an error and the entry is retryable. retryEntries = append(retryEntries, entry) } } return retryEntries } // doApplyBulk does the work of a single ApplyBulk invocation func (t *Table) doApplyBulk(ctx context.Context, entryErrs []*entryErr, opts ...ApplyOption) error { after := func(res proto.Message) { for _, o := range opts { o.after(res) } } entries := make([]*btpb.MutateRowsRequest_Entry, len(entryErrs)) for i, entryErr := range entryErrs { entries[i] = entryErr.Entry } req := &btpb.MutateRowsRequest{ TableName: t.c.fullTableName(t.table), AppProfileId: t.c.appProfile, Entries: entries, } stream, err := t.c.client.MutateRows(ctx, req) if err != nil { return err } for { res, err := stream.Recv() if err == io.EOF { break } if err != nil { return err } for i, entry := range res.Entries { s := entry.Status if s.Code == int32(codes.OK) { entryErrs[i].Err = nil } else { entryErrs[i].Err = status.Errorf(codes.Code(s.Code), s.Message) } } after(res) } return nil } // groupEntries groups entries into groups of a specified size without breaking up // individual entries. func groupEntries(entries []*entryErr, maxSize int) [][]*entryErr { var ( res [][]*entryErr start int gmuts int ) addGroup := func(end int) { if end-start > 0 { res = append(res, entries[start:end]) start = end gmuts = 0 } } for i, e := range entries { emuts := len(e.Entry.Mutations) if gmuts+emuts > maxSize { addGroup(i) } gmuts += emuts } addGroup(len(entries)) return res } // Timestamp is in units of microseconds since 1 January 1970. type Timestamp int64 // ServerTime is a specific Timestamp that may be passed to (*Mutation).Set. // It indicates that the server's timestamp should be used. const ServerTime Timestamp = -1 // Time converts a time.Time into a Timestamp. func Time(t time.Time) Timestamp { return Timestamp(t.UnixNano() / 1e3) } // Now returns the Timestamp representation of the current time on the client. func Now() Timestamp { return Time(time.Now()) } // Time converts a Timestamp into a time.Time. func (ts Timestamp) Time() time.Time { return time.Unix(0, int64(ts)*1e3) } // TruncateToMilliseconds truncates a Timestamp to millisecond granularity, // which is currently the only granularity supported. func (ts Timestamp) TruncateToMilliseconds() Timestamp { if ts == ServerTime { return ts } return ts - ts%1000 } // ApplyReadModifyWrite applies a ReadModifyWrite to a specific row. // It returns the newly written cells. func (t *Table) ApplyReadModifyWrite(ctx context.Context, row string, m *ReadModifyWrite) (Row, error) { ctx = mergeOutgoingMetadata(ctx, t.md) req := &btpb.ReadModifyWriteRowRequest{ TableName: t.c.fullTableName(t.table), AppProfileId: t.c.appProfile, RowKey: []byte(row), Rules: m.ops, } res, err := t.c.client.ReadModifyWriteRow(ctx, req) if err != nil { return nil, err } if res.Row == nil { return nil, errors.New("unable to apply ReadModifyWrite: res.Row=nil") } r := make(Row) for _, fam := range res.Row.Families { // res is *btpb.Row, fam is *btpb.Family decodeFamilyProto(r, row, fam) } return r, nil } // ReadModifyWrite represents a set of operations on a single row of a table. // It is like Mutation but for non-idempotent changes. // When applied, these operations operate on the latest values of the row's cells, // and result in a new value being written to the relevant cell with a timestamp // that is max(existing timestamp, current server time). // // The application of a ReadModifyWrite is atomic; concurrent ReadModifyWrites will // be executed serially by the server. type ReadModifyWrite struct { ops []*btpb.ReadModifyWriteRule } // NewReadModifyWrite returns a new ReadModifyWrite. func NewReadModifyWrite() *ReadModifyWrite { return new(ReadModifyWrite) } // AppendValue appends a value to a specific cell's value. // If the cell is unset, it will be treated as an empty value. func (m *ReadModifyWrite) AppendValue(family, column string, v []byte) { m.ops = append(m.ops, &btpb.ReadModifyWriteRule{ FamilyName: family, ColumnQualifier: []byte(column), Rule: &btpb.ReadModifyWriteRule_AppendValue{AppendValue: v}, }) } // Increment interprets the value in a specific cell as a 64-bit big-endian signed integer, // and adds a value to it. If the cell is unset, it will be treated as zero. // If the cell is set and is not an 8-byte value, the entire ApplyReadModifyWrite // operation will fail. func (m *ReadModifyWrite) Increment(family, column string, delta int64) { m.ops = append(m.ops, &btpb.ReadModifyWriteRule{ FamilyName: family, ColumnQualifier: []byte(column), Rule: &btpb.ReadModifyWriteRule_IncrementAmount{IncrementAmount: delta}, }) } // SampleRowKeys returns a sample of row keys in the table. The returned row keys will delimit contiguous sections of // the table of approximately equal size, which can be used to break up the data for distributed tasks like mapreduces. func (t *Table) SampleRowKeys(ctx context.Context) ([]string, error) { ctx = mergeOutgoingMetadata(ctx, t.md) var sampledRowKeys []string err := gax.Invoke(ctx, func(ctx context.Context, _ gax.CallSettings) error { sampledRowKeys = nil req := &btpb.SampleRowKeysRequest{ TableName: t.c.fullTableName(t.table), AppProfileId: t.c.appProfile, } ctx, cancel := context.WithCancel(ctx) // for aborting the stream defer cancel() stream, err := t.c.client.SampleRowKeys(ctx, req) if err != nil { return err } for { res, err := stream.Recv() if err == io.EOF { break } if err != nil { return err } key := string(res.RowKey) if key == "" { continue } sampledRowKeys = append(sampledRowKeys, key) } return nil }, retryOptions...) return sampledRowKeys, err } google-cloud-go-0.49.0/bigtable/bigtable_test.go000066400000000000000000000157071356504100700215120ustar00rootroot00000000000000/* Copyright 2015 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package bigtable import ( "context" "testing" "time" "github.com/google/go-cmp/cmp" "google.golang.org/api/option" btpb "google.golang.org/genproto/googleapis/bigtable/v2" "google.golang.org/grpc" ) func TestPrefix(t *testing.T) { for _, test := range []struct { prefix, succ string }{ {"", ""}, {"\xff", ""}, // when used, "" means Infinity {"x\xff", "y"}, {"\xfe", "\xff"}, } { got := prefixSuccessor(test.prefix) if got != test.succ { t.Errorf("prefixSuccessor(%q) = %q, want %s", test.prefix, got, test.succ) continue } r := PrefixRange(test.prefix) if test.succ == "" && r.limit != "" { t.Errorf("PrefixRange(%q) got limit %q", test.prefix, r.limit) } if test.succ != "" && r.limit != test.succ { t.Errorf("PrefixRange(%q) got limit %q, want %q", test.prefix, r.limit, test.succ) } } } func TestApplyErrors(t *testing.T) { ctx := context.Background() table := &Table{ c: &Client{ project: "P", instance: "I", }, table: "t", } f := ColumnFilter("C") m := NewMutation() m.DeleteRow() // Test nested conditional mutations. cm := NewCondMutation(f, NewCondMutation(f, m, nil), nil) if err := table.Apply(ctx, "x", cm); err == nil { t.Error("got nil, want error") } cm = NewCondMutation(f, nil, NewCondMutation(f, m, nil)) if err := table.Apply(ctx, "x", cm); err == nil { t.Error("got nil, want error") } } func TestGroupEntries(t *testing.T) { for _, test := range []struct { desc string in []*entryErr size int want [][]*entryErr }{ { desc: "one entry less than max size is one group", in: []*entryErr{buildEntry(5)}, size: 10, want: [][]*entryErr{{buildEntry(5)}}, }, { desc: "one entry equal to max size is one group", in: []*entryErr{buildEntry(10)}, size: 10, want: [][]*entryErr{{buildEntry(10)}}, }, { desc: "one entry greater than max size is one group", in: []*entryErr{buildEntry(15)}, size: 10, want: [][]*entryErr{{buildEntry(15)}}, }, { desc: "all entries fitting within max size are one group", in: []*entryErr{buildEntry(10), buildEntry(10)}, size: 20, want: [][]*entryErr{{buildEntry(10), buildEntry(10)}}, }, { desc: "entries each under max size and together over max size are grouped separately", in: []*entryErr{buildEntry(10), buildEntry(10)}, size: 15, want: [][]*entryErr{{buildEntry(10)}, {buildEntry(10)}}, }, { desc: "entries together over max size are grouped by max size", in: []*entryErr{buildEntry(5), buildEntry(5), buildEntry(5)}, size: 10, want: [][]*entryErr{{buildEntry(5), buildEntry(5)}, {buildEntry(5)}}, }, { desc: "one entry over max size and one entry under max size are two groups", in: []*entryErr{buildEntry(15), buildEntry(5)}, size: 10, want: [][]*entryErr{{buildEntry(15)}, {buildEntry(5)}}, }, } { t.Run(test.desc, func(t *testing.T) { if got, want := groupEntries(test.in, test.size), test.want; !cmp.Equal(mutationCounts(got), mutationCounts(want)) { t.Fatalf("[%s] want = %v, got = %v", test.desc, mutationCounts(want), mutationCounts(got)) } }) } } func buildEntry(numMutations int) *entryErr { var muts []*btpb.Mutation for i := 0; i < numMutations; i++ { muts = append(muts, &btpb.Mutation{}) } return &entryErr{Entry: &btpb.MutateRowsRequest_Entry{Mutations: muts}} } func mutationCounts(batched [][]*entryErr) []int { var res []int for _, entries := range batched { var count int for _, e := range entries { count += len(e.Entry.Mutations) } res = append(res, count) } return res } type requestCountingInterceptor struct { grpc.ClientStream requestCallback func() } func (i *requestCountingInterceptor) SendMsg(m interface{}) error { i.requestCallback() return i.ClientStream.SendMsg(m) } func (i *requestCountingInterceptor) RecvMsg(m interface{}) error { return i.ClientStream.RecvMsg(m) } func requestCallback(callback func()) func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) { return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) { clientStream, err := streamer(ctx, desc, cc, method, opts...) return &requestCountingInterceptor{ ClientStream: clientStream, requestCallback: callback, }, err } } // TestReadRowsInvalidRowSet verifies that the client doesn't send ReadRows() requests with invalid RowSets. func TestReadRowsInvalidRowSet(t *testing.T) { testEnv, err := NewEmulatedEnv(IntegrationTestConfig{}) if err != nil { t.Fatalf("NewEmulatedEnv failed: %v", err) } var requestCount int incrementRequestCount := func() { requestCount++ } conn, err := grpc.Dial(testEnv.server.Addr, grpc.WithInsecure(), grpc.WithBlock(), grpc.WithDefaultCallOptions(grpc.MaxCallSendMsgSize(100<<20), grpc.MaxCallRecvMsgSize(100<<20)), grpc.WithStreamInterceptor(requestCallback(incrementRequestCount)), ) if err != nil { t.Fatalf("grpc.Dial failed: %v", err) } ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) defer cancel() adminClient, err := NewAdminClient(ctx, testEnv.config.Project, testEnv.config.Instance, option.WithGRPCConn(conn)) if err != nil { t.Fatalf("NewClient failed: %v", err) } defer adminClient.Close() if err := adminClient.CreateTable(ctx, testEnv.config.Table); err != nil { t.Fatalf("CreateTable(%v) failed: %v", testEnv.config.Table, err) } client, err := NewClient(ctx, testEnv.config.Project, testEnv.config.Instance, option.WithGRPCConn(conn)) if err != nil { t.Fatalf("NewClient failed: %v", err) } defer client.Close() table := client.Open(testEnv.config.Table) tests := []struct { rr RowSet valid bool }{ { rr: RowRange{}, valid: true, }, { rr: RowRange{start: "b"}, valid: true, }, { rr: RowRange{start: "b", limit: "c"}, valid: true, }, { rr: RowRange{start: "b", limit: "a"}, valid: false, }, { rr: RowList{"a"}, valid: true, }, { rr: RowList{}, valid: false, }, } for _, test := range tests { requestCount = 0 err = table.ReadRows(ctx, test.rr, func(r Row) bool { return true }) if err != nil { t.Fatalf("ReadRows(%v) failed: %v", test.rr, err) } requestValid := requestCount != 0 if requestValid != test.valid { t.Errorf("%s: got %v, want %v", test.rr, requestValid, test.valid) } } } google-cloud-go-0.49.0/bigtable/bttest/000077500000000000000000000000001356504100700176465ustar00rootroot00000000000000google-cloud-go-0.49.0/bigtable/bttest/example_test.go000066400000000000000000000036301356504100700226710ustar00rootroot00000000000000/* Copyright 2016 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package bttest_test import ( "context" "fmt" "log" "cloud.google.com/go/bigtable" "cloud.google.com/go/bigtable/bttest" "google.golang.org/api/option" "google.golang.org/grpc" ) func ExampleNewServer() { srv, err := bttest.NewServer("localhost:0") if err != nil { log.Fatalln(err) } ctx := context.Background() conn, err := grpc.Dial(srv.Addr, grpc.WithInsecure()) if err != nil { log.Fatalln(err) } proj, instance := "proj", "instance" adminClient, err := bigtable.NewAdminClient(ctx, proj, instance, option.WithGRPCConn(conn)) if err != nil { log.Fatalln(err) } if err = adminClient.CreateTable(ctx, "example"); err != nil { log.Fatalln(err) } if err = adminClient.CreateColumnFamily(ctx, "example", "links"); err != nil { log.Fatalln(err) } client, err := bigtable.NewClient(ctx, proj, instance, option.WithGRPCConn(conn)) if err != nil { log.Fatalln(err) } tbl := client.Open("example") mut := bigtable.NewMutation() mut.Set("links", "golang.org", bigtable.Now(), []byte("Gophers!")) if err = tbl.Apply(ctx, "com.google.cloud", mut); err != nil { log.Fatalln(err) } if row, err := tbl.ReadRow(ctx, "com.google.cloud"); err != nil { log.Fatalln(err) } else { for _, column := range row["links"] { fmt.Println(column.Column) fmt.Println(string(column.Value)) } } // Output: // links:golang.org // Gophers! } google-cloud-go-0.49.0/bigtable/bttest/inmem.go000066400000000000000000001162141356504100700213070ustar00rootroot00000000000000/* Copyright 2015 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Package bttest contains test helpers for working with the bigtable package. To use a Server, create it, and then connect to it with no security: (The project/instance values are ignored.) srv, err := bttest.NewServer("localhost:0") ... conn, err := grpc.Dial(srv.Addr, grpc.WithInsecure()) ... client, err := bigtable.NewClient(ctx, proj, instance, option.WithGRPCConn(conn)) ... */ package bttest // import "cloud.google.com/go/bigtable/bttest" import ( "bytes" "context" "encoding/binary" "fmt" "log" "math/rand" "net" "regexp" "sort" "strings" "sync" "time" emptypb "github.com/golang/protobuf/ptypes/empty" "github.com/golang/protobuf/ptypes/wrappers" "github.com/google/btree" btapb "google.golang.org/genproto/googleapis/bigtable/admin/v2" btpb "google.golang.org/genproto/googleapis/bigtable/v2" "google.golang.org/genproto/googleapis/longrunning" statpb "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "rsc.io/binaryregexp" ) const ( // MilliSeconds field of the minimum valid Timestamp. minValidMilliSeconds = 0 // MilliSeconds field of the max valid Timestamp. maxValidMilliSeconds = int64(time.Millisecond) * 253402300800 ) var ( validLabelTransformer = regexp.MustCompile(`[a-z0-9\-]{1,15}`) ) // Server is an in-memory Cloud Bigtable fake. // It is unauthenticated, and only a rough approximation. type Server struct { Addr string l net.Listener srv *grpc.Server s *server } // server is the real implementation of the fake. // It is a separate and unexported type so the API won't be cluttered with // methods that are only relevant to the fake's implementation. type server struct { mu sync.Mutex tables map[string]*table // keyed by fully qualified name instances map[string]*btapb.Instance // keyed by fully qualified name gcc chan int // set when gcloop starts, closed when server shuts down // Any unimplemented methods will cause a panic. btapb.BigtableTableAdminServer btapb.BigtableInstanceAdminServer btpb.BigtableServer } // NewServer creates a new Server. // The Server will be listening for gRPC connections, without TLS, // on the provided address. The resolved address is named by the Addr field. func NewServer(laddr string, opt ...grpc.ServerOption) (*Server, error) { l, err := net.Listen("tcp", laddr) if err != nil { return nil, err } s := &Server{ Addr: l.Addr().String(), l: l, srv: grpc.NewServer(opt...), s: &server{ tables: make(map[string]*table), instances: make(map[string]*btapb.Instance), }, } btapb.RegisterBigtableInstanceAdminServer(s.srv, s.s) btapb.RegisterBigtableTableAdminServer(s.srv, s.s) btpb.RegisterBigtableServer(s.srv, s.s) go s.srv.Serve(s.l) return s, nil } // Close shuts down the server. func (s *Server) Close() { s.s.mu.Lock() if s.s.gcc != nil { close(s.s.gcc) } s.s.mu.Unlock() s.srv.Stop() s.l.Close() } func (s *server) CreateTable(ctx context.Context, req *btapb.CreateTableRequest) (*btapb.Table, error) { tbl := req.Parent + "/tables/" + req.TableId s.mu.Lock() if _, ok := s.tables[tbl]; ok { s.mu.Unlock() return nil, status.Errorf(codes.AlreadyExists, "table %q already exists", tbl) } s.tables[tbl] = newTable(req) s.mu.Unlock() ct := &btapb.Table{ Name: tbl, ColumnFamilies: req.GetTable().GetColumnFamilies(), Granularity: req.GetTable().GetGranularity(), } if ct.Granularity == 0 { ct.Granularity = btapb.Table_MILLIS } return ct, nil } func (s *server) CreateTableFromSnapshot(context.Context, *btapb.CreateTableFromSnapshotRequest) (*longrunning.Operation, error) { return nil, status.Errorf(codes.Unimplemented, "the emulator does not currently support snapshots") } func (s *server) ListTables(ctx context.Context, req *btapb.ListTablesRequest) (*btapb.ListTablesResponse, error) { res := &btapb.ListTablesResponse{} prefix := req.Parent + "/tables/" s.mu.Lock() for tbl := range s.tables { if strings.HasPrefix(tbl, prefix) { res.Tables = append(res.Tables, &btapb.Table{Name: tbl}) } } s.mu.Unlock() return res, nil } func (s *server) GetTable(ctx context.Context, req *btapb.GetTableRequest) (*btapb.Table, error) { tbl := req.Name s.mu.Lock() tblIns, ok := s.tables[tbl] s.mu.Unlock() if !ok { return nil, status.Errorf(codes.NotFound, "table %q not found", tbl) } return &btapb.Table{ Name: tbl, ColumnFamilies: toColumnFamilies(tblIns.columnFamilies()), }, nil } func (s *server) DeleteTable(ctx context.Context, req *btapb.DeleteTableRequest) (*emptypb.Empty, error) { s.mu.Lock() defer s.mu.Unlock() if _, ok := s.tables[req.Name]; !ok { return nil, status.Errorf(codes.NotFound, "table %q not found", req.Name) } delete(s.tables, req.Name) return &emptypb.Empty{}, nil } func (s *server) ModifyColumnFamilies(ctx context.Context, req *btapb.ModifyColumnFamiliesRequest) (*btapb.Table, error) { s.mu.Lock() tbl, ok := s.tables[req.Name] s.mu.Unlock() if !ok { return nil, status.Errorf(codes.NotFound, "table %q not found", req.Name) } tbl.mu.Lock() defer tbl.mu.Unlock() for _, mod := range req.Modifications { if create := mod.GetCreate(); create != nil { if _, ok := tbl.families[mod.Id]; ok { return nil, status.Errorf(codes.AlreadyExists, "family %q already exists", mod.Id) } newcf := &columnFamily{ name: req.Name + "/columnFamilies/" + mod.Id, order: tbl.counter, gcRule: create.GcRule, } tbl.counter++ tbl.families[mod.Id] = newcf } else if mod.GetDrop() { if _, ok := tbl.families[mod.Id]; !ok { return nil, fmt.Errorf("can't delete unknown family %q", mod.Id) } delete(tbl.families, mod.Id) } else if modify := mod.GetUpdate(); modify != nil { if _, ok := tbl.families[mod.Id]; !ok { return nil, fmt.Errorf("no such family %q", mod.Id) } newcf := &columnFamily{ name: req.Name + "/columnFamilies/" + mod.Id, gcRule: modify.GcRule, } // assume that we ALWAYS want to replace by the new setting // we may need partial update through tbl.families[mod.Id] = newcf } } s.needGC() return &btapb.Table{ Name: req.Name, ColumnFamilies: toColumnFamilies(tbl.families), Granularity: btapb.Table_TimestampGranularity(btapb.Table_MILLIS), }, nil } func (s *server) DropRowRange(ctx context.Context, req *btapb.DropRowRangeRequest) (*emptypb.Empty, error) { s.mu.Lock() defer s.mu.Unlock() tbl, ok := s.tables[req.Name] if !ok { return nil, status.Errorf(codes.NotFound, "table %q not found", req.Name) } if req.GetDeleteAllDataFromTable() { tbl.rows = btree.New(btreeDegree) } else { // Delete rows by prefix. prefixBytes := req.GetRowKeyPrefix() if prefixBytes == nil { return nil, fmt.Errorf("missing row key prefix") } prefix := string(prefixBytes) // The BTree does not specify what happens if rows are deleted during // iteration, and it provides no "delete range" method. // So we collect the rows first, then delete them one by one. var rowsToDelete []*row tbl.rows.AscendGreaterOrEqual(btreeKey(prefix), func(i btree.Item) bool { r := i.(*row) if strings.HasPrefix(r.key, prefix) { rowsToDelete = append(rowsToDelete, r) return true } return false // stop iteration }) for _, r := range rowsToDelete { tbl.rows.Delete(r) } } return &emptypb.Empty{}, nil } func (s *server) GenerateConsistencyToken(ctx context.Context, req *btapb.GenerateConsistencyTokenRequest) (*btapb.GenerateConsistencyTokenResponse, error) { // Check that the table exists. _, ok := s.tables[req.Name] if !ok { return nil, status.Errorf(codes.NotFound, "table %q not found", req.Name) } return &btapb.GenerateConsistencyTokenResponse{ ConsistencyToken: "TokenFor-" + req.Name, }, nil } func (s *server) CheckConsistency(ctx context.Context, req *btapb.CheckConsistencyRequest) (*btapb.CheckConsistencyResponse, error) { // Check that the table exists. _, ok := s.tables[req.Name] if !ok { return nil, status.Errorf(codes.NotFound, "table %q not found", req.Name) } // Check this is the right token. if req.ConsistencyToken != "TokenFor-"+req.Name { return nil, status.Errorf(codes.InvalidArgument, "token %q not valid", req.ConsistencyToken) } // Single cluster instances are always consistent. return &btapb.CheckConsistencyResponse{ Consistent: true, }, nil } func (s *server) SnapshotTable(context.Context, *btapb.SnapshotTableRequest) (*longrunning.Operation, error) { return nil, status.Errorf(codes.Unimplemented, "the emulator does not currently support snapshots") } func (s *server) GetSnapshot(context.Context, *btapb.GetSnapshotRequest) (*btapb.Snapshot, error) { return nil, status.Errorf(codes.Unimplemented, "the emulator does not currently support snapshots") } func (s *server) ListSnapshots(context.Context, *btapb.ListSnapshotsRequest) (*btapb.ListSnapshotsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "the emulator does not currently support snapshots") } func (s *server) DeleteSnapshot(context.Context, *btapb.DeleteSnapshotRequest) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "the emulator does not currently support snapshots") } func (s *server) ReadRows(req *btpb.ReadRowsRequest, stream btpb.Bigtable_ReadRowsServer) error { s.mu.Lock() tbl, ok := s.tables[req.TableName] s.mu.Unlock() if !ok { return status.Errorf(codes.NotFound, "table %q not found", req.TableName) } if err := validateRowRanges(req); err != nil { return err } // Rows to read can be specified by a set of row keys and/or a set of row ranges. // Output is a stream of sorted, de-duped rows. tbl.mu.RLock() rowSet := make(map[string]*row) addRow := func(i btree.Item) bool { r := i.(*row) rowSet[r.key] = r return true } if req.Rows != nil && len(req.Rows.RowKeys)+len(req.Rows.RowRanges) > 0 { // Add the explicitly given keys for _, key := range req.Rows.RowKeys { k := string(key) if i := tbl.rows.Get(btreeKey(k)); i != nil { addRow(i) } } // Add keys from row ranges for _, rr := range req.Rows.RowRanges { var start, end string switch sk := rr.StartKey.(type) { case *btpb.RowRange_StartKeyClosed: start = string(sk.StartKeyClosed) case *btpb.RowRange_StartKeyOpen: start = string(sk.StartKeyOpen) + "\x00" } switch ek := rr.EndKey.(type) { case *btpb.RowRange_EndKeyClosed: end = string(ek.EndKeyClosed) + "\x00" case *btpb.RowRange_EndKeyOpen: end = string(ek.EndKeyOpen) } switch { case start == "" && end == "": tbl.rows.Ascend(addRow) // all rows case start == "": tbl.rows.AscendLessThan(btreeKey(end), addRow) case end == "": tbl.rows.AscendGreaterOrEqual(btreeKey(start), addRow) default: tbl.rows.AscendRange(btreeKey(start), btreeKey(end), addRow) } } } else { // Read all rows tbl.rows.Ascend(addRow) } tbl.mu.RUnlock() rows := make([]*row, 0, len(rowSet)) for _, r := range rowSet { r.mu.Lock() fams := len(r.families) r.mu.Unlock() if fams != 0 { rows = append(rows, r) } } sort.Sort(byRowKey(rows)) limit := int(req.RowsLimit) count := 0 for _, r := range rows { if limit > 0 && count >= limit { return nil } streamed, err := streamRow(stream, r, req.Filter) if err != nil { return err } if streamed { count++ } } return nil } // streamRow filters the given row and sends it via the given stream. // Returns true if at least one cell matched the filter and was streamed, false otherwise. func streamRow(stream btpb.Bigtable_ReadRowsServer, r *row, f *btpb.RowFilter) (bool, error) { r.mu.Lock() nr := r.copy() r.mu.Unlock() r = nr match, err := filterRow(f, r) if err != nil { return false, err } if !match { return false, nil } rrr := &btpb.ReadRowsResponse{} families := r.sortedFamilies() for _, fam := range families { for _, colName := range fam.colNames { cells := fam.cells[colName] if len(cells) == 0 { continue } for _, cell := range cells { rrr.Chunks = append(rrr.Chunks, &btpb.ReadRowsResponse_CellChunk{ RowKey: []byte(r.key), FamilyName: &wrappers.StringValue{Value: fam.name}, Qualifier: &wrappers.BytesValue{Value: []byte(colName)}, TimestampMicros: cell.ts, Value: cell.value, Labels: cell.labels, }) } } } // We can't have a cell with just COMMIT set, which would imply a new empty cell. // So modify the last cell to have the COMMIT flag set. if len(rrr.Chunks) > 0 { rrr.Chunks[len(rrr.Chunks)-1].RowStatus = &btpb.ReadRowsResponse_CellChunk_CommitRow{CommitRow: true} } return true, stream.Send(rrr) } // filterRow modifies a row with the given filter. Returns true if at least one cell from the row matches, // false otherwise. If a filter is invalid, filterRow returns false and an error. func filterRow(f *btpb.RowFilter, r *row) (bool, error) { if f == nil { return true, nil } // Handle filters that apply beyond just including/excluding cells. switch f := f.Filter.(type) { case *btpb.RowFilter_BlockAllFilter: return !f.BlockAllFilter, nil case *btpb.RowFilter_PassAllFilter: return f.PassAllFilter, nil case *btpb.RowFilter_Chain_: for _, sub := range f.Chain.Filters { match, err := filterRow(sub, r) if err != nil { return false, err } if !match { return false, nil } } return true, nil case *btpb.RowFilter_Interleave_: srs := make([]*row, 0, len(f.Interleave.Filters)) for _, sub := range f.Interleave.Filters { sr := r.copy() match, err := filterRow(sub, sr) if err != nil { return false, err } if match { srs = append(srs, sr) } } // merge // TODO(dsymonds): is this correct? r.families = make(map[string]*family) for _, sr := range srs { for _, fam := range sr.families { f := r.getOrCreateFamily(fam.name, fam.order) for colName, cs := range fam.cells { f.cells[colName] = append(f.cellsByColumn(colName), cs...) } } } var count int for _, fam := range r.families { for _, cs := range fam.cells { sort.Sort(byDescTS(cs)) count += len(cs) } } return count > 0, nil case *btpb.RowFilter_CellsPerColumnLimitFilter: lim := int(f.CellsPerColumnLimitFilter) for _, fam := range r.families { for col, cs := range fam.cells { if len(cs) > lim { fam.cells[col] = cs[:lim] } } } return true, nil case *btpb.RowFilter_Condition_: match, err := filterRow(f.Condition.PredicateFilter, r.copy()) if err != nil { return false, err } if match { if f.Condition.TrueFilter == nil { return false, nil } return filterRow(f.Condition.TrueFilter, r) } if f.Condition.FalseFilter == nil { return false, nil } return filterRow(f.Condition.FalseFilter, r) case *btpb.RowFilter_RowKeyRegexFilter: rx, err := newRegexp(f.RowKeyRegexFilter) if err != nil { return false, status.Errorf(codes.InvalidArgument, "Error in field 'rowkey_regex_filter' : %v", err) } if !rx.MatchString(r.key) { return false, nil } case *btpb.RowFilter_CellsPerRowLimitFilter: // Grab the first n cells in the row. lim := int(f.CellsPerRowLimitFilter) for _, fam := range r.families { for _, col := range fam.colNames { cs := fam.cells[col] if len(cs) > lim { fam.cells[col] = cs[:lim] lim = 0 } else { lim -= len(cs) } } } return true, nil case *btpb.RowFilter_CellsPerRowOffsetFilter: // Skip the first n cells in the row. offset := int(f.CellsPerRowOffsetFilter) for _, fam := range r.families { for _, col := range fam.colNames { cs := fam.cells[col] if len(cs) > offset { fam.cells[col] = cs[offset:] offset = 0 return true, nil } fam.cells[col] = cs[:0] offset -= len(cs) } } return true, nil case *btpb.RowFilter_RowSampleFilter: // The row sample filter "matches all cells from a row with probability // p, and matches no cells from the row with probability 1-p." // See https://github.com/googleapis/googleapis/blob/master/google/bigtable/v2/data.proto if f.RowSampleFilter <= 0.0 || f.RowSampleFilter >= 1.0 { return false, status.Error(codes.InvalidArgument, "row_sample_filter argument must be between 0.0 and 1.0") } return randFloat() < f.RowSampleFilter, nil } // Any other case, operate on a per-cell basis. cellCount := 0 for _, fam := range r.families { for colName, cs := range fam.cells { filtered, err := filterCells(f, fam.name, colName, cs) if err != nil { return false, err } fam.cells[colName] = filtered cellCount += len(fam.cells[colName]) } } return cellCount > 0, nil } var randFloat = rand.Float64 func filterCells(f *btpb.RowFilter, fam, col string, cs []cell) ([]cell, error) { var ret []cell for _, cell := range cs { include, err := includeCell(f, fam, col, cell) if err != nil { return nil, err } if include { cell, err = modifyCell(f, cell) if err != nil { return nil, err } ret = append(ret, cell) } } return ret, nil } func modifyCell(f *btpb.RowFilter, c cell) (cell, error) { if f == nil { return c, nil } // Consider filters that may modify the cell contents switch filter := f.Filter.(type) { case *btpb.RowFilter_StripValueTransformer: return cell{ts: c.ts}, nil case *btpb.RowFilter_ApplyLabelTransformer: if !validLabelTransformer.MatchString(filter.ApplyLabelTransformer) { return cell{}, status.Errorf( codes.InvalidArgument, `apply_label_transformer must match RE2([a-z0-9\-]+), but found %v`, filter.ApplyLabelTransformer, ) } return cell{ts: c.ts, value: c.value, labels: []string{filter.ApplyLabelTransformer}}, nil default: return c, nil } } func includeCell(f *btpb.RowFilter, fam, col string, cell cell) (bool, error) { if f == nil { return true, nil } // TODO(dsymonds): Implement many more filters. switch f := f.Filter.(type) { case *btpb.RowFilter_CellsPerColumnLimitFilter: // Don't log, row-level filter return true, nil case *btpb.RowFilter_RowKeyRegexFilter: // Don't log, row-level filter return true, nil case *btpb.RowFilter_StripValueTransformer: // Don't log, cell-modifying filter return true, nil case *btpb.RowFilter_ApplyLabelTransformer: // Don't log, cell-modifying filter return true, nil default: log.Printf("WARNING: don't know how to handle filter of type %T (ignoring it)", f) return true, nil case *btpb.RowFilter_FamilyNameRegexFilter: rx, err := newRegexp([]byte(f.FamilyNameRegexFilter)) if err != nil { return false, status.Errorf(codes.InvalidArgument, "Error in field 'family_name_regex_filter' : %v", err) } return rx.MatchString(fam), nil case *btpb.RowFilter_ColumnQualifierRegexFilter: rx, err := newRegexp(f.ColumnQualifierRegexFilter) if err != nil { return false, status.Errorf(codes.InvalidArgument, "Error in field 'column_qualifier_regex_filter' : %v", err) } return rx.MatchString(col), nil case *btpb.RowFilter_ValueRegexFilter: rx, err := newRegexp(f.ValueRegexFilter) if err != nil { return false, status.Errorf(codes.InvalidArgument, "Error in field 'value_regex_filter' : %v", err) } return rx.Match(cell.value), nil case *btpb.RowFilter_ColumnRangeFilter: if fam != f.ColumnRangeFilter.FamilyName { return false, nil } // Start qualifier defaults to empty string closed inRangeStart := func() bool { return col >= "" } switch sq := f.ColumnRangeFilter.StartQualifier.(type) { case *btpb.ColumnRange_StartQualifierOpen: inRangeStart = func() bool { return col > string(sq.StartQualifierOpen) } case *btpb.ColumnRange_StartQualifierClosed: inRangeStart = func() bool { return col >= string(sq.StartQualifierClosed) } } // End qualifier defaults to no upper boundary inRangeEnd := func() bool { return true } switch eq := f.ColumnRangeFilter.EndQualifier.(type) { case *btpb.ColumnRange_EndQualifierClosed: inRangeEnd = func() bool { return col <= string(eq.EndQualifierClosed) } case *btpb.ColumnRange_EndQualifierOpen: inRangeEnd = func() bool { return col < string(eq.EndQualifierOpen) } } return inRangeStart() && inRangeEnd(), nil case *btpb.RowFilter_TimestampRangeFilter: // Lower bound is inclusive and defaults to 0, upper bound is exclusive and defaults to infinity. return cell.ts >= f.TimestampRangeFilter.StartTimestampMicros && (f.TimestampRangeFilter.EndTimestampMicros == 0 || cell.ts < f.TimestampRangeFilter.EndTimestampMicros), nil case *btpb.RowFilter_ValueRangeFilter: v := cell.value // Start value defaults to empty string closed inRangeStart := func() bool { return bytes.Compare(v, []byte{}) >= 0 } switch sv := f.ValueRangeFilter.StartValue.(type) { case *btpb.ValueRange_StartValueOpen: inRangeStart = func() bool { return bytes.Compare(v, sv.StartValueOpen) > 0 } case *btpb.ValueRange_StartValueClosed: inRangeStart = func() bool { return bytes.Compare(v, sv.StartValueClosed) >= 0 } } // End value defaults to no upper boundary inRangeEnd := func() bool { return true } switch ev := f.ValueRangeFilter.EndValue.(type) { case *btpb.ValueRange_EndValueClosed: inRangeEnd = func() bool { return bytes.Compare(v, ev.EndValueClosed) <= 0 } case *btpb.ValueRange_EndValueOpen: inRangeEnd = func() bool { return bytes.Compare(v, ev.EndValueOpen) < 0 } } return inRangeStart() && inRangeEnd(), nil } } func newRegexp(pat []byte) (*binaryregexp.Regexp, error) { re, err := binaryregexp.Compile("^(?:" + string(pat) + ")$") // match entire target if err != nil { log.Printf("Bad pattern %q: %v", pat, err) } return re, err } func (s *server) MutateRow(ctx context.Context, req *btpb.MutateRowRequest) (*btpb.MutateRowResponse, error) { s.mu.Lock() tbl, ok := s.tables[req.TableName] s.mu.Unlock() if !ok { return nil, status.Errorf(codes.NotFound, "table %q not found", req.TableName) } fs := tbl.columnFamilies() r := tbl.mutableRow(string(req.RowKey)) r.mu.Lock() defer r.mu.Unlock() if err := applyMutations(tbl, r, req.Mutations, fs); err != nil { return nil, err } return &btpb.MutateRowResponse{}, nil } func (s *server) MutateRows(req *btpb.MutateRowsRequest, stream btpb.Bigtable_MutateRowsServer) error { s.mu.Lock() tbl, ok := s.tables[req.TableName] s.mu.Unlock() if !ok { return status.Errorf(codes.NotFound, "table %q not found", req.TableName) } res := &btpb.MutateRowsResponse{Entries: make([]*btpb.MutateRowsResponse_Entry, len(req.Entries))} fs := tbl.columnFamilies() for i, entry := range req.Entries { r := tbl.mutableRow(string(entry.RowKey)) r.mu.Lock() code, msg := int32(codes.OK), "" if err := applyMutations(tbl, r, entry.Mutations, fs); err != nil { code = int32(codes.Internal) msg = err.Error() } res.Entries[i] = &btpb.MutateRowsResponse_Entry{ Index: int64(i), Status: &statpb.Status{Code: code, Message: msg}, } r.mu.Unlock() } return stream.Send(res) } func (s *server) CheckAndMutateRow(ctx context.Context, req *btpb.CheckAndMutateRowRequest) (*btpb.CheckAndMutateRowResponse, error) { s.mu.Lock() tbl, ok := s.tables[req.TableName] s.mu.Unlock() if !ok { return nil, status.Errorf(codes.NotFound, "table %q not found", req.TableName) } res := &btpb.CheckAndMutateRowResponse{} fs := tbl.columnFamilies() r := tbl.mutableRow(string(req.RowKey)) r.mu.Lock() defer r.mu.Unlock() // Figure out which mutation to apply. whichMut := false if req.PredicateFilter == nil { // Use true_mutations iff row contains any cells. whichMut = !r.isEmpty() } else { // Use true_mutations iff any cells in the row match the filter. // TODO(dsymonds): This could be cheaper. nr := r.copy() match, err := filterRow(req.PredicateFilter, nr) if err != nil { return nil, err } whichMut = match && !nr.isEmpty() } res.PredicateMatched = whichMut muts := req.FalseMutations if whichMut { muts = req.TrueMutations } if err := applyMutations(tbl, r, muts, fs); err != nil { return nil, err } return res, nil } // applyMutations applies a sequence of mutations to a row. // fam should be a snapshot of the keys of tbl.families. // It assumes r.mu is locked. func applyMutations(tbl *table, r *row, muts []*btpb.Mutation, fs map[string]*columnFamily) error { for _, mut := range muts { switch mut := mut.Mutation.(type) { default: return fmt.Errorf("can't handle mutation type %T", mut) case *btpb.Mutation_SetCell_: set := mut.SetCell if _, ok := fs[set.FamilyName]; !ok { return fmt.Errorf("unknown family %q", set.FamilyName) } ts := set.TimestampMicros if ts == -1 { // bigtable.ServerTime ts = newTimestamp() } if !tbl.validTimestamp(ts) { return fmt.Errorf("invalid timestamp %d", ts) } fam := set.FamilyName col := string(set.ColumnQualifier) newCell := cell{ts: ts, value: set.Value} f := r.getOrCreateFamily(fam, fs[fam].order) f.cells[col] = appendOrReplaceCell(f.cellsByColumn(col), newCell) case *btpb.Mutation_DeleteFromColumn_: del := mut.DeleteFromColumn if _, ok := fs[del.FamilyName]; !ok { return fmt.Errorf("unknown family %q", del.FamilyName) } fam := del.FamilyName col := string(del.ColumnQualifier) if _, ok := r.families[fam]; ok { cs := r.families[fam].cells[col] if del.TimeRange != nil { tsr := del.TimeRange if !tbl.validTimestamp(tsr.StartTimestampMicros) { return fmt.Errorf("invalid timestamp %d", tsr.StartTimestampMicros) } if !tbl.validTimestamp(tsr.EndTimestampMicros) && tsr.EndTimestampMicros != 0 { return fmt.Errorf("invalid timestamp %d", tsr.EndTimestampMicros) } if tsr.StartTimestampMicros >= tsr.EndTimestampMicros && tsr.EndTimestampMicros != 0 { return fmt.Errorf("inverted or invalid timestamp range [%d, %d]", tsr.StartTimestampMicros, tsr.EndTimestampMicros) } // Find half-open interval to remove. // Cells are in descending timestamp order, // so the predicates to sort.Search are inverted. si, ei := 0, len(cs) if tsr.StartTimestampMicros > 0 { ei = sort.Search(len(cs), func(i int) bool { return cs[i].ts < tsr.StartTimestampMicros }) } if tsr.EndTimestampMicros > 0 { si = sort.Search(len(cs), func(i int) bool { return cs[i].ts < tsr.EndTimestampMicros }) } if si < ei { copy(cs[si:], cs[ei:]) cs = cs[:len(cs)-(ei-si)] } } else { cs = nil } if len(cs) == 0 { delete(r.families[fam].cells, col) colNames := r.families[fam].colNames i := sort.Search(len(colNames), func(i int) bool { return colNames[i] >= col }) if i < len(colNames) && colNames[i] == col { r.families[fam].colNames = append(colNames[:i], colNames[i+1:]...) } if len(r.families[fam].cells) == 0 { delete(r.families, fam) } } else { r.families[fam].cells[col] = cs } } case *btpb.Mutation_DeleteFromRow_: r.families = make(map[string]*family) case *btpb.Mutation_DeleteFromFamily_: fampre := mut.DeleteFromFamily.FamilyName delete(r.families, fampre) } } return nil } func maxTimestamp(x, y int64) int64 { if x > y { return x } return y } func newTimestamp() int64 { ts := time.Now().UnixNano() / 1e3 ts -= ts % 1000 // round to millisecond granularity return ts } func appendOrReplaceCell(cs []cell, newCell cell) []cell { replaced := false for i, cell := range cs { if cell.ts == newCell.ts { cs[i] = newCell replaced = true break } } if !replaced { cs = append(cs, newCell) } sort.Sort(byDescTS(cs)) return cs } func (s *server) ReadModifyWriteRow(ctx context.Context, req *btpb.ReadModifyWriteRowRequest) (*btpb.ReadModifyWriteRowResponse, error) { s.mu.Lock() tbl, ok := s.tables[req.TableName] s.mu.Unlock() if !ok { return nil, status.Errorf(codes.NotFound, "table %q not found", req.TableName) } fs := tbl.columnFamilies() rowKey := string(req.RowKey) r := tbl.mutableRow(rowKey) resultRow := newRow(rowKey) // copy of updated cells // This must be done before the row lock, acquired below, is released. r.mu.Lock() defer r.mu.Unlock() // Assume all mutations apply to the most recent version of the cell. // TODO(dsymonds): Verify this assumption and document it in the proto. for _, rule := range req.Rules { if _, ok := fs[rule.FamilyName]; !ok { return nil, fmt.Errorf("unknown family %q", rule.FamilyName) } fam := rule.FamilyName col := string(rule.ColumnQualifier) isEmpty := false f := r.getOrCreateFamily(fam, fs[fam].order) cs := f.cells[col] isEmpty = len(cs) == 0 ts := newTimestamp() var newCell, prevCell cell if !isEmpty { cells := r.families[fam].cells[col] prevCell = cells[0] // ts is the max of now or the prev cell's timestamp in case the // prev cell is in the future ts = maxTimestamp(ts, prevCell.ts) } switch rule := rule.Rule.(type) { default: return nil, fmt.Errorf("unknown RMW rule oneof %T", rule) case *btpb.ReadModifyWriteRule_AppendValue: newCell = cell{ts: ts, value: append(prevCell.value, rule.AppendValue...)} case *btpb.ReadModifyWriteRule_IncrementAmount: var v int64 if !isEmpty { prevVal := prevCell.value if len(prevVal) != 8 { return nil, fmt.Errorf("increment on non-64-bit value") } v = int64(binary.BigEndian.Uint64(prevVal)) } v += rule.IncrementAmount var val [8]byte binary.BigEndian.PutUint64(val[:], uint64(v)) newCell = cell{ts: ts, value: val[:]} } // Store the new cell f.cells[col] = appendOrReplaceCell(f.cellsByColumn(col), newCell) // Store a copy for the result row resultFamily := resultRow.getOrCreateFamily(fam, fs[fam].order) resultFamily.cellsByColumn(col) // create the column resultFamily.cells[col] = []cell{newCell} // overwrite the cells } // Build the response using the result row res := &btpb.Row{ Key: req.RowKey, Families: make([]*btpb.Family, len(resultRow.families)), } for i, family := range resultRow.sortedFamilies() { res.Families[i] = &btpb.Family{ Name: family.name, Columns: make([]*btpb.Column, len(family.colNames)), } for j, colName := range family.colNames { res.Families[i].Columns[j] = &btpb.Column{ Qualifier: []byte(colName), Cells: []*btpb.Cell{{ TimestampMicros: family.cells[colName][0].ts, Value: family.cells[colName][0].value, }}, } } } return &btpb.ReadModifyWriteRowResponse{Row: res}, nil } func (s *server) SampleRowKeys(req *btpb.SampleRowKeysRequest, stream btpb.Bigtable_SampleRowKeysServer) error { s.mu.Lock() tbl, ok := s.tables[req.TableName] s.mu.Unlock() if !ok { return status.Errorf(codes.NotFound, "table %q not found", req.TableName) } tbl.mu.RLock() defer tbl.mu.RUnlock() // The return value of SampleRowKeys is very loosely defined. Return at least the // final row key in the table and choose other row keys randomly. var offset int64 var err error i := 0 tbl.rows.Ascend(func(it btree.Item) bool { row := it.(*row) if i == tbl.rows.Len()-1 || rand.Int31n(100) == 0 { resp := &btpb.SampleRowKeysResponse{ RowKey: []byte(row.key), OffsetBytes: offset, } err = stream.Send(resp) if err != nil { return false } } offset += int64(row.size()) i++ return true }) return err } // needGC is invoked whenever the server needs gcloop running. func (s *server) needGC() { s.mu.Lock() if s.gcc == nil { s.gcc = make(chan int) go s.gcloop(s.gcc) } s.mu.Unlock() } func (s *server) gcloop(done <-chan int) { const ( minWait = 500 // ms maxWait = 1500 // ms ) for { // Wait for a random time interval. d := time.Duration(minWait+rand.Intn(maxWait-minWait)) * time.Millisecond select { case <-time.After(d): case <-done: return // server has been closed } // Do a GC pass over all tables. var tables []*table s.mu.Lock() for _, tbl := range s.tables { tables = append(tables, tbl) } s.mu.Unlock() for _, tbl := range tables { tbl.gc() } } } type table struct { mu sync.RWMutex counter uint64 // increment by 1 when a new family is created families map[string]*columnFamily // keyed by plain family name rows *btree.BTree // indexed by row key } const btreeDegree = 16 func newTable(ctr *btapb.CreateTableRequest) *table { fams := make(map[string]*columnFamily) c := uint64(0) if ctr.Table != nil { for id, cf := range ctr.Table.ColumnFamilies { fams[id] = &columnFamily{ name: ctr.Parent + "/columnFamilies/" + id, order: c, gcRule: cf.GcRule, } c++ } } return &table{ families: fams, counter: c, rows: btree.New(btreeDegree), } } func (t *table) validTimestamp(ts int64) bool { if ts < minValidMilliSeconds || ts > maxValidMilliSeconds { return false } // Assume millisecond granularity is required. return ts%1000 == 0 } func (t *table) columnFamilies() map[string]*columnFamily { cp := make(map[string]*columnFamily) t.mu.RLock() for fam, cf := range t.families { cp[fam] = cf } t.mu.RUnlock() return cp } func (t *table) mutableRow(key string) *row { bkey := btreeKey(key) // Try fast path first. t.mu.RLock() i := t.rows.Get(bkey) t.mu.RUnlock() if i != nil { return i.(*row) } // We probably need to create the row. t.mu.Lock() defer t.mu.Unlock() i = t.rows.Get(bkey) if i != nil { return i.(*row) } r := newRow(key) t.rows.ReplaceOrInsert(r) return r } func (t *table) gc() { // This method doesn't add or remove rows, so we only need a read lock for the table. t.mu.RLock() defer t.mu.RUnlock() // Gather GC rules we'll apply. rules := make(map[string]*btapb.GcRule) // keyed by "fam" for fam, cf := range t.families { if cf.gcRule != nil { rules[fam] = cf.gcRule } } if len(rules) == 0 { return } t.rows.Ascend(func(i btree.Item) bool { r := i.(*row) r.mu.Lock() r.gc(rules) r.mu.Unlock() return true }) } type byRowKey []*row func (b byRowKey) Len() int { return len(b) } func (b byRowKey) Swap(i, j int) { b[i], b[j] = b[j], b[i] } func (b byRowKey) Less(i, j int) bool { return b[i].key < b[j].key } type row struct { key string mu sync.Mutex families map[string]*family // keyed by family name } func newRow(key string) *row { return &row{ key: key, families: make(map[string]*family), } } // copy returns a copy of the row. // Cell values are aliased. // r.mu should be held. func (r *row) copy() *row { nr := newRow(r.key) for _, fam := range r.families { nr.families[fam.name] = &family{ name: fam.name, order: fam.order, colNames: fam.colNames, cells: make(map[string][]cell), } for col, cs := range fam.cells { // Copy the []cell slice, but not the []byte inside each cell. nr.families[fam.name].cells[col] = append([]cell(nil), cs...) } } return nr } // isEmpty returns true if a row doesn't contain any cell func (r *row) isEmpty() bool { for _, fam := range r.families { for _, cs := range fam.cells { if len(cs) > 0 { return false } } } return true } // sortedFamilies returns a column family set // sorted in ascending creation order in a row. func (r *row) sortedFamilies() []*family { var families []*family for _, fam := range r.families { families = append(families, fam) } sort.Sort(byCreationOrder(families)) return families } func (r *row) getOrCreateFamily(name string, order uint64) *family { if _, ok := r.families[name]; !ok { r.families[name] = &family{ name: name, order: order, cells: make(map[string][]cell), } } return r.families[name] } // gc applies the given GC rules to the row. // r.mu should be held. func (r *row) gc(rules map[string]*btapb.GcRule) { for _, fam := range r.families { rule, ok := rules[fam.name] if !ok { continue } for col, cs := range fam.cells { r.families[fam.name].cells[col] = applyGC(cs, rule) } } } // size returns the total size of all cell values in the row. func (r *row) size() int { size := 0 for _, fam := range r.families { for _, cells := range fam.cells { for _, cell := range cells { size += len(cell.value) } } } return size } // Less implements btree.Less. func (r *row) Less(i btree.Item) bool { return r.key < i.(*row).key } // btreeKey returns a row for use as a key into the BTree. func btreeKey(s string) *row { return &row{key: s} } func (r *row) String() string { return r.key } var gcTypeWarn sync.Once // applyGC applies the given GC rule to the cells. func applyGC(cells []cell, rule *btapb.GcRule) []cell { switch rule := rule.Rule.(type) { default: // TODO(dsymonds): Support GcRule_Intersection_ gcTypeWarn.Do(func() { log.Printf("Unsupported GC rule type %T", rule) }) case *btapb.GcRule_Union_: for _, sub := range rule.Union.Rules { cells = applyGC(cells, sub) } return cells case *btapb.GcRule_MaxAge: // Timestamps are in microseconds. cutoff := time.Now().UnixNano() / 1e3 cutoff -= rule.MaxAge.Seconds * 1e6 cutoff -= int64(rule.MaxAge.Nanos) / 1e3 // The slice of cells in in descending timestamp order. // This sort.Search will return the index of the first cell whose timestamp is chronologically before the cutoff. si := sort.Search(len(cells), func(i int) bool { return cells[i].ts < cutoff }) if si < len(cells) { log.Printf("bttest: GC MaxAge(%v) deleted %d cells.", rule.MaxAge, len(cells)-si) } return cells[:si] case *btapb.GcRule_MaxNumVersions: n := int(rule.MaxNumVersions) if len(cells) > n { cells = cells[:n] } return cells } return cells } type family struct { name string // Column family name order uint64 // Creation order of column family colNames []string // Column names are sorted in lexicographical ascending order cells map[string][]cell // Keyed by column name; cells are in descending timestamp order } type byCreationOrder []*family func (b byCreationOrder) Len() int { return len(b) } func (b byCreationOrder) Swap(i, j int) { b[i], b[j] = b[j], b[i] } func (b byCreationOrder) Less(i, j int) bool { return b[i].order < b[j].order } // cellsByColumn adds the column name to colNames set if it does not exist // and returns all cells within a column func (f *family) cellsByColumn(name string) []cell { if _, ok := f.cells[name]; !ok { f.colNames = append(f.colNames, name) sort.Strings(f.colNames) } return f.cells[name] } type cell struct { ts int64 value []byte labels []string } type byDescTS []cell func (b byDescTS) Len() int { return len(b) } func (b byDescTS) Swap(i, j int) { b[i], b[j] = b[j], b[i] } func (b byDescTS) Less(i, j int) bool { return b[i].ts > b[j].ts } type columnFamily struct { name string order uint64 // Creation order of column family gcRule *btapb.GcRule } func (c *columnFamily) proto() *btapb.ColumnFamily { return &btapb.ColumnFamily{ GcRule: c.gcRule, } } func toColumnFamilies(families map[string]*columnFamily) map[string]*btapb.ColumnFamily { fs := make(map[string]*btapb.ColumnFamily) for k, v := range families { fs[k] = v.proto() } return fs } google-cloud-go-0.49.0/bigtable/bttest/inmem_test.go000066400000000000000000001371661356504100700223570ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bttest import ( "bytes" "context" "fmt" "math/rand" "sort" "strconv" "sync" "sync/atomic" "testing" "time" "cloud.google.com/go/internal/testutil" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes/wrappers" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" btapb "google.golang.org/genproto/googleapis/bigtable/admin/v2" btpb "google.golang.org/genproto/googleapis/bigtable/v2" "google.golang.org/grpc" ) func TestConcurrentMutationsReadModifyAndGC(t *testing.T) { s := &server{ tables: make(map[string]*table), } ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond) defer cancel() if _, err := s.CreateTable( ctx, &btapb.CreateTableRequest{Parent: "cluster", TableId: "t"}); err != nil { t.Fatal(err) } const name = `cluster/tables/t` tbl := s.tables[name] req := &btapb.ModifyColumnFamiliesRequest{ Name: name, Modifications: []*btapb.ModifyColumnFamiliesRequest_Modification{{ Id: "cf", Mod: &btapb.ModifyColumnFamiliesRequest_Modification_Create{Create: &btapb.ColumnFamily{}}, }}, } _, err := s.ModifyColumnFamilies(ctx, req) if err != nil { t.Fatal(err) } req = &btapb.ModifyColumnFamiliesRequest{ Name: name, Modifications: []*btapb.ModifyColumnFamiliesRequest_Modification{{ Id: "cf", Mod: &btapb.ModifyColumnFamiliesRequest_Modification_Update{Update: &btapb.ColumnFamily{ GcRule: &btapb.GcRule{Rule: &btapb.GcRule_MaxNumVersions{MaxNumVersions: 1}}, }}, }}, } if _, err := s.ModifyColumnFamilies(ctx, req); err != nil { t.Fatal(err) } var wg sync.WaitGroup var ts int64 ms := func() []*btpb.Mutation { return []*btpb.Mutation{{ Mutation: &btpb.Mutation_SetCell_{SetCell: &btpb.Mutation_SetCell{ FamilyName: "cf", ColumnQualifier: []byte(`col`), TimestampMicros: atomic.AddInt64(&ts, 1000), }}, }} } rmw := func() *btpb.ReadModifyWriteRowRequest { return &btpb.ReadModifyWriteRowRequest{ TableName: name, RowKey: []byte(fmt.Sprint(rand.Intn(100))), Rules: []*btpb.ReadModifyWriteRule{{ FamilyName: "cf", ColumnQualifier: []byte("col"), Rule: &btpb.ReadModifyWriteRule_IncrementAmount{IncrementAmount: 1}, }}, } } for i := 0; i < 100; i++ { wg.Add(1) go func() { defer wg.Done() for ctx.Err() == nil { req := &btpb.MutateRowRequest{ TableName: name, RowKey: []byte(fmt.Sprint(rand.Intn(100))), Mutations: ms(), } if _, err := s.MutateRow(ctx, req); err != nil { panic(err) // can't use t.Fatal in goroutine } } }() wg.Add(1) go func() { defer wg.Done() for ctx.Err() == nil { _, _ = s.ReadModifyWriteRow(ctx, rmw()) } }() wg.Add(1) go func() { defer wg.Done() tbl.gc() }() } done := make(chan struct{}) go func() { wg.Wait() close(done) }() select { case <-done: case <-time.After(1 * time.Second): t.Error("Concurrent mutations and GCs haven't completed after 1s") } } func TestCreateTableResponse(t *testing.T) { // We need to ensure that invoking CreateTable returns // the ColumnFamilies as well as Granularity. // See issue https://github.com/googleapis/google-cloud-go/issues/1512. s := &server{ tables: make(map[string]*table), } ctx := context.Background() got, err := s.CreateTable(ctx, &btapb.CreateTableRequest{ Parent: "projects/issue-1512/instances/instance", TableId: "table", Table: &btapb.Table{ ColumnFamilies: map[string]*btapb.ColumnFamily{ "cf1": {GcRule: &btapb.GcRule{Rule: &btapb.GcRule_MaxNumVersions{MaxNumVersions: 123}}}, "cf2": {GcRule: &btapb.GcRule{Rule: &btapb.GcRule_MaxNumVersions{MaxNumVersions: 456}}}, }, }, }) if err != nil { t.Fatalf("Creating table: %v", err) } want := &btapb.Table{ Name: "projects/issue-1512/instances/instance/tables/table", // If no Granularity was specified, we should get back "MILLIS". Granularity: btapb.Table_MILLIS, ColumnFamilies: map[string]*btapb.ColumnFamily{ "cf1": {GcRule: &btapb.GcRule{Rule: &btapb.GcRule_MaxNumVersions{MaxNumVersions: 123}}}, "cf2": {GcRule: &btapb.GcRule{Rule: &btapb.GcRule_MaxNumVersions{MaxNumVersions: 456}}}, }, } if diff := testutil.Diff(got, want); diff != "" { t.Fatalf("Response mismatch: got - want +\n%s", diff) } } func TestCreateTableWithFamily(t *testing.T) { // The Go client currently doesn't support creating a table with column families // in one operation but it is allowed by the API. This must still be supported by the // fake server so this test lives here instead of in the main bigtable // integration test. s := &server{ tables: make(map[string]*table), } ctx := context.Background() newTbl := btapb.Table{ ColumnFamilies: map[string]*btapb.ColumnFamily{ "cf1": {GcRule: &btapb.GcRule{Rule: &btapb.GcRule_MaxNumVersions{MaxNumVersions: 123}}}, "cf2": {GcRule: &btapb.GcRule{Rule: &btapb.GcRule_MaxNumVersions{MaxNumVersions: 456}}}, }, } cTbl, err := s.CreateTable(ctx, &btapb.CreateTableRequest{Parent: "cluster", TableId: "t", Table: &newTbl}) if err != nil { t.Fatalf("Creating table: %v", err) } tbl, err := s.GetTable(ctx, &btapb.GetTableRequest{Name: cTbl.Name}) if err != nil { t.Fatalf("Getting table: %v", err) } cf := tbl.ColumnFamilies["cf1"] if cf == nil { t.Fatalf("Missing col family cf1") } if got, want := cf.GcRule.GetMaxNumVersions(), int32(123); got != want { t.Errorf("Invalid MaxNumVersions: wanted:%d, got:%d", want, got) } cf = tbl.ColumnFamilies["cf2"] if cf == nil { t.Fatalf("Missing col family cf2") } if got, want := cf.GcRule.GetMaxNumVersions(), int32(456); got != want { t.Errorf("Invalid MaxNumVersions: wanted:%d, got:%d", want, got) } } type MockSampleRowKeysServer struct { responses []*btpb.SampleRowKeysResponse grpc.ServerStream } func (s *MockSampleRowKeysServer) Send(resp *btpb.SampleRowKeysResponse) error { s.responses = append(s.responses, resp) return nil } func TestSampleRowKeys(t *testing.T) { s := &server{ tables: make(map[string]*table), } ctx := context.Background() newTbl := btapb.Table{ ColumnFamilies: map[string]*btapb.ColumnFamily{ "cf": {GcRule: &btapb.GcRule{Rule: &btapb.GcRule_MaxNumVersions{MaxNumVersions: 1}}}, }, } tbl, err := s.CreateTable(ctx, &btapb.CreateTableRequest{Parent: "cluster", TableId: "t", Table: &newTbl}) if err != nil { t.Fatalf("Creating table: %v", err) } // Populate the table val := []byte("value") rowCount := 1000 for i := 0; i < rowCount; i++ { req := &btpb.MutateRowRequest{ TableName: tbl.Name, RowKey: []byte("row-" + strconv.Itoa(i)), Mutations: []*btpb.Mutation{{ Mutation: &btpb.Mutation_SetCell_{SetCell: &btpb.Mutation_SetCell{ FamilyName: "cf", ColumnQualifier: []byte("col"), TimestampMicros: 1000, Value: val, }}, }}, } if _, err := s.MutateRow(ctx, req); err != nil { t.Fatalf("Populating table: %v", err) } } mock := &MockSampleRowKeysServer{} if err := s.SampleRowKeys(&btpb.SampleRowKeysRequest{TableName: tbl.Name}, mock); err != nil { t.Errorf("SampleRowKeys error: %v", err) } if len(mock.responses) == 0 { t.Fatal("Response count: got 0, want > 0") } // Make sure the offset of the final response is the offset of the final row got := mock.responses[len(mock.responses)-1].OffsetBytes want := int64((rowCount - 1) * len(val)) if got != want { t.Errorf("Invalid offset: got %d, want %d", got, want) } } func TestDropRowRange(t *testing.T) { s := &server{ tables: make(map[string]*table), } ctx := context.Background() newTbl := btapb.Table{ ColumnFamilies: map[string]*btapb.ColumnFamily{ "cf": {GcRule: &btapb.GcRule{Rule: &btapb.GcRule_MaxNumVersions{MaxNumVersions: 1}}}, }, } tblInfo, err := s.CreateTable(ctx, &btapb.CreateTableRequest{Parent: "cluster", TableId: "t", Table: &newTbl}) if err != nil { t.Fatalf("Creating table: %v", err) } tbl := s.tables[tblInfo.Name] // Populate the table prefixes := []string{"AAA", "BBB", "CCC", "DDD"} count := 3 doWrite := func() { for _, prefix := range prefixes { for i := 0; i < count; i++ { req := &btpb.MutateRowRequest{ TableName: tblInfo.Name, RowKey: []byte(prefix + strconv.Itoa(i)), Mutations: []*btpb.Mutation{{ Mutation: &btpb.Mutation_SetCell_{SetCell: &btpb.Mutation_SetCell{ FamilyName: "cf", ColumnQualifier: []byte("col"), TimestampMicros: 1000, Value: []byte{}, }}, }}, } if _, err := s.MutateRow(ctx, req); err != nil { t.Fatalf("Populating table: %v", err) } } } } doWrite() tblSize := tbl.rows.Len() req := &btapb.DropRowRangeRequest{ Name: tblInfo.Name, Target: &btapb.DropRowRangeRequest_RowKeyPrefix{RowKeyPrefix: []byte("AAA")}, } if _, err = s.DropRowRange(ctx, req); err != nil { t.Fatalf("Dropping first range: %v", err) } got, want := tbl.rows.Len(), tblSize-count if got != want { t.Errorf("Row count after first drop: got %d (%v), want %d", got, tbl.rows, want) } req = &btapb.DropRowRangeRequest{ Name: tblInfo.Name, Target: &btapb.DropRowRangeRequest_RowKeyPrefix{RowKeyPrefix: []byte("DDD")}, } if _, err = s.DropRowRange(ctx, req); err != nil { t.Fatalf("Dropping second range: %v", err) } got, want = tbl.rows.Len(), tblSize-(2*count) if got != want { t.Errorf("Row count after second drop: got %d (%v), want %d", got, tbl.rows, want) } req = &btapb.DropRowRangeRequest{ Name: tblInfo.Name, Target: &btapb.DropRowRangeRequest_RowKeyPrefix{RowKeyPrefix: []byte("XXX")}, } if _, err = s.DropRowRange(ctx, req); err != nil { t.Fatalf("Dropping invalid range: %v", err) } got, want = tbl.rows.Len(), tblSize-(2*count) if got != want { t.Errorf("Row count after invalid drop: got %d (%v), want %d", got, tbl.rows, want) } req = &btapb.DropRowRangeRequest{ Name: tblInfo.Name, Target: &btapb.DropRowRangeRequest_DeleteAllDataFromTable{DeleteAllDataFromTable: true}, } if _, err = s.DropRowRange(ctx, req); err != nil { t.Fatalf("Dropping all data: %v", err) } got, want = tbl.rows.Len(), 0 if got != want { t.Errorf("Row count after drop all: got %d, want %d", got, want) } // Test that we can write rows, delete some and then write them again. count = 1 doWrite() req = &btapb.DropRowRangeRequest{ Name: tblInfo.Name, Target: &btapb.DropRowRangeRequest_DeleteAllDataFromTable{DeleteAllDataFromTable: true}, } if _, err = s.DropRowRange(ctx, req); err != nil { t.Fatalf("Dropping all data: %v", err) } got, want = tbl.rows.Len(), 0 if got != want { t.Errorf("Row count after drop all: got %d, want %d", got, want) } doWrite() got, want = tbl.rows.Len(), len(prefixes) if got != want { t.Errorf("Row count after rewrite: got %d, want %d", got, want) } req = &btapb.DropRowRangeRequest{ Name: tblInfo.Name, Target: &btapb.DropRowRangeRequest_RowKeyPrefix{RowKeyPrefix: []byte("BBB")}, } if _, err = s.DropRowRange(ctx, req); err != nil { t.Fatalf("Dropping range: %v", err) } doWrite() got, want = tbl.rows.Len(), len(prefixes) if got != want { t.Errorf("Row count after drop range: got %d, want %d", got, want) } } type MockReadRowsServer struct { responses []*btpb.ReadRowsResponse grpc.ServerStream } func (s *MockReadRowsServer) Send(resp *btpb.ReadRowsResponse) error { s.responses = append(s.responses, resp) return nil } func TestReadRows(t *testing.T) { ctx := context.Background() s := &server{ tables: make(map[string]*table), } newTbl := btapb.Table{ ColumnFamilies: map[string]*btapb.ColumnFamily{ "cf0": {GcRule: &btapb.GcRule{Rule: &btapb.GcRule_MaxNumVersions{MaxNumVersions: 1}}}, }, } tblInfo, err := s.CreateTable(ctx, &btapb.CreateTableRequest{Parent: "cluster", TableId: "t", Table: &newTbl}) if err != nil { t.Fatalf("Creating table: %v", err) } mreq := &btpb.MutateRowRequest{ TableName: tblInfo.Name, RowKey: []byte("row"), Mutations: []*btpb.Mutation{{ Mutation: &btpb.Mutation_SetCell_{SetCell: &btpb.Mutation_SetCell{ FamilyName: "cf0", ColumnQualifier: []byte("col"), TimestampMicros: 1000, Value: []byte{}, }}, }}, } if _, err := s.MutateRow(ctx, mreq); err != nil { t.Fatalf("Populating table: %v", err) } for _, rowset := range []*btpb.RowSet{ {RowKeys: [][]byte{[]byte("row")}}, {RowRanges: []*btpb.RowRange{{StartKey: &btpb.RowRange_StartKeyClosed{StartKeyClosed: []byte("")}}}}, {RowRanges: []*btpb.RowRange{{StartKey: &btpb.RowRange_StartKeyClosed{StartKeyClosed: []byte("r")}}}}, {RowRanges: []*btpb.RowRange{{ StartKey: &btpb.RowRange_StartKeyClosed{StartKeyClosed: []byte("")}, EndKey: &btpb.RowRange_EndKeyOpen{EndKeyOpen: []byte("s")}, }}}, } { mock := &MockReadRowsServer{} req := &btpb.ReadRowsRequest{TableName: tblInfo.Name, Rows: rowset} if err = s.ReadRows(req, mock); err != nil { t.Fatalf("ReadRows error: %v", err) } if got, want := len(mock.responses), 1; got != want { t.Errorf("%+v: response count: got %d, want %d", rowset, got, want) } } } func TestReadRowsError(t *testing.T) { ctx := context.Background() s := &server{ tables: make(map[string]*table), } newTbl := btapb.Table{ ColumnFamilies: map[string]*btapb.ColumnFamily{ "cf0": {GcRule: &btapb.GcRule{Rule: &btapb.GcRule_MaxNumVersions{MaxNumVersions: 1}}}, }, } tblInfo, err := s.CreateTable(ctx, &btapb.CreateTableRequest{Parent: "cluster", TableId: "t", Table: &newTbl}) if err != nil { t.Fatalf("Creating table: %v", err) } mreq := &btpb.MutateRowRequest{ TableName: tblInfo.Name, RowKey: []byte("row"), Mutations: []*btpb.Mutation{{ Mutation: &btpb.Mutation_SetCell_{SetCell: &btpb.Mutation_SetCell{ FamilyName: "cf0", ColumnQualifier: []byte("col"), TimestampMicros: 1000, Value: []byte{}, }}, }}, } if _, err := s.MutateRow(ctx, mreq); err != nil { t.Fatalf("Populating table: %v", err) } mock := &MockReadRowsServer{} req := &btpb.ReadRowsRequest{TableName: tblInfo.Name, Filter: &btpb.RowFilter{ Filter: &btpb.RowFilter_RowKeyRegexFilter{RowKeyRegexFilter: []byte("[")}}, // Invalid regex. } if err = s.ReadRows(req, mock); err == nil { t.Fatal("ReadRows got no error, want error") } } func TestReadRowsAfterDeletion(t *testing.T) { ctx := context.Background() s := &server{ tables: make(map[string]*table), } newTbl := btapb.Table{ ColumnFamilies: map[string]*btapb.ColumnFamily{ "cf0": {}, }, } tblInfo, err := s.CreateTable(ctx, &btapb.CreateTableRequest{ Parent: "cluster", TableId: "t", Table: &newTbl, }) if err != nil { t.Fatalf("Creating table: %v", err) } populateTable(ctx, s) dreq := &btpb.MutateRowRequest{ TableName: tblInfo.Name, RowKey: []byte("row"), Mutations: []*btpb.Mutation{{ Mutation: &btpb.Mutation_DeleteFromRow_{ DeleteFromRow: &btpb.Mutation_DeleteFromRow{}, }, }}, } if _, err := s.MutateRow(ctx, dreq); err != nil { t.Fatalf("Deleting from table: %v", err) } mock := &MockReadRowsServer{} req := &btpb.ReadRowsRequest{TableName: tblInfo.Name} if err = s.ReadRows(req, mock); err != nil { t.Fatalf("ReadRows error: %v", err) } if got, want := len(mock.responses), 0; got != want { t.Errorf("response count: got %d, want %d", got, want) } } func TestReadRowsOrder(t *testing.T) { s := &server{ tables: make(map[string]*table), } ctx := context.Background() newTbl := btapb.Table{ ColumnFamilies: map[string]*btapb.ColumnFamily{ "cf0": {GcRule: &btapb.GcRule{Rule: &btapb.GcRule_MaxNumVersions{MaxNumVersions: 1}}}, }, } tblInfo, err := s.CreateTable(ctx, &btapb.CreateTableRequest{Parent: "cluster", TableId: "t", Table: &newTbl}) if err != nil { t.Fatalf("Creating table: %v", err) } count := 3 mcf := func(i int) *btapb.ModifyColumnFamiliesRequest { return &btapb.ModifyColumnFamiliesRequest{ Name: tblInfo.Name, Modifications: []*btapb.ModifyColumnFamiliesRequest_Modification{{ Id: "cf" + strconv.Itoa(i), Mod: &btapb.ModifyColumnFamiliesRequest_Modification_Create{Create: &btapb.ColumnFamily{}}, }}, } } for i := 1; i <= count; i++ { _, err = s.ModifyColumnFamilies(ctx, mcf(i)) if err != nil { t.Fatal(err) } } // Populate the table for fc := 0; fc < count; fc++ { for cc := count; cc > 0; cc-- { for tc := 0; tc < count; tc++ { req := &btpb.MutateRowRequest{ TableName: tblInfo.Name, RowKey: []byte("row"), Mutations: []*btpb.Mutation{{ Mutation: &btpb.Mutation_SetCell_{SetCell: &btpb.Mutation_SetCell{ FamilyName: "cf" + strconv.Itoa(fc), ColumnQualifier: []byte("col" + strconv.Itoa(cc)), TimestampMicros: int64((tc + 1) * 1000), Value: []byte{}, }}, }}, } if _, err := s.MutateRow(ctx, req); err != nil { t.Fatalf("Populating table: %v", err) } } } } req := &btpb.ReadRowsRequest{ TableName: tblInfo.Name, Rows: &btpb.RowSet{RowKeys: [][]byte{[]byte("row")}}, } mock := &MockReadRowsServer{} if err = s.ReadRows(req, mock); err != nil { t.Errorf("ReadRows error: %v", err) } if len(mock.responses) == 0 { t.Fatal("Response count: got 0, want > 0") } if len(mock.responses[0].Chunks) != 27 { t.Fatalf("Chunk count: got %d, want 27", len(mock.responses[0].Chunks)) } testOrder := func(ms *MockReadRowsServer) { var prevFam, prevCol string var prevTime int64 for _, cc := range ms.responses[0].Chunks { if prevFam == "" { prevFam = cc.FamilyName.Value prevCol = string(cc.Qualifier.Value) prevTime = cc.TimestampMicros continue } if cc.FamilyName.Value < prevFam { t.Errorf("Family order is not correct: got %s < %s", cc.FamilyName.Value, prevFam) } else if cc.FamilyName.Value == prevFam { if string(cc.Qualifier.Value) < prevCol { t.Errorf("Column order is not correct: got %s < %s", string(cc.Qualifier.Value), prevCol) } else if string(cc.Qualifier.Value) == prevCol { if cc.TimestampMicros > prevTime { t.Errorf("cell order is not correct: got %d > %d", cc.TimestampMicros, prevTime) } } } prevFam = cc.FamilyName.Value prevCol = string(cc.Qualifier.Value) prevTime = cc.TimestampMicros } } testOrder(mock) // Read with interleave filter inter := &btpb.RowFilter_Interleave{} fnr := &btpb.RowFilter{Filter: &btpb.RowFilter_FamilyNameRegexFilter{FamilyNameRegexFilter: "cf1"}} cqr := &btpb.RowFilter{Filter: &btpb.RowFilter_ColumnQualifierRegexFilter{ColumnQualifierRegexFilter: []byte("col2")}} inter.Filters = append(inter.Filters, fnr, cqr) req = &btpb.ReadRowsRequest{ TableName: tblInfo.Name, Rows: &btpb.RowSet{RowKeys: [][]byte{[]byte("row")}}, Filter: &btpb.RowFilter{ Filter: &btpb.RowFilter_Interleave_{Interleave: inter}, }, } mock = &MockReadRowsServer{} if err = s.ReadRows(req, mock); err != nil { t.Errorf("ReadRows error: %v", err) } if len(mock.responses) == 0 { t.Fatal("Response count: got 0, want > 0") } if len(mock.responses[0].Chunks) != 18 { t.Fatalf("Chunk count: got %d, want 18", len(mock.responses[0].Chunks)) } testOrder(mock) // Check order after ReadModifyWriteRow rmw := func(i int) *btpb.ReadModifyWriteRowRequest { return &btpb.ReadModifyWriteRowRequest{ TableName: tblInfo.Name, RowKey: []byte("row"), Rules: []*btpb.ReadModifyWriteRule{{ FamilyName: "cf3", ColumnQualifier: []byte("col" + strconv.Itoa(i)), Rule: &btpb.ReadModifyWriteRule_IncrementAmount{IncrementAmount: 1}, }}, } } for i := count; i > 0; i-- { if _, err := s.ReadModifyWriteRow(ctx, rmw(i)); err != nil { t.Fatal(err) } } req = &btpb.ReadRowsRequest{ TableName: tblInfo.Name, Rows: &btpb.RowSet{RowKeys: [][]byte{[]byte("row")}}, } mock = &MockReadRowsServer{} if err = s.ReadRows(req, mock); err != nil { t.Errorf("ReadRows error: %v", err) } if len(mock.responses) == 0 { t.Fatal("Response count: got 0, want > 0") } if len(mock.responses[0].Chunks) != 30 { t.Fatalf("Chunk count: got %d, want 30", len(mock.responses[0].Chunks)) } testOrder(mock) } func TestReadRowsWithlabelTransformer(t *testing.T) { ctx := context.Background() s := &server{ tables: make(map[string]*table), } newTbl := btapb.Table{ ColumnFamilies: map[string]*btapb.ColumnFamily{ "cf0": {GcRule: &btapb.GcRule{Rule: &btapb.GcRule_MaxNumVersions{MaxNumVersions: 1}}}, }, } tblInfo, err := s.CreateTable(ctx, &btapb.CreateTableRequest{Parent: "cluster", TableId: "t", Table: &newTbl}) if err != nil { t.Fatalf("Creating table: %v", err) } mreq := &btpb.MutateRowRequest{ TableName: tblInfo.Name, RowKey: []byte("row"), Mutations: []*btpb.Mutation{{ Mutation: &btpb.Mutation_SetCell_{SetCell: &btpb.Mutation_SetCell{ FamilyName: "cf0", ColumnQualifier: []byte("col"), TimestampMicros: 1000, Value: []byte{}, }}, }}, } if _, err := s.MutateRow(ctx, mreq); err != nil { t.Fatalf("Populating table: %v", err) } mock := &MockReadRowsServer{} req := &btpb.ReadRowsRequest{ TableName: tblInfo.Name, Filter: &btpb.RowFilter{ Filter: &btpb.RowFilter_ApplyLabelTransformer{ ApplyLabelTransformer: "label", }, }, } if err = s.ReadRows(req, mock); err != nil { t.Fatalf("ReadRows error: %v", err) } if got, want := len(mock.responses), 1; got != want { t.Fatalf("response count: got %d, want %d", got, want) } resp := mock.responses[0] if got, want := len(resp.Chunks), 1; got != want { t.Fatalf("chunks count: got %d, want %d", got, want) } chunk := resp.Chunks[0] if got, want := len(chunk.Labels), 1; got != want { t.Fatalf("labels count: got %d, want %d", got, want) } if got, want := chunk.Labels[0], "label"; got != want { t.Fatalf("label: got %s, want %s", got, want) } mock = &MockReadRowsServer{} req = &btpb.ReadRowsRequest{ TableName: tblInfo.Name, Filter: &btpb.RowFilter{ Filter: &btpb.RowFilter_ApplyLabelTransformer{ ApplyLabelTransformer: "", // invalid label }, }, } if err = s.ReadRows(req, mock); err == nil { t.Fatal("ReadRows want invalid label error, got none") } } func TestCheckAndMutateRowWithoutPredicate(t *testing.T) { s := &server{ tables: make(map[string]*table), } ctx := context.Background() newTbl := btapb.Table{ ColumnFamilies: map[string]*btapb.ColumnFamily{ "cf": {GcRule: &btapb.GcRule{Rule: &btapb.GcRule_MaxNumVersions{MaxNumVersions: 1}}}, }, } tbl, err := s.CreateTable(ctx, &btapb.CreateTableRequest{Parent: "cluster", TableId: "t", Table: &newTbl}) if err != nil { t.Fatalf("Creating table: %v", err) } // Populate the table val := []byte("value") mrreq := &btpb.MutateRowRequest{ TableName: tbl.Name, RowKey: []byte("row-present"), Mutations: []*btpb.Mutation{{ Mutation: &btpb.Mutation_SetCell_{SetCell: &btpb.Mutation_SetCell{ FamilyName: "cf", ColumnQualifier: []byte("col"), TimestampMicros: 1000, Value: val, }}, }}, } if _, err := s.MutateRow(ctx, mrreq); err != nil { t.Fatalf("Populating table: %v", err) } req := &btpb.CheckAndMutateRowRequest{ TableName: tbl.Name, RowKey: []byte("row-not-present"), } if res, err := s.CheckAndMutateRow(ctx, req); err != nil { t.Errorf("CheckAndMutateRow error: %v", err) } else if got, want := res.PredicateMatched, false; got != want { t.Errorf("Invalid PredicateMatched value: got %t, want %t", got, want) } req = &btpb.CheckAndMutateRowRequest{ TableName: tbl.Name, RowKey: []byte("row-present"), } if res, err := s.CheckAndMutateRow(ctx, req); err != nil { t.Errorf("CheckAndMutateRow error: %v", err) } else if got, want := res.PredicateMatched, true; got != want { t.Errorf("Invalid PredicateMatched value: got %t, want %t", got, want) } } func TestCheckAndMutateRowWithPredicate(t *testing.T) { ctx := context.Background() srv := &server{tables: make(map[string]*table)} tblReq := &btapb.CreateTableRequest{ Parent: "issue-1435", TableId: "table_id", Table: &btapb.Table{ ColumnFamilies: map[string]*btapb.ColumnFamily{ "cf": {}, "df": {}, "ef": {}, "ff": {}, "zf": {}, }, }, } tbl, err := srv.CreateTable(ctx, tblReq) if err != nil { t.Fatalf("Failed to create the table: %v", err) } entries := []struct { row string value []byte familyName, columnQualifier string }{ {"row1", []byte{0x11}, "cf", "cq"}, {"row2", []byte{0x1a}, "df", "dq"}, {"row3", []byte{'a'}, "ef", "eq"}, {"row4", []byte{'b'}, "ff", "fq"}, } for _, entry := range entries { req := &btpb.MutateRowRequest{ TableName: tbl.Name, RowKey: []byte(entry.row), Mutations: []*btpb.Mutation{{ Mutation: &btpb.Mutation_SetCell_{SetCell: &btpb.Mutation_SetCell{ FamilyName: entry.familyName, ColumnQualifier: []byte(entry.columnQualifier), TimestampMicros: 1000, Value: entry.value, }}, }}, } if _, err := srv.MutateRow(ctx, req); err != nil { t.Fatalf("Failed to insert entry %v into server: %v", entry, err) } } tests := []struct { req *btpb.CheckAndMutateRowRequest wantMatch bool name string // if wantState is nil, that means we don't care to check // what the state of the world is. wantState []*btpb.ReadRowsResponse_CellChunk }{ { req: &btpb.CheckAndMutateRowRequest{ TableName: tbl.Name, PredicateFilter: &btpb.RowFilter{ Filter: &btpb.RowFilter_RowKeyRegexFilter{ RowKeyRegexFilter: []byte("not-one"), }, }, }, name: "no match", }, { req: &btpb.CheckAndMutateRowRequest{ TableName: tbl.Name, RowKey: []byte("row1"), PredicateFilter: &btpb.RowFilter{ Filter: &btpb.RowFilter_RowKeyRegexFilter{ RowKeyRegexFilter: []byte("ro.+"), }, }, }, wantMatch: true, name: "rowkey regex", }, { req: &btpb.CheckAndMutateRowRequest{ TableName: tbl.Name, RowKey: []byte("row1"), PredicateFilter: &btpb.RowFilter{ Filter: &btpb.RowFilter_PassAllFilter{ PassAllFilter: true, }, }, }, wantMatch: true, name: "pass all", }, { req: &btpb.CheckAndMutateRowRequest{ TableName: tbl.Name, RowKey: []byte("row1"), PredicateFilter: &btpb.RowFilter{ Filter: &btpb.RowFilter_BlockAllFilter{ BlockAllFilter: true, }, }, FalseMutations: []*btpb.Mutation{ { Mutation: &btpb.Mutation_SetCell_{ SetCell: &btpb.Mutation_SetCell{ FamilyName: "zf", Value: []byte("foo"), TimestampMicros: 2000, ColumnQualifier: []byte("et"), }, }, }, }, }, name: "BlockAll for row1", wantMatch: false, wantState: []*btpb.ReadRowsResponse_CellChunk{ { RowKey: []byte("row1"), FamilyName: &wrappers.StringValue{ Value: "cf", }, Qualifier: &wrappers.BytesValue{ Value: []byte("cq"), }, TimestampMicros: 1000, Value: []byte{0x11}, }, { RowKey: []byte("row1"), FamilyName: &wrappers.StringValue{ Value: "zf", }, Qualifier: &wrappers.BytesValue{ Value: []byte("et"), }, TimestampMicros: 2000, Value: []byte("foo"), RowStatus: &btpb.ReadRowsResponse_CellChunk_CommitRow{ CommitRow: true, }, }, { RowKey: []byte("row2"), FamilyName: &wrappers.StringValue{ Value: "df", }, Qualifier: &wrappers.BytesValue{ Value: []byte("dq"), }, TimestampMicros: 1000, Value: []byte{0x1a}, RowStatus: &btpb.ReadRowsResponse_CellChunk_CommitRow{ CommitRow: true, }, }, { RowKey: []byte("row3"), FamilyName: &wrappers.StringValue{ Value: "ef", }, Qualifier: &wrappers.BytesValue{ Value: []byte("eq"), }, TimestampMicros: 1000, Value: []byte("a"), RowStatus: &btpb.ReadRowsResponse_CellChunk_CommitRow{ CommitRow: true, }, }, { RowKey: []byte("row4"), FamilyName: &wrappers.StringValue{ Value: "ff", }, Qualifier: &wrappers.BytesValue{ Value: []byte("fq"), }, TimestampMicros: 1000, Value: []byte("b"), RowStatus: &btpb.ReadRowsResponse_CellChunk_CommitRow{ CommitRow: true, }, }, }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { res, err := srv.CheckAndMutateRow(ctx, tt.req) if err != nil { t.Fatalf("CheckAndMutateRow error: %v", err) } got, want := res.PredicateMatched, tt.wantMatch if got != want { t.Fatalf("Invalid PredicateMatched value: got %t, want %t\nRequest: %+v", got, want, tt.req) } if tt.wantState == nil { return } rreq := &btpb.ReadRowsRequest{TableName: tbl.Name} mock := &MockReadRowsServer{} if err = srv.ReadRows(rreq, mock); err != nil { t.Fatalf("ReadRows error: %v", err) } // Collect all the cellChunks var gotCellChunks []*btpb.ReadRowsResponse_CellChunk for _, res := range mock.responses { gotCellChunks = append(gotCellChunks, res.Chunks...) } sort.Slice(gotCellChunks, func(i, j int) bool { ci, cj := gotCellChunks[i], gotCellChunks[j] return compareCellChunks(ci, cj) }) wantCellChunks := tt.wantState[0:] sort.Slice(wantCellChunks, func(i, j int) bool { return compareCellChunks(wantCellChunks[i], wantCellChunks[j]) }) // bttest for some reason undeterministically returns: // RowStatus: &bigtable.ReadRowsResponse_CellChunk_CommitRow{CommitRow: true}, // so we'll ignore that field during comparison. ignore := cmpopts.IgnoreFields(btpb.ReadRowsResponse_CellChunk{}, "RowStatus") diff := cmp.Diff(gotCellChunks, wantCellChunks, ignore) if diff != "" { t.Fatalf("unexpected response: %s", diff) } }) } } // compareCellChunks is a comparator that is passed // into sort.Slice to stably sort cell chunks. func compareCellChunks(ci, cj *btpb.ReadRowsResponse_CellChunk) bool { if bytes.Compare(ci.RowKey, cj.RowKey) > 0 { return false } if bytes.Compare(ci.Value, cj.Value) > 0 { return false } return ci.FamilyName.GetValue() < cj.FamilyName.GetValue() } func TestServer_ReadModifyWriteRow(t *testing.T) { s := &server{ tables: make(map[string]*table), } ctx := context.Background() newTbl := btapb.Table{ ColumnFamilies: map[string]*btapb.ColumnFamily{ "cf": {GcRule: &btapb.GcRule{Rule: &btapb.GcRule_MaxNumVersions{MaxNumVersions: 1}}}, }, } tbl, err := s.CreateTable(ctx, &btapb.CreateTableRequest{Parent: "cluster", TableId: "t", Table: &newTbl}) if err != nil { t.Fatalf("Creating table: %v", err) } req := &btpb.ReadModifyWriteRowRequest{ TableName: tbl.Name, RowKey: []byte("row-key"), Rules: []*btpb.ReadModifyWriteRule{ { FamilyName: "cf", ColumnQualifier: []byte("q1"), Rule: &btpb.ReadModifyWriteRule_AppendValue{ AppendValue: []byte("a"), }, }, // multiple ops for same cell { FamilyName: "cf", ColumnQualifier: []byte("q1"), Rule: &btpb.ReadModifyWriteRule_AppendValue{ AppendValue: []byte("b"), }, }, // different cell whose qualifier should sort before the prior rules { FamilyName: "cf", ColumnQualifier: []byte("q0"), Rule: &btpb.ReadModifyWriteRule_IncrementAmount{ IncrementAmount: 1, }, }, }, } got, err := s.ReadModifyWriteRow(ctx, req) if err != nil { t.Fatalf("ReadModifyWriteRow error: %v", err) } want := &btpb.ReadModifyWriteRowResponse{ Row: &btpb.Row{ Key: []byte("row-key"), Families: []*btpb.Family{{ Name: "cf", Columns: []*btpb.Column{ { Qualifier: []byte("q0"), Cells: []*btpb.Cell{{ Value: []byte{0, 0, 0, 0, 0, 0, 0, 1}, }}, }, { Qualifier: []byte("q1"), Cells: []*btpb.Cell{{ Value: []byte("ab"), }}, }, }, }}, }, } diff := cmp.Diff(got, want, cmpopts.IgnoreFields(btpb.Cell{}, "TimestampMicros")) if diff != "" { t.Errorf("unexpected response: %s", diff) } } // helper function to populate table data func populateTable(ctx context.Context, s *server) (*btapb.Table, error) { newTbl := btapb.Table{ ColumnFamilies: map[string]*btapb.ColumnFamily{ "cf0": {GcRule: &btapb.GcRule{Rule: &btapb.GcRule_MaxNumVersions{1}}}, }, } tblInfo, err := s.CreateTable(ctx, &btapb.CreateTableRequest{Parent: "cluster", TableId: "t", Table: &newTbl}) if err != nil { return nil, err } count := 3 mcf := func(i int) *btapb.ModifyColumnFamiliesRequest { return &btapb.ModifyColumnFamiliesRequest{ Name: tblInfo.Name, Modifications: []*btapb.ModifyColumnFamiliesRequest_Modification{{ Id: "cf" + strconv.Itoa(i), Mod: &btapb.ModifyColumnFamiliesRequest_Modification_Create{&btapb.ColumnFamily{}}, }}, } } for i := 1; i <= count; i++ { _, err = s.ModifyColumnFamilies(ctx, mcf(i)) if err != nil { return nil, err } } // Populate the table for fc := 0; fc < count; fc++ { for cc := count; cc > 0; cc-- { for tc := 0; tc < count; tc++ { req := &btpb.MutateRowRequest{ TableName: tblInfo.Name, RowKey: []byte("row"), Mutations: []*btpb.Mutation{{ Mutation: &btpb.Mutation_SetCell_{&btpb.Mutation_SetCell{ FamilyName: "cf" + strconv.Itoa(fc), ColumnQualifier: []byte("col" + strconv.Itoa(cc)), TimestampMicros: int64((tc + 1) * 1000), Value: []byte{}, }}, }}, } if _, err := s.MutateRow(ctx, req); err != nil { return nil, err } } } } return tblInfo, nil } func TestFilters(t *testing.T) { tests := []struct { in *btpb.RowFilter out int }{ {in: &btpb.RowFilter{Filter: &btpb.RowFilter_BlockAllFilter{true}}, out: 0}, {in: &btpb.RowFilter{Filter: &btpb.RowFilter_BlockAllFilter{false}}, out: 1}, {in: &btpb.RowFilter{Filter: &btpb.RowFilter_PassAllFilter{true}}, out: 1}, {in: &btpb.RowFilter{Filter: &btpb.RowFilter_PassAllFilter{false}}, out: 0}, } ctx := context.Background() s := &server{ tables: make(map[string]*table), } tblInfo, err := populateTable(ctx, s) if err != nil { t.Fatal(err) } req := &btpb.ReadRowsRequest{ TableName: tblInfo.Name, Rows: &btpb.RowSet{RowKeys: [][]byte{[]byte("row")}}, } for _, tc := range tests { req.Filter = tc.in mock := &MockReadRowsServer{} if err = s.ReadRows(req, mock); err != nil { t.Errorf("ReadRows error: %v", err) continue } if len(mock.responses) != tc.out { t.Errorf("Response count: got %d, want %d", len(mock.responses), tc.out) continue } } } func Test_Mutation_DeleteFromColumn(t *testing.T) { ctx := context.Background() s := &server{ tables: make(map[string]*table), } tblInfo, err := populateTable(ctx, s) if err != nil { t.Fatal(err) } tests := []struct { in *btpb.MutateRowRequest fail bool }{ { in: &btpb.MutateRowRequest{ TableName: tblInfo.Name, RowKey: []byte("row"), Mutations: []*btpb.Mutation{{ Mutation: &btpb.Mutation_DeleteFromColumn_{DeleteFromColumn: &btpb.Mutation_DeleteFromColumn{ FamilyName: "cf1", ColumnQualifier: []byte("col1"), TimeRange: &btpb.TimestampRange{ StartTimestampMicros: 2000, EndTimestampMicros: 1000, }, }}, }}, }, fail: true, }, { in: &btpb.MutateRowRequest{ TableName: tblInfo.Name, RowKey: []byte("row"), Mutations: []*btpb.Mutation{{ Mutation: &btpb.Mutation_DeleteFromColumn_{DeleteFromColumn: &btpb.Mutation_DeleteFromColumn{ FamilyName: "cf2", ColumnQualifier: []byte("col2"), TimeRange: &btpb.TimestampRange{ StartTimestampMicros: 1000, EndTimestampMicros: 2000, }, }}, }}, }, fail: false, }, { in: &btpb.MutateRowRequest{ TableName: tblInfo.Name, RowKey: []byte("row"), Mutations: []*btpb.Mutation{{ Mutation: &btpb.Mutation_DeleteFromColumn_{DeleteFromColumn: &btpb.Mutation_DeleteFromColumn{ FamilyName: "cf3", ColumnQualifier: []byte("col3"), TimeRange: &btpb.TimestampRange{ StartTimestampMicros: 1000, EndTimestampMicros: 0, }, }}, }}, }, fail: false, }, { in: &btpb.MutateRowRequest{ TableName: tblInfo.Name, RowKey: []byte("row"), Mutations: []*btpb.Mutation{{ Mutation: &btpb.Mutation_DeleteFromColumn_{DeleteFromColumn: &btpb.Mutation_DeleteFromColumn{ FamilyName: "cf4", ColumnQualifier: []byte("col4"), TimeRange: &btpb.TimestampRange{ StartTimestampMicros: 0, EndTimestampMicros: 1000, }, }}, }}, }, fail: true, }, } for _, test := range tests { _, err = s.MutateRow(ctx, test.in) if err != nil && !test.fail { t.Errorf("expected passed got failure for : %v \n with err: %v", test.in, err) } if err == nil && test.fail { t.Errorf("expected failure got passed for : %v", test) } } } func TestFilterRow(t *testing.T) { row := &row{ key: "row", families: map[string]*family{ "fam": { name: "fam", cells: map[string][]cell{ "col": {{ts: 100, value: []byte("val")}}, }, }, }, } for _, test := range []struct { filter *btpb.RowFilter want bool }{ // The regexp-based filters perform whole-string, case-sensitive matches. {&btpb.RowFilter{Filter: &btpb.RowFilter_RowKeyRegexFilter{[]byte("row")}}, true}, {&btpb.RowFilter{Filter: &btpb.RowFilter_RowKeyRegexFilter{[]byte("ro")}}, false}, {&btpb.RowFilter{Filter: &btpb.RowFilter_RowKeyRegexFilter{[]byte("ROW")}}, false}, {&btpb.RowFilter{Filter: &btpb.RowFilter_RowKeyRegexFilter{[]byte("moo")}}, false}, {&btpb.RowFilter{Filter: &btpb.RowFilter_FamilyNameRegexFilter{"fam"}}, true}, {&btpb.RowFilter{Filter: &btpb.RowFilter_FamilyNameRegexFilter{"f.*"}}, true}, {&btpb.RowFilter{Filter: &btpb.RowFilter_FamilyNameRegexFilter{"[fam]+"}}, true}, {&btpb.RowFilter{Filter: &btpb.RowFilter_FamilyNameRegexFilter{"fa"}}, false}, {&btpb.RowFilter{Filter: &btpb.RowFilter_FamilyNameRegexFilter{"FAM"}}, false}, {&btpb.RowFilter{Filter: &btpb.RowFilter_FamilyNameRegexFilter{"moo"}}, false}, {&btpb.RowFilter{Filter: &btpb.RowFilter_ColumnQualifierRegexFilter{[]byte("col")}}, true}, {&btpb.RowFilter{Filter: &btpb.RowFilter_ColumnQualifierRegexFilter{[]byte("co")}}, false}, {&btpb.RowFilter{Filter: &btpb.RowFilter_ColumnQualifierRegexFilter{[]byte("COL")}}, false}, {&btpb.RowFilter{Filter: &btpb.RowFilter_ColumnQualifierRegexFilter{[]byte("moo")}}, false}, {&btpb.RowFilter{Filter: &btpb.RowFilter_ValueRegexFilter{[]byte("val")}}, true}, {&btpb.RowFilter{Filter: &btpb.RowFilter_ValueRegexFilter{[]byte("va")}}, false}, {&btpb.RowFilter{Filter: &btpb.RowFilter_ValueRegexFilter{[]byte("VAL")}}, false}, {&btpb.RowFilter{Filter: &btpb.RowFilter_ValueRegexFilter{[]byte("moo")}}, false}, } { got, _ := filterRow(test.filter, row.copy()) if got != test.want { t.Errorf("%s: got %t, want %t", proto.CompactTextString(test.filter), got, test.want) } } } func TestFilterRowWithErrors(t *testing.T) { row := &row{ key: "row", families: map[string]*family{ "fam": { name: "fam", cells: map[string][]cell{ "col": {{ts: 100, value: []byte("val")}}, }, }, }, } for _, test := range []struct { badRegex *btpb.RowFilter }{ {&btpb.RowFilter{Filter: &btpb.RowFilter_RowKeyRegexFilter{[]byte("[")}}}, {&btpb.RowFilter{Filter: &btpb.RowFilter_FamilyNameRegexFilter{"["}}}, {&btpb.RowFilter{Filter: &btpb.RowFilter_ColumnQualifierRegexFilter{[]byte("[")}}}, {&btpb.RowFilter{Filter: &btpb.RowFilter_ValueRegexFilter{[]byte("[")}}}, {&btpb.RowFilter{Filter: &btpb.RowFilter_Chain_{ Chain: &btpb.RowFilter_Chain{Filters: []*btpb.RowFilter{ {Filter: &btpb.RowFilter_ValueRegexFilter{[]byte("[")}}}, }, }}}, {&btpb.RowFilter{Filter: &btpb.RowFilter_Condition_{ Condition: &btpb.RowFilter_Condition{ PredicateFilter: &btpb.RowFilter{Filter: &btpb.RowFilter_ValueRegexFilter{[]byte("[")}}, }, }}}, {&btpb.RowFilter{Filter: &btpb.RowFilter_RowSampleFilter{0.0}}}, // 0.0 is invalid. {&btpb.RowFilter{Filter: &btpb.RowFilter_RowSampleFilter{1.0}}}, // 1.0 is invalid. } { got, err := filterRow(test.badRegex, row.copy()) if got != false { t.Errorf("%s: got true, want false", proto.CompactTextString(test.badRegex)) } if err == nil { t.Errorf("%s: got no error, want error", proto.CompactTextString(test.badRegex)) } } } func TestFilterRowWithRowSampleFilter(t *testing.T) { prev := randFloat randFloat = func() float64 { return 0.5 } defer func() { randFloat = prev }() for _, test := range []struct { p float64 want bool }{ {0.1, false}, // Less than random float. Return no rows. {0.5, false}, // Equal to random float. Return no rows. {0.9, true}, // Greater than random float. Return all rows. } { got, err := filterRow(&btpb.RowFilter{Filter: &btpb.RowFilter_RowSampleFilter{test.p}}, &row{}) if err != nil { t.Fatalf("%f: %v", test.p, err) } if got != test.want { t.Errorf("%v: got %t, want %t", test.p, got, test.want) } } } func TestFilterRowWithBinaryColumnQualifier(t *testing.T) { rs := []byte{128, 128} row := &row{ key: string(rs), families: map[string]*family{ "fam": { name: "fam", cells: map[string][]cell{ string(rs): {{ts: 100, value: []byte("val")}}, }, }, }, } for _, test := range []struct { filter string want bool }{ {`\x80\x80`, true}, // succeeds, exact match {`\x80\x81`, false}, // fails {`\x80`, false}, // fails, because the regexp must match the entire input {`\x80*`, true}, // succeeds: 0 or more 128s {`[\x7f\x80]{2}`, true}, // succeeds: exactly two of either 127 or 128 {`\C{2}`, true}, // succeeds: two bytes } { got, _ := filterRow(&btpb.RowFilter{Filter: &btpb.RowFilter_ColumnQualifierRegexFilter{[]byte(test.filter)}}, row.copy()) if got != test.want { t.Errorf("%v: got %t, want %t", test.filter, got, test.want) } } } // Test that a single column qualifier with the interleave filter returns // the correct result and not return every single row. // See Issue https://github.com/googleapis/google-cloud-go/issues/1399 func TestFilterRowWithSingleColumnQualifier(t *testing.T) { ctx := context.Background() srv := &server{tables: make(map[string]*table)} tblReq := &btapb.CreateTableRequest{ Parent: "issue-1399", TableId: "table_id", Table: &btapb.Table{ ColumnFamilies: map[string]*btapb.ColumnFamily{ "cf": {}, }, }, } tbl, err := srv.CreateTable(ctx, tblReq) if err != nil { t.Fatalf("Failed to create the table: %v", err) } entries := []struct { row string value []byte }{ {"row1", []byte{0x11}}, {"row2", []byte{0x1a}}, {"row3", []byte{'a'}}, {"row4", []byte{'b'}}, } for _, entry := range entries { req := &btpb.MutateRowRequest{ TableName: tbl.Name, RowKey: []byte(entry.row), Mutations: []*btpb.Mutation{{ Mutation: &btpb.Mutation_SetCell_{SetCell: &btpb.Mutation_SetCell{ FamilyName: "cf", ColumnQualifier: []byte("cq"), TimestampMicros: 1000, Value: entry.value, }}, }}, } if _, err := srv.MutateRow(ctx, req); err != nil { t.Fatalf("Failed to insert entry %v into server: %v", entry, err) } } // After insertion now it is time for querying. req := &btpb.ReadRowsRequest{ TableName: tbl.Name, Filter: &btpb.RowFilter{Filter: &btpb.RowFilter_Chain_{ Chain: &btpb.RowFilter_Chain{Filters: []*btpb.RowFilter{{ Filter: &btpb.RowFilter_Interleave_{ Interleave: &btpb.RowFilter_Interleave{ Filters: []*btpb.RowFilter{{Filter: &btpb.RowFilter_Condition_{ Condition: &btpb.RowFilter_Condition{ PredicateFilter: &btpb.RowFilter{Filter: &btpb.RowFilter_Chain_{ Chain: &btpb.RowFilter_Chain{Filters: []*btpb.RowFilter{ { Filter: &btpb.RowFilter_ValueRangeFilter{ValueRangeFilter: &btpb.ValueRange{ StartValue: &btpb.ValueRange_StartValueClosed{ StartValueClosed: []byte("a"), }, EndValue: &btpb.ValueRange_EndValueClosed{EndValueClosed: []byte("a")}, }}, }, }}, }}, TrueFilter: &btpb.RowFilter{Filter: &btpb.RowFilter_PassAllFilter{PassAllFilter: true}}, }, }}}, }, }, }}}, }}, } rrss := new(MockReadRowsServer) if err := srv.ReadRows(req, rrss); err != nil { t.Fatalf("Failed to read rows: %v", err) } if g, w := len(rrss.responses), 1; g != w { t.Fatalf("Results/Streamed chunks mismatch:: got %d want %d", g, w) } got := rrss.responses[0] // Only row3 should be matched. want := &btpb.ReadRowsResponse{ Chunks: []*btpb.ReadRowsResponse_CellChunk{ { RowKey: []byte("row3"), FamilyName: &wrappers.StringValue{Value: "cf"}, Qualifier: &wrappers.BytesValue{Value: []byte("cq")}, TimestampMicros: 1000, Value: []byte("a"), RowStatus: &btpb.ReadRowsResponse_CellChunk_CommitRow{ CommitRow: true, }, }, }, } if diff := cmp.Diff(got, want); diff != "" { t.Fatalf("Response mismatch: got: + want -\n%s", diff) } } func TestValueFilterRowWithAlternationInRegex(t *testing.T) { // Test that regex alternation is applied properly. // See Issue https://github.com/googleapis/google-cloud-go/issues/1499 ctx := context.Background() srv := &server{tables: make(map[string]*table)} tblReq := &btapb.CreateTableRequest{ Parent: "issue-1499", TableId: "table_id", Table: &btapb.Table{ ColumnFamilies: map[string]*btapb.ColumnFamily{ "cf": {}, }, }, } tbl, err := srv.CreateTable(ctx, tblReq) if err != nil { t.Fatalf("Failed to create the table: %v", err) } entries := []struct { row string value []byte }{ {"row1", []byte("")}, {"row2", []byte{'x'}}, {"row3", []byte{'a'}}, {"row4", []byte{'m'}}, } for _, entry := range entries { req := &btpb.MutateRowRequest{ TableName: tbl.Name, RowKey: []byte(entry.row), Mutations: []*btpb.Mutation{{ Mutation: &btpb.Mutation_SetCell_{SetCell: &btpb.Mutation_SetCell{ FamilyName: "cf", ColumnQualifier: []byte("cq"), TimestampMicros: 1000, Value: entry.value, }}, }}, } if _, err := srv.MutateRow(ctx, req); err != nil { t.Fatalf("Failed to insert entry %v into server: %v", entry, err) } } // After insertion now it is time for querying. req := &btpb.ReadRowsRequest{ TableName: tbl.Name, Rows: &btpb.RowSet{}, Filter: &btpb.RowFilter{ Filter: &btpb.RowFilter_ValueRegexFilter{ ValueRegexFilter: []byte("|a"), }, }, } rrss := new(MockReadRowsServer) if err := srv.ReadRows(req, rrss); err != nil { t.Fatalf("Failed to read rows: %v", err) } var gotChunks []*btpb.ReadRowsResponse_CellChunk for _, res := range rrss.responses { gotChunks = append(gotChunks, res.Chunks...) } // Only row1 "" and row3 "a" should be matched. wantChunks := []*btpb.ReadRowsResponse_CellChunk{ { RowKey: []byte("row1"), FamilyName: &wrappers.StringValue{Value: "cf"}, Qualifier: &wrappers.BytesValue{Value: []byte("cq")}, TimestampMicros: 1000, Value: []byte(""), RowStatus: &btpb.ReadRowsResponse_CellChunk_CommitRow{ CommitRow: true, }, }, { RowKey: []byte("row3"), FamilyName: &wrappers.StringValue{Value: "cf"}, Qualifier: &wrappers.BytesValue{Value: []byte("cq")}, TimestampMicros: 1000, Value: []byte("a"), RowStatus: &btpb.ReadRowsResponse_CellChunk_CommitRow{ CommitRow: true, }, }, } if diff := cmp.Diff(gotChunks, wantChunks); diff != "" { t.Fatalf("Response chunks mismatch: got: + want -\n%s", diff) } } google-cloud-go-0.49.0/bigtable/bttest/instance_server.go000066400000000000000000000112171356504100700233710ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bttest import ( "context" "regexp" "github.com/golang/protobuf/ptypes/empty" btapb "google.golang.org/genproto/googleapis/bigtable/admin/v2" iampb "google.golang.org/genproto/googleapis/iam/v1" "google.golang.org/genproto/googleapis/longrunning" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) var _ btapb.BigtableInstanceAdminServer = (*server)(nil) var errUnimplemented = status.Error(codes.Unimplemented, "unimplemented feature") func (s *server) CreateInstance(ctx context.Context, req *btapb.CreateInstanceRequest) (*longrunning.Operation, error) { return nil, errUnimplemented } func (s *server) GetInstance(ctx context.Context, req *btapb.GetInstanceRequest) (*btapb.Instance, error) { return nil, errUnimplemented } func (s *server) ListInstances(ctx context.Context, req *btapb.ListInstancesRequest) (*btapb.ListInstancesResponse, error) { return nil, errUnimplemented } func (s *server) UpdateInstance(ctx context.Context, req *btapb.Instance) (*btapb.Instance, error) { return nil, errUnimplemented } func (s *server) PartialUpdateInstance(ctx context.Context, req *btapb.PartialUpdateInstanceRequest) (*longrunning.Operation, error) { return nil, errUnimplemented } var ( // As per https://godoc.org/google.golang.org/genproto/googleapis/bigtable/admin/v2#DeleteInstanceRequest.Name // the Name should be of the form: // `projects//instances/` instanceNameRegRaw = `^projects/[a-z][a-z0-9\\-]+[a-z0-9]/instances/[a-z][a-z0-9\\-]+[a-z0-9]$` regInstanceName = regexp.MustCompile(instanceNameRegRaw) ) func (s *server) DeleteInstance(ctx context.Context, req *btapb.DeleteInstanceRequest) (*empty.Empty, error) { name := req.GetName() if !regInstanceName.Match([]byte(name)) { return nil, status.Errorf(codes.InvalidArgument, "Error in field 'instance_name' : Invalid name for collection instances : Should match %s but found '%s'", instanceNameRegRaw, name) } s.mu.Lock() defer s.mu.Unlock() _, ok := s.instances[name] if !ok { return nil, status.Errorf(codes.NotFound, "instance %q not found", name) } // Then finally remove the instance. delete(s.instances, name) return new(empty.Empty), nil } func (s *server) CreateCluster(ctx context.Context, req *btapb.CreateClusterRequest) (*longrunning.Operation, error) { return nil, errUnimplemented } func (s *server) GetCluster(ctx context.Context, req *btapb.GetClusterRequest) (*btapb.Cluster, error) { return nil, errUnimplemented } func (s *server) ListClusters(ctx context.Context, req *btapb.ListClustersRequest) (*btapb.ListClustersResponse, error) { return nil, errUnimplemented } func (s *server) UpdateCluster(ctx context.Context, req *btapb.Cluster) (*longrunning.Operation, error) { return nil, errUnimplemented } func (s *server) DeleteCluster(ctx context.Context, req *btapb.DeleteClusterRequest) (*empty.Empty, error) { return nil, errUnimplemented } func (s *server) CreateAppProfile(ctx context.Context, req *btapb.CreateAppProfileRequest) (*btapb.AppProfile, error) { return nil, errUnimplemented } func (s *server) GetAppProfile(ctx context.Context, req *btapb.GetAppProfileRequest) (*btapb.AppProfile, error) { return nil, errUnimplemented } func (s *server) ListAppProfiles(ctx context.Context, req *btapb.ListAppProfilesRequest) (*btapb.ListAppProfilesResponse, error) { return nil, errUnimplemented } func (s *server) UpdateAppProfile(ctx context.Context, req *btapb.UpdateAppProfileRequest) (*longrunning.Operation, error) { return nil, errUnimplemented } func (s *server) DeleteAppProfile(ctx context.Context, req *btapb.DeleteAppProfileRequest) (*empty.Empty, error) { return nil, errUnimplemented } func (s *server) GetIamPolicy(ctx context.Context, req *iampb.GetIamPolicyRequest) (*iampb.Policy, error) { return nil, errUnimplemented } func (s *server) SetIamPolicy(ctx context.Context, req *iampb.SetIamPolicyRequest) (*iampb.Policy, error) { return nil, errUnimplemented } func (s *server) TestIamPermissions(ctx context.Context, req *iampb.TestIamPermissionsRequest) (*iampb.TestIamPermissionsResponse, error) { return nil, errUnimplemented } google-cloud-go-0.49.0/bigtable/bttest/instance_server_test.go000066400000000000000000000056561356504100700244420ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bttest import ( "context" "testing" btapb "google.golang.org/genproto/googleapis/bigtable/admin/v2" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) func TestDeleteInstance(t *testing.T) { srv := &server{ instances: map[string]*btapb.Instance{ "projects/test/instances/a1042-instance": { Name: "projects/test/instances/a1042-instance/test1", DisplayName: "test1", State: btapb.Instance_READY, Labels: map[string]string{ "component": "ingest", "cost-center": "sales", }, }, }, } ctx := context.Background() // 1. Deletion of a just created instance should succeed. delReq := &btapb.DeleteInstanceRequest{Name: "projects/test/instances/a1042-instance"} if _, err := srv.DeleteInstance(ctx, delReq); err != nil { t.Fatalf("Unexpected failed to delete the newly created instance: %v", err) } // 2. Deleting a now non-existent instance should fail. _, err := srv.DeleteInstance(ctx, delReq) if err == nil { t.Fatal("Expected an error from deleting a non-existent instance") } gstatus, _ := status.FromError(err) if g, w := gstatus.Code(), codes.NotFound; g != w { t.Errorf("Mismatched status code\ngot %d %s\nwant %d %s", g, g, w, w) } if g, w := gstatus.Message(), `instance "projects/test/instances/a1042-instance" not found`; g != w { t.Errorf("Mismatched status message\ngot %q\nwant %q", g, w) } // 3. Now test deletion with invalid names which should always fail. invalidNames := []string{ "", " ", "//", "/", "projects/foo", "projects/foo/instances", "projects/foo/instances/", "projects/foo/instances/a10/bar", "projects/foo/instances/a10/bar/fizz", "/projects/foo*", } for _, invalidName := range invalidNames { req := &btapb.DeleteInstanceRequest{Name: invalidName} _, err := srv.DeleteInstance(ctx, req) gstatus, _ := status.FromError(err) if g, w := gstatus.Code(), codes.InvalidArgument; g != w { t.Errorf("Mismatched status code\ngot %d %s\nwant %d %s", g, g, w, w) } wantMsg := "Error in field 'instance_name' : Invalid name for collection instances : " + "Should match " + `^projects/[a-z][a-z0-9\\-]+[a-z0-9]/instances/[a-z][a-z0-9\\-]+[a-z0-9]$` + " but found '" + invalidName + "'" if g, w := gstatus.Message(), wantMsg; g != w { t.Errorf("%q: mismatched status message\ngot %q\nwant %q\n\n", invalidName, g, w) } } } google-cloud-go-0.49.0/bigtable/bttest/validation.go000066400000000000000000000054071356504100700223350ustar00rootroot00000000000000/* Copyright 2019 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package bttest import ( "bytes" btpb "google.golang.org/genproto/googleapis/bigtable/v2" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) // validateRowRanges returns a status.Error for req if: // * both start_qualifier_closed and start_qualifier_open are set // * both end_qualifier_closed and end_qualifier_open are set // * start_qualifier_closed > end_qualifier_closed // * start_qualifier_closed > end_qualifier_open // * start_qualifier_open > end_qualifier_closed // * start_qualifier_open > end_qualifier_open func validateRowRanges(req *btpb.ReadRowsRequest) error { rowRanges := req.GetRows().GetRowRanges() if len(rowRanges) == 0 { return nil } for i, rowRange := range rowRanges { skC := rowRange.GetStartKeyClosed() ekC := rowRange.GetEndKeyClosed() skO := rowRange.GetStartKeyOpen() ekO := rowRange.GetEndKeyOpen() if msg := messageOnInvalidKeyRanges(skC, skO, ekC, ekO); msg != "" { return status.Errorf(codes.InvalidArgument, "Error in element #%d: %s", i, msg) } } return nil } func messageOnInvalidKeyRanges(startKeyClosed, startKeyOpen, endKeyClosed, endKeyOpen []byte) string { switch { case len(startKeyClosed) != 0 && len(startKeyOpen) != 0: return "both start_key_closed and start_key_open cannot be set" case len(endKeyClosed) != 0 && len(endKeyOpen) != 0: return "both end_key_closed and end_key_open cannot be set" case keysOutOfRange(startKeyClosed, endKeyClosed): return "start_key_closed must be less than end_key_closed" case keysOutOfRange(startKeyOpen, endKeyOpen): return "start_key_open must be less than end_key_open" case keysOutOfRange(startKeyClosed, endKeyOpen): return "start_key_closed must be less than end_key_open" case keysOutOfRange(startKeyOpen, endKeyClosed): return "start_key_open must be less than end_key_closed" } return "" } func keysOutOfRange(start, end []byte) bool { if len(start) == 0 && len(end) == 0 { // Neither keys have been set, this is an implicit indefinite range. return false } if len(start) == 0 || len(end) == 0 { // Either of the keys have been set so this is an explicit indefinite range. return false } // Both keys have been set now check if start > end. return bytes.Compare(start, end) > 0 } google-cloud-go-0.49.0/bigtable/bttest/validation_test.go000066400000000000000000000114021356504100700233640ustar00rootroot00000000000000/* Copyright 2019 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package bttest import ( "testing" btpb "google.golang.org/genproto/googleapis/bigtable/v2" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) func TestMessageOnInvalidKeyRange(t *testing.T) { tests := []struct { startOpen, startClosed, endOpen, endClosed string wantErr string }{ { startOpen: "A", startClosed: "A", wantErr: "both start_key_closed and start_key_open cannot be set", }, { endOpen: "Z", endClosed: "Z", wantErr: "both end_key_closed and end_key_open cannot be set", }, { startClosed: "Z", endClosed: "A", wantErr: "start_key_closed must be less than end_key_closed", }, { startClosed: "Z", endOpen: "A", wantErr: "start_key_closed must be less than end_key_open", }, { startOpen: "Z", endClosed: "A", wantErr: "start_key_open must be less than end_key_closed", }, { startOpen: "Z", endOpen: "A", wantErr: "start_key_open must be less than end_key_open", }, // All values not set. { startClosed: "", startOpen: "", endClosed: "", endOpen: "", wantErr: "", }, // Indefinite ranges on each side. { startClosed: "A", startOpen: "", endClosed: "", endOpen: "", wantErr: "", }, { startClosed: "", startOpen: "A", endClosed: "", endOpen: "", wantErr: "", }, { startClosed: "", startOpen: "", endClosed: "A", endOpen: "", wantErr: "", }, { startClosed: "", startOpen: "", endClosed: "", endOpen: "A", wantErr: "", }, // startClosed, endClosed ranges properly set. { startClosed: "A", startOpen: "", endClosed: "Z", endOpen: "", wantErr: "", }, // startClosed, endOpen range. { startClosed: "A", startOpen: "", endClosed: "", endOpen: "Z", wantErr: "", }, // startOpen, endClosed ranges properly set. { startClosed: "", startOpen: "A", endClosed: "Z", endOpen: "", wantErr: "", }, // startOpen, endOpen range. { startClosed: "", startOpen: "A", endClosed: "", endOpen: "Z", wantErr: "", }, } for i, tt := range tests { gotErr := messageOnInvalidKeyRanges( []byte(tt.startClosed), []byte(tt.startOpen), []byte(tt.endClosed), []byte(tt.endOpen)) if gotErr != tt.wantErr { t.Errorf("#%d. Error mismatch\nGot: %q\nGiven:\n%+v", i, gotErr, tt) } } } // This test is just to ensure that the emulator always sends back // an RPC error with a status code just like Google Bigtable does. func TestValidateReadRowsRequestSendsRPCError(t *testing.T) { tableName := "foo.org/bar" // Minimal server to reproduce failures. srv := &server{ tables: map[string]*table{tableName: new(table)}, } badValues := []struct { startKeyClosed, startKeyOpen, endKeyClosed, endKeyOpen string }{ {startKeyClosed: "Z", endKeyClosed: "A"}, {startKeyClosed: "Z", endKeyOpen: "A"}, {startKeyOpen: "Z", endKeyClosed: "A"}, {startKeyOpen: "Z", endKeyOpen: "A"}, } for i, tt := range badValues { badReq := &btpb.ReadRowsRequest{ TableName: tableName, Rows: &btpb.RowSet{ RowRanges: []*btpb.RowRange{ { StartKey: &btpb.RowRange_StartKeyClosed{ StartKeyClosed: []byte(tt.startKeyClosed), }, EndKey: &btpb.RowRange_EndKeyClosed{ EndKeyClosed: []byte(tt.endKeyClosed), }, }, { StartKey: &btpb.RowRange_StartKeyClosed{ StartKeyClosed: []byte(tt.startKeyClosed), }, EndKey: &btpb.RowRange_EndKeyOpen{ EndKeyOpen: []byte(tt.endKeyOpen), }, }, { StartKey: &btpb.RowRange_StartKeyOpen{ StartKeyOpen: []byte(tt.startKeyOpen), }, EndKey: &btpb.RowRange_EndKeyOpen{ EndKeyOpen: []byte(tt.endKeyOpen), }, }, { StartKey: &btpb.RowRange_StartKeyOpen{ StartKeyOpen: []byte(tt.startKeyOpen), }, EndKey: &btpb.RowRange_EndKeyClosed{ EndKeyClosed: []byte(tt.endKeyClosed), }, }, }, }, } err := srv.ReadRows(badReq, nil) if err == nil { t.Errorf("#%d: unexpectedly returned nil error", i) continue } status, ok := status.FromError(err) if !ok { t.Errorf("#%d: wrong error type %T, expected status.Error", i, err) continue } if g, w := status.Code(), codes.InvalidArgument; g != w { t.Errorf("#%d: wrong error code\nGot %d %s\nWant %d %s", i, g, g, w, w) } } } google-cloud-go-0.49.0/bigtable/cmd/000077500000000000000000000000001356504100700171045ustar00rootroot00000000000000google-cloud-go-0.49.0/bigtable/cmd/cbt/000077500000000000000000000000001356504100700176545ustar00rootroot00000000000000google-cloud-go-0.49.0/bigtable/cmd/cbt/README.md000066400000000000000000000035271356504100700211420ustar00rootroot00000000000000# CBT: Cloud Bigtable Tool This is the source for `cbt`. ## Build and Run To build the tool locally, run this command in this directory: ``` go build . ``` That will build the cbt binary in that directory. To run commands with the `cbt` you built (rather than the official one) invoke it with the directory prefix like this: ``` ./cbt help ``` ## Documentation This tool gets documented on the [Go packages website](https://godoc.org/cloud.google.com/go/bigtable/cmd/cbt) as well as the [cloud site](https://cloud.google.com/bigtable/docs/cbt-reference). ### Go Package Documentation This command will generate a file with a package description which gets used for the godoc.org. You should update this after any changes to the usage or descriptions of the commands. To generate the file, run: ``` go generate ``` The output will be in [cbtdoc.go](cbtdoc.go). You may want to verify this looks good locally. To do that, you will need to generate the doc into your GOPATH version of the directory, then run `godoc` and you can view the [local version](http://localhost:6060/pkg/cloud.google.com/go/bigtable/cmd/cbt/) ``` go run . -o $(go env GOPATH)/src/cloud.google.com/go/bigtable/cmd/cbt/cbtdoc.go doc godoc ``` ### Cloud Site Documentation The Cloud documentation uses the `cbt mddoc` command to generate part of the [cbt Reference](https://cloud.google.com/bigtable/docs/cbt-reference) page. To preview what it will look like upon generation, you can generate it into a file with the command: ``` go run . -o doc.md mddoc ``` This will create a file doc.md. You don't need to check it into this repository, so delete it once you are happy with the output. ## Configuration The configuration for the options (`-project`, `-instance`, and `-creds`) is in [cbtconfig.go](../../internal/cbtconfig/cbtconfig.go). So change that file if you need to modify those.google-cloud-go-0.49.0/bigtable/cmd/cbt/cbt.go000066400000000000000000001420771356504100700207660ustar00rootroot00000000000000/* Copyright 2015 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package main // Command docs are in cbtdoc.go. import ( "bytes" "context" "encoding/csv" "flag" "fmt" "go/format" "io" "log" "os" "regexp" "sort" "strconv" "strings" "text/tabwriter" "text/template" "time" "cloud.google.com/go/bigtable" "cloud.google.com/go/bigtable/internal/cbtconfig" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/grpc" "google.golang.org/grpc/metadata" ) var ( oFlag = flag.String("o", "", "if set, redirect stdout to this file") config *cbtconfig.Config client *bigtable.Client adminClient *bigtable.AdminClient instanceAdminClient *bigtable.InstanceAdminClient version = "" revision = "" revisionDate = "" cliUserAgent = "cbt-cli-go/unknown" ) func getCredentialOpts(opts []option.ClientOption) []option.ClientOption { if ts := config.TokenSource; ts != nil { opts = append(opts, option.WithTokenSource(ts)) } if tlsCreds := config.TLSCreds; tlsCreds != nil { opts = append(opts, option.WithGRPCDialOption(grpc.WithTransportCredentials(tlsCreds))) } return opts } func getClient(clientConf bigtable.ClientConfig) *bigtable.Client { if client == nil { var opts []option.ClientOption if ep := config.DataEndpoint; ep != "" { opts = append(opts, option.WithEndpoint(ep)) } opts = append(opts, option.WithUserAgent(cliUserAgent)) opts = getCredentialOpts(opts) var err error client, err = bigtable.NewClientWithConfig(context.Background(), config.Project, config.Instance, clientConf, opts...) if err != nil { log.Fatalf("Making bigtable.Client: %v", err) } } return client } func getAdminClient() *bigtable.AdminClient { if adminClient == nil { var opts []option.ClientOption if ep := config.AdminEndpoint; ep != "" { opts = append(opts, option.WithEndpoint(ep)) } opts = append(opts, option.WithUserAgent(cliUserAgent)) opts = getCredentialOpts(opts) var err error adminClient, err = bigtable.NewAdminClient(context.Background(), config.Project, config.Instance, opts...) if err != nil { log.Fatalf("Making bigtable.AdminClient: %v", err) } } return adminClient } func getInstanceAdminClient() *bigtable.InstanceAdminClient { if instanceAdminClient == nil { var opts []option.ClientOption if ep := config.AdminEndpoint; ep != "" { opts = append(opts, option.WithEndpoint(ep)) } opts = getCredentialOpts(opts) var err error instanceAdminClient, err = bigtable.NewInstanceAdminClient(context.Background(), config.Project, opts...) if err != nil { log.Fatalf("Making bigtable.InstanceAdminClient: %v", err) } } return instanceAdminClient } func main() { var err error config, err = cbtconfig.Load() if err != nil { log.Fatal(err) } config.RegisterFlags() flag.Usage = func() { usage(os.Stderr) } flag.Parse() if flag.NArg() == 0 { usage(os.Stderr) os.Exit(1) } if *oFlag != "" { f, err := os.Create(*oFlag) if err != nil { log.Fatal(err) } defer func() { if err := f.Close(); err != nil { log.Fatal(err) } }() os.Stdout = f } if config.UserAgent != "" { cliUserAgent = config.UserAgent } ctx := context.Background() if config.AuthToken != "" { ctx = metadata.AppendToOutgoingContext(ctx, "x-goog-iam-authorization-token", config.AuthToken) } for _, cmd := range commands { if cmd.Name == flag.Arg(0) { if err := config.CheckFlags(cmd.Required); err != nil { log.Fatal(err) } cmd.do(ctx, flag.Args()[1:]...) return } } log.Fatalf("Unknown command %q", flag.Arg(0)) } func usage(w io.Writer) { fmt.Fprintf(w, "Usage: %s [flags] ...\n", os.Args[0]) flag.CommandLine.SetOutput(w) flag.CommandLine.PrintDefaults() fmt.Fprintf(w, "\n%s", cmdSummary) } var cmdSummary string // generated in init, below func init() { var buf bytes.Buffer tw := tabwriter.NewWriter(&buf, 10, 8, 4, '\t', 0) for _, cmd := range commands { fmt.Fprintf(tw, "cbt %s\t%s\n", cmd.Name, cmd.Desc) } tw.Flush() buf.WriteString(configHelp) buf.WriteString("\ncbt " + version + " " + revision + " " + revisionDate + "\n") cmdSummary = buf.String() } const configHelp = ` Alpha features are not currently available to most Cloud Bigtable customers. Alpha features might be changed in backward-incompatible ways and are not recommended for production use. They are not subject to any SLA or deprecation policy. Syntax rules for the Bash shell apply to the ` + "`cbt`" + ` tool. This means, for example, that you must put quotes around values that contain spaces or operators. It also means that if a value is arbitrary bytes, you need to prefix it with a dollar sign and use single quotes. Example: cbt -project my-project -instance my-instance lookup my-table $'\224\257\312W\365:\205d\333\2471\315\' For convenience, you can add values for the -project, -instance, -creds, -admin-endpoint and -data-endpoint options to your ~/.cbtrc file in the following format: project = my-project-123 instance = my-instance creds = path-to-account-key.json admin-endpoint = hostname:port data-endpoint = hostname:port auth-token = AJAvW039NO1nDcijk_J6_rFXG_... All values are optional and can be overridden at the command prompt. ` const docIntroTemplate = `The ` + "`cbt`" + ` tool is a command-line tool that allows you to interact with Cloud Bigtable. See the [cbt overview](https://cloud.google.com/bigtable/docs/cbt-overview) to learn how to install the ` + "`cbt`" + ` tool. Usage: cbt [-
((maxage= | maxversions=) [(and|or) (maxage= | maxversions=),...] | never)\n" + " maxage= Maximum timestamp age to preserve. Acceptable units: ms, s, m, h, d\n" + " maxversions= Maximum number of versions to preserve\n" + " Put garbage collection policies in quotes when they include shell operators && and ||.\n\n" + " Examples:\n" + " cbt setgcpolicy mobile-time-series stats_detail maxage=10d\n" + " cbt setgcpolicy mobile-time-series stats_summary maxage=10d or maxversion=1\n", Required: cbtconfig.ProjectAndInstanceRequired, }, { Name: "waitforreplication", Desc: "Block until all the completed writes have been replicated to all the clusters", do: doWaitForReplicaiton, Usage: "cbt waitforreplication \n", Required: cbtconfig.ProjectAndInstanceRequired, }, { Name: "createtablefromsnapshot", Desc: "Create a table from a snapshot (snapshots alpha)", do: doCreateTableFromSnapshot, Usage: "cbt createtablefromsnapshot
\n" + " table The name of the table to create\n" + " cluster The cluster where the snapshot is located\n" + " snapshot The snapshot to restore\n", Required: cbtconfig.ProjectAndInstanceRequired, }, { Name: "createsnapshot", Desc: "Create a snapshot from a source table (snapshots alpha)", do: doSnapshotTable, Usage: "cbt createsnapshot
[ttl=]\n" + ` [ttl=] Lifespan of the snapshot (e.g. "1h", "4d")`, Required: cbtconfig.ProjectAndInstanceRequired, }, { Name: "listsnapshots", Desc: "List snapshots in a cluster (snapshots alpha)", do: doListSnapshots, Usage: "cbt listsnapshots []", Required: cbtconfig.ProjectAndInstanceRequired, }, { Name: "getsnapshot", Desc: "Get snapshot info (snapshots alpha)", do: doGetSnapshot, Usage: "cbt getsnapshot ", Required: cbtconfig.ProjectAndInstanceRequired, }, { Name: "deletesnapshot", Desc: "Delete snapshot in a cluster (snapshots alpha)", do: doDeleteSnapshot, Usage: "cbt deletesnapshot ", Required: cbtconfig.ProjectAndInstanceRequired, }, { Name: "version", Desc: "Print the current cbt version", do: doVersion, Usage: "cbt version", Required: cbtconfig.NoneRequired, }, { Name: "createappprofile", Desc: "Create app profile for an instance", do: doCreateAppProfile, Usage: "cbt createappprofile " + "(route-any | [ route-to= : transactional-writes]) [-force] \n" + " force: Optional flag to override any warnings causing the command to fail\n\n" + " Examples:\n" + " cbt createappprofile my-instance multi-cluster \"Routes to nearest available cluster\" route-any\n" + " cbt createappprofile my-instance single-cluster \"Europe routing\" route-to=my-instance-c2", Required: cbtconfig.ProjectAndInstanceRequired, }, { Name: "getappprofile", Desc: "Read app profile for an instance", do: doGetAppProfile, Usage: "cbt getappprofile ", Required: cbtconfig.ProjectAndInstanceRequired, }, { Name: "listappprofile", Desc: "Lists app profile for an instance", do: doListAppProfiles, Usage: "cbt listappprofile ", Required: cbtconfig.ProjectAndInstanceRequired, }, { Name: "updateappprofile", Desc: "Update app profile for an instance", do: doUpdateAppProfile, Usage: "cbt updateappprofile " + "(route-any | [ route-to= : transactional-writes]) [-force] \n" + " force: Optional flag to override any warnings causing the command to fail\n\n" + " Example: cbt updateappprofile my-instance multi-cluster \"Use this one.\" route-any", Required: cbtconfig.ProjectAndInstanceRequired, }, { Name: "deleteappprofile", Desc: "Delete app profile for an instance", do: doDeleteAppProfile, Usage: "cbt deleteappprofile \n\n" + " Example: cbt deleteappprofile my-instance single-cluster", Required: cbtconfig.ProjectAndInstanceRequired, }, } func doCount(ctx context.Context, args ...string) { if len(args) != 1 { log.Fatal("usage: cbt count
") } tbl := getClient(bigtable.ClientConfig{}).Open(args[0]) n := 0 err := tbl.ReadRows(ctx, bigtable.InfiniteRange(""), func(_ bigtable.Row) bool { n++ return true }, bigtable.RowFilter(bigtable.StripValueFilter())) if err != nil { log.Fatalf("Reading rows: %v", err) } fmt.Println(n) } func doCreateTable(ctx context.Context, args ...string) { if len(args) < 1 { log.Fatal("usage: cbt createtable
[families=family[:gcpolicy],...] [splits=split,...]") } tblConf := bigtable.TableConf{TableID: args[0]} parsed, err := parseArgs(args[1:], []string{"families", "splits"}) if err != nil { log.Fatal(err) } for key, val := range parsed { chunks, err := csv.NewReader(strings.NewReader(val)).Read() if err != nil { log.Fatalf("Invalid %s arg format: %v", key, err) } switch key { case "families": tblConf.Families = make(map[string]bigtable.GCPolicy) for _, family := range chunks { famPolicy := strings.Split(family, ":") var gcPolicy bigtable.GCPolicy if len(famPolicy) < 2 { gcPolicy = bigtable.MaxVersionsPolicy(1) log.Printf("Using default GC Policy of %v for family %v", gcPolicy, family) } else { gcPolicy, err = parseGCPolicy(famPolicy[1]) if err != nil { log.Fatal(err) } } tblConf.Families[famPolicy[0]] = gcPolicy } case "splits": tblConf.SplitKeys = chunks } } if err := getAdminClient().CreateTableFromConf(ctx, &tblConf); err != nil { log.Fatalf("Creating table: %v", err) } } func doCreateFamily(ctx context.Context, args ...string) { if len(args) != 2 { log.Fatal("usage: cbt createfamily
") } err := getAdminClient().CreateColumnFamily(ctx, args[0], args[1]) if err != nil { log.Fatalf("Creating column family: %v", err) } } func doCreateInstance(ctx context.Context, args ...string) { if len(args) < 6 { log.Fatal("cbt createinstance ") } numNodes, err := strconv.ParseInt(args[4], 0, 32) if err != nil { log.Fatalf("Bad num-nodes %q: %v", args[4], err) } sType, err := parseStorageType(args[5]) if err != nil { log.Fatal(err) } ic := bigtable.InstanceWithClustersConfig{ InstanceID: args[0], DisplayName: args[1], Clusters: []bigtable.ClusterConfig{{ ClusterID: args[2], Zone: args[3], NumNodes: int32(numNodes), StorageType: sType, }}, } err = getInstanceAdminClient().CreateInstanceWithClusters(ctx, &ic) if err != nil { log.Fatalf("Creating instance: %v", err) } } func doCreateCluster(ctx context.Context, args ...string) { if len(args) < 4 { log.Fatal("usage: cbt createcluster ") } numNodes, err := strconv.ParseInt(args[2], 0, 32) if err != nil { log.Fatalf("Bad num_nodes %q: %v", args[2], err) } sType, err := parseStorageType(args[3]) if err != nil { log.Fatal(err) } cc := bigtable.ClusterConfig{ InstanceID: config.Instance, ClusterID: args[0], Zone: args[1], NumNodes: int32(numNodes), StorageType: sType, } err = getInstanceAdminClient().CreateCluster(ctx, &cc) if err != nil { log.Fatalf("Creating cluster: %v", err) } } func doUpdateCluster(ctx context.Context, args ...string) { if len(args) < 2 { log.Fatal("cbt updatecluster [num-nodes=num-nodes]") } numNodes := int64(0) parsed, err := parseArgs(args[1:], []string{"num-nodes"}) if err != nil { log.Fatal(err) } if val, ok := parsed["num-nodes"]; ok { numNodes, err = strconv.ParseInt(val, 0, 32) if err != nil { log.Fatalf("Bad num-nodes %q: %v", val, err) } } if numNodes > 0 { err = getInstanceAdminClient().UpdateCluster(ctx, config.Instance, args[0], int32(numNodes)) if err != nil { log.Fatalf("Updating cluster: %v", err) } } else { log.Fatal("Updating cluster: nothing to update") } } func doDeleteInstance(ctx context.Context, args ...string) { if len(args) != 1 { log.Fatal("usage: cbt deleteinstance ") } err := getInstanceAdminClient().DeleteInstance(ctx, args[0]) if err != nil { log.Fatalf("Deleting instance: %v", err) } } func doDeleteCluster(ctx context.Context, args ...string) { if len(args) != 1 { log.Fatal("usage: cbt deletecluster ") } err := getInstanceAdminClient().DeleteCluster(ctx, config.Instance, args[0]) if err != nil { log.Fatalf("Deleting cluster: %v", err) } } func doDeleteColumn(ctx context.Context, args ...string) { usage := "usage: cbt deletecolumn
[app-profile=]" if len(args) != 4 && len(args) != 5 { log.Fatal(usage) } var appProfile string if len(args) == 5 { if !strings.HasPrefix(args[4], "app-profile=") { log.Fatal(usage) } appProfile = strings.Split(args[4], "=")[1] } tbl := getClient(bigtable.ClientConfig{AppProfile: appProfile}).Open(args[0]) mut := bigtable.NewMutation() mut.DeleteCellsInColumn(args[2], args[3]) if err := tbl.Apply(ctx, args[1], mut); err != nil { log.Fatalf("Deleting cells in column: %v", err) } } func doDeleteFamily(ctx context.Context, args ...string) { if len(args) != 2 { log.Fatal("usage: cbt deletefamily
") } err := getAdminClient().DeleteColumnFamily(ctx, args[0], args[1]) if err != nil { log.Fatalf("Deleting column family: %v", err) } } func doDeleteRow(ctx context.Context, args ...string) { usage := "usage: cbt deleterow
[app-profile=]" if len(args) != 2 && len(args) != 3 { log.Fatal(usage) } var appProfile string if len(args) == 3 { if !strings.HasPrefix(args[2], "app-profile=") { log.Fatal(usage) } appProfile = strings.Split(args[2], "=")[1] } tbl := getClient(bigtable.ClientConfig{AppProfile: appProfile}).Open(args[0]) mut := bigtable.NewMutation() mut.DeleteRow() if err := tbl.Apply(ctx, args[1], mut); err != nil { log.Fatalf("Deleting row: %v", err) } } func doDeleteAllRows(ctx context.Context, args ...string) { if len(args) != 1 { log.Fatalf("Can't do `cbt deleteallrows %s`", args) } err := getAdminClient().DropAllRows(ctx, args[0]) if err != nil { log.Fatalf("Deleting all rows: %v", err) } } func doDeleteTable(ctx context.Context, args ...string) { if len(args) != 1 { log.Fatalf("Can't do `cbt deletetable %s`", args) } err := getAdminClient().DeleteTable(ctx, args[0]) if err != nil { log.Fatalf("Deleting table: %v", err) } } // to break circular dependencies var ( doDocFn func(ctx context.Context, args ...string) doHelpFn func(ctx context.Context, args ...string) doMDDocFn func(ctx context.Context, args ...string) ) func init() { doDocFn = doDocReal doHelpFn = doHelpReal doMDDocFn = doMDDocReal } func doDoc(ctx context.Context, args ...string) { doDocFn(ctx, args...) } func doHelp(ctx context.Context, args ...string) { doHelpFn(ctx, args...) } func doMDDoc(ctx context.Context, args ...string) { doMDDocFn(ctx, args...) } func docFlags() []*flag.Flag { // Only include specific flags, in a specific order. var flags []*flag.Flag for _, name := range []string{"project", "instance", "creds"} { f := flag.Lookup(name) if f == nil { log.Fatalf("Flag not linked: -%s", name) } flags = append(flags, f) } return flags } func doDocReal(ctx context.Context, args ...string) { data := map[string]interface{}{ "Commands": commands, "Flags": docFlags(), "ConfigHelp": configHelp, } var buf bytes.Buffer if err := docTemplate.Execute(&buf, data); err != nil { log.Fatalf("Bad doc template: %v", err) } out, err := format.Source(buf.Bytes()) if err != nil { log.Fatalf("Bad doc output: %v", err) } os.Stdout.Write(out) } func indentLines(s, ind string) string { ss := strings.Split(s, "\n") for i, p := range ss { ss[i] = ind + p } return strings.Join(ss, "\n") } var docTemplate = template.Must(template.New("doc").Funcs(template.FuncMap{ "indent": indentLines, }). Parse(` // Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // DO NOT EDIT. THIS IS AUTOMATICALLY GENERATED. // Run "go generate" to regenerate. //go:generate go run cbt.go gcpolicy.go -o cbtdoc.go doc /* ` + docIntroTemplate + ` {{range .Commands}} {{.Desc}} Usage: {{indent .Usage "\t"}} {{end}} */ package main `)) func doHelpReal(ctx context.Context, args ...string) { if len(args) == 0 { usage(os.Stdout) return } for _, cmd := range commands { if cmd.Name == args[0] { fmt.Println(cmd.Usage) return } } log.Fatalf("Don't know command %q", args[0]) } func doListInstances(ctx context.Context, args ...string) { if len(args) != 0 { log.Fatalf("usage: cbt listinstances") } is, err := getInstanceAdminClient().Instances(ctx) if err != nil { log.Fatalf("Getting list of instances: %v", err) } tw := tabwriter.NewWriter(os.Stdout, 10, 8, 4, '\t', 0) fmt.Fprintf(tw, "Instance Name\tInfo\n") fmt.Fprintf(tw, "-------------\t----\n") for _, i := range is { fmt.Fprintf(tw, "%s\t%s\n", i.Name, i.DisplayName) } tw.Flush() } func doListClusters(ctx context.Context, args ...string) { if len(args) != 0 { log.Fatalf("usage: cbt listclusters") } cis, err := getInstanceAdminClient().Clusters(ctx, config.Instance) if err != nil { log.Fatalf("Getting list of clusters: %v", err) } tw := tabwriter.NewWriter(os.Stdout, 10, 8, 4, '\t', 0) fmt.Fprintf(tw, "Cluster Name\tZone\tState\n") fmt.Fprintf(tw, "------------\t----\t----\n") for _, ci := range cis { fmt.Fprintf(tw, "%s\t%s\t%s (%d serve nodes)\n", ci.Name, ci.Zone, ci.State, ci.ServeNodes) } tw.Flush() } func doLookup(ctx context.Context, args ...string) { if len(args) < 2 { log.Fatalf("usage: cbt lookup
[columns=...] [cells-per-column=] " + "[app-profile=]") } parsed, err := parseArgs(args[2:], []string{"columns", "cells-per-column", "app-profile"}) if err != nil { log.Fatal(err) } var opts []bigtable.ReadOption var filters []bigtable.Filter if cellsPerColumn := parsed["cells-per-column"]; cellsPerColumn != "" { n, err := strconv.Atoi(cellsPerColumn) if err != nil { log.Fatalf("Bad number of cells per column %q: %v", cellsPerColumn, err) } filters = append(filters, bigtable.LatestNFilter(n)) } if columns := parsed["columns"]; columns != "" { columnFilters, err := parseColumnsFilter(columns) if err != nil { log.Fatal(err) } filters = append(filters, columnFilters) } if len(filters) > 1 { opts = append(opts, bigtable.RowFilter(bigtable.ChainFilters(filters...))) } else if len(filters) == 1 { opts = append(opts, bigtable.RowFilter(filters[0])) } table, row := args[0], args[1] tbl := getClient(bigtable.ClientConfig{AppProfile: parsed["app-profile"]}).Open(table) r, err := tbl.ReadRow(ctx, row, opts...) if err != nil { log.Fatalf("Reading row: %v", err) } printRow(r) } func printRow(r bigtable.Row) { fmt.Println(strings.Repeat("-", 40)) fmt.Println(r.Key()) var fams []string for fam := range r { fams = append(fams, fam) } sort.Strings(fams) for _, fam := range fams { ris := r[fam] sort.Sort(byColumn(ris)) for _, ri := range ris { ts := time.Unix(0, int64(ri.Timestamp)*1e3) fmt.Printf(" %-40s @ %s\n", ri.Column, ts.Format("2006/01/02-15:04:05.000000")) fmt.Printf(" %q\n", ri.Value) } } } type byColumn []bigtable.ReadItem func (b byColumn) Len() int { return len(b) } func (b byColumn) Swap(i, j int) { b[i], b[j] = b[j], b[i] } func (b byColumn) Less(i, j int) bool { return b[i].Column < b[j].Column } type byFamilyName []bigtable.FamilyInfo func (b byFamilyName) Len() int { return len(b) } func (b byFamilyName) Swap(i, j int) { b[i], b[j] = b[j], b[i] } func (b byFamilyName) Less(i, j int) bool { return b[i].Name < b[j].Name } func doLS(ctx context.Context, args ...string) { switch len(args) { default: log.Fatalf("Can't do `cbt ls %s`", args) case 0: tables, err := getAdminClient().Tables(ctx) if err != nil { log.Fatalf("Getting list of tables: %v", err) } sort.Strings(tables) for _, table := range tables { fmt.Println(table) } case 1: table := args[0] ti, err := getAdminClient().TableInfo(ctx, table) if err != nil { log.Fatalf("Getting table info: %v", err) } sort.Sort(byFamilyName(ti.FamilyInfos)) tw := tabwriter.NewWriter(os.Stdout, 10, 8, 4, '\t', 0) fmt.Fprintf(tw, "Family Name\tGC Policy\n") fmt.Fprintf(tw, "-----------\t---------\n") for _, fam := range ti.FamilyInfos { fmt.Fprintf(tw, "%s\t%s\n", fam.Name, fam.GCPolicy) } tw.Flush() } } func doMDDocReal(ctx context.Context, args ...string) { data := map[string]interface{}{ "Commands": commands, "Flags": docFlags(), "ConfigHelp": configHelp, } var buf bytes.Buffer if err := mddocTemplate.Execute(&buf, data); err != nil { log.Fatalf("Bad mddoc template: %v", err) } io.Copy(os.Stdout, &buf) } var mddocTemplate = template.Must(template.New("mddoc").Funcs(template.FuncMap{ "indent": indentLines, }). Parse(docIntroTemplate + ` {{range .Commands}} ## {{.Desc}} {{indent .Usage "\t"}} {{end}} `)) func doRead(ctx context.Context, args ...string) { if len(args) < 1 { log.Fatalf("usage: cbt read
[args ...]") } parsed, err := parseArgs(args[1:], []string{ "start", "end", "prefix", "columns", "count", "cells-per-column", "regex", "app-profile", "limit", }) if err != nil { log.Fatal(err) } if _, ok := parsed["limit"]; ok { // Be nicer; we used to support this, but renamed it to "end". log.Fatal("Unknown arg key 'limit'; did you mean 'end'?") } if (parsed["start"] != "" || parsed["end"] != "") && parsed["prefix"] != "" { log.Fatal(`"start"/"end" may not be mixed with "prefix"`) } var rr bigtable.RowRange if start, end := parsed["start"], parsed["end"]; end != "" { rr = bigtable.NewRange(start, end) } else if start != "" { rr = bigtable.InfiniteRange(start) } if prefix := parsed["prefix"]; prefix != "" { rr = bigtable.PrefixRange(prefix) } var opts []bigtable.ReadOption if count := parsed["count"]; count != "" { n, err := strconv.ParseInt(count, 0, 64) if err != nil { log.Fatalf("Bad count %q: %v", count, err) } opts = append(opts, bigtable.LimitRows(n)) } var filters []bigtable.Filter if cellsPerColumn := parsed["cells-per-column"]; cellsPerColumn != "" { n, err := strconv.Atoi(cellsPerColumn) if err != nil { log.Fatalf("Bad number of cells per column %q: %v", cellsPerColumn, err) } filters = append(filters, bigtable.LatestNFilter(n)) } if regex := parsed["regex"]; regex != "" { filters = append(filters, bigtable.RowKeyFilter(regex)) } if columns := parsed["columns"]; columns != "" { columnFilters, err := parseColumnsFilter(columns) if err != nil { log.Fatal(err) } filters = append(filters, columnFilters) } if len(filters) > 1 { opts = append(opts, bigtable.RowFilter(bigtable.ChainFilters(filters...))) } else if len(filters) == 1 { opts = append(opts, bigtable.RowFilter(filters[0])) } // TODO(dsymonds): Support filters. tbl := getClient(bigtable.ClientConfig{AppProfile: parsed["app-profile"]}).Open(args[0]) err = tbl.ReadRows(ctx, rr, func(r bigtable.Row) bool { printRow(r) return true }, opts...) if err != nil { log.Fatalf("Reading rows: %v", err) } } var setArg = regexp.MustCompile(`([^:]+):([^=]*)=(.*)`) func doSet(ctx context.Context, args ...string) { if len(args) < 3 { log.Fatalf("usage: cbt set
[app-profile=] family:[column]=val[@ts] ...") } var appProfile string row := args[1] mut := bigtable.NewMutation() for _, arg := range args[2:] { if strings.HasPrefix(arg, "app-profile=") { appProfile = strings.Split(arg, "=")[1] continue } m := setArg.FindStringSubmatch(arg) if m == nil { log.Fatalf("Bad set arg %q", arg) } val := m[3] ts := bigtable.Now() if i := strings.LastIndex(val, "@"); i >= 0 { // Try parsing a timestamp. n, err := strconv.ParseInt(val[i+1:], 0, 64) if err == nil { val = val[:i] ts = bigtable.Timestamp(n) } } mut.Set(m[1], m[2], ts, []byte(val)) } tbl := getClient(bigtable.ClientConfig{AppProfile: appProfile}).Open(args[0]) if err := tbl.Apply(ctx, row, mut); err != nil { log.Fatalf("Applying mutation: %v", err) } } func doSetGCPolicy(ctx context.Context, args ...string) { if len(args) < 3 { log.Fatalf("usage: cbt setgcpolicy
((maxage= | maxversions=) [(and|or) (maxage= | maxversions=),...] | never)") } table := args[0] fam := args[1] pol, err := parseGCPolicy(strings.Join(args[2:], " ")) if err != nil { log.Fatal(err) } if err := getAdminClient().SetGCPolicy(ctx, table, fam, pol); err != nil { log.Fatalf("Setting GC policy: %v", err) } } func doWaitForReplicaiton(ctx context.Context, args ...string) { if len(args) != 1 { log.Fatalf("usage: cbt waitforreplication
") } table := args[0] fmt.Printf("Waiting for all writes up to %s to be replicated.\n", time.Now().Format("2006/01/02-15:04:05")) if err := getAdminClient().WaitForReplication(ctx, table); err != nil { log.Fatalf("Waiting for replication: %v", err) } } func parseStorageType(storageTypeStr string) (bigtable.StorageType, error) { switch storageTypeStr { case "SSD": return bigtable.SSD, nil case "HDD": return bigtable.HDD, nil } return -1, fmt.Errorf("Invalid storage type: %v, must be SSD or HDD", storageTypeStr) } func doCreateTableFromSnapshot(ctx context.Context, args ...string) { if len(args) != 3 { log.Fatal("usage: cbt createtablefromsnapshot
") } tableName := args[0] clusterName := args[1] snapshotName := args[2] err := getAdminClient().CreateTableFromSnapshot(ctx, tableName, clusterName, snapshotName) if err != nil { log.Fatalf("Creating table: %v", err) } } func doSnapshotTable(ctx context.Context, args ...string) { if len(args) != 3 && len(args) != 4 { log.Fatal("usage: cbt createsnapshot
[ttl=]") } clusterName := args[0] snapshotName := args[1] tableName := args[2] ttl := bigtable.DefaultSnapshotDuration parsed, err := parseArgs(args[3:], []string{"ttl"}) if err != nil { log.Fatal(err) } if val, ok := parsed["ttl"]; ok { var err error ttl, err = parseDuration(val) if err != nil { log.Fatalf("Invalid snapshot ttl value %q: %v", val, err) } } err = getAdminClient().SnapshotTable(ctx, tableName, clusterName, snapshotName, ttl) if err != nil { log.Fatalf("Failed to create Snapshot: %v", err) } } func doListSnapshots(ctx context.Context, args ...string) { if len(args) != 0 && len(args) != 1 { log.Fatal("usage: cbt listsnapshots []") } var cluster string if len(args) == 0 { cluster = "-" } else { cluster = args[0] } it := getAdminClient().Snapshots(ctx, cluster) tw := tabwriter.NewWriter(os.Stdout, 10, 8, 4, '\t', 0) fmt.Fprintf(tw, "Snapshot\tSource Table\tCreated At\tExpires At\n") fmt.Fprintf(tw, "--------\t------------\t----------\t----------\n") timeLayout := "2006-01-02 15:04 MST" for { snapshot, err := it.Next() if err == iterator.Done { break } if err != nil { log.Fatalf("Failed to fetch snapshots %v", err) } fmt.Fprintf(tw, "%s\t%s\t%s\t%s\n", snapshot.Name, snapshot.SourceTable, snapshot.CreateTime.Format(timeLayout), snapshot.DeleteTime.Format(timeLayout)) } tw.Flush() } func doGetSnapshot(ctx context.Context, args ...string) { if len(args) != 2 { log.Fatalf("usage: cbt getsnapshot ") } clusterName := args[0] snapshotName := args[1] snapshot, err := getAdminClient().SnapshotInfo(ctx, clusterName, snapshotName) if err != nil { log.Fatalf("Failed to get snapshot: %v", err) } timeLayout := "2006-01-02 15:04 MST" fmt.Printf("Name: %s\n", snapshot.Name) fmt.Printf("Source table: %s\n", snapshot.SourceTable) fmt.Printf("Created at: %s\n", snapshot.CreateTime.Format(timeLayout)) fmt.Printf("Expires at: %s\n", snapshot.DeleteTime.Format(timeLayout)) } func doDeleteSnapshot(ctx context.Context, args ...string) { if len(args) != 2 { log.Fatal("usage: cbt deletesnapshot ") } cluster := args[0] snapshot := args[1] err := getAdminClient().DeleteSnapshot(ctx, cluster, snapshot) if err != nil { log.Fatalf("Failed to delete snapshot: %v", err) } } func doCreateAppProfile(ctx context.Context, args ...string) { if len(args) < 4 || len(args) > 6 { log.Fatal("usage: cbt createappprofile " + " (route-any | [ route-to= : transactional-writes]) [optional flag] \n" + "optional flags may be `force`") } routingPolicy, clusterID, err := parseProfileRoute(args[3]) if err != nil { log.Fatalln("Exactly one of (route-any | [route-to : transactional-writes]) must be specified.") } config := bigtable.ProfileConf{ RoutingPolicy: routingPolicy, InstanceID: args[0], ProfileID: args[1], Description: args[2], } opFlags := []string{"force", "transactional-writes"} parseValues, err := parseArgs(args[4:], opFlags) if err != nil { log.Fatalf("optional flags can be specified as (force=|transactional-writes=) got %s ", args[4:]) } for _, f := range opFlags { fv, err := parseProfileOpts(f, parseValues) if err != nil { log.Fatalf("optional flags can be specified as (force=|transactional-writes=) got %s ", args[4:]) } switch f { case opFlags[0]: config.IgnoreWarnings = fv case opFlags[1]: config.AllowTransactionalWrites = fv default: } } if routingPolicy == bigtable.SingleClusterRouting { config.ClusterID = clusterID } profile, err := getInstanceAdminClient().CreateAppProfile(ctx, config) if err != nil { log.Fatalf("Failed to create app profile : %v", err) } fmt.Printf("Name: %s\n", profile.Name) fmt.Printf("RoutingPolicy: %v\n", profile.RoutingPolicy) } func doGetAppProfile(ctx context.Context, args ...string) { if len(args) != 2 { log.Fatalln("usage: cbt getappprofile ") } instanceID := args[0] profileID := args[1] profile, err := getInstanceAdminClient().GetAppProfile(ctx, instanceID, profileID) if err != nil { log.Fatalf("Failed to get app profile : %v", err) } fmt.Printf("Name: %s\n", profile.Name) fmt.Printf("Etag: %s\n", profile.Etag) fmt.Printf("Description: %s\n", profile.Description) fmt.Printf("RoutingPolicy: %v\n", profile.RoutingPolicy) } func doListAppProfiles(ctx context.Context, args ...string) { if len(args) != 1 { log.Fatalln("usage: cbt listappprofile ") } instance := args[0] it := getInstanceAdminClient().ListAppProfiles(ctx, instance) tw := tabwriter.NewWriter(os.Stdout, 10, 8, 4, '\t', 0) fmt.Fprintf(tw, "AppProfile\tProfile Description\tProfile Etag\tProfile Routing Policy\n") fmt.Fprintf(tw, "-----------\t--------------------\t------------\t----------------------\n") for { profile, err := it.Next() if err == iterator.Done { break } if err != nil { log.Fatalf("Failed to fetch app profile %v", err) } fmt.Fprintf(tw, "%s\t%s\t%s\t%s\n", profile.Name, profile.Description, profile.Etag, profile.RoutingPolicy) } tw.Flush() } func doUpdateAppProfile(ctx context.Context, args ...string) { if len(args) < 4 { log.Fatal("usage: cbt updateappprofile " + " (route-any | [ route-to= : transactional-writes]) [optional flag] \n" + "optional flags may be `force`") } routingPolicy, clusterID, err := parseProfileRoute(args[3]) if err != nil { log.Fatalln("Exactly one of (route-any | [route-to : transactional-writes]) must be specified.") } InstanceID := args[0] ProfileID := args[1] config := bigtable.ProfileAttrsToUpdate{ RoutingPolicy: routingPolicy, Description: args[2], } opFlags := []string{"force", "transactional-writes"} parseValues, err := parseArgs(args[4:], opFlags) if err != nil { log.Fatalf("optional flags can be specified as (force=|transactional-writes=) got %s ", args[4:]) } for _, f := range opFlags { fv, err := parseProfileOpts(f, parseValues) if err != nil { log.Fatalf("optional flags can be specified as (force=|transactional-writes=) got %s ", args[4:]) } switch f { case opFlags[0]: config.IgnoreWarnings = fv case opFlags[1]: config.AllowTransactionalWrites = fv default: } } if routingPolicy == bigtable.SingleClusterRouting { config.ClusterID = clusterID } err = getInstanceAdminClient().UpdateAppProfile(ctx, InstanceID, ProfileID, config) if err != nil { log.Fatalf("Failed to update app profile : %v", err) } } func doDeleteAppProfile(ctx context.Context, args ...string) { if len(args) != 2 { log.Println("usage: cbt deleteappprofile ") } err := getInstanceAdminClient().DeleteAppProfile(ctx, args[0], args[1]) if err != nil { log.Fatalf("Failed to delete app profile : %v", err) } } // parseDuration parses a duration string. // It is similar to Go's time.ParseDuration, except with a different set of supported units, // and only simple formats supported. func parseDuration(s string) (time.Duration, error) { // [0-9]+[a-z]+ // Split [0-9]+ from [a-z]+. i := 0 for ; i < len(s); i++ { c := s[i] if c < '0' || c > '9' { break } } ds, u := s[:i], s[i:] if ds == "" || u == "" { return 0, fmt.Errorf("invalid duration %q", s) } // Parse them. d, err := strconv.ParseUint(ds, 10, 32) if err != nil { return 0, fmt.Errorf("invalid duration %q: %v", s, err) } unit, ok := unitMap[u] if !ok { return 0, fmt.Errorf("unknown unit %q in duration %q", u, s) } if d > uint64((1<<63-1)/unit) { // overflow return 0, fmt.Errorf("invalid duration %q overflows", s) } return time.Duration(d) * unit, nil } var unitMap = map[string]time.Duration{ "ms": time.Millisecond, "s": time.Second, "m": time.Minute, "h": time.Hour, "d": 24 * time.Hour, } func doVersion(ctx context.Context, args ...string) { fmt.Printf("%s %s %s\n", version, revision, revisionDate) } // parseArgs takes a slice of arguments of the form key=value and returns a map from // key to value. It returns an error if an argument is malformed or a key is not in // the valid slice. func parseArgs(args []string, valid []string) (map[string]string, error) { parsed := make(map[string]string) for _, arg := range args { i := strings.Index(arg, "=") if i < 0 { return nil, fmt.Errorf("Bad arg %q", arg) } key, val := arg[:i], arg[i+1:] if !stringInSlice(key, valid) { return nil, fmt.Errorf("Unknown arg key %q", key) } parsed[key] = val } return parsed, nil } func stringInSlice(s string, list []string) bool { for _, e := range list { if s == e { return true } } return false } func parseColumnsFilter(columns string) (bigtable.Filter, error) { splitColumns := strings.FieldsFunc(columns, func(c rune) bool { return c == ',' }) if len(splitColumns) == 1 { filter, err := columnFilter(splitColumns[0]) if err != nil { return nil, err } return filter, nil } var columnFilters []bigtable.Filter for _, column := range splitColumns { filter, err := columnFilter(column) if err != nil { return nil, err } columnFilters = append(columnFilters, filter) } return bigtable.InterleaveFilters(columnFilters...), nil } func columnFilter(column string) (bigtable.Filter, error) { splitColumn := strings.Split(column, ":") if len(splitColumn) == 1 { return bigtable.ColumnFilter(splitColumn[0]), nil } else if len(splitColumn) == 2 { if strings.HasSuffix(column, ":") { return bigtable.FamilyFilter(splitColumn[0]), nil } else if strings.HasPrefix(column, ":") { return bigtable.ColumnFilter(splitColumn[1]), nil } else { familyFilter := bigtable.FamilyFilter(splitColumn[0]) qualifierFilter := bigtable.ColumnFilter(splitColumn[1]) return bigtable.ChainFilters(familyFilter, qualifierFilter), nil } } else { return nil, fmt.Errorf("Bad format for column %q", column) } } func parseProfileRoute(str string) (routingPolicy, clusterID string, err error) { route := strings.Split(str, "=") switch route[0] { case "route-any": if len(route) > 1 { err = fmt.Errorf("got %v", route) break } routingPolicy = bigtable.MultiClusterRouting case "route-to": if len(route) != 2 || route[1] == "" { err = fmt.Errorf("got %v", route) break } routingPolicy = bigtable.SingleClusterRouting clusterID = route[1] default: err = fmt.Errorf("got %v", route) } return } func parseProfileOpts(opt string, parsedArgs map[string]string) (bool, error) { if val, ok := parsedArgs[opt]; ok { status, err := strconv.ParseBool(val) if err != nil { return false, fmt.Errorf("expected %s = got %s ", opt, val) } return status, nil } return false, nil } google-cloud-go-0.49.0/bigtable/cmd/cbt/cbt_test.go000066400000000000000000000105761356504100700220230ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package main import ( "testing" "time" "cloud.google.com/go/bigtable" "cloud.google.com/go/internal/testutil" "github.com/google/go-cmp/cmp" ) func TestParseDuration(t *testing.T) { tests := []struct { in string // out or fail are mutually exclusive out time.Duration fail bool }{ {in: "10ms", out: 10 * time.Millisecond}, {in: "3s", out: 3 * time.Second}, {in: "60m", out: 60 * time.Minute}, {in: "12h", out: 12 * time.Hour}, {in: "7d", out: 168 * time.Hour}, {in: "", fail: true}, {in: "0", fail: true}, {in: "7ns", fail: true}, {in: "14mo", fail: true}, {in: "3.5h", fail: true}, {in: "106752d", fail: true}, // overflow } for _, tc := range tests { got, err := parseDuration(tc.in) if !tc.fail && err != nil { t.Errorf("parseDuration(%q) unexpectedly failed: %v", tc.in, err) continue } if tc.fail && err == nil { t.Errorf("parseDuration(%q) did not fail", tc.in) continue } if tc.fail { continue } if got != tc.out { t.Errorf("parseDuration(%q) = %v, want %v", tc.in, got, tc.out) } } } func TestParseArgs(t *testing.T) { got, err := parseArgs([]string{"a=1", "b=2"}, []string{"a", "b"}) if err != nil { t.Fatal(err) } want := map[string]string{"a": "1", "b": "2"} if !testutil.Equal(got, want) { t.Fatalf("got %v, want %v", got, want) } if _, err := parseArgs([]string{"a1"}, []string{"a1"}); err == nil { t.Error("malformed: got nil, want error") } if _, err := parseArgs([]string{"a=1"}, []string{"b"}); err == nil { t.Error("invalid: got nil, want error") } } func TestParseColumnsFilter(t *testing.T) { tests := []struct { in string out bigtable.Filter fail bool }{ { in: "columnA", out: bigtable.ColumnFilter("columnA"), }, { in: "familyA:columnA", out: bigtable.ChainFilters(bigtable.FamilyFilter("familyA"), bigtable.ColumnFilter("columnA")), }, { in: "columnA,columnB", out: bigtable.InterleaveFilters(bigtable.ColumnFilter("columnA"), bigtable.ColumnFilter("columnB")), }, { in: "familyA:columnA,columnB", out: bigtable.InterleaveFilters( bigtable.ChainFilters(bigtable.FamilyFilter("familyA"), bigtable.ColumnFilter("columnA")), bigtable.ColumnFilter("columnB"), ), }, { in: "columnA,familyB:columnB", out: bigtable.InterleaveFilters( bigtable.ColumnFilter("columnA"), bigtable.ChainFilters(bigtable.FamilyFilter("familyB"), bigtable.ColumnFilter("columnB")), ), }, { in: "familyA:columnA,familyB:columnB", out: bigtable.InterleaveFilters( bigtable.ChainFilters(bigtable.FamilyFilter("familyA"), bigtable.ColumnFilter("columnA")), bigtable.ChainFilters(bigtable.FamilyFilter("familyB"), bigtable.ColumnFilter("columnB")), ), }, { in: "familyA:", out: bigtable.FamilyFilter("familyA"), }, { in: ":columnA", out: bigtable.ColumnFilter("columnA"), }, { in: ",:columnA,,familyB:columnB,", out: bigtable.InterleaveFilters( bigtable.ColumnFilter("columnA"), bigtable.ChainFilters(bigtable.FamilyFilter("familyB"), bigtable.ColumnFilter("columnB")), ), }, { in: "familyA:columnA:cellA", fail: true, }, { in: "familyA::columnA", fail: true, }, } for _, tc := range tests { got, err := parseColumnsFilter(tc.in) if !tc.fail && err != nil { t.Errorf("parseColumnsFilter(%q) unexpectedly failed: %v", tc.in, err) continue } if tc.fail && err == nil { t.Errorf("parseColumnsFilter(%q) did not fail", tc.in) continue } if tc.fail { continue } var cmpOpts cmp.Options cmpOpts = append( cmpOpts, cmp.AllowUnexported(bigtable.ChainFilters([]bigtable.Filter{}...)), cmp.AllowUnexported(bigtable.InterleaveFilters([]bigtable.Filter{}...))) if !cmp.Equal(got, tc.out, cmpOpts) { t.Errorf("parseColumnsFilter(%q) = %v, want %v", tc.in, got, tc.out) } } } google-cloud-go-0.49.0/bigtable/cmd/cbt/cbtdoc.go000066400000000000000000000331751356504100700214520ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // DO NOT EDIT. THIS IS AUTOMATICALLY GENERATED. // Run "go generate" to regenerate. //go:generate go run cbt.go gcpolicy.go -o cbtdoc.go doc /* The `cbt` tool is a command-line tool that allows you to interact with Cloud Bigtable. See the [cbt overview](https://cloud.google.com/bigtable/docs/cbt-overview) to learn how to install the `cbt` tool. Usage: cbt [-
((maxage= | maxversions=) [(and|or) (maxage= | maxversions=),...] | never) maxage= Maximum timestamp age to preserve. Acceptable units: ms, s, m, h, d maxversions= Maximum number of versions to preserve Put garbage collection policies in quotes when they include shell operators && and ||. Examples: cbt setgcpolicy mobile-time-series stats_detail maxage=10d cbt setgcpolicy mobile-time-series stats_summary maxage=10d or maxversion=1 Block until all the completed writes have been replicated to all the clusters Usage: cbt waitforreplication Create a table from a snapshot (snapshots alpha) Usage: cbt createtablefromsnapshot
table The name of the table to create cluster The cluster where the snapshot is located snapshot The snapshot to restore Create a snapshot from a source table (snapshots alpha) Usage: cbt createsnapshot
[ttl=] [ttl=] Lifespan of the snapshot (e.g. "1h", "4d") List snapshots in a cluster (snapshots alpha) Usage: cbt listsnapshots [] Get snapshot info (snapshots alpha) Usage: cbt getsnapshot Delete snapshot in a cluster (snapshots alpha) Usage: cbt deletesnapshot Print the current cbt version Usage: cbt version Create app profile for an instance Usage: cbt createappprofile (route-any | [ route-to= : transactional-writes]) [-force] force: Optional flag to override any warnings causing the command to fail Examples: cbt createappprofile my-instance multi-cluster "Routes to nearest available cluster" route-any cbt createappprofile my-instance single-cluster "Europe routing" route-to=my-instance-c2 Read app profile for an instance Usage: cbt getappprofile Lists app profile for an instance Usage: cbt listappprofile Update app profile for an instance Usage: cbt updateappprofile (route-any | [ route-to= : transactional-writes]) [-force] force: Optional flag to override any warnings causing the command to fail Example: cbt updateappprofile my-instance multi-cluster "Use this one." route-any Delete app profile for an instance Usage: cbt deleteappprofile Example: cbt deleteappprofile my-instance single-cluster */ package main google-cloud-go-0.49.0/bigtable/cmd/cbt/gcpolicy.go000066400000000000000000000112231356504100700220130ustar00rootroot00000000000000/* Copyright 2015 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package main import ( "bytes" "errors" "fmt" "io" "strconv" "strings" "unicode" "cloud.google.com/go/bigtable" ) // Parse a GC policy. Valid policies include // never // maxage = 5d // maxversions = 3 // maxage = 5d || maxversions = 3 // maxage=30d || (maxage=3d && maxversions=100) func parseGCPolicy(s string) (bigtable.GCPolicy, error) { if strings.TrimSpace(s) == "never" { return bigtable.NoGcPolicy(), nil } r := strings.NewReader(s) p, err := parsePolicyExpr(r) if err != nil { return nil, fmt.Errorf("invalid GC policy: %v", err) } tok, err := getToken(r) if err != nil { return nil, err } if tok != "" { return nil, fmt.Errorf("invalid GC policy: want end of input, got %q", tok) } return p, nil } // expr ::= term (op term)* // op ::= "and" | "or" | "&&" | "||" func parsePolicyExpr(r io.RuneScanner) (bigtable.GCPolicy, error) { policy, err := parsePolicyTerm(r) if err != nil { return nil, err } for { tok, err := getToken(r) if err != nil { return nil, err } var f func(...bigtable.GCPolicy) bigtable.GCPolicy switch tok { case "and", "&&": f = bigtable.IntersectionPolicy case "or", "||": f = bigtable.UnionPolicy default: ungetToken(tok) return policy, nil } p2, err := parsePolicyTerm(r) if err != nil { return nil, err } policy = f(policy, p2) } } // term ::= "maxage" "=" duration | "maxversions" "=" int | "(" policy ")" func parsePolicyTerm(r io.RuneScanner) (bigtable.GCPolicy, error) { tok, err := getToken(r) if err != nil { return nil, err } switch tok { case "": return nil, errors.New("empty GC policy term") case "maxage", "maxversions": if err := expectToken(r, "="); err != nil { return nil, err } tok2, err := getToken(r) if err != nil { return nil, err } if tok2 == "" { return nil, errors.New("expected a token after '='") } if tok == "maxage" { dur, err := parseDuration(tok2) if err != nil { return nil, err } return bigtable.MaxAgePolicy(dur), nil } n, err := strconv.ParseUint(tok2, 10, 16) if err != nil { return nil, err } return bigtable.MaxVersionsPolicy(int(n)), nil case "(": p, err := parsePolicyExpr(r) if err != nil { return nil, err } if err := expectToken(r, ")"); err != nil { return nil, err } return p, nil default: return nil, fmt.Errorf("unexpected token: %q", tok) } } func expectToken(r io.RuneScanner, want string) error { got, err := getToken(r) if err != nil { return err } if got != want { return fmt.Errorf("expected %q, saw %q", want, got) } return nil } const noToken = "_" // empty token is valid, so use "_" instead // If not noToken, getToken will return this instead of reading a new token // from the input. var ungotToken = noToken // getToken extracts the first token from the input. Valid tokens include // any sequence of letters and digits, and these symbols: &&, ||, =, ( and ). // getToken returns ("", nil) at end of input. func getToken(r io.RuneScanner) (string, error) { if ungotToken != noToken { t := ungotToken ungotToken = noToken return t, nil } var err error // Skip leading whitespace. c := ' ' for unicode.IsSpace(c) { c, _, err = r.ReadRune() if err == io.EOF { return "", nil } if err != nil { return "", err } } switch { case c == '=' || c == '(' || c == ')': return string(c), nil case c == '&' || c == '|': c2, _, err := r.ReadRune() if err != nil && err != io.EOF { return "", err } if c != c2 { return "", fmt.Errorf("expected %c%c", c, c) } return string([]rune{c, c}), nil case unicode.IsLetter(c) || unicode.IsDigit(c): // Collect an alphanumeric token. var b bytes.Buffer for unicode.IsLetter(c) || unicode.IsDigit(c) { b.WriteRune(c) c, _, err = r.ReadRune() if err == io.EOF { break } if err != nil { return "", err } } r.UnreadRune() return b.String(), nil default: return "", fmt.Errorf("bad rune %q", c) } } // "unget" a token so the next call to getToken will return it. func ungetToken(tok string) { if ungotToken != noToken { panic("ungetToken called twice") } ungotToken = tok } google-cloud-go-0.49.0/bigtable/cmd/cbt/gcpolicy_test.go000066400000000000000000000107751356504100700230650ustar00rootroot00000000000000/* Copyright 2015 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package main import ( "strings" "testing" "time" "cloud.google.com/go/bigtable" "github.com/google/go-cmp/cmp" ) func TestParseGCPolicy(t *testing.T) { for _, test := range []struct { in string want bigtable.GCPolicy }{ { "never", bigtable.NoGcPolicy(), }, { "maxage=3h", bigtable.MaxAgePolicy(3 * time.Hour), }, { "maxversions=2", bigtable.MaxVersionsPolicy(2), }, { "maxversions=2 and maxage=1h", bigtable.IntersectionPolicy(bigtable.MaxVersionsPolicy(2), bigtable.MaxAgePolicy(time.Hour)), }, { "(((maxversions=2 and (maxage=1h))))", bigtable.IntersectionPolicy(bigtable.MaxVersionsPolicy(2), bigtable.MaxAgePolicy(time.Hour)), }, { "maxversions=7 or maxage=8h", bigtable.UnionPolicy(bigtable.MaxVersionsPolicy(7), bigtable.MaxAgePolicy(8*time.Hour)), }, { "maxversions = 7||maxage = 8h", bigtable.UnionPolicy(bigtable.MaxVersionsPolicy(7), bigtable.MaxAgePolicy(8*time.Hour)), }, { "maxversions=7||maxage=8h", bigtable.UnionPolicy(bigtable.MaxVersionsPolicy(7), bigtable.MaxAgePolicy(8*time.Hour)), }, { "maxage=30d || (maxage=3d && maxversions=100)", bigtable.UnionPolicy( bigtable.MaxAgePolicy(30*24*time.Hour), bigtable.IntersectionPolicy( bigtable.MaxAgePolicy(3*24*time.Hour), bigtable.MaxVersionsPolicy(100))), }, { "maxage=30d || (maxage=3d && maxversions=100) || maxversions=7", bigtable.UnionPolicy( bigtable.UnionPolicy( bigtable.MaxAgePolicy(30*24*time.Hour), bigtable.IntersectionPolicy( bigtable.MaxAgePolicy(3*24*time.Hour), bigtable.MaxVersionsPolicy(100))), bigtable.MaxVersionsPolicy(7)), }, { // && and || have same precedence, left associativity "maxage=1h && maxage=2h || maxage=3h", bigtable.UnionPolicy( bigtable.IntersectionPolicy( bigtable.MaxAgePolicy(1*time.Hour), bigtable.MaxAgePolicy(2*time.Hour)), bigtable.MaxAgePolicy(3*time.Hour)), }, } { got, err := parseGCPolicy(test.in) if err != nil { t.Errorf("%s: %v", test.in, err) continue } if !cmp.Equal(got, test.want, cmp.AllowUnexported(bigtable.IntersectionPolicy(), bigtable.UnionPolicy())) { t.Errorf("%s: got %+v, want %+v", test.in, got, test.want) } } } func TestParseGCPolicyErrors(t *testing.T) { for _, in := range []string{ "", "a", "b = 1h", "c = 1", "maxage=1", // need duration "maxversions=1h", // need int "maxage", "maxversions", "never=never", "maxversions=1 && never", "(((maxage=1h))", "((maxage=1h)))", "maxage=30d || ((maxage=3d && maxversions=100)", "maxversions = 3 and", } { _, err := parseGCPolicy(in) if err == nil { t.Errorf("%s: got nil, want error", in) } } } func TestTokenizeGCPolicy(t *testing.T) { for _, test := range []struct { in string want []string }{ { "maxage=5d", []string{"maxage", "=", "5d"}, }, { "maxage = 5d", []string{"maxage", "=", "5d"}, }, { "maxage=5d or maxversions=5", []string{"maxage", "=", "5d", "or", "maxversions", "=", "5"}, }, { "maxage=5d || (maxversions=5)", []string{"maxage", "=", "5d", "||", "(", "maxversions", "=", "5", ")"}, }, { "maxage=5d||( maxversions=5 )", []string{"maxage", "=", "5d", "||", "(", "maxversions", "=", "5", ")"}, }, } { got, err := tokenizeGCPolicy(test.in) if err != nil { t.Errorf("%s: %v", test.in, err) continue } if diff := cmp.Diff(got, test.want); diff != "" { t.Errorf("%s: %s", test.in, diff) } } } func TestTokenizeGCPolicyErrors(t *testing.T) { for _, in := range []string{ "a &", "a & b", "a &x b", "a |", "a | b", "a |& b", "a % b", } { _, err := tokenizeGCPolicy(in) if err == nil { t.Errorf("%s: got nil, want error", in) } } } func tokenizeGCPolicy(s string) ([]string, error) { var tokens []string r := strings.NewReader(s) for { tok, err := getToken(r) if err != nil { return nil, err } if tok == "" { break } tokens = append(tokens, tok) } return tokens, nil } google-cloud-go-0.49.0/bigtable/cmd/emulator/000077500000000000000000000000001356504100700207345ustar00rootroot00000000000000google-cloud-go-0.49.0/bigtable/cmd/emulator/cbtemulator.go000066400000000000000000000025741356504100700236140ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. /* cbtemulator launches the in-memory Cloud Bigtable server on the given address. */ package main import ( "flag" "fmt" "log" "cloud.google.com/go/bigtable/bttest" "google.golang.org/grpc" ) var ( host = flag.String("host", "localhost", "the address to bind to on the local machine") port = flag.Int("port", 9000, "the port number to bind to on the local machine") ) const ( maxMsgSize = 256 * 1024 * 1024 // 256 MiB ) func main() { grpc.EnableTracing = false flag.Parse() opts := []grpc.ServerOption{ grpc.MaxRecvMsgSize(maxMsgSize), grpc.MaxSendMsgSize(maxMsgSize), } srv, err := bttest.NewServer(fmt.Sprintf("%s:%d", *host, *port), opts...) if err != nil { log.Fatalf("failed to start emulator: %v", err) } fmt.Printf("Cloud Bigtable emulator running on %s\n", srv.Addr) select {} } google-cloud-go-0.49.0/bigtable/cmd/loadtest/000077500000000000000000000000001356504100700207235ustar00rootroot00000000000000google-cloud-go-0.49.0/bigtable/cmd/loadtest/loadtest.go000066400000000000000000000131651356504100700230770ustar00rootroot00000000000000/* Copyright 2015 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Loadtest does some load testing through the Go client library for Cloud Bigtable. */ package main import ( "bytes" "context" "flag" "fmt" "log" "math/rand" "os" "os/signal" "sync" "sync/atomic" "time" "cloud.google.com/go/bigtable" "cloud.google.com/go/bigtable/internal/cbtconfig" "cloud.google.com/go/bigtable/internal/stat" "google.golang.org/api/option" "google.golang.org/grpc" ) var ( runFor = flag.Duration("run_for", 5*time.Second, "how long to run the load test for; 0 to run forever until SIGTERM") scratchTable = flag.String("scratch_table", "loadtest-scratch", "name of table to use; should not already exist") csvOutput = flag.String("csv_output", "", "output path for statistics in .csv format. If this file already exists it will be overwritten.") poolSize = flag.Int("pool_size", 1, "size of the gRPC connection pool to use for the data client") reqCount = flag.Int("req_count", 100, "number of concurrent requests") config *cbtconfig.Config client *bigtable.Client adminClient *bigtable.AdminClient ) func main() { var err error config, err = cbtconfig.Load() if err != nil { log.Fatal(err) } config.RegisterFlags() flag.Parse() if err := config.CheckFlags(cbtconfig.ProjectAndInstanceRequired); err != nil { log.Fatal(err) } if config.Creds != "" { os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", config.Creds) } if flag.NArg() != 0 { flag.Usage() os.Exit(1) } var options []option.ClientOption if *poolSize > 1 { options = append(options, option.WithGRPCConnectionPool(*poolSize), // TODO(grpc/grpc-go#1388) using connection pool without WithBlock // can cause RPCs to fail randomly. We can delete this after the issue is fixed. option.WithGRPCDialOption(grpc.WithBlock())) } var csvFile *os.File if *csvOutput != "" { csvFile, err = os.Create(*csvOutput) if err != nil { log.Fatalf("creating csv output file: %v", err) } defer csvFile.Close() log.Printf("Writing statistics to %q ...", *csvOutput) } log.Printf("Dialing connections...") client, err = bigtable.NewClient(context.Background(), config.Project, config.Instance, options...) if err != nil { log.Fatalf("Making bigtable.Client: %v", err) } defer client.Close() adminClient, err = bigtable.NewAdminClient(context.Background(), config.Project, config.Instance) if err != nil { log.Fatalf("Making bigtable.AdminClient: %v", err) } defer adminClient.Close() // Create a scratch table. log.Printf("Setting up scratch table...") tblConf := bigtable.TableConf{ TableID: *scratchTable, Families: map[string]bigtable.GCPolicy{"f": bigtable.MaxVersionsPolicy(1)}, } if err := adminClient.CreateTableFromConf(context.Background(), &tblConf); err != nil { log.Fatalf("Making scratch table %q: %v", *scratchTable, err) } // Upon a successful run, delete the table. Don't bother checking for errors. defer adminClient.DeleteTable(context.Background(), *scratchTable) // Also delete the table on SIGTERM. c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt) go func() { s := <-c log.Printf("Caught %v, cleaning scratch table.", s) _ = adminClient.DeleteTable(context.Background(), *scratchTable) os.Exit(1) }() log.Printf("Starting load test... (run for %v)", *runFor) tbl := client.Open(*scratchTable) sem := make(chan int, *reqCount) // limit the number of requests happening at once var reads, writes stats stopTime := time.Now().Add(*runFor) var wg sync.WaitGroup for time.Now().Before(stopTime) || *runFor == 0 { sem <- 1 wg.Add(1) go func() { defer wg.Done() defer func() { <-sem }() ok := true opStart := time.Now() var stats *stats defer func() { stats.Record(ok, time.Since(opStart)) }() row := fmt.Sprintf("row%d", rand.Intn(100)) // operate on 1 of 100 rows switch rand.Intn(10) { default: // read stats = &reads _, err := tbl.ReadRow(context.Background(), row, bigtable.RowFilter(bigtable.LatestNFilter(1))) if err != nil { log.Printf("Error doing read: %v", err) ok = false } case 0, 1, 2, 3, 4: // write stats = &writes mut := bigtable.NewMutation() mut.Set("f", "col", bigtable.Now(), bytes.Repeat([]byte("0"), 1<<10)) // 1 KB write if err := tbl.Apply(context.Background(), row, mut); err != nil { log.Printf("Error doing mutation: %v", err) ok = false } } }() } wg.Wait() readsAgg := stat.NewAggregate("reads", reads.ds, reads.tries-reads.ok) writesAgg := stat.NewAggregate("writes", writes.ds, writes.tries-writes.ok) log.Printf("Reads (%d ok / %d tries):\n%v", reads.ok, reads.tries, readsAgg) log.Printf("Writes (%d ok / %d tries):\n%v", writes.ok, writes.tries, writesAgg) if csvFile != nil { stat.WriteCSV([]*stat.Aggregate{readsAgg, writesAgg}, csvFile) } } var allStats int64 // atomic type stats struct { mu sync.Mutex tries, ok int ds []time.Duration } func (s *stats) Record(ok bool, d time.Duration) { s.mu.Lock() s.tries++ if ok { s.ok++ } s.ds = append(s.ds, d) s.mu.Unlock() if n := atomic.AddInt64(&allStats, 1); n%1000 == 0 { log.Printf("Progress: done %d ops", n) } } google-cloud-go-0.49.0/bigtable/cmd/scantest/000077500000000000000000000000001356504100700207305ustar00rootroot00000000000000google-cloud-go-0.49.0/bigtable/cmd/scantest/scantest.go000066400000000000000000000072761356504100700231170ustar00rootroot00000000000000/* Copyright 2016 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Scantest does scan-related load testing against Cloud Bigtable. The logic here mimics a similar test written using the Java client. */ package main import ( "bytes" "context" "flag" "fmt" "log" "math/rand" "os" "sync" "sync/atomic" "text/tabwriter" "time" "cloud.google.com/go/bigtable" "cloud.google.com/go/bigtable/internal/cbtconfig" "cloud.google.com/go/bigtable/internal/stat" ) var ( runFor = flag.Duration("run_for", 5*time.Second, "how long to run the load test for") numScans = flag.Int("concurrent_scans", 1, "number of concurrent scans") rowLimit = flag.Int("row_limit", 10000, "max number of records per scan") config *cbtconfig.Config client *bigtable.Client ) func main() { flag.Usage = func() { fmt.Printf("Usage: scantest [options] \n\n") flag.PrintDefaults() } var err error config, err = cbtconfig.Load() if err != nil { log.Fatal(err) } config.RegisterFlags() flag.Parse() if err := config.CheckFlags(cbtconfig.ProjectAndInstanceRequired); err != nil { log.Fatal(err) } if config.Creds != "" { os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", config.Creds) } if flag.NArg() != 1 { flag.Usage() os.Exit(1) } table := flag.Arg(0) log.Printf("Dialing connections...") client, err = bigtable.NewClient(context.Background(), config.Project, config.Instance) if err != nil { log.Fatalf("Making bigtable.Client: %v", err) } defer client.Close() log.Printf("Starting scan test... (run for %v)", *runFor) tbl := client.Open(table) sem := make(chan int, *numScans) // limit the number of requests happening at once var scans stats stopTime := time.Now().Add(*runFor) var wg sync.WaitGroup for time.Now().Before(stopTime) { sem <- 1 wg.Add(1) go func() { defer wg.Done() defer func() { <-sem }() ok := true opStart := time.Now() defer func() { scans.Record(ok, time.Since(opStart)) }() // Start at a random row key key := fmt.Sprintf("user%d", rand.Int63()) limit := bigtable.LimitRows(int64(*rowLimit)) noop := func(bigtable.Row) bool { return true } if err := tbl.ReadRows(context.Background(), bigtable.NewRange(key, ""), noop, limit); err != nil { log.Printf("Error during scan: %v", err) ok = false } }() } wg.Wait() agg := stat.NewAggregate("scans", scans.ds, scans.tries-scans.ok) log.Printf("Scans (%d ok / %d tries):\nscan times:\n%v\nthroughput (rows/second):\n%v", scans.ok, scans.tries, agg, throughputString(agg)) } func throughputString(agg *stat.Aggregate) string { var buf bytes.Buffer tw := tabwriter.NewWriter(&buf, 0, 0, 1, ' ', 0) // one-space padding rowLimitF := float64(*rowLimit) fmt.Fprintf( tw, "min:\t%.2f\nmedian:\t%.2f\nmax:\t%.2f\n", rowLimitF/agg.Max.Seconds(), rowLimitF/agg.Median.Seconds(), rowLimitF/agg.Min.Seconds()) tw.Flush() return buf.String() } var allStats int64 // atomic type stats struct { mu sync.Mutex tries, ok int ds []time.Duration } func (s *stats) Record(ok bool, d time.Duration) { s.mu.Lock() s.tries++ if ok { s.ok++ } s.ds = append(s.ds, d) s.mu.Unlock() if n := atomic.AddInt64(&allStats, 1); n%1000 == 0 { log.Printf("Progress: done %d ops", n) } } google-cloud-go-0.49.0/bigtable/conformance_test.go000066400000000000000000000105051356504100700222220ustar00rootroot00000000000000/* Copyright 2019 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package bigtable import ( "bytes" "context" "io/ioutil" "path/filepath" "sort" "strings" "testing" "time" pb "cloud.google.com/go/bigtable/internal/conformance" "cloud.google.com/go/bigtable/internal/mockserver" "github.com/golang/protobuf/jsonpb" "google.golang.org/api/option" btpb "google.golang.org/genproto/googleapis/bigtable/v2" "google.golang.org/grpc" ) func TestConformance(t *testing.T) { ctx := context.Background() dir := "internal/conformance/testdata" files, err := filepath.Glob(dir + "/*.json") if err != nil { t.Fatal(err) } srv, err := mockserver.NewServer("localhost:0") if err != nil { t.Fatal(err) } defer srv.Close() conn, err := grpc.Dial(srv.Addr, grpc.WithInsecure(), grpc.WithBlock()) if err != nil { t.Fatal(err) } defer conn.Close() c, err := NewClient(ctx, "some-project", "some-instance", option.WithGRPCConn(conn)) if err != nil { t.Fatal(err) } for _, f := range files { inBytes, err := ioutil.ReadFile(f) if err != nil { t.Fatalf("%s: %v", f, err) } var tf pb.TestFile if err := jsonpb.Unmarshal(bytes.NewReader(inBytes), &tf); err != nil { t.Fatalf("unmarshalling %s: %v", f, err) } for _, tc := range tf.GetReadRowsTests() { t.Run(tc.Description, func(t *testing.T) { runReadRowsTest(ctx, t, tc, c, srv) }) } } } func runReadRowsTest(ctx context.Context, t *testing.T, tc *pb.ReadRowsTest, c *Client, srv *mockserver.Server) { srv.ReadRowsFn = func(req *btpb.ReadRowsRequest, something btpb.Bigtable_ReadRowsServer) error { something.Send(&btpb.ReadRowsResponse{ Chunks: tc.GetChunks(), }) return nil } var resIndex int // We perform a SingleRow here, but that arg is basically nonsense since // the server is hard-coded to return a specific response. As in, we could // pass RowRange, ListRows, etc and the result would all be the same. err := c.Open("some-table").ReadRows(ctx, SingleRow("some-row"), func(r Row) bool { type rowElem struct { family string readItems []ReadItem } // Row comes in as a map, which has undefined iteration order. So, we // first stick it in a slice, then sort that slice by family (the // results appear ordered as such), then we're ready to use it. var byFamily []rowElem for family, items := range r { byFamily = append(byFamily, rowElem{family: family, readItems: items}) } sort.Slice(byFamily, func(i, j int) bool { return strings.Compare(byFamily[i].family, byFamily[j].family) < 0 }) for _, row := range byFamily { family := row.family items := row.readItems for _, item := range items { want := tc.GetResults()[resIndex] if got, want := string(item.Value), want.GetValue(); got != want { t.Fatalf("got %s, want %s", got, want) } if got, want := family, want.GetFamilyName(); got != want { t.Fatalf("got %s, want %s", got, want) } gotMicros := item.Timestamp.Time().UnixNano() / int64(time.Microsecond) if got, want := gotMicros, want.GetTimestampMicros(); got != want { t.Fatalf("got %d, want %d", got, want) } if got, want := item.Column, want.GetFamilyName()+":"+want.GetQualifier(); got != want { t.Fatalf("got %s, want %s", got, want) } // TODO: labels do not appear to be accessible. If they ever do become // accessible, we should assert on want.GetLabels(). resIndex++ } } return true }) wantNumResults := len(tc.GetResults()) if wantNumResults == 0 { return } if tc.GetResults()[wantNumResults-1].GetError() { // Last expected result is an error, which means we wouldn't // count it with gotRowIndex. wantNumResults-- if err == nil { t.Fatal("expected err, got nil") } } else if err != nil { t.Fatal(err) } if got, want := resIndex, wantNumResults; got != want { t.Fatalf("got %d results, want %d", got, want) } } google-cloud-go-0.49.0/bigtable/doc.go000066400000000000000000000110151356504100700174330ustar00rootroot00000000000000/* Copyright 2015 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Package bigtable is an API to Google Cloud Bigtable. See https://cloud.google.com/bigtable/docs/ for general product documentation. See https://godoc.org/cloud.google.com/go for authentication, timeouts, connection pooling and similar aspects of this package. Reading The principal way to read from a Bigtable is to use the ReadRows method on *Table. A RowRange specifies a contiguous portion of a table. A Filter may be provided through RowFilter to limit or transform the data that is returned. tbl := client.Open("mytable") // Read all the rows starting with "com.google.", but only fetch the columns // in the "links" family. rr := bigtable.PrefixRange("com.google.") err := tbl.ReadRows(ctx, rr, func(r Row) bool { // TODO: do something with r. return true // Keep going. }, bigtable.RowFilter(bigtable.FamilyFilter("links"))) if err != nil { // TODO: handle err. } To read a single row, use the ReadRow helper method: r, err := tbl.ReadRow(ctx, "com.google.cloud") // "com.google.cloud" is the entire row key if err != nil { // TODO: handle err. } // TODO: use r. Writing This API exposes two distinct forms of writing to a Bigtable: a Mutation and a ReadModifyWrite. The former expresses idempotent operations. The latter expresses non-idempotent operations and returns the new values of updated cells. These operations are performed by creating a Mutation or ReadModifyWrite (with NewMutation or NewReadModifyWrite), building up one or more operations on that, and then using the Apply or ApplyReadModifyWrite methods on a Table. For instance, to set a couple of cells in a table: tbl := client.Open("mytable") mut := bigtable.NewMutation() // To use numeric values that will later be incremented, // they need to be big-endian encoded as 64-bit integers. buf := new(bytes.Buffer) initialLinkCount := 1 // The initial number of links. if err := binary.Write(buf, binary.BigEndian, initialLinkCount); err != nil { // TODO: handle err. } mut.Set("links", "maps.google.com", bigtable.Now(), buf.Bytes()) mut.Set("links", "golang.org", bigtable.Now(), buf.Bytes()) err := tbl.Apply(ctx, "com.google.cloud", mut) if err != nil { // TODO: handle err. } To increment an encoded value in one cell: tbl := client.Open("mytable") rmw := bigtable.NewReadModifyWrite() rmw.Increment("links", "golang.org", 12) // add 12 to the cell in column "links:golang.org" r, err := tbl.ApplyReadModifyWrite(ctx, "com.google.cloud", rmw) if err != nil { // TODO: handle err. } // TODO: use r. Retries If a read or write operation encounters a transient error it will be retried until a successful response, an unretryable error or the context deadline is reached. Non-idempotent writes (where the timestamp is set to ServerTime) will not be retried. In the case of ReadRows, retried calls will not re-scan rows that have already been processed. */ package bigtable // import "cloud.google.com/go/bigtable" // Scope constants for authentication credentials. These should be used when // using credential creation functions such as oauth.NewServiceAccountFromFile. const ( // Scope is the OAuth scope for Cloud Bigtable data operations. Scope = "https://www.googleapis.com/auth/bigtable.data" // ReadonlyScope is the OAuth scope for Cloud Bigtable read-only data // operations. ReadonlyScope = "https://www.googleapis.com/auth/bigtable.readonly" // AdminScope is the OAuth scope for Cloud Bigtable table admin operations. AdminScope = "https://www.googleapis.com/auth/bigtable.admin.table" // InstanceAdminScope is the OAuth scope for Cloud Bigtable instance (and // cluster) admin operations. InstanceAdminScope = "https://www.googleapis.com/auth/bigtable.admin.cluster" ) // clientUserAgent identifies the version of this package. // It should be bumped upon significant changes only. const clientUserAgent = "cbt-go/20180601" // resourcePrefixHeader is the name of the metadata header used to indicate // the resource being operated on. const resourcePrefixHeader = "google-cloud-resource-prefix" google-cloud-go-0.49.0/bigtable/export_test.go000066400000000000000000000175571356504100700212670ustar00rootroot00000000000000/* Copyright 2016 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package bigtable import ( "context" "errors" "flag" "fmt" "strings" "time" "cloud.google.com/go/bigtable/bttest" btopt "cloud.google.com/go/bigtable/internal/option" "cloud.google.com/go/internal/testutil" "google.golang.org/api/option" gtransport "google.golang.org/api/transport/grpc" "google.golang.org/grpc" ) var legacyUseProd string var integrationConfig IntegrationTestConfig func init() { c := &integrationConfig flag.BoolVar(&c.UseProd, "it.use-prod", false, "Use remote bigtable instead of local emulator") flag.StringVar(&c.AdminEndpoint, "it.admin-endpoint", "", "Admin api host and port") flag.StringVar(&c.DataEndpoint, "it.data-endpoint", "", "Data api host and port") flag.StringVar(&c.Project, "it.project", "", "Project to use for integration test") flag.StringVar(&c.Instance, "it.instance", "", "Bigtable instance to use") flag.StringVar(&c.Cluster, "it.cluster", "", "Bigtable cluster to use") flag.StringVar(&c.Table, "it.table", "", "Bigtable table to create") // Backwards compat flag.StringVar(&legacyUseProd, "use_prod", "", `DEPRECATED: if set to "proj,instance,table", run integration test against production`) } // IntegrationTestConfig contains parameters to pick and setup a IntegrationEnv for testing type IntegrationTestConfig struct { UseProd bool AdminEndpoint string DataEndpoint string Project string Instance string Cluster string Table string } // IntegrationEnv represents a testing environment. // The environment can be implemented using production or an emulator type IntegrationEnv interface { Config() IntegrationTestConfig NewAdminClient() (*AdminClient, error) // NewInstanceAdminClient will return nil if instance administration is unsupported in this environment NewInstanceAdminClient() (*InstanceAdminClient, error) NewClient() (*Client, error) Close() } // NewIntegrationEnv creates a new environment based on the command line args func NewIntegrationEnv() (IntegrationEnv, error) { c := integrationConfig if legacyUseProd != "" { fmt.Println("WARNING: using legacy commandline arg -use_prod, please switch to -it.*") parts := strings.SplitN(legacyUseProd, ",", 3) c.UseProd = true c.Project = parts[0] c.Instance = parts[1] c.Table = parts[2] } if integrationConfig.UseProd { return NewProdEnv(c) } return NewEmulatedEnv(c) } // EmulatedEnv encapsulates the state of an emulator type EmulatedEnv struct { config IntegrationTestConfig server *bttest.Server } // NewEmulatedEnv builds and starts the emulator based environment func NewEmulatedEnv(config IntegrationTestConfig) (*EmulatedEnv, error) { srv, err := bttest.NewServer("localhost:0", grpc.MaxRecvMsgSize(200<<20), grpc.MaxSendMsgSize(100<<20)) if err != nil { return nil, err } if config.Project == "" { config.Project = "project" } if config.Instance == "" { config.Instance = "instance" } if config.Table == "" { config.Table = "mytable" } config.AdminEndpoint = srv.Addr config.DataEndpoint = srv.Addr env := &EmulatedEnv{ config: config, server: srv, } return env, nil } // Close stops & cleans up the emulator func (e *EmulatedEnv) Close() { e.server.Close() } // Config gets the config used to build this environment func (e *EmulatedEnv) Config() IntegrationTestConfig { return e.config } var headersInterceptor = testutil.DefaultHeadersEnforcer() // NewAdminClient builds a new connected admin client for this environment func (e *EmulatedEnv) NewAdminClient() (*AdminClient, error) { o, err := btopt.DefaultClientOptions(e.server.Addr, AdminScope, clientUserAgent) if err != nil { return nil, err } // Add gRPC client interceptors to supply Google client information. // // Inject interceptors from headersInterceptor, since they are used to verify // client requests under test. o = append(o, btopt.ClientInterceptorOptions( headersInterceptor.StreamInterceptors(), headersInterceptor.UnaryInterceptors())...) timeout := 20 * time.Second ctx, _ := context.WithTimeout(context.Background(), timeout) o = append(o, option.WithGRPCDialOption(grpc.WithBlock())) conn, err := gtransport.DialInsecure(ctx, o...) if err != nil { return nil, err } return NewAdminClient(ctx, e.config.Project, e.config.Instance, option.WithGRPCConn(conn)) } // NewInstanceAdminClient returns nil for the emulated environment since the API is not implemented. func (e *EmulatedEnv) NewInstanceAdminClient() (*InstanceAdminClient, error) { return nil, nil } // NewClient builds a new connected data client for this environment func (e *EmulatedEnv) NewClient() (*Client, error) { o, err := btopt.DefaultClientOptions(e.server.Addr, Scope, clientUserAgent) if err != nil { return nil, err } // Add gRPC client interceptors to supply Google client information. // // Inject interceptors from headersInterceptor, since they are used to verify // client requests under test. o = append(o, btopt.ClientInterceptorOptions( headersInterceptor.StreamInterceptors(), headersInterceptor.UnaryInterceptors())...) timeout := 20 * time.Second ctx, _ := context.WithTimeout(context.Background(), timeout) o = append(o, option.WithGRPCDialOption(grpc.WithBlock())) o = append(o, option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallSendMsgSize(100<<20), grpc.MaxCallRecvMsgSize(100<<20)))) conn, err := gtransport.DialInsecure(ctx, o...) if err != nil { return nil, err } return NewClient(ctx, e.config.Project, e.config.Instance, option.WithGRPCConn(conn)) } // ProdEnv encapsulates the state necessary to connect to the external Bigtable service type ProdEnv struct { config IntegrationTestConfig } // NewProdEnv builds the environment representation func NewProdEnv(config IntegrationTestConfig) (*ProdEnv, error) { if config.Project == "" { return nil, errors.New("Project not set") } if config.Instance == "" { return nil, errors.New("Instance not set") } if config.Table == "" { return nil, errors.New("Table not set") } return &ProdEnv{config}, nil } // Close is a no-op for production environments func (e *ProdEnv) Close() {} // Config gets the config used to build this environment func (e *ProdEnv) Config() IntegrationTestConfig { return e.config } // NewAdminClient builds a new connected admin client for this environment func (e *ProdEnv) NewAdminClient() (*AdminClient, error) { clientOpts := headersInterceptor.CallOptions() if endpoint := e.config.AdminEndpoint; endpoint != "" { clientOpts = append(clientOpts, option.WithEndpoint(endpoint)) } return NewAdminClient(context.Background(), e.config.Project, e.config.Instance, clientOpts...) } // NewInstanceAdminClient returns a new connected instance admin client for this environment func (e *ProdEnv) NewInstanceAdminClient() (*InstanceAdminClient, error) { clientOpts := headersInterceptor.CallOptions() if endpoint := e.config.AdminEndpoint; endpoint != "" { clientOpts = append(clientOpts, option.WithEndpoint(endpoint)) } return NewInstanceAdminClient(context.Background(), e.config.Project, clientOpts...) } // NewClient builds a connected data client for this environment func (e *ProdEnv) NewClient() (*Client, error) { clientOpts := headersInterceptor.CallOptions() if endpoint := e.config.DataEndpoint; endpoint != "" { clientOpts = append(clientOpts, option.WithEndpoint(endpoint)) } return NewClient(context.Background(), e.config.Project, e.config.Instance, clientOpts...) } google-cloud-go-0.49.0/bigtable/filter.go000066400000000000000000000265721356504100700201710ustar00rootroot00000000000000/* Copyright 2015 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package bigtable import ( "fmt" "strings" "time" btpb "google.golang.org/genproto/googleapis/bigtable/v2" ) // A Filter represents a row filter. type Filter interface { String() string proto() *btpb.RowFilter } // ChainFilters returns a filter that applies a sequence of filters. func ChainFilters(sub ...Filter) Filter { return chainFilter{sub} } type chainFilter struct { sub []Filter } func (cf chainFilter) String() string { var ss []string for _, sf := range cf.sub { ss = append(ss, sf.String()) } return "(" + strings.Join(ss, " | ") + ")" } func (cf chainFilter) proto() *btpb.RowFilter { chain := &btpb.RowFilter_Chain{} for _, sf := range cf.sub { chain.Filters = append(chain.Filters, sf.proto()) } return &btpb.RowFilter{ Filter: &btpb.RowFilter_Chain_{Chain: chain}, } } // InterleaveFilters returns a filter that applies a set of filters in parallel // and interleaves the results. func InterleaveFilters(sub ...Filter) Filter { return interleaveFilter{sub} } type interleaveFilter struct { sub []Filter } func (ilf interleaveFilter) String() string { var ss []string for _, sf := range ilf.sub { ss = append(ss, sf.String()) } return "(" + strings.Join(ss, " + ") + ")" } func (ilf interleaveFilter) proto() *btpb.RowFilter { inter := &btpb.RowFilter_Interleave{} for _, sf := range ilf.sub { inter.Filters = append(inter.Filters, sf.proto()) } return &btpb.RowFilter{ Filter: &btpb.RowFilter_Interleave_{Interleave: inter}, } } // RowKeyFilter returns a filter that matches cells from rows whose // key matches the provided RE2 pattern. // See https://github.com/google/re2/wiki/Syntax for the accepted syntax. func RowKeyFilter(pattern string) Filter { return rowKeyFilter(pattern) } type rowKeyFilter string func (rkf rowKeyFilter) String() string { return fmt.Sprintf("row(%s)", string(rkf)) } func (rkf rowKeyFilter) proto() *btpb.RowFilter { return &btpb.RowFilter{Filter: &btpb.RowFilter_RowKeyRegexFilter{RowKeyRegexFilter: []byte(rkf)}} } // FamilyFilter returns a filter that matches cells whose family name // matches the provided RE2 pattern. // See https://github.com/google/re2/wiki/Syntax for the accepted syntax. func FamilyFilter(pattern string) Filter { return familyFilter(pattern) } type familyFilter string func (ff familyFilter) String() string { return fmt.Sprintf("col(%s:)", string(ff)) } func (ff familyFilter) proto() *btpb.RowFilter { return &btpb.RowFilter{Filter: &btpb.RowFilter_FamilyNameRegexFilter{FamilyNameRegexFilter: string(ff)}} } // ColumnFilter returns a filter that matches cells whose column name // matches the provided RE2 pattern. // See https://github.com/google/re2/wiki/Syntax for the accepted syntax. func ColumnFilter(pattern string) Filter { return columnFilter(pattern) } type columnFilter string func (cf columnFilter) String() string { return fmt.Sprintf("col(.*:%s)", string(cf)) } func (cf columnFilter) proto() *btpb.RowFilter { return &btpb.RowFilter{Filter: &btpb.RowFilter_ColumnQualifierRegexFilter{ColumnQualifierRegexFilter: []byte(cf)}} } // ValueFilter returns a filter that matches cells whose value // matches the provided RE2 pattern. // See https://github.com/google/re2/wiki/Syntax for the accepted syntax. func ValueFilter(pattern string) Filter { return valueFilter(pattern) } type valueFilter string func (vf valueFilter) String() string { return fmt.Sprintf("value_match(%s)", string(vf)) } func (vf valueFilter) proto() *btpb.RowFilter { return &btpb.RowFilter{Filter: &btpb.RowFilter_ValueRegexFilter{ValueRegexFilter: []byte(vf)}} } // LatestNFilter returns a filter that matches the most recent N cells in each column. func LatestNFilter(n int) Filter { return latestNFilter(n) } type latestNFilter int32 func (lnf latestNFilter) String() string { return fmt.Sprintf("col(*,%d)", lnf) } func (lnf latestNFilter) proto() *btpb.RowFilter { return &btpb.RowFilter{Filter: &btpb.RowFilter_CellsPerColumnLimitFilter{CellsPerColumnLimitFilter: int32(lnf)}} } // StripValueFilter returns a filter that replaces each value with the empty string. func StripValueFilter() Filter { return stripValueFilter{} } type stripValueFilter struct{} func (stripValueFilter) String() string { return "strip_value()" } func (stripValueFilter) proto() *btpb.RowFilter { return &btpb.RowFilter{Filter: &btpb.RowFilter_StripValueTransformer{StripValueTransformer: true}} } // TimestampRangeFilter returns a filter that matches any cells whose timestamp is within the given time bounds. A zero // time means no bound. // The timestamp will be truncated to millisecond granularity. func TimestampRangeFilter(startTime time.Time, endTime time.Time) Filter { trf := timestampRangeFilter{} if !startTime.IsZero() { trf.startTime = Time(startTime) } if !endTime.IsZero() { trf.endTime = Time(endTime) } return trf } // TimestampRangeFilterMicros returns a filter that matches any cells whose timestamp is within the given time bounds, // specified in units of microseconds since 1 January 1970. A zero value for the end time is interpreted as no bound. // The timestamp will be truncated to millisecond granularity. func TimestampRangeFilterMicros(startTime Timestamp, endTime Timestamp) Filter { return timestampRangeFilter{startTime, endTime} } type timestampRangeFilter struct { startTime Timestamp endTime Timestamp } func (trf timestampRangeFilter) String() string { return fmt.Sprintf("timestamp_range(%v,%v)", trf.startTime, trf.endTime) } func (trf timestampRangeFilter) proto() *btpb.RowFilter { return &btpb.RowFilter{ Filter: &btpb.RowFilter_TimestampRangeFilter{TimestampRangeFilter: &btpb.TimestampRange{ StartTimestampMicros: int64(trf.startTime.TruncateToMilliseconds()), EndTimestampMicros: int64(trf.endTime.TruncateToMilliseconds()), }, }} } // ColumnRangeFilter returns a filter that matches a contiguous range of columns within a single // family, as specified by an inclusive start qualifier and exclusive end qualifier. func ColumnRangeFilter(family, start, end string) Filter { return columnRangeFilter{family, start, end} } type columnRangeFilter struct { family string start string end string } func (crf columnRangeFilter) String() string { return fmt.Sprintf("columnRangeFilter(%s,%s,%s)", crf.family, crf.start, crf.end) } func (crf columnRangeFilter) proto() *btpb.RowFilter { r := &btpb.ColumnRange{FamilyName: crf.family} if crf.start != "" { r.StartQualifier = &btpb.ColumnRange_StartQualifierClosed{StartQualifierClosed: []byte(crf.start)} } if crf.end != "" { r.EndQualifier = &btpb.ColumnRange_EndQualifierOpen{EndQualifierOpen: []byte(crf.end)} } return &btpb.RowFilter{Filter: &btpb.RowFilter_ColumnRangeFilter{ColumnRangeFilter: r}} } // ValueRangeFilter returns a filter that matches cells with values that fall within // the given range, as specified by an inclusive start value and exclusive end value. func ValueRangeFilter(start, end []byte) Filter { return valueRangeFilter{start, end} } type valueRangeFilter struct { start []byte end []byte } func (vrf valueRangeFilter) String() string { return fmt.Sprintf("valueRangeFilter(%s,%s)", vrf.start, vrf.end) } func (vrf valueRangeFilter) proto() *btpb.RowFilter { r := &btpb.ValueRange{} if vrf.start != nil { r.StartValue = &btpb.ValueRange_StartValueClosed{StartValueClosed: vrf.start} } if vrf.end != nil { r.EndValue = &btpb.ValueRange_EndValueOpen{EndValueOpen: vrf.end} } return &btpb.RowFilter{Filter: &btpb.RowFilter_ValueRangeFilter{ValueRangeFilter: r}} } // ConditionFilter returns a filter that evaluates to one of two possible filters depending // on whether or not the given predicate filter matches at least one cell. // If the matched filter is nil then no results will be returned. // IMPORTANT NOTE: The predicate filter does not execute atomically with the // true and false filters, which may lead to inconsistent or unexpected // results. Additionally, condition filters have poor performance, especially // when filters are set for the false condition. func ConditionFilter(predicateFilter, trueFilter, falseFilter Filter) Filter { return conditionFilter{predicateFilter, trueFilter, falseFilter} } type conditionFilter struct { predicateFilter Filter trueFilter Filter falseFilter Filter } func (cf conditionFilter) String() string { return fmt.Sprintf("conditionFilter(%s,%s,%s)", cf.predicateFilter, cf.trueFilter, cf.falseFilter) } func (cf conditionFilter) proto() *btpb.RowFilter { var tf *btpb.RowFilter var ff *btpb.RowFilter if cf.trueFilter != nil { tf = cf.trueFilter.proto() } if cf.falseFilter != nil { ff = cf.falseFilter.proto() } return &btpb.RowFilter{ Filter: &btpb.RowFilter_Condition_{Condition: &btpb.RowFilter_Condition{ PredicateFilter: cf.predicateFilter.proto(), TrueFilter: tf, FalseFilter: ff, }}} } // CellsPerRowOffsetFilter returns a filter that skips the first N cells of each row, matching all subsequent cells. func CellsPerRowOffsetFilter(n int) Filter { return cellsPerRowOffsetFilter(n) } type cellsPerRowOffsetFilter int32 func (cof cellsPerRowOffsetFilter) String() string { return fmt.Sprintf("cells_per_row_offset(%d)", cof) } func (cof cellsPerRowOffsetFilter) proto() *btpb.RowFilter { return &btpb.RowFilter{Filter: &btpb.RowFilter_CellsPerRowOffsetFilter{CellsPerRowOffsetFilter: int32(cof)}} } // CellsPerRowLimitFilter returns a filter that matches only the first N cells of each row. func CellsPerRowLimitFilter(n int) Filter { return cellsPerRowLimitFilter(n) } type cellsPerRowLimitFilter int32 func (clf cellsPerRowLimitFilter) String() string { return fmt.Sprintf("cells_per_row_limit(%d)", clf) } func (clf cellsPerRowLimitFilter) proto() *btpb.RowFilter { return &btpb.RowFilter{Filter: &btpb.RowFilter_CellsPerRowLimitFilter{CellsPerRowLimitFilter: int32(clf)}} } // RowSampleFilter returns a filter that matches a row with a probability of p (must be in the interval (0, 1)). func RowSampleFilter(p float64) Filter { return rowSampleFilter(p) } type rowSampleFilter float64 func (rsf rowSampleFilter) String() string { return fmt.Sprintf("filter(%f)", rsf) } func (rsf rowSampleFilter) proto() *btpb.RowFilter { return &btpb.RowFilter{Filter: &btpb.RowFilter_RowSampleFilter{RowSampleFilter: float64(rsf)}} } // PassAllFilter returns a filter that matches everything. func PassAllFilter() Filter { return passAllFilter{} } type passAllFilter struct{} func (paf passAllFilter) String() string { return "passAllFilter()" } func (paf passAllFilter) proto() *btpb.RowFilter { return &btpb.RowFilter{Filter: &btpb.RowFilter_PassAllFilter{PassAllFilter: true}} } // BlockAllFilter returns a filter that matches nothing. func BlockAllFilter() Filter { return blockAllFilter{} } type blockAllFilter struct{} func (baf blockAllFilter) String() string { return "blockAllFilter()" } func (baf blockAllFilter) proto() *btpb.RowFilter { return &btpb.RowFilter{Filter: &btpb.RowFilter_BlockAllFilter{BlockAllFilter: true}} } google-cloud-go-0.49.0/bigtable/gc.go000066400000000000000000000110021356504100700172530ustar00rootroot00000000000000/* Copyright 2015 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package bigtable import ( "fmt" "strings" "time" durpb "github.com/golang/protobuf/ptypes/duration" bttdpb "google.golang.org/genproto/googleapis/bigtable/admin/v2" ) // A GCPolicy represents a rule that determines which cells are eligible for garbage collection. type GCPolicy interface { String() string proto() *bttdpb.GcRule } // IntersectionPolicy returns a GC policy that only applies when all its sub-policies apply. func IntersectionPolicy(sub ...GCPolicy) GCPolicy { return intersectionPolicy{sub} } type intersectionPolicy struct { sub []GCPolicy } func (ip intersectionPolicy) String() string { var ss []string for _, sp := range ip.sub { ss = append(ss, sp.String()) } return "(" + strings.Join(ss, " && ") + ")" } func (ip intersectionPolicy) proto() *bttdpb.GcRule { inter := &bttdpb.GcRule_Intersection{} for _, sp := range ip.sub { inter.Rules = append(inter.Rules, sp.proto()) } return &bttdpb.GcRule{ Rule: &bttdpb.GcRule_Intersection_{Intersection: inter}, } } // UnionPolicy returns a GC policy that applies when any of its sub-policies apply. func UnionPolicy(sub ...GCPolicy) GCPolicy { return unionPolicy{sub} } type unionPolicy struct { sub []GCPolicy } func (up unionPolicy) String() string { var ss []string for _, sp := range up.sub { ss = append(ss, sp.String()) } return "(" + strings.Join(ss, " || ") + ")" } func (up unionPolicy) proto() *bttdpb.GcRule { union := &bttdpb.GcRule_Union{} for _, sp := range up.sub { union.Rules = append(union.Rules, sp.proto()) } return &bttdpb.GcRule{ Rule: &bttdpb.GcRule_Union_{Union: union}, } } // MaxVersionsPolicy returns a GC policy that applies to all versions of a cell // except for the most recent n. func MaxVersionsPolicy(n int) GCPolicy { return maxVersionsPolicy(n) } type maxVersionsPolicy int func (mvp maxVersionsPolicy) String() string { return fmt.Sprintf("versions() > %d", int(mvp)) } func (mvp maxVersionsPolicy) proto() *bttdpb.GcRule { return &bttdpb.GcRule{Rule: &bttdpb.GcRule_MaxNumVersions{MaxNumVersions: int32(mvp)}} } // MaxAgePolicy returns a GC policy that applies to all cells // older than the given age. func MaxAgePolicy(d time.Duration) GCPolicy { return maxAgePolicy(d) } type maxAgePolicy time.Duration var units = []struct { d time.Duration suffix string }{ {24 * time.Hour, "d"}, {time.Hour, "h"}, {time.Minute, "m"}, } func (ma maxAgePolicy) String() string { d := time.Duration(ma) for _, u := range units { if d%u.d == 0 { return fmt.Sprintf("age() > %d%s", d/u.d, u.suffix) } } return fmt.Sprintf("age() > %d", d/time.Microsecond) } func (ma maxAgePolicy) proto() *bttdpb.GcRule { // This doesn't handle overflows, etc. // Fix this if people care about GC policies over 290 years. ns := time.Duration(ma).Nanoseconds() return &bttdpb.GcRule{ Rule: &bttdpb.GcRule_MaxAge{MaxAge: &durpb.Duration{ Seconds: ns / 1e9, Nanos: int32(ns % 1e9), }}, } } type noGCPolicy struct{} func (n noGCPolicy) String() string { return "" } func (n noGCPolicy) proto() *bttdpb.GcRule { return &bttdpb.GcRule{Rule: nil} } // NoGcPolicy applies to all cells setting maxage and maxversions to nil implies no gc policies func NoGcPolicy() GCPolicy { return noGCPolicy{} } // GCRuleToString converts the given GcRule proto to a user-visible string. func GCRuleToString(rule *bttdpb.GcRule) string { if rule == nil { return "" } switch r := rule.Rule.(type) { case *bttdpb.GcRule_MaxNumVersions: return MaxVersionsPolicy(int(r.MaxNumVersions)).String() case *bttdpb.GcRule_MaxAge: return MaxAgePolicy(time.Duration(r.MaxAge.Seconds) * time.Second).String() case *bttdpb.GcRule_Intersection_: return joinRules(r.Intersection.Rules, " && ") case *bttdpb.GcRule_Union_: return joinRules(r.Union.Rules, " || ") default: return "" } } func joinRules(rules []*bttdpb.GcRule, sep string) string { var chunks []string for _, r := range rules { chunks = append(chunks, GCRuleToString(r)) } return "(" + strings.Join(chunks, sep) + ")" } google-cloud-go-0.49.0/bigtable/gc_test.go000066400000000000000000000025531356504100700203250ustar00rootroot00000000000000/* Copyright 2017 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package bigtable import ( "testing" "time" bttdpb "google.golang.org/genproto/googleapis/bigtable/admin/v2" ) func TestGcRuleToString(t *testing.T) { intersection := IntersectionPolicy(MaxVersionsPolicy(5), MaxVersionsPolicy(10), MaxAgePolicy(16*time.Hour)) var tests = []struct { proto *bttdpb.GcRule want string }{ {MaxAgePolicy(72 * time.Hour).proto(), "age() > 3d"}, {MaxVersionsPolicy(5).proto(), "versions() > 5"}, {intersection.proto(), "(versions() > 5 && versions() > 10 && age() > 16h)"}, {UnionPolicy(intersection, MaxAgePolicy(72*time.Hour)).proto(), "((versions() > 5 && versions() > 10 && age() > 16h) || age() > 3d)"}, } for _, test := range tests { got := GCRuleToString(test.proto) if got != test.want { t.Errorf("got gc rule string: %v, wanted: %v", got, test.want) } } } google-cloud-go-0.49.0/bigtable/go.mod000066400000000000000000000015741356504100700174560ustar00rootroot00000000000000module cloud.google.com/go/bigtable go 1.11 require ( cloud.google.com/go v0.47.1-0.20191029230648-0c44e5fc99c3 github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 // indirect github.com/golang/protobuf v1.3.2 github.com/google/btree v1.0.0 github.com/google/go-cmp v0.3.1 github.com/googleapis/gax-go/v2 v2.0.5 go.opencensus.io v0.22.1 // indirect golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136 // indirect golang.org/x/net v0.0.0-20191028085509-fe3aa8a45271 // indirect golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 golang.org/x/sys v0.0.0-20191029155521-f43be2a4598c // indirect golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2 // indirect google.golang.org/api v0.14.0 google.golang.org/appengine v1.6.5 // indirect google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9 google.golang.org/grpc v1.24.0 rsc.io/binaryregexp v0.2.0 ) google-cloud-go-0.49.0/bigtable/go.sum000066400000000000000000000501201356504100700174720ustar00rootroot00000000000000cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2 h1:yH/xNMI6CEel8IuF+gaXLvg2N1JZ6pOMkkr25uH8+2k= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3 h1:AVXDdKsrtX33oR9fbCMu/+c1o8Ofjq6Ku/MInaLVg5Y= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.47.1-0.20191029230648-0c44e5fc99c3 h1:kPMz9rfkCbDY1DgBkV8hUyQ4GVw+WmSHe6HMWZDalZ0= cloud.google.com/go v0.47.1-0.20191029230648-0c44e5fc99c3/go.mod h1:tDHScF2RQOxc+IDlv4lWP2QPnIhNPcTVd+D2YqXB7kE= cloud.google.com/go/bigquery v1.0.1 h1:hL+ycaJpVE9M7nLoiXb/Pn10ENE2u+oddxbD8uu0ZVU= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/datastore v1.0.0 h1:Kt+gOPPp2LEPWp8CSfxhsM8ik9CcyE/gYu+0r+RnZvM= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/pubsub v1.0.1 h1:W9tAK3E57P75u0XLLR82LZyw8VpAnhmyTOxW9qzmyj8= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/storage v1.0.0 h1:VV2nUM3wwLLGh9lSABFgZMjInyUbJeaRSE64WuAIQ+4= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 h1:uHTyIjqVhYRhLbJ8nIiOJHkEZZ+5YoOsAbD3sk82NiE= github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024 h1:rBMNdlhTLzJjJSDIjNEXX1Pz3Hmwmz91v+zycvx9PJc= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.1 h1:8dP3SGL7MPB94crU3bEPplMPe83FI4EouesJUeFHv50= go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522 h1:OeRHuibLsmZkFj773W4LcfAGsSxJgfPONhr8cmO+eLA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979 h1:Agxu5KLo8o7Bb634SVDnhIfpTvxmzUwhbYAzBvXt6h4= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191029154019-8994fa331a53 h1:QzIrbrpgiq5AZk7Vyo+9TfeGdhgmGZzAZbnKqRSnkc0= golang.org/x/exp v0.0.0-20191029154019-8994fa331a53/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136 h1:A1gGSx58LAGVHUUsOf7IiR0u8Xb6W51gRwfDBhkdcaw= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422 h1:QzoH/1pFpZguR8NrRHLcO6jKqfv2zpuSqZLgdm7ZmjI= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac h1:8R1esu+8QioDxo4E4mX6bFztO+dMTM49DNAaWfO5OeY= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191028085509-fe3aa8a45271 h1:N66aaryRB3Ax92gH0v3hp1QYZ3zWWCCUR/j8Ifh45Ss= golang.org/x/net v0.0.0-20191028085509-fe3aa8a45271/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0 h1:HyfiK1WMnHj5FXFXatD+Qs1A/xC2Run6RzeW1SyHxpc= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191029155521-f43be2a4598c h1:S/FtSvpNLtFBgjTqcKsRpsa6aVsI6iztaz1bQd9BJwE= golang.org/x/sys v0.0.0-20191029155521-f43be2a4598c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0 h1:Dh6fw+p6FyRl5x/FvNswO1ji0lIGzm3KP8Y9VkS9PTE= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff h1:On1qIo75ByTwFJ4/W2bIqHcwJ9XAqtSWUs8GwRrIhtc= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5 h1:hKsoRgsbwY1NafxrwTs+k64bikrLBkAgPir1TNCj3Zs= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2 h1:EtTFh6h4SAKemS+CURDMTDIANuduG5zKEXShyy18bGA= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0 h1:VGGbLNyPF7dvYHhcUGYBBGCRDDK0RRJAI6KCvo0CL+E= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0 h1:jbyannxz0XFD3zdjgrSUsaJbgpH4eTrkdhRChkHPfO8= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.13.0 h1:Q3Ui3V3/CVinFWFiW39Iw0kMuVrRzYX0wN6OPFp0lTA= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.14.0 h1:uMf5uLi4eQMRrMKhCplNik4U4H8Z6C1br3zOtAa/aDE= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64 h1:iKtrH9Y8mcbADOP0YFaEMth7OfuHY9xHOwNj4znpM1A= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51 h1:Ex1mq5jaJof+kRnYi3SlYJ8KKa9Ao3NHyIT5XJ1gF6U= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191028173616-919d9bdd9fe6 h1:UXl+Zk3jqqcbEVV7ace5lrt4YdA4tXiz3f/KbmD29Vo= google.golang.org/genproto v0.0.0-20191028173616-919d9bdd9fe6/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9 h1:6XzpBoANz1NqMNfDXzc2QmHmbb1vyMsvRfoP5rM+K1I= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1 h1:j6XxA85m/6txkUCHvzlV5f+HBNl/1r5cZ2A/3IEFOO8= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.24.0 h1:vb/1TCsVn3DcJlQ0Gs1yB1pKI6Do2/QNwxdKqmc/b0s= google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a h1:LJwr7TCTghdatWv40WobzlKXc9c4s8oGa7QKJUtHhWA= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= google-cloud-go-0.49.0/bigtable/go_mod_tidy_hack.go000066400000000000000000000016271356504100700221610ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // This file, and the cloud.google.com/go import, won't actually become part of // the resultant binary. // +build modhack package bigtable // Necessary for safely adding multi-module repo. See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository import _ "cloud.google.com/go" google-cloud-go-0.49.0/bigtable/integration_test.go000066400000000000000000001571071356504100700222650ustar00rootroot00000000000000/* Copyright 2019 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package bigtable import ( "context" "flag" "fmt" "math" "math/rand" "sort" "strings" "sync" "testing" "time" "cloud.google.com/go/internal/testutil" "github.com/golang/protobuf/proto" "google.golang.org/api/iterator" btapb "google.golang.org/genproto/googleapis/bigtable/admin/v2" ) var presidentsSocialGraph = map[string][]string{ "wmckinley": {"tjefferson"}, "gwashington": {"jadams"}, "tjefferson": {"gwashington", "jadams"}, "jadams": {"gwashington", "tjefferson"}, } func populatePresidentsGraph(table *Table) error { ctx := context.Background() for row, ss := range presidentsSocialGraph { mut := NewMutation() for _, name := range ss { mut.Set("follows", name, 1000, []byte("1")) } if err := table.Apply(ctx, row, mut); err != nil { return fmt.Errorf("Mutating row %q: %v", row, err) } } return nil } var instanceToCreate string var instanceToCreateZone string var instanceToCreateZone2 string func init() { // Don't test instance creation by default, as quota is necessary and aborted tests could strand resources. flag.StringVar(&instanceToCreate, "it.instance-to-create", "", "The id of an instance to create, update and delete. Requires sufficient Cloud Bigtable quota. Requires that it.use-prod is true.") flag.StringVar(&instanceToCreateZone, "it.instance-to-create-zone", "us-central1-b", "The zone in which to create the new test instance.") flag.StringVar(&instanceToCreateZone2, "it.instance-to-create-zone2", "us-east1-c", "The zone in which to create a second cluster in the test instance.") } func TestIntegration_ConditionalMutations(t *testing.T) { ctx := context.Background() _, _, table, _, cleanup, err := setupIntegration(ctx, t) if err != nil { t.Fatal(err) } defer cleanup() if err := populatePresidentsGraph(table); err != nil { t.Fatal(err) } // Do a conditional mutation with a complex filter. mutTrue := NewMutation() mutTrue.Set("follows", "wmckinley", 1000, []byte("1")) filter := ChainFilters(ColumnFilter("gwash[iz].*"), ValueFilter(".")) mut := NewCondMutation(filter, mutTrue, nil) if err := table.Apply(ctx, "tjefferson", mut); err != nil { t.Fatalf("Conditionally mutating row: %v", err) } // Do a second condition mutation with a filter that does not match, // and thus no changes should be made. mutTrue = NewMutation() mutTrue.DeleteRow() filter = ColumnFilter("snoop.dogg") mut = NewCondMutation(filter, mutTrue, nil) if err := table.Apply(ctx, "tjefferson", mut); err != nil { t.Fatalf("Conditionally mutating row: %v", err) } // Fetch a row. row, err := table.ReadRow(ctx, "jadams") if err != nil { t.Fatalf("Reading a row: %v", err) } wantRow := Row{ "follows": []ReadItem{ {Row: "jadams", Column: "follows:gwashington", Timestamp: 1000, Value: []byte("1")}, {Row: "jadams", Column: "follows:tjefferson", Timestamp: 1000, Value: []byte("1")}, }, } if !testutil.Equal(row, wantRow) { t.Fatalf("Read row mismatch.\n got %#v\nwant %#v", row, wantRow) } } func TestIntegration_PartialReadRows(t *testing.T) { ctx := context.Background() _, _, table, _, cleanup, err := setupIntegration(ctx, t) if err != nil { t.Fatal(err) } defer cleanup() if err := populatePresidentsGraph(table); err != nil { t.Fatal(err) } // Do a scan and stop part way through. // Verify that the ReadRows callback doesn't keep running. stopped := false err = table.ReadRows(ctx, InfiniteRange(""), func(r Row) bool { if r.Key() < "h" { return true } if !stopped { stopped = true return false } t.Fatalf("ReadRows kept scanning to row %q after being told to stop", r.Key()) return false }) if err != nil { t.Fatalf("Partial ReadRows: %v", err) } } func TestIntegration_ReadRowList(t *testing.T) { ctx := context.Background() _, _, table, _, cleanup, err := setupIntegration(ctx, t) if err != nil { t.Fatal(err) } defer cleanup() if err := populatePresidentsGraph(table); err != nil { t.Fatal(err) } // Read a RowList var elt []string keys := RowList{"wmckinley", "gwashington", "jadams"} want := "gwashington-jadams-1,jadams-gwashington-1,jadams-tjefferson-1,wmckinley-tjefferson-1" err = table.ReadRows(ctx, keys, func(r Row) bool { for _, ris := range r { for _, ri := range ris { elt = append(elt, formatReadItem(ri)) } } return true }) if err != nil { t.Fatalf("read RowList: %v", err) } if got := strings.Join(elt, ","); got != want { t.Fatalf("bulk read: wrong reads.\n got %q\nwant %q", got, want) } } func TestIntegration_DeleteRow(t *testing.T) { ctx := context.Background() _, _, table, _, cleanup, err := setupIntegration(ctx, t) if err != nil { t.Fatal(err) } defer cleanup() if err := populatePresidentsGraph(table); err != nil { t.Fatal(err) } // Delete a row and check it goes away. mut := NewMutation() mut.DeleteRow() if err := table.Apply(ctx, "wmckinley", mut); err != nil { t.Fatalf("Apply DeleteRow: %v", err) } row, err := table.ReadRow(ctx, "wmckinley") if err != nil { t.Fatalf("Reading a row after DeleteRow: %v", err) } if len(row) != 0 { t.Fatalf("Read non-zero row after DeleteRow: %v", row) } } func TestIntegration_ReadModifyWrite(t *testing.T) { ctx := context.Background() _, adminClient, table, tableName, cleanup, err := setupIntegration(ctx, t) if err != nil { t.Fatal(err) } defer cleanup() if err := populatePresidentsGraph(table); err != nil { t.Fatal(err) } if err := adminClient.CreateColumnFamily(ctx, tableName, "counter"); err != nil { t.Fatalf("Creating column family: %v", err) } appendRMW := func(b []byte) *ReadModifyWrite { rmw := NewReadModifyWrite() rmw.AppendValue("counter", "likes", b) return rmw } incRMW := func(n int64) *ReadModifyWrite { rmw := NewReadModifyWrite() rmw.Increment("counter", "likes", n) return rmw } rmwSeq := []struct { desc string rmw *ReadModifyWrite want []byte }{ { desc: "append #1", rmw: appendRMW([]byte{0, 0, 0}), want: []byte{0, 0, 0}, }, { desc: "append #2", rmw: appendRMW([]byte{0, 0, 0, 0, 17}), // the remaining 40 bits to make a big-endian 17 want: []byte{0, 0, 0, 0, 0, 0, 0, 17}, }, { desc: "increment", rmw: incRMW(8), want: []byte{0, 0, 0, 0, 0, 0, 0, 25}, }, } for _, step := range rmwSeq { row, err := table.ApplyReadModifyWrite(ctx, "gwashington", step.rmw) if err != nil { t.Fatalf("ApplyReadModifyWrite %+v: %v", step.rmw, err) } // Make sure the modified cell returned by the RMW operation has a timestamp. if row["counter"][0].Timestamp == 0 { t.Fatalf("RMW returned cell timestamp: got %v, want > 0", row["counter"][0].Timestamp) } clearTimestamps(row) wantRow := Row{"counter": []ReadItem{{Row: "gwashington", Column: "counter:likes", Value: step.want}}} if !testutil.Equal(row, wantRow) { t.Fatalf("After %s,\n got %v\nwant %v", step.desc, row, wantRow) } } // Check for google-cloud-go/issues/723. RMWs that insert new rows should keep row order sorted in the emulator. _, err = table.ApplyReadModifyWrite(ctx, "issue-723-2", appendRMW([]byte{0})) if err != nil { t.Fatalf("ApplyReadModifyWrite null string: %v", err) } _, err = table.ApplyReadModifyWrite(ctx, "issue-723-1", appendRMW([]byte{0})) if err != nil { t.Fatalf("ApplyReadModifyWrite null string: %v", err) } // Get only the correct row back on read. r, err := table.ReadRow(ctx, "issue-723-1") if err != nil { t.Fatalf("Reading row: %v", err) } if r.Key() != "issue-723-1" { t.Fatalf("ApplyReadModifyWrite: incorrect read after RMW,\n got %v\nwant %v", r.Key(), "issue-723-1") } } func TestIntegration_ArbitraryTimestamps(t *testing.T) { ctx := context.Background() _, adminClient, table, tableName, cleanup, err := setupIntegration(ctx, t) if err != nil { t.Fatal(err) } defer cleanup() // Test arbitrary timestamps more thoroughly. if err := adminClient.CreateColumnFamily(ctx, tableName, "ts"); err != nil { t.Fatalf("Creating column family: %v", err) } const numVersions = 4 mut := NewMutation() for i := 1; i < numVersions; i++ { // Timestamps are used in thousands because the server // only permits that granularity. mut.Set("ts", "col", Timestamp(i*1000), []byte(fmt.Sprintf("val-%d", i))) mut.Set("ts", "col2", Timestamp(i*1000), []byte(fmt.Sprintf("val-%d", i))) } if err := table.Apply(ctx, "testrow", mut); err != nil { t.Fatalf("Mutating row: %v", err) } r, err := table.ReadRow(ctx, "testrow") if err != nil { t.Fatalf("Reading row: %v", err) } wantRow := Row{"ts": []ReadItem{ // These should be returned in descending timestamp order. {Row: "testrow", Column: "ts:col", Timestamp: 3000, Value: []byte("val-3")}, {Row: "testrow", Column: "ts:col", Timestamp: 2000, Value: []byte("val-2")}, {Row: "testrow", Column: "ts:col", Timestamp: 1000, Value: []byte("val-1")}, {Row: "testrow", Column: "ts:col2", Timestamp: 3000, Value: []byte("val-3")}, {Row: "testrow", Column: "ts:col2", Timestamp: 2000, Value: []byte("val-2")}, {Row: "testrow", Column: "ts:col2", Timestamp: 1000, Value: []byte("val-1")}, }} if !testutil.Equal(r, wantRow) { t.Fatalf("Cell with multiple versions,\n got %v\nwant %v", r, wantRow) } // Do the same read, but filter to the latest two versions. r, err = table.ReadRow(ctx, "testrow", RowFilter(LatestNFilter(2))) if err != nil { t.Fatalf("Reading row: %v", err) } wantRow = Row{"ts": []ReadItem{ {Row: "testrow", Column: "ts:col", Timestamp: 3000, Value: []byte("val-3")}, {Row: "testrow", Column: "ts:col", Timestamp: 2000, Value: []byte("val-2")}, {Row: "testrow", Column: "ts:col2", Timestamp: 3000, Value: []byte("val-3")}, {Row: "testrow", Column: "ts:col2", Timestamp: 2000, Value: []byte("val-2")}, }} if !testutil.Equal(r, wantRow) { t.Fatalf("Cell with multiple versions and LatestNFilter(2),\n got %v\nwant %v", r, wantRow) } // Check cell offset / limit r, err = table.ReadRow(ctx, "testrow", RowFilter(CellsPerRowLimitFilter(3))) if err != nil { t.Fatalf("Reading row: %v", err) } wantRow = Row{"ts": []ReadItem{ {Row: "testrow", Column: "ts:col", Timestamp: 3000, Value: []byte("val-3")}, {Row: "testrow", Column: "ts:col", Timestamp: 2000, Value: []byte("val-2")}, {Row: "testrow", Column: "ts:col", Timestamp: 1000, Value: []byte("val-1")}, }} if !testutil.Equal(r, wantRow) { t.Fatalf("Cell with multiple versions and CellsPerRowLimitFilter(3),\n got %v\nwant %v", r, wantRow) } r, err = table.ReadRow(ctx, "testrow", RowFilter(CellsPerRowOffsetFilter(3))) if err != nil { t.Fatalf("Reading row: %v", err) } wantRow = Row{"ts": []ReadItem{ {Row: "testrow", Column: "ts:col2", Timestamp: 3000, Value: []byte("val-3")}, {Row: "testrow", Column: "ts:col2", Timestamp: 2000, Value: []byte("val-2")}, {Row: "testrow", Column: "ts:col2", Timestamp: 1000, Value: []byte("val-1")}, }} if !testutil.Equal(r, wantRow) { t.Fatalf("Cell with multiple versions and CellsPerRowOffsetFilter(3),\n got %v\nwant %v", r, wantRow) } // Check timestamp range filtering (with truncation) r, err = table.ReadRow(ctx, "testrow", RowFilter(TimestampRangeFilterMicros(1001, 3000))) if err != nil { t.Fatalf("Reading row: %v", err) } wantRow = Row{"ts": []ReadItem{ {Row: "testrow", Column: "ts:col", Timestamp: 2000, Value: []byte("val-2")}, {Row: "testrow", Column: "ts:col", Timestamp: 1000, Value: []byte("val-1")}, {Row: "testrow", Column: "ts:col2", Timestamp: 2000, Value: []byte("val-2")}, {Row: "testrow", Column: "ts:col2", Timestamp: 1000, Value: []byte("val-1")}, }} if !testutil.Equal(r, wantRow) { t.Fatalf("Cell with multiple versions and TimestampRangeFilter(1000, 3000),\n got %v\nwant %v", r, wantRow) } r, err = table.ReadRow(ctx, "testrow", RowFilter(TimestampRangeFilterMicros(1000, 0))) if err != nil { t.Fatalf("Reading row: %v", err) } wantRow = Row{"ts": []ReadItem{ {Row: "testrow", Column: "ts:col", Timestamp: 3000, Value: []byte("val-3")}, {Row: "testrow", Column: "ts:col", Timestamp: 2000, Value: []byte("val-2")}, {Row: "testrow", Column: "ts:col", Timestamp: 1000, Value: []byte("val-1")}, {Row: "testrow", Column: "ts:col2", Timestamp: 3000, Value: []byte("val-3")}, {Row: "testrow", Column: "ts:col2", Timestamp: 2000, Value: []byte("val-2")}, {Row: "testrow", Column: "ts:col2", Timestamp: 1000, Value: []byte("val-1")}, }} if !testutil.Equal(r, wantRow) { t.Fatalf("Cell with multiple versions and TimestampRangeFilter(1000, 0),\n got %v\nwant %v", r, wantRow) } // Delete non-existing cells, no such column family in this row // Should not delete anything if err := adminClient.CreateColumnFamily(ctx, tableName, "non-existing"); err != nil { t.Fatalf("Creating column family: %v", err) } mut = NewMutation() mut.DeleteTimestampRange("non-existing", "col", 2000, 3000) // half-open interval if err := table.Apply(ctx, "testrow", mut); err != nil { t.Fatalf("Mutating row: %v", err) } r, err = table.ReadRow(ctx, "testrow", RowFilter(LatestNFilter(3))) if err != nil { t.Fatalf("Reading row: %v", err) } if !testutil.Equal(r, wantRow) { t.Fatalf("Cell was deleted unexpectly,\n got %v\nwant %v", r, wantRow) } // Delete non-existing cells, no such column in this column family // Should not delete anything mut = NewMutation() mut.DeleteTimestampRange("ts", "non-existing", 2000, 3000) // half-open interval if err := table.Apply(ctx, "testrow", mut); err != nil { t.Fatalf("Mutating row: %v", err) } r, err = table.ReadRow(ctx, "testrow", RowFilter(LatestNFilter(3))) if err != nil { t.Fatalf("Reading row: %v", err) } if !testutil.Equal(r, wantRow) { t.Fatalf("Cell was deleted unexpectly,\n got %v\nwant %v", r, wantRow) } // Delete the cell with timestamp 2000 and repeat the last read, // checking that we get ts 3000 and ts 1000. mut = NewMutation() mut.DeleteTimestampRange("ts", "col", 2001, 3000) // half-open interval if err := table.Apply(ctx, "testrow", mut); err != nil { t.Fatalf("Mutating row: %v", err) } r, err = table.ReadRow(ctx, "testrow", RowFilter(LatestNFilter(2))) if err != nil { t.Fatalf("Reading row: %v", err) } wantRow = Row{"ts": []ReadItem{ {Row: "testrow", Column: "ts:col", Timestamp: 3000, Value: []byte("val-3")}, {Row: "testrow", Column: "ts:col", Timestamp: 1000, Value: []byte("val-1")}, {Row: "testrow", Column: "ts:col2", Timestamp: 3000, Value: []byte("val-3")}, {Row: "testrow", Column: "ts:col2", Timestamp: 2000, Value: []byte("val-2")}, }} if !testutil.Equal(r, wantRow) { t.Fatalf("Cell with multiple versions and LatestNFilter(2), after deleting timestamp 2000,\n got %v\nwant %v", r, wantRow) } // Check DeleteCellsInFamily if err := adminClient.CreateColumnFamily(ctx, tableName, "status"); err != nil { t.Fatalf("Creating column family: %v", err) } mut = NewMutation() mut.Set("status", "start", 2000, []byte("2")) mut.Set("status", "end", 3000, []byte("3")) mut.Set("ts", "col", 1000, []byte("1")) if err := table.Apply(ctx, "row1", mut); err != nil { t.Fatalf("Mutating row: %v", err) } if err := table.Apply(ctx, "row2", mut); err != nil { t.Fatalf("Mutating row: %v", err) } mut = NewMutation() mut.DeleteCellsInFamily("status") if err := table.Apply(ctx, "row1", mut); err != nil { t.Fatalf("Delete cf: %v", err) } // ColumnFamily removed r, err = table.ReadRow(ctx, "row1") if err != nil { t.Fatalf("Reading row: %v", err) } wantRow = Row{"ts": []ReadItem{ {Row: "row1", Column: "ts:col", Timestamp: 1000, Value: []byte("1")}, }} if !testutil.Equal(r, wantRow) { t.Fatalf("column family was not deleted.\n got %v\n want %v", r, wantRow) } // ColumnFamily not removed r, err = table.ReadRow(ctx, "row2") if err != nil { t.Fatalf("Reading row: %v", err) } wantRow = Row{ "ts": []ReadItem{ {Row: "row2", Column: "ts:col", Timestamp: 1000, Value: []byte("1")}, }, "status": []ReadItem{ {Row: "row2", Column: "status:end", Timestamp: 3000, Value: []byte("3")}, {Row: "row2", Column: "status:start", Timestamp: 2000, Value: []byte("2")}, }, } if !testutil.Equal(r, wantRow) { t.Fatalf("Column family was deleted unexpectedly.\n got %v\n want %v", r, wantRow) } // Check DeleteCellsInColumn mut = NewMutation() mut.Set("status", "start", 2000, []byte("2")) mut.Set("status", "middle", 3000, []byte("3")) mut.Set("status", "end", 1000, []byte("1")) if err := table.Apply(ctx, "row3", mut); err != nil { t.Fatalf("Mutating row: %v", err) } mut = NewMutation() mut.DeleteCellsInColumn("status", "middle") if err := table.Apply(ctx, "row3", mut); err != nil { t.Fatalf("Delete column: %v", err) } r, err = table.ReadRow(ctx, "row3") if err != nil { t.Fatalf("Reading row: %v", err) } wantRow = Row{ "status": []ReadItem{ {Row: "row3", Column: "status:end", Timestamp: 1000, Value: []byte("1")}, {Row: "row3", Column: "status:start", Timestamp: 2000, Value: []byte("2")}, }, } if !testutil.Equal(r, wantRow) { t.Fatalf("Column was not deleted.\n got %v\n want %v", r, wantRow) } mut = NewMutation() mut.DeleteCellsInColumn("status", "start") if err := table.Apply(ctx, "row3", mut); err != nil { t.Fatalf("Delete column: %v", err) } r, err = table.ReadRow(ctx, "row3") if err != nil { t.Fatalf("Reading row: %v", err) } wantRow = Row{ "status": []ReadItem{ {Row: "row3", Column: "status:end", Timestamp: 1000, Value: []byte("1")}, }, } if !testutil.Equal(r, wantRow) { t.Fatalf("Column was not deleted.\n got %v\n want %v", r, wantRow) } mut = NewMutation() mut.DeleteCellsInColumn("status", "end") if err := table.Apply(ctx, "row3", mut); err != nil { t.Fatalf("Delete column: %v", err) } r, err = table.ReadRow(ctx, "row3") if err != nil { t.Fatalf("Reading row: %v", err) } if len(r) != 0 { t.Fatalf("Delete column: got %v, want empty row", r) } // Add same cell after delete mut = NewMutation() mut.Set("status", "end", 1000, []byte("1")) if err := table.Apply(ctx, "row3", mut); err != nil { t.Fatalf("Mutating row: %v", err) } r, err = table.ReadRow(ctx, "row3") if err != nil { t.Fatalf("Reading row: %v", err) } if !testutil.Equal(r, wantRow) { t.Fatalf("Column was not deleted correctly.\n got %v\n want %v", r, wantRow) } } func TestIntegration_HighlyConcurrentReadsAndWrites(t *testing.T) { ctx := context.Background() _, adminClient, table, tableName, cleanup, err := setupIntegration(ctx, t) if err != nil { t.Fatal(err) } defer cleanup() if err := populatePresidentsGraph(table); err != nil { t.Fatal(err) } if err := adminClient.CreateColumnFamily(ctx, tableName, "ts"); err != nil { t.Fatalf("Creating column family: %v", err) } // Do highly concurrent reads/writes. const maxConcurrency = 1000 var wg sync.WaitGroup for i := 0; i < maxConcurrency; i++ { wg.Add(1) go func() { defer wg.Done() switch r := rand.Intn(100); { // r ∈ [0,100) case 0 <= r && r < 30: // Do a read. _, err := table.ReadRow(ctx, "testrow", RowFilter(LatestNFilter(1))) if err != nil { t.Errorf("Concurrent read: %v", err) } case 30 <= r && r < 100: // Do a write. mut := NewMutation() mut.Set("ts", "col", 1000, []byte("data")) if err := table.Apply(ctx, "testrow", mut); err != nil { t.Errorf("Concurrent write: %v", err) } } }() } wg.Wait() } func TestIntegration_LargeReadsWritesAndScans(t *testing.T) { ctx := context.Background() _, adminClient, table, tableName, cleanup, err := setupIntegration(ctx, t) if err != nil { t.Fatal(err) } defer cleanup() if err := adminClient.CreateColumnFamily(ctx, tableName, "ts"); err != nil { t.Fatalf("Creating column family: %v", err) } bigBytes := make([]byte, 5<<20) // 5 MB is larger than current default gRPC max of 4 MB, but less than the max we set. nonsense := []byte("lorem ipsum dolor sit amet, ") fill(bigBytes, nonsense) mut := NewMutation() mut.Set("ts", "col", 1000, bigBytes) if err := table.Apply(ctx, "bigrow", mut); err != nil { t.Fatalf("Big write: %v", err) } r, err := table.ReadRow(ctx, "bigrow") if err != nil { t.Fatalf("Big read: %v", err) } wantRow := Row{"ts": []ReadItem{ {Row: "bigrow", Column: "ts:col", Timestamp: 1000, Value: bigBytes}, }} if !testutil.Equal(r, wantRow) { t.Fatalf("Big read returned incorrect bytes: %v", r) } var wg sync.WaitGroup // Now write 1000 rows, each with 82 KB values, then scan them all. medBytes := make([]byte, 82<<10) fill(medBytes, nonsense) sem := make(chan int, 50) // do up to 50 mutations at a time. for i := 0; i < 1000; i++ { mut := NewMutation() mut.Set("ts", "big-scan", 1000, medBytes) row := fmt.Sprintf("row-%d", i) wg.Add(1) go func() { defer wg.Done() defer func() { <-sem }() sem <- 1 if err := table.Apply(ctx, row, mut); err != nil { t.Errorf("Preparing large scan: %v", err) } }() } wg.Wait() n := 0 err = table.ReadRows(ctx, PrefixRange("row-"), func(r Row) bool { for _, ris := range r { for _, ri := range ris { n += len(ri.Value) } } return true }, RowFilter(ColumnFilter("big-scan"))) if err != nil { t.Fatalf("Doing large scan: %v", err) } if want := 1000 * len(medBytes); n != want { t.Fatalf("Large scan returned %d bytes, want %d", n, want) } // Scan a subset of the 1000 rows that we just created, using a LimitRows ReadOption. rc := 0 wantRc := 3 err = table.ReadRows(ctx, PrefixRange("row-"), func(r Row) bool { rc++ return true }, LimitRows(int64(wantRc))) if err != nil { t.Fatal(err) } if rc != wantRc { t.Fatalf("Scan with row limit returned %d rows, want %d", rc, wantRc) } // Test bulk mutations if err := adminClient.CreateColumnFamily(ctx, tableName, "bulk"); err != nil { t.Fatalf("Creating column family: %v", err) } bulkData := map[string][]string{ "red sox": {"2004", "2007", "2013"}, "patriots": {"2001", "2003", "2004", "2014"}, "celtics": {"1981", "1984", "1986", "2008"}, } var rowKeys []string var muts []*Mutation for row, ss := range bulkData { mut := NewMutation() for _, name := range ss { mut.Set("bulk", name, 1000, []byte("1")) } rowKeys = append(rowKeys, row) muts = append(muts, mut) } status, err := table.ApplyBulk(ctx, rowKeys, muts) if err != nil { t.Fatalf("Bulk mutating rows %q: %v", rowKeys, err) } if status != nil { t.Fatalf("non-nil errors: %v", err) } // Read each row back for rowKey, ss := range bulkData { row, err := table.ReadRow(ctx, rowKey) if err != nil { t.Fatalf("Reading a bulk row: %v", err) } var wantItems []ReadItem for _, val := range ss { wantItems = append(wantItems, ReadItem{Row: rowKey, Column: "bulk:" + val, Timestamp: 1000, Value: []byte("1")}) } wantRow := Row{"bulk": wantItems} if !testutil.Equal(row, wantRow) { t.Fatalf("Read row mismatch.\n got %#v\nwant %#v", row, wantRow) } } // Test bulk write errors. // Note: Setting timestamps as ServerTime makes sure the mutations are not retried on error. badMut := NewMutation() badMut.Set("badfamily", "col", ServerTime, nil) badMut2 := NewMutation() badMut2.Set("badfamily2", "goodcol", ServerTime, []byte("1")) status, err = table.ApplyBulk(ctx, []string{"badrow", "badrow2"}, []*Mutation{badMut, badMut2}) if err != nil { t.Fatalf("Bulk mutating rows %q: %v", rowKeys, err) } if status == nil { t.Fatalf("No errors for bad bulk mutation") } else if status[0] == nil || status[1] == nil { t.Fatalf("No error for bad bulk mutation") } } func TestIntegration_Read(t *testing.T) { ctx := context.Background() _, _, table, _, cleanup, err := setupIntegration(ctx, t) if err != nil { t.Fatal(err) } defer cleanup() // Insert some data. initialData := map[string][]string{ "wmckinley": {"tjefferson"}, "gwashington": {"jadams"}, "tjefferson": {"gwashington", "jadams", "wmckinley"}, "jadams": {"gwashington", "tjefferson"}, } for row, ss := range initialData { mut := NewMutation() for _, name := range ss { mut.Set("follows", name, 1000, []byte("1")) } if err := table.Apply(ctx, row, mut); err != nil { t.Fatalf("Mutating row %q: %v", row, err) } } for _, test := range []struct { desc string rr RowSet filter Filter // may be nil limit ReadOption // may be nil // We do the read, grab all the cells, turn them into "--", // and join with a comma. want string }{ { desc: "read all, unfiltered", rr: RowRange{}, want: "gwashington-jadams-1,jadams-gwashington-1,jadams-tjefferson-1,tjefferson-gwashington-1,tjefferson-jadams-1,tjefferson-wmckinley-1,wmckinley-tjefferson-1", }, { desc: "read with InfiniteRange, unfiltered", rr: InfiniteRange("tjefferson"), want: "tjefferson-gwashington-1,tjefferson-jadams-1,tjefferson-wmckinley-1,wmckinley-tjefferson-1", }, { desc: "read with NewRange, unfiltered", rr: NewRange("gargamel", "hubbard"), want: "gwashington-jadams-1", }, { desc: "read with PrefixRange, unfiltered", rr: PrefixRange("jad"), want: "jadams-gwashington-1,jadams-tjefferson-1", }, { desc: "read with SingleRow, unfiltered", rr: SingleRow("wmckinley"), want: "wmckinley-tjefferson-1", }, { desc: "read all, with ColumnFilter", rr: RowRange{}, filter: ColumnFilter(".*j.*"), // matches "jadams" and "tjefferson" want: "gwashington-jadams-1,jadams-tjefferson-1,tjefferson-jadams-1,wmckinley-tjefferson-1", }, { desc: "read all, with ColumnFilter, prefix", rr: RowRange{}, filter: ColumnFilter("j"), // no matches want: "", }, { desc: "read range, with ColumnRangeFilter", rr: RowRange{}, filter: ColumnRangeFilter("follows", "h", "k"), want: "gwashington-jadams-1,tjefferson-jadams-1", }, { desc: "read range from empty, with ColumnRangeFilter", rr: RowRange{}, filter: ColumnRangeFilter("follows", "", "u"), want: "gwashington-jadams-1,jadams-gwashington-1,jadams-tjefferson-1,tjefferson-gwashington-1,tjefferson-jadams-1,wmckinley-tjefferson-1", }, { desc: "read range from start to empty, with ColumnRangeFilter", rr: RowRange{}, filter: ColumnRangeFilter("follows", "h", ""), want: "gwashington-jadams-1,jadams-tjefferson-1,tjefferson-jadams-1,tjefferson-wmckinley-1,wmckinley-tjefferson-1", }, { desc: "read with RowKeyFilter", rr: RowRange{}, filter: RowKeyFilter(".*wash.*"), want: "gwashington-jadams-1", }, { desc: "read with RowKeyFilter, prefix", rr: RowRange{}, filter: RowKeyFilter("gwash"), want: "", }, { desc: "read with RowKeyFilter, no matches", rr: RowRange{}, filter: RowKeyFilter(".*xxx.*"), want: "", }, { desc: "read with FamilyFilter, no matches", rr: RowRange{}, filter: FamilyFilter(".*xxx.*"), want: "", }, { desc: "read with ColumnFilter + row limit", rr: RowRange{}, filter: ColumnFilter(".*j.*"), // matches "jadams" and "tjefferson" limit: LimitRows(2), want: "gwashington-jadams-1,jadams-tjefferson-1", }, { desc: "read all, strip values", rr: RowRange{}, filter: StripValueFilter(), want: "gwashington-jadams-,jadams-gwashington-,jadams-tjefferson-,tjefferson-gwashington-,tjefferson-jadams-,tjefferson-wmckinley-,wmckinley-tjefferson-", }, { desc: "read with ColumnFilter + row limit + strip values", rr: RowRange{}, filter: ChainFilters(ColumnFilter(".*j.*"), StripValueFilter()), // matches "jadams" and "tjefferson" limit: LimitRows(2), want: "gwashington-jadams-,jadams-tjefferson-", }, { desc: "read with condition, strip values on true", rr: RowRange{}, filter: ConditionFilter(ColumnFilter(".*j.*"), StripValueFilter(), nil), want: "gwashington-jadams-,jadams-gwashington-,jadams-tjefferson-,tjefferson-gwashington-,tjefferson-jadams-,tjefferson-wmckinley-,wmckinley-tjefferson-", }, { desc: "read with condition, strip values on false", rr: RowRange{}, filter: ConditionFilter(ColumnFilter(".*xxx.*"), nil, StripValueFilter()), want: "gwashington-jadams-,jadams-gwashington-,jadams-tjefferson-,tjefferson-gwashington-,tjefferson-jadams-,tjefferson-wmckinley-,wmckinley-tjefferson-", }, { desc: "read with ValueRangeFilter + row limit", rr: RowRange{}, filter: ValueRangeFilter([]byte("1"), []byte("5")), // matches our value of "1" limit: LimitRows(2), want: "gwashington-jadams-1,jadams-gwashington-1,jadams-tjefferson-1", }, { desc: "read with ValueRangeFilter, no match on exclusive end", rr: RowRange{}, filter: ValueRangeFilter([]byte("0"), []byte("1")), // no match want: "", }, { desc: "read with ValueRangeFilter, no matches", rr: RowRange{}, filter: ValueRangeFilter([]byte("3"), []byte("5")), // matches nothing want: "", }, { desc: "read with InterleaveFilter, no matches on all filters", rr: RowRange{}, filter: InterleaveFilters(ColumnFilter(".*x.*"), ColumnFilter(".*z.*")), want: "", }, { desc: "read with InterleaveFilter, no duplicate cells", rr: RowRange{}, filter: InterleaveFilters(ColumnFilter(".*g.*"), ColumnFilter(".*j.*")), want: "gwashington-jadams-1,jadams-gwashington-1,jadams-tjefferson-1,tjefferson-gwashington-1,tjefferson-jadams-1,wmckinley-tjefferson-1", }, { desc: "read with InterleaveFilter, with duplicate cells", rr: RowRange{}, filter: InterleaveFilters(ColumnFilter(".*g.*"), ColumnFilter(".*g.*")), want: "jadams-gwashington-1,jadams-gwashington-1,tjefferson-gwashington-1,tjefferson-gwashington-1", }, { desc: "read with a RowRangeList and no filter", rr: RowRangeList{NewRange("gargamel", "hubbard"), InfiniteRange("wmckinley")}, want: "gwashington-jadams-1,wmckinley-tjefferson-1", }, { desc: "chain that excludes rows and matches nothing, in a condition", rr: RowRange{}, filter: ConditionFilter(ChainFilters(ColumnFilter(".*j.*"), ColumnFilter(".*mckinley.*")), StripValueFilter(), nil), want: "", }, { desc: "chain that ends with an interleave that has no match. covers #804", rr: RowRange{}, filter: ConditionFilter(ChainFilters(ColumnFilter(".*j.*"), InterleaveFilters(ColumnFilter(".*x.*"), ColumnFilter(".*z.*"))), StripValueFilter(), nil), want: "", }, } { t.Run(test.desc, func(t *testing.T) { var opts []ReadOption if test.filter != nil { opts = append(opts, RowFilter(test.filter)) } if test.limit != nil { opts = append(opts, test.limit) } var elt []string err := table.ReadRows(ctx, test.rr, func(r Row) bool { for _, ris := range r { for _, ri := range ris { elt = append(elt, formatReadItem(ri)) } } return true }, opts...) if err != nil { t.Fatal(err) } if got := strings.Join(elt, ","); got != test.want { t.Fatalf("got %q\nwant %q", got, test.want) } }) } } func TestIntegration_SampleRowKeys(t *testing.T) { ctx := context.Background() _, _, table, _, cleanup, err := setupIntegration(ctx, t) if err != nil { t.Fatal(err) } defer cleanup() // Insert some data. initialData := map[string][]string{ "wmckinley11": {"tjefferson11"}, "gwashington77": {"jadams77"}, "tjefferson0": {"gwashington0", "jadams0"}, } for row, ss := range initialData { mut := NewMutation() for _, name := range ss { mut.Set("follows", name, 1000, []byte("1")) } if err := table.Apply(ctx, row, mut); err != nil { t.Fatalf("Mutating row %q: %v", row, err) } } sampleKeys, err := table.SampleRowKeys(context.Background()) if err != nil { t.Fatalf("%s: %v", "SampleRowKeys:", err) } if len(sampleKeys) == 0 { t.Error("SampleRowKeys length 0") } } func TestIntegration_Admin(t *testing.T) { testEnv, err := NewIntegrationEnv() if err != nil { t.Fatalf("IntegrationEnv: %v", err) } defer testEnv.Close() timeout := 2 * time.Second if testEnv.Config().UseProd { timeout = 5 * time.Minute } ctx, _ := context.WithTimeout(context.Background(), timeout) adminClient, err := testEnv.NewAdminClient() if err != nil { t.Fatalf("NewAdminClient: %v", err) } defer adminClient.Close() iAdminClient, err := testEnv.NewInstanceAdminClient() if err != nil { t.Fatalf("NewInstanceAdminClient: %v", err) } if iAdminClient != nil { defer iAdminClient.Close() iInfo, err := iAdminClient.InstanceInfo(ctx, adminClient.instance) if err != nil { t.Errorf("InstanceInfo: %v", err) } if iInfo.Name != adminClient.instance { t.Errorf("InstanceInfo returned name %#v, want %#v", iInfo.Name, adminClient.instance) } } list := func() []string { tbls, err := adminClient.Tables(ctx) if err != nil { t.Fatalf("Fetching list of tables: %v", err) } sort.Strings(tbls) return tbls } containsAll := func(got, want []string) bool { gotSet := make(map[string]bool) for _, s := range got { gotSet[s] = true } for _, s := range want { if !gotSet[s] { return false } } return true } defer adminClient.DeleteTable(ctx, "mytable") if err := adminClient.CreateTable(ctx, "mytable"); err != nil { t.Fatalf("Creating table: %v", err) } defer adminClient.DeleteTable(ctx, "myothertable") if err := adminClient.CreateTable(ctx, "myothertable"); err != nil { t.Fatalf("Creating table: %v", err) } if got, want := list(), []string{"myothertable", "mytable"}; !containsAll(got, want) { t.Errorf("adminClient.Tables returned %#v, want %#v", got, want) } must(adminClient.WaitForReplication(ctx, "mytable")) if err := adminClient.DeleteTable(ctx, "myothertable"); err != nil { t.Fatalf("Deleting table: %v", err) } tables := list() if got, want := tables, []string{"mytable"}; !containsAll(got, want) { t.Errorf("adminClient.Tables returned %#v, want %#v", got, want) } if got, unwanted := tables, []string{"myothertable"}; containsAll(got, unwanted) { t.Errorf("adminClient.Tables return %#v. unwanted %#v", got, unwanted) } tblConf := TableConf{ TableID: "conftable", Families: map[string]GCPolicy{ "fam1": MaxVersionsPolicy(1), "fam2": MaxVersionsPolicy(2), }, } if err := adminClient.CreateTableFromConf(ctx, &tblConf); err != nil { t.Fatalf("Creating table from TableConf: %v", err) } defer adminClient.DeleteTable(ctx, tblConf.TableID) tblInfo, err := adminClient.TableInfo(ctx, tblConf.TableID) if err != nil { t.Fatalf("Getting table info: %v", err) } sort.Strings(tblInfo.Families) wantFams := []string{"fam1", "fam2"} if !testutil.Equal(tblInfo.Families, wantFams) { t.Errorf("Column family mismatch, got %v, want %v", tblInfo.Families, wantFams) } // Populate mytable and drop row ranges if err = adminClient.CreateColumnFamily(ctx, "mytable", "cf"); err != nil { t.Fatalf("Creating column family: %v", err) } client, err := testEnv.NewClient() if err != nil { t.Fatalf("NewClient: %v", err) } defer client.Close() tbl := client.Open("mytable") prefixes := []string{"a", "b", "c"} for _, prefix := range prefixes { for i := 0; i < 5; i++ { mut := NewMutation() mut.Set("cf", "col", 1000, []byte("1")) if err := tbl.Apply(ctx, fmt.Sprintf("%v-%v", prefix, i), mut); err != nil { t.Fatalf("Mutating row: %v", err) } } } if err = adminClient.DropRowRange(ctx, "mytable", "a"); err != nil { t.Errorf("DropRowRange a: %v", err) } if err = adminClient.DropRowRange(ctx, "mytable", "c"); err != nil { t.Errorf("DropRowRange c: %v", err) } if err = adminClient.DropRowRange(ctx, "mytable", "x"); err != nil { t.Errorf("DropRowRange x: %v", err) } var gotRowCount int must(tbl.ReadRows(ctx, RowRange{}, func(row Row) bool { gotRowCount++ if !strings.HasPrefix(row.Key(), "b") { t.Errorf("Invalid row after dropping range: %v", row) } return true })) if gotRowCount != 5 { t.Errorf("Invalid row count after dropping range: got %v, want %v", gotRowCount, 5) } if err = adminClient.DropAllRows(ctx, "mytable"); err != nil { t.Errorf("DropAllRows mytable: %v", err) } gotRowCount = 0 must(tbl.ReadRows(ctx, RowRange{}, func(row Row) bool { gotRowCount++ return true })) if gotRowCount != 0 { t.Errorf("Invalid row count after truncating table: got %v, want %v", gotRowCount, 0) } } func TestIntegration_TableIam(t *testing.T) { testEnv, err := NewIntegrationEnv() if err != nil { t.Fatalf("IntegrationEnv: %v", err) } defer testEnv.Close() if !testEnv.Config().UseProd { t.Skip("emulator doesn't support IAM Policy creation") } timeout := 5 * time.Minute ctx, _ := context.WithTimeout(context.Background(), timeout) adminClient, err := testEnv.NewAdminClient() if err != nil { t.Fatalf("NewAdminClient: %v", err) } defer adminClient.Close() defer adminClient.DeleteTable(ctx, "mytable") if err := adminClient.CreateTable(ctx, "mytable"); err != nil { t.Fatalf("Creating table: %v", err) } // Verify that the IAM Controls work for Tables. iamHandle := adminClient.TableIAM("mytable") p, err := iamHandle.Policy(ctx) if err != nil { t.Errorf("Iam GetPolicy mytable: %v", err) } if err = iamHandle.SetPolicy(ctx, p); err != nil { t.Errorf("Iam SetPolicy mytable: %v", err) } if _, err = iamHandle.TestPermissions(ctx, []string{"bigtable.tables.get"}); err != nil { t.Errorf("Iam TestPermissions mytable: %v", err) } } func TestIntegration_AdminCreateInstance(t *testing.T) { if instanceToCreate == "" { t.Skip("instanceToCreate not set, skipping instance creation testing") } testEnv, err := NewIntegrationEnv() if err != nil { t.Fatalf("IntegrationEnv: %v", err) } defer testEnv.Close() if !testEnv.Config().UseProd { t.Skip("emulator doesn't support instance creation") } timeout := 5 * time.Minute ctx, _ := context.WithTimeout(context.Background(), timeout) iAdminClient, err := testEnv.NewInstanceAdminClient() if err != nil { t.Fatalf("NewInstanceAdminClient: %v", err) } defer iAdminClient.Close() clusterID := instanceToCreate + "-cluster" // Create a development instance conf := &InstanceConf{ InstanceId: instanceToCreate, ClusterId: clusterID, DisplayName: "test instance", Zone: instanceToCreateZone, InstanceType: DEVELOPMENT, } if err := iAdminClient.CreateInstance(ctx, conf); err != nil { t.Fatalf("CreateInstance: %v", err) } defer iAdminClient.DeleteInstance(ctx, instanceToCreate) iInfo, err := iAdminClient.InstanceInfo(ctx, instanceToCreate) if err != nil { t.Fatalf("InstanceInfo: %v", err) } // Basic return values are tested elsewhere, check instance type if iInfo.InstanceType != DEVELOPMENT { t.Fatalf("Instance is not DEVELOPMENT: %v", err) } // Update everything we can about the instance in one call. confWithClusters := &InstanceWithClustersConfig{ InstanceID: instanceToCreate, DisplayName: "new display name", InstanceType: PRODUCTION, Clusters: []ClusterConfig{ {ClusterID: clusterID, NumNodes: 5, StorageType: HDD}}, } if err = iAdminClient.UpdateInstanceWithClusters(ctx, confWithClusters); err != nil { t.Fatalf("UpdateInstanceWithClusters: %v", err) } iInfo, err = iAdminClient.InstanceInfo(ctx, instanceToCreate) if err != nil { t.Fatalf("InstanceInfo: %v", err) } if iInfo.InstanceType != PRODUCTION { t.Fatalf("Instance type is not PRODUCTION: %v", err) } if got, want := iInfo.DisplayName, confWithClusters.DisplayName; got != want { t.Fatalf("Display name: %q, want: %q", got, want) } cInfo, err := iAdminClient.GetCluster(ctx, instanceToCreate, clusterID) if err != nil { t.Fatalf("GetCluster: %v", err) } if cInfo.ServeNodes != 5 { t.Fatalf("NumNodes: %v, want: %v", cInfo.ServeNodes, 5) } if cInfo.StorageType != HDD { t.Fatalf("StorageType: %v, want: %v", cInfo.StorageType, HDD) } } func TestIntegration_AdminUpdateInstanceAndSyncClusters(t *testing.T) { if instanceToCreate == "" { t.Skip("instanceToCreate not set, skipping instance update testing") } testEnv, err := NewIntegrationEnv() if err != nil { t.Fatalf("IntegrationEnv: %v", err) } defer testEnv.Close() if !testEnv.Config().UseProd { t.Skip("emulator doesn't support instance creation") } timeout := 5 * time.Minute ctx, _ := context.WithTimeout(context.Background(), timeout) iAdminClient, err := testEnv.NewInstanceAdminClient() if err != nil { t.Fatalf("NewInstanceAdminClient: %v", err) } defer iAdminClient.Close() clusterID := instanceToCreate + "-cluster" // Create a development instance conf := &InstanceConf{ InstanceId: instanceToCreate, ClusterId: clusterID, DisplayName: "test instance", Zone: instanceToCreateZone, InstanceType: DEVELOPMENT, } if err := iAdminClient.CreateInstance(ctx, conf); err != nil { t.Fatalf("CreateInstance: %v", err) } defer iAdminClient.DeleteInstance(ctx, instanceToCreate) iInfo, err := iAdminClient.InstanceInfo(ctx, instanceToCreate) if err != nil { t.Fatalf("InstanceInfo: %v", err) } // Basic return values are tested elsewhere, check instance type if iInfo.InstanceType != DEVELOPMENT { t.Fatalf("Instance is not DEVELOPMENT: %v", err) } // Update everything we can about the instance in one call. confWithClusters := &InstanceWithClustersConfig{ InstanceID: instanceToCreate, DisplayName: "new display name", InstanceType: PRODUCTION, Clusters: []ClusterConfig{ {ClusterID: clusterID, NumNodes: 5}}, } results, err := UpdateInstanceAndSyncClusters(ctx, iAdminClient, confWithClusters) if err != nil { t.Fatalf("UpdateInstanceAndSyncClusters: %v", err) } wantResults := UpdateInstanceResults{ InstanceUpdated: true, UpdatedClusters: []string{clusterID}, } if diff := testutil.Diff(*results, wantResults); diff != "" { t.Fatalf("UpdateInstanceResults: got - want +\n%s", diff) } iInfo, err = iAdminClient.InstanceInfo(ctx, instanceToCreate) if err != nil { t.Fatalf("InstanceInfo: %v", err) } if iInfo.InstanceType != PRODUCTION { t.Fatalf("Instance type is not PRODUCTION: %v", err) } if got, want := iInfo.DisplayName, confWithClusters.DisplayName; got != want { t.Fatalf("Display name: %q, want: %q", got, want) } cInfo, err := iAdminClient.GetCluster(ctx, instanceToCreate, clusterID) if err != nil { t.Fatalf("GetCluster: %v", err) } if cInfo.ServeNodes != 5 { t.Fatalf("NumNodes: %v, want: %v", cInfo.ServeNodes, 5) } // Now add a second cluster as the only change. The first cluster must also be provided so // it is not removed. clusterID2 := clusterID + "-2" confWithClusters = &InstanceWithClustersConfig{ InstanceID: instanceToCreate, Clusters: []ClusterConfig{ {ClusterID: clusterID}, {ClusterID: clusterID2, NumNodes: 3, StorageType: SSD, Zone: instanceToCreateZone2}}, } results, err = UpdateInstanceAndSyncClusters(ctx, iAdminClient, confWithClusters) if err != nil { t.Fatalf("UpdateInstanceAndSyncClusters: %v %v", confWithClusters, err) } wantResults = UpdateInstanceResults{ InstanceUpdated: false, CreatedClusters: []string{clusterID2}, } if diff := testutil.Diff(*results, wantResults); diff != "" { t.Fatalf("UpdateInstanceResults: got - want +\n%s", diff) } // Now update one cluster and delete the other confWithClusters = &InstanceWithClustersConfig{ InstanceID: instanceToCreate, Clusters: []ClusterConfig{ {ClusterID: clusterID, NumNodes: 4}}, } results, err = UpdateInstanceAndSyncClusters(ctx, iAdminClient, confWithClusters) if err != nil { t.Fatalf("UpdateInstanceAndSyncClusters: %v %v", confWithClusters, err) } wantResults = UpdateInstanceResults{ InstanceUpdated: false, UpdatedClusters: []string{clusterID}, DeletedClusters: []string{clusterID2}, } if diff := testutil.Diff(*results, wantResults); diff != "" { t.Fatalf("UpdateInstanceResults: got - want +\n%s", diff) } // Make sure the instance looks as we would expect clusters, err := iAdminClient.Clusters(ctx, conf.InstanceId) if err != nil { t.Fatalf("Clusters: %v", err) } if len(clusters) != 1 { t.Fatalf("Clusters length %v, want: 1", len(clusters)) } wantCluster := &ClusterInfo{ Name: clusterID, Zone: instanceToCreateZone, ServeNodes: 4, State: "READY", } if diff := testutil.Diff(clusters[0], wantCluster); diff != "" { t.Fatalf("InstanceEquality: got - want +\n%s", diff) } } func TestIntegration_AdminSnapshot(t *testing.T) { testEnv, err := NewIntegrationEnv() if err != nil { t.Fatalf("IntegrationEnv: %v", err) } defer testEnv.Close() if !testEnv.Config().UseProd { t.Skip("emulator doesn't support snapshots") } timeout := 2 * time.Second if testEnv.Config().UseProd { timeout = 5 * time.Minute } ctx, _ := context.WithTimeout(context.Background(), timeout) adminClient, err := testEnv.NewAdminClient() if err != nil { t.Fatalf("NewAdminClient: %v", err) } defer adminClient.Close() table := testEnv.Config().Table cluster := testEnv.Config().Cluster list := func(cluster string) ([]*SnapshotInfo, error) { infos := []*SnapshotInfo(nil) it := adminClient.Snapshots(ctx, cluster) for { s, err := it.Next() if err == iterator.Done { break } if err != nil { return nil, err } infos = append(infos, s) } return infos, err } // Delete the table at the end of the test. Schedule ahead of time // in case the client fails defer adminClient.DeleteTable(ctx, table) if err := adminClient.CreateTable(ctx, table); err != nil { t.Fatalf("Creating table: %v", err) } // Precondition: no snapshots snapshots, err := list(cluster) if err != nil { t.Fatalf("Initial snapshot list: %v", err) } if got, want := len(snapshots), 0; got != want { t.Fatalf("Initial snapshot list len: %d, want: %d", got, want) } // Create snapshot defer adminClient.DeleteSnapshot(ctx, cluster, "mysnapshot") if err = adminClient.SnapshotTable(ctx, table, cluster, "mysnapshot", 5*time.Hour); err != nil { t.Fatalf("Creating snaphot: %v", err) } // List snapshot snapshots, err = list(cluster) if err != nil { t.Fatalf("Listing snapshots: %v", err) } if got, want := len(snapshots), 1; got != want { t.Fatalf("Listing snapshot count: %d, want: %d", got, want) } if got, want := snapshots[0].Name, "mysnapshot"; got != want { t.Fatalf("Snapshot name: %s, want: %s", got, want) } if got, want := snapshots[0].SourceTable, table; got != want { t.Fatalf("Snapshot SourceTable: %s, want: %s", got, want) } if got, want := snapshots[0].DeleteTime, snapshots[0].CreateTime.Add(5*time.Hour); math.Abs(got.Sub(want).Minutes()) > 1 { t.Fatalf("Snapshot DeleteTime: %s, want: %s", got, want) } // Get snapshot snapshot, err := adminClient.SnapshotInfo(ctx, cluster, "mysnapshot") if err != nil { t.Fatalf("SnapshotInfo: %v", snapshot) } if got, want := *snapshot, *snapshots[0]; got != want { t.Fatalf("SnapshotInfo: %v, want: %v", got, want) } // Restore restoredTable := table + "-restored" defer adminClient.DeleteTable(ctx, restoredTable) if err = adminClient.CreateTableFromSnapshot(ctx, restoredTable, cluster, "mysnapshot"); err != nil { t.Fatalf("CreateTableFromSnapshot: %v", err) } if _, err := adminClient.TableInfo(ctx, restoredTable); err != nil { t.Fatalf("Restored TableInfo: %v", err) } // Delete snapshot if err = adminClient.DeleteSnapshot(ctx, cluster, "mysnapshot"); err != nil { t.Fatalf("DeleteSnapshot: %v", err) } snapshots, err = list(cluster) if err != nil { t.Fatalf("List after Delete: %v", err) } if got, want := len(snapshots), 0; got != want { t.Fatalf("List after delete len: %d, want: %d", got, want) } } func TestIntegration_Granularity(t *testing.T) { testEnv, err := NewIntegrationEnv() if err != nil { t.Fatalf("IntegrationEnv: %v", err) } defer testEnv.Close() timeout := 2 * time.Second if testEnv.Config().UseProd { timeout = 5 * time.Minute } ctx, _ := context.WithTimeout(context.Background(), timeout) adminClient, err := testEnv.NewAdminClient() if err != nil { t.Fatalf("NewAdminClient: %v", err) } defer adminClient.Close() list := func() []string { tbls, err := adminClient.Tables(ctx) if err != nil { t.Fatalf("Fetching list of tables: %v", err) } sort.Strings(tbls) return tbls } containsAll := func(got, want []string) bool { gotSet := make(map[string]bool) for _, s := range got { gotSet[s] = true } for _, s := range want { if !gotSet[s] { return false } } return true } defer adminClient.DeleteTable(ctx, "mytable") if err := adminClient.CreateTable(ctx, "mytable"); err != nil { t.Fatalf("Creating table: %v", err) } tables := list() if got, want := tables, []string{"mytable"}; !containsAll(got, want) { t.Errorf("adminClient.Tables returned %#v, want %#v", got, want) } // calling ModifyColumnFamilies to check the granularity of table prefix := adminClient.instancePrefix() req := &btapb.ModifyColumnFamiliesRequest{ Name: prefix + "/tables/" + "mytable", Modifications: []*btapb.ModifyColumnFamiliesRequest_Modification{{ Id: "cf", Mod: &btapb.ModifyColumnFamiliesRequest_Modification_Create{&btapb.ColumnFamily{}}, }}, } table, err := adminClient.tClient.ModifyColumnFamilies(ctx, req) if err != nil { t.Fatalf("Creating column family: %v", err) } if table.Granularity != btapb.Table_TimestampGranularity(btapb.Table_MILLIS) { t.Errorf("ModifyColumnFamilies returned granularity %#v, want %#v", table.Granularity, btapb.Table_TimestampGranularity(btapb.Table_MILLIS)) } } func TestIntegration_InstanceAdminClient_AppProfile(t *testing.T) { testEnv, err := NewIntegrationEnv() if err != nil { t.Fatalf("IntegrationEnv: %v", err) } defer testEnv.Close() timeout := 2 * time.Second if testEnv.Config().UseProd { timeout = 5 * time.Minute } ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() adminClient, err := testEnv.NewAdminClient() if err != nil { t.Fatalf("NewAdminClient: %v", err) } defer adminClient.Close() iAdminClient, err := testEnv.NewInstanceAdminClient() if err != nil { t.Fatalf("NewInstanceAdminClient: %v", err) } if iAdminClient == nil { return } defer iAdminClient.Close() profile := ProfileConf{ ProfileID: "app_profile1", InstanceID: adminClient.instance, ClusterID: testEnv.Config().Cluster, Description: "creating new app profile 1", RoutingPolicy: SingleClusterRouting, } createdProfile, err := iAdminClient.CreateAppProfile(ctx, profile) if err != nil { t.Fatalf("Creating app profile: %v", err) } gotProfile, err := iAdminClient.GetAppProfile(ctx, adminClient.instance, "app_profile1") if err != nil { t.Fatalf("Get app profile: %v", err) } if !proto.Equal(createdProfile, gotProfile) { t.Fatalf("created profile: %s, got profile: %s", createdProfile.Name, gotProfile.Name) } list := func(instanceID string) ([]*btapb.AppProfile, error) { profiles := []*btapb.AppProfile(nil) it := iAdminClient.ListAppProfiles(ctx, instanceID) for { s, err := it.Next() if err == iterator.Done { break } if err != nil { return nil, err } profiles = append(profiles, s) } return profiles, err } profiles, err := list(adminClient.instance) if err != nil { t.Fatalf("List app profile: %v", err) } if got, want := len(profiles), 1; got != want { t.Fatalf("Initial app profile list len: %d, want: %d", got, want) } for _, test := range []struct { desc string uattrs ProfileAttrsToUpdate want *btapb.AppProfile // nil means error }{ { desc: "empty update", uattrs: ProfileAttrsToUpdate{}, want: nil, }, { desc: "empty description update", uattrs: ProfileAttrsToUpdate{Description: ""}, want: &btapb.AppProfile{ Name: gotProfile.Name, Description: "", RoutingPolicy: gotProfile.RoutingPolicy, Etag: gotProfile.Etag}, }, { desc: "routing update", uattrs: ProfileAttrsToUpdate{ RoutingPolicy: SingleClusterRouting, ClusterID: testEnv.Config().Cluster, }, want: &btapb.AppProfile{ Name: gotProfile.Name, Description: "", Etag: gotProfile.Etag, RoutingPolicy: &btapb.AppProfile_SingleClusterRouting_{ SingleClusterRouting: &btapb.AppProfile_SingleClusterRouting{ ClusterId: testEnv.Config().Cluster, }}, }, }, } { err = iAdminClient.UpdateAppProfile(ctx, adminClient.instance, "app_profile1", test.uattrs) if err != nil { if test.want != nil { t.Errorf("%s: %v", test.desc, err) } continue } if err == nil && test.want == nil { t.Errorf("%s: got nil, want error", test.desc) continue } got, _ := iAdminClient.GetAppProfile(ctx, adminClient.instance, "app_profile1") if !proto.Equal(got, test.want) { t.Fatalf("%s : got profile : %v, want profile: %v", test.desc, gotProfile, test.want) } } err = iAdminClient.DeleteAppProfile(ctx, adminClient.instance, "app_profile1") if err != nil { t.Fatalf("Delete app profile: %v", err) } } func TestIntegration_InstanceUpdate(t *testing.T) { testEnv, err := NewIntegrationEnv() if err != nil { t.Fatalf("IntegrationEnv: %v", err) } defer testEnv.Close() timeout := 2 * time.Second if testEnv.Config().UseProd { timeout = 5 * time.Minute } ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() adminClient, err := testEnv.NewAdminClient() if err != nil { t.Fatalf("NewAdminClient: %v", err) } defer adminClient.Close() iAdminClient, err := testEnv.NewInstanceAdminClient() if err != nil { t.Fatalf("NewInstanceAdminClient: %v", err) } if iAdminClient == nil { return } defer iAdminClient.Close() iInfo, err := iAdminClient.InstanceInfo(ctx, adminClient.instance) if err != nil { t.Errorf("InstanceInfo: %v", err) } if iInfo.Name != adminClient.instance { t.Errorf("InstanceInfo returned name %#v, want %#v", iInfo.Name, adminClient.instance) } if iInfo.DisplayName != adminClient.instance { t.Errorf("InstanceInfo returned name %#v, want %#v", iInfo.Name, adminClient.instance) } const numNodes = 4 // update cluster nodes if err := iAdminClient.UpdateCluster(ctx, adminClient.instance, testEnv.Config().Cluster, int32(numNodes)); err != nil { t.Errorf("UpdateCluster: %v", err) } // get cluster after updating cis, err := iAdminClient.GetCluster(ctx, adminClient.instance, testEnv.Config().Cluster) if err != nil { t.Errorf("GetCluster %v", err) } if cis.ServeNodes != int(numNodes) { t.Errorf("ServeNodes returned %d, want %d", cis.ServeNodes, int(numNodes)) } } func setupIntegration(ctx context.Context, t *testing.T) (_ *Client, _ *AdminClient, table *Table, tableName string, cleanup func(), _ error) { testEnv, err := NewIntegrationEnv() if err != nil { return nil, nil, nil, "", nil, err } var timeout time.Duration if testEnv.Config().UseProd { timeout = 10 * time.Minute t.Logf("Running test against production") } else { timeout = 1 * time.Minute t.Logf("bttest.Server running on %s", testEnv.Config().AdminEndpoint) } ctx, cancel := context.WithTimeout(ctx, timeout) defer cancel() client, err := testEnv.NewClient() if err != nil { return nil, nil, nil, "", nil, err } adminClient, err := testEnv.NewAdminClient() if err != nil { return nil, nil, nil, "", nil, err } tableName = testEnv.Config().Table if err := adminClient.CreateTable(ctx, tableName); err != nil { return nil, nil, nil, "", nil, err } if err := adminClient.CreateColumnFamily(ctx, tableName, "follows"); err != nil { return nil, nil, nil, "", nil, err } return client, adminClient, client.Open(tableName), tableName, func() { adminClient.DeleteTable(ctx, tableName) client.Close() adminClient.Close() }, nil } func formatReadItem(ri ReadItem) string { // Use the column qualifier only to make the test data briefer. col := ri.Column[strings.Index(ri.Column, ":")+1:] return fmt.Sprintf("%s-%s-%s", ri.Row, col, ri.Value) } func fill(b, sub []byte) { for len(b) > len(sub) { n := copy(b, sub) b = b[n:] } } func clearTimestamps(r Row) { for _, ris := range r { for i := range ris { ris[i].Timestamp = 0 } } } google-cloud-go-0.49.0/bigtable/internal/000077500000000000000000000000001356504100700201555ustar00rootroot00000000000000google-cloud-go-0.49.0/bigtable/internal/cbtconfig/000077500000000000000000000000001356504100700221135ustar00rootroot00000000000000google-cloud-go-0.49.0/bigtable/internal/cbtconfig/cbtconfig.go000066400000000000000000000200171356504100700244000ustar00rootroot00000000000000/* Copyright 2015 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // Package cbtconfig encapsulates common code for reading configuration from .cbtrc and gcloud. package cbtconfig import ( "bufio" "bytes" "crypto/tls" "crypto/x509" "encoding/json" "flag" "fmt" "io/ioutil" "log" "os" "os/exec" "path/filepath" "runtime" "strings" "time" "golang.org/x/oauth2" "google.golang.org/grpc/credentials" ) // Config represents a configuration. type Config struct { Project, Instance string // required Creds string // optional AdminEndpoint string // optional DataEndpoint string // optional CertFile string // optional UserAgent string // optional AuthToken string // optional TokenSource oauth2.TokenSource // derived TLSCreds credentials.TransportCredentials // derived } // RequiredFlags describes the flag requirements for a cbt command. type RequiredFlags uint const ( // NoneRequired specifies that not flags are required. NoneRequired RequiredFlags = 0 // ProjectRequired specifies that the -project flag is required. ProjectRequired RequiredFlags = 1 << iota // InstanceRequired specifies that the -instance flag is required. InstanceRequired // ProjectAndInstanceRequired specifies that both -project and -instance is required. ProjectAndInstanceRequired = ProjectRequired | InstanceRequired ) // RegisterFlags registers a set of standard flags for this config. // It should be called before flag.Parse. func (c *Config) RegisterFlags() { flag.StringVar(&c.Project, "project", c.Project, "project ID. If unset uses gcloud configured project") flag.StringVar(&c.Instance, "instance", c.Instance, "Cloud Bigtable instance") flag.StringVar(&c.Creds, "creds", c.Creds, "Path to the credentials file. If set, uses the application credentials in this file") flag.StringVar(&c.AdminEndpoint, "admin-endpoint", c.AdminEndpoint, "Override the admin api endpoint") flag.StringVar(&c.DataEndpoint, "data-endpoint", c.DataEndpoint, "Override the data api endpoint") flag.StringVar(&c.CertFile, "cert-file", c.CertFile, "Override the TLS certificates file") flag.StringVar(&c.UserAgent, "user-agent", c.UserAgent, "Override the user agent string") flag.StringVar(&c.AuthToken, "auth-token", c.AuthToken, "if set, use IAM Auth Token for requests") } // CheckFlags checks that the required config values are set. func (c *Config) CheckFlags(required RequiredFlags) error { var missing []string if c.CertFile != "" { b, err := ioutil.ReadFile(c.CertFile) if err != nil { return fmt.Errorf("Failed to load certificates from %s: %v", c.CertFile, err) } cp := x509.NewCertPool() if !cp.AppendCertsFromPEM(b) { return fmt.Errorf("Failed to append certificates from %s", c.CertFile) } c.TLSCreds = credentials.NewTLS(&tls.Config{RootCAs: cp}) } if required != NoneRequired { c.SetFromGcloud() } if required&ProjectRequired != 0 && c.Project == "" { missing = append(missing, "-project") } if required&InstanceRequired != 0 && c.Instance == "" { missing = append(missing, "-instance") } if len(missing) > 0 { return fmt.Errorf("Missing %s", strings.Join(missing, " and ")) } return nil } // Filename returns the filename consulted for standard configuration. func Filename() string { // TODO(dsymonds): Might need tweaking for Windows. return filepath.Join(os.Getenv("HOME"), ".cbtrc") } // Load loads a .cbtrc file. // If the file is not present, an empty config is returned. func Load() (*Config, error) { filename := Filename() data, err := ioutil.ReadFile(filename) if err != nil { // silent fail if the file isn't there if os.IsNotExist(err) { return &Config{}, nil } return nil, fmt.Errorf("Reading %s: %v", filename, err) } c := new(Config) s := bufio.NewScanner(bytes.NewReader(data)) for s.Scan() { line := s.Text() i := strings.Index(line, "=") if i < 0 { return nil, fmt.Errorf("Bad line in %s: %q", filename, line) } key, val := strings.TrimSpace(line[:i]), strings.TrimSpace(line[i+1:]) switch key { default: return nil, fmt.Errorf("Unknown key in %s: %q", filename, key) case "project": c.Project = val case "instance": c.Instance = val case "creds": c.Creds = val case "admin-endpoint": c.AdminEndpoint = val case "data-endpoint": c.DataEndpoint = val case "cert-file": c.CertFile = val case "user-agent": c.UserAgent = val case "auth-token": c.AuthToken = val } } return c, s.Err() } // GcloudCredential holds gcloud credential information. type GcloudCredential struct { AccessToken string `json:"access_token"` Expiry time.Time `json:"token_expiry"` } // Token creates an oauth2 token using gcloud credentials. func (cred *GcloudCredential) Token() *oauth2.Token { return &oauth2.Token{AccessToken: cred.AccessToken, TokenType: "Bearer", Expiry: cred.Expiry} } // GcloudConfig holds gcloud configuration values. type GcloudConfig struct { Configuration struct { Properties struct { Core struct { Project string `json:"project"` } `json:"core"` } `json:"properties"` } `json:"configuration"` Credential GcloudCredential `json:"credential"` } // GcloudCmdTokenSource holds the comamnd arguments. It is only intended to be set by the program. // TODO(deklerk): Can this be unexported? type GcloudCmdTokenSource struct { Command string Args []string } // Token implements the oauth2.TokenSource interface func (g *GcloudCmdTokenSource) Token() (*oauth2.Token, error) { gcloudConfig, err := LoadGcloudConfig(g.Command, g.Args) if err != nil { return nil, err } return gcloudConfig.Credential.Token(), nil } // LoadGcloudConfig retrieves the gcloud configuration values we need use via the // 'config-helper' command func LoadGcloudConfig(gcloudCmd string, gcloudCmdArgs []string) (*GcloudConfig, error) { out, err := exec.Command(gcloudCmd, gcloudCmdArgs...).Output() if err != nil { return nil, fmt.Errorf("Could not retrieve gcloud configuration") } var gcloudConfig GcloudConfig if err := json.Unmarshal(out, &gcloudConfig); err != nil { return nil, fmt.Errorf("Could not parse gcloud configuration") } return &gcloudConfig, nil } // SetFromGcloud retrieves and sets any missing config values from the gcloud // configuration if possible possible func (c *Config) SetFromGcloud() error { if c.Creds == "" { c.Creds = os.Getenv("GOOGLE_APPLICATION_CREDENTIALS") if c.Creds == "" { log.Printf("-creds flag unset, will use gcloud credential") } } else { os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", c.Creds) } if c.Project == "" { log.Printf("-project flag unset, will use gcloud active project") } if c.Creds != "" && c.Project != "" { return nil } gcloudCmd := "gcloud" if runtime.GOOS == "windows" { gcloudCmd = gcloudCmd + ".cmd" } gcloudCmdArgs := []string{"config", "config-helper", "--format=json(configuration.properties.core.project,credential)"} gcloudConfig, err := LoadGcloudConfig(gcloudCmd, gcloudCmdArgs) if err != nil { return err } if c.Project == "" && gcloudConfig.Configuration.Properties.Core.Project != "" { log.Printf("gcloud active project is \"%s\"", gcloudConfig.Configuration.Properties.Core.Project) c.Project = gcloudConfig.Configuration.Properties.Core.Project } if c.Creds == "" { c.TokenSource = oauth2.ReuseTokenSource( gcloudConfig.Credential.Token(), &GcloudCmdTokenSource{Command: gcloudCmd, Args: gcloudCmdArgs}) } return nil } google-cloud-go-0.49.0/bigtable/internal/conformance/000077500000000000000000000000001356504100700224475ustar00rootroot00000000000000google-cloud-go-0.49.0/bigtable/internal/conformance/README.md000066400000000000000000000004571356504100700237340ustar00rootroot00000000000000# Generating tests.pb.go ``` # Note: Change /usr/local/google/home/deklerk/workspace/googleapis to wherever # you've installed https://github.com/googleapis/googleapis. # Note: Run whilst cd-ed in this directory. protoc --go_out=. -I /usr/local/google/home/deklerk/workspace/googleapis -I . *.proto ```google-cloud-go-0.49.0/bigtable/internal/conformance/testdata/000077500000000000000000000000001356504100700242605ustar00rootroot00000000000000google-cloud-go-0.49.0/bigtable/internal/conformance/testdata/readrows.json000066400000000000000000001112421356504100700270020ustar00rootroot00000000000000{ "readRowsTests": [ { "description": "invalid - no commit", "chunks": [ { "rowKey": "Uks=", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dmFsdWUtVkFM", "commitRow": false } ], "results": [ { "error": true } ] }, { "description": "invalid - no cell key before commit", "chunks": [ { "commitRow": true } ], "results": [ { "error": true } ] }, { "description": "invalid - no cell key before value", "chunks": [ { "timestampMicros": "100", "value": "dmFsdWUtVkFM", "commitRow": false } ], "results": [ { "error": true } ] }, { "description": "invalid - new col family must specify qualifier", "chunks": [ { "rowKey": "Uks=", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "99", "value": "dmFsdWUtVkFMXzE=", "commitRow": false }, { "familyName": "B", "timestampMicros": "98", "value": "dmFsdWUtVkFMXzI=", "commitRow": true } ], "results": [ { "error": true } ] }, { "description": "bare commit implies ts=0", "chunks": [ { "rowKey": "Uks=", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dmFsdWUtVkFM", "commitRow": false }, { "commitRow": true } ], "results": [ { "rowKey": "RK", "familyName": "A", "qualifier": "C", "timestampMicros": "100", "value": "value-VAL" }, { "rowKey": "RK", "familyName": "A", "qualifier": "C" } ] }, { "description": "simple row with timestamp", "chunks": [ { "rowKey": "Uks=", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dmFsdWUtVkFM", "commitRow": true } ], "results": [ { "rowKey": "RK", "familyName": "A", "qualifier": "C", "timestampMicros": "100", "value": "value-VAL" } ] }, { "description": "missing timestamp, implied ts=0", "chunks": [ { "rowKey": "Uks=", "familyName": "A", "qualifier": "Qw==", "value": "dmFsdWUtVkFM", "commitRow": true } ], "results": [ { "rowKey": "RK", "familyName": "A", "qualifier": "C", "value": "value-VAL" } ] }, { "description": "empty cell value", "chunks": [ { "rowKey": "Uks=", "familyName": "A", "qualifier": "Qw==", "commitRow": true } ], "results": [ { "rowKey": "RK", "familyName": "A", "qualifier": "C" } ] }, { "description": "two unsplit cells", "chunks": [ { "rowKey": "Uks=", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "99", "value": "dmFsdWUtVkFMXzE=", "commitRow": false }, { "timestampMicros": "98", "value": "dmFsdWUtVkFMXzI=", "commitRow": true } ], "results": [ { "rowKey": "RK", "familyName": "A", "qualifier": "C", "timestampMicros": "99", "value": "value-VAL_1" }, { "rowKey": "RK", "familyName": "A", "qualifier": "C", "timestampMicros": "98", "value": "value-VAL_2" } ] }, { "description": "two qualifiers", "chunks": [ { "rowKey": "Uks=", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "99", "value": "dmFsdWUtVkFMXzE=", "commitRow": false }, { "qualifier": "RA==", "timestampMicros": "98", "value": "dmFsdWUtVkFMXzI=", "commitRow": true } ], "results": [ { "rowKey": "RK", "familyName": "A", "qualifier": "C", "timestampMicros": "99", "value": "value-VAL_1" }, { "rowKey": "RK", "familyName": "A", "qualifier": "D", "timestampMicros": "98", "value": "value-VAL_2" } ] }, { "description": "two families", "chunks": [ { "rowKey": "Uks=", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "99", "value": "dmFsdWUtVkFMXzE=", "commitRow": false }, { "familyName": "B", "qualifier": "RQ==", "timestampMicros": "98", "value": "dmFsdWUtVkFMXzI=", "commitRow": true } ], "results": [ { "rowKey": "RK", "familyName": "A", "qualifier": "C", "timestampMicros": "99", "value": "value-VAL_1" }, { "rowKey": "RK", "familyName": "B", "qualifier": "E", "timestampMicros": "98", "value": "value-VAL_2" } ] }, { "description": "with labels", "chunks": [ { "rowKey": "Uks=", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "99", "labels": [ "L_1" ], "value": "dmFsdWUtVkFMXzE=", "commitRow": false }, { "timestampMicros": "98", "labels": [ "L_2" ], "value": "dmFsdWUtVkFMXzI=", "commitRow": true } ], "results": [ { "rowKey": "RK", "familyName": "A", "qualifier": "C", "timestampMicros": "99", "value": "value-VAL_1", "label": "L_1" }, { "rowKey": "RK", "familyName": "A", "qualifier": "C", "timestampMicros": "98", "value": "value-VAL_2", "label": "L_2" } ] }, { "description": "split cell, bare commit", "chunks": [ { "rowKey": "Uks=", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dg==", "valueSize": 9, "commitRow": false }, { "value": "YWx1ZS1WQUw=", "commitRow": false }, { "commitRow": true } ], "results": [ { "rowKey": "RK", "familyName": "A", "qualifier": "C", "timestampMicros": "100", "value": "value-VAL" }, { "rowKey": "RK", "familyName": "A", "qualifier": "C" } ] }, { "description": "split cell", "chunks": [ { "rowKey": "Uks=", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dg==", "valueSize": 9, "commitRow": false }, { "value": "YWx1ZS1WQUw=", "commitRow": true } ], "results": [ { "rowKey": "RK", "familyName": "A", "qualifier": "C", "timestampMicros": "100", "value": "value-VAL" } ] }, { "description": "split four ways", "chunks": [ { "rowKey": "Uks=", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "labels": [ "L" ], "value": "dg==", "valueSize": 9, "commitRow": false }, { "value": "YQ==", "valueSize": 9, "commitRow": false }, { "value": "bA==", "valueSize": 9, "commitRow": false }, { "value": "dWUtVkFM", "commitRow": true } ], "results": [ { "rowKey": "RK", "familyName": "A", "qualifier": "C", "timestampMicros": "100", "value": "value-VAL", "label": "L" } ] }, { "description": "two split cells", "chunks": [ { "rowKey": "Uks=", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "99", "value": "dg==", "valueSize": 11, "commitRow": false }, { "value": "YWx1ZS1WQUxfMQ==", "commitRow": false }, { "timestampMicros": "98", "value": "dg==", "valueSize": 11, "commitRow": false }, { "value": "YWx1ZS1WQUxfMg==", "commitRow": true } ], "results": [ { "rowKey": "RK", "familyName": "A", "qualifier": "C", "timestampMicros": "99", "value": "value-VAL_1" }, { "rowKey": "RK", "familyName": "A", "qualifier": "C", "timestampMicros": "98", "value": "value-VAL_2" } ] }, { "description": "multi-qualifier splits", "chunks": [ { "rowKey": "Uks=", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "99", "value": "dg==", "valueSize": 11, "commitRow": false }, { "value": "YWx1ZS1WQUxfMQ==", "commitRow": false }, { "qualifier": "RA==", "timestampMicros": "98", "value": "dg==", "valueSize": 11, "commitRow": false }, { "value": "YWx1ZS1WQUxfMg==", "commitRow": true } ], "results": [ { "rowKey": "RK", "familyName": "A", "qualifier": "C", "timestampMicros": "99", "value": "value-VAL_1" }, { "rowKey": "RK", "familyName": "A", "qualifier": "D", "timestampMicros": "98", "value": "value-VAL_2" } ] }, { "description": "multi-qualifier multi-split", "chunks": [ { "rowKey": "Uks=", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "99", "value": "dg==", "valueSize": 11, "commitRow": false }, { "value": "YQ==", "valueSize": 11, "commitRow": false }, { "value": "bHVlLVZBTF8x", "commitRow": false }, { "qualifier": "RA==", "timestampMicros": "98", "value": "dg==", "valueSize": 11, "commitRow": false }, { "value": "YQ==", "valueSize": 11, "commitRow": false }, { "value": "bHVlLVZBTF8y", "commitRow": true } ], "results": [ { "rowKey": "RK", "familyName": "A", "qualifier": "C", "timestampMicros": "99", "value": "value-VAL_1" }, { "rowKey": "RK", "familyName": "A", "qualifier": "D", "timestampMicros": "98", "value": "value-VAL_2" } ] }, { "description": "multi-family split", "chunks": [ { "rowKey": "Uks=", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "99", "value": "dg==", "valueSize": 11, "commitRow": false }, { "value": "YWx1ZS1WQUxfMQ==", "commitRow": false }, { "familyName": "B", "qualifier": "RQ==", "timestampMicros": "98", "value": "dg==", "valueSize": 11, "commitRow": false }, { "value": "YWx1ZS1WQUxfMg==", "commitRow": true } ], "results": [ { "rowKey": "RK", "familyName": "A", "qualifier": "C", "timestampMicros": "99", "value": "value-VAL_1" }, { "rowKey": "RK", "familyName": "B", "qualifier": "E", "timestampMicros": "98", "value": "value-VAL_2" } ] }, { "description": "invalid - no commit between rows", "chunks": [ { "rowKey": "UktfMQ==", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dmFsdWUtVkFM", "commitRow": false }, { "rowKey": "UktfMg==", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dmFsdWUtVkFM", "commitRow": false } ], "results": [ { "error": true } ] }, { "description": "invalid - no commit after first row", "chunks": [ { "rowKey": "UktfMQ==", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dmFsdWUtVkFM", "commitRow": false }, { "rowKey": "UktfMg==", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dmFsdWUtVkFM", "commitRow": true } ], "results": [ { "error": true } ] }, { "description": "invalid - last row missing commit", "chunks": [ { "rowKey": "UktfMQ==", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dmFsdWUtVkFM", "commitRow": true }, { "rowKey": "UktfMg==", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dmFsdWUtVkFM", "commitRow": false } ], "results": [ { "rowKey": "RK_1", "familyName": "A", "qualifier": "C", "timestampMicros": "100", "value": "value-VAL" }, { "error": true } ] }, { "description": "invalid - duplicate row key", "chunks": [ { "rowKey": "UktfMQ==", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dmFsdWUtVkFM", "commitRow": true }, { "rowKey": "UktfMQ==", "familyName": "B", "qualifier": "RA==", "timestampMicros": "100", "value": "dmFsdWUtVkFM", "commitRow": true } ], "results": [ { "rowKey": "RK_1", "familyName": "A", "qualifier": "C", "timestampMicros": "100", "value": "value-VAL" }, { "error": true } ] }, { "description": "invalid - new row missing row key", "chunks": [ { "rowKey": "UktfMQ==", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dmFsdWUtVkFM", "commitRow": true }, { "timestampMicros": "100", "value": "dmFsdWUtVkFM", "commitRow": true } ], "results": [ { "rowKey": "RK_1", "familyName": "A", "qualifier": "C", "timestampMicros": "100", "value": "value-VAL" }, { "error": true } ] }, { "description": "two rows", "chunks": [ { "rowKey": "UktfMQ==", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dmFsdWUtVkFM", "commitRow": true }, { "rowKey": "UktfMg==", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dmFsdWUtVkFM", "commitRow": true } ], "results": [ { "rowKey": "RK_1", "familyName": "A", "qualifier": "C", "timestampMicros": "100", "value": "value-VAL" }, { "rowKey": "RK_2", "familyName": "A", "qualifier": "C", "timestampMicros": "100", "value": "value-VAL" } ] }, { "description": "two rows implicit timestamp", "chunks": [ { "rowKey": "UktfMQ==", "familyName": "A", "qualifier": "Qw==", "value": "dmFsdWUtVkFM", "commitRow": true }, { "rowKey": "UktfMg==", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dmFsdWUtVkFM", "commitRow": true } ], "results": [ { "rowKey": "RK_1", "familyName": "A", "qualifier": "C", "value": "value-VAL" }, { "rowKey": "RK_2", "familyName": "A", "qualifier": "C", "timestampMicros": "100", "value": "value-VAL" } ] }, { "description": "two rows empty value", "chunks": [ { "rowKey": "UktfMQ==", "familyName": "A", "qualifier": "Qw==", "commitRow": true }, { "rowKey": "UktfMg==", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dmFsdWUtVkFM", "commitRow": true } ], "results": [ { "rowKey": "RK_1", "familyName": "A", "qualifier": "C" }, { "rowKey": "RK_2", "familyName": "A", "qualifier": "C", "timestampMicros": "100", "value": "value-VAL" } ] }, { "description": "two rows, one with multiple cells", "chunks": [ { "rowKey": "UktfMQ==", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "99", "value": "dmFsdWUtVkFMXzE=", "commitRow": false }, { "timestampMicros": "98", "value": "dmFsdWUtVkFMXzI=", "commitRow": true }, { "rowKey": "UktfMg==", "familyName": "B", "qualifier": "RA==", "timestampMicros": "97", "value": "dmFsdWUtVkFMXzM=", "commitRow": true } ], "results": [ { "rowKey": "RK_1", "familyName": "A", "qualifier": "C", "timestampMicros": "99", "value": "value-VAL_1" }, { "rowKey": "RK_1", "familyName": "A", "qualifier": "C", "timestampMicros": "98", "value": "value-VAL_2" }, { "rowKey": "RK_2", "familyName": "B", "qualifier": "D", "timestampMicros": "97", "value": "value-VAL_3" } ] }, { "description": "two rows, multiple cells", "chunks": [ { "rowKey": "UktfMQ==", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "99", "value": "dmFsdWUtVkFMXzE=", "commitRow": false }, { "qualifier": "RA==", "timestampMicros": "98", "value": "dmFsdWUtVkFMXzI=", "commitRow": true }, { "rowKey": "UktfMg==", "familyName": "B", "qualifier": "RQ==", "timestampMicros": "97", "value": "dmFsdWUtVkFMXzM=", "commitRow": false }, { "qualifier": "Rg==", "timestampMicros": "96", "value": "dmFsdWUtVkFMXzQ=", "commitRow": true } ], "results": [ { "rowKey": "RK_1", "familyName": "A", "qualifier": "C", "timestampMicros": "99", "value": "value-VAL_1" }, { "rowKey": "RK_1", "familyName": "A", "qualifier": "D", "timestampMicros": "98", "value": "value-VAL_2" }, { "rowKey": "RK_2", "familyName": "B", "qualifier": "E", "timestampMicros": "97", "value": "value-VAL_3" }, { "rowKey": "RK_2", "familyName": "B", "qualifier": "F", "timestampMicros": "96", "value": "value-VAL_4" } ] }, { "description": "two rows, multiple cells, multiple families", "chunks": [ { "rowKey": "UktfMQ==", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "99", "value": "dmFsdWUtVkFMXzE=", "commitRow": false }, { "familyName": "B", "qualifier": "RQ==", "timestampMicros": "98", "value": "dmFsdWUtVkFMXzI=", "commitRow": true }, { "rowKey": "UktfMg==", "familyName": "M", "qualifier": "Tw==", "timestampMicros": "97", "value": "dmFsdWUtVkFMXzM=", "commitRow": false }, { "familyName": "N", "qualifier": "UA==", "timestampMicros": "96", "value": "dmFsdWUtVkFMXzQ=", "commitRow": true } ], "results": [ { "rowKey": "RK_1", "familyName": "A", "qualifier": "C", "timestampMicros": "99", "value": "value-VAL_1" }, { "rowKey": "RK_1", "familyName": "B", "qualifier": "E", "timestampMicros": "98", "value": "value-VAL_2" }, { "rowKey": "RK_2", "familyName": "M", "qualifier": "O", "timestampMicros": "97", "value": "value-VAL_3" }, { "rowKey": "RK_2", "familyName": "N", "qualifier": "P", "timestampMicros": "96", "value": "value-VAL_4" } ] }, { "description": "two rows, four cells, 2 labels", "chunks": [ { "rowKey": "UktfMQ==", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "99", "labels": [ "L_1" ], "value": "dmFsdWUtVkFMXzE=", "commitRow": false }, { "timestampMicros": "98", "value": "dmFsdWUtVkFMXzI=", "commitRow": true }, { "rowKey": "UktfMg==", "familyName": "B", "qualifier": "RA==", "timestampMicros": "97", "labels": [ "L_3" ], "value": "dmFsdWUtVkFMXzM=", "commitRow": false }, { "timestampMicros": "96", "value": "dmFsdWUtVkFMXzQ=", "commitRow": true } ], "results": [ { "rowKey": "RK_1", "familyName": "A", "qualifier": "C", "timestampMicros": "99", "value": "value-VAL_1", "label": "L_1" }, { "rowKey": "RK_1", "familyName": "A", "qualifier": "C", "timestampMicros": "98", "value": "value-VAL_2" }, { "rowKey": "RK_2", "familyName": "B", "qualifier": "D", "timestampMicros": "97", "value": "value-VAL_3", "label": "L_3" }, { "rowKey": "RK_2", "familyName": "B", "qualifier": "D", "timestampMicros": "96", "value": "value-VAL_4" } ] }, { "description": "two rows with splits, same timestamp", "chunks": [ { "rowKey": "UktfMQ==", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dg==", "valueSize": 11, "commitRow": false }, { "value": "YWx1ZS1WQUxfMQ==", "commitRow": true }, { "rowKey": "UktfMg==", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dg==", "valueSize": 11, "commitRow": false }, { "value": "YWx1ZS1WQUxfMg==", "commitRow": true } ], "results": [ { "rowKey": "RK_1", "familyName": "A", "qualifier": "C", "timestampMicros": "100", "value": "value-VAL_1" }, { "rowKey": "RK_2", "familyName": "A", "qualifier": "C", "timestampMicros": "100", "value": "value-VAL_2" } ] }, { "description": "invalid - bare reset", "chunks": [ { "resetRow": true } ], "results": [ { "error": true } ] }, { "description": "invalid - bad reset, no commit", "chunks": [ { "resetRow": true }, { "rowKey": "Uks=", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dmFsdWUtVkFM", "commitRow": false } ], "results": [ { "error": true } ] }, { "description": "invalid - missing key after reset", "chunks": [ { "rowKey": "Uks=", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dmFsdWUtVkFM", "commitRow": false }, { "resetRow": true }, { "timestampMicros": "100", "value": "dmFsdWUtVkFM", "commitRow": true } ], "results": [ { "error": true } ] }, { "description": "no data after reset", "chunks": [ { "rowKey": "Uks=", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dmFsdWUtVkFM", "commitRow": false }, { "resetRow": true } ] }, { "description": "simple reset", "chunks": [ { "rowKey": "Uks=", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dmFsdWUtVkFM", "commitRow": false }, { "resetRow": true }, { "rowKey": "Uks=", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dmFsdWUtVkFM", "commitRow": true } ], "results": [ { "rowKey": "RK", "familyName": "A", "qualifier": "C", "timestampMicros": "100", "value": "value-VAL" } ] }, { "description": "reset to new val", "chunks": [ { "rowKey": "Uks=", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dmFsdWUtVkFMXzE=", "commitRow": false }, { "resetRow": true }, { "rowKey": "Uks=", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dmFsdWUtVkFMXzI=", "commitRow": true } ], "results": [ { "rowKey": "RK", "familyName": "A", "qualifier": "C", "timestampMicros": "100", "value": "value-VAL_2" } ] }, { "description": "reset to new qual", "chunks": [ { "rowKey": "Uks=", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dmFsdWUtVkFMXzE=", "commitRow": false }, { "resetRow": true }, { "rowKey": "Uks=", "familyName": "A", "qualifier": "RA==", "timestampMicros": "100", "value": "dmFsdWUtVkFMXzE=", "commitRow": true } ], "results": [ { "rowKey": "RK", "familyName": "A", "qualifier": "D", "timestampMicros": "100", "value": "value-VAL_1" } ] }, { "description": "reset with splits", "chunks": [ { "rowKey": "Uks=", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dmFsdWUtVkFMXzE=", "commitRow": false }, { "timestampMicros": "98", "value": "dmFsdWUtVkFMXzI=", "commitRow": false }, { "resetRow": true }, { "rowKey": "Uks=", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dmFsdWUtVkFMXzI=", "commitRow": true } ], "results": [ { "rowKey": "RK", "familyName": "A", "qualifier": "C", "timestampMicros": "100", "value": "value-VAL_2" } ] }, { "description": "reset two cells", "chunks": [ { "rowKey": "Uks=", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dmFsdWUtVkFMXzE=", "commitRow": false }, { "resetRow": true }, { "rowKey": "Uks=", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dmFsdWUtVkFMXzI=", "commitRow": false }, { "timestampMicros": "97", "value": "dmFsdWUtVkFMXzM=", "commitRow": true } ], "results": [ { "rowKey": "RK", "familyName": "A", "qualifier": "C", "timestampMicros": "100", "value": "value-VAL_2" }, { "rowKey": "RK", "familyName": "A", "qualifier": "C", "timestampMicros": "97", "value": "value-VAL_3" } ] }, { "description": "two resets", "chunks": [ { "rowKey": "Uks=", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dmFsdWUtVkFMXzE=", "commitRow": false }, { "resetRow": true }, { "rowKey": "Uks=", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dmFsdWUtVkFMXzI=", "commitRow": false }, { "resetRow": true }, { "rowKey": "Uks=", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dmFsdWUtVkFMXzM=", "commitRow": true } ], "results": [ { "rowKey": "RK", "familyName": "A", "qualifier": "C", "timestampMicros": "100", "value": "value-VAL_3" } ] }, { "description": "reset then two cells", "chunks": [ { "rowKey": "Uks=", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dmFsdWUtVkFMXzE=", "commitRow": false }, { "resetRow": true }, { "rowKey": "Uks=", "familyName": "B", "qualifier": "Qw==", "timestampMicros": "100", "value": "dmFsdWUtVkFMXzI=", "commitRow": false }, { "qualifier": "RA==", "timestampMicros": "97", "value": "dmFsdWUtVkFMXzM=", "commitRow": true } ], "results": [ { "rowKey": "RK", "familyName": "B", "qualifier": "C", "timestampMicros": "100", "value": "value-VAL_2" }, { "rowKey": "RK", "familyName": "B", "qualifier": "D", "timestampMicros": "97", "value": "value-VAL_3" } ] }, { "description": "reset to new row", "chunks": [ { "rowKey": "UktfMQ==", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dmFsdWUtVkFMXzE=", "commitRow": false }, { "resetRow": true }, { "rowKey": "UktfMg==", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dmFsdWUtVkFMXzI=", "commitRow": true } ], "results": [ { "rowKey": "RK_2", "familyName": "A", "qualifier": "C", "timestampMicros": "100", "value": "value-VAL_2" } ] }, { "description": "reset in between chunks", "chunks": [ { "rowKey": "Uks=", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "labels": [ "L" ], "value": "dg==", "valueSize": 10, "commitRow": false }, { "value": "YQ==", "valueSize": 10, "commitRow": false }, { "resetRow": true }, { "rowKey": "UktfMQ==", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dmFsdWUtVkFMXzE=", "commitRow": true } ], "results": [ { "rowKey": "RK_1", "familyName": "A", "qualifier": "C", "timestampMicros": "100", "value": "value-VAL_1" } ] }, { "description": "invalid - reset with chunk", "chunks": [ { "rowKey": "Uks=", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "labels": [ "L" ], "value": "dg==", "valueSize": 10, "commitRow": false }, { "value": "YQ==", "valueSize": 10, "resetRow": true } ], "results": [ { "error": true } ] }, { "description": "invalid - commit with chunk", "chunks": [ { "rowKey": "Uks=", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "labels": [ "L" ], "value": "dg==", "valueSize": 10, "commitRow": false }, { "value": "YQ==", "valueSize": 10, "commitRow": true } ], "results": [ { "error": true } ] }, { "description": "empty cell chunk", "chunks": [ { "rowKey": "Uks=", "familyName": "A", "qualifier": "Qw==", "timestampMicros": "100", "value": "dmFsdWUtVkFM", "commitRow": false }, { "commitRow": false }, { "commitRow": true } ], "results": [ { "rowKey": "RK", "familyName": "A", "qualifier": "C", "timestampMicros": "100", "value": "value-VAL" }, { "rowKey": "RK", "familyName": "A", "qualifier": "C" }, { "rowKey": "RK", "familyName": "A", "qualifier": "C" } ] } ] }google-cloud-go-0.49.0/bigtable/internal/conformance/tests.pb.go000066400000000000000000000224331356504100700245440ustar00rootroot00000000000000// Code generated by protoc-gen-go. DO NOT EDIT. // source: tests.proto package google_cloud_conformance_bigtable_v2 import ( fmt "fmt" math "math" proto "github.com/golang/protobuf/proto" v2 "google.golang.org/genproto/googleapis/bigtable/v2" ) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal var _ = fmt.Errorf var _ = math.Inf // This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package type TestFile struct { ReadRowsTests []*ReadRowsTest `protobuf:"bytes,1,rep,name=read_rows_tests,json=readRowsTests,proto3" json:"read_rows_tests,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *TestFile) Reset() { *m = TestFile{} } func (m *TestFile) String() string { return proto.CompactTextString(m) } func (*TestFile) ProtoMessage() {} func (*TestFile) Descriptor() ([]byte, []int) { return fileDescriptor_e49b496f4919bda1, []int{0} } func (m *TestFile) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_TestFile.Unmarshal(m, b) } func (m *TestFile) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_TestFile.Marshal(b, m, deterministic) } func (m *TestFile) XXX_Merge(src proto.Message) { xxx_messageInfo_TestFile.Merge(m, src) } func (m *TestFile) XXX_Size() int { return xxx_messageInfo_TestFile.Size(m) } func (m *TestFile) XXX_DiscardUnknown() { xxx_messageInfo_TestFile.DiscardUnknown(m) } var xxx_messageInfo_TestFile proto.InternalMessageInfo func (m *TestFile) GetReadRowsTests() []*ReadRowsTest { if m != nil { return m.ReadRowsTests } return nil } type ReadRowsTest struct { Description string `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"` Chunks []*v2.ReadRowsResponse_CellChunk `protobuf:"bytes,2,rep,name=chunks,proto3" json:"chunks,omitempty"` Results []*ReadRowsTest_Result `protobuf:"bytes,3,rep,name=results,proto3" json:"results,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *ReadRowsTest) Reset() { *m = ReadRowsTest{} } func (m *ReadRowsTest) String() string { return proto.CompactTextString(m) } func (*ReadRowsTest) ProtoMessage() {} func (*ReadRowsTest) Descriptor() ([]byte, []int) { return fileDescriptor_e49b496f4919bda1, []int{1} } func (m *ReadRowsTest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ReadRowsTest.Unmarshal(m, b) } func (m *ReadRowsTest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ReadRowsTest.Marshal(b, m, deterministic) } func (m *ReadRowsTest) XXX_Merge(src proto.Message) { xxx_messageInfo_ReadRowsTest.Merge(m, src) } func (m *ReadRowsTest) XXX_Size() int { return xxx_messageInfo_ReadRowsTest.Size(m) } func (m *ReadRowsTest) XXX_DiscardUnknown() { xxx_messageInfo_ReadRowsTest.DiscardUnknown(m) } var xxx_messageInfo_ReadRowsTest proto.InternalMessageInfo func (m *ReadRowsTest) GetDescription() string { if m != nil { return m.Description } return "" } func (m *ReadRowsTest) GetChunks() []*v2.ReadRowsResponse_CellChunk { if m != nil { return m.Chunks } return nil } func (m *ReadRowsTest) GetResults() []*ReadRowsTest_Result { if m != nil { return m.Results } return nil } // Expected results of reading the row. // Only the last result can be an error. type ReadRowsTest_Result struct { RowKey string `protobuf:"bytes,1,opt,name=row_key,json=rowKey,proto3" json:"row_key,omitempty"` FamilyName string `protobuf:"bytes,2,opt,name=family_name,json=familyName,proto3" json:"family_name,omitempty"` Qualifier string `protobuf:"bytes,3,opt,name=qualifier,proto3" json:"qualifier,omitempty"` TimestampMicros int64 `protobuf:"varint,4,opt,name=timestamp_micros,json=timestampMicros,proto3" json:"timestamp_micros,omitempty"` Value string `protobuf:"bytes,5,opt,name=value,proto3" json:"value,omitempty"` Label string `protobuf:"bytes,6,opt,name=label,proto3" json:"label,omitempty"` Error bool `protobuf:"varint,7,opt,name=error,proto3" json:"error,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *ReadRowsTest_Result) Reset() { *m = ReadRowsTest_Result{} } func (m *ReadRowsTest_Result) String() string { return proto.CompactTextString(m) } func (*ReadRowsTest_Result) ProtoMessage() {} func (*ReadRowsTest_Result) Descriptor() ([]byte, []int) { return fileDescriptor_e49b496f4919bda1, []int{1, 0} } func (m *ReadRowsTest_Result) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ReadRowsTest_Result.Unmarshal(m, b) } func (m *ReadRowsTest_Result) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ReadRowsTest_Result.Marshal(b, m, deterministic) } func (m *ReadRowsTest_Result) XXX_Merge(src proto.Message) { xxx_messageInfo_ReadRowsTest_Result.Merge(m, src) } func (m *ReadRowsTest_Result) XXX_Size() int { return xxx_messageInfo_ReadRowsTest_Result.Size(m) } func (m *ReadRowsTest_Result) XXX_DiscardUnknown() { xxx_messageInfo_ReadRowsTest_Result.DiscardUnknown(m) } var xxx_messageInfo_ReadRowsTest_Result proto.InternalMessageInfo func (m *ReadRowsTest_Result) GetRowKey() string { if m != nil { return m.RowKey } return "" } func (m *ReadRowsTest_Result) GetFamilyName() string { if m != nil { return m.FamilyName } return "" } func (m *ReadRowsTest_Result) GetQualifier() string { if m != nil { return m.Qualifier } return "" } func (m *ReadRowsTest_Result) GetTimestampMicros() int64 { if m != nil { return m.TimestampMicros } return 0 } func (m *ReadRowsTest_Result) GetValue() string { if m != nil { return m.Value } return "" } func (m *ReadRowsTest_Result) GetLabel() string { if m != nil { return m.Label } return "" } func (m *ReadRowsTest_Result) GetError() bool { if m != nil { return m.Error } return false } func init() { proto.RegisterType((*TestFile)(nil), "google.cloud.conformance.bigtable.v2.TestFile") proto.RegisterType((*ReadRowsTest)(nil), "google.cloud.conformance.bigtable.v2.ReadRowsTest") proto.RegisterType((*ReadRowsTest_Result)(nil), "google.cloud.conformance.bigtable.v2.ReadRowsTest.Result") } func init() { proto.RegisterFile("tests.proto", fileDescriptor_e49b496f4919bda1) } var fileDescriptor_e49b496f4919bda1 = []byte{ // 404 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x92, 0xc1, 0x6e, 0xd4, 0x30, 0x10, 0x86, 0x95, 0x0d, 0xcd, 0xb6, 0x5e, 0xa0, 0xc8, 0x42, 0xc2, 0xaa, 0x90, 0x08, 0x15, 0x87, 0xc0, 0xc1, 0x95, 0xc2, 0x89, 0xeb, 0x2e, 0x2a, 0x07, 0x04, 0x07, 0x83, 0x38, 0x70, 0x89, 0xbc, 0xd9, 0xc9, 0x62, 0xd5, 0xce, 0x04, 0xdb, 0xd9, 0x68, 0x1f, 0x86, 0x17, 0xe0, 0x5d, 0x78, 0x27, 0x14, 0xbb, 0x69, 0xf7, 0xc0, 0x61, 0xb9, 0xe5, 0xff, 0xc6, 0xff, 0x3f, 0xf6, 0x4c, 0xc8, 0xc2, 0x83, 0xf3, 0x8e, 0x77, 0x16, 0x3d, 0xd2, 0x57, 0x5b, 0xc4, 0xad, 0x06, 0x5e, 0x6b, 0xec, 0x37, 0xbc, 0xc6, 0xb6, 0x41, 0x6b, 0x64, 0x5b, 0x03, 0x5f, 0xab, 0xad, 0x97, 0x6b, 0x0d, 0x7c, 0x57, 0x5e, 0xbc, 0x8c, 0xa7, 0xae, 0x26, 0x76, 0xb5, 0x2b, 0xef, 0xbe, 0x63, 0xd0, 0x65, 0x43, 0x4e, 0xbf, 0x82, 0xf3, 0xd7, 0x4a, 0x03, 0xfd, 0x4e, 0xce, 0x2d, 0xc8, 0x4d, 0x65, 0x71, 0x70, 0x55, 0xe8, 0xc6, 0x92, 0x3c, 0x2d, 0x16, 0x65, 0xc9, 0x8f, 0x69, 0xc7, 0x05, 0xc8, 0x8d, 0xc0, 0xc1, 0x8d, 0x81, 0xe2, 0x91, 0x3d, 0x50, 0xee, 0xf2, 0x57, 0x4a, 0x1e, 0x1e, 0xd6, 0x69, 0x4e, 0x16, 0x1b, 0x70, 0xb5, 0x55, 0x9d, 0x57, 0xd8, 0xb2, 0x24, 0x4f, 0x8a, 0x33, 0x71, 0x88, 0xe8, 0x35, 0xc9, 0xea, 0x1f, 0x7d, 0x7b, 0xe3, 0xd8, 0x2c, 0xdc, 0x82, 0x4f, 0xb7, 0xf8, 0x57, 0x4f, 0x01, 0xae, 0xc3, 0xd6, 0x01, 0x5f, 0x81, 0xd6, 0xab, 0xd1, 0x26, 0x6e, 0xdd, 0xf4, 0x0b, 0x99, 0x5b, 0x70, 0xbd, 0xf6, 0x8e, 0xa5, 0x21, 0xe8, 0xdd, 0xff, 0x3f, 0x87, 0x8b, 0x90, 0x20, 0xa6, 0xa4, 0x8b, 0x3f, 0x09, 0xc9, 0x22, 0xa3, 0xcf, 0xc8, 0xdc, 0xe2, 0x50, 0xdd, 0xc0, 0xfe, 0xf6, 0x15, 0x99, 0xc5, 0xe1, 0x23, 0xec, 0xe9, 0x0b, 0xb2, 0x68, 0xa4, 0x51, 0x7a, 0x5f, 0xb5, 0xd2, 0x00, 0x9b, 0x85, 0x22, 0x89, 0xe8, 0xb3, 0x34, 0x40, 0x9f, 0x93, 0xb3, 0x9f, 0xbd, 0xd4, 0xaa, 0x51, 0x60, 0x59, 0x1a, 0xca, 0xf7, 0x80, 0xbe, 0x26, 0x4f, 0xbc, 0x32, 0xe0, 0xbc, 0x34, 0x5d, 0x65, 0x54, 0x6d, 0xd1, 0xb1, 0x07, 0x79, 0x52, 0xa4, 0xe2, 0xfc, 0x8e, 0x7f, 0x0a, 0x98, 0x3e, 0x25, 0x27, 0x3b, 0xa9, 0x7b, 0x60, 0x27, 0x21, 0x24, 0x8a, 0x91, 0x6a, 0xb9, 0x06, 0xcd, 0xb2, 0x48, 0x83, 0x18, 0x29, 0x58, 0x8b, 0x96, 0xcd, 0xf3, 0xa4, 0x38, 0x15, 0x51, 0x2c, 0xb7, 0xa4, 0xa8, 0xd1, 0x1c, 0x35, 0x98, 0xe5, 0xe3, 0x71, 0x22, 0xef, 0xa1, 0x51, 0xad, 0x1a, 0x17, 0xf5, 0x7b, 0xf6, 0xe6, 0x43, 0xb4, 0xad, 0x82, 0x6d, 0x39, 0x1d, 0xfd, 0x56, 0xf2, 0xb0, 0x7c, 0xbe, 0xba, 0x0f, 0x5a, 0x67, 0xe1, 0xbf, 0x7b, 0xfb, 0x37, 0x00, 0x00, 0xff, 0xff, 0x51, 0xe2, 0xc6, 0xe8, 0xcf, 0x02, 0x00, 0x00, } google-cloud-go-0.49.0/bigtable/internal/conformance/tests.proto000066400000000000000000000025621356504100700247030ustar00rootroot00000000000000// Copyright 2019, Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. syntax = "proto3"; package google.cloud.conformance.bigtable.v2; import "google/bigtable/v2/bigtable.proto"; option csharp_namespace = "Google.Cloud.Bigtable.V2.Tests.Conformance"; option java_outer_classname = "TestDefinition"; option java_package = "com.google.cloud.conformance.bigtable.v2"; message TestFile { repeated ReadRowsTest read_rows_tests = 1; } message ReadRowsTest { // Expected results of reading the row. // Only the last result can be an error. message Result { string row_key = 1; string family_name = 2; string qualifier = 3; int64 timestamp_micros = 4; string value = 5; string label = 6; bool error = 7; } string description = 1; repeated google.bigtable.v2.ReadRowsResponse.CellChunk chunks = 2; repeated Result results = 3; } google-cloud-go-0.49.0/bigtable/internal/mockserver/000077500000000000000000000000001356504100700223355ustar00rootroot00000000000000google-cloud-go-0.49.0/bigtable/internal/mockserver/inmem.go000066400000000000000000000106441356504100700237760ustar00rootroot00000000000000/* Copyright 2019 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package mockserver import ( "context" "net" btpb "google.golang.org/genproto/googleapis/bigtable/v2" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) // Server is an in-memory Cloud Bigtable fake. // It is unauthenticated, and only a rough approximation. type Server struct { Addr string l net.Listener srv *grpc.Server // Any unimplemented methods will cause a panic when called. btpb.BigtableServer // Assign new functions to these parameters to implement specific mock // functionality. // ReadRowsFn mocks ReadRows. ReadRowsFn func(*btpb.ReadRowsRequest, btpb.Bigtable_ReadRowsServer) error // SampleRowKeysFn mocks SampleRowKeys. SampleRowKeysFn func(*btpb.SampleRowKeysRequest, btpb.Bigtable_SampleRowKeysServer) error // MutateRowFn mocks MutateRow. MutateRowFn func(context.Context, *btpb.MutateRowRequest) (*btpb.MutateRowResponse, error) // MutateRowsFn mocks MutateRows. MutateRowsFn func(*btpb.MutateRowsRequest, btpb.Bigtable_MutateRowsServer) error // CheckAndMutateRowFn mocks CheckAndMutateRow. CheckAndMutateRowFn func(context.Context, *btpb.CheckAndMutateRowRequest) (*btpb.CheckAndMutateRowResponse, error) // ReadModifyWriteRowFn mocks ReadModifyWriteRow. ReadModifyWriteRowFn func(context.Context, *btpb.ReadModifyWriteRowRequest) (*btpb.ReadModifyWriteRowResponse, error) } // NewServer creates a new Server. // The Server will be listening for gRPC connections, without TLS, // on the provided address. The resolved address is named by the Addr field. func NewServer(laddr string, opt ...grpc.ServerOption) (*Server, error) { l, err := net.Listen("tcp", laddr) if err != nil { return nil, err } srv := grpc.NewServer(opt...) s := &Server{ Addr: l.Addr().String(), l: l, srv: srv, } btpb.RegisterBigtableServer(srv, s) go srv.Serve(s.l) return s, nil } // Close closes the server. func (s *Server) Close() error { if err := s.l.Close(); err != nil { return err } s.srv.Stop() return nil } // ReadRows implements ReadRows of the BigtableServer interface. func (s *Server) ReadRows(req *btpb.ReadRowsRequest, srv btpb.Bigtable_ReadRowsServer) error { if s.ReadRowsFn != nil { return s.ReadRowsFn(req, srv) } return status.Error(codes.Unimplemented, "unimplemented") } // SampleRowKeys implements SampleRowKeys of the BigtableServer interface. func (s *Server) SampleRowKeys(req *btpb.SampleRowKeysRequest, srv btpb.Bigtable_SampleRowKeysServer) error { if s.SampleRowKeysFn != nil { return s.SampleRowKeysFn(req, srv) } return status.Error(codes.Unimplemented, "unimplemented") } // MutateRow implements MutateRow of the BigtableServer interface. func (s *Server) MutateRow(ctx context.Context, req *btpb.MutateRowRequest) (*btpb.MutateRowResponse, error) { if s.MutateRowFn != nil { return s.MutateRowFn(ctx, req) } return nil, status.Error(codes.Unimplemented, "unimplemented") } // MutateRows implements MutateRows of the BigtableServer interface. func (s *Server) MutateRows(req *btpb.MutateRowsRequest, srv btpb.Bigtable_MutateRowsServer) error { if s.MutateRowsFn != nil { return s.MutateRowsFn(req, srv) } return status.Error(codes.Unimplemented, "unimplemented") } // CheckAndMutateRow implements CheckAndMutateRow of the BigtableServer interface. func (s *Server) CheckAndMutateRow(ctx context.Context, srv *btpb.CheckAndMutateRowRequest) (*btpb.CheckAndMutateRowResponse, error) { if s.CheckAndMutateRowFn != nil { return s.CheckAndMutateRowFn(ctx, srv) } return nil, status.Error(codes.Unimplemented, "unimplemented") } // ReadModifyWriteRow implements ReadModifyWriteRow of the BigtableServer interface. func (s *Server) ReadModifyWriteRow(ctx context.Context, srv *btpb.ReadModifyWriteRowRequest) (*btpb.ReadModifyWriteRowResponse, error) { if s.ReadModifyWriteRowFn != nil { return s.ReadModifyWriteRowFn(ctx, srv) } return nil, status.Error(codes.Unimplemented, "unimplemented") } google-cloud-go-0.49.0/bigtable/internal/option/000077500000000000000000000000001356504100700214655ustar00rootroot00000000000000google-cloud-go-0.49.0/bigtable/internal/option/option.go000066400000000000000000000102741356504100700233300ustar00rootroot00000000000000/* Copyright 2015 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // Package option contains common code for dealing with client options. package option import ( "context" "fmt" "os" "cloud.google.com/go/internal/version" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" "google.golang.org/grpc" "google.golang.org/grpc/metadata" ) // mergeOutgoingMetadata returns a context populated by the existing outgoing // metadata merged with the provided mds. func mergeOutgoingMetadata(ctx context.Context, mds ...metadata.MD) context.Context { // There may not be metadata in the context, only insert the existing // metadata if it exists (ok). ctxMD, ok := metadata.FromOutgoingContext(ctx) if ok { // The ordering matters, hence why ctxMD is added to the front. mds = append([]metadata.MD{ctxMD}, mds...) } return metadata.NewOutgoingContext(ctx, metadata.Join(mds...)) } // withGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func withGoogleClientInfo() metadata.MD { kv := []string{ "gl-go", version.Go(), "gax", gax.Version, "grpc", grpc.Version, } return metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // streamInterceptor intercepts the creation of ClientStream within the bigtable // client to inject Google client information into the context metadata for // streaming RPCs. func streamInterceptor(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) { ctx = mergeOutgoingMetadata(ctx, withGoogleClientInfo()) return streamer(ctx, desc, cc, method, opts...) } // unaryInterceptor intercepts the creation of UnaryInvoker within the bigtable // client to inject Google client information into the context metadata for // unary RPCs. func unaryInterceptor(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { ctx = mergeOutgoingMetadata(ctx, withGoogleClientInfo()) return invoker(ctx, method, req, reply, cc, opts...) } // DefaultClientOptions returns the default client options to use for the // client's gRPC connection. func DefaultClientOptions(endpoint, scope, userAgent string) ([]option.ClientOption, error) { var o []option.ClientOption // Check the environment variables for the bigtable emulator. // Dial it directly and don't pass any credentials. if addr := os.Getenv("BIGTABLE_EMULATOR_HOST"); addr != "" { conn, err := grpc.Dial(addr, grpc.WithInsecure()) if err != nil { return nil, fmt.Errorf("emulator grpc.Dial: %v", err) } o = []option.ClientOption{option.WithGRPCConn(conn)} } else { o = []option.ClientOption{ option.WithEndpoint(endpoint), option.WithScopes(scope), option.WithUserAgent(userAgent), } } return o, nil } // ClientInterceptorOptions returns client options to use for the client's gRPC // connection, using the given streaming and unary RPC interceptors. // // The passed interceptors are applied after internal interceptors which inject // Google client information into the gRPC context. func ClientInterceptorOptions(stream []grpc.StreamClientInterceptor, unary []grpc.UnaryClientInterceptor) []option.ClientOption { // By prepending the interceptors defined here, they will be applied first. stream = append([]grpc.StreamClientInterceptor{streamInterceptor}, stream...) unary = append([]grpc.UnaryClientInterceptor{unaryInterceptor}, unary...) return []option.ClientOption{ option.WithGRPCDialOption(grpc.WithChainStreamInterceptor(stream...)), option.WithGRPCDialOption(grpc.WithChainUnaryInterceptor(unary...)), } } google-cloud-go-0.49.0/bigtable/internal/stat/000077500000000000000000000000001356504100700211305ustar00rootroot00000000000000google-cloud-go-0.49.0/bigtable/internal/stat/stats.go000066400000000000000000000075071356504100700226260ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package stat import ( "bytes" "encoding/csv" "fmt" "io" "math" "sort" "strconv" "text/tabwriter" "time" ) type byDuration []time.Duration func (data byDuration) Len() int { return len(data) } func (data byDuration) Swap(i, j int) { data[i], data[j] = data[j], data[i] } func (data byDuration) Less(i, j int) bool { return data[i] < data[j] } // quantile returns a value representing the kth of q quantiles. // May alter the order of data. func quantile(data []time.Duration, k, q int) (quantile time.Duration, ok bool) { if len(data) < 1 { return 0, false } if k > q { return 0, false } if k < 0 || q < 1 { return 0, false } sort.Sort(byDuration(data)) if k == 0 { return data[0], true } if k == q { return data[len(data)-1], true } bucketSize := float64(len(data)-1) / float64(q) i := float64(k) * bucketSize lower := int(math.Trunc(i)) var upper int if i > float64(lower) && lower+1 < len(data) { // If the quantile lies between two elements upper = lower + 1 } else { upper = lower } weightUpper := i - float64(lower) weightLower := 1 - weightUpper return time.Duration(weightLower*float64(data[lower]) + weightUpper*float64(data[upper])), true } // Aggregate is an aggregate of latencies. type Aggregate struct { Name string Count, Errors int Min, Median, Max time.Duration P75, P90, P95, P99 time.Duration // percentiles } // NewAggregate constructs an aggregate from latencies. Returns nil if latencies does not contain aggregateable data. func NewAggregate(name string, latencies []time.Duration, errorCount int) *Aggregate { agg := Aggregate{Name: name, Count: len(latencies), Errors: errorCount} if len(latencies) == 0 { return nil } var ok bool if agg.Min, ok = quantile(latencies, 0, 2); !ok { return nil } if agg.Median, ok = quantile(latencies, 1, 2); !ok { return nil } if agg.Max, ok = quantile(latencies, 2, 2); !ok { return nil } if agg.P75, ok = quantile(latencies, 75, 100); !ok { return nil } if agg.P90, ok = quantile(latencies, 90, 100); !ok { return nil } if agg.P95, ok = quantile(latencies, 95, 100); !ok { return nil } if agg.P99, ok = quantile(latencies, 99, 100); !ok { return nil } return &agg } func (agg *Aggregate) String() string { if agg == nil { return "no data" } var buf bytes.Buffer tw := tabwriter.NewWriter(&buf, 0, 0, 1, ' ', 0) // one-space padding fmt.Fprintf(tw, "min:\t%v\nmedian:\t%v\nmax:\t%v\n95th percentile:\t%v\n99th percentile:\t%v\n", agg.Min, agg.Median, agg.Max, agg.P95, agg.P99) tw.Flush() return buf.String() } // WriteCSV writes a csv file to the given Writer, // with a header row and one row per aggregate. func WriteCSV(aggs []*Aggregate, iow io.Writer) (err error) { w := csv.NewWriter(iow) defer func() { w.Flush() if err == nil { err = w.Error() } }() err = w.Write([]string{"name", "count", "errors", "min", "median", "max", "p75", "p90", "p95", "p99"}) if err != nil { return err } for _, agg := range aggs { err = w.Write([]string{ agg.Name, strconv.Itoa(agg.Count), strconv.Itoa(agg.Errors), agg.Min.String(), agg.Median.String(), agg.Max.String(), agg.P75.String(), agg.P90.String(), agg.P95.String(), agg.P99.String(), }) if err != nil { return err } } return nil } google-cloud-go-0.49.0/bigtable/reader.go000066400000000000000000000147031356504100700201370ustar00rootroot00000000000000/* Copyright 2016 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package bigtable import ( "bytes" "fmt" btpb "google.golang.org/genproto/googleapis/bigtable/v2" ) // A Row is returned by ReadRows. The map is keyed by column family (the prefix // of the column name before the colon). The values are the returned ReadItems // for that column family in the order returned by Read. type Row map[string][]ReadItem // Key returns the row's key, or "" if the row is empty. func (r Row) Key() string { for _, items := range r { if len(items) > 0 { return items[0].Row } } return "" } // A ReadItem is returned by Read. A ReadItem contains data from a specific row and column. type ReadItem struct { Row, Column string Timestamp Timestamp Value []byte } // The current state of the read rows state machine. type rrState int64 const ( newRow rrState = iota rowInProgress cellInProgress ) // chunkReader handles cell chunks from the read rows response and combines // them into full Rows. type chunkReader struct { state rrState curKey []byte curFam string curQual []byte curTS int64 curVal []byte curRow Row lastKey string } // newChunkReader returns a new chunkReader for handling read rows responses. func newChunkReader() *chunkReader { return &chunkReader{state: newRow} } // Process takes a cell chunk and returns a new Row if the given chunk // completes a Row, or nil otherwise. func (cr *chunkReader) Process(cc *btpb.ReadRowsResponse_CellChunk) (Row, error) { var row Row switch cr.state { case newRow: if err := cr.validateNewRow(cc); err != nil { return nil, err } cr.curRow = make(Row) cr.curKey = cc.RowKey cr.curFam = cc.FamilyName.Value cr.curQual = cc.Qualifier.Value cr.curTS = cc.TimestampMicros row = cr.handleCellValue(cc) case rowInProgress: if err := cr.validateRowInProgress(cc); err != nil { return nil, err } if cc.GetResetRow() { cr.resetToNewRow() return nil, nil } if cc.FamilyName != nil { cr.curFam = cc.FamilyName.Value } if cc.Qualifier != nil { cr.curQual = cc.Qualifier.Value } cr.curTS = cc.TimestampMicros row = cr.handleCellValue(cc) case cellInProgress: if err := cr.validateCellInProgress(cc); err != nil { return nil, err } if cc.GetResetRow() { cr.resetToNewRow() return nil, nil } row = cr.handleCellValue(cc) } return row, nil } // Close must be called after all cell chunks from the response // have been processed. An error will be returned if the reader is // in an invalid state, in which case the error should be propagated to the caller. func (cr *chunkReader) Close() error { if cr.state != newRow { return fmt.Errorf("invalid state for end of stream %q", cr.state) } return nil } // handleCellValue returns a Row if the cell value includes a commit, otherwise nil. func (cr *chunkReader) handleCellValue(cc *btpb.ReadRowsResponse_CellChunk) Row { if cc.ValueSize > 0 { // ValueSize is specified so expect a split value of ValueSize bytes if cr.curVal == nil { cr.curVal = make([]byte, 0, cc.ValueSize) } cr.curVal = append(cr.curVal, cc.Value...) cr.state = cellInProgress } else { // This cell is either the complete value or the last chunk of a split if cr.curVal == nil { cr.curVal = cc.Value } else { cr.curVal = append(cr.curVal, cc.Value...) } cr.finishCell() if cc.GetCommitRow() { return cr.commitRow() } cr.state = rowInProgress } return nil } func (cr *chunkReader) finishCell() { ri := ReadItem{ Row: string(cr.curKey), Column: string(cr.curFam) + ":" + string(cr.curQual), Timestamp: Timestamp(cr.curTS), Value: cr.curVal, } cr.curRow[cr.curFam] = append(cr.curRow[cr.curFam], ri) cr.curVal = nil } func (cr *chunkReader) commitRow() Row { row := cr.curRow cr.lastKey = cr.curRow.Key() cr.resetToNewRow() return row } func (cr *chunkReader) resetToNewRow() { cr.curKey = nil cr.curFam = "" cr.curQual = nil cr.curVal = nil cr.curRow = nil cr.curTS = 0 cr.state = newRow } func (cr *chunkReader) validateNewRow(cc *btpb.ReadRowsResponse_CellChunk) error { if cc.GetResetRow() { return fmt.Errorf("reset_row not allowed between rows") } if cc.RowKey == nil || cc.FamilyName == nil || cc.Qualifier == nil { return fmt.Errorf("missing key field for new row %v", cc) } if cr.lastKey != "" && cr.lastKey >= string(cc.RowKey) { return fmt.Errorf("out of order row key: %q, %q", cr.lastKey, string(cc.RowKey)) } return nil } func (cr *chunkReader) validateRowInProgress(cc *btpb.ReadRowsResponse_CellChunk) error { if err := cr.validateRowStatus(cc); err != nil { return err } if cc.RowKey != nil && !bytes.Equal(cc.RowKey, cr.curKey) { return fmt.Errorf("received new row key %q during existing row %q", cc.RowKey, cr.curKey) } if cc.FamilyName != nil && cc.Qualifier == nil { return fmt.Errorf("family name %q specified without a qualifier", cc.FamilyName) } return nil } func (cr *chunkReader) validateCellInProgress(cc *btpb.ReadRowsResponse_CellChunk) error { if err := cr.validateRowStatus(cc); err != nil { return err } if cr.curVal == nil { return fmt.Errorf("no cached cell while CELL_IN_PROGRESS %v", cc) } if cc.GetResetRow() == false && cr.isAnyKeyPresent(cc) { return fmt.Errorf("cell key components found while CELL_IN_PROGRESS %v", cc) } return nil } func (cr *chunkReader) isAnyKeyPresent(cc *btpb.ReadRowsResponse_CellChunk) bool { return cc.RowKey != nil || cc.FamilyName != nil || cc.Qualifier != nil || cc.TimestampMicros != 0 } // Validate a RowStatus, commit or reset, if present. func (cr *chunkReader) validateRowStatus(cc *btpb.ReadRowsResponse_CellChunk) error { // Resets can't be specified with any other part of a cell if cc.GetResetRow() && (cr.isAnyKeyPresent(cc) || cc.Value != nil || cc.ValueSize != 0 || cc.Labels != nil) { return fmt.Errorf("reset must not be specified with other fields %v", cc) } if cc.GetCommitRow() && cc.ValueSize > 0 { return fmt.Errorf("commit row found in between chunks in a cell") } return nil } google-cloud-go-0.49.0/bigtable/reader_test.go000066400000000000000000000231671356504100700212020ustar00rootroot00000000000000/* Copyright 2016 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package bigtable import ( "encoding/json" "fmt" "io/ioutil" "strings" "testing" "cloud.google.com/go/internal/testutil" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes/wrappers" btspb "google.golang.org/genproto/googleapis/bigtable/v2" ) // Indicates that a field in the proto should be omitted, rather than included // as a wrapped empty string. const nilStr = "<>" func TestSingleCell(t *testing.T) { cr := newChunkReader() // All in one cell row, err := cr.Process(cc("rk", "fm", "col", 1, "value", 0, true)) if err != nil { t.Fatalf("Processing chunk: %v", err) } if row == nil { t.Fatalf("Missing row") } if len(row["fm"]) != 1 { t.Fatalf("Family name length mismatch %d, %d", 1, len(row["fm"])) } want := []ReadItem{ri("rk", "fm", "col", 1, "value")} if !testutil.Equal(row["fm"], want) { t.Fatalf("Incorrect ReadItem: got: %v\nwant: %v\n", row["fm"], want) } if err := cr.Close(); err != nil { t.Fatalf("Close: %v", err) } } func TestMultipleCells(t *testing.T) { cr := newChunkReader() mustProcess(t, cr, cc("rs", "fm1", "col1", 0, "val1", 0, false)) mustProcess(t, cr, cc("rs", "fm1", "col1", 1, "val2", 0, false)) mustProcess(t, cr, cc("rs", "fm1", "col2", 0, "val3", 0, false)) mustProcess(t, cr, cc("rs", "fm2", "col1", 0, "val4", 0, false)) row, err := cr.Process(cc("rs", "fm2", "col2", 1, "extralongval5", 0, true)) if err != nil { t.Fatalf("Processing chunk: %v", err) } if row == nil { t.Fatalf("Missing row") } want := []ReadItem{ ri("rs", "fm1", "col1", 0, "val1"), ri("rs", "fm1", "col1", 1, "val2"), ri("rs", "fm1", "col2", 0, "val3"), } if !testutil.Equal(row["fm1"], want) { t.Fatalf("Incorrect ReadItem: got: %v\nwant: %v\n", row["fm1"], want) } want = []ReadItem{ ri("rs", "fm2", "col1", 0, "val4"), ri("rs", "fm2", "col2", 1, "extralongval5"), } if !testutil.Equal(row["fm2"], want) { t.Fatalf("Incorrect ReadItem: got: %v\nwant: %v\n", row["fm2"], want) } if err := cr.Close(); err != nil { t.Fatalf("Close: %v", err) } } func TestSplitCells(t *testing.T) { cr := newChunkReader() mustProcess(t, cr, cc("rs", "fm1", "col1", 0, "hello ", 11, false)) mustProcess(t, cr, ccData("world", 0, false)) row, err := cr.Process(cc("rs", "fm1", "col2", 0, "val2", 0, true)) if err != nil { t.Fatalf("Processing chunk: %v", err) } if row == nil { t.Fatalf("Missing row") } want := []ReadItem{ ri("rs", "fm1", "col1", 0, "hello world"), ri("rs", "fm1", "col2", 0, "val2"), } if !testutil.Equal(row["fm1"], want) { t.Fatalf("Incorrect ReadItem: got: %v\nwant: %v\n", row["fm1"], want) } if err := cr.Close(); err != nil { t.Fatalf("Close: %v", err) } } func TestMultipleRows(t *testing.T) { cr := newChunkReader() row, err := cr.Process(cc("rs1", "fm1", "col1", 1, "val1", 0, true)) if err != nil { t.Fatalf("Processing chunk: %v", err) } want := []ReadItem{ri("rs1", "fm1", "col1", 1, "val1")} if !testutil.Equal(row["fm1"], want) { t.Fatalf("Incorrect ReadItem: got: %v\nwant: %v\n", row["fm1"], want) } row, err = cr.Process(cc("rs2", "fm2", "col2", 2, "val2", 0, true)) if err != nil { t.Fatalf("Processing chunk: %v", err) } want = []ReadItem{ri("rs2", "fm2", "col2", 2, "val2")} if !testutil.Equal(row["fm2"], want) { t.Fatalf("Incorrect ReadItem: got: %v\nwant: %v\n", row["fm2"], want) } if err := cr.Close(); err != nil { t.Fatalf("Close: %v", err) } } func TestBlankQualifier(t *testing.T) { cr := newChunkReader() row, err := cr.Process(cc("rs1", "fm1", "", 1, "val1", 0, true)) if err != nil { t.Fatalf("Processing chunk: %v", err) } want := []ReadItem{ri("rs1", "fm1", "", 1, "val1")} if !testutil.Equal(row["fm1"], want) { t.Fatalf("Incorrect ReadItem: got: %v\nwant: %v\n", row["fm1"], want) } row, err = cr.Process(cc("rs2", "fm2", "col2", 2, "val2", 0, true)) if err != nil { t.Fatalf("Processing chunk: %v", err) } want = []ReadItem{ri("rs2", "fm2", "col2", 2, "val2")} if !testutil.Equal(row["fm2"], want) { t.Fatalf("Incorrect ReadItem: got: %v\nwant: %v\n", row["fm2"], want) } if err := cr.Close(); err != nil { t.Fatalf("Close: %v", err) } } func TestReset(t *testing.T) { cr := newChunkReader() mustProcess(t, cr, cc("rs", "fm1", "col1", 0, "val1", 0, false)) mustProcess(t, cr, cc("rs", "fm1", "col1", 1, "val2", 0, false)) mustProcess(t, cr, cc("rs", "fm1", "col2", 0, "val3", 0, false)) mustProcess(t, cr, ccReset()) row := mustProcess(t, cr, cc("rs1", "fm1", "col1", 1, "val1", 0, true)) want := []ReadItem{ri("rs1", "fm1", "col1", 1, "val1")} if !testutil.Equal(row["fm1"], want) { t.Fatalf("Reset: got: %v\nwant: %v\n", row["fm1"], want) } if err := cr.Close(); err != nil { t.Fatalf("Close: %v", err) } } func TestNewFamEmptyQualifier(t *testing.T) { cr := newChunkReader() mustProcess(t, cr, cc("rs", "fm1", "col1", 0, "val1", 0, false)) _, err := cr.Process(cc(nilStr, "fm2", nilStr, 0, "val2", 0, true)) if err == nil { t.Fatalf("Expected error on second chunk with no qualifier set") } } func mustProcess(t *testing.T, cr *chunkReader, cc *btspb.ReadRowsResponse_CellChunk) Row { row, err := cr.Process(cc) if err != nil { t.Fatal(err) } return row } // The read rows acceptance test reads a json file specifying a number of tests, // each consisting of one or more cell chunk text protos and one or more resulting // cells or errors. type AcceptanceTest struct { Tests []TestCase `json:"tests"` } type TestCase struct { Name string `json:"name"` Chunks []string `json:"chunks"` Results []TestResult `json:"results"` } type TestResult struct { RK string `json:"rk"` FM string `json:"fm"` Qual string `json:"qual"` TS int64 `json:"ts"` Value string `json:"value"` Error bool `json:"error"` // If true, expect an error. Ignore any other field. } func TestAcceptance(t *testing.T) { testJSON, err := ioutil.ReadFile("./testdata/read-rows-acceptance-test.json") if err != nil { t.Fatalf("could not open acceptance test file %v", err) } var accTest AcceptanceTest err = json.Unmarshal(testJSON, &accTest) if err != nil { t.Fatalf("could not parse acceptance test file: %v", err) } for _, test := range accTest.Tests { runTestCase(t, test) } } func runTestCase(t *testing.T, test TestCase) { // Increment an index into the result array as we get results cr := newChunkReader() var results []TestResult var seenErr bool for _, chunkText := range test.Chunks { // Parse and pass each cell chunk to the ChunkReader cc := &btspb.ReadRowsResponse_CellChunk{} err := proto.UnmarshalText(chunkText, cc) if err != nil { t.Errorf("[%s] failed to unmarshal text proto: %s\n%s", test.Name, chunkText, err) return } row, err := cr.Process(cc) if err != nil { results = append(results, TestResult{Error: true}) seenErr = true break } else { // Turn the Row into TestResults for fm, ris := range row { for _, ri := range ris { tr := TestResult{ RK: ri.Row, FM: fm, Qual: strings.Split(ri.Column, ":")[1], TS: int64(ri.Timestamp), Value: string(ri.Value), } results = append(results, tr) } } } } // Only Close if we don't have an error yet, otherwise Close: is expected. if !seenErr { err := cr.Close() if err != nil { results = append(results, TestResult{Error: true}) } } got := toSet(results) want := toSet(test.Results) if !testutil.Equal(got, want) { t.Fatalf("[%s]: got: %v\nwant: %v\n", test.Name, got, want) } } func toSet(res []TestResult) map[TestResult]bool { set := make(map[TestResult]bool) for _, tr := range res { set[tr] = true } return set } // ri returns a ReadItem for the given components func ri(rk string, fm string, qual string, ts int64, val string) ReadItem { return ReadItem{Row: rk, Column: fmt.Sprintf("%s:%s", fm, qual), Value: []byte(val), Timestamp: Timestamp(ts)} } // cc returns a CellChunk proto func cc(rk string, fm string, qual string, ts int64, val string, size int32, commit bool) *btspb.ReadRowsResponse_CellChunk { // The components of the cell key are wrapped and can be null or empty var rkWrapper []byte if rk == nilStr { rkWrapper = nil } else { rkWrapper = []byte(rk) } var fmWrapper *wrappers.StringValue if fm != nilStr { fmWrapper = &wrappers.StringValue{Value: fm} } else { fmWrapper = nil } var qualWrapper *wrappers.BytesValue if qual != nilStr { qualWrapper = &wrappers.BytesValue{Value: []byte(qual)} } else { qualWrapper = nil } return &btspb.ReadRowsResponse_CellChunk{ RowKey: rkWrapper, FamilyName: fmWrapper, Qualifier: qualWrapper, TimestampMicros: ts, Value: []byte(val), ValueSize: size, RowStatus: &btspb.ReadRowsResponse_CellChunk_CommitRow{CommitRow: commit}} } // ccData returns a CellChunk with only a value and size func ccData(val string, size int32, commit bool) *btspb.ReadRowsResponse_CellChunk { return cc(nilStr, nilStr, nilStr, 0, val, size, commit) } // ccReset returns a CellChunk with RestRow set to true func ccReset() *btspb.ReadRowsResponse_CellChunk { return &btspb.ReadRowsResponse_CellChunk{ RowStatus: &btspb.ReadRowsResponse_CellChunk_ResetRow{ResetRow: true}} } google-cloud-go-0.49.0/bigtable/retry_test.go000066400000000000000000000326701356504100700211040ustar00rootroot00000000000000/* Copyright 2016 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package bigtable import ( "context" "strings" "testing" "time" "cloud.google.com/go/bigtable/bttest" "cloud.google.com/go/internal/testutil" "github.com/golang/protobuf/ptypes/wrappers" "github.com/google/go-cmp/cmp" "google.golang.org/api/option" btpb "google.golang.org/genproto/googleapis/bigtable/v2" rpcpb "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) func setupFakeServer(opt ...grpc.ServerOption) (tbl *Table, cleanup func(), err error) { srv, err := bttest.NewServer("localhost:0", opt...) if err != nil { return nil, nil, err } conn, err := grpc.Dial(srv.Addr, grpc.WithInsecure(), grpc.WithBlock()) if err != nil { return nil, nil, err } client, err := NewClient(context.Background(), "client", "instance", option.WithGRPCConn(conn), option.WithGRPCDialOption(grpc.WithBlock())) if err != nil { return nil, nil, err } adminClient, err := NewAdminClient(context.Background(), "client", "instance", option.WithGRPCConn(conn), option.WithGRPCDialOption(grpc.WithBlock())) if err != nil { return nil, nil, err } if err := adminClient.CreateTable(context.Background(), "table"); err != nil { return nil, nil, err } if err := adminClient.CreateColumnFamily(context.Background(), "table", "cf"); err != nil { return nil, nil, err } t := client.Open("table") cleanupFunc := func() { adminClient.Close() client.Close() srv.Close() } return t, cleanupFunc, nil } func TestRetryApply(t *testing.T) { ctx := context.Background() errCount := 0 code := codes.Unavailable // Will be retried // Intercept requests and return an error or defer to the underlying handler errInjector := func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { if strings.HasSuffix(info.FullMethod, "MutateRow") && errCount < 3 { errCount++ return nil, status.Errorf(code, "") } return handler(ctx, req) } tbl, cleanup, err := setupFakeServer(grpc.UnaryInterceptor(errInjector)) if err != nil { t.Fatalf("fake server setup: %v", err) } defer cleanup() mut := NewMutation() mut.Set("cf", "col", 1000, []byte("val")) if err := tbl.Apply(ctx, "row1", mut); err != nil { t.Errorf("applying single mutation with retries: %v", err) } row, err := tbl.ReadRow(ctx, "row1") if err != nil { t.Errorf("reading single value with retries: %v", err) } if row == nil { t.Errorf("applying single mutation with retries: could not read back row") } code = codes.FailedPrecondition // Won't be retried errCount = 0 if err := tbl.Apply(ctx, "row", mut); err == nil { t.Errorf("applying single mutation with no retries: no error") } // Check and mutate mutTrue := NewMutation() mutTrue.DeleteRow() mutFalse := NewMutation() mutFalse.Set("cf", "col", 1000, []byte("val")) condMut := NewCondMutation(ValueFilter(".*"), mutTrue, mutFalse) errCount = 0 code = codes.Unavailable // Will be retried if err := tbl.Apply(ctx, "row1", condMut); err != nil { t.Errorf("conditionally mutating row with retries: %v", err) } row, err = tbl.ReadRow(ctx, "row1") // row1 already in the table if err != nil { t.Errorf("reading single value after conditional mutation: %v", err) } if row != nil { t.Errorf("reading single value after conditional mutation: row not deleted") } errCount = 0 code = codes.FailedPrecondition // Won't be retried if err := tbl.Apply(ctx, "row", condMut); err == nil { t.Errorf("conditionally mutating row with no retries: no error") } } // Test overall request failure and retries. func TestRetryApplyBulk_OverallRequestFailure(t *testing.T) { ctx := context.Background() // Intercept requests and delegate to an interceptor defined by the test case errCount := 0 errInjector := func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { if strings.HasSuffix(info.FullMethod, "MutateRows") { return func() error { if errCount < 3 { errCount++ return status.Errorf(codes.Aborted, "") } return nil }() } return handler(ctx, ss) } tbl, cleanup, err := setupFakeServer(grpc.StreamInterceptor(errInjector)) defer cleanup() if err != nil { t.Fatalf("fake server setup: %v", err) } errCount = 0 mut := NewMutation() mut.Set("cf", "col", 1, []byte{}) errors, err := tbl.ApplyBulk(ctx, []string{"row2"}, []*Mutation{mut}) if errors != nil || err != nil { t.Errorf("bulk with request failure: got: %v, %v, want: nil", errors, err) } } func TestRetryApplyBulk_FailuresAndRetriesInOneRequest(t *testing.T) { ctx := context.Background() // Intercept requests and delegate to an interceptor defined by the test case errCount := 0 errInjector := func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { if strings.HasSuffix(info.FullMethod, "MutateRows") { return func(ss grpc.ServerStream) error { var err error req := new(btpb.MutateRowsRequest) must(ss.RecvMsg(req)) switch errCount { case 0: // Retryable request failure err = status.Errorf(codes.Unavailable, "") case 1: // Two mutations fail must(writeMutateRowsResponse(ss, codes.Unavailable, codes.OK, codes.Aborted)) err = nil case 2: // Two failures were retried. One will succeed. if want, got := 2, len(req.Entries); want != got { t.Fatalf("2 bulk retries, got: %d, want %d", got, want) } must(writeMutateRowsResponse(ss, codes.OK, codes.Aborted)) err = nil case 3: // One failure was retried and will succeed. if want, got := 1, len(req.Entries); want != got { t.Fatalf("1 bulk retry, got: %d, want %d", got, want) } must(writeMutateRowsResponse(ss, codes.OK)) err = nil } errCount++ return err }(ss) } return handler(ctx, ss) } tbl, cleanup, err := setupFakeServer(grpc.StreamInterceptor(errInjector)) defer cleanup() if err != nil { t.Fatalf("fake server setup: %v", err) } errCount = 0 errCount = 0 m1 := NewMutation() m1.Set("cf", "col", 1, []byte{}) m2 := NewMutation() m2.Set("cf", "col2", 1, []byte{}) m3 := NewMutation() m3.Set("cf", "col3", 1, []byte{}) errors, err := tbl.ApplyBulk(ctx, []string{"row1", "row2", "row3"}, []*Mutation{m1, m2, m3}) if errors != nil || err != nil { t.Errorf("bulk with retries: got: %v, %v, want: nil", errors, err) } } func TestRetryApplyBulk_UnretryableErrors(t *testing.T) { ctx := context.Background() // Intercept requests and delegate to an interceptor defined by the test case errCount := 0 errInjector := func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { if strings.HasSuffix(info.FullMethod, "MutateRows") { return func(ss grpc.ServerStream) error { var err error req := new(btpb.MutateRowsRequest) must(ss.RecvMsg(req)) switch errCount { case 0: // Give non-idempotent mutation a retryable error code. // Nothing should be retried. must(writeMutateRowsResponse(ss, codes.FailedPrecondition, codes.Aborted)) err = nil case 1: t.Fatalf("unretryable errors: got one retry, want no retries") } errCount++ return err }(ss) } return handler(ctx, ss) } tbl, cleanup, err := setupFakeServer(grpc.StreamInterceptor(errInjector)) defer cleanup() if err != nil { t.Fatalf("fake server setup: %v", err) } errCount = 0 m1 := NewMutation() m1.Set("cf", "col", 1, []byte{}) m2 := NewMutation() m2.Set("cf", "col2", 1, []byte{}) m3 := NewMutation() m3.Set("cf", "col3", 1, []byte{}) niMut := NewMutation() niMut.Set("cf", "col", ServerTime, []byte{}) // Non-idempotent errCount = 0 errors, err := tbl.ApplyBulk(ctx, []string{"row1", "row2"}, []*Mutation{m1, niMut}) if err != nil { t.Fatalf("unretryable errors: request failed %v", err) } want := []error{ status.Errorf(codes.FailedPrecondition, ""), status.Errorf(codes.Aborted, ""), } if !testutil.Equal(want, errors) { t.Errorf("unretryable errors: got: %v, want: %v", errors, want) } } func TestRetryApplyBulk_IndividualErrorsAndDeadlineExceeded(t *testing.T) { ctx := context.Background() // Intercept requests and delegate to an interceptor defined by the test case errInjector := func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { if strings.HasSuffix(info.FullMethod, "MutateRows") { return func(ss grpc.ServerStream) error { return writeMutateRowsResponse(ss, codes.FailedPrecondition, codes.OK, codes.Aborted) }(ss) } return handler(ctx, ss) } tbl, cleanup, err := setupFakeServer(grpc.StreamInterceptor(errInjector)) defer cleanup() if err != nil { t.Fatalf("fake server setup: %v", err) } m1 := NewMutation() m1.Set("cf", "col", 1, []byte{}) m2 := NewMutation() m2.Set("cf", "col2", 1, []byte{}) m3 := NewMutation() m3.Set("cf", "col3", 1, []byte{}) // This should cause a deadline exceeded error. ctx, cancel := context.WithTimeout(ctx, -10*time.Millisecond) defer cancel() errors, err := tbl.ApplyBulk(ctx, []string{"row1", "row2", "row3"}, []*Mutation{m1, m2, m3}) wantErr := context.DeadlineExceeded if wantErr != err { t.Fatalf("deadline exceeded error: got: %v, want: %v", err, wantErr) } if errors != nil { t.Errorf("deadline exceeded errors: got: %v, want: nil", err) } } func writeMutateRowsResponse(ss grpc.ServerStream, codes ...codes.Code) error { res := &btpb.MutateRowsResponse{Entries: make([]*btpb.MutateRowsResponse_Entry, len(codes))} for i, code := range codes { res.Entries[i] = &btpb.MutateRowsResponse_Entry{ Index: int64(i), Status: &rpcpb.Status{Code: int32(code), Message: ""}, } } return ss.SendMsg(res) } func TestRetainRowsAfter(t *testing.T) { prevRowRange := NewRange("a", "z") prevRowKey := "m" want := NewRange("m\x00", "z") got := prevRowRange.retainRowsAfter(prevRowKey) if !testutil.Equal(want, got, cmp.AllowUnexported(RowRange{})) { t.Errorf("range retry: got %v, want %v", got, want) } prevRowRangeList := RowRangeList{NewRange("a", "d"), NewRange("e", "g"), NewRange("h", "l")} prevRowKey = "f" wantRowRangeList := RowRangeList{NewRange("f\x00", "g"), NewRange("h", "l")} got = prevRowRangeList.retainRowsAfter(prevRowKey) if !testutil.Equal(wantRowRangeList, got, cmp.AllowUnexported(RowRange{})) { t.Errorf("range list retry: got %v, want %v", got, wantRowRangeList) } prevRowList := RowList{"a", "b", "c", "d", "e", "f"} prevRowKey = "b" wantList := RowList{"c", "d", "e", "f"} got = prevRowList.retainRowsAfter(prevRowKey) if !testutil.Equal(wantList, got) { t.Errorf("list retry: got %v, want %v", got, wantList) } } func TestRetryReadRows(t *testing.T) { ctx := context.Background() // Intercept requests and delegate to an interceptor defined by the test case errCount := 0 var f func(grpc.ServerStream) error errInjector := func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { if strings.HasSuffix(info.FullMethod, "ReadRows") { return f(ss) } return handler(ctx, ss) } tbl, cleanup, err := setupFakeServer(grpc.StreamInterceptor(errInjector)) defer cleanup() if err != nil { t.Fatalf("fake server setup: %v", err) } errCount = 0 // Test overall request failure and retries f = func(ss grpc.ServerStream) error { var err error req := new(btpb.ReadRowsRequest) must(ss.RecvMsg(req)) switch errCount { case 0: // Retryable request failure err = status.Errorf(codes.Unavailable, "") case 1: // Write two rows then error if want, got := "a", string(req.Rows.RowRanges[0].GetStartKeyClosed()); want != got { t.Errorf("first retry, no data received yet: got %q, want %q", got, want) } must(writeReadRowsResponse(ss, "a", "b")) err = status.Errorf(codes.Unavailable, "") case 2: // Retryable request failure if want, got := "b\x00", string(req.Rows.RowRanges[0].GetStartKeyClosed()); want != got { t.Errorf("2 range retries: got %q, want %q", got, want) } err = status.Errorf(codes.Unavailable, "") case 3: // Write two more rows must(writeReadRowsResponse(ss, "c", "d")) err = nil } errCount++ return err } var got []string must(tbl.ReadRows(ctx, NewRange("a", "z"), func(r Row) bool { got = append(got, r.Key()) return true })) want := []string{"a", "b", "c", "d"} if !testutil.Equal(got, want) { t.Errorf("retry range integration: got %v, want %v", got, want) } } func writeReadRowsResponse(ss grpc.ServerStream, rowKeys ...string) error { var chunks []*btpb.ReadRowsResponse_CellChunk for _, key := range rowKeys { chunks = append(chunks, &btpb.ReadRowsResponse_CellChunk{ RowKey: []byte(key), FamilyName: &wrappers.StringValue{Value: "fm"}, Qualifier: &wrappers.BytesValue{Value: []byte("col")}, RowStatus: &btpb.ReadRowsResponse_CellChunk_CommitRow{CommitRow: true}, }) } return ss.SendMsg(&btpb.ReadRowsResponse{Chunks: chunks}) } func must(err error) { if err != nil { panic(err) } } google-cloud-go-0.49.0/bigtable/testdata/000077500000000000000000000000001356504100700201525ustar00rootroot00000000000000google-cloud-go-0.49.0/bigtable/testdata/read-rows-acceptance-test.json000066400000000000000000001065121356504100700260160ustar00rootroot00000000000000{ "tests": [ { "name": "invalid - no commit", "chunks": [ "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL\"\ncommit_row: false\n" ], "results": [ { "rk": "", "fm": "", "qual": "", "ts": 0, "value": "", "label": "", "error": true } ] }, { "name": "invalid - no cell key before commit", "chunks": [ "commit_row: true\n" ], "results": [ { "rk": "", "fm": "", "qual": "", "ts": 0, "value": "", "label": "", "error": true } ] }, { "name": "invalid - no cell key before value", "chunks": [ "timestamp_micros: 100\nvalue: \"value-VAL\"\ncommit_row: false\n" ], "results": [ { "rk": "", "fm": "", "qual": "", "ts": 0, "value": "", "label": "", "error": true } ] }, { "name": "invalid - new col family must specify qualifier", "chunks": [ "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 101\nvalue: \"value-VAL_1\"\ncommit_row: false\n", "family_name: \u003c\n value: \"B\"\n\u003e\ntimestamp_micros: 102\nvalue: \"value-VAL_2\"\ncommit_row: true\n" ], "results": [ { "rk": "", "fm": "", "qual": "", "ts": 0, "value": "", "label": "", "error": true } ] }, { "name": "bare commit implies ts=0", "chunks": [ "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL\"\ncommit_row: false\n", "commit_row: true\n" ], "results": [ { "rk": "RK", "fm": "A", "qual": "C", "ts": 100, "value": "value-VAL", "label": "", "error": false }, { "rk": "RK", "fm": "A", "qual": "C", "ts": 0, "value": "", "label": "", "error": false } ] }, { "name": "simple row with timestamp", "chunks": [ "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL\"\ncommit_row: true\n" ], "results": [ { "rk": "RK", "fm": "A", "qual": "C", "ts": 100, "value": "value-VAL", "label": "", "error": false } ] }, { "name": "missing timestamp, implied ts=0", "chunks": [ "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\nvalue: \"value-VAL\"\ncommit_row: true\n" ], "results": [ { "rk": "RK", "fm": "A", "qual": "C", "ts": 0, "value": "value-VAL", "label": "", "error": false } ] }, { "name": "empty cell value", "chunks": [ "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ncommit_row: true\n" ], "results": [ { "rk": "RK", "fm": "A", "qual": "C", "ts": 0, "value": "", "label": "", "error": false } ] }, { "name": "two unsplit cells", "chunks": [ "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 101\nvalue: \"value-VAL_1\"\ncommit_row: false\n", "timestamp_micros: 102\nvalue: \"value-VAL_2\"\ncommit_row: true\n" ], "results": [ { "rk": "RK", "fm": "A", "qual": "C", "ts": 101, "value": "value-VAL_1", "label": "", "error": false }, { "rk": "RK", "fm": "A", "qual": "C", "ts": 102, "value": "value-VAL_2", "label": "", "error": false } ] }, { "name": "two qualifiers", "chunks": [ "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 101\nvalue: \"value-VAL_1\"\ncommit_row: false\n", "qualifier: \u003c\n value: \"D\"\n\u003e\ntimestamp_micros: 102\nvalue: \"value-VAL_2\"\ncommit_row: true\n" ], "results": [ { "rk": "RK", "fm": "A", "qual": "C", "ts": 101, "value": "value-VAL_1", "label": "", "error": false }, { "rk": "RK", "fm": "A", "qual": "D", "ts": 102, "value": "value-VAL_2", "label": "", "error": false } ] }, { "name": "two families", "chunks": [ "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 101\nvalue: \"value-VAL_1\"\ncommit_row: false\n", "family_name: \u003c\n value: \"B\"\n\u003e\nqualifier: \u003c\n value: \"E\"\n\u003e\ntimestamp_micros: 102\nvalue: \"value-VAL_2\"\ncommit_row: true\n" ], "results": [ { "rk": "RK", "fm": "A", "qual": "C", "ts": 101, "value": "value-VAL_1", "label": "", "error": false }, { "rk": "RK", "fm": "B", "qual": "E", "ts": 102, "value": "value-VAL_2", "label": "", "error": false } ] }, { "name": "with labels", "chunks": [ "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 101\nlabels: \"L_1\"\nvalue: \"value-VAL_1\"\ncommit_row: false\n", "timestamp_micros: 102\nlabels: \"L_2\"\nvalue: \"value-VAL_2\"\ncommit_row: true\n" ], "results": [ { "rk": "RK", "fm": "A", "qual": "C", "ts": 101, "value": "value-VAL_1", "label": "L_1", "error": false }, { "rk": "RK", "fm": "A", "qual": "C", "ts": 102, "value": "value-VAL_2", "label": "L_2", "error": false } ] }, { "name": "split cell, bare commit", "chunks": [ "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"v\"\nvalue_size: 10\ncommit_row: false\n", "value: \"alue-VAL\"\ncommit_row: false\n", "commit_row: true\n" ], "results": [ { "rk": "RK", "fm": "A", "qual": "C", "ts": 100, "value": "value-VAL", "label": "", "error": false }, { "rk": "RK", "fm": "A", "qual": "C", "ts": 0, "value": "", "label": "", "error": false } ] }, { "name": "split cell", "chunks": [ "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"v\"\nvalue_size: 10\ncommit_row: false\n", "value: \"alue-VAL\"\ncommit_row: true\n" ], "results": [ { "rk": "RK", "fm": "A", "qual": "C", "ts": 100, "value": "value-VAL", "label": "", "error": false } ] }, { "name": "split four ways", "chunks": [ "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nlabels: \"L\"\nvalue: \"v\"\nvalue_size: 10\ncommit_row: false\n", "value: \"a\"\nvalue_size: 10\ncommit_row: false\n", "value: \"l\"\nvalue_size: 10\ncommit_row: false\n", "value: \"ue-VAL\"\ncommit_row: true\n" ], "results": [ { "rk": "RK", "fm": "A", "qual": "C", "ts": 100, "value": "value-VAL", "label": "L", "error": false } ] }, { "name": "two split cells", "chunks": [ "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 101\nvalue: \"v\"\nvalue_size: 10\ncommit_row: false\n", "value: \"alue-VAL_1\"\ncommit_row: false\n", "timestamp_micros: 102\nvalue: \"v\"\nvalue_size: 10\ncommit_row: false\n", "value: \"alue-VAL_2\"\ncommit_row: true\n" ], "results": [ { "rk": "RK", "fm": "A", "qual": "C", "ts": 101, "value": "value-VAL_1", "label": "", "error": false }, { "rk": "RK", "fm": "A", "qual": "C", "ts": 102, "value": "value-VAL_2", "label": "", "error": false } ] }, { "name": "multi-qualifier splits", "chunks": [ "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 101\nvalue: \"v\"\nvalue_size: 10\ncommit_row: false\n", "value: \"alue-VAL_1\"\ncommit_row: false\n", "qualifier: \u003c\n value: \"D\"\n\u003e\ntimestamp_micros: 102\nvalue: \"v\"\nvalue_size: 10\ncommit_row: false\n", "value: \"alue-VAL_2\"\ncommit_row: true\n" ], "results": [ { "rk": "RK", "fm": "A", "qual": "C", "ts": 101, "value": "value-VAL_1", "label": "", "error": false }, { "rk": "RK", "fm": "A", "qual": "D", "ts": 102, "value": "value-VAL_2", "label": "", "error": false } ] }, { "name": "multi-qualifier multi-split", "chunks": [ "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 101\nvalue: \"v\"\nvalue_size: 10\ncommit_row: false\n", "value: \"a\"\nvalue_size: 10\ncommit_row: false\n", "value: \"lue-VAL_1\"\ncommit_row: false\n", "qualifier: \u003c\n value: \"D\"\n\u003e\ntimestamp_micros: 102\nvalue: \"v\"\nvalue_size: 10\ncommit_row: false\n", "value: \"a\"\nvalue_size: 10\ncommit_row: false\n", "value: \"lue-VAL_2\"\ncommit_row: true\n" ], "results": [ { "rk": "RK", "fm": "A", "qual": "C", "ts": 101, "value": "value-VAL_1", "label": "", "error": false }, { "rk": "RK", "fm": "A", "qual": "D", "ts": 102, "value": "value-VAL_2", "label": "", "error": false } ] }, { "name": "multi-family split", "chunks": [ "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 101\nvalue: \"v\"\nvalue_size: 10\ncommit_row: false\n", "value: \"alue-VAL_1\"\ncommit_row: false\n", "family_name: \u003c\n value: \"B\"\n\u003e\nqualifier: \u003c\n value: \"E\"\n\u003e\ntimestamp_micros: 102\nvalue: \"v\"\nvalue_size: 10\ncommit_row: false\n", "value: \"alue-VAL_2\"\ncommit_row: true\n" ], "results": [ { "rk": "RK", "fm": "A", "qual": "C", "ts": 101, "value": "value-VAL_1", "label": "", "error": false }, { "rk": "RK", "fm": "B", "qual": "E", "ts": 102, "value": "value-VAL_2", "label": "", "error": false } ] }, { "name": "invalid - no commit between rows", "chunks": [ "row_key: \"RK_1\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL\"\ncommit_row: false\n", "row_key: \"RK_2\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL\"\ncommit_row: false\n" ], "results": [ { "rk": "", "fm": "", "qual": "", "ts": 0, "value": "", "label": "", "error": true } ] }, { "name": "invalid - no commit after first row", "chunks": [ "row_key: \"RK_1\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL\"\ncommit_row: false\n", "row_key: \"RK_2\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL\"\ncommit_row: true\n" ], "results": [ { "rk": "", "fm": "", "qual": "", "ts": 0, "value": "", "label": "", "error": true } ] }, { "name": "invalid - last row missing commit", "chunks": [ "row_key: \"RK_1\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL\"\ncommit_row: true\n", "row_key: \"RK_2\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL\"\ncommit_row: false\n" ], "results": [ { "rk": "RK_1", "fm": "A", "qual": "C", "ts": 100, "value": "value-VAL", "label": "", "error": false }, { "rk": "", "fm": "", "qual": "", "ts": 0, "value": "", "label": "", "error": true } ] }, { "name": "invalid - duplicate row key", "chunks": [ "row_key: \"RK_1\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL\"\ncommit_row: true\n", "row_key: \"RK_1\"\nfamily_name: \u003c\n value: \"B\"\n\u003e\nqualifier: \u003c\n value: \"D\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL\"\ncommit_row: true\n" ], "results": [ { "rk": "RK_1", "fm": "A", "qual": "C", "ts": 100, "value": "value-VAL", "label": "", "error": false }, { "rk": "", "fm": "", "qual": "", "ts": 0, "value": "", "label": "", "error": true } ] }, { "name": "invalid - new row missing row key", "chunks": [ "row_key: \"RK_1\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL\"\ncommit_row: true\n", "timestamp_micros: 100\nvalue: \"value-VAL\"\ncommit_row: true\n" ], "results": [ { "rk": "RK_1", "fm": "A", "qual": "C", "ts": 100, "value": "value-VAL", "label": "", "error": false }, { "rk": "", "fm": "", "qual": "", "ts": 0, "value": "", "label": "", "error": true } ] }, { "name": "two rows", "chunks": [ "row_key: \"RK_1\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL\"\ncommit_row: true\n", "row_key: \"RK_2\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL\"\ncommit_row: true\n" ], "results": [ { "rk": "RK_1", "fm": "A", "qual": "C", "ts": 100, "value": "value-VAL", "label": "", "error": false }, { "rk": "RK_2", "fm": "A", "qual": "C", "ts": 100, "value": "value-VAL", "label": "", "error": false } ] }, { "name": "two rows implicit timestamp", "chunks": [ "row_key: \"RK_1\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\nvalue: \"value-VAL\"\ncommit_row: true\n", "row_key: \"RK_2\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL\"\ncommit_row: true\n" ], "results": [ { "rk": "RK_1", "fm": "A", "qual": "C", "ts": 0, "value": "value-VAL", "label": "", "error": false }, { "rk": "RK_2", "fm": "A", "qual": "C", "ts": 100, "value": "value-VAL", "label": "", "error": false } ] }, { "name": "two rows empty value", "chunks": [ "row_key: \"RK_1\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ncommit_row: true\n", "row_key: \"RK_2\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL\"\ncommit_row: true\n" ], "results": [ { "rk": "RK_1", "fm": "A", "qual": "C", "ts": 0, "value": "", "label": "", "error": false }, { "rk": "RK_2", "fm": "A", "qual": "C", "ts": 100, "value": "value-VAL", "label": "", "error": false } ] }, { "name": "two rows, one with multiple cells", "chunks": [ "row_key: \"RK_1\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 101\nvalue: \"value-VAL_1\"\ncommit_row: false\n", "timestamp_micros: 102\nvalue: \"value-VAL_2\"\ncommit_row: true\n", "row_key: \"RK_2\"\nfamily_name: \u003c\n value: \"B\"\n\u003e\nqualifier: \u003c\n value: \"D\"\n\u003e\ntimestamp_micros: 103\nvalue: \"value-VAL_3\"\ncommit_row: true\n" ], "results": [ { "rk": "RK_1", "fm": "A", "qual": "C", "ts": 101, "value": "value-VAL_1", "label": "", "error": false }, { "rk": "RK_1", "fm": "A", "qual": "C", "ts": 102, "value": "value-VAL_2", "label": "", "error": false }, { "rk": "RK_2", "fm": "B", "qual": "D", "ts": 103, "value": "value-VAL_3", "label": "", "error": false } ] }, { "name": "two rows, multiple cells", "chunks": [ "row_key: \"RK_1\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 101\nvalue: \"value-VAL_1\"\ncommit_row: false\n", "qualifier: \u003c\n value: \"D\"\n\u003e\ntimestamp_micros: 102\nvalue: \"value-VAL_2\"\ncommit_row: true\n", "row_key: \"RK_2\"\nfamily_name: \u003c\n value: \"B\"\n\u003e\nqualifier: \u003c\n value: \"E\"\n\u003e\ntimestamp_micros: 103\nvalue: \"value-VAL_3\"\ncommit_row: false\n", "qualifier: \u003c\n value: \"F\"\n\u003e\ntimestamp_micros: 104\nvalue: \"value-VAL_4\"\ncommit_row: true\n" ], "results": [ { "rk": "RK_1", "fm": "A", "qual": "C", "ts": 101, "value": "value-VAL_1", "label": "", "error": false }, { "rk": "RK_1", "fm": "A", "qual": "D", "ts": 102, "value": "value-VAL_2", "label": "", "error": false }, { "rk": "RK_2", "fm": "B", "qual": "E", "ts": 103, "value": "value-VAL_3", "label": "", "error": false }, { "rk": "RK_2", "fm": "B", "qual": "F", "ts": 104, "value": "value-VAL_4", "label": "", "error": false } ] }, { "name": "two rows, multiple cells, multiple families", "chunks": [ "row_key: \"RK_1\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 101\nvalue: \"value-VAL_1\"\ncommit_row: false\n", "family_name: \u003c\n value: \"B\"\n\u003e\nqualifier: \u003c\n value: \"E\"\n\u003e\ntimestamp_micros: 102\nvalue: \"value-VAL_2\"\ncommit_row: true\n", "row_key: \"RK_2\"\nfamily_name: \u003c\n value: \"M\"\n\u003e\nqualifier: \u003c\n value: \"O\"\n\u003e\ntimestamp_micros: 103\nvalue: \"value-VAL_3\"\ncommit_row: false\n", "family_name: \u003c\n value: \"N\"\n\u003e\nqualifier: \u003c\n value: \"P\"\n\u003e\ntimestamp_micros: 104\nvalue: \"value-VAL_4\"\ncommit_row: true\n" ], "results": [ { "rk": "RK_1", "fm": "A", "qual": "C", "ts": 101, "value": "value-VAL_1", "label": "", "error": false }, { "rk": "RK_1", "fm": "B", "qual": "E", "ts": 102, "value": "value-VAL_2", "label": "", "error": false }, { "rk": "RK_2", "fm": "M", "qual": "O", "ts": 103, "value": "value-VAL_3", "label": "", "error": false }, { "rk": "RK_2", "fm": "N", "qual": "P", "ts": 104, "value": "value-VAL_4", "label": "", "error": false } ] }, { "name": "two rows, four cells, 2 labels", "chunks": [ "row_key: \"RK_1\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 101\nlabels: \"L_1\"\nvalue: \"value-VAL_1\"\ncommit_row: false\n", "timestamp_micros: 102\nvalue: \"value-VAL_2\"\ncommit_row: true\n", "row_key: \"RK_2\"\nfamily_name: \u003c\n value: \"B\"\n\u003e\nqualifier: \u003c\n value: \"D\"\n\u003e\ntimestamp_micros: 103\nlabels: \"L_3\"\nvalue: \"value-VAL_3\"\ncommit_row: false\n", "timestamp_micros: 104\nvalue: \"value-VAL_4\"\ncommit_row: true\n" ], "results": [ { "rk": "RK_1", "fm": "A", "qual": "C", "ts": 101, "value": "value-VAL_1", "label": "L_1", "error": false }, { "rk": "RK_1", "fm": "A", "qual": "C", "ts": 102, "value": "value-VAL_2", "label": "", "error": false }, { "rk": "RK_2", "fm": "B", "qual": "D", "ts": 103, "value": "value-VAL_3", "label": "L_3", "error": false }, { "rk": "RK_2", "fm": "B", "qual": "D", "ts": 104, "value": "value-VAL_4", "label": "", "error": false } ] }, { "name": "two rows with splits, same timestamp", "chunks": [ "row_key: \"RK_1\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"v\"\nvalue_size: 10\ncommit_row: false\n", "value: \"alue-VAL_1\"\ncommit_row: true\n", "row_key: \"RK_2\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"v\"\nvalue_size: 10\ncommit_row: false\n", "value: \"alue-VAL_2\"\ncommit_row: true\n" ], "results": [ { "rk": "RK_1", "fm": "A", "qual": "C", "ts": 100, "value": "value-VAL_1", "label": "", "error": false }, { "rk": "RK_2", "fm": "A", "qual": "C", "ts": 100, "value": "value-VAL_2", "label": "", "error": false } ] }, { "name": "invalid - bare reset", "chunks": [ "reset_row: true\n" ], "results": [ { "rk": "", "fm": "", "qual": "", "ts": 0, "value": "", "label": "", "error": true } ] }, { "name": "invalid - bad reset, no commit", "chunks": [ "reset_row: true\n", "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL\"\ncommit_row: false\n" ], "results": [ { "rk": "", "fm": "", "qual": "", "ts": 0, "value": "", "label": "", "error": true } ] }, { "name": "invalid - missing key after reset", "chunks": [ "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL\"\ncommit_row: false\n", "reset_row: true\n", "timestamp_micros: 100\nvalue: \"value-VAL\"\ncommit_row: true\n" ], "results": [ { "rk": "", "fm": "", "qual": "", "ts": 0, "value": "", "label": "", "error": true } ] }, { "name": "no data after reset", "chunks": [ "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL\"\ncommit_row: false\n", "reset_row: true\n" ], "results": null }, { "name": "simple reset", "chunks": [ "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL\"\ncommit_row: false\n", "reset_row: true\n", "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL\"\ncommit_row: true\n" ], "results": [ { "rk": "RK", "fm": "A", "qual": "C", "ts": 100, "value": "value-VAL", "label": "", "error": false } ] }, { "name": "reset to new val", "chunks": [ "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL_1\"\ncommit_row: false\n", "reset_row: true\n", "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL_2\"\ncommit_row: true\n" ], "results": [ { "rk": "RK", "fm": "A", "qual": "C", "ts": 100, "value": "value-VAL_2", "label": "", "error": false } ] }, { "name": "reset to new qual", "chunks": [ "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL_1\"\ncommit_row: false\n", "reset_row: true\n", "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"D\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL_1\"\ncommit_row: true\n" ], "results": [ { "rk": "RK", "fm": "A", "qual": "D", "ts": 100, "value": "value-VAL_1", "label": "", "error": false } ] }, { "name": "reset with splits", "chunks": [ "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL_1\"\ncommit_row: false\n", "timestamp_micros: 102\nvalue: \"value-VAL_2\"\ncommit_row: false\n", "reset_row: true\n", "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL_2\"\ncommit_row: true\n" ], "results": [ { "rk": "RK", "fm": "A", "qual": "C", "ts": 100, "value": "value-VAL_2", "label": "", "error": false } ] }, { "name": "reset two cells", "chunks": [ "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL_1\"\ncommit_row: false\n", "reset_row: true\n", "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL_2\"\ncommit_row: false\n", "timestamp_micros: 103\nvalue: \"value-VAL_3\"\ncommit_row: true\n" ], "results": [ { "rk": "RK", "fm": "A", "qual": "C", "ts": 100, "value": "value-VAL_2", "label": "", "error": false }, { "rk": "RK", "fm": "A", "qual": "C", "ts": 103, "value": "value-VAL_3", "label": "", "error": false } ] }, { "name": "two resets", "chunks": [ "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL_1\"\ncommit_row: false\n", "reset_row: true\n", "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL_2\"\ncommit_row: false\n", "reset_row: true\n", "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL_3\"\ncommit_row: true\n" ], "results": [ { "rk": "RK", "fm": "A", "qual": "C", "ts": 100, "value": "value-VAL_3", "label": "", "error": false } ] }, { "name": "reset then two cells", "chunks": [ "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL_1\"\ncommit_row: false\n", "reset_row: true\n", "row_key: \"RK\"\nfamily_name: \u003c\n value: \"B\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL_2\"\ncommit_row: false\n", "qualifier: \u003c\n value: \"D\"\n\u003e\ntimestamp_micros: 103\nvalue: \"value-VAL_3\"\ncommit_row: true\n" ], "results": [ { "rk": "RK", "fm": "B", "qual": "C", "ts": 100, "value": "value-VAL_2", "label": "", "error": false }, { "rk": "RK", "fm": "B", "qual": "D", "ts": 103, "value": "value-VAL_3", "label": "", "error": false } ] }, { "name": "reset to new row", "chunks": [ "row_key: \"RK_1\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL_1\"\ncommit_row: false\n", "reset_row: true\n", "row_key: \"RK_2\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL_2\"\ncommit_row: true\n" ], "results": [ { "rk": "RK_2", "fm": "A", "qual": "C", "ts": 100, "value": "value-VAL_2", "label": "", "error": false } ] }, { "name": "reset in between chunks", "chunks": [ "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nlabels: \"L\"\nvalue: \"v\"\nvalue_size: 10\ncommit_row: false\n", "value: \"a\"\nvalue_size: 10\ncommit_row: false\n", "reset_row: true\n", "row_key: \"RK_1\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL_1\"\ncommit_row: true\n" ], "results": [ { "rk": "RK_1", "fm": "A", "qual": "C", "ts": 100, "value": "value-VAL_1", "label": "", "error": false } ] }, { "name": "invalid - reset with chunk", "chunks": [ "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nlabels: \"L\"\nvalue: \"v\"\nvalue_size: 10\ncommit_row: false\n", "value: \"a\"\nvalue_size: 10\nreset_row: true\n" ], "results": [ { "rk": "", "fm": "", "qual": "", "ts": 0, "value": "", "label": "", "error": true } ] }, { "name": "invalid - commit with chunk", "chunks": [ "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nlabels: \"L\"\nvalue: \"v\"\nvalue_size: 10\ncommit_row: false\n", "value: \"a\"\nvalue_size: 10\ncommit_row: true\n" ], "results": [ { "rk": "", "fm": "", "qual": "", "ts": 0, "value": "", "label": "", "error": true } ] }, { "name": "empty cell chunk", "chunks": [ "row_key: \"RK\"\nfamily_name: \u003c\n value: \"A\"\n\u003e\nqualifier: \u003c\n value: \"C\"\n\u003e\ntimestamp_micros: 100\nvalue: \"value-VAL\"\ncommit_row: false\n", "commit_row: false\n", "commit_row: true\n" ], "results": [ { "rk": "RK", "fm": "A", "qual": "C", "ts": 100, "value": "value-VAL", "label": "", "error": false }, { "rk": "RK", "fm": "A", "qual": "C", "ts": 0, "value": "", "label": "", "error": false }, { "rk": "RK", "fm": "A", "qual": "C", "ts": 0, "value": "", "label": "", "error": false } ] } ] }google-cloud-go-0.49.0/civil/000077500000000000000000000000001356504100700156765ustar00rootroot00000000000000google-cloud-go-0.49.0/civil/civil.go000066400000000000000000000220541356504100700173360ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package civil implements types for civil time, a time-zone-independent // representation of time that follows the rules of the proleptic // Gregorian calendar with exactly 24-hour days, 60-minute hours, and 60-second // minutes. // // Because they lack location information, these types do not represent unique // moments or intervals of time. Use time.Time for that purpose. package civil import ( "fmt" "time" ) // A Date represents a date (year, month, day). // // This type does not include location information, and therefore does not // describe a unique 24-hour timespan. type Date struct { Year int // Year (e.g., 2014). Month time.Month // Month of the year (January = 1, ...). Day int // Day of the month, starting at 1. } // DateOf returns the Date in which a time occurs in that time's location. func DateOf(t time.Time) Date { var d Date d.Year, d.Month, d.Day = t.Date() return d } // ParseDate parses a string in RFC3339 full-date format and returns the date value it represents. func ParseDate(s string) (Date, error) { t, err := time.Parse("2006-01-02", s) if err != nil { return Date{}, err } return DateOf(t), nil } // String returns the date in RFC3339 full-date format. func (d Date) String() string { return fmt.Sprintf("%04d-%02d-%02d", d.Year, d.Month, d.Day) } // IsValid reports whether the date is valid. func (d Date) IsValid() bool { return DateOf(d.In(time.UTC)) == d } // In returns the time corresponding to time 00:00:00 of the date in the location. // // In is always consistent with time.Date, even when time.Date returns a time // on a different day. For example, if loc is America/Indiana/Vincennes, then both // time.Date(1955, time.May, 1, 0, 0, 0, 0, loc) // and // civil.Date{Year: 1955, Month: time.May, Day: 1}.In(loc) // return 23:00:00 on April 30, 1955. // // In panics if loc is nil. func (d Date) In(loc *time.Location) time.Time { return time.Date(d.Year, d.Month, d.Day, 0, 0, 0, 0, loc) } // AddDays returns the date that is n days in the future. // n can also be negative to go into the past. func (d Date) AddDays(n int) Date { return DateOf(d.In(time.UTC).AddDate(0, 0, n)) } // DaysSince returns the signed number of days between the date and s, not including the end day. // This is the inverse operation to AddDays. func (d Date) DaysSince(s Date) (days int) { // We convert to Unix time so we do not have to worry about leap seconds: // Unix time increases by exactly 86400 seconds per day. deltaUnix := d.In(time.UTC).Unix() - s.In(time.UTC).Unix() return int(deltaUnix / 86400) } // Before reports whether d1 occurs before d2. func (d1 Date) Before(d2 Date) bool { if d1.Year != d2.Year { return d1.Year < d2.Year } if d1.Month != d2.Month { return d1.Month < d2.Month } return d1.Day < d2.Day } // After reports whether d1 occurs after d2. func (d1 Date) After(d2 Date) bool { return d2.Before(d1) } // MarshalText implements the encoding.TextMarshaler interface. // The output is the result of d.String(). func (d Date) MarshalText() ([]byte, error) { return []byte(d.String()), nil } // UnmarshalText implements the encoding.TextUnmarshaler interface. // The date is expected to be a string in a format accepted by ParseDate. func (d *Date) UnmarshalText(data []byte) error { var err error *d, err = ParseDate(string(data)) return err } // A Time represents a time with nanosecond precision. // // This type does not include location information, and therefore does not // describe a unique moment in time. // // This type exists to represent the TIME type in storage-based APIs like BigQuery. // Most operations on Times are unlikely to be meaningful. Prefer the DateTime type. type Time struct { Hour int // The hour of the day in 24-hour format; range [0-23] Minute int // The minute of the hour; range [0-59] Second int // The second of the minute; range [0-59] Nanosecond int // The nanosecond of the second; range [0-999999999] } // TimeOf returns the Time representing the time of day in which a time occurs // in that time's location. It ignores the date. func TimeOf(t time.Time) Time { var tm Time tm.Hour, tm.Minute, tm.Second = t.Clock() tm.Nanosecond = t.Nanosecond() return tm } // ParseTime parses a string and returns the time value it represents. // ParseTime accepts an extended form of the RFC3339 partial-time format. After // the HH:MM:SS part of the string, an optional fractional part may appear, // consisting of a decimal point followed by one to nine decimal digits. // (RFC3339 admits only one digit after the decimal point). func ParseTime(s string) (Time, error) { t, err := time.Parse("15:04:05.999999999", s) if err != nil { return Time{}, err } return TimeOf(t), nil } // String returns the date in the format described in ParseTime. If Nanoseconds // is zero, no fractional part will be generated. Otherwise, the result will // end with a fractional part consisting of a decimal point and nine digits. func (t Time) String() string { s := fmt.Sprintf("%02d:%02d:%02d", t.Hour, t.Minute, t.Second) if t.Nanosecond == 0 { return s } return s + fmt.Sprintf(".%09d", t.Nanosecond) } // IsValid reports whether the time is valid. func (t Time) IsValid() bool { // Construct a non-zero time. tm := time.Date(2, 2, 2, t.Hour, t.Minute, t.Second, t.Nanosecond, time.UTC) return TimeOf(tm) == t } // MarshalText implements the encoding.TextMarshaler interface. // The output is the result of t.String(). func (t Time) MarshalText() ([]byte, error) { return []byte(t.String()), nil } // UnmarshalText implements the encoding.TextUnmarshaler interface. // The time is expected to be a string in a format accepted by ParseTime. func (t *Time) UnmarshalText(data []byte) error { var err error *t, err = ParseTime(string(data)) return err } // A DateTime represents a date and time. // // This type does not include location information, and therefore does not // describe a unique moment in time. type DateTime struct { Date Date Time Time } // Note: We deliberately do not embed Date into DateTime, to avoid promoting AddDays and Sub. // DateTimeOf returns the DateTime in which a time occurs in that time's location. func DateTimeOf(t time.Time) DateTime { return DateTime{ Date: DateOf(t), Time: TimeOf(t), } } // ParseDateTime parses a string and returns the DateTime it represents. // ParseDateTime accepts a variant of the RFC3339 date-time format that omits // the time offset but includes an optional fractional time, as described in // ParseTime. Informally, the accepted format is // YYYY-MM-DDTHH:MM:SS[.FFFFFFFFF] // where the 'T' may be a lower-case 't'. func ParseDateTime(s string) (DateTime, error) { t, err := time.Parse("2006-01-02T15:04:05.999999999", s) if err != nil { t, err = time.Parse("2006-01-02t15:04:05.999999999", s) if err != nil { return DateTime{}, err } } return DateTimeOf(t), nil } // String returns the date in the format described in ParseDate. func (dt DateTime) String() string { return dt.Date.String() + "T" + dt.Time.String() } // IsValid reports whether the datetime is valid. func (dt DateTime) IsValid() bool { return dt.Date.IsValid() && dt.Time.IsValid() } // In returns the time corresponding to the DateTime in the given location. // // If the time is missing or ambigous at the location, In returns the same // result as time.Date. For example, if loc is America/Indiana/Vincennes, then // both // time.Date(1955, time.May, 1, 0, 30, 0, 0, loc) // and // civil.DateTime{ // civil.Date{Year: 1955, Month: time.May, Day: 1}}, // civil.Time{Minute: 30}}.In(loc) // return 23:30:00 on April 30, 1955. // // In panics if loc is nil. func (dt DateTime) In(loc *time.Location) time.Time { return time.Date(dt.Date.Year, dt.Date.Month, dt.Date.Day, dt.Time.Hour, dt.Time.Minute, dt.Time.Second, dt.Time.Nanosecond, loc) } // Before reports whether dt1 occurs before dt2. func (dt1 DateTime) Before(dt2 DateTime) bool { return dt1.In(time.UTC).Before(dt2.In(time.UTC)) } // After reports whether dt1 occurs after dt2. func (dt1 DateTime) After(dt2 DateTime) bool { return dt2.Before(dt1) } // MarshalText implements the encoding.TextMarshaler interface. // The output is the result of dt.String(). func (dt DateTime) MarshalText() ([]byte, error) { return []byte(dt.String()), nil } // UnmarshalText implements the encoding.TextUnmarshaler interface. // The datetime is expected to be a string in a format accepted by ParseDateTime func (dt *DateTime) UnmarshalText(data []byte) error { var err error *dt, err = ParseDateTime(string(data)) return err } google-cloud-go-0.49.0/civil/civil_test.go000066400000000000000000000270211356504100700203740ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package civil import ( "encoding/json" "testing" "time" "github.com/google/go-cmp/cmp" ) func TestDates(t *testing.T) { for _, test := range []struct { date Date loc *time.Location wantStr string wantTime time.Time }{ { date: Date{2014, 7, 29}, loc: time.Local, wantStr: "2014-07-29", wantTime: time.Date(2014, time.July, 29, 0, 0, 0, 0, time.Local), }, { date: DateOf(time.Date(2014, 8, 20, 15, 8, 43, 1, time.Local)), loc: time.UTC, wantStr: "2014-08-20", wantTime: time.Date(2014, 8, 20, 0, 0, 0, 0, time.UTC), }, { date: DateOf(time.Date(999, time.January, 26, 0, 0, 0, 0, time.Local)), loc: time.UTC, wantStr: "0999-01-26", wantTime: time.Date(999, 1, 26, 0, 0, 0, 0, time.UTC), }, } { if got := test.date.String(); got != test.wantStr { t.Errorf("%#v.String() = %q, want %q", test.date, got, test.wantStr) } if got := test.date.In(test.loc); !got.Equal(test.wantTime) { t.Errorf("%#v.In(%v) = %v, want %v", test.date, test.loc, got, test.wantTime) } } } func TestDateIsValid(t *testing.T) { for _, test := range []struct { date Date want bool }{ {Date{2014, 7, 29}, true}, {Date{2000, 2, 29}, true}, {Date{10000, 12, 31}, true}, {Date{1, 1, 1}, true}, {Date{0, 1, 1}, true}, // year zero is OK {Date{-1, 1, 1}, true}, // negative year is OK {Date{1, 0, 1}, false}, {Date{1, 1, 0}, false}, {Date{2016, 1, 32}, false}, {Date{2016, 13, 1}, false}, {Date{1, -1, 1}, false}, {Date{1, 1, -1}, false}, } { got := test.date.IsValid() if got != test.want { t.Errorf("%#v: got %t, want %t", test.date, got, test.want) } } } func TestParseDate(t *testing.T) { for _, test := range []struct { str string want Date // if empty, expect an error }{ {"2016-01-02", Date{2016, 1, 2}}, {"2016-12-31", Date{2016, 12, 31}}, {"0003-02-04", Date{3, 2, 4}}, {"999-01-26", Date{}}, {"", Date{}}, {"2016-01-02x", Date{}}, } { got, err := ParseDate(test.str) if got != test.want { t.Errorf("ParseDate(%q) = %+v, want %+v", test.str, got, test.want) } if err != nil && test.want != (Date{}) { t.Errorf("Unexpected error %v from ParseDate(%q)", err, test.str) } } } func TestDateArithmetic(t *testing.T) { for _, test := range []struct { desc string start Date end Date days int }{ { desc: "zero days noop", start: Date{2014, 5, 9}, end: Date{2014, 5, 9}, days: 0, }, { desc: "crossing a year boundary", start: Date{2014, 12, 31}, end: Date{2015, 1, 1}, days: 1, }, { desc: "negative number of days", start: Date{2015, 1, 1}, end: Date{2014, 12, 31}, days: -1, }, { desc: "full leap year", start: Date{2004, 1, 1}, end: Date{2005, 1, 1}, days: 366, }, { desc: "full non-leap year", start: Date{2001, 1, 1}, end: Date{2002, 1, 1}, days: 365, }, { desc: "crossing a leap second", start: Date{1972, 6, 30}, end: Date{1972, 7, 1}, days: 1, }, { desc: "dates before the unix epoch", start: Date{101, 1, 1}, end: Date{102, 1, 1}, days: 365, }, } { if got := test.start.AddDays(test.days); got != test.end { t.Errorf("[%s] %#v.AddDays(%v) = %#v, want %#v", test.desc, test.start, test.days, got, test.end) } if got := test.end.DaysSince(test.start); got != test.days { t.Errorf("[%s] %#v.Sub(%#v) = %v, want %v", test.desc, test.end, test.start, got, test.days) } } } func TestDateBefore(t *testing.T) { for _, test := range []struct { d1, d2 Date want bool }{ {Date{2016, 12, 31}, Date{2017, 1, 1}, true}, {Date{2016, 1, 1}, Date{2016, 1, 1}, false}, {Date{2016, 12, 30}, Date{2016, 12, 31}, true}, } { if got := test.d1.Before(test.d2); got != test.want { t.Errorf("%v.Before(%v): got %t, want %t", test.d1, test.d2, got, test.want) } } } func TestDateAfter(t *testing.T) { for _, test := range []struct { d1, d2 Date want bool }{ {Date{2016, 12, 31}, Date{2017, 1, 1}, false}, {Date{2016, 1, 1}, Date{2016, 1, 1}, false}, {Date{2016, 12, 30}, Date{2016, 12, 31}, false}, } { if got := test.d1.After(test.d2); got != test.want { t.Errorf("%v.After(%v): got %t, want %t", test.d1, test.d2, got, test.want) } } } func TestTimeToString(t *testing.T) { for _, test := range []struct { str string time Time roundTrip bool // ParseTime(str).String() == str? }{ {"13:26:33", Time{13, 26, 33, 0}, true}, {"01:02:03.000023456", Time{1, 2, 3, 23456}, true}, {"00:00:00.000000001", Time{0, 0, 0, 1}, true}, {"13:26:03.1", Time{13, 26, 3, 100000000}, false}, {"13:26:33.0000003", Time{13, 26, 33, 300}, false}, } { gotTime, err := ParseTime(test.str) if err != nil { t.Errorf("ParseTime(%q): got error: %v", test.str, err) continue } if gotTime != test.time { t.Errorf("ParseTime(%q) = %+v, want %+v", test.str, gotTime, test.time) } if test.roundTrip { gotStr := test.time.String() if gotStr != test.str { t.Errorf("%#v.String() = %q, want %q", test.time, gotStr, test.str) } } } } func TestTimeOf(t *testing.T) { for _, test := range []struct { time time.Time want Time }{ {time.Date(2014, 8, 20, 15, 8, 43, 1, time.Local), Time{15, 8, 43, 1}}, {time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC), Time{0, 0, 0, 0}}, } { if got := TimeOf(test.time); got != test.want { t.Errorf("TimeOf(%v) = %+v, want %+v", test.time, got, test.want) } } } func TestTimeIsValid(t *testing.T) { for _, test := range []struct { time Time want bool }{ {Time{0, 0, 0, 0}, true}, {Time{23, 0, 0, 0}, true}, {Time{23, 59, 59, 999999999}, true}, {Time{24, 59, 59, 999999999}, false}, {Time{23, 60, 59, 999999999}, false}, {Time{23, 59, 60, 999999999}, false}, {Time{23, 59, 59, 1000000000}, false}, {Time{-1, 0, 0, 0}, false}, {Time{0, -1, 0, 0}, false}, {Time{0, 0, -1, 0}, false}, {Time{0, 0, 0, -1}, false}, } { got := test.time.IsValid() if got != test.want { t.Errorf("%#v: got %t, want %t", test.time, got, test.want) } } } func TestDateTimeToString(t *testing.T) { for _, test := range []struct { str string dateTime DateTime roundTrip bool // ParseDateTime(str).String() == str? }{ {"2016-03-22T13:26:33", DateTime{Date{2016, 03, 22}, Time{13, 26, 33, 0}}, true}, {"2016-03-22T13:26:33.000000600", DateTime{Date{2016, 03, 22}, Time{13, 26, 33, 600}}, true}, {"2016-03-22t13:26:33", DateTime{Date{2016, 03, 22}, Time{13, 26, 33, 0}}, false}, } { gotDateTime, err := ParseDateTime(test.str) if err != nil { t.Errorf("ParseDateTime(%q): got error: %v", test.str, err) continue } if gotDateTime != test.dateTime { t.Errorf("ParseDateTime(%q) = %+v, want %+v", test.str, gotDateTime, test.dateTime) } if test.roundTrip { gotStr := test.dateTime.String() if gotStr != test.str { t.Errorf("%#v.String() = %q, want %q", test.dateTime, gotStr, test.str) } } } } func TestParseDateTimeErrors(t *testing.T) { for _, str := range []string{ "", "2016-03-22", // just a date "13:26:33", // just a time "2016-03-22 13:26:33", // wrong separating character "2016-03-22T13:26:33x", // extra at end } { if _, err := ParseDateTime(str); err == nil { t.Errorf("ParseDateTime(%q) succeeded, want error", str) } } } func TestDateTimeOf(t *testing.T) { for _, test := range []struct { time time.Time want DateTime }{ {time.Date(2014, 8, 20, 15, 8, 43, 1, time.Local), DateTime{Date{2014, 8, 20}, Time{15, 8, 43, 1}}}, {time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC), DateTime{Date{1, 1, 1}, Time{0, 0, 0, 0}}}, } { if got := DateTimeOf(test.time); got != test.want { t.Errorf("DateTimeOf(%v) = %+v, want %+v", test.time, got, test.want) } } } func TestDateTimeIsValid(t *testing.T) { // No need to be exhaustive here; it's just Date.IsValid && Time.IsValid. for _, test := range []struct { dt DateTime want bool }{ {DateTime{Date{2016, 3, 20}, Time{0, 0, 0, 0}}, true}, {DateTime{Date{2016, -3, 20}, Time{0, 0, 0, 0}}, false}, {DateTime{Date{2016, 3, 20}, Time{24, 0, 0, 0}}, false}, } { got := test.dt.IsValid() if got != test.want { t.Errorf("%#v: got %t, want %t", test.dt, got, test.want) } } } func TestDateTimeIn(t *testing.T) { dt := DateTime{Date{2016, 1, 2}, Time{3, 4, 5, 6}} got := dt.In(time.UTC) want := time.Date(2016, 1, 2, 3, 4, 5, 6, time.UTC) if !got.Equal(want) { t.Errorf("got %v, want %v", got, want) } } func TestDateTimeBefore(t *testing.T) { d1 := Date{2016, 12, 31} d2 := Date{2017, 1, 1} t1 := Time{5, 6, 7, 8} t2 := Time{5, 6, 7, 9} for _, test := range []struct { dt1, dt2 DateTime want bool }{ {DateTime{d1, t1}, DateTime{d2, t1}, true}, {DateTime{d1, t1}, DateTime{d1, t2}, true}, {DateTime{d2, t1}, DateTime{d1, t1}, false}, {DateTime{d2, t1}, DateTime{d2, t1}, false}, } { if got := test.dt1.Before(test.dt2); got != test.want { t.Errorf("%v.Before(%v): got %t, want %t", test.dt1, test.dt2, got, test.want) } } } func TestDateTimeAfter(t *testing.T) { d1 := Date{2016, 12, 31} d2 := Date{2017, 1, 1} t1 := Time{5, 6, 7, 8} t2 := Time{5, 6, 7, 9} for _, test := range []struct { dt1, dt2 DateTime want bool }{ {DateTime{d1, t1}, DateTime{d2, t1}, false}, {DateTime{d1, t1}, DateTime{d1, t2}, false}, {DateTime{d2, t1}, DateTime{d1, t1}, true}, {DateTime{d2, t1}, DateTime{d2, t1}, false}, } { if got := test.dt1.After(test.dt2); got != test.want { t.Errorf("%v.After(%v): got %t, want %t", test.dt1, test.dt2, got, test.want) } } } func TestMarshalJSON(t *testing.T) { for _, test := range []struct { value interface{} want string }{ {Date{1987, 4, 15}, `"1987-04-15"`}, {Time{18, 54, 2, 0}, `"18:54:02"`}, {DateTime{Date{1987, 4, 15}, Time{18, 54, 2, 0}}, `"1987-04-15T18:54:02"`}, } { bgot, err := json.Marshal(test.value) if err != nil { t.Fatal(err) } if got := string(bgot); got != test.want { t.Errorf("%#v: got %s, want %s", test.value, got, test.want) } } } func TestUnmarshalJSON(t *testing.T) { var d Date var tm Time var dt DateTime for _, test := range []struct { data string ptr interface{} want interface{} }{ {`"1987-04-15"`, &d, &Date{1987, 4, 15}}, {`"1987-04-\u0031\u0035"`, &d, &Date{1987, 4, 15}}, {`"18:54:02"`, &tm, &Time{18, 54, 2, 0}}, {`"1987-04-15T18:54:02"`, &dt, &DateTime{Date{1987, 4, 15}, Time{18, 54, 2, 0}}}, } { if err := json.Unmarshal([]byte(test.data), test.ptr); err != nil { t.Fatalf("%s: %v", test.data, err) } if !cmp.Equal(test.ptr, test.want) { t.Errorf("%s: got %#v, want %#v", test.data, test.ptr, test.want) } } for _, bad := range []string{"", `""`, `"bad"`, `"1987-04-15x"`, `19870415`, // a JSON number `11987-04-15x`, // not a JSON string } { if json.Unmarshal([]byte(bad), &d) == nil { t.Errorf("%q, Date: got nil, want error", bad) } if json.Unmarshal([]byte(bad), &tm) == nil { t.Errorf("%q, Time: got nil, want error", bad) } if json.Unmarshal([]byte(bad), &dt) == nil { t.Errorf("%q, DateTime: got nil, want error", bad) } } } google-cloud-go-0.49.0/cloudbuild/000077500000000000000000000000001356504100700167165ustar00rootroot00000000000000google-cloud-go-0.49.0/cloudbuild/apiv1/000077500000000000000000000000001356504100700177365ustar00rootroot00000000000000google-cloud-go-0.49.0/cloudbuild/apiv1/cloud_build_client.go000066400000000000000000000505001356504100700241100ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package cloudbuild import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" cloudbuildpb "google.golang.org/genproto/googleapis/devtools/cloudbuild/v1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // CallOptions contains the retry settings for each method of Client. type CallOptions struct { CreateBuild []gax.CallOption GetBuild []gax.CallOption ListBuilds []gax.CallOption CancelBuild []gax.CallOption CreateBuildTrigger []gax.CallOption GetBuildTrigger []gax.CallOption ListBuildTriggers []gax.CallOption DeleteBuildTrigger []gax.CallOption UpdateBuildTrigger []gax.CallOption RunBuildTrigger []gax.CallOption RetryBuild []gax.CallOption CreateWorkerPool []gax.CallOption GetWorkerPool []gax.CallOption DeleteWorkerPool []gax.CallOption UpdateWorkerPool []gax.CallOption ListWorkerPools []gax.CallOption } func defaultClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("cloudbuild.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultCallOptions() *CallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &CallOptions{ CreateBuild: retry[[2]string{"default", "non_idempotent"}], GetBuild: retry[[2]string{"default", "idempotent"}], ListBuilds: retry[[2]string{"default", "idempotent"}], CancelBuild: retry[[2]string{"default", "non_idempotent"}], CreateBuildTrigger: retry[[2]string{"default", "non_idempotent"}], GetBuildTrigger: retry[[2]string{"default", "idempotent"}], ListBuildTriggers: retry[[2]string{"default", "idempotent"}], DeleteBuildTrigger: retry[[2]string{"default", "idempotent"}], UpdateBuildTrigger: retry[[2]string{"default", "non_idempotent"}], RunBuildTrigger: retry[[2]string{"default", "non_idempotent"}], RetryBuild: retry[[2]string{"default", "non_idempotent"}], CreateWorkerPool: retry[[2]string{"default", "non_idempotent"}], GetWorkerPool: retry[[2]string{"default", "non_idempotent"}], DeleteWorkerPool: retry[[2]string{"default", "non_idempotent"}], UpdateWorkerPool: retry[[2]string{"default", "non_idempotent"}], ListWorkerPools: retry[[2]string{"default", "non_idempotent"}], } } // Client is a client for interacting with Cloud Build API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. client cloudbuildpb.CloudBuildClient // The call options for this service. CallOptions *CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewClient creates a new cloud build client. // // Creates and manages builds on Google Cloud Platform. // // The main concept used by this API is a Build, which describes the location // of the source to build, how to build the source, and where to store the // built artifacts, if any. // // A user can list previously-requested builds or get builds by their ID to // determine the status of the build. func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultClientOptions(), opts...)...) if err != nil { return nil, err } c := &Client{ conn: conn, CallOptions: defaultCallOptions(), client: cloudbuildpb.NewCloudBuildClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *Client) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *Client) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // CreateBuild starts a build with the specified configuration. // // This method returns a long-running Operation, which includes the build // ID. Pass the build ID to GetBuild to determine the build status (such as // SUCCESS or FAILURE). func (c *Client) CreateBuild(ctx context.Context, req *cloudbuildpb.CreateBuildRequest, opts ...gax.CallOption) (*longrunningpb.Operation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "project_id", url.QueryEscape(req.GetProjectId()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateBuild[0:len(c.CallOptions.CreateBuild):len(c.CallOptions.CreateBuild)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CreateBuild(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetBuild returns information about a previously requested build. // // The Build that is returned includes its status (such as SUCCESS, // FAILURE, or WORKING), and timing information. func (c *Client) GetBuild(ctx context.Context, req *cloudbuildpb.GetBuildRequest, opts ...gax.CallOption) (*cloudbuildpb.Build, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.GetBuild[0:len(c.CallOptions.GetBuild):len(c.CallOptions.GetBuild)], opts...) var resp *cloudbuildpb.Build err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetBuild(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListBuilds lists previously requested builds. // // Previously requested builds may still be in-progress, or may have finished // successfully or unsuccessfully. func (c *Client) ListBuilds(ctx context.Context, req *cloudbuildpb.ListBuildsRequest, opts ...gax.CallOption) *BuildIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "project_id", url.QueryEscape(req.GetProjectId()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListBuilds[0:len(c.CallOptions.ListBuilds):len(c.CallOptions.ListBuilds)], opts...) it := &BuildIterator{} req = proto.Clone(req).(*cloudbuildpb.ListBuildsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*cloudbuildpb.Build, string, error) { var resp *cloudbuildpb.ListBuildsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListBuilds(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Builds, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // CancelBuild cancels a build in progress. func (c *Client) CancelBuild(ctx context.Context, req *cloudbuildpb.CancelBuildRequest, opts ...gax.CallOption) (*cloudbuildpb.Build, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.CancelBuild[0:len(c.CallOptions.CancelBuild):len(c.CallOptions.CancelBuild)], opts...) var resp *cloudbuildpb.Build err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CancelBuild(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateBuildTrigger creates a new BuildTrigger. // // This API is experimental. func (c *Client) CreateBuildTrigger(ctx context.Context, req *cloudbuildpb.CreateBuildTriggerRequest, opts ...gax.CallOption) (*cloudbuildpb.BuildTrigger, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "project_id", url.QueryEscape(req.GetProjectId()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateBuildTrigger[0:len(c.CallOptions.CreateBuildTrigger):len(c.CallOptions.CreateBuildTrigger)], opts...) var resp *cloudbuildpb.BuildTrigger err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CreateBuildTrigger(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetBuildTrigger returns information about a BuildTrigger. // // This API is experimental. func (c *Client) GetBuildTrigger(ctx context.Context, req *cloudbuildpb.GetBuildTriggerRequest, opts ...gax.CallOption) (*cloudbuildpb.BuildTrigger, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.GetBuildTrigger[0:len(c.CallOptions.GetBuildTrigger):len(c.CallOptions.GetBuildTrigger)], opts...) var resp *cloudbuildpb.BuildTrigger err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetBuildTrigger(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListBuildTriggers lists existing BuildTriggers. // // This API is experimental. func (c *Client) ListBuildTriggers(ctx context.Context, req *cloudbuildpb.ListBuildTriggersRequest, opts ...gax.CallOption) (*cloudbuildpb.ListBuildTriggersResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "project_id", url.QueryEscape(req.GetProjectId()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListBuildTriggers[0:len(c.CallOptions.ListBuildTriggers):len(c.CallOptions.ListBuildTriggers)], opts...) var resp *cloudbuildpb.ListBuildTriggersResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListBuildTriggers(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteBuildTrigger deletes a BuildTrigger by its project ID and trigger ID. // // This API is experimental. func (c *Client) DeleteBuildTrigger(ctx context.Context, req *cloudbuildpb.DeleteBuildTriggerRequest, opts ...gax.CallOption) error { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.DeleteBuildTrigger[0:len(c.CallOptions.DeleteBuildTrigger):len(c.CallOptions.DeleteBuildTrigger)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.client.DeleteBuildTrigger(ctx, req, settings.GRPC...) return err }, opts...) return err } // UpdateBuildTrigger updates a BuildTrigger by its project ID and trigger ID. // // This API is experimental. func (c *Client) UpdateBuildTrigger(ctx context.Context, req *cloudbuildpb.UpdateBuildTriggerRequest, opts ...gax.CallOption) (*cloudbuildpb.BuildTrigger, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.UpdateBuildTrigger[0:len(c.CallOptions.UpdateBuildTrigger):len(c.CallOptions.UpdateBuildTrigger)], opts...) var resp *cloudbuildpb.BuildTrigger err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.UpdateBuildTrigger(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // RunBuildTrigger runs a BuildTrigger at a particular source revision. func (c *Client) RunBuildTrigger(ctx context.Context, req *cloudbuildpb.RunBuildTriggerRequest, opts ...gax.CallOption) (*longrunningpb.Operation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.RunBuildTrigger[0:len(c.CallOptions.RunBuildTrigger):len(c.CallOptions.RunBuildTrigger)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.RunBuildTrigger(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // RetryBuild creates a new build based on the specified build. // // This method creates a new build using the original build request, which may // or may not result in an identical build. // // For triggered builds: // // Triggered builds resolve to a precise revision; therefore a retry of a // triggered build will result in a build that uses the same revision. // // For non-triggered builds that specify RepoSource: // // If the original build built from the tip of a branch, the retried build // will build from the tip of that branch, which may not be the same revision // as the original build. // // If the original build specified a commit sha or revision ID, the retried // build will use the identical source. // // For builds that specify StorageSource: // // If the original build pulled source from Google Cloud Storage without // specifying the generation of the object, the new build will use the current // object, which may be different from the original build source. // // If the original build pulled source from Cloud Storage and specified the // generation of the object, the new build will attempt to use the same // object, which may or may not be available depending on the bucket's // lifecycle management settings. func (c *Client) RetryBuild(ctx context.Context, req *cloudbuildpb.RetryBuildRequest, opts ...gax.CallOption) (*longrunningpb.Operation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.RetryBuild[0:len(c.CallOptions.RetryBuild):len(c.CallOptions.RetryBuild)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.RetryBuild(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateWorkerPool creates a WorkerPool to run the builds, and returns the new worker pool. // // This API is experimental. func (c *Client) CreateWorkerPool(ctx context.Context, req *cloudbuildpb.CreateWorkerPoolRequest, opts ...gax.CallOption) (*cloudbuildpb.WorkerPool, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.CreateWorkerPool[0:len(c.CallOptions.CreateWorkerPool):len(c.CallOptions.CreateWorkerPool)], opts...) var resp *cloudbuildpb.WorkerPool err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CreateWorkerPool(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetWorkerPool returns information about a WorkerPool. // // This API is experimental. func (c *Client) GetWorkerPool(ctx context.Context, req *cloudbuildpb.GetWorkerPoolRequest, opts ...gax.CallOption) (*cloudbuildpb.WorkerPool, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.GetWorkerPool[0:len(c.CallOptions.GetWorkerPool):len(c.CallOptions.GetWorkerPool)], opts...) var resp *cloudbuildpb.WorkerPool err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetWorkerPool(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteWorkerPool deletes a WorkerPool by its project ID and WorkerPool name. // // This API is experimental. func (c *Client) DeleteWorkerPool(ctx context.Context, req *cloudbuildpb.DeleteWorkerPoolRequest, opts ...gax.CallOption) error { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.DeleteWorkerPool[0:len(c.CallOptions.DeleteWorkerPool):len(c.CallOptions.DeleteWorkerPool)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.client.DeleteWorkerPool(ctx, req, settings.GRPC...) return err }, opts...) return err } // UpdateWorkerPool update a WorkerPool. // // This API is experimental. func (c *Client) UpdateWorkerPool(ctx context.Context, req *cloudbuildpb.UpdateWorkerPoolRequest, opts ...gax.CallOption) (*cloudbuildpb.WorkerPool, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.UpdateWorkerPool[0:len(c.CallOptions.UpdateWorkerPool):len(c.CallOptions.UpdateWorkerPool)], opts...) var resp *cloudbuildpb.WorkerPool err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.UpdateWorkerPool(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListWorkerPools list project's WorkerPools. // // This API is experimental. func (c *Client) ListWorkerPools(ctx context.Context, req *cloudbuildpb.ListWorkerPoolsRequest, opts ...gax.CallOption) (*cloudbuildpb.ListWorkerPoolsResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.ListWorkerPools[0:len(c.CallOptions.ListWorkerPools):len(c.CallOptions.ListWorkerPools)], opts...) var resp *cloudbuildpb.ListWorkerPoolsResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListWorkerPools(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // BuildIterator manages a stream of *cloudbuildpb.Build. type BuildIterator struct { items []*cloudbuildpb.Build pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*cloudbuildpb.Build, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *BuildIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *BuildIterator) Next() (*cloudbuildpb.Build, error) { var item *cloudbuildpb.Build if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *BuildIterator) bufLen() int { return len(it.items) } func (it *BuildIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/cloudbuild/apiv1/cloud_build_client_example_test.go000066400000000000000000000151051356504100700266640ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package cloudbuild_test import ( "context" cloudbuild "cloud.google.com/go/cloudbuild/apiv1" "google.golang.org/api/iterator" cloudbuildpb "google.golang.org/genproto/googleapis/devtools/cloudbuild/v1" ) func ExampleNewClient() { ctx := context.Background() c, err := cloudbuild.NewClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleClient_CreateBuild() { ctx := context.Background() c, err := cloudbuild.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &cloudbuildpb.CreateBuildRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateBuild(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_GetBuild() { ctx := context.Background() c, err := cloudbuild.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &cloudbuildpb.GetBuildRequest{ // TODO: Fill request struct fields. } resp, err := c.GetBuild(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ListBuilds() { ctx := context.Background() c, err := cloudbuild.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &cloudbuildpb.ListBuildsRequest{ // TODO: Fill request struct fields. } it := c.ListBuilds(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_CancelBuild() { ctx := context.Background() c, err := cloudbuild.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &cloudbuildpb.CancelBuildRequest{ // TODO: Fill request struct fields. } resp, err := c.CancelBuild(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_CreateBuildTrigger() { ctx := context.Background() c, err := cloudbuild.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &cloudbuildpb.CreateBuildTriggerRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateBuildTrigger(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_GetBuildTrigger() { ctx := context.Background() c, err := cloudbuild.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &cloudbuildpb.GetBuildTriggerRequest{ // TODO: Fill request struct fields. } resp, err := c.GetBuildTrigger(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ListBuildTriggers() { ctx := context.Background() c, err := cloudbuild.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &cloudbuildpb.ListBuildTriggersRequest{ // TODO: Fill request struct fields. } resp, err := c.ListBuildTriggers(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_DeleteBuildTrigger() { ctx := context.Background() c, err := cloudbuild.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &cloudbuildpb.DeleteBuildTriggerRequest{ // TODO: Fill request struct fields. } err = c.DeleteBuildTrigger(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleClient_UpdateBuildTrigger() { ctx := context.Background() c, err := cloudbuild.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &cloudbuildpb.UpdateBuildTriggerRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateBuildTrigger(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_RunBuildTrigger() { ctx := context.Background() c, err := cloudbuild.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &cloudbuildpb.RunBuildTriggerRequest{ // TODO: Fill request struct fields. } resp, err := c.RunBuildTrigger(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_RetryBuild() { ctx := context.Background() c, err := cloudbuild.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &cloudbuildpb.RetryBuildRequest{ // TODO: Fill request struct fields. } resp, err := c.RetryBuild(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_CreateWorkerPool() { ctx := context.Background() c, err := cloudbuild.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &cloudbuildpb.CreateWorkerPoolRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateWorkerPool(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_GetWorkerPool() { ctx := context.Background() c, err := cloudbuild.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &cloudbuildpb.GetWorkerPoolRequest{ // TODO: Fill request struct fields. } resp, err := c.GetWorkerPool(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_DeleteWorkerPool() { ctx := context.Background() c, err := cloudbuild.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &cloudbuildpb.DeleteWorkerPoolRequest{ // TODO: Fill request struct fields. } err = c.DeleteWorkerPool(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleClient_UpdateWorkerPool() { ctx := context.Background() c, err := cloudbuild.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &cloudbuildpb.UpdateWorkerPoolRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateWorkerPool(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ListWorkerPools() { ctx := context.Background() c, err := cloudbuild.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &cloudbuildpb.ListWorkerPoolsRequest{ // TODO: Fill request struct fields. } resp, err := c.ListWorkerPools(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/cloudbuild/apiv1/doc.go000066400000000000000000000053211356504100700210330ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package cloudbuild is an auto-generated package for the // Cloud Build API. // // NOTE: This package is in alpha. It is not stable, and is likely to change. // // Creates and manages builds on Google Cloud Platform. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package cloudbuild // import "cloud.google.com/go/cloudbuild/apiv1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191115" google-cloud-go-0.49.0/cloudbuild/apiv1/mock_test.go000066400000000000000000001113741356504100700222640ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package cloudbuild import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" "google.golang.org/api/option" cloudbuildpb "google.golang.org/genproto/googleapis/devtools/cloudbuild/v1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockCloudBuildServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. cloudbuildpb.CloudBuildServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockCloudBuildServer) CreateBuild(ctx context.Context, req *cloudbuildpb.CreateBuildRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockCloudBuildServer) GetBuild(ctx context.Context, req *cloudbuildpb.GetBuildRequest) (*cloudbuildpb.Build, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*cloudbuildpb.Build), nil } func (s *mockCloudBuildServer) ListBuilds(ctx context.Context, req *cloudbuildpb.ListBuildsRequest) (*cloudbuildpb.ListBuildsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*cloudbuildpb.ListBuildsResponse), nil } func (s *mockCloudBuildServer) CancelBuild(ctx context.Context, req *cloudbuildpb.CancelBuildRequest) (*cloudbuildpb.Build, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*cloudbuildpb.Build), nil } func (s *mockCloudBuildServer) RetryBuild(ctx context.Context, req *cloudbuildpb.RetryBuildRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockCloudBuildServer) CreateBuildTrigger(ctx context.Context, req *cloudbuildpb.CreateBuildTriggerRequest) (*cloudbuildpb.BuildTrigger, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*cloudbuildpb.BuildTrigger), nil } func (s *mockCloudBuildServer) GetBuildTrigger(ctx context.Context, req *cloudbuildpb.GetBuildTriggerRequest) (*cloudbuildpb.BuildTrigger, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*cloudbuildpb.BuildTrigger), nil } func (s *mockCloudBuildServer) ListBuildTriggers(ctx context.Context, req *cloudbuildpb.ListBuildTriggersRequest) (*cloudbuildpb.ListBuildTriggersResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*cloudbuildpb.ListBuildTriggersResponse), nil } func (s *mockCloudBuildServer) DeleteBuildTrigger(ctx context.Context, req *cloudbuildpb.DeleteBuildTriggerRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockCloudBuildServer) UpdateBuildTrigger(ctx context.Context, req *cloudbuildpb.UpdateBuildTriggerRequest) (*cloudbuildpb.BuildTrigger, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*cloudbuildpb.BuildTrigger), nil } func (s *mockCloudBuildServer) RunBuildTrigger(ctx context.Context, req *cloudbuildpb.RunBuildTriggerRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockCloudBuildServer) CreateWorkerPool(ctx context.Context, req *cloudbuildpb.CreateWorkerPoolRequest) (*cloudbuildpb.WorkerPool, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*cloudbuildpb.WorkerPool), nil } func (s *mockCloudBuildServer) GetWorkerPool(ctx context.Context, req *cloudbuildpb.GetWorkerPoolRequest) (*cloudbuildpb.WorkerPool, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*cloudbuildpb.WorkerPool), nil } func (s *mockCloudBuildServer) DeleteWorkerPool(ctx context.Context, req *cloudbuildpb.DeleteWorkerPoolRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockCloudBuildServer) UpdateWorkerPool(ctx context.Context, req *cloudbuildpb.UpdateWorkerPoolRequest) (*cloudbuildpb.WorkerPool, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*cloudbuildpb.WorkerPool), nil } func (s *mockCloudBuildServer) ListWorkerPools(ctx context.Context, req *cloudbuildpb.ListWorkerPoolsRequest) (*cloudbuildpb.ListWorkerPoolsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*cloudbuildpb.ListWorkerPoolsResponse), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockCloudBuild mockCloudBuildServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() cloudbuildpb.RegisterCloudBuildServer(serv, &mockCloudBuild) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestCloudBuildCreateBuild(t *testing.T) { var name string = "name3373707" var done bool = true var expectedResponse = &longrunningpb.Operation{ Name: name, Done: done, } mockCloudBuild.err = nil mockCloudBuild.reqs = nil mockCloudBuild.resps = append(mockCloudBuild.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var build *cloudbuildpb.Build = &cloudbuildpb.Build{} var request = &cloudbuildpb.CreateBuildRequest{ ProjectId: projectId, Build: build, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateBuild(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudBuild.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudBuildCreateBuildError(t *testing.T) { errCode := codes.PermissionDenied mockCloudBuild.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var build *cloudbuildpb.Build = &cloudbuildpb.Build{} var request = &cloudbuildpb.CreateBuildRequest{ ProjectId: projectId, Build: build, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateBuild(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudBuildGetBuild(t *testing.T) { var id2 string = "id23227150" var projectId2 string = "projectId2939242356" var statusDetail string = "statusDetail2089931070" var logsBucket string = "logsBucket1565363834" var buildTriggerId string = "buildTriggerId1105559411" var logUrl string = "logUrl342054388" var expectedResponse = &cloudbuildpb.Build{ Id: id2, ProjectId: projectId2, StatusDetail: statusDetail, LogsBucket: logsBucket, BuildTriggerId: buildTriggerId, LogUrl: logUrl, } mockCloudBuild.err = nil mockCloudBuild.reqs = nil mockCloudBuild.resps = append(mockCloudBuild.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var id string = "id3355" var request = &cloudbuildpb.GetBuildRequest{ ProjectId: projectId, Id: id, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetBuild(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudBuild.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudBuildGetBuildError(t *testing.T) { errCode := codes.PermissionDenied mockCloudBuild.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var id string = "id3355" var request = &cloudbuildpb.GetBuildRequest{ ProjectId: projectId, Id: id, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetBuild(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudBuildListBuilds(t *testing.T) { var nextPageToken string = "" var buildsElement *cloudbuildpb.Build = &cloudbuildpb.Build{} var builds = []*cloudbuildpb.Build{buildsElement} var expectedResponse = &cloudbuildpb.ListBuildsResponse{ NextPageToken: nextPageToken, Builds: builds, } mockCloudBuild.err = nil mockCloudBuild.reqs = nil mockCloudBuild.resps = append(mockCloudBuild.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var request = &cloudbuildpb.ListBuildsRequest{ ProjectId: projectId, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListBuilds(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockCloudBuild.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Builds[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudBuildListBuildsError(t *testing.T) { errCode := codes.PermissionDenied mockCloudBuild.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var request = &cloudbuildpb.ListBuildsRequest{ ProjectId: projectId, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListBuilds(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudBuildCancelBuild(t *testing.T) { var id2 string = "id23227150" var projectId2 string = "projectId2939242356" var statusDetail string = "statusDetail2089931070" var logsBucket string = "logsBucket1565363834" var buildTriggerId string = "buildTriggerId1105559411" var logUrl string = "logUrl342054388" var expectedResponse = &cloudbuildpb.Build{ Id: id2, ProjectId: projectId2, StatusDetail: statusDetail, LogsBucket: logsBucket, BuildTriggerId: buildTriggerId, LogUrl: logUrl, } mockCloudBuild.err = nil mockCloudBuild.reqs = nil mockCloudBuild.resps = append(mockCloudBuild.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var id string = "id3355" var request = &cloudbuildpb.CancelBuildRequest{ ProjectId: projectId, Id: id, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CancelBuild(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudBuild.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudBuildCancelBuildError(t *testing.T) { errCode := codes.PermissionDenied mockCloudBuild.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var id string = "id3355" var request = &cloudbuildpb.CancelBuildRequest{ ProjectId: projectId, Id: id, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CancelBuild(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudBuildCreateBuildTrigger(t *testing.T) { var id string = "id3355" var description string = "description-1724546052" var name string = "name3373707" var filename string = "filename-734768633" var disabled bool = true var expectedResponse = &cloudbuildpb.BuildTrigger{ Id: id, Description: description, Name: name, BuildTemplate: &cloudbuildpb.BuildTrigger_Filename{ Filename: filename, }, Disabled: disabled, } mockCloudBuild.err = nil mockCloudBuild.reqs = nil mockCloudBuild.resps = append(mockCloudBuild.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var trigger *cloudbuildpb.BuildTrigger = &cloudbuildpb.BuildTrigger{} var request = &cloudbuildpb.CreateBuildTriggerRequest{ ProjectId: projectId, Trigger: trigger, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateBuildTrigger(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudBuild.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudBuildCreateBuildTriggerError(t *testing.T) { errCode := codes.PermissionDenied mockCloudBuild.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var trigger *cloudbuildpb.BuildTrigger = &cloudbuildpb.BuildTrigger{} var request = &cloudbuildpb.CreateBuildTriggerRequest{ ProjectId: projectId, Trigger: trigger, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateBuildTrigger(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudBuildGetBuildTrigger(t *testing.T) { var id string = "id3355" var description string = "description-1724546052" var name string = "name3373707" var filename string = "filename-734768633" var disabled bool = true var expectedResponse = &cloudbuildpb.BuildTrigger{ Id: id, Description: description, Name: name, BuildTemplate: &cloudbuildpb.BuildTrigger_Filename{ Filename: filename, }, Disabled: disabled, } mockCloudBuild.err = nil mockCloudBuild.reqs = nil mockCloudBuild.resps = append(mockCloudBuild.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var triggerId string = "triggerId1363517698" var request = &cloudbuildpb.GetBuildTriggerRequest{ ProjectId: projectId, TriggerId: triggerId, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetBuildTrigger(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudBuild.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudBuildGetBuildTriggerError(t *testing.T) { errCode := codes.PermissionDenied mockCloudBuild.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var triggerId string = "triggerId1363517698" var request = &cloudbuildpb.GetBuildTriggerRequest{ ProjectId: projectId, TriggerId: triggerId, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetBuildTrigger(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudBuildListBuildTriggers(t *testing.T) { var nextPageToken string = "nextPageToken-1530815211" var expectedResponse = &cloudbuildpb.ListBuildTriggersResponse{ NextPageToken: nextPageToken, } mockCloudBuild.err = nil mockCloudBuild.reqs = nil mockCloudBuild.resps = append(mockCloudBuild.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var request = &cloudbuildpb.ListBuildTriggersRequest{ ProjectId: projectId, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListBuildTriggers(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudBuild.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudBuildListBuildTriggersError(t *testing.T) { errCode := codes.PermissionDenied mockCloudBuild.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var request = &cloudbuildpb.ListBuildTriggersRequest{ ProjectId: projectId, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListBuildTriggers(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudBuildDeleteBuildTrigger(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockCloudBuild.err = nil mockCloudBuild.reqs = nil mockCloudBuild.resps = append(mockCloudBuild.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var triggerId string = "triggerId1363517698" var request = &cloudbuildpb.DeleteBuildTriggerRequest{ ProjectId: projectId, TriggerId: triggerId, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteBuildTrigger(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudBuild.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestCloudBuildDeleteBuildTriggerError(t *testing.T) { errCode := codes.PermissionDenied mockCloudBuild.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var triggerId string = "triggerId1363517698" var request = &cloudbuildpb.DeleteBuildTriggerRequest{ ProjectId: projectId, TriggerId: triggerId, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteBuildTrigger(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestCloudBuildUpdateBuildTrigger(t *testing.T) { var id string = "id3355" var description string = "description-1724546052" var name string = "name3373707" var filename string = "filename-734768633" var disabled bool = true var expectedResponse = &cloudbuildpb.BuildTrigger{ Id: id, Description: description, Name: name, BuildTemplate: &cloudbuildpb.BuildTrigger_Filename{ Filename: filename, }, Disabled: disabled, } mockCloudBuild.err = nil mockCloudBuild.reqs = nil mockCloudBuild.resps = append(mockCloudBuild.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var triggerId string = "triggerId1363517698" var trigger *cloudbuildpb.BuildTrigger = &cloudbuildpb.BuildTrigger{} var request = &cloudbuildpb.UpdateBuildTriggerRequest{ ProjectId: projectId, TriggerId: triggerId, Trigger: trigger, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateBuildTrigger(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudBuild.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudBuildUpdateBuildTriggerError(t *testing.T) { errCode := codes.PermissionDenied mockCloudBuild.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var triggerId string = "triggerId1363517698" var trigger *cloudbuildpb.BuildTrigger = &cloudbuildpb.BuildTrigger{} var request = &cloudbuildpb.UpdateBuildTriggerRequest{ ProjectId: projectId, TriggerId: triggerId, Trigger: trigger, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateBuildTrigger(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudBuildRunBuildTrigger(t *testing.T) { var name string = "name3373707" var done bool = true var expectedResponse = &longrunningpb.Operation{ Name: name, Done: done, } mockCloudBuild.err = nil mockCloudBuild.reqs = nil mockCloudBuild.resps = append(mockCloudBuild.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var triggerId string = "triggerId1363517698" var source *cloudbuildpb.RepoSource = &cloudbuildpb.RepoSource{} var request = &cloudbuildpb.RunBuildTriggerRequest{ ProjectId: projectId, TriggerId: triggerId, Source: source, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.RunBuildTrigger(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudBuild.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudBuildRunBuildTriggerError(t *testing.T) { errCode := codes.PermissionDenied mockCloudBuild.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var triggerId string = "triggerId1363517698" var source *cloudbuildpb.RepoSource = &cloudbuildpb.RepoSource{} var request = &cloudbuildpb.RunBuildTriggerRequest{ ProjectId: projectId, TriggerId: triggerId, Source: source, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.RunBuildTrigger(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudBuildRetryBuild(t *testing.T) { var name string = "name3373707" var done bool = true var expectedResponse = &longrunningpb.Operation{ Name: name, Done: done, } mockCloudBuild.err = nil mockCloudBuild.reqs = nil mockCloudBuild.resps = append(mockCloudBuild.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var id string = "id3355" var request = &cloudbuildpb.RetryBuildRequest{ ProjectId: projectId, Id: id, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.RetryBuild(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudBuild.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudBuildRetryBuildError(t *testing.T) { errCode := codes.PermissionDenied mockCloudBuild.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var id string = "id3355" var request = &cloudbuildpb.RetryBuildRequest{ ProjectId: projectId, Id: id, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.RetryBuild(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudBuildCreateWorkerPool(t *testing.T) { var name string = "name3373707" var projectId string = "projectId-1969970175" var serviceAccountEmail string = "serviceAccountEmail-1300473088" var workerCount int64 = 372044046 var expectedResponse = &cloudbuildpb.WorkerPool{ Name: name, ProjectId: projectId, ServiceAccountEmail: serviceAccountEmail, WorkerCount: workerCount, } mockCloudBuild.err = nil mockCloudBuild.reqs = nil mockCloudBuild.resps = append(mockCloudBuild.resps[:0], expectedResponse) var request *cloudbuildpb.CreateWorkerPoolRequest = &cloudbuildpb.CreateWorkerPoolRequest{} c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateWorkerPool(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudBuild.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudBuildCreateWorkerPoolError(t *testing.T) { errCode := codes.PermissionDenied mockCloudBuild.err = gstatus.Error(errCode, "test error") var request *cloudbuildpb.CreateWorkerPoolRequest = &cloudbuildpb.CreateWorkerPoolRequest{} c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateWorkerPool(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudBuildGetWorkerPool(t *testing.T) { var name string = "name3373707" var projectId string = "projectId-1969970175" var serviceAccountEmail string = "serviceAccountEmail-1300473088" var workerCount int64 = 372044046 var expectedResponse = &cloudbuildpb.WorkerPool{ Name: name, ProjectId: projectId, ServiceAccountEmail: serviceAccountEmail, WorkerCount: workerCount, } mockCloudBuild.err = nil mockCloudBuild.reqs = nil mockCloudBuild.resps = append(mockCloudBuild.resps[:0], expectedResponse) var request *cloudbuildpb.GetWorkerPoolRequest = &cloudbuildpb.GetWorkerPoolRequest{} c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetWorkerPool(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudBuild.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudBuildGetWorkerPoolError(t *testing.T) { errCode := codes.PermissionDenied mockCloudBuild.err = gstatus.Error(errCode, "test error") var request *cloudbuildpb.GetWorkerPoolRequest = &cloudbuildpb.GetWorkerPoolRequest{} c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetWorkerPool(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudBuildDeleteWorkerPool(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockCloudBuild.err = nil mockCloudBuild.reqs = nil mockCloudBuild.resps = append(mockCloudBuild.resps[:0], expectedResponse) var request *cloudbuildpb.DeleteWorkerPoolRequest = &cloudbuildpb.DeleteWorkerPoolRequest{} c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteWorkerPool(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudBuild.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestCloudBuildDeleteWorkerPoolError(t *testing.T) { errCode := codes.PermissionDenied mockCloudBuild.err = gstatus.Error(errCode, "test error") var request *cloudbuildpb.DeleteWorkerPoolRequest = &cloudbuildpb.DeleteWorkerPoolRequest{} c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteWorkerPool(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestCloudBuildUpdateWorkerPool(t *testing.T) { var name string = "name3373707" var projectId string = "projectId-1969970175" var serviceAccountEmail string = "serviceAccountEmail-1300473088" var workerCount int64 = 372044046 var expectedResponse = &cloudbuildpb.WorkerPool{ Name: name, ProjectId: projectId, ServiceAccountEmail: serviceAccountEmail, WorkerCount: workerCount, } mockCloudBuild.err = nil mockCloudBuild.reqs = nil mockCloudBuild.resps = append(mockCloudBuild.resps[:0], expectedResponse) var request *cloudbuildpb.UpdateWorkerPoolRequest = &cloudbuildpb.UpdateWorkerPoolRequest{} c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateWorkerPool(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudBuild.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudBuildUpdateWorkerPoolError(t *testing.T) { errCode := codes.PermissionDenied mockCloudBuild.err = gstatus.Error(errCode, "test error") var request *cloudbuildpb.UpdateWorkerPoolRequest = &cloudbuildpb.UpdateWorkerPoolRequest{} c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateWorkerPool(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudBuildListWorkerPools(t *testing.T) { var expectedResponse *cloudbuildpb.ListWorkerPoolsResponse = &cloudbuildpb.ListWorkerPoolsResponse{} mockCloudBuild.err = nil mockCloudBuild.reqs = nil mockCloudBuild.resps = append(mockCloudBuild.resps[:0], expectedResponse) var request *cloudbuildpb.ListWorkerPoolsRequest = &cloudbuildpb.ListWorkerPoolsRequest{} c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListWorkerPools(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudBuild.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudBuildListWorkerPoolsError(t *testing.T) { errCode := codes.PermissionDenied mockCloudBuild.err = gstatus.Error(errCode, "test error") var request *cloudbuildpb.ListWorkerPoolsRequest = &cloudbuildpb.ListWorkerPoolsRequest{} c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListWorkerPools(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/cloudtasks/000077500000000000000000000000001356504100700167445ustar00rootroot00000000000000google-cloud-go-0.49.0/cloudtasks/apiv2/000077500000000000000000000000001356504100700177655ustar00rootroot00000000000000google-cloud-go-0.49.0/cloudtasks/apiv2/.repo-metadata.json000066400000000000000000000006431356504100700234640ustar00rootroot00000000000000{ "name": "cloudtasks", "name_pretty": "Cloud Tasks API", "product_documentation": "https://cloud.google.com/tasks", "client_documentation": "https://godoc.org/cloud.google.com/go/cloudtasks/apiv2", "release_level": "ga", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go/cloudtasks", "api_id": "cloudtasks.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/cloudtasks/apiv2/cloud_tasks_client.go000066400000000000000000000637401356504100700241770ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package cloudtasks import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" taskspb "google.golang.org/genproto/googleapis/cloud/tasks/v2" iampb "google.golang.org/genproto/googleapis/iam/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // CallOptions contains the retry settings for each method of Client. type CallOptions struct { ListQueues []gax.CallOption GetQueue []gax.CallOption CreateQueue []gax.CallOption UpdateQueue []gax.CallOption DeleteQueue []gax.CallOption PurgeQueue []gax.CallOption PauseQueue []gax.CallOption ResumeQueue []gax.CallOption GetIamPolicy []gax.CallOption SetIamPolicy []gax.CallOption TestIamPermissions []gax.CallOption ListTasks []gax.CallOption GetTask []gax.CallOption CreateTask []gax.CallOption DeleteTask []gax.CallOption RunTask []gax.CallOption } func defaultClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("cloudtasks.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultCallOptions() *CallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &CallOptions{ ListQueues: retry[[2]string{"default", "idempotent"}], GetQueue: retry[[2]string{"default", "idempotent"}], CreateQueue: retry[[2]string{"default", "non_idempotent"}], UpdateQueue: retry[[2]string{"default", "non_idempotent"}], DeleteQueue: retry[[2]string{"default", "idempotent"}], PurgeQueue: retry[[2]string{"default", "non_idempotent"}], PauseQueue: retry[[2]string{"default", "non_idempotent"}], ResumeQueue: retry[[2]string{"default", "non_idempotent"}], GetIamPolicy: retry[[2]string{"default", "idempotent"}], SetIamPolicy: retry[[2]string{"default", "non_idempotent"}], TestIamPermissions: retry[[2]string{"default", "idempotent"}], ListTasks: retry[[2]string{"default", "idempotent"}], GetTask: retry[[2]string{"default", "idempotent"}], CreateTask: retry[[2]string{"default", "non_idempotent"}], DeleteTask: retry[[2]string{"default", "idempotent"}], RunTask: retry[[2]string{"default", "non_idempotent"}], } } // Client is a client for interacting with Cloud Tasks API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. client taskspb.CloudTasksClient // The call options for this service. CallOptions *CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewClient creates a new cloud tasks client. // // Cloud Tasks allows developers to manage the execution of background // work in their applications. func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultClientOptions(), opts...)...) if err != nil { return nil, err } c := &Client{ conn: conn, CallOptions: defaultCallOptions(), client: taskspb.NewCloudTasksClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *Client) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *Client) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // ListQueues lists queues. // // Queues are returned in lexicographical order. func (c *Client) ListQueues(ctx context.Context, req *taskspb.ListQueuesRequest, opts ...gax.CallOption) *QueueIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListQueues[0:len(c.CallOptions.ListQueues):len(c.CallOptions.ListQueues)], opts...) it := &QueueIterator{} req = proto.Clone(req).(*taskspb.ListQueuesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*taskspb.Queue, string, error) { var resp *taskspb.ListQueuesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListQueues(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Queues, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetQueue gets a queue. func (c *Client) GetQueue(ctx context.Context, req *taskspb.GetQueueRequest, opts ...gax.CallOption) (*taskspb.Queue, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetQueue[0:len(c.CallOptions.GetQueue):len(c.CallOptions.GetQueue)], opts...) var resp *taskspb.Queue err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetQueue(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateQueue creates a queue. // // Queues created with this method allow tasks to live for a maximum of 31 // days. After a task is 31 days old, the task will be deleted regardless of whether // it was dispatched or not. // // WARNING: Using this method may have unintended side effects if you are // using an App Engine queue.yaml or queue.xml file to manage your queues. // Read // Overview of Queue Management and // queue.yaml (at https://cloud.google.com/tasks/docs/queue-yaml) before using // this method. func (c *Client) CreateQueue(ctx context.Context, req *taskspb.CreateQueueRequest, opts ...gax.CallOption) (*taskspb.Queue, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateQueue[0:len(c.CallOptions.CreateQueue):len(c.CallOptions.CreateQueue)], opts...) var resp *taskspb.Queue err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CreateQueue(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateQueue updates a queue. // // This method creates the queue if it does not exist and updates // the queue if it does exist. // // Queues created with this method allow tasks to live for a maximum of 31 // days. After a task is 31 days old, the task will be deleted regardless of whether // it was dispatched or not. // // WARNING: Using this method may have unintended side effects if you are // using an App Engine queue.yaml or queue.xml file to manage your queues. // Read // Overview of Queue Management and // queue.yaml (at https://cloud.google.com/tasks/docs/queue-yaml) before using // this method. func (c *Client) UpdateQueue(ctx context.Context, req *taskspb.UpdateQueueRequest, opts ...gax.CallOption) (*taskspb.Queue, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "queue.name", url.QueryEscape(req.GetQueue().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateQueue[0:len(c.CallOptions.UpdateQueue):len(c.CallOptions.UpdateQueue)], opts...) var resp *taskspb.Queue err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.UpdateQueue(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteQueue deletes a queue. // // This command will delete the queue even if it has tasks in it. // // Note: If you delete a queue, a queue with the same name can't be created // for 7 days. // // WARNING: Using this method may have unintended side effects if you are // using an App Engine queue.yaml or queue.xml file to manage your queues. // Read // Overview of Queue Management and // queue.yaml (at https://cloud.google.com/tasks/docs/queue-yaml) before using // this method. func (c *Client) DeleteQueue(ctx context.Context, req *taskspb.DeleteQueueRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteQueue[0:len(c.CallOptions.DeleteQueue):len(c.CallOptions.DeleteQueue)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.client.DeleteQueue(ctx, req, settings.GRPC...) return err }, opts...) return err } // PurgeQueue purges a queue by deleting all of its tasks. // // All tasks created before this method is called are permanently deleted. // // Purge operations can take up to one minute to take effect. Tasks // might be dispatched before the purge takes effect. A purge is irreversible. func (c *Client) PurgeQueue(ctx context.Context, req *taskspb.PurgeQueueRequest, opts ...gax.CallOption) (*taskspb.Queue, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.PurgeQueue[0:len(c.CallOptions.PurgeQueue):len(c.CallOptions.PurgeQueue)], opts...) var resp *taskspb.Queue err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.PurgeQueue(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // PauseQueue pauses the queue. // // If a queue is paused then the system will stop dispatching tasks // until the queue is resumed via // [ResumeQueue][google.cloud.tasks.v2.CloudTasks.ResumeQueue]. Tasks can still be added // when the queue is paused. A queue is paused if its // [state][google.cloud.tasks.v2.Queue.state] is [PAUSED][google.cloud.tasks.v2.Queue.State.PAUSED]. func (c *Client) PauseQueue(ctx context.Context, req *taskspb.PauseQueueRequest, opts ...gax.CallOption) (*taskspb.Queue, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.PauseQueue[0:len(c.CallOptions.PauseQueue):len(c.CallOptions.PauseQueue)], opts...) var resp *taskspb.Queue err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.PauseQueue(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ResumeQueue resume a queue. // // This method resumes a queue after it has been // [PAUSED][google.cloud.tasks.v2.Queue.State.PAUSED] or // [DISABLED][google.cloud.tasks.v2.Queue.State.DISABLED]. The state of a queue is stored // in the queue's [state][google.cloud.tasks.v2.Queue.state]; after calling this method it // will be set to [RUNNING][google.cloud.tasks.v2.Queue.State.RUNNING]. // // WARNING: Resuming many high-QPS queues at the same time can // lead to target overloading. If you are resuming high-QPS // queues, follow the 500/50/5 pattern described in // Managing Cloud Tasks Scaling // Risks (at https://cloud.google.com/tasks/docs/manage-cloud-task-scaling). func (c *Client) ResumeQueue(ctx context.Context, req *taskspb.ResumeQueueRequest, opts ...gax.CallOption) (*taskspb.Queue, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ResumeQueue[0:len(c.CallOptions.ResumeQueue):len(c.CallOptions.ResumeQueue)], opts...) var resp *taskspb.Queue err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ResumeQueue(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetIamPolicy gets the access control policy for a [Queue][google.cloud.tasks.v2.Queue]. // Returns an empty policy if the resource exists and does not have a policy // set. // // Authorization requires the following // Google IAM (at https://cloud.google.com/iam) permission on the specified // resource parent: // // cloudtasks.queues.getIamPolicy func (c *Client) GetIamPolicy(ctx context.Context, req *iampb.GetIamPolicyRequest, opts ...gax.CallOption) (*iampb.Policy, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetIamPolicy[0:len(c.CallOptions.GetIamPolicy):len(c.CallOptions.GetIamPolicy)], opts...) var resp *iampb.Policy err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetIamPolicy(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // SetIamPolicy sets the access control policy for a [Queue][google.cloud.tasks.v2.Queue]. Replaces any existing // policy. // // Note: The Cloud Console does not check queue-level IAM permissions yet. // Project-level permissions are required to use the Cloud Console. // // Authorization requires the following // Google IAM (at https://cloud.google.com/iam) permission on the specified // resource parent: // // cloudtasks.queues.setIamPolicy func (c *Client) SetIamPolicy(ctx context.Context, req *iampb.SetIamPolicyRequest, opts ...gax.CallOption) (*iampb.Policy, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.SetIamPolicy[0:len(c.CallOptions.SetIamPolicy):len(c.CallOptions.SetIamPolicy)], opts...) var resp *iampb.Policy err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.SetIamPolicy(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // TestIamPermissions returns permissions that a caller has on a [Queue][google.cloud.tasks.v2.Queue]. // If the resource does not exist, this will return an empty set of // permissions, not a [NOT_FOUND][google.rpc.Code.NOT_FOUND] error. // // Note: This operation is designed to be used for building permission-aware // UIs and command-line tools, not for authorization checking. This operation // may "fail open" without warning. func (c *Client) TestIamPermissions(ctx context.Context, req *iampb.TestIamPermissionsRequest, opts ...gax.CallOption) (*iampb.TestIamPermissionsResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.TestIamPermissions[0:len(c.CallOptions.TestIamPermissions):len(c.CallOptions.TestIamPermissions)], opts...) var resp *iampb.TestIamPermissionsResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.TestIamPermissions(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListTasks lists the tasks in a queue. // // By default, only the [BASIC][google.cloud.tasks.v2.Task.View.BASIC] view is retrieved // due to performance considerations; // [response_view][google.cloud.tasks.v2.ListTasksRequest.response_view] controls the // subset of information which is returned. // // The tasks may be returned in any order. The ordering may change at any // time. func (c *Client) ListTasks(ctx context.Context, req *taskspb.ListTasksRequest, opts ...gax.CallOption) *TaskIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListTasks[0:len(c.CallOptions.ListTasks):len(c.CallOptions.ListTasks)], opts...) it := &TaskIterator{} req = proto.Clone(req).(*taskspb.ListTasksRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*taskspb.Task, string, error) { var resp *taskspb.ListTasksResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListTasks(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Tasks, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetTask gets a task. func (c *Client) GetTask(ctx context.Context, req *taskspb.GetTaskRequest, opts ...gax.CallOption) (*taskspb.Task, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetTask[0:len(c.CallOptions.GetTask):len(c.CallOptions.GetTask)], opts...) var resp *taskspb.Task err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetTask(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateTask creates a task and adds it to a queue. // // Tasks cannot be updated after creation; there is no UpdateTask command. // // The maximum task size is 100KB. func (c *Client) CreateTask(ctx context.Context, req *taskspb.CreateTaskRequest, opts ...gax.CallOption) (*taskspb.Task, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateTask[0:len(c.CallOptions.CreateTask):len(c.CallOptions.CreateTask)], opts...) var resp *taskspb.Task err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CreateTask(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteTask deletes a task. // // A task can be deleted if it is scheduled or dispatched. A task // cannot be deleted if it has executed successfully or permanently // failed. func (c *Client) DeleteTask(ctx context.Context, req *taskspb.DeleteTaskRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteTask[0:len(c.CallOptions.DeleteTask):len(c.CallOptions.DeleteTask)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.client.DeleteTask(ctx, req, settings.GRPC...) return err }, opts...) return err } // RunTask forces a task to run now. // // When this method is called, Cloud Tasks will dispatch the task, even if // the task is already running, the queue has reached its [RateLimits][google.cloud.tasks.v2.RateLimits] or // is [PAUSED][google.cloud.tasks.v2.Queue.State.PAUSED]. // // This command is meant to be used for manual debugging. For // example, [RunTask][google.cloud.tasks.v2.CloudTasks.RunTask] can be used to retry a failed // task after a fix has been made or to manually force a task to be // dispatched now. // // The dispatched task is returned. That is, the task that is returned // contains the [status][Task.status] after the task is dispatched but // before the task is received by its target. // // If Cloud Tasks receives a successful response from the task's // target, then the task will be deleted; otherwise the task's // [schedule_time][google.cloud.tasks.v2.Task.schedule_time] will be reset to the time that // [RunTask][google.cloud.tasks.v2.CloudTasks.RunTask] was called plus the retry delay specified // in the queue's [RetryConfig][google.cloud.tasks.v2.RetryConfig]. // // [RunTask][google.cloud.tasks.v2.CloudTasks.RunTask] returns // [NOT_FOUND][google.rpc.Code.NOT_FOUND] when it is called on a // task that has already succeeded or permanently failed. func (c *Client) RunTask(ctx context.Context, req *taskspb.RunTaskRequest, opts ...gax.CallOption) (*taskspb.Task, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.RunTask[0:len(c.CallOptions.RunTask):len(c.CallOptions.RunTask)], opts...) var resp *taskspb.Task err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.RunTask(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // QueueIterator manages a stream of *taskspb.Queue. type QueueIterator struct { items []*taskspb.Queue pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*taskspb.Queue, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *QueueIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *QueueIterator) Next() (*taskspb.Queue, error) { var item *taskspb.Queue if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *QueueIterator) bufLen() int { return len(it.items) } func (it *QueueIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // TaskIterator manages a stream of *taskspb.Task. type TaskIterator struct { items []*taskspb.Task pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*taskspb.Task, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *TaskIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *TaskIterator) Next() (*taskspb.Task, error) { var item *taskspb.Task if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *TaskIterator) bufLen() int { return len(it.items) } func (it *TaskIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/cloudtasks/apiv2/cloud_tasks_client_example_test.go000066400000000000000000000146561356504100700267530ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package cloudtasks_test import ( "context" cloudtasks "cloud.google.com/go/cloudtasks/apiv2" "google.golang.org/api/iterator" taskspb "google.golang.org/genproto/googleapis/cloud/tasks/v2" iampb "google.golang.org/genproto/googleapis/iam/v1" ) func ExampleNewClient() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleClient_ListQueues() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.ListQueuesRequest{ // TODO: Fill request struct fields. } it := c.ListQueues(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_GetQueue() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.GetQueueRequest{ // TODO: Fill request struct fields. } resp, err := c.GetQueue(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_CreateQueue() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.CreateQueueRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateQueue(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_UpdateQueue() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.UpdateQueueRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateQueue(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_DeleteQueue() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.DeleteQueueRequest{ // TODO: Fill request struct fields. } err = c.DeleteQueue(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleClient_PurgeQueue() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.PurgeQueueRequest{ // TODO: Fill request struct fields. } resp, err := c.PurgeQueue(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_PauseQueue() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.PauseQueueRequest{ // TODO: Fill request struct fields. } resp, err := c.PauseQueue(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ResumeQueue() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.ResumeQueueRequest{ // TODO: Fill request struct fields. } resp, err := c.ResumeQueue(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_GetIamPolicy() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &iampb.GetIamPolicyRequest{ // TODO: Fill request struct fields. } resp, err := c.GetIamPolicy(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_SetIamPolicy() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &iampb.SetIamPolicyRequest{ // TODO: Fill request struct fields. } resp, err := c.SetIamPolicy(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_TestIamPermissions() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &iampb.TestIamPermissionsRequest{ // TODO: Fill request struct fields. } resp, err := c.TestIamPermissions(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ListTasks() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.ListTasksRequest{ // TODO: Fill request struct fields. } it := c.ListTasks(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_GetTask() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.GetTaskRequest{ // TODO: Fill request struct fields. } resp, err := c.GetTask(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_CreateTask() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.CreateTaskRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateTask(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_DeleteTask() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.DeleteTaskRequest{ // TODO: Fill request struct fields. } err = c.DeleteTask(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleClient_RunTask() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.RunTaskRequest{ // TODO: Fill request struct fields. } resp, err := c.RunTask(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/cloudtasks/apiv2/doc.go000066400000000000000000000052121356504100700210610ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package cloudtasks is an auto-generated package for the // Cloud Tasks API. // // Manages the execution of large numbers of distributed requests. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package cloudtasks // import "cloud.google.com/go/cloudtasks/apiv2" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191115" google-cloud-go-0.49.0/cloudtasks/apiv2/mock_test.go000066400000000000000000001064661356504100700223210ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package cloudtasks import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" "google.golang.org/api/option" taskspb "google.golang.org/genproto/googleapis/cloud/tasks/v2" iampb "google.golang.org/genproto/googleapis/iam/v1" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockCloudTasksServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. taskspb.CloudTasksServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockCloudTasksServer) ListQueues(ctx context.Context, req *taskspb.ListQueuesRequest) (*taskspb.ListQueuesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*taskspb.ListQueuesResponse), nil } func (s *mockCloudTasksServer) GetQueue(ctx context.Context, req *taskspb.GetQueueRequest) (*taskspb.Queue, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*taskspb.Queue), nil } func (s *mockCloudTasksServer) CreateQueue(ctx context.Context, req *taskspb.CreateQueueRequest) (*taskspb.Queue, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*taskspb.Queue), nil } func (s *mockCloudTasksServer) UpdateQueue(ctx context.Context, req *taskspb.UpdateQueueRequest) (*taskspb.Queue, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*taskspb.Queue), nil } func (s *mockCloudTasksServer) DeleteQueue(ctx context.Context, req *taskspb.DeleteQueueRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockCloudTasksServer) PurgeQueue(ctx context.Context, req *taskspb.PurgeQueueRequest) (*taskspb.Queue, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*taskspb.Queue), nil } func (s *mockCloudTasksServer) PauseQueue(ctx context.Context, req *taskspb.PauseQueueRequest) (*taskspb.Queue, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*taskspb.Queue), nil } func (s *mockCloudTasksServer) ResumeQueue(ctx context.Context, req *taskspb.ResumeQueueRequest) (*taskspb.Queue, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*taskspb.Queue), nil } func (s *mockCloudTasksServer) GetIamPolicy(ctx context.Context, req *iampb.GetIamPolicyRequest) (*iampb.Policy, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iampb.Policy), nil } func (s *mockCloudTasksServer) SetIamPolicy(ctx context.Context, req *iampb.SetIamPolicyRequest) (*iampb.Policy, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iampb.Policy), nil } func (s *mockCloudTasksServer) TestIamPermissions(ctx context.Context, req *iampb.TestIamPermissionsRequest) (*iampb.TestIamPermissionsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iampb.TestIamPermissionsResponse), nil } func (s *mockCloudTasksServer) ListTasks(ctx context.Context, req *taskspb.ListTasksRequest) (*taskspb.ListTasksResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*taskspb.ListTasksResponse), nil } func (s *mockCloudTasksServer) GetTask(ctx context.Context, req *taskspb.GetTaskRequest) (*taskspb.Task, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*taskspb.Task), nil } func (s *mockCloudTasksServer) CreateTask(ctx context.Context, req *taskspb.CreateTaskRequest) (*taskspb.Task, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*taskspb.Task), nil } func (s *mockCloudTasksServer) DeleteTask(ctx context.Context, req *taskspb.DeleteTaskRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockCloudTasksServer) RunTask(ctx context.Context, req *taskspb.RunTaskRequest) (*taskspb.Task, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*taskspb.Task), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockCloudTasks mockCloudTasksServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() taskspb.RegisterCloudTasksServer(serv, &mockCloudTasks) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestCloudTasksListQueues(t *testing.T) { var nextPageToken string = "" var queuesElement *taskspb.Queue = &taskspb.Queue{} var queues = []*taskspb.Queue{queuesElement} var expectedResponse = &taskspb.ListQueuesResponse{ NextPageToken: nextPageToken, Queues: queues, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &taskspb.ListQueuesRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListQueues(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Queues[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksListQueuesError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &taskspb.ListQueuesRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListQueues(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksGetQueue(t *testing.T) { var name2 string = "name2-1052831874" var expectedResponse = &taskspb.Queue{ Name: name2, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &taskspb.GetQueueRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetQueue(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksGetQueueError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &taskspb.GetQueueRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetQueue(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksCreateQueue(t *testing.T) { var name string = "name3373707" var expectedResponse = &taskspb.Queue{ Name: name, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var queue *taskspb.Queue = &taskspb.Queue{} var request = &taskspb.CreateQueueRequest{ Parent: formattedParent, Queue: queue, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateQueue(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksCreateQueueError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var queue *taskspb.Queue = &taskspb.Queue{} var request = &taskspb.CreateQueueRequest{ Parent: formattedParent, Queue: queue, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateQueue(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksUpdateQueue(t *testing.T) { var name string = "name3373707" var expectedResponse = &taskspb.Queue{ Name: name, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var queue *taskspb.Queue = &taskspb.Queue{} var request = &taskspb.UpdateQueueRequest{ Queue: queue, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateQueue(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksUpdateQueueError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var queue *taskspb.Queue = &taskspb.Queue{} var request = &taskspb.UpdateQueueRequest{ Queue: queue, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateQueue(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksDeleteQueue(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &taskspb.DeleteQueueRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteQueue(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestCloudTasksDeleteQueueError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &taskspb.DeleteQueueRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteQueue(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestCloudTasksPurgeQueue(t *testing.T) { var name2 string = "name2-1052831874" var expectedResponse = &taskspb.Queue{ Name: name2, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &taskspb.PurgeQueueRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.PurgeQueue(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksPurgeQueueError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &taskspb.PurgeQueueRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.PurgeQueue(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksPauseQueue(t *testing.T) { var name2 string = "name2-1052831874" var expectedResponse = &taskspb.Queue{ Name: name2, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &taskspb.PauseQueueRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.PauseQueue(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksPauseQueueError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &taskspb.PauseQueueRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.PauseQueue(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksResumeQueue(t *testing.T) { var name2 string = "name2-1052831874" var expectedResponse = &taskspb.Queue{ Name: name2, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &taskspb.ResumeQueueRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ResumeQueue(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksResumeQueueError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &taskspb.ResumeQueueRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ResumeQueue(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksGetIamPolicy(t *testing.T) { var version int32 = 351608024 var etag []byte = []byte("21") var expectedResponse = &iampb.Policy{ Version: version, Etag: etag, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedResource string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &iampb.GetIamPolicyRequest{ Resource: formattedResource, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetIamPolicy(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksGetIamPolicyError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedResource string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &iampb.GetIamPolicyRequest{ Resource: formattedResource, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetIamPolicy(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksSetIamPolicy(t *testing.T) { var version int32 = 351608024 var etag []byte = []byte("21") var expectedResponse = &iampb.Policy{ Version: version, Etag: etag, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedResource string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var policy *iampb.Policy = &iampb.Policy{} var request = &iampb.SetIamPolicyRequest{ Resource: formattedResource, Policy: policy, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetIamPolicy(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksSetIamPolicyError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedResource string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var policy *iampb.Policy = &iampb.Policy{} var request = &iampb.SetIamPolicyRequest{ Resource: formattedResource, Policy: policy, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetIamPolicy(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksTestIamPermissions(t *testing.T) { var expectedResponse *iampb.TestIamPermissionsResponse = &iampb.TestIamPermissionsResponse{} mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedResource string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var permissions []string = nil var request = &iampb.TestIamPermissionsRequest{ Resource: formattedResource, Permissions: permissions, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.TestIamPermissions(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksTestIamPermissionsError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedResource string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var permissions []string = nil var request = &iampb.TestIamPermissionsRequest{ Resource: formattedResource, Permissions: permissions, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.TestIamPermissions(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksListTasks(t *testing.T) { var nextPageToken string = "" var tasksElement *taskspb.Task = &taskspb.Task{} var tasks = []*taskspb.Task{tasksElement} var expectedResponse = &taskspb.ListTasksResponse{ NextPageToken: nextPageToken, Tasks: tasks, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &taskspb.ListTasksRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListTasks(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Tasks[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksListTasksError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &taskspb.ListTasksRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListTasks(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksGetTask(t *testing.T) { var name2 string = "name2-1052831874" var dispatchCount int32 = 1217252086 var responseCount int32 = 424727441 var expectedResponse = &taskspb.Task{ Name: name2, DispatchCount: dispatchCount, ResponseCount: responseCount, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s/tasks/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]", "[TASK]") var request = &taskspb.GetTaskRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetTask(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksGetTaskError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s/tasks/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]", "[TASK]") var request = &taskspb.GetTaskRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetTask(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksCreateTask(t *testing.T) { var name string = "name3373707" var dispatchCount int32 = 1217252086 var responseCount int32 = 424727441 var expectedResponse = &taskspb.Task{ Name: name, DispatchCount: dispatchCount, ResponseCount: responseCount, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var task *taskspb.Task = &taskspb.Task{} var request = &taskspb.CreateTaskRequest{ Parent: formattedParent, Task: task, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateTask(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksCreateTaskError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var task *taskspb.Task = &taskspb.Task{} var request = &taskspb.CreateTaskRequest{ Parent: formattedParent, Task: task, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateTask(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksDeleteTask(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s/tasks/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]", "[TASK]") var request = &taskspb.DeleteTaskRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteTask(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestCloudTasksDeleteTaskError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s/tasks/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]", "[TASK]") var request = &taskspb.DeleteTaskRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteTask(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestCloudTasksRunTask(t *testing.T) { var name2 string = "name2-1052831874" var dispatchCount int32 = 1217252086 var responseCount int32 = 424727441 var expectedResponse = &taskspb.Task{ Name: name2, DispatchCount: dispatchCount, ResponseCount: responseCount, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s/tasks/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]", "[TASK]") var request = &taskspb.RunTaskRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.RunTask(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksRunTaskError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s/tasks/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]", "[TASK]") var request = &taskspb.RunTaskRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.RunTask(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/cloudtasks/apiv2beta2/000077500000000000000000000000001356504100700207035ustar00rootroot00000000000000google-cloud-go-0.49.0/cloudtasks/apiv2beta2/.repo-metadata.json000066400000000000000000000006351356504100700244030ustar00rootroot00000000000000{ "name": "cloudtasks", "name_pretty": "Cloud Tasks API", "product_documentation": "https://cloud.google.com/tasks", "client_documentation": "https://godoc.org/cloud.google.com/go/cloudtasks/apiv2beta2", "release_level": "ga", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "cloudtasks.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/cloudtasks/apiv2beta2/cloud_tasks_client.go000066400000000000000000000776431356504100700251240ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package cloudtasks import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" taskspb "google.golang.org/genproto/googleapis/cloud/tasks/v2beta2" iampb "google.golang.org/genproto/googleapis/iam/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // CallOptions contains the retry settings for each method of Client. type CallOptions struct { ListQueues []gax.CallOption GetQueue []gax.CallOption CreateQueue []gax.CallOption UpdateQueue []gax.CallOption DeleteQueue []gax.CallOption PurgeQueue []gax.CallOption PauseQueue []gax.CallOption ResumeQueue []gax.CallOption GetIamPolicy []gax.CallOption SetIamPolicy []gax.CallOption TestIamPermissions []gax.CallOption ListTasks []gax.CallOption GetTask []gax.CallOption CreateTask []gax.CallOption DeleteTask []gax.CallOption LeaseTasks []gax.CallOption AcknowledgeTask []gax.CallOption RenewLease []gax.CallOption CancelLease []gax.CallOption RunTask []gax.CallOption } func defaultClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("cloudtasks.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultCallOptions() *CallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &CallOptions{ ListQueues: retry[[2]string{"default", "idempotent"}], GetQueue: retry[[2]string{"default", "idempotent"}], CreateQueue: retry[[2]string{"default", "non_idempotent"}], UpdateQueue: retry[[2]string{"default", "non_idempotent"}], DeleteQueue: retry[[2]string{"default", "idempotent"}], PurgeQueue: retry[[2]string{"default", "non_idempotent"}], PauseQueue: retry[[2]string{"default", "non_idempotent"}], ResumeQueue: retry[[2]string{"default", "non_idempotent"}], GetIamPolicy: retry[[2]string{"default", "idempotent"}], SetIamPolicy: retry[[2]string{"default", "non_idempotent"}], TestIamPermissions: retry[[2]string{"default", "idempotent"}], ListTasks: retry[[2]string{"default", "idempotent"}], GetTask: retry[[2]string{"default", "idempotent"}], CreateTask: retry[[2]string{"default", "non_idempotent"}], DeleteTask: retry[[2]string{"default", "idempotent"}], LeaseTasks: retry[[2]string{"default", "non_idempotent"}], AcknowledgeTask: retry[[2]string{"default", "non_idempotent"}], RenewLease: retry[[2]string{"default", "non_idempotent"}], CancelLease: retry[[2]string{"default", "non_idempotent"}], RunTask: retry[[2]string{"default", "non_idempotent"}], } } // Client is a client for interacting with Cloud Tasks API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. client taskspb.CloudTasksClient // The call options for this service. CallOptions *CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewClient creates a new cloud tasks client. // // Cloud Tasks allows developers to manage the execution of background // work in their applications. func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultClientOptions(), opts...)...) if err != nil { return nil, err } c := &Client{ conn: conn, CallOptions: defaultCallOptions(), client: taskspb.NewCloudTasksClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *Client) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *Client) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // ListQueues lists queues. // // Queues are returned in lexicographical order. func (c *Client) ListQueues(ctx context.Context, req *taskspb.ListQueuesRequest, opts ...gax.CallOption) *QueueIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListQueues[0:len(c.CallOptions.ListQueues):len(c.CallOptions.ListQueues)], opts...) it := &QueueIterator{} req = proto.Clone(req).(*taskspb.ListQueuesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*taskspb.Queue, string, error) { var resp *taskspb.ListQueuesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListQueues(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Queues, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetQueue gets a queue. func (c *Client) GetQueue(ctx context.Context, req *taskspb.GetQueueRequest, opts ...gax.CallOption) (*taskspb.Queue, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetQueue[0:len(c.CallOptions.GetQueue):len(c.CallOptions.GetQueue)], opts...) var resp *taskspb.Queue err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetQueue(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateQueue creates a queue. // // Queues created with this method allow tasks to live for a maximum of 31 // days. After a task is 31 days old, the task will be deleted regardless of whether // it was dispatched or not. // // WARNING: Using this method may have unintended side effects if you are // using an App Engine queue.yaml or queue.xml file to manage your queues. // Read // Overview of Queue Management and // queue.yaml (at https://cloud.google.com/tasks/docs/queue-yaml) before using // this method. func (c *Client) CreateQueue(ctx context.Context, req *taskspb.CreateQueueRequest, opts ...gax.CallOption) (*taskspb.Queue, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateQueue[0:len(c.CallOptions.CreateQueue):len(c.CallOptions.CreateQueue)], opts...) var resp *taskspb.Queue err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CreateQueue(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateQueue updates a queue. // // This method creates the queue if it does not exist and updates // the queue if it does exist. // // Queues created with this method allow tasks to live for a maximum of 31 // days. After a task is 31 days old, the task will be deleted regardless of whether // it was dispatched or not. // // WARNING: Using this method may have unintended side effects if you are // using an App Engine queue.yaml or queue.xml file to manage your queues. // Read // Overview of Queue Management and // queue.yaml (at https://cloud.google.com/tasks/docs/queue-yaml) before using // this method. func (c *Client) UpdateQueue(ctx context.Context, req *taskspb.UpdateQueueRequest, opts ...gax.CallOption) (*taskspb.Queue, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "queue.name", url.QueryEscape(req.GetQueue().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateQueue[0:len(c.CallOptions.UpdateQueue):len(c.CallOptions.UpdateQueue)], opts...) var resp *taskspb.Queue err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.UpdateQueue(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteQueue deletes a queue. // // This command will delete the queue even if it has tasks in it. // // Note: If you delete a queue, a queue with the same name can't be created // for 7 days. // // WARNING: Using this method may have unintended side effects if you are // using an App Engine queue.yaml or queue.xml file to manage your queues. // Read // Overview of Queue Management and // queue.yaml (at https://cloud.google.com/tasks/docs/queue-yaml) before using // this method. func (c *Client) DeleteQueue(ctx context.Context, req *taskspb.DeleteQueueRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteQueue[0:len(c.CallOptions.DeleteQueue):len(c.CallOptions.DeleteQueue)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.client.DeleteQueue(ctx, req, settings.GRPC...) return err }, opts...) return err } // PurgeQueue purges a queue by deleting all of its tasks. // // All tasks created before this method is called are permanently deleted. // // Purge operations can take up to one minute to take effect. Tasks // might be dispatched before the purge takes effect. A purge is irreversible. func (c *Client) PurgeQueue(ctx context.Context, req *taskspb.PurgeQueueRequest, opts ...gax.CallOption) (*taskspb.Queue, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.PurgeQueue[0:len(c.CallOptions.PurgeQueue):len(c.CallOptions.PurgeQueue)], opts...) var resp *taskspb.Queue err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.PurgeQueue(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // PauseQueue pauses the queue. // // If a queue is paused then the system will stop dispatching tasks // until the queue is resumed via // [ResumeQueue][google.cloud.tasks.v2beta2.CloudTasks.ResumeQueue]. Tasks can still be added // when the queue is paused. A queue is paused if its // [state][google.cloud.tasks.v2beta2.Queue.state] is [PAUSED][google.cloud.tasks.v2beta2.Queue.State.PAUSED]. func (c *Client) PauseQueue(ctx context.Context, req *taskspb.PauseQueueRequest, opts ...gax.CallOption) (*taskspb.Queue, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.PauseQueue[0:len(c.CallOptions.PauseQueue):len(c.CallOptions.PauseQueue)], opts...) var resp *taskspb.Queue err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.PauseQueue(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ResumeQueue resume a queue. // // This method resumes a queue after it has been // [PAUSED][google.cloud.tasks.v2beta2.Queue.State.PAUSED] or // [DISABLED][google.cloud.tasks.v2beta2.Queue.State.DISABLED]. The state of a queue is stored // in the queue's [state][google.cloud.tasks.v2beta2.Queue.state]; after calling this method it // will be set to [RUNNING][google.cloud.tasks.v2beta2.Queue.State.RUNNING]. // // WARNING: Resuming many high-QPS queues at the same time can // lead to target overloading. If you are resuming high-QPS // queues, follow the 500/50/5 pattern described in // Managing Cloud Tasks Scaling // Risks (at https://cloud.google.com/tasks/docs/manage-cloud-task-scaling). func (c *Client) ResumeQueue(ctx context.Context, req *taskspb.ResumeQueueRequest, opts ...gax.CallOption) (*taskspb.Queue, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ResumeQueue[0:len(c.CallOptions.ResumeQueue):len(c.CallOptions.ResumeQueue)], opts...) var resp *taskspb.Queue err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ResumeQueue(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetIamPolicy gets the access control policy for a [Queue][google.cloud.tasks.v2beta2.Queue]. // Returns an empty policy if the resource exists and does not have a policy // set. // // Authorization requires the following // Google IAM (at https://cloud.google.com/iam) permission on the specified // resource parent: // // cloudtasks.queues.getIamPolicy func (c *Client) GetIamPolicy(ctx context.Context, req *iampb.GetIamPolicyRequest, opts ...gax.CallOption) (*iampb.Policy, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetIamPolicy[0:len(c.CallOptions.GetIamPolicy):len(c.CallOptions.GetIamPolicy)], opts...) var resp *iampb.Policy err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetIamPolicy(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // SetIamPolicy sets the access control policy for a [Queue][google.cloud.tasks.v2beta2.Queue]. Replaces any existing // policy. // // Note: The Cloud Console does not check queue-level IAM permissions yet. // Project-level permissions are required to use the Cloud Console. // // Authorization requires the following // Google IAM (at https://cloud.google.com/iam) permission on the specified // resource parent: // // cloudtasks.queues.setIamPolicy func (c *Client) SetIamPolicy(ctx context.Context, req *iampb.SetIamPolicyRequest, opts ...gax.CallOption) (*iampb.Policy, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.SetIamPolicy[0:len(c.CallOptions.SetIamPolicy):len(c.CallOptions.SetIamPolicy)], opts...) var resp *iampb.Policy err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.SetIamPolicy(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // TestIamPermissions returns permissions that a caller has on a [Queue][google.cloud.tasks.v2beta2.Queue]. // If the resource does not exist, this will return an empty set of // permissions, not a [NOT_FOUND][google.rpc.Code.NOT_FOUND] error. // // Note: This operation is designed to be used for building permission-aware // UIs and command-line tools, not for authorization checking. This operation // may "fail open" without warning. func (c *Client) TestIamPermissions(ctx context.Context, req *iampb.TestIamPermissionsRequest, opts ...gax.CallOption) (*iampb.TestIamPermissionsResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.TestIamPermissions[0:len(c.CallOptions.TestIamPermissions):len(c.CallOptions.TestIamPermissions)], opts...) var resp *iampb.TestIamPermissionsResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.TestIamPermissions(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListTasks lists the tasks in a queue. // // By default, only the [BASIC][google.cloud.tasks.v2beta2.Task.View.BASIC] view is retrieved // due to performance considerations; // [response_view][google.cloud.tasks.v2beta2.ListTasksRequest.response_view] controls the // subset of information which is returned. // // The tasks may be returned in any order. The ordering may change at any // time. func (c *Client) ListTasks(ctx context.Context, req *taskspb.ListTasksRequest, opts ...gax.CallOption) *TaskIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListTasks[0:len(c.CallOptions.ListTasks):len(c.CallOptions.ListTasks)], opts...) it := &TaskIterator{} req = proto.Clone(req).(*taskspb.ListTasksRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*taskspb.Task, string, error) { var resp *taskspb.ListTasksResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListTasks(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Tasks, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetTask gets a task. func (c *Client) GetTask(ctx context.Context, req *taskspb.GetTaskRequest, opts ...gax.CallOption) (*taskspb.Task, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetTask[0:len(c.CallOptions.GetTask):len(c.CallOptions.GetTask)], opts...) var resp *taskspb.Task err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetTask(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateTask creates a task and adds it to a queue. // // Tasks cannot be updated after creation; there is no UpdateTask command. // // For [App Engine queues][google.cloud.tasks.v2beta2.AppEngineHttpTarget], the maximum task size is // 100KB. // // For [pull queues][google.cloud.tasks.v2beta2.PullTarget], the maximum task size is 1MB. func (c *Client) CreateTask(ctx context.Context, req *taskspb.CreateTaskRequest, opts ...gax.CallOption) (*taskspb.Task, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateTask[0:len(c.CallOptions.CreateTask):len(c.CallOptions.CreateTask)], opts...) var resp *taskspb.Task err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CreateTask(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteTask deletes a task. // // A task can be deleted if it is scheduled or dispatched. A task // cannot be deleted if it has completed successfully or permanently // failed. func (c *Client) DeleteTask(ctx context.Context, req *taskspb.DeleteTaskRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteTask[0:len(c.CallOptions.DeleteTask):len(c.CallOptions.DeleteTask)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.client.DeleteTask(ctx, req, settings.GRPC...) return err }, opts...) return err } // LeaseTasks leases tasks from a pull queue for // [lease_duration][google.cloud.tasks.v2beta2.LeaseTasksRequest.lease_duration]. // // This method is invoked by the worker to obtain a lease. The // worker must acknowledge the task via // [AcknowledgeTask][google.cloud.tasks.v2beta2.CloudTasks.AcknowledgeTask] after they have // performed the work associated with the task. // // The [payload][google.cloud.tasks.v2beta2.PullMessage.payload] is intended to store data that // the worker needs to perform the work associated with the task. To // return the payloads in the [response][google.cloud.tasks.v2beta2.LeaseTasksResponse], set // [response_view][google.cloud.tasks.v2beta2.LeaseTasksRequest.response_view] to // [FULL][google.cloud.tasks.v2beta2.Task.View.FULL]. // // A maximum of 10 qps of [LeaseTasks][google.cloud.tasks.v2beta2.CloudTasks.LeaseTasks] // requests are allowed per // queue. [RESOURCE_EXHAUSTED][google.rpc.Code.RESOURCE_EXHAUSTED] // is returned when this limit is // exceeded. [RESOURCE_EXHAUSTED][google.rpc.Code.RESOURCE_EXHAUSTED] // is also returned when // [max_tasks_dispatched_per_second][google.cloud.tasks.v2beta2.RateLimits.max_tasks_dispatched_per_second] // is exceeded. func (c *Client) LeaseTasks(ctx context.Context, req *taskspb.LeaseTasksRequest, opts ...gax.CallOption) (*taskspb.LeaseTasksResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.LeaseTasks[0:len(c.CallOptions.LeaseTasks):len(c.CallOptions.LeaseTasks)], opts...) var resp *taskspb.LeaseTasksResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.LeaseTasks(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // AcknowledgeTask acknowledges a pull task. // // The worker, that is, the entity that // [leased][google.cloud.tasks.v2beta2.CloudTasks.LeaseTasks] this task must call this method // to indicate that the work associated with the task has finished. // // The worker must acknowledge a task within the // [lease_duration][google.cloud.tasks.v2beta2.LeaseTasksRequest.lease_duration] or the lease // will expire and the task will become available to be leased // again. After the task is acknowledged, it will not be returned // by a later [LeaseTasks][google.cloud.tasks.v2beta2.CloudTasks.LeaseTasks], // [GetTask][google.cloud.tasks.v2beta2.CloudTasks.GetTask], or // [ListTasks][google.cloud.tasks.v2beta2.CloudTasks.ListTasks]. func (c *Client) AcknowledgeTask(ctx context.Context, req *taskspb.AcknowledgeTaskRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.AcknowledgeTask[0:len(c.CallOptions.AcknowledgeTask):len(c.CallOptions.AcknowledgeTask)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.client.AcknowledgeTask(ctx, req, settings.GRPC...) return err }, opts...) return err } // RenewLease renew the current lease of a pull task. // // The worker can use this method to extend the lease by a new // duration, starting from now. The new task lease will be // returned in the task's [schedule_time][google.cloud.tasks.v2beta2.Task.schedule_time]. func (c *Client) RenewLease(ctx context.Context, req *taskspb.RenewLeaseRequest, opts ...gax.CallOption) (*taskspb.Task, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.RenewLease[0:len(c.CallOptions.RenewLease):len(c.CallOptions.RenewLease)], opts...) var resp *taskspb.Task err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.RenewLease(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CancelLease cancel a pull task's lease. // // The worker can use this method to cancel a task's lease by // setting its [schedule_time][google.cloud.tasks.v2beta2.Task.schedule_time] to now. This will // make the task available to be leased to the next caller of // [LeaseTasks][google.cloud.tasks.v2beta2.CloudTasks.LeaseTasks]. func (c *Client) CancelLease(ctx context.Context, req *taskspb.CancelLeaseRequest, opts ...gax.CallOption) (*taskspb.Task, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CancelLease[0:len(c.CallOptions.CancelLease):len(c.CallOptions.CancelLease)], opts...) var resp *taskspb.Task err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CancelLease(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // RunTask forces a task to run now. // // When this method is called, Cloud Tasks will dispatch the task, even if // the task is already running, the queue has reached its [RateLimits][google.cloud.tasks.v2beta2.RateLimits] or // is [PAUSED][google.cloud.tasks.v2beta2.Queue.State.PAUSED]. // // This command is meant to be used for manual debugging. For // example, [RunTask][google.cloud.tasks.v2beta2.CloudTasks.RunTask] can be used to retry a failed // task after a fix has been made or to manually force a task to be // dispatched now. // // The dispatched task is returned. That is, the task that is returned // contains the [status][google.cloud.tasks.v2beta2.Task.status] after the task is dispatched but // before the task is received by its target. // // If Cloud Tasks receives a successful response from the task's // target, then the task will be deleted; otherwise the task's // [schedule_time][google.cloud.tasks.v2beta2.Task.schedule_time] will be reset to the time that // [RunTask][google.cloud.tasks.v2beta2.CloudTasks.RunTask] was called plus the retry delay specified // in the queue's [RetryConfig][google.cloud.tasks.v2beta2.RetryConfig]. // // [RunTask][google.cloud.tasks.v2beta2.CloudTasks.RunTask] returns // [NOT_FOUND][google.rpc.Code.NOT_FOUND] when it is called on a // task that has already succeeded or permanently failed. // // [RunTask][google.cloud.tasks.v2beta2.CloudTasks.RunTask] cannot be called on a // [pull task][google.cloud.tasks.v2beta2.PullMessage]. func (c *Client) RunTask(ctx context.Context, req *taskspb.RunTaskRequest, opts ...gax.CallOption) (*taskspb.Task, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.RunTask[0:len(c.CallOptions.RunTask):len(c.CallOptions.RunTask)], opts...) var resp *taskspb.Task err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.RunTask(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // QueueIterator manages a stream of *taskspb.Queue. type QueueIterator struct { items []*taskspb.Queue pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*taskspb.Queue, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *QueueIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *QueueIterator) Next() (*taskspb.Queue, error) { var item *taskspb.Queue if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *QueueIterator) bufLen() int { return len(it.items) } func (it *QueueIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // TaskIterator manages a stream of *taskspb.Task. type TaskIterator struct { items []*taskspb.Task pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*taskspb.Task, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *TaskIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *TaskIterator) Next() (*taskspb.Task, error) { var item *taskspb.Task if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *TaskIterator) bufLen() int { return len(it.items) } func (it *TaskIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/cloudtasks/apiv2beta2/cloud_tasks_client_example_test.go000066400000000000000000000173611356504100700276650ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package cloudtasks_test import ( "context" cloudtasks "cloud.google.com/go/cloudtasks/apiv2beta2" "google.golang.org/api/iterator" taskspb "google.golang.org/genproto/googleapis/cloud/tasks/v2beta2" iampb "google.golang.org/genproto/googleapis/iam/v1" ) func ExampleNewClient() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleClient_ListQueues() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.ListQueuesRequest{ // TODO: Fill request struct fields. } it := c.ListQueues(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_GetQueue() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.GetQueueRequest{ // TODO: Fill request struct fields. } resp, err := c.GetQueue(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_CreateQueue() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.CreateQueueRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateQueue(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_UpdateQueue() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.UpdateQueueRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateQueue(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_DeleteQueue() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.DeleteQueueRequest{ // TODO: Fill request struct fields. } err = c.DeleteQueue(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleClient_PurgeQueue() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.PurgeQueueRequest{ // TODO: Fill request struct fields. } resp, err := c.PurgeQueue(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_PauseQueue() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.PauseQueueRequest{ // TODO: Fill request struct fields. } resp, err := c.PauseQueue(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ResumeQueue() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.ResumeQueueRequest{ // TODO: Fill request struct fields. } resp, err := c.ResumeQueue(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_GetIamPolicy() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &iampb.GetIamPolicyRequest{ // TODO: Fill request struct fields. } resp, err := c.GetIamPolicy(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_SetIamPolicy() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &iampb.SetIamPolicyRequest{ // TODO: Fill request struct fields. } resp, err := c.SetIamPolicy(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_TestIamPermissions() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &iampb.TestIamPermissionsRequest{ // TODO: Fill request struct fields. } resp, err := c.TestIamPermissions(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ListTasks() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.ListTasksRequest{ // TODO: Fill request struct fields. } it := c.ListTasks(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_GetTask() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.GetTaskRequest{ // TODO: Fill request struct fields. } resp, err := c.GetTask(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_CreateTask() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.CreateTaskRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateTask(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_DeleteTask() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.DeleteTaskRequest{ // TODO: Fill request struct fields. } err = c.DeleteTask(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleClient_LeaseTasks() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.LeaseTasksRequest{ // TODO: Fill request struct fields. } resp, err := c.LeaseTasks(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_AcknowledgeTask() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.AcknowledgeTaskRequest{ // TODO: Fill request struct fields. } err = c.AcknowledgeTask(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleClient_RenewLease() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.RenewLeaseRequest{ // TODO: Fill request struct fields. } resp, err := c.RenewLease(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_CancelLease() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.CancelLeaseRequest{ // TODO: Fill request struct fields. } resp, err := c.CancelLease(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_RunTask() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.RunTaskRequest{ // TODO: Fill request struct fields. } resp, err := c.RunTask(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/cloudtasks/apiv2beta2/doc.go000066400000000000000000000053451356504100700220060ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package cloudtasks is an auto-generated package for the // Cloud Tasks API. // // NOTE: This package is in beta. It is not stable, and may be subject to changes. // // Manages the execution of large numbers of distributed requests. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package cloudtasks // import "cloud.google.com/go/cloudtasks/apiv2beta2" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "UNKNOWN" google-cloud-go-0.49.0/cloudtasks/apiv2beta2/mock_test.go000066400000000000000000001277201356504100700232330ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package cloudtasks import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" durationpb "github.com/golang/protobuf/ptypes/duration" emptypb "github.com/golang/protobuf/ptypes/empty" timestamppb "github.com/golang/protobuf/ptypes/timestamp" "google.golang.org/api/option" taskspb "google.golang.org/genproto/googleapis/cloud/tasks/v2beta2" iampb "google.golang.org/genproto/googleapis/iam/v1" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockCloudTasksServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. taskspb.CloudTasksServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockCloudTasksServer) ListQueues(ctx context.Context, req *taskspb.ListQueuesRequest) (*taskspb.ListQueuesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*taskspb.ListQueuesResponse), nil } func (s *mockCloudTasksServer) GetQueue(ctx context.Context, req *taskspb.GetQueueRequest) (*taskspb.Queue, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*taskspb.Queue), nil } func (s *mockCloudTasksServer) CreateQueue(ctx context.Context, req *taskspb.CreateQueueRequest) (*taskspb.Queue, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*taskspb.Queue), nil } func (s *mockCloudTasksServer) UpdateQueue(ctx context.Context, req *taskspb.UpdateQueueRequest) (*taskspb.Queue, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*taskspb.Queue), nil } func (s *mockCloudTasksServer) DeleteQueue(ctx context.Context, req *taskspb.DeleteQueueRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockCloudTasksServer) PurgeQueue(ctx context.Context, req *taskspb.PurgeQueueRequest) (*taskspb.Queue, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*taskspb.Queue), nil } func (s *mockCloudTasksServer) PauseQueue(ctx context.Context, req *taskspb.PauseQueueRequest) (*taskspb.Queue, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*taskspb.Queue), nil } func (s *mockCloudTasksServer) ResumeQueue(ctx context.Context, req *taskspb.ResumeQueueRequest) (*taskspb.Queue, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*taskspb.Queue), nil } func (s *mockCloudTasksServer) GetIamPolicy(ctx context.Context, req *iampb.GetIamPolicyRequest) (*iampb.Policy, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iampb.Policy), nil } func (s *mockCloudTasksServer) SetIamPolicy(ctx context.Context, req *iampb.SetIamPolicyRequest) (*iampb.Policy, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iampb.Policy), nil } func (s *mockCloudTasksServer) TestIamPermissions(ctx context.Context, req *iampb.TestIamPermissionsRequest) (*iampb.TestIamPermissionsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iampb.TestIamPermissionsResponse), nil } func (s *mockCloudTasksServer) ListTasks(ctx context.Context, req *taskspb.ListTasksRequest) (*taskspb.ListTasksResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*taskspb.ListTasksResponse), nil } func (s *mockCloudTasksServer) GetTask(ctx context.Context, req *taskspb.GetTaskRequest) (*taskspb.Task, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*taskspb.Task), nil } func (s *mockCloudTasksServer) CreateTask(ctx context.Context, req *taskspb.CreateTaskRequest) (*taskspb.Task, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*taskspb.Task), nil } func (s *mockCloudTasksServer) DeleteTask(ctx context.Context, req *taskspb.DeleteTaskRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockCloudTasksServer) LeaseTasks(ctx context.Context, req *taskspb.LeaseTasksRequest) (*taskspb.LeaseTasksResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*taskspb.LeaseTasksResponse), nil } func (s *mockCloudTasksServer) AcknowledgeTask(ctx context.Context, req *taskspb.AcknowledgeTaskRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockCloudTasksServer) RenewLease(ctx context.Context, req *taskspb.RenewLeaseRequest) (*taskspb.Task, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*taskspb.Task), nil } func (s *mockCloudTasksServer) CancelLease(ctx context.Context, req *taskspb.CancelLeaseRequest) (*taskspb.Task, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*taskspb.Task), nil } func (s *mockCloudTasksServer) RunTask(ctx context.Context, req *taskspb.RunTaskRequest) (*taskspb.Task, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*taskspb.Task), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockCloudTasks mockCloudTasksServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() taskspb.RegisterCloudTasksServer(serv, &mockCloudTasks) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestCloudTasksListQueues(t *testing.T) { var nextPageToken string = "" var queuesElement *taskspb.Queue = &taskspb.Queue{} var queues = []*taskspb.Queue{queuesElement} var expectedResponse = &taskspb.ListQueuesResponse{ NextPageToken: nextPageToken, Queues: queues, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &taskspb.ListQueuesRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListQueues(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Queues[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksListQueuesError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &taskspb.ListQueuesRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListQueues(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksGetQueue(t *testing.T) { var name2 string = "name2-1052831874" var expectedResponse = &taskspb.Queue{ Name: name2, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &taskspb.GetQueueRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetQueue(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksGetQueueError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &taskspb.GetQueueRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetQueue(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksCreateQueue(t *testing.T) { var name string = "name3373707" var expectedResponse = &taskspb.Queue{ Name: name, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var queue *taskspb.Queue = &taskspb.Queue{} var request = &taskspb.CreateQueueRequest{ Parent: formattedParent, Queue: queue, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateQueue(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksCreateQueueError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var queue *taskspb.Queue = &taskspb.Queue{} var request = &taskspb.CreateQueueRequest{ Parent: formattedParent, Queue: queue, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateQueue(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksUpdateQueue(t *testing.T) { var name string = "name3373707" var expectedResponse = &taskspb.Queue{ Name: name, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var queue *taskspb.Queue = &taskspb.Queue{} var request = &taskspb.UpdateQueueRequest{ Queue: queue, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateQueue(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksUpdateQueueError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var queue *taskspb.Queue = &taskspb.Queue{} var request = &taskspb.UpdateQueueRequest{ Queue: queue, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateQueue(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksDeleteQueue(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &taskspb.DeleteQueueRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteQueue(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestCloudTasksDeleteQueueError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &taskspb.DeleteQueueRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteQueue(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestCloudTasksPurgeQueue(t *testing.T) { var name2 string = "name2-1052831874" var expectedResponse = &taskspb.Queue{ Name: name2, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &taskspb.PurgeQueueRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.PurgeQueue(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksPurgeQueueError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &taskspb.PurgeQueueRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.PurgeQueue(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksPauseQueue(t *testing.T) { var name2 string = "name2-1052831874" var expectedResponse = &taskspb.Queue{ Name: name2, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &taskspb.PauseQueueRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.PauseQueue(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksPauseQueueError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &taskspb.PauseQueueRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.PauseQueue(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksResumeQueue(t *testing.T) { var name2 string = "name2-1052831874" var expectedResponse = &taskspb.Queue{ Name: name2, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &taskspb.ResumeQueueRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ResumeQueue(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksResumeQueueError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &taskspb.ResumeQueueRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ResumeQueue(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksGetIamPolicy(t *testing.T) { var version int32 = 351608024 var etag []byte = []byte("21") var expectedResponse = &iampb.Policy{ Version: version, Etag: etag, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedResource string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &iampb.GetIamPolicyRequest{ Resource: formattedResource, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetIamPolicy(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksGetIamPolicyError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedResource string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &iampb.GetIamPolicyRequest{ Resource: formattedResource, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetIamPolicy(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksSetIamPolicy(t *testing.T) { var version int32 = 351608024 var etag []byte = []byte("21") var expectedResponse = &iampb.Policy{ Version: version, Etag: etag, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedResource string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var policy *iampb.Policy = &iampb.Policy{} var request = &iampb.SetIamPolicyRequest{ Resource: formattedResource, Policy: policy, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetIamPolicy(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksSetIamPolicyError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedResource string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var policy *iampb.Policy = &iampb.Policy{} var request = &iampb.SetIamPolicyRequest{ Resource: formattedResource, Policy: policy, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetIamPolicy(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksTestIamPermissions(t *testing.T) { var expectedResponse *iampb.TestIamPermissionsResponse = &iampb.TestIamPermissionsResponse{} mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedResource string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var permissions []string = nil var request = &iampb.TestIamPermissionsRequest{ Resource: formattedResource, Permissions: permissions, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.TestIamPermissions(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksTestIamPermissionsError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedResource string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var permissions []string = nil var request = &iampb.TestIamPermissionsRequest{ Resource: formattedResource, Permissions: permissions, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.TestIamPermissions(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksListTasks(t *testing.T) { var nextPageToken string = "" var tasksElement *taskspb.Task = &taskspb.Task{} var tasks = []*taskspb.Task{tasksElement} var expectedResponse = &taskspb.ListTasksResponse{ NextPageToken: nextPageToken, Tasks: tasks, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &taskspb.ListTasksRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListTasks(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Tasks[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksListTasksError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &taskspb.ListTasksRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListTasks(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksGetTask(t *testing.T) { var name2 string = "name2-1052831874" var expectedResponse = &taskspb.Task{ Name: name2, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s/tasks/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]", "[TASK]") var request = &taskspb.GetTaskRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetTask(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksGetTaskError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s/tasks/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]", "[TASK]") var request = &taskspb.GetTaskRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetTask(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksCreateTask(t *testing.T) { var name string = "name3373707" var expectedResponse = &taskspb.Task{ Name: name, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var task *taskspb.Task = &taskspb.Task{} var request = &taskspb.CreateTaskRequest{ Parent: formattedParent, Task: task, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateTask(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksCreateTaskError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var task *taskspb.Task = &taskspb.Task{} var request = &taskspb.CreateTaskRequest{ Parent: formattedParent, Task: task, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateTask(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksDeleteTask(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s/tasks/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]", "[TASK]") var request = &taskspb.DeleteTaskRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteTask(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestCloudTasksDeleteTaskError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s/tasks/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]", "[TASK]") var request = &taskspb.DeleteTaskRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteTask(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestCloudTasksLeaseTasks(t *testing.T) { var expectedResponse *taskspb.LeaseTasksResponse = &taskspb.LeaseTasksResponse{} mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var leaseDuration *durationpb.Duration = &durationpb.Duration{} var request = &taskspb.LeaseTasksRequest{ Parent: formattedParent, LeaseDuration: leaseDuration, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.LeaseTasks(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksLeaseTasksError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var leaseDuration *durationpb.Duration = &durationpb.Duration{} var request = &taskspb.LeaseTasksRequest{ Parent: formattedParent, LeaseDuration: leaseDuration, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.LeaseTasks(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksAcknowledgeTask(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s/tasks/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]", "[TASK]") var scheduleTime *timestamppb.Timestamp = ×tamppb.Timestamp{} var request = &taskspb.AcknowledgeTaskRequest{ Name: formattedName, ScheduleTime: scheduleTime, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.AcknowledgeTask(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestCloudTasksAcknowledgeTaskError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s/tasks/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]", "[TASK]") var scheduleTime *timestamppb.Timestamp = ×tamppb.Timestamp{} var request = &taskspb.AcknowledgeTaskRequest{ Name: formattedName, ScheduleTime: scheduleTime, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.AcknowledgeTask(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestCloudTasksRenewLease(t *testing.T) { var name2 string = "name2-1052831874" var expectedResponse = &taskspb.Task{ Name: name2, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s/tasks/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]", "[TASK]") var scheduleTime *timestamppb.Timestamp = ×tamppb.Timestamp{} var leaseDuration *durationpb.Duration = &durationpb.Duration{} var request = &taskspb.RenewLeaseRequest{ Name: formattedName, ScheduleTime: scheduleTime, LeaseDuration: leaseDuration, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.RenewLease(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksRenewLeaseError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s/tasks/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]", "[TASK]") var scheduleTime *timestamppb.Timestamp = ×tamppb.Timestamp{} var leaseDuration *durationpb.Duration = &durationpb.Duration{} var request = &taskspb.RenewLeaseRequest{ Name: formattedName, ScheduleTime: scheduleTime, LeaseDuration: leaseDuration, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.RenewLease(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksCancelLease(t *testing.T) { var name2 string = "name2-1052831874" var expectedResponse = &taskspb.Task{ Name: name2, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s/tasks/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]", "[TASK]") var scheduleTime *timestamppb.Timestamp = ×tamppb.Timestamp{} var request = &taskspb.CancelLeaseRequest{ Name: formattedName, ScheduleTime: scheduleTime, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CancelLease(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksCancelLeaseError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s/tasks/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]", "[TASK]") var scheduleTime *timestamppb.Timestamp = ×tamppb.Timestamp{} var request = &taskspb.CancelLeaseRequest{ Name: formattedName, ScheduleTime: scheduleTime, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CancelLease(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksRunTask(t *testing.T) { var name2 string = "name2-1052831874" var expectedResponse = &taskspb.Task{ Name: name2, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s/tasks/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]", "[TASK]") var request = &taskspb.RunTaskRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.RunTask(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksRunTaskError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s/tasks/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]", "[TASK]") var request = &taskspb.RunTaskRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.RunTask(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/cloudtasks/apiv2beta3/000077500000000000000000000000001356504100700207045ustar00rootroot00000000000000google-cloud-go-0.49.0/cloudtasks/apiv2beta3/.repo-metadata.json000066400000000000000000000006371356504100700244060ustar00rootroot00000000000000{ "name": "cloudtasks", "name_pretty": "Cloud Tasks API", "product_documentation": "https://cloud.google.com/tasks", "client_documentation": "https://godoc.org/cloud.google.com/go/cloudtasks/apiv2beta3", "release_level": "beta", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "cloudtasks.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/cloudtasks/apiv2beta3/cloud_tasks_client.go000066400000000000000000000641041356504100700251110ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package cloudtasks import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" taskspb "google.golang.org/genproto/googleapis/cloud/tasks/v2beta3" iampb "google.golang.org/genproto/googleapis/iam/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // CallOptions contains the retry settings for each method of Client. type CallOptions struct { ListQueues []gax.CallOption GetQueue []gax.CallOption CreateQueue []gax.CallOption UpdateQueue []gax.CallOption DeleteQueue []gax.CallOption PurgeQueue []gax.CallOption PauseQueue []gax.CallOption ResumeQueue []gax.CallOption GetIamPolicy []gax.CallOption SetIamPolicy []gax.CallOption TestIamPermissions []gax.CallOption ListTasks []gax.CallOption GetTask []gax.CallOption CreateTask []gax.CallOption DeleteTask []gax.CallOption RunTask []gax.CallOption } func defaultClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("cloudtasks.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultCallOptions() *CallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &CallOptions{ ListQueues: retry[[2]string{"default", "idempotent"}], GetQueue: retry[[2]string{"default", "idempotent"}], CreateQueue: retry[[2]string{"default", "non_idempotent"}], UpdateQueue: retry[[2]string{"default", "non_idempotent"}], DeleteQueue: retry[[2]string{"default", "idempotent"}], PurgeQueue: retry[[2]string{"default", "non_idempotent"}], PauseQueue: retry[[2]string{"default", "non_idempotent"}], ResumeQueue: retry[[2]string{"default", "non_idempotent"}], GetIamPolicy: retry[[2]string{"default", "idempotent"}], SetIamPolicy: retry[[2]string{"default", "non_idempotent"}], TestIamPermissions: retry[[2]string{"default", "idempotent"}], ListTasks: retry[[2]string{"default", "idempotent"}], GetTask: retry[[2]string{"default", "idempotent"}], CreateTask: retry[[2]string{"default", "non_idempotent"}], DeleteTask: retry[[2]string{"default", "idempotent"}], RunTask: retry[[2]string{"default", "non_idempotent"}], } } // Client is a client for interacting with Cloud Tasks API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. client taskspb.CloudTasksClient // The call options for this service. CallOptions *CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewClient creates a new cloud tasks client. // // Cloud Tasks allows developers to manage the execution of background // work in their applications. func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultClientOptions(), opts...)...) if err != nil { return nil, err } c := &Client{ conn: conn, CallOptions: defaultCallOptions(), client: taskspb.NewCloudTasksClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *Client) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *Client) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // ListQueues lists queues. // // Queues are returned in lexicographical order. func (c *Client) ListQueues(ctx context.Context, req *taskspb.ListQueuesRequest, opts ...gax.CallOption) *QueueIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListQueues[0:len(c.CallOptions.ListQueues):len(c.CallOptions.ListQueues)], opts...) it := &QueueIterator{} req = proto.Clone(req).(*taskspb.ListQueuesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*taskspb.Queue, string, error) { var resp *taskspb.ListQueuesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListQueues(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Queues, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetQueue gets a queue. func (c *Client) GetQueue(ctx context.Context, req *taskspb.GetQueueRequest, opts ...gax.CallOption) (*taskspb.Queue, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetQueue[0:len(c.CallOptions.GetQueue):len(c.CallOptions.GetQueue)], opts...) var resp *taskspb.Queue err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetQueue(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateQueue creates a queue. // // Queues created with this method allow tasks to live for a maximum of 31 // days. After a task is 31 days old, the task will be deleted regardless of whether // it was dispatched or not. // // WARNING: Using this method may have unintended side effects if you are // using an App Engine queue.yaml or queue.xml file to manage your queues. // Read // Overview of Queue Management and // queue.yaml (at https://cloud.google.com/tasks/docs/queue-yaml) before using // this method. func (c *Client) CreateQueue(ctx context.Context, req *taskspb.CreateQueueRequest, opts ...gax.CallOption) (*taskspb.Queue, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateQueue[0:len(c.CallOptions.CreateQueue):len(c.CallOptions.CreateQueue)], opts...) var resp *taskspb.Queue err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CreateQueue(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateQueue updates a queue. // // This method creates the queue if it does not exist and updates // the queue if it does exist. // // Queues created with this method allow tasks to live for a maximum of 31 // days. After a task is 31 days old, the task will be deleted regardless of whether // it was dispatched or not. // // WARNING: Using this method may have unintended side effects if you are // using an App Engine queue.yaml or queue.xml file to manage your queues. // Read // Overview of Queue Management and // queue.yaml (at https://cloud.google.com/tasks/docs/queue-yaml) before using // this method. func (c *Client) UpdateQueue(ctx context.Context, req *taskspb.UpdateQueueRequest, opts ...gax.CallOption) (*taskspb.Queue, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "queue.name", url.QueryEscape(req.GetQueue().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateQueue[0:len(c.CallOptions.UpdateQueue):len(c.CallOptions.UpdateQueue)], opts...) var resp *taskspb.Queue err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.UpdateQueue(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteQueue deletes a queue. // // This command will delete the queue even if it has tasks in it. // // Note: If you delete a queue, a queue with the same name can't be created // for 7 days. // // WARNING: Using this method may have unintended side effects if you are // using an App Engine queue.yaml or queue.xml file to manage your queues. // Read // Overview of Queue Management and // queue.yaml (at https://cloud.google.com/tasks/docs/queue-yaml) before using // this method. func (c *Client) DeleteQueue(ctx context.Context, req *taskspb.DeleteQueueRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteQueue[0:len(c.CallOptions.DeleteQueue):len(c.CallOptions.DeleteQueue)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.client.DeleteQueue(ctx, req, settings.GRPC...) return err }, opts...) return err } // PurgeQueue purges a queue by deleting all of its tasks. // // All tasks created before this method is called are permanently deleted. // // Purge operations can take up to one minute to take effect. Tasks // might be dispatched before the purge takes effect. A purge is irreversible. func (c *Client) PurgeQueue(ctx context.Context, req *taskspb.PurgeQueueRequest, opts ...gax.CallOption) (*taskspb.Queue, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.PurgeQueue[0:len(c.CallOptions.PurgeQueue):len(c.CallOptions.PurgeQueue)], opts...) var resp *taskspb.Queue err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.PurgeQueue(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // PauseQueue pauses the queue. // // If a queue is paused then the system will stop dispatching tasks // until the queue is resumed via // [ResumeQueue][google.cloud.tasks.v2beta3.CloudTasks.ResumeQueue]. Tasks can still be added // when the queue is paused. A queue is paused if its // [state][google.cloud.tasks.v2beta3.Queue.state] is [PAUSED][google.cloud.tasks.v2beta3.Queue.State.PAUSED]. func (c *Client) PauseQueue(ctx context.Context, req *taskspb.PauseQueueRequest, opts ...gax.CallOption) (*taskspb.Queue, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.PauseQueue[0:len(c.CallOptions.PauseQueue):len(c.CallOptions.PauseQueue)], opts...) var resp *taskspb.Queue err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.PauseQueue(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ResumeQueue resume a queue. // // This method resumes a queue after it has been // [PAUSED][google.cloud.tasks.v2beta3.Queue.State.PAUSED] or // [DISABLED][google.cloud.tasks.v2beta3.Queue.State.DISABLED]. The state of a queue is stored // in the queue's [state][google.cloud.tasks.v2beta3.Queue.state]; after calling this method it // will be set to [RUNNING][google.cloud.tasks.v2beta3.Queue.State.RUNNING]. // // WARNING: Resuming many high-QPS queues at the same time can // lead to target overloading. If you are resuming high-QPS // queues, follow the 500/50/5 pattern described in // Managing Cloud Tasks Scaling // Risks (at https://cloud.google.com/tasks/docs/manage-cloud-task-scaling). func (c *Client) ResumeQueue(ctx context.Context, req *taskspb.ResumeQueueRequest, opts ...gax.CallOption) (*taskspb.Queue, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ResumeQueue[0:len(c.CallOptions.ResumeQueue):len(c.CallOptions.ResumeQueue)], opts...) var resp *taskspb.Queue err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ResumeQueue(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetIamPolicy gets the access control policy for a [Queue][google.cloud.tasks.v2beta3.Queue]. // Returns an empty policy if the resource exists and does not have a policy // set. // // Authorization requires the following // Google IAM (at https://cloud.google.com/iam) permission on the specified // resource parent: // // cloudtasks.queues.getIamPolicy func (c *Client) GetIamPolicy(ctx context.Context, req *iampb.GetIamPolicyRequest, opts ...gax.CallOption) (*iampb.Policy, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetIamPolicy[0:len(c.CallOptions.GetIamPolicy):len(c.CallOptions.GetIamPolicy)], opts...) var resp *iampb.Policy err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetIamPolicy(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // SetIamPolicy sets the access control policy for a [Queue][google.cloud.tasks.v2beta3.Queue]. Replaces any existing // policy. // // Note: The Cloud Console does not check queue-level IAM permissions yet. // Project-level permissions are required to use the Cloud Console. // // Authorization requires the following // Google IAM (at https://cloud.google.com/iam) permission on the specified // resource parent: // // cloudtasks.queues.setIamPolicy func (c *Client) SetIamPolicy(ctx context.Context, req *iampb.SetIamPolicyRequest, opts ...gax.CallOption) (*iampb.Policy, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.SetIamPolicy[0:len(c.CallOptions.SetIamPolicy):len(c.CallOptions.SetIamPolicy)], opts...) var resp *iampb.Policy err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.SetIamPolicy(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // TestIamPermissions returns permissions that a caller has on a [Queue][google.cloud.tasks.v2beta3.Queue]. // If the resource does not exist, this will return an empty set of // permissions, not a [NOT_FOUND][google.rpc.Code.NOT_FOUND] error. // // Note: This operation is designed to be used for building permission-aware // UIs and command-line tools, not for authorization checking. This operation // may "fail open" without warning. func (c *Client) TestIamPermissions(ctx context.Context, req *iampb.TestIamPermissionsRequest, opts ...gax.CallOption) (*iampb.TestIamPermissionsResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.TestIamPermissions[0:len(c.CallOptions.TestIamPermissions):len(c.CallOptions.TestIamPermissions)], opts...) var resp *iampb.TestIamPermissionsResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.TestIamPermissions(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListTasks lists the tasks in a queue. // // By default, only the [BASIC][google.cloud.tasks.v2beta3.Task.View.BASIC] view is retrieved // due to performance considerations; // [response_view][google.cloud.tasks.v2beta3.ListTasksRequest.response_view] controls the // subset of information which is returned. // // The tasks may be returned in any order. The ordering may change at any // time. func (c *Client) ListTasks(ctx context.Context, req *taskspb.ListTasksRequest, opts ...gax.CallOption) *TaskIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListTasks[0:len(c.CallOptions.ListTasks):len(c.CallOptions.ListTasks)], opts...) it := &TaskIterator{} req = proto.Clone(req).(*taskspb.ListTasksRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*taskspb.Task, string, error) { var resp *taskspb.ListTasksResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListTasks(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Tasks, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetTask gets a task. func (c *Client) GetTask(ctx context.Context, req *taskspb.GetTaskRequest, opts ...gax.CallOption) (*taskspb.Task, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetTask[0:len(c.CallOptions.GetTask):len(c.CallOptions.GetTask)], opts...) var resp *taskspb.Task err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetTask(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateTask creates a task and adds it to a queue. // // Tasks cannot be updated after creation; there is no UpdateTask command. // // The maximum task size is 100KB. func (c *Client) CreateTask(ctx context.Context, req *taskspb.CreateTaskRequest, opts ...gax.CallOption) (*taskspb.Task, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateTask[0:len(c.CallOptions.CreateTask):len(c.CallOptions.CreateTask)], opts...) var resp *taskspb.Task err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CreateTask(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteTask deletes a task. // // A task can be deleted if it is scheduled or dispatched. A task // cannot be deleted if it has executed successfully or permanently // failed. func (c *Client) DeleteTask(ctx context.Context, req *taskspb.DeleteTaskRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteTask[0:len(c.CallOptions.DeleteTask):len(c.CallOptions.DeleteTask)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.client.DeleteTask(ctx, req, settings.GRPC...) return err }, opts...) return err } // RunTask forces a task to run now. // // When this method is called, Cloud Tasks will dispatch the task, even if // the task is already running, the queue has reached its [RateLimits][google.cloud.tasks.v2beta3.RateLimits] or // is [PAUSED][google.cloud.tasks.v2beta3.Queue.State.PAUSED]. // // This command is meant to be used for manual debugging. For // example, [RunTask][google.cloud.tasks.v2beta3.CloudTasks.RunTask] can be used to retry a failed // task after a fix has been made or to manually force a task to be // dispatched now. // // The dispatched task is returned. That is, the task that is returned // contains the [status][Task.status] after the task is dispatched but // before the task is received by its target. // // If Cloud Tasks receives a successful response from the task's // target, then the task will be deleted; otherwise the task's // [schedule_time][google.cloud.tasks.v2beta3.Task.schedule_time] will be reset to the time that // [RunTask][google.cloud.tasks.v2beta3.CloudTasks.RunTask] was called plus the retry delay specified // in the queue's [RetryConfig][google.cloud.tasks.v2beta3.RetryConfig]. // // [RunTask][google.cloud.tasks.v2beta3.CloudTasks.RunTask] returns // [NOT_FOUND][google.rpc.Code.NOT_FOUND] when it is called on a // task that has already succeeded or permanently failed. func (c *Client) RunTask(ctx context.Context, req *taskspb.RunTaskRequest, opts ...gax.CallOption) (*taskspb.Task, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.RunTask[0:len(c.CallOptions.RunTask):len(c.CallOptions.RunTask)], opts...) var resp *taskspb.Task err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.RunTask(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // QueueIterator manages a stream of *taskspb.Queue. type QueueIterator struct { items []*taskspb.Queue pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*taskspb.Queue, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *QueueIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *QueueIterator) Next() (*taskspb.Queue, error) { var item *taskspb.Queue if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *QueueIterator) bufLen() int { return len(it.items) } func (it *QueueIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // TaskIterator manages a stream of *taskspb.Task. type TaskIterator struct { items []*taskspb.Task pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*taskspb.Task, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *TaskIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *TaskIterator) Next() (*taskspb.Task, error) { var item *taskspb.Task if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *TaskIterator) bufLen() int { return len(it.items) } func (it *TaskIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/cloudtasks/apiv2beta3/cloud_tasks_client_example_test.go000066400000000000000000000146701356504100700276660ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package cloudtasks_test import ( "context" cloudtasks "cloud.google.com/go/cloudtasks/apiv2beta3" "google.golang.org/api/iterator" taskspb "google.golang.org/genproto/googleapis/cloud/tasks/v2beta3" iampb "google.golang.org/genproto/googleapis/iam/v1" ) func ExampleNewClient() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleClient_ListQueues() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.ListQueuesRequest{ // TODO: Fill request struct fields. } it := c.ListQueues(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_GetQueue() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.GetQueueRequest{ // TODO: Fill request struct fields. } resp, err := c.GetQueue(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_CreateQueue() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.CreateQueueRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateQueue(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_UpdateQueue() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.UpdateQueueRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateQueue(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_DeleteQueue() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.DeleteQueueRequest{ // TODO: Fill request struct fields. } err = c.DeleteQueue(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleClient_PurgeQueue() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.PurgeQueueRequest{ // TODO: Fill request struct fields. } resp, err := c.PurgeQueue(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_PauseQueue() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.PauseQueueRequest{ // TODO: Fill request struct fields. } resp, err := c.PauseQueue(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ResumeQueue() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.ResumeQueueRequest{ // TODO: Fill request struct fields. } resp, err := c.ResumeQueue(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_GetIamPolicy() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &iampb.GetIamPolicyRequest{ // TODO: Fill request struct fields. } resp, err := c.GetIamPolicy(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_SetIamPolicy() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &iampb.SetIamPolicyRequest{ // TODO: Fill request struct fields. } resp, err := c.SetIamPolicy(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_TestIamPermissions() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &iampb.TestIamPermissionsRequest{ // TODO: Fill request struct fields. } resp, err := c.TestIamPermissions(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ListTasks() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.ListTasksRequest{ // TODO: Fill request struct fields. } it := c.ListTasks(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_GetTask() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.GetTaskRequest{ // TODO: Fill request struct fields. } resp, err := c.GetTask(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_CreateTask() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.CreateTaskRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateTask(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_DeleteTask() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.DeleteTaskRequest{ // TODO: Fill request struct fields. } err = c.DeleteTask(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleClient_RunTask() { ctx := context.Background() c, err := cloudtasks.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &taskspb.RunTaskRequest{ // TODO: Fill request struct fields. } resp, err := c.RunTask(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/cloudtasks/apiv2beta3/doc.go000066400000000000000000000053451356504100700220070ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package cloudtasks is an auto-generated package for the // Cloud Tasks API. // // NOTE: This package is in beta. It is not stable, and may be subject to changes. // // Manages the execution of large numbers of distributed requests. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package cloudtasks // import "cloud.google.com/go/cloudtasks/apiv2beta3" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "UNKNOWN" google-cloud-go-0.49.0/cloudtasks/apiv2beta3/mock_test.go000066400000000000000000001064731356504100700232360ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package cloudtasks import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" "google.golang.org/api/option" taskspb "google.golang.org/genproto/googleapis/cloud/tasks/v2beta3" iampb "google.golang.org/genproto/googleapis/iam/v1" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockCloudTasksServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. taskspb.CloudTasksServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockCloudTasksServer) ListQueues(ctx context.Context, req *taskspb.ListQueuesRequest) (*taskspb.ListQueuesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*taskspb.ListQueuesResponse), nil } func (s *mockCloudTasksServer) GetQueue(ctx context.Context, req *taskspb.GetQueueRequest) (*taskspb.Queue, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*taskspb.Queue), nil } func (s *mockCloudTasksServer) CreateQueue(ctx context.Context, req *taskspb.CreateQueueRequest) (*taskspb.Queue, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*taskspb.Queue), nil } func (s *mockCloudTasksServer) UpdateQueue(ctx context.Context, req *taskspb.UpdateQueueRequest) (*taskspb.Queue, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*taskspb.Queue), nil } func (s *mockCloudTasksServer) DeleteQueue(ctx context.Context, req *taskspb.DeleteQueueRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockCloudTasksServer) PurgeQueue(ctx context.Context, req *taskspb.PurgeQueueRequest) (*taskspb.Queue, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*taskspb.Queue), nil } func (s *mockCloudTasksServer) PauseQueue(ctx context.Context, req *taskspb.PauseQueueRequest) (*taskspb.Queue, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*taskspb.Queue), nil } func (s *mockCloudTasksServer) ResumeQueue(ctx context.Context, req *taskspb.ResumeQueueRequest) (*taskspb.Queue, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*taskspb.Queue), nil } func (s *mockCloudTasksServer) GetIamPolicy(ctx context.Context, req *iampb.GetIamPolicyRequest) (*iampb.Policy, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iampb.Policy), nil } func (s *mockCloudTasksServer) SetIamPolicy(ctx context.Context, req *iampb.SetIamPolicyRequest) (*iampb.Policy, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iampb.Policy), nil } func (s *mockCloudTasksServer) TestIamPermissions(ctx context.Context, req *iampb.TestIamPermissionsRequest) (*iampb.TestIamPermissionsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iampb.TestIamPermissionsResponse), nil } func (s *mockCloudTasksServer) ListTasks(ctx context.Context, req *taskspb.ListTasksRequest) (*taskspb.ListTasksResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*taskspb.ListTasksResponse), nil } func (s *mockCloudTasksServer) GetTask(ctx context.Context, req *taskspb.GetTaskRequest) (*taskspb.Task, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*taskspb.Task), nil } func (s *mockCloudTasksServer) CreateTask(ctx context.Context, req *taskspb.CreateTaskRequest) (*taskspb.Task, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*taskspb.Task), nil } func (s *mockCloudTasksServer) DeleteTask(ctx context.Context, req *taskspb.DeleteTaskRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockCloudTasksServer) RunTask(ctx context.Context, req *taskspb.RunTaskRequest) (*taskspb.Task, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*taskspb.Task), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockCloudTasks mockCloudTasksServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() taskspb.RegisterCloudTasksServer(serv, &mockCloudTasks) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestCloudTasksListQueues(t *testing.T) { var nextPageToken string = "" var queuesElement *taskspb.Queue = &taskspb.Queue{} var queues = []*taskspb.Queue{queuesElement} var expectedResponse = &taskspb.ListQueuesResponse{ NextPageToken: nextPageToken, Queues: queues, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &taskspb.ListQueuesRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListQueues(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Queues[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksListQueuesError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &taskspb.ListQueuesRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListQueues(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksGetQueue(t *testing.T) { var name2 string = "name2-1052831874" var expectedResponse = &taskspb.Queue{ Name: name2, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &taskspb.GetQueueRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetQueue(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksGetQueueError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &taskspb.GetQueueRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetQueue(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksCreateQueue(t *testing.T) { var name string = "name3373707" var expectedResponse = &taskspb.Queue{ Name: name, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var queue *taskspb.Queue = &taskspb.Queue{} var request = &taskspb.CreateQueueRequest{ Parent: formattedParent, Queue: queue, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateQueue(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksCreateQueueError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var queue *taskspb.Queue = &taskspb.Queue{} var request = &taskspb.CreateQueueRequest{ Parent: formattedParent, Queue: queue, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateQueue(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksUpdateQueue(t *testing.T) { var name string = "name3373707" var expectedResponse = &taskspb.Queue{ Name: name, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var queue *taskspb.Queue = &taskspb.Queue{} var request = &taskspb.UpdateQueueRequest{ Queue: queue, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateQueue(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksUpdateQueueError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var queue *taskspb.Queue = &taskspb.Queue{} var request = &taskspb.UpdateQueueRequest{ Queue: queue, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateQueue(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksDeleteQueue(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &taskspb.DeleteQueueRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteQueue(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestCloudTasksDeleteQueueError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &taskspb.DeleteQueueRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteQueue(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestCloudTasksPurgeQueue(t *testing.T) { var name2 string = "name2-1052831874" var expectedResponse = &taskspb.Queue{ Name: name2, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &taskspb.PurgeQueueRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.PurgeQueue(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksPurgeQueueError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &taskspb.PurgeQueueRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.PurgeQueue(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksPauseQueue(t *testing.T) { var name2 string = "name2-1052831874" var expectedResponse = &taskspb.Queue{ Name: name2, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &taskspb.PauseQueueRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.PauseQueue(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksPauseQueueError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &taskspb.PauseQueueRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.PauseQueue(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksResumeQueue(t *testing.T) { var name2 string = "name2-1052831874" var expectedResponse = &taskspb.Queue{ Name: name2, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &taskspb.ResumeQueueRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ResumeQueue(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksResumeQueueError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &taskspb.ResumeQueueRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ResumeQueue(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksGetIamPolicy(t *testing.T) { var version int32 = 351608024 var etag []byte = []byte("21") var expectedResponse = &iampb.Policy{ Version: version, Etag: etag, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedResource string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &iampb.GetIamPolicyRequest{ Resource: formattedResource, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetIamPolicy(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksGetIamPolicyError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedResource string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &iampb.GetIamPolicyRequest{ Resource: formattedResource, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetIamPolicy(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksSetIamPolicy(t *testing.T) { var version int32 = 351608024 var etag []byte = []byte("21") var expectedResponse = &iampb.Policy{ Version: version, Etag: etag, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedResource string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var policy *iampb.Policy = &iampb.Policy{} var request = &iampb.SetIamPolicyRequest{ Resource: formattedResource, Policy: policy, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetIamPolicy(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksSetIamPolicyError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedResource string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var policy *iampb.Policy = &iampb.Policy{} var request = &iampb.SetIamPolicyRequest{ Resource: formattedResource, Policy: policy, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetIamPolicy(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksTestIamPermissions(t *testing.T) { var expectedResponse *iampb.TestIamPermissionsResponse = &iampb.TestIamPermissionsResponse{} mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedResource string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var permissions []string = nil var request = &iampb.TestIamPermissionsRequest{ Resource: formattedResource, Permissions: permissions, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.TestIamPermissions(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksTestIamPermissionsError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedResource string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var permissions []string = nil var request = &iampb.TestIamPermissionsRequest{ Resource: formattedResource, Permissions: permissions, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.TestIamPermissions(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksListTasks(t *testing.T) { var nextPageToken string = "" var tasksElement *taskspb.Task = &taskspb.Task{} var tasks = []*taskspb.Task{tasksElement} var expectedResponse = &taskspb.ListTasksResponse{ NextPageToken: nextPageToken, Tasks: tasks, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &taskspb.ListTasksRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListTasks(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Tasks[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksListTasksError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var request = &taskspb.ListTasksRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListTasks(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksGetTask(t *testing.T) { var name2 string = "name2-1052831874" var dispatchCount int32 = 1217252086 var responseCount int32 = 424727441 var expectedResponse = &taskspb.Task{ Name: name2, DispatchCount: dispatchCount, ResponseCount: responseCount, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s/tasks/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]", "[TASK]") var request = &taskspb.GetTaskRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetTask(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksGetTaskError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s/tasks/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]", "[TASK]") var request = &taskspb.GetTaskRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetTask(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksCreateTask(t *testing.T) { var name string = "name3373707" var dispatchCount int32 = 1217252086 var responseCount int32 = 424727441 var expectedResponse = &taskspb.Task{ Name: name, DispatchCount: dispatchCount, ResponseCount: responseCount, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var task *taskspb.Task = &taskspb.Task{} var request = &taskspb.CreateTaskRequest{ Parent: formattedParent, Task: task, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateTask(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksCreateTaskError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/queues/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]") var task *taskspb.Task = &taskspb.Task{} var request = &taskspb.CreateTaskRequest{ Parent: formattedParent, Task: task, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateTask(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudTasksDeleteTask(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s/tasks/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]", "[TASK]") var request = &taskspb.DeleteTaskRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteTask(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestCloudTasksDeleteTaskError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s/tasks/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]", "[TASK]") var request = &taskspb.DeleteTaskRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteTask(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestCloudTasksRunTask(t *testing.T) { var name2 string = "name2-1052831874" var dispatchCount int32 = 1217252086 var responseCount int32 = 424727441 var expectedResponse = &taskspb.Task{ Name: name2, DispatchCount: dispatchCount, ResponseCount: responseCount, } mockCloudTasks.err = nil mockCloudTasks.reqs = nil mockCloudTasks.resps = append(mockCloudTasks.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s/tasks/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]", "[TASK]") var request = &taskspb.RunTaskRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.RunTask(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudTasks.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudTasksRunTaskError(t *testing.T) { errCode := codes.PermissionDenied mockCloudTasks.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/queues/%s/tasks/%s", "[PROJECT]", "[LOCATION]", "[QUEUE]", "[TASK]") var request = &taskspb.RunTaskRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.RunTask(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/cmd/000077500000000000000000000000001356504100700153335ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/000077500000000000000000000000001356504100700212245ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/debuglet.go000066400000000000000000000353661356504100700233630ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // +build linux,go1.7 package main import ( "context" "encoding/json" "flag" "fmt" "io/ioutil" "log" "math/rand" "os" "sync" "time" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/breakpoints" debuglet "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/controller" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/local" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/valuecollector" "cloud.google.com/go/compute/metadata" "golang.org/x/oauth2" "golang.org/x/oauth2/google" cd "google.golang.org/api/clouddebugger/v2" ) var ( appModule = flag.String("appmodule", "", "Optional application module name.") appVersion = flag.String("appversion", "", "Optional application module version name.") sourceContextFile = flag.String("sourcecontext", "", "File containing JSON-encoded source context.") verbose = flag.Bool("v", false, "Output verbose log messages.") projectNumber = flag.String("projectnumber", "", "Project number."+ " If this is not set, it is read from the GCP metadata server.") projectID = flag.String("projectid", "", "Project ID."+ " If this is not set, it is read from the GCP metadata server.") serviceAccountFile = flag.String("serviceaccountfile", "", "File containing JSON service account credentials.") ) const ( maxCapturedStackFrames = 50 maxCapturedVariables = 1000 ) func main() { flag.Usage = usage flag.Parse() args := flag.Args() if len(args) == 0 { // The user needs to supply the name of the executable to run. flag.Usage() return } if *projectNumber == "" { var err error *projectNumber, err = metadata.NumericProjectID() if err != nil { log.Print("Debuglet initialization: ", err) } } if *projectID == "" { var err error *projectID, err = metadata.ProjectID() if err != nil { log.Print("Debuglet initialization: ", err) } } sourceContexts, err := readSourceContextFile(*sourceContextFile) if err != nil { log.Print("Reading source context file: ", err) } var ts oauth2.TokenSource ctx := context.Background() if *serviceAccountFile != "" { if ts, err = serviceAcctTokenSource(ctx, *serviceAccountFile, cd.CloudDebuggerScope); err != nil { log.Fatalf("Error getting credentials from file %s: %v", *serviceAccountFile, err) } } else if ts, err = google.DefaultTokenSource(ctx, cd.CloudDebuggerScope); err != nil { log.Print("Error getting application default credentials for Cloud Debugger:", err) os.Exit(103) } c, err := debuglet.NewController(ctx, debuglet.Options{ ProjectNumber: *projectNumber, ProjectID: *projectID, AppModule: *appModule, AppVersion: *appVersion, SourceContexts: sourceContexts, Verbose: *verbose, TokenSource: ts, }) if err != nil { log.Fatal("Error connecting to Cloud Debugger: ", err) } prog, err := local.New(args[0]) if err != nil { log.Fatal("Error loading program: ", err) } // Load the program, but don't actually start it running yet. if _, err = prog.Run(args[1:]...); err != nil { log.Fatal("Error loading program: ", err) } bs := breakpoints.NewBreakpointStore(prog) // Seed the random number generator. rand.Seed(time.Now().UnixNano()) // Now we want to do two things: run the user's program, and start sending // List requests periodically to the Debuglet Controller to get breakpoints // to set. // // We want to give the Debuglet Controller a chance to give us breakpoints // before we start the program, otherwise we would miss any breakpoint // triggers that occur during program startup -- for example, a breakpoint on // the first line of main. But if the Debuglet Controller is not responding or // is returning errors, we don't want to delay starting the program // indefinitely. // // We pass a channel to breakpointListLoop, which will close it when the first // List call finishes. Then we wait until either the channel is closed or a // 5-second timer has finished before starting the program. ch := make(chan bool) // Start a goroutine that sends List requests to the Debuglet Controller, and // sets any breakpoints it gets back. go breakpointListLoop(ctx, c, bs, ch) // Wait until 5 seconds have passed or breakpointListLoop has closed ch. select { case <-time.After(5 * time.Second): case <-ch: } // Run the debuggee. programLoop(ctx, c, bs, prog) } // usage prints a usage message to stderr and exits. func usage() { me := "a.out" if len(os.Args) >= 1 { me = os.Args[0] } fmt.Fprintf(os.Stderr, "Usage of %s:\n", me) fmt.Fprintf(os.Stderr, "\t%s [flags...] -- args...\n", me) fmt.Fprintf(os.Stderr, "Flags:\n") flag.PrintDefaults() fmt.Fprintf(os.Stderr, "See https://cloud.google.com/tools/cloud-debugger/setting-up-on-compute-engine for more information.\n") os.Exit(2) } // readSourceContextFile reads a JSON-encoded source context from the given file. // It returns a non-empty slice on success. func readSourceContextFile(filename string) ([]*cd.SourceContext, error) { if filename == "" { return nil, nil } scJSON, err := ioutil.ReadFile(filename) if err != nil { return nil, fmt.Errorf("reading file %q: %v", filename, err) } var sc cd.SourceContext if err = json.Unmarshal(scJSON, &sc); err != nil { return nil, fmt.Errorf("parsing file %q: %v", filename, err) } return []*cd.SourceContext{&sc}, nil } // breakpointListLoop repeatedly calls the Debuglet Controller's List RPC, and // passes the results to the BreakpointStore so it can set and unset breakpoints // in the program. // // After the first List call finishes, ch is closed. func breakpointListLoop(ctx context.Context, c *debuglet.Controller, bs *breakpoints.BreakpointStore, first chan bool) { const ( avgTimeBetweenCalls = time.Second errorDelay = 5 * time.Second ) // randomDuration returns a random duration with expected value avg. randomDuration := func(avg time.Duration) time.Duration { return time.Duration(rand.Int63n(int64(2*avg + 1))) } var consecutiveFailures uint for { callStart := time.Now() resp, err := c.List(ctx) if err != nil && err != debuglet.ErrListUnchanged { log.Printf("Debuglet controller server error: %v", err) } if err == nil { bs.ProcessBreakpointList(resp.Breakpoints) } if first != nil { // We've finished one call to List and set any breakpoints we received. close(first) first = nil } // Asynchronously send updates for any breakpoints that caused an error when // the BreakpointStore tried to process them. We don't wait for the update // to finish before the program can exit, as we do for normal updates. errorBps := bs.ErrorBreakpoints() for _, bp := range errorBps { go func(bp *cd.Breakpoint) { if err := c.Update(ctx, bp.Id, bp); err != nil { log.Printf("Failed to send breakpoint update for %s: %s", bp.Id, err) } }(bp) } // Make the next call not too soon after the one we just did. delay := randomDuration(avgTimeBetweenCalls) // If the call returned an error other than ErrListUnchanged, wait longer. if err != nil && err != debuglet.ErrListUnchanged { // Wait twice as long after each consecutive failure, to a maximum of 16x. delay += randomDuration(errorDelay * (1 << consecutiveFailures)) if consecutiveFailures < 4 { consecutiveFailures++ } } else { consecutiveFailures = 0 } // Sleep until we reach time callStart+delay. If we've already passed that // time, time.Sleep will return immediately -- this should be the common // case, since the server will delay responding to List for a while when // there are no changes to report. time.Sleep(callStart.Add(delay).Sub(time.Now())) } } // programLoop runs the program being debugged to completion. When a breakpoint's // conditions are satisfied, it sends an Update RPC to the Debuglet Controller. // The function returns when the program exits and all Update RPCs have finished. func programLoop(ctx context.Context, c *debuglet.Controller, bs *breakpoints.BreakpointStore, prog debug.Program) { var wg sync.WaitGroup for { // Run the program until it hits a breakpoint or exits. status, err := prog.Resume() if err != nil { break } // Get the breakpoints at this address whose conditions were satisfied, // and remove the ones that aren't logpoints. bps := bs.BreakpointsAtPC(status.PC) bps = bpsWithConditionSatisfied(bps, prog) for _, bp := range bps { if bp.Action != "LOG" { bs.RemoveBreakpoint(bp) } } if len(bps) == 0 { continue } // Evaluate expressions and get the stack. vc := valuecollector.NewCollector(prog, maxCapturedVariables) needStackFrames := false for _, bp := range bps { // If evaluating bp's condition didn't return an error, evaluate bp's // expressions, and later get the stack frames. if bp.Status == nil { bp.EvaluatedExpressions = expressionValues(bp.Expressions, prog, vc) needStackFrames = true } } var ( stack []*cd.StackFrame stackFramesStatusMessage *cd.StatusMessage ) if needStackFrames { stack, stackFramesStatusMessage = stackFrames(prog, vc) } // Read variable values from the program. variableTable := vc.ReadValues() // Start a goroutine to send updates to the Debuglet Controller or write // to logs, concurrently with resuming the program. // TODO: retry Update on failure. for _, bp := range bps { wg.Add(1) switch bp.Action { case "LOG": go func(format string, evaluatedExpressions []*cd.Variable) { s := valuecollector.LogString(format, evaluatedExpressions, variableTable) log.Print(s) wg.Done() }(bp.LogMessageFormat, bp.EvaluatedExpressions) bp.Status = nil bp.EvaluatedExpressions = nil default: go func(bp *cd.Breakpoint) { defer wg.Done() bp.IsFinalState = true if bp.Status == nil { // If evaluating bp's condition didn't return an error, include the // stack frames, variable table, and any status message produced when // getting the stack frames. bp.StackFrames = stack bp.VariableTable = variableTable bp.Status = stackFramesStatusMessage } if err := c.Update(ctx, bp.Id, bp); err != nil { log.Printf("Failed to send breakpoint update for %s: %s", bp.Id, err) } }(bp) } } } // Wait for all updates to finish before returning. wg.Wait() } // bpsWithConditionSatisfied returns the breakpoints whose conditions are true // (or that do not have a condition.) func bpsWithConditionSatisfied(bpsIn []*cd.Breakpoint, prog debug.Program) []*cd.Breakpoint { var bpsOut []*cd.Breakpoint for _, bp := range bpsIn { cond, err := condTruth(bp.Condition, prog) if err != nil { bp.Status = errorStatusMessage(err.Error(), refersToBreakpointCondition) // Include bp in the list to be updated when there's an error, so that // the user gets a response. bpsOut = append(bpsOut, bp) } else if cond { bpsOut = append(bpsOut, bp) } } return bpsOut } // condTruth evaluates a condition. func condTruth(condition string, prog debug.Program) (bool, error) { if condition == "" { // A condition wasn't set. return true, nil } val, err := prog.Evaluate(condition) if err != nil { return false, err } if v, ok := val.(bool); !ok { return false, fmt.Errorf("condition expression has type %T, should be bool", val) } else { return v, nil } } // expressionValues evaluates a slice of expressions and returns a []*cd.Variable // containing the results. // If the result of an expression evaluation refers to values from the program's // memory (e.g., the expression evaluates to a slice) a corresponding variable is // added to the value collector, to be read later. func expressionValues(expressions []string, prog debug.Program, vc *valuecollector.Collector) []*cd.Variable { evaluatedExpressions := make([]*cd.Variable, len(expressions)) for i, exp := range expressions { ee := &cd.Variable{Name: exp} evaluatedExpressions[i] = ee if val, err := prog.Evaluate(exp); err != nil { ee.Status = errorStatusMessage(err.Error(), refersToBreakpointExpression) } else { vc.FillValue(val, ee) } } return evaluatedExpressions } // stackFrames returns a stack trace for the program. It passes references to // function parameters and local variables to the value collector, so it can read // their values later. func stackFrames(prog debug.Program, vc *valuecollector.Collector) ([]*cd.StackFrame, *cd.StatusMessage) { frames, err := prog.Frames(maxCapturedStackFrames) if err != nil { return nil, errorStatusMessage("Error getting stack: "+err.Error(), refersToUnspecified) } stackFrames := make([]*cd.StackFrame, len(frames)) for i, f := range frames { frame := &cd.StackFrame{} frame.Function = f.Function for _, v := range f.Params { frame.Arguments = append(frame.Arguments, vc.AddVariable(debug.LocalVar(v))) } for _, v := range f.Vars { frame.Locals = append(frame.Locals, vc.AddVariable(v)) } frame.Location = &cd.SourceLocation{ Path: f.File, Line: int64(f.Line), } stackFrames[i] = frame } return stackFrames, nil } // errorStatusMessage returns a *cd.StatusMessage indicating an error, // with the given message and refersTo field. func errorStatusMessage(msg string, refersTo int) *cd.StatusMessage { return &cd.StatusMessage{ Description: &cd.FormatMessage{Format: "$0", Parameters: []string{msg}}, IsError: true, RefersTo: refersToString[refersTo], } } const ( // RefersTo values for cd.StatusMessage. refersToUnspecified = iota refersToBreakpointCondition refersToBreakpointExpression ) // refersToString contains the strings for each refersTo value. // See the definition of StatusMessage in the v2/clouddebugger package. var refersToString = map[int]string{ refersToUnspecified: "UNSPECIFIED", refersToBreakpointCondition: "BREAKPOINT_CONDITION", refersToBreakpointExpression: "BREAKPOINT_EXPRESSION", } func serviceAcctTokenSource(ctx context.Context, filename string, scope ...string) (oauth2.TokenSource, error) { data, err := ioutil.ReadFile(filename) if err != nil { return nil, fmt.Errorf("cannot read service account file: %v", err) } cfg, err := google.JWTConfigFromJSON(data, scope...) if err != nil { return nil, fmt.Errorf("google.JWTConfigFromJSON: %v", err) } return cfg.TokenSource(ctx), nil } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/000077500000000000000000000000001356504100700230405ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/breakpoints/000077500000000000000000000000001356504100700253615ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/breakpoints/breakpoints.go000066400000000000000000000144121356504100700302330ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package breakpoints handles breakpoint requests we get from the user through // the Debuglet Controller, and manages corresponding breakpoints set in the code. package breakpoints import ( "log" "sync" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug" cd "google.golang.org/api/clouddebugger/v2" ) // BreakpointStore stores the set of breakpoints for a program. type BreakpointStore struct { mu sync.Mutex // prog is the program being debugged. prog debug.Program // idToBreakpoint is a map from breakpoint identifier to *cd.Breakpoint. The // map value is nil if the breakpoint is inactive. A breakpoint is active if: // - We received it from the Debuglet Controller, and it was active at the time; // - We were able to set code breakpoints for it; // - We have not reached any of those code breakpoints while satisfying the // breakpoint's conditions, or the breakpoint has action LOG; and // - The Debuglet Controller hasn't informed us the breakpoint has become inactive. idToBreakpoint map[string]*cd.Breakpoint // pcToBps and bpToPCs store the many-to-many relationship between breakpoints we // received from the Debuglet Controller and the code breakpoints we set for them. pcToBps map[uint64][]*cd.Breakpoint bpToPCs map[*cd.Breakpoint][]uint64 // errors contains any breakpoints which couldn't be set because they caused an // error. These are retrieved with ErrorBreakpoints, and the caller is // expected to handle sending updates for them. errors []*cd.Breakpoint } // NewBreakpointStore returns a BreakpointStore for the given program. func NewBreakpointStore(prog debug.Program) *BreakpointStore { return &BreakpointStore{ idToBreakpoint: make(map[string]*cd.Breakpoint), pcToBps: make(map[uint64][]*cd.Breakpoint), bpToPCs: make(map[*cd.Breakpoint][]uint64), prog: prog, } } // ProcessBreakpointList applies updates received from the Debuglet Controller through a List call. func (bs *BreakpointStore) ProcessBreakpointList(bps []*cd.Breakpoint) { bs.mu.Lock() defer bs.mu.Unlock() for _, bp := range bps { if storedBp, ok := bs.idToBreakpoint[bp.Id]; ok { if storedBp != nil && bp.IsFinalState { // IsFinalState indicates that the breakpoint has been made inactive. bs.removeBreakpointLocked(storedBp) } } else { if bp.IsFinalState { // The controller is notifying us that the breakpoint is no longer active, // but we didn't know about it anyway. continue } if bp.Action != "" && bp.Action != "CAPTURE" && bp.Action != "LOG" { bp.IsFinalState = true bp.Status = &cd.StatusMessage{ Description: &cd.FormatMessage{Format: "Action is not supported"}, IsError: true, } bs.errors = append(bs.errors, bp) // Note in idToBreakpoint that we've already seen this breakpoint, so that we // don't try to report it as an error multiple times. bs.idToBreakpoint[bp.Id] = nil continue } pcs, err := bs.prog.BreakpointAtLine(bp.Location.Path, uint64(bp.Location.Line)) if err != nil { log.Printf("error setting breakpoint at %s:%d: %v", bp.Location.Path, bp.Location.Line, err) } if len(pcs) == 0 { // We can't find a PC for this breakpoint's source line, so don't make it active. // TODO: we could snap the line to a location where we can break, or report an error to the user. bs.idToBreakpoint[bp.Id] = nil } else { bs.idToBreakpoint[bp.Id] = bp for _, pc := range pcs { bs.pcToBps[pc] = append(bs.pcToBps[pc], bp) } bs.bpToPCs[bp] = pcs } } } } // ErrorBreakpoints returns a slice of Breakpoints that caused errors when the // BreakpointStore tried to process them, and resets the list of such // breakpoints. // The caller is expected to send updates to the server to indicate the errors. func (bs *BreakpointStore) ErrorBreakpoints() []*cd.Breakpoint { bs.mu.Lock() defer bs.mu.Unlock() bps := bs.errors bs.errors = nil return bps } // BreakpointsAtPC returns all the breakpoints for which we set a code // breakpoint at the given address. func (bs *BreakpointStore) BreakpointsAtPC(pc uint64) []*cd.Breakpoint { bs.mu.Lock() defer bs.mu.Unlock() return bs.pcToBps[pc] } // RemoveBreakpoint makes the given breakpoint inactive. // This is called when either the debugged program hits the breakpoint, or the Debuglet // Controller informs us that the breakpoint is now inactive. func (bs *BreakpointStore) RemoveBreakpoint(bp *cd.Breakpoint) { bs.mu.Lock() bs.removeBreakpointLocked(bp) bs.mu.Unlock() } func (bs *BreakpointStore) removeBreakpointLocked(bp *cd.Breakpoint) { // Set the ID's corresponding breakpoint to nil, so that we won't activate it // if we see it again. // TODO: we could delete it after a few seconds. bs.idToBreakpoint[bp.Id] = nil // Delete bp from the list of cd breakpoints at each of its corresponding // code breakpoint locations, and delete any code breakpoints which no longer // have a corresponding cd breakpoint. var codeBreakpointsToDelete []uint64 for _, pc := range bs.bpToPCs[bp] { bps := remove(bs.pcToBps[pc], bp) if len(bps) == 0 { // bp was the last breakpoint set at this PC, so delete the code breakpoint. codeBreakpointsToDelete = append(codeBreakpointsToDelete, pc) delete(bs.pcToBps, pc) } else { bs.pcToBps[pc] = bps } } if len(codeBreakpointsToDelete) > 0 { bs.prog.DeleteBreakpoints(codeBreakpointsToDelete) } delete(bs.bpToPCs, bp) } // remove updates rs by removing r, then returns rs. // The mutex in the BreakpointStore which contains rs should be held. func remove(rs []*cd.Breakpoint, r *cd.Breakpoint) []*cd.Breakpoint { for i := range rs { if rs[i] == r { rs[i] = rs[len(rs)-1] rs = rs[0 : len(rs)-1] return rs } } // We shouldn't reach here. return rs } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/breakpoints/breakpoints_test.go000066400000000000000000000117431356504100700312760ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package breakpoints import ( "testing" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug" "cloud.google.com/go/internal/testutil" cd "google.golang.org/api/clouddebugger/v2" ) var ( testPC1 uint64 = 0x1234 testPC2 uint64 = 0x5678 testPC3 uint64 = 0x3333 testFile = "foo.go" testLine uint64 = 42 testLine2 uint64 = 99 testLogPC uint64 = 0x9abc testLogLine uint64 = 43 testBadPC uint64 = 0xdef0 testBadLine uint64 = 44 testBP = &cd.Breakpoint{ Action: "CAPTURE", Id: "TestBreakpoint", IsFinalState: false, Location: &cd.SourceLocation{Path: testFile, Line: int64(testLine)}, } testBP2 = &cd.Breakpoint{ Action: "CAPTURE", Id: "TestBreakpoint2", IsFinalState: false, Location: &cd.SourceLocation{Path: testFile, Line: int64(testLine2)}, } testLogBP = &cd.Breakpoint{ Action: "LOG", Id: "TestLogBreakpoint", IsFinalState: false, Location: &cd.SourceLocation{Path: testFile, Line: int64(testLogLine)}, } testBadBP = &cd.Breakpoint{ Action: "BEEP", Id: "TestBadBreakpoint", IsFinalState: false, Location: &cd.SourceLocation{Path: testFile, Line: int64(testBadLine)}, } ) func TestBreakpointStore(t *testing.T) { p := &Program{breakpointPCs: make(map[uint64]bool)} bs := NewBreakpointStore(p) checkPCs := func(expected map[uint64]bool) { if !testutil.Equal(p.breakpointPCs, expected) { t.Errorf("got breakpoint map %v want %v", p.breakpointPCs, expected) } } bs.ProcessBreakpointList([]*cd.Breakpoint{testBP, testBP2, testLogBP, testBadBP}) checkPCs(map[uint64]bool{ testPC1: true, testPC2: true, testPC3: true, testLogPC: true, }) for _, test := range []struct { pc uint64 expected []*cd.Breakpoint }{ {testPC1, []*cd.Breakpoint{testBP}}, {testPC2, []*cd.Breakpoint{testBP}}, {testPC3, []*cd.Breakpoint{testBP2}}, {testLogPC, []*cd.Breakpoint{testLogBP}}, } { if bps := bs.BreakpointsAtPC(test.pc); !testutil.Equal(bps, test.expected) { t.Errorf("BreakpointsAtPC(%x): got %v want %v", test.pc, bps, test.expected) } } testBP2.IsFinalState = true bs.ProcessBreakpointList([]*cd.Breakpoint{testBP, testBP2, testLogBP, testBadBP}) checkPCs(map[uint64]bool{ testPC1: true, testPC2: true, testPC3: false, testLogPC: true, }) bs.RemoveBreakpoint(testBP) checkPCs(map[uint64]bool{ testPC1: false, testPC2: false, testPC3: false, testLogPC: true, }) for _, pc := range []uint64{testPC1, testPC2, testPC3} { if bps := bs.BreakpointsAtPC(pc); len(bps) != 0 { t.Errorf("BreakpointsAtPC(%x): got %v want []", pc, bps) } } // bs.ErrorBreakpoints should return testBadBP. errorBps := bs.ErrorBreakpoints() if len(errorBps) != 1 { t.Errorf("ErrorBreakpoints: got %d want 1", len(errorBps)) } else { bp := errorBps[0] if bp.Id != testBadBP.Id { t.Errorf("ErrorBreakpoints: got id %q want 1", bp.Id) } if bp.Status == nil || !bp.Status.IsError { t.Errorf("ErrorBreakpoints: got %v, want error", bp.Status) } } // The error should have been removed by the last call to bs.ErrorBreakpoints. errorBps = bs.ErrorBreakpoints() if len(errorBps) != 0 { t.Errorf("ErrorBreakpoints: got %d want 0", len(errorBps)) } // Even if testBadBP is sent in a new list, it should not be returned again. bs.ProcessBreakpointList([]*cd.Breakpoint{testBadBP}) errorBps = bs.ErrorBreakpoints() if len(errorBps) != 0 { t.Errorf("ErrorBreakpoints: got %d want 0", len(errorBps)) } } // Program implements the similarly-named interface in x/debug. // ValueCollector should only call its BreakpointAtLine and DeleteBreakpoints methods. type Program struct { debug.Program // breakpointPCs contains the state of code breakpoints -- true if the // breakpoint is currently set, false if it has been deleted. breakpointPCs map[uint64]bool } func (p *Program) BreakpointAtLine(file string, line uint64) ([]uint64, error) { var pcs []uint64 switch { case file == testFile && line == testLine: pcs = []uint64{testPC1, testPC2} case file == testFile && line == testLine2: pcs = []uint64{testPC3} case file == testFile && line == testLogLine: pcs = []uint64{testLogPC} default: pcs = []uint64{0xbad} } for _, pc := range pcs { p.breakpointPCs[pc] = true } return pcs, nil } func (p *Program) DeleteBreakpoints(pcs []uint64) error { for _, pc := range pcs { p.breakpointPCs[pc] = false } return nil } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/controller/000077500000000000000000000000001356504100700252235ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/controller/client.go000066400000000000000000000230731356504100700270350ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package controller is a library for interacting with the Google Cloud Debugger's Debuglet Controller service. package controller import ( "context" "crypto/sha256" "encoding/json" "errors" "fmt" "log" "sync" "golang.org/x/oauth2" cd "google.golang.org/api/clouddebugger/v2" "google.golang.org/api/googleapi" "google.golang.org/api/option" htransport "google.golang.org/api/transport/http" ) const ( // agentVersionString identifies the agent to the service. agentVersionString = "google.com/go-gcp/v0.2" // initWaitToken is the wait token sent in the first Update request to a server. initWaitToken = "init" ) var ( // ErrListUnchanged is returned by List if the server time limit is reached // before the list of breakpoints changes. ErrListUnchanged = errors.New("breakpoint list unchanged") // ErrDebuggeeDisabled is returned by List or Update if the server has disabled // this Debuggee. The caller can retry later. ErrDebuggeeDisabled = errors.New("debuglet disabled by server") ) // Controller manages a connection to the Debuglet Controller service. type Controller struct { s serviceInterface // waitToken is sent with List requests so the server knows which set of // breakpoints this client has already seen. Each successful List request // returns a new waitToken to send in the next request. waitToken string // verbose determines whether to do some logging verbose bool // options, uniquifier and description are used in register. options Options uniquifier string description string // labels are included when registering the debuggee. They should contain // the module name, version and minorversion, and are used by the debug UI // to label the correct version active for debugging. labels map[string]string // mu protects debuggeeID mu sync.Mutex // debuggeeID is returned from the server on registration, and is passed back // to the server in List and Update requests. debuggeeID string } // Options controls how the Debuglet Controller client identifies itself to the server. // See https://cloud.google.com/storage/docs/projects and // https://cloud.google.com/tools/cloud-debugger/setting-up-on-compute-engine // for further documentation of these parameters. type Options struct { ProjectNumber string // GCP Project Number. ProjectID string // GCP Project ID. AppModule string // Module name for the debugged program. AppVersion string // Version number for this module. SourceContexts []*cd.SourceContext // Description of source. Verbose bool TokenSource oauth2.TokenSource // Source of Credentials used for Stackdriver Debugger. } type serviceInterface interface { Register(ctx context.Context, req *cd.RegisterDebuggeeRequest) (*cd.RegisterDebuggeeResponse, error) Update(ctx context.Context, debuggeeID, breakpointID string, req *cd.UpdateActiveBreakpointRequest) (*cd.UpdateActiveBreakpointResponse, error) List(ctx context.Context, debuggeeID, waitToken string) (*cd.ListActiveBreakpointsResponse, error) } var newService = func(ctx context.Context, tokenSource oauth2.TokenSource) (serviceInterface, error) { httpClient, endpoint, err := htransport.NewClient(ctx, option.WithTokenSource(tokenSource)) if err != nil { return nil, err } s, err := cd.New(httpClient) if err != nil { return nil, err } if endpoint != "" { s.BasePath = endpoint } return &service{s: s}, nil } type service struct { s *cd.Service } func (s service) Register(ctx context.Context, req *cd.RegisterDebuggeeRequest) (*cd.RegisterDebuggeeResponse, error) { call := cd.NewControllerDebuggeesService(s.s).Register(req) return call.Context(ctx).Do() } func (s service) Update(ctx context.Context, debuggeeID, breakpointID string, req *cd.UpdateActiveBreakpointRequest) (*cd.UpdateActiveBreakpointResponse, error) { call := cd.NewControllerDebuggeesBreakpointsService(s.s).Update(debuggeeID, breakpointID, req) return call.Context(ctx).Do() } func (s service) List(ctx context.Context, debuggeeID, waitToken string) (*cd.ListActiveBreakpointsResponse, error) { call := cd.NewControllerDebuggeesBreakpointsService(s.s).List(debuggeeID) call.WaitToken(waitToken) return call.Context(ctx).Do() } // NewController connects to the Debuglet Controller server using the given options, // and returns a Controller for that connection. // Google Application Default Credentials are used to connect to the Debuglet Controller; // see https://developers.google.com/identity/protocols/application-default-credentials func NewController(ctx context.Context, o Options) (*Controller, error) { // We build a JSON encoding of o.SourceContexts so we can hash it. scJSON, err := json.Marshal(o.SourceContexts) if err != nil { scJSON = nil o.SourceContexts = nil } const minorversion = "107157" // any arbitrary numeric string // Compute a uniquifier string by hashing the project number, app module name, // app module version, debuglet version, and source context. // The choice of hash function is arbitrary. h := sha256.Sum256([]byte(fmt.Sprintf("%d %s %d %s %d %s %d %s %d %s %d %s", len(o.ProjectNumber), o.ProjectNumber, len(o.AppModule), o.AppModule, len(o.AppVersion), o.AppVersion, len(agentVersionString), agentVersionString, len(scJSON), scJSON, len(minorversion), minorversion))) uniquifier := fmt.Sprintf("%X", h[0:16]) // 32 hex characters description := o.ProjectID if o.AppModule != "" { description += "-" + o.AppModule } if o.AppVersion != "" { description += "-" + o.AppVersion } s, err := newService(ctx, o.TokenSource) if err != nil { return nil, err } // Construct client. c := &Controller{ s: s, waitToken: initWaitToken, verbose: o.Verbose, options: o, uniquifier: uniquifier, description: description, labels: map[string]string{ "module": o.AppModule, "version": o.AppVersion, "minorversion": minorversion, }, } return c, nil } func (c *Controller) getDebuggeeID(ctx context.Context) (string, error) { c.mu.Lock() defer c.mu.Unlock() if c.debuggeeID != "" { return c.debuggeeID, nil } // The debuglet hasn't been registered yet, or it is disabled and we should try registering again. if err := c.register(ctx); err != nil { return "", err } return c.debuggeeID, nil } // List retrieves the current list of breakpoints from the server. // If the set of breakpoints on the server is the same as the one returned in // the previous call to List, the server can delay responding until it changes, // and return an error instead if no change occurs before a time limit the // server sets. List can't be called concurrently with itself. func (c *Controller) List(ctx context.Context) (*cd.ListActiveBreakpointsResponse, error) { id, err := c.getDebuggeeID(ctx) if err != nil { return nil, err } resp, err := c.s.List(ctx, id, c.waitToken) if err != nil { if isAbortedError(err) { return nil, ErrListUnchanged } // For other errors, the protocol requires that we attempt to re-register. c.mu.Lock() defer c.mu.Unlock() if regError := c.register(ctx); regError != nil { return nil, regError } return nil, err } if resp == nil { return nil, errors.New("no response") } if c.verbose { log.Printf("List response: %v", resp) } c.waitToken = resp.NextWaitToken return resp, nil } // isAbortedError tests if err is a *googleapi.Error, that it contains one error // in Errors, and that that error's Reason is "aborted". func isAbortedError(err error) bool { e, _ := err.(*googleapi.Error) if e == nil { return false } if len(e.Errors) != 1 { return false } return e.Errors[0].Reason == "aborted" } // Update reports information to the server about a breakpoint that was hit. // Update can be called concurrently with List and Update. func (c *Controller) Update(ctx context.Context, breakpointID string, bp *cd.Breakpoint) error { req := &cd.UpdateActiveBreakpointRequest{Breakpoint: bp} if c.verbose { log.Printf("sending update for %s: %v", breakpointID, req) } id, err := c.getDebuggeeID(ctx) if err != nil { return err } _, err = c.s.Update(ctx, id, breakpointID, req) return err } // register calls the Debuglet Controller Register method, and sets c.debuggeeID. // c.mu should be locked while calling this function. List and Update can't // make progress until it returns. func (c *Controller) register(ctx context.Context) error { req := cd.RegisterDebuggeeRequest{ Debuggee: &cd.Debuggee{ AgentVersion: agentVersionString, Description: c.description, Project: c.options.ProjectNumber, SourceContexts: c.options.SourceContexts, Uniquifier: c.uniquifier, Labels: c.labels, }, } resp, err := c.s.Register(ctx, &req) if err != nil { return err } if resp == nil { return errors.New("register: no response") } if resp.Debuggee.IsDisabled { // Setting c.debuggeeID to empty makes sure future List and Update calls // will call register first. c.debuggeeID = "" } else { c.debuggeeID = resp.Debuggee.Id } if c.debuggeeID == "" { return ErrDebuggeeDisabled } return nil } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/controller/client_test.go000066400000000000000000000154141356504100700300740ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package controller import ( "bytes" "context" "errors" "fmt" "strconv" "testing" "golang.org/x/oauth2" cd "google.golang.org/api/clouddebugger/v2" "google.golang.org/api/googleapi" ) const ( testDebuggeeID = "d12345" testBreakpointID = "bp12345" ) var ( // The sequence of wait tokens in List requests and responses. expectedWaitToken = []string{"init", "token1", "token2", "token1", "token1"} // The set of breakpoints returned from each List call. expectedBreakpoints = [][]*cd.Breakpoint{ nil, { &cd.Breakpoint{ Id: testBreakpointID, IsFinalState: false, Location: &cd.SourceLocation{Line: 42, Path: "foo.go"}, }, }, nil, } abortedError error = &googleapi.Error{ Code: 409, Message: "Conflict", Body: `{ "error": { "errors": [ { "domain": "global", "reason": "aborted", "message": "Conflict" } ], "code": 409, "message": "Conflict" } }`, Errors: []googleapi.ErrorItem{ {Reason: "aborted", Message: "Conflict"}, }, } backendError error = &googleapi.Error{ Code: 503, Message: "Backend Error", Body: `{ "error": { "errors": [ { "domain": "global", "reason": "backendError", "message": "Backend Error" } ], "code": 503, "message": "Backend Error" } }`, Errors: []googleapi.ErrorItem{ {Reason: "backendError", Message: "Backend Error"}, }, } ) type mockService struct { t *testing.T listCallsSeen int registerCallsSeen int } func (s *mockService) Register(ctx context.Context, req *cd.RegisterDebuggeeRequest) (*cd.RegisterDebuggeeResponse, error) { s.registerCallsSeen++ if req.Debuggee == nil { s.t.Errorf("missing debuggee") return nil, nil } if req.Debuggee.AgentVersion == "" { s.t.Errorf("missing agent version") } if req.Debuggee.Description == "" { s.t.Errorf("missing debuglet description") } if req.Debuggee.Project == "" { s.t.Errorf("missing project id") } if req.Debuggee.Uniquifier == "" { s.t.Errorf("missing uniquifier") } return &cd.RegisterDebuggeeResponse{ Debuggee: &cd.Debuggee{Id: testDebuggeeID}, }, nil } func (s *mockService) Update(ctx context.Context, id, breakpointID string, req *cd.UpdateActiveBreakpointRequest) (*cd.UpdateActiveBreakpointResponse, error) { if id != testDebuggeeID { s.t.Errorf("got debuggee ID %s want %s", id, testDebuggeeID) } if breakpointID != testBreakpointID { s.t.Errorf("got breakpoint ID %s want %s", breakpointID, testBreakpointID) } if !req.Breakpoint.IsFinalState { s.t.Errorf("got IsFinalState = false, want true") } return nil, nil } func (s *mockService) List(ctx context.Context, id, waitToken string) (*cd.ListActiveBreakpointsResponse, error) { if id != testDebuggeeID { s.t.Errorf("got debuggee ID %s want %s", id, testDebuggeeID) } if waitToken != expectedWaitToken[s.listCallsSeen] { s.t.Errorf("got wait token %s want %s", waitToken, expectedWaitToken[s.listCallsSeen]) } s.listCallsSeen++ if s.listCallsSeen == 4 { return nil, backendError } if s.listCallsSeen == 5 { return nil, abortedError } resp := &cd.ListActiveBreakpointsResponse{ Breakpoints: expectedBreakpoints[s.listCallsSeen-1], NextWaitToken: expectedWaitToken[s.listCallsSeen], } return resp, nil } func TestDebugletControllerClientLibrary(t *testing.T) { var ( m *mockService c *Controller list *cd.ListActiveBreakpointsResponse err error ) m = &mockService{t: t} newService = func(context.Context, oauth2.TokenSource) (serviceInterface, error) { return m, nil } opts := Options{ ProjectNumber: "5", ProjectID: "p1", AppModule: "mod1", AppVersion: "v1", } ctx := context.Background() if c, err = NewController(ctx, opts); err != nil { t.Fatal("Initializing Controller client:", err) } if err := validateLabels(c, opts); err != nil { t.Fatalf("Invalid labels:\n%v", err) } if list, err = c.List(ctx); err != nil { t.Fatal("List:", err) } if m.registerCallsSeen != 1 { t.Errorf("saw %d Register calls, want 1", m.registerCallsSeen) } if list, err = c.List(ctx); err != nil { t.Fatal("List:", err) } if len(list.Breakpoints) != 1 { t.Fatalf("got %d breakpoints, want 1", len(list.Breakpoints)) } if err = c.Update(ctx, list.Breakpoints[0].Id, &cd.Breakpoint{Id: testBreakpointID, IsFinalState: true}); err != nil { t.Fatal("Update:", err) } if list, err = c.List(ctx); err != nil { t.Fatal("List:", err) } if m.registerCallsSeen != 1 { t.Errorf("saw %d Register calls, want 1", m.registerCallsSeen) } // The next List call produces an error that should cause a Register call. if list, err = c.List(ctx); err == nil { t.Fatal("List should have returned an error") } if m.registerCallsSeen != 2 { t.Errorf("saw %d Register calls, want 2", m.registerCallsSeen) } // The next List call produces an error that should not cause a Register call. if list, err = c.List(ctx); err == nil { t.Fatal("List should have returned an error") } if m.registerCallsSeen != 2 { t.Errorf("saw %d Register calls, want 2", m.registerCallsSeen) } if m.listCallsSeen != 5 { t.Errorf("saw %d list calls, want 5", m.listCallsSeen) } } func validateLabels(c *Controller, o Options) error { errMsg := new(bytes.Buffer) if m, ok := c.labels["module"]; ok { if m != o.AppModule { errMsg.WriteString(fmt.Sprintf("label module: want %s, got %s\n", o.AppModule, m)) } } else { errMsg.WriteString("Missing \"module\" label\n") } if v, ok := c.labels["version"]; ok { if v != o.AppVersion { errMsg.WriteString(fmt.Sprintf("label version: want %s, got %s\n", o.AppVersion, v)) } } else { errMsg.WriteString("Missing \"version\" label\n") } if mv, ok := c.labels["minorversion"]; ok { if _, err := strconv.Atoi(mv); err != nil { errMsg.WriteString(fmt.Sprintln("label minorversion: not a numeric string:", mv)) } } else { errMsg.WriteString("Missing \"minorversion\" label\n") } if errMsg.Len() != 0 { return errors.New(errMsg.String()) } return nil } func TestIsAbortedError(t *testing.T) { if !isAbortedError(abortedError) { t.Errorf("isAborted(%+v): got false, want true", abortedError) } if isAbortedError(backendError) { t.Errorf("isAborted(%+v): got true, want false", backendError) } } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/000077500000000000000000000000001356504100700241265ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/arch/000077500000000000000000000000001356504100700250435ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/arch/arch.go000066400000000000000000000106511356504100700263120ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package arch contains architecture-specific definitions. package arch import ( "encoding/binary" "math" ) const MaxBreakpointSize = 4 // TODO // Architecture defines the architecture-specific details for a given machine. type Architecture struct { // BreakpointSize is the size of a breakpoint instruction, in bytes. BreakpointSize int // IntSize is the size of the int type, in bytes. IntSize int // PointerSize is the size of a pointer, in bytes. PointerSize int // ByteOrder is the byte order for ints and pointers. ByteOrder binary.ByteOrder // FloatByteOrder is the byte order for floats. FloatByteOrder binary.ByteOrder BreakpointInstr [MaxBreakpointSize]byte } func (a *Architecture) Int(buf []byte) int64 { return int64(a.Uint(buf)) } func (a *Architecture) Uint(buf []byte) uint64 { if len(buf) != a.IntSize { panic("bad IntSize") } switch a.IntSize { case 4: return uint64(a.ByteOrder.Uint32(buf[:4])) case 8: return a.ByteOrder.Uint64(buf[:8]) } panic("no IntSize") } func (a *Architecture) Int16(buf []byte) int16 { return int16(a.Uint16(buf)) } func (a *Architecture) Int32(buf []byte) int32 { return int32(a.Uint32(buf)) } func (a *Architecture) Int64(buf []byte) int64 { return int64(a.Uint64(buf)) } func (a *Architecture) Uint16(buf []byte) uint16 { return a.ByteOrder.Uint16(buf) } func (a *Architecture) Uint32(buf []byte) uint32 { return a.ByteOrder.Uint32(buf) } func (a *Architecture) Uint64(buf []byte) uint64 { return a.ByteOrder.Uint64(buf) } func (a *Architecture) IntN(buf []byte) int64 { if len(buf) == 0 { return 0 } x := int64(0) if a.ByteOrder == binary.LittleEndian { i := len(buf) - 1 x = int64(int8(buf[i])) // sign-extended for i--; i >= 0; i-- { x <<= 8 x |= int64(buf[i]) // not sign-extended } } else { x = int64(int8(buf[0])) // sign-extended for i := 1; i < len(buf); i++ { x <<= 8 x |= int64(buf[i]) // not sign-extended } } return x } func (a *Architecture) UintN(buf []byte) uint64 { u := uint64(0) if a.ByteOrder == binary.LittleEndian { shift := uint(0) for _, c := range buf { u |= uint64(c) << shift shift += 8 } } else { for _, c := range buf { u <<= 8 u |= uint64(c) } } return u } func (a *Architecture) Uintptr(buf []byte) uint64 { if len(buf) != a.PointerSize { panic("bad PointerSize") } switch a.PointerSize { case 4: return uint64(a.ByteOrder.Uint32(buf[:4])) case 8: return a.ByteOrder.Uint64(buf[:8]) } panic("no PointerSize") } func (a *Architecture) Float32(buf []byte) float32 { if len(buf) != 4 { panic("bad float32 size") } return math.Float32frombits(a.FloatByteOrder.Uint32(buf)) } func (a *Architecture) Float64(buf []byte) float64 { if len(buf) != 8 { panic("bad float64 size") } return math.Float64frombits(a.FloatByteOrder.Uint64(buf)) } func (a *Architecture) Complex64(buf []byte) complex64 { if len(buf) != 8 { panic("bad complex64 size") } return complex(a.Float32(buf[0:4]), a.Float32(buf[4:8])) } func (a *Architecture) Complex128(buf []byte) complex128 { if len(buf) != 16 { panic("bad complex128 size") } return complex(a.Float64(buf[0:8]), a.Float64(buf[8:16])) } var AMD64 = Architecture{ BreakpointSize: 1, IntSize: 8, PointerSize: 8, ByteOrder: binary.LittleEndian, FloatByteOrder: binary.LittleEndian, BreakpointInstr: [MaxBreakpointSize]byte{0xCC}, // INT 3 } var X86 = Architecture{ BreakpointSize: 1, IntSize: 4, PointerSize: 4, ByteOrder: binary.LittleEndian, FloatByteOrder: binary.LittleEndian, BreakpointInstr: [MaxBreakpointSize]byte{0xCC}, // INT 3 } var ARM = Architecture{ BreakpointSize: 4, // TODO IntSize: 4, PointerSize: 4, ByteOrder: binary.LittleEndian, FloatByteOrder: binary.LittleEndian, // TODO BreakpointInstr: [MaxBreakpointSize]byte{0x00, 0x00, 0x00, 0x00}, // TODO } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/cmd/000077500000000000000000000000001356504100700246715ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/cmd/debugproxy/000077500000000000000000000000001356504100700270615ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/cmd/debugproxy/main.go000066400000000000000000000035311356504100700303360ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // debugproxy connects to the target binary, and serves an RPC interface using // the types in server/protocol to access and control it. // +build linux package main import ( "flag" "fmt" "log" "net/rpc" "os" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/server" ) var ( textFlag = flag.String("text", "", "file name of binary being debugged") ) func main() { log.SetFlags(0) log.SetPrefix("debugproxy: ") flag.Parse() if *textFlag == "" { flag.Usage() os.Exit(2) } s, err := server.New(*textFlag) if err != nil { fmt.Printf("server.New: %v\n", err) os.Exit(2) } err = rpc.Register(s) if err != nil { fmt.Printf("rpc.Register: %v\n", err) os.Exit(2) } fmt.Println("OK") log.Print("starting server") rpc.ServeConn(&rwc{ os.Stdin, os.Stdout, }) log.Print("server finished") } // rwc creates a single io.ReadWriteCloser from a read side and a write side. // It allows us to do RPC using standard in and standard out. type rwc struct { r *os.File w *os.File } func (rwc *rwc) Read(p []byte) (int, error) { return rwc.r.Read(p) } func (rwc *rwc) Write(p []byte) (int, error) { return rwc.w.Write(p) } func (rwc *rwc) Close() error { rerr := rwc.r.Close() werr := rwc.w.Close() if rerr != nil { return rerr } return werr } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/doc/000077500000000000000000000000001356504100700246735ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/doc/ptrace-nptl.txt000066400000000000000000000140511356504100700276660ustar00rootroot00000000000000ptrace and NTPL, the missing manpage == Signals == A signal sent to a ptrace'd process or thread causes only the thread that receives it to stop and report to the attached process. Use tgkill to target a signal (for example, SIGSTOP) at a particular thread. If you use kill, the signal could be delivered to another thread in the same process. Note that SIGSTOP differs from its usual behavior when a process is being traced. Usually, a SIGSTOP sent to any thread in a thread group will stop all threads in the thread group. When a thread is traced, however, a SIGSTOP affects only the receiving thread (and any other threads in the thread group that are not traced). SIGKILL behaves like it does for non-traced processes. It affects all threads in the process and terminates them without the WSTOPSIG event generated by other signals. However, if PTRACE_O_TRACEEXIT is set, the attached process will still receive PTRACE_EVENT_EXIT events before receiving WIFSIGNALED events. See "Following thread death" for a caveat regarding signal delivery to zombie threads. == Waiting on threads == Cloned threads in ptrace'd processes are treated similarly to cloned threads in your own process. Thus, you must use the __WALL option in order to receive notifications from threads created by the child process. Similarly, the __WCLONE option will wait only on notifications from threads created by the child process and *not* on notifications from the initial child thread. Even when waiting on a specific thread's PID using waitpid or similar, __WALL or __WCLONE is necessary or waitpid will return ECHILD. == Attaching to existing threads == libthread_db (which gdb uses), attaches to existing threads by pulling the pthread data structures out of the traced process. The much easier way is to traverse the /proc/PID/task directory, though it's unclear how the semantics of these two approaches differ. Unfortunately, if the main thread has exited (but the overall process has not), it sticks around as a zombie process. This zombie will appear in the /proc/PID/task directory, but trying to attach to it will yield EPERM. In this case, the third field of the /proc/PID/task/PID/stat file will be "Z". Attempting to open the stat file is also a convenient way to detect races between listing the task directory and the thread exiting. Coincidentally, gdb will simply fail to attach to a process whose main thread is a zombie. Because new threads may be created while the debugger is in the process of attaching to existing threads, the debugger must repeatedly re-list the task directory until it has attached to (and thus stopped) every thread listed. In order to follow new threads created by existing threads, PTRACE_O_TRACECLONE must be set on each thread attached to. == Following new threads == With the child process stopped, use PTRACE_SETOPTIONS to set the PTRACE_O_TRACECLONE option. This option is per-thread, and thus must be set on each existing thread individually. When an existing thread with PTRACE_O_TRACECLONE set spawns a new thread, the existing thread will stop with (SIGTRAP | PTRACE_EVENT_CLONE << 8) and the PID of the new thread can be retrieved with PTRACE_GETEVENTMSG on the creating thread. At this time, the new thread will exist, but will initially be stopped with a SIGSTOP. The new thread will automatically be traced and will inherit the PTRACE_O_TRACECLONE option from its parent. The attached process should wait on the new thread to receive the SIGSTOP notification. When using waitpid(-1, ...), don't rely on the parent thread reporting a SIGTRAP before receiving the SIGSTOP from the new child thread. Without PTRACE_O_TRACECLONE, newly cloned threads will not be ptrace'd. As a result, signals received by new threads will be handled in the usual way, which may affect the parent and in turn appear to the attached process, but attributed to the parent (possibly in unexpected ways). == Following thread death == If any thread with the PTRACE_O_TRACEEXIT option set exits (either by returning or pthread_exit'ing), the tracing process will receive an immediate PTRACE_EVENT_EXIT. At this point, the thread will still exist. The exit status, encoded as for wait, can be queried using PTRACE_GETEVENTMSG on the exiting thread's PID. The thread should be continued so it can actually exit, after which its wait behavior is the same as for a thread without the PTRACE_O_TRACEEXIT option. If a non-main thread exits (either by returning or pthread_exit'ing), its corresponding process will also exit, producing a WIFEXITED event (after the process is continued from a possible PTRACE_EVENT_EXIT event). It is *not* necessary for another thread to ptrace_join for this to happen. If the main thread exits by returning, then all threads will exit, first generating a PTRACE_EVENT_EXIT event for each thread if appropriate, then producing a WIFEXITED event for each thread. If the main thread exits using pthread_exit, then it enters a non-waitable zombie state. It will still produce an immediate PTRACE_O_TRACEEXIT event, but the WIFEXITED event will be delayed until the entire process exits. This state exists so that shells don't think the process is done until all of the threads have exited. Unfortunately, signals cannot be delivered to non-waitable zombies. Most notably, SIGSTOP cannot be delivered; as a result, when you broadcast SIGSTOP to all of the threads, you must not wait for non-waitable zombies to stop. Furthermore, any ptrace command on a non-waitable zombie, including PTRACE_DETACH, will return ESRCH. == Multi-threaded debuggers == If the debugger itself is multi-threaded, ptrace calls must come from the same thread that originally attached to the remote thread. The kernel simply compares the PID of the caller of ptrace against the tracer PID of the process passed to ptrace. Because each debugger thread has a different PID, calling ptrace from a different thread might as well be calling it from a different process and the kernel will return ESRCH. wait, on the other hand, does not have this restriction. Any debugger thread can wait on any thread in the attached process. google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/dwarf/000077500000000000000000000000001356504100700252315ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/dwarf/buf.go000066400000000000000000000103301356504100700263310ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Buffered reading and decoding of DWARF data streams. package dwarf import ( "encoding/binary" "fmt" "strconv" ) // Data buffer being decoded. type buf struct { dwarf *Data order binary.ByteOrder format dataFormat name string off Offset data []byte err error } // Data format, other than byte order. This affects the handling of // certain field formats. type dataFormat interface { // DWARF version number. Zero means unknown. version() int // 64-bit DWARF format? dwarf64() (dwarf64 bool, isKnown bool) // Size of an address, in bytes. Zero means unknown. addrsize() int } // Some parts of DWARF have no data format, e.g., abbrevs. type unknownFormat struct{} func (u unknownFormat) version() int { return 0 } func (u unknownFormat) dwarf64() (bool, bool) { return false, false } func (u unknownFormat) addrsize() int { return 0 } func makeBuf(d *Data, format dataFormat, name string, off Offset, data []byte) buf { return buf{d, d.order, format, name, off, data, nil} } func (b *buf) slice(length int) buf { n := *b data := b.data b.skip(length) // Will validate length. n.data = data[:length] return n } func (b *buf) uint8() uint8 { if len(b.data) < 1 { b.error("underflow") return 0 } val := b.data[0] b.data = b.data[1:] b.off++ return val } func (b *buf) bytes(n int) []byte { if len(b.data) < n { b.error("underflow") return nil } data := b.data[0:n] b.data = b.data[n:] b.off += Offset(n) return data } func (b *buf) skip(n int) { b.bytes(n) } // string returns the NUL-terminated (C-like) string at the start of the buffer. // The terminal NUL is discarded. func (b *buf) string() string { for i := 0; i < len(b.data); i++ { if b.data[i] == 0 { s := string(b.data[0:i]) b.data = b.data[i+1:] b.off += Offset(i + 1) return s } } b.error("underflow") return "" } func (b *buf) uint16() uint16 { a := b.bytes(2) if a == nil { return 0 } return b.order.Uint16(a) } func (b *buf) uint32() uint32 { a := b.bytes(4) if a == nil { return 0 } return b.order.Uint32(a) } func (b *buf) uint64() uint64 { a := b.bytes(8) if a == nil { return 0 } return b.order.Uint64(a) } // Read a varint, which is 7 bits per byte, little endian. // the 0x80 bit means read another byte. func (b *buf) varint() (c uint64, bits uint) { for i := 0; i < len(b.data); i++ { byte := b.data[i] c |= uint64(byte&0x7F) << bits bits += 7 if byte&0x80 == 0 { b.off += Offset(i + 1) b.data = b.data[i+1:] return c, bits } } return 0, 0 } // Unsigned int is just a varint. func (b *buf) uint() uint64 { x, _ := b.varint() return x } // Signed int is a sign-extended varint. func (b *buf) int() int64 { ux, bits := b.varint() x := int64(ux) if x&(1<<(bits-1)) != 0 { x |= -1 << bits } return x } // Address-sized uint. func (b *buf) addr() uint64 { switch b.format.addrsize() { case 1: return uint64(b.uint8()) case 2: return uint64(b.uint16()) case 4: return uint64(b.uint32()) case 8: return uint64(b.uint64()) } b.error("unknown address size") return 0 } // assertEmpty checks that everything has been read from b. func (b *buf) assertEmpty() { if len(b.data) == 0 { return } if len(b.data) > 5 { b.error(fmt.Sprintf("unexpected extra data: %x...", b.data[0:5])) } b.error(fmt.Sprintf("unexpected extra data: %x", b.data)) } func (b *buf) error(s string) { if b.err == nil { b.data = nil b.err = DecodeError{b.name, b.off, s} } } type DecodeError struct { Name string Offset Offset Err string } func (e DecodeError) Error() string { return "decoding dwarf section " + e.Name + " at offset 0x" + strconv.FormatInt(int64(e.Offset), 16) + ": " + e.Err } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/dwarf/cache.go000066400000000000000000000177601356504100700266360ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package dwarf import ( "fmt" "sort" ) // pcToFuncEntries maps PC ranges to function entries. // // Each element contains a *Entry for a function and its corresponding start PC. // If we know the address one past the last instruction of a function, and it is // not equal to the start address of the next function, we mark that with // another element containing that address and a nil entry. The elements are // sorted by PC. Among elements with the same PC, those with non-nil *Entry // are put earlier. type pcToFuncEntries []pcToFuncEntry type pcToFuncEntry struct { pc uint64 entry *Entry } func (p pcToFuncEntries) Len() int { return len(p) } func (p pcToFuncEntries) Swap(i, j int) { p[i], p[j] = p[j], p[i] } func (p pcToFuncEntries) Less(i, j int) bool { if p[i].pc != p[j].pc { return p[i].pc < p[j].pc } return p[i].entry != nil && p[j].entry == nil } // nameCache maps each symbol name to a linked list of the entries with that name. type nameCache map[string]*nameCacheEntry type nameCacheEntry struct { entry *Entry link *nameCacheEntry } // pcToLineEntries maps PCs to line numbers. // // It is a slice of (PC, line, file number) triples, sorted by PC. The file // number is an index into the source files slice. // If (PC1, line1, file1) and (PC2, line2, file2) are two consecutive elements, // then the span of addresses [PC1, PC2) belongs to (line1, file1). If an // element's file number is zero, it only marks the end of a span. // // TODO: could save memory by changing pcToLineEntries and lineToPCEntries to use // interval trees containing references into .debug_line. type pcToLineEntries []pcToLineEntry type pcToLineEntry struct { pc uint64 line uint64 file uint64 } func (p pcToLineEntries) Len() int { return len(p) } func (p pcToLineEntries) Swap(i, j int) { p[i], p[j] = p[j], p[i] } func (p pcToLineEntries) Less(i, j int) bool { if p[i].pc != p[j].pc { return p[i].pc < p[j].pc } return p[i].file > p[j].file } // byFileLine is used temporarily while building lineToPCEntries. type byFileLine []pcToLineEntry func (b byFileLine) Len() int { return len(b) } func (b byFileLine) Swap(i, j int) { b[i], b[j] = b[j], b[i] } func (b byFileLine) Less(i, j int) bool { if b[i].file != b[j].file { return b[i].file < b[j].file } return b[i].line < b[j].line } // lineToPCEntries maps line numbers to breakpoint addresses. // // The slice contains, for each source file in Data, a slice of (line, PC) // pairs, sorted by line. Note that there may be more than one PC for a line. type lineToPCEntries [][]lineToPCEntry type lineToPCEntry struct { line uint64 pc uint64 } func (d *Data) buildLineToPCCache(pclfs pcToLineEntries) { // TODO: only include lines where is_stmt is true sort.Sort(byFileLine(pclfs)) // Make a slice of (line, PC) pairs for each (non-zero) file. var ( c = make(lineToPCEntries, len(d.sourceFiles)) curSlice []lineToPCEntry ) for i, pclf := range pclfs { if pclf.file == 0 { // This entry indicated the end of an instruction sequence, not a breakpoint. continue } curSlice = append(curSlice, lineToPCEntry{line: pclf.line, pc: pclf.pc}) if i+1 == len(pclfs) || pclf.file != pclfs[i+1].file { // curSlice now contains all of the entries for pclf.file. if pclf.file > 0 && pclf.file < uint64(len(c)) { c[pclf.file] = curSlice } curSlice = nil } } d.lineToPCEntries = c } func (d *Data) buildPCToLineCache(cache pcToLineEntries) { // Sort cache by PC (in increasing order), then by file number (in decreasing order). sort.Sort(cache) // Build a copy without redundant entries. var out pcToLineEntries for i, pclf := range cache { if i > 0 && pclf.pc == cache[i-1].pc { // This entry is for the same PC as the previous entry. continue } if i > 0 && pclf.file == cache[i-1].file && pclf.line == cache[i-1].line { // This entry is for the same file and line as the previous entry. continue } out = append(out, pclf) } d.pcToLineEntries = out } // buildLineCaches constructs d.sourceFiles, d.lineToPCEntries, d.pcToLineEntries. func (d *Data) buildLineCaches() error { var cache pcToLineEntries r := d.Reader() for { entry, err := r.Next() if err != nil { return err } if entry == nil { break } if entry.Tag != TagCompileUnit { r.SkipChildren() continue } // Get the offset of this unit's line number program in .debug_line. offset, ok := entry.Val(AttrStmtList).(int64) if !ok { return fmt.Errorf("AttrStmtList not present or not int64 for unit %d", r.unit) } buf := makeBuf(d, &d.unit[r.unit], "line", Offset(offset), d.line[offset:]) var m lineMachine if err := m.parseHeader(&buf); err != nil { return err } fileNumOffset := uint64(len(d.sourceFiles)) for _, f := range m.header.file { d.sourceFiles = append(d.sourceFiles, f.name) } fn := func(m *lineMachine) bool { if m.endSequence { cache = append(cache, pcToLineEntry{ pc: m.address, line: 0, file: 0, }) } else { // m.file is a 1-based index into the files of this line number program's // header. Translate it to a 0-based index into d.sourceFiles. fnum := fileNumOffset + m.file - 1 cache = append(cache, pcToLineEntry{ pc: m.address, line: m.line, file: fnum, }) } return true } if err := m.evalCompilationUnit(&buf, fn); err != nil { return err } } d.buildLineToPCCache(cache) d.buildPCToLineCache(cache) return nil } // buildInfoCaches initializes nameCache and pcToFuncEntries by walking the // top-level entries under each compile unit. It swallows any errors in parsing. func (d *Data) buildInfoCaches() { // TODO: record errors somewhere? d.nameCache = make(map[string]*nameCacheEntry) var pcToFuncEntries pcToFuncEntries r := d.Reader() loop: for { entry, err := r.Next() if entry == nil || err != nil { break loop } if entry.Tag != TagCompileUnit /* DW_TAG_compile_unit */ { r.SkipChildren() continue } for { entry, err := r.Next() if entry == nil || err != nil { break loop } if entry.Tag == 0 { // End of children of current compile unit. break } r.SkipChildren() // Update name-to-entry cache. if name, ok := entry.Val(AttrName).(string); ok { d.nameCache[name] = &nameCacheEntry{entry: entry, link: d.nameCache[name]} } // If this entry is a function, update PC-to-containing-function cache. if entry.Tag != TagSubprogram /* DW_TAG_subprogram */ { continue } // DW_AT_low_pc, if present, is the address of the first instruction of // the function. lowpc, ok := entry.Val(AttrLowpc).(uint64) if !ok { continue } pcToFuncEntries = append(pcToFuncEntries, pcToFuncEntry{lowpc, entry}) // DW_AT_high_pc, if present (TODO: and of class address) is the address // one past the last instruction of the function. highpc, ok := entry.Val(AttrHighpc).(uint64) if !ok { continue } pcToFuncEntries = append(pcToFuncEntries, pcToFuncEntry{highpc, nil}) } } // Sort elements by PC. If there are multiple elements with the same PC, // those with non-nil *Entry are placed earlier. sort.Sort(pcToFuncEntries) // Copy only the first element for each PC to out. n := 0 for i, ce := range pcToFuncEntries { if i == 0 || ce.pc != pcToFuncEntries[i-1].pc { n++ } } out := make([]pcToFuncEntry, 0, n) for i, ce := range pcToFuncEntries { if i == 0 || ce.pc != pcToFuncEntries[i-1].pc { out = append(out, ce) } } d.pcToFuncEntries = out } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/dwarf/const.go000066400000000000000000000357621356504100700267230ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Constants package dwarf import "strconv" // An Attr identifies the attribute type in a DWARF Entry's Field. type Attr uint32 const ( AttrSibling Attr = 0x01 AttrLocation Attr = 0x02 AttrName Attr = 0x03 AttrOrdering Attr = 0x09 AttrByteSize Attr = 0x0B AttrBitOffset Attr = 0x0C AttrBitSize Attr = 0x0D AttrStmtList Attr = 0x10 AttrLowpc Attr = 0x11 AttrHighpc Attr = 0x12 AttrLanguage Attr = 0x13 AttrDiscr Attr = 0x15 AttrDiscrValue Attr = 0x16 AttrVisibility Attr = 0x17 AttrImport Attr = 0x18 AttrStringLength Attr = 0x19 AttrCommonRef Attr = 0x1A AttrCompDir Attr = 0x1B AttrConstValue Attr = 0x1C AttrContainingType Attr = 0x1D AttrDefaultValue Attr = 0x1E AttrInline Attr = 0x20 AttrIsOptional Attr = 0x21 AttrLowerBound Attr = 0x22 AttrProducer Attr = 0x25 AttrPrototyped Attr = 0x27 AttrReturnAddr Attr = 0x2A AttrStartScope Attr = 0x2C AttrStrideSize Attr = 0x2E AttrUpperBound Attr = 0x2F AttrAbstractOrigin Attr = 0x31 AttrAccessibility Attr = 0x32 AttrAddrClass Attr = 0x33 AttrArtificial Attr = 0x34 AttrBaseTypes Attr = 0x35 AttrCalling Attr = 0x36 AttrCount Attr = 0x37 AttrDataMemberLoc Attr = 0x38 AttrDeclColumn Attr = 0x39 AttrDeclFile Attr = 0x3A AttrDeclLine Attr = 0x3B AttrDeclaration Attr = 0x3C AttrDiscrList Attr = 0x3D AttrEncoding Attr = 0x3E AttrExternal Attr = 0x3F AttrFrameBase Attr = 0x40 AttrFriend Attr = 0x41 AttrIdentifierCase Attr = 0x42 AttrMacroInfo Attr = 0x43 AttrNamelistItem Attr = 0x44 AttrPriority Attr = 0x45 AttrSegment Attr = 0x46 AttrSpecification Attr = 0x47 AttrStaticLink Attr = 0x48 AttrType Attr = 0x49 AttrUseLocation Attr = 0x4A AttrVarParam Attr = 0x4B AttrVirtuality Attr = 0x4C AttrVtableElemLoc Attr = 0x4D AttrAllocated Attr = 0x4E AttrAssociated Attr = 0x4F AttrDataLocation Attr = 0x50 AttrStride Attr = 0x51 AttrEntrypc Attr = 0x52 AttrUseUTF8 Attr = 0x53 AttrExtension Attr = 0x54 AttrRanges Attr = 0x55 AttrTrampoline Attr = 0x56 AttrCallColumn Attr = 0x57 AttrCallFile Attr = 0x58 AttrCallLine Attr = 0x59 AttrDescription Attr = 0x5A // Go-specific attributes. AttrGoKind Attr = 0x2900 AttrGoKey Attr = 0x2901 AttrGoElem Attr = 0x2902 AttrGoEmbeddedField Attr = 0x2903 ) var attrNames = [...]string{ AttrSibling: "Sibling", AttrLocation: "Location", AttrName: "Name", AttrOrdering: "Ordering", AttrByteSize: "ByteSize", AttrBitOffset: "BitOffset", AttrBitSize: "BitSize", AttrStmtList: "StmtList", AttrLowpc: "Lowpc", AttrHighpc: "Highpc", AttrLanguage: "Language", AttrDiscr: "Discr", AttrDiscrValue: "DiscrValue", AttrVisibility: "Visibility", AttrImport: "Import", AttrStringLength: "StringLength", AttrCommonRef: "CommonRef", AttrCompDir: "CompDir", AttrConstValue: "ConstValue", AttrContainingType: "ContainingType", AttrDefaultValue: "DefaultValue", AttrInline: "Inline", AttrIsOptional: "IsOptional", AttrLowerBound: "LowerBound", AttrProducer: "Producer", AttrPrototyped: "Prototyped", AttrReturnAddr: "ReturnAddr", AttrStartScope: "StartScope", AttrStrideSize: "StrideSize", AttrUpperBound: "UpperBound", AttrAbstractOrigin: "AbstractOrigin", AttrAccessibility: "Accessibility", AttrAddrClass: "AddrClass", AttrArtificial: "Artificial", AttrBaseTypes: "BaseTypes", AttrCalling: "Calling", AttrCount: "Count", AttrDataMemberLoc: "DataMemberLoc", AttrDeclColumn: "DeclColumn", AttrDeclFile: "DeclFile", AttrDeclLine: "DeclLine", AttrDeclaration: "Declaration", AttrDiscrList: "DiscrList", AttrEncoding: "Encoding", AttrExternal: "External", AttrFrameBase: "FrameBase", AttrFriend: "Friend", AttrIdentifierCase: "IdentifierCase", AttrMacroInfo: "MacroInfo", AttrNamelistItem: "NamelistItem", AttrPriority: "Priority", AttrSegment: "Segment", AttrSpecification: "Specification", AttrStaticLink: "StaticLink", AttrType: "Type", AttrUseLocation: "UseLocation", AttrVarParam: "VarParam", AttrVirtuality: "Virtuality", AttrVtableElemLoc: "VtableElemLoc", AttrAllocated: "Allocated", AttrAssociated: "Associated", AttrDataLocation: "DataLocation", AttrStride: "Stride", AttrEntrypc: "Entrypc", AttrUseUTF8: "UseUTF8", AttrExtension: "Extension", AttrRanges: "Ranges", AttrTrampoline: "Trampoline", AttrCallColumn: "CallColumn", AttrCallFile: "CallFile", AttrCallLine: "CallLine", AttrDescription: "Description", } func (a Attr) String() string { if int(a) < len(attrNames) { s := attrNames[a] if s != "" { return s } } switch a { case AttrGoKind: return "GoKind" case AttrGoKey: return "GoKey" case AttrGoElem: return "GoElem" case AttrGoEmbeddedField: return "GoEmbeddedField" } return strconv.Itoa(int(a)) } func (a Attr) GoString() string { if int(a) < len(attrNames) { s := attrNames[a] if s != "" { return "dwarf.Attr" + s } } return "dwarf.Attr(" + strconv.FormatInt(int64(a), 10) + ")" } // A format is a DWARF data encoding format. type format uint32 const ( // value formats formAddr format = 0x01 formDwarfBlock2 format = 0x03 formDwarfBlock4 format = 0x04 formData2 format = 0x05 formData4 format = 0x06 formData8 format = 0x07 formString format = 0x08 formDwarfBlock format = 0x09 formDwarfBlock1 format = 0x0A formData1 format = 0x0B formFlag format = 0x0C formSdata format = 0x0D formStrp format = 0x0E formUdata format = 0x0F formRefAddr format = 0x10 formRef1 format = 0x11 formRef2 format = 0x12 formRef4 format = 0x13 formRef8 format = 0x14 formRefUdata format = 0x15 formIndirect format = 0x16 // The following are new in DWARF 4. formSecOffset format = 0x17 formExprloc format = 0x18 formFlagPresent format = 0x19 formRefSig8 format = 0x20 // Extensions for multi-file compression (.dwz) // http://www.dwarfstd.org/ShowIssue.php?issue=120604.1 formGnuRefAlt format = 0x1f20 formGnuStrpAlt format = 0x1f21 ) // A Tag is the classification (the type) of an Entry. type Tag uint32 const ( TagArrayType Tag = 0x01 TagClassType Tag = 0x02 TagEntryPoint Tag = 0x03 TagEnumerationType Tag = 0x04 TagFormalParameter Tag = 0x05 TagImportedDeclaration Tag = 0x08 TagLabel Tag = 0x0A TagLexDwarfBlock Tag = 0x0B TagMember Tag = 0x0D TagPointerType Tag = 0x0F TagReferenceType Tag = 0x10 TagCompileUnit Tag = 0x11 TagStringType Tag = 0x12 TagStructType Tag = 0x13 TagSubroutineType Tag = 0x15 TagTypedef Tag = 0x16 TagUnionType Tag = 0x17 TagUnspecifiedParameters Tag = 0x18 TagVariant Tag = 0x19 TagCommonDwarfBlock Tag = 0x1A TagCommonInclusion Tag = 0x1B TagInheritance Tag = 0x1C TagInlinedSubroutine Tag = 0x1D TagModule Tag = 0x1E TagPtrToMemberType Tag = 0x1F TagSetType Tag = 0x20 TagSubrangeType Tag = 0x21 TagWithStmt Tag = 0x22 TagAccessDeclaration Tag = 0x23 TagBaseType Tag = 0x24 TagCatchDwarfBlock Tag = 0x25 TagConstType Tag = 0x26 TagConstant Tag = 0x27 TagEnumerator Tag = 0x28 TagFileType Tag = 0x29 TagFriend Tag = 0x2A TagNamelist Tag = 0x2B TagNamelistItem Tag = 0x2C TagPackedType Tag = 0x2D TagSubprogram Tag = 0x2E TagTemplateTypeParameter Tag = 0x2F TagTemplateValueParameter Tag = 0x30 TagThrownType Tag = 0x31 TagTryDwarfBlock Tag = 0x32 TagVariantPart Tag = 0x33 TagVariable Tag = 0x34 TagVolatileType Tag = 0x35 // The following are new in DWARF 3. TagDwarfProcedure Tag = 0x36 TagRestrictType Tag = 0x37 TagInterfaceType Tag = 0x38 TagNamespace Tag = 0x39 TagImportedModule Tag = 0x3A TagUnspecifiedType Tag = 0x3B TagPartialUnit Tag = 0x3C TagImportedUnit Tag = 0x3D TagMutableType Tag = 0x3E // Later removed from DWARF. TagCondition Tag = 0x3F TagSharedType Tag = 0x40 // The following are new in DWARF 4. TagTypeUnit Tag = 0x41 TagRvalueReferenceType Tag = 0x42 TagTemplateAlias Tag = 0x43 ) var tagNames = [...]string{ TagArrayType: "ArrayType", TagClassType: "ClassType", TagEntryPoint: "EntryPoint", TagEnumerationType: "EnumerationType", TagFormalParameter: "FormalParameter", TagImportedDeclaration: "ImportedDeclaration", TagLabel: "Label", TagLexDwarfBlock: "LexDwarfBlock", TagMember: "Member", TagPointerType: "PointerType", TagReferenceType: "ReferenceType", TagCompileUnit: "CompileUnit", TagStringType: "StringType", TagStructType: "StructType", TagSubroutineType: "SubroutineType", TagTypedef: "Typedef", TagUnionType: "UnionType", TagUnspecifiedParameters: "UnspecifiedParameters", TagVariant: "Variant", TagCommonDwarfBlock: "CommonDwarfBlock", TagCommonInclusion: "CommonInclusion", TagInheritance: "Inheritance", TagInlinedSubroutine: "InlinedSubroutine", TagModule: "Module", TagPtrToMemberType: "PtrToMemberType", TagSetType: "SetType", TagSubrangeType: "SubrangeType", TagWithStmt: "WithStmt", TagAccessDeclaration: "AccessDeclaration", TagBaseType: "BaseType", TagCatchDwarfBlock: "CatchDwarfBlock", TagConstType: "ConstType", TagConstant: "Constant", TagEnumerator: "Enumerator", TagFileType: "FileType", TagFriend: "Friend", TagNamelist: "Namelist", TagNamelistItem: "NamelistItem", TagPackedType: "PackedType", TagSubprogram: "Subprogram", TagTemplateTypeParameter: "TemplateTypeParameter", TagTemplateValueParameter: "TemplateValueParameter", TagThrownType: "ThrownType", TagTryDwarfBlock: "TryDwarfBlock", TagVariantPart: "VariantPart", TagVariable: "Variable", TagVolatileType: "VolatileType", TagDwarfProcedure: "DwarfProcedure", TagRestrictType: "RestrictType", TagInterfaceType: "InterfaceType", TagNamespace: "Namespace", TagImportedModule: "ImportedModule", TagUnspecifiedType: "UnspecifiedType", TagPartialUnit: "PartialUnit", TagImportedUnit: "ImportedUnit", TagMutableType: "MutableType", TagCondition: "Condition", TagSharedType: "SharedType", TagTypeUnit: "TypeUnit", TagRvalueReferenceType: "RvalueReferenceType", TagTemplateAlias: "TemplateAlias", } func (t Tag) String() string { if int(t) < len(tagNames) { s := tagNames[t] if s != "" { return s } } return strconv.Itoa(int(t)) } func (t Tag) GoString() string { if int(t) < len(tagNames) { s := tagNames[t] if s != "" { return "dwarf.Tag" + s } } return "dwarf.Tag(" + strconv.FormatInt(int64(t), 10) + ")" } // Location expression operators. // The debug info encodes value locations like 8(R3) // as a sequence of these op codes. // This package does not implement full expressions; // the opPlusUconst operator is expected by the type parser. const ( opAddr = 0x03 /* 1 op, const addr */ opDeref = 0x06 opConst1u = 0x08 /* 1 op, 1 byte const */ opConst1s = 0x09 /* " signed */ opConst2u = 0x0A /* 1 op, 2 byte const */ opConst2s = 0x0B /* " signed */ opConst4u = 0x0C /* 1 op, 4 byte const */ opConst4s = 0x0D /* " signed */ opConst8u = 0x0E /* 1 op, 8 byte const */ opConst8s = 0x0F /* " signed */ opConstu = 0x10 /* 1 op, LEB128 const */ opConsts = 0x11 /* " signed */ opDup = 0x12 opDrop = 0x13 opOver = 0x14 opPick = 0x15 /* 1 op, 1 byte stack index */ opSwap = 0x16 opRot = 0x17 opXderef = 0x18 opAbs = 0x19 opAnd = 0x1A opDiv = 0x1B opMinus = 0x1C opMod = 0x1D opMul = 0x1E opNeg = 0x1F opNot = 0x20 opOr = 0x21 opPlus = 0x22 opPlusUconst = 0x23 /* 1 op, ULEB128 addend */ opShl = 0x24 opShr = 0x25 opShra = 0x26 opXor = 0x27 opSkip = 0x2F /* 1 op, signed 2-byte constant */ opBra = 0x28 /* 1 op, signed 2-byte constant */ opEq = 0x29 opGe = 0x2A opGt = 0x2B opLe = 0x2C opLt = 0x2D opNe = 0x2E opLit0 = 0x30 /* OpLitN = OpLit0 + N for N = 0..31 */ opReg0 = 0x50 /* OpRegN = OpReg0 + N for N = 0..31 */ opBreg0 = 0x70 /* 1 op, signed LEB128 constant */ /* OpBregN = OpBreg0 + N for N = 0..31 */ opRegx = 0x90 /* 1 op, ULEB128 register */ opFbreg = 0x91 /* 1 op, SLEB128 offset */ opBregx = 0x92 /* 2 op, ULEB128 reg; SLEB128 off */ opPiece = 0x93 /* 1 op, ULEB128 size of piece */ opDerefSize = 0x94 /* 1-byte size of data retrieved */ opXderefSize = 0x95 /* 1-byte size of data retrieved */ opNop = 0x96 /* next four new in Dwarf v3 */ opPushObjAddr = 0x97 opCall2 = 0x98 /* 2-byte offset of DIE */ opCall4 = 0x99 /* 4-byte offset of DIE */ opCallRef = 0x9A /* 4- or 8- byte offset of DIE */ /* 0xE0-0xFF reserved for user-specific */ ) // Basic type encodings -- the value for AttrEncoding in a TagBaseType Entry. const ( encAddress = 0x01 encBoolean = 0x02 encComplexFloat = 0x03 encFloat = 0x04 encSigned = 0x05 encSignedChar = 0x06 encUnsigned = 0x07 encUnsignedChar = 0x08 encImaginaryFloat = 0x09 ) google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/dwarf/entry.go000066400000000000000000000234501356504100700267250ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // DWARF debug information entry parser. // An entry is a sequence of data items of a given format. // The first word in the entry is an index into what DWARF // calls the ``abbreviation table.'' An abbreviation is really // just a type descriptor: it's an array of attribute tag/value format pairs. package dwarf import ( "errors" "strconv" ) // a single entry's description: a sequence of attributes type abbrev struct { tag Tag children bool field []afield } type afield struct { attr Attr fmt format } // a map from entry format ids to their descriptions type abbrevTable map[uint32]abbrev // ParseAbbrev returns the abbreviation table that starts at byte off // in the .debug_abbrev section. func (d *Data) parseAbbrev(off uint32) (abbrevTable, error) { if m, ok := d.abbrevCache[off]; ok { return m, nil } data := d.abbrev if off > uint32(len(data)) { data = nil } else { data = data[off:] } b := makeBuf(d, unknownFormat{}, "abbrev", 0, data) // Error handling is simplified by the buf getters // returning an endless stream of 0s after an error. m := make(abbrevTable) for { // Table ends with id == 0. id := uint32(b.uint()) if id == 0 { break } // Walk over attributes, counting. n := 0 b1 := b // Read from copy of b. b1.uint() b1.uint8() for { tag := b1.uint() fmt := b1.uint() if tag == 0 && fmt == 0 { break } n++ } if b1.err != nil { return nil, b1.err } // Walk over attributes again, this time writing them down. var a abbrev a.tag = Tag(b.uint()) a.children = b.uint8() != 0 a.field = make([]afield, n) for i := range a.field { a.field[i].attr = Attr(b.uint()) a.field[i].fmt = format(b.uint()) } b.uint() b.uint() m[id] = a } if b.err != nil { return nil, b.err } d.abbrevCache[off] = m return m, nil } // An entry is a sequence of attribute/value pairs. type Entry struct { Offset Offset // offset of Entry in DWARF info Tag Tag // tag (kind of Entry) Children bool // whether Entry is followed by children Field []Field } // A Field is a single attribute/value pair in an Entry. type Field struct { Attr Attr Val interface{} } // Val returns the value associated with attribute Attr in Entry, // or nil if there is no such attribute. // // A common idiom is to merge the check for nil return with // the check that the value has the expected dynamic type, as in: // v, ok := e.Val(AttrSibling).(int64); // func (e *Entry) Val(a Attr) interface{} { for _, f := range e.Field { if f.Attr == a { return f.Val } } return nil } // An Offset represents the location of an Entry within the DWARF info. // (See Reader.Seek.) type Offset uint32 // Entry reads a single entry from buf, decoding // according to the given abbreviation table. func (b *buf) entry(atab abbrevTable, ubase Offset) *Entry { off := b.off id := uint32(b.uint()) if id == 0 { return &Entry{} } a, ok := atab[id] if !ok { b.error("unknown abbreviation table index") return nil } e := &Entry{ Offset: off, Tag: a.tag, Children: a.children, Field: make([]Field, len(a.field)), } for i := range e.Field { e.Field[i].Attr = a.field[i].attr fmt := a.field[i].fmt if fmt == formIndirect { fmt = format(b.uint()) } var val interface{} switch fmt { default: b.error("unknown entry attr format 0x" + strconv.FormatInt(int64(fmt), 16)) // address case formAddr: val = b.addr() // block case formDwarfBlock1: val = b.bytes(int(b.uint8())) case formDwarfBlock2: val = b.bytes(int(b.uint16())) case formDwarfBlock4: val = b.bytes(int(b.uint32())) case formDwarfBlock: val = b.bytes(int(b.uint())) // constant case formData1: val = int64(b.uint8()) case formData2: val = int64(b.uint16()) case formData4: val = int64(b.uint32()) case formData8: val = int64(b.uint64()) case formSdata: val = int64(b.int()) case formUdata: val = int64(b.uint()) // flag case formFlag: val = b.uint8() == 1 // New in DWARF 4. case formFlagPresent: // The attribute is implicitly indicated as present, and no value is // encoded in the debugging information entry itself. val = true // reference to other entry case formRefAddr: vers := b.format.version() if vers == 0 { b.error("unknown version for DW_FORM_ref_addr") } else if vers == 2 { val = Offset(b.addr()) } else { is64, known := b.format.dwarf64() if !known { b.error("unknown size for DW_FORM_ref_addr") } else if is64 { val = Offset(b.uint64()) } else { val = Offset(b.uint32()) } } case formRef1: val = Offset(b.uint8()) + ubase case formRef2: val = Offset(b.uint16()) + ubase case formRef4: val = Offset(b.uint32()) + ubase case formRef8: val = Offset(b.uint64()) + ubase case formRefUdata: val = Offset(b.uint()) + ubase // string case formString: val = b.string() case formStrp: off := b.uint32() // offset into .debug_str if b.err != nil { return nil } b1 := makeBuf(b.dwarf, unknownFormat{}, "str", 0, b.dwarf.str) b1.skip(int(off)) val = b1.string() if b1.err != nil { b.err = b1.err return nil } // lineptr, loclistptr, macptr, rangelistptr // New in DWARF 4, but clang can generate them with -gdwarf-2. // Section reference, replacing use of formData4 and formData8. case formSecOffset, formGnuRefAlt, formGnuStrpAlt: is64, known := b.format.dwarf64() if !known { b.error("unknown size for form 0x" + strconv.FormatInt(int64(fmt), 16)) } else if is64 { val = int64(b.uint64()) } else { val = int64(b.uint32()) } // exprloc // New in DWARF 4. case formExprloc: val = b.bytes(int(b.uint())) // reference // New in DWARF 4. case formRefSig8: // 64-bit type signature. val = b.uint64() } e.Field[i].Val = val } if b.err != nil { return nil } return e } // A Reader allows reading Entry structures from a DWARF ``info'' section. // The Entry structures are arranged in a tree. The Reader's Next function // return successive entries from a pre-order traversal of the tree. // If an entry has children, its Children field will be true, and the children // follow, terminated by an Entry with Tag 0. type Reader struct { b buf d *Data err error unit int lastChildren bool // .Children of last entry returned by Next lastSibling Offset // .Val(AttrSibling) of last entry returned by Next } // Reader returns a new Reader for Data. // The reader is positioned at byte offset 0 in the DWARF ``info'' section. func (d *Data) Reader() *Reader { r := &Reader{d: d} r.Seek(0) return r } // AddressSize returns the size in bytes of addresses in the current compilation // unit. func (r *Reader) AddressSize() int { return r.d.unit[r.unit].asize } // Seek positions the Reader at offset off in the encoded entry stream. // Offset 0 can be used to denote the first entry. func (r *Reader) Seek(off Offset) { d := r.d r.err = nil r.lastChildren = false if off == 0 { if len(d.unit) == 0 { return } u := &d.unit[0] r.unit = 0 r.b = makeBuf(r.d, u, "info", u.off, u.data) return } // TODO(rsc): binary search (maybe a new package) var i int var u *unit for i = range d.unit { u = &d.unit[i] if u.off <= off && off < u.off+Offset(len(u.data)) { r.unit = i r.b = makeBuf(r.d, u, "info", off, u.data[off-u.off:]) return } } r.err = errors.New("offset out of range") } // maybeNextUnit advances to the next unit if this one is finished. func (r *Reader) maybeNextUnit() { for len(r.b.data) == 0 && r.unit+1 < len(r.d.unit) { r.unit++ u := &r.d.unit[r.unit] r.b = makeBuf(r.d, u, "info", u.off, u.data) } } // Next reads the next entry from the encoded entry stream. // It returns nil, nil when it reaches the end of the section. // It returns an error if the current offset is invalid or the data at the // offset cannot be decoded as a valid Entry. func (r *Reader) Next() (*Entry, error) { if r.err != nil { return nil, r.err } r.maybeNextUnit() if len(r.b.data) == 0 { return nil, nil } u := &r.d.unit[r.unit] e := r.b.entry(u.atable, u.base) if r.b.err != nil { r.err = r.b.err return nil, r.err } if e != nil { r.lastChildren = e.Children if r.lastChildren { r.lastSibling, _ = e.Val(AttrSibling).(Offset) } } else { r.lastChildren = false } return e, nil } // SkipChildren skips over the child entries associated with // the last Entry returned by Next. If that Entry did not have // children or Next has not been called, SkipChildren is a no-op. func (r *Reader) SkipChildren() { if r.err != nil || !r.lastChildren { return } // If the last entry had a sibling attribute, // that attribute gives the offset of the next // sibling, so we can avoid decoding the // child subtrees. if r.lastSibling >= r.b.off { r.Seek(r.lastSibling) return } for { e, err := r.Next() if err != nil || e == nil || e.Tag == 0 { break } if e.Children { r.SkipChildren() } } } // clone returns a copy of the reader. This is used by the typeReader // interface. func (r *Reader) clone() typeReader { return r.d.Reader() } // offset returns the current buffer offset. This is used by the // typeReader interface. func (r *Reader) offset() Offset { return r.b.off } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/dwarf/frame.go000066400000000000000000000301431356504100700266530ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Mapping from PC to SP offset (called CFA - Canonical Frame Address - in DWARF). // This value is the offset from the stack pointer to the virtual frame pointer // (address of zeroth argument) at each PC value in the program. package dwarf import "fmt" // http://www.dwarfstd.org/doc/DWARF4.pdf Section 6.4 page 126 // We implement only the CFA column of the table, not the location // information about other registers. In other words, we implement // only what we need to understand Go programs compiled by gc. // PCToSPOffset returns the offset, at the specified PC, to add to the // SP to reach the virtual frame pointer, which corresponds to the // address of the zeroth argument of the function, the word on the // stack immediately above the return PC. func (d *Data) PCToSPOffset(pc uint64) (offset int64, err error) { if len(d.frame) == 0 { return 0, fmt.Errorf("PCToSPOffset: no frame table") } var m frameMachine // Assume the first info unit is the same as us. Extremely likely. TODO? if len(d.unit) == 0 { return 0, fmt.Errorf("PCToSPOffset: no info section") } buf := makeBuf(d, &d.unit[0], "frame", 0, d.frame) for len(buf.data) > 0 { offset, err := m.evalCompilationUnit(&buf, pc) if err != nil { return 0, err } return offset, nil } return 0, fmt.Errorf("PCToSPOffset: no frame defined for PC %#x", pc) } // Call Frame instructions. Figure 40, page 181. // Structure is high two bits plus low 6 bits specified by + in comment. // Some take one or two operands. const ( frameNop = 0<<6 + 0x00 frameAdvanceLoc = 1<<6 + 0x00 // + delta frameOffset = 2<<6 + 0x00 // + register op: ULEB128 offset frameRestore = 3<<6 + 0x00 // + register frameSetLoc = 0<<6 + 0x01 // op: address frameAdvanceLoc1 = 0<<6 + 0x02 // op: 1-byte delta frameAdvanceLoc2 = 0<<6 + 0x03 // op: 2-byte delta frameAdvanceLoc4 = 0<<6 + 0x04 // op: 4-byte delta frameOffsetExtended = 0<<6 + 0x05 // ops: ULEB128 register ULEB128 offset frameRestoreExtended = 0<<6 + 0x06 // op: ULEB128 register frameUndefined = 0<<6 + 0x07 // op: ULEB128 register frameSameValue = 0<<6 + 0x08 // op: ULEB128 register frameRegister = 0<<6 + 0x09 // op: ULEB128 register ULEB128 register frameRememberState = 0<<6 + 0x0a frameRestoreState = 0<<6 + 0x0b frameDefCFA = 0<<6 + 0x0c // op: ULEB128 register ULEB128 offset frameDefCFARegister = 0<<6 + 0x0d // op: ULEB128 register frameDefCFAOffset = 0<<6 + 0x0e // op: ULEB128 offset frameDefCFAExpression = 0<<6 + 0x0f // op: BLOCK frameExpression = 0<<6 + 0x10 // op: ULEB128 register BLOCK frameOffsetExtendedSf = 0<<6 + 0x11 // op: ULEB128 register SLEB128 offset frameDefCFASf = 0<<6 + 0x12 // op: ULEB128 register SLEB128 offset frameDefCFAOffsetSf = 0<<6 + 0x13 // op: SLEB128 offset frameValOffset = 0<<6 + 0x14 // op: ULEB128 ULEB128 frameValOffsetSf = 0<<6 + 0x15 // op: ULEB128 SLEB128 frameValExpression = 0<<6 + 0x16 // op: ULEB128 BLOCK frameLoUser = 0<<6 + 0x1c frameHiUser = 0<<6 + 0x3f ) // frameMachine represents the PC/SP engine. // Section 6.4, page 129. type frameMachine struct { // Initial values from CIE. version uint8 // Version number, "independent of DWARF version" augmentation string // Augmentation; treated as unexpected for now. TODO. addressSize uint8 // In DWARF v4 and above. Size of a target address. segmentSize uint8 // In DWARF v4 and above. Size of a segment selector. codeAlignmentFactor uint64 // Unit of code size in advance instructions. dataAlignmentFactor int64 // Unit of data size in certain offset instructions. returnAddressRegister int // Pseudo-register (actually data column) representing return address. returnRegisterOffset int64 // Offset to saved PC from CFA in bytes. // CFA definition. cfaRegister int // Which register represents the SP. cfaOffset int64 // CFA offset value. // Running machine. location uint64 } // evalCompilationUnit scans the frame data for one compilation unit to retrieve // the offset information for the specified pc. func (m *frameMachine) evalCompilationUnit(b *buf, pc uint64) (int64, error) { err := m.parseCIE(b) if err != nil { return 0, err } for { offset, found, err := m.scanFDE(b, pc) if err != nil { return 0, err } if found { return offset, nil } } } // parseCIE assumes the incoming buffer starts with a CIE block and parses it // to initialize a frameMachine. func (m *frameMachine) parseCIE(allBuf *buf) error { length := int(allBuf.uint32()) if len(allBuf.data) < length { return fmt.Errorf("CIE parse error: too short") } // Create buffer for just this section. b := allBuf.slice(length) cie := b.uint32() if cie != 0xFFFFFFFF { return fmt.Errorf("CIE parse error: not CIE: %x", cie) } m.version = b.uint8() if m.version != 3 && m.version != 4 { return fmt.Errorf("CIE parse error: unsupported version %d", m.version) } m.augmentation = b.string() if len(m.augmentation) > 0 { return fmt.Errorf("CIE: can't handled augmentation string %q", m.augmentation) } if m.version >= 4 { m.addressSize = b.uint8() m.segmentSize = b.uint8() } else { // Unused. Gc generates version 3, so these values will not be // set, but they are also not used so it's OK. } m.codeAlignmentFactor = b.uint() m.dataAlignmentFactor = b.int() m.returnAddressRegister = int(b.uint()) // Initial instructions. At least for Go, establishes SP register number // and initial value of CFA offset at start of function. _, err := m.run(&b, ^uint64(0)) if err != nil { return err } // There's padding, but we can ignore it. return nil } // scanFDE assumes the incoming buffer starts with a FDE block and parses it // to run a frameMachine and, if the PC is represented in its range, return // the CFA offset for that PC. The boolean returned reports whether the // PC is in range for this FDE. func (m *frameMachine) scanFDE(allBuf *buf, pc uint64) (int64, bool, error) { length := int(allBuf.uint32()) if len(allBuf.data) < length { return 0, false, fmt.Errorf("FDE parse error: too short") } if length <= 0 { if length == 0 { // EOF. return 0, false, fmt.Errorf("PC %#x not found in PC/SP table", pc) } return 0, false, fmt.Errorf("bad FDE length %d", length) } // Create buffer for just this section. b := allBuf.slice(length) cieOffset := b.uint32() // TODO: assumes 32 bits. // Expect 0: first CIE in this segment. TODO. if cieOffset != 0 { return 0, false, fmt.Errorf("FDE parse error: bad CIE offset: %.2x", cieOffset) } // Initial location. m.location = b.addr() addressRange := b.addr() // If the PC is not in this function, there's no point in executing the instructions. if pc < m.location || m.location+addressRange <= pc { return 0, false, nil } // The PC appears in this FDE. Scan to find the location. offset, err := m.run(&b, pc) if err != nil { return 0, false, err } // There's padding, but we can ignore it. return offset, true, nil } // run executes the instructions in the buffer, which has been sliced to contain // only the data for this block. When we run out of data, we return. // Since we are only called when we know the PC is in this block, reaching // EOF is not an error, it just means the final CFA definition matches the // tail of the block that holds the PC. // The return value is the CFA at the end of the block or the PC, whichever // comes first. func (m *frameMachine) run(b *buf, pc uint64) (int64, error) { // We run the machine at location == PC because if the PC is at the first // instruction of a block, the definition of its offset arrives as an // offset-defining operand after the PC is set to that location. for m.location <= pc && len(b.data) > 0 { op := b.uint8() // Ops with embedded operands switch op & 0xC0 { case frameAdvanceLoc: // (6.4.2.1) // delta in low bits m.location += uint64(op & 0x3F) continue case frameOffset: // (6.4.2.3) // Register in low bits; ULEB128 offset. // For Go binaries we only see this in the CIE for the return address register. if int(op&0x3F) != m.returnAddressRegister { return 0, fmt.Errorf("invalid frameOffset register R%d should be R%d", op&0x3f, m.returnAddressRegister) } m.returnRegisterOffset = int64(b.uint()) * m.dataAlignmentFactor continue case frameRestore: // (6.4.2.3) // register in low bits return 0, fmt.Errorf("unimplemented frameRestore(R%d)\n", op&0x3F) } // The remaining ops do not have embedded operands. switch op { // Row creation instructions (6.4.2.1) case frameNop: case frameSetLoc: // op: address return 0, fmt.Errorf("unimplemented setloc") // what size is operand? case frameAdvanceLoc1: // op: 1-byte delta m.location += uint64(b.uint8()) case frameAdvanceLoc2: // op: 2-byte delta m.location += uint64(b.uint16()) case frameAdvanceLoc4: // op: 4-byte delta m.location += uint64(b.uint32()) // CFA definition instructions (6.4.2.2) case frameDefCFA: // op: ULEB128 register ULEB128 offset m.cfaRegister = int(b.int()) m.cfaOffset = int64(b.uint()) case frameDefCFASf: // op: ULEB128 register SLEB128 offset return 0, fmt.Errorf("unimplemented frameDefCFASf") case frameDefCFARegister: // op: ULEB128 register return 0, fmt.Errorf("unimplemented frameDefCFARegister") case frameDefCFAOffset: // op: ULEB128 offset return 0, fmt.Errorf("unimplemented frameDefCFAOffset") case frameDefCFAOffsetSf: // op: SLEB128 offset offset := b.int() m.cfaOffset = offset * m.dataAlignmentFactor // TODO: Verify we are using a factored offset. case frameDefCFAExpression: // op: BLOCK return 0, fmt.Errorf("unimplemented frameDefCFAExpression") // Register Rule instructions (6.4.2.3) case frameOffsetExtended: // ops: ULEB128 register ULEB128 offset // The same as frameOffset, but with the register specified in an operand. reg := b.uint() // For Go binaries we only see this in the CIE for the return address register. if reg != uint64(m.returnAddressRegister) { return 0, fmt.Errorf("invalid frameOffsetExtended: register R%d should be R%d", reg, m.returnAddressRegister) } m.returnRegisterOffset = int64(b.uint()) * m.dataAlignmentFactor case frameRestoreExtended: // op: ULEB128 register return 0, fmt.Errorf("unimplemented frameRestoreExtended") case frameUndefined: // op: ULEB128 register; unimplemented return 0, fmt.Errorf("unimplemented frameUndefined") case frameSameValue: // op: ULEB128 register return 0, fmt.Errorf("unimplemented frameSameValue") case frameRegister: // op: ULEB128 register ULEB128 register return 0, fmt.Errorf("unimplemented frameRegister") case frameRememberState: return 0, fmt.Errorf("unimplemented frameRememberState") case frameRestoreState: return 0, fmt.Errorf("unimplemented frameRestoreState") case frameExpression: // op: ULEB128 register BLOCK return 0, fmt.Errorf("unimplemented frameExpression") case frameOffsetExtendedSf: // op: ULEB128 register SLEB128 offset return 0, fmt.Errorf("unimplemented frameOffsetExtended_sf") case frameValOffset: // op: ULEB128 ULEB128 return 0, fmt.Errorf("unimplemented frameValOffset") case frameValOffsetSf: // op: ULEB128 SLEB128 return 0, fmt.Errorf("unimplemented frameValOffsetSf") case frameValExpression: // op: ULEB128 BLOCK return 0, fmt.Errorf("unimplemented frameValExpression") default: if frameLoUser <= op && op <= frameHiUser { return 0, fmt.Errorf("unknown user-defined frame op %#x", op) } return 0, fmt.Errorf("unknown frame op %#x", op) } } return m.cfaOffset, nil } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/dwarf/frame_test.go000066400000000000000000000100001356504100700277000ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package dwarf_test import ( "fmt" "io/ioutil" "os" "os/exec" "path/filepath" "runtime" "strings" "testing" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/dwarf" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/elf" ) var ( pcspTempDir string pcsptestBinary string ) func doPCToSPTest(self bool) bool { // For now, only works on amd64 platforms. if runtime.GOARCH != "amd64" { return false } // Self test reads test binary; only works on Linux or Mac. if self { if runtime.GOOS != "linux" && runtime.GOOS != "darwin" { return false } } // Command below expects "sh", so Unix. if runtime.GOOS == "windows" || runtime.GOOS == "plan9" { return false } if pcsptestBinary != "" { return true } var err error pcspTempDir, err = ioutil.TempDir("", "pcsptest") if err != nil { panic(err) } if strings.Contains(pcspTempDir, " ") { panic("unexpected space in tempdir") } // This command builds pcsptest from testdata/pcsptest.go. pcsptestBinary = filepath.Join(pcspTempDir, "pcsptest") command := fmt.Sprintf("go tool compile -o %s.6 testdata/pcsptest.go && go tool link -H %s -o %s %s.6", pcsptestBinary, runtime.GOOS, pcsptestBinary, pcsptestBinary) cmd := exec.Command("sh", "-c", command) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { panic(err) } return true } func endPCToSPTest() { if pcspTempDir != "" { os.RemoveAll(pcspTempDir) pcspTempDir = "" pcsptestBinary = "" } } func TestPCToSPOffset(t *testing.T) { t.Skip("gets a stack layout it doesn't expect") if !doPCToSPTest(false) { return } defer endPCToSPTest() data, err := getData(pcsptestBinary) if err != nil { t.Fatal(err) } entry, err := data.LookupFunction("main.test") if err != nil { t.Fatal("lookup startPC:", err) } startPC, ok := entry.Val(dwarf.AttrLowpc).(uint64) if !ok { t.Fatal(`DWARF data for function "main.test" has no low PC`) } endPC, ok := entry.Val(dwarf.AttrHighpc).(uint64) if !ok { t.Fatal(`DWARF data for function "main.test" has no high PC`) } const addrSize = 8 // TODO: Assumes amd64. const argSize = 8 // Defined by int64 arguments in test binary. // On 64-bit machines, the first offset must be one address size, // for the return PC. offset, err := data.PCToSPOffset(startPC) if err != nil { t.Fatal("startPC:", err) } if offset != addrSize { t.Fatalf("expected %d at start of function; got %d", addrSize, offset) } // On 64-bit machines, expect some 8s and some 32s. (See the // comments in testdata/pcsptest.go. // TODO: The test could be stronger, but not much unless we // disassemble the binary. count := make(map[int64]int) for pc := startPC; pc < endPC; pc++ { offset, err := data.PCToSPOffset(pc) if err != nil { t.Fatal("scanning function:", err) } count[offset]++ } if len(count) != 2 { t.Errorf("expected 2 offset values, got %d; counts are: %v", len(count), count) } if count[addrSize] == 0 { t.Errorf("expected some values at offset %d; got %v", addrSize, count) } if count[addrSize+3*argSize] == 0 { t.Errorf("expected some values at offset %d; got %v", addrSize+3*argSize, count) } } func getData(file string) (*dwarf.Data, error) { switch runtime.GOOS { case "linux": f, err := elf.Open(file) if err != nil { return nil, err } dwarf, err := f.DWARF() if err != nil { return nil, err } f.Close() return dwarf, nil } panic("unimplemented DWARF for GOOS=" + runtime.GOOS) } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/dwarf/line.go000066400000000000000000000361711356504100700265170ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package dwarf // This file implements the mapping from PC to lines. // TODO: Find a way to test this properly. // http://www.dwarfstd.org/doc/DWARF4.pdf Section 6.2 page 108 import ( "fmt" "sort" "strings" ) // PCToLine returns the file and line number corresponding to the PC value. // It returns an error if a correspondence cannot be found. func (d *Data) PCToLine(pc uint64) (file string, line uint64, err error) { c := d.pcToLineEntries if len(c) == 0 { return "", 0, fmt.Errorf("PCToLine: no line table") } i := sort.Search(len(c), func(i int) bool { return c[i].pc > pc }) - 1 // c[i] is now the entry in pcToLineEntries with the largest pc that is not // larger than the query pc. // The search has failed if: // - All pcs in c were larger than the query pc (i == -1). // - c[i] marked the end of a sequence of instructions (c[i].file == 0). // - c[i] is the last element of c, and isn't the end of a sequence of // instructions, and the search pc is much larger than c[i].pc. In this // case, we don't know the range of the last instruction, but the search // pc is probably past it. if i == -1 || c[i].file == 0 || (i+1 == len(c) && pc-c[i].pc > 1024) { return "", 0, fmt.Errorf("no source line defined for PC %#x", pc) } if c[i].file >= uint64(len(d.sourceFiles)) { return "", 0, fmt.Errorf("invalid file number in DWARF data") } return d.sourceFiles[c[i].file], c[i].line, nil } // LineToBreakpointPCs returns the PCs that should be used as breakpoints // corresponding to the given file and line number. // It returns an empty slice if no PCs were found. func (d *Data) LineToBreakpointPCs(file string, line uint64) ([]uint64, error) { compDir := d.compilationDirectory() // Find the closest match in the executable for the specified file. // We choose the file with the largest number of path components matching // at the end of the name. If there is a tie, we prefer files that are // under the compilation directory. If there is still a tie, we choose // the file with the shortest name. // TODO: handle duplicate file names in the DWARF? var bestFile struct { fileNum uint64 // Index of the file in the DWARF data. components int // Number of matching path components. length int // Length of the filename. underComp bool // File is under the compilation directory. } for filenum, filename := range d.sourceFiles { c := matchingPathComponentSuffixSize(filename, file) underComp := strings.HasPrefix(filename, compDir) better := false if c != bestFile.components { better = c > bestFile.components } else if underComp != bestFile.underComp { better = underComp } else { better = len(filename) < bestFile.length } if better { bestFile.fileNum = uint64(filenum) bestFile.components = c bestFile.length = len(filename) bestFile.underComp = underComp } } if bestFile.components == 0 { return nil, fmt.Errorf("couldn't find file %q", file) } c := d.lineToPCEntries[bestFile.fileNum] // c contains all (pc, line) pairs for the appropriate file. start := sort.Search(len(c), func(i int) bool { return c[i].line >= line }) end := sort.Search(len(c), func(i int) bool { return c[i].line > line }) // c[i].line == line for all i in the range [start, end). pcs := make([]uint64, 0, end-start) for i := start; i < end; i++ { pcs = append(pcs, c[i].pc) } return pcs, nil } // compilationDirectory finds the first compilation unit entry in d and returns // the compilation directory contained in it. // If it fails, it returns the empty string. func (d *Data) compilationDirectory() string { r := d.Reader() for { entry, err := r.Next() if entry == nil || err != nil { return "" } if entry.Tag == TagCompileUnit { name, _ := entry.Val(AttrCompDir).(string) return name } } } // matchingPathComponentSuffixSize returns the largest n such that the last n // components of the paths p1 and p2 are equal. // e.g. matchingPathComponentSuffixSize("a/b/x/y.go", "b/a/x/y.go") returns 2. func matchingPathComponentSuffixSize(p1, p2 string) int { // TODO: deal with other path separators. c1 := strings.Split(p1, "/") c2 := strings.Split(p2, "/") min := len(c1) if len(c2) < min { min = len(c2) } var n int for n = 0; n < min; n++ { if c1[len(c1)-1-n] != c2[len(c2)-1-n] { break } } return n } // Standard opcodes. Figure 37, page 178. // If an opcode >= lineMachine.prologue.opcodeBase, it is a special // opcode rather than the opcode defined in this table. const ( lineStdCopy = 0x01 lineStdAdvancePC = 0x02 lineStdAdvanceLine = 0x03 lineStdSetFile = 0x04 lineStdSetColumn = 0x05 lineStdNegateStmt = 0x06 lineStdSetBasicBlock = 0x07 lineStdConstAddPC = 0x08 lineStdFixedAdvancePC = 0x09 lineStdSetPrologueEnd = 0x0a lineStdSetEpilogueBegin = 0x0b lineStdSetISA = 0x0c ) // Extended opcodes. Figure 38, page 179. const ( lineStartExtendedOpcode = 0x00 // Not defined as a named constant in the spec. lineExtEndSequence = 0x01 lineExtSetAddress = 0x02 lineExtDefineFile = 0x03 lineExtSetDiscriminator = 0x04 // New in version 4. lineExtLoUser = 0x80 lineExtHiUser = 0xff ) // lineHeader holds the information stored in the header of the line table for a // single compilation unit. // Section 6.2.4, page 112. type lineHeader struct { unitLength int version int headerLength int minInstructionLength int maxOpsPerInstruction int defaultIsStmt bool lineBase int lineRange int opcodeBase byte stdOpcodeLengths []byte include []string // entry 0 is empty; means current directory file []lineFile // entry 0 is empty. } // lineFile represents a file name stored in the PC/line table, usually in the header. type lineFile struct { name string index int // index into include directories time int // implementation-defined time of last modification length int // length in bytes, 0 if not available. } // lineMachine holds the registers evaluated during executing of the PC/line mapping engine. // Section 6.2.2, page 109. // A .debug_line section consists of multiple line number programs, one for each compilation unit. type lineMachine struct { // The program-counter value corresponding to a machine instruction generated by the compiler. address uint64 // An unsigned integer representing the index of an operation within a VLIW // instruction. The index of the first operation is 0. For non-VLIW // architectures, this register will always be 0. // The address and op_index registers, taken together, form an operation // pointer that can reference any individual operation with the instruction // stream. opIndex uint64 // An unsigned integer indicating the identity of the source file corresponding to a machine instruction. file uint64 // An unsigned integer indicating a source line number. Lines are numbered // beginning at 1. The compiler may emit the value 0 in cases where an // instruction cannot be attributed to any source line. line uint64 // An unsigned integer indicating a column number within a source line. // Columns are numbered beginning at 1. The value 0 is reserved to indicate // that a statement begins at the “left edge†of the line. column uint64 // A boolean indicating that the current instruction is a recommended // breakpoint location. A recommended breakpoint location is intended to // “represent†a line, a statement and/or a semantically distinct subpart of a // statement. isStmt bool // A boolean indicating that the current instruction is the beginning of a basic // block. basicBlock bool // A boolean indicating that the current address is that of the first byte after // the end of a sequence of target machine instructions. end_sequence // terminates a sequence of lines; therefore other information in the same // row is not meaningful. endSequence bool // A boolean indicating that the current address is one (of possibly many) // where execution should be suspended for an entry breakpoint of a // function. prologueEnd bool // A boolean indicating that the current address is one (of possibly many) // where execution should be suspended for an exit breakpoint of a function. epilogueBegin bool // An unsigned integer whose value encodes the applicable instruction set // architecture for the current instruction. // The encoding of instruction sets should be shared by all users of a given // architecture. It is recommended that this encoding be defined by the ABI // authoring committee for each architecture. isa uint64 // An unsigned integer identifying the block to which the current instruction // belongs. Discriminator values are assigned arbitrarily by the DWARF // producer and serve to distinguish among multiple blocks that may all be // associated with the same source file, line, and column. Where only one // block exists for a given source position, the discriminator value should be // zero. discriminator uint64 // The header for the current compilation unit. // Not an actual register, but stored here for cleanliness. header lineHeader // Offset in buf of the end of the line number program for the current unit. unitEndOff Offset } // parseHeader parses the header describing the compilation unit in the line // table starting at the specified offset. func (m *lineMachine) parseHeader(b *buf) error { m.header = lineHeader{} m.header.unitLength = int(b.uint32()) // Note: We are assuming 32-bit DWARF format. m.unitEndOff = b.off + Offset(m.header.unitLength) if m.header.unitLength > len(b.data) { return fmt.Errorf("DWARF: bad PC/line header length") } m.header.version = int(b.uint16()) m.header.headerLength = int(b.uint32()) m.header.minInstructionLength = int(b.uint8()) if m.header.version >= 4 { m.header.maxOpsPerInstruction = int(b.uint8()) } else { m.header.maxOpsPerInstruction = 1 } m.header.defaultIsStmt = b.uint8() != 0 m.header.lineBase = int(int8(b.uint8())) m.header.lineRange = int(b.uint8()) m.header.opcodeBase = b.uint8() m.header.stdOpcodeLengths = make([]byte, m.header.opcodeBase-1) copy(m.header.stdOpcodeLengths, b.bytes(int(m.header.opcodeBase-1))) m.header.include = make([]string, 1) // First entry is empty; file index entries are 1-indexed. // Includes for { name := b.string() if name == "" { break } m.header.include = append(m.header.include, name) } // Files // Files are 1-indexed in line number program, but we'll deal with that in Data.buildLineCaches. // Here, just collect the filenames. for { name := b.string() if name == "" { break } index := b.uint() time := b.uint() length := b.uint() f := lineFile{ name: name, index: int(index), time: int(time), length: int(length), } m.header.file = append(m.header.file, f) } return nil } // Special opcodes, page 117. // There are seven steps to processing special opcodes. We break them up here // because the caller needs to output a row between steps 2 and 4, and because // we need to perform just step 2 for the opcode DW_LNS_const_add_pc. func (m *lineMachine) specialOpcodeStep1(opcode byte) { adjustedOpcode := int(opcode - m.header.opcodeBase) lineAdvance := m.header.lineBase + (adjustedOpcode % m.header.lineRange) m.line += uint64(lineAdvance) } func (m *lineMachine) specialOpcodeStep2(opcode byte) { adjustedOpcode := int(opcode - m.header.opcodeBase) advance := adjustedOpcode / m.header.lineRange delta := (int(m.opIndex) + advance) / m.header.maxOpsPerInstruction m.address += uint64(m.header.minInstructionLength * delta) m.opIndex = (m.opIndex + uint64(advance)) % uint64(m.header.maxOpsPerInstruction) } func (m *lineMachine) specialOpcodeSteps4To7() { m.basicBlock = false m.prologueEnd = false m.epilogueBegin = false m.discriminator = 0 } // evalCompilationUnit reads the next compilation unit and calls f at each output row. // Line machine execution continues while f returns true. func (m *lineMachine) evalCompilationUnit(b *buf, f func(m *lineMachine) (cont bool)) error { m.reset() for b.off < m.unitEndOff { op := b.uint8() if op >= m.header.opcodeBase { m.specialOpcodeStep1(op) m.specialOpcodeStep2(op) // Step 3 is to output a row, so we call f here. if !f(m) { return nil } m.specialOpcodeSteps4To7() continue } switch op { case lineStartExtendedOpcode: if len(b.data) == 0 { return fmt.Errorf("DWARF: short extended opcode (1)") } size := b.uint() if uint64(len(b.data)) < size { return fmt.Errorf("DWARF: short extended opcode (2)") } op = b.uint8() switch op { case lineExtEndSequence: m.endSequence = true if !f(m) { return nil } if len(b.data) == 0 { return nil } m.reset() case lineExtSetAddress: m.address = b.addr() m.opIndex = 0 case lineExtDefineFile: return fmt.Errorf("DWARF: unimplemented define_file op") case lineExtSetDiscriminator: discriminator := b.uint() m.discriminator = discriminator default: return fmt.Errorf("DWARF: unknown extended opcode %#x", op) } case lineStdCopy: if !f(m) { return nil } m.discriminator = 0 m.basicBlock = false m.prologueEnd = false m.epilogueBegin = false case lineStdAdvancePC: advance := b.uint() delta := (int(m.opIndex) + int(advance)) / m.header.maxOpsPerInstruction m.address += uint64(m.header.minInstructionLength * delta) m.opIndex = (m.opIndex + uint64(advance)) % uint64(m.header.maxOpsPerInstruction) m.basicBlock = false m.prologueEnd = false m.epilogueBegin = false m.discriminator = 0 case lineStdAdvanceLine: advance := b.int() m.line = uint64(int64(m.line) + advance) case lineStdSetFile: index := b.uint() m.file = index case lineStdSetColumn: column := b.uint() m.column = column case lineStdNegateStmt: m.isStmt = !m.isStmt case lineStdSetBasicBlock: m.basicBlock = true case lineStdFixedAdvancePC: m.address += uint64(b.uint16()) m.opIndex = 0 case lineStdSetPrologueEnd: m.prologueEnd = true case lineStdSetEpilogueBegin: m.epilogueBegin = true case lineStdSetISA: m.isa = b.uint() case lineStdConstAddPC: // Update the address and op_index registers. m.specialOpcodeStep2(255) default: panic("not reached") } } return nil } // reset sets the machine's registers to the initial state. Page 111. func (m *lineMachine) reset() { m.address = 0 m.opIndex = 0 m.file = 1 m.line = 1 m.column = 0 m.isStmt = m.header.defaultIsStmt m.basicBlock = false m.endSequence = false m.prologueEnd = false m.epilogueBegin = false m.isa = 0 m.discriminator = 0 } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/dwarf/open.go000066400000000000000000000072271356504100700265310ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package dwarf provides access to DWARF debugging information loaded from // executable files, as defined in the DWARF 2.0 Standard at // http://dwarfstd.org/doc/dwarf-2.0.0.pdf package dwarf // import "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/dwarf" import "encoding/binary" // Data represents the DWARF debugging information // loaded from an executable file (for example, an ELF or Mach-O executable). type Data struct { // raw data abbrev []byte aranges []byte frame []byte info []byte line []byte pubnames []byte ranges []byte str []byte // parsed data abbrevCache map[uint32]abbrevTable order binary.ByteOrder typeCache map[Offset]Type typeSigs map[uint64]*typeUnit unit []unit sourceFiles []string // All the source files listed in .debug_line, from all the compilation units. nameCache // map from name to top-level entries in .debug_info. pcToFuncEntries // cache of .debug_info data for function bounds. pcToLineEntries // cache of .debug_line data, used for efficient PC-to-line mapping. lineToPCEntries // cache of .debug_line data, used for efficient line-to-[]PC mapping. } // New returns a new Data object initialized from the given parameters. // Rather than calling this function directly, clients should typically use // the DWARF method of the File type of the appropriate package debug/elf, // debug/macho, or debug/pe. // // The []byte arguments are the data from the corresponding debug section // in the object file; for example, for an ELF object, abbrev is the contents of // the ".debug_abbrev" section. func New(abbrev, aranges, frame, info, line, pubnames, ranges, str []byte) (*Data, error) { d := &Data{ abbrev: abbrev, aranges: aranges, frame: frame, info: info, line: line, pubnames: pubnames, ranges: ranges, str: str, abbrevCache: make(map[uint32]abbrevTable), typeCache: make(map[Offset]Type), typeSigs: make(map[uint64]*typeUnit), } // Sniff .debug_info to figure out byte order. // bytes 4:6 are the version, a tiny 16-bit number (1, 2, 3). if len(d.info) < 6 { return nil, DecodeError{"info", Offset(len(d.info)), "too short"} } x, y := d.info[4], d.info[5] switch { case x == 0 && y == 0: return nil, DecodeError{"info", 4, "unsupported version 0"} case x == 0: d.order = binary.BigEndian case y == 0: d.order = binary.LittleEndian default: return nil, DecodeError{"info", 4, "cannot determine byte order"} } u, err := d.parseUnits() if err != nil { return nil, err } d.unit = u d.buildInfoCaches() if err := d.buildLineCaches(); err != nil { return nil, err } return d, nil } // AddTypes will add one .debug_types section to the DWARF data. A // typical object with DWARF version 4 debug info will have multiple // .debug_types sections. The name is used for error reporting only, // and serves to distinguish one .debug_types section from another. func (d *Data) AddTypes(name string, types []byte) error { return d.parseTypes(name, types) } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/dwarf/pclntab_test.go000066400000000000000000000066701356504100700302530ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // +build go1.10 package dwarf_test // Stripped-down, simplified version of ../../gosym/pclntab_test.go import ( "fmt" "io/ioutil" "os" "os/exec" "path/filepath" "runtime" "strings" "testing" . "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/dwarf" ) var ( pclineTempDir string pclinetestBinary string ) func dotest(self bool) bool { // For now, only works on amd64 platforms. if runtime.GOARCH != "amd64" { return false } // Self test reads test binary; only works on Linux or Mac. if self { if runtime.GOOS != "linux" && runtime.GOOS != "darwin" { return false } } // Command below expects "sh", so Unix. if runtime.GOOS == "windows" || runtime.GOOS == "plan9" { return false } if pclinetestBinary != "" { return true } var err error pclineTempDir, err = ioutil.TempDir("", "pclinetest") if err != nil { panic(err) } if strings.Contains(pclineTempDir, " ") { panic("unexpected space in tempdir") } pclinetestBinary = filepath.Join(pclineTempDir, "pclinetest") command := fmt.Sprintf("go tool compile -o %s.6 testdata/pclinetest.go && go tool link -H %s -E main -o %s %s.6", pclinetestBinary, runtime.GOOS, pclinetestBinary, pclinetestBinary) cmd := exec.Command("sh", "-c", command) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { panic(err) } return true } func endtest() { if pclineTempDir != "" { os.RemoveAll(pclineTempDir) pclineTempDir = "" pclinetestBinary = "" } } func TestPCAndLine(t *testing.T) { t.Skip("This stopped working in Go 1.12") // TODO(jba): go1.9: use subtests if !dotest(false) { return } defer endtest() data, err := getData(pclinetestBinary) if err != nil { t.Fatal(err) } testLineToBreakpointPCs(t, data) testPCToLine(t, data) } func testPCToLine(t *testing.T, data *Data) { entry, err := data.LookupFunction("main.main") if err != nil { t.Fatal(err) } pc, ok := entry.Val(AttrLowpc).(uint64) if !ok { t.Fatal(`DWARF data for function "main" has no PC`) } for _, tt := range []struct { offset, want uint64 }{ {0, 19}, {19, 19}, {33, 20}, {97, 22}, {165, 23}, } { file, line, err := data.PCToLine(pc + tt.offset) if err != nil { t.Fatal(err) } if !strings.HasSuffix(file, "/pclinetest.go") { t.Errorf("got %s; want %s", file, "/pclinetest.go") } if line != tt.want { t.Errorf("line for offset %d: got %d; want %d", tt.offset, line, tt.want) } } } func testLineToBreakpointPCs(t *testing.T, data *Data) { for _, tt := range []struct { line uint64 want bool }{ {18, false}, {19, true}, {20, true}, {21, false}, {22, true}, {23, true}, {24, false}, } { pcs, err := data.LineToBreakpointPCs("pclinetest.go", uint64(tt.line)) if err != nil { t.Fatal(err) } if got := len(pcs) > 0; got != tt.want { t.Errorf("line %d: got pcs=%t, want pcs=%t", tt.line, got, tt.want) } } } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/dwarf/symbol.go000066400000000000000000000101161356504100700270640ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package dwarf // This file provides simple methods to access the symbol table by name and address. import ( "fmt" "regexp" "sort" ) // lookupEntry returns the first Entry for the name. // If tag is non-zero, only entries with that tag are considered. func (d *Data) lookupEntry(name string, tag Tag) (*Entry, error) { x, ok := d.nameCache[name] if !ok { return nil, fmt.Errorf("DWARF entry for %q not found", name) } for ; x != nil; x = x.link { if tag == 0 || x.entry.Tag == tag { return x.entry, nil } } return nil, fmt.Errorf("no DWARF entry for %q with tag %s", name, tag) } // LookupMatchingSymbols returns the names of all top-level entries matching // the given regular expression. func (d *Data) LookupMatchingSymbols(nameRE *regexp.Regexp) (result []string, err error) { for name := range d.nameCache { if nameRE.MatchString(name) { result = append(result, name) } } return result, nil } // LookupEntry returns the Entry for the named symbol. func (d *Data) LookupEntry(name string) (*Entry, error) { return d.lookupEntry(name, 0) } // LookupFunction returns the entry for a function. func (d *Data) LookupFunction(name string) (*Entry, error) { return d.lookupEntry(name, TagSubprogram) } // LookupVariable returns the entry for a (global) variable. func (d *Data) LookupVariable(name string) (*Entry, error) { return d.lookupEntry(name, TagVariable) } // EntryLocation returns the address of the object referred to by the given Entry. func (d *Data) EntryLocation(e *Entry) (uint64, error) { loc, _ := e.Val(AttrLocation).([]byte) if len(loc) == 0 { return 0, fmt.Errorf("DWARF entry has no Location attribute") } // TODO: implement the DWARF Location bytecode. What we have here only // recognizes a program with a single literal opAddr bytecode. if asize := d.unit[0].asize; loc[0] == opAddr && len(loc) == 1+asize { switch asize { case 1: return uint64(loc[1]), nil case 2: return uint64(d.order.Uint16(loc[1:])), nil case 4: return uint64(d.order.Uint32(loc[1:])), nil case 8: return d.order.Uint64(loc[1:]), nil } } return 0, fmt.Errorf("DWARF entry has an unimplemented Location op") } // EntryType returns the Type for an Entry. func (d *Data) EntryType(e *Entry) (Type, error) { off, err := d.EntryTypeOffset(e) if err != nil { return nil, err } return d.Type(off) } // EntryTypeOffset returns the offset in the given Entry's type attribute. func (d *Data) EntryTypeOffset(e *Entry) (Offset, error) { v := e.Val(AttrType) if v == nil { return 0, fmt.Errorf("DWARF entry has no Type attribute") } off, ok := v.(Offset) if !ok { return 0, fmt.Errorf("DWARF entry has an invalid Type attribute") } return off, nil } // PCToFunction returns the entry and address for the function containing the // specified PC. func (d *Data) PCToFunction(pc uint64) (entry *Entry, lowpc uint64, err error) { p := d.pcToFuncEntries if len(p) == 0 { return nil, 0, fmt.Errorf("no function addresses loaded") } i := sort.Search(len(p), func(i int) bool { return p[i].pc > pc }) - 1 // The search failed if: // - pc was before the start of any function. // - The largest function bound not larger than pc was the end of a function, // not the start of one. // - The largest function bound not larger than pc was the start of a function // that we don't know the end of, and the PC is much larger than the start. if i == -1 || p[i].entry == nil || (i+1 == len(p) && pc-p[i].pc >= 1<<20) { return nil, 0, fmt.Errorf("no function at %x", pc) } return p[i].entry, p[i].pc, nil } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/dwarf/testdata/000077500000000000000000000000001356504100700270425ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/dwarf/testdata/pclinetest.go000066400000000000000000000012461356504100700315460ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package main import "fmt" func main() { fmt.Print("line 20") fmt.Print("line 22") } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/dwarf/testdata/pcsptest.go000066400000000000000000000022601356504100700312360ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package main import "fmt" func main() { test(1, 2, 3) } // This is the function we examine. After the preamble its stack should be // pulled down 1*addrSize for the return PC plus 3*8 for the three // arguments. That will be (1+3)*8=32 on 64-bit machines. func test(a, b, c int64) int64 { // Put in enough code that it's not inlined. for a = 0; a < 100; a++ { b += c } afterTest(a, b, c) return b } // This function follows test in the binary. We use it to force arguments // onto the stack and as a delimiter in the text we scan in the test. func afterTest(a, b, c int64) { fmt.Println(a, b, c) } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/dwarf/testdata/typedef.c000066400000000000000000000047201356504100700306510ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. /* Linux ELF: gcc -gdwarf-2 -m64 -c typedef.c && gcc -gdwarf-2 -m64 -o typedef.elf typedef.o OS X Mach-O: gcc -gdwarf-2 -m64 -c typedef.c -o typedef.macho */ #include typedef volatile int* t_ptr_volatile_int; typedef const char *t_ptr_const_char; typedef long t_long; typedef unsigned short t_ushort; typedef int t_func_int_of_float_double(float, double); typedef int (*t_ptr_func_int_of_float_double)(float, double); typedef int (*t_ptr_func_int_of_float_complex)(float complex); typedef int (*t_ptr_func_int_of_double_complex)(double complex); typedef int (*t_ptr_func_int_of_long_double_complex)(long double complex); typedef int *t_func_ptr_int_of_char_schar_uchar(char, signed char, unsigned char); typedef void t_func_void_of_char(char); typedef void t_func_void_of_void(void); typedef void t_func_void_of_ptr_char_dots(char*, ...); typedef struct my_struct { volatile int vi; char x : 1; int y : 4; int z[0]; long long array[40]; int zz[0]; } t_my_struct; typedef struct my_struct1 { int zz [1]; } t_my_struct1; typedef union my_union { volatile int vi; char x : 1; int y : 4; long long array[40]; } t_my_union; typedef enum my_enum { e1 = 1, e2 = 2, e3 = -5, e4 = 1000000000000000LL, } t_my_enum; typedef struct list t_my_list; struct list { short val; t_my_list *next; }; typedef struct tree { struct tree *left, *right; unsigned long long val; } t_my_tree; t_ptr_volatile_int *a2; t_ptr_const_char **a3a; t_long *a4; t_ushort *a5; t_func_int_of_float_double *a6; t_ptr_func_int_of_float_double *a7; t_func_ptr_int_of_char_schar_uchar *a8; t_func_void_of_char *a9; t_func_void_of_void *a10; t_func_void_of_ptr_char_dots *a11; t_my_struct *a12; t_my_struct1 *a12a; t_my_union *a12b; t_my_enum *a13; t_my_list *a14; t_my_tree *a15; t_ptr_func_int_of_float_complex *a16; t_ptr_func_int_of_double_complex *a17; t_ptr_func_int_of_long_double_complex *a18; int main() { return 0; } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/dwarf/testdata/typedef.elf000077500000000000000000000302401356504100700311740ustar00rootroot00000000000000ELF>à@@ˆ@8 @&#@@@@@øø88@8@@@\\ ``¨ @@`@`  TT@T@DDPåtd¼¼@¼@$$QåtdRåtd``èè/lib64/ld-linux-x86-64.so.2GNUGNU<ºûíXßõÂ4ïË n²I¤¬ __gmon_start__libc.so.6__libc_start_mainGLIBC_2.2.5ui ,à``Hƒìè[èêèµHƒÄÃÿ5* ÿ%, @ÿ%* héàÿÿÿ1íI‰Ñ^H‰âHƒäðPTIÇÀÐ@HÇÁà@HÇÇÄ@èÇÿÿÿôHƒìH‹É H…ÀtÿÐHƒÄÃUH‰åSHƒì€=Ø uK»0`H‹Ò Hë(`HÁûHƒëH9Øs$fDHƒÀH‰­ ÿÅ(`H‹Ÿ H9ØrâÆ‹ HƒÄ[ÉÃfff.„UHƒ= H‰åt¸H…Àt¿8`ÉÿàÉÃUH‰å¸ÉÃóÃfffff.„H‰l$ØL‰d$àH-# L% L‰l$èL‰t$ðL‰|$øH‰\$ÐHƒì8L)åA‰ýI‰öHÁýI‰×èƒþÿÿH…ít1Û@L‰úL‰öD‰ïAÿÜHƒÃH9ërêH‹\$H‹l$L‹d$L‹l$ L‹t$(L‹|$0HƒÄ8ÃUH‰åSHƒìH‹˜ Hƒøÿt»`DHƒëÿÐH‹HƒøÿuñHƒÄ[ÉÃHƒìèþÿÿHƒÄÃ; ÿÿÿ<ÿÿÿ\$ÿÿÿtzRx Äþÿÿ AC† <°þÿÿ$T¨þÿÿ‰QŒ†_@FƒŽÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ¨@ ¨@˜@õþÿo°@@Ð@ 8 è`@x@ þÿÿoX@ÿÿÿoðÿÿoP@@`Ö@GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3,Ä@ ªÍŸmain¿a2Úa3aüa4a52a6Ma7ha8ƒa9ža10ºa11Öa12òa12aa12b*a13Fa14\a15xa16”a17°a18É·à%Ä@Ï@Ã8>CintU[`Zr®d„™²–C« « ²—ú;Ä–ÍÕÛCë ëýC ê4%+C; ; íMgg ` m tCzx'† ’ ` mª · · ` ŸHvi>#x`#yC#z#¬ 0#zz!G#ÈC--@@-'©CV-"½ˆ#{zz${#C‹-†%a2@&Ñvi'>x(`y)C¬*00+–û,e1e2e3{e4€€š¦ê¯ãù1ÜZ3_3Cval5C#;6J#Ö+9‡/:‡#“:‡#val;#Pa&Ô @`-a3a?ð `öJa4@ x`ga5A, ¸`ya6BG H`‹a7Cb ``¹a8D} €`Ba9E˜ ˜`{a10F´  `’a11GÐ h`Ÿa12Hì P`V@I ˆ`‹ŠJ$ 8`Ña13K@ (`a14LJ ¨`a15Mr p`”a16NŽ X`Êa17Oª 0`òa18PÆ °`% : ; I I5I$ > &I$ > ' I I '  '   : ;  : ; I8  : ; I 8  : ; I8 I!I$ > !I/  : ;  : ;  : ; I : ; I  : ; I : ; ( .? : ; I@4: ; I?  4: ; I?  < û typedef.c Ä@ÒKYt_ptr_const_chart_func_void_of_void/home/rscleftt_ptr_func_int_of_long_double_complext_longlong long unsigned intunsigned chart_my_struct1rightshort unsigned intarrayt_func_int_of_float_doublet_ptr_func_int_of_float_complexcomplex long doublet_ptr_func_int_of_double_complexmaint_func_void_of_chart_ptr_func_int_of_float_doublet_my_listt_ushortt_func_void_of_ptr_char_dotsa12bcomplex floatt_my_structlong long intGNU C 4.4.3t_ptr_volatile_intshort inttypedef.ccomplex doublet_my_enumt_func_ptr_int_of_char_schar_uchart_my_treet_my_unionnexta12aww v.symtab.strtab.shstrtab.interp.note.ABI-tag.note.gnu.build-id.gnu.hash.dynsym.dynstr.gnu.version.gnu.version_r.rela.dyn.rela.plt.init.text.fini.rodata.eh_frame_hdr.eh_frame.ctors.dtors.jcr.dynamic.got.got.plt.data.bss.comment.debug_aranges.debug_pubnames.debug_info.debug_abbrev.debug_line.debug_str.debug_loc8@8#T@T 1t@t$H˜@˜Döÿÿo°@°N Ð@ÐHV@8^ÿÿÿoP@PkþÿÿoX@X zx@x„@ ލ@¨‰À@À ”à@àÈš¨@¨ ¸@¸¨¼@¼$¶à@à|À`Ç(`(Î8`8Ó@`@ Üà`àáè`è ê`ð`¨õ0#þ;0 k®Í)æs7Y@C0™ENÞL*Y&p%6 x.(8@T@t@˜@°@Ð@@P@ X@ x@ @ ¨@ À@à@¨@¸@¼@à@`(`8`@`à`è``` !" @ñÿ`*(`88`E0@[`j `x @ñÿ„ `‘X@Ÿ8`«p@ÁñÿËè`á`ò`@` `(`Ð@-à@4 C W0`[¨@a8`f@`iH`l‹P`¸@ž`«X`¯``²h`¶`Ã0`Ðà@‰àp`äñÿ`ðx`ó€`öñÿÀ`ûˆ``˜` ` ¨`ñÿ`°`¸`Ä@ " ¨@call_gmon_startcrtstuff.c__CTOR_LIST____DTOR_LIST____JCR_LIST____do_global_dtors_auxcompleted.7382dtor_idx.7384frame_dummy__CTOR_END____FRAME_END____JCR_END____do_global_ctors_auxtypedef.c_GLOBAL_OFFSET_TABLE___init_array_end__init_array_start_DYNAMICdata_starta13__libc_csu_fini_start__gmon_start___Jv_RegisterClassesa17_finia12ba2a6__libc_start_main@@GLIBC_2.2.5a12_IO_stdin_used__data_starta16a7a11__dso_handle__DTOR_END____libc_csu_inita15__bss_starta4a8_enda12aa3aa9a10a14_edataa18a5main_initgoogle-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/dwarf/testdata/typedef.elf4000066400000000000000000000224301356504100700312570ustar00rootroot00000000000000ELF>Ð @@%"  UH‰å¸]ÃXé!è;¨Áy9N:N:Nval;TWIzcñv:74Bval5B6IO3>õò«´Ò3#ß, e1 e2 e3{ e4€€š¦ê¯ã†$Ø(‰AÁ\Ž @&X vi'X x(] y)d *kdint{{‚'P3£û1·Y#5zz$5EELint¾_©uxHrvirxwy~z… ”zz!¤H~int~”³º¤³'~³³E8>CintU[`r„–Cªª±Ã–ÔÚCééûC"(C77 Ibb`hoCŒ`—£¯¯`"_©ux%3£û1·Y+$Ø(‰AÁ\Ž1õò«´Ò3#ß3Izcñv:7ÿ<é!è;¨ÁyRCœa2>b -a3a?} ƒJa4@ ga5A· ya6BÑ ‹a7Cë ¸a8D >a9E va10F: Œa11GU ˜a12Hp à I‹ Ò J¦ áa13KÁ ða14L a15Mñ "a16N  Éa17O' ða18PB A  : ;  : ; I8  : ; I8  I$ > : ; I : ; (  : ;  : ; I : ; I : ; I5I$ > I!I/  : ;  : ; I 8  : ; I8!I% &I'II'': ; I .?: ; I@4: ; I? 4: ; I?, < û typedef.c ÒKYrightnexta12at_ptr_const_chart_func_void_of_voidleftt_ptr_func_int_of_long_double_complext_longfloatlong long unsigned intunsigned chart_my_struct1short unsigned intarraymy_structdoublet_func_int_of_float_doublet_ptr_func_int_of_float_complexmy_struct1complex long doublet_ptr_func_int_of_double_complex/home/iant/go3/src/pkg/debug/dwarf/testdatat_func_void_of_chart_ushortt_ptr_func_int_of_float_doublet_my_listcharmy_enumGNU C 4.8.0 20120420 (experimental)t_func_void_of_ptr_char_dotsa12bcomplex floatlistt_my_structsizetypemainlong long intt_ptr_volatile_intshort inttypedef.ccomplex doublet_my_enumlong intt_func_ptr_int_of_char_schar_uchart_my_treesigned chart_my_unionmy_uniontreeGCC: (GNU) 4.8.0 20120420 (experimental)zRx  A†C F .symtab.strtab.shstrtab.text.data.bss.rela.debug_types.rela.debug_info.debug_abbrev.rela.debug_aranges.rela.debug_line.debug_str.comment.note.GNU-stack.rela.eh_framewt.e921e83ba8c10e79wt.497a63f1763a8137wt.f5f2abb4d23323dfwt.24d8288941c15c8ewt.3300a31ffb31b759wt.5fa97504030f780fµ@#ÉH#ÝP#ñX#`#h#p !|'|1|\, # 1Ø[,0# 13B,ÀH#1uŠ,¨#1ÿT,°`#1SÂ,¨#CI>¸#O^bë0]¸$0#v @qè$#‚0[ ß0: *–d «h 8¦%#   -8$ HWñÿ     òÿòÿòÿòÿòÿòÿòÿ!òÿ$òÿ(òÿ,òÿ0òÿ5òÿ:òÿ>òÿBòÿFòÿJòÿNòÿR typedef.ca2a3aa4a5a6a7a8a9a10a11a12a12aa12ba13a14a15a16a17a18main   Ú* 56 W m   6 E WP ¬   »   ÑM ²` ¶~ 6… (   O (   ¸Z ²z ¶¶ (½ 6  à a D! ) . DK c ¶h `u „z „‡ ŸŒ É­ g´ ¹ Ê äì ñ # k :: ? k ºr „w p !™ ç¸ (¿ 6Ä Ó ’â Æñ z ¬ W m# °2 1<D Zu•¯Éãý 2!M"h#w ƒ$’ ž%¹&Ô'é()*:+ - google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/dwarf/testdata/typedef.macho000066400000000000000000000116401356504100700315150ustar00rootroot00000000000000Ïúíþ` øb €b __text__TEXT€€__debug_frame__DWARF<˜ä__debug_info__DWARFTQÔì__debug_abbrev__DWARF¥-%__debug_aranges__DWARFÒ R__debug_macinfo__DWARFÒ R__debug_loc__DWARFÒ R__debug_pubnames__DWARFÒ ®R__debug_pubtypes__DWARF€ __debug_str__DWARF’ __debug_ranges__DWARF’ __data__DATA’ __eh_frame__TEXT˜ H¤ h__debug_line__DWARFà {`´__debug_inlined__DWARF[ ÛÌ,t PUH‰åÇEø‹Eø‰Eü‹Eü]Ãÿÿÿÿx $† M4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.1.00)typedef.c/Users/rsc/g/go/src/pkg/debug/dwarf/testdata/intÑmainmainSVÑÙt_ptr_volatile_intáa2û> char  (t_ptr_const_char0Ha3aP? long intnt_longza4ˆ@ short unsigned int¥t_ushort»a5ËA floatdouble  è ñût_func_int_of_float_doublea62B ûOt_ptr_func_int_of_float_doubleWa7}C signed charunsigned char Üš  ¢ ±Ât_func_ptr_int_of_char_schar_ucharÜa8D  / #t_func_void_of_char/a9JE  gt_func_void_of_voidia10„F  ¶ ¢ªt_func_void_of_ptr_char_dots¶a11ÚG  ølong long int, ø'•my_structHviÑ#x#y#zû#array #zzû!#È,t_my_struct#•a12¨H Öø÷my_struct1#zzÆ$#Öt_my_struct1&÷a12a I xmy_union@&viÑ'#x(#y)#array*#*t_my_union,xa12bŠJ Òmy_enum,e1e2e3{e4€€š¦z©t_my_enum3Òa13ãK short int9list3val5#nextJ6#t_my_list99a14JL Šlong long unsigned intÅtree9lefth:#righth:#valp;#Št_my_tree<Åa15ÖM complex float  ôt_ptr_func_int_of_float_complexa16DN complex double „ bt„t_ptr_func_int_of_double_complexŒa17´O complex long double ù Òéùt_ptr_func_int_of_long_double_complexa18.P % R$>  .‡@: ; ' I? @  5I : ; I : ; I: ; 4I? : ;  &I : ; I' I ' ' $ > I!I/  : ;  I: ; 8  I: ; 8  : ;  : ;  : ; ( ªQŒa10âa11°a12–maina12a’a12bëa13Ra14Þa15La16¼a176a18a2Xa3aÓa5:a6a4…a7Ra9a8QzRx ,øÿÿÿÿÿÿÿ† wKöõ /Users/rsc/g/go/src/pkg/debug/dwarf/testdata/typedef.c f  D Ê Z ì ` ù¡"¾ðš_’GàfÈÀµ­ ^ pdXj ˜ a ° (-27=CHMRW\  $_main_a2_a3a_a4_a5_a6_a7_a8_a9_a10_a11_a12_a12a_a12b_a13_a14_a15_a16_a17_a18_main.ehEH_frame0google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/dwarf/type.go000066400000000000000000000517701356504100700265530ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // DWARF type information structures. // The format is heavily biased toward C, but for simplicity // the String methods use a pseudo-Go syntax. package dwarf import ( "fmt" "reflect" "strconv" ) // A Type conventionally represents a pointer to any of the // specific Type structures (CharType, StructType, etc.). type Type interface { Common() *CommonType String() string Size() int64 } // A CommonType holds fields common to multiple types. // If a field is not known or not applicable for a given type, // the zero value is used. type CommonType struct { ByteSize int64 // size of value of this type, in bytes Name string // name that can be used to refer to type ReflectKind reflect.Kind // the reflect kind of the type. Offset Offset // the offset at which this type was read } func (c *CommonType) Common() *CommonType { return c } func (c *CommonType) Size() int64 { return c.ByteSize } // Basic types // A BasicType holds fields common to all basic types. type BasicType struct { CommonType BitSize int64 BitOffset int64 } func (b *BasicType) Basic() *BasicType { return b } func (t *BasicType) String() string { if t.Name != "" { return t.Name } return "?" } // A CharType represents a signed character type. type CharType struct { BasicType } // A UcharType represents an unsigned character type. type UcharType struct { BasicType } // An IntType represents a signed integer type. type IntType struct { BasicType } // A UintType represents an unsigned integer type. type UintType struct { BasicType } // A FloatType represents a floating point type. type FloatType struct { BasicType } // A ComplexType represents a complex floating point type. type ComplexType struct { BasicType } // A BoolType represents a boolean type. type BoolType struct { BasicType } // An AddrType represents a machine address type. type AddrType struct { BasicType } // An UnspecifiedType represents an implicit, unknown, ambiguous or nonexistent type. type UnspecifiedType struct { BasicType } // qualifiers // A QualType represents a type that has the C/C++ "const", "restrict", or "volatile" qualifier. type QualType struct { CommonType Qual string Type Type } func (t *QualType) String() string { return t.Qual + " " + t.Type.String() } func (t *QualType) Size() int64 { return t.Type.Size() } // An ArrayType represents a fixed size array type. type ArrayType struct { CommonType Type Type StrideBitSize int64 // if > 0, number of bits to hold each element Count int64 // if == -1, an incomplete array, like char x[]. } func (t *ArrayType) String() string { return "[" + strconv.FormatInt(t.Count, 10) + "]" + t.Type.String() } func (t *ArrayType) Size() int64 { return t.Count * t.Type.Size() } // A VoidType represents the C void type. type VoidType struct { CommonType } func (t *VoidType) String() string { return "void" } // A PtrType represents a pointer type. type PtrType struct { CommonType Type Type } func (t *PtrType) String() string { return "*" + t.Type.String() } // A StructType represents a struct, union, or C++ class type. type StructType struct { CommonType StructName string Kind string // "struct", "union", or "class". Field []*StructField Incomplete bool // if true, struct, union, class is declared but not defined } // A StructField represents a field in a struct, union, or C++ class type. type StructField struct { Name string Type Type ByteOffset int64 ByteSize int64 BitOffset int64 // within the ByteSize bytes at ByteOffset BitSize int64 // zero if not a bit field Embedded bool } func (t *StructType) String() string { if t.StructName != "" { return t.Kind + " " + t.StructName } return t.Defn() } func (t *StructType) Defn() string { s := t.Kind if t.StructName != "" { s += " " + t.StructName } if t.Incomplete { s += " /*incomplete*/" return s } s += " {" for i, f := range t.Field { if i > 0 { s += "; " } s += f.Name + " " + f.Type.String() s += "@" + strconv.FormatInt(f.ByteOffset, 10) if f.BitSize > 0 { s += " : " + strconv.FormatInt(f.BitSize, 10) s += "@" + strconv.FormatInt(f.BitOffset, 10) } } s += "}" return s } // A SliceType represents a Go slice type. It looks like a StructType, describing // the runtime-internal structure, with extra fields. type SliceType struct { StructType ElemType Type } func (t *SliceType) String() string { if t.Name != "" { return t.Name } return "[]" + t.ElemType.String() } // A StringType represents a Go string type. It looks like a StructType, describing // the runtime-internal structure, but we wrap it for neatness. type StringType struct { StructType } func (t *StringType) String() string { if t.Name != "" { return t.Name } return "string" } // An InterfaceType represents a Go interface. type InterfaceType struct { TypedefType } func (t *InterfaceType) String() string { if t.Name != "" { return t.Name } return "Interface" } // An EnumType represents an enumerated type. // The only indication of its native integer type is its ByteSize // (inside CommonType). type EnumType struct { CommonType EnumName string Val []*EnumValue } // An EnumValue represents a single enumeration value. type EnumValue struct { Name string Val int64 } func (t *EnumType) String() string { s := "enum" if t.EnumName != "" { s += " " + t.EnumName } s += " {" for i, v := range t.Val { if i > 0 { s += "; " } s += v.Name + "=" + strconv.FormatInt(v.Val, 10) } s += "}" return s } // A FuncType represents a function type. type FuncType struct { CommonType ReturnType Type ParamType []Type } func (t *FuncType) String() string { s := "func(" for i, t := range t.ParamType { if i > 0 { s += ", " } s += t.String() } s += ")" if t.ReturnType != nil { s += " " + t.ReturnType.String() } return s } // A DotDotDotType represents the variadic ... function parameter. type DotDotDotType struct { CommonType } func (t *DotDotDotType) String() string { return "..." } // A TypedefType represents a named type. type TypedefType struct { CommonType Type Type } func (t *TypedefType) String() string { return t.Name } func (t *TypedefType) Size() int64 { return t.Type.Size() } // A MapType represents a Go map type. It looks like a TypedefType, describing // the runtime-internal structure, with extra fields. type MapType struct { TypedefType KeyType Type ElemType Type } func (t *MapType) String() string { if t.Name != "" { return t.Name } return "map[" + t.KeyType.String() + "]" + t.ElemType.String() } // A ChanType represents a Go channel type. type ChanType struct { TypedefType ElemType Type } func (t *ChanType) String() string { if t.Name != "" { return t.Name } return "chan " + t.ElemType.String() } // typeReader is used to read from either the info section or the // types section. type typeReader interface { Seek(Offset) Next() (*Entry, error) clone() typeReader offset() Offset // AddressSize returns the size in bytes of addresses in the current // compilation unit. AddressSize() int } // Type reads the type at off in the DWARF ``info'' section. func (d *Data) Type(off Offset) (Type, error) { return d.readType("info", d.Reader(), off, d.typeCache) } func getKind(e *Entry) reflect.Kind { integer, _ := e.Val(AttrGoKind).(int64) return reflect.Kind(integer) } // readType reads a type from r at off of name using and updating a // type cache. func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Offset]Type) (Type, error) { if t, ok := typeCache[off]; ok { return t, nil } r.Seek(off) e, err := r.Next() if err != nil { return nil, err } addressSize := r.AddressSize() if e == nil || e.Offset != off { return nil, DecodeError{name, off, "no type at offset"} } // Parse type from Entry. // Must always set typeCache[off] before calling // d.Type recursively, to handle circular types correctly. var typ Type nextDepth := 0 // Get next child; set err if error happens. next := func() *Entry { if !e.Children { return nil } // Only return direct children. // Skip over composite entries that happen to be nested // inside this one. Most DWARF generators wouldn't generate // such a thing, but clang does. // See golang.org/issue/6472. for { kid, err1 := r.Next() if err1 != nil { err = err1 return nil } if kid == nil { err = DecodeError{name, r.offset(), "unexpected end of DWARF entries"} return nil } if kid.Tag == 0 { if nextDepth > 0 { nextDepth-- continue } return nil } if kid.Children { nextDepth++ } if nextDepth > 0 { continue } return kid } } // Get Type referred to by Entry's attr. // Set err if error happens. Not having a type is an error. typeOf := func(e *Entry, attr Attr) Type { tval := e.Val(attr) var t Type switch toff := tval.(type) { case Offset: if t, err = d.readType(name, r.clone(), toff, typeCache); err != nil { return nil } case uint64: if t, err = d.sigToType(toff); err != nil { return nil } default: // It appears that no Type means "void". return new(VoidType) } return t } switch e.Tag { case TagArrayType: // Multi-dimensional array. (DWARF v2 §5.4) // Attributes: // AttrType:subtype [required] // AttrStrideSize: distance in bits between each element of the array // AttrStride: distance in bytes between each element of the array // AttrByteSize: size of entire array // Children: // TagSubrangeType or TagEnumerationType giving one dimension. // dimensions are in left to right order. t := new(ArrayType) t.Name, _ = e.Val(AttrName).(string) t.ReflectKind = getKind(e) typ = t typeCache[off] = t if t.Type = typeOf(e, AttrType); err != nil { goto Error } if bytes, ok := e.Val(AttrStride).(int64); ok { t.StrideBitSize = 8 * bytes } else if bits, ok := e.Val(AttrStrideSize).(int64); ok { t.StrideBitSize = bits } else { // If there's no stride specified, assume it's the size of the // array's element type. t.StrideBitSize = 8 * t.Type.Size() } // Accumulate dimensions, ndim := 0 for kid := next(); kid != nil; kid = next() { // TODO(rsc): Can also be TagEnumerationType // but haven't seen that in the wild yet. switch kid.Tag { case TagSubrangeType: count, ok := kid.Val(AttrCount).(int64) if !ok { // Old binaries may have an upper bound instead. count, ok = kid.Val(AttrUpperBound).(int64) if ok { count++ // Length is one more than upper bound. } else { count = -1 // As in x[]. } } if ndim == 0 { t.Count = count } else { // Multidimensional array. // Create new array type underneath this one. t.Type = &ArrayType{Type: t.Type, Count: count} } ndim++ case TagEnumerationType: err = DecodeError{name, kid.Offset, "cannot handle enumeration type as array bound"} goto Error } } if ndim == 0 { // LLVM generates this for x[]. t.Count = -1 } case TagBaseType: // Basic type. (DWARF v2 §5.1) // Attributes: // AttrName: name of base type in programming language of the compilation unit [required] // AttrEncoding: encoding value for type (encFloat etc) [required] // AttrByteSize: size of type in bytes [required] // AttrBitOffset: for sub-byte types, size in bits // AttrBitSize: for sub-byte types, bit offset of high order bit in the AttrByteSize bytes name, _ := e.Val(AttrName).(string) enc, ok := e.Val(AttrEncoding).(int64) if !ok { err = DecodeError{name, e.Offset, "missing encoding attribute for " + name} goto Error } switch enc { default: err = DecodeError{name, e.Offset, "unrecognized encoding attribute value"} goto Error case encAddress: typ = new(AddrType) case encBoolean: typ = new(BoolType) case encComplexFloat: typ = new(ComplexType) if name == "complex" { // clang writes out 'complex' instead of 'complex float' or 'complex double'. // clang also writes out a byte size that we can use to distinguish. // See issue 8694. switch byteSize, _ := e.Val(AttrByteSize).(int64); byteSize { case 8: name = "complex float" case 16: name = "complex double" } } case encFloat: typ = new(FloatType) case encSigned: typ = new(IntType) case encUnsigned: typ = new(UintType) case encSignedChar: typ = new(CharType) case encUnsignedChar: typ = new(UcharType) } typeCache[off] = typ t := typ.(interface { Basic() *BasicType }).Basic() t.Name = name t.BitSize, _ = e.Val(AttrBitSize).(int64) t.BitOffset, _ = e.Val(AttrBitOffset).(int64) t.ReflectKind = getKind(e) case TagClassType, TagStructType, TagUnionType: // Structure, union, or class type. (DWARF v2 §5.5) // Also Slices and Strings (Go-specific). // Attributes: // AttrName: name of struct, union, or class // AttrByteSize: byte size [required] // AttrDeclaration: if true, struct/union/class is incomplete // AttrGoElem: present for slices only. // Children: // TagMember to describe one member. // AttrName: name of member [required] // AttrType: type of member [required] // AttrByteSize: size in bytes // AttrBitOffset: bit offset within bytes for bit fields // AttrBitSize: bit size for bit fields // AttrDataMemberLoc: location within struct [required for struct, class] // There is much more to handle C++, all ignored for now. t := new(StructType) t.ReflectKind = getKind(e) switch t.ReflectKind { case reflect.Slice: slice := new(SliceType) slice.ElemType = typeOf(e, AttrGoElem) t = &slice.StructType typ = slice case reflect.String: str := new(StringType) t = &str.StructType typ = str default: typ = t } typeCache[off] = typ switch e.Tag { case TagClassType: t.Kind = "class" case TagStructType: t.Kind = "struct" case TagUnionType: t.Kind = "union" } t.Name, _ = e.Val(AttrName).(string) t.StructName, _ = e.Val(AttrName).(string) t.Incomplete = e.Val(AttrDeclaration) != nil t.Field = make([]*StructField, 0, 8) var lastFieldType Type var lastFieldBitOffset int64 for kid := next(); kid != nil; kid = next() { if kid.Tag == TagMember { f := new(StructField) if f.Type = typeOf(kid, AttrType); err != nil { goto Error } switch loc := kid.Val(AttrDataMemberLoc).(type) { case []byte: // TODO: Should have original compilation // unit here, not unknownFormat. if len(loc) == 0 { // Empty exprloc. f.ByteOffset=0. break } b := makeBuf(d, unknownFormat{}, "location", 0, loc) op := b.uint8() switch op { case opPlusUconst: // Handle opcode sequence [DW_OP_plus_uconst ] f.ByteOffset = int64(b.uint()) b.assertEmpty() case opConsts: // Handle opcode sequence [DW_OP_consts DW_OP_plus] f.ByteOffset = b.int() op = b.uint8() if op != opPlus { err = DecodeError{name, kid.Offset, fmt.Sprintf("unexpected opcode 0x%x", op)} goto Error } b.assertEmpty() default: err = DecodeError{name, kid.Offset, fmt.Sprintf("unexpected opcode 0x%x", op)} goto Error } if b.err != nil { err = b.err goto Error } case int64: f.ByteOffset = loc } haveBitOffset := false f.Name, _ = kid.Val(AttrName).(string) f.ByteSize, _ = kid.Val(AttrByteSize).(int64) f.BitOffset, haveBitOffset = kid.Val(AttrBitOffset).(int64) f.BitSize, _ = kid.Val(AttrBitSize).(int64) f.Embedded, _ = kid.Val(AttrGoEmbeddedField).(bool) t.Field = append(t.Field, f) bito := f.BitOffset if !haveBitOffset { bito = f.ByteOffset * 8 } if bito == lastFieldBitOffset && t.Kind != "union" { // Last field was zero width. Fix array length. // (DWARF writes out 0-length arrays as if they were 1-length arrays.) zeroArray(lastFieldType) } lastFieldType = f.Type lastFieldBitOffset = bito } } if t.Kind != "union" { b, ok := e.Val(AttrByteSize).(int64) if ok && b*8 == lastFieldBitOffset { // Final field must be zero width. Fix array length. zeroArray(lastFieldType) } } case TagConstType, TagVolatileType, TagRestrictType: // Type modifier (DWARF v2 §5.2) // Attributes: // AttrType: subtype t := new(QualType) t.Name, _ = e.Val(AttrName).(string) t.ReflectKind = getKind(e) typ = t typeCache[off] = t if t.Type = typeOf(e, AttrType); err != nil { goto Error } switch e.Tag { case TagConstType: t.Qual = "const" case TagRestrictType: t.Qual = "restrict" case TagVolatileType: t.Qual = "volatile" } case TagEnumerationType: // Enumeration type (DWARF v2 §5.6) // Attributes: // AttrName: enum name if any // AttrByteSize: bytes required to represent largest value // Children: // TagEnumerator: // AttrName: name of constant // AttrConstValue: value of constant t := new(EnumType) t.ReflectKind = getKind(e) typ = t typeCache[off] = t t.Name, _ = e.Val(AttrName).(string) t.EnumName, _ = e.Val(AttrName).(string) t.Val = make([]*EnumValue, 0, 8) for kid := next(); kid != nil; kid = next() { if kid.Tag == TagEnumerator { f := new(EnumValue) f.Name, _ = kid.Val(AttrName).(string) f.Val, _ = kid.Val(AttrConstValue).(int64) n := len(t.Val) if n >= cap(t.Val) { val := make([]*EnumValue, n, n*2) copy(val, t.Val) t.Val = val } t.Val = t.Val[0 : n+1] t.Val[n] = f } } case TagPointerType: // Type modifier (DWARF v2 §5.2) // Attributes: // AttrType: subtype [not required! void* has no AttrType] // AttrAddrClass: address class [ignored] t := new(PtrType) t.Name, _ = e.Val(AttrName).(string) t.ReflectKind = getKind(e) typ = t typeCache[off] = t if e.Val(AttrType) == nil { t.Type = &VoidType{} break } t.Type = typeOf(e, AttrType) case TagSubroutineType: // Subroutine type. (DWARF v2 §5.7) // Attributes: // AttrType: type of return value if any // AttrName: possible name of type [ignored] // AttrPrototyped: whether used ANSI C prototype [ignored] // Children: // TagFormalParameter: typed parameter // AttrType: type of parameter // TagUnspecifiedParameter: final ... t := new(FuncType) t.Name, _ = e.Val(AttrName).(string) t.ReflectKind = getKind(e) typ = t typeCache[off] = t if t.ReturnType = typeOf(e, AttrType); err != nil { goto Error } t.ParamType = make([]Type, 0, 8) for kid := next(); kid != nil; kid = next() { var tkid Type switch kid.Tag { default: continue case TagFormalParameter: if tkid = typeOf(kid, AttrType); err != nil { goto Error } case TagUnspecifiedParameters: tkid = &DotDotDotType{} } t.ParamType = append(t.ParamType, tkid) } case TagTypedef: // Typedef (DWARF v2 §5.3) // Also maps and channels (Go-specific). // Attributes: // AttrName: name [required] // AttrType: type definition [required] // AttrGoKey: present for maps. // AttrGoElem: present for maps and channels. t := new(TypedefType) t.ReflectKind = getKind(e) switch t.ReflectKind { case reflect.Map: m := new(MapType) m.KeyType = typeOf(e, AttrGoKey) m.ElemType = typeOf(e, AttrGoElem) t = &m.TypedefType typ = m case reflect.Chan: c := new(ChanType) c.ElemType = typeOf(e, AttrGoElem) t = &c.TypedefType typ = c case reflect.Interface: it := new(InterfaceType) t = &it.TypedefType typ = it default: typ = t } typeCache[off] = typ t.Name, _ = e.Val(AttrName).(string) t.Type = typeOf(e, AttrType) case TagUnspecifiedType: // Unspecified type (DWARF v3 §5.2) // Attributes: // AttrName: name t := new(UnspecifiedType) typ = t typeCache[off] = t t.Name, _ = e.Val(AttrName).(string) default: err = DecodeError{name, off, "unsupported type tag"} } if err != nil { goto Error } typ.Common().Offset = off { b, ok := e.Val(AttrByteSize).(int64) if !ok { b = -1 switch t := typ.(type) { case *TypedefType: b = t.Type.Size() case *MapType: b = t.Type.Size() case *ChanType: b = t.Type.Size() case *InterfaceType: b = t.Type.Size() case *PtrType: b = int64(addressSize) } } typ.Common().ByteSize = b } return typ, nil Error: // If the parse fails, take the type out of the cache // so that the next call with this offset doesn't hit // the cache and return success. delete(typeCache, off) return nil, err } func zeroArray(t Type) { for { at, ok := t.(*ArrayType) if !ok { break } at.Count = 0 t = at.Type } } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/dwarf/type_test.go000066400000000000000000000076141356504100700276100ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package dwarf_test import ( "testing" . "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/dwarf" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/elf" ) var typedefTests = map[string]string{ "t_ptr_volatile_int": "*volatile int", "t_ptr_const_char": "*const char", "t_long": "long int", "t_ushort": "short unsigned int", "t_func_int_of_float_double": "func(float, double) int", "t_ptr_func_int_of_float_double": "*func(float, double) int", "t_ptr_func_int_of_float_complex": "*func(complex float) int", "t_ptr_func_int_of_double_complex": "*func(complex double) int", "t_ptr_func_int_of_long_double_complex": "*func(complex long double) int", "t_func_ptr_int_of_char_schar_uchar": "func(char, signed char, unsigned char) *int", "t_func_void_of_char": "func(char) void", "t_func_void_of_void": "func() void", "t_func_void_of_ptr_char_dots": "func(*char, ...) void", "t_my_struct": "struct my_struct {vi volatile int@0; x char@4 : 1@7; y int@4 : 4@27; z [0]int@8; array [40]long long int@8; zz [0]int@328}", "t_my_struct1": "struct my_struct1 {zz [1]int@0}", "t_my_union": "union my_union {vi volatile int@0; x char@0 : 1@7; y int@0 : 4@28; array [40]long long int@0}", "t_my_enum": "enum my_enum {e1=1; e2=2; e3=-5; e4=1000000000000000}", "t_my_list": "struct list {val short int@0; next *t_my_list@8}", "t_my_tree": "struct tree {left *struct tree@0; right *struct tree@8; val long long unsigned int@16}", } func elfData(t *testing.T, name string) *Data { f, err := elf.Open(name) if err != nil { t.Fatal(err) } d, err := f.DWARF() if err != nil { t.Fatal(err) } return d } func TestTypedefsELF(t *testing.T) { testTypedefs(t, elfData(t, "testdata/typedef.elf"), "elf") } func TestTypedefsELFDwarf4(t *testing.T) { testTypedefs(t, elfData(t, "testdata/typedef.elf4"), "elf") } func testTypedefs(t *testing.T, d *Data, kind string) { r := d.Reader() seen := make(map[string]bool) for { e, err := r.Next() if err != nil { t.Fatal("r.Next:", err) } if e == nil { break } if e.Tag == TagTypedef { typ, err := d.Type(e.Offset) if err != nil { t.Fatal("d.Type:", err) } t1 := typ.(*TypedefType) var typstr string if ts, ok := t1.Type.(*StructType); ok { typstr = ts.Defn() } else { typstr = t1.Type.String() } if want, ok := typedefTests[t1.Name]; ok { if seen[t1.Name] { t.Errorf("multiple definitions for %s", t1.Name) } seen[t1.Name] = true if typstr != want { t.Errorf("%s:\n\thave %s\n\twant %s", t1.Name, typstr, want) } } } if e.Tag != TagCompileUnit { r.SkipChildren() } } for k := range typedefTests { if !seen[k] { t.Errorf("missing %s", k) } } } func TestTypeForNonTypeEntry(t *testing.T) { d := elfData(t, "testdata/typedef.elf") // The returned entry will be a Subprogram. ent, err := d.LookupFunction("main") if err != nil { t.Fatal("d.LookupFunction:", err) } _, err = d.Type(ent.Offset) if err == nil { t.Fatal("nil error for unreadable entry") } } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/dwarf/typeunit.go000066400000000000000000000104121356504100700274370ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package dwarf import ( "fmt" "strconv" ) // Parse the type units stored in a DWARF4 .debug_types section. Each // type unit defines a single primary type and an 8-byte signature. // Other sections may then use formRefSig8 to refer to the type. // The typeUnit format is a single type with a signature. It holds // the same data as a compilation unit. type typeUnit struct { unit toff Offset // Offset to signature type within data. name string // Name of .debug_type section. cache Type // Cache the type, nil to start. } // Parse a .debug_types section. func (d *Data) parseTypes(name string, types []byte) error { b := makeBuf(d, unknownFormat{}, name, 0, types) for len(b.data) > 0 { base := b.off dwarf64 := false n := b.uint32() if n == 0xffffffff { n64 := b.uint64() if n64 != uint64(uint32(n64)) { b.error("type unit length overflow") return b.err } n = uint32(n64) dwarf64 = true } hdroff := b.off vers := b.uint16() if vers != 4 { b.error("unsupported DWARF version " + strconv.Itoa(int(vers))) return b.err } var ao uint32 if !dwarf64 { ao = b.uint32() } else { ao64 := b.uint64() if ao64 != uint64(uint32(ao64)) { b.error("type unit abbrev offset overflow") return b.err } ao = uint32(ao64) } atable, err := d.parseAbbrev(ao) if err != nil { return err } asize := b.uint8() sig := b.uint64() var toff uint32 if !dwarf64 { toff = b.uint32() } else { to64 := b.uint64() if to64 != uint64(uint32(to64)) { b.error("type unit type offset overflow") return b.err } toff = uint32(to64) } boff := b.off d.typeSigs[sig] = &typeUnit{ unit: unit{ base: base, off: boff, data: b.bytes(int(Offset(n) - (b.off - hdroff))), atable: atable, asize: int(asize), vers: int(vers), is64: dwarf64, }, toff: Offset(toff), name: name, } if b.err != nil { return b.err } } return nil } // Return the type for a type signature. func (d *Data) sigToType(sig uint64) (Type, error) { tu := d.typeSigs[sig] if tu == nil { return nil, fmt.Errorf("no type unit with signature %v", sig) } if tu.cache != nil { return tu.cache, nil } b := makeBuf(d, tu, tu.name, tu.off, tu.data) r := &typeUnitReader{d: d, tu: tu, b: b} t, err := d.readType(tu.name, r, Offset(tu.toff), make(map[Offset]Type)) if err != nil { return nil, err } tu.cache = t return t, nil } // typeUnitReader is a typeReader for a tagTypeUnit. type typeUnitReader struct { d *Data tu *typeUnit b buf err error } // Seek to a new position in the type unit. func (tur *typeUnitReader) Seek(off Offset) { tur.err = nil doff := off - tur.tu.off if doff < 0 || doff >= Offset(len(tur.tu.data)) { tur.err = fmt.Errorf("%s: offset %d out of range; max %d", tur.tu.name, doff, len(tur.tu.data)) return } tur.b = makeBuf(tur.d, tur.tu, tur.tu.name, off, tur.tu.data[doff:]) } // AddressSize returns the size in bytes of addresses in the current type unit. func (tur *typeUnitReader) AddressSize() int { return tur.tu.unit.asize } // Next reads the next Entry from the type unit. func (tur *typeUnitReader) Next() (*Entry, error) { if tur.err != nil { return nil, tur.err } if len(tur.tu.data) == 0 { return nil, nil } e := tur.b.entry(tur.tu.atable, tur.tu.base) if tur.b.err != nil { tur.err = tur.b.err return nil, tur.err } return e, nil } // clone returns a new reader for the type unit. func (tur *typeUnitReader) clone() typeReader { return &typeUnitReader{ d: tur.d, tu: tur.tu, b: makeBuf(tur.d, tur.tu, tur.tu.name, tur.tu.off, tur.tu.data), } } // offset returns the current offset. func (tur *typeUnitReader) offset() Offset { return tur.b.off } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/dwarf/unit.go000066400000000000000000000044461356504100700265470ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package dwarf import "strconv" // DWARF debug info is split into a sequence of compilation units. // Each unit has its own abbreviation table and address size. type unit struct { base Offset // byte offset of header within the aggregate info off Offset // byte offset of data within the aggregate info data []byte atable abbrevTable asize int vers int is64 bool // True for 64-bit DWARF format } // Implement the dataFormat interface. func (u *unit) version() int { return u.vers } func (u *unit) dwarf64() (bool, bool) { return u.is64, true } func (u *unit) addrsize() int { return u.asize } func (d *Data) parseUnits() ([]unit, error) { // Count units. nunit := 0 b := makeBuf(d, unknownFormat{}, "info", 0, d.info) for len(b.data) > 0 { len := b.uint32() if len == 0xffffffff { len64 := b.uint64() if len64 != uint64(uint32(len64)) { b.error("unit length overflow") break } len = uint32(len64) } b.skip(int(len)) nunit++ } if b.err != nil { return nil, b.err } // Again, this time writing them down. b = makeBuf(d, unknownFormat{}, "info", 0, d.info) units := make([]unit, nunit) for i := range units { u := &units[i] u.base = b.off n := b.uint32() if n == 0xffffffff { u.is64 = true n = uint32(b.uint64()) } vers := b.uint16() if vers != 2 && vers != 3 && vers != 4 { b.error("unsupported DWARF version " + strconv.Itoa(int(vers))) break } u.vers = int(vers) atable, err := d.parseAbbrev(b.uint32()) if err != nil { if b.err == nil { b.err = err } break } u.atable = atable u.asize = int(b.uint8()) u.off = b.off u.data = b.bytes(int(n - (2 + 4 + 1))) } if b.err != nil { return nil, b.err } return units, nil } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/elf/000077500000000000000000000000001356504100700246745ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/elf/elf.go000066400000000000000000003351321356504100700260000ustar00rootroot00000000000000/* * ELF constants and data structures * * Derived from: * $FreeBSD: src/sys/sys/elf32.h,v 1.8.14.1 2005/12/30 22:13:58 marcel Exp $ * $FreeBSD: src/sys/sys/elf64.h,v 1.10.14.1 2005/12/30 22:13:58 marcel Exp $ * $FreeBSD: src/sys/sys/elf_common.h,v 1.15.8.1 2005/12/30 22:13:58 marcel Exp $ * $FreeBSD: src/sys/alpha/include/elf.h,v 1.14 2003/09/25 01:10:22 peter Exp $ * $FreeBSD: src/sys/amd64/include/elf.h,v 1.18 2004/08/03 08:21:48 dfr Exp $ * $FreeBSD: src/sys/arm/include/elf.h,v 1.5.2.1 2006/06/30 21:42:52 cognet Exp $ * $FreeBSD: src/sys/i386/include/elf.h,v 1.16 2004/08/02 19:12:17 dfr Exp $ * $FreeBSD: src/sys/powerpc/include/elf.h,v 1.7 2004/11/02 09:47:01 ssouhlal Exp $ * $FreeBSD: src/sys/sparc64/include/elf.h,v 1.12 2003/09/25 01:10:26 peter Exp $ * "System V ABI" (http://www.sco.com/developers/gabi/latest/ch4.eheader.html) * "ELF for the ARM® 64-bit Architecture (AArch64)" (ARM IHI 0056B) * "RISC-V ELF psABI specification" (https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md) * llvm/BinaryFormat/ELF.h - ELF constants and structures * * Copyright (c) 1996-1998 John D. Polstra. All rights reserved. * Copyright (c) 2001 David E. O'Brien * Portions Copyright 2018 Google LLC. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ package elf import "strconv" /* * Constants */ // Indexes into the Header.Ident array. const ( EI_CLASS = 4 /* Class of machine. */ EI_DATA = 5 /* Data format. */ EI_VERSION = 6 /* ELF format version. */ EI_OSABI = 7 /* Operating system / ABI identification */ EI_ABIVERSION = 8 /* ABI version */ EI_PAD = 9 /* Start of padding (per SVR4 ABI). */ EI_NIDENT = 16 /* Size of e_ident array. */ ) // Initial magic number for ELF files. const ELFMAG = "\177ELF" // Version is found in Header.Ident[EI_VERSION] and Header.Version. type Version byte const ( EV_NONE Version = 0 EV_CURRENT Version = 1 ) var versionStrings = []intName{ {0, "EV_NONE"}, {1, "EV_CURRENT"}, } func (i Version) String() string { return stringName(uint32(i), versionStrings, false) } func (i Version) GoString() string { return stringName(uint32(i), versionStrings, true) } // Class is found in Header.Ident[EI_CLASS] and Header.Class. type Class byte const ( ELFCLASSNONE Class = 0 /* Unknown class. */ ELFCLASS32 Class = 1 /* 32-bit architecture. */ ELFCLASS64 Class = 2 /* 64-bit architecture. */ ) var classStrings = []intName{ {0, "ELFCLASSNONE"}, {1, "ELFCLASS32"}, {2, "ELFCLASS64"}, } func (i Class) String() string { return stringName(uint32(i), classStrings, false) } func (i Class) GoString() string { return stringName(uint32(i), classStrings, true) } // Data is found in Header.Ident[EI_DATA] and Header.Data. type Data byte const ( ELFDATANONE Data = 0 /* Unknown data format. */ ELFDATA2LSB Data = 1 /* 2's complement little-endian. */ ELFDATA2MSB Data = 2 /* 2's complement big-endian. */ ) var dataStrings = []intName{ {0, "ELFDATANONE"}, {1, "ELFDATA2LSB"}, {2, "ELFDATA2MSB"}, } func (i Data) String() string { return stringName(uint32(i), dataStrings, false) } func (i Data) GoString() string { return stringName(uint32(i), dataStrings, true) } // OSABI is found in Header.Ident[EI_OSABI] and Header.OSABI. type OSABI byte const ( ELFOSABI_NONE OSABI = 0 /* UNIX System V ABI */ ELFOSABI_HPUX OSABI = 1 /* HP-UX operating system */ ELFOSABI_NETBSD OSABI = 2 /* NetBSD */ ELFOSABI_LINUX OSABI = 3 /* GNU/Linux */ ELFOSABI_HURD OSABI = 4 /* GNU/Hurd */ ELFOSABI_86OPEN OSABI = 5 /* 86Open common IA32 ABI */ ELFOSABI_SOLARIS OSABI = 6 /* Solaris */ ELFOSABI_AIX OSABI = 7 /* AIX */ ELFOSABI_IRIX OSABI = 8 /* IRIX */ ELFOSABI_FREEBSD OSABI = 9 /* FreeBSD */ ELFOSABI_TRU64 OSABI = 10 /* TRU64 UNIX */ ELFOSABI_MODESTO OSABI = 11 /* Novell Modesto */ ELFOSABI_OPENBSD OSABI = 12 /* OpenBSD */ ELFOSABI_OPENVMS OSABI = 13 /* Open VMS */ ELFOSABI_NSK OSABI = 14 /* HP Non-Stop Kernel */ ELFOSABI_AROS OSABI = 15 /* Amiga Research OS */ ELFOSABI_FENIXOS OSABI = 16 /* The FenixOS highly scalable multi-core OS */ ELFOSABI_CLOUDABI OSABI = 17 /* Nuxi CloudABI */ ELFOSABI_ARM OSABI = 97 /* ARM */ ELFOSABI_STANDALONE OSABI = 255 /* Standalone (embedded) application */ ) var osabiStrings = []intName{ {0, "ELFOSABI_NONE"}, {1, "ELFOSABI_HPUX"}, {2, "ELFOSABI_NETBSD"}, {3, "ELFOSABI_LINUX"}, {4, "ELFOSABI_HURD"}, {5, "ELFOSABI_86OPEN"}, {6, "ELFOSABI_SOLARIS"}, {7, "ELFOSABI_AIX"}, {8, "ELFOSABI_IRIX"}, {9, "ELFOSABI_FREEBSD"}, {10, "ELFOSABI_TRU64"}, {11, "ELFOSABI_MODESTO"}, {12, "ELFOSABI_OPENBSD"}, {13, "ELFOSABI_OPENVMS"}, {14, "ELFOSABI_NSK"}, {15, "ELFOSABI_AROS"}, {16, "ELFOSABI_FENIXOS"}, {17, "ELFOSABI_CLOUDABI"}, {97, "ELFOSABI_ARM"}, {255, "ELFOSABI_STANDALONE"}, } func (i OSABI) String() string { return stringName(uint32(i), osabiStrings, false) } func (i OSABI) GoString() string { return stringName(uint32(i), osabiStrings, true) } // Type is found in Header.Type. type Type uint16 const ( ET_NONE Type = 0 /* Unknown type. */ ET_REL Type = 1 /* Relocatable. */ ET_EXEC Type = 2 /* Executable. */ ET_DYN Type = 3 /* Shared object. */ ET_CORE Type = 4 /* Core file. */ ET_LOOS Type = 0xfe00 /* First operating system specific. */ ET_HIOS Type = 0xfeff /* Last operating system-specific. */ ET_LOPROC Type = 0xff00 /* First processor-specific. */ ET_HIPROC Type = 0xffff /* Last processor-specific. */ ) var typeStrings = []intName{ {0, "ET_NONE"}, {1, "ET_REL"}, {2, "ET_EXEC"}, {3, "ET_DYN"}, {4, "ET_CORE"}, {0xfe00, "ET_LOOS"}, {0xfeff, "ET_HIOS"}, {0xff00, "ET_LOPROC"}, {0xffff, "ET_HIPROC"}, } func (i Type) String() string { return stringName(uint32(i), typeStrings, false) } func (i Type) GoString() string { return stringName(uint32(i), typeStrings, true) } // Machine is found in Header.Machine. type Machine uint16 const ( EM_NONE Machine = 0 /* Unknown machine. */ EM_M32 Machine = 1 /* AT&T WE32100. */ EM_SPARC Machine = 2 /* Sun SPARC. */ EM_386 Machine = 3 /* Intel i386. */ EM_68K Machine = 4 /* Motorola 68000. */ EM_88K Machine = 5 /* Motorola 88000. */ EM_860 Machine = 7 /* Intel i860. */ EM_MIPS Machine = 8 /* MIPS R3000 Big-Endian only. */ EM_S370 Machine = 9 /* IBM System/370. */ EM_MIPS_RS3_LE Machine = 10 /* MIPS R3000 Little-Endian. */ EM_PARISC Machine = 15 /* HP PA-RISC. */ EM_VPP500 Machine = 17 /* Fujitsu VPP500. */ EM_SPARC32PLUS Machine = 18 /* SPARC v8plus. */ EM_960 Machine = 19 /* Intel 80960. */ EM_PPC Machine = 20 /* PowerPC 32-bit. */ EM_PPC64 Machine = 21 /* PowerPC 64-bit. */ EM_S390 Machine = 22 /* IBM System/390. */ EM_V800 Machine = 36 /* NEC V800. */ EM_FR20 Machine = 37 /* Fujitsu FR20. */ EM_RH32 Machine = 38 /* TRW RH-32. */ EM_RCE Machine = 39 /* Motorola RCE. */ EM_ARM Machine = 40 /* ARM. */ EM_SH Machine = 42 /* Hitachi SH. */ EM_SPARCV9 Machine = 43 /* SPARC v9 64-bit. */ EM_TRICORE Machine = 44 /* Siemens TriCore embedded processor. */ EM_ARC Machine = 45 /* Argonaut RISC Core. */ EM_H8_300 Machine = 46 /* Hitachi H8/300. */ EM_H8_300H Machine = 47 /* Hitachi H8/300H. */ EM_H8S Machine = 48 /* Hitachi H8S. */ EM_H8_500 Machine = 49 /* Hitachi H8/500. */ EM_IA_64 Machine = 50 /* Intel IA-64 Processor. */ EM_MIPS_X Machine = 51 /* Stanford MIPS-X. */ EM_COLDFIRE Machine = 52 /* Motorola ColdFire. */ EM_68HC12 Machine = 53 /* Motorola M68HC12. */ EM_MMA Machine = 54 /* Fujitsu MMA. */ EM_PCP Machine = 55 /* Siemens PCP. */ EM_NCPU Machine = 56 /* Sony nCPU. */ EM_NDR1 Machine = 57 /* Denso NDR1 microprocessor. */ EM_STARCORE Machine = 58 /* Motorola Star*Core processor. */ EM_ME16 Machine = 59 /* Toyota ME16 processor. */ EM_ST100 Machine = 60 /* STMicroelectronics ST100 processor. */ EM_TINYJ Machine = 61 /* Advanced Logic Corp. TinyJ processor. */ EM_X86_64 Machine = 62 /* Advanced Micro Devices x86-64 */ EM_PDSP Machine = 63 /* Sony DSP Processor */ EM_PDP10 Machine = 64 /* Digital Equipment Corp. PDP-10 */ EM_PDP11 Machine = 65 /* Digital Equipment Corp. PDP-11 */ EM_FX66 Machine = 66 /* Siemens FX66 microcontroller */ EM_ST9PLUS Machine = 67 /* STMicroelectronics ST9+ 8/16 bit microcontroller */ EM_ST7 Machine = 68 /* STMicroelectronics ST7 8-bit microcontroller */ EM_68HC16 Machine = 69 /* Motorola MC68HC16 Microcontroller */ EM_68HC11 Machine = 70 /* Motorola MC68HC11 Microcontroller */ EM_68HC08 Machine = 71 /* Motorola MC68HC08 Microcontroller */ EM_68HC05 Machine = 72 /* Motorola MC68HC05 Microcontroller */ EM_SVX Machine = 73 /* Silicon Graphics SVx */ EM_ST19 Machine = 74 /* STMicroelectronics ST19 8-bit microcontroller */ EM_VAX Machine = 75 /* Digital VAX */ EM_CRIS Machine = 76 /* Axis Communications 32-bit embedded processor */ EM_JAVELIN Machine = 77 /* Infineon Technologies 32-bit embedded processor */ EM_FIREPATH Machine = 78 /* Element 14 64-bit DSP Processor */ EM_ZSP Machine = 79 /* LSI Logic 16-bit DSP Processor */ EM_MMIX Machine = 80 /* Donald Knuth's educational 64-bit processor */ EM_HUANY Machine = 81 /* Harvard University machine-independent object files */ EM_PRISM Machine = 82 /* SiTera Prism */ EM_AVR Machine = 83 /* Atmel AVR 8-bit microcontroller */ EM_FR30 Machine = 84 /* Fujitsu FR30 */ EM_D10V Machine = 85 /* Mitsubishi D10V */ EM_D30V Machine = 86 /* Mitsubishi D30V */ EM_V850 Machine = 87 /* NEC v850 */ EM_M32R Machine = 88 /* Mitsubishi M32R */ EM_MN10300 Machine = 89 /* Matsushita MN10300 */ EM_MN10200 Machine = 90 /* Matsushita MN10200 */ EM_PJ Machine = 91 /* picoJava */ EM_OPENRISC Machine = 92 /* OpenRISC 32-bit embedded processor */ EM_ARC_COMPACT Machine = 93 /* ARC International ARCompact processor (old spelling/synonym: EM_ARC_A5) */ EM_XTENSA Machine = 94 /* Tensilica Xtensa Architecture */ EM_VIDEOCORE Machine = 95 /* Alphamosaic VideoCore processor */ EM_TMM_GPP Machine = 96 /* Thompson Multimedia General Purpose Processor */ EM_NS32K Machine = 97 /* National Semiconductor 32000 series */ EM_TPC Machine = 98 /* Tenor Network TPC processor */ EM_SNP1K Machine = 99 /* Trebia SNP 1000 processor */ EM_ST200 Machine = 100 /* STMicroelectronics (www.st.com) ST200 microcontroller */ EM_IP2K Machine = 101 /* Ubicom IP2xxx microcontroller family */ EM_MAX Machine = 102 /* MAX Processor */ EM_CR Machine = 103 /* National Semiconductor CompactRISC microprocessor */ EM_F2MC16 Machine = 104 /* Fujitsu F2MC16 */ EM_MSP430 Machine = 105 /* Texas Instruments embedded microcontroller msp430 */ EM_BLACKFIN Machine = 106 /* Analog Devices Blackfin (DSP) processor */ EM_SE_C33 Machine = 107 /* S1C33 Family of Seiko Epson processors */ EM_SEP Machine = 108 /* Sharp embedded microprocessor */ EM_ARCA Machine = 109 /* Arca RISC Microprocessor */ EM_UNICORE Machine = 110 /* Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University */ EM_EXCESS Machine = 111 /* eXcess: 16/32/64-bit configurable embedded CPU */ EM_DXP Machine = 112 /* Icera Semiconductor Inc. Deep Execution Processor */ EM_ALTERA_NIOS2 Machine = 113 /* Altera Nios II soft-core processor */ EM_CRX Machine = 114 /* National Semiconductor CompactRISC CRX microprocessor */ EM_XGATE Machine = 115 /* Motorola XGATE embedded processor */ EM_C166 Machine = 116 /* Infineon C16x/XC16x processor */ EM_M16C Machine = 117 /* Renesas M16C series microprocessors */ EM_DSPIC30F Machine = 118 /* Microchip Technology dsPIC30F Digital Signal Controller */ EM_CE Machine = 119 /* Freescale Communication Engine RISC core */ EM_M32C Machine = 120 /* Renesas M32C series microprocessors */ EM_TSK3000 Machine = 131 /* Altium TSK3000 core */ EM_RS08 Machine = 132 /* Freescale RS08 embedded processor */ EM_SHARC Machine = 133 /* Analog Devices SHARC family of 32-bit DSP processors */ EM_ECOG2 Machine = 134 /* Cyan Technology eCOG2 microprocessor */ EM_SCORE7 Machine = 135 /* Sunplus S+core7 RISC processor */ EM_DSP24 Machine = 136 /* New Japan Radio (NJR) 24-bit DSP Processor */ EM_VIDEOCORE3 Machine = 137 /* Broadcom VideoCore III processor */ EM_LATTICEMICO32 Machine = 138 /* RISC processor for Lattice FPGA architecture */ EM_SE_C17 Machine = 139 /* Seiko Epson C17 family */ EM_TI_C6000 Machine = 140 /* The Texas Instruments TMS320C6000 DSP family */ EM_TI_C2000 Machine = 141 /* The Texas Instruments TMS320C2000 DSP family */ EM_TI_C5500 Machine = 142 /* The Texas Instruments TMS320C55x DSP family */ EM_TI_ARP32 Machine = 143 /* Texas Instruments Application Specific RISC Processor, 32bit fetch */ EM_TI_PRU Machine = 144 /* Texas Instruments Programmable Realtime Unit */ EM_MMDSP_PLUS Machine = 160 /* STMicroelectronics 64bit VLIW Data Signal Processor */ EM_CYPRESS_M8C Machine = 161 /* Cypress M8C microprocessor */ EM_R32C Machine = 162 /* Renesas R32C series microprocessors */ EM_TRIMEDIA Machine = 163 /* NXP Semiconductors TriMedia architecture family */ EM_QDSP6 Machine = 164 /* QUALCOMM DSP6 Processor */ EM_8051 Machine = 165 /* Intel 8051 and variants */ EM_STXP7X Machine = 166 /* STMicroelectronics STxP7x family of configurable and extensible RISC processors */ EM_NDS32 Machine = 167 /* Andes Technology compact code size embedded RISC processor family */ EM_ECOG1 Machine = 168 /* Cyan Technology eCOG1X family */ EM_ECOG1X Machine = 168 /* Cyan Technology eCOG1X family */ EM_MAXQ30 Machine = 169 /* Dallas Semiconductor MAXQ30 Core Micro-controllers */ EM_XIMO16 Machine = 170 /* New Japan Radio (NJR) 16-bit DSP Processor */ EM_MANIK Machine = 171 /* M2000 Reconfigurable RISC Microprocessor */ EM_CRAYNV2 Machine = 172 /* Cray Inc. NV2 vector architecture */ EM_RX Machine = 173 /* Renesas RX family */ EM_METAG Machine = 174 /* Imagination Technologies META processor architecture */ EM_MCST_ELBRUS Machine = 175 /* MCST Elbrus general purpose hardware architecture */ EM_ECOG16 Machine = 176 /* Cyan Technology eCOG16 family */ EM_CR16 Machine = 177 /* National Semiconductor CompactRISC CR16 16-bit microprocessor */ EM_ETPU Machine = 178 /* Freescale Extended Time Processing Unit */ EM_SLE9X Machine = 179 /* Infineon Technologies SLE9X core */ EM_L10M Machine = 180 /* Intel L10M */ EM_K10M Machine = 181 /* Intel K10M */ EM_AARCH64 Machine = 183 /* ARM 64-bit Architecture (AArch64) */ EM_AVR32 Machine = 185 /* Atmel Corporation 32-bit microprocessor family */ EM_STM8 Machine = 186 /* STMicroeletronics STM8 8-bit microcontroller */ EM_TILE64 Machine = 187 /* Tilera TILE64 multicore architecture family */ EM_TILEPRO Machine = 188 /* Tilera TILEPro multicore architecture family */ EM_MICROBLAZE Machine = 189 /* Xilinx MicroBlaze 32-bit RISC soft processor core */ EM_CUDA Machine = 190 /* NVIDIA CUDA architecture */ EM_TILEGX Machine = 191 /* Tilera TILE-Gx multicore architecture family */ EM_CLOUDSHIELD Machine = 192 /* CloudShield architecture family */ EM_COREA_1ST Machine = 193 /* KIPO-KAIST Core-A 1st generation processor family */ EM_COREA_2ND Machine = 194 /* KIPO-KAIST Core-A 2nd generation processor family */ EM_ARC_COMPACT2 Machine = 195 /* Synopsys ARCompact V2 */ EM_OPEN8 Machine = 196 /* Open8 8-bit RISC soft processor core */ EM_RL78 Machine = 197 /* Renesas RL78 family */ EM_VIDEOCORE5 Machine = 198 /* Broadcom VideoCore V processor */ EM_78KOR Machine = 199 /* Renesas 78KOR family */ EM_56800EX Machine = 200 /* Freescale 56800EX Digital Signal Controller (DSC) */ EM_BA1 Machine = 201 /* Beyond BA1 CPU architecture */ EM_BA2 Machine = 202 /* Beyond BA2 CPU architecture */ EM_XCORE Machine = 203 /* XMOS xCORE processor family */ EM_MCHP_PIC Machine = 204 /* Microchip 8-bit PIC(r) family */ EM_INTEL205 Machine = 205 /* Reserved by Intel */ EM_INTEL206 Machine = 206 /* Reserved by Intel */ EM_INTEL207 Machine = 207 /* Reserved by Intel */ EM_INTEL208 Machine = 208 /* Reserved by Intel */ EM_INTEL209 Machine = 209 /* Reserved by Intel */ EM_KM32 Machine = 210 /* KM211 KM32 32-bit processor */ EM_KMX32 Machine = 211 /* KM211 KMX32 32-bit processor */ EM_KMX16 Machine = 212 /* KM211 KMX16 16-bit processor */ EM_KMX8 Machine = 213 /* KM211 KMX8 8-bit processor */ EM_KVARC Machine = 214 /* KM211 KVARC processor */ EM_CDP Machine = 215 /* Paneve CDP architecture family */ EM_COGE Machine = 216 /* Cognitive Smart Memory Processor */ EM_COOL Machine = 217 /* Bluechip Systems CoolEngine */ EM_NORC Machine = 218 /* Nanoradio Optimized RISC */ EM_CSR_KALIMBA Machine = 219 /* CSR Kalimba architecture family */ EM_Z80 Machine = 220 /* Zilog Z80 */ EM_VISIUM Machine = 221 /* Controls and Data Services VISIUMcore processor */ EM_FT32 Machine = 222 /* FTDI Chip FT32 high performance 32-bit RISC architecture */ EM_MOXIE Machine = 223 /* Moxie processor family */ EM_AMDGPU Machine = 224 /* AMD GPU architecture */ EM_RISCV Machine = 243 /* RISC-V */ EM_LANAI Machine = 244 /* Lanai 32-bit processor */ EM_BPF Machine = 247 /* Linux BPF – in-kernel virtual machine */ /* Non-standard or deprecated. */ EM_486 Machine = 6 /* Intel i486. */ EM_MIPS_RS4_BE Machine = 10 /* MIPS R4000 Big-Endian */ EM_ALPHA_STD Machine = 41 /* Digital Alpha (standard value). */ EM_ALPHA Machine = 0x9026 /* Alpha (written in the absence of an ABI) */ ) var machineStrings = []intName{ {0, "EM_NONE"}, {1, "EM_M32"}, {2, "EM_SPARC"}, {3, "EM_386"}, {4, "EM_68K"}, {5, "EM_88K"}, {7, "EM_860"}, {8, "EM_MIPS"}, {9, "EM_S370"}, {10, "EM_MIPS_RS3_LE"}, {15, "EM_PARISC"}, {17, "EM_VPP500"}, {18, "EM_SPARC32PLUS"}, {19, "EM_960"}, {20, "EM_PPC"}, {21, "EM_PPC64"}, {22, "EM_S390"}, {36, "EM_V800"}, {37, "EM_FR20"}, {38, "EM_RH32"}, {39, "EM_RCE"}, {40, "EM_ARM"}, {42, "EM_SH"}, {43, "EM_SPARCV9"}, {44, "EM_TRICORE"}, {45, "EM_ARC"}, {46, "EM_H8_300"}, {47, "EM_H8_300H"}, {48, "EM_H8S"}, {49, "EM_H8_500"}, {50, "EM_IA_64"}, {51, "EM_MIPS_X"}, {52, "EM_COLDFIRE"}, {53, "EM_68HC12"}, {54, "EM_MMA"}, {55, "EM_PCP"}, {56, "EM_NCPU"}, {57, "EM_NDR1"}, {58, "EM_STARCORE"}, {59, "EM_ME16"}, {60, "EM_ST100"}, {61, "EM_TINYJ"}, {62, "EM_X86_64"}, {63, "EM_PDSP"}, {64, "EM_PDP10"}, {65, "EM_PDP11"}, {66, "EM_FX66"}, {67, "EM_ST9PLUS"}, {68, "EM_ST7"}, {69, "EM_68HC16"}, {70, "EM_68HC11"}, {71, "EM_68HC08"}, {72, "EM_68HC05"}, {73, "EM_SVX"}, {74, "EM_ST19"}, {75, "EM_VAX"}, {76, "EM_CRIS"}, {77, "EM_JAVELIN"}, {78, "EM_FIREPATH"}, {79, "EM_ZSP"}, {80, "EM_MMIX"}, {81, "EM_HUANY"}, {82, "EM_PRISM"}, {83, "EM_AVR"}, {84, "EM_FR30"}, {85, "EM_D10V"}, {86, "EM_D30V"}, {87, "EM_V850"}, {88, "EM_M32R"}, {89, "EM_MN10300"}, {90, "EM_MN10200"}, {91, "EM_PJ"}, {92, "EM_OPENRISC"}, {93, "EM_ARC_COMPACT"}, {94, "EM_XTENSA"}, {95, "EM_VIDEOCORE"}, {96, "EM_TMM_GPP"}, {97, "EM_NS32K"}, {98, "EM_TPC"}, {99, "EM_SNP1K"}, {100, "EM_ST200"}, {101, "EM_IP2K"}, {102, "EM_MAX"}, {103, "EM_CR"}, {104, "EM_F2MC16"}, {105, "EM_MSP430"}, {106, "EM_BLACKFIN"}, {107, "EM_SE_C33"}, {108, "EM_SEP"}, {109, "EM_ARCA"}, {110, "EM_UNICORE"}, {111, "EM_EXCESS"}, {112, "EM_DXP"}, {113, "EM_ALTERA_NIOS2"}, {114, "EM_CRX"}, {115, "EM_XGATE"}, {116, "EM_C166"}, {117, "EM_M16C"}, {118, "EM_DSPIC30F"}, {119, "EM_CE"}, {120, "EM_M32C"}, {131, "EM_TSK3000"}, {132, "EM_RS08"}, {133, "EM_SHARC"}, {134, "EM_ECOG2"}, {135, "EM_SCORE7"}, {136, "EM_DSP24"}, {137, "EM_VIDEOCORE3"}, {138, "EM_LATTICEMICO32"}, {139, "EM_SE_C17"}, {140, "EM_TI_C6000"}, {141, "EM_TI_C2000"}, {142, "EM_TI_C5500"}, {143, "EM_TI_ARP32"}, {144, "EM_TI_PRU"}, {160, "EM_MMDSP_PLUS"}, {161, "EM_CYPRESS_M8C"}, {162, "EM_R32C"}, {163, "EM_TRIMEDIA"}, {164, "EM_QDSP6"}, {165, "EM_8051"}, {166, "EM_STXP7X"}, {167, "EM_NDS32"}, {168, "EM_ECOG1"}, {168, "EM_ECOG1X"}, {169, "EM_MAXQ30"}, {170, "EM_XIMO16"}, {171, "EM_MANIK"}, {172, "EM_CRAYNV2"}, {173, "EM_RX"}, {174, "EM_METAG"}, {175, "EM_MCST_ELBRUS"}, {176, "EM_ECOG16"}, {177, "EM_CR16"}, {178, "EM_ETPU"}, {179, "EM_SLE9X"}, {180, "EM_L10M"}, {181, "EM_K10M"}, {183, "EM_AARCH64"}, {185, "EM_AVR32"}, {186, "EM_STM8"}, {187, "EM_TILE64"}, {188, "EM_TILEPRO"}, {189, "EM_MICROBLAZE"}, {190, "EM_CUDA"}, {191, "EM_TILEGX"}, {192, "EM_CLOUDSHIELD"}, {193, "EM_COREA_1ST"}, {194, "EM_COREA_2ND"}, {195, "EM_ARC_COMPACT2"}, {196, "EM_OPEN8"}, {197, "EM_RL78"}, {198, "EM_VIDEOCORE5"}, {199, "EM_78KOR"}, {200, "EM_56800EX"}, {201, "EM_BA1"}, {202, "EM_BA2"}, {203, "EM_XCORE"}, {204, "EM_MCHP_PIC"}, {205, "EM_INTEL205"}, {206, "EM_INTEL206"}, {207, "EM_INTEL207"}, {208, "EM_INTEL208"}, {209, "EM_INTEL209"}, {210, "EM_KM32"}, {211, "EM_KMX32"}, {212, "EM_KMX16"}, {213, "EM_KMX8"}, {214, "EM_KVARC"}, {215, "EM_CDP"}, {216, "EM_COGE"}, {217, "EM_COOL"}, {218, "EM_NORC"}, {219, "EM_CSR_KALIMBA "}, {220, "EM_Z80 "}, {221, "EM_VISIUM "}, {222, "EM_FT32 "}, {223, "EM_MOXIE"}, {224, "EM_AMDGPU"}, {243, "EM_RISCV"}, {244, "EM_LANAI"}, {247, "EM_BPF"}, /* Non-standard or deprecated. */ {6, "EM_486"}, {10, "EM_MIPS_RS4_BE"}, {41, "EM_ALPHA_STD"}, {0x9026, "EM_ALPHA"}, } func (i Machine) String() string { return stringName(uint32(i), machineStrings, false) } func (i Machine) GoString() string { return stringName(uint32(i), machineStrings, true) } // Special section indices. type SectionIndex int const ( SHN_UNDEF SectionIndex = 0 /* Undefined, missing, irrelevant. */ SHN_LORESERVE SectionIndex = 0xff00 /* First of reserved range. */ SHN_LOPROC SectionIndex = 0xff00 /* First processor-specific. */ SHN_HIPROC SectionIndex = 0xff1f /* Last processor-specific. */ SHN_LOOS SectionIndex = 0xff20 /* First operating system-specific. */ SHN_HIOS SectionIndex = 0xff3f /* Last operating system-specific. */ SHN_ABS SectionIndex = 0xfff1 /* Absolute values. */ SHN_COMMON SectionIndex = 0xfff2 /* Common data. */ SHN_XINDEX SectionIndex = 0xffff /* Escape; index stored elsewhere. */ SHN_HIRESERVE SectionIndex = 0xffff /* Last of reserved range. */ ) var shnStrings = []intName{ {0, "SHN_UNDEF"}, {0xff00, "SHN_LOPROC"}, {0xff20, "SHN_LOOS"}, {0xfff1, "SHN_ABS"}, {0xfff2, "SHN_COMMON"}, {0xffff, "SHN_XINDEX"}, } func (i SectionIndex) String() string { return stringName(uint32(i), shnStrings, false) } func (i SectionIndex) GoString() string { return stringName(uint32(i), shnStrings, true) } // Section type. type SectionType uint32 const ( SHT_NULL SectionType = 0 /* inactive */ SHT_PROGBITS SectionType = 1 /* program defined information */ SHT_SYMTAB SectionType = 2 /* symbol table section */ SHT_STRTAB SectionType = 3 /* string table section */ SHT_RELA SectionType = 4 /* relocation section with addends */ SHT_HASH SectionType = 5 /* symbol hash table section */ SHT_DYNAMIC SectionType = 6 /* dynamic section */ SHT_NOTE SectionType = 7 /* note section */ SHT_NOBITS SectionType = 8 /* no space section */ SHT_REL SectionType = 9 /* relocation section - no addends */ SHT_SHLIB SectionType = 10 /* reserved - purpose unknown */ SHT_DYNSYM SectionType = 11 /* dynamic symbol table section */ SHT_INIT_ARRAY SectionType = 14 /* Initialization function pointers. */ SHT_FINI_ARRAY SectionType = 15 /* Termination function pointers. */ SHT_PREINIT_ARRAY SectionType = 16 /* Pre-initialization function ptrs. */ SHT_GROUP SectionType = 17 /* Section group. */ SHT_SYMTAB_SHNDX SectionType = 18 /* Section indexes (see SHN_XINDEX). */ SHT_LOOS SectionType = 0x60000000 /* First of OS specific semantics */ SHT_GNU_ATTRIBUTES SectionType = 0x6ffffff5 /* GNU object attributes */ SHT_GNU_HASH SectionType = 0x6ffffff6 /* GNU hash table */ SHT_GNU_LIBLIST SectionType = 0x6ffffff7 /* GNU prelink library list */ SHT_GNU_VERDEF SectionType = 0x6ffffffd /* GNU version definition section */ SHT_GNU_VERNEED SectionType = 0x6ffffffe /* GNU version needs section */ SHT_GNU_VERSYM SectionType = 0x6fffffff /* GNU version symbol table */ SHT_HIOS SectionType = 0x6fffffff /* Last of OS specific semantics */ SHT_LOPROC SectionType = 0x70000000 /* reserved range for processor */ SHT_HIPROC SectionType = 0x7fffffff /* specific section header types */ SHT_LOUSER SectionType = 0x80000000 /* reserved range for application */ SHT_HIUSER SectionType = 0xffffffff /* specific indexes */ ) var shtStrings = []intName{ {0, "SHT_NULL"}, {1, "SHT_PROGBITS"}, {2, "SHT_SYMTAB"}, {3, "SHT_STRTAB"}, {4, "SHT_RELA"}, {5, "SHT_HASH"}, {6, "SHT_DYNAMIC"}, {7, "SHT_NOTE"}, {8, "SHT_NOBITS"}, {9, "SHT_REL"}, {10, "SHT_SHLIB"}, {11, "SHT_DYNSYM"}, {14, "SHT_INIT_ARRAY"}, {15, "SHT_FINI_ARRAY"}, {16, "SHT_PREINIT_ARRAY"}, {17, "SHT_GROUP"}, {18, "SHT_SYMTAB_SHNDX"}, {0x60000000, "SHT_LOOS"}, {0x6ffffff5, "SHT_GNU_ATTRIBUTES"}, {0x6ffffff6, "SHT_GNU_HASH"}, {0x6ffffff7, "SHT_GNU_LIBLIST"}, {0x6ffffffd, "SHT_GNU_VERDEF"}, {0x6ffffffe, "SHT_GNU_VERNEED"}, {0x6fffffff, "SHT_GNU_VERSYM"}, {0x70000000, "SHT_LOPROC"}, {0x7fffffff, "SHT_HIPROC"}, {0x80000000, "SHT_LOUSER"}, {0xffffffff, "SHT_HIUSER"}, } func (i SectionType) String() string { return stringName(uint32(i), shtStrings, false) } func (i SectionType) GoString() string { return stringName(uint32(i), shtStrings, true) } // Section flags. type SectionFlag uint32 const ( SHF_WRITE SectionFlag = 0x1 /* Section contains writable data. */ SHF_ALLOC SectionFlag = 0x2 /* Section occupies memory. */ SHF_EXECINSTR SectionFlag = 0x4 /* Section contains instructions. */ SHF_MERGE SectionFlag = 0x10 /* Section may be merged. */ SHF_STRINGS SectionFlag = 0x20 /* Section contains strings. */ SHF_INFO_LINK SectionFlag = 0x40 /* sh_info holds section index. */ SHF_LINK_ORDER SectionFlag = 0x80 /* Special ordering requirements. */ SHF_OS_NONCONFORMING SectionFlag = 0x100 /* OS-specific processing required. */ SHF_GROUP SectionFlag = 0x200 /* Member of section group. */ SHF_TLS SectionFlag = 0x400 /* Section contains TLS data. */ SHF_COMPRESSED SectionFlag = 0x800 /* Section is compressed. */ SHF_MASKOS SectionFlag = 0x0ff00000 /* OS-specific semantics. */ SHF_MASKPROC SectionFlag = 0xf0000000 /* Processor-specific semantics. */ ) var shfStrings = []intName{ {0x1, "SHF_WRITE"}, {0x2, "SHF_ALLOC"}, {0x4, "SHF_EXECINSTR"}, {0x10, "SHF_MERGE"}, {0x20, "SHF_STRINGS"}, {0x40, "SHF_INFO_LINK"}, {0x80, "SHF_LINK_ORDER"}, {0x100, "SHF_OS_NONCONFORMING"}, {0x200, "SHF_GROUP"}, {0x400, "SHF_TLS"}, {0x800, "SHF_COMPRESSED"}, } func (i SectionFlag) String() string { return flagName(uint32(i), shfStrings, false) } func (i SectionFlag) GoString() string { return flagName(uint32(i), shfStrings, true) } // Section compression type. type CompressionType int const ( COMPRESS_ZLIB CompressionType = 1 /* ZLIB compression. */ COMPRESS_LOOS CompressionType = 0x60000000 /* First OS-specific. */ COMPRESS_HIOS CompressionType = 0x6fffffff /* Last OS-specific. */ COMPRESS_LOPROC CompressionType = 0x70000000 /* First processor-specific type. */ COMPRESS_HIPROC CompressionType = 0x7fffffff /* Last processor-specific type. */ ) var compressionStrings = []intName{ {0, "COMPRESS_ZLIB"}, {0x60000000, "COMPRESS_LOOS"}, {0x6fffffff, "COMPRESS_HIOS"}, {0x70000000, "COMPRESS_LOPROC"}, {0x7fffffff, "COMPRESS_HIPROC"}, } func (i CompressionType) String() string { return stringName(uint32(i), compressionStrings, false) } func (i CompressionType) GoString() string { return stringName(uint32(i), compressionStrings, true) } // Prog.Type type ProgType int const ( PT_NULL ProgType = 0 /* Unused entry. */ PT_LOAD ProgType = 1 /* Loadable segment. */ PT_DYNAMIC ProgType = 2 /* Dynamic linking information segment. */ PT_INTERP ProgType = 3 /* Pathname of interpreter. */ PT_NOTE ProgType = 4 /* Auxiliary information. */ PT_SHLIB ProgType = 5 /* Reserved (not used). */ PT_PHDR ProgType = 6 /* Location of program header itself. */ PT_TLS ProgType = 7 /* Thread local storage segment */ PT_LOOS ProgType = 0x60000000 /* First OS-specific. */ PT_HIOS ProgType = 0x6fffffff /* Last OS-specific. */ PT_LOPROC ProgType = 0x70000000 /* First processor-specific type. */ PT_HIPROC ProgType = 0x7fffffff /* Last processor-specific type. */ ) var ptStrings = []intName{ {0, "PT_NULL"}, {1, "PT_LOAD"}, {2, "PT_DYNAMIC"}, {3, "PT_INTERP"}, {4, "PT_NOTE"}, {5, "PT_SHLIB"}, {6, "PT_PHDR"}, {7, "PT_TLS"}, {0x60000000, "PT_LOOS"}, {0x6fffffff, "PT_HIOS"}, {0x70000000, "PT_LOPROC"}, {0x7fffffff, "PT_HIPROC"}, } func (i ProgType) String() string { return stringName(uint32(i), ptStrings, false) } func (i ProgType) GoString() string { return stringName(uint32(i), ptStrings, true) } // Prog.Flag type ProgFlag uint32 const ( PF_X ProgFlag = 0x1 /* Executable. */ PF_W ProgFlag = 0x2 /* Writable. */ PF_R ProgFlag = 0x4 /* Readable. */ PF_MASKOS ProgFlag = 0x0ff00000 /* Operating system-specific. */ PF_MASKPROC ProgFlag = 0xf0000000 /* Processor-specific. */ ) var pfStrings = []intName{ {0x1, "PF_X"}, {0x2, "PF_W"}, {0x4, "PF_R"}, } func (i ProgFlag) String() string { return flagName(uint32(i), pfStrings, false) } func (i ProgFlag) GoString() string { return flagName(uint32(i), pfStrings, true) } // Dyn.Tag type DynTag int const ( DT_NULL DynTag = 0 /* Terminating entry. */ DT_NEEDED DynTag = 1 /* String table offset of a needed shared library. */ DT_PLTRELSZ DynTag = 2 /* Total size in bytes of PLT relocations. */ DT_PLTGOT DynTag = 3 /* Processor-dependent address. */ DT_HASH DynTag = 4 /* Address of symbol hash table. */ DT_STRTAB DynTag = 5 /* Address of string table. */ DT_SYMTAB DynTag = 6 /* Address of symbol table. */ DT_RELA DynTag = 7 /* Address of ElfNN_Rela relocations. */ DT_RELASZ DynTag = 8 /* Total size of ElfNN_Rela relocations. */ DT_RELAENT DynTag = 9 /* Size of each ElfNN_Rela relocation entry. */ DT_STRSZ DynTag = 10 /* Size of string table. */ DT_SYMENT DynTag = 11 /* Size of each symbol table entry. */ DT_INIT DynTag = 12 /* Address of initialization function. */ DT_FINI DynTag = 13 /* Address of finalization function. */ DT_SONAME DynTag = 14 /* String table offset of shared object name. */ DT_RPATH DynTag = 15 /* String table offset of library path. [sup] */ DT_SYMBOLIC DynTag = 16 /* Indicates "symbolic" linking. [sup] */ DT_REL DynTag = 17 /* Address of ElfNN_Rel relocations. */ DT_RELSZ DynTag = 18 /* Total size of ElfNN_Rel relocations. */ DT_RELENT DynTag = 19 /* Size of each ElfNN_Rel relocation. */ DT_PLTREL DynTag = 20 /* Type of relocation used for PLT. */ DT_DEBUG DynTag = 21 /* Reserved (not used). */ DT_TEXTREL DynTag = 22 /* Indicates there may be relocations in non-writable segments. [sup] */ DT_JMPREL DynTag = 23 /* Address of PLT relocations. */ DT_BIND_NOW DynTag = 24 /* [sup] */ DT_INIT_ARRAY DynTag = 25 /* Address of the array of pointers to initialization functions */ DT_FINI_ARRAY DynTag = 26 /* Address of the array of pointers to termination functions */ DT_INIT_ARRAYSZ DynTag = 27 /* Size in bytes of the array of initialization functions. */ DT_FINI_ARRAYSZ DynTag = 28 /* Size in bytes of the array of termination functions. */ DT_RUNPATH DynTag = 29 /* String table offset of a null-terminated library search path string. */ DT_FLAGS DynTag = 30 /* Object specific flag values. */ DT_ENCODING DynTag = 32 /* Values greater than or equal to DT_ENCODING and less than DT_LOOS follow the rules for the interpretation of the d_un union as follows: even == 'd_ptr', even == 'd_val' or none */ DT_PREINIT_ARRAY DynTag = 32 /* Address of the array of pointers to pre-initialization functions. */ DT_PREINIT_ARRAYSZ DynTag = 33 /* Size in bytes of the array of pre-initialization functions. */ DT_LOOS DynTag = 0x6000000d /* First OS-specific */ DT_HIOS DynTag = 0x6ffff000 /* Last OS-specific */ DT_VERSYM DynTag = 0x6ffffff0 DT_VERNEED DynTag = 0x6ffffffe DT_VERNEEDNUM DynTag = 0x6fffffff DT_LOPROC DynTag = 0x70000000 /* First processor-specific type. */ DT_HIPROC DynTag = 0x7fffffff /* Last processor-specific type. */ ) var dtStrings = []intName{ {0, "DT_NULL"}, {1, "DT_NEEDED"}, {2, "DT_PLTRELSZ"}, {3, "DT_PLTGOT"}, {4, "DT_HASH"}, {5, "DT_STRTAB"}, {6, "DT_SYMTAB"}, {7, "DT_RELA"}, {8, "DT_RELASZ"}, {9, "DT_RELAENT"}, {10, "DT_STRSZ"}, {11, "DT_SYMENT"}, {12, "DT_INIT"}, {13, "DT_FINI"}, {14, "DT_SONAME"}, {15, "DT_RPATH"}, {16, "DT_SYMBOLIC"}, {17, "DT_REL"}, {18, "DT_RELSZ"}, {19, "DT_RELENT"}, {20, "DT_PLTREL"}, {21, "DT_DEBUG"}, {22, "DT_TEXTREL"}, {23, "DT_JMPREL"}, {24, "DT_BIND_NOW"}, {25, "DT_INIT_ARRAY"}, {26, "DT_FINI_ARRAY"}, {27, "DT_INIT_ARRAYSZ"}, {28, "DT_FINI_ARRAYSZ"}, {29, "DT_RUNPATH"}, {30, "DT_FLAGS"}, {32, "DT_ENCODING"}, {32, "DT_PREINIT_ARRAY"}, {33, "DT_PREINIT_ARRAYSZ"}, {0x6000000d, "DT_LOOS"}, {0x6ffff000, "DT_HIOS"}, {0x6ffffff0, "DT_VERSYM"}, {0x6ffffffe, "DT_VERNEED"}, {0x6fffffff, "DT_VERNEEDNUM"}, {0x70000000, "DT_LOPROC"}, {0x7fffffff, "DT_HIPROC"}, } func (i DynTag) String() string { return stringName(uint32(i), dtStrings, false) } func (i DynTag) GoString() string { return stringName(uint32(i), dtStrings, true) } // DT_FLAGS values. type DynFlag int const ( DF_ORIGIN DynFlag = 0x0001 /* Indicates that the object being loaded may make reference to the $ORIGIN substitution string */ DF_SYMBOLIC DynFlag = 0x0002 /* Indicates "symbolic" linking. */ DF_TEXTREL DynFlag = 0x0004 /* Indicates there may be relocations in non-writable segments. */ DF_BIND_NOW DynFlag = 0x0008 /* Indicates that the dynamic linker should process all relocations for the object containing this entry before transferring control to the program. */ DF_STATIC_TLS DynFlag = 0x0010 /* Indicates that the shared object or executable contains code using a static thread-local storage scheme. */ ) var dflagStrings = []intName{ {0x0001, "DF_ORIGIN"}, {0x0002, "DF_SYMBOLIC"}, {0x0004, "DF_TEXTREL"}, {0x0008, "DF_BIND_NOW"}, {0x0010, "DF_STATIC_TLS"}, } func (i DynFlag) String() string { return flagName(uint32(i), dflagStrings, false) } func (i DynFlag) GoString() string { return flagName(uint32(i), dflagStrings, true) } // NType values; used in core files. type NType int const ( NT_PRSTATUS NType = 1 /* Process status. */ NT_FPREGSET NType = 2 /* Floating point registers. */ NT_PRPSINFO NType = 3 /* Process state info. */ ) var ntypeStrings = []intName{ {1, "NT_PRSTATUS"}, {2, "NT_FPREGSET"}, {3, "NT_PRPSINFO"}, } func (i NType) String() string { return stringName(uint32(i), ntypeStrings, false) } func (i NType) GoString() string { return stringName(uint32(i), ntypeStrings, true) } /* Symbol Binding - ELFNN_ST_BIND - st_info */ type SymBind int const ( STB_LOCAL SymBind = 0 /* Local symbol */ STB_GLOBAL SymBind = 1 /* Global symbol */ STB_WEAK SymBind = 2 /* like global - lower precedence */ STB_LOOS SymBind = 10 /* Reserved range for operating system */ STB_HIOS SymBind = 12 /* specific semantics. */ STB_LOPROC SymBind = 13 /* reserved range for processor */ STB_HIPROC SymBind = 15 /* specific semantics. */ ) var stbStrings = []intName{ {0, "STB_LOCAL"}, {1, "STB_GLOBAL"}, {2, "STB_WEAK"}, {10, "STB_LOOS"}, {12, "STB_HIOS"}, {13, "STB_LOPROC"}, {15, "STB_HIPROC"}, } func (i SymBind) String() string { return stringName(uint32(i), stbStrings, false) } func (i SymBind) GoString() string { return stringName(uint32(i), stbStrings, true) } /* Symbol type - ELFNN_ST_TYPE - st_info */ type SymType int const ( STT_NOTYPE SymType = 0 /* Unspecified type. */ STT_OBJECT SymType = 1 /* Data object. */ STT_FUNC SymType = 2 /* Function. */ STT_SECTION SymType = 3 /* Section. */ STT_FILE SymType = 4 /* Source file. */ STT_COMMON SymType = 5 /* Uninitialized common block. */ STT_TLS SymType = 6 /* TLS object. */ STT_LOOS SymType = 10 /* Reserved range for operating system */ STT_HIOS SymType = 12 /* specific semantics. */ STT_LOPROC SymType = 13 /* reserved range for processor */ STT_HIPROC SymType = 15 /* specific semantics. */ ) var sttStrings = []intName{ {0, "STT_NOTYPE"}, {1, "STT_OBJECT"}, {2, "STT_FUNC"}, {3, "STT_SECTION"}, {4, "STT_FILE"}, {5, "STT_COMMON"}, {6, "STT_TLS"}, {10, "STT_LOOS"}, {12, "STT_HIOS"}, {13, "STT_LOPROC"}, {15, "STT_HIPROC"}, } func (i SymType) String() string { return stringName(uint32(i), sttStrings, false) } func (i SymType) GoString() string { return stringName(uint32(i), sttStrings, true) } /* Symbol visibility - ELFNN_ST_VISIBILITY - st_other */ type SymVis int const ( STV_DEFAULT SymVis = 0x0 /* Default visibility (see binding). */ STV_INTERNAL SymVis = 0x1 /* Special meaning in relocatable objects. */ STV_HIDDEN SymVis = 0x2 /* Not visible. */ STV_PROTECTED SymVis = 0x3 /* Visible but not preemptible. */ ) var stvStrings = []intName{ {0x0, "STV_DEFAULT"}, {0x1, "STV_INTERNAL"}, {0x2, "STV_HIDDEN"}, {0x3, "STV_PROTECTED"}, } func (i SymVis) String() string { return stringName(uint32(i), stvStrings, false) } func (i SymVis) GoString() string { return stringName(uint32(i), stvStrings, true) } /* * Relocation types. */ // Relocation types for x86-64. type R_X86_64 int const ( R_X86_64_NONE R_X86_64 = 0 /* No relocation. */ R_X86_64_64 R_X86_64 = 1 /* Add 64 bit symbol value. */ R_X86_64_PC32 R_X86_64 = 2 /* PC-relative 32 bit signed sym value. */ R_X86_64_GOT32 R_X86_64 = 3 /* PC-relative 32 bit GOT offset. */ R_X86_64_PLT32 R_X86_64 = 4 /* PC-relative 32 bit PLT offset. */ R_X86_64_COPY R_X86_64 = 5 /* Copy data from shared object. */ R_X86_64_GLOB_DAT R_X86_64 = 6 /* Set GOT entry to data address. */ R_X86_64_JMP_SLOT R_X86_64 = 7 /* Set GOT entry to code address. */ R_X86_64_RELATIVE R_X86_64 = 8 /* Add load address of shared object. */ R_X86_64_GOTPCREL R_X86_64 = 9 /* Add 32 bit signed pcrel offset to GOT. */ R_X86_64_32 R_X86_64 = 10 /* Add 32 bit zero extended symbol value */ R_X86_64_32S R_X86_64 = 11 /* Add 32 bit sign extended symbol value */ R_X86_64_16 R_X86_64 = 12 /* Add 16 bit zero extended symbol value */ R_X86_64_PC16 R_X86_64 = 13 /* Add 16 bit signed extended pc relative symbol value */ R_X86_64_8 R_X86_64 = 14 /* Add 8 bit zero extended symbol value */ R_X86_64_PC8 R_X86_64 = 15 /* Add 8 bit signed extended pc relative symbol value */ R_X86_64_DTPMOD64 R_X86_64 = 16 /* ID of module containing symbol */ R_X86_64_DTPOFF64 R_X86_64 = 17 /* Offset in TLS block */ R_X86_64_TPOFF64 R_X86_64 = 18 /* Offset in static TLS block */ R_X86_64_TLSGD R_X86_64 = 19 /* PC relative offset to GD GOT entry */ R_X86_64_TLSLD R_X86_64 = 20 /* PC relative offset to LD GOT entry */ R_X86_64_DTPOFF32 R_X86_64 = 21 /* Offset in TLS block */ R_X86_64_GOTTPOFF R_X86_64 = 22 /* PC relative offset to IE GOT entry */ R_X86_64_TPOFF32 R_X86_64 = 23 /* Offset in static TLS block */ R_X86_64_PC64 R_X86_64 = 24 /* PC relative 64-bit sign extended symbol value. */ R_X86_64_GOTOFF64 R_X86_64 = 25 R_X86_64_GOTPC32 R_X86_64 = 26 R_X86_64_GOT64 R_X86_64 = 27 R_X86_64_GOTPCREL64 R_X86_64 = 28 R_X86_64_GOTPC64 R_X86_64 = 29 R_X86_64_GOTPLT64 R_X86_64 = 30 R_X86_64_PLTOFF64 R_X86_64 = 31 R_X86_64_SIZE32 R_X86_64 = 32 R_X86_64_SIZE64 R_X86_64 = 33 R_X86_64_GOTPC32_TLSDESC R_X86_64 = 34 R_X86_64_TLSDESC_CALL R_X86_64 = 35 R_X86_64_TLSDESC R_X86_64 = 36 R_X86_64_IRELATIVE R_X86_64 = 37 R_X86_64_RELATIVE64 R_X86_64 = 38 R_X86_64_PC32_BND R_X86_64 = 39 R_X86_64_PLT32_BND R_X86_64 = 40 R_X86_64_GOTPCRELX R_X86_64 = 41 R_X86_64_REX_GOTPCRELX R_X86_64 = 42 ) var rx86_64Strings = []intName{ {0, "R_X86_64_NONE"}, {1, "R_X86_64_64"}, {2, "R_X86_64_PC32"}, {3, "R_X86_64_GOT32"}, {4, "R_X86_64_PLT32"}, {5, "R_X86_64_COPY"}, {6, "R_X86_64_GLOB_DAT"}, {7, "R_X86_64_JMP_SLOT"}, {8, "R_X86_64_RELATIVE"}, {9, "R_X86_64_GOTPCREL"}, {10, "R_X86_64_32"}, {11, "R_X86_64_32S"}, {12, "R_X86_64_16"}, {13, "R_X86_64_PC16"}, {14, "R_X86_64_8"}, {15, "R_X86_64_PC8"}, {16, "R_X86_64_DTPMOD64"}, {17, "R_X86_64_DTPOFF64"}, {18, "R_X86_64_TPOFF64"}, {19, "R_X86_64_TLSGD"}, {20, "R_X86_64_TLSLD"}, {21, "R_X86_64_DTPOFF32"}, {22, "R_X86_64_GOTTPOFF"}, {23, "R_X86_64_TPOFF32"}, {24, "R_X86_64_PC64"}, {25, "R_X86_64_GOTOFF64"}, {26, "R_X86_64_GOTPC32"}, {27, "R_X86_64_GOT64"}, {28, "R_X86_64_GOTPCREL64"}, {29, "R_X86_64_GOTPC64"}, {30, "R_X86_64_GOTPLT64"}, {31, "R_X86_64_PLTOFF64"}, {32, "R_X86_64_SIZE32"}, {33, "R_X86_64_SIZE64"}, {34, "R_X86_64_GOTPC32_TLSDESC"}, {35, "R_X86_64_TLSDESC_CALL"}, {36, "R_X86_64_TLSDESC"}, {37, "R_X86_64_IRELATIVE"}, {38, "R_X86_64_RELATIVE64"}, {39, "R_X86_64_PC32_BND"}, {40, "R_X86_64_PLT32_BND"}, {41, "R_X86_64_GOTPCRELX"}, {42, "R_X86_64_REX_GOTPCRELX"}, } func (i R_X86_64) String() string { return stringName(uint32(i), rx86_64Strings, false) } func (i R_X86_64) GoString() string { return stringName(uint32(i), rx86_64Strings, true) } // Relocation types for AArch64 (aka arm64) type R_AARCH64 int const ( R_AARCH64_NONE R_AARCH64 = 0 R_AARCH64_P32_ABS32 R_AARCH64 = 1 R_AARCH64_P32_ABS16 R_AARCH64 = 2 R_AARCH64_P32_PREL32 R_AARCH64 = 3 R_AARCH64_P32_PREL16 R_AARCH64 = 4 R_AARCH64_P32_MOVW_UABS_G0 R_AARCH64 = 5 R_AARCH64_P32_MOVW_UABS_G0_NC R_AARCH64 = 6 R_AARCH64_P32_MOVW_UABS_G1 R_AARCH64 = 7 R_AARCH64_P32_MOVW_SABS_G0 R_AARCH64 = 8 R_AARCH64_P32_LD_PREL_LO19 R_AARCH64 = 9 R_AARCH64_P32_ADR_PREL_LO21 R_AARCH64 = 10 R_AARCH64_P32_ADR_PREL_PG_HI21 R_AARCH64 = 11 R_AARCH64_P32_ADD_ABS_LO12_NC R_AARCH64 = 12 R_AARCH64_P32_LDST8_ABS_LO12_NC R_AARCH64 = 13 R_AARCH64_P32_LDST16_ABS_LO12_NC R_AARCH64 = 14 R_AARCH64_P32_LDST32_ABS_LO12_NC R_AARCH64 = 15 R_AARCH64_P32_LDST64_ABS_LO12_NC R_AARCH64 = 16 R_AARCH64_P32_LDST128_ABS_LO12_NC R_AARCH64 = 17 R_AARCH64_P32_TSTBR14 R_AARCH64 = 18 R_AARCH64_P32_CONDBR19 R_AARCH64 = 19 R_AARCH64_P32_JUMP26 R_AARCH64 = 20 R_AARCH64_P32_CALL26 R_AARCH64 = 21 R_AARCH64_P32_GOT_LD_PREL19 R_AARCH64 = 25 R_AARCH64_P32_ADR_GOT_PAGE R_AARCH64 = 26 R_AARCH64_P32_LD32_GOT_LO12_NC R_AARCH64 = 27 R_AARCH64_P32_TLSGD_ADR_PAGE21 R_AARCH64 = 81 R_AARCH64_P32_TLSGD_ADD_LO12_NC R_AARCH64 = 82 R_AARCH64_P32_TLSIE_ADR_GOTTPREL_PAGE21 R_AARCH64 = 103 R_AARCH64_P32_TLSIE_LD32_GOTTPREL_LO12_NC R_AARCH64 = 104 R_AARCH64_P32_TLSIE_LD_GOTTPREL_PREL19 R_AARCH64 = 105 R_AARCH64_P32_TLSLE_MOVW_TPREL_G1 R_AARCH64 = 106 R_AARCH64_P32_TLSLE_MOVW_TPREL_G0 R_AARCH64 = 107 R_AARCH64_P32_TLSLE_MOVW_TPREL_G0_NC R_AARCH64 = 108 R_AARCH64_P32_TLSLE_ADD_TPREL_HI12 R_AARCH64 = 109 R_AARCH64_P32_TLSLE_ADD_TPREL_LO12 R_AARCH64 = 110 R_AARCH64_P32_TLSLE_ADD_TPREL_LO12_NC R_AARCH64 = 111 R_AARCH64_P32_TLSDESC_LD_PREL19 R_AARCH64 = 122 R_AARCH64_P32_TLSDESC_ADR_PREL21 R_AARCH64 = 123 R_AARCH64_P32_TLSDESC_ADR_PAGE21 R_AARCH64 = 124 R_AARCH64_P32_TLSDESC_LD32_LO12_NC R_AARCH64 = 125 R_AARCH64_P32_TLSDESC_ADD_LO12_NC R_AARCH64 = 126 R_AARCH64_P32_TLSDESC_CALL R_AARCH64 = 127 R_AARCH64_P32_COPY R_AARCH64 = 180 R_AARCH64_P32_GLOB_DAT R_AARCH64 = 181 R_AARCH64_P32_JUMP_SLOT R_AARCH64 = 182 R_AARCH64_P32_RELATIVE R_AARCH64 = 183 R_AARCH64_P32_TLS_DTPMOD R_AARCH64 = 184 R_AARCH64_P32_TLS_DTPREL R_AARCH64 = 185 R_AARCH64_P32_TLS_TPREL R_AARCH64 = 186 R_AARCH64_P32_TLSDESC R_AARCH64 = 187 R_AARCH64_P32_IRELATIVE R_AARCH64 = 188 R_AARCH64_NULL R_AARCH64 = 256 R_AARCH64_ABS64 R_AARCH64 = 257 R_AARCH64_ABS32 R_AARCH64 = 258 R_AARCH64_ABS16 R_AARCH64 = 259 R_AARCH64_PREL64 R_AARCH64 = 260 R_AARCH64_PREL32 R_AARCH64 = 261 R_AARCH64_PREL16 R_AARCH64 = 262 R_AARCH64_MOVW_UABS_G0 R_AARCH64 = 263 R_AARCH64_MOVW_UABS_G0_NC R_AARCH64 = 264 R_AARCH64_MOVW_UABS_G1 R_AARCH64 = 265 R_AARCH64_MOVW_UABS_G1_NC R_AARCH64 = 266 R_AARCH64_MOVW_UABS_G2 R_AARCH64 = 267 R_AARCH64_MOVW_UABS_G2_NC R_AARCH64 = 268 R_AARCH64_MOVW_UABS_G3 R_AARCH64 = 269 R_AARCH64_MOVW_SABS_G0 R_AARCH64 = 270 R_AARCH64_MOVW_SABS_G1 R_AARCH64 = 271 R_AARCH64_MOVW_SABS_G2 R_AARCH64 = 272 R_AARCH64_LD_PREL_LO19 R_AARCH64 = 273 R_AARCH64_ADR_PREL_LO21 R_AARCH64 = 274 R_AARCH64_ADR_PREL_PG_HI21 R_AARCH64 = 275 R_AARCH64_ADR_PREL_PG_HI21_NC R_AARCH64 = 276 R_AARCH64_ADD_ABS_LO12_NC R_AARCH64 = 277 R_AARCH64_LDST8_ABS_LO12_NC R_AARCH64 = 278 R_AARCH64_TSTBR14 R_AARCH64 = 279 R_AARCH64_CONDBR19 R_AARCH64 = 280 R_AARCH64_JUMP26 R_AARCH64 = 282 R_AARCH64_CALL26 R_AARCH64 = 283 R_AARCH64_LDST16_ABS_LO12_NC R_AARCH64 = 284 R_AARCH64_LDST32_ABS_LO12_NC R_AARCH64 = 285 R_AARCH64_LDST64_ABS_LO12_NC R_AARCH64 = 286 R_AARCH64_LDST128_ABS_LO12_NC R_AARCH64 = 299 R_AARCH64_GOT_LD_PREL19 R_AARCH64 = 309 R_AARCH64_LD64_GOTOFF_LO15 R_AARCH64 = 310 R_AARCH64_ADR_GOT_PAGE R_AARCH64 = 311 R_AARCH64_LD64_GOT_LO12_NC R_AARCH64 = 312 R_AARCH64_LD64_GOTPAGE_LO15 R_AARCH64 = 313 R_AARCH64_TLSGD_ADR_PREL21 R_AARCH64 = 512 R_AARCH64_TLSGD_ADR_PAGE21 R_AARCH64 = 513 R_AARCH64_TLSGD_ADD_LO12_NC R_AARCH64 = 514 R_AARCH64_TLSGD_MOVW_G1 R_AARCH64 = 515 R_AARCH64_TLSGD_MOVW_G0_NC R_AARCH64 = 516 R_AARCH64_TLSLD_ADR_PREL21 R_AARCH64 = 517 R_AARCH64_TLSLD_ADR_PAGE21 R_AARCH64 = 518 R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 R_AARCH64 = 539 R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC R_AARCH64 = 540 R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 R_AARCH64 = 541 R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC R_AARCH64 = 542 R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 R_AARCH64 = 543 R_AARCH64_TLSLE_MOVW_TPREL_G2 R_AARCH64 = 544 R_AARCH64_TLSLE_MOVW_TPREL_G1 R_AARCH64 = 545 R_AARCH64_TLSLE_MOVW_TPREL_G1_NC R_AARCH64 = 546 R_AARCH64_TLSLE_MOVW_TPREL_G0 R_AARCH64 = 547 R_AARCH64_TLSLE_MOVW_TPREL_G0_NC R_AARCH64 = 548 R_AARCH64_TLSLE_ADD_TPREL_HI12 R_AARCH64 = 549 R_AARCH64_TLSLE_ADD_TPREL_LO12 R_AARCH64 = 550 R_AARCH64_TLSLE_ADD_TPREL_LO12_NC R_AARCH64 = 551 R_AARCH64_TLSDESC_LD_PREL19 R_AARCH64 = 560 R_AARCH64_TLSDESC_ADR_PREL21 R_AARCH64 = 561 R_AARCH64_TLSDESC_ADR_PAGE21 R_AARCH64 = 562 R_AARCH64_TLSDESC_LD64_LO12_NC R_AARCH64 = 563 R_AARCH64_TLSDESC_ADD_LO12_NC R_AARCH64 = 564 R_AARCH64_TLSDESC_OFF_G1 R_AARCH64 = 565 R_AARCH64_TLSDESC_OFF_G0_NC R_AARCH64 = 566 R_AARCH64_TLSDESC_LDR R_AARCH64 = 567 R_AARCH64_TLSDESC_ADD R_AARCH64 = 568 R_AARCH64_TLSDESC_CALL R_AARCH64 = 569 R_AARCH64_TLSLE_LDST128_TPREL_LO12 R_AARCH64 = 570 R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC R_AARCH64 = 571 R_AARCH64_TLSLD_LDST128_DTPREL_LO12 R_AARCH64 = 572 R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC R_AARCH64 = 573 R_AARCH64_COPY R_AARCH64 = 1024 R_AARCH64_GLOB_DAT R_AARCH64 = 1025 R_AARCH64_JUMP_SLOT R_AARCH64 = 1026 R_AARCH64_RELATIVE R_AARCH64 = 1027 R_AARCH64_TLS_DTPMOD64 R_AARCH64 = 1028 R_AARCH64_TLS_DTPREL64 R_AARCH64 = 1029 R_AARCH64_TLS_TPREL64 R_AARCH64 = 1030 R_AARCH64_TLSDESC R_AARCH64 = 1031 R_AARCH64_IRELATIVE R_AARCH64 = 1032 ) var raarch64Strings = []intName{ {0, "R_AARCH64_NONE"}, {1, "R_AARCH64_P32_ABS32"}, {2, "R_AARCH64_P32_ABS16"}, {3, "R_AARCH64_P32_PREL32"}, {4, "R_AARCH64_P32_PREL16"}, {5, "R_AARCH64_P32_MOVW_UABS_G0"}, {6, "R_AARCH64_P32_MOVW_UABS_G0_NC"}, {7, "R_AARCH64_P32_MOVW_UABS_G1"}, {8, "R_AARCH64_P32_MOVW_SABS_G0"}, {9, "R_AARCH64_P32_LD_PREL_LO19"}, {10, "R_AARCH64_P32_ADR_PREL_LO21"}, {11, "R_AARCH64_P32_ADR_PREL_PG_HI21"}, {12, "R_AARCH64_P32_ADD_ABS_LO12_NC"}, {13, "R_AARCH64_P32_LDST8_ABS_LO12_NC"}, {14, "R_AARCH64_P32_LDST16_ABS_LO12_NC"}, {15, "R_AARCH64_P32_LDST32_ABS_LO12_NC"}, {16, "R_AARCH64_P32_LDST64_ABS_LO12_NC"}, {17, "R_AARCH64_P32_LDST128_ABS_LO12_NC"}, {18, "R_AARCH64_P32_TSTBR14"}, {19, "R_AARCH64_P32_CONDBR19"}, {20, "R_AARCH64_P32_JUMP26"}, {21, "R_AARCH64_P32_CALL26"}, {25, "R_AARCH64_P32_GOT_LD_PREL19"}, {26, "R_AARCH64_P32_ADR_GOT_PAGE"}, {27, "R_AARCH64_P32_LD32_GOT_LO12_NC"}, {81, "R_AARCH64_P32_TLSGD_ADR_PAGE21"}, {82, "R_AARCH64_P32_TLSGD_ADD_LO12_NC"}, {103, "R_AARCH64_P32_TLSIE_ADR_GOTTPREL_PAGE21"}, {104, "R_AARCH64_P32_TLSIE_LD32_GOTTPREL_LO12_NC"}, {105, "R_AARCH64_P32_TLSIE_LD_GOTTPREL_PREL19"}, {106, "R_AARCH64_P32_TLSLE_MOVW_TPREL_G1"}, {107, "R_AARCH64_P32_TLSLE_MOVW_TPREL_G0"}, {108, "R_AARCH64_P32_TLSLE_MOVW_TPREL_G0_NC"}, {109, "R_AARCH64_P32_TLSLE_ADD_TPREL_HI12"}, {110, "R_AARCH64_P32_TLSLE_ADD_TPREL_LO12"}, {111, "R_AARCH64_P32_TLSLE_ADD_TPREL_LO12_NC"}, {122, "R_AARCH64_P32_TLSDESC_LD_PREL19"}, {123, "R_AARCH64_P32_TLSDESC_ADR_PREL21"}, {124, "R_AARCH64_P32_TLSDESC_ADR_PAGE21"}, {125, "R_AARCH64_P32_TLSDESC_LD32_LO12_NC"}, {126, "R_AARCH64_P32_TLSDESC_ADD_LO12_NC"}, {127, "R_AARCH64_P32_TLSDESC_CALL"}, {180, "R_AARCH64_P32_COPY"}, {181, "R_AARCH64_P32_GLOB_DAT"}, {182, "R_AARCH64_P32_JUMP_SLOT"}, {183, "R_AARCH64_P32_RELATIVE"}, {184, "R_AARCH64_P32_TLS_DTPMOD"}, {185, "R_AARCH64_P32_TLS_DTPREL"}, {186, "R_AARCH64_P32_TLS_TPREL"}, {187, "R_AARCH64_P32_TLSDESC"}, {188, "R_AARCH64_P32_IRELATIVE"}, {256, "R_AARCH64_NULL"}, {257, "R_AARCH64_ABS64"}, {258, "R_AARCH64_ABS32"}, {259, "R_AARCH64_ABS16"}, {260, "R_AARCH64_PREL64"}, {261, "R_AARCH64_PREL32"}, {262, "R_AARCH64_PREL16"}, {263, "R_AARCH64_MOVW_UABS_G0"}, {264, "R_AARCH64_MOVW_UABS_G0_NC"}, {265, "R_AARCH64_MOVW_UABS_G1"}, {266, "R_AARCH64_MOVW_UABS_G1_NC"}, {267, "R_AARCH64_MOVW_UABS_G2"}, {268, "R_AARCH64_MOVW_UABS_G2_NC"}, {269, "R_AARCH64_MOVW_UABS_G3"}, {270, "R_AARCH64_MOVW_SABS_G0"}, {271, "R_AARCH64_MOVW_SABS_G1"}, {272, "R_AARCH64_MOVW_SABS_G2"}, {273, "R_AARCH64_LD_PREL_LO19"}, {274, "R_AARCH64_ADR_PREL_LO21"}, {275, "R_AARCH64_ADR_PREL_PG_HI21"}, {276, "R_AARCH64_ADR_PREL_PG_HI21_NC"}, {277, "R_AARCH64_ADD_ABS_LO12_NC"}, {278, "R_AARCH64_LDST8_ABS_LO12_NC"}, {279, "R_AARCH64_TSTBR14"}, {280, "R_AARCH64_CONDBR19"}, {282, "R_AARCH64_JUMP26"}, {283, "R_AARCH64_CALL26"}, {284, "R_AARCH64_LDST16_ABS_LO12_NC"}, {285, "R_AARCH64_LDST32_ABS_LO12_NC"}, {286, "R_AARCH64_LDST64_ABS_LO12_NC"}, {299, "R_AARCH64_LDST128_ABS_LO12_NC"}, {309, "R_AARCH64_GOT_LD_PREL19"}, {310, "R_AARCH64_LD64_GOTOFF_LO15"}, {311, "R_AARCH64_ADR_GOT_PAGE"}, {312, "R_AARCH64_LD64_GOT_LO12_NC"}, {313, "R_AARCH64_LD64_GOTPAGE_LO15"}, {512, "R_AARCH64_TLSGD_ADR_PREL21"}, {513, "R_AARCH64_TLSGD_ADR_PAGE21"}, {514, "R_AARCH64_TLSGD_ADD_LO12_NC"}, {515, "R_AARCH64_TLSGD_MOVW_G1"}, {516, "R_AARCH64_TLSGD_MOVW_G0_NC"}, {517, "R_AARCH64_TLSLD_ADR_PREL21"}, {518, "R_AARCH64_TLSLD_ADR_PAGE21"}, {539, "R_AARCH64_TLSIE_MOVW_GOTTPREL_G1"}, {540, "R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC"}, {541, "R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21"}, {542, "R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC"}, {543, "R_AARCH64_TLSIE_LD_GOTTPREL_PREL19"}, {544, "R_AARCH64_TLSLE_MOVW_TPREL_G2"}, {545, "R_AARCH64_TLSLE_MOVW_TPREL_G1"}, {546, "R_AARCH64_TLSLE_MOVW_TPREL_G1_NC"}, {547, "R_AARCH64_TLSLE_MOVW_TPREL_G0"}, {548, "R_AARCH64_TLSLE_MOVW_TPREL_G0_NC"}, {549, "R_AARCH64_TLSLE_ADD_TPREL_HI12"}, {550, "R_AARCH64_TLSLE_ADD_TPREL_LO12"}, {551, "R_AARCH64_TLSLE_ADD_TPREL_LO12_NC"}, {560, "R_AARCH64_TLSDESC_LD_PREL19"}, {561, "R_AARCH64_TLSDESC_ADR_PREL21"}, {562, "R_AARCH64_TLSDESC_ADR_PAGE21"}, {563, "R_AARCH64_TLSDESC_LD64_LO12_NC"}, {564, "R_AARCH64_TLSDESC_ADD_LO12_NC"}, {565, "R_AARCH64_TLSDESC_OFF_G1"}, {566, "R_AARCH64_TLSDESC_OFF_G0_NC"}, {567, "R_AARCH64_TLSDESC_LDR"}, {568, "R_AARCH64_TLSDESC_ADD"}, {569, "R_AARCH64_TLSDESC_CALL"}, {570, "R_AARCH64_TLSLE_LDST128_TPREL_LO12"}, {571, "R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC"}, {572, "R_AARCH64_TLSLD_LDST128_DTPREL_LO12"}, {573, "R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC"}, {1024, "R_AARCH64_COPY"}, {1025, "R_AARCH64_GLOB_DAT"}, {1026, "R_AARCH64_JUMP_SLOT"}, {1027, "R_AARCH64_RELATIVE"}, {1028, "R_AARCH64_TLS_DTPMOD64"}, {1029, "R_AARCH64_TLS_DTPREL64"}, {1030, "R_AARCH64_TLS_TPREL64"}, {1031, "R_AARCH64_TLSDESC"}, {1032, "R_AARCH64_IRELATIVE"}, } func (i R_AARCH64) String() string { return stringName(uint32(i), raarch64Strings, false) } func (i R_AARCH64) GoString() string { return stringName(uint32(i), raarch64Strings, true) } // Relocation types for Alpha. type R_ALPHA int const ( R_ALPHA_NONE R_ALPHA = 0 /* No reloc */ R_ALPHA_REFLONG R_ALPHA = 1 /* Direct 32 bit */ R_ALPHA_REFQUAD R_ALPHA = 2 /* Direct 64 bit */ R_ALPHA_GPREL32 R_ALPHA = 3 /* GP relative 32 bit */ R_ALPHA_LITERAL R_ALPHA = 4 /* GP relative 16 bit w/optimization */ R_ALPHA_LITUSE R_ALPHA = 5 /* Optimization hint for LITERAL */ R_ALPHA_GPDISP R_ALPHA = 6 /* Add displacement to GP */ R_ALPHA_BRADDR R_ALPHA = 7 /* PC+4 relative 23 bit shifted */ R_ALPHA_HINT R_ALPHA = 8 /* PC+4 relative 16 bit shifted */ R_ALPHA_SREL16 R_ALPHA = 9 /* PC relative 16 bit */ R_ALPHA_SREL32 R_ALPHA = 10 /* PC relative 32 bit */ R_ALPHA_SREL64 R_ALPHA = 11 /* PC relative 64 bit */ R_ALPHA_OP_PUSH R_ALPHA = 12 /* OP stack push */ R_ALPHA_OP_STORE R_ALPHA = 13 /* OP stack pop and store */ R_ALPHA_OP_PSUB R_ALPHA = 14 /* OP stack subtract */ R_ALPHA_OP_PRSHIFT R_ALPHA = 15 /* OP stack right shift */ R_ALPHA_GPVALUE R_ALPHA = 16 R_ALPHA_GPRELHIGH R_ALPHA = 17 R_ALPHA_GPRELLOW R_ALPHA = 18 R_ALPHA_IMMED_GP_16 R_ALPHA = 19 R_ALPHA_IMMED_GP_HI32 R_ALPHA = 20 R_ALPHA_IMMED_SCN_HI32 R_ALPHA = 21 R_ALPHA_IMMED_BR_HI32 R_ALPHA = 22 R_ALPHA_IMMED_LO32 R_ALPHA = 23 R_ALPHA_COPY R_ALPHA = 24 /* Copy symbol at runtime */ R_ALPHA_GLOB_DAT R_ALPHA = 25 /* Create GOT entry */ R_ALPHA_JMP_SLOT R_ALPHA = 26 /* Create PLT entry */ R_ALPHA_RELATIVE R_ALPHA = 27 /* Adjust by program base */ ) var ralphaStrings = []intName{ {0, "R_ALPHA_NONE"}, {1, "R_ALPHA_REFLONG"}, {2, "R_ALPHA_REFQUAD"}, {3, "R_ALPHA_GPREL32"}, {4, "R_ALPHA_LITERAL"}, {5, "R_ALPHA_LITUSE"}, {6, "R_ALPHA_GPDISP"}, {7, "R_ALPHA_BRADDR"}, {8, "R_ALPHA_HINT"}, {9, "R_ALPHA_SREL16"}, {10, "R_ALPHA_SREL32"}, {11, "R_ALPHA_SREL64"}, {12, "R_ALPHA_OP_PUSH"}, {13, "R_ALPHA_OP_STORE"}, {14, "R_ALPHA_OP_PSUB"}, {15, "R_ALPHA_OP_PRSHIFT"}, {16, "R_ALPHA_GPVALUE"}, {17, "R_ALPHA_GPRELHIGH"}, {18, "R_ALPHA_GPRELLOW"}, {19, "R_ALPHA_IMMED_GP_16"}, {20, "R_ALPHA_IMMED_GP_HI32"}, {21, "R_ALPHA_IMMED_SCN_HI32"}, {22, "R_ALPHA_IMMED_BR_HI32"}, {23, "R_ALPHA_IMMED_LO32"}, {24, "R_ALPHA_COPY"}, {25, "R_ALPHA_GLOB_DAT"}, {26, "R_ALPHA_JMP_SLOT"}, {27, "R_ALPHA_RELATIVE"}, } func (i R_ALPHA) String() string { return stringName(uint32(i), ralphaStrings, false) } func (i R_ALPHA) GoString() string { return stringName(uint32(i), ralphaStrings, true) } // Relocation types for ARM. type R_ARM int const ( R_ARM_NONE R_ARM = 0 /* No relocation. */ R_ARM_PC24 R_ARM = 1 R_ARM_ABS32 R_ARM = 2 R_ARM_REL32 R_ARM = 3 R_ARM_PC13 R_ARM = 4 R_ARM_ABS16 R_ARM = 5 R_ARM_ABS12 R_ARM = 6 R_ARM_THM_ABS5 R_ARM = 7 R_ARM_ABS8 R_ARM = 8 R_ARM_SBREL32 R_ARM = 9 R_ARM_THM_PC22 R_ARM = 10 R_ARM_THM_PC8 R_ARM = 11 R_ARM_AMP_VCALL9 R_ARM = 12 R_ARM_SWI24 R_ARM = 13 R_ARM_THM_SWI8 R_ARM = 14 R_ARM_XPC25 R_ARM = 15 R_ARM_THM_XPC22 R_ARM = 16 R_ARM_TLS_DTPMOD32 R_ARM = 17 R_ARM_TLS_DTPOFF32 R_ARM = 18 R_ARM_TLS_TPOFF32 R_ARM = 19 R_ARM_COPY R_ARM = 20 /* Copy data from shared object. */ R_ARM_GLOB_DAT R_ARM = 21 /* Set GOT entry to data address. */ R_ARM_JUMP_SLOT R_ARM = 22 /* Set GOT entry to code address. */ R_ARM_RELATIVE R_ARM = 23 /* Add load address of shared object. */ R_ARM_GOTOFF R_ARM = 24 /* Add GOT-relative symbol address. */ R_ARM_GOTPC R_ARM = 25 /* Add PC-relative GOT table address. */ R_ARM_GOT32 R_ARM = 26 /* Add PC-relative GOT offset. */ R_ARM_PLT32 R_ARM = 27 /* Add PC-relative PLT offset. */ R_ARM_CALL R_ARM = 28 R_ARM_JUMP24 R_ARM = 29 R_ARM_THM_JUMP24 R_ARM = 30 R_ARM_BASE_ABS R_ARM = 31 R_ARM_ALU_PCREL_7_0 R_ARM = 32 R_ARM_ALU_PCREL_15_8 R_ARM = 33 R_ARM_ALU_PCREL_23_15 R_ARM = 34 R_ARM_LDR_SBREL_11_10_NC R_ARM = 35 R_ARM_ALU_SBREL_19_12_NC R_ARM = 36 R_ARM_ALU_SBREL_27_20_CK R_ARM = 37 R_ARM_TARGET1 R_ARM = 38 R_ARM_SBREL31 R_ARM = 39 R_ARM_V4BX R_ARM = 40 R_ARM_TARGET2 R_ARM = 41 R_ARM_PREL31 R_ARM = 42 R_ARM_MOVW_ABS_NC R_ARM = 43 R_ARM_MOVT_ABS R_ARM = 44 R_ARM_MOVW_PREL_NC R_ARM = 45 R_ARM_MOVT_PREL R_ARM = 46 R_ARM_THM_MOVW_ABS_NC R_ARM = 47 R_ARM_THM_MOVT_ABS R_ARM = 48 R_ARM_THM_MOVW_PREL_NC R_ARM = 49 R_ARM_THM_MOVT_PREL R_ARM = 50 R_ARM_THM_JUMP19 R_ARM = 51 R_ARM_THM_JUMP6 R_ARM = 52 R_ARM_THM_ALU_PREL_11_0 R_ARM = 53 R_ARM_THM_PC12 R_ARM = 54 R_ARM_ABS32_NOI R_ARM = 55 R_ARM_REL32_NOI R_ARM = 56 R_ARM_ALU_PC_G0_NC R_ARM = 57 R_ARM_ALU_PC_G0 R_ARM = 58 R_ARM_ALU_PC_G1_NC R_ARM = 59 R_ARM_ALU_PC_G1 R_ARM = 60 R_ARM_ALU_PC_G2 R_ARM = 61 R_ARM_LDR_PC_G1 R_ARM = 62 R_ARM_LDR_PC_G2 R_ARM = 63 R_ARM_LDRS_PC_G0 R_ARM = 64 R_ARM_LDRS_PC_G1 R_ARM = 65 R_ARM_LDRS_PC_G2 R_ARM = 66 R_ARM_LDC_PC_G0 R_ARM = 67 R_ARM_LDC_PC_G1 R_ARM = 68 R_ARM_LDC_PC_G2 R_ARM = 69 R_ARM_ALU_SB_G0_NC R_ARM = 70 R_ARM_ALU_SB_G0 R_ARM = 71 R_ARM_ALU_SB_G1_NC R_ARM = 72 R_ARM_ALU_SB_G1 R_ARM = 73 R_ARM_ALU_SB_G2 R_ARM = 74 R_ARM_LDR_SB_G0 R_ARM = 75 R_ARM_LDR_SB_G1 R_ARM = 76 R_ARM_LDR_SB_G2 R_ARM = 77 R_ARM_LDRS_SB_G0 R_ARM = 78 R_ARM_LDRS_SB_G1 R_ARM = 79 R_ARM_LDRS_SB_G2 R_ARM = 80 R_ARM_LDC_SB_G0 R_ARM = 81 R_ARM_LDC_SB_G1 R_ARM = 82 R_ARM_LDC_SB_G2 R_ARM = 83 R_ARM_MOVW_BREL_NC R_ARM = 84 R_ARM_MOVT_BREL R_ARM = 85 R_ARM_MOVW_BREL R_ARM = 86 R_ARM_THM_MOVW_BREL_NC R_ARM = 87 R_ARM_THM_MOVT_BREL R_ARM = 88 R_ARM_THM_MOVW_BREL R_ARM = 89 R_ARM_TLS_GOTDESC R_ARM = 90 R_ARM_TLS_CALL R_ARM = 91 R_ARM_TLS_DESCSEQ R_ARM = 92 R_ARM_THM_TLS_CALL R_ARM = 93 R_ARM_PLT32_ABS R_ARM = 94 R_ARM_GOT_ABS R_ARM = 95 R_ARM_GOT_PREL R_ARM = 96 R_ARM_GOT_BREL12 R_ARM = 97 R_ARM_GOTOFF12 R_ARM = 98 R_ARM_GOTRELAX R_ARM = 99 R_ARM_GNU_VTENTRY R_ARM = 100 R_ARM_GNU_VTINHERIT R_ARM = 101 R_ARM_THM_JUMP11 R_ARM = 102 R_ARM_THM_JUMP8 R_ARM = 103 R_ARM_TLS_GD32 R_ARM = 104 R_ARM_TLS_LDM32 R_ARM = 105 R_ARM_TLS_LDO32 R_ARM = 106 R_ARM_TLS_IE32 R_ARM = 107 R_ARM_TLS_LE32 R_ARM = 108 R_ARM_TLS_LDO12 R_ARM = 109 R_ARM_TLS_LE12 R_ARM = 110 R_ARM_TLS_IE12GP R_ARM = 111 R_ARM_PRIVATE_0 R_ARM = 112 R_ARM_PRIVATE_1 R_ARM = 113 R_ARM_PRIVATE_2 R_ARM = 114 R_ARM_PRIVATE_3 R_ARM = 115 R_ARM_PRIVATE_4 R_ARM = 116 R_ARM_PRIVATE_5 R_ARM = 117 R_ARM_PRIVATE_6 R_ARM = 118 R_ARM_PRIVATE_7 R_ARM = 119 R_ARM_PRIVATE_8 R_ARM = 120 R_ARM_PRIVATE_9 R_ARM = 121 R_ARM_PRIVATE_10 R_ARM = 122 R_ARM_PRIVATE_11 R_ARM = 123 R_ARM_PRIVATE_12 R_ARM = 124 R_ARM_PRIVATE_13 R_ARM = 125 R_ARM_PRIVATE_14 R_ARM = 126 R_ARM_PRIVATE_15 R_ARM = 127 R_ARM_ME_TOO R_ARM = 128 R_ARM_THM_TLS_DESCSEQ16 R_ARM = 129 R_ARM_THM_TLS_DESCSEQ32 R_ARM = 130 R_ARM_THM_GOT_BREL12 R_ARM = 131 R_ARM_THM_ALU_ABS_G0_NC R_ARM = 132 R_ARM_THM_ALU_ABS_G1_NC R_ARM = 133 R_ARM_THM_ALU_ABS_G2_NC R_ARM = 134 R_ARM_THM_ALU_ABS_G3 R_ARM = 135 R_ARM_IRELATIVE R_ARM = 160 R_ARM_RXPC25 R_ARM = 249 R_ARM_RSBREL32 R_ARM = 250 R_ARM_THM_RPC22 R_ARM = 251 R_ARM_RREL32 R_ARM = 252 R_ARM_RABS32 R_ARM = 253 R_ARM_RPC24 R_ARM = 254 R_ARM_RBASE R_ARM = 255 ) var rarmStrings = []intName{ {0, "R_ARM_NONE"}, {1, "R_ARM_PC24"}, {2, "R_ARM_ABS32"}, {3, "R_ARM_REL32"}, {4, "R_ARM_PC13"}, {5, "R_ARM_ABS16"}, {6, "R_ARM_ABS12"}, {7, "R_ARM_THM_ABS5"}, {8, "R_ARM_ABS8"}, {9, "R_ARM_SBREL32"}, {10, "R_ARM_THM_PC22"}, {11, "R_ARM_THM_PC8"}, {12, "R_ARM_AMP_VCALL9"}, {13, "R_ARM_SWI24"}, {14, "R_ARM_THM_SWI8"}, {15, "R_ARM_XPC25"}, {16, "R_ARM_THM_XPC22"}, {17, "R_ARM_TLS_DTPMOD32"}, {18, "R_ARM_TLS_DTPOFF32"}, {19, "R_ARM_TLS_TPOFF32"}, {20, "R_ARM_COPY"}, {21, "R_ARM_GLOB_DAT"}, {22, "R_ARM_JUMP_SLOT"}, {23, "R_ARM_RELATIVE"}, {24, "R_ARM_GOTOFF"}, {25, "R_ARM_GOTPC"}, {26, "R_ARM_GOT32"}, {27, "R_ARM_PLT32"}, {28, "R_ARM_CALL"}, {29, "R_ARM_JUMP24"}, {30, "R_ARM_THM_JUMP24"}, {31, "R_ARM_BASE_ABS"}, {32, "R_ARM_ALU_PCREL_7_0"}, {33, "R_ARM_ALU_PCREL_15_8"}, {34, "R_ARM_ALU_PCREL_23_15"}, {35, "R_ARM_LDR_SBREL_11_10_NC"}, {36, "R_ARM_ALU_SBREL_19_12_NC"}, {37, "R_ARM_ALU_SBREL_27_20_CK"}, {38, "R_ARM_TARGET1"}, {39, "R_ARM_SBREL31"}, {40, "R_ARM_V4BX"}, {41, "R_ARM_TARGET2"}, {42, "R_ARM_PREL31"}, {43, "R_ARM_MOVW_ABS_NC"}, {44, "R_ARM_MOVT_ABS"}, {45, "R_ARM_MOVW_PREL_NC"}, {46, "R_ARM_MOVT_PREL"}, {47, "R_ARM_THM_MOVW_ABS_NC"}, {48, "R_ARM_THM_MOVT_ABS"}, {49, "R_ARM_THM_MOVW_PREL_NC"}, {50, "R_ARM_THM_MOVT_PREL"}, {51, "R_ARM_THM_JUMP19"}, {52, "R_ARM_THM_JUMP6"}, {53, "R_ARM_THM_ALU_PREL_11_0"}, {54, "R_ARM_THM_PC12"}, {55, "R_ARM_ABS32_NOI"}, {56, "R_ARM_REL32_NOI"}, {57, "R_ARM_ALU_PC_G0_NC"}, {58, "R_ARM_ALU_PC_G0"}, {59, "R_ARM_ALU_PC_G1_NC"}, {60, "R_ARM_ALU_PC_G1"}, {61, "R_ARM_ALU_PC_G2"}, {62, "R_ARM_LDR_PC_G1"}, {63, "R_ARM_LDR_PC_G2"}, {64, "R_ARM_LDRS_PC_G0"}, {65, "R_ARM_LDRS_PC_G1"}, {66, "R_ARM_LDRS_PC_G2"}, {67, "R_ARM_LDC_PC_G0"}, {68, "R_ARM_LDC_PC_G1"}, {69, "R_ARM_LDC_PC_G2"}, {70, "R_ARM_ALU_SB_G0_NC"}, {71, "R_ARM_ALU_SB_G0"}, {72, "R_ARM_ALU_SB_G1_NC"}, {73, "R_ARM_ALU_SB_G1"}, {74, "R_ARM_ALU_SB_G2"}, {75, "R_ARM_LDR_SB_G0"}, {76, "R_ARM_LDR_SB_G1"}, {77, "R_ARM_LDR_SB_G2"}, {78, "R_ARM_LDRS_SB_G0"}, {79, "R_ARM_LDRS_SB_G1"}, {80, "R_ARM_LDRS_SB_G2"}, {81, "R_ARM_LDC_SB_G0"}, {82, "R_ARM_LDC_SB_G1"}, {83, "R_ARM_LDC_SB_G2"}, {84, "R_ARM_MOVW_BREL_NC"}, {85, "R_ARM_MOVT_BREL"}, {86, "R_ARM_MOVW_BREL"}, {87, "R_ARM_THM_MOVW_BREL_NC"}, {88, "R_ARM_THM_MOVT_BREL"}, {89, "R_ARM_THM_MOVW_BREL"}, {90, "R_ARM_TLS_GOTDESC"}, {91, "R_ARM_TLS_CALL"}, {92, "R_ARM_TLS_DESCSEQ"}, {93, "R_ARM_THM_TLS_CALL"}, {94, "R_ARM_PLT32_ABS"}, {95, "R_ARM_GOT_ABS"}, {96, "R_ARM_GOT_PREL"}, {97, "R_ARM_GOT_BREL12"}, {98, "R_ARM_GOTOFF12"}, {99, "R_ARM_GOTRELAX"}, {100, "R_ARM_GNU_VTENTRY"}, {101, "R_ARM_GNU_VTINHERIT"}, {102, "R_ARM_THM_JUMP11"}, {103, "R_ARM_THM_JUMP8"}, {104, "R_ARM_TLS_GD32"}, {105, "R_ARM_TLS_LDM32"}, {106, "R_ARM_TLS_LDO32"}, {107, "R_ARM_TLS_IE32"}, {108, "R_ARM_TLS_LE32"}, {109, "R_ARM_TLS_LDO12"}, {110, "R_ARM_TLS_LE12"}, {111, "R_ARM_TLS_IE12GP"}, {112, "R_ARM_PRIVATE_0"}, {113, "R_ARM_PRIVATE_1"}, {114, "R_ARM_PRIVATE_2"}, {115, "R_ARM_PRIVATE_3"}, {116, "R_ARM_PRIVATE_4"}, {117, "R_ARM_PRIVATE_5"}, {118, "R_ARM_PRIVATE_6"}, {119, "R_ARM_PRIVATE_7"}, {120, "R_ARM_PRIVATE_8"}, {121, "R_ARM_PRIVATE_9"}, {122, "R_ARM_PRIVATE_10"}, {123, "R_ARM_PRIVATE_11"}, {124, "R_ARM_PRIVATE_12"}, {125, "R_ARM_PRIVATE_13"}, {126, "R_ARM_PRIVATE_14"}, {127, "R_ARM_PRIVATE_15"}, {128, "R_ARM_ME_TOO"}, {129, "R_ARM_THM_TLS_DESCSEQ16"}, {130, "R_ARM_THM_TLS_DESCSEQ32"}, {131, "R_ARM_THM_GOT_BREL12"}, {132, "R_ARM_THM_ALU_ABS_G0_NC"}, {133, "R_ARM_THM_ALU_ABS_G1_NC"}, {134, "R_ARM_THM_ALU_ABS_G2_NC"}, {135, "R_ARM_THM_ALU_ABS_G3"}, {160, "R_ARM_IRELATIVE"}, {249, "R_ARM_RXPC25"}, {250, "R_ARM_RSBREL32"}, {251, "R_ARM_THM_RPC22"}, {252, "R_ARM_RREL32"}, {253, "R_ARM_RABS32"}, {254, "R_ARM_RPC24"}, {255, "R_ARM_RBASE"}, } func (i R_ARM) String() string { return stringName(uint32(i), rarmStrings, false) } func (i R_ARM) GoString() string { return stringName(uint32(i), rarmStrings, true) } // Relocation types for 386. type R_386 int const ( R_386_NONE R_386 = 0 /* No relocation. */ R_386_32 R_386 = 1 /* Add symbol value. */ R_386_PC32 R_386 = 2 /* Add PC-relative symbol value. */ R_386_GOT32 R_386 = 3 /* Add PC-relative GOT offset. */ R_386_PLT32 R_386 = 4 /* Add PC-relative PLT offset. */ R_386_COPY R_386 = 5 /* Copy data from shared object. */ R_386_GLOB_DAT R_386 = 6 /* Set GOT entry to data address. */ R_386_JMP_SLOT R_386 = 7 /* Set GOT entry to code address. */ R_386_RELATIVE R_386 = 8 /* Add load address of shared object. */ R_386_GOTOFF R_386 = 9 /* Add GOT-relative symbol address. */ R_386_GOTPC R_386 = 10 /* Add PC-relative GOT table address. */ R_386_32PLT R_386 = 11 R_386_TLS_TPOFF R_386 = 14 /* Negative offset in static TLS block */ R_386_TLS_IE R_386 = 15 /* Absolute address of GOT for -ve static TLS */ R_386_TLS_GOTIE R_386 = 16 /* GOT entry for negative static TLS block */ R_386_TLS_LE R_386 = 17 /* Negative offset relative to static TLS */ R_386_TLS_GD R_386 = 18 /* 32 bit offset to GOT (index,off) pair */ R_386_TLS_LDM R_386 = 19 /* 32 bit offset to GOT (index,zero) pair */ R_386_16 R_386 = 20 R_386_PC16 R_386 = 21 R_386_8 R_386 = 22 R_386_PC8 R_386 = 23 R_386_TLS_GD_32 R_386 = 24 /* 32 bit offset to GOT (index,off) pair */ R_386_TLS_GD_PUSH R_386 = 25 /* pushl instruction for Sun ABI GD sequence */ R_386_TLS_GD_CALL R_386 = 26 /* call instruction for Sun ABI GD sequence */ R_386_TLS_GD_POP R_386 = 27 /* popl instruction for Sun ABI GD sequence */ R_386_TLS_LDM_32 R_386 = 28 /* 32 bit offset to GOT (index,zero) pair */ R_386_TLS_LDM_PUSH R_386 = 29 /* pushl instruction for Sun ABI LD sequence */ R_386_TLS_LDM_CALL R_386 = 30 /* call instruction for Sun ABI LD sequence */ R_386_TLS_LDM_POP R_386 = 31 /* popl instruction for Sun ABI LD sequence */ R_386_TLS_LDO_32 R_386 = 32 /* 32 bit offset from start of TLS block */ R_386_TLS_IE_32 R_386 = 33 /* 32 bit offset to GOT static TLS offset entry */ R_386_TLS_LE_32 R_386 = 34 /* 32 bit offset within static TLS block */ R_386_TLS_DTPMOD32 R_386 = 35 /* GOT entry containing TLS index */ R_386_TLS_DTPOFF32 R_386 = 36 /* GOT entry containing TLS offset */ R_386_TLS_TPOFF32 R_386 = 37 /* GOT entry of -ve static TLS offset */ R_386_SIZE32 R_386 = 38 R_386_TLS_GOTDESC R_386 = 39 R_386_TLS_DESC_CALL R_386 = 40 R_386_TLS_DESC R_386 = 41 R_386_IRELATIVE R_386 = 42 R_386_GOT32X R_386 = 43 ) var r386Strings = []intName{ {0, "R_386_NONE"}, {1, "R_386_32"}, {2, "R_386_PC32"}, {3, "R_386_GOT32"}, {4, "R_386_PLT32"}, {5, "R_386_COPY"}, {6, "R_386_GLOB_DAT"}, {7, "R_386_JMP_SLOT"}, {8, "R_386_RELATIVE"}, {9, "R_386_GOTOFF"}, {10, "R_386_GOTPC"}, {11, "R_386_32PLT"}, {14, "R_386_TLS_TPOFF"}, {15, "R_386_TLS_IE"}, {16, "R_386_TLS_GOTIE"}, {17, "R_386_TLS_LE"}, {18, "R_386_TLS_GD"}, {19, "R_386_TLS_LDM"}, {20, "R_386_16"}, {21, "R_386_PC16"}, {22, "R_386_8"}, {23, "R_386_PC8"}, {24, "R_386_TLS_GD_32"}, {25, "R_386_TLS_GD_PUSH"}, {26, "R_386_TLS_GD_CALL"}, {27, "R_386_TLS_GD_POP"}, {28, "R_386_TLS_LDM_32"}, {29, "R_386_TLS_LDM_PUSH"}, {30, "R_386_TLS_LDM_CALL"}, {31, "R_386_TLS_LDM_POP"}, {32, "R_386_TLS_LDO_32"}, {33, "R_386_TLS_IE_32"}, {34, "R_386_TLS_LE_32"}, {35, "R_386_TLS_DTPMOD32"}, {36, "R_386_TLS_DTPOFF32"}, {37, "R_386_TLS_TPOFF32"}, {38, "R_386_SIZE32"}, {39, "R_386_TLS_GOTDESC"}, {40, "R_386_TLS_DESC_CALL"}, {41, "R_386_TLS_DESC"}, {42, "R_386_IRELATIVE"}, {43, "R_386_GOT32X"}, } func (i R_386) String() string { return stringName(uint32(i), r386Strings, false) } func (i R_386) GoString() string { return stringName(uint32(i), r386Strings, true) } // Relocation types for MIPS. type R_MIPS int const ( R_MIPS_NONE R_MIPS = 0 R_MIPS_16 R_MIPS = 1 R_MIPS_32 R_MIPS = 2 R_MIPS_REL32 R_MIPS = 3 R_MIPS_26 R_MIPS = 4 R_MIPS_HI16 R_MIPS = 5 /* high 16 bits of symbol value */ R_MIPS_LO16 R_MIPS = 6 /* low 16 bits of symbol value */ R_MIPS_GPREL16 R_MIPS = 7 /* GP-relative reference */ R_MIPS_LITERAL R_MIPS = 8 /* Reference to literal section */ R_MIPS_GOT16 R_MIPS = 9 /* Reference to global offset table */ R_MIPS_PC16 R_MIPS = 10 /* 16 bit PC relative reference */ R_MIPS_CALL16 R_MIPS = 11 /* 16 bit call through glbl offset tbl */ R_MIPS_GPREL32 R_MIPS = 12 R_MIPS_SHIFT5 R_MIPS = 16 R_MIPS_SHIFT6 R_MIPS = 17 R_MIPS_64 R_MIPS = 18 R_MIPS_GOT_DISP R_MIPS = 19 R_MIPS_GOT_PAGE R_MIPS = 20 R_MIPS_GOT_OFST R_MIPS = 21 R_MIPS_GOT_HI16 R_MIPS = 22 R_MIPS_GOT_LO16 R_MIPS = 23 R_MIPS_SUB R_MIPS = 24 R_MIPS_INSERT_A R_MIPS = 25 R_MIPS_INSERT_B R_MIPS = 26 R_MIPS_DELETE R_MIPS = 27 R_MIPS_HIGHER R_MIPS = 28 R_MIPS_HIGHEST R_MIPS = 29 R_MIPS_CALL_HI16 R_MIPS = 30 R_MIPS_CALL_LO16 R_MIPS = 31 R_MIPS_SCN_DISP R_MIPS = 32 R_MIPS_REL16 R_MIPS = 33 R_MIPS_ADD_IMMEDIATE R_MIPS = 34 R_MIPS_PJUMP R_MIPS = 35 R_MIPS_RELGOT R_MIPS = 36 R_MIPS_JALR R_MIPS = 37 R_MIPS_TLS_DTPMOD32 R_MIPS = 38 /* Module number 32 bit */ R_MIPS_TLS_DTPREL32 R_MIPS = 39 /* Module-relative offset 32 bit */ R_MIPS_TLS_DTPMOD64 R_MIPS = 40 /* Module number 64 bit */ R_MIPS_TLS_DTPREL64 R_MIPS = 41 /* Module-relative offset 64 bit */ R_MIPS_TLS_GD R_MIPS = 42 /* 16 bit GOT offset for GD */ R_MIPS_TLS_LDM R_MIPS = 43 /* 16 bit GOT offset for LDM */ R_MIPS_TLS_DTPREL_HI16 R_MIPS = 44 /* Module-relative offset, high 16 bits */ R_MIPS_TLS_DTPREL_LO16 R_MIPS = 45 /* Module-relative offset, low 16 bits */ R_MIPS_TLS_GOTTPREL R_MIPS = 46 /* 16 bit GOT offset for IE */ R_MIPS_TLS_TPREL32 R_MIPS = 47 /* TP-relative offset, 32 bit */ R_MIPS_TLS_TPREL64 R_MIPS = 48 /* TP-relative offset, 64 bit */ R_MIPS_TLS_TPREL_HI16 R_MIPS = 49 /* TP-relative offset, high 16 bits */ R_MIPS_TLS_TPREL_LO16 R_MIPS = 50 /* TP-relative offset, low 16 bits */ ) var rmipsStrings = []intName{ {0, "R_MIPS_NONE"}, {1, "R_MIPS_16"}, {2, "R_MIPS_32"}, {3, "R_MIPS_REL32"}, {4, "R_MIPS_26"}, {5, "R_MIPS_HI16"}, {6, "R_MIPS_LO16"}, {7, "R_MIPS_GPREL16"}, {8, "R_MIPS_LITERAL"}, {9, "R_MIPS_GOT16"}, {10, "R_MIPS_PC16"}, {11, "R_MIPS_CALL16"}, {12, "R_MIPS_GPREL32"}, {16, "R_MIPS_SHIFT5"}, {17, "R_MIPS_SHIFT6"}, {18, "R_MIPS_64"}, {19, "R_MIPS_GOT_DISP"}, {20, "R_MIPS_GOT_PAGE"}, {21, "R_MIPS_GOT_OFST"}, {22, "R_MIPS_GOT_HI16"}, {23, "R_MIPS_GOT_LO16"}, {24, "R_MIPS_SUB"}, {25, "R_MIPS_INSERT_A"}, {26, "R_MIPS_INSERT_B"}, {27, "R_MIPS_DELETE"}, {28, "R_MIPS_HIGHER"}, {29, "R_MIPS_HIGHEST"}, {30, "R_MIPS_CALL_HI16"}, {31, "R_MIPS_CALL_LO16"}, {32, "R_MIPS_SCN_DISP"}, {33, "R_MIPS_REL16"}, {34, "R_MIPS_ADD_IMMEDIATE"}, {35, "R_MIPS_PJUMP"}, {36, "R_MIPS_RELGOT"}, {37, "R_MIPS_JALR"}, {38, "R_MIPS_TLS_DTPMOD32"}, {39, "R_MIPS_TLS_DTPREL32"}, {40, "R_MIPS_TLS_DTPMOD64"}, {41, "R_MIPS_TLS_DTPREL64"}, {42, "R_MIPS_TLS_GD"}, {43, "R_MIPS_TLS_LDM"}, {44, "R_MIPS_TLS_DTPREL_HI16"}, {45, "R_MIPS_TLS_DTPREL_LO16"}, {46, "R_MIPS_TLS_GOTTPREL"}, {47, "R_MIPS_TLS_TPREL32"}, {48, "R_MIPS_TLS_TPREL64"}, {49, "R_MIPS_TLS_TPREL_HI16"}, {50, "R_MIPS_TLS_TPREL_LO16"}, } func (i R_MIPS) String() string { return stringName(uint32(i), rmipsStrings, false) } func (i R_MIPS) GoString() string { return stringName(uint32(i), rmipsStrings, true) } // Relocation types for PowerPC. // // Values that are shared by both R_PPC and R_PPC64 are prefixed with // R_POWERPC_ in the ELF standard. For the R_PPC type, the relevant // shared relocations have been renamed with the prefix R_PPC_. // The original name follows the value in a comment. type R_PPC int const ( R_PPC_NONE R_PPC = 0 // R_POWERPC_NONE R_PPC_ADDR32 R_PPC = 1 // R_POWERPC_ADDR32 R_PPC_ADDR24 R_PPC = 2 // R_POWERPC_ADDR24 R_PPC_ADDR16 R_PPC = 3 // R_POWERPC_ADDR16 R_PPC_ADDR16_LO R_PPC = 4 // R_POWERPC_ADDR16_LO R_PPC_ADDR16_HI R_PPC = 5 // R_POWERPC_ADDR16_HI R_PPC_ADDR16_HA R_PPC = 6 // R_POWERPC_ADDR16_HA R_PPC_ADDR14 R_PPC = 7 // R_POWERPC_ADDR14 R_PPC_ADDR14_BRTAKEN R_PPC = 8 // R_POWERPC_ADDR14_BRTAKEN R_PPC_ADDR14_BRNTAKEN R_PPC = 9 // R_POWERPC_ADDR14_BRNTAKEN R_PPC_REL24 R_PPC = 10 // R_POWERPC_REL24 R_PPC_REL14 R_PPC = 11 // R_POWERPC_REL14 R_PPC_REL14_BRTAKEN R_PPC = 12 // R_POWERPC_REL14_BRTAKEN R_PPC_REL14_BRNTAKEN R_PPC = 13 // R_POWERPC_REL14_BRNTAKEN R_PPC_GOT16 R_PPC = 14 // R_POWERPC_GOT16 R_PPC_GOT16_LO R_PPC = 15 // R_POWERPC_GOT16_LO R_PPC_GOT16_HI R_PPC = 16 // R_POWERPC_GOT16_HI R_PPC_GOT16_HA R_PPC = 17 // R_POWERPC_GOT16_HA R_PPC_PLTREL24 R_PPC = 18 R_PPC_COPY R_PPC = 19 // R_POWERPC_COPY R_PPC_GLOB_DAT R_PPC = 20 // R_POWERPC_GLOB_DAT R_PPC_JMP_SLOT R_PPC = 21 // R_POWERPC_JMP_SLOT R_PPC_RELATIVE R_PPC = 22 // R_POWERPC_RELATIVE R_PPC_LOCAL24PC R_PPC = 23 R_PPC_UADDR32 R_PPC = 24 // R_POWERPC_UADDR32 R_PPC_UADDR16 R_PPC = 25 // R_POWERPC_UADDR16 R_PPC_REL32 R_PPC = 26 // R_POWERPC_REL32 R_PPC_PLT32 R_PPC = 27 // R_POWERPC_PLT32 R_PPC_PLTREL32 R_PPC = 28 // R_POWERPC_PLTREL32 R_PPC_PLT16_LO R_PPC = 29 // R_POWERPC_PLT16_LO R_PPC_PLT16_HI R_PPC = 30 // R_POWERPC_PLT16_HI R_PPC_PLT16_HA R_PPC = 31 // R_POWERPC_PLT16_HA R_PPC_SDAREL16 R_PPC = 32 R_PPC_SECTOFF R_PPC = 33 // R_POWERPC_SECTOFF R_PPC_SECTOFF_LO R_PPC = 34 // R_POWERPC_SECTOFF_LO R_PPC_SECTOFF_HI R_PPC = 35 // R_POWERPC_SECTOFF_HI R_PPC_SECTOFF_HA R_PPC = 36 // R_POWERPC_SECTOFF_HA R_PPC_TLS R_PPC = 67 // R_POWERPC_TLS R_PPC_DTPMOD32 R_PPC = 68 // R_POWERPC_DTPMOD32 R_PPC_TPREL16 R_PPC = 69 // R_POWERPC_TPREL16 R_PPC_TPREL16_LO R_PPC = 70 // R_POWERPC_TPREL16_LO R_PPC_TPREL16_HI R_PPC = 71 // R_POWERPC_TPREL16_HI R_PPC_TPREL16_HA R_PPC = 72 // R_POWERPC_TPREL16_HA R_PPC_TPREL32 R_PPC = 73 // R_POWERPC_TPREL32 R_PPC_DTPREL16 R_PPC = 74 // R_POWERPC_DTPREL16 R_PPC_DTPREL16_LO R_PPC = 75 // R_POWERPC_DTPREL16_LO R_PPC_DTPREL16_HI R_PPC = 76 // R_POWERPC_DTPREL16_HI R_PPC_DTPREL16_HA R_PPC = 77 // R_POWERPC_DTPREL16_HA R_PPC_DTPREL32 R_PPC = 78 // R_POWERPC_DTPREL32 R_PPC_GOT_TLSGD16 R_PPC = 79 // R_POWERPC_GOT_TLSGD16 R_PPC_GOT_TLSGD16_LO R_PPC = 80 // R_POWERPC_GOT_TLSGD16_LO R_PPC_GOT_TLSGD16_HI R_PPC = 81 // R_POWERPC_GOT_TLSGD16_HI R_PPC_GOT_TLSGD16_HA R_PPC = 82 // R_POWERPC_GOT_TLSGD16_HA R_PPC_GOT_TLSLD16 R_PPC = 83 // R_POWERPC_GOT_TLSLD16 R_PPC_GOT_TLSLD16_LO R_PPC = 84 // R_POWERPC_GOT_TLSLD16_LO R_PPC_GOT_TLSLD16_HI R_PPC = 85 // R_POWERPC_GOT_TLSLD16_HI R_PPC_GOT_TLSLD16_HA R_PPC = 86 // R_POWERPC_GOT_TLSLD16_HA R_PPC_GOT_TPREL16 R_PPC = 87 // R_POWERPC_GOT_TPREL16 R_PPC_GOT_TPREL16_LO R_PPC = 88 // R_POWERPC_GOT_TPREL16_LO R_PPC_GOT_TPREL16_HI R_PPC = 89 // R_POWERPC_GOT_TPREL16_HI R_PPC_GOT_TPREL16_HA R_PPC = 90 // R_POWERPC_GOT_TPREL16_HA R_PPC_EMB_NADDR32 R_PPC = 101 R_PPC_EMB_NADDR16 R_PPC = 102 R_PPC_EMB_NADDR16_LO R_PPC = 103 R_PPC_EMB_NADDR16_HI R_PPC = 104 R_PPC_EMB_NADDR16_HA R_PPC = 105 R_PPC_EMB_SDAI16 R_PPC = 106 R_PPC_EMB_SDA2I16 R_PPC = 107 R_PPC_EMB_SDA2REL R_PPC = 108 R_PPC_EMB_SDA21 R_PPC = 109 R_PPC_EMB_MRKREF R_PPC = 110 R_PPC_EMB_RELSEC16 R_PPC = 111 R_PPC_EMB_RELST_LO R_PPC = 112 R_PPC_EMB_RELST_HI R_PPC = 113 R_PPC_EMB_RELST_HA R_PPC = 114 R_PPC_EMB_BIT_FLD R_PPC = 115 R_PPC_EMB_RELSDA R_PPC = 116 ) var rppcStrings = []intName{ {0, "R_PPC_NONE"}, {1, "R_PPC_ADDR32"}, {2, "R_PPC_ADDR24"}, {3, "R_PPC_ADDR16"}, {4, "R_PPC_ADDR16_LO"}, {5, "R_PPC_ADDR16_HI"}, {6, "R_PPC_ADDR16_HA"}, {7, "R_PPC_ADDR14"}, {8, "R_PPC_ADDR14_BRTAKEN"}, {9, "R_PPC_ADDR14_BRNTAKEN"}, {10, "R_PPC_REL24"}, {11, "R_PPC_REL14"}, {12, "R_PPC_REL14_BRTAKEN"}, {13, "R_PPC_REL14_BRNTAKEN"}, {14, "R_PPC_GOT16"}, {15, "R_PPC_GOT16_LO"}, {16, "R_PPC_GOT16_HI"}, {17, "R_PPC_GOT16_HA"}, {18, "R_PPC_PLTREL24"}, {19, "R_PPC_COPY"}, {20, "R_PPC_GLOB_DAT"}, {21, "R_PPC_JMP_SLOT"}, {22, "R_PPC_RELATIVE"}, {23, "R_PPC_LOCAL24PC"}, {24, "R_PPC_UADDR32"}, {25, "R_PPC_UADDR16"}, {26, "R_PPC_REL32"}, {27, "R_PPC_PLT32"}, {28, "R_PPC_PLTREL32"}, {29, "R_PPC_PLT16_LO"}, {30, "R_PPC_PLT16_HI"}, {31, "R_PPC_PLT16_HA"}, {32, "R_PPC_SDAREL16"}, {33, "R_PPC_SECTOFF"}, {34, "R_PPC_SECTOFF_LO"}, {35, "R_PPC_SECTOFF_HI"}, {36, "R_PPC_SECTOFF_HA"}, {67, "R_PPC_TLS"}, {68, "R_PPC_DTPMOD32"}, {69, "R_PPC_TPREL16"}, {70, "R_PPC_TPREL16_LO"}, {71, "R_PPC_TPREL16_HI"}, {72, "R_PPC_TPREL16_HA"}, {73, "R_PPC_TPREL32"}, {74, "R_PPC_DTPREL16"}, {75, "R_PPC_DTPREL16_LO"}, {76, "R_PPC_DTPREL16_HI"}, {77, "R_PPC_DTPREL16_HA"}, {78, "R_PPC_DTPREL32"}, {79, "R_PPC_GOT_TLSGD16"}, {80, "R_PPC_GOT_TLSGD16_LO"}, {81, "R_PPC_GOT_TLSGD16_HI"}, {82, "R_PPC_GOT_TLSGD16_HA"}, {83, "R_PPC_GOT_TLSLD16"}, {84, "R_PPC_GOT_TLSLD16_LO"}, {85, "R_PPC_GOT_TLSLD16_HI"}, {86, "R_PPC_GOT_TLSLD16_HA"}, {87, "R_PPC_GOT_TPREL16"}, {88, "R_PPC_GOT_TPREL16_LO"}, {89, "R_PPC_GOT_TPREL16_HI"}, {90, "R_PPC_GOT_TPREL16_HA"}, {101, "R_PPC_EMB_NADDR32"}, {102, "R_PPC_EMB_NADDR16"}, {103, "R_PPC_EMB_NADDR16_LO"}, {104, "R_PPC_EMB_NADDR16_HI"}, {105, "R_PPC_EMB_NADDR16_HA"}, {106, "R_PPC_EMB_SDAI16"}, {107, "R_PPC_EMB_SDA2I16"}, {108, "R_PPC_EMB_SDA2REL"}, {109, "R_PPC_EMB_SDA21"}, {110, "R_PPC_EMB_MRKREF"}, {111, "R_PPC_EMB_RELSEC16"}, {112, "R_PPC_EMB_RELST_LO"}, {113, "R_PPC_EMB_RELST_HI"}, {114, "R_PPC_EMB_RELST_HA"}, {115, "R_PPC_EMB_BIT_FLD"}, {116, "R_PPC_EMB_RELSDA"}, } func (i R_PPC) String() string { return stringName(uint32(i), rppcStrings, false) } func (i R_PPC) GoString() string { return stringName(uint32(i), rppcStrings, true) } // Relocation types for 64-bit PowerPC or Power Architecture processors. // // Values that are shared by both R_PPC and R_PPC64 are prefixed with // R_POWERPC_ in the ELF standard. For the R_PPC64 type, the relevant // shared relocations have been renamed with the prefix R_PPC64_. // The original name follows the value in a comment. type R_PPC64 int const ( R_PPC64_NONE R_PPC64 = 0 // R_POWERPC_NONE R_PPC64_ADDR32 R_PPC64 = 1 // R_POWERPC_ADDR32 R_PPC64_ADDR24 R_PPC64 = 2 // R_POWERPC_ADDR24 R_PPC64_ADDR16 R_PPC64 = 3 // R_POWERPC_ADDR16 R_PPC64_ADDR16_LO R_PPC64 = 4 // R_POWERPC_ADDR16_LO R_PPC64_ADDR16_HI R_PPC64 = 5 // R_POWERPC_ADDR16_HI R_PPC64_ADDR16_HA R_PPC64 = 6 // R_POWERPC_ADDR16_HA R_PPC64_ADDR14 R_PPC64 = 7 // R_POWERPC_ADDR14 R_PPC64_ADDR14_BRTAKEN R_PPC64 = 8 // R_POWERPC_ADDR14_BRTAKEN R_PPC64_ADDR14_BRNTAKEN R_PPC64 = 9 // R_POWERPC_ADDR14_BRNTAKEN R_PPC64_REL24 R_PPC64 = 10 // R_POWERPC_REL24 R_PPC64_REL14 R_PPC64 = 11 // R_POWERPC_REL14 R_PPC64_REL14_BRTAKEN R_PPC64 = 12 // R_POWERPC_REL14_BRTAKEN R_PPC64_REL14_BRNTAKEN R_PPC64 = 13 // R_POWERPC_REL14_BRNTAKEN R_PPC64_GOT16 R_PPC64 = 14 // R_POWERPC_GOT16 R_PPC64_GOT16_LO R_PPC64 = 15 // R_POWERPC_GOT16_LO R_PPC64_GOT16_HI R_PPC64 = 16 // R_POWERPC_GOT16_HI R_PPC64_GOT16_HA R_PPC64 = 17 // R_POWERPC_GOT16_HA R_PPC64_JMP_SLOT R_PPC64 = 21 // R_POWERPC_JMP_SLOT R_PPC64_REL32 R_PPC64 = 26 // R_POWERPC_REL32 R_PPC64_ADDR64 R_PPC64 = 38 R_PPC64_ADDR16_HIGHER R_PPC64 = 39 R_PPC64_ADDR16_HIGHERA R_PPC64 = 40 R_PPC64_ADDR16_HIGHEST R_PPC64 = 41 R_PPC64_ADDR16_HIGHESTA R_PPC64 = 42 R_PPC64_REL64 R_PPC64 = 44 R_PPC64_TOC16 R_PPC64 = 47 R_PPC64_TOC16_LO R_PPC64 = 48 R_PPC64_TOC16_HI R_PPC64 = 49 R_PPC64_TOC16_HA R_PPC64 = 50 R_PPC64_TOC R_PPC64 = 51 R_PPC64_PLTGOT16 R_PPC64 = 52 R_PPC64_PLTGOT16_LO R_PPC64 = 53 R_PPC64_PLTGOT16_HI R_PPC64 = 54 R_PPC64_PLTGOT16_HA R_PPC64 = 55 R_PPC64_ADDR16_DS R_PPC64 = 56 R_PPC64_ADDR16_LO_DS R_PPC64 = 57 R_PPC64_GOT16_DS R_PPC64 = 58 R_PPC64_GOT16_LO_DS R_PPC64 = 59 R_PPC64_PLT16_LO_DS R_PPC64 = 60 R_PPC64_SECTOFF_DS R_PPC64 = 61 R_PPC64_SECTOFF_LO_DS R_PPC64 = 61 R_PPC64_TOC16_DS R_PPC64 = 63 R_PPC64_TOC16_LO_DS R_PPC64 = 64 R_PPC64_PLTGOT16_DS R_PPC64 = 65 R_PPC64_PLTGOT_LO_DS R_PPC64 = 66 R_PPC64_TLS R_PPC64 = 67 // R_POWERPC_TLS R_PPC64_DTPMOD64 R_PPC64 = 68 // R_POWERPC_DTPMOD64 R_PPC64_TPREL16 R_PPC64 = 69 // R_POWERPC_TPREL16 R_PPC64_TPREL16_LO R_PPC64 = 70 // R_POWERPC_TPREL16_LO R_PPC64_TPREL16_HI R_PPC64 = 71 // R_POWERPC_TPREL16_HI R_PPC64_TPREL16_HA R_PPC64 = 72 // R_POWERPC_TPREL16_HA R_PPC64_TPREL64 R_PPC64 = 73 // R_POWERPC_TPREL64 R_PPC64_DTPREL16 R_PPC64 = 74 // R_POWERPC_DTPREL16 R_PPC64_DTPREL16_LO R_PPC64 = 75 // R_POWERPC_DTPREL16_LO R_PPC64_DTPREL16_HI R_PPC64 = 76 // R_POWERPC_DTPREL16_HI R_PPC64_DTPREL16_HA R_PPC64 = 77 // R_POWERPC_DTPREL16_HA R_PPC64_DTPREL64 R_PPC64 = 78 // R_POWERPC_DTPREL64 R_PPC64_GOT_TLSGD16 R_PPC64 = 79 // R_POWERPC_GOT_TLSGD16 R_PPC64_GOT_TLSGD16_LO R_PPC64 = 80 // R_POWERPC_GOT_TLSGD16_LO R_PPC64_GOT_TLSGD16_HI R_PPC64 = 81 // R_POWERPC_GOT_TLSGD16_HI R_PPC64_GOT_TLSGD16_HA R_PPC64 = 82 // R_POWERPC_GOT_TLSGD16_HA R_PPC64_GOT_TLSLD16 R_PPC64 = 83 // R_POWERPC_GOT_TLSLD16 R_PPC64_GOT_TLSLD16_LO R_PPC64 = 84 // R_POWERPC_GOT_TLSLD16_LO R_PPC64_GOT_TLSLD16_HI R_PPC64 = 85 // R_POWERPC_GOT_TLSLD16_HI R_PPC64_GOT_TLSLD16_HA R_PPC64 = 86 // R_POWERPC_GOT_TLSLD16_HA R_PPC64_GOT_TPREL16_DS R_PPC64 = 87 // R_POWERPC_GOT_TPREL16_DS R_PPC64_GOT_TPREL16_LO_DS R_PPC64 = 88 // R_POWERPC_GOT_TPREL16_LO_DS R_PPC64_GOT_TPREL16_HI R_PPC64 = 89 // R_POWERPC_GOT_TPREL16_HI R_PPC64_GOT_TPREL16_HA R_PPC64 = 90 // R_POWERPC_GOT_TPREL16_HA R_PPC64_GOT_DTPREL16_DS R_PPC64 = 91 // R_POWERPC_GOT_DTPREL16_DS R_PPC64_GOT_DTPREL16_LO_DS R_PPC64 = 92 // R_POWERPC_GOT_DTPREL16_LO_DS R_PPC64_GOT_DTPREL16_HI R_PPC64 = 93 // R_POWERPC_GOT_DTPREL16_HI R_PPC64_GOT_DTPREL16_HA R_PPC64 = 94 // R_POWERPC_GOT_DTPREL16_HA R_PPC64_TPREL16_DS R_PPC64 = 95 R_PPC64_TPREL16_LO_DS R_PPC64 = 96 R_PPC64_TPREL16_HIGHER R_PPC64 = 97 R_PPC64_TPREL16_HIGHERA R_PPC64 = 98 R_PPC64_TPREL16_HIGHEST R_PPC64 = 99 R_PPC64_TPREL16_HIGHESTA R_PPC64 = 100 R_PPC64_DTPREL16_DS R_PPC64 = 101 R_PPC64_DTPREL16_LO_DS R_PPC64 = 102 R_PPC64_DTPREL16_HIGHER R_PPC64 = 103 R_PPC64_DTPREL16_HIGHERA R_PPC64 = 104 R_PPC64_DTPREL16_HIGHEST R_PPC64 = 105 R_PPC64_DTPREL16_HIGHESTA R_PPC64 = 106 R_PPC64_TLSGD R_PPC64 = 107 R_PPC64_TLSLD R_PPC64 = 108 R_PPC64_TOCSAVE R_PPC64 = 109 R_PPC64_ADDR16_HIGH R_PPC64 = 110 R_PPC64_ADDR16_HIGHA R_PPC64 = 111 R_PPC64_TPREL16_HIGH R_PPC64 = 112 R_PPC64_TPREL16_HIGHA R_PPC64 = 113 R_PPC64_DTPREL16_HIGH R_PPC64 = 114 R_PPC64_DTPREL16_HIGHA R_PPC64 = 115 R_PPC64_REL24_NOTOC R_PPC64 = 116 R_PPC64_ADDR64_LOCAL R_PPC64 = 117 R_PPC64_ENTRY R_PPC64 = 118 R_PPC64_REL16DX_HA R_PPC64 = 246 // R_POWERPC_REL16DX_HA R_PPC64_JMP_IREL R_PPC64 = 247 R_PPC64_IRELATIVE R_PPC64 = 248 // R_POWERPC_IRELATIVE R_PPC64_REL16 R_PPC64 = 249 // R_POWERPC_REL16 R_PPC64_REL16_LO R_PPC64 = 250 // R_POWERPC_REL16_LO R_PPC64_REL16_HI R_PPC64 = 251 // R_POWERPC_REL16_HI R_PPC64_REL16_HA R_PPC64 = 252 // R_POWERPC_REL16_HA ) var rppc64Strings = []intName{ {0, "R_PPC64_NONE"}, {1, "R_PPC64_ADDR32"}, {2, "R_PPC64_ADDR24"}, {3, "R_PPC64_ADDR16"}, {4, "R_PPC64_ADDR16_LO"}, {5, "R_PPC64_ADDR16_HI"}, {6, "R_PPC64_ADDR16_HA"}, {7, "R_PPC64_ADDR14"}, {8, "R_PPC64_ADDR14_BRTAKEN"}, {9, "R_PPC64_ADDR14_BRNTAKEN"}, {10, "R_PPC64_REL24"}, {11, "R_PPC64_REL14"}, {12, "R_PPC64_REL14_BRTAKEN"}, {13, "R_PPC64_REL14_BRNTAKEN"}, {14, "R_PPC64_GOT16"}, {15, "R_PPC64_GOT16_LO"}, {16, "R_PPC64_GOT16_HI"}, {17, "R_PPC64_GOT16_HA"}, {21, "R_PPC64_JMP_SLOT"}, {26, "R_PPC64_REL32"}, {38, "R_PPC64_ADDR64"}, {39, "R_PPC64_ADDR16_HIGHER"}, {40, "R_PPC64_ADDR16_HIGHERA"}, {41, "R_PPC64_ADDR16_HIGHEST"}, {42, "R_PPC64_ADDR16_HIGHESTA"}, {44, "R_PPC64_REL64"}, {47, "R_PPC64_TOC16"}, {48, "R_PPC64_TOC16_LO"}, {49, "R_PPC64_TOC16_HI"}, {50, "R_PPC64_TOC16_HA"}, {51, "R_PPC64_TOC"}, {52, "R_PPC64_PLTGOT16"}, {53, "R_PPC64_PLTGOT16_LO"}, {54, "R_PPC64_PLTGOT16_HI"}, {55, "R_PPC64_PLTGOT16_HA"}, {56, "R_PPC64_ADDR16_DS"}, {57, "R_PPC64_ADDR16_LO_DS"}, {58, "R_PPC64_GOT16_DS"}, {59, "R_PPC64_GOT16_LO_DS"}, {60, "R_PPC64_PLT16_LO_DS"}, {61, "R_PPC64_SECTOFF_DS"}, {61, "R_PPC64_SECTOFF_LO_DS"}, {63, "R_PPC64_TOC16_DS"}, {64, "R_PPC64_TOC16_LO_DS"}, {65, "R_PPC64_PLTGOT16_DS"}, {66, "R_PPC64_PLTGOT_LO_DS"}, {67, "R_PPC64_TLS"}, {68, "R_PPC64_DTPMOD64"}, {69, "R_PPC64_TPREL16"}, {70, "R_PPC64_TPREL16_LO"}, {71, "R_PPC64_TPREL16_HI"}, {72, "R_PPC64_TPREL16_HA"}, {73, "R_PPC64_TPREL64"}, {74, "R_PPC64_DTPREL16"}, {75, "R_PPC64_DTPREL16_LO"}, {76, "R_PPC64_DTPREL16_HI"}, {77, "R_PPC64_DTPREL16_HA"}, {78, "R_PPC64_DTPREL64"}, {79, "R_PPC64_GOT_TLSGD16"}, {80, "R_PPC64_GOT_TLSGD16_LO"}, {81, "R_PPC64_GOT_TLSGD16_HI"}, {82, "R_PPC64_GOT_TLSGD16_HA"}, {83, "R_PPC64_GOT_TLSLD16"}, {84, "R_PPC64_GOT_TLSLD16_LO"}, {85, "R_PPC64_GOT_TLSLD16_HI"}, {86, "R_PPC64_GOT_TLSLD16_HA"}, {87, "R_PPC64_GOT_TPREL16_DS"}, {88, "R_PPC64_GOT_TPREL16_LO_DS"}, {89, "R_PPC64_GOT_TPREL16_HI"}, {90, "R_PPC64_GOT_TPREL16_HA"}, {91, "R_PPC64_GOT_DTPREL16_DS"}, {92, "R_PPC64_GOT_DTPREL16_LO_DS"}, {93, "R_PPC64_GOT_DTPREL16_HI"}, {94, "R_PPC64_GOT_DTPREL16_HA"}, {95, "R_PPC64_TPREL16_DS"}, {96, "R_PPC64_TPREL16_LO_DS"}, {97, "R_PPC64_TPREL16_HIGHER"}, {98, "R_PPC64_TPREL16_HIGHERA"}, {99, "R_PPC64_TPREL16_HIGHEST"}, {100, "R_PPC64_TPREL16_HIGHESTA"}, {101, "R_PPC64_DTPREL16_DS"}, {102, "R_PPC64_DTPREL16_LO_DS"}, {103, "R_PPC64_DTPREL16_HIGHER"}, {104, "R_PPC64_DTPREL16_HIGHERA"}, {105, "R_PPC64_DTPREL16_HIGHEST"}, {106, "R_PPC64_DTPREL16_HIGHESTA"}, {107, "R_PPC64_TLSGD"}, {108, "R_PPC64_TLSLD"}, {109, "R_PPC64_TOCSAVE"}, {110, "R_PPC64_ADDR16_HIGH"}, {111, "R_PPC64_ADDR16_HIGHA"}, {112, "R_PPC64_TPREL16_HIGH"}, {113, "R_PPC64_TPREL16_HIGHA"}, {114, "R_PPC64_DTPREL16_HIGH"}, {115, "R_PPC64_DTPREL16_HIGHA"}, {116, "R_PPC64_REL24_NOTOC"}, {117, "R_PPC64_ADDR64_LOCAL"}, {118, "R_PPC64_ENTRY"}, {246, "R_PPC64_REL16DX_HA"}, {247, "R_PPC64_JMP_IREL"}, {248, "R_PPC64_IRELATIVE"}, {249, "R_PPC64_REL16"}, {250, "R_PPC64_REL16_LO"}, {251, "R_PPC64_REL16_HI"}, {252, "R_PPC64_REL16_HA"}, } func (i R_PPC64) String() string { return stringName(uint32(i), rppc64Strings, false) } func (i R_PPC64) GoString() string { return stringName(uint32(i), rppc64Strings, true) } // Relocation types for RISC-V processors. type R_RISCV int const ( R_RISCV_NONE R_RISCV = 0 /* No relocation. */ R_RISCV_32 R_RISCV = 1 /* Add 32 bit zero extended symbol value */ R_RISCV_64 R_RISCV = 2 /* Add 64 bit symbol value. */ R_RISCV_RELATIVE R_RISCV = 3 /* Add load address of shared object. */ R_RISCV_COPY R_RISCV = 4 /* Copy data from shared object. */ R_RISCV_JUMP_SLOT R_RISCV = 5 /* Set GOT entry to code address. */ R_RISCV_TLS_DTPMOD32 R_RISCV = 6 /* 32 bit ID of module containing symbol */ R_RISCV_TLS_DTPMOD64 R_RISCV = 7 /* ID of module containing symbol */ R_RISCV_TLS_DTPREL32 R_RISCV = 8 /* 32 bit relative offset in TLS block */ R_RISCV_TLS_DTPREL64 R_RISCV = 9 /* Relative offset in TLS block */ R_RISCV_TLS_TPREL32 R_RISCV = 10 /* 32 bit relative offset in static TLS block */ R_RISCV_TLS_TPREL64 R_RISCV = 11 /* Relative offset in static TLS block */ R_RISCV_BRANCH R_RISCV = 16 /* PC-relative branch */ R_RISCV_JAL R_RISCV = 17 /* PC-relative jump */ R_RISCV_CALL R_RISCV = 18 /* PC-relative call */ R_RISCV_CALL_PLT R_RISCV = 19 /* PC-relative call (PLT) */ R_RISCV_GOT_HI20 R_RISCV = 20 /* PC-relative GOT reference */ R_RISCV_TLS_GOT_HI20 R_RISCV = 21 /* PC-relative TLS IE GOT offset */ R_RISCV_TLS_GD_HI20 R_RISCV = 22 /* PC-relative TLS GD reference */ R_RISCV_PCREL_HI20 R_RISCV = 23 /* PC-relative reference */ R_RISCV_PCREL_LO12_I R_RISCV = 24 /* PC-relative reference */ R_RISCV_PCREL_LO12_S R_RISCV = 25 /* PC-relative reference */ R_RISCV_HI20 R_RISCV = 26 /* Absolute address */ R_RISCV_LO12_I R_RISCV = 27 /* Absolute address */ R_RISCV_LO12_S R_RISCV = 28 /* Absolute address */ R_RISCV_TPREL_HI20 R_RISCV = 29 /* TLS LE thread offset */ R_RISCV_TPREL_LO12_I R_RISCV = 30 /* TLS LE thread offset */ R_RISCV_TPREL_LO12_S R_RISCV = 31 /* TLS LE thread offset */ R_RISCV_TPREL_ADD R_RISCV = 32 /* TLS LE thread usage */ R_RISCV_ADD8 R_RISCV = 33 /* 8-bit label addition */ R_RISCV_ADD16 R_RISCV = 34 /* 16-bit label addition */ R_RISCV_ADD32 R_RISCV = 35 /* 32-bit label addition */ R_RISCV_ADD64 R_RISCV = 36 /* 64-bit label addition */ R_RISCV_SUB8 R_RISCV = 37 /* 8-bit label subtraction */ R_RISCV_SUB16 R_RISCV = 38 /* 16-bit label subtraction */ R_RISCV_SUB32 R_RISCV = 39 /* 32-bit label subtraction */ R_RISCV_SUB64 R_RISCV = 40 /* 64-bit label subtraction */ R_RISCV_GNU_VTINHERIT R_RISCV = 41 /* GNU C++ vtable hierarchy */ R_RISCV_GNU_VTENTRY R_RISCV = 42 /* GNU C++ vtable member usage */ R_RISCV_ALIGN R_RISCV = 43 /* Alignment statement */ R_RISCV_RVC_BRANCH R_RISCV = 44 /* PC-relative branch offset */ R_RISCV_RVC_JUMP R_RISCV = 45 /* PC-relative jump offset */ R_RISCV_RVC_LUI R_RISCV = 46 /* Absolute address */ R_RISCV_GPREL_I R_RISCV = 47 /* GP-relative reference */ R_RISCV_GPREL_S R_RISCV = 48 /* GP-relative reference */ R_RISCV_TPREL_I R_RISCV = 49 /* TP-relative TLS LE load */ R_RISCV_TPREL_S R_RISCV = 50 /* TP-relative TLS LE store */ R_RISCV_RELAX R_RISCV = 51 /* Instruction pair can be relaxed */ R_RISCV_SUB6 R_RISCV = 52 /* Local label subtraction */ R_RISCV_SET6 R_RISCV = 53 /* Local label subtraction */ R_RISCV_SET8 R_RISCV = 54 /* Local label subtraction */ R_RISCV_SET16 R_RISCV = 55 /* Local label subtraction */ R_RISCV_SET32 R_RISCV = 56 /* Local label subtraction */ ) var rriscvStrings = []intName{ {0, "R_RISCV_NONE"}, {1, "R_RISCV_32"}, {2, "R_RISCV_64"}, {3, "R_RISCV_RELATIVE"}, {4, "R_RISCV_COPY"}, {5, "R_RISCV_JUMP_SLOT"}, {6, "R_RISCV_TLS_DTPMOD32"}, {7, "R_RISCV_TLS_DTPMOD64"}, {8, "R_RISCV_TLS_DTPREL32"}, {9, "R_RISCV_TLS_DTPREL64"}, {10, "R_RISCV_TLS_TPREL32"}, {11, "R_RISCV_TLS_TPREL64"}, {16, "R_RISCV_BRANCH"}, {17, "R_RISCV_JAL"}, {18, "R_RISCV_CALL"}, {19, "R_RISCV_CALL_PLT"}, {20, "R_RISCV_GOT_HI20"}, {21, "R_RISCV_TLS_GOT_HI20"}, {22, "R_RISCV_TLS_GD_HI20"}, {23, "R_RISCV_PCREL_HI20"}, {24, "R_RISCV_PCREL_LO12_I"}, {25, "R_RISCV_PCREL_LO12_S"}, {26, "R_RISCV_HI20"}, {27, "R_RISCV_LO12_I"}, {28, "R_RISCV_LO12_S"}, {29, "R_RISCV_TPREL_HI20"}, {30, "R_RISCV_TPREL_LO12_I"}, {31, "R_RISCV_TPREL_LO12_S"}, {32, "R_RISCV_TPREL_ADD"}, {33, "R_RISCV_ADD8"}, {34, "R_RISCV_ADD16"}, {35, "R_RISCV_ADD32"}, {36, "R_RISCV_ADD64"}, {37, "R_RISCV_SUB8"}, {38, "R_RISCV_SUB16"}, {39, "R_RISCV_SUB32"}, {40, "R_RISCV_SUB64"}, {41, "R_RISCV_GNU_VTINHERIT"}, {42, "R_RISCV_GNU_VTENTRY"}, {43, "R_RISCV_ALIGN"}, {44, "R_RISCV_RVC_BRANCH"}, {45, "R_RISCV_RVC_JUMP"}, {46, "R_RISCV_RVC_LUI"}, {47, "R_RISCV_GPREL_I"}, {48, "R_RISCV_GPREL_S"}, {49, "R_RISCV_TPREL_I"}, {50, "R_RISCV_TPREL_S"}, {51, "R_RISCV_RELAX"}, {52, "R_RISCV_SUB6"}, {53, "R_RISCV_SET6"}, {54, "R_RISCV_SET8"}, {55, "R_RISCV_SET16"}, {56, "R_RISCV_SET32"}, } func (i R_RISCV) String() string { return stringName(uint32(i), rriscvStrings, false) } func (i R_RISCV) GoString() string { return stringName(uint32(i), rriscvStrings, true) } // Relocation types for s390x processors. type R_390 int const ( R_390_NONE R_390 = 0 R_390_8 R_390 = 1 R_390_12 R_390 = 2 R_390_16 R_390 = 3 R_390_32 R_390 = 4 R_390_PC32 R_390 = 5 R_390_GOT12 R_390 = 6 R_390_GOT32 R_390 = 7 R_390_PLT32 R_390 = 8 R_390_COPY R_390 = 9 R_390_GLOB_DAT R_390 = 10 R_390_JMP_SLOT R_390 = 11 R_390_RELATIVE R_390 = 12 R_390_GOTOFF R_390 = 13 R_390_GOTPC R_390 = 14 R_390_GOT16 R_390 = 15 R_390_PC16 R_390 = 16 R_390_PC16DBL R_390 = 17 R_390_PLT16DBL R_390 = 18 R_390_PC32DBL R_390 = 19 R_390_PLT32DBL R_390 = 20 R_390_GOTPCDBL R_390 = 21 R_390_64 R_390 = 22 R_390_PC64 R_390 = 23 R_390_GOT64 R_390 = 24 R_390_PLT64 R_390 = 25 R_390_GOTENT R_390 = 26 R_390_GOTOFF16 R_390 = 27 R_390_GOTOFF64 R_390 = 28 R_390_GOTPLT12 R_390 = 29 R_390_GOTPLT16 R_390 = 30 R_390_GOTPLT32 R_390 = 31 R_390_GOTPLT64 R_390 = 32 R_390_GOTPLTENT R_390 = 33 R_390_GOTPLTOFF16 R_390 = 34 R_390_GOTPLTOFF32 R_390 = 35 R_390_GOTPLTOFF64 R_390 = 36 R_390_TLS_LOAD R_390 = 37 R_390_TLS_GDCALL R_390 = 38 R_390_TLS_LDCALL R_390 = 39 R_390_TLS_GD32 R_390 = 40 R_390_TLS_GD64 R_390 = 41 R_390_TLS_GOTIE12 R_390 = 42 R_390_TLS_GOTIE32 R_390 = 43 R_390_TLS_GOTIE64 R_390 = 44 R_390_TLS_LDM32 R_390 = 45 R_390_TLS_LDM64 R_390 = 46 R_390_TLS_IE32 R_390 = 47 R_390_TLS_IE64 R_390 = 48 R_390_TLS_IEENT R_390 = 49 R_390_TLS_LE32 R_390 = 50 R_390_TLS_LE64 R_390 = 51 R_390_TLS_LDO32 R_390 = 52 R_390_TLS_LDO64 R_390 = 53 R_390_TLS_DTPMOD R_390 = 54 R_390_TLS_DTPOFF R_390 = 55 R_390_TLS_TPOFF R_390 = 56 R_390_20 R_390 = 57 R_390_GOT20 R_390 = 58 R_390_GOTPLT20 R_390 = 59 R_390_TLS_GOTIE20 R_390 = 60 ) var r390Strings = []intName{ {0, "R_390_NONE"}, {1, "R_390_8"}, {2, "R_390_12"}, {3, "R_390_16"}, {4, "R_390_32"}, {5, "R_390_PC32"}, {6, "R_390_GOT12"}, {7, "R_390_GOT32"}, {8, "R_390_PLT32"}, {9, "R_390_COPY"}, {10, "R_390_GLOB_DAT"}, {11, "R_390_JMP_SLOT"}, {12, "R_390_RELATIVE"}, {13, "R_390_GOTOFF"}, {14, "R_390_GOTPC"}, {15, "R_390_GOT16"}, {16, "R_390_PC16"}, {17, "R_390_PC16DBL"}, {18, "R_390_PLT16DBL"}, {19, "R_390_PC32DBL"}, {20, "R_390_PLT32DBL"}, {21, "R_390_GOTPCDBL"}, {22, "R_390_64"}, {23, "R_390_PC64"}, {24, "R_390_GOT64"}, {25, "R_390_PLT64"}, {26, "R_390_GOTENT"}, {27, "R_390_GOTOFF16"}, {28, "R_390_GOTOFF64"}, {29, "R_390_GOTPLT12"}, {30, "R_390_GOTPLT16"}, {31, "R_390_GOTPLT32"}, {32, "R_390_GOTPLT64"}, {33, "R_390_GOTPLTENT"}, {34, "R_390_GOTPLTOFF16"}, {35, "R_390_GOTPLTOFF32"}, {36, "R_390_GOTPLTOFF64"}, {37, "R_390_TLS_LOAD"}, {38, "R_390_TLS_GDCALL"}, {39, "R_390_TLS_LDCALL"}, {40, "R_390_TLS_GD32"}, {41, "R_390_TLS_GD64"}, {42, "R_390_TLS_GOTIE12"}, {43, "R_390_TLS_GOTIE32"}, {44, "R_390_TLS_GOTIE64"}, {45, "R_390_TLS_LDM32"}, {46, "R_390_TLS_LDM64"}, {47, "R_390_TLS_IE32"}, {48, "R_390_TLS_IE64"}, {49, "R_390_TLS_IEENT"}, {50, "R_390_TLS_LE32"}, {51, "R_390_TLS_LE64"}, {52, "R_390_TLS_LDO32"}, {53, "R_390_TLS_LDO64"}, {54, "R_390_TLS_DTPMOD"}, {55, "R_390_TLS_DTPOFF"}, {56, "R_390_TLS_TPOFF"}, {57, "R_390_20"}, {58, "R_390_GOT20"}, {59, "R_390_GOTPLT20"}, {60, "R_390_TLS_GOTIE20"}, } func (i R_390) String() string { return stringName(uint32(i), r390Strings, false) } func (i R_390) GoString() string { return stringName(uint32(i), r390Strings, true) } // Relocation types for SPARC. type R_SPARC int const ( R_SPARC_NONE R_SPARC = 0 R_SPARC_8 R_SPARC = 1 R_SPARC_16 R_SPARC = 2 R_SPARC_32 R_SPARC = 3 R_SPARC_DISP8 R_SPARC = 4 R_SPARC_DISP16 R_SPARC = 5 R_SPARC_DISP32 R_SPARC = 6 R_SPARC_WDISP30 R_SPARC = 7 R_SPARC_WDISP22 R_SPARC = 8 R_SPARC_HI22 R_SPARC = 9 R_SPARC_22 R_SPARC = 10 R_SPARC_13 R_SPARC = 11 R_SPARC_LO10 R_SPARC = 12 R_SPARC_GOT10 R_SPARC = 13 R_SPARC_GOT13 R_SPARC = 14 R_SPARC_GOT22 R_SPARC = 15 R_SPARC_PC10 R_SPARC = 16 R_SPARC_PC22 R_SPARC = 17 R_SPARC_WPLT30 R_SPARC = 18 R_SPARC_COPY R_SPARC = 19 R_SPARC_GLOB_DAT R_SPARC = 20 R_SPARC_JMP_SLOT R_SPARC = 21 R_SPARC_RELATIVE R_SPARC = 22 R_SPARC_UA32 R_SPARC = 23 R_SPARC_PLT32 R_SPARC = 24 R_SPARC_HIPLT22 R_SPARC = 25 R_SPARC_LOPLT10 R_SPARC = 26 R_SPARC_PCPLT32 R_SPARC = 27 R_SPARC_PCPLT22 R_SPARC = 28 R_SPARC_PCPLT10 R_SPARC = 29 R_SPARC_10 R_SPARC = 30 R_SPARC_11 R_SPARC = 31 R_SPARC_64 R_SPARC = 32 R_SPARC_OLO10 R_SPARC = 33 R_SPARC_HH22 R_SPARC = 34 R_SPARC_HM10 R_SPARC = 35 R_SPARC_LM22 R_SPARC = 36 R_SPARC_PC_HH22 R_SPARC = 37 R_SPARC_PC_HM10 R_SPARC = 38 R_SPARC_PC_LM22 R_SPARC = 39 R_SPARC_WDISP16 R_SPARC = 40 R_SPARC_WDISP19 R_SPARC = 41 R_SPARC_GLOB_JMP R_SPARC = 42 R_SPARC_7 R_SPARC = 43 R_SPARC_5 R_SPARC = 44 R_SPARC_6 R_SPARC = 45 R_SPARC_DISP64 R_SPARC = 46 R_SPARC_PLT64 R_SPARC = 47 R_SPARC_HIX22 R_SPARC = 48 R_SPARC_LOX10 R_SPARC = 49 R_SPARC_H44 R_SPARC = 50 R_SPARC_M44 R_SPARC = 51 R_SPARC_L44 R_SPARC = 52 R_SPARC_REGISTER R_SPARC = 53 R_SPARC_UA64 R_SPARC = 54 R_SPARC_UA16 R_SPARC = 55 ) var rsparcStrings = []intName{ {0, "R_SPARC_NONE"}, {1, "R_SPARC_8"}, {2, "R_SPARC_16"}, {3, "R_SPARC_32"}, {4, "R_SPARC_DISP8"}, {5, "R_SPARC_DISP16"}, {6, "R_SPARC_DISP32"}, {7, "R_SPARC_WDISP30"}, {8, "R_SPARC_WDISP22"}, {9, "R_SPARC_HI22"}, {10, "R_SPARC_22"}, {11, "R_SPARC_13"}, {12, "R_SPARC_LO10"}, {13, "R_SPARC_GOT10"}, {14, "R_SPARC_GOT13"}, {15, "R_SPARC_GOT22"}, {16, "R_SPARC_PC10"}, {17, "R_SPARC_PC22"}, {18, "R_SPARC_WPLT30"}, {19, "R_SPARC_COPY"}, {20, "R_SPARC_GLOB_DAT"}, {21, "R_SPARC_JMP_SLOT"}, {22, "R_SPARC_RELATIVE"}, {23, "R_SPARC_UA32"}, {24, "R_SPARC_PLT32"}, {25, "R_SPARC_HIPLT22"}, {26, "R_SPARC_LOPLT10"}, {27, "R_SPARC_PCPLT32"}, {28, "R_SPARC_PCPLT22"}, {29, "R_SPARC_PCPLT10"}, {30, "R_SPARC_10"}, {31, "R_SPARC_11"}, {32, "R_SPARC_64"}, {33, "R_SPARC_OLO10"}, {34, "R_SPARC_HH22"}, {35, "R_SPARC_HM10"}, {36, "R_SPARC_LM22"}, {37, "R_SPARC_PC_HH22"}, {38, "R_SPARC_PC_HM10"}, {39, "R_SPARC_PC_LM22"}, {40, "R_SPARC_WDISP16"}, {41, "R_SPARC_WDISP19"}, {42, "R_SPARC_GLOB_JMP"}, {43, "R_SPARC_7"}, {44, "R_SPARC_5"}, {45, "R_SPARC_6"}, {46, "R_SPARC_DISP64"}, {47, "R_SPARC_PLT64"}, {48, "R_SPARC_HIX22"}, {49, "R_SPARC_LOX10"}, {50, "R_SPARC_H44"}, {51, "R_SPARC_M44"}, {52, "R_SPARC_L44"}, {53, "R_SPARC_REGISTER"}, {54, "R_SPARC_UA64"}, {55, "R_SPARC_UA16"}, } func (i R_SPARC) String() string { return stringName(uint32(i), rsparcStrings, false) } func (i R_SPARC) GoString() string { return stringName(uint32(i), rsparcStrings, true) } // Magic number for the elf trampoline, chosen wisely to be an immediate value. const ARM_MAGIC_TRAMP_NUMBER = 0x5c000003 // ELF32 File header. type Header32 struct { Ident [EI_NIDENT]byte /* File identification. */ Type uint16 /* File type. */ Machine uint16 /* Machine architecture. */ Version uint32 /* ELF format version. */ Entry uint32 /* Entry point. */ Phoff uint32 /* Program header file offset. */ Shoff uint32 /* Section header file offset. */ Flags uint32 /* Architecture-specific flags. */ Ehsize uint16 /* Size of ELF header in bytes. */ Phentsize uint16 /* Size of program header entry. */ Phnum uint16 /* Number of program header entries. */ Shentsize uint16 /* Size of section header entry. */ Shnum uint16 /* Number of section header entries. */ Shstrndx uint16 /* Section name strings section. */ } // ELF32 Section header. type Section32 struct { Name uint32 /* Section name (index into the section header string table). */ Type uint32 /* Section type. */ Flags uint32 /* Section flags. */ Addr uint32 /* Address in memory image. */ Off uint32 /* Offset in file. */ Size uint32 /* Size in bytes. */ Link uint32 /* Index of a related section. */ Info uint32 /* Depends on section type. */ Addralign uint32 /* Alignment in bytes. */ Entsize uint32 /* Size of each entry in section. */ } // ELF32 Program header. type Prog32 struct { Type uint32 /* Entry type. */ Off uint32 /* File offset of contents. */ Vaddr uint32 /* Virtual address in memory image. */ Paddr uint32 /* Physical address (not used). */ Filesz uint32 /* Size of contents in file. */ Memsz uint32 /* Size of contents in memory. */ Flags uint32 /* Access permission flags. */ Align uint32 /* Alignment in memory and file. */ } // ELF32 Dynamic structure. The ".dynamic" section contains an array of them. type Dyn32 struct { Tag int32 /* Entry type. */ Val uint32 /* Integer/Address value. */ } // ELF32 Compression header. type Chdr32 struct { Type uint32 Size uint32 Addralign uint32 } /* * Relocation entries. */ // ELF32 Relocations that don't need an addend field. type Rel32 struct { Off uint32 /* Location to be relocated. */ Info uint32 /* Relocation type and symbol index. */ } // ELF32 Relocations that need an addend field. type Rela32 struct { Off uint32 /* Location to be relocated. */ Info uint32 /* Relocation type and symbol index. */ Addend int32 /* Addend. */ } func R_SYM32(info uint32) uint32 { return info >> 8 } func R_TYPE32(info uint32) uint32 { return info & 0xff } func R_INFO32(sym, typ uint32) uint32 { return sym<<8 | typ } // ELF32 Symbol. type Sym32 struct { Name uint32 Value uint32 Size uint32 Info uint8 Other uint8 Shndx uint16 } const Sym32Size = 16 func ST_BIND(info uint8) SymBind { return SymBind(info >> 4) } func ST_TYPE(info uint8) SymType { return SymType(info & 0xF) } func ST_INFO(bind SymBind, typ SymType) uint8 { return uint8(bind)<<4 | uint8(typ)&0xf } func ST_VISIBILITY(other uint8) SymVis { return SymVis(other & 3) } /* * ELF64 */ // ELF64 file header. type Header64 struct { Ident [EI_NIDENT]byte /* File identification. */ Type uint16 /* File type. */ Machine uint16 /* Machine architecture. */ Version uint32 /* ELF format version. */ Entry uint64 /* Entry point. */ Phoff uint64 /* Program header file offset. */ Shoff uint64 /* Section header file offset. */ Flags uint32 /* Architecture-specific flags. */ Ehsize uint16 /* Size of ELF header in bytes. */ Phentsize uint16 /* Size of program header entry. */ Phnum uint16 /* Number of program header entries. */ Shentsize uint16 /* Size of section header entry. */ Shnum uint16 /* Number of section header entries. */ Shstrndx uint16 /* Section name strings section. */ } // ELF64 Section header. type Section64 struct { Name uint32 /* Section name (index into the section header string table). */ Type uint32 /* Section type. */ Flags uint64 /* Section flags. */ Addr uint64 /* Address in memory image. */ Off uint64 /* Offset in file. */ Size uint64 /* Size in bytes. */ Link uint32 /* Index of a related section. */ Info uint32 /* Depends on section type. */ Addralign uint64 /* Alignment in bytes. */ Entsize uint64 /* Size of each entry in section. */ } // ELF64 Program header. type Prog64 struct { Type uint32 /* Entry type. */ Flags uint32 /* Access permission flags. */ Off uint64 /* File offset of contents. */ Vaddr uint64 /* Virtual address in memory image. */ Paddr uint64 /* Physical address (not used). */ Filesz uint64 /* Size of contents in file. */ Memsz uint64 /* Size of contents in memory. */ Align uint64 /* Alignment in memory and file. */ } // ELF64 Dynamic structure. The ".dynamic" section contains an array of them. type Dyn64 struct { Tag int64 /* Entry type. */ Val uint64 /* Integer/address value */ } // ELF64 Compression header. type Chdr64 struct { Type uint32 _ uint32 /* Reserved. */ Size uint64 Addralign uint64 } /* * Relocation entries. */ /* ELF64 relocations that don't need an addend field. */ type Rel64 struct { Off uint64 /* Location to be relocated. */ Info uint64 /* Relocation type and symbol index. */ } /* ELF64 relocations that need an addend field. */ type Rela64 struct { Off uint64 /* Location to be relocated. */ Info uint64 /* Relocation type and symbol index. */ Addend int64 /* Addend. */ } func R_SYM64(info uint64) uint32 { return uint32(info >> 32) } func R_TYPE64(info uint64) uint32 { return uint32(info) } func R_INFO(sym, typ uint32) uint64 { return uint64(sym)<<32 | uint64(typ) } // ELF64 symbol table entries. type Sym64 struct { Name uint32 /* String table index of name. */ Info uint8 /* Type and binding information. */ Other uint8 /* Reserved (not used). */ Shndx uint16 /* Section index of symbol. */ Value uint64 /* Symbol value. */ Size uint64 /* Size of associated object. */ } const Sym64Size = 24 type intName struct { i uint32 s string } func stringName(i uint32, names []intName, goSyntax bool) string { for _, n := range names { if n.i == i { if goSyntax { return "elf." + n.s } return n.s } } // second pass - look for smaller to add with. // assume sorted already for j := len(names) - 1; j >= 0; j-- { n := names[j] if n.i < i { s := n.s if goSyntax { s = "elf." + s } return s + "+" + strconv.FormatUint(uint64(i-n.i), 10) } } return strconv.FormatUint(uint64(i), 10) } func flagName(i uint32, names []intName, goSyntax bool) string { s := "" for _, n := range names { if n.i&i == n.i { if len(s) > 0 { s += "+" } if goSyntax { s += "elf." } s += n.s i -= n.i } } if len(s) == 0 { return "0x" + strconv.FormatUint(uint64(i), 16) } if i != 0 { s += "+0x" + strconv.FormatUint(uint64(i), 16) } return s } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/elf/elf_test.go000066400000000000000000000031041356504100700270260ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package elf import ( "fmt" "testing" ) type nameTest struct { val interface{} str string } var nameTests = []nameTest{ {ELFOSABI_LINUX, "ELFOSABI_LINUX"}, {ET_EXEC, "ET_EXEC"}, {EM_860, "EM_860"}, {SHN_LOPROC, "SHN_LOPROC"}, {SHT_PROGBITS, "SHT_PROGBITS"}, {SHF_MERGE + SHF_TLS, "SHF_MERGE+SHF_TLS"}, {PT_LOAD, "PT_LOAD"}, {PF_W + PF_R + 0x50, "PF_W+PF_R+0x50"}, {DT_SYMBOLIC, "DT_SYMBOLIC"}, {DF_BIND_NOW, "DF_BIND_NOW"}, {NT_FPREGSET, "NT_FPREGSET"}, {STB_GLOBAL, "STB_GLOBAL"}, {STT_COMMON, "STT_COMMON"}, {STV_HIDDEN, "STV_HIDDEN"}, {R_X86_64_PC32, "R_X86_64_PC32"}, {R_ALPHA_OP_PUSH, "R_ALPHA_OP_PUSH"}, {R_ARM_THM_ABS5, "R_ARM_THM_ABS5"}, {R_386_GOT32, "R_386_GOT32"}, {R_PPC_GOT16_HI, "R_PPC_GOT16_HI"}, {R_SPARC_GOT22, "R_SPARC_GOT22"}, {ET_LOOS + 5, "ET_LOOS+5"}, {ProgFlag(0x50), "0x50"}, } func TestNames(t *testing.T) { for i, tt := range nameTests { s := fmt.Sprint(tt.val) if s != tt.str { t.Errorf("#%d: Sprint(%d) = %q, want %q", i, tt.val, s, tt.str) } } } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/elf/file.go000066400000000000000000001030221356504100700261400ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package elf implements access to ELF object files. package elf import ( "bytes" "compress/zlib" "encoding/binary" "errors" "fmt" "io" "os" "strings" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/dwarf" ) // seekStart, seekCurrent, seekEnd are copies of // io.SeekStart, io.SeekCurrent, and io.SeekEnd. // We can't use the ones from package io because // we want this code to build with Go 1.4 during // cmd/dist bootstrap. const ( seekStart int = 0 seekCurrent int = 1 seekEnd int = 2 ) // TODO: error reporting detail /* * Internal ELF representation */ // A FileHeader represents an ELF file header. type FileHeader struct { Class Class Data Data Version Version OSABI OSABI ABIVersion uint8 ByteOrder binary.ByteOrder Type Type Machine Machine Entry uint64 } // A File represents an open ELF file. type File struct { FileHeader Sections []*Section Progs []*Prog closer io.Closer gnuNeed []verneed gnuVersym []byte } // A SectionHeader represents a single ELF section header. type SectionHeader struct { Name string Type SectionType Flags SectionFlag Addr uint64 Offset uint64 Size uint64 Link uint32 Info uint32 Addralign uint64 Entsize uint64 // FileSize is the size of this section in the file in bytes. // If a section is compressed, FileSize is the size of the // compressed data, while Size (above) is the size of the // uncompressed data. FileSize uint64 } // A Section represents a single section in an ELF file. type Section struct { SectionHeader // Embed ReaderAt for ReadAt method. // Do not embed SectionReader directly // to avoid having Read and Seek. // If a client wants Read and Seek it must use // Open() to avoid fighting over the seek offset // with other clients. // // ReaderAt may be nil if the section is not easily available // in a random-access form. For example, a compressed section // may have a nil ReaderAt. io.ReaderAt sr *io.SectionReader compressionType CompressionType compressionOffset int64 } // Data reads and returns the contents of the ELF section. // Even if the section is stored compressed in the ELF file, // Data returns uncompressed data. func (s *Section) Data() ([]byte, error) { dat := make([]byte, s.Size) n, err := io.ReadFull(s.Open(), dat) return dat[0:n], err } // stringTable reads and returns the string table given by the // specified link value. func (f *File) stringTable(link uint32) ([]byte, error) { if link <= 0 || link >= uint32(len(f.Sections)) { return nil, errors.New("section has invalid string table link") } return f.Sections[link].Data() } // Open returns a new ReadSeeker reading the ELF section. // Even if the section is stored compressed in the ELF file, // the ReadSeeker reads uncompressed data. func (s *Section) Open() io.ReadSeeker { if s.Flags&SHF_COMPRESSED == 0 { return io.NewSectionReader(s.sr, 0, 1<<63-1) } if s.compressionType == COMPRESS_ZLIB { return &readSeekerFromReader{ reset: func() (io.Reader, error) { fr := io.NewSectionReader(s.sr, s.compressionOffset, int64(s.FileSize)-s.compressionOffset) return zlib.NewReader(fr) }, size: int64(s.Size), } } err := &FormatError{int64(s.Offset), "unknown compression type", s.compressionType} return errorReader{err} } // A ProgHeader represents a single ELF program header. type ProgHeader struct { Type ProgType Flags ProgFlag Off uint64 Vaddr uint64 Paddr uint64 Filesz uint64 Memsz uint64 Align uint64 } // A Prog represents a single ELF program header in an ELF binary. type Prog struct { ProgHeader // Embed ReaderAt for ReadAt method. // Do not embed SectionReader directly // to avoid having Read and Seek. // If a client wants Read and Seek it must use // Open() to avoid fighting over the seek offset // with other clients. io.ReaderAt sr *io.SectionReader } // Open returns a new ReadSeeker reading the ELF program body. func (p *Prog) Open() io.ReadSeeker { return io.NewSectionReader(p.sr, 0, 1<<63-1) } // A Symbol represents an entry in an ELF symbol table section. type Symbol struct { Name string Info, Other byte Section SectionIndex Value, Size uint64 } /* * ELF reader */ type FormatError struct { off int64 msg string val interface{} } func (e *FormatError) Error() string { msg := e.msg if e.val != nil { msg += fmt.Sprintf(" '%v' ", e.val) } msg += fmt.Sprintf("in record at byte %#x", e.off) return msg } // Open opens the named file using os.Open and prepares it for use as an ELF binary. func Open(name string) (*File, error) { f, err := os.Open(name) if err != nil { return nil, err } ff, err := NewFile(f) if err != nil { f.Close() return nil, err } ff.closer = f return ff, nil } // Close closes the File. // If the File was created using NewFile directly instead of Open, // Close has no effect. func (f *File) Close() error { var err error if f.closer != nil { err = f.closer.Close() f.closer = nil } return err } // SectionByType returns the first section in f with the // given type, or nil if there is no such section. func (f *File) SectionByType(typ SectionType) *Section { for _, s := range f.Sections { if s.Type == typ { return s } } return nil } // NewFile creates a new File for accessing an ELF binary in an underlying reader. // The ELF binary is expected to start at position 0 in the ReaderAt. func NewFile(r io.ReaderAt) (*File, error) { sr := io.NewSectionReader(r, 0, 1<<63-1) // Read and decode ELF identifier var ident [16]uint8 if _, err := r.ReadAt(ident[0:], 0); err != nil { return nil, err } if ident[0] != '\x7f' || ident[1] != 'E' || ident[2] != 'L' || ident[3] != 'F' { return nil, &FormatError{0, "bad magic number", ident[0:4]} } f := new(File) f.Class = Class(ident[EI_CLASS]) switch f.Class { case ELFCLASS32: case ELFCLASS64: // ok default: return nil, &FormatError{0, "unknown ELF class", f.Class} } f.Data = Data(ident[EI_DATA]) switch f.Data { case ELFDATA2LSB: f.ByteOrder = binary.LittleEndian case ELFDATA2MSB: f.ByteOrder = binary.BigEndian default: return nil, &FormatError{0, "unknown ELF data encoding", f.Data} } f.Version = Version(ident[EI_VERSION]) if f.Version != EV_CURRENT { return nil, &FormatError{0, "unknown ELF version", f.Version} } f.OSABI = OSABI(ident[EI_OSABI]) f.ABIVersion = ident[EI_ABIVERSION] // Read ELF file header var phoff int64 var phentsize, phnum int var shoff int64 var shentsize, shnum, shstrndx int shstrndx = -1 switch f.Class { case ELFCLASS32: hdr := new(Header32) sr.Seek(0, seekStart) if err := binary.Read(sr, f.ByteOrder, hdr); err != nil { return nil, err } f.Type = Type(hdr.Type) f.Machine = Machine(hdr.Machine) f.Entry = uint64(hdr.Entry) if v := Version(hdr.Version); v != f.Version { return nil, &FormatError{0, "mismatched ELF version", v} } phoff = int64(hdr.Phoff) phentsize = int(hdr.Phentsize) phnum = int(hdr.Phnum) shoff = int64(hdr.Shoff) shentsize = int(hdr.Shentsize) shnum = int(hdr.Shnum) shstrndx = int(hdr.Shstrndx) case ELFCLASS64: hdr := new(Header64) sr.Seek(0, seekStart) if err := binary.Read(sr, f.ByteOrder, hdr); err != nil { return nil, err } f.Type = Type(hdr.Type) f.Machine = Machine(hdr.Machine) f.Entry = hdr.Entry if v := Version(hdr.Version); v != f.Version { return nil, &FormatError{0, "mismatched ELF version", v} } phoff = int64(hdr.Phoff) phentsize = int(hdr.Phentsize) phnum = int(hdr.Phnum) shoff = int64(hdr.Shoff) shentsize = int(hdr.Shentsize) shnum = int(hdr.Shnum) shstrndx = int(hdr.Shstrndx) } if shnum > 0 && shoff > 0 && (shstrndx < 0 || shstrndx >= shnum) { return nil, &FormatError{0, "invalid ELF shstrndx", shstrndx} } // Read program headers f.Progs = make([]*Prog, phnum) for i := 0; i < phnum; i++ { off := phoff + int64(i)*int64(phentsize) sr.Seek(off, seekStart) p := new(Prog) switch f.Class { case ELFCLASS32: ph := new(Prog32) if err := binary.Read(sr, f.ByteOrder, ph); err != nil { return nil, err } p.ProgHeader = ProgHeader{ Type: ProgType(ph.Type), Flags: ProgFlag(ph.Flags), Off: uint64(ph.Off), Vaddr: uint64(ph.Vaddr), Paddr: uint64(ph.Paddr), Filesz: uint64(ph.Filesz), Memsz: uint64(ph.Memsz), Align: uint64(ph.Align), } case ELFCLASS64: ph := new(Prog64) if err := binary.Read(sr, f.ByteOrder, ph); err != nil { return nil, err } p.ProgHeader = ProgHeader{ Type: ProgType(ph.Type), Flags: ProgFlag(ph.Flags), Off: ph.Off, Vaddr: ph.Vaddr, Paddr: ph.Paddr, Filesz: ph.Filesz, Memsz: ph.Memsz, Align: ph.Align, } } p.sr = io.NewSectionReader(r, int64(p.Off), int64(p.Filesz)) p.ReaderAt = p.sr f.Progs[i] = p } // Read section headers f.Sections = make([]*Section, shnum) names := make([]uint32, shnum) for i := 0; i < shnum; i++ { off := shoff + int64(i)*int64(shentsize) sr.Seek(off, seekStart) s := new(Section) switch f.Class { case ELFCLASS32: sh := new(Section32) if err := binary.Read(sr, f.ByteOrder, sh); err != nil { return nil, err } names[i] = sh.Name s.SectionHeader = SectionHeader{ Type: SectionType(sh.Type), Flags: SectionFlag(sh.Flags), Addr: uint64(sh.Addr), Offset: uint64(sh.Off), FileSize: uint64(sh.Size), Link: sh.Link, Info: sh.Info, Addralign: uint64(sh.Addralign), Entsize: uint64(sh.Entsize), } case ELFCLASS64: sh := new(Section64) if err := binary.Read(sr, f.ByteOrder, sh); err != nil { return nil, err } names[i] = sh.Name s.SectionHeader = SectionHeader{ Type: SectionType(sh.Type), Flags: SectionFlag(sh.Flags), Offset: sh.Off, FileSize: sh.Size, Addr: sh.Addr, Link: sh.Link, Info: sh.Info, Addralign: sh.Addralign, Entsize: sh.Entsize, } } s.sr = io.NewSectionReader(r, int64(s.Offset), int64(s.FileSize)) if s.Flags&SHF_COMPRESSED == 0 { s.ReaderAt = s.sr s.Size = s.FileSize } else { // Read the compression header. switch f.Class { case ELFCLASS32: ch := new(Chdr32) if err := binary.Read(s.sr, f.ByteOrder, ch); err != nil { return nil, err } s.compressionType = CompressionType(ch.Type) s.Size = uint64(ch.Size) s.Addralign = uint64(ch.Addralign) s.compressionOffset = int64(binary.Size(ch)) case ELFCLASS64: ch := new(Chdr64) if err := binary.Read(s.sr, f.ByteOrder, ch); err != nil { return nil, err } s.compressionType = CompressionType(ch.Type) s.Size = ch.Size s.Addralign = ch.Addralign s.compressionOffset = int64(binary.Size(ch)) } } f.Sections[i] = s } if len(f.Sections) == 0 { return f, nil } // Load section header string table. shstrtab, err := f.Sections[shstrndx].Data() if err != nil { return nil, err } for i, s := range f.Sections { var ok bool s.Name, ok = getString(shstrtab, int(names[i])) if !ok { return nil, &FormatError{shoff + int64(i*shentsize), "bad section name index", names[i]} } } return f, nil } // getSymbols returns a slice of Symbols from parsing the symbol table // with the given type, along with the associated string table. func (f *File) getSymbols(typ SectionType) ([]Symbol, []byte, error) { switch f.Class { case ELFCLASS64: return f.getSymbols64(typ) case ELFCLASS32: return f.getSymbols32(typ) } return nil, nil, errors.New("not implemented") } // ErrNoSymbols is returned by File.Symbols and File.DynamicSymbols // if there is no such section in the File. var ErrNoSymbols = errors.New("no symbol section") func (f *File) getSymbols32(typ SectionType) ([]Symbol, []byte, error) { symtabSection := f.SectionByType(typ) if symtabSection == nil { return nil, nil, ErrNoSymbols } data, err := symtabSection.Data() if err != nil { return nil, nil, errors.New("cannot load symbol section") } symtab := bytes.NewReader(data) if symtab.Len()%Sym32Size != 0 { return nil, nil, errors.New("length of symbol section is not a multiple of SymSize") } strdata, err := f.stringTable(symtabSection.Link) if err != nil { return nil, nil, errors.New("cannot load string table section") } // The first entry is all zeros. var skip [Sym32Size]byte symtab.Read(skip[:]) symbols := make([]Symbol, symtab.Len()/Sym32Size) i := 0 var sym Sym32 for symtab.Len() > 0 { binary.Read(symtab, f.ByteOrder, &sym) str, _ := getString(strdata, int(sym.Name)) symbols[i].Name = str symbols[i].Info = sym.Info symbols[i].Other = sym.Other symbols[i].Section = SectionIndex(sym.Shndx) symbols[i].Value = uint64(sym.Value) symbols[i].Size = uint64(sym.Size) i++ } return symbols, strdata, nil } func (f *File) getSymbols64(typ SectionType) ([]Symbol, []byte, error) { symtabSection := f.SectionByType(typ) if symtabSection == nil { return nil, nil, ErrNoSymbols } data, err := symtabSection.Data() if err != nil { return nil, nil, errors.New("cannot load symbol section") } symtab := bytes.NewReader(data) if symtab.Len()%Sym64Size != 0 { return nil, nil, errors.New("length of symbol section is not a multiple of Sym64Size") } strdata, err := f.stringTable(symtabSection.Link) if err != nil { return nil, nil, errors.New("cannot load string table section") } // The first entry is all zeros. var skip [Sym64Size]byte symtab.Read(skip[:]) symbols := make([]Symbol, symtab.Len()/Sym64Size) i := 0 var sym Sym64 for symtab.Len() > 0 { binary.Read(symtab, f.ByteOrder, &sym) str, _ := getString(strdata, int(sym.Name)) symbols[i].Name = str symbols[i].Info = sym.Info symbols[i].Other = sym.Other symbols[i].Section = SectionIndex(sym.Shndx) symbols[i].Value = sym.Value symbols[i].Size = sym.Size i++ } return symbols, strdata, nil } // getString extracts a string from an ELF string table. func getString(section []byte, start int) (string, bool) { if start < 0 || start >= len(section) { return "", false } for end := start; end < len(section); end++ { if section[end] == 0 { return string(section[start:end]), true } } return "", false } // Section returns a section with the given name, or nil if no such // section exists. func (f *File) Section(name string) *Section { for _, s := range f.Sections { if s.Name == name { return s } } return nil } // applyRelocations applies relocations to dst. rels is a relocations section // in REL or RELA format. func (f *File) applyRelocations(dst []byte, rels []byte) error { switch { case f.Class == ELFCLASS64 && f.Machine == EM_X86_64: return f.applyRelocationsAMD64(dst, rels) case f.Class == ELFCLASS32 && f.Machine == EM_386: return f.applyRelocations386(dst, rels) case f.Class == ELFCLASS32 && f.Machine == EM_ARM: return f.applyRelocationsARM(dst, rels) case f.Class == ELFCLASS64 && f.Machine == EM_AARCH64: return f.applyRelocationsARM64(dst, rels) case f.Class == ELFCLASS32 && f.Machine == EM_PPC: return f.applyRelocationsPPC(dst, rels) case f.Class == ELFCLASS64 && f.Machine == EM_PPC64: return f.applyRelocationsPPC64(dst, rels) case f.Class == ELFCLASS32 && f.Machine == EM_MIPS: return f.applyRelocationsMIPS(dst, rels) case f.Class == ELFCLASS64 && f.Machine == EM_MIPS: return f.applyRelocationsMIPS64(dst, rels) case f.Class == ELFCLASS64 && f.Machine == EM_RISCV: return f.applyRelocationsRISCV64(dst, rels) case f.Class == ELFCLASS64 && f.Machine == EM_S390: return f.applyRelocationss390x(dst, rels) case f.Class == ELFCLASS64 && f.Machine == EM_SPARCV9: return f.applyRelocationsSPARC64(dst, rels) default: return errors.New("applyRelocations: not implemented") } } func (f *File) applyRelocationsAMD64(dst []byte, rels []byte) error { // 24 is the size of Rela64. if len(rels)%24 != 0 { return errors.New("length of relocation section is not a multiple of 24") } symbols, _, err := f.getSymbols(SHT_SYMTAB) if err != nil { return err } b := bytes.NewReader(rels) var rela Rela64 for b.Len() > 0 { binary.Read(b, f.ByteOrder, &rela) symNo := rela.Info >> 32 t := R_X86_64(rela.Info & 0xffff) if symNo == 0 || symNo > uint64(len(symbols)) { continue } sym := &symbols[symNo-1] if SymType(sym.Info&0xf) != STT_SECTION { // We don't handle non-section relocations for now. continue } // There are relocations, so this must be a normal // object file, and we only look at section symbols, // so we assume that the symbol value is 0. switch t { case R_X86_64_64: if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 { continue } f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], uint64(rela.Addend)) case R_X86_64_32: if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 { continue } f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend)) } } return nil } func (f *File) applyRelocations386(dst []byte, rels []byte) error { // 8 is the size of Rel32. if len(rels)%8 != 0 { return errors.New("length of relocation section is not a multiple of 8") } symbols, _, err := f.getSymbols(SHT_SYMTAB) if err != nil { return err } b := bytes.NewReader(rels) var rel Rel32 for b.Len() > 0 { binary.Read(b, f.ByteOrder, &rel) symNo := rel.Info >> 8 t := R_386(rel.Info & 0xff) if symNo == 0 || symNo > uint32(len(symbols)) { continue } sym := &symbols[symNo-1] if t == R_386_32 { if rel.Off+4 >= uint32(len(dst)) { continue } val := f.ByteOrder.Uint32(dst[rel.Off : rel.Off+4]) val += uint32(sym.Value) f.ByteOrder.PutUint32(dst[rel.Off:rel.Off+4], val) } } return nil } func (f *File) applyRelocationsARM(dst []byte, rels []byte) error { // 8 is the size of Rel32. if len(rels)%8 != 0 { return errors.New("length of relocation section is not a multiple of 8") } symbols, _, err := f.getSymbols(SHT_SYMTAB) if err != nil { return err } b := bytes.NewReader(rels) var rel Rel32 for b.Len() > 0 { binary.Read(b, f.ByteOrder, &rel) symNo := rel.Info >> 8 t := R_ARM(rel.Info & 0xff) if symNo == 0 || symNo > uint32(len(symbols)) { continue } sym := &symbols[symNo-1] switch t { case R_ARM_ABS32: if rel.Off+4 >= uint32(len(dst)) { continue } val := f.ByteOrder.Uint32(dst[rel.Off : rel.Off+4]) val += uint32(sym.Value) f.ByteOrder.PutUint32(dst[rel.Off:rel.Off+4], val) } } return nil } func (f *File) applyRelocationsARM64(dst []byte, rels []byte) error { // 24 is the size of Rela64. if len(rels)%24 != 0 { return errors.New("length of relocation section is not a multiple of 24") } symbols, _, err := f.getSymbols(SHT_SYMTAB) if err != nil { return err } b := bytes.NewReader(rels) var rela Rela64 for b.Len() > 0 { binary.Read(b, f.ByteOrder, &rela) symNo := rela.Info >> 32 t := R_AARCH64(rela.Info & 0xffff) if symNo == 0 || symNo > uint64(len(symbols)) { continue } sym := &symbols[symNo-1] if SymType(sym.Info&0xf) != STT_SECTION { // We don't handle non-section relocations for now. continue } // There are relocations, so this must be a normal // object file, and we only look at section symbols, // so we assume that the symbol value is 0. switch t { case R_AARCH64_ABS64: if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 { continue } f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], uint64(rela.Addend)) case R_AARCH64_ABS32: if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 { continue } f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend)) } } return nil } func (f *File) applyRelocationsPPC(dst []byte, rels []byte) error { // 12 is the size of Rela32. if len(rels)%12 != 0 { return errors.New("length of relocation section is not a multiple of 12") } symbols, _, err := f.getSymbols(SHT_SYMTAB) if err != nil { return err } b := bytes.NewReader(rels) var rela Rela32 for b.Len() > 0 { binary.Read(b, f.ByteOrder, &rela) symNo := rela.Info >> 8 t := R_PPC(rela.Info & 0xff) if symNo == 0 || symNo > uint32(len(symbols)) { continue } sym := &symbols[symNo-1] if SymType(sym.Info&0xf) != STT_SECTION { // We don't handle non-section relocations for now. continue } switch t { case R_PPC_ADDR32: if rela.Off+4 >= uint32(len(dst)) || rela.Addend < 0 { continue } f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend)) } } return nil } func (f *File) applyRelocationsPPC64(dst []byte, rels []byte) error { // 24 is the size of Rela64. if len(rels)%24 != 0 { return errors.New("length of relocation section is not a multiple of 24") } symbols, _, err := f.getSymbols(SHT_SYMTAB) if err != nil { return err } b := bytes.NewReader(rels) var rela Rela64 for b.Len() > 0 { binary.Read(b, f.ByteOrder, &rela) symNo := rela.Info >> 32 t := R_PPC64(rela.Info & 0xffff) if symNo == 0 || symNo > uint64(len(symbols)) { continue } sym := &symbols[symNo-1] if SymType(sym.Info&0xf) != STT_SECTION { // We don't handle non-section relocations for now. continue } switch t { case R_PPC64_ADDR64: if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 { continue } f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], uint64(rela.Addend)) case R_PPC64_ADDR32: if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 { continue } f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend)) } } return nil } func (f *File) applyRelocationsMIPS(dst []byte, rels []byte) error { // 8 is the size of Rel32. if len(rels)%8 != 0 { return errors.New("length of relocation section is not a multiple of 8") } symbols, _, err := f.getSymbols(SHT_SYMTAB) if err != nil { return err } b := bytes.NewReader(rels) var rel Rel32 for b.Len() > 0 { binary.Read(b, f.ByteOrder, &rel) symNo := rel.Info >> 8 t := R_MIPS(rel.Info & 0xff) if symNo == 0 || symNo > uint32(len(symbols)) { continue } sym := &symbols[symNo-1] switch t { case R_MIPS_32: if rel.Off+4 >= uint32(len(dst)) { continue } val := f.ByteOrder.Uint32(dst[rel.Off : rel.Off+4]) val += uint32(sym.Value) f.ByteOrder.PutUint32(dst[rel.Off:rel.Off+4], val) } } return nil } func (f *File) applyRelocationsMIPS64(dst []byte, rels []byte) error { // 24 is the size of Rela64. if len(rels)%24 != 0 { return errors.New("length of relocation section is not a multiple of 24") } symbols, _, err := f.getSymbols(SHT_SYMTAB) if err != nil { return err } b := bytes.NewReader(rels) var rela Rela64 for b.Len() > 0 { binary.Read(b, f.ByteOrder, &rela) var symNo uint64 var t R_MIPS if f.ByteOrder == binary.BigEndian { symNo = rela.Info >> 32 t = R_MIPS(rela.Info & 0xff) } else { symNo = rela.Info & 0xffffffff t = R_MIPS(rela.Info >> 56) } if symNo == 0 || symNo > uint64(len(symbols)) { continue } sym := &symbols[symNo-1] if SymType(sym.Info&0xf) != STT_SECTION { // We don't handle non-section relocations for now. continue } switch t { case R_MIPS_64: if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 { continue } f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], uint64(rela.Addend)) case R_MIPS_32: if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 { continue } f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend)) } } return nil } func (f *File) applyRelocationsRISCV64(dst []byte, rels []byte) error { // 24 is the size of Rela64. if len(rels)%24 != 0 { return errors.New("length of relocation section is not a multiple of 24") } symbols, _, err := f.getSymbols(SHT_SYMTAB) if err != nil { return err } b := bytes.NewReader(rels) var rela Rela64 for b.Len() > 0 { binary.Read(b, f.ByteOrder, &rela) symNo := rela.Info >> 32 t := R_RISCV(rela.Info & 0xffff) if symNo == 0 || symNo > uint64(len(symbols)) { continue } sym := &symbols[symNo-1] switch SymType(sym.Info & 0xf) { case STT_SECTION, STT_NOTYPE: break default: continue } switch t { case R_RISCV_64: if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 { continue } val := sym.Value + uint64(rela.Addend) f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val) case R_RISCV_32: if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 { continue } val := uint32(sym.Value) + uint32(rela.Addend) f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val) } } return nil } func (f *File) applyRelocationss390x(dst []byte, rels []byte) error { // 24 is the size of Rela64. if len(rels)%24 != 0 { return errors.New("length of relocation section is not a multiple of 24") } symbols, _, err := f.getSymbols(SHT_SYMTAB) if err != nil { return err } b := bytes.NewReader(rels) var rela Rela64 for b.Len() > 0 { binary.Read(b, f.ByteOrder, &rela) symNo := rela.Info >> 32 t := R_390(rela.Info & 0xffff) if symNo == 0 || symNo > uint64(len(symbols)) { continue } sym := &symbols[symNo-1] switch SymType(sym.Info & 0xf) { case STT_SECTION, STT_NOTYPE: break default: continue } switch t { case R_390_64: if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 { continue } val := sym.Value + uint64(rela.Addend) f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val) case R_390_32: if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 { continue } val := uint32(sym.Value) + uint32(rela.Addend) f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val) } } return nil } func (f *File) applyRelocationsSPARC64(dst []byte, rels []byte) error { // 24 is the size of Rela64. if len(rels)%24 != 0 { return errors.New("length of relocation section is not a multiple of 24") } symbols, _, err := f.getSymbols(SHT_SYMTAB) if err != nil { return err } b := bytes.NewReader(rels) var rela Rela64 for b.Len() > 0 { binary.Read(b, f.ByteOrder, &rela) symNo := rela.Info >> 32 t := R_SPARC(rela.Info & 0xff) if symNo == 0 || symNo > uint64(len(symbols)) { continue } sym := &symbols[symNo-1] if SymType(sym.Info&0xf) != STT_SECTION { // We don't handle non-section relocations for now. continue } switch t { case R_SPARC_64, R_SPARC_UA64: if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 { continue } f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], uint64(rela.Addend)) case R_SPARC_32, R_SPARC_UA32: if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 { continue } f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend)) } } return nil } func (f *File) DWARF() (*dwarf.Data, error) { dwarfSuffix := func(s *Section) string { switch { case strings.HasPrefix(s.Name, ".debug_"): return s.Name[7:] case strings.HasPrefix(s.Name, ".zdebug_"): return s.Name[8:] default: return "" } } // sectionData gets the data for s, checks its size, and // applies any applicable relations. sectionData := func(i int, s *Section) ([]byte, error) { b, err := s.Data() if err != nil && uint64(len(b)) < s.Size { return nil, err } if len(b) >= 12 && string(b[:4]) == "ZLIB" { dlen := binary.BigEndian.Uint64(b[4:12]) dbuf := make([]byte, dlen) r, err := zlib.NewReader(bytes.NewBuffer(b[12:])) if err != nil { return nil, err } if _, err := io.ReadFull(r, dbuf); err != nil { return nil, err } if err := r.Close(); err != nil { return nil, err } b = dbuf } for _, r := range f.Sections { if r.Type != SHT_RELA && r.Type != SHT_REL { continue } if int(r.Info) != i { continue } rd, err := r.Data() if err != nil { return nil, err } err = f.applyRelocations(b, rd) if err != nil { return nil, err } } return b, nil } // There are many other DWARF sections, but these // are the ones the debug/dwarf package uses. // Don't bother loading others. var dat = map[string][]byte{"abbrev": nil, "info": nil, "str": nil, "line": nil, "ranges": nil} for i, s := range f.Sections { suffix := dwarfSuffix(s) if suffix == "" { continue } if _, ok := dat[suffix]; !ok { continue } b, err := sectionData(i, s) if err != nil { return nil, err } dat[suffix] = b } d, err := dwarf.New(dat["abbrev"], nil, nil, dat["info"], dat["line"], nil, dat["ranges"], dat["str"]) if err != nil { return nil, err } // Look for DWARF4 .debug_types sections. for i, s := range f.Sections { suffix := dwarfSuffix(s) if suffix != "types" { continue } b, err := sectionData(i, s) if err != nil { return nil, err } err = d.AddTypes(fmt.Sprintf("types-%d", i), b) if err != nil { return nil, err } } return d, nil } // Symbols returns the symbol table for f. The symbols will be listed in the order // they appear in f. // // For compatibility with Go 1.0, Symbols omits the null symbol at index 0. // After retrieving the symbols as symtab, an externally supplied index x // corresponds to symtab[x-1], not symtab[x]. func (f *File) Symbols() ([]Symbol, error) { sym, _, err := f.getSymbols(SHT_SYMTAB) return sym, err } // DynamicSymbols returns the dynamic symbol table for f. The symbols // will be listed in the order they appear in f. // // For compatibility with Symbols, DynamicSymbols omits the null symbol at index 0. // After retrieving the symbols as symtab, an externally supplied index x // corresponds to symtab[x-1], not symtab[x]. func (f *File) DynamicSymbols() ([]Symbol, error) { sym, _, err := f.getSymbols(SHT_DYNSYM) return sym, err } type ImportedSymbol struct { Name string Version string Library string } // ImportedSymbols returns the names of all symbols // referred to by the binary f that are expected to be // satisfied by other libraries at dynamic load time. // It does not return weak symbols. func (f *File) ImportedSymbols() ([]ImportedSymbol, error) { sym, str, err := f.getSymbols(SHT_DYNSYM) if err != nil { return nil, err } f.gnuVersionInit(str) var all []ImportedSymbol for i, s := range sym { if ST_BIND(s.Info) == STB_GLOBAL && s.Section == SHN_UNDEF { all = append(all, ImportedSymbol{Name: s.Name}) f.gnuVersion(i, &all[len(all)-1]) } } return all, nil } type verneed struct { File string Name string } // gnuVersionInit parses the GNU version tables // for use by calls to gnuVersion. func (f *File) gnuVersionInit(str []byte) { // Accumulate verneed information. vn := f.SectionByType(SHT_GNU_VERNEED) if vn == nil { return } d, _ := vn.Data() var need []verneed i := 0 for { if i+16 > len(d) { break } vers := f.ByteOrder.Uint16(d[i : i+2]) if vers != 1 { break } cnt := f.ByteOrder.Uint16(d[i+2 : i+4]) fileoff := f.ByteOrder.Uint32(d[i+4 : i+8]) aux := f.ByteOrder.Uint32(d[i+8 : i+12]) next := f.ByteOrder.Uint32(d[i+12 : i+16]) file, _ := getString(str, int(fileoff)) var name string j := i + int(aux) for c := 0; c < int(cnt); c++ { if j+16 > len(d) { break } // hash := f.ByteOrder.Uint32(d[j:j+4]) // flags := f.ByteOrder.Uint16(d[j+4:j+6]) other := f.ByteOrder.Uint16(d[j+6 : j+8]) nameoff := f.ByteOrder.Uint32(d[j+8 : j+12]) next := f.ByteOrder.Uint32(d[j+12 : j+16]) name, _ = getString(str, int(nameoff)) ndx := int(other) if ndx >= len(need) { a := make([]verneed, 2*(ndx+1)) copy(a, need) need = a } need[ndx] = verneed{file, name} if next == 0 { break } j += int(next) } if next == 0 { break } i += int(next) } // Versym parallels symbol table, indexing into verneed. vs := f.SectionByType(SHT_GNU_VERSYM) if vs == nil { return } d, _ = vs.Data() f.gnuNeed = need f.gnuVersym = d } // gnuVersion adds Library and Version information to sym, // which came from offset i of the symbol table. func (f *File) gnuVersion(i int, sym *ImportedSymbol) { // Each entry is two bytes. i = (i + 1) * 2 if i >= len(f.gnuVersym) { return } j := int(f.ByteOrder.Uint16(f.gnuVersym[i:])) if j < 2 || j >= len(f.gnuNeed) { return } n := &f.gnuNeed[j] sym.Library = n.File sym.Version = n.Name } // ImportedLibraries returns the names of all libraries // referred to by the binary f that are expected to be // linked with the binary at dynamic link time. func (f *File) ImportedLibraries() ([]string, error) { return f.DynString(DT_NEEDED) } // DynString returns the strings listed for the given tag in the file's dynamic // section. // // The tag must be one that takes string values: DT_NEEDED, DT_SONAME, DT_RPATH, or // DT_RUNPATH. func (f *File) DynString(tag DynTag) ([]string, error) { switch tag { case DT_NEEDED, DT_SONAME, DT_RPATH, DT_RUNPATH: default: return nil, fmt.Errorf("non-string-valued tag %v", tag) } ds := f.SectionByType(SHT_DYNAMIC) if ds == nil { // not dynamic, so no libraries return nil, nil } d, err := ds.Data() if err != nil { return nil, err } str, err := f.stringTable(ds.Link) if err != nil { return nil, err } var all []string for len(d) > 0 { var t DynTag var v uint64 switch f.Class { case ELFCLASS32: t = DynTag(f.ByteOrder.Uint32(d[0:4])) v = uint64(f.ByteOrder.Uint32(d[4:8])) d = d[8:] case ELFCLASS64: t = DynTag(f.ByteOrder.Uint64(d[0:8])) v = f.ByteOrder.Uint64(d[8:16]) d = d[16:] } if t == tag { s, ok := getString(str, int(v)) if ok { all = append(all, s) } } } return all, nil } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/elf/file_test.go000066400000000000000000000774171356504100700272210ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // +build go1.7 package elf import ( "bytes" "compress/gzip" "encoding/binary" "io" "math/rand" "net" "os" "path" "reflect" "runtime" "testing" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/dwarf" ) type fileTest struct { file string hdr FileHeader sections []SectionHeader progs []ProgHeader needed []string } var fileTests = []fileTest{ { "testdata/gcc-386-freebsd-exec", FileHeader{ELFCLASS32, ELFDATA2LSB, EV_CURRENT, ELFOSABI_FREEBSD, 0, binary.LittleEndian, ET_EXEC, EM_386, 0x80483cc}, []SectionHeader{ {"", SHT_NULL, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, {".interp", SHT_PROGBITS, SHF_ALLOC, 0x80480d4, 0xd4, 0x15, 0x0, 0x0, 0x1, 0x0, 0x15}, {".hash", SHT_HASH, SHF_ALLOC, 0x80480ec, 0xec, 0x90, 0x3, 0x0, 0x4, 0x4, 0x90}, {".dynsym", SHT_DYNSYM, SHF_ALLOC, 0x804817c, 0x17c, 0x110, 0x4, 0x1, 0x4, 0x10, 0x110}, {".dynstr", SHT_STRTAB, SHF_ALLOC, 0x804828c, 0x28c, 0xbb, 0x0, 0x0, 0x1, 0x0, 0xbb}, {".rel.plt", SHT_REL, SHF_ALLOC, 0x8048348, 0x348, 0x20, 0x3, 0x7, 0x4, 0x8, 0x20}, {".init", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x8048368, 0x368, 0x11, 0x0, 0x0, 0x4, 0x0, 0x11}, {".plt", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x804837c, 0x37c, 0x50, 0x0, 0x0, 0x4, 0x4, 0x50}, {".text", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x80483cc, 0x3cc, 0x180, 0x0, 0x0, 0x4, 0x0, 0x180}, {".fini", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x804854c, 0x54c, 0xc, 0x0, 0x0, 0x4, 0x0, 0xc}, {".rodata", SHT_PROGBITS, SHF_ALLOC, 0x8048558, 0x558, 0xa3, 0x0, 0x0, 0x1, 0x0, 0xa3}, {".data", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80495fc, 0x5fc, 0xc, 0x0, 0x0, 0x4, 0x0, 0xc}, {".eh_frame", SHT_PROGBITS, SHF_ALLOC, 0x8049608, 0x608, 0x4, 0x0, 0x0, 0x4, 0x0, 0x4}, {".dynamic", SHT_DYNAMIC, SHF_WRITE + SHF_ALLOC, 0x804960c, 0x60c, 0x98, 0x4, 0x0, 0x4, 0x8, 0x98}, {".ctors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496a4, 0x6a4, 0x8, 0x0, 0x0, 0x4, 0x0, 0x8}, {".dtors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496ac, 0x6ac, 0x8, 0x0, 0x0, 0x4, 0x0, 0x8}, {".jcr", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496b4, 0x6b4, 0x4, 0x0, 0x0, 0x4, 0x0, 0x4}, {".got", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496b8, 0x6b8, 0x1c, 0x0, 0x0, 0x4, 0x4, 0x1c}, {".bss", SHT_NOBITS, SHF_WRITE + SHF_ALLOC, 0x80496d4, 0x6d4, 0x20, 0x0, 0x0, 0x4, 0x0, 0x20}, {".comment", SHT_PROGBITS, 0x0, 0x0, 0x6d4, 0x12d, 0x0, 0x0, 0x1, 0x0, 0x12d}, {".debug_aranges", SHT_PROGBITS, 0x0, 0x0, 0x801, 0x20, 0x0, 0x0, 0x1, 0x0, 0x20}, {".debug_pubnames", SHT_PROGBITS, 0x0, 0x0, 0x821, 0x1b, 0x0, 0x0, 0x1, 0x0, 0x1b}, {".debug_info", SHT_PROGBITS, 0x0, 0x0, 0x83c, 0x11d, 0x0, 0x0, 0x1, 0x0, 0x11d}, {".debug_abbrev", SHT_PROGBITS, 0x0, 0x0, 0x959, 0x41, 0x0, 0x0, 0x1, 0x0, 0x41}, {".debug_line", SHT_PROGBITS, 0x0, 0x0, 0x99a, 0x35, 0x0, 0x0, 0x1, 0x0, 0x35}, {".debug_frame", SHT_PROGBITS, 0x0, 0x0, 0x9d0, 0x30, 0x0, 0x0, 0x4, 0x0, 0x30}, {".debug_str", SHT_PROGBITS, 0x0, 0x0, 0xa00, 0xd, 0x0, 0x0, 0x1, 0x0, 0xd}, {".shstrtab", SHT_STRTAB, 0x0, 0x0, 0xa0d, 0xf8, 0x0, 0x0, 0x1, 0x0, 0xf8}, {".symtab", SHT_SYMTAB, 0x0, 0x0, 0xfb8, 0x4b0, 0x1d, 0x38, 0x4, 0x10, 0x4b0}, {".strtab", SHT_STRTAB, 0x0, 0x0, 0x1468, 0x206, 0x0, 0x0, 0x1, 0x0, 0x206}, }, []ProgHeader{ {PT_PHDR, PF_R + PF_X, 0x34, 0x8048034, 0x8048034, 0xa0, 0xa0, 0x4}, {PT_INTERP, PF_R, 0xd4, 0x80480d4, 0x80480d4, 0x15, 0x15, 0x1}, {PT_LOAD, PF_R + PF_X, 0x0, 0x8048000, 0x8048000, 0x5fb, 0x5fb, 0x1000}, {PT_LOAD, PF_R + PF_W, 0x5fc, 0x80495fc, 0x80495fc, 0xd8, 0xf8, 0x1000}, {PT_DYNAMIC, PF_R + PF_W, 0x60c, 0x804960c, 0x804960c, 0x98, 0x98, 0x4}, }, []string{"libc.so.6"}, }, { "testdata/gcc-amd64-linux-exec", FileHeader{ELFCLASS64, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE, 0, binary.LittleEndian, ET_EXEC, EM_X86_64, 0x4003e0}, []SectionHeader{ {"", SHT_NULL, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, {".interp", SHT_PROGBITS, SHF_ALLOC, 0x400200, 0x200, 0x1c, 0x0, 0x0, 0x1, 0x0, 0x1c}, {".note.ABI-tag", SHT_NOTE, SHF_ALLOC, 0x40021c, 0x21c, 0x20, 0x0, 0x0, 0x4, 0x0, 0x20}, {".hash", SHT_HASH, SHF_ALLOC, 0x400240, 0x240, 0x24, 0x5, 0x0, 0x8, 0x4, 0x24}, {".gnu.hash", SHT_LOOS + 268435446, SHF_ALLOC, 0x400268, 0x268, 0x1c, 0x5, 0x0, 0x8, 0x0, 0x1c}, {".dynsym", SHT_DYNSYM, SHF_ALLOC, 0x400288, 0x288, 0x60, 0x6, 0x1, 0x8, 0x18, 0x60}, {".dynstr", SHT_STRTAB, SHF_ALLOC, 0x4002e8, 0x2e8, 0x3d, 0x0, 0x0, 0x1, 0x0, 0x3d}, {".gnu.version", SHT_HIOS, SHF_ALLOC, 0x400326, 0x326, 0x8, 0x5, 0x0, 0x2, 0x2, 0x8}, {".gnu.version_r", SHT_LOOS + 268435454, SHF_ALLOC, 0x400330, 0x330, 0x20, 0x6, 0x1, 0x8, 0x0, 0x20}, {".rela.dyn", SHT_RELA, SHF_ALLOC, 0x400350, 0x350, 0x18, 0x5, 0x0, 0x8, 0x18, 0x18}, {".rela.plt", SHT_RELA, SHF_ALLOC, 0x400368, 0x368, 0x30, 0x5, 0xc, 0x8, 0x18, 0x30}, {".init", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x400398, 0x398, 0x18, 0x0, 0x0, 0x4, 0x0, 0x18}, {".plt", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x4003b0, 0x3b0, 0x30, 0x0, 0x0, 0x4, 0x10, 0x30}, {".text", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x4003e0, 0x3e0, 0x1b4, 0x0, 0x0, 0x10, 0x0, 0x1b4}, {".fini", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x400594, 0x594, 0xe, 0x0, 0x0, 0x4, 0x0, 0xe}, {".rodata", SHT_PROGBITS, SHF_ALLOC, 0x4005a4, 0x5a4, 0x11, 0x0, 0x0, 0x4, 0x0, 0x11}, {".eh_frame_hdr", SHT_PROGBITS, SHF_ALLOC, 0x4005b8, 0x5b8, 0x24, 0x0, 0x0, 0x4, 0x0, 0x24}, {".eh_frame", SHT_PROGBITS, SHF_ALLOC, 0x4005e0, 0x5e0, 0xa4, 0x0, 0x0, 0x8, 0x0, 0xa4}, {".ctors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600688, 0x688, 0x10, 0x0, 0x0, 0x8, 0x0, 0x10}, {".dtors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600698, 0x698, 0x10, 0x0, 0x0, 0x8, 0x0, 0x10}, {".jcr", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x6006a8, 0x6a8, 0x8, 0x0, 0x0, 0x8, 0x0, 0x8}, {".dynamic", SHT_DYNAMIC, SHF_WRITE + SHF_ALLOC, 0x6006b0, 0x6b0, 0x1a0, 0x6, 0x0, 0x8, 0x10, 0x1a0}, {".got", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600850, 0x850, 0x8, 0x0, 0x0, 0x8, 0x8, 0x8}, {".got.plt", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600858, 0x858, 0x28, 0x0, 0x0, 0x8, 0x8, 0x28}, {".data", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600880, 0x880, 0x18, 0x0, 0x0, 0x8, 0x0, 0x18}, {".bss", SHT_NOBITS, SHF_WRITE + SHF_ALLOC, 0x600898, 0x898, 0x8, 0x0, 0x0, 0x4, 0x0, 0x8}, {".comment", SHT_PROGBITS, 0x0, 0x0, 0x898, 0x126, 0x0, 0x0, 0x1, 0x0, 0x126}, {".debug_aranges", SHT_PROGBITS, 0x0, 0x0, 0x9c0, 0x90, 0x0, 0x0, 0x10, 0x0, 0x90}, {".debug_pubnames", SHT_PROGBITS, 0x0, 0x0, 0xa50, 0x25, 0x0, 0x0, 0x1, 0x0, 0x25}, {".debug_info", SHT_PROGBITS, 0x0, 0x0, 0xa75, 0x1a7, 0x0, 0x0, 0x1, 0x0, 0x1a7}, {".debug_abbrev", SHT_PROGBITS, 0x0, 0x0, 0xc1c, 0x6f, 0x0, 0x0, 0x1, 0x0, 0x6f}, {".debug_line", SHT_PROGBITS, 0x0, 0x0, 0xc8b, 0x13f, 0x0, 0x0, 0x1, 0x0, 0x13f}, {".debug_str", SHT_PROGBITS, SHF_MERGE + SHF_STRINGS, 0x0, 0xdca, 0xb1, 0x0, 0x0, 0x1, 0x1, 0xb1}, {".debug_ranges", SHT_PROGBITS, 0x0, 0x0, 0xe80, 0x90, 0x0, 0x0, 0x10, 0x0, 0x90}, {".shstrtab", SHT_STRTAB, 0x0, 0x0, 0xf10, 0x149, 0x0, 0x0, 0x1, 0x0, 0x149}, {".symtab", SHT_SYMTAB, 0x0, 0x0, 0x19a0, 0x6f0, 0x24, 0x39, 0x8, 0x18, 0x6f0}, {".strtab", SHT_STRTAB, 0x0, 0x0, 0x2090, 0x1fc, 0x0, 0x0, 0x1, 0x0, 0x1fc}, }, []ProgHeader{ {PT_PHDR, PF_R + PF_X, 0x40, 0x400040, 0x400040, 0x1c0, 0x1c0, 0x8}, {PT_INTERP, PF_R, 0x200, 0x400200, 0x400200, 0x1c, 0x1c, 1}, {PT_LOAD, PF_R + PF_X, 0x0, 0x400000, 0x400000, 0x684, 0x684, 0x200000}, {PT_LOAD, PF_R + PF_W, 0x688, 0x600688, 0x600688, 0x210, 0x218, 0x200000}, {PT_DYNAMIC, PF_R + PF_W, 0x6b0, 0x6006b0, 0x6006b0, 0x1a0, 0x1a0, 0x8}, {PT_NOTE, PF_R, 0x21c, 0x40021c, 0x40021c, 0x20, 0x20, 0x4}, {PT_LOOS + 0x474E550, PF_R, 0x5b8, 0x4005b8, 0x4005b8, 0x24, 0x24, 0x4}, {PT_LOOS + 0x474E551, PF_R + PF_W, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8}, }, []string{"libc.so.6"}, }, { "testdata/hello-world-core.gz", FileHeader{ELFCLASS64, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE, 0x0, binary.LittleEndian, ET_CORE, EM_X86_64, 0x0}, []SectionHeader{}, []ProgHeader{ {Type: PT_NOTE, Flags: 0x0, Off: 0x3f8, Vaddr: 0x0, Paddr: 0x0, Filesz: 0x8ac, Memsz: 0x0, Align: 0x0}, {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x1000, Vaddr: 0x400000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x1000, Align: 0x1000}, {Type: PT_LOAD, Flags: PF_R, Off: 0x1000, Vaddr: 0x401000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000}, {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x2000, Vaddr: 0x402000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000}, {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x3000, Vaddr: 0x7f54078b8000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x1b5000, Align: 0x1000}, {Type: PT_LOAD, Flags: 0x0, Off: 0x3000, Vaddr: 0x7f5407a6d000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x1ff000, Align: 0x1000}, {Type: PT_LOAD, Flags: PF_R, Off: 0x3000, Vaddr: 0x7f5407c6c000, Paddr: 0x0, Filesz: 0x4000, Memsz: 0x4000, Align: 0x1000}, {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x7000, Vaddr: 0x7f5407c70000, Paddr: 0x0, Filesz: 0x2000, Memsz: 0x2000, Align: 0x1000}, {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x9000, Vaddr: 0x7f5407c72000, Paddr: 0x0, Filesz: 0x5000, Memsz: 0x5000, Align: 0x1000}, {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0xe000, Vaddr: 0x7f5407c77000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x22000, Align: 0x1000}, {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0xe000, Vaddr: 0x7f5407e81000, Paddr: 0x0, Filesz: 0x3000, Memsz: 0x3000, Align: 0x1000}, {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x11000, Vaddr: 0x7f5407e96000, Paddr: 0x0, Filesz: 0x3000, Memsz: 0x3000, Align: 0x1000}, {Type: PT_LOAD, Flags: PF_R, Off: 0x14000, Vaddr: 0x7f5407e99000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000}, {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x15000, Vaddr: 0x7f5407e9a000, Paddr: 0x0, Filesz: 0x2000, Memsz: 0x2000, Align: 0x1000}, {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x17000, Vaddr: 0x7fff79972000, Paddr: 0x0, Filesz: 0x23000, Memsz: 0x23000, Align: 0x1000}, {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x3a000, Vaddr: 0x7fff799f8000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000}, {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x3b000, Vaddr: 0xffffffffff600000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000}, }, nil, }, { "testdata/compressed-32.obj", FileHeader{ELFCLASS32, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE, 0x0, binary.LittleEndian, ET_REL, EM_386, 0x0}, []SectionHeader{ {"", SHT_NULL, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, {".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR, 0x0, 0x34, 0x17, 0x0, 0x0, 0x1, 0x0, 0x17}, {".rel.text", SHT_REL, SHF_INFO_LINK, 0x0, 0x3dc, 0x10, 0x13, 0x1, 0x4, 0x8, 0x10}, {".data", SHT_PROGBITS, SHF_WRITE | SHF_ALLOC, 0x0, 0x4b, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0}, {".bss", SHT_NOBITS, SHF_WRITE | SHF_ALLOC, 0x0, 0x4b, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0}, {".rodata", SHT_PROGBITS, SHF_ALLOC, 0x0, 0x4b, 0xd, 0x0, 0x0, 0x1, 0x0, 0xd}, {".debug_info", SHT_PROGBITS, SHF_COMPRESSED, 0x0, 0x58, 0xb4, 0x0, 0x0, 0x1, 0x0, 0x84}, {".rel.debug_info", SHT_REL, SHF_INFO_LINK, 0x0, 0x3ec, 0xa0, 0x13, 0x6, 0x4, 0x8, 0xa0}, {".debug_abbrev", SHT_PROGBITS, 0x0, 0x0, 0xdc, 0x5a, 0x0, 0x0, 0x1, 0x0, 0x5a}, {".debug_aranges", SHT_PROGBITS, 0x0, 0x0, 0x136, 0x20, 0x0, 0x0, 0x1, 0x0, 0x20}, {".rel.debug_aranges", SHT_REL, SHF_INFO_LINK, 0x0, 0x48c, 0x10, 0x13, 0x9, 0x4, 0x8, 0x10}, {".debug_line", SHT_PROGBITS, 0x0, 0x0, 0x156, 0x5c, 0x0, 0x0, 0x1, 0x0, 0x5c}, {".rel.debug_line", SHT_REL, SHF_INFO_LINK, 0x0, 0x49c, 0x8, 0x13, 0xb, 0x4, 0x8, 0x8}, {".debug_str", SHT_PROGBITS, SHF_MERGE | SHF_STRINGS | SHF_COMPRESSED, 0x0, 0x1b2, 0x10f, 0x0, 0x0, 0x1, 0x1, 0xb3}, {".comment", SHT_PROGBITS, SHF_MERGE | SHF_STRINGS, 0x0, 0x265, 0x2a, 0x0, 0x0, 0x1, 0x1, 0x2a}, {".note.GNU-stack", SHT_PROGBITS, 0x0, 0x0, 0x28f, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0}, {".eh_frame", SHT_PROGBITS, SHF_ALLOC, 0x0, 0x290, 0x38, 0x0, 0x0, 0x4, 0x0, 0x38}, {".rel.eh_frame", SHT_REL, SHF_INFO_LINK, 0x0, 0x4a4, 0x8, 0x13, 0x10, 0x4, 0x8, 0x8}, {".shstrtab", SHT_STRTAB, 0x0, 0x0, 0x4ac, 0xab, 0x0, 0x0, 0x1, 0x0, 0xab}, {".symtab", SHT_SYMTAB, 0x0, 0x0, 0x2c8, 0x100, 0x14, 0xe, 0x4, 0x10, 0x100}, {".strtab", SHT_STRTAB, 0x0, 0x0, 0x3c8, 0x13, 0x0, 0x0, 0x1, 0x0, 0x13}, }, []ProgHeader{}, nil, }, { "testdata/compressed-64.obj", FileHeader{ELFCLASS64, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE, 0x0, binary.LittleEndian, ET_REL, EM_X86_64, 0x0}, []SectionHeader{ {"", SHT_NULL, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, {".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR, 0x0, 0x40, 0x1b, 0x0, 0x0, 0x1, 0x0, 0x1b}, {".rela.text", SHT_RELA, SHF_INFO_LINK, 0x0, 0x488, 0x30, 0x13, 0x1, 0x8, 0x18, 0x30}, {".data", SHT_PROGBITS, SHF_WRITE | SHF_ALLOC, 0x0, 0x5b, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0}, {".bss", SHT_NOBITS, SHF_WRITE | SHF_ALLOC, 0x0, 0x5b, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0}, {".rodata", SHT_PROGBITS, SHF_ALLOC, 0x0, 0x5b, 0xd, 0x0, 0x0, 0x1, 0x0, 0xd}, {".debug_info", SHT_PROGBITS, SHF_COMPRESSED, 0x0, 0x68, 0xba, 0x0, 0x0, 0x1, 0x0, 0x72}, {".rela.debug_info", SHT_RELA, SHF_INFO_LINK, 0x0, 0x4b8, 0x1c8, 0x13, 0x6, 0x8, 0x18, 0x1c8}, {".debug_abbrev", SHT_PROGBITS, 0x0, 0x0, 0xda, 0x5c, 0x0, 0x0, 0x1, 0x0, 0x5c}, {".debug_aranges", SHT_PROGBITS, SHF_COMPRESSED, 0x0, 0x136, 0x30, 0x0, 0x0, 0x1, 0x0, 0x2f}, {".rela.debug_aranges", SHT_RELA, SHF_INFO_LINK, 0x0, 0x680, 0x30, 0x13, 0x9, 0x8, 0x18, 0x30}, {".debug_line", SHT_PROGBITS, 0x0, 0x0, 0x165, 0x60, 0x0, 0x0, 0x1, 0x0, 0x60}, {".rela.debug_line", SHT_RELA, SHF_INFO_LINK, 0x0, 0x6b0, 0x18, 0x13, 0xb, 0x8, 0x18, 0x18}, {".debug_str", SHT_PROGBITS, SHF_MERGE | SHF_STRINGS | SHF_COMPRESSED, 0x0, 0x1c5, 0x104, 0x0, 0x0, 0x1, 0x1, 0xc3}, {".comment", SHT_PROGBITS, SHF_MERGE | SHF_STRINGS, 0x0, 0x288, 0x2a, 0x0, 0x0, 0x1, 0x1, 0x2a}, {".note.GNU-stack", SHT_PROGBITS, 0x0, 0x0, 0x2b2, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0}, {".eh_frame", SHT_PROGBITS, SHF_ALLOC, 0x0, 0x2b8, 0x38, 0x0, 0x0, 0x8, 0x0, 0x38}, {".rela.eh_frame", SHT_RELA, SHF_INFO_LINK, 0x0, 0x6c8, 0x18, 0x13, 0x10, 0x8, 0x18, 0x18}, {".shstrtab", SHT_STRTAB, 0x0, 0x0, 0x6e0, 0xb0, 0x0, 0x0, 0x1, 0x0, 0xb0}, {".symtab", SHT_SYMTAB, 0x0, 0x0, 0x2f0, 0x180, 0x14, 0xe, 0x8, 0x18, 0x180}, {".strtab", SHT_STRTAB, 0x0, 0x0, 0x470, 0x13, 0x0, 0x0, 0x1, 0x0, 0x13}, }, []ProgHeader{}, nil, }, } func TestOpen(t *testing.T) { for i := range fileTests { tt := &fileTests[i] var f *File var err error if path.Ext(tt.file) == ".gz" { var r io.ReaderAt if r, err = decompress(tt.file); err == nil { f, err = NewFile(r) } } else { f, err = Open(tt.file) } if err != nil { t.Errorf("cannot open file %s: %v", tt.file, err) continue } defer f.Close() if !reflect.DeepEqual(f.FileHeader, tt.hdr) { t.Errorf("open %s:\n\thave %#v\n\twant %#v\n", tt.file, f.FileHeader, tt.hdr) continue } for i, s := range f.Sections { if i >= len(tt.sections) { break } sh := &tt.sections[i] if !reflect.DeepEqual(&s.SectionHeader, sh) { t.Errorf("open %s, section %d:\n\thave %#v\n\twant %#v\n", tt.file, i, &s.SectionHeader, sh) } } for i, p := range f.Progs { if i >= len(tt.progs) { break } ph := &tt.progs[i] if !reflect.DeepEqual(&p.ProgHeader, ph) { t.Errorf("open %s, program %d:\n\thave %#v\n\twant %#v\n", tt.file, i, &p.ProgHeader, ph) } } tn := len(tt.sections) fn := len(f.Sections) if tn != fn { t.Errorf("open %s: len(Sections) = %d, want %d", tt.file, fn, tn) } tn = len(tt.progs) fn = len(f.Progs) if tn != fn { t.Errorf("open %s: len(Progs) = %d, want %d", tt.file, fn, tn) } tl := tt.needed fl, err := f.ImportedLibraries() if err != nil { t.Error(err) } if !reflect.DeepEqual(tl, fl) { t.Errorf("open %s: DT_NEEDED = %v, want %v", tt.file, tl, fl) } } } // elf.NewFile requires io.ReaderAt, which compress/gzip cannot // provide. Decompress the file to a bytes.Reader. func decompress(gz string) (io.ReaderAt, error) { in, err := os.Open(gz) if err != nil { return nil, err } defer in.Close() r, err := gzip.NewReader(in) if err != nil { return nil, err } var out bytes.Buffer _, err = io.Copy(&out, r) return bytes.NewReader(out.Bytes()), err } type relocationTestEntry struct { entryNumber int entry *dwarf.Entry } type relocationTest struct { file string entries []relocationTestEntry } var relocationTests = []relocationTest{ { "testdata/go-relocation-test-gcc441-x86-64.obj", []relocationTestEntry{ {0, &dwarf.Entry{ Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{ {Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "go-relocation-test.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: uint64(0x6)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}, }, }}, }, }, { "testdata/go-relocation-test-gcc441-x86.obj", []relocationTestEntry{ {0, &dwarf.Entry{ Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{ {Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "t.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: uint64(0x5)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}, }, }}, }, }, { "testdata/go-relocation-test-gcc424-x86-64.obj", []relocationTestEntry{ {0, &dwarf.Entry{ Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{ {Attr: dwarf.AttrProducer, Val: "GNU C 4.2.4 (Ubuntu 4.2.4-1ubuntu4)"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc424.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: uint64(0x6)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}, }, }}, }, }, { "testdata/go-relocation-test-gcc482-aarch64.obj", []relocationTestEntry{ {0, &dwarf.Entry{ Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{ {Attr: dwarf.AttrProducer, Val: "GNU C 4.8.2 -g -fstack-protector"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc482.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: int64(0x24)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}, }, }}, }, }, { "testdata/go-relocation-test-gcc492-arm.obj", []relocationTestEntry{ {0, &dwarf.Entry{ Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{ {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.2 20141224 (prerelease) -march=armv7-a -mfloat-abi=hard -mfpu=vfpv3-d16 -mtls-dialect=gnu -g"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc492.c"}, {Attr: dwarf.AttrCompDir, Val: "/root/go/src/debug/elf/testdata"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: int64(0x28)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}, }, }}, }, }, { "testdata/go-relocation-test-clang-arm.obj", []relocationTestEntry{ {0, &dwarf.Entry{ Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{ {Attr: dwarf.AttrProducer, Val: "Debian clang version 3.5.0-10 (tags/RELEASE_350/final) (based on LLVM 3.5.0)"}, {Attr: dwarf.AttrLanguage, Val: int64(12)}, {Attr: dwarf.AttrName, Val: "hello.c"}, {Attr: dwarf.AttrStmtList, Val: int64(0x0)}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: int64(48)}, }, }}, }, }, { "testdata/go-relocation-test-gcc5-ppc.obj", []relocationTestEntry{ {0, &dwarf.Entry{ Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{ {Attr: dwarf.AttrProducer, Val: "GNU C11 5.0.0 20150116 (experimental) -Asystem=linux -Asystem=unix -Asystem=posix -g"}, {Attr: dwarf.AttrLanguage, Val: int64(12)}, {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc5-ppc.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: int64(0x44)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}, }, }}, }, }, { "testdata/go-relocation-test-gcc482-ppc64le.obj", []relocationTestEntry{ {0, &dwarf.Entry{ Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{ {Attr: dwarf.AttrProducer, Val: "GNU C 4.8.2 -Asystem=linux -Asystem=unix -Asystem=posix -msecure-plt -mtune=power8 -mcpu=power7 -gdwarf-2 -fstack-protector"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc482-ppc64le.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: uint64(0x24)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}, }, }}, }, }, { "testdata/go-relocation-test-gcc492-mips64.obj", []relocationTestEntry{ {0, &dwarf.Entry{ Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{ {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.2 -meb -mabi=64 -march=mips3 -mtune=mips64 -mllsc -mno-shared -g"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "hello.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: int64(100)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}, }, }}, }, }, { "testdata/go-relocation-test-gcc531-s390x.obj", []relocationTestEntry{ {0, &dwarf.Entry{ Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{ {Attr: dwarf.AttrProducer, Val: "GNU C11 5.3.1 20160316 -march=zEC12 -m64 -mzarch -g -fstack-protector-strong"}, {Attr: dwarf.AttrLanguage, Val: int64(12)}, {Attr: dwarf.AttrName, Val: "hello.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: int64(58)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}, }, }}, }, }, { "testdata/go-relocation-test-gcc620-sparc64.obj", []relocationTestEntry{ {0, &dwarf.Entry{ Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{ {Attr: dwarf.AttrProducer, Val: "GNU C11 6.2.0 20160914 -mcpu=v9 -g -fstack-protector-strong"}, {Attr: dwarf.AttrLanguage, Val: int64(12)}, {Attr: dwarf.AttrName, Val: "hello.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: int64(0x2c)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}, }, }}, }, }, { "testdata/go-relocation-test-gcc492-mipsle.obj", []relocationTestEntry{ {0, &dwarf.Entry{ Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{ {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.2 -mel -march=mips2 -mtune=mips32 -mllsc -mno-shared -mabi=32 -g"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "hello.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: int64(0x58)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}, }, }}, }, }, { "testdata/go-relocation-test-gcc540-mips.obj", []relocationTestEntry{ {0, &dwarf.Entry{ Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{ {Attr: dwarf.AttrProducer, Val: "GNU C11 5.4.0 20160609 -meb -mips32 -mtune=mips32r2 -mfpxx -mllsc -mno-shared -mabi=32 -g -gdwarf-2"}, {Attr: dwarf.AttrLanguage, Val: int64(12)}, {Attr: dwarf.AttrName, Val: "hello.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: uint64(0x5c)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}, }, }}, }, }, { "testdata/go-relocation-test-gcc493-mips64le.obj", []relocationTestEntry{ {0, &dwarf.Entry{ Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{ {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.3 -mel -mabi=64 -mllsc -mno-shared -g -fstack-protector-strong"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "hello.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: int64(100)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}, }, }}, }, }, { "testdata/go-relocation-test-gcc720-riscv64.obj", []relocationTestEntry{ {0, &dwarf.Entry{ Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{ {Attr: dwarf.AttrProducer, Val: "GNU C11 7.2.0 -march=rv64imafdc -mabi=lp64d -g -gdwarf-2"}, {Attr: dwarf.AttrLanguage, Val: int64(12)}, {Attr: dwarf.AttrName, Val: "hello.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: uint64(0x2c)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}, }, }}, }, }, { "testdata/go-relocation-test-clang-x86.obj", []relocationTestEntry{ {0, &dwarf.Entry{ Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{ {Attr: dwarf.AttrProducer, Val: "clang version google3-trunk (trunk r209387)"}, {Attr: dwarf.AttrLanguage, Val: int64(12)}, {Attr: dwarf.AttrName, Val: "go-relocation-test-clang.c"}, {Attr: dwarf.AttrStmtList, Val: int64(0)}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, }, }}, }, }, { "testdata/gcc-amd64-openbsd-debug-with-rela.obj", []relocationTestEntry{ {203, &dwarf.Entry{ Offset: 0xc62, Tag: dwarf.TagMember, Children: false, Field: []dwarf.Field{ {Attr: dwarf.AttrName, Val: "it_interval"}, {Attr: dwarf.AttrDeclFile, Val: int64(7)}, {Attr: dwarf.AttrDeclLine, Val: int64(236)}, {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f)}, {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x0}}, }, }}, {204, &dwarf.Entry{ Offset: 0xc70, Tag: dwarf.TagMember, Children: false, Field: []dwarf.Field{ {Attr: dwarf.AttrName, Val: "it_value"}, {Attr: dwarf.AttrDeclFile, Val: int64(7)}, {Attr: dwarf.AttrDeclLine, Val: int64(237)}, {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f)}, {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x10}}, }, }}, }, }, } func TestDWARFRelocations(t *testing.T) { for i, test := range relocationTests { f, err := Open(test.file) if err != nil { t.Error(err) continue } dwarf, err := f.DWARF() if err != nil { t.Error(err) continue } for _, testEntry := range test.entries { reader := dwarf.Reader() for j := 0; j < testEntry.entryNumber; j++ { entry, err := reader.Next() if entry == nil || err != nil { t.Errorf("Failed to skip to entry %d: %v", testEntry.entryNumber, err) continue } } entry, err := reader.Next() if err != nil { t.Error(err) continue } if !reflect.DeepEqual(testEntry.entry, entry) { t.Errorf("#%d/%d: mismatch: got:%#v want:%#v", i, testEntry.entryNumber, entry, testEntry.entry) continue } } } } func TestCompressedDWARF(t *testing.T) { // Test file built with GCC 4.8.4 and as 2.24 using: // gcc -Wa,--compress-debug-sections -g -c -o zdebug-test-gcc484-x86-64.obj hello.c f, err := Open("testdata/zdebug-test-gcc484-x86-64.obj") if err != nil { t.Fatal(err) } dwarf, err := f.DWARF() if err != nil { t.Fatal(err) } reader := dwarf.Reader() n := 0 for { entry, err := reader.Next() if err != nil { t.Fatal(err) } if entry == nil { break } n++ } if n != 18 { t.Fatalf("want %d DWARF entries, got %d", 18, n) } } func TestCompressedSection(t *testing.T) { // Test files built with gcc -g -S hello.c and assembled with // --compress-debug-sections=zlib-gabi. f, err := Open("testdata/compressed-64.obj") if err != nil { t.Fatal(err) } sec := f.Section(".debug_info") wantData := []byte{ 182, 0, 0, 0, 4, 0, 0, 0, 0, 0, 8, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 8, 7, 0, 0, 0, 0, 2, 1, 8, 0, 0, 0, 0, 2, 2, 7, 0, 0, 0, 0, 2, 4, 7, 0, 0, 0, 0, 2, 1, 6, 0, 0, 0, 0, 2, 2, 5, 0, 0, 0, 0, 3, 4, 5, 105, 110, 116, 0, 2, 8, 5, 0, 0, 0, 0, 2, 8, 7, 0, 0, 0, 0, 4, 8, 114, 0, 0, 0, 2, 1, 6, 0, 0, 0, 0, 5, 0, 0, 0, 0, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 1, 156, 179, 0, 0, 0, 6, 0, 0, 0, 0, 1, 4, 87, 0, 0, 0, 2, 145, 108, 6, 0, 0, 0, 0, 1, 4, 179, 0, 0, 0, 2, 145, 96, 0, 4, 8, 108, 0, 0, 0, 0, } // Test Data method. b, err := sec.Data() if err != nil { t.Fatal(err) } if !bytes.Equal(wantData, b) { t.Fatalf("want data %x, got %x", wantData, b) } // Test Open method and seeking. buf, have, count := make([]byte, len(b)), make([]bool, len(b)), 0 sf := sec.Open() if got, err := sf.Seek(0, io.SeekEnd); got != int64(len(b)) || err != nil { t.Fatalf("want seek end %d, got %d error %v", len(b), got, err) } if n, err := sf.Read(buf); n != 0 || err != io.EOF { t.Fatalf("want EOF with 0 bytes, got %v with %d bytes", err, n) } pos := int64(len(buf)) for count < len(buf) { // Construct random seek arguments. whence := rand.Intn(3) target := rand.Int63n(int64(len(buf))) var offset int64 switch whence { case io.SeekStart: offset = target case io.SeekCurrent: offset = target - pos case io.SeekEnd: offset = target - int64(len(buf)) } pos, err = sf.Seek(offset, whence) if err != nil { t.Fatal(err) } if pos != target { t.Fatalf("want position %d, got %d", target, pos) } // Read data from the new position. end := pos + 16 if end > int64(len(buf)) { end = int64(len(buf)) } n, err := io.ReadFull(sf, buf[pos:end]) if err != nil { t.Fatal(err) } for i := 0; i < n; i++ { if !have[pos] { have[pos] = true count++ } pos++ } } if !bytes.Equal(wantData, buf) { t.Fatalf("want data %x, got %x", wantData, buf) } } func TestNoSectionOverlaps(t *testing.T) { // Ensure cmd/link outputs sections without overlaps. switch runtime.GOOS { case "android", "darwin", "js", "nacl", "plan9", "windows": t.Skipf("cmd/link doesn't produce ELF binaries on %s", runtime.GOOS) } _ = net.ResolveIPAddr // force dynamic linkage f, err := Open(os.Args[0]) if err != nil { t.Error(err) return } for i, si := range f.Sections { sih := si.SectionHeader if sih.Type == SHT_NOBITS { continue } for j, sj := range f.Sections { sjh := sj.SectionHeader if i == j || sjh.Type == SHT_NOBITS || sih.Offset == sjh.Offset && sih.Size == 0 { continue } if sih.Offset >= sjh.Offset && sih.Offset < sjh.Offset+sjh.Size { t.Errorf("ld produced ELF with section %s within %s: 0x%x <= 0x%x..0x%x < 0x%x", sih.Name, sjh.Name, sjh.Offset, sih.Offset, sih.Offset+sih.Size, sjh.Offset+sjh.Size) } } } } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/elf/reader.go000066400000000000000000000050021356504100700264620ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package elf import ( "io" "os" ) // errorReader returns error from all operations. type errorReader struct { error } func (r errorReader) Read(p []byte) (n int, err error) { return 0, r.error } func (r errorReader) ReadAt(p []byte, off int64) (n int, err error) { return 0, r.error } func (r errorReader) Seek(offset int64, whence int) (int64, error) { return 0, r.error } func (r errorReader) Close() error { return r.error } // readSeekerFromReader converts an io.Reader into an io.ReadSeeker. // In general Seek may not be efficient, but it is optimized for // common cases such as seeking to the end to find the length of the // data. type readSeekerFromReader struct { reset func() (io.Reader, error) r io.Reader size int64 offset int64 } func (r *readSeekerFromReader) start() { x, err := r.reset() if err != nil { r.r = errorReader{err} } else { r.r = x } r.offset = 0 } func (r *readSeekerFromReader) Read(p []byte) (n int, err error) { if r.r == nil { r.start() } n, err = r.r.Read(p) r.offset += int64(n) return n, err } func (r *readSeekerFromReader) Seek(offset int64, whence int) (int64, error) { var newOffset int64 switch whence { case seekStart: newOffset = offset case seekCurrent: newOffset = r.offset + offset case seekEnd: newOffset = r.size + offset default: return 0, os.ErrInvalid } switch { case newOffset == r.offset: return newOffset, nil case newOffset < 0, newOffset > r.size: return 0, os.ErrInvalid case newOffset == 0: r.r = nil case newOffset == r.size: r.r = errorReader{io.EOF} default: if newOffset < r.offset { // Restart at the beginning. r.start() } // Read until we reach offset. var buf [512]byte for r.offset < newOffset { b := buf[:] if newOffset-r.offset < int64(len(buf)) { b = buf[:newOffset-r.offset] } if _, err := r.Read(b); err != nil { return 0, err } } } r.offset = newOffset return r.offset, nil } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/elf/symbols_test.go000066400000000000000000000334111356504100700277540ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // +build go1.7 package elf import ( "io" "path" "reflect" "testing" ) // TODO: remove duplicate code func TestSymbols(t *testing.T) { do := func(file string, ts []Symbol, getfunc func(*File) ([]Symbol, error)) { var f *File var err error if path.Ext(file) == ".gz" { var r io.ReaderAt if r, err = decompress(file); err == nil { f, err = NewFile(r) } } else { f, err = Open(file) } if err != nil { t.Errorf("TestSymbols: cannot open file %s: %v", file, err) return } defer f.Close() fs, err := getfunc(f) if err != nil && err != ErrNoSymbols { t.Error(err) return } else if err == ErrNoSymbols { fs = []Symbol{} } if !reflect.DeepEqual(ts, fs) { t.Errorf("%s: Symbols = %v, want %v", file, ts, fs) } } for file, ts := range symbolsGolden { do(file, ts, (*File).Symbols) } for file, ts := range dynamicSymbolsGolden { do(file, ts, (*File).DynamicSymbols) } } // golden symbol table data generated by testdata/getgoldsym.c var symbolsGolden = map[string][]Symbol{ "testdata/gcc-amd64-linux-exec": { Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0x1, Value: 0x400200, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0x2, Value: 0x40021C, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0x3, Value: 0x400240, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0x4, Value: 0x400268, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0x5, Value: 0x400288, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0x6, Value: 0x4002E8, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0x7, Value: 0x400326, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0x8, Value: 0x400330, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0x9, Value: 0x400350, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0xA, Value: 0x400368, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0xB, Value: 0x400398, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0xC, Value: 0x4003B0, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0xD, Value: 0x4003E0, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0xE, Value: 0x400594, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0xF, Value: 0x4005A4, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0x10, Value: 0x4005B8, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0x11, Value: 0x4005E0, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0x12, Value: 0x600688, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0x13, Value: 0x600698, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0x14, Value: 0x6006A8, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0x15, Value: 0x6006B0, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0x16, Value: 0x600850, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0x17, Value: 0x600858, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0x18, Value: 0x600880, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0x19, Value: 0x600898, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0x1A, Value: 0x0, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0x1B, Value: 0x0, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0x1C, Value: 0x0, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0x1D, Value: 0x0, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0x1E, Value: 0x0, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0x1F, Value: 0x0, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0x20, Value: 0x0, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0x21, Value: 0x0, Size: 0x0, }, Symbol{ Name: "init.c", Info: 0x4, Other: 0x0, Section: 0xFFF1, Value: 0x0, Size: 0x0, }, Symbol{ Name: "initfini.c", Info: 0x4, Other: 0x0, Section: 0xFFF1, Value: 0x0, Size: 0x0, }, Symbol{ Name: "call_gmon_start", Info: 0x2, Other: 0x0, Section: 0xD, Value: 0x40040C, Size: 0x0, }, Symbol{ Name: "crtstuff.c", Info: 0x4, Other: 0x0, Section: 0xFFF1, Value: 0x0, Size: 0x0, }, Symbol{ Name: "__CTOR_LIST__", Info: 0x1, Other: 0x0, Section: 0x12, Value: 0x600688, Size: 0x0, }, Symbol{ Name: "__DTOR_LIST__", Info: 0x1, Other: 0x0, Section: 0x13, Value: 0x600698, Size: 0x0, }, Symbol{ Name: "__JCR_LIST__", Info: 0x1, Other: 0x0, Section: 0x14, Value: 0x6006A8, Size: 0x0, }, Symbol{ Name: "__do_global_dtors_aux", Info: 0x2, Other: 0x0, Section: 0xD, Value: 0x400430, Size: 0x0, }, Symbol{ Name: "completed.6183", Info: 0x1, Other: 0x0, Section: 0x19, Value: 0x600898, Size: 0x1, }, Symbol{ Name: "p.6181", Info: 0x1, Other: 0x0, Section: 0x18, Value: 0x600890, Size: 0x0, }, Symbol{ Name: "frame_dummy", Info: 0x2, Other: 0x0, Section: 0xD, Value: 0x400470, Size: 0x0, }, Symbol{ Name: "crtstuff.c", Info: 0x4, Other: 0x0, Section: 0xFFF1, Value: 0x0, Size: 0x0, }, Symbol{ Name: "__CTOR_END__", Info: 0x1, Other: 0x0, Section: 0x12, Value: 0x600690, Size: 0x0, }, Symbol{ Name: "__DTOR_END__", Info: 0x1, Other: 0x0, Section: 0x13, Value: 0x6006A0, Size: 0x0, }, Symbol{ Name: "__FRAME_END__", Info: 0x1, Other: 0x0, Section: 0x11, Value: 0x400680, Size: 0x0, }, Symbol{ Name: "__JCR_END__", Info: 0x1, Other: 0x0, Section: 0x14, Value: 0x6006A8, Size: 0x0, }, Symbol{ Name: "__do_global_ctors_aux", Info: 0x2, Other: 0x0, Section: 0xD, Value: 0x400560, Size: 0x0, }, Symbol{ Name: "initfini.c", Info: 0x4, Other: 0x0, Section: 0xFFF1, Value: 0x0, Size: 0x0, }, Symbol{ Name: "hello.c", Info: 0x4, Other: 0x0, Section: 0xFFF1, Value: 0x0, Size: 0x0, }, Symbol{ Name: "_GLOBAL_OFFSET_TABLE_", Info: 0x1, Other: 0x2, Section: 0x17, Value: 0x600858, Size: 0x0, }, Symbol{ Name: "__init_array_end", Info: 0x0, Other: 0x2, Section: 0x12, Value: 0x600684, Size: 0x0, }, Symbol{ Name: "__init_array_start", Info: 0x0, Other: 0x2, Section: 0x12, Value: 0x600684, Size: 0x0, }, Symbol{ Name: "_DYNAMIC", Info: 0x1, Other: 0x2, Section: 0x15, Value: 0x6006B0, Size: 0x0, }, Symbol{ Name: "data_start", Info: 0x20, Other: 0x0, Section: 0x18, Value: 0x600880, Size: 0x0, }, Symbol{ Name: "__libc_csu_fini", Info: 0x12, Other: 0x0, Section: 0xD, Value: 0x4004C0, Size: 0x2, }, Symbol{ Name: "_start", Info: 0x12, Other: 0x0, Section: 0xD, Value: 0x4003E0, Size: 0x0, }, Symbol{ Name: "__gmon_start__", Info: 0x20, Other: 0x0, Section: 0x0, Value: 0x0, Size: 0x0, }, Symbol{ Name: "_Jv_RegisterClasses", Info: 0x20, Other: 0x0, Section: 0x0, Value: 0x0, Size: 0x0, }, Symbol{ Name: "puts@@GLIBC_2.2.5", Info: 0x12, Other: 0x0, Section: 0x0, Value: 0x0, Size: 0x18C, }, Symbol{ Name: "_fini", Info: 0x12, Other: 0x0, Section: 0xE, Value: 0x400594, Size: 0x0, }, Symbol{ Name: "__libc_start_main@@GLIBC_2.2.5", Info: 0x12, Other: 0x0, Section: 0x0, Value: 0x0, Size: 0x1C2, }, Symbol{ Name: "_IO_stdin_used", Info: 0x11, Other: 0x0, Section: 0xF, Value: 0x4005A4, Size: 0x4, }, Symbol{ Name: "__data_start", Info: 0x10, Other: 0x0, Section: 0x18, Value: 0x600880, Size: 0x0, }, Symbol{ Name: "__dso_handle", Info: 0x11, Other: 0x2, Section: 0x18, Value: 0x600888, Size: 0x0, }, Symbol{ Name: "__libc_csu_init", Info: 0x12, Other: 0x0, Section: 0xD, Value: 0x4004D0, Size: 0x89, }, Symbol{ Name: "__bss_start", Info: 0x10, Other: 0x0, Section: 0xFFF1, Value: 0x600898, Size: 0x0, }, Symbol{ Name: "_end", Info: 0x10, Other: 0x0, Section: 0xFFF1, Value: 0x6008A0, Size: 0x0, }, Symbol{ Name: "_edata", Info: 0x10, Other: 0x0, Section: 0xFFF1, Value: 0x600898, Size: 0x0, }, Symbol{ Name: "main", Info: 0x12, Other: 0x0, Section: 0xD, Value: 0x400498, Size: 0x1B, }, Symbol{ Name: "_init", Info: 0x12, Other: 0x0, Section: 0xB, Value: 0x400398, Size: 0x0, }, }, "testdata/go-relocation-test-clang-x86.obj": { Symbol{ Name: "go-relocation-test-clang.c", Info: 0x4, Other: 0x0, Section: 0xFFF1, Value: 0x0, Size: 0x0, }, Symbol{ Name: ".Linfo_string0", Info: 0x0, Other: 0x0, Section: 0xC, Value: 0x0, Size: 0x0, }, Symbol{ Name: ".Linfo_string1", Info: 0x0, Other: 0x0, Section: 0xC, Value: 0x2C, Size: 0x0, }, Symbol{ Name: ".Linfo_string2", Info: 0x0, Other: 0x0, Section: 0xC, Value: 0x47, Size: 0x0, }, Symbol{ Name: ".Linfo_string3", Info: 0x0, Other: 0x0, Section: 0xC, Value: 0x4C, Size: 0x0, }, Symbol{ Name: ".Linfo_string4", Info: 0x0, Other: 0x0, Section: 0xC, Value: 0x4E, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0x1, Value: 0x0, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0x2, Value: 0x0, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0x3, Value: 0x0, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0x4, Value: 0x0, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0x6, Value: 0x0, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0x7, Value: 0x0, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0x8, Value: 0x0, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0xA, Value: 0x0, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0xC, Value: 0x0, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0xD, Value: 0x0, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0xE, Value: 0x0, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0xF, Value: 0x0, Size: 0x0, }, Symbol{ Name: "", Info: 0x3, Other: 0x0, Section: 0x10, Value: 0x0, Size: 0x0, }, Symbol{ Name: "v", Info: 0x11, Other: 0x0, Section: 0xFFF2, Value: 0x4, Size: 0x4, }, }, "testdata/hello-world-core.gz": {}, } var dynamicSymbolsGolden = map[string][]Symbol{ "testdata/gcc-amd64-linux-exec": { Symbol{ Name: "__gmon_start__", Info: 0x20, Other: 0x0, Section: 0x0, Value: 0x0, Size: 0x0, }, Symbol{ Name: "puts", Info: 0x12, Other: 0x0, Section: 0x0, Value: 0x0, Size: 0x18C, }, Symbol{ Name: "__libc_start_main", Info: 0x12, Other: 0x0, Section: 0x0, Value: 0x0, Size: 0x1C2, }, }, "testdata/go-relocation-test-clang-x86.obj": {}, "testdata/hello-world-core.gz": {}, } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/elf/testdata/000077500000000000000000000000001356504100700265055ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/elf/testdata/compressed-32.obj000077500000000000000000000042401356504100700315720ustar00rootroot00000000000000ELFX4(U‰åƒäðƒìÇ$èüÿÿÿÉÃhello, world´xœÛÀÀÀÀÂ,ŒÛ€$cˆCi&v>ÅÈá ¢˜Ø§C¥Á‚l«À‚¬ß3 kf^ +X».X%k D##Жˆ6 Ųf㜵@’-,è R6‘‹Ä[ æ±µçT.v ¡% $ > $ >  I.?: ; '@–B: ; IXCû /home/iant/go/src/debug/elf/testdatahello.c‘»xœeŽM‚0…{”^&QBذráÎËÐ6–)i=½€ÆŸ°yÉ÷’÷Í„ÈV‡%<‹š8{ËÔ­°¶Ûf[‡é;]i@Ïê£Åd,`#äd £ËdBBY:G!ÄÒ¨ìb’ÿ+¿úã鬺*›²ÒŰßÍ!Sk‰)y3#&ãZ_7µ.¬.ú,h®Å˜¢‘˜Þþ—öAriyò¦žì¢^PGCC: (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4zR| ˆA…B SÅ ñÿ    hello.cmainputs     $ + 2 9 @ G U \ c j w | ‚‘ Ÿ P .symtab.strtab.shstrtab.rel.text.data.bss.rodata.rel.debug_info.debug_abbrev.rel.debug_aranges.rel.debug_line.debug_str.comment.note.GNU-stack.rel.eh_frame4 @Ü%K+K0K <X„8 @ì HÜZZ6 V @Œ mV\i @œ y0²³„0e*¡8 @¤¬«È Ègoogle-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/elf/testdata/compressed-64.obj000077500000000000000000000063201356504100700316000ustar00rootroot00000000000000ELF>@@UH‰åHƒì‰}üH‰uð¿èÉÃhello, worldºxœÛÆÀÀÀÂŒ L i$6;˜bäSL T "È ¢˜YX3óJ€X‘ô±p!‚%YЭaœ³H²A$ÃAÊ'æ@y›Á¼ 19 é}#% $ > $ >  I.?: ; '@–B: ; I0xœÓa```bd Í€ €R\Cû /home/iant/go/src/debug/elf/testdatahello.c åŸxœUN1‚0ÌSòB†¡¡²°³óár$QÈ1ÉÅQ_¯ˆã@±ÅîÞî^‰9¸ˆV†Èât¾È£¬«¶ª¥š¸DìFL>Ô$ðÝ£mTó1TCf75'b¦$FŠN–mx“Ä_ù²É„(´§ u0‘µXàè ¨¿Úð«YÒ&9Ø’Î ´Å¾8ã 3[ÃF{Gª@dO‰÷/l·W{U_ÈÏ—»x(†ZiGCC: (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4zRx A†C V ñÿ    hello.cmainputs üÿÿÿÿÿÿÿ     u) 0 K7 b> ÍE L àS ìa ’h öu ]z p€— ›¥ ÿ P .symtab.strtab.shstrtab.rela.text.data.bss.rodata.rela.debug_info.debug_abbrev.rela.debug_aranges.rela.debug_line.debug_str.comment.note.GNU-stack.rela.eh_frame @@ˆ0&[,[1[ >hr9@¸ÈJÚ\]6/X@€0 qe`l@° }0ÅÈ0ˆ*‘²¦¸8¡@Èà°ð€ pgoogle-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/elf/testdata/gcc-386-freebsd-exec000077500000000000000000000131561356504100700320450ustar00rootroot00000000000000ELF ̃4 4 (44€4€  ÔÔ€Ô€€€ûûüü•ü•Øø  – –˜˜/libexec/ld-elf.so.1     , –ñÿhƒ!ð–) Aü• ªÔ–ñÿLVL… \+£Ô–ñÿc¸–ñÿ¶ô–ñÿ^Dy libc.so.6printf_DYNAMIC_initenviron__deregister_frame_info__progname_init_tls_finiatexit_GLOBAL_OFFSET_TABLE__Jv_RegisterClasses__register_frame_info_edata__bss_start_endÄ–È–Ì– Жƒì è<è³ƒÄ Ãÿ5¼–ÿ%À–ÿ%Ä–héàÿÿÿÿ%È–héÐÿÿÿÿ%Ì–héÀÿÿÿÿ%Жhé°ÿÿÿU‰åWVSƒì ƒäð‹]‰×t …Û‰5ð–~$‹E…Àt£ü•‰ÁŠ„Àtƒì Wè‹ÿÿÿƒÄƒì hL…è{ÿÿÿè2ÿÿÿPVEPS趃ÄPèqÿÿÿ‰Ñ‰ü•ë³èAÿÿÿëÇU‰åƒì€=Ô–të8vƒÀ£–ÿÒ¡–‹…Òu븅Àtƒì h–èa{û÷ƒÄÆÔ–ÉÃU¸‰åƒì…ÀtƒìhØ–h–è3{û÷ƒÄ¡´–…Àt¸…Àtƒì h´–è{û÷ƒÄ‰öÉÃU‰åƒìƒäð¸ƒÀƒÀÁèÁà)ăì h£…èkþÿÿƒÄÉÃU‰åSR»¤–¡¤–ë vƒëÿЋƒøÿuôX[ÉÃì è ÿÿÿƒÄ Ã$FreeBSD: src/lib/csu/i386-elf/crti.S,v 1.7 2005/05/19 07:31:06 dfr Exp $hello, world $FreeBSD: src/lib/csu/i386-elf/crtn.S,v 1.6 2005/05/19 07:31:06 dfr Exp $X…°– hƒ L…쀌‚| » ¸– Hƒÿÿÿÿÿÿÿÿ –’ƒ¢ƒ²ƒƒ$FreeBSD: src/lib/csu/common/crtbrand.c,v 1.4 2003/10/17 15:43:13 peter Exp $$FreeBSD: src/lib/csu/i386-elf/crt1.c,v 1.14 2005/05/19 07:36:07 dfr Exp $GCC: (GNU) 3.4.6 [FreeBSD] 20060305GCC: (GNU) 3.4.6 [FreeBSD] 20060305GCC: (GNU) 3.4.6 [FreeBSD] 20060305GCC: (GNU) 3.4.6 [FreeBSD] 20060305ø„.main&…ø„GNU C 3.4.6 [FreeBSD] 20060305hello.c/home/am8/rscsigned charunsigned charshort intshort unsigned intintlong long intlong long unsigned intlong unsigned intdoublecharlong intmain‘ø„&…U% $ > $ > .? : ; ' I@ 1û hello.cø„ªðÿÿÿÿ| ˆø„.A…B a.unsigned int.symtab.strtab.shstrtab.interp.hash.dynsym.dynstr.rel.plt.init.text.fini.rodata.data.eh_frame.dynamic.ctors.dtors.jcr.got.bss.comment.debug_aranges.debug_pubnames.debug_info.debug_abbrev.debug_line.debug_frame.debug_strÔ€Ô#ì€ì) ||1Œ‚Œ»9 HƒH Bhƒh=|ƒ|PH̃Ì€NL…L TX…X£\ü•ü b–l – ˜u¤–¤|¬–¬ƒ´–´ˆ¸–¸Ô–Ô ’Ô-› ª!º<ÆY AÔš 5àÐ 0í  ø¸°8 hÔ€ì€|Œ‚Hƒhƒ|ƒ̃L… X… ü• – – ¤–¬–´–¸–Ô–ñÿñÿ)ñÿ8ñÿñÿCñÿN¤–\¬–j– }´–Š– ŽÔ–š`„°Ø–¹¬„CñÿŨ–Ò°–ß– í´–ù(…ñÿ)ñÿ8ñÿñÿ0ñÿ8,? –ñÿH– Uhƒ[ð–c {ü• †̃‘Ô–ñÿ™ø„.ž¨L… ®+µÔ–ñÿ¼¸–ñÿÒô–ñÿ×DÜ ð crt1.c/usr/src/lib/csu/i386-elf/crti.Scrtstuff.c__CTOR_LIST____DTOR_LIST____EH_FRAME_BEGIN____JCR_LIST__p.0completed.1__do_global_dtors_auxobject.2frame_dummy__CTOR_END____DTOR_END____FRAME_END____JCR_END____do_global_ctors_aux/usr/src/lib/csu/i386-elf/crtn.Shello.cprintf_DYNAMIC__dso_handle_initenviron__deregister_frame_info__progname_start__bss_startmain_init_tls_finiatexit_edata_GLOBAL_OFFSET_TABLE__endexit_Jv_RegisterClasses__register_frame_infogoogle-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/elf/testdata/gcc-amd64-linux-exec000077500000000000000000000212141356504100700321570ustar00rootroot00000000000000ELF>à@@`@8@%"@@@@@ÀÀ@@@@„„ ˆˆ`ˆ` °°`°`  @@ Påtd¸¸@¸@$$Qåtd/lib64/ld-linux-x86-64.so.2GNU ŒÂ__gmon_start__libc.so.6puts__libc_start_mainGLIBC_2.2.5ui 1P`p`x`HƒìèkèÊèµHƒÄÃÿ5ª ÿ%¬ @ÿ%ª héàÿÿÿÿ%¢ héÐÿÿÿ1íI‰Ñ^H‰âHƒäðPTIÇÀÀ@HÇÁÐ@HÇǘ@èÇÿÿÿôHƒìH‹9 H…ÀtÿÐHƒÄÀ=a UH‰åtë$HƒÀH‰E ÿÒH‹< H‹H…ÒuäÆ5 ÉÃff.„UHƒ=/ H‰åt¸H…Àt ¿¨`I‰ÃÉAÿãÉÃUH‰åHƒì‰}üH‰uð¿¨@èÿÿÿÉÃóÃfffff.„H‰l$ØL‰|$øH-£ L=œ L‰d$àL‰l$èL‰t$ðH‰\$ÐHƒì8L)ýA‰þI‰õHÁýI‰ÔèƒþÿÿH…ít1Û@L‰âL‰îD‰÷AÿßHƒÃH9ÝuêH‹\$H‹l$L‹d$L‹l$ L‹t$(L‹|$0HƒÄ8ÃUH‰åSHƒìH‹ Hƒøÿt1ÛÿÐH‹ƒ€`HƒëHƒøÿuíHƒÄ[ÉÃHƒìè“þÿÿHƒÄÃhello, world;$àþÿÿ@ÿÿÿ€ÿÿÿ˜zRx $˜@† zRx €þÿÿ,4xþÿÿ‰ †&@ƒŽŒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ˜@ ”@@@õþÿoh@è@ˆ@ = X`0h@P@ þÿÿo0@ÿÿÿoðÿÿo&@°`Æ@Ö@ `GCC: (GNU) 4.2.4 (Ubuntu 4.2.4-1ubuntu1)GCC: (GNU) 4.2.4 (Ubuntu 4.2.4-1ubuntu1)GCC: (GNU) 4.2.4 (Ubuntu 4.2.4-1ubuntu4)GCC: (GNU) 4.2.4 (Ubuntu 4.2.4-1ubuntu4)GCC: (GNU) 4.2.4 (Ubuntu 4.2.4-1ubuntu1)GCC: (GNU) 4.2.4 (Ubuntu 4.2.4-1ubuntu4)GCC: (GNU) 4.2.4 (Ubuntu 4.2.4-1ubuntu1)L‹ @˜@ ”@<«@@!‹o_IO_stdin_used‡Uªy @ @>@%intLG/… ¤@WŠK'/build/buildd/glibc-2.7/build-tree/amd64-libc/csu/crti.S/build/buildd/glibc-2.7/build-tree/glibc-2.7/csuGNU AS 2.18.0€Š]ÀP/build/buildd/glibc-2.7/build-tree/amd64-libc/csu/crtn.S/build/buildd/glibc-2.7/build-tree/glibc-2.7/csuGNU AS 2.18.0€% $ > $ > $ > 4: ; I?  &IU%U%#û init.c•Oû /build/buildd/glibc-2.7/build-tree/amd64-libc/csucrti.S  @ Ku=/0K ˜@K ”@${Oû /build/buildd/glibc-2.7/build-tree/amd64-libc/csucrtn.S «@K @Klong unsigned intshort unsigned intshort int_IO_stdin_usedunsigned charlong intGNU C 4.2.4 (Ubuntu 4.2.4-1ubuntu1)/build/buildd/glibc-2.7/build-tree/glibc-2.7/csuinit.cÿÿÿÿÿÿÿÿ @#@˜@¡@”@˜@ÿÿÿÿÿÿÿÿ«@°@@¢@.symtab.strtab.shstrtab.interp.note.ABI-tag.gnu.hash.dynsym.dynstr.gnu.version.gnu.version_r.rela.dyn.rela.plt.init.text.fini.rodata.eh_frame_hdr.eh_frame.ctors.dtors.jcr.dynamic.got.got.plt.data.bss.comment.debug_aranges.debug_pubnames.debug_info.debug_abbrev.debug_line.debug_str.debug_ranges@#@ 5@@@$1öÿÿoh@h; ˆ@ˆ`Cè@è=Kÿÿÿo&@&Xþÿÿo0@0 gP@Pqh@h0 {˜@˜v°@°0à@à´‡”@”¤@¤•¸@¸$£à@भˆ`ˆ´˜`˜»¨`¨À°`° ÉP`PÎX`X(×€`€Ý˜`˜â˜&ëÀ úP % u § o$‹ ?00Ê ±;€I ð$9  ü@@@@h@ˆ@è@&@0@ P@ h@ ˜@ °@ à@”@¤@¸@à@ˆ`˜`¨`°`P`X`€`˜` !ñÿñÿ @#ñÿ.ˆ`<˜`J¨`W 0@m˜`|`ƒ p@#ñÿ`œ `©€@·¨`à `@ñÿÙñÿáX`÷„`„`°`$ €`/ À@? à@F U iŒ{”@ ¤@¯€`¼ˆ`É Ð@‰Ùñÿ˜`åñÿ `êñÿ˜`ñ ˜@ö ˜@init.cinitfini.ccall_gmon_startcrtstuff.c__CTOR_LIST____DTOR_LIST____JCR_LIST____do_global_dtors_auxcompleted.6183p.6181frame_dummy__CTOR_END____DTOR_END____FRAME_END____JCR_END____do_global_ctors_auxhello.c_GLOBAL_OFFSET_TABLE___init_array_end__init_array_start_DYNAMICdata_start__libc_csu_fini_start__gmon_start___Jv_RegisterClassesputs@@GLIBC_2.2.5_fini__libc_start_main@@GLIBC_2.2.5_IO_stdin_used__data_start__dso_handle__libc_csu_init__bss_start_end_edatamain_initgcc-amd64-openbsd-debug-with-rela.obj000077500000000000000000000146201356504100700352030ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/elf/testdataELF>H@@ %  : ;  : ; I8  I$ > : ; II!I/ $ >  : ;    : ;  : ; I : ; I8  : ; : ;I8 4: ; I?  JGNU C 4.2.1 20070719 /home/joel/src/go/src/cmd/cgovpv#n„#|charint_GoString_UÊpv#n„#c„# _GoBytes___int8_t;ësigned char__uint8_t< unsigned char__int16_t=-short int__uint16_t>Lshort unsigned int__int32_t?„__uint32_t@…unsigned int__int64_tB¦long long int__uint64_tDÉlong long unsigned int__int_least8_tGÛ__uint_least8_tHú__int_least16_tI__uint_least16_tJ:__int_least32_tKb__uint_least32_tLs__int_least64_tM•__uint_least64_tN·__int_fast8_tQb__uint_fast8_tRs__int_fast16_tSb__uint_fast16_tTs__int_fast32_tUb__uint_fast32_tVs__int_fast64_tW•__uint_fast64_tX·__intptr_tgalong int__uintptr_th€long unsigned int__intmax_tk•__uintmax_tl·__register_toa__vaddr_tr€__paddr_ts€__vsize_tt€__psize_tu€__clock_tx„__clockid_ty„__double_tzHdouble__float_t{cfloat__off_t|¦__ptrdiff_t}a__size_t~€__ssize_ta__time_t€„__timer_t„__va_listƒáôññ  __va_list_tagggp_offset…#fp_offset…#overflow_arg_areag#reg_save_areag# __wchar_tŠ„__wint_tŒ„__rune_t„__wctrans_tŽg__wctype_tg__cpuid_t'€__dev_t(b__fixpt_t)s__gid_t*s__id_t+s__in_addr_t,s__in_port_t-:__ino_t.s__key_t/a__mode_t0s__nlink_t1s__pid_t2b__rlim_t3·__sa_family_t4ú__segsz_t5b__socklen_t6s__swblk_t7b__uid_t8s__useconds_t9s__suseconds_t:b__fsblkcnt_t;·__fsfilcnt_t<· €Bh __mbstate8Ch __mbstateLD•|xñ__mbstate_tE;u_char0 u_short1Lu_int2…u_long3€unchar5 ushort6Luint7…ulong8€cpuid_t:¿register_t;ºint8_tHÛuint8_tMúint16_tRuint16_tW:int32_t\buint32_tasint64_tf•uint64_tk·u_int8_toúu_int16_tp:u_int32_tqsu_int64_tr·quad_tu•u_quad_tv·qaddr_tw Övaddr_t{Îpaddr_t|ßvsize_t}ðpsize_t~caddr_t‚vdaddr32_tƒbdaddr_t„•daddr64_t…•dev_t†Ðfixpt_t‡ßgid_tˆðid_t‰ÿino_tŠ3key_t‹Bmode_tŒQnlink_tapid_tŽrrlim_tsegsz_t¦swblk_t‘Êuid_t’Ûuseconds_t“êsuseconds_t”þfsblkcnt_t•fsfilcnt_t–'in_addr_t  in_port_t¡ sa_family_t¢‘socklen_t£·clock_tªclockid_t¯#size_t´Žssize_t¹žtime_t¾¯timer_tÿoff_tÈl__fd_mask7U fd_set€;a fds_bits timevalZ° 2a#tv_usec3a# timespec;â < #tv_nsec=a# timezoneJ" tz_minuteswestK„#tz_dsttimeL„# bintime‹P secŒ #fracƒ# itimerval ë ì #í # clockinfoóâ hzô„#tickõ„#tickadjö„#stathz÷„# profhzø„# itimerspec , -° #.° # tm8 hä tm_sec i„#tm_min j„#tm_hour k„#tm_mday l„# tm_mon m„#tm_year n„#tm_wday o„#tm_yday p„#tm_isdst q„# tm_gmtoff ra#(tm_zone sv#0bpf_int32 .Ubpf_u_int32 /´ bpf_program >Abf_len ?¨#bf_insns @ˆ# bpf_insn @ˆcode û£#jt ü‹#jf ý‹#k þ´#A bpf_stat FÄbs_recv G¨#bs_drop H¨# bpf_version Vÿbv_major W™#bv_minor X™# bpf_timeval 4 ‚´#tv_usec ƒ´# bpf_hdr ‰–bh_tstamp Šÿ#bh_caplen ‹´#bh_datalen Œ´# bh_hdrlen £#bpf_dltlist Óbfl_len ¨#bfl_list Ó#¨__cgo__0 ô ° __cgo__1   ¦+ñ__cgodebug_data  ðêû /usr/include/machine/usr/include/sys/usr/include/usr/include/net../../pkg/syscall_types.h_types.htypes.hselect.htime.h_time.htime.hbpf.htypes_openbsd.go<NÙ__cgo__0ú__cgo__1+__cgodebug_datait_intervaltv_secit_value.symtab.strtab.shstrtab.text.data.bss.debug_abbrev.rela.debug_info.debug_line.rela.debug_pubnames.debug_str@!@'X,XØ?0N:(P K~ô\r@Wx l²ÎwÈ8  #ñÿ òÿòÿ__cgodebug_data__cgo__0__cgo__1 AIQ   c q ö   ì  E  go-relocation-test-clang-arm.obj000077500000000000000000000060241356504100700345050ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/elf/testdataELF(Ä4(H-é ° áÐMâ Ÿå åå áþÿÿëå РሽèA4aeabi*ARM1136JF-S j 00[‘|U}\af%.@: ; '?2 : ; I$> I9û hello.c uƒn&mainnUintfcharDebian clang version 3.5.0-10 (tags/RELEASE_350/final) (based on LLVM 3.5.0)hello.c/tmpmainargcintargvcharhello, world Debian clang version 3.5.0-10 (tags/RELEASE_350/final) (based on LLVM 3.5.0) ÿÿÿÿ| 0DŽ‹D .rel.ARM.exidx.debug_abbrev.rel.text.comment.bss.ARM.attributes.rel.debug_pubtypes.rel.debug_pubnames.debug_ranges.debug_str.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.shstrtab.strtab.symtab.data.rodata.str1.1"40 t Ýd1d6pd5‹™n‡ „ `L›S=— ä  ^Z ì  J«#F ô  |0Îr¸@n@p‚@ ü ã2H(0VN«¤,§  ÃÐòÕü (Íœ Øñÿ¹Óͳ™ Ÿ,…q]I5!  ¾¤MŠUvZb_Nd:h&m   0 .L.strmainprintfhello.c$d.9$d.8.Linfo_string7$d.7.Linfo_string6$d.6.Linfo_string5$d.5.Linfo_string4$d.4.Linfo_string3$d.3.Linfo_string2$d.12$d.2.Linfo_string1$d.11$a.1.Linfo_string0$d.10$d.0), '1<JVg+*'go-relocation-test-clang-x86.obj000077500000000000000000000035541356504100700343600ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/elf/testdataELF@4(4 0%4I? : ;  $> 71û go-relocation-test-clang.c8v80intclang version google3-trunk (trunk r209387)go-relocation-test-clang.c/tmpvintclang version google3-trunk (trunk r209387).debug_abbrev.text.comment.bss.rel.debug_pubtypes.rel.debug_pubnames.debug_ranges.debug_str.rel.debug_info.note.GNU-stack.debug_line.debug_loc.shstrtab.strtab.symtab.data4µ44h48d @l,„˜;;Ó7 \'ë# d Y0RWKW0W-t„›„»­`P¥°iñÿZ K, <G -L N    òÿvgo-relocation-test-clang.c.Linfo_string4.Linfo_string3.Linfo_string2.Linfo_string1.Linfo_string0  ,1  go-relocation-test-gcc424-x86-64.obj000077500000000000000000000060201356504100700345000ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/elf/testdataELF>`@@UH‰åÉÃ% .? : ; I@$ > ˆGNU C 4.2.4 (Ubuntu 4.2.4-1ubuntu4)go-relocation-test-gcc424.c/tmpf„intJ2û go-relocation-test-gcc424.c Kÿÿÿÿx $† zRx $† wwvŒff,GCC: (GNU) 4.2.4 (Ubuntu 4.2.4-1ubuntu4).symtab.strtab.shstrtab.text.data.bss.debug_abbrev.rela.debug_info.rela.debug_line.rela.debug_frame.rela.eh_frame.debug_loc.rela.debug_pubnames.rela.debug_aranges.comment.note.GNU-stack@!H'H,H4?|Œ:À ¨PNKh aX@\€ 0 s˜@n°  }ØL$ˆÈ ¢<0à 0±l*º––Ê €   ñÿ   go-relocation-test-gcc424.cf RZb px€ ?     go-relocation-test-gcc441-x86-64.obj000077500000000000000000000055701356504100700345100ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/elf/testdataELF>ø@@UH‰åÉÃ% .? : ; I@$ > OfKintC+û go-relocation-test.c JwwvS-f,GNU C 4.4.1go-relocation-test.c/tmpGCC: (Ubuntu 4.4.1-4ubuntu1) 4.4.1zRx AC† .symtab.strtab.shstrtab.text.data.bss.debug_abbrev.rela.debug_info.rela.debug_line.debug_loc.rela.debug_pubnames.rela.debug_aranges.debug_str.comment.note.GNU-stack.rela.eh_frame@!H'H,H4?|S: ðPÏGK \Llbg  z0|0 0 0ª&›0Ð$¤ô¹ø8´` 0Ãx€ ø ñÿ   go-relocation-test.cf    !!) 7?G 8   go-relocation-test-gcc441-x86.obj000077500000000000000000000035341356504100700342570ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/elf/testdataELFt4(U‰å]Ã% .? : ; I@$ > ?t.c f;int.û t.c=ttuC%fGNU C 4.4.1/tmpGCC: (Ubuntu 4.4.1-4ubuntu1) 4.4.1zR| ˆAB… .symtab.strtab.shstrtab.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack.rel.eh_frame4!<'<,<4>pC: ìHN³2J 4Zå,ie < }) y D Œ0I—0Z$ ~´€4° T´¾ä äñÿ   t.cf   !/37' go-relocation-test-gcc482-aarch64.obj000077500000000000000000000065001356504100700350630ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/elf/testdataELF·Ø@@ý{¾©ý‘ ¹¡ ù‘”ý{¨À_Öhello, world¶$intr$œ³W‘|³‘pl% $ > $ >  I.?: ; '@–B: ; I,$K2û go-relocation-test-gcc482.c ƒgunsigned intGNU C 4.8.2 -g -fstack-protectorlong unsigned intcharunsigned charmainlong int/tmpargcshort unsigned intsigned chargo-relocation-test-gcc482.cshort intsizetypeargvGCC: (Ubuntu/Linaro 4.8.2-19ubuntu1) 4.8.2 ÿÿÿÿ| $$B žB LÞÝ .symtab.strtab.shstrtab.rela.text.data.bss.rodata.rela.debug_info.debug_abbrev.rela.debug_aranges.rela.debug_line.debug_str.comment.rela.debug_frame @$¸ H&d,d1h>xº9 ÈJ2\]Ž0XÈ 0 q¾Olø  }0 ¾ˆ0Ë,–ø8‘ 00£Ø° ˆ -ñÿ    #$(go-relocation-test-gcc482.c$d$xmainputs   Š a) 0 .7 E> kE L ~S ¦a Xh °u @z S€— f¥ ¹?go-relocation-test-gcc482-ppc64le.obj000077500000000000000000000057101356504100700351120ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/elf/testdataELFx@@øÿáûÑÿ!øx ?|0?8øÿáë €N€Ef% .? : ; @—B q q0 0$q,$R:û go-relocation-test-gcc482-ppc64le.c <go-relocation-test-gcc482-ppc64le.cGNU C 4.8.2 -Asystem=linux -Asystem=unix -Asystem=posix -msecure-plt -mtune=power8 -mcpu=power7 -gdwarf-2 -fstack-protector/tmpGCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2 ÿÿÿÿxA $$B0ŸA A .symtab.strtab.shstrtab.text.data.bss.toc.rela.debug_info.debug_abbrev.debug_loc.rela.debug_aranges.rela.debug_line.debug_str.comment.note.GNU-stack.rela.debug_frame@$!d'd,d6dI1` ðB­*P×``70[P 0 tgVo€  €0½¥‹0b%”‡©ˆ8¤˜ 0À¶¸€ 8 'ñÿ   %$go-relocation-test-gcc482-ppc64le.cf  $   &!&$) 3&;&$C&G& &go-relocation-test-gcc492-arm.obj000077500000000000000000000051301356504100700344110ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/elf/testdataELF(è4(H-é°âÐMâ å  åã@ãþÿÿëÐK∽èhello, world´ž$(¿àuóint‡ÒxºÍ(œ±ÛO‘tÿ±‘pr% $ > $ >  I.?: ; '@–B: ; I(G2û go-relocation-test-gcc492.cŸglong long intGNU C 4.9.2 20141224 (prerelease) -march=armv7-a -mfloat-abi=hard -mfpu=vfpv3-d16 -mtls-dialect=gnu -glong unsigned intlong long unsigned intgo-relocation-test-gcc492.ccharunsigned charmainlong intargcshort unsigned intsigned charargvshort intunsigned intsizetype/root/go/src/debug/elf/testdataGCC: (GNU) 4.9.2 20141224 (prerelease) ÿÿÿÿ| (B‹ŽB N A4aeabi*7-A A  ".symtab.strtab.shstrtab.rel.text.data.bss.rodata.rel.debug_info.debug_abbrev.rel.debug_aranges.rel.debug_line.debug_str.comment.note.GNU-stack.rel.debug_frame.ARM.attributesñÿ %   ((-go-relocation-test-gcc492.c$d.LC0$amainputs+,    ! ( / 6 = D K Y ` g n { € †• £  ?4( @%\+\0\<l¸8 @¨H$\Z€ V @À m Ki @Ð y0ëD„0/(W¡X0 @Ø®pˆ5½¾|P Ì2go-relocation-test-gcc492-mips64.obj000077500000000000000000000100301356504100700347470ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/elf/testdataELF ˜ @@g½ÿÐÿ¿(ÿ¾ ÿ¼ ð-<™à-gœ€-ÿůÂß‚dDß‚@È- ø %Àè-ß¿(ß¾ ß¼g½0à % % % %(ò4Ðÿÿÿø0hello, world¶dintrdœ³W‘P³‘Xl% $ > $ >  I.?: ; '@–B: ; I,d:û hello.c 0uunsigned intlong unsigned intcharunsigned charmainlong int/tmpargcshort unsigned intsigned charGNU C 4.9.2 -meb -mabi=64 -march=mips3 -mtune=mips64 -mllsc -mno-shared -gshort inthello.csizetypeargvGCC: (Debian 4.9.2-10) 4.9.2 ÿÿÿÿ| ,dD0LŸžœD x PÜÞßAgnu.symtab.strtab.shstrtab.rela.text.data.bss.MIPS.options.MIPS.abiflags.rela.pdr.mdebug.abi64.rodata.rela.debug_info.debug_abbrev.rela.debug_aranges.rela.debug_line.debug_str.comment.rela.debug_frame.gnu.attributesÿñ     dhello.cmainputs0 4 8  i ¾ @) 0  7 $> JE L ]S ´a 7h Æu z 2€— E¥ Ï+  @p@Èx&°,°1p °(?p*ØSð N@@Xfsp ºn@XÈ pÚ\’p60@ 0¦pf>¡@ P²p0¤Ô½0xËp˜@Æ@ h0ØoÿÿõØèèÐà °go-relocation-test-gcc492-mipsle.obj000077500000000000000000000054601356504100700351310ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/elf/testdataELF 4(àÿ½'¿¯¾¯!ð <œ'¼¯ į$ů<D$‚!È@ ø % Ü!èÀ¿¾ ½'à% % % 4òÀüÿÿÿ hello, world´oãeXIºÍÙint-\ëxDWXœ±jO‘ô±‘r% $ > $ >  I.?: ; '@–B: ; IX6û hello.c$­long long intunsigned intlong unsigned intlong long unsigned intcharunsigned charmainlong int/tmpargcGNU C 4.9.2 -mel -march=mips2 -mtune=mips32 -mllsc -mno-shared -mabi=32 -gshort unsigned intsigned charshort inthello.csizetypeargvGCC: (Debian 4.9.2-10) 4.9.2 ÿÿÿÿ|  XD HŸžD t LÞßAgnu.symtab.strtab.shstrtab.rel.text.data.bss.reginfo.MIPS.abiflags.rel.pdr.mdebug.abi32.rodata.rel.debug_info.debug_abbrev.rel.debug_aranges.rel.debug_line.debug_str.comment.rel.debug_frame.gnu.attributesñÿ     Xhello.cmain__gnu_local_gpputs$ ( ,     ! ( / 6 = D K Y ` g n { € †• £ + @` @ (% + 0p 9*p¸LÐ H @HQð_ðkp¸g @P¨ wp¸\‰p … @øœp4:˜ @¨p0nù³0gÀpˆ4¼ @Íõÿÿo¼ÌݬP ü"go-relocation-test-gcc493-mips64le.obj000077500000000000000000000101001356504100700352670ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/elf/testdataELFÀ  @@Ðÿ½g(¿ÿ ¾ÿ¼ÿ-ð <-à™œg-€Åÿ ¯‚ßDd‚ß-È@ ø -èÀ(¿ß ¾ß¼ß0½gà(4òÐøÿÿÿ0hello, world¶dintrdœ³W‘\³‘Pl% $ > $ >  I.?: ; '@–B: ; I,d:û hello.c 0uunsigned intlong unsigned intGNU C 4.9.3 -mel -mabi=64 -mllsc -mno-shared -g -fstack-protector-strongcharunsigned charmainlong int/tmpargcshort unsigned intsigned charshort inthello.csizetypeargvGCC: (Gentoo 4.9.3 p1.2, pie-0.6.3) 4.9.3 ÿÿÿÿ| ,dD0LŸžœD x PÜÞßAgnu.symtab.strtab.shstrtab.rela.text.data.bss.MIPS.options.MIPS.abiflags.rela.pdr.mdebug.abi64.rodata.rela.debug_info.debug_abbrev.rela.debug_aranges.rela.debug_line.debug_str.comment.rela.debug_frame.gnu.attributesñÿ     dhello.cmainputs0 4 8 @%  ¼ ‰) 0  7 m> “E L ¦S ²a €h Äu hz {€— Ž¥ Í+  @p@Ø&°,°1 p°(?*pØSð N@hXfsp ºn@€È pÚ\’p60@H 0¦pf>¡@x ²p0¤Ò½0v+Ëp¨@Æ@ 0Øõÿÿoèøèàà Àgo-relocation-test-gcc5-ppc.obj000077500000000000000000000044641356504100700342530ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/elf/testdataELFì4(”!ÿà|¦$“á|? xŸ = 8iH`9 € |¦ƒëÿü}a[xN€ hello, world ÿÿÿÿ|A 4D  AŸ ( ß ‰GNU C11 5.0.0 20150116 (experimental) -Asystem=linux -Asystem=unix -Asystem=posix -g go-relocation-test-gcc5-ppc.c/tmpDunsigned intunsigned charshort unsigned intlong unsigned intsigned charshort intintlong long intlong long unsigned intlong intsizetypeIcharmainDœ†argcù‘hargv†‘lC% $ >  I.?: ; '@–B: ; ID]5öò go-relocation-test-gcc5-ppc.cGCC: (GNU) 5.0.0 20150116 (experimental).symtab.strtab.shstrtab.rela.text.data.bss.rodata.rela.debug_frame.rela.debug_info.debug_abbrev.rela.debug_aranges.rela.debug_line.debug_str.comment.note.GNU-stackÿñ   D$go-relocation-test-gcc5-ppc.cmainputs"$ … YBJR(ZD 4D@8$ &x,x1x >ˆH9@\ PÐK@t0 \]Qo® j@¤  ƒÎa~@¼0  /š0/*£YY³   )go-relocation-test-gcc531-s390x.obj000077500000000000000000000074301356504100700345170ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/elf/testdataELF Ø@@ë¿ðX$ãðÿPÿq¹¿¹ã0° $P°¬À Àåã@± 뿱ôhello, world¸ :intr:œµW‘Ü~µ‘Ð~l% $ > $ >  I.?: ; '@–B: ; I,:8û hello.c É»unsigned intlong unsigned intcharunsigned charmainlong int/tmpargcshort unsigned intsigned charGNU C11 5.3.1 20160316 -march=zEC12 -m64 -mzarch -g -fstack-protector-strongshort inthello.csizetypeargvGCC: (Ubuntu 5.3.1-12ubuntu1) 5.3.1 20160316zRx  ,:F‹ ŒŽFÐD hÏÎÍÌË  ÿñ    i À @! ( $/ J6 = ]D ¶K 7R ÈY ` 2h Eo Ñw:|hello.c.LASF11.LASF12.LASF13.LASF0.LASF1.LASF2.LASF3.LASF4.LASF5.LASF6.LASF7.LASF8.LASF14.LASF9.LASF10mainputs & ) 07>ELSahuz€—¦+ .symtab.strtab.shstrtab.rela.text.data.bss.rodata.rela.debug_info.debug_abbrev.rela.debug_aranges.rela.debug_line.debug_str.comment.note.GNU-stack.rela.eh_frame @@@Ð0&€,€1€>޼9@ÈJJ\]¦0X@È0 qÖ<l@ø }0Öˆ0è.‘¦H¡@  (°`è Hgo-relocation-test-gcc540-mips.obj000077500000000000000000000057701356504100700346060ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/elf/testdataELFÀP4('½ÿ௿¯¾ ð%<'œ¯¼¯Ä ¯Å$<$D‚@È% ø %Ü %Àè%¿¾'½ à % %ò4 Àÿÿÿü hello, world¹D üÉ\­Óæòint-Àx¨»\¶ÎO‘ ¶‘r% $ > $ >  I.? : ; ' @–B : ; I  HŽ HT T\\6û hello.c$­long long intunsigned intlong unsigned intlong long unsigned intGNU C11 5.4.0 20160609 -meb -mips32 -mtune=mips32r2 -mfpxx -mllsc -mno-shared -mabi=32 -g -gdwarf-2charunsigned charmainlong int/tmpargcshort unsigned intsigned charshort inthello.csizetypeargvGCC: (Debian 5.4.0-4) 5.4.0 20160609 ÿÿÿÿ|  \D HŸžD x LÞßAgnuÿñ     \hello.cmain__gnu_local_gpputs$ ( , 4%   ! ( / 6 = D K Y ` g n {  ˆŒš ¨ + .symtab.strtab.shstrtab.rel.text.data.bss.reginfo.MIPS.abiflags.rel.pdr.mdebug.abi32.rodata.rel.debug_info.debug_abbrev.debug_loc.rel.debug_aranges.rel.debug_line.debug_str.comment.rel.debug_frame.gnu.attributes@` @¸0% + 0p 9p*¸LÐ H @èQð_ðkp½g @ðÀ wp½\…pD”p]  @°§p}:£ @À³p0·¾0É&Ëpð4Ç @ÈØoÿÿõ$Øè4` ”"go-relocation-test-gcc620-sparc64.obj000077500000000000000000000135001356504100700351050ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/elf/testdataELF+@@ã¿P‚òw¨‡Â'¨`@Ïàhello, worldB ,Ø8intƒi„i••Øñ òb ÷ ø ù ú û( ü0 ý8 þ@ H P X V` \h bp  bt px F€ T‚ bƒ rˆ !{ )˜ *  +¨ ,° .-¸ /bÀ 1xÄ –œV V ž\ ¢b%¡ •r † •ˆ †;ˆ<ˆ=ˆœ±ª\«\¬\b ·óèó,œ?b‘€?‘ˆ% : ; I$ > $ >   I&I : ;  : ; I8 : ;I8 : ; I !I/ <4: ;I?<4: ; I?<!.?: ; '@–B: ; I,,϶û /usr/lib/gcc/sparc64-linux-gnu/6/include/usr/include/sparc64-linux-gnu/bits/usr/includehello.cstddef.htypes.hlibio.hstdio.hsys_errlist.h KK_IO_buf_end_old_offsetsys_nerr_IO_save_endshort intsize_tsizetype_offset_IO_write_ptr_flags_IO_buf_base_markers_IO_read_endstderr_locklong intGNU C11 6.2.0 20160914 -mcpu=v9 -g -fstack-protector-strong_cur_column_IO_2_1_stderr__IO_FILE_plus_posargv_sbuf_IO_FILEunsigned charargcsigned char_IO_2_1_stdin_unsigned int_IO_marker_shortbuf_IO_write_base_unused2_IO_read_ptrshort unsigned intcharmain_next__pad1__pad2__pad3__pad4__pad5long unsigned int_IO_write_end__off64_t_IO_2_1_stdout___off_t_chain_IO_backup_basestdin_flags2_mode_IO_read_base_vtable_offset_IO_save_basesys_errlist_filenohello.cstdout/tmp_IO_lock_tGCC: (Debian 6.2.0-4+sparc64) 6.2.0 20160914ÿÿÿÿx ÿ,A-  ÿñ    ,hello.cmainputs   ž „ “6) . 8; ØB I ’P KW 0^ .l •q | ø‰ ?˜ ¥¢ ® ^º …Æ {Ò EÞ mê Pö ê e  b' !4 !A rN [ |h 7u  ‚ Ú Sœ c© ¶ Hà µÐ ¼Ý Ãê Ê÷ Ñ ? | ˜& X2 ¯> J ‰ öŽ <š ¦ æ½ 1È ŒÓ ˆÞ ù p ª 6! +0  6Ã6  6.symtab.strtab.shstrtab.rela.text.data.bss.rodata.rela.debug_info.debug_abbrev.rela.debug_aranges.rela.debug_line.debug_str.comment.note.GNU-stack.rela.debug_frame @,@ XH&l,l1p >}F9@  0JÃñ]´0X@Ð0 qäÓl@ }0·£ˆ0Z.‘ˆ¦ˆ8¡@0H³À€  @go-relocation-test-gcc720-riscv64.obj000077500000000000000000000225501356504100700351310ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/elf/testdataELFóè@@ì"誇#0´þ#&ôþ·…—ç€â`Bda‚€hello, world› Ø8intŒiiŽŽØñ] òb# ÷ˆ# øˆ# ùˆ# úˆ# ûˆ#( üˆ#0 ýˆ#8 þˆ#@ ˆ#H ˆ#P ˆ#X ›#` ¡#h b#p  b#t p#x F#€ T#‚ §#ƒ ·#ˆ !{# )†#˜ *†#  +†#¨ ,†#° .-#¸ /b#À 1½#Ä –œ› ›# ž¡# ¢b#dš Ž· 8] ŽÍ 8;Í<Í=Í•ý‡¡ˆ¡‰¡b G<G˜b‘l˜‘`ˆ% : ; I$ > $ >   I&I : ;  : ; I8 : ;I8 : ; I !I/ < 4: ;I? < 4: ; I? < !.? : ; ' @–B : ; I rr xr, æû /scratch/riscv/lib/gcc/riscv64-unknown-linux-gnu/7.2.0/include/scratch/riscv/sysroot/usr/include/bits/scratch/riscv/sysroot/usr/includehello.cstddef.htypes.hlibio.hstdio.hsys_errlist.h    _IO_buf_end_old_offsetsys_nerr_IO_save_endshort intsize_t_offsetGNU C11 7.2.0 -march=rv64imafdc -mabi=lp64d -g -gdwarf-2_IO_write_ptr_flags_IO_buf_base_markers_IO_read_endstderr_locklong int_cur_column_IO_2_1_stderr__IO_FILE_plus_posargv_sbuf_IO_FILEunsigned charargcsigned char_IO_2_1_stdin_unsigned int_IO_marker_shortbuf_IO_write_base_unused2_IO_read_ptrshort unsigned intcharmain_next__pad1__pad2__pad3__pad4__pad5long unsigned int_IO_write_end__off64_t_IO_2_1_stdout___off_t_chain_IO_backup_basestdin_flags2_mode_IO_read_base_vtable_offset_IO_save_basesys_errlist_filenohello.cstdout/tmp_IO_lock_tGCC: (GNU) 7.2.0 ÿÿÿÿ| ,B DˆB ^ÁBÈB ñÿ     " & ,    , #G+x3‡;C,L Z8aÌho†v?}$„.‹Å’™ì ™¨°ޏyÀ«È9ÐaØ€àÞè•ðøV!¢ p(+0 8Î@GHWP¿X?`©h°p·x¾€Åˆ3p˜Œ L¨£°¸øÀêÈ0ÐöØÚà%è€ð¸ødž, #+ý3:A*HV,[hello.c.L0 .LC0.Ldebug_abbrev0.LASF55.LASF56.LASF57.Ltext0.Letext0.Ldebug_line0.LASF7.LASF0.LASF1.LASF2.LASF3.LASF4.LASF5.LASF6.LASF8.LASF9.LASF10.LASF40.LASF11.LASF12.LASF13.LASF14.LASF15.LASF16.LASF17.LASF18.LASF19.LASF20.LASF21.LASF22.LASF23.LASF24.LASF25.LASF26.LASF27.LASF28.LASF29.LASF30.LASF31.LASF32.LASF33.LASF34.LASF35.LASF36.LASF37.LASF38.LASF39.LASF58.LASF41.LASF42.LASF43.LASF44.LASF59.LASF45.LASF46.LASF47.LASF48.LASF49.LASF50.LASF51.LASF52.LASF60.LFB0.LFE0.LLST0.LASF53.LASF54.LCFI0.LCFI1.LCFI2.Ldebug_info0mainputs33a3 !).;BI P!W"^#l$q%|&‘'›(§)µ*Ã+Ñ,ß-í.û/ 01%243C4R5a6p78Ž9:­;½<Í=Ý>í?ý@ AB-C=DME^FeGqHIJÎKÔLâMðN OP#Q0RMS[TbUjVrW|XŠY$U($Z($Z($[(($[((0$\0(<$\<(D$VD(]$(óÿ" ÿ&" & " &  $ (45 44.symtab.strtab.shstrtab.rela.text.data.bss.rodata.rela.debug_info.debug_abbrev.rela.debug_loc.rela.debug_aranges.rela.debug_line.debug_str.comment.rela.debug_frame @,@(&l,l1p >}Ÿ9@¸`Jñ] `X@€ mm0h@˜` |@ø¨ 0«—˜0B ¦X @¡@ ˜ 0 ` È`0³google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/elf/testdata/hello-world-core.gz000077500000000000000000000306061356504100700322350ustar00rootroot00000000000000‹ì |EúÇ7ii‹x°@ymÐR@¥-¯9`9TXµ)´Ðjmc_¤ ˆ€J,`(Þ‰‚šSTNô¬/ü¯ÞŸ“ jÁS/¢" ø ˜"h=@‹"ùïf~Óf—MÒ–Ñ{~wõË33ÏÌ3³³ï›ÝÅcÓÆéu:+R)Ô[‚ çJR…öuå™j#4 Jz!F;]n£•üC¨–ò õ~‘Št1dù@¿(ùF¤îç3é¶²èôÅqš»ã'ú¹ŸÕö«‰?Ç/2ÐÏõŽÒOTQÝ?+/X¥ô3ª¨ösð|•ŸYEõ¸xn­ÒîŸQ¯Ý÷3x•~)*ªý YKuƒýüã)ÂÏ¡ò 7_ÌðsV7n<­ð3>r·O§^Iõx:±"ÙžTú…›Ÿ|´ød…ók…®Éþc¦L+§®ÂZ«³)_ÝQÏæVEâ£þ>;#E¿mëÀæ”å2Æq²ËÕŽ}0‡ÎúªÛ8©ç äô>êO›×ŸÓ›Åq•ºþНûò/ØXò1¦!3õÑÁþÔc›™TPRPgR²?ÅØð(BKŽ-EÇæ*­ÏÄÜãSÆ÷Ó×[eFñ|dð}@È猈þÔ€6eµ£y}Øv¨w¼Ÿm`{ÑÐ¥*ûw*»­Ê¿ ø×~lycK,ÔLav;د#_-ôþÿ×áâ ûA›TyÀZyÑ(Y%­2aØ­äuD”æ€^ši&OŸ!Мø­):|…ô-‰D"Ÿ«Îÿõ8ÿçÇ\"Ò÷<Éçÿ­¥ÿ¥#&y)ž–Š Ö¢jN~Œ¿TlSõ¢‚ÝQŽS@~É[ ¤ gNõyY-k{ˆ öEWë•~zøp0iè)*èF`nUÿ"ñ—ŽúÒÑ/ÎëPò²Ì‡‹³äwGüÝ£E¯F¹«U~S%¿ºãóFhü‚K â¯#ü’órgœœ—Õ?/7¿¤´iêÐþC'$ ôÇ$Ÿ<$ã'O÷—ç㇘c6äü—?]òUîɘý«§=4âÀ×?Œ^,^¹Îé݃¤' õ§è$}fô¢ é¼ìâ"a|Ú„?ŒÉ˜40iˆ Ìy† ò¿3ŠŠ3 ‹3îÈÌÍ—RæÝQ” !cBúõYÙ…Ùór‹Š³ Ó¯“WŸž9;/›åiçL¼+c2Æäee±q‰®;)¤Wƒè¤ÿÉcÅÏïJºæ¶–ËÎO¼è§œ¦8|Åu³hAy\ƒié±ïÿ?ÞŠÙ.7¹§›ôßÞ ¥ÿ:$ùzËvŽ\´Ú#Ÿ´÷.”m¹Šj·d8>Áþá­&ûAÓÒC5æô U.K”(˜ª¶¹[ɨzA‚÷ïRÁ“sr[¦²V­¥ L÷¹Šõ>·¿Ñ¹’’ÚÅ/óÇSÙG tº©¿Q‚iim[“ýð|ý-Û+ý±JN'oÙ*gù<íâmþòÆ€òÛj#¤ò&û›¦mGG™tn“ýÓ‡gK$ÿ0ÿ]uþáoñzWyˆÛO—<½‹¤@oy§Õ³R’îÄövñr #¬ò:QÜ­.„öÓ·ÊkŸTÞç¾¥zäR}—ôŸ¹¹ ©Óʱ>“½Êë>ëóíôw¯¾&{^ž4{V‚Ç´²²TsÚÊÞFRº7Í^œP“f_˜Pk²ßœ αԴ~‡GÛž`ÿÞ´íçˆ öO½“¤JM÷/î>`¯_šýÇ4û÷×Ù¿í‹ÝgZº]göuÉQSÙÍ ÒPç%ÒʲâÒ¤ÓÊŠú¦•-LH‘F=u;úb;– [üÒÜ`³&–ÏÅ{¦ ºRƒ®Û¥Ñ1[å¿X©Çä£Ûî×ù]ÔT©€d&H¿—þâ¤|»œ?uE«û£2ÚŠK£Ò¯ŠX©ŸÑ6õË×%lR¹Ày*û/”þJöùü— ÛƵ›Ø®Íü›0ªëð+%Ô]^Òu‹>Cò÷oÇ¥òKÿvHÃS,ñ5‰K¼NúÛâ»ÏâH$‰D .‹tü$Ëòc=/Žÿø¾“ßVã§)8?äûñhãÏÏâÀÖ*»#èz…Ý£áÇ kõÌ¿ª Û[û8½åÄÏW½gÛ;ü´ýy%ã’òFÝã"‘H$‰D"‘H$‰ôëÑ]‘‚08JâjúabnœX"á±Èz»\Ê;r·¡\¥T¦+ÒžH$‰tK4°ßØ&1:f×ÃåŒæ¿ÿ…]¯dL­ °…ÑóOFÃŒ"X:Þ…½•±´¸Kcõ¶â6øÁß Ûü&Ê ç_ŒnØÂvÄ Z@è®B=Ö°8vªâ}WY¯ZÆØ§CÞ7pí‚ÿGðÿ˜Ñõ £q7òw+ë?ÉíOQ´€Å íSí¸¸äÃùkÝS¬‹ÒLîÊúaÜ©ü½¿vòEU>?Ì™…|‹*ŸßçÉD¾M•ÏõegíqÑ¥o烀O‚¯€ï_‚§ÀÖ=Sg2v‡= Nç‹Á2ðð5ð-ð#ð¨ï‰qA{`÷ƒiàL°\Úàÿ ìà›à' ÔÅ£ÜLå¸vDz 8ÌKÁÀ?ÿOQFÆ^`2˜ ^oTÆñGØàRðOàÓàðs°Ôõbì ö‡€SA XÞº1.å°_ßk‘oü#£ Ìׂ.°<ÿ“`ßYŒ—£>ЄôÜ3À»ÁÕ`Ê¿{-ìw`ï+‘î#=ê Æ˜›±üÁàrЈrC@8œ .Ÿ_ß«Áè¬g`p48œÞ®ÿþ/¸ ÜVܬœWÁtå#{c{öÃÁ±à­`6¸\Õ[¹žn€]þX~ ~~ þ¶IÄr‡€×ƒsÁ…àÃàÓ`øFbÃÆ…ÄôÆk¸üÜ zÀÃ`5xüøxÔõaÁ(° Øì v{‰àU` 8ŽÇ‚A3xxSš‘e={>ĹŽÑõ£ t‚æÇ+ûu?ObÝ:~ÇkGÿ~­²þ˜áÌ>‹òaóãò®Ã•å“aŸAùÁ°ùq¾yeónÆ£þƒä®ìcµþÏ.°4LÜÆÇÙú zÀPèõxHk–ïNdtÒk`{µë1Ldé6£a£t"ÝaÒö·Ý¿Àé(Û:•1%þfF3Òø;¦i×o)„¿ý(@;°E°Âªíï¸ã°ý¼W›–ÿÑö7/béFPXˆñFyãÂÐþŽ5LJl÷Ÿ‘¾&ôòÖ¡¿ ùqŒÇzp]hó hçyÄ ÚÀšM¿çµëqmF¼¯b9 ùžWµýGÑþøÕ¦Á¤Õhù¨ÇÛ}$´Ê7(íÖïPl÷ñ þ†'X:XZÀ”vŒ"h t‚j¹;²tèݱ¨·êmH7À6s¿Xíú=³Q~üA! 6èÊÒö7䡟V´süî€]‚x ÑÎmÊz<Ÿk_oá*»Œm-ÿ^©()Iæ:ä[?ÒÎߌ|ãgÚùU<¿v~5òÅu¾Î'í4òkÎàz$âÔE1ÿ.¸þæ¾d•Â_¯gùýoë°JU¿Þ¿‹œˆ|ÏAeýRûþCˆYÈ¿:'>þÝÜ¿›vûÞþÚíWä¯ ¹|ZZ—$7n/ï§åŽóý¹í\‡<¤¼iûBe }’Ë…ë™—ìÁuOÏEÄa< ]£ ùé /¿*••ß:ç̓‹®d܄뒥qžÔqfGÆ”¯ÓÓŠ8ħ™}ì\'mg€0´‚¥  lî8ùï€Aþ®§Áàp(x ÈßY4 œ„ؾÃõë(vÙ8€Ñ2î)Åø\÷lÃæ•ˆyâÙå A×>\÷й÷@Ïçð øÒ÷hÏ¿¦Ì™°?ÀxïwƒŸƒ_€Á#àQð;°pþp xؼì^&ƒƒÀkÀáà(p 8œNogYàmªú­` xx/X®׃πÁM  Ü î¿l$¹¸½ë×Zp#X î÷€^°ŒÝ€þb>;ÀJ0ùØi°oóÀ…à p=ø¸|ÜÏ€1Ï1ö/Åö'áeý¿‡m³¸ ¿Rp-èm¼Ћtq#¶3 Ì{¶aüËãÚ-)þM„öAðÊæËïŸhoÿë´Ç7_F×QFñ0ìCÊã Ê{@‹—ÑXÍèÔcûV¹¿áû¾ýhiSS·_üwdqÏžqÚëÓ9ãÝLí'ÁnìúÍ™w~ŒÕ4¿æŽ£±,éÃÆmë§ü‹Pmû]]°åØÔåǧxbˆö¸$©üš»}~½ª:¼+H;M­Ÿ?˜d¹csµÏ—¹öú¦­MW­óݾ 3~-Õ>¿þy0L;M­Ÿ¿;fêÝåT ÎBz.8¼O5kÂŒÏ#È_–®~JÑŸ¦ÆYÃ]ZTÆrœG¬yªAóÁ9–=§ã‰q0?‘Ù) s £…Û£ãc]€ú*ž2•Q S•匰›*q7»oâÉ[­ÿǸ¯ô£qoyƒâwï+¿ ñ ¨wÚMÒW¼rüEåŠø==àÚ²Y¾»±LŸ äñ›AKcûÓÄø]Ö4(~à Œòa[ïcùâ ÆÅïì߼ׇ /àþåMˆk¦²ÿ®YÚëg¦öüsm*oÒúÓÔåçIG=¯–7KüM]ÿ›¿Ëƒñú€ÑÛƒí‚p@{ý7)c×ÿóßxà×?_ÿ]5X½Êøùö·â4îçc}­8©ŒßØqž@ú{¡×ìÆ®ÿáâ·^ økZ(~ÏѦÅÏ·¿zügšwþ§ ¾ =ÿùþOˆ ½ÿ«¸ v{åö“ÏŸ†îÿš{þóø­ñ¡ã÷tD|=µã¯iß°ø›{þ7ôøƒÏÿó=þh®ñçûßæ:~¸Ðû_éôÇ_:?‰gƒÜÿSK'ÔK%òÜìF·ÏÛåq¨ï/ªÅÛåq4T™y¹™þ¤Bâö;ìâœìÂúdÁ€ôy…%ÖÛl–žSPTP\ð =7?·ØïƒLGKÏÏ.VTeœS—>¿ ðöºªjP5³¨h~V}ýž^XP\0§ ;¸xzÉì¼Ü9·gßôÔ_h£¤eÞ•;§~ ܨ§('3«`~}qçì ßñáýÆü·´Yÿ«šÿ#Ùó|îa‡{î*ežÛ­xÉ–­¬ï!ÜæßÙ›¿oÌË®Èð÷‡Æ÷“¿?Œ_O©ûfÊ*ö½(þ>³Ê%ì»SüºR­}…ßæ×!7naùü}h¶›ÕïO«—/[Îü:Q :¢~Ÿß›û¶~òôå§Xûü½g¦RFõûÝÎà}gk Y?ÃæíôTõŸ¿/mF +¯~_¿ZéÖþiØ/žÏF)„\ø–P-¨Þö˜âØ8º±Þ¯ÂïÈžÄ}aä;à/f1;eû½—·ìöŒfä/‚oá»S”[ÁX‰újn…Ös#¯ÿ ægÄú,¾„ý$ât£>!¿Ã|8†z]똿v%üDÄ™ ZÐnÚ1ó| ê¿JÙòݰSP΀8„hÆh×Û€zrОýŽùs>}QŸã \Éž[uñçXQ/OÊÛôÊížËmÊíAÿKQΚÁ®_ÕêÐ>òmˆ¯íÄ¢~¾œkx¹ÍØn!Æß…üh߉åÍ÷+ Ѿ9Š]ÿë‹ñ4`œ¼ëñ­+ô-ÿV‰ ØvȵLù^ÀïóÙúUÀØ LÝËñ¨Oúí‘>:<̖œ3ñÉ ÛéÀï㨿í%†Y?e×—‡u|ôË-ÏtzCñ¼žSu#ŸÐ<¹ÕŠÈÌÎQæSï¼}ÙÕö.·½ôÈmö¡§M{Ó—Ùc£>ô]³ÞW¶9òÎ3'<¸úßKW\ÓúÎ UÓþ:²ßJÝö)ñoܹw{÷ɯ ;=yCí˶²´¾ÛwÙ?ië‡ÅWvv›ôMõW[2fôí³nøüí7Nù¼aÂ?׫פv½k¤úÓC:ë÷P\ꯄɷ©²E¡Aù£„úc9wÀ»'Ôƒ¥õk%ÂoO/µ˜´â‘ûÈ¿ ³Òä‘"(‡Lí¯µÄCÍ‚ªR×§¶ùqøño­óåÏ—7Ïw]ÉòÕéblèøƒÉò=[®Ë.Pÿø7äùŸíÄ•ï'zg7CË$Ò//zï(‰D"ýWJ ’îZV­¸ïÏm‰D"‘H$‰D"‘H$‰D"‘H$‰D"‘HŸÌVv_ÿ‹Á;÷÷]W0»S#ës©ïSÔ×µ‘õÕ©ï?¨¯U#ëãR×W‹úZ7±>‰D"‘H$‰D"‘H$‰Ôx%çåÎN.Mš1tpÿ¼Üü’ÒþÿÏÞ¹ÇU^wüZX8<äB‚!ÂŒ‘vW»z]uaeiõ@¯EF±¼Ú]í®÷é}H+áALmó˜Q %h˜61m†zHC  f –Û¦qfJÇ3LÌ$iMC'ê00n¡¨÷~ßùö>¼+Y $Pþ¿ùιç{ßûÝÝ«Õ:ϪA_u:Q]'I3²çvsô÷I®÷_gzæYîçŽr5ÿý’õÑ夸.’?Kz„tžÔJy.Ré :~Št—¨—ð˜ü•(ÿ p~…)ž4Õ;S¤™"õ æèø,i’tW‘ró+Ôw®ù˜êù´0Góï¢ós汇™®—®.˜¿Åt>ž~žû¡¸^®ÄÞY+IKŠ^¬ü,ÜÇë]x€kò‰óå7¹Š÷+÷æC,oX´Gý;ã§ï[8ñ]~=ýpù¿÷+%Ýx®³Æü5e\w‘£p?]¿þ;†Ë‹7ͰþâACyq}çãÇøü‹z’Eêñ|ÛíM\¹¬5åw˜ú-Êév$FÁ}K—%ú+ö)ó8D\œÅòW:~®´­u1Í^f¿é'µ¼|ßÓìûÞË>gžºUñÝSü<ýHño˜â£ÿ¦)¾›â÷ÿÌwÁrñ4_æõñÕrû䱂çÉÅÍçC”âæuœ ¸¹ÿÀ'‰k??Z1lÅ÷ÅëÎ[+½¸•cþM9=èš§çUâaŒŸ´D2>o»GIX«>_|ÿ·¯.×Ö!üù«î}n·Kø3ü¹xïI-ðñy¹J£äßOþe\=OpM>Ãuöo¹.~“ë‘7 >G4OëQúžK1æõ/ÿYY{‰Væòg ’X<笸—÷_d…è9—˜ï]t|qi)¡ú¯Óñ?†ÿªMôÿ ¤_1> ™|óú ŽùžÐÜ¿˜üFjý òÛvÓ/“_fê×â~~¿û!Ÿ·Ã©c†Ïu—Mp_ÌóLú=Gçì]ciþáãŸXêYÒËHב^NzzŠ×/â¡÷E¿g¨=ñH´÷­û<ü_òÅ8Äy±Ÿž3ý7ùbÞ>n:¾ÃÇ=,ž“ÎüðQÃzwT_W°¼õ%žçú+®³t½Íý„û3/3âù´Xï•~¯€ÿgŸuнž9××9ÅòJMþ<ùç†÷3wæ_Óû±òô~2ɵ¡Äŋ׋‚bŸ'Øu¤ðë·ÓTþ$iŽô1ÒäŸæº…´ô(_øNáúÍý[‰3EòËž6ƇMy¡U¶SŒaj§ãéÂõåŠÄWKècªçÓÂAšWÒøÜc]ñ"™}è­üûÆ ¿Ô÷pGéýåIÒËÒZ;›–©O¼oËCýïo^*öä÷ÀjÞ3•gx¿Íßë~òàGûü…@¼Ï™7¦Ï9´ßZI<¾`xž‘_;ëiúˆçwâói..7æÍn=ûù—‘ Mþù«;>c:ì’Vu\Ü_æŠÜ7V¢ÙtÝ­t?}ê%ãN±Ò÷ |o›±FW°ÈÿÿôY¡ÂØÿò ¦ñ”›üÅÛ?‘G. çøÿ ©«ÄúÞùÊ‹—²ò’¥_½tM¡gÐêYy£òs·¤=ËåUÄ>ìŠ,ܧ/Øø>]~µ‹ùây´dªG0l:~ŠÊUŠzGÈŸ%õî"M’ΓΑ.Šz®1Öw®¸¨üŒ©?V³Oõ—“ºH+VÙn’òw}Äþ~T<¿çö>iNÐú¸hãœ+å*ž/›ã9Zx=©ËÓ_Ð'és¼§HHÕœ«¤âÏû}Öç¹}׎uÔßsüœ¸ëž·R¾¹?s+|N|%N•¸V‘}îœÙÄë-+1ÆÍûÇçÍ$MçéYk6c™Vïb?Îíç¿/¯GE½gíÏ/ŸÛ눊§èïH]O-_î(µ¿°¿ðïírEâŸVNSO~Âýö¬0¯ŸU\3Æy+•.a:wÔøÿb*r>V< íÇ…þÂA¿/Þr¯ÖÎrßeuÖï“©?`T±¿ZT¸_b?>ñ£åóVçñwvæ>•½²ü~ÄÿFgŸN¨Ÿc“†)_ü^YøbþFÈ_gò™hšþüÇÂôüM|ßšøž4ñýfŸ7v¼ylÝà=c…ž/3qUpž0\M\ç¸Î<Æõ̯)NåÖ~Œ]û42·ÿ-6ÿò7mY0¬Ç¤¤kŠÔsbÓãSKJ¹C×óò"ožêÇÿruëýŒ±?N=dðï{—×7³‘k]éõ,¾ë*Þž_ÿZïÏóoåË«}t]ÍóĺŸojÿ½ÍÇ=,·Œû¿»Èa˜‡ÿ¼·p¿O>Cç]9ùqÝSú¬¾Çß8^©êÛ‹Q¾ÜèŽ?eþä/vÜXlNôˆq¦q‰óu×÷ÿÄó–a¾þâ=ãüÏ]ËÇ_Œ ½Æ ’¤Ö³¾H9uäww[Éí¬Y+ÝÌ*˜ÙXÂó(¾ñ í:uI J½.©RºŽ­Çyº<³ZKŒZ–oG’J•ŸòÖÌ7ëU”'´\7ÆüQ€³÷•Š|9vî´S¼½É 3·q÷ÌS’¡\ •sÝÍ˹în2è)š:¡b|¥ô“¤q›µU2j)é:a駘‡$©ð=¿ÉøÕr7Ñü™5’ *Ú»M)g¾¦–CŒ¯ŸÚ“®ççç ©ØOùýà:~|ÿú…‚û‹8çŽòòºîÿ7ÕﺔçÏßÂUÖÕ·¤À ZË[ç*JÖìº÷iŸ5µ·HqÑŽ¸çQ{‹ßÚ«úÏýÏÝÇóE{ÖJc{¹—dy‡I%:.ú}ò wC¥ñúˆ·'æé'ùõ~æÏ/Ï3ì÷•Ñ>øþë,îz—KŠö¨ß¢^­Ã™g¹oÿ¢q¾EÞ—~þkÞùpI”ˆýKG«š'Iÿò“ÙKh>(úçÊ['æZOã=´gŠ]Ææó¡Øú<ÖþmÃúˆùUÏnvÿºÞ¸>óO×gŽŽ‹óààßñ¸y¼e×§™Æ/ÖçH‰6j_IcÖôã/ßÌÛýõZ).îæõy…ÖG_î¯_2Žo†ê=AêÚÇû[&ýSǧÖ9b_³n½ÕãÊŒë'Ê/R;Õ½Î÷ôýÞu)¿´1YÇaþ¨üÓ:Ï^«Œi­¶§_|ÐÔáR£;¿îÙýwº÷­šBþ•äÿñÁZiD?Fã˜+åãþà–G ã8cyÔg.w³Ë˜ÿâ×1¬ç Sýóçq=rCáûzìÛÊÕå©sö}*Ÿ¯ÿ5éß•|²GÔ_¬Þ¯Íÿç_ <â5Ïñ3÷Ø Æ æQý¢Ýb¯'‹µwœâ‡).îߢžWn6æ¿FþIÒ o¡r¤U¤_%=Dú$é?‘¾Mú.é—Ü\=¤ûI@úÜ­\ß$µuqÝIš%mèæÚC:Eú éß“þ+醺.H{H¤÷’&ýÒWINúÒ ½\7‘Þ@ê"í$ýKÒÿ!½²ë6ÒÒÛIGI§HŸ$}™ô Ò_ö×ëZaÌð}T¼þXzÿ·¯ªš-AÄõî'ûº‹^!ŠË»Tìâ}Í:Q_òXÁýLä‰óQì3§©¡ MþE&ÿb“¹©þ+HŸÝÊçáòi^.!ÿÅ­E^§ÿôƒM‡þëí¥¥™wöýé §Çr u£uމðÿ€j‹·:‘ÍH£ÍíîÞÁQOg«Ófo°Iížv uö¶õ9-©lÜ’MRÿ¸Ï L¥Âñ`ÕÄp{oÏLe«l“:ÜÝÝNËX8nó¦CÒ »¿Ç™ËR±*_"šHIíí£îξÞÑ–¾¾®N·³¡ÖQë«o´ÙÆÆ½þñú€¿Öçk¯µ6új}öÚ*›½Öa·7ÔÔÛ«ëê¬5jÄVßP[ÓØ`•{<­ýNK&–”îèìmí»Cé¾R¡ÝQo¯—Ú{ûzÜ£]î;û;{Û•özûûº—‰Ô>Ø5ÚÓ×:Ôíp&&©¨wª*íK%¢Ñ1oJp÷;•RR÷€R]w_ÿ€3•vZeØiµ5Ùr4ÎŒ:9rZ­r2ìtX›ìv9`ñZÙ/Œ1??ÔdµÉ>H1Û¦Úé¬Ó^ßäPŒ ÓnmrØeŸ—693ÉŒ9¡ÕHgX²CäX5òÕoŠÙ6ÕNçmoj·÷jñètHgǼZRTKÊä4{:œÔì¼µ#oùµ`PßLÞÔÕ56]£³µæŒ¶–“ÑâþÀXÞN%cy{·nü“:; ³Ó:;¥³½¾€6´D"oû’aÍ©×úÒÌÝÉ ­²j4'ÏÛc±dÞNŽÅ4;¨³“š zóvN—ŸÓçèêWlÍIƵN¤' ötމ钒¾œOLh¶nh1ýÐb5º¤ˆfOt}MèÆK:4Û¡oAçL$ÆòöžLÞŒgu Ä4Û›Ö†œŠéÌ ­šñ¨OËŸëâz[«3Í›~ÍÌù´–r“þ¼=¥ë™O7Ú@LË÷æt=Žçt³3¡³µ¸×«ôتî*ŠÍ›ãQ]<öëí°æD¼š´ël­p"ÌÛ)-}Ò;¡µ›óêÒ5;Ìåí\:9NŽa£÷4v8-‰TÐ2ž üt$“HZZÃ餲»öxãÞ ²Òép"n¥’̓çZÌ›±òÛ×Ð`Çè@_K×ò·ª4Ý–Zš=Ζ½º›ÓÞÛ+lV«¥¹w ³bX¹Ù8*&©LÖ­P“ÂqoTYÜÚçqßµÙ¿]îvs«UîïäV‹<äáV³<––Ç2ª³ƒS6yžUV¶E»d_TÕ‹±BáÍþ¦ÍþÙÇŠÙƒ¬œrÇØy«g¥[ädFNù³AVn<#nŸœV½zu÷qwÈÙ¤"=¬\4àÜÙ!E;Ûe_ʹ³Gg*äP‚5+Ç'u˯sg§VëÚjåå•ê&Qi«·ÊÞ˜œ‹Ë¹ ¹Û#§S¬n/ëw·ÜÜÍÚÍG—Ö %ûYRÜJI=²_íç]¹µ…G<¬X˜ Ü’afDåXXaµÞb ¸,?àèˆûfy‚•¹¥¦6*O°¸Ýâ<‘æ¾dži³:Cr&w¢r–å9br–Ek+ÍfÈc%Ó<¬x±1ÕªU ¶6ÅP'ä®zÅ`IЦY™–„2ÏIoeCnncumöÇäæí¬%ÕL$Y´±ÉѨćY¡ µú Ü®Ì¹Ú¥-ŠªµnÙÎŽ*WúˆÍaU¼Þññ`p÷îH$ÅâñD"™Ü³'•J§3™lvbbr2—›ššž¾ûî½{¿úÕ}ûª««ª¶m»é¦P¨³ÓÊ—8ÉFX–•ëUíSXŽXÙ˜¬ûäˆM±úûÕ#µ,»VÉ®cV½bÕ3«A±˜Õ¸—id¨ÖÜÄ,Û>¹ÍÆ'U±jø¬+–•jªá'F›ƒÜÛä¶Z2ûå¶:2ä6Þ^mS o§·Z¯úm¼/Ìnæ½QíȘó¹‹ ÌÍ;·_Ÿ‘6ªw»é'³Y¾‘õÁ®–¼±ž¢m¬\e ¹r%ëwšT)úÜ*ofg{ÝÌNŽ|?7‡)©EŽ„˜¹OvÙȈt°õP"õd°^ö²Ê”ÃloQ§m7êˆZY#«ŽªYލ'g?i"êùÙ§´£^Œ}­r$&K­î¶æ¡îÁÚ]³é”%ò¦– /·dDzñLVy=5îÍF3ÕIo&$‰m¼§¹Wy?ÐïŒ&|Þ¨%šõE¦d—úÊÛRÝÙâ®ÊÆÃ9‹Í‰YüxÃlƒW^‹·u¶*¯Ýœ–@ÆgÉùƒêOï€,bJºû<â^âäÇ%ÞûP"`{¼ò†Cfc‰†Ç”Ÿ`(ã ¥¬Ói-‘ùyW;À îæcAo,Ö—£@¾ý`‚';´ìai`ðN§½±ÞQ̤«jªÙ|I=n÷àg´ÙÓ©¾mqÖÛküµ‡Õî«sÔÕÛÇkëÊ?¾±Æú1ÉsG«n Ò)ŸÔ|Ç€2Q-ýîÁÑæ–eÆX%;rádàV¿õ¶VeBvoãXßtãp¿¯.»§3fµÆ-]Û¶gRÓ^©»¹·Ýˆ+wÒê¡Á¶ªIYñÖæÁ¾þ;—?[b޸ߛI¤¦øùÒÒ×ãéÜ!–ØÓß×Ö©Ü(iᆶõö¸{‡”#Ãw:•ó*/sñlu:!y”KᮑÀW¬M#Y×HH®™ñŽ|e$´edrkÅæ ©½µÇt.¨£Ö†;úímlTEp¯×/‘òª!ˆQCýhT¤g¯)…R.rôà¶pô°íi‰âõz÷ÊûåÝ{Ò*õZÂ¥bjô‡AhÔÄ‰Ñø£×ÔBˆF£?êWÂY£U“*}μݽ{·€ÆDnJoßÎÎÌÎÎîÜî¼î {k“{Km«kàvoÍêMžmn¿›Pˆ³ö‚PÕw›ÏUc:ëš |ÚG¼þ¿¿Íe>IJ‹»Ò¢Ýñ*øQbj8¤©âó{›ÝÐöñ) N¹Q665[l‰q2[]k‰gc 5#ŸÝO T]è:ëBq-‚“éR‘N=^µ»6ì¦Þ5áC«vépþ[[_[[£Ö‡k"õjZ³¦¾ÞY]×Z]ÝY¿¶Kušžêæ~—Náu– îƒÑ縎‰¶’ˆ‘[ýÛ75»öVd†ÓǸXo•q0d®›OSëvŸ{‡k]µƒóZ`14¡a1†·žÚHc£+ÜêÛž---ø"‚ÛßèëÖ†Ìî}þÖM®sõŽ ´ã™ÐßÒž–MG{H×¢ý1aÆðæK s¼UâœG‚.ñfÄïóä8Z敉€óåmâ¼mlàøŽ‹³¯]0o£>ˉrŽ< Æ'ʦ/à½A~qo°Ñ‹rž“‹R·XÎïÙ-·3zQ®çtë-ô"¯¡óµqzQŠ›tµ’ãÐQ}¼“(î ZÁn¡/àö(!gß1<›¯$£‡À!Ï5¤ŒTsû?Ãó<ð~ø%ä'C–± ~/ú¥Œ~'ŸÊ:Žß¾ˆá]œþ*._¦wŠ~9ý2NïâxYŽË—õ\)ð’ Þ‰÷Ãàww©šÖÝ« $¯öwEBC'µ‡tÒÓݧV!¾lNâkj´kuÜòòÓ“ý<÷îeK »G챌¡>ôÃö¥$kg„bËœú°_œÓ"»‰[JØœ{›ä©Ö6å5ï×ßòã'Ó«÷>ÑüþWE^Ûö†jÂÖÁ!PÃåP¢×íä!¬C_@yÊ3\¦©Ó}-Ä6Xn»bqIé(x×¹øW!{Iù¾‚ƲâÎEÓ@ânYËÇÕtæ\:ï£öDatÑäÆãnÆp¿å™ÉÄÄ‚˜¹rø f2Ä[XO¨ êÿ[[{Œ¾¹¬x31}óvW¦}kY±jêëúŠû²rÞR…­ñ-`uq¸ƒ·‹¯“»x)ä.çåÃèÇr–óÿÎë|™’y^Ÿ.Èõ¿ÿ ã a³|±ÛçÇàY9<¯>ù_÷>Ðä·]]c â¤ã_U$Sô¢ :ZX964hý‰=E4ybç$MNÌ-(+6˜ôî¶Všø¾LrùçéÓ,ÿìÙüsïdúõŒ^g¢Ý S6=|j£WVî7ÙŠñªù´¹d!2q†× s¦§ ”áŸQJ“¢¡öÍ¥tt uG6(ûÐuœ*+­"Ç6$&l¬eÏÔvläs j*Ã_þaÎTúZXq]Ê Xü#†2rVý”‘›@êø’¬ã‘sè˜&÷Yu<$éø&a:šöøk=GÚAÁt-è}ÎÏ X7±5=?‹J\[XùVW¾€Uåå úÑoéÏÅ×?äóœ&õÙä'OFÀaé¨>;úÀɹa°«óÃô+ {L´{,íÏü2–~Ûì8g}R°í°, Dƒ,L‚eWZ,‹6g¦-ɘ֛cÚé¬iðØÀé‡irœÚý¥¾Ñúð)fÝWLë‚~3hÔûI:Å÷|ç³M@?u M^Fßúà×Ö¯_|zªb[xŠþú?]BoÔËJ-F» $»Wá[ÙœJ0B}ýšJj4؃P8IJ5SB¨·ŽÊ‘îx8úPÖRõ°âYD0¦ô„Â*€qhê |†û{Í꿸Kà^(ö-±?VðsÛŽíÖs2Â%\†hûg‡È3æ¥Ó~±^niCûq”#Äþ+@ÎóÂ< ïüb¿æq>,8Oé€ßß-üb?Ÿå‘ï#ë/Ï %yÙxÕ×KôRš i$âœÈ 7°ºœ#óß*ñïçüû9ÿ¼D/ëagQ‘rùE»àùTÞ¿hñùã,¡—yþz%ýwsþÝœ¹D/ó?H,9ópþG8¿œ3.ó?)ñ‹¸T H/Ï­’ƒœ¿Z‹xTþÏä\c«í¬ð:çþoôÿ¿}/ÕAð¨6y<yÈÃàÿGóþŸ‡<\˜þ¿Ú–÷ÿ<ä!yÈC.(øÈ_káÀgoogle-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/elf/testdata/hello.c000077500000000000000000000001251356504100700277550ustar00rootroot00000000000000#include void main(int argc, char *argv[]) { printf("hello, world\n"); } zdebug-test-gcc484-x86-64.obj000077500000000000000000000062201356504100700332260ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/elf/testdataELF>`@@UH‰åHƒì‰}üH‰uð¿èÉÃhello, worldZLIBºxœÛÆÀÀÀÂŒ L i$6;˜bäSL T "È ¢˜YX3óJ€X‘ô±p!‚%YЭaœ³H²A$ÃAÊ'æ@y›Á¼ 19 é}#ZLIB\xœcdTåæfæ“ædbg``Raàæ¶ 100C™ ,ü@¦§0«£½$3Ÿ·5·º$HƒÄ4'IF  +DÜS˜I‚êªZLIB0xœÓa```bd Í€ €RZLIB;xœ3g```b’ŒŒ¿ùx$##ˆB©99ùzÉ `ÀÉÄbOç31ÆÆZLIBíxœUA E9 6é¦+îÜy„)éÐ C£žÞÖ&¦.ÿÿyï7¬) x™Ååz“gÙé^wRM܆”Ü-¹8<û“:­cj¬lÝCÍT¹`íèsÑ’ø5ß4Ù„ÂÄ2±­rBŠö°˜JÎx¸·` †¡²·lwéæ²œ¨±ÿåû¼µr.zÒø5Æ/â¡RtGCC: (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4zRx A†C V .symtab.strtab.shstrtab.rela.text.data.bss.rodata.rela.zdebug_info.zdebug_abbrev.rela.zdebug_aranges.rela.zdebug_line.zdebug_str.comment.note.GNU-stack.rela.eh_frame @8 0&[,[1[ >hf9h ÈKÎa_/#Z0 0 tR>o`  0¯0?*–i«p8¦x ¨µ €  ñÿ    hello.cmainputs üÿÿÿÿÿÿÿ   × u) 0 K7 b> ®E L ÁS Ía  h ßu ]z p€— ©¥ è + google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/gosym/000077500000000000000000000000001356504100700252645ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/gosym/pclinetest.asm000066400000000000000000000241551356504100700301470ustar00rootroot00000000000000TEXT linefrompc(SB),4,$0 // Each byte stores its line delta BYTE $2; BYTE $1; BYTE $1; BYTE $0; BYTE $1; BYTE $0; BYTE $0; BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $1; BYTE $1; BYTE $1; BYTE $0; BYTE $1; BYTE $0; BYTE $0; BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; #include "pclinetest.h" BYTE $2; #include "pclinetest.h" BYTE $2; BYTE $255; TEXT pcfromline(SB),4,$0 // Each record stores its line delta, then n, then n more bytes BYTE $32; BYTE $0; BYTE $1; BYTE $1; BYTE $0; BYTE $1; BYTE $0; BYTE $2; BYTE $4; BYTE $0; BYTE $0; BYTE $0; BYTE $0; #include "pclinetest.h" BYTE $4; BYTE $0; BYTE $3; BYTE $3; BYTE $0; BYTE $0; BYTE $0; #include "pclinetest.h" BYTE $4; BYTE $3; BYTE $0; BYTE $0; BYTE $0; BYTE $255; // Keep the linker happy TEXT main·main(SB),4,$0 RET TEXT main·init(SB),4,$0 // Prevent GC of our test symbols CALL linefrompc(SB) CALL pcfromline(SB) RET google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/gosym/pclinetest.h000066400000000000000000000001121356504100700276010ustar00rootroot00000000000000// +build ignore // Empty include file to generate z symbols // EOF google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/gosym/pclntab.go000066400000000000000000000311021356504100700272330ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. /* * Line tables */ package gosym import ( "encoding/binary" "sync" ) // A LineTable is a data structure mapping program counters to line numbers. // // In Go 1.1 and earlier, each function (represented by a Func) had its own LineTable, // and the line number corresponded to a numbering of all source lines in the // program, across all files. That absolute line number would then have to be // converted separately to a file name and line number within the file. // // In Go 1.2, the format of the data changed so that there is a single LineTable // for the entire program, shared by all Funcs, and there are no absolute line // numbers, just line numbers within specific files. // // For the most part, LineTable's methods should be treated as an internal // detail of the package; callers should use the methods on Table instead. type LineTable struct { Data []byte PC uint64 Line int // Go 1.2 state mu sync.Mutex go12 int // is this in Go 1.2 format? -1 no, 0 unknown, 1 yes binary binary.ByteOrder quantum uint32 ptrsize uint32 functab []byte nfunctab uint32 filetab []byte nfiletab uint32 fileMap map[string]uint32 } // NOTE(rsc): This is wrong for GOARCH=arm, which uses a quantum of 4, // but we have no idea whether we're using arm or not. This only // matters in the old (pre-Go 1.2) symbol table format, so it's not worth // fixing. const oldQuantum = 1 func (t *LineTable) parse(targetPC uint64, targetLine int) (b []byte, pc uint64, line int) { // The PC/line table can be thought of as a sequence of // * // batches. Each update batch results in a (pc, line) pair, // where line applies to every PC from pc up to but not // including the pc of the next pair. // // Here we process each update individually, which simplifies // the code, but makes the corner cases more confusing. b, pc, line = t.Data, t.PC, t.Line for pc <= targetPC && line != targetLine && len(b) > 0 { code := b[0] b = b[1:] switch { case code == 0: if len(b) < 4 { b = b[0:0] break } val := binary.BigEndian.Uint32(b) b = b[4:] line += int(val) case code <= 64: line += int(code) case code <= 128: line -= int(code - 64) default: pc += oldQuantum * uint64(code-128) continue } pc += oldQuantum } return b, pc, line } func (t *LineTable) slice(pc uint64) *LineTable { data, pc, line := t.parse(pc, -1) return &LineTable{Data: data, PC: pc, Line: line} } // PCToLine returns the line number for the given program counter. // Callers should use Table's PCToLine method instead. func (t *LineTable) PCToLine(pc uint64) int { if t.isGo12() { return t.go12PCToLine(pc) } _, _, line := t.parse(pc, -1) return line } // LineToPC returns the program counter for the given line number, // considering only program counters before maxpc. // Callers should use Table's LineToPC method instead. func (t *LineTable) LineToPC(line int, maxpc uint64) uint64 { if t.isGo12() { return 0 } _, pc, line1 := t.parse(maxpc, line) if line1 != line { return 0 } // Subtract quantum from PC to account for post-line increment return pc - oldQuantum } // NewLineTable returns a new PC/line table // corresponding to the encoded data. // Text must be the start address of the // corresponding text segment. func NewLineTable(data []byte, text uint64) *LineTable { return &LineTable{Data: data, PC: text, Line: 0} } // Go 1.2 symbol table format. // See golang.org/s/go12symtab. // // A general note about the methods here: rather than try to avoid // index out of bounds errors, we trust Go to detect them, and then // we recover from the panics and treat them as indicative of a malformed // or incomplete table. // // The methods called by symtab.go, which begin with "go12" prefixes, // are expected to have that recovery logic. // isGo12 reports whether this is a Go 1.2 (or later) symbol table. func (t *LineTable) isGo12() bool { t.go12Init() return t.go12 == 1 } const go12magic = 0xfffffffb // uintptr returns the pointer-sized value encoded at b. // The pointer size is dictated by the table being read. func (t *LineTable) uintptr(b []byte) uint64 { if t.ptrsize == 4 { return uint64(t.binary.Uint32(b)) } return t.binary.Uint64(b) } // go12init initializes the Go 1.2 metadata if t is a Go 1.2 symbol table. func (t *LineTable) go12Init() { t.mu.Lock() defer t.mu.Unlock() if t.go12 != 0 { return } defer func() { // If we panic parsing, assume it's not a Go 1.2 symbol table. recover() }() // Check header: 4-byte magic, two zeros, pc quantum, pointer size. t.go12 = -1 // not Go 1.2 until proven otherwise if len(t.Data) < 16 || t.Data[4] != 0 || t.Data[5] != 0 || (t.Data[6] != 1 && t.Data[6] != 4) || // pc quantum (t.Data[7] != 4 && t.Data[7] != 8) { // pointer size return } switch uint32(go12magic) { case binary.LittleEndian.Uint32(t.Data): t.binary = binary.LittleEndian case binary.BigEndian.Uint32(t.Data): t.binary = binary.BigEndian default: return } t.quantum = uint32(t.Data[6]) t.ptrsize = uint32(t.Data[7]) t.nfunctab = uint32(t.uintptr(t.Data[8:])) t.functab = t.Data[8+t.ptrsize:] functabsize := t.nfunctab*2*t.ptrsize + t.ptrsize fileoff := t.binary.Uint32(t.functab[functabsize:]) t.functab = t.functab[:functabsize] t.filetab = t.Data[fileoff:] t.nfiletab = t.binary.Uint32(t.filetab) t.filetab = t.filetab[:t.nfiletab*4] t.go12 = 1 // so far so good } // go12Funcs returns a slice of Funcs derived from the Go 1.2 pcln table. func (t *LineTable) go12Funcs() []Func { // Assume it is malformed and return nil on error. defer func() { recover() }() n := len(t.functab) / int(t.ptrsize) / 2 funcs := make([]Func, n) for i := range funcs { f := &funcs[i] f.Entry = uint64(t.uintptr(t.functab[2*i*int(t.ptrsize):])) f.End = uint64(t.uintptr(t.functab[(2*i+2)*int(t.ptrsize):])) info := t.Data[t.uintptr(t.functab[(2*i+1)*int(t.ptrsize):]):] f.LineTable = t f.FrameSize = int(t.binary.Uint32(info[t.ptrsize+2*4:])) f.Sym = &Sym{ Value: f.Entry, Type: 'T', Name: t.string(t.binary.Uint32(info[t.ptrsize:])), GoType: 0, Func: f, } } return funcs } // findFunc returns the func corresponding to the given program counter. func (t *LineTable) findFunc(pc uint64) []byte { if pc < t.uintptr(t.functab) || pc >= t.uintptr(t.functab[len(t.functab)-int(t.ptrsize):]) { return nil } // The function table is a list of 2*nfunctab+1 uintptrs, // alternating program counters and offsets to func structures. f := t.functab nf := t.nfunctab for nf > 0 { m := nf / 2 fm := f[2*t.ptrsize*m:] if t.uintptr(fm) <= pc && pc < t.uintptr(fm[2*t.ptrsize:]) { return t.Data[t.uintptr(fm[t.ptrsize:]):] } else if pc < t.uintptr(fm) { nf = m } else { f = f[(m+1)*2*t.ptrsize:] nf -= m + 1 } } return nil } // readvarint reads, removes, and returns a varint from *pp. func (t *LineTable) readvarint(pp *[]byte) uint32 { var v, shift uint32 p := *pp for shift = 0; ; shift += 7 { b := p[0] p = p[1:] v |= (uint32(b) & 0x7F) << shift if b&0x80 == 0 { break } } *pp = p return v } // string returns a Go string found at off. func (t *LineTable) string(off uint32) string { for i := off; ; i++ { if t.Data[i] == 0 { return string(t.Data[off:i]) } } } // step advances to the next pc, value pair in the encoded table. func (t *LineTable) step(p *[]byte, pc *uint64, val *int32, first bool) bool { uvdelta := t.readvarint(p) if uvdelta == 0 && !first { return false } if uvdelta&1 != 0 { uvdelta = ^(uvdelta >> 1) } else { uvdelta >>= 1 } vdelta := int32(uvdelta) pcdelta := t.readvarint(p) * t.quantum *pc += uint64(pcdelta) *val += vdelta return true } // pcvalue reports the value associated with the target pc. // off is the offset to the beginning of the pc-value table, // and entry is the start PC for the corresponding function. func (t *LineTable) pcvalue(off uint32, entry, targetpc uint64) int32 { if off == 0 { return -1 } p := t.Data[off:] val := int32(-1) pc := entry for t.step(&p, &pc, &val, pc == entry) { if targetpc < pc { return val } } return -1 } // findFileLine scans one function in the binary looking for a // program counter in the given file on the given line. // It does so by running the pc-value tables mapping program counter // to file number. Since most functions come from a single file, these // are usually short and quick to scan. If a file match is found, then the // code goes to the expense of looking for a simultaneous line number match. func (t *LineTable) findFileLine(entry uint64, filetab, linetab uint32, filenum, line int32) uint64 { if filetab == 0 || linetab == 0 { return 0 } fp := t.Data[filetab:] fl := t.Data[linetab:] fileVal := int32(-1) filePC := entry lineVal := int32(-1) linePC := entry fileStartPC := filePC for t.step(&fp, &filePC, &fileVal, filePC == entry) { if fileVal == filenum && fileStartPC < filePC { // fileVal is in effect starting at fileStartPC up to // but not including filePC, and it's the file we want. // Run the PC table looking for a matching line number // or until we reach filePC. lineStartPC := linePC for linePC < filePC && t.step(&fl, &linePC, &lineVal, linePC == entry) { // lineVal is in effect until linePC, and lineStartPC < filePC. if lineVal == line { if fileStartPC <= lineStartPC { return lineStartPC } if fileStartPC < linePC { return fileStartPC } } lineStartPC = linePC } } fileStartPC = filePC } return 0 } // go12PCToLine maps program counter to line number for the Go 1.2 pcln table. func (t *LineTable) go12PCToLine(pc uint64) (line int) { return t.go12PCToVal(pc, t.ptrsize+5*4) } // go12PCToSPAdj maps program counter to Stack Pointer adjustment for the Go 1.2 pcln table. func (t *LineTable) go12PCToSPAdj(pc uint64) (spadj int) { return t.go12PCToVal(pc, t.ptrsize+3*4) } func (t *LineTable) go12PCToVal(pc uint64, fOffset uint32) (val int) { defer func() { if recover() != nil { val = -1 } }() f := t.findFunc(pc) if f == nil { return -1 } entry := t.uintptr(f) linetab := t.binary.Uint32(f[fOffset:]) return int(t.pcvalue(linetab, entry, pc)) } // go12PCToFile maps program counter to file name for the Go 1.2 pcln table. func (t *LineTable) go12PCToFile(pc uint64) (file string) { defer func() { if recover() != nil { file = "" } }() f := t.findFunc(pc) if f == nil { return "" } entry := t.uintptr(f) filetab := t.binary.Uint32(f[t.ptrsize+4*4:]) fno := t.pcvalue(filetab, entry, pc) if fno <= 0 { return "" } return t.string(t.binary.Uint32(t.filetab[4*fno:])) } // go12LineToPC maps a (file, line) pair to a program counter for the Go 1.2 pcln table. func (t *LineTable) go12LineToPC(file string, line int) (pc uint64) { defer func() { if recover() != nil { pc = 0 } }() t.initFileMap() filenum := t.fileMap[file] if filenum == 0 { return 0 } // Scan all functions. // If this turns out to be a bottleneck, we could build a map[int32][]int32 // mapping file number to a list of functions with code from that file. for i := uint32(0); i < t.nfunctab; i++ { f := t.Data[t.uintptr(t.functab[2*t.ptrsize*i+t.ptrsize:]):] entry := t.uintptr(f) filetab := t.binary.Uint32(f[t.ptrsize+4*4:]) linetab := t.binary.Uint32(f[t.ptrsize+5*4:]) pc := t.findFileLine(entry, filetab, linetab, int32(filenum), int32(line)) if pc != 0 { return pc } } return 0 } // initFileMap initializes the map from file name to file number. func (t *LineTable) initFileMap() { t.mu.Lock() defer t.mu.Unlock() if t.fileMap != nil { return } m := make(map[string]uint32) for i := uint32(1); i < t.nfiletab; i++ { s := t.string(t.binary.Uint32(t.filetab[4*i:])) m[s] = i } t.fileMap = m } // go12MapFiles adds to m a key for every file in the Go 1.2 LineTable. // Every key maps to obj. That's not a very interesting map, but it provides // a way for callers to obtain the list of files in the program. func (t *LineTable) go12MapFiles(m map[string]*Obj, obj *Obj) { defer func() { recover() }() t.initFileMap() for file := range t.fileMap { m[file] = obj } } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/gosym/pclntab_test.go000066400000000000000000000165621356504100700303070ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package gosym import ( "debug/elf" "fmt" "io/ioutil" "os" "os/exec" "path/filepath" "runtime" "strings" "testing" ) var ( pclineTempDir string pclinetestBinary string ) func dotest(self bool) bool { // For now, only works on amd64 platforms. if runtime.GOARCH != "amd64" { return false } // Self test reads test binary; only works on Linux. if self && runtime.GOOS != "linux" { return false } // Command below expects "sh", so Unix. if runtime.GOOS == "windows" || runtime.GOOS == "plan9" { return false } if pclinetestBinary != "" { return true } var err error pclineTempDir, err = ioutil.TempDir("", "pclinetest") if err != nil { panic(err) } if strings.Contains(pclineTempDir, " ") { panic("unexpected space in tempdir") } // This command builds pclinetest from pclinetest.asm; // the resulting binary looks like it was built from pclinetest.s, // but we have renamed it to keep it away from the go tool. pclinetestBinary = filepath.Join(pclineTempDir, "pclinetest") command := fmt.Sprintf("go tool 6a -o %s.6 pclinetest.asm && go tool 6l -H linux -E main -o %s %s.6", pclinetestBinary, pclinetestBinary, pclinetestBinary) cmd := exec.Command("sh", "-c", command) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { panic(err) } return true } func endtest() { if pclineTempDir != "" { os.RemoveAll(pclineTempDir) pclineTempDir = "" pclinetestBinary = "" } } func getTable(t *testing.T) *Table { f, tab := crack(os.Args[0], t) f.Close() return tab } func crack(file string, t *testing.T) (*elf.File, *Table) { // Open self f, err := elf.Open(file) if err != nil { t.Fatal(err) } return parse(file, f, t) } func parse(file string, f *elf.File, t *testing.T) (*elf.File, *Table) { symdat, err := f.Section(".gosymtab").Data() if err != nil { f.Close() t.Fatalf("reading %s gosymtab: %v", file, err) } pclndat, err := f.Section(".gopclntab").Data() if err != nil { f.Close() t.Fatalf("reading %s gopclntab: %v", file, err) } pcln := NewLineTable(pclndat, f.Section(".text").Addr) tab, err := NewTable(symdat, pcln) if err != nil { f.Close() t.Fatalf("parsing %s gosymtab: %v", file, err) } return f, tab } var goarch = os.Getenv("O") func TestLineFromAline(t *testing.T) { t.Skip("wants to use go tool 6a which hasn't existed for who knows how long") if !dotest(true) { return } defer endtest() tab := getTable(t) if tab.go12line != nil { // aline's don't exist in the Go 1.2 table. t.Skip("not relevant to Go 1.2 symbol table") } // Find the sym package pkg := tab.LookupFunc("debug/gosym.TestLineFromAline").Obj if pkg == nil { t.Fatalf("nil pkg") } // Walk every absolute line and ensure that we hit every // source line monotonically lastline := make(map[string]int) final := -1 for i := 0; i < 10000; i++ { path, line := pkg.lineFromAline(i) // Check for end of object if path == "" { if final == -1 { final = i - 1 } continue } else if final != -1 { t.Fatalf("reached end of package at absolute line %d, but absolute line %d mapped to %s:%d", final, i, path, line) } // It's okay to see files multiple times (e.g., sys.a) if line == 1 { lastline[path] = 1 continue } // Check that the is the next line in path ll, ok := lastline[path] if !ok { t.Errorf("file %s starts on line %d", path, line) } else if line != ll+1 { t.Fatalf("expected next line of file %s to be %d, got %d", path, ll+1, line) } lastline[path] = line } if final == -1 { t.Errorf("never reached end of object") } } func TestLineAline(t *testing.T) { t.Skip("wants to use go tool 6a which hasn't existed for who knows how long") if !dotest(true) { return } defer endtest() tab := getTable(t) if tab.go12line != nil { // aline's don't exist in the Go 1.2 table. t.Skip("not relevant to Go 1.2 symbol table") } for _, o := range tab.Files { // A source file can appear multiple times in a // object. alineFromLine will always return alines in // the first file, so track which lines we've seen. found := make(map[string]int) for i := 0; i < 1000; i++ { path, line := o.lineFromAline(i) if path == "" { break } // cgo files are full of 'Z' symbols, which we don't handle if len(path) > 4 && path[len(path)-4:] == ".cgo" { continue } if minline, ok := found[path]; path != "" && ok { if minline >= line { // We've already covered this file continue } } found[path] = line a, err := o.alineFromLine(path, line) if err != nil { t.Errorf("absolute line %d in object %s maps to %s:%d, but mapping that back gives error %s", i, o.Paths[0].Name, path, line, err) } else if a != i { t.Errorf("absolute line %d in object %s maps to %s:%d, which maps back to absolute line %d\n", i, o.Paths[0].Name, path, line, a) } } } } func TestPCLine(t *testing.T) { t.Skip("wants to use go tool 6a which hasn't existed for who knows how long") if !dotest(false) { return } defer endtest() f, tab := crack(pclinetestBinary, t) text := f.Section(".text") textdat, err := text.Data() if err != nil { t.Fatalf("reading .text: %v", err) } // Test PCToLine sym := tab.LookupFunc("linefrompc") wantLine := 0 for pc := sym.Entry; pc < sym.End; pc++ { off := pc - text.Addr // TODO(rsc): should not need off; bug in 8g if textdat[off] == 255 { break } wantLine += int(textdat[off]) t.Logf("off is %d %#x (max %d)", off, textdat[off], sym.End-pc) file, line, fn := tab.PCToLine(pc) if fn == nil { t.Errorf("failed to get line of PC %#x", pc) } else if !strings.HasSuffix(file, "pclinetest.asm") || line != wantLine || fn != sym { t.Errorf("PCToLine(%#x) = %s:%d (%s), want %s:%d (%s)", pc, file, line, fn.Name, "pclinetest.asm", wantLine, sym.Name) } } // Test LineToPC sym = tab.LookupFunc("pcfromline") lookupline := -1 wantLine = 0 off := uint64(0) // TODO(rsc): should not need off; bug in 8g for pc := sym.Value; pc < sym.End; pc += 2 + uint64(textdat[off]) { file, line, fn := tab.PCToLine(pc) off = pc - text.Addr if textdat[off] == 255 { break } wantLine += int(textdat[off]) if line != wantLine { t.Errorf("expected line %d at PC %#x in pcfromline, got %d", wantLine, pc, line) off = pc + 1 - text.Addr continue } if lookupline == -1 { lookupline = line } for ; lookupline <= line; lookupline++ { pc2, fn2, err := tab.LineToPC(file, lookupline) if lookupline != line { // Should be nothing on this line if err == nil { t.Errorf("expected no PC at line %d, got %#x (%s)", lookupline, pc2, fn2.Name) } } else if err != nil { t.Errorf("failed to get PC of line %d: %s", lookupline, err) } else if pc != pc2 { t.Errorf("expected PC %#x (%s) at line %d, got PC %#x (%s)", pc, fn.Name, line, pc2, fn2.Name) } } off = pc + 1 - text.Addr } } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/gosym/symtab.go000066400000000000000000000402401356504100700271120ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package gosym implements access to the Go symbol // and line number tables embedded in Go binaries generated // by the gc compilers. package gosym // The table format is a variant of the format used in Plan 9's a.out // format, documented at http://plan9.bell-labs.com/magic/man2html/6/a.out. // The best reference for the differences between the Plan 9 format // and the Go format is the runtime source, specifically ../../runtime/symtab.c. import ( "bytes" "encoding/binary" "fmt" "strconv" "strings" ) /* * Symbols */ // A Sym represents a single symbol table entry. type Sym struct { Value uint64 Type byte Name string GoType uint64 // If this symbol if a function symbol, the corresponding Func Func *Func } // Static reports whether this symbol is static (not visible outside its file). func (s *Sym) Static() bool { return s.Type >= 'a' } // PackageName returns the package part of the symbol name, // or the empty string if there is none. func (s *Sym) PackageName() string { if i := strings.Index(s.Name, "."); i != -1 { return s.Name[0:i] } return "" } // ReceiverName returns the receiver type name of this symbol, // or the empty string if there is none. func (s *Sym) ReceiverName() string { l := strings.Index(s.Name, ".") r := strings.LastIndex(s.Name, ".") if l == -1 || r == -1 || l == r { return "" } return s.Name[l+1 : r] } // BaseName returns the symbol name without the package or receiver name. func (s *Sym) BaseName() string { if i := strings.LastIndex(s.Name, "."); i != -1 { return s.Name[i+1:] } return s.Name } // A Func collects information about a single function. type Func struct { Entry uint64 *Sym End uint64 Params []*Sym Locals []*Sym FrameSize int LineTable *LineTable Obj *Obj } // An Obj represents a collection of functions in a symbol table. // // The exact method of division of a binary into separate Objs is an internal detail // of the symbol table format. // // In early versions of Go each source file became a different Obj. // // In Go 1 and Go 1.1, each package produced one Obj for all Go sources // and one Obj per C source file. // // In Go 1.2, there is a single Obj for the entire program. type Obj struct { // Funcs is a list of functions in the Obj. Funcs []Func // In Go 1.1 and earlier, Paths is a list of symbols corresponding // to the source file names that produced the Obj. // In Go 1.2, Paths is nil. // Use the keys of Table.Files to obtain a list of source files. Paths []Sym // meta } /* * Symbol tables */ // Table represents a Go symbol table. It stores all of the // symbols decoded from the program and provides methods to translate // between symbols, names, and addresses. type Table struct { Syms []Sym Funcs []Func Files map[string]*Obj // nil for Go 1.2 and later binaries Objs []Obj // nil for Go 1.2 and later binaries go12line *LineTable // Go 1.2 line number table } type sym struct { value uint64 gotype uint64 typ byte name []byte } var ( littleEndianSymtab = []byte{0xFD, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00} bigEndianSymtab = []byte{0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00} oldLittleEndianSymtab = []byte{0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00} ) func walksymtab(data []byte, fn func(sym) error) error { if len(data) == 0 { // missing symtab is okay return nil } var order binary.ByteOrder = binary.BigEndian newTable := false switch { case bytes.HasPrefix(data, oldLittleEndianSymtab): // Same as Go 1.0, but little endian. // Format was used during interim development between Go 1.0 and Go 1.1. // Should not be widespread, but easy to support. data = data[6:] order = binary.LittleEndian case bytes.HasPrefix(data, bigEndianSymtab): newTable = true case bytes.HasPrefix(data, littleEndianSymtab): newTable = true order = binary.LittleEndian } var ptrsz int if newTable { if len(data) < 8 { return &DecodingError{len(data), "unexpected EOF", nil} } ptrsz = int(data[7]) if ptrsz != 4 && ptrsz != 8 { return &DecodingError{7, "invalid pointer size", ptrsz} } data = data[8:] } var s sym p := data for len(p) >= 4 { var typ byte if newTable { // Symbol type, value, Go type. typ = p[0] & 0x3F wideValue := p[0]&0x40 != 0 goType := p[0]&0x80 != 0 if typ < 26 { typ += 'A' } else { typ += 'a' - 26 } s.typ = typ p = p[1:] if wideValue { if len(p) < ptrsz { return &DecodingError{len(data), "unexpected EOF", nil} } // fixed-width value if ptrsz == 8 { s.value = order.Uint64(p[0:8]) p = p[8:] } else { s.value = uint64(order.Uint32(p[0:4])) p = p[4:] } } else { // varint value s.value = 0 shift := uint(0) for len(p) > 0 && p[0]&0x80 != 0 { s.value |= uint64(p[0]&0x7F) << shift shift += 7 p = p[1:] } if len(p) == 0 { return &DecodingError{len(data), "unexpected EOF", nil} } s.value |= uint64(p[0]) << shift p = p[1:] } if goType { if len(p) < ptrsz { return &DecodingError{len(data), "unexpected EOF", nil} } // fixed-width go type if ptrsz == 8 { s.gotype = order.Uint64(p[0:8]) p = p[8:] } else { s.gotype = uint64(order.Uint32(p[0:4])) p = p[4:] } } } else { // Value, symbol type. s.value = uint64(order.Uint32(p[0:4])) if len(p) < 5 { return &DecodingError{len(data), "unexpected EOF", nil} } typ = p[4] if typ&0x80 == 0 { return &DecodingError{len(data) - len(p) + 4, "bad symbol type", typ} } typ &^= 0x80 s.typ = typ p = p[5:] } // Name. var i int var nnul int for i = 0; i < len(p); i++ { if p[i] == 0 { nnul = 1 break } } switch typ { case 'z', 'Z': p = p[i+nnul:] for i = 0; i+2 <= len(p); i += 2 { if p[i] == 0 && p[i+1] == 0 { nnul = 2 break } } } if len(p) < i+nnul { return &DecodingError{len(data), "unexpected EOF", nil} } s.name = p[0:i] i += nnul p = p[i:] if !newTable { if len(p) < 4 { return &DecodingError{len(data), "unexpected EOF", nil} } // Go type. s.gotype = uint64(order.Uint32(p[:4])) p = p[4:] } fn(s) } return nil } // NewTable decodes the Go symbol table in data, // returning an in-memory representation. func NewTable(symtab []byte, pcln *LineTable) (*Table, error) { var n int err := walksymtab(symtab, func(s sym) error { n++ return nil }) if err != nil { return nil, err } var t Table if pcln.isGo12() { t.go12line = pcln } fname := make(map[uint16]string) t.Syms = make([]Sym, 0, n) nf := 0 nz := 0 lasttyp := uint8(0) err = walksymtab(symtab, func(s sym) error { n := len(t.Syms) t.Syms = t.Syms[0 : n+1] ts := &t.Syms[n] ts.Type = s.typ ts.Value = uint64(s.value) ts.GoType = uint64(s.gotype) switch s.typ { default: // rewrite name to use . instead of · (c2 b7) w := 0 b := s.name for i := 0; i < len(b); i++ { if b[i] == 0xc2 && i+1 < len(b) && b[i+1] == 0xb7 { i++ b[i] = '.' } b[w] = b[i] w++ } ts.Name = string(s.name[0:w]) case 'z', 'Z': if lasttyp != 'z' && lasttyp != 'Z' { nz++ } for i := 0; i < len(s.name); i += 2 { eltIdx := binary.BigEndian.Uint16(s.name[i : i+2]) elt, ok := fname[eltIdx] if !ok { return &DecodingError{-1, "bad filename code", eltIdx} } if n := len(ts.Name); n > 0 && ts.Name[n-1] != '/' { ts.Name += "/" } ts.Name += elt } } switch s.typ { case 'T', 't', 'L', 'l': nf++ case 'f': fname[uint16(s.value)] = ts.Name } lasttyp = s.typ return nil }) if err != nil { return nil, err } t.Funcs = make([]Func, 0, nf) t.Files = make(map[string]*Obj) var obj *Obj if t.go12line != nil { // Put all functions into one Obj. t.Objs = make([]Obj, 1) obj = &t.Objs[0] t.go12line.go12MapFiles(t.Files, obj) } else { t.Objs = make([]Obj, 0, nz) } // Count text symbols and attach frame sizes, parameters, and // locals to them. Also, find object file boundaries. lastf := 0 for i := 0; i < len(t.Syms); i++ { sym := &t.Syms[i] switch sym.Type { case 'Z', 'z': // path symbol if t.go12line != nil { // Go 1.2 binaries have the file information elsewhere. Ignore. break } // Finish the current object if obj != nil { obj.Funcs = t.Funcs[lastf:] } lastf = len(t.Funcs) // Start new object n := len(t.Objs) t.Objs = t.Objs[0 : n+1] obj = &t.Objs[n] // Count & copy path symbols var end int for end = i + 1; end < len(t.Syms); end++ { if c := t.Syms[end].Type; c != 'Z' && c != 'z' { break } } obj.Paths = t.Syms[i:end] i = end - 1 // loop will i++ // Record file names depth := 0 for j := range obj.Paths { s := &obj.Paths[j] if s.Name == "" { depth-- } else { if depth == 0 { t.Files[s.Name] = obj } depth++ } } case 'T', 't', 'L', 'l': // text symbol if n := len(t.Funcs); n > 0 { t.Funcs[n-1].End = sym.Value } if sym.Name == "etext" { continue } // Count parameter and local (auto) syms var np, na int var end int countloop: for end = i + 1; end < len(t.Syms); end++ { switch t.Syms[end].Type { case 'T', 't', 'L', 'l', 'Z', 'z': break countloop case 'p': np++ case 'a': na++ } } // Fill in the function symbol n := len(t.Funcs) t.Funcs = t.Funcs[0 : n+1] fn := &t.Funcs[n] sym.Func = fn fn.Params = make([]*Sym, 0, np) fn.Locals = make([]*Sym, 0, na) fn.Sym = sym fn.Entry = sym.Value fn.Obj = obj if t.go12line != nil { // All functions share the same line table. // It knows how to narrow down to a specific // function quickly. fn.LineTable = t.go12line } else if pcln != nil { fn.LineTable = pcln.slice(fn.Entry) pcln = fn.LineTable } for j := i; j < end; j++ { s := &t.Syms[j] switch s.Type { case 'm': fn.FrameSize = int(s.Value) case 'p': n := len(fn.Params) fn.Params = fn.Params[0 : n+1] fn.Params[n] = s case 'a': n := len(fn.Locals) fn.Locals = fn.Locals[0 : n+1] fn.Locals[n] = s } } i = end - 1 // loop will i++ } } if t.go12line != nil && nf == 0 { t.Funcs = t.go12line.go12Funcs() } if obj != nil { obj.Funcs = t.Funcs[lastf:] } return &t, nil } // PCToFunc returns the function containing the program counter pc, // or nil if there is no such function. func (t *Table) PCToFunc(pc uint64) *Func { funcs := t.Funcs for len(funcs) > 0 { m := len(funcs) / 2 fn := &funcs[m] switch { case pc < fn.Entry: funcs = funcs[0:m] case fn.Entry <= pc && pc < fn.End: return fn default: funcs = funcs[m+1:] } } return nil } // PCToLine looks up line number information for a program counter. // If there is no information, it returns fn == nil. func (t *Table) PCToLine(pc uint64) (file string, line int, fn *Func) { if fn = t.PCToFunc(pc); fn == nil { return } if t.go12line != nil { file = t.go12line.go12PCToFile(pc) line = t.go12line.go12PCToLine(pc) } else { file, line = fn.Obj.lineFromAline(fn.LineTable.PCToLine(pc)) } return } // PCToSPAdj returns the stack pointer adjustment for a program counter. func (t *Table) PCToSPAdj(pc uint64) (spadj int) { if fn := t.PCToFunc(pc); fn == nil { return 0 } if t.go12line != nil { return t.go12line.go12PCToSPAdj(pc) } return 0 } // LineToPC looks up the first program counter on the given line in // the named file. It returns UnknownPathError or UnknownLineError if // there is an error looking up this line. func (t *Table) LineToPC(file string, line int) (pc uint64, fn *Func, err error) { obj, ok := t.Files[file] if !ok { return 0, nil, UnknownFileError(file) } if t.go12line != nil { pc := t.go12line.go12LineToPC(file, line) if pc == 0 { return 0, nil, &UnknownLineError{file, line} } return pc, t.PCToFunc(pc), nil } abs, err := obj.alineFromLine(file, line) if err != nil { return } for i := range obj.Funcs { f := &obj.Funcs[i] pc := f.LineTable.LineToPC(abs, f.End) if pc != 0 { return pc, f, nil } } return 0, nil, &UnknownLineError{file, line} } // LookupSym returns the text, data, or bss symbol with the given name, // or nil if no such symbol is found. func (t *Table) LookupSym(name string) *Sym { // TODO(austin) Maybe make a map for i := range t.Syms { s := &t.Syms[i] switch s.Type { case 'T', 't', 'L', 'l', 'D', 'd', 'B', 'b': if s.Name == name { return s } } } return nil } // LookupFunc returns the text, data, or bss symbol with the given name, // or nil if no such symbol is found. func (t *Table) LookupFunc(name string) *Func { for i := range t.Funcs { f := &t.Funcs[i] if f.Sym.Name == name { return f } } return nil } // SymByAddr returns the text, data, or bss symbol starting at the given address. func (t *Table) SymByAddr(addr uint64) *Sym { for i := range t.Syms { s := &t.Syms[i] switch s.Type { case 'T', 't', 'L', 'l', 'D', 'd', 'B', 'b': if s.Value == addr { return s } } } return nil } /* * Object files */ // This is legacy code for Go 1.1 and earlier, which used the // Plan 9 format for pc-line tables. This code was never quite // correct. It's probably very close, and it's usually correct, but // we never quite found all the corner cases. // // Go 1.2 and later use a simpler format, documented at golang.org/s/go12symtab. func (o *Obj) lineFromAline(aline int) (string, int) { type stackEnt struct { path string start int offset int prev *stackEnt } noPath := &stackEnt{"", 0, 0, nil} tos := noPath pathloop: for _, s := range o.Paths { val := int(s.Value) switch { case val > aline: break pathloop case val == 1: // Start a new stack tos = &stackEnt{s.Name, val, 0, noPath} case s.Name == "": // Pop if tos == noPath { return "", 0 } tos.prev.offset += val - tos.start tos = tos.prev default: // Push tos = &stackEnt{s.Name, val, 0, tos} } } if tos == noPath { return "", 0 } return tos.path, aline - tos.start - tos.offset + 1 } func (o *Obj) alineFromLine(path string, line int) (int, error) { if line < 1 { return 0, &UnknownLineError{path, line} } for i, s := range o.Paths { // Find this path if s.Name != path { continue } // Find this line at this stack level depth := 0 var incstart int line += int(s.Value) pathloop: for _, s := range o.Paths[i:] { val := int(s.Value) switch { case depth == 1 && val >= line: return line - 1, nil case s.Name == "": depth-- if depth == 0 { break pathloop } else if depth == 1 { line += val - incstart } default: if depth == 1 { incstart = val } depth++ } } return 0, &UnknownLineError{path, line} } return 0, UnknownFileError(path) } /* * Errors */ // UnknownFileError represents a failure to find the specific file in // the symbol table. type UnknownFileError string func (e UnknownFileError) Error() string { return "unknown file: " + string(e) } // UnknownLineError represents a failure to map a line to a program // counter, either because the line is beyond the bounds of the file // or because there is no code on the given line. type UnknownLineError struct { File string Line int } func (e *UnknownLineError) Error() string { return "no code at " + e.File + ":" + strconv.Itoa(e.Line) } // DecodingError represents an error during the decoding of // the symbol table. type DecodingError struct { off int msg string val interface{} } func (e *DecodingError) Error() string { msg := e.msg if e.val != nil { msg += fmt.Sprintf(" '%v'", e.val) } msg += fmt.Sprintf(" at byte %#x", e.off) return msg } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/local/000077500000000000000000000000001356504100700252205ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/local/local.go000066400000000000000000000124241356504100700266440ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // +build linux // Package local provides access to a local program. package local import ( "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/server" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/server/protocol" ) var _ debug.Program = (*Program)(nil) var _ debug.File = (*File)(nil) // Program implements the debug.Program interface. // Through that interface it provides access to a program being debugged. type Program struct { s *server.Server } // New creates a new program from the specified file. // The program can then be started by the Run method. func New(textFile string) (*Program, error) { s, err := server.New(textFile) return &Program{s: s}, err } func (p *Program) Open(name string, mode string) (debug.File, error) { req := protocol.OpenRequest{ Name: name, Mode: mode, } var resp protocol.OpenResponse err := p.s.Open(&req, &resp) if err != nil { return nil, err } f := &File{ prog: p, fd: resp.FD, } return f, nil } func (p *Program) Run(args ...string) (debug.Status, error) { req := protocol.RunRequest{args} var resp protocol.RunResponse err := p.s.Run(&req, &resp) if err != nil { return debug.Status{}, err } return resp.Status, nil } func (p *Program) Stop() (debug.Status, error) { panic("unimplemented") } func (p *Program) Resume() (debug.Status, error) { req := protocol.ResumeRequest{} var resp protocol.ResumeResponse err := p.s.Resume(&req, &resp) if err != nil { return debug.Status{}, err } return resp.Status, nil } func (p *Program) Kill() (debug.Status, error) { panic("unimplemented") } func (p *Program) Breakpoint(address uint64) ([]uint64, error) { req := protocol.BreakpointRequest{ Address: address, } var resp protocol.BreakpointResponse err := p.s.Breakpoint(&req, &resp) return resp.PCs, err } func (p *Program) BreakpointAtFunction(name string) ([]uint64, error) { req := protocol.BreakpointAtFunctionRequest{ Function: name, } var resp protocol.BreakpointResponse err := p.s.BreakpointAtFunction(&req, &resp) return resp.PCs, err } func (p *Program) BreakpointAtLine(file string, line uint64) ([]uint64, error) { req := protocol.BreakpointAtLineRequest{ File: file, Line: line, } var resp protocol.BreakpointResponse err := p.s.BreakpointAtLine(&req, &resp) return resp.PCs, err } func (p *Program) DeleteBreakpoints(pcs []uint64) error { req := protocol.DeleteBreakpointsRequest{PCs: pcs} var resp protocol.DeleteBreakpointsResponse return p.s.DeleteBreakpoints(&req, &resp) } func (p *Program) Eval(expr string) ([]string, error) { req := protocol.EvalRequest{ Expr: expr, } var resp protocol.EvalResponse err := p.s.Eval(&req, &resp) return resp.Result, err } func (p *Program) Evaluate(e string) (debug.Value, error) { req := protocol.EvaluateRequest{ Expression: e, } var resp protocol.EvaluateResponse err := p.s.Evaluate(&req, &resp) return resp.Result, err } func (p *Program) Frames(count int) ([]debug.Frame, error) { req := protocol.FramesRequest{ Count: count, } var resp protocol.FramesResponse err := p.s.Frames(&req, &resp) return resp.Frames, err } func (p *Program) Goroutines() ([]*debug.Goroutine, error) { req := protocol.GoroutinesRequest{} var resp protocol.GoroutinesResponse err := p.s.Goroutines(&req, &resp) return resp.Goroutines, err } func (p *Program) VarByName(name string) (debug.Var, error) { req := protocol.VarByNameRequest{Name: name} var resp protocol.VarByNameResponse err := p.s.VarByName(&req, &resp) return resp.Var, err } func (p *Program) Value(v debug.Var) (debug.Value, error) { req := protocol.ValueRequest{Var: v} var resp protocol.ValueResponse err := p.s.Value(&req, &resp) return resp.Value, err } func (p *Program) MapElement(m debug.Map, index uint64) (debug.Var, debug.Var, error) { req := protocol.MapElementRequest{Map: m, Index: index} var resp protocol.MapElementResponse err := p.s.MapElement(&req, &resp) return resp.Key, resp.Value, err } // File implements the debug.File interface, providing access // to file-like resources associated with the target program. type File struct { prog *Program // The Program associated with the file. fd int // File descriptor. } func (f *File) ReadAt(p []byte, offset int64) (int, error) { req := protocol.ReadAtRequest{ FD: f.fd, Len: len(p), Offset: offset, } var resp protocol.ReadAtResponse err := f.prog.s.ReadAt(&req, &resp) return copy(p, resp.Data), err } func (f *File) WriteAt(p []byte, offset int64) (int, error) { panic("unimplemented") } func (f *File) Close() error { req := protocol.CloseRequest{ FD: f.fd, } var resp protocol.CloseResponse err := f.prog.s.Close(&req, &resp) return err } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/program.go000066400000000000000000000240241356504100700261260ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package debug provides the portable interface to a program being debugged. package debug import ( "fmt" "io" "strings" ) // Program is the interface to a (possibly remote) program being debugged. // The process (if any) and text file associated with it may change during // the session, but many resources are associated with the Program rather // than process or text file so they persist across debuggging runs. type Program interface { // Open opens a virtual file associated with the process. // Names are things like "text", "mem", "fd/2". // Mode is one of "r", "w", "rw". // Return values are open File and error. // When the target binary is re-run, open files are // automatically updated to refer to the corresponding // file in the new process. Open(name string, mode string) (File, error) // Run abandons the current running process, if any, // and execs a new instance of the target binary file // (which may have changed underfoot). // Breakpoints and open files are re-established. // The call hangs until the program stops executing, // at which point it returns the program status. // args contains the command-line arguments for the process. Run(args ...string) (Status, error) // Stop stops execution of the current process but // does not kill it. Stop() (Status, error) // Resume resumes execution of a stopped process. // The call hangs until the program stops executing, // at which point it returns the program status. Resume() (Status, error) // TODO: Step(). Where does the granularity happen, // on the proxy end or the debugging control end? // Kill kills the current process. Kill() (Status, error) // Breakpoint sets a breakpoint at the specified address. Breakpoint(address uint64) (PCs []uint64, err error) // BreakpointAtFunction sets a breakpoint at the start of the specified function. BreakpointAtFunction(name string) (PCs []uint64, err error) // BreakpointAtLine sets a breakpoint at the specified source line. BreakpointAtLine(file string, line uint64) (PCs []uint64, err error) // DeleteBreakpoints removes the breakpoints at the specified addresses. // Addresses where no breakpoint is set are ignored. DeleteBreakpoints(pcs []uint64) error // Eval evaluates the expression (typically an address) and returns // its string representation(s). Multivalued expressions such as // matches for regular expressions return multiple values. // TODO: change this to multiple functions with more specific names. // Syntax: // re:regexp // Returns a list of symbol names that match the expression // addr:symbol // Returns a one-element list holding the hexadecimal // ("0x1234") value of the address of the symbol // val:symbol // Returns a one-element list holding the formatted // value of the symbol // 0x1234, 01234, 467 // Returns a one-element list holding the name of the // symbol ("main.foo") at that address (hex, octal, decimal). Eval(expr string) ([]string, error) // Evaluate evaluates an expression. Accepts a subset of Go expression syntax: // basic literals, identifiers, parenthesized expressions, and most operators. // Only the len function call is available. // // The expression can refer to local variables and function parameters of the // function where the program is stopped. // // On success, the type of the value returned will be one of: // int8, int16, int32, int64, uint8, uint16, uint32, uint64, float32, float64, // complex64, complex128, bool, Pointer, Array, Slice, String, Map, Struct, // Channel, Func, or Interface. Evaluate(e string) (Value, error) // Frames returns up to count stack frames from where the program // is currently stopped. Frames(count int) ([]Frame, error) // VarByName returns a Var referring to a global variable with the given name. // TODO: local variables VarByName(name string) (Var, error) // Value gets the value of a variable by reading the program's memory. Value(v Var) (Value, error) // MapElement returns Vars for the key and value of a map element specified by // a 0-based index. MapElement(m Map, index uint64) (Var, Var, error) // Goroutines gets the current goroutines. Goroutines() ([]*Goroutine, error) } type Goroutine struct { ID int64 Status GoroutineStatus StatusString string // A human-readable string explaining the status in more detail. Function string // Name of the goroutine function. Caller string // Name of the function that created this goroutine. StackFrames []Frame } type GoroutineStatus byte const ( Running GoroutineStatus = iota Queued Blocked ) func (g GoroutineStatus) String() string { switch g { case Running: return "running" case Queued: return "queued" case Blocked: return "blocked" } return "invalid status" } func (g *Goroutine) String() string { return fmt.Sprintf("goroutine %d [%s] %s -> %s", g.ID, g.StatusString, g.Caller, g.Function) } // A reference to a variable in a program. // TODO: handle variables stored in registers type Var struct { TypeID uint64 // A type identifier, opaque to the user. Address uint64 // The address of the variable. } // A value read from a remote program. type Value interface{} // Pointer is a Value representing a pointer. // Note that the TypeID field will be the type of the variable being pointed to, // not the type of this pointer. type Pointer struct { TypeID uint64 // A type identifier, opaque to the user. Address uint64 // The address of the variable. } // Array is a Value representing an array. type Array struct { ElementTypeID uint64 Address uint64 Length uint64 // Number of elements in the array StrideBits uint64 // Number of bits between array entries } // Len returns the number of elements in the array. func (a Array) Len() uint64 { return a.Length } // Element returns a Var referring to the given element of the array. func (a Array) Element(index uint64) Var { return Var{ TypeID: a.ElementTypeID, Address: a.Address + index*(a.StrideBits/8), } } // Slice is a Value representing a slice. type Slice struct { Array Capacity uint64 } // String is a Value representing a string. // TODO: a method to access more of a truncated string. type String struct { // Length contains the length of the remote string, in bytes. Length uint64 // String contains the string itself; it may be truncated to fewer bytes than the value of the Length field. String string } // Map is a Value representing a map. type Map struct { TypeID uint64 Address uint64 Length uint64 // Number of elements in the map. } // Struct is a Value representing a struct. type Struct struct { Fields []StructField } // StructField represents a field in a struct object. type StructField struct { Name string Var Var } // Channel is a Value representing a channel. type Channel struct { ElementTypeID uint64 Address uint64 // Location of the channel struct in memory. Buffer uint64 // Location of the buffer; zero for nil channels. Length uint64 // Number of elements stored in the channel buffer. Capacity uint64 // Capacity of the buffer; zero for unbuffered channels. Stride uint64 // Number of bytes between buffer entries. BufferStart uint64 // Index in the buffer of the element at the head of the queue. } // Element returns a Var referring to the given element of the channel's queue. // If the channel is unbuffered, nil, or if the index is too large, returns a Var with Address == 0. func (m Channel) Element(index uint64) Var { if index >= m.Length { return Var{ TypeID: m.ElementTypeID, Address: 0, } } if index < m.Capacity-m.BufferStart { // The element is in the part of the queue that occurs later in the buffer // than the head of the queue. return Var{ TypeID: m.ElementTypeID, Address: m.Buffer + (m.BufferStart+index)*m.Stride, } } // The element is in the part of the queue that has wrapped around to the // start of the buffer. return Var{ TypeID: m.ElementTypeID, Address: m.Buffer + (m.BufferStart+index-m.Capacity)*m.Stride, } } // Func is a Value representing a func. type Func struct { Address uint64 } // Interface is a Value representing an interface. type Interface struct{} // The File interface provides access to file-like resources in the program. // It implements only ReaderAt and WriterAt, not Reader and Writer, because // random access is a far more common pattern for things like symbol tables, // and because enormous address space of virtual memory makes routines // like io.Copy dangerous. type File interface { io.ReaderAt io.WriterAt io.Closer } type Status struct { PC, SP uint64 } type Frame struct { // PC is the hardware program counter. PC uint64 // SP is the hardware stack pointer. SP uint64 // File and Line are the source code location of the PC. File string Line uint64 // Function is the name of this frame's function. Function string // FunctionStart is the starting PC of the function. FunctionStart uint64 // Params contains the function's parameters. Params []Param // Vars contains the function's local variables. Vars []LocalVar } func (f Frame) String() string { params := make([]string, len(f.Params)) for i, p := range f.Params { params[i] = p.Name // TODO: more information } p := strings.Join(params, ", ") off := f.PC - f.FunctionStart return fmt.Sprintf("%s(%s)\n\t%s:%d +0x%x", f.Function, p, f.File, f.Line, off) } // Param is a parameter of a function. type Param struct { Name string Var Var } // LocalVar is a local variable of a function. type LocalVar struct { Name string Var Var } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/remote/000077500000000000000000000000001356504100700254215ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/remote/remote.go000066400000000000000000000175161356504100700272550ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package remote provides remote access to a debugproxy server. package remote import ( "fmt" "io" "net/rpc" "os" "os/exec" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/server/protocol" ) var _ debug.Program = (*Program)(nil) var _ debug.File = (*File)(nil) // Program implements the debug.Program interface. // Through that interface it provides access to a program being // debugged on a possibly remote machine by communicating // with a debugproxy adjacent to the target program. type Program struct { client *rpc.Client } // DebugproxyCmd is the path to the debugproxy command. It is a variable in case // the default value, "debugproxy", is not in the $PATH. var DebugproxyCmd = "debugproxy" // New connects to the specified host using SSH, starts DebugproxyCmd // there, and creates a new program from the specified file. // The program can then be started by the Run method. func New(host string, textFile string) (*Program, error) { // TODO: add args. cmdStrs := []string{"/usr/bin/ssh", host, DebugproxyCmd, "-text", textFile} if host == "localhost" { cmdStrs = cmdStrs[2:] } cmd := exec.Command(cmdStrs[0], cmdStrs[1:]...) stdin, toStdin, err := os.Pipe() if err != nil { return nil, err } fromStdout, stdout, err := os.Pipe() if err != nil { return nil, err } cmd.Stdin = stdin cmd.Stdout = stdout cmd.Stderr = os.Stderr // Stderr from proxy appears on our stderr. err = cmd.Start() if err != nil { return nil, err } stdout.Close() if msg, err := readLine(fromStdout); err != nil { return nil, err } else if msg != "OK" { // Communication error. return nil, fmt.Errorf("unrecognized message %q", msg) } program := &Program{ client: rpc.NewClient(&rwc{ ssh: cmd, r: fromStdout, w: toStdin, }), } return program, nil } // readLine reads one line of text from the reader. It does no buffering. // The trailing newline is read but not returned. func readLine(r io.Reader) (string, error) { b := make([]byte, 0, 10) var c [1]byte for { _, err := io.ReadFull(r, c[:]) if err != nil { return "", err } if c[0] == '\n' { break } b = append(b, c[0]) } return string(b), nil } // rwc creates a single io.ReadWriteCloser from a read side and a write side. // It also holds the command object so we can wait for SSH to complete. // It allows us to do RPC over an SSH connection. type rwc struct { ssh *exec.Cmd r *os.File w *os.File } func (rwc *rwc) Read(p []byte) (int, error) { return rwc.r.Read(p) } func (rwc *rwc) Write(p []byte) (int, error) { return rwc.w.Write(p) } func (rwc *rwc) Close() error { rerr := rwc.r.Close() werr := rwc.w.Close() cerr := rwc.ssh.Wait() if cerr != nil { // Wait exit status is most important. return cerr } if rerr != nil { return rerr } return werr } func (p *Program) Open(name string, mode string) (debug.File, error) { req := protocol.OpenRequest{ Name: name, Mode: mode, } var resp protocol.OpenResponse err := p.client.Call("Server.Open", &req, &resp) if err != nil { return nil, err } f := &File{ prog: p, fd: resp.FD, } return f, nil } func (p *Program) Run(args ...string) (debug.Status, error) { req := protocol.RunRequest{args} var resp protocol.RunResponse err := p.client.Call("Server.Run", &req, &resp) if err != nil { return debug.Status{}, err } return resp.Status, nil } func (p *Program) Stop() (debug.Status, error) { panic("unimplemented") } func (p *Program) Resume() (debug.Status, error) { req := protocol.ResumeRequest{} var resp protocol.ResumeResponse err := p.client.Call("Server.Resume", &req, &resp) if err != nil { return debug.Status{}, err } return resp.Status, nil } func (p *Program) Kill() (debug.Status, error) { panic("unimplemented") } func (p *Program) Breakpoint(address uint64) ([]uint64, error) { req := protocol.BreakpointRequest{ Address: address, } var resp protocol.BreakpointResponse err := p.client.Call("Server.Breakpoint", &req, &resp) return resp.PCs, err } func (p *Program) BreakpointAtFunction(name string) ([]uint64, error) { req := protocol.BreakpointAtFunctionRequest{ Function: name, } var resp protocol.BreakpointResponse err := p.client.Call("Server.BreakpointAtFunction", &req, &resp) return resp.PCs, err } func (p *Program) BreakpointAtLine(file string, line uint64) ([]uint64, error) { req := protocol.BreakpointAtLineRequest{ File: file, Line: line, } var resp protocol.BreakpointResponse err := p.client.Call("Server.BreakpointAtLine", &req, &resp) return resp.PCs, err } func (p *Program) DeleteBreakpoints(pcs []uint64) error { req := protocol.DeleteBreakpointsRequest{PCs: pcs} var resp protocol.DeleteBreakpointsResponse return p.client.Call("Server.DeleteBreakpoints", &req, &resp) } func (p *Program) Eval(expr string) ([]string, error) { req := protocol.EvalRequest{ Expr: expr, } var resp protocol.EvalResponse err := p.client.Call("Server.Eval", &req, &resp) return resp.Result, err } func (p *Program) Evaluate(e string) (debug.Value, error) { req := protocol.EvaluateRequest{ Expression: e, } var resp protocol.EvaluateResponse err := p.client.Call("Server.Evaluate", &req, &resp) return resp.Result, err } func (p *Program) Frames(count int) ([]debug.Frame, error) { req := protocol.FramesRequest{ Count: count, } var resp protocol.FramesResponse err := p.client.Call("Server.Frames", &req, &resp) return resp.Frames, err } func (p *Program) Goroutines() ([]*debug.Goroutine, error) { req := protocol.GoroutinesRequest{} var resp protocol.GoroutinesResponse err := p.client.Call("Server.Goroutines", &req, &resp) return resp.Goroutines, err } func (p *Program) VarByName(name string) (debug.Var, error) { req := protocol.VarByNameRequest{Name: name} var resp protocol.VarByNameResponse err := p.client.Call("Server.VarByName", &req, &resp) return resp.Var, err } func (p *Program) Value(v debug.Var) (debug.Value, error) { req := protocol.ValueRequest{Var: v} var resp protocol.ValueResponse err := p.client.Call("Server.Value", &req, &resp) return resp.Value, err } func (p *Program) MapElement(m debug.Map, index uint64) (debug.Var, debug.Var, error) { req := protocol.MapElementRequest{Map: m, Index: index} var resp protocol.MapElementResponse err := p.client.Call("Server.MapElement", &req, &resp) return resp.Key, resp.Value, err } // File implements the debug.File interface, providing access // to file-like resources associated with the target program. type File struct { prog *Program // The Program associated with the file. fd int // File descriptor. } func (f *File) ReadAt(p []byte, offset int64) (int, error) { req := protocol.ReadAtRequest{ FD: f.fd, Len: len(p), Offset: offset, } var resp protocol.ReadAtResponse err := f.prog.client.Call("Server.ReadAt", &req, &resp) return copy(p, resp.Data), err } func (f *File) WriteAt(p []byte, offset int64) (int, error) { req := protocol.WriteAtRequest{ FD: f.fd, Data: p, Offset: offset, } var resp protocol.WriteAtResponse err := f.prog.client.Call("Server.WriteAt", &req, &resp) return resp.Len, err } func (f *File) Close() error { req := protocol.CloseRequest{ FD: f.fd, } var resp protocol.CloseResponse err := f.prog.client.Call("Server.Close", &req, &resp) return err } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/server/000077500000000000000000000000001356504100700254345ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/server/dwarf.go000066400000000000000000000055501356504100700270730ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // +build linux package server import ( "errors" "fmt" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/dwarf" ) func (s *Server) functionStartAddress(name string) (uint64, error) { entry, err := s.dwarfData.LookupFunction(name) if err != nil { return 0, err } addrAttr := entry.Val(dwarf.AttrLowpc) if addrAttr == nil { return 0, fmt.Errorf("symbol %q has no LowPC attribute", name) } addr, ok := addrAttr.(uint64) if !ok { return 0, fmt.Errorf("symbol %q has non-uint64 LowPC attribute", name) } return addr, nil } // evalLocation parses a DWARF location description encoded in v. It works for // cases where the variable is stored at an offset from the Canonical Frame // Address. The return value is this offset. // TODO: a more general location-description-parsing function. func evalLocation(v []uint8) (int64, error) { // Some DWARF constants. const ( opConsts = 0x11 opPlus = 0x22 opCallFrameCFA = 0x9C ) if len(v) == 0 { return 0, errors.New("empty location specifier") } if v[0] != opCallFrameCFA { return 0, errors.New("unsupported location specifier") } if len(v) == 1 { // The location description was just DW_OP_call_frame_cfa, so the location is exactly the CFA. return 0, nil } if v[1] != opConsts { return 0, errors.New("unsupported location specifier") } offset, v, err := sleb128(v[2:]) if err != nil { return 0, err } if len(v) == 1 && v[0] == opPlus { // The location description was DW_OP_call_frame_cfa, DW_OP_consts , DW_OP_plus. // So return the offset. return offset, nil } return 0, errors.New("unsupported location specifier") } func uleb128(v []uint8) (u uint64) { var shift uint for _, x := range v { u |= (uint64(x) & 0x7F) << shift shift += 7 if x&0x80 == 0 { break } } return u } // sleb128 parses a signed integer encoded with sleb128 at the start of v, and // returns the integer and the remainder of v. func sleb128(v []uint8) (s int64, rest []uint8, err error) { var shift uint var sign int64 = -1 var i int var x uint8 for i, x = range v { s |= (int64(x) & 0x7F) << shift shift += 7 sign <<= 7 if x&0x80 == 0 { if x&0x40 != 0 { s |= sign } break } } if i == len(v) { return 0, nil, errors.New("truncated sleb128") } return s, v[i+1:], nil } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/server/eval.go000066400000000000000000001420731356504100700267210ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Evaluates Go expressions, using the current values of variables in a program // being debugged. // // TODOs: // More overflow checking. // Stricter type checking. // More expression types. // +build linux package server import ( "errors" "fmt" "go/ast" "go/parser" "go/token" "math" "math/big" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/dwarf" ) const prec = 256 // precision for untyped float and complex constants. var ( // Some big.Ints to use in overflow checks. bigIntMaxInt32 = big.NewInt(math.MaxInt32) bigIntMinInt32 = big.NewInt(math.MinInt32) bigIntMaxInt64 = big.NewInt(math.MaxInt64) bigIntMinInt64 = big.NewInt(math.MinInt64) bigIntMaxUint64 = new(big.Int).SetUint64(math.MaxUint64) ) // result stores an intermediate value produced during evaluation of an expression. // // d contains the DWARF type of the value. For untyped values, d will be nil. // // v contains the value itself. For numeric and bool types, v will have the // corresponding predeclared Go type. // For untyped integer, rune, float, complex, string, and bool constants, v will // have type untInt, untRune, untFloat, untComplex, untString, or bool, // respectively. // For values of type int, uint and uintptr, v will be an int32, int64, uint32 // or uint64 as appropriate. // For address operations, v will have type pointerToValue. // For the operands of address operations, v will have type addressableValue. // Other types are represented using the corresponding implementation of // debug.Value in program.go. // // If an evaluation results in an error, the zero value of result is used. type result struct { d dwarf.Type v interface{} } // untInt is an untyped integer constant type untInt struct { *big.Int } // untRune is an untyped rune constant type untRune struct { *big.Int } // untFloat is an untyped floating-point constant type untFloat struct { *big.Float } // untComplex is an untyped complex constant type untComplex struct { r *big.Float i *big.Float } // untString is an untyped string constant type untString string // pointerToValue is a pointer to a value in memory. // The evaluator constructs these as the result of address operations like "&x". // Unlike debug.Pointer, the DWARF type stored alongside values of this type // is the type of the variable, not the type of the pointer. type pointerToValue struct { a uint64 } // addressableValue is the memory location of a value. // The evaluator constructs these while evaluating the operands of address // operations like "&x", instead of computing the value of x itself. type addressableValue struct { a uint64 } // A sliceOf is a slice created by slicing an array. // Unlike debug.Slice, the DWARF type stored alongside a value of this type is // the type of the slice's elements, not the type of the slice. type sliceOf debug.Slice // ident is a value for representing a special identifier. type ident string // identLookup is a built-in function of the expression evaluator which gets the // value of a global symbol. var identLookup ident = "lookup" // evalExpression evaluates a Go expression. // If the program counter and stack pointer are nonzero, they are used to determine // what local variables are available and where in memory they are. func (s *Server) evalExpression(expression string, pc, sp uint64) (debug.Value, error) { e := evaluator{server: s, expression: expression, pc: pc, sp: sp} node, err := parser.ParseExpr(expression) if err != nil { return nil, err } val := e.evalNode(node, false) if e.evalError != nil { return nil, e.evalError } // Convert untyped constants to their default types. switch v := val.v.(type) { case untInt: return e.intFromInteger(v) case untRune: if v.Cmp(bigIntMaxInt32) == +1 { return nil, errors.New("constant overflows rune") } if v.Cmp(bigIntMinInt32) == -1 { return nil, errors.New("constant overflows rune") } return int32(v.Int64()), nil case untFloat: f, _ := v.Float64() if math.IsInf(f, 0) { return nil, errors.New("constant overflows float64") } if math.IsNaN(f) { return nil, errors.New("constant is NaN") } return f, nil case untComplex: r, _ := v.r.Float64() i, _ := v.i.Float64() if math.IsInf(r, 0) || math.IsInf(i, 0) { return nil, errors.New("constant overflows complex128") } if math.IsNaN(r) || math.IsNaN(i) { return nil, errors.New("constant is NaN") } return complex(r, i), nil case untString: return debug.String{Length: uint64(len(v)), String: string(v)}, nil case pointerToValue: return debug.Pointer{TypeID: uint64(val.d.Common().Offset), Address: v.a}, nil case sliceOf: return debug.Slice(v), nil case nil, addressableValue: // This case should not be reachable. return nil, errors.New("unknown error") } return val.v, nil } type evaluator struct { // expression is the expression being evaluated. expression string // server interacts with the program being debugged. server *Server // curNode is the current parse tree node. This is set so that error messages // can quote the part of the expression that caused an error. curNode ast.Node // evalError is the first error that occurred while evaluating the expression, // or nil if no error has occurred. evalError error // pc and sp are the current program counter and stack pointer, used for // finding local variables. If either are zero, the expression is evaluated // without using local variables. pc uint64 sp uint64 } // setNode sets curNode, and returns curNode's previous value. func (e *evaluator) setNode(node ast.Node) (old ast.Node) { old, e.curNode = e.curNode, node return old } // err saves an error that occurred during evaluation. // It returns a zero result, so that functions can exit and set an error with // return e.err(...) func (e *evaluator) err(s string) result { if e.evalError != nil { return result{} } // Append the substring of the expression that corresponds to the current AST node. start := int(e.curNode.Pos() - 1) end := int(e.curNode.End() - 1) if start < 0 { start = 0 } if end > len(e.expression) { end = len(e.expression) } if start > end { start, end = 0, 0 } e.evalError = errors.New(s + `: "` + e.expression[start:end] + `"`) return result{} } // evalNode computes the value of a node in the expression tree. // If getAddress is true, the node is the argument of an & operator, so evalNode // will return a result with a value of type addressableValue if possible. func (e *evaluator) evalNode(node ast.Node, getAddress bool) result { // Set the current node in the evaluator, so that error messages can refer to // it. Defer a function call that changes it back. defer e.setNode(e.setNode(node)) switch n := node.(type) { case *ast.Ident: if e.pc != 0 && e.sp != 0 { a, t := e.server.findLocalVar(n.Name, e.pc, e.sp) if t != nil { return e.resultFrom(a, t, getAddress) } } a, t := e.server.findGlobalVar(n.Name) if t != nil { return e.resultFrom(a, t, getAddress) } switch n.Name { // Note: these could have been redefined as constants in the code, but we // don't have a way to detect that. case "true": return result{nil, true} case "false": return result{nil, false} case "lookup": return result{nil, identLookup} } return e.err("unknown identifier") case *ast.BasicLit: switch n.Kind { case token.INT: i := new(big.Int) if _, ok := i.SetString(n.Value, 0); !ok { return e.err("invalid integer constant") } return result{nil, untInt{i}} case token.FLOAT: r, _, err := big.ParseFloat(n.Value, 10, prec, big.ToNearestEven) if err != nil { return e.err(err.Error()) } return result{nil, untFloat{r}} case token.IMAG: if len(n.Value) <= 1 || n.Value[len(n.Value)-1] != 'i' { return e.err("invalid imaginary constant") } r, _, err := big.ParseFloat(n.Value[:len(n.Value)-1], 10, prec, big.ToNearestEven) if err != nil { return e.err(err.Error()) } return result{nil, untComplex{new(big.Float), r}} case token.CHAR: // TODO: unescaping return result{nil, untRune{new(big.Int).SetInt64(int64(n.Value[1]))}} case token.STRING: // TODO: unescaping if len(n.Value) <= 1 { return e.err("invalid string constant") } return result{nil, untString(n.Value[1 : len(n.Value)-1])} } case *ast.ParenExpr: return e.evalNode(n.X, getAddress) case *ast.StarExpr: x := e.evalNode(n.X, false) switch v := x.v.(type) { case debug.Pointer: // x.d may be a typedef pointing to a pointer type (or a typedef pointing // to a typedef pointing to a pointer type, etc.), so remove typedefs // until we get the underlying pointer type. t := followTypedefs(x.d) if pt, ok := t.(*dwarf.PtrType); ok { return e.resultFrom(v.Address, pt.Type, getAddress) } else { return e.err("invalid DWARF type for pointer") } case pointerToValue: return e.resultFrom(v.a, x.d, getAddress) case nil: return x } return e.err("invalid indirect") case *ast.SelectorExpr: x := e.evalNode(n.X, false) sel := n.Sel.Name switch v := x.v.(type) { case debug.Struct: for _, f := range v.Fields { if f.Name == sel { t, err := e.server.dwarfData.Type(dwarf.Offset(f.Var.TypeID)) if err != nil { return e.err(err.Error()) } return e.resultFrom(f.Var.Address, t, getAddress) } } return e.err("struct field not found") case debug.Pointer: pt, ok := followTypedefs(x.d).(*dwarf.PtrType) // x.d should be a pointer to struct. if !ok { return e.err("invalid DWARF information for pointer") } st, ok := followTypedefs(pt.Type).(*dwarf.StructType) if !ok { break } for _, f := range st.Field { if f.Name == sel { return e.resultFrom(v.Address+uint64(f.ByteOffset), f.Type, getAddress) } } return e.err("struct field not found") case pointerToValue: st, ok := followTypedefs(x.d).(*dwarf.StructType) // x.d should be a struct. if !ok { break } for _, f := range st.Field { if f.Name == sel { return e.resultFrom(v.a+uint64(f.ByteOffset), f.Type, getAddress) } } return e.err("struct field not found") } return e.err("invalid selector expression") case *ast.IndexExpr: x, index := e.evalNode(n.X, false), e.evalNode(n.Index, false) if x.v == nil || index.v == nil { return result{} } // The expression is x[index] if m, ok := x.v.(debug.Map); ok { if getAddress { return e.err("can't take address of map value") } mt, ok := followTypedefs(x.d).(*dwarf.MapType) if !ok { return e.err("invalid DWARF type for map") } var ( found bool // true if the key was found value result // the map value for the key abort bool // true if an error occurred while searching // fn is a function that checks if one (key, value) pair corresponds // to the index in the expression. fn = func(keyAddr, valAddr uint64, keyType, valType dwarf.Type) bool { key := e.resultFrom(keyAddr, keyType, false) if key.v == nil { abort = true return false // stop searching map } equal, ok := e.evalBinaryOp(token.EQL, index, key).v.(bool) if !ok { abort = true return false // stop searching map } if equal { found = true value = e.resultFrom(valAddr, valType, false) return false // stop searching map } return true // continue searching map } ) if err := e.server.peekMapValues(mt, m.Address, fn); err != nil { return e.err(err.Error()) } if abort { // Some operation on individual map keys failed. return result{} } if found { return value } // The key wasn't in the map; return the zero value. return e.zero(mt.ElemType) } // The index should be a non-negative integer for the remaining cases. u, err := uint64FromResult(index) if err != nil { return e.err("invalid index: " + err.Error()) } switch v := x.v.(type) { case debug.Array: if u >= v.Length { return e.err("array index out of bounds") } elemType, err := e.server.dwarfData.Type(dwarf.Offset(v.ElementTypeID)) if err != nil { return e.err(err.Error()) } return e.resultFrom(v.Element(u).Address, elemType, getAddress) case debug.Slice: if u >= v.Length { return e.err("slice index out of bounds") } elemType, err := e.server.dwarfData.Type(dwarf.Offset(v.ElementTypeID)) if err != nil { return e.err(err.Error()) } return e.resultFrom(v.Element(u).Address, elemType, getAddress) case sliceOf: if u >= v.Length { return e.err("slice index out of bounds") } return e.resultFrom(v.Element(u).Address, x.d, getAddress) case debug.String: if getAddress { return e.err("can't take address of string element") } if u >= v.Length { return e.err("string index out of bounds") } if u >= uint64(len(v.String)) { return e.err("string element unavailable") } return e.uint8Result(v.String[u]) case untString: if getAddress { return e.err("can't take address of string element") } if u >= uint64(len(v)) { return e.err("string index out of bounds") } return e.uint8Result(v[u]) } return e.err("invalid index expression") case *ast.SliceExpr: if n.Slice3 && n.High == nil { return e.err("middle index required in full slice") } if n.Slice3 && n.Max == nil { return e.err("final index required in full slice") } var ( low, high, max uint64 err error ) if n.Low != nil { low, err = uint64FromResult(e.evalNode(n.Low, false)) if err != nil { return e.err("invalid slice lower bound: " + err.Error()) } } if n.High != nil { high, err = uint64FromResult(e.evalNode(n.High, false)) if err != nil { return e.err("invalid slice upper bound: " + err.Error()) } } if n.Max != nil { max, err = uint64FromResult(e.evalNode(n.Max, false)) if err != nil { return e.err("invalid slice capacity: " + err.Error()) } } x := e.evalNode(n.X, false) switch v := x.v.(type) { case debug.Array, debug.Pointer, pointerToValue: // This case handles the slicing of arrays and pointers to arrays. var arr debug.Array switch v := x.v.(type) { case debug.Array: arr = v case debug.Pointer: pt, ok := followTypedefs(x.d).(*dwarf.PtrType) if !ok { return e.err("invalid DWARF type for pointer") } a := e.resultFrom(v.Address, pt.Type, false) arr, ok = a.v.(debug.Array) if !ok { // v is a pointer to something other than an array. return e.err("cannot slice pointer") } case pointerToValue: a := e.resultFrom(v.a, x.d, false) var ok bool arr, ok = a.v.(debug.Array) if !ok { // v is a pointer to something other than an array. return e.err("cannot slice pointer") } } elemType, err := e.server.dwarfData.Type(dwarf.Offset(arr.ElementTypeID)) if err != nil { return e.err(err.Error()) } if n.High == nil { high = arr.Length } else if high > arr.Length { return e.err("slice upper bound is too large") } if n.Max == nil { max = arr.Length } else if max > arr.Length { return e.err("slice capacity is too large") } if low > high || high > max { return e.err("invalid slice index") } return result{ d: elemType, v: sliceOf{ Array: debug.Array{ ElementTypeID: arr.ElementTypeID, Address: arr.Element(low).Address, Length: high - low, StrideBits: uint64(elemType.Common().ByteSize) * 8, }, Capacity: max - low, }, } case debug.Slice: if n.High == nil { high = v.Length } else if high > v.Capacity { return e.err("slice upper bound is too large") } if n.Max == nil { max = v.Capacity } else if max > v.Capacity { return e.err("slice capacity is too large") } if low > high || high > max { return e.err("invalid slice index") } v.Address += low * (v.StrideBits / 8) v.Length = high - low v.Capacity = max - low return result{x.d, v} case sliceOf: if n.High == nil { high = v.Length } else if high > v.Capacity { return e.err("slice upper bound is too large") } if n.Max == nil { max = v.Capacity } else if max > v.Capacity { return e.err("slice capacity is too large") } if low > high || high > max { return e.err("invalid slice index") } v.Address += low * (v.StrideBits / 8) v.Length = high - low v.Capacity = max - low return result{x.d, v} case debug.String: if n.Max != nil { return e.err("full slice of string") } if n.High == nil { high = v.Length } if low > high || high > v.Length { return e.err("invalid slice index") } v.Length = high - low if low > uint64(len(v.String)) { // v.String was truncated before the point where this slice starts. v.String = "" } else { if high > uint64(len(v.String)) { // v.String was truncated before the point where this slice ends. high = uint64(len(v.String)) } v.String = v.String[low:high] } return result{x.d, v} case untString: if n.Max != nil { return e.err("full slice of string") } if n.High == nil { high = uint64(len(v)) } if low > high { return e.err("invalid slice expression") } if high > uint64(len(v)) { return e.err("slice upper bound is too large") } return e.stringResult(string(v[low:high])) default: return e.err("invalid slice expression") } case *ast.CallExpr: // Only supports lookup("x"), which gets the value of a global symbol x. fun := e.evalNode(n.Fun, false) var args []result for _, a := range n.Args { args = append(args, e.evalNode(a, false)) } if fun.v == identLookup { if len(args) != 1 { return e.err("lookup should have one argument") } ident, ok := args[0].v.(untString) if !ok { return e.err("argument for lookup should be a string constant") } if a, t := e.server.findGlobalVar(string(ident)); t == nil { return e.err("symbol not found") } else { return e.resultFrom(a, t, getAddress) } } return e.err("function calls not implemented") case *ast.UnaryExpr: if n.Op == token.AND { x := e.evalNode(n.X, true) switch v := x.v.(type) { case addressableValue: return result{x.d, pointerToValue{v.a}} case nil: return x } return e.err("can't take address") } x := e.evalNode(n.X, false) if x.v == nil { return x } switch v := x.v.(type) { case int8: switch n.Op { case token.ADD: case token.SUB: v = -v case token.XOR: v = ^v default: return e.err("invalid operation") } return result{x.d, v} case int16: switch n.Op { case token.ADD: case token.SUB: v = -v case token.XOR: v = ^v default: return e.err("invalid operation") } return result{x.d, v} case int32: switch n.Op { case token.ADD: case token.SUB: v = -v case token.XOR: v = ^v default: return e.err("invalid operation") } return result{x.d, v} case int64: switch n.Op { case token.ADD: case token.SUB: v = -v case token.XOR: v = ^v default: return e.err("invalid operation") } return result{x.d, v} case uint8: switch n.Op { case token.ADD: case token.SUB: v = -v case token.XOR: v = ^v default: return e.err("invalid operation") } return result{x.d, v} case uint16: switch n.Op { case token.ADD: case token.SUB: v = -v case token.XOR: v = ^v default: return e.err("invalid operation") } return result{x.d, v} case uint32: switch n.Op { case token.ADD: case token.SUB: v = -v case token.XOR: v = ^v default: return e.err("invalid operation") } return result{x.d, v} case uint64: switch n.Op { case token.ADD: case token.SUB: v = -v case token.XOR: v = ^v default: return e.err("invalid operation") } return result{x.d, v} case float32: switch n.Op { case token.ADD: case token.SUB: v = -v default: return e.err("invalid operation") } return result{x.d, v} case float64: switch n.Op { case token.ADD: case token.SUB: v = -v default: return e.err("invalid operation") } return result{x.d, v} case complex64: switch n.Op { case token.ADD: case token.SUB: v = -v default: return e.err("invalid operation") } return result{x.d, v} case complex128: switch n.Op { case token.ADD: case token.SUB: v = -v default: return e.err("invalid operation") } return result{x.d, v} case untInt: switch n.Op { case token.ADD: case token.SUB: v.Int.Neg(v.Int) case token.XOR: v.Int.Not(v.Int) default: return e.err("invalid operation") } return result{x.d, v} case untRune: switch n.Op { case token.ADD: case token.SUB: v.Int.Neg(v.Int) case token.XOR: v.Int.Not(v.Int) default: return e.err("invalid operation") } return result{x.d, v} case untFloat: switch n.Op { case token.ADD: case token.SUB: v.Float.Neg(v.Float) default: return e.err("invalid operation") } return result{x.d, v} case untComplex: switch n.Op { case token.ADD: case token.SUB: v.r.Neg(v.r) v.i.Neg(v.i) default: return e.err("invalid operation") } return result{x.d, v} case bool: switch n.Op { case token.NOT: v = !v default: return e.err("invalid operation") } return result{x.d, v} } case *ast.BinaryExpr: x := e.evalNode(n.X, false) if x.v == nil { return x } y := e.evalNode(n.Y, false) if y.v == nil { return y } return e.evalBinaryOp(n.Op, x, y) } return e.err("invalid expression") } // evalBinaryOp evaluates a binary operator op applied to x and y. func (e *evaluator) evalBinaryOp(op token.Token, x, y result) result { if op == token.NEQ { tmp := e.evalBinaryOp(token.EQL, x, y) b, ok := tmp.v.(bool) if !ok { return tmp } return result{nil, !b} } if op == token.GTR { return e.evalBinaryOp(token.LSS, y, x) } if op == token.GEQ { return e.evalBinaryOp(token.LEQ, x, y) } x = convertUntyped(x, y) y = convertUntyped(y, x) switch a := x.v.(type) { case int8: b, ok := y.v.(int8) if !ok { return e.err("type mismatch") } var c int8 switch op { case token.EQL: return result{nil, a == b} case token.LSS: return result{nil, a < b} case token.LEQ: return result{nil, a <= b} case token.ADD: c = a + b case token.SUB: c = a - b case token.OR: c = a | b case token.XOR: c = a ^ b case token.MUL: c = a * b case token.QUO: if b == 0 { return e.err("integer divide by zero") } c = a / b case token.REM: if b == 0 { return e.err("integer divide by zero") } c = a % b case token.AND: c = a & b case token.AND_NOT: c = a &^ b default: return e.err("invalid operation") } return result{x.d, c} case int16: b, ok := y.v.(int16) if !ok { return e.err("type mismatch") } var c int16 switch op { case token.EQL: return result{nil, a == b} case token.LSS: return result{nil, a < b} case token.LEQ: return result{nil, a <= b} case token.ADD: c = a + b case token.SUB: c = a - b case token.OR: c = a | b case token.XOR: c = a ^ b case token.MUL: c = a * b case token.QUO: if b == 0 { return e.err("integer divide by zero") } c = a / b case token.REM: if b == 0 { return e.err("integer divide by zero") } c = a % b case token.AND: c = a & b case token.AND_NOT: c = a &^ b default: return e.err("invalid operation") } return result{x.d, c} case int32: b, ok := y.v.(int32) if !ok { return e.err("type mismatch") } var c int32 switch op { case token.EQL: return result{nil, a == b} case token.LSS: return result{nil, a < b} case token.LEQ: return result{nil, a <= b} case token.ADD: c = a + b case token.SUB: c = a - b case token.OR: c = a | b case token.XOR: c = a ^ b case token.MUL: c = a * b case token.QUO: if b == 0 { return e.err("integer divide by zero") } c = a / b case token.REM: if b == 0 { return e.err("integer divide by zero") } c = a % b case token.AND: c = a & b case token.AND_NOT: c = a &^ b default: return e.err("invalid operation") } return result{x.d, c} case int64: b, ok := y.v.(int64) if !ok { return e.err("type mismatch") } var c int64 switch op { case token.EQL: return result{nil, a == b} case token.LSS: return result{nil, a < b} case token.LEQ: return result{nil, a <= b} case token.ADD: c = a + b case token.SUB: c = a - b case token.OR: c = a | b case token.XOR: c = a ^ b case token.MUL: c = a * b case token.QUO: if b == 0 { return e.err("integer divide by zero") } c = a / b case token.REM: if b == 0 { return e.err("integer divide by zero") } c = a % b case token.AND: c = a & b case token.AND_NOT: c = a &^ b default: return e.err("invalid operation") } return result{x.d, c} case uint8: b, ok := y.v.(uint8) if !ok { return e.err("type mismatch") } var c uint8 switch op { case token.EQL: return result{nil, a == b} case token.LSS: return result{nil, a < b} case token.LEQ: return result{nil, a <= b} case token.ADD: c = a + b case token.SUB: c = a - b case token.OR: c = a | b case token.XOR: c = a ^ b case token.MUL: c = a * b case token.QUO: if b == 0 { return e.err("integer divide by zero") } c = a / b case token.REM: if b == 0 { return e.err("integer divide by zero") } c = a % b case token.AND: c = a & b case token.AND_NOT: c = a &^ b default: return e.err("invalid operation") } return result{x.d, c} case uint16: b, ok := y.v.(uint16) if !ok { return e.err("type mismatch") } var c uint16 switch op { case token.EQL: return result{nil, a == b} case token.LSS: return result{nil, a < b} case token.LEQ: return result{nil, a <= b} case token.ADD: c = a + b case token.SUB: c = a - b case token.OR: c = a | b case token.XOR: c = a ^ b case token.MUL: c = a * b case token.QUO: if b == 0 { return e.err("integer divide by zero") } c = a / b case token.REM: if b == 0 { return e.err("integer divide by zero") } c = a % b case token.AND: c = a & b case token.AND_NOT: c = a &^ b default: return e.err("invalid operation") } return result{x.d, c} case uint32: b, ok := y.v.(uint32) if !ok { return e.err("type mismatch") } var c uint32 switch op { case token.EQL: return result{nil, a == b} case token.LSS: return result{nil, a < b} case token.LEQ: return result{nil, a <= b} case token.ADD: c = a + b case token.SUB: c = a - b case token.OR: c = a | b case token.XOR: c = a ^ b case token.MUL: c = a * b case token.QUO: if b == 0 { return e.err("integer divide by zero") } c = a / b case token.REM: if b == 0 { return e.err("integer divide by zero") } c = a % b case token.AND: c = a & b case token.AND_NOT: c = a &^ b default: return e.err("invalid operation") } return result{x.d, c} case uint64: b, ok := y.v.(uint64) if !ok { return e.err("type mismatch") } var c uint64 switch op { case token.EQL: return result{nil, a == b} case token.LSS: return result{nil, a < b} case token.LEQ: return result{nil, a <= b} case token.ADD: c = a + b case token.SUB: c = a - b case token.OR: c = a | b case token.XOR: c = a ^ b case token.MUL: c = a * b case token.QUO: if b == 0 { return e.err("integer divide by zero") } c = a / b case token.REM: if b == 0 { return e.err("integer divide by zero") } c = a % b case token.AND: c = a & b case token.AND_NOT: c = a &^ b default: return e.err("invalid operation") } return result{x.d, c} case float32: b, ok := y.v.(float32) if !ok { return e.err("type mismatch") } var c float32 switch op { case token.EQL: return result{nil, a == b} case token.LSS: return result{nil, a < b} case token.LEQ: return result{nil, a <= b} case token.ADD: c = a + b case token.SUB: c = a - b case token.MUL: c = a * b case token.QUO: c = a / b default: return e.err("invalid operation") } return result{x.d, c} case float64: b, ok := y.v.(float64) if !ok { return e.err("type mismatch") } var c float64 switch op { case token.EQL: return result{nil, a == b} case token.LSS: return result{nil, a < b} case token.LEQ: return result{nil, a <= b} case token.ADD: c = a + b case token.SUB: c = a - b case token.MUL: c = a * b case token.QUO: c = a / b default: return e.err("invalid operation") } return result{x.d, c} case complex64: b, ok := y.v.(complex64) if !ok { return e.err("type mismatch") } var c complex64 switch op { case token.EQL: return result{nil, a == b} case token.ADD: c = a + b case token.SUB: c = a - b case token.MUL: c = a * b case token.QUO: c = a / b default: return e.err("invalid operation") } return result{x.d, c} case complex128: b, ok := y.v.(complex128) if !ok { return e.err("type mismatch") } var c complex128 switch op { case token.EQL: return result{nil, a == b} case token.ADD: c = a + b case token.SUB: c = a - b case token.MUL: c = a * b case token.QUO: c = a / b default: return e.err("invalid operation") } return result{x.d, c} case bool: b, ok := y.v.(bool) if !ok { return e.err("type mismatch") } var c bool switch op { case token.LOR: c = a || b case token.LAND: c = a && b case token.EQL: c = a == b default: return e.err("invalid operation") } return result{x.d, c} case debug.String: b, ok := y.v.(debug.String) if !ok { return e.err("type mismatch") } var c debug.String switch op { // TODO: these comparison operators only use the part of the string that // was read. Very large strings do not have their entire contents read by // server.value. case token.EQL: return result{nil, a.Length == b.Length && a.String == b.String} case token.LSS: return result{nil, a.String < b.String} case token.LEQ: return result{nil, a.String <= b.String} case token.ADD: c.Length = a.Length + b.Length if a.Length == uint64(len(a.String)) { c.String = a.String + b.String } else { // The first string was truncated at a.Length characters, so the sum // must be truncated there too. c.String = a.String } default: return e.err("invalid operation") } return result{x.d, c} case untString: b, ok := y.v.(untString) if !ok { return e.err("type mismatch") } var c untString switch op { case token.EQL: return result{nil, a == b} case token.LSS: return result{nil, a < b} case token.LEQ: return result{nil, a <= b} case token.ADD: c = a + b default: return e.err("invalid operation") } return result{x.d, c} case untInt: i := a.Int b, ok := y.v.(untInt) if !ok { return e.err("type mismatch") } switch op { case token.EQL: return result{nil, i.Cmp(b.Int) == 0} case token.LSS: return result{nil, i.Cmp(b.Int) < 0} case token.LEQ: return result{nil, i.Cmp(b.Int) <= 0} } c := new(big.Int) switch op { case token.ADD: c.Add(i, b.Int) case token.SUB: c.Sub(i, b.Int) case token.OR: c.Or(i, b.Int) case token.XOR: c.Xor(i, b.Int) case token.MUL: c.Mul(i, b.Int) case token.QUO: if b.Sign() == 0 { return e.err("integer divide by zero") } c.Quo(i, b.Int) case token.REM: if b.Sign() == 0 { return e.err("integer divide by zero") } c.Mod(i, b.Int) case token.AND: c.And(i, b.Int) case token.AND_NOT: c.AndNot(i, b.Int) default: return e.err("invalid operation") } return result{nil, untInt{c}} case untRune: i := a.Int b, ok := y.v.(untRune) if !ok { return e.err("type mismatch") } switch op { case token.EQL: return result{nil, i.Cmp(b.Int) == 0} case token.LSS: return result{nil, i.Cmp(b.Int) < 0} case token.LEQ: return result{nil, i.Cmp(b.Int) <= 0} } c := new(big.Int) switch op { case token.ADD: c.Add(i, b.Int) case token.SUB: c.Sub(i, b.Int) case token.OR: c.Or(i, b.Int) case token.XOR: c.Xor(i, b.Int) case token.MUL: c.Mul(i, b.Int) case token.QUO: if b.Sign() == 0 { return e.err("integer divide by zero") } c.Quo(i, b.Int) case token.REM: if b.Sign() == 0 { return e.err("integer divide by zero") } c.Mod(i, b.Int) case token.AND: c.And(i, b.Int) case token.AND_NOT: c.AndNot(i, b.Int) default: return e.err("invalid operation") } return result{nil, untRune{c}} case untFloat: r := a.Float b, ok := y.v.(untFloat) if !ok { return e.err("type mismatch") } switch op { case token.EQL: return result{nil, r.Cmp(b.Float) == 0} case token.LSS: return result{nil, r.Cmp(b.Float) < 0} case token.LEQ: return result{nil, r.Cmp(b.Float) <= 0} } c := new(big.Float) switch op { case token.ADD: c.Add(r, b.Float) case token.SUB: c.Sub(r, b.Float) case token.MUL: c.Mul(r, b.Float) case token.QUO: if b.Sign() == 0 { return e.err("divide by zero") } c.Quo(r, b.Float) default: return e.err("invalid operation") } return result{nil, untFloat{c}} case untComplex: b, ok := y.v.(untComplex) if !ok { return e.err("type mismatch") } var ( ar = a.r br = b.r ai = a.i bi = b.i ) if op == token.EQL { return result{nil, ar.Cmp(br) == 0 && ai.Cmp(bi) == 0} } var ( cr = new(big.Float) ci = new(big.Float) ) switch op { case token.ADD: cr.Add(ar, br) ci.Add(ai, bi) case token.SUB: cr.Sub(ar, br) ci.Sub(ai, bi) case token.MUL: var t0, t1 big.Float t0.Mul(ar, br) t1.Mul(ai, bi) cr.Sub(&t0, &t1) t0.Mul(ar, bi) t1.Mul(ai, br) ci.Add(&t0, &t1) case token.QUO: // a/b = a*conj(b)/|b|^2 var t0, t1 big.Float cr.Mul(ar, br) t0.Mul(ai, bi) cr.Add(cr, &t0) // cr = Re(a*conj(b)) ci.Mul(ai, br) t0.Mul(ar, bi) ci.Sub(ci, &t0) // ci = Im(a*conj(b)) t0.Mul(br, br) t1.Mul(bi, bi) t0.Add(&t0, &t1) // t0 = |b|^2 if t0.Sign() == 0 { return e.err("divide by zero") } cr.Quo(cr, &t0) // cr = Re(a*conj(b))/|b|^2 = Re(a/b) ci.Quo(ci, &t0) // ci = Im(a*conj(b))/|b|^2 = Im(a/b) } return result{nil, untComplex{cr, ci}} } return e.err("invalid operation") } // findLocalVar finds a local variable (or function parameter) by name, and // returns its address and DWARF type. It returns a nil type on failure. // The PC and SP are used to determine the current function and stack frame. func (s *Server) findLocalVar(name string, pc, sp uint64) (uint64, dwarf.Type) { // Find the DWARF entry for the function at pc. funcEntry, _, err := s.dwarfData.PCToFunction(uint64(pc)) if err != nil { return 0, nil } // Compute the stack frame pointer. fpOffset, err := s.dwarfData.PCToSPOffset(uint64(pc)) if err != nil { return 0, nil } framePointer := sp + uint64(fpOffset) // Check each child of the function's DWARF entry to see if it is a parameter // or local variable with the right name. If so, return its address and type. r := s.dwarfData.Reader() r.Seek(funcEntry.Offset) for { varEntry, err := r.Next() if err != nil { break } if varEntry.Tag == 0 { // This tag marks the end of the function's DWARF entry's children. break } // Check this entry corresponds to a local variable or function parameter, // that it has the correct name, and that we can get its type and location. // If so, return them. if varEntry.Tag != dwarf.TagFormalParameter && varEntry.Tag != dwarf.TagVariable { continue } varName, ok := varEntry.Val(dwarf.AttrName).(string) if !ok { continue } if varName != name { continue } varTypeOffset, ok := varEntry.Val(dwarf.AttrType).(dwarf.Offset) if !ok { continue } varType, err := s.dwarfData.Type(varTypeOffset) if err != nil { continue } locationAttribute := varEntry.Val(dwarf.AttrLocation) if locationAttribute == nil { continue } locationDescription, ok := locationAttribute.([]uint8) if !ok { continue } frameOffset, err := evalLocation(locationDescription) if err != nil { continue } return framePointer + uint64(frameOffset), varType } return 0, nil } // findGlobalVar finds a global variable by name, and returns its address and // DWARF type. It returns a nil type on failure. func (s *Server) findGlobalVar(name string) (uint64, dwarf.Type) { entry, err := s.dwarfData.LookupVariable(name) if err != nil { return 0, nil } loc, err := s.dwarfData.EntryLocation(entry) if err != nil { return 0, nil } ofs, err := s.dwarfData.EntryTypeOffset(entry) if err != nil { return 0, nil } typ, err := s.dwarfData.Type(ofs) if err != nil { return 0, nil } return loc, typ } // intFromInteger converts an untyped integer constant to an int32 or int64, // depending on the int size of the debugged program. // It returns an error on overflow, or if it can't determine the int size. func (e *evaluator) intFromInteger(v untInt) (interface{}, error) { t, ok := e.getBaseType("int") if !ok { return nil, errors.New("couldn't get int size from DWARF info") } switch t.Common().ByteSize { case 4: if v.Cmp(bigIntMaxInt32) == +1 || v.Cmp(bigIntMinInt32) == -1 { return nil, errors.New("constant overflows int") } return int32(v.Int64()), nil case 8: if v.Cmp(bigIntMaxInt64) == +1 || v.Cmp(bigIntMinInt64) == -1 { return nil, errors.New("constant overflows int") } return v.Int64(), nil } return nil, errors.New("invalid int size in DWARF info") } // uint8Result constructs a result for a uint8 value. func (e *evaluator) uint8Result(v uint8) result { t, ok := e.getBaseType("uint8") if !ok { e.err("couldn't construct uint8") } return result{t, uint8(v)} } // stringResult constructs a result for a string value. func (e *evaluator) stringResult(s string) result { t, ok := e.getBaseType("string") if !ok { e.err("couldn't construct string") } return result{t, debug.String{Length: uint64(len(s)), String: s}} } // getBaseType returns the *dwarf.Type with a given name. // TODO: cache this. func (e *evaluator) getBaseType(name string) (dwarf.Type, bool) { entry, err := e.server.dwarfData.LookupEntry(name) if err != nil { return nil, false } t, err := e.server.dwarfData.Type(entry.Offset) if err != nil { return nil, false } return t, true } // resultFrom constructs a result corresponding to a value in the program with // the given address and DWARF type. // If getAddress is true, the result will be the operand of an address expression, // so resultFrom returns a result containing a value of type addressableValue. func (e *evaluator) resultFrom(a uint64, t dwarf.Type, getAddress bool) result { if a == 0 { return e.err("nil pointer dereference") } if getAddress { return result{t, addressableValue{a}} } v, err := e.server.value(t, a) if err != nil { return e.err(err.Error()) } return result{t, v} } // zero returns the zero value of type t. // TODO: implement for array and struct. func (e *evaluator) zero(t dwarf.Type) result { var v interface{} switch typ := followTypedefs(t).(type) { case *dwarf.CharType, *dwarf.IntType, *dwarf.EnumType: switch typ.Common().ByteSize { case 1: v = int8(0) case 2: v = int16(0) case 4: v = int32(0) case 8: v = int64(0) default: return e.err("invalid integer size " + fmt.Sprint(typ.Common().ByteSize)) } case *dwarf.UcharType, *dwarf.UintType: switch typ.Common().ByteSize { case 1: v = uint8(0) case 2: v = uint16(0) case 4: v = uint32(0) case 8: v = uint64(0) default: return e.err("invalid unsigned integer size " + fmt.Sprint(typ.Common().ByteSize)) } case *dwarf.FloatType: switch typ.Common().ByteSize { case 4: v = float32(0) case 8: v = float64(0) default: return e.err("invalid float size " + fmt.Sprint(typ.Common().ByteSize)) } case *dwarf.ComplexType: switch typ.Common().ByteSize { case 8: v = complex64(0) case 16: v = complex128(0) default: return e.err("invalid complex size " + fmt.Sprint(typ.Common().ByteSize)) } case *dwarf.BoolType: v = false case *dwarf.PtrType: v = debug.Pointer{TypeID: uint64(t.Common().Offset)} case *dwarf.SliceType: v = debug.Slice{ Array: debug.Array{ ElementTypeID: uint64(typ.ElemType.Common().Offset), StrideBits: uint64(typ.ElemType.Common().ByteSize) * 8, }, } case *dwarf.StringType: v = debug.String{} case *dwarf.InterfaceType: v = debug.Interface{} case *dwarf.FuncType: v = debug.Func{} case *dwarf.MapType: v = debug.Map{TypeID: uint64(t.Common().Offset)} case *dwarf.ChanType: v = debug.Channel{ ElementTypeID: uint64(typ.ElemType.Common().Offset), Stride: uint64(typ.ElemType.Common().ByteSize), } default: return e.err("can't get zero value of this type") } return result{t, v} } // convertUntyped converts x to be the same type as y, if x is untyped and the // conversion is possible. // // An untyped bool can be converted to a boolean type. // An untyped string can be converted to a string type. // An untyped integer, rune, float or complex value can be converted to a // numeric type, or to an untyped value later in that list. // // x is returned unchanged if none of these cases apply. func convertUntyped(x, y result) result { switch a := x.v.(type) { case untInt: i := a.Int switch y.v.(type) { case int8: return result{y.d, int8(i.Int64())} case int16: return result{y.d, int16(i.Int64())} case int32: return result{y.d, int32(i.Int64())} case int64: return result{y.d, int64(i.Int64())} case uint8: return result{y.d, uint8(i.Uint64())} case uint16: return result{y.d, uint16(i.Uint64())} case uint32: return result{y.d, uint32(i.Uint64())} case uint64: return result{y.d, uint64(i.Uint64())} case float32: f, _ := new(big.Float).SetInt(i).Float32() return result{y.d, f} case float64: f, _ := new(big.Float).SetInt(i).Float64() return result{y.d, f} case complex64: f, _ := new(big.Float).SetInt(i).Float32() return result{y.d, complex(f, 0)} case complex128: f, _ := new(big.Float).SetInt(i).Float64() return result{y.d, complex(f, 0)} case untRune: return result{nil, untRune{i}} case untFloat: return result{nil, untFloat{new(big.Float).SetPrec(prec).SetInt(i)}} case untComplex: return result{nil, untComplex{new(big.Float).SetPrec(prec).SetInt(i), new(big.Float)}} } case untRune: i := a.Int switch y.v.(type) { case int8: return result{y.d, int8(i.Int64())} case int16: return result{y.d, int16(i.Int64())} case int32: return result{y.d, int32(i.Int64())} case int64: return result{y.d, int64(i.Int64())} case uint8: return result{y.d, uint8(i.Uint64())} case uint16: return result{y.d, uint16(i.Uint64())} case uint32: return result{y.d, uint32(i.Uint64())} case uint64: return result{y.d, uint64(i.Uint64())} case float32: f, _ := new(big.Float).SetInt(i).Float32() return result{y.d, f} case float64: f, _ := new(big.Float).SetInt(i).Float64() return result{y.d, f} case complex64: f, _ := new(big.Float).SetInt(i).Float32() return result{y.d, complex(f, 0)} case complex128: f, _ := new(big.Float).SetInt(i).Float64() return result{y.d, complex(f, 0)} case untRune: return result{nil, untRune{i}} case untFloat: return result{nil, untFloat{new(big.Float).SetPrec(prec).SetInt(i)}} case untComplex: return result{nil, untComplex{new(big.Float).SetPrec(prec).SetInt(i), new(big.Float)}} } case untFloat: if a.IsInt() { i, _ := a.Int(nil) switch y.v.(type) { case int8: return result{y.d, int8(i.Int64())} case int16: return result{y.d, int16(i.Int64())} case int32: return result{y.d, int32(i.Int64())} case int64: return result{y.d, int64(i.Int64())} case uint8: return result{y.d, uint8(i.Uint64())} case uint16: return result{y.d, uint16(i.Uint64())} case uint32: return result{y.d, uint32(i.Uint64())} case uint64: return result{y.d, uint64(i.Uint64())} } } switch y.v.(type) { case float32: f, _ := a.Float32() return result{y.d, float32(f)} case float64: f, _ := a.Float64() return result{y.d, float64(f)} case complex64: f, _ := a.Float32() return result{y.d, complex(f, 0)} case complex128: f, _ := a.Float64() return result{y.d, complex(f, 0)} case untComplex: return result{nil, untComplex{a.Float, new(big.Float)}} } case untComplex: if a.i.Sign() == 0 { // a is a real number. if a.r.IsInt() { // a is an integer. i, _ := a.r.Int(nil) switch y.v.(type) { case int8: return result{y.d, int8(i.Int64())} case int16: return result{y.d, int16(i.Int64())} case int32: return result{y.d, int32(i.Int64())} case int64: return result{y.d, int64(i.Int64())} case uint8: return result{y.d, uint8(i.Uint64())} case uint16: return result{y.d, uint16(i.Uint64())} case uint32: return result{y.d, uint32(i.Uint64())} case uint64: return result{y.d, uint64(i.Uint64())} } } switch y.v.(type) { case float32: f, _ := a.r.Float32() return result{y.d, float32(f)} case float64: f, _ := a.r.Float64() return result{y.d, float64(f)} } } switch y.v.(type) { case complex64: r, _ := a.r.Float32() i, _ := a.i.Float32() return result{y.d, complex(r, i)} case complex128: r, _ := a.r.Float64() i, _ := a.i.Float64() return result{y.d, complex(r, i)} } case bool: if x.d != nil { // x is a typed bool, not an untyped bool. break } switch y.v.(type) { case bool: return result{y.d, bool(a)} } case untString: switch y.v.(type) { case debug.String: return result{y.d, debug.String{Length: uint64(len(a)), String: string(a)}} } } return x } // uint64FromResult converts a result into a uint64 for slice or index expressions. // It returns an error if the conversion cannot be done. func uint64FromResult(x result) (uint64, error) { switch v := x.v.(type) { case int8: if v < 0 { return 0, errors.New("value is negative") } return uint64(v), nil case int16: if v < 0 { return 0, errors.New("value is negative") } return uint64(v), nil case int32: if v < 0 { return 0, errors.New("value is negative") } return uint64(v), nil case int64: if v < 0 { return 0, errors.New("value is negative") } return uint64(v), nil case uint8: return uint64(v), nil case uint16: return uint64(v), nil case uint32: return uint64(v), nil case uint64: return v, nil case untInt: if v.Int.Sign() == -1 { return 0, errors.New("value is negative") } if v.Int.Cmp(bigIntMaxUint64) == +1 { return 0, errors.New("value is too large") } return v.Int.Uint64(), nil case untRune: if v.Sign() == -1 { return 0, errors.New("value is negative") } if v.Cmp(bigIntMaxUint64) == +1 { return 0, errors.New("value is too large") } return v.Uint64(), nil case untFloat: if !v.IsInt() { return 0, errors.New("value is not an integer") } if v.Sign() == -1 { return 0, errors.New("value is negative") } i, _ := v.Int(nil) if i.Cmp(bigIntMaxUint64) == +1 { return 0, errors.New("value is too large") } return i.Uint64(), nil case untComplex: if v.i.Sign() != 0 { return 0, errors.New("value is complex") } if !v.r.IsInt() { return 0, errors.New("value is not an integer") } if v.r.Sign() == -1 { return 0, errors.New("value is negative") } i, _ := v.r.Int(nil) if i.Cmp(bigIntMaxUint64) == +1 { return 0, errors.New("value is too large") } return i.Uint64(), nil } return 0, fmt.Errorf("cannot convert to unsigned integer") } // followTypedefs returns the underlying type of t, removing any typedefs. // If t leads to a cycle of typedefs, followTypedefs returns nil. func followTypedefs(t dwarf.Type) dwarf.Type { // If t is a *dwarf.TypedefType, next returns t.Type, otherwise it returns t. // The bool returned is true when the argument was a typedef. next := func(t dwarf.Type) (dwarf.Type, bool) { tt, ok := t.(*dwarf.TypedefType) if !ok { return t, false } return tt.Type, true } // Advance two pointers, one at twice the speed, so we can detect if we get // stuck in a cycle. slow, fast := t, t for { var wasTypedef bool fast, wasTypedef = next(fast) if !wasTypedef { return fast } fast, wasTypedef = next(fast) if !wasTypedef { return fast } slow, _ = next(slow) if slow == fast { return nil } } } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/server/eval.m4000066400000000000000000001253131356504100700266320ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //m4_changequote(`@',`@') // Evaluates Go expressions, using the current values of variables in a program // being debugged. // // TODOs: // More overflow checking. // Stricter type checking. // More expression types. package server import ( "errors" "fmt" "go/ast" "go/parser" "go/token" "math" "math/big" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/dwarf" ) const prec = 256 // precision for untyped float and complex constants. var ( // Some big.Ints to use in overflow checks. bigIntMaxInt32 = big.NewInt(math.MaxInt32) bigIntMinInt32 = big.NewInt(math.MinInt32) bigIntMaxInt64 = big.NewInt(math.MaxInt64) bigIntMinInt64 = big.NewInt(math.MinInt64) bigIntMaxUint64 = new(big.Int).SetUint64(math.MaxUint64) ) // result stores an intermediate value produced during evaluation of an expression. // // d contains the DWARF type of the value. For untyped values, d will be nil. // // v contains the value itself. For numeric and bool types, v will have the // corresponding predeclared Go type. // For untyped integer, rune, float, complex, string, and bool constants, v will // have type untInt, untRune, untFloat, untComplex, untString, or bool, // respectively. // For values of type int, uint and uintptr, v will be an int32, int64, uint32 // or uint64 as appropriate. // For address operations, v will have type pointerToValue. // For the operands of address operations, v will have type addressableValue. // Other types are represented using the corresponding implementation of // debug.Value in program.go. // // If an evaluation results in an error, the zero value of result is used. type result struct { d dwarf.Type v interface{} } // untInt is an untyped integer constant type untInt struct { *big.Int } // untRune is an untyped rune constant type untRune struct { *big.Int } // untFloat is an untyped floating-point constant type untFloat struct { *big.Float } // untComplex is an untyped complex constant type untComplex struct { r *big.Float i *big.Float } // untString is an untyped string constant type untString string // pointerToValue is a pointer to a value in memory. // The evaluator constructs these as the result of address operations like "&x". // Unlike debug.Pointer, the DWARF type stored alongside values of this type // is the type of the variable, not the type of the pointer. type pointerToValue struct { a uint64 } // addressableValue is the memory location of a value. // The evaluator constructs these while evaluating the operands of address // operations like "&x", instead of computing the value of x itself. type addressableValue struct { a uint64 } // A sliceOf is a slice created by slicing an array. // Unlike debug.Slice, the DWARF type stored alongside a value of this type is // the type of the slice's elements, not the type of the slice. type sliceOf debug.Slice // ident is a value for representing a special identifier. type ident string // identLookup is a built-in function of the expression evaluator which gets the // value of a global symbol. var identLookup ident = "lookup" // evalExpression evaluates a Go expression. // If the program counter and stack pointer are nonzero, they are used to determine // what local variables are available and where in memory they are. func (s *Server) evalExpression(expression string, pc, sp uint64) (debug.Value, error) { e := evaluator{server: s, expression: expression, pc: pc, sp: sp} node, err := parser.ParseExpr(expression) if err != nil { return nil, err } val := e.evalNode(node, false) if e.evalError != nil { return nil, e.evalError } // Convert untyped constants to their default types. switch v := val.v.(type) { case untInt: return e.intFromInteger(v) case untRune: if v.Cmp(bigIntMaxInt32) == +1 { return nil, errors.New("constant overflows rune") } if v.Cmp(bigIntMinInt32) == -1 { return nil, errors.New("constant overflows rune") } return int32(v.Int64()), nil case untFloat: f, _ := v.Float64() if math.IsInf(f, 0) { return nil, errors.New("constant overflows float64") } if math.IsNaN(f) { return nil, errors.New("constant is NaN") } return f, nil case untComplex: r, _ := v.r.Float64() i, _ := v.i.Float64() if math.IsInf(r, 0) || math.IsInf(i, 0) { return nil, errors.New("constant overflows complex128") } if math.IsNaN(r) || math.IsNaN(i) { return nil, errors.New("constant is NaN") } return complex(r, i), nil case untString: return debug.String{Length: uint64(len(v)), String: string(v)}, nil case pointerToValue: return debug.Pointer{TypeID: uint64(val.d.Common().Offset), Address: v.a}, nil case sliceOf: return debug.Slice(v), nil case nil, addressableValue: // This case should not be reachable. return nil, errors.New("unknown error") } return val.v, nil } type evaluator struct { // expression is the expression being evaluated. expression string // server interacts with the program being debugged. server *Server // curNode is the current parse tree node. This is set so that error messages // can quote the part of the expression that caused an error. curNode ast.Node // evalError is the first error that occurred while evaluating the expression, // or nil if no error has occurred. evalError error // pc and sp are the current program counter and stack pointer, used for // finding local variables. If either are zero, the expression is evaluated // without using local variables. pc uint64 sp uint64 } // setNode sets curNode, and returns curNode's previous value. func (e *evaluator) setNode(node ast.Node) (old ast.Node) { old, e.curNode = e.curNode, node return old } // err saves an error that occurred during evaluation. // It returns a zero result, so that functions can exit and set an error with // return e.err(...) func (e *evaluator) err(s string) result { if e.evalError != nil { return result{} } // Append the substring of the expression that corresponds to the current AST node. start := int(e.curNode.Pos() - 1) end := int(e.curNode.End() - 1) if start < 0 { start = 0 } if end > len(e.expression) { end = len(e.expression) } if start > end { start, end = 0, 0 } e.evalError = errors.New(s + `: "` + e.expression[start:end] + `"`) return result{} } // evalNode computes the value of a node in the expression tree. // If getAddress is true, the node is the argument of an & operator, so evalNode // will return a result with a value of type addressableValue if possible. func (e *evaluator) evalNode(node ast.Node, getAddress bool) result { // Set the current node in the evaluator, so that error messages can refer to // it. Defer a function call that changes it back. defer e.setNode(e.setNode(node)) switch n := node.(type) { case *ast.Ident: if e.pc != 0 && e.sp != 0 { a, t := e.server.findLocalVar(n.Name, e.pc, e.sp) if t != nil { return e.resultFrom(a, t, getAddress) } } a, t := e.server.findGlobalVar(n.Name) if t != nil { return e.resultFrom(a, t, getAddress) } switch n.Name { // Note: these could have been redefined as constants in the code, but we // don't have a way to detect that. case "true": return result{nil, true} case "false": return result{nil, false} case "lookup": return result{nil, identLookup} } return e.err("unknown identifier") case *ast.BasicLit: switch n.Kind { case token.INT: i := new(big.Int) if _, ok := i.SetString(n.Value, 0); !ok { return e.err("invalid integer constant") } return result{nil, untInt{i}} case token.FLOAT: r, _, err := big.ParseFloat(n.Value, 10, prec, big.ToNearestEven) if err != nil { return e.err(err.Error()) } return result{nil, untFloat{r}} case token.IMAG: if len(n.Value) <= 1 || n.Value[len(n.Value)-1] != 'i' { return e.err("invalid imaginary constant") } r, _, err := big.ParseFloat(n.Value[:len(n.Value)-1], 10, prec, big.ToNearestEven) if err != nil { return e.err(err.Error()) } return result{nil, untComplex{new(big.Float), r}} case token.CHAR: // TODO: unescaping return result{nil, untRune{new(big.Int).SetInt64(int64(n.Value[1]))}} case token.STRING: // TODO: unescaping if len(n.Value) <= 1 { return e.err("invalid string constant") } return result{nil, untString(n.Value[1 : len(n.Value)-1])} } case *ast.ParenExpr: return e.evalNode(n.X, getAddress) case *ast.StarExpr: x := e.evalNode(n.X, false) switch v := x.v.(type) { case debug.Pointer: // x.d may be a typedef pointing to a pointer type (or a typedef pointing // to a typedef pointing to a pointer type, etc.), so remove typedefs // until we get the underlying pointer type. t := followTypedefs(x.d) if pt, ok := t.(*dwarf.PtrType); ok { return e.resultFrom(v.Address, pt.Type, getAddress) } else { return e.err("invalid DWARF type for pointer") } case pointerToValue: return e.resultFrom(v.a, x.d, getAddress) case nil: return x } return e.err("invalid indirect") case *ast.SelectorExpr: x := e.evalNode(n.X, false) sel := n.Sel.Name switch v := x.v.(type) { case debug.Struct: for _, f := range v.Fields { if f.Name == sel { t, err := e.server.dwarfData.Type(dwarf.Offset(f.Var.TypeID)) if err != nil { return e.err(err.Error()) } return e.resultFrom(f.Var.Address, t, getAddress) } } return e.err("struct field not found") case debug.Pointer: pt, ok := followTypedefs(x.d).(*dwarf.PtrType) // x.d should be a pointer to struct. if !ok { return e.err("invalid DWARF information for pointer") } st, ok := followTypedefs(pt.Type).(*dwarf.StructType) if !ok { break } for _, f := range st.Field { if f.Name == sel { return e.resultFrom(v.Address+uint64(f.ByteOffset), f.Type, getAddress) } } return e.err("struct field not found") case pointerToValue: st, ok := followTypedefs(x.d).(*dwarf.StructType) // x.d should be a struct. if !ok { break } for _, f := range st.Field { if f.Name == sel { return e.resultFrom(v.a+uint64(f.ByteOffset), f.Type, getAddress) } } return e.err("struct field not found") } return e.err("invalid selector expression") case *ast.IndexExpr: x, index := e.evalNode(n.X, false), e.evalNode(n.Index, false) if x.v == nil || index.v == nil { return result{} } // The expression is x[index] if m, ok := x.v.(debug.Map); ok { if getAddress { return e.err("can't take address of map value") } mt, ok := followTypedefs(x.d).(*dwarf.MapType) if !ok { return e.err("invalid DWARF type for map") } var ( found bool // true if the key was found value result // the map value for the key abort bool // true if an error occurred while searching // fn is a function that checks if one (key, value) pair corresponds // to the index in the expression. fn = func(keyAddr, valAddr uint64, keyType, valType dwarf.Type) bool { key := e.resultFrom(keyAddr, keyType, false) if key.v == nil { abort = true return false // stop searching map } equal, ok := e.evalBinaryOp(token.EQL, index, key).v.(bool) if !ok { abort = true return false // stop searching map } if equal { found = true value = e.resultFrom(valAddr, valType, false) return false // stop searching map } return true // continue searching map } ) if err := e.server.peekMapValues(mt, m.Address, fn); err != nil { return e.err(err.Error()) } if abort { // Some operation on individual map keys failed. return result{} } if found { return value } // The key wasn't in the map; return the zero value. return e.zero(mt.ElemType) } // The index should be a non-negative integer for the remaining cases. u, err := uint64FromResult(index) if err != nil { return e.err("invalid index: " + err.Error()) } switch v := x.v.(type) { case debug.Array: if u >= v.Length { return e.err("array index out of bounds") } elemType, err := e.server.dwarfData.Type(dwarf.Offset(v.ElementTypeID)) if err != nil { return e.err(err.Error()) } return e.resultFrom(v.Element(u).Address, elemType, getAddress) case debug.Slice: if u >= v.Length { return e.err("slice index out of bounds") } elemType, err := e.server.dwarfData.Type(dwarf.Offset(v.ElementTypeID)) if err != nil { return e.err(err.Error()) } return e.resultFrom(v.Element(u).Address, elemType, getAddress) case sliceOf: if u >= v.Length { return e.err("slice index out of bounds") } return e.resultFrom(v.Element(u).Address, x.d, getAddress) case debug.String: if getAddress { return e.err("can't take address of string element") } if u >= v.Length { return e.err("string index out of bounds") } if u >= uint64(len(v.String)) { return e.err("string element unavailable") } return e.uint8Result(v.String[u]) case untString: if getAddress { return e.err("can't take address of string element") } if u >= uint64(len(v)) { return e.err("string index out of bounds") } return e.uint8Result(v[u]) } return e.err("invalid index expression") case *ast.SliceExpr: if n.Slice3 && n.High == nil { return e.err("middle index required in full slice") } if n.Slice3 && n.Max == nil { return e.err("final index required in full slice") } var ( low, high, max uint64 err error ) if n.Low != nil { low, err = uint64FromResult(e.evalNode(n.Low, false)) if err != nil { return e.err("invalid slice lower bound: " + err.Error()) } } if n.High != nil { high, err = uint64FromResult(e.evalNode(n.High, false)) if err != nil { return e.err("invalid slice upper bound: " + err.Error()) } } if n.Max != nil { max, err = uint64FromResult(e.evalNode(n.Max, false)) if err != nil { return e.err("invalid slice capacity: " + err.Error()) } } x := e.evalNode(n.X, false) switch v := x.v.(type) { case debug.Array, debug.Pointer, pointerToValue: // This case handles the slicing of arrays and pointers to arrays. var arr debug.Array switch v := x.v.(type) { case debug.Array: arr = v case debug.Pointer: pt, ok := followTypedefs(x.d).(*dwarf.PtrType) if !ok { return e.err("invalid DWARF type for pointer") } a := e.resultFrom(v.Address, pt.Type, false) arr, ok = a.v.(debug.Array) if !ok { // v is a pointer to something other than an array. return e.err("cannot slice pointer") } case pointerToValue: a := e.resultFrom(v.a, x.d, false) var ok bool arr, ok = a.v.(debug.Array) if !ok { // v is a pointer to something other than an array. return e.err("cannot slice pointer") } } elemType, err := e.server.dwarfData.Type(dwarf.Offset(arr.ElementTypeID)) if err != nil { return e.err(err.Error()) } if n.High == nil { high = arr.Length } else if high > arr.Length { return e.err("slice upper bound is too large") } if n.Max == nil { max = arr.Length } else if max > arr.Length { return e.err("slice capacity is too large") } if low > high || high > max { return e.err("invalid slice index") } return result{ d: elemType, v: sliceOf{ Array: debug.Array{ ElementTypeID: arr.ElementTypeID, Address: arr.Element(low).Address, Length: high - low, StrideBits: uint64(elemType.Common().ByteSize) * 8, }, Capacity: max - low, }, } case debug.Slice: if n.High == nil { high = v.Length } else if high > v.Capacity { return e.err("slice upper bound is too large") } if n.Max == nil { max = v.Capacity } else if max > v.Capacity { return e.err("slice capacity is too large") } if low > high || high > max { return e.err("invalid slice index") } v.Address += low * (v.StrideBits / 8) v.Length = high - low v.Capacity = max - low return result{x.d, v} case sliceOf: if n.High == nil { high = v.Length } else if high > v.Capacity { return e.err("slice upper bound is too large") } if n.Max == nil { max = v.Capacity } else if max > v.Capacity { return e.err("slice capacity is too large") } if low > high || high > max { return e.err("invalid slice index") } v.Address += low * (v.StrideBits / 8) v.Length = high - low v.Capacity = max - low return result{x.d, v} case debug.String: if n.Max != nil { return e.err("full slice of string") } if n.High == nil { high = v.Length } if low > high || high > v.Length { return e.err("invalid slice index") } v.Length = high - low if low > uint64(len(v.String)) { // v.String was truncated before the point where this slice starts. v.String = "" } else { if high > uint64(len(v.String)) { // v.String was truncated before the point where this slice ends. high = uint64(len(v.String)) } v.String = v.String[low:high] } return result{x.d, v} case untString: if n.Max != nil { return e.err("full slice of string") } if n.High == nil { high = uint64(len(v)) } if low > high { return e.err("invalid slice expression") } if high > uint64(len(v)) { return e.err("slice upper bound is too large") } return e.stringResult(string(v[low:high])) default: return e.err("invalid slice expression") } case *ast.CallExpr: // Only supports lookup("x"), which gets the value of a global symbol x. fun := e.evalNode(n.Fun, false) var args []result for _, a := range n.Args { args = append(args, e.evalNode(a, false)) } if fun.v == identLookup { if len(args) != 1 { return e.err("lookup should have one argument") } ident, ok := args[0].v.(untString) if !ok { return e.err("argument for lookup should be a string constant") } if a, t := e.server.findGlobalVar(string(ident)); t == nil { return e.err("symbol not found") } else { return e.resultFrom(a, t, getAddress) } } return e.err("function calls not implemented") case *ast.UnaryExpr: if n.Op == token.AND { x := e.evalNode(n.X, true) switch v := x.v.(type) { case addressableValue: return result{x.d, pointerToValue{v.a}} case nil: return x } return e.err("can't take address") } x := e.evalNode(n.X, false) if x.v == nil { return x } switch v := x.v.(type) { m4_define(UNARY_INT_OPS, @case $1: switch n.Op { case token.ADD: case token.SUB: v = -v case token.XOR: v = ^v default: return e.err("invalid operation") } return result{x.d, v} @) m4_define(UNARY_FLOAT_OPS, @case $1: switch n.Op { case token.ADD: case token.SUB: v = -v default: return e.err("invalid operation") } return result{x.d, v} @) UNARY_INT_OPS(int8) UNARY_INT_OPS(int16) UNARY_INT_OPS(int32) UNARY_INT_OPS(int64) UNARY_INT_OPS(uint8) UNARY_INT_OPS(uint16) UNARY_INT_OPS(uint32) UNARY_INT_OPS(uint64) UNARY_FLOAT_OPS(float32) UNARY_FLOAT_OPS(float64) UNARY_FLOAT_OPS(complex64) UNARY_FLOAT_OPS(complex128) case untInt: switch n.Op { case token.ADD: case token.SUB: v.Int.Neg(v.Int) case token.XOR: v.Int.Not(v.Int) default: return e.err("invalid operation") } return result{x.d, v} case untRune: switch n.Op { case token.ADD: case token.SUB: v.Int.Neg(v.Int) case token.XOR: v.Int.Not(v.Int) default: return e.err("invalid operation") } return result{x.d, v} case untFloat: switch n.Op { case token.ADD: case token.SUB: v.Float.Neg(v.Float) default: return e.err("invalid operation") } return result{x.d, v} case untComplex: switch n.Op { case token.ADD: case token.SUB: v.r.Neg(v.r) v.i.Neg(v.i) default: return e.err("invalid operation") } return result{x.d, v} case bool: switch n.Op { case token.NOT: v = !v default: return e.err("invalid operation") } return result{x.d, v} } case *ast.BinaryExpr: x := e.evalNode(n.X, false) if x.v == nil { return x } y := e.evalNode(n.Y, false) if y.v == nil { return y } return e.evalBinaryOp(n.Op, x, y) } return e.err("invalid expression") } // evalBinaryOp evaluates a binary operator op applied to x and y. func (e *evaluator) evalBinaryOp(op token.Token, x, y result) result { if op == token.NEQ { tmp := e.evalBinaryOp(token.EQL, x, y) b, ok := tmp.v.(bool) if !ok { return tmp } return result{nil, !b} } if op == token.GTR { return e.evalBinaryOp(token.LSS, y, x) } if op == token.GEQ { return e.evalBinaryOp(token.LEQ, x, y) } x = convertUntyped(x, y) y = convertUntyped(y, x) switch a := x.v.(type) { m4_define(INT_OPS, @case $1: b, ok := y.v.($1) if !ok { return e.err("type mismatch") } var c $1 switch op { case token.EQL: return result{nil, a == b} case token.LSS: return result{nil, a < b} case token.LEQ: return result{nil, a <= b} case token.ADD: c = a + b case token.SUB: c = a - b case token.OR: c = a | b case token.XOR: c = a ^ b case token.MUL: c = a * b case token.QUO: if b == 0 { return e.err("integer divide by zero") } c = a / b case token.REM: if b == 0 { return e.err("integer divide by zero") } c = a % b case token.AND: c = a & b case token.AND_NOT: c = a &^ b default: return e.err("invalid operation") } return result{x.d, c} @) m4_define(UINT_OPS, @case $1: b, ok := y.v.($1) if !ok { return e.err("type mismatch") } var c $1 switch op { case token.EQL: return result{nil, a == b} case token.LSS: return result{nil, a < b} case token.LEQ: return result{nil, a <= b} case token.ADD: c = a + b case token.SUB: c = a - b case token.OR: c = a | b case token.XOR: c = a ^ b case token.MUL: c = a * b case token.QUO: if b == 0 { return e.err("integer divide by zero") } c = a / b case token.REM: if b == 0 { return e.err("integer divide by zero") } c = a % b case token.AND: c = a & b case token.AND_NOT: c = a &^ b default: return e.err("invalid operation") } return result{x.d, c} @) m4_define(FLOAT_OPS, @case $1: b, ok := y.v.($1) if !ok { return e.err("type mismatch") } var c $1 switch op { case token.EQL: return result{nil, a == b} case token.LSS: return result{nil, a < b} case token.LEQ: return result{nil, a <= b} case token.ADD: c = a + b case token.SUB: c = a - b case token.MUL: c = a * b case token.QUO: c = a / b default: return e.err("invalid operation") } return result{x.d, c} @) m4_define(COMPLEX_OPS, @case $1: b, ok := y.v.($1) if !ok { return e.err("type mismatch") } var c $1 switch op { case token.EQL: return result{nil, a == b} case token.ADD: c = a + b case token.SUB: c = a - b case token.MUL: c = a * b case token.QUO: c = a / b default: return e.err("invalid operation") } return result{x.d, c} @) INT_OPS(int8) INT_OPS(int16) INT_OPS(int32) INT_OPS(int64) UINT_OPS(uint8) UINT_OPS(uint16) UINT_OPS(uint32) UINT_OPS(uint64) FLOAT_OPS(float32) FLOAT_OPS(float64) COMPLEX_OPS(complex64) COMPLEX_OPS(complex128) case bool: b, ok := y.v.(bool) if !ok { return e.err("type mismatch") } var c bool switch op { case token.LOR: c = a || b case token.LAND: c = a && b case token.EQL: c = a == b default: return e.err("invalid operation") } return result{x.d, c} case debug.String: b, ok := y.v.(debug.String) if !ok { return e.err("type mismatch") } var c debug.String switch op { // TODO: these comparison operators only use the part of the string that // was read. Very large strings do not have their entire contents read by // server.value. case token.EQL: return result{nil, a.Length == b.Length && a.String == b.String} case token.LSS: return result{nil, a.String < b.String} case token.LEQ: return result{nil, a.String <= b.String} case token.ADD: c.Length = a.Length + b.Length if a.Length == uint64(len(a.String)) { c.String = a.String + b.String } else { // The first string was truncated at a.Length characters, so the sum // must be truncated there too. c.String = a.String } default: return e.err("invalid operation") } return result{x.d, c} case untString: b, ok := y.v.(untString) if !ok { return e.err("type mismatch") } var c untString switch op { case token.EQL: return result{nil, a == b} case token.LSS: return result{nil, a < b} case token.LEQ: return result{nil, a <= b} case token.ADD: c = a + b default: return e.err("invalid operation") } return result{x.d, c} case untInt: i := a.Int b, ok := y.v.(untInt) if !ok { return e.err("type mismatch") } switch op { case token.EQL: return result{nil, i.Cmp(b.Int) == 0} case token.LSS: return result{nil, i.Cmp(b.Int) < 0} case token.LEQ: return result{nil, i.Cmp(b.Int) <= 0} } c := new(big.Int) switch op { case token.ADD: c.Add(i, b.Int) case token.SUB: c.Sub(i, b.Int) case token.OR: c.Or(i, b.Int) case token.XOR: c.Xor(i, b.Int) case token.MUL: c.Mul(i, b.Int) case token.QUO: if b.Sign() == 0 { return e.err("integer divide by zero") } c.Quo(i, b.Int) case token.REM: if b.Sign() == 0 { return e.err("integer divide by zero") } c.Mod(i, b.Int) case token.AND: c.And(i, b.Int) case token.AND_NOT: c.AndNot(i, b.Int) default: return e.err("invalid operation") } return result{nil, untInt{c}} case untRune: i := a.Int b, ok := y.v.(untRune) if !ok { return e.err("type mismatch") } switch op { case token.EQL: return result{nil, i.Cmp(b.Int) == 0} case token.LSS: return result{nil, i.Cmp(b.Int) < 0} case token.LEQ: return result{nil, i.Cmp(b.Int) <= 0} } c := new(big.Int) switch op { case token.ADD: c.Add(i, b.Int) case token.SUB: c.Sub(i, b.Int) case token.OR: c.Or(i, b.Int) case token.XOR: c.Xor(i, b.Int) case token.MUL: c.Mul(i, b.Int) case token.QUO: if b.Sign() == 0 { return e.err("integer divide by zero") } c.Quo(i, b.Int) case token.REM: if b.Sign() == 0 { return e.err("integer divide by zero") } c.Mod(i, b.Int) case token.AND: c.And(i, b.Int) case token.AND_NOT: c.AndNot(i, b.Int) default: return e.err("invalid operation") } return result{nil, untRune{c}} case untFloat: r := a.Float b, ok := y.v.(untFloat) if !ok { return e.err("type mismatch") } switch op { case token.EQL: return result{nil, r.Cmp(b.Float) == 0} case token.LSS: return result{nil, r.Cmp(b.Float) < 0} case token.LEQ: return result{nil, r.Cmp(b.Float) <= 0} } c := new(big.Float) switch op { case token.ADD: c.Add(r, b.Float) case token.SUB: c.Sub(r, b.Float) case token.MUL: c.Mul(r, b.Float) case token.QUO: if b.Sign() == 0 { return e.err("divide by zero") } c.Quo(r, b.Float) default: return e.err("invalid operation") } return result{nil, untFloat{c}} case untComplex: b, ok := y.v.(untComplex) if !ok { return e.err("type mismatch") } var ( ar = a.r br = b.r ai = a.i bi = b.i ) if op == token.EQL { return result{nil, ar.Cmp(br) == 0 && ai.Cmp(bi) == 0} } var ( cr = new(big.Float) ci = new(big.Float) ) switch op { case token.ADD: cr.Add(ar, br) ci.Add(ai, bi) case token.SUB: cr.Sub(ar, br) ci.Sub(ai, bi) case token.MUL: var t0, t1 big.Float t0.Mul(ar, br) t1.Mul(ai, bi) cr.Sub(&t0, &t1) t0.Mul(ar, bi) t1.Mul(ai, br) ci.Add(&t0, &t1) case token.QUO: // a/b = a*conj(b)/|b|^2 var t0, t1 big.Float cr.Mul(ar, br) t0.Mul(ai, bi) cr.Add(cr, &t0) // cr = Re(a*conj(b)) ci.Mul(ai, br) t0.Mul(ar, bi) ci.Sub(ci, &t0) // ci = Im(a*conj(b)) t0.Mul(br, br) t1.Mul(bi, bi) t0.Add(&t0, &t1) // t0 = |b|^2 if t0.Sign() == 0 { return e.err("divide by zero") } cr.Quo(cr, &t0) // cr = Re(a*conj(b))/|b|^2 = Re(a/b) ci.Quo(ci, &t0) // ci = Im(a*conj(b))/|b|^2 = Im(a/b) } return result{nil, untComplex{cr, ci}} } return e.err("invalid operation") } // findLocalVar finds a local variable (or function parameter) by name, and // returns its address and DWARF type. It returns a nil type on failure. // The PC and SP are used to determine the current function and stack frame. func (s *Server) findLocalVar(name string, pc, sp uint64) (uint64, dwarf.Type) { // Find the DWARF entry for the function at pc. funcEntry, _, err := s.dwarfData.PCToFunction(uint64(pc)) if err != nil { return 0, nil } // Compute the stack frame pointer. fpOffset, err := s.dwarfData.PCToSPOffset(uint64(pc)) if err != nil { return 0, nil } framePointer := sp + uint64(fpOffset) // Check each child of the function's DWARF entry to see if it is a parameter // or local variable with the right name. If so, return its address and type. r := s.dwarfData.Reader() r.Seek(funcEntry.Offset) for { varEntry, err := r.Next() if err != nil { break } if varEntry.Tag == 0 { // This tag marks the end of the function's DWARF entry's children. break } // Check this entry corresponds to a local variable or function parameter, // that it has the correct name, and that we can get its type and location. // If so, return them. if varEntry.Tag != dwarf.TagFormalParameter && varEntry.Tag != dwarf.TagVariable { continue } varName, ok := varEntry.Val(dwarf.AttrName).(string) if !ok { continue } if varName != name { continue } varTypeOffset, ok := varEntry.Val(dwarf.AttrType).(dwarf.Offset) if !ok { continue } varType, err := s.dwarfData.Type(varTypeOffset) if err != nil { continue } locationAttribute := varEntry.Val(dwarf.AttrLocation) if locationAttribute == nil { continue } locationDescription, ok := locationAttribute.([]uint8) if !ok { continue } frameOffset, err := evalLocation(locationDescription) if err != nil { continue } return framePointer + uint64(frameOffset), varType } return 0, nil } // findGlobalVar finds a global variable by name, and returns its address and // DWARF type. It returns a nil type on failure. func (s *Server) findGlobalVar(name string) (uint64, dwarf.Type) { entry, err := s.dwarfData.LookupVariable(name) if err != nil { return 0, nil } loc, err := s.dwarfData.EntryLocation(entry) if err != nil { return 0, nil } ofs, err := s.dwarfData.EntryTypeOffset(entry) if err != nil { return 0, nil } typ, err := s.dwarfData.Type(ofs) if err != nil { return 0, nil } return loc, typ } // intFromInteger converts an untyped integer constant to an int32 or int64, // depending on the int size of the debugged program. // It returns an error on overflow, or if it can't determine the int size. func (e *evaluator) intFromInteger(v untInt) (interface{}, error) { t, ok := e.getBaseType("int") if !ok { return nil, errors.New("couldn't get int size from DWARF info") } switch t.Common().ByteSize { case 4: if v.Cmp(bigIntMaxInt32) == +1 || v.Cmp(bigIntMinInt32) == -1 { return nil, errors.New("constant overflows int") } return int32(v.Int64()), nil case 8: if v.Cmp(bigIntMaxInt64) == +1 || v.Cmp(bigIntMinInt64) == -1 { return nil, errors.New("constant overflows int") } return v.Int64(), nil } return nil, errors.New("invalid int size in DWARF info") } // uint8Result constructs a result for a uint8 value. func (e *evaluator) uint8Result(v uint8) result { t, ok := e.getBaseType("uint8") if !ok { e.err("couldn't construct uint8") } return result{t, uint8(v)} } // stringResult constructs a result for a string value. func (e *evaluator) stringResult(s string) result { t, ok := e.getBaseType("string") if !ok { e.err("couldn't construct string") } return result{t, debug.String{Length: uint64(len(s)), String: s}} } // getBaseType returns the *dwarf.Type with a given name. // TODO: cache this. func (e *evaluator) getBaseType(name string) (dwarf.Type, bool) { entry, err := e.server.dwarfData.LookupEntry(name) if err != nil { return nil, false } t, err := e.server.dwarfData.Type(entry.Offset) if err != nil { return nil, false } return t, true } // resultFrom constructs a result corresponding to a value in the program with // the given address and DWARF type. // If getAddress is true, the result will be the operand of an address expression, // so resultFrom returns a result containing a value of type addressableValue. func (e *evaluator) resultFrom(a uint64, t dwarf.Type, getAddress bool) result { if a == 0 { return e.err("nil pointer dereference") } if getAddress { return result{t, addressableValue{a}} } v, err := e.server.value(t, a) if err != nil { return e.err(err.Error()) } return result{t, v} } // zero returns the zero value of type t. // TODO: implement for array and struct. func (e *evaluator) zero(t dwarf.Type) result { var v interface{} switch typ := followTypedefs(t).(type) { case *dwarf.CharType, *dwarf.IntType, *dwarf.EnumType: switch typ.Common().ByteSize { case 1: v = int8(0) case 2: v = int16(0) case 4: v = int32(0) case 8: v = int64(0) default: return e.err("invalid integer size " + fmt.Sprint(typ.Common().ByteSize)) } case *dwarf.UcharType, *dwarf.UintType: switch typ.Common().ByteSize { case 1: v = uint8(0) case 2: v = uint16(0) case 4: v = uint32(0) case 8: v = uint64(0) default: return e.err("invalid unsigned integer size " + fmt.Sprint(typ.Common().ByteSize)) } case *dwarf.FloatType: switch typ.Common().ByteSize { case 4: v = float32(0) case 8: v = float64(0) default: return e.err("invalid float size " + fmt.Sprint(typ.Common().ByteSize)) } case *dwarf.ComplexType: switch typ.Common().ByteSize { case 8: v = complex64(0) case 16: v = complex128(0) default: return e.err("invalid complex size " + fmt.Sprint(typ.Common().ByteSize)) } case *dwarf.BoolType: v = false case *dwarf.PtrType: v = debug.Pointer{TypeID: uint64(t.Common().Offset)} case *dwarf.SliceType: v = debug.Slice{ Array: debug.Array{ ElementTypeID: uint64(typ.ElemType.Common().Offset), StrideBits: uint64(typ.ElemType.Common().ByteSize) * 8, }, } case *dwarf.StringType: v = debug.String{} case *dwarf.InterfaceType: v = debug.Interface{} case *dwarf.FuncType: v = debug.Func{} case *dwarf.MapType: v = debug.Map{TypeID: uint64(t.Common().Offset)} case *dwarf.ChanType: v = debug.Channel{ ElementTypeID: uint64(typ.ElemType.Common().Offset), Stride: uint64(typ.ElemType.Common().ByteSize), } default: return e.err("can't get zero value of this type") } return result{t, v} } // convertUntyped converts x to be the same type as y, if x is untyped and the // conversion is possible. // // An untyped bool can be converted to a boolean type. // An untyped string can be converted to a string type. // An untyped integer, rune, float or complex value can be converted to a // numeric type, or to an untyped value later in that list. // // x is returned unchanged if none of these cases apply. func convertUntyped(x, y result) result { switch a := x.v.(type) { case untInt: i := a.Int switch y.v.(type) { case int8: return result{y.d, int8(i.Int64())} case int16: return result{y.d, int16(i.Int64())} case int32: return result{y.d, int32(i.Int64())} case int64: return result{y.d, int64(i.Int64())} case uint8: return result{y.d, uint8(i.Uint64())} case uint16: return result{y.d, uint16(i.Uint64())} case uint32: return result{y.d, uint32(i.Uint64())} case uint64: return result{y.d, uint64(i.Uint64())} case float32: f, _ := new(big.Float).SetInt(i).Float32() return result{y.d, f} case float64: f, _ := new(big.Float).SetInt(i).Float64() return result{y.d, f} case complex64: f, _ := new(big.Float).SetInt(i).Float32() return result{y.d, complex(f, 0)} case complex128: f, _ := new(big.Float).SetInt(i).Float64() return result{y.d, complex(f, 0)} case untRune: return result{nil, untRune{i}} case untFloat: return result{nil, untFloat{new(big.Float).SetPrec(prec).SetInt(i)}} case untComplex: return result{nil, untComplex{new(big.Float).SetPrec(prec).SetInt(i), new(big.Float)}} } case untRune: i := a.Int switch y.v.(type) { case int8: return result{y.d, int8(i.Int64())} case int16: return result{y.d, int16(i.Int64())} case int32: return result{y.d, int32(i.Int64())} case int64: return result{y.d, int64(i.Int64())} case uint8: return result{y.d, uint8(i.Uint64())} case uint16: return result{y.d, uint16(i.Uint64())} case uint32: return result{y.d, uint32(i.Uint64())} case uint64: return result{y.d, uint64(i.Uint64())} case float32: f, _ := new(big.Float).SetInt(i).Float32() return result{y.d, f} case float64: f, _ := new(big.Float).SetInt(i).Float64() return result{y.d, f} case complex64: f, _ := new(big.Float).SetInt(i).Float32() return result{y.d, complex(f, 0)} case complex128: f, _ := new(big.Float).SetInt(i).Float64() return result{y.d, complex(f, 0)} case untRune: return result{nil, untRune{i}} case untFloat: return result{nil, untFloat{new(big.Float).SetPrec(prec).SetInt(i)}} case untComplex: return result{nil, untComplex{new(big.Float).SetPrec(prec).SetInt(i), new(big.Float)}} } case untFloat: if a.IsInt() { i, _ := a.Int(nil) switch y.v.(type) { case int8: return result{y.d, int8(i.Int64())} case int16: return result{y.d, int16(i.Int64())} case int32: return result{y.d, int32(i.Int64())} case int64: return result{y.d, int64(i.Int64())} case uint8: return result{y.d, uint8(i.Uint64())} case uint16: return result{y.d, uint16(i.Uint64())} case uint32: return result{y.d, uint32(i.Uint64())} case uint64: return result{y.d, uint64(i.Uint64())} } } switch y.v.(type) { case float32: f, _ := a.Float32() return result{y.d, float32(f)} case float64: f, _ := a.Float64() return result{y.d, float64(f)} case complex64: f, _ := a.Float32() return result{y.d, complex(f, 0)} case complex128: f, _ := a.Float64() return result{y.d, complex(f, 0)} case untComplex: return result{nil, untComplex{a.Float, new(big.Float)}} } case untComplex: if a.i.Sign() == 0 { // a is a real number. if a.r.IsInt() { // a is an integer. i, _ := a.r.Int(nil) switch y.v.(type) { case int8: return result{y.d, int8(i.Int64())} case int16: return result{y.d, int16(i.Int64())} case int32: return result{y.d, int32(i.Int64())} case int64: return result{y.d, int64(i.Int64())} case uint8: return result{y.d, uint8(i.Uint64())} case uint16: return result{y.d, uint16(i.Uint64())} case uint32: return result{y.d, uint32(i.Uint64())} case uint64: return result{y.d, uint64(i.Uint64())} } } switch y.v.(type) { case float32: f, _ := a.r.Float32() return result{y.d, float32(f)} case float64: f, _ := a.r.Float64() return result{y.d, float64(f)} } } switch y.v.(type) { case complex64: r, _ := a.r.Float32() i, _ := a.i.Float32() return result{y.d, complex(r, i)} case complex128: r, _ := a.r.Float64() i, _ := a.i.Float64() return result{y.d, complex(r, i)} } case bool: if x.d != nil { // x is a typed bool, not an untyped bool. break } switch y.v.(type) { case bool: return result{y.d, bool(a)} } case untString: switch y.v.(type) { case debug.String: return result{y.d, debug.String{Length: uint64(len(a)), String: string(a)}} } } return x } // uint64FromResult converts a result into a uint64 for slice or index expressions. // It returns an error if the conversion cannot be done. func uint64FromResult(x result) (uint64, error) { switch v := x.v.(type) { case int8: if v < 0 { return 0, errors.New("value is negative") } return uint64(v), nil case int16: if v < 0 { return 0, errors.New("value is negative") } return uint64(v), nil case int32: if v < 0 { return 0, errors.New("value is negative") } return uint64(v), nil case int64: if v < 0 { return 0, errors.New("value is negative") } return uint64(v), nil case uint8: return uint64(v), nil case uint16: return uint64(v), nil case uint32: return uint64(v), nil case uint64: return v, nil case untInt: if v.Int.Sign() == -1 { return 0, errors.New("value is negative") } if v.Int.Cmp(bigIntMaxUint64) == +1 { return 0, errors.New("value is too large") } return v.Int.Uint64(), nil case untRune: if v.Sign() == -1 { return 0, errors.New("value is negative") } if v.Cmp(bigIntMaxUint64) == +1 { return 0, errors.New("value is too large") } return v.Uint64(), nil case untFloat: if !v.IsInt() { return 0, errors.New("value is not an integer") } if v.Sign() == -1 { return 0, errors.New("value is negative") } i, _ := v.Int(nil) if i.Cmp(bigIntMaxUint64) == +1 { return 0, errors.New("value is too large") } return i.Uint64(), nil case untComplex: if v.i.Sign() != 0 { return 0, errors.New("value is complex") } if !v.r.IsInt() { return 0, errors.New("value is not an integer") } if v.r.Sign() == -1 { return 0, errors.New("value is negative") } i, _ := v.r.Int(nil) if i.Cmp(bigIntMaxUint64) == +1 { return 0, errors.New("value is too large") } return i.Uint64(), nil } return 0, fmt.Errorf("cannot convert to unsigned integer") } // followTypedefs returns the underlying type of t, removing any typedefs. // If t leads to a cycle of typedefs, followTypedefs returns nil. func followTypedefs(t dwarf.Type) dwarf.Type { // If t is a *dwarf.TypedefType, next returns t.Type, otherwise it returns t. // The bool returned is true when the argument was a typedef. next := func(t dwarf.Type) (dwarf.Type, bool) { tt, ok := t.(*dwarf.TypedefType) if !ok { return t, false } return tt.Type, true } // Advance two pointers, one at twice the speed, so we can detect if we get // stuck in a cycle. slow, fast := t, t for { var wasTypedef bool fast, wasTypedef = next(fast) if !wasTypedef { return fast } fast, wasTypedef = next(fast) if !wasTypedef { return fast } slow, _ = next(slow) if slow == fast { return nil } } } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/server/peek.go000066400000000000000000000277001356504100700267150ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Functions for reading values of various types from a program's memory. // +build linux package server import ( "errors" "fmt" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/dwarf" ) // peekBytes reads len(buf) bytes at addr. func (s *Server) peekBytes(addr uint64, buf []byte) error { return s.ptracePeek(s.stoppedPid, uintptr(addr), buf) } // peekPtr reads a pointer at addr. func (s *Server) peekPtr(addr uint64) (uint64, error) { buf := make([]byte, s.arch.PointerSize) if err := s.peekBytes(addr, buf); err != nil { return 0, err } return s.arch.Uintptr(buf), nil } // peekUint8 reads a single byte at addr. func (s *Server) peekUint8(addr uint64) (byte, error) { buf := make([]byte, 1) if err := s.peekBytes(addr, buf); err != nil { return 0, err } return uint8(s.arch.UintN(buf)), nil } // peekInt reads an int of size n bytes at addr. func (s *Server) peekInt(addr uint64, n int64) (int64, error) { buf := make([]byte, n) if err := s.peekBytes(addr, buf); err != nil { return 0, err } return s.arch.IntN(buf), nil } // peekUint reads a uint of size n bytes at addr. func (s *Server) peekUint(addr uint64, n int64) (uint64, error) { buf := make([]byte, n) if err := s.peekBytes(addr, buf); err != nil { return 0, err } return s.arch.UintN(buf), nil } // peekSlice reads the header of a slice with the given type and address. func (s *Server) peekSlice(t *dwarf.SliceType, addr uint64) (debug.Slice, error) { ptr, err := s.peekPtrStructField(&t.StructType, addr, "array") if err != nil { return debug.Slice{}, fmt.Errorf("reading slice location: %s", err) } length, err := s.peekUintOrIntStructField(&t.StructType, addr, "len") if err != nil { return debug.Slice{}, fmt.Errorf("reading slice length: %s", err) } capacity, err := s.peekUintOrIntStructField(&t.StructType, addr, "cap") if err != nil { return debug.Slice{}, fmt.Errorf("reading slice capacity: %s", err) } if capacity < length { return debug.Slice{}, fmt.Errorf("slice's capacity %d is less than its length %d", capacity, length) } return debug.Slice{ debug.Array{ ElementTypeID: uint64(t.ElemType.Common().Offset), Address: uint64(ptr), Length: length, StrideBits: uint64(t.ElemType.Common().ByteSize) * 8, }, capacity, }, nil } // peekString reads a string of the given type at the given address. // At most byteLimit bytes will be read. If the string is longer, "..." is appended. func (s *Server) peekString(typ *dwarf.StringType, a uint64, byteLimit uint64) (string, error) { ptr, err := s.peekPtrStructField(&typ.StructType, a, "str") if err != nil { return "", err } length, err := s.peekUintOrIntStructField(&typ.StructType, a, "len") if err != nil { return "", err } if length > byteLimit { buf := make([]byte, byteLimit, byteLimit+3) if err := s.peekBytes(ptr, buf); err != nil { return "", err } else { buf = append(buf, '.', '.', '.') return string(buf), nil } } else { buf := make([]byte, length) if err := s.peekBytes(ptr, buf); err != nil { return "", err } else { return string(buf), nil } } } // peekCString reads a NUL-terminated string at the given address. // At most byteLimit bytes will be read. If the string is longer, "..." is appended. // peekCString never returns errors; if an error occurs, the string will be truncated in some way. func (s *Server) peekCString(a uint64, byteLimit uint64) string { buf := make([]byte, byteLimit, byteLimit+3) s.peekBytes(a, buf) for i, c := range buf { if c == 0 { return string(buf[0:i]) } } buf = append(buf, '.', '.', '.') return string(buf) } // peekPtrStructField reads a pointer in the field fieldName of the struct // of type t at addr. func (s *Server) peekPtrStructField(t *dwarf.StructType, addr uint64, fieldName string) (uint64, error) { f, err := getField(t, fieldName) if err != nil { return 0, fmt.Errorf("reading field %s: %s", fieldName, err) } if _, ok := f.Type.(*dwarf.PtrType); !ok { return 0, fmt.Errorf("field %s is not a pointer", fieldName) } return s.peekPtr(addr + uint64(f.ByteOffset)) } // peekUintOrIntStructField reads a signed or unsigned integer in the field fieldName // of the struct of type t at addr. If the value is negative, it returns an error. // This function is used when the value should be non-negative, but the DWARF // type of the field may be signed or unsigned. func (s *Server) peekUintOrIntStructField(t *dwarf.StructType, addr uint64, fieldName string) (uint64, error) { f, err := getField(t, fieldName) if err != nil { return 0, fmt.Errorf("reading field %s: %s", fieldName, err) } ut, ok := f.Type.(*dwarf.UintType) if ok { return s.peekUint(addr+uint64(f.ByteOffset), ut.ByteSize) } it, ok := f.Type.(*dwarf.IntType) if !ok { return 0, fmt.Errorf("field %s is not an integer", fieldName) } i, err := s.peekInt(addr+uint64(f.ByteOffset), it.ByteSize) if err != nil { return 0, err } if i < 0 { return 0, fmt.Errorf("field %s is negative", fieldName) } return uint64(i), nil } // peekUintStructField reads a uint in the field fieldName of the struct // of type t at addr. The size of the uint is determined by the field. func (s *Server) peekUintStructField(t *dwarf.StructType, addr uint64, fieldName string) (uint64, error) { f, err := getField(t, fieldName) if err != nil { return 0, fmt.Errorf("reading field %s: %s", fieldName, err) } ut, ok := f.Type.(*dwarf.UintType) if !ok { return 0, fmt.Errorf("field %s is not an unsigned integer", fieldName) } return s.peekUint(addr+uint64(f.ByteOffset), ut.ByteSize) } // peekIntStructField reads an int in the field fieldName of the struct // of type t at addr. The size of the int is determined by the field. func (s *Server) peekIntStructField(t *dwarf.StructType, addr uint64, fieldName string) (int64, error) { f, err := getField(t, fieldName) if err != nil { return 0, fmt.Errorf("reading field %s: %s", fieldName, err) } it, ok := f.Type.(*dwarf.IntType) if !ok { return 0, fmt.Errorf("field %s is not a signed integer", fieldName) } return s.peekInt(addr+uint64(f.ByteOffset), it.ByteSize) } // peekStringStructField reads a string field from the struct of the given type // at the given address. // At most byteLimit bytes will be read. If the string is longer, "..." is appended. func (s *Server) peekStringStructField(t *dwarf.StructType, addr uint64, fieldName string, byteLimit uint64) (string, error) { f, err := getField(t, fieldName) if err != nil { return "", fmt.Errorf("reading field %s: %s", fieldName, err) } st, ok := followTypedefs(f.Type).(*dwarf.StringType) if !ok { return "", fmt.Errorf("field %s is not a string", fieldName) } return s.peekString(st, addr+uint64(f.ByteOffset), byteLimit) } // peekMapLocationAndType returns the address and DWARF type of the underlying // struct of a map variable. func (s *Server) peekMapLocationAndType(t *dwarf.MapType, a uint64) (uint64, *dwarf.StructType, error) { // Maps are pointers to structs. pt, ok := t.Type.(*dwarf.PtrType) if !ok { return 0, nil, errors.New("bad map type: not a pointer") } st, ok := pt.Type.(*dwarf.StructType) if !ok { return 0, nil, errors.New("bad map type: not a pointer to a struct") } // a is the address of a pointer to a struct. Get the pointer's value. a, err := s.peekPtr(a) if err != nil { return 0, nil, fmt.Errorf("reading map pointer: %s", err) } return a, st, nil } // peekMapValues reads a map at the given address and calls fn with the addresses for each (key, value) pair. // If fn returns false, peekMapValues stops. func (s *Server) peekMapValues(t *dwarf.MapType, a uint64, fn func(keyAddr, valAddr uint64, keyType, valType dwarf.Type) bool) error { a, st, err := s.peekMapLocationAndType(t, a) if err != nil { return err } if a == 0 { // The pointer was nil, so the map is empty. return nil } // Gather information about the struct type and the map bucket type. b, err := s.peekUintStructField(st, a, "B") if err != nil { return fmt.Errorf("reading map: %s", err) } buckets, err := s.peekPtrStructField(st, a, "buckets") if err != nil { return fmt.Errorf("reading map: %s", err) } oldbuckets, err := s.peekPtrStructField(st, a, "oldbuckets") if err != nil { return fmt.Errorf("reading map: %s", err) } bf, err := getField(st, "buckets") if err != nil { return fmt.Errorf("reading map: %s", err) } bucketPtrType, ok := bf.Type.(*dwarf.PtrType) if !ok { return errors.New("bad map bucket type: not a pointer") } bt, ok := bucketPtrType.Type.(*dwarf.StructType) if !ok { return errors.New("bad map bucket type: not a pointer to a struct") } bucketSize := uint64(bucketPtrType.Type.Size()) tophashField, err := getField(bt, "tophash") if err != nil { return fmt.Errorf("reading map: %s", err) } bucketCnt := uint64(tophashField.Type.Size()) tophashFieldOffset := uint64(tophashField.ByteOffset) keysField, err := getField(bt, "keys") if err != nil { return fmt.Errorf("reading map: %s", err) } keysType, ok := keysField.Type.(*dwarf.ArrayType) if !ok { return errors.New(`bad map bucket type: "keys" is not an array`) } keyType := keysType.Type keysStride := uint64(keysType.StrideBitSize / 8) keysFieldOffset := uint64(keysField.ByteOffset) valuesField, err := getField(bt, "values") if err != nil { return fmt.Errorf("reading map: %s", err) } valuesType, ok := valuesField.Type.(*dwarf.ArrayType) if !ok { return errors.New(`bad map bucket type: "values" is not an array`) } valueType := valuesType.Type valuesStride := uint64(valuesType.StrideBitSize / 8) valuesFieldOffset := uint64(valuesField.ByteOffset) overflowField, err := getField(bt, "overflow") if err != nil { return fmt.Errorf("reading map: %s", err) } overflowFieldOffset := uint64(overflowField.ByteOffset) // Iterate through the two arrays of buckets. bucketArrays := [2]struct { addr uint64 size uint64 }{ {buckets, 1 << b}, {oldbuckets, 1 << (b - 1)}, } for _, bucketArray := range bucketArrays { if bucketArray.addr == 0 { continue } for i := uint64(0); i < bucketArray.size; i++ { bucketAddr := bucketArray.addr + i*bucketSize // Iterate through the linked list of buckets. // TODO: check for repeated bucket pointers. for bucketAddr != 0 { // Iterate through each entry in the bucket. for j := uint64(0); j < bucketCnt; j++ { tophash, err := s.peekUint8(bucketAddr + tophashFieldOffset + j) if err != nil { return errors.New("reading map: " + err.Error()) } // From runtime/hashmap.go const minTopHash = 4 if tophash < minTopHash { continue } keyAddr := bucketAddr + keysFieldOffset + j*keysStride valAddr := bucketAddr + valuesFieldOffset + j*valuesStride if !fn(keyAddr, valAddr, keyType, valueType) { return nil } } var err error bucketAddr, err = s.peekPtr(bucketAddr + overflowFieldOffset) if err != nil { return errors.New("reading map: " + err.Error()) } } } } return nil } // peekMapLength returns the number of elements in a map at the given address. func (s *Server) peekMapLength(t *dwarf.MapType, a uint64) (uint64, error) { a, st, err := s.peekMapLocationAndType(t, a) if err != nil { return 0, err } if a == 0 { // The pointer was nil, so the map is empty. return 0, nil } length, err := s.peekUintOrIntStructField(st, a, "count") if err != nil { return 0, fmt.Errorf("reading map: %s", err) } return uint64(length), nil } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/server/print.go000066400000000000000000000344401356504100700271240ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // +build linux package server import ( "bytes" "fmt" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/arch" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/dwarf" ) // typeAndAddress associates an address in the target with a DWARF type. type typeAndAddress struct { Type dwarf.Type Address uint64 } // Routines to print a value using DWARF type descriptions. // TODO: Does this deserve its own package? It has no dependencies on Server. // A Printer pretty-prints values in the target address space. // It can be reused after each printing operation to avoid unnecessary // allocations. However, it is not safe for concurrent access. type Printer struct { err error // Sticky error value. server *Server dwarf *dwarf.Data arch *arch.Architecture printBuf bytes.Buffer // Accumulates the output. visited map[typeAndAddress]bool // Prevents looping on cyclic data. } // printf prints to printBuf. func (p *Printer) printf(format string, args ...interface{}) { fmt.Fprintf(&p.printBuf, format, args...) } // errorf prints the error to printBuf, then sets the sticky error for the // printer, if not already set. func (p *Printer) errorf(format string, args ...interface{}) { fmt.Fprintf(&p.printBuf, "<"+format+">", args...) if p.err != nil { return } p.err = fmt.Errorf(format, args...) } // NewPrinter returns a printer that can use the Server to access and print // values of the specified architecture described by the provided DWARF data. func NewPrinter(arch *arch.Architecture, dwarf *dwarf.Data, server *Server) *Printer { return &Printer{ server: server, arch: arch, dwarf: dwarf, visited: make(map[typeAndAddress]bool), } } // reset resets the Printer. It must be called before starting a new // printing operation. func (p *Printer) reset() { p.err = nil p.printBuf.Reset() // Just wipe the map rather than reallocating. It's almost always tiny. for k := range p.visited { delete(p.visited, k) } } // Sprint returns the pretty-printed value of the item with the given name, such as "main.global". func (p *Printer) Sprint(name string) (string, error) { entry, err := p.dwarf.LookupEntry(name) if err != nil { return "", err } p.reset() switch entry.Tag { case dwarf.TagVariable: // TODO: What other entries have global location attributes? var a uint64 iface := entry.Val(dwarf.AttrLocation) if iface != nil { a = p.decodeLocation(iface.([]byte)) } p.printEntryValueAt(entry, a) default: p.errorf("unrecognized entry type %s", entry.Tag) } return p.printBuf.String(), p.err } // Figure 24 of DWARF v4. const ( locationAddr = 0x03 ) // decodeLocation decodes the dwarf data describing an address. func (p *Printer) decodeLocation(data []byte) uint64 { switch data[0] { case locationAddr: return p.arch.Uintptr(data[1:]) default: p.errorf("unimplemented location type %#x", data[0]) } return 0 } // SprintEntry returns the pretty-printed value of the item with the specified DWARF Entry and address. func (p *Printer) SprintEntry(entry *dwarf.Entry, a uint64) (string, error) { p.reset() p.printEntryValueAt(entry, a) return p.printBuf.String(), p.err } // printEntryValueAt pretty-prints the data at the specified address. // using the type information in the Entry. func (p *Printer) printEntryValueAt(entry *dwarf.Entry, a uint64) { if a == 0 { p.printf("") return } switch entry.Tag { case dwarf.TagVariable, dwarf.TagFormalParameter: // OK default: p.errorf("unrecognized entry type %s", entry.Tag) return } iface := entry.Val(dwarf.AttrType) if iface == nil { p.errorf("no type") return } typ, err := p.dwarf.Type(iface.(dwarf.Offset)) if err != nil { p.errorf("type lookup: %v", err) return } p.printValueAt(typ, a) } // printValueAt pretty-prints the data at the specified address. // using the provided type information. func (p *Printer) printValueAt(typ dwarf.Type, a uint64) { if a != 0 { // Check if we are repeating the same type and address. ta := typeAndAddress{typ, a} if p.visited[ta] { p.printf("(%v %#x)", typ, a) return } p.visited[ta] = true } switch typ := typ.(type) { case *dwarf.BoolType: if typ.ByteSize != 1 { p.errorf("unrecognized bool size %d", typ.ByteSize) return } if b, err := p.server.peekUint8(a); err != nil { p.errorf("reading bool: %s", err) } else { p.printf("%t", b != 0) } case *dwarf.PtrType: if ptr, err := p.server.peekPtr(a); err != nil { p.errorf("reading pointer: %s", err) } else { p.printf("%#x", ptr) } case *dwarf.IntType: // Sad we can't tell a rune from an int32. if i, err := p.server.peekInt(a, typ.ByteSize); err != nil { p.errorf("reading integer: %s", err) } else { p.printf("%d", i) } case *dwarf.UintType: if u, err := p.server.peekUint(a, typ.ByteSize); err != nil { p.errorf("reading unsigned integer: %s", err) } else { p.printf("%d", u) } case *dwarf.FloatType: buf := make([]byte, typ.ByteSize) if err := p.server.peekBytes(a, buf); err != nil { p.errorf("reading float: %s", err) return } switch typ.ByteSize { case 4: p.printf("%g", p.arch.Float32(buf)) case 8: p.printf("%g", p.arch.Float64(buf)) default: p.errorf("unrecognized float size %d", typ.ByteSize) } case *dwarf.ComplexType: buf := make([]byte, typ.ByteSize) if err := p.server.peekBytes(a, buf); err != nil { p.errorf("reading complex: %s", err) return } switch typ.ByteSize { case 8: p.printf("%g", p.arch.Complex64(buf)) case 16: p.printf("%g", p.arch.Complex128(buf)) default: p.errorf("unrecognized complex size %d", typ.ByteSize) } case *dwarf.StructType: if typ.Kind != "struct" { // Could be "class" or "union". p.errorf("can't handle struct type %s", typ.Kind) return } p.printf("%s {", typ.String()) for i, field := range typ.Field { if i != 0 { p.printf(", ") } p.printValueAt(field.Type, a+uint64(field.ByteOffset)) } p.printf("}") case *dwarf.ArrayType: p.printArrayAt(typ, a) case *dwarf.InterfaceType: p.printInterfaceAt(typ, a) case *dwarf.MapType: p.printMapAt(typ, a) case *dwarf.ChanType: p.printChannelAt(typ, a) case *dwarf.SliceType: p.printSliceAt(typ, a) case *dwarf.StringType: p.printStringAt(typ, a) case *dwarf.TypedefType: p.printValueAt(typ.Type, a) case *dwarf.FuncType: p.printf("%v @%#x ", typ, a) case *dwarf.VoidType: p.printf("void") default: p.errorf("unimplemented type %v", typ) } } func (p *Printer) printArrayAt(typ *dwarf.ArrayType, a uint64) { elemType := typ.Type length := typ.Count stride, ok := p.arrayStride(typ) if !ok { p.errorf("can't determine element size") } p.printf("%s{", typ) n := length if n > 100 { n = 100 // TODO: Have a way to control this? } for i := int64(0); i < n; i++ { if i != 0 { p.printf(", ") } p.printValueAt(elemType, a) a += stride // TODO: Alignment and padding - not given by Type } if n < length { p.printf(", ...") } p.printf("}") } func (p *Printer) printInterfaceAt(t *dwarf.InterfaceType, a uint64) { // t embeds a TypedefType, which may point to another typedef. // The underlying type should be a struct. st, ok := followTypedefs(&t.TypedefType).(*dwarf.StructType) if !ok { p.errorf("bad interface type: not a struct") return } p.printf("(") tab, err := p.server.peekPtrStructField(st, a, "tab") if err != nil { p.errorf("reading interface type: %s", err) } else { f, err := getField(st, "tab") if err != nil { p.errorf("%s", err) } else { p.printTypeOfInterface(f.Type, tab) } } p.printf(", ") data, err := p.server.peekPtrStructField(st, a, "data") if err != nil { p.errorf("reading interface value: %s", err) } else if data == 0 { p.printf("") } else { p.printf("%#x", data) } p.printf(")") } // printTypeOfInterface prints the type of the given tab pointer. func (p *Printer) printTypeOfInterface(t dwarf.Type, a uint64) { if a == 0 { p.printf("") return } // t should be a pointer to a struct containing _type, which is a pointer to a // struct containing _string, which is the name of the type. // Depending on the compiler version, some of these types can be typedefs, and // _string may be a string or a *string. t1, ok := followTypedefs(t).(*dwarf.PtrType) if !ok { p.errorf("interface's tab is not a pointer") return } t2, ok := followTypedefs(t1.Type).(*dwarf.StructType) if !ok { p.errorf("interface's tab is not a pointer to struct") return } typeField, err := getField(t2, "_type") if err != nil { p.errorf("%s", err) return } t3, ok := followTypedefs(typeField.Type).(*dwarf.PtrType) if !ok { p.errorf("interface's _type is not a pointer") return } t4, ok := followTypedefs(t3.Type).(*dwarf.StructType) if !ok { p.errorf("interface's _type is not a pointer to struct") return } stringField, err := getField(t4, "_string") if err != nil { p.errorf("%s", err) return } if t5, ok := stringField.Type.(*dwarf.PtrType); ok { stringType, ok := t5.Type.(*dwarf.StringType) if !ok { p.errorf("interface _string is a pointer to %T, want string or *string", t5.Type) return } typeAddr, err := p.server.peekPtrStructField(t2, a, "_type") if err != nil { p.errorf("reading interface type: %s", err) return } stringAddr, err := p.server.peekPtrStructField(t4, typeAddr, "_string") if err != nil { p.errorf("reading interface type: %s", err) return } p.printStringAt(stringType, stringAddr) } else { stringType, ok := stringField.Type.(*dwarf.StringType) if !ok { p.errorf("interface _string is a %T, want string or *string", stringField.Type) return } typeAddr, err := p.server.peekPtrStructField(t2, a, "_type") if err != nil { p.errorf("reading interface type: %s", err) return } stringAddr := typeAddr + uint64(stringField.ByteOffset) p.printStringAt(stringType, stringAddr) } } // maxMapValuesToPrint values are printed for each map; any remaining values are // truncated to "...". const maxMapValuesToPrint = 8 func (p *Printer) printMapAt(typ *dwarf.MapType, a uint64) { count := 0 fn := func(keyAddr, valAddr uint64, keyType, valType dwarf.Type) (stop bool) { count++ if count > maxMapValuesToPrint { return false } if count > 1 { p.printf(" ") } p.printValueAt(keyType, keyAddr) p.printf(":") p.printValueAt(valType, valAddr) return true } p.printf("map[") if err := p.server.peekMapValues(typ, a, fn); err != nil { p.errorf("reading map values: %s", err) } if count > maxMapValuesToPrint { p.printf(" ...") } p.printf("]") } func (p *Printer) printChannelAt(ct *dwarf.ChanType, a uint64) { p.printf("(chan %s ", ct.ElemType) defer p.printf(")") a, err := p.server.peekPtr(a) if err != nil { p.errorf("reading channel: %s", err) return } if a == 0 { p.printf("") return } p.printf("%#x", a) // ct is a typedef for a pointer to a struct. pt, ok := ct.TypedefType.Type.(*dwarf.PtrType) if !ok { p.errorf("bad channel type: not a pointer") return } st, ok := pt.Type.(*dwarf.StructType) if !ok { p.errorf("bad channel type: not a pointer to a struct") return } // Print the channel buffer's length (qcount) and capacity (dataqsiz), // if not 0/0. qcount, err := p.server.peekUintOrIntStructField(st, a, "qcount") if err != nil { p.errorf("reading channel: %s", err) return } dataqsiz, err := p.server.peekUintOrIntStructField(st, a, "dataqsiz") if err != nil { p.errorf("reading channel: %s", err) return } if qcount != 0 || dataqsiz != 0 { p.printf(" [%d/%d]", qcount, dataqsiz) } } func (p *Printer) printSliceAt(typ *dwarf.SliceType, a uint64) { // Slices look like a struct with fields array *elemtype, len uint32/64, cap uint32/64. // BUG: Slice header appears to have fields with ByteSize == 0 ptr, err := p.server.peekPtrStructField(&typ.StructType, a, "array") if err != nil { p.errorf("reading slice: %s", err) return } length, err := p.server.peekUintOrIntStructField(&typ.StructType, a, "len") if err != nil { p.errorf("reading slice: %s", err) return } // Capacity is not used yet. _, err = p.server.peekUintOrIntStructField(&typ.StructType, a, "cap") if err != nil { p.errorf("reading slice: %s", err) return } elemType := typ.ElemType size, ok := p.sizeof(typ.ElemType) if !ok { p.errorf("can't determine element size") } p.printf("%s{", typ) for i := uint64(0); i < length; i++ { if i != 0 { p.printf(", ") } p.printValueAt(elemType, ptr) ptr += size // TODO: Alignment and padding - not given by Type } p.printf("}") } func (p *Printer) printStringAt(typ *dwarf.StringType, a uint64) { const maxStringSize = 100 if s, err := p.server.peekString(typ, a, maxStringSize); err != nil { p.errorf("reading string: %s", err) } else { p.printf("%q", s) } } // sizeof returns the byte size of the type. func (p *Printer) sizeof(typ dwarf.Type) (uint64, bool) { size := typ.Size() // Will be -1 if ByteSize is not set. if size >= 0 { return uint64(size), true } switch typ.(type) { case *dwarf.PtrType: // This is the only one we know of, but more may arise. return uint64(p.arch.PointerSize), true } return 0, false } // arrayStride returns the stride of a dwarf.ArrayType in bytes. func (p *Printer) arrayStride(t *dwarf.ArrayType) (uint64, bool) { stride := t.StrideBitSize if stride > 0 { return uint64(stride / 8), true } return p.sizeof(t.Type) } // getField finds the *dwarf.StructField in a dwarf.StructType with name fieldName. func getField(t *dwarf.StructType, fieldName string) (*dwarf.StructField, error) { var r *dwarf.StructField for _, f := range t.Field { if f.Name == fieldName { if r != nil { return nil, fmt.Errorf("struct definition repeats field %s", fieldName) } r = f } } if r == nil { return nil, fmt.Errorf("struct field %s missing", fieldName) } return r, nil } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/server/protocol/000077500000000000000000000000001356504100700272755ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/server/protocol/protocol.go000066400000000000000000000055461356504100700314770ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package protocol defines the types used to represent calls to the debug server. package protocol import ( "encoding/gob" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug" ) func init() { // Register implementations of debug.Value with gob. gob.Register(debug.Pointer{}) gob.Register(debug.Array{}) gob.Register(debug.Struct{}) gob.Register(debug.Slice{}) gob.Register(debug.Map{}) gob.Register(debug.String{}) gob.Register(debug.Channel{}) gob.Register(debug.Func{}) gob.Register(debug.Interface{}) } // For regularity, each method has a unique Request and a Response type even // when not strictly necessary. // File I/O, at the top because they're simple. type ReadAtRequest struct { FD int Len int Offset int64 } type ReadAtResponse struct { Data []byte } type WriteAtRequest struct { FD int Data []byte Offset int64 } type WriteAtResponse struct { Len int } type CloseRequest struct { FD int } type CloseResponse struct { } // Program methods. type OpenRequest struct { Name string Mode string } type OpenResponse struct { FD int } type RunRequest struct { Args []string } type RunResponse struct { Status debug.Status } type ResumeRequest struct { } type ResumeResponse struct { Status debug.Status } type BreakpointRequest struct { Address uint64 } type BreakpointAtFunctionRequest struct { Function string } type BreakpointAtLineRequest struct { File string Line uint64 } type BreakpointResponse struct { PCs []uint64 } type DeleteBreakpointsRequest struct { PCs []uint64 } type DeleteBreakpointsResponse struct { } type EvalRequest struct { Expr string } type EvalResponse struct { Result []string } type EvaluateRequest struct { Expression string } type EvaluateResponse struct { Result debug.Value } type FramesRequest struct { Count int } type FramesResponse struct { Frames []debug.Frame } type VarByNameRequest struct { Name string } type VarByNameResponse struct { Var debug.Var } type ValueRequest struct { Var debug.Var } type ValueResponse struct { Value debug.Value } type MapElementRequest struct { Map debug.Map Index uint64 } type MapElementResponse struct { Key debug.Var Value debug.Var } type GoroutinesRequest struct { } type GoroutinesResponse struct { Goroutines []*debug.Goroutine } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/server/ptrace.go000066400000000000000000000073651356504100700272540ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // +build linux package server import ( "fmt" "os" "runtime" "syscall" "time" ) // ptraceRun runs all the closures from fc on a dedicated OS thread. Errors // are returned on ec. Both channels must be unbuffered, to ensure that the // resultant error is sent back to the same goroutine that sent the closure. func ptraceRun(fc chan func() error, ec chan error) { if cap(fc) != 0 || cap(ec) != 0 { panic("ptraceRun was given buffered channels") } runtime.LockOSThread() for f := range fc { ec <- f() } } func (s *Server) startProcess(name string, argv []string, attr *os.ProcAttr) (proc *os.Process, err error) { s.fc <- func() error { var err1 error proc, err1 = os.StartProcess(name, argv, attr) return err1 } err = <-s.ec return } func (s *Server) ptraceCont(pid int, signal int) (err error) { s.fc <- func() error { return syscall.PtraceCont(pid, signal) } return <-s.ec } func (s *Server) ptraceGetRegs(pid int, regsout *syscall.PtraceRegs) (err error) { s.fc <- func() error { return syscall.PtraceGetRegs(pid, regsout) } return <-s.ec } func (s *Server) ptracePeek(pid int, addr uintptr, out []byte) (err error) { s.fc <- func() error { n, err := syscall.PtracePeekText(pid, addr, out) if err != nil { return err } if n != len(out) { return fmt.Errorf("ptracePeek: peeked %d bytes, want %d", n, len(out)) } return nil } return <-s.ec } func (s *Server) ptracePoke(pid int, addr uintptr, data []byte) (err error) { s.fc <- func() error { n, err := syscall.PtracePokeText(pid, addr, data) if err != nil { return err } if n != len(data) { return fmt.Errorf("ptracePoke: poked %d bytes, want %d", n, len(data)) } return nil } return <-s.ec } func (s *Server) ptraceSetOptions(pid int, options int) (err error) { s.fc <- func() error { return syscall.PtraceSetOptions(pid, options) } return <-s.ec } func (s *Server) ptraceSetRegs(pid int, regs *syscall.PtraceRegs) (err error) { s.fc <- func() error { return syscall.PtraceSetRegs(pid, regs) } return <-s.ec } func (s *Server) ptraceSingleStep(pid int) (err error) { s.fc <- func() error { return syscall.PtraceSingleStep(pid) } return <-s.ec } type breakpointsChangedError struct { call call } func (*breakpointsChangedError) Error() string { return "breakpoints changed" } func (s *Server) wait(pid int, allowBreakpointsChange bool) (wpid int, status syscall.WaitStatus, err error) { // We poll syscall.Wait4 with WNOHANG, sleeping in between, as a poor man's // waitpid-with-timeout. This allows adding and removing breakpoints // concurrently with waiting to hit an existing breakpoint. f := func() error { var err1 error wpid, err1 = syscall.Wait4(pid, &status, syscall.WALL|syscall.WNOHANG, nil) return err1 } const ( minSleep = 1 * time.Microsecond maxSleep = 100 * time.Millisecond ) for sleep := minSleep; ; { s.fc <- f err = <-s.ec // wpid == 0 means that wait found nothing (and returned due to WNOHANG). if wpid != 0 { return } if allowBreakpointsChange { select { case c := <-s.breakpointc: return 0, 0, &breakpointsChangedError{c} default: } } time.Sleep(sleep) if sleep < maxSleep { sleep *= 10 } } } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/server/server.go000066400000000000000000000761651356504100700273100ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // +build linux // Package server provides RPC access to a local program being debugged. // It is the remote end of the client implementation of the Program interface. package server //go:generate sh -c "m4 -P eval.m4 > eval.go" import ( "bytes" "errors" "fmt" "os" "regexp" "strconv" "strings" "sync" "syscall" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/arch" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/dwarf" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/elf" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/server/protocol" ) type breakpoint struct { pc uint64 origInstr [arch.MaxBreakpointSize]byte } type call struct { req, resp interface{} errc chan error } type Server struct { arch arch.Architecture executable string // Name of executable. dwarfData *dwarf.Data breakpointc chan call otherc chan call fc chan func() error ec chan error proc *os.Process procIsUp bool stoppedPid int stoppedRegs syscall.PtraceRegs topOfStackAddrs []uint64 breakpoints map[uint64]breakpoint files []*file // Index == file descriptor. printer *Printer // goroutineStack reads the stack of a (non-running) goroutine. goroutineStack func(uint64) ([]debug.Frame, error) goroutineStackOnce sync.Once } // peek implements the Peeker interface required by the printer. func (s *Server) peek(offset uintptr, buf []byte) error { return s.ptracePeek(s.stoppedPid, offset, buf) } // New parses the executable and builds local data structures for answering requests. // It returns a Server ready to serve requests about the executable. func New(executable string) (*Server, error) { fd, err := os.Open(executable) if err != nil { return nil, err } defer fd.Close() architecture, dwarfData, err := loadExecutable(fd) if err != nil { return nil, err } srv := &Server{ arch: *architecture, executable: executable, dwarfData: dwarfData, breakpointc: make(chan call), otherc: make(chan call), fc: make(chan func() error), ec: make(chan error), breakpoints: make(map[uint64]breakpoint), } srv.printer = NewPrinter(architecture, dwarfData, srv) go ptraceRun(srv.fc, srv.ec) go srv.loop() return srv, nil } func loadExecutable(f *os.File) (*arch.Architecture, *dwarf.Data, error) { // TODO: How do we detect NaCl? if obj, err := elf.NewFile(f); err == nil { dwarfData, err := obj.DWARF() if err != nil { return nil, nil, err } switch obj.Machine { case elf.EM_ARM: return &arch.ARM, dwarfData, nil case elf.EM_386: switch obj.Class { case elf.ELFCLASS32: return &arch.X86, dwarfData, nil case elf.ELFCLASS64: return &arch.AMD64, dwarfData, nil } case elf.EM_X86_64: return &arch.AMD64, dwarfData, nil } return nil, nil, fmt.Errorf("unrecognized ELF architecture") } return nil, nil, fmt.Errorf("unrecognized binary format") } func (s *Server) loop() { for { var c call select { case c = <-s.breakpointc: case c = <-s.otherc: } s.dispatch(c) } } func (s *Server) dispatch(c call) { switch req := c.req.(type) { case *protocol.BreakpointRequest: c.errc <- s.handleBreakpoint(req, c.resp.(*protocol.BreakpointResponse)) case *protocol.BreakpointAtFunctionRequest: c.errc <- s.handleBreakpointAtFunction(req, c.resp.(*protocol.BreakpointResponse)) case *protocol.BreakpointAtLineRequest: c.errc <- s.handleBreakpointAtLine(req, c.resp.(*protocol.BreakpointResponse)) case *protocol.DeleteBreakpointsRequest: c.errc <- s.handleDeleteBreakpoints(req, c.resp.(*protocol.DeleteBreakpointsResponse)) case *protocol.CloseRequest: c.errc <- s.handleClose(req, c.resp.(*protocol.CloseResponse)) case *protocol.EvalRequest: c.errc <- s.handleEval(req, c.resp.(*protocol.EvalResponse)) case *protocol.EvaluateRequest: c.errc <- s.handleEvaluate(req, c.resp.(*protocol.EvaluateResponse)) case *protocol.FramesRequest: c.errc <- s.handleFrames(req, c.resp.(*protocol.FramesResponse)) case *protocol.OpenRequest: c.errc <- s.handleOpen(req, c.resp.(*protocol.OpenResponse)) case *protocol.ReadAtRequest: c.errc <- s.handleReadAt(req, c.resp.(*protocol.ReadAtResponse)) case *protocol.ResumeRequest: c.errc <- s.handleResume(req, c.resp.(*protocol.ResumeResponse)) case *protocol.RunRequest: c.errc <- s.handleRun(req, c.resp.(*protocol.RunResponse)) case *protocol.VarByNameRequest: c.errc <- s.handleVarByName(req, c.resp.(*protocol.VarByNameResponse)) case *protocol.ValueRequest: c.errc <- s.handleValue(req, c.resp.(*protocol.ValueResponse)) case *protocol.MapElementRequest: c.errc <- s.handleMapElement(req, c.resp.(*protocol.MapElementResponse)) case *protocol.GoroutinesRequest: c.errc <- s.handleGoroutines(req, c.resp.(*protocol.GoroutinesResponse)) default: panic(fmt.Sprintf("unexpected call request type %T", c.req)) } } func (s *Server) call(c chan call, req, resp interface{}) error { errc := make(chan error) c <- call{req, resp, errc} return <-errc } type file struct { mode string index int f debug.File } func (s *Server) Open(req *protocol.OpenRequest, resp *protocol.OpenResponse) error { return s.call(s.otherc, req, resp) } func (s *Server) handleOpen(req *protocol.OpenRequest, resp *protocol.OpenResponse) error { // TODO: Better simulation. For now we just open the named OS file. var flag int switch req.Mode { case "r": flag = os.O_RDONLY case "w": flag = os.O_WRONLY case "rw": flag = os.O_RDWR default: return fmt.Errorf("Open: bad open mode %q", req.Mode) } osFile, err := os.OpenFile(req.Name, flag, 0) if err != nil { return err } // Find a file descriptor (index) slot. index := 0 for ; index < len(s.files) && s.files[index] != nil; index++ { } f := &file{ mode: req.Mode, index: index, f: osFile, } if index == len(s.files) { s.files = append(s.files, f) } else { s.files[index] = f } return nil } func (s *Server) ReadAt(req *protocol.ReadAtRequest, resp *protocol.ReadAtResponse) error { return s.call(s.otherc, req, resp) } func (s *Server) handleReadAt(req *protocol.ReadAtRequest, resp *protocol.ReadAtResponse) error { fd := req.FD if fd < 0 || len(s.files) <= fd || s.files[fd] == nil { return fmt.Errorf("ReadAt: bad file descriptor %d", fd) } f := s.files[fd] buf := make([]byte, req.Len) // TODO: Don't allocate every time n, err := f.f.ReadAt(buf, req.Offset) resp.Data = buf[:n] return err } func (s *Server) Close(req *protocol.CloseRequest, resp *protocol.CloseResponse) error { return s.call(s.otherc, req, resp) } func (s *Server) handleClose(req *protocol.CloseRequest, resp *protocol.CloseResponse) error { fd := req.FD if fd < 0 || fd >= len(s.files) || s.files[fd] == nil { return fmt.Errorf("Close: bad file descriptor %d", fd) } err := s.files[fd].f.Close() // Remove it regardless s.files[fd] = nil return err } func (s *Server) Run(req *protocol.RunRequest, resp *protocol.RunResponse) error { return s.call(s.otherc, req, resp) } func (s *Server) handleRun(req *protocol.RunRequest, resp *protocol.RunResponse) error { if s.proc != nil { s.proc.Kill() s.proc = nil s.procIsUp = false s.stoppedPid = 0 s.stoppedRegs = syscall.PtraceRegs{} s.topOfStackAddrs = nil } argv := append([]string{s.executable}, req.Args...) p, err := s.startProcess(s.executable, argv, &os.ProcAttr{ Files: []*os.File{ nil, // TODO: be able to feed the target's stdin. os.Stderr, // TODO: be able to capture the target's stdout. os.Stderr, }, Sys: &syscall.SysProcAttr{ Pdeathsig: syscall.SIGKILL, Ptrace: true, }, }) if err != nil { return err } s.proc = p s.stoppedPid = p.Pid return nil } func (s *Server) Resume(req *protocol.ResumeRequest, resp *protocol.ResumeResponse) error { return s.call(s.otherc, req, resp) } func (s *Server) handleResume(req *protocol.ResumeRequest, resp *protocol.ResumeResponse) error { if s.proc == nil { return fmt.Errorf("Resume: Run did not successfully start a process") } if !s.procIsUp { s.procIsUp = true if _, err := s.waitForTrap(s.stoppedPid, false); err != nil { return err } if err := s.ptraceSetOptions(s.stoppedPid, syscall.PTRACE_O_TRACECLONE); err != nil { return fmt.Errorf("ptraceSetOptions: %v", err) } } else if _, ok := s.breakpoints[s.stoppedRegs.Rip]; ok { if err := s.ptraceSingleStep(s.stoppedPid); err != nil { return fmt.Errorf("ptraceSingleStep: %v", err) } if _, err := s.waitForTrap(s.stoppedPid, false); err != nil { return err } } for { if err := s.setBreakpoints(); err != nil { return err } if err := s.ptraceCont(s.stoppedPid, 0); err != nil { return fmt.Errorf("ptraceCont: %v", err) } wpid, err := s.waitForTrap(-1, true) if err == nil { s.stoppedPid = wpid break } bce, ok := err.(*breakpointsChangedError) if !ok { return err } if err := syscall.Kill(s.stoppedPid, syscall.SIGSTOP); err != nil { return fmt.Errorf("kill(SIGSTOP): %v", err) } _, status, err := s.wait(s.stoppedPid, false) if err != nil { return fmt.Errorf("wait (after SIGSTOP): %v", err) } if !status.Stopped() || status.StopSignal() != syscall.SIGSTOP { return fmt.Errorf("wait (after SIGSTOP): unexpected wait status 0x%x", status) } if err := s.liftBreakpoints(); err != nil { return err } loop: for c := bce.call; ; { s.dispatch(c) select { case c = <-s.breakpointc: default: break loop } } } if err := s.liftBreakpoints(); err != nil { return err } if err := s.ptraceGetRegs(s.stoppedPid, &s.stoppedRegs); err != nil { return fmt.Errorf("ptraceGetRegs: %v", err) } s.stoppedRegs.Rip -= uint64(s.arch.BreakpointSize) if err := s.ptraceSetRegs(s.stoppedPid, &s.stoppedRegs); err != nil { return fmt.Errorf("ptraceSetRegs: %v", err) } resp.Status.PC = s.stoppedRegs.Rip resp.Status.SP = s.stoppedRegs.Rsp return nil } func (s *Server) waitForTrap(pid int, allowBreakpointsChange bool) (wpid int, err error) { for { wpid, status, err := s.wait(pid, allowBreakpointsChange) if err != nil { if _, ok := err.(*breakpointsChangedError); !ok { err = fmt.Errorf("wait: %v", err) } return 0, err } if status.StopSignal() == syscall.SIGTRAP && status.TrapCause() != syscall.PTRACE_EVENT_CLONE { return wpid, nil } if status.StopSignal() == syscall.SIGPROF { err = s.ptraceCont(wpid, int(syscall.SIGPROF)) } else { err = s.ptraceCont(wpid, 0) // TODO: non-zero when wait catches other signals? } if err != nil { return 0, fmt.Errorf("ptraceCont: %v", err) } } } func (s *Server) Breakpoint(req *protocol.BreakpointRequest, resp *protocol.BreakpointResponse) error { return s.call(s.breakpointc, req, resp) } func (s *Server) handleBreakpoint(req *protocol.BreakpointRequest, resp *protocol.BreakpointResponse) error { return s.addBreakpoints([]uint64{req.Address}, resp) } func (s *Server) BreakpointAtFunction(req *protocol.BreakpointAtFunctionRequest, resp *protocol.BreakpointResponse) error { return s.call(s.breakpointc, req, resp) } func (s *Server) handleBreakpointAtFunction(req *protocol.BreakpointAtFunctionRequest, resp *protocol.BreakpointResponse) error { pc, err := s.functionStartAddress(req.Function) if err != nil { return err } return s.addBreakpoints([]uint64{pc}, resp) } func (s *Server) BreakpointAtLine(req *protocol.BreakpointAtLineRequest, resp *protocol.BreakpointResponse) error { return s.call(s.breakpointc, req, resp) } func (s *Server) handleBreakpointAtLine(req *protocol.BreakpointAtLineRequest, resp *protocol.BreakpointResponse) error { if s.dwarfData == nil { return fmt.Errorf("no DWARF data") } if pcs, err := s.dwarfData.LineToBreakpointPCs(req.File, req.Line); err != nil { return err } else { return s.addBreakpoints(pcs, resp) } } // addBreakpoints adds breakpoints at the addresses in pcs, then stores pcs in the response. func (s *Server) addBreakpoints(pcs []uint64, resp *protocol.BreakpointResponse) error { // Get the original code at each address with ptracePeek. bps := make([]breakpoint, 0, len(pcs)) for _, pc := range pcs { if _, alreadySet := s.breakpoints[pc]; alreadySet { continue } var bp breakpoint if err := s.ptracePeek(s.stoppedPid, uintptr(pc), bp.origInstr[:s.arch.BreakpointSize]); err != nil { return fmt.Errorf("ptracePeek: %v", err) } bp.pc = pc bps = append(bps, bp) } // If all the peeks succeeded, update the list of breakpoints. for _, bp := range bps { s.breakpoints[bp.pc] = bp } resp.PCs = pcs return nil } func (s *Server) DeleteBreakpoints(req *protocol.DeleteBreakpointsRequest, resp *protocol.DeleteBreakpointsResponse) error { return s.call(s.breakpointc, req, resp) } func (s *Server) handleDeleteBreakpoints(req *protocol.DeleteBreakpointsRequest, resp *protocol.DeleteBreakpointsResponse) error { for _, pc := range req.PCs { delete(s.breakpoints, pc) } return nil } func (s *Server) setBreakpoints() error { for pc := range s.breakpoints { err := s.ptracePoke(s.stoppedPid, uintptr(pc), s.arch.BreakpointInstr[:s.arch.BreakpointSize]) if err != nil { return fmt.Errorf("setBreakpoints: %v", err) } } return nil } func (s *Server) liftBreakpoints() error { for pc, breakpoint := range s.breakpoints { err := s.ptracePoke(s.stoppedPid, uintptr(pc), breakpoint.origInstr[:s.arch.BreakpointSize]) if err != nil { return fmt.Errorf("liftBreakpoints: %v", err) } } return nil } func (s *Server) Eval(req *protocol.EvalRequest, resp *protocol.EvalResponse) error { return s.call(s.otherc, req, resp) } func (s *Server) handleEval(req *protocol.EvalRequest, resp *protocol.EvalResponse) (err error) { resp.Result, err = s.eval(req.Expr) return err } // eval evaluates an expression. // TODO: very weak. func (s *Server) eval(expr string) ([]string, error) { switch { case strings.HasPrefix(expr, "re:"): // Regular expression. Return list of symbols. re, err := regexp.Compile(expr[3:]) if err != nil { return nil, err } return s.dwarfData.LookupMatchingSymbols(re) case strings.HasPrefix(expr, "addr:"): // Symbol lookup. Return address. addr, err := s.functionStartAddress(expr[5:]) if err != nil { return nil, err } return []string{fmt.Sprintf("%#x", addr)}, nil case strings.HasPrefix(expr, "val:"): // Symbol lookup. Return formatted value. value, err := s.printer.Sprint(expr[4:]) if err != nil { return nil, err } return []string{value}, nil case strings.HasPrefix(expr, "src:"): // Numerical address. Return file.go:123. addr, err := strconv.ParseUint(expr[4:], 0, 0) if err != nil { return nil, err } file, line, err := s.lookupSource(addr) if err != nil { return nil, err } return []string{fmt.Sprintf("%s:%d", file, line)}, nil case len(expr) > 0 && '0' <= expr[0] && expr[0] <= '9': // Numerical address. Return symbol. addr, err := strconv.ParseUint(expr, 0, 0) if err != nil { return nil, err } entry, _, err := s.dwarfData.PCToFunction(addr) if err != nil { return nil, err } name, ok := entry.Val(dwarf.AttrName).(string) if !ok { return nil, fmt.Errorf("function at 0x%x has no name", addr) } return []string{name}, nil } return nil, fmt.Errorf("bad expression syntax: %q", expr) } func (s *Server) Evaluate(req *protocol.EvaluateRequest, resp *protocol.EvaluateResponse) error { return s.call(s.otherc, req, resp) } func (s *Server) handleEvaluate(req *protocol.EvaluateRequest, resp *protocol.EvaluateResponse) (err error) { resp.Result, err = s.evalExpression(req.Expression, s.stoppedRegs.Rip, s.stoppedRegs.Rsp) return err } func (s *Server) lookupSource(pc uint64) (file string, line uint64, err error) { if s.dwarfData == nil { return } // TODO: The gosym equivalent also returns the relevant Func. Do that when // DWARF has the same facility. return s.dwarfData.PCToLine(pc) } func (s *Server) Frames(req *protocol.FramesRequest, resp *protocol.FramesResponse) error { return s.call(s.otherc, req, resp) } func (s *Server) handleFrames(req *protocol.FramesRequest, resp *protocol.FramesResponse) error { // TODO: verify that we're stopped. if s.topOfStackAddrs == nil { if err := s.evaluateTopOfStackAddrs(); err != nil { return err } } regs := syscall.PtraceRegs{} err := s.ptraceGetRegs(s.stoppedPid, ®s) if err != nil { return err } resp.Frames, err = s.walkStack(regs.Rip, regs.Rsp, req.Count) return err } // walkStack returns up to the requested number of stack frames. func (s *Server) walkStack(pc, sp uint64, count int) ([]debug.Frame, error) { var frames []debug.Frame var buf [8]byte b := new(bytes.Buffer) r := s.dwarfData.Reader() // TODO: handle walking over a split stack. for i := 0; i < count; i++ { b.Reset() file, line, err := s.dwarfData.PCToLine(pc) if err != nil { return frames, err } fpOffset, err := s.dwarfData.PCToSPOffset(pc) if err != nil { return frames, err } fp := sp + uint64(fpOffset) entry, funcEntry, err := s.dwarfData.PCToFunction(pc) if err != nil { return frames, err } frame := debug.Frame{ PC: pc, SP: sp, File: file, Line: line, FunctionStart: funcEntry, } frame.Function, _ = entry.Val(dwarf.AttrName).(string) r.Seek(entry.Offset) for { entry, err := r.Next() if err != nil { return frames, err } if entry.Tag == 0 { break } // TODO: report variables we couldn't parse? if entry.Tag == dwarf.TagFormalParameter { if v, err := s.parseParameterOrLocal(entry, fp); err == nil { frame.Params = append(frame.Params, debug.Param(v)) } } if entry.Tag == dwarf.TagVariable { if v, err := s.parseParameterOrLocal(entry, fp); err == nil { frame.Vars = append(frame.Vars, v) } } } frames = append(frames, frame) // Walk to the caller's PC and SP. if s.topOfStack(funcEntry) { break } err = s.ptracePeek(s.stoppedPid, uintptr(fp-uint64(s.arch.PointerSize)), buf[:s.arch.PointerSize]) if err != nil { return frames, fmt.Errorf("ptracePeek: %v", err) } pc, sp = s.arch.Uintptr(buf[:s.arch.PointerSize]), fp } return frames, nil } // parseParameterOrLocal parses the entry for a function parameter or local // variable, which are both specified the same way. fp contains the frame // pointer, which is used to calculate the variable location. func (s *Server) parseParameterOrLocal(entry *dwarf.Entry, fp uint64) (debug.LocalVar, error) { var v debug.LocalVar v.Name, _ = entry.Val(dwarf.AttrName).(string) if off, err := s.dwarfData.EntryTypeOffset(entry); err != nil { return v, err } else { v.Var.TypeID = uint64(off) } if i := entry.Val(dwarf.AttrLocation); i == nil { return v, fmt.Errorf("missing location description") } else if locationDescription, ok := i.([]uint8); !ok { return v, fmt.Errorf("unsupported location description") } else if offset, err := evalLocation(locationDescription); err != nil { return v, err } else { v.Var.Address = fp + uint64(offset) } return v, nil } func (s *Server) evaluateTopOfStackAddrs() error { var ( lookup func(name string) (uint64, error) indirect bool names []string ) if _, err := s.dwarfData.LookupVariable("runtime.rt0_goPC"); err != nil { // Look for a Go 1.3 binary (or earlier version). lookup, indirect, names = s.functionStartAddress, false, []string{ "runtime.goexit", "runtime.mstart", "runtime.mcall", "runtime.morestack", "runtime.lessstack", "_rt0_go", } } else { // Look for a Go 1.4 binary (or later version). lookup = func(name string) (uint64, error) { entry, err := s.dwarfData.LookupVariable(name) if err != nil { return 0, err } return s.dwarfData.EntryLocation(entry) } indirect, names = true, []string{ "runtime.goexitPC", "runtime.mstartPC", "runtime.mcallPC", "runtime.morestackPC", "runtime.rt0_goPC", } } // TODO: also look for runtime.externalthreadhandlerp, on Windows. addrs := make([]uint64, 0, len(names)) for _, name := range names { addr, err := lookup(name) if err != nil { return err } addrs = append(addrs, addr) } if indirect { buf := make([]byte, s.arch.PointerSize) for i, addr := range addrs { if err := s.ptracePeek(s.stoppedPid, uintptr(addr), buf); err != nil { return fmt.Errorf("ptracePeek: %v", err) } addrs[i] = s.arch.Uintptr(buf) } } s.topOfStackAddrs = addrs return nil } // topOfStack is the out-of-process equivalent of runtime·topofstack. func (s *Server) topOfStack(funcEntry uint64) bool { for _, addr := range s.topOfStackAddrs { if addr == funcEntry { return true } } return false } func (s *Server) VarByName(req *protocol.VarByNameRequest, resp *protocol.VarByNameResponse) error { return s.call(s.otherc, req, resp) } func (s *Server) handleVarByName(req *protocol.VarByNameRequest, resp *protocol.VarByNameResponse) error { entry, err := s.dwarfData.LookupVariable(req.Name) if err != nil { return fmt.Errorf("variable %s: %s", req.Name, err) } loc, err := s.dwarfData.EntryLocation(entry) if err != nil { return fmt.Errorf("variable %s: %s", req.Name, err) } off, err := s.dwarfData.EntryTypeOffset(entry) if err != nil { return fmt.Errorf("variable %s: %s", req.Name, err) } resp.Var.TypeID = uint64(off) resp.Var.Address = loc return nil } func (s *Server) Value(req *protocol.ValueRequest, resp *protocol.ValueResponse) error { return s.call(s.otherc, req, resp) } func (s *Server) handleValue(req *protocol.ValueRequest, resp *protocol.ValueResponse) error { t, err := s.dwarfData.Type(dwarf.Offset(req.Var.TypeID)) if err != nil { return err } resp.Value, err = s.value(t, req.Var.Address) return err } func (s *Server) MapElement(req *protocol.MapElementRequest, resp *protocol.MapElementResponse) error { return s.call(s.otherc, req, resp) } func (s *Server) handleMapElement(req *protocol.MapElementRequest, resp *protocol.MapElementResponse) error { t, err := s.dwarfData.Type(dwarf.Offset(req.Map.TypeID)) if err != nil { return err } m, ok := t.(*dwarf.MapType) if !ok { return fmt.Errorf("variable is not a map") } var count uint64 // fn will be called for each element of the map. // When we reach the requested element, we fill in *resp and stop. // TODO: cache locations of elements. fn := func(keyAddr, valAddr uint64, keyType, valType dwarf.Type) bool { count++ if count == req.Index+1 { resp.Key = debug.Var{TypeID: uint64(keyType.Common().Offset), Address: keyAddr} resp.Value = debug.Var{TypeID: uint64(valType.Common().Offset), Address: valAddr} return false } return true } if err := s.peekMapValues(m, req.Map.Address, fn); err != nil { return err } if count <= req.Index { // There weren't enough elements. return fmt.Errorf("map has no element %d", req.Index) } return nil } func (s *Server) Goroutines(req *protocol.GoroutinesRequest, resp *protocol.GoroutinesResponse) error { return s.call(s.otherc, req, resp) } const invalidStatus debug.GoroutineStatus = 99 var ( gStatus = [...]debug.GoroutineStatus{ 0: debug.Queued, // _Gidle 1: debug.Queued, // _Grunnable 2: debug.Running, // _Grunning 3: debug.Blocked, // _Gsyscall 4: debug.Blocked, // _Gwaiting 5: invalidStatus, // _Gmoribund_unused 6: invalidStatus, // _Gdead 7: invalidStatus, // _Genqueue 8: debug.Running, // _Gcopystack } gScanStatus = [...]debug.GoroutineStatus{ 0: invalidStatus, // _Gscan + _Gidle 1: debug.Queued, // _Gscanrunnable 2: debug.Running, // _Gscanrunning 3: debug.Blocked, // _Gscansyscall 4: debug.Blocked, // _Gscanwaiting 5: invalidStatus, // _Gscan + _Gmoribund_unused 6: invalidStatus, // _Gscan + _Gdead 7: debug.Queued, // _Gscanenqueue } gStatusString = [...]string{ 0: "idle", 1: "runnable", 2: "running", 3: "syscall", 4: "waiting", 8: "copystack", } gScanStatusString = [...]string{ 1: "scanrunnable", 2: "scanrunning", 3: "scansyscall", 4: "scanwaiting", 7: "scanenqueue", } ) func (s *Server) handleGoroutines(req *protocol.GoroutinesRequest, resp *protocol.GoroutinesResponse) error { // Get DWARF type information for runtime.g. ge, err := s.dwarfData.LookupEntry("runtime.g") if err != nil { return err } t, err := s.dwarfData.Type(ge.Offset) if err != nil { return err } gType, ok := followTypedefs(t).(*dwarf.StructType) if !ok { return errors.New("runtime.g is not a struct") } var ( allgPtr, allgLen uint64 allgPtrOk bool ) for { // Try to read the slice runtime.allgs. allgsEntry, err := s.dwarfData.LookupVariable("runtime.allgs") if err != nil { break } allgsAddr, err := s.dwarfData.EntryLocation(allgsEntry) if err != nil { break } off, err := s.dwarfData.EntryTypeOffset(allgsEntry) if err != nil { break } t, err := s.dwarfData.Type(off) if err != nil { break } allgsType, ok := followTypedefs(t).(*dwarf.SliceType) if !ok { break } allgs, err := s.peekSlice(allgsType, allgsAddr) if err != nil { break } allgPtr, allgLen, allgPtrOk = allgs.Address, allgs.Length, true break } if !allgPtrOk { // Read runtime.allg. allgEntry, err := s.dwarfData.LookupVariable("runtime.allg") if err != nil { return err } allgAddr, err := s.dwarfData.EntryLocation(allgEntry) if err != nil { return err } allgPtr, err = s.peekPtr(allgAddr) if err != nil { return fmt.Errorf("reading allg: %v", err) } // Read runtime.allglen. allglenEntry, err := s.dwarfData.LookupVariable("runtime.allglen") if err != nil { return err } off, err := s.dwarfData.EntryTypeOffset(allglenEntry) if err != nil { return err } allglenType, err := s.dwarfData.Type(off) if err != nil { return err } allglenAddr, err := s.dwarfData.EntryLocation(allglenEntry) if err != nil { return err } switch followTypedefs(allglenType).(type) { case *dwarf.UintType, *dwarf.IntType: allgLen, err = s.peekUint(allglenAddr, allglenType.Common().ByteSize) if err != nil { return fmt.Errorf("reading allglen: %v", err) } default: // Some runtimes don't specify the type for allglen. Assume it's uint32. allgLen, err = s.peekUint(allglenAddr, 4) if err != nil { return fmt.Errorf("reading allglen: %v", err) } if allgLen != 0 { break } // Zero? Let's try uint64. allgLen, err = s.peekUint(allglenAddr, 8) if err != nil { return fmt.Errorf("reading allglen: %v", err) } } } // Initialize s.goroutineStack. s.goroutineStackOnce.Do(func() { s.goroutineStackInit(gType) }) for i := uint64(0); i < allgLen; i++ { // allg is an array of pointers to g structs. Read allg[i]. g, err := s.peekPtr(allgPtr + i*uint64(s.arch.PointerSize)) if err != nil { return err } gr := debug.Goroutine{} // Read status from the field named "atomicstatus" or "status". status, err := s.peekUintStructField(gType, g, "atomicstatus") if err != nil { status, err = s.peekUintOrIntStructField(gType, g, "status") } if err != nil { return err } if status == 6 { // _Gdead. continue } gr.Status = invalidStatus if status < uint64(len(gStatus)) { gr.Status = gStatus[status] gr.StatusString = gStatusString[status] } else if status^0x1000 < uint64(len(gScanStatus)) { gr.Status = gScanStatus[status^0x1000] gr.StatusString = gScanStatusString[status^0x1000] } if gr.Status == invalidStatus { return fmt.Errorf("unexpected goroutine status 0x%x", status) } if status == 4 || status == 0x1004 { // _Gwaiting or _Gscanwaiting. // Try reading waitreason to get a better value for StatusString. // Depending on the runtime, waitreason may be a Go string or a C string. if waitreason, err := s.peekStringStructField(gType, g, "waitreason", 80); err == nil { if waitreason != "" { gr.StatusString = waitreason } } else if ptr, err := s.peekPtrStructField(gType, g, "waitreason"); err == nil { waitreason := s.peekCString(ptr, 80) if waitreason != "" { gr.StatusString = waitreason } } } gr.ID, err = s.peekIntStructField(gType, g, "goid") if err != nil { return err } // Best-effort attempt to get the names of the goroutine function and the // function that created the goroutine. They aren't always available. functionName := func(pc uint64) string { entry, _, err := s.dwarfData.PCToFunction(pc) if err != nil { return "" } name, _ := entry.Val(dwarf.AttrName).(string) return name } if startpc, err := s.peekUintStructField(gType, g, "startpc"); err == nil { gr.Function = functionName(startpc) } if gopc, err := s.peekUintStructField(gType, g, "gopc"); err == nil { gr.Caller = functionName(gopc) } if gr.Status != debug.Running { // TODO: running goroutines too. gr.StackFrames, _ = s.goroutineStack(g) } resp.Goroutines = append(resp.Goroutines, &gr) } return nil } // TODO: let users specify how many frames they want. 10 will be enough to // determine the reason a goroutine is blocked. const goroutineStackFrameCount = 10 // goroutineStackInit initializes s.goroutineStack. func (s *Server) goroutineStackInit(gType *dwarf.StructType) { // If we fail to read the DWARF data needed for s.goroutineStack, calling it // will always return the error that occurred during initialization. var err error // err is captured by the func below. s.goroutineStack = func(gAddr uint64) ([]debug.Frame, error) { return nil, err } // Get g field "sched", which contains fields pc and sp. schedField, err := getField(gType, "sched") if err != nil { return } schedOffset := uint64(schedField.ByteOffset) schedType, ok := followTypedefs(schedField.Type).(*dwarf.StructType) if !ok { err = errors.New(`g field "sched" has the wrong type`) return } // Get the size of the pc and sp fields and their offsets inside the g struct, // so we can quickly peek those values for each goroutine later. var ( schedPCOffset, schedSPOffset uint64 schedPCByteSize, schedSPByteSize int64 ) for _, x := range []struct { field string offset *uint64 bytesize *int64 }{ {"pc", &schedPCOffset, &schedPCByteSize}, {"sp", &schedSPOffset, &schedSPByteSize}, } { var f *dwarf.StructField f, err = getField(schedType, x.field) if err != nil { return } *x.offset = schedOffset + uint64(f.ByteOffset) switch t := followTypedefs(f.Type).(type) { case *dwarf.UintType, *dwarf.IntType: *x.bytesize = t.Common().ByteSize default: err = fmt.Errorf("gobuf field %q has the wrong type", x.field) return } } s.goroutineStack = func(gAddr uint64) ([]debug.Frame, error) { schedPC, err := s.peekUint(gAddr+schedPCOffset, schedPCByteSize) if err != nil { return nil, err } schedSP, err := s.peekUint(gAddr+schedSPOffset, schedSPByteSize) if err != nil { return nil, err } return s.walkStack(schedPC, schedSP, goroutineStackFrameCount) } } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/server/value.go000066400000000000000000000155331356504100700271060ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // +build linux package server import ( "fmt" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/dwarf" ) // value peeks the program's memory at the given address, parsing it as a value of type t. func (s *Server) value(t dwarf.Type, addr uint64) (debug.Value, error) { // readBasic reads the memory for a basic type of size n bytes. readBasic := func(n int64) ([]byte, error) { switch n { case 1, 2, 4, 8, 16: default: return nil, fmt.Errorf("invalid size: %d", n) } buf := make([]byte, n) if err := s.peek(uintptr(addr), buf); err != nil { return nil, err } return buf, nil } switch t := t.(type) { case *dwarf.CharType, *dwarf.IntType: bs := t.Common().ByteSize buf, err := readBasic(bs) if err != nil { return nil, fmt.Errorf("reading integer: %s", err) } x := s.arch.IntN(buf) switch bs { case 1: return int8(x), nil case 2: return int16(x), nil case 4: return int32(x), nil case 8: return int64(x), nil default: return nil, fmt.Errorf("invalid integer size: %d", bs) } case *dwarf.UcharType, *dwarf.UintType, *dwarf.AddrType: bs := t.Common().ByteSize buf, err := readBasic(bs) if err != nil { return nil, fmt.Errorf("reading unsigned integer: %s", err) } x := s.arch.UintN(buf) switch bs { case 1: return uint8(x), nil case 2: return uint16(x), nil case 4: return uint32(x), nil case 8: return uint64(x), nil default: return nil, fmt.Errorf("invalid unsigned integer size: %d", bs) } case *dwarf.BoolType: bs := t.Common().ByteSize buf, err := readBasic(bs) if err != nil { return nil, fmt.Errorf("reading boolean: %s", err) } for _, b := range buf { if b != 0 { return true, nil } } return false, nil case *dwarf.FloatType: bs := t.Common().ByteSize buf, err := readBasic(bs) if err != nil { return nil, fmt.Errorf("reading float: %s", err) } switch bs { case 4: return s.arch.Float32(buf), nil case 8: return s.arch.Float64(buf), nil default: return nil, fmt.Errorf("invalid float size: %d", bs) } case *dwarf.ComplexType: bs := t.Common().ByteSize buf, err := readBasic(bs) if err != nil { return nil, fmt.Errorf("reading complex: %s", err) } switch bs { case 8: return s.arch.Complex64(buf), nil case 16: return s.arch.Complex128(buf), nil default: return nil, fmt.Errorf("invalid complex size: %d", bs) } case *dwarf.PtrType: bs := t.Common().ByteSize if bs != int64(s.arch.PointerSize) { return nil, fmt.Errorf("invalid pointer size: %d", bs) } buf, err := readBasic(bs) if err != nil { return nil, fmt.Errorf("reading pointer: %s", err) } return debug.Pointer{ TypeID: uint64(t.Type.Common().Offset), Address: uint64(s.arch.Uintptr(buf)), }, nil case *dwarf.SliceType: if s, err := s.peekSlice(t, addr); err != nil { return nil, err } else { return s, nil } case *dwarf.ArrayType: length := t.Count stride := t.StrideBitSize if stride%8 != 0 { return nil, fmt.Errorf("array is not byte-aligned") } return debug.Array{ ElementTypeID: uint64(t.Type.Common().Offset), Address: uint64(addr), Length: uint64(length), StrideBits: uint64(stride), }, nil case *dwarf.StructType: fields := make([]debug.StructField, len(t.Field)) for i, field := range t.Field { fields[i] = debug.StructField{ Name: field.Name, Var: debug.Var{ TypeID: uint64(field.Type.Common().Offset), Address: uint64(addr) + uint64(field.ByteOffset), }, } } return debug.Struct{fields}, nil case *dwarf.TypedefType: return s.value(t.Type, addr) case *dwarf.MapType: length, err := s.peekMapLength(t, addr) if err != nil { return nil, err } return debug.Map{ TypeID: uint64(t.Common().Offset), Address: addr, Length: length, }, nil case *dwarf.StringType: ptr, err := s.peekPtrStructField(&t.StructType, addr, "str") if err != nil { return nil, fmt.Errorf("reading string location: %s", err) } length, err := s.peekUintOrIntStructField(&t.StructType, addr, "len") if err != nil { return nil, fmt.Errorf("reading string length: %s", err) } const maxStringSize = 256 n := length if n > maxStringSize { n = maxStringSize } tmp := make([]byte, n) if err := s.peekBytes(ptr, tmp); err != nil { return nil, fmt.Errorf("reading string contents: %s", err) } return debug.String{Length: length, String: string(tmp)}, nil case *dwarf.ChanType: pt, ok := t.TypedefType.Type.(*dwarf.PtrType) if !ok { return nil, fmt.Errorf("reading channel: type is not a pointer") } st, ok := pt.Type.(*dwarf.StructType) if !ok { return nil, fmt.Errorf("reading channel: type is not a pointer to struct") } a, err := s.peekPtr(addr) if err != nil { return nil, fmt.Errorf("reading channel pointer: %s", err) } if a == 0 { // This channel is nil. return debug.Channel{ ElementTypeID: uint64(t.ElemType.Common().Offset), Address: 0, Buffer: 0, Length: 0, Capacity: 0, Stride: uint64(t.ElemType.Common().ByteSize), BufferStart: 0, }, nil } buf, err := s.peekPtrStructField(st, a, "buf") if err != nil { return nil, fmt.Errorf("reading channel buffer location: %s", err) } qcount, err := s.peekUintOrIntStructField(st, a, "qcount") if err != nil { return nil, fmt.Errorf("reading channel length: %s", err) } capacity, err := s.peekUintOrIntStructField(st, a, "dataqsiz") if err != nil { return nil, fmt.Errorf("reading channel capacity: %s", err) } recvx, err := s.peekUintOrIntStructField(st, a, "recvx") if err != nil { return nil, fmt.Errorf("reading channel buffer index: %s", err) } return debug.Channel{ ElementTypeID: uint64(t.ElemType.Common().Offset), Address: a, Buffer: buf, Length: qcount, Capacity: capacity, Stride: uint64(t.ElemType.Common().ByteSize), BufferStart: recvx, }, nil case *dwarf.FuncType: a, err := s.peekPtr(addr) if err != nil { return nil, fmt.Errorf("reading func: %s", err) } return debug.Func{Address: a}, nil case *dwarf.InterfaceType: return debug.Interface{}, nil // TODO: more types } return nil, fmt.Errorf("Unsupported type %T", t) } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/tests/000077500000000000000000000000001356504100700252705ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/tests/peek/000077500000000000000000000000001356504100700262145ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/tests/peek/doc.go000066400000000000000000000011321356504100700273050ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package peek google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/tests/peek/peek_test.go000066400000000000000000001150551356504100700305350ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // +build linux package peek_test import ( "flag" "fmt" "log" "os" "os/exec" "reflect" "regexp" "sync" "testing" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/local" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/remote" ) var expectedVarValues = map[string]interface{}{ `main.Z_bool_false`: false, `main.Z_bool_true`: true, `main.Z_complex128`: complex128(1.987654321 - 2.987654321i), `main.Z_complex64`: complex64(1.54321 + 2.54321i), `main.Z_float32`: float32(1.54321), `main.Z_float64`: float64(1.987654321), `main.Z_int16`: int16(-32321), `main.Z_int32`: int32(-1987654321), `main.Z_int64`: int64(-9012345678987654321), `main.Z_int8`: int8(-121), `main.Z_uint16`: uint16(54321), `main.Z_uint32`: uint32(3217654321), `main.Z_uint64`: uint64(12345678900987654321), `main.Z_uint8`: uint8(231), } // TODO: the string forms of some types we're testing aren't stable var expectedVars = map[string]string{ `main.Z_array`: `[5]int8{-121, 121, 3, 2, 1}`, `main.Z_array_empty`: `[0]int8{}`, `main.Z_bool_false`: `false`, `main.Z_bool_true`: `true`, `main.Z_channel`: `(chan int16 0xX)`, `main.Z_channel_2`: `(chan int16 0xX)`, `main.Z_channel_buffered`: `(chan int16 0xX [6/10])`, `main.Z_channel_nil`: `(chan int16 )`, `main.Z_array_of_empties`: `[2]{}{{} {}, ({} 0xX)}`, `main.Z_complex128`: `(1.987654321-2.987654321i)`, `main.Z_complex64`: `(1.54321+2.54321i)`, `main.Z_float32`: `1.54321`, `main.Z_float64`: `1.987654321`, `main.Z_func_int8_r_int8`: `func(int8, *int8) void @0xX `, `main.Z_func_int8_r_pint8`: `func(int8, **int8) void @0xX `, `main.Z_func_bar`: `func(*main.FooStruct) void @0xX `, `main.Z_func_nil`: `func(int8, *int8) void @0xX `, `main.Z_int`: `-21`, `main.Z_int16`: `-32321`, `main.Z_int32`: `-1987654321`, `main.Z_int64`: `-9012345678987654321`, `main.Z_int8`: `-121`, `main.Z_int_typedef`: `88`, `main.Z_interface`: `("*main.FooStruct", 0xX)`, `main.Z_interface_nil`: `(, )`, `main.Z_interface_typed_nil`: `("*main.FooStruct", )`, `main.Z_map`: `map[-21:3.54321]`, `main.Z_map_2`: `map[1024:1]`, `main.Z_map_3`: `map[1024:1 512:-1]`, `main.Z_map_empty`: `map[]`, `main.Z_map_nil`: `map[]`, `main.Z_pointer`: `0xX`, `main.Z_pointer_nil`: `0x0`, `main.Z_slice`: `[]uint8{115, 108, 105, 99, 101}`, `main.Z_slice_2`: `[]int8{-121, 121}`, `main.Z_slice_nil`: `[]uint8{}`, `main.Z_string`: `"I'm a string"`, `main.Z_struct`: `main.FooStruct {21, "hi"}`, `main.Z_uint`: `21`, `main.Z_uint16`: `54321`, `main.Z_uint32`: `3217654321`, `main.Z_uint64`: `12345678900987654321`, `main.Z_uint8`: `231`, `main.Z_uintptr`: `21`, `main.Z_unsafe_pointer`: `0xX`, `main.Z_unsafe_pointer_nil`: `0x0`, } // expectedEvaluate contains expected results of the debug.Evaluate function. // A nil value indicates that an error is expected. var expectedEvaluate = map[string]debug.Value{ `x`: int16(42), `local_array`: debug.Array{42, 42, 5, 8}, `local_channel`: debug.Channel{42, 42, 42, 0, 0, 2, 0}, `local_channel_buffered`: debug.Channel{42, 42, 42, 6, 10, 2, 8}, `local_map`: debug.Map{42, 42, 1}, `local_map_2`: debug.Map{42, 42, 1}, `local_map_3`: debug.Map{42, 42, 2}, `local_map_empty`: debug.Map{42, 42, 0}, `x + 5`: int16(47), `x - 5`: int16(37), `x / 5`: int16(8), `x % 5`: int16(2), `x & 2`: int16(2), `x | 1`: int16(43), `x ^ 3`: int16(41), `5 + x`: int16(47), `5 - x`: int16(-37), `100 / x`: int16(2), `100 % x`: int16(16), `2 & x`: int16(2), `1 | x`: int16(43), `3 ^ x`: int16(41), `12`: 12, `+42`: 42, `23i`: 23i, `34.0`: 34.0, `34.5`: 34.5, `1e5`: 100000.0, `0x42`: 66, `'c'`: 'c', `"de"`: debug.String{2, `de`}, "`ef`": debug.String{2, `ef`}, `"de" + "fg"`: debug.String{4, `defg`}, `/* comment */ -5`: -5, `false`: false, `true`: true, `!false`: true, `!true`: false, `5 + 5`: 10, `true || false`: true, `false || false`: false, `true && false`: false, `true && true`: true, `!(5 > 8)`: true, `10 + 'a'`: 'k', `10 + 10.5`: 20.5, `10 + 10.5i`: 10 + 10.5i, `'a' + 10.5`: 107.5, `'a' + 10.5i`: 97 + 10.5i, `10.5 + 20.5i`: 10.5 + 20.5i, `10 * 20`: 200, `10.0 - 20.5`: -10.5, `(6 + 8i) * 4`: 24 + 32i, `(6 + 8i) * (1 + 1i)`: -2 + 14i, `(6 + 8i) * (6 - 8i)`: complex128(100), `(6 + 8i) / (3 + 4i)`: complex128(2), `local_array[2]`: int8(3), `&local_array[1]`: debug.Pointer{42, 42}, `local_map[-21]`: float32(3.54321), `local_map[+21]`: float32(0), `local_map_3[1024]`: int8(1), `local_map_3[512]`: int8(-1), `local_map_empty[21]`: float32(0), `"hello"[2]`: uint8('l'), `local_array[1:3][1]`: int8(3), `local_array[0:4][2:3][0]`: int8(3), `local_array[:]`: debug.Slice{debug.Array{42, 42, 5, 8}, 5}, `local_array[:2]`: debug.Slice{debug.Array{42, 42, 2, 8}, 5}, `local_array[2:]`: debug.Slice{debug.Array{42, 42, 3, 8}, 3}, `local_array[1:3]`: debug.Slice{debug.Array{42, 42, 2, 8}, 4}, `local_array[:3:4]`: debug.Slice{debug.Array{42, 42, 3, 8}, 4}, `local_array[1:3:4]`: debug.Slice{debug.Array{42, 42, 2, 8}, 3}, `local_array[1:][1:][1:]`: debug.Slice{debug.Array{42, 42, 2, 8}, 2}, `(&local_array)[:]`: debug.Slice{debug.Array{42, 42, 5, 8}, 5}, `(&local_array)[:2]`: debug.Slice{debug.Array{42, 42, 2, 8}, 5}, `(&local_array)[2:]`: debug.Slice{debug.Array{42, 42, 3, 8}, 3}, `(&local_array)[1:3]`: debug.Slice{debug.Array{42, 42, 2, 8}, 4}, `(&local_array)[:3:4]`: debug.Slice{debug.Array{42, 42, 3, 8}, 4}, `(&local_array)[1:3:4]`: debug.Slice{debug.Array{42, 42, 2, 8}, 3}, `lookup("main.Z_array")`: debug.Array{42, 42, 5, 8}, `lookup("main.Z_array_empty")`: debug.Array{42, 42, 0, 8}, `lookup("main.Z_bool_false")`: false, `lookup("main.Z_bool_true")`: true, `lookup("main.Z_channel")`: debug.Channel{42, 42, 42, 0, 0, 2, 0}, `lookup("main.Z_channel_buffered")`: debug.Channel{42, 42, 42, 6, 10, 2, 8}, `lookup("main.Z_channel_nil")`: debug.Channel{42, 0, 0, 0, 0, 2, 0}, `lookup("main.Z_array_of_empties")`: debug.Array{42, 42, 2, 0}, `lookup("main.Z_complex128")`: complex128(1.987654321 - 2.987654321i), `lookup("main.Z_complex64")`: complex64(1.54321 + 2.54321i), `lookup("main.Z_float32")`: float32(1.54321), `lookup("main.Z_float64")`: float64(1.987654321), `lookup("main.Z_func_int8_r_int8")`: debug.Func{42}, `lookup("main.Z_func_int8_r_pint8")`: debug.Func{42}, `lookup("main.Z_func_bar")`: debug.Func{42}, `lookup("main.Z_func_nil")`: debug.Func{0}, `lookup("main.Z_int")`: -21, `lookup("main.Z_int16")`: int16(-32321), `lookup("main.Z_int32")`: int32(-1987654321), `lookup("main.Z_int64")`: int64(-9012345678987654321), `lookup("main.Z_int8")`: int8(-121), `lookup("main.Z_int_typedef")`: int16(88), `lookup("main.Z_interface")`: debug.Interface{}, `lookup("main.Z_interface_nil")`: debug.Interface{}, `lookup("main.Z_interface_typed_nil")`: debug.Interface{}, `lookup("main.Z_map")`: debug.Map{42, 42, 1}, `lookup("main.Z_map_2")`: debug.Map{42, 42, 1}, `lookup("main.Z_map_3")`: debug.Map{42, 42, 2}, `lookup("main.Z_map_empty")`: debug.Map{42, 42, 0}, `lookup("main.Z_map_nil")`: debug.Map{42, 42, 0}, `lookup("main.Z_pointer")`: debug.Pointer{42, 42}, `lookup("main.Z_pointer_nil")`: debug.Pointer{42, 0}, `lookup("main.Z_slice")`: debug.Slice{debug.Array{42, 42, 5, 8}, 5}, `lookup("main.Z_slice_2")`: debug.Slice{debug.Array{42, 42, 2, 8}, 5}, `lookup("main.Z_slice_nil")`: debug.Slice{debug.Array{42, 0, 0, 8}, 0}, `lookup("main.Z_string")`: debug.String{12, `I'm a string`}, `lookup("main.Z_struct")`: debug.Struct{[]debug.StructField{{"a", debug.Var{}}, {"b", debug.Var{}}}}, `lookup("main.Z_uint")`: uint(21), `lookup("main.Z_uint16")`: uint16(54321), `lookup("main.Z_uint32")`: uint32(3217654321), `lookup("main.Z_uint64")`: uint64(12345678900987654321), `lookup("main.Z_uint8")`: uint8(231), `lookup("main.Z_uintptr")`: uint(21), `lookup("main.Z_unsafe_pointer")`: debug.Pointer{0, 42}, `lookup("main.Z_unsafe_pointer_nil")`: debug.Pointer{0, 0}, `lookup("main.Z_int") + lookup("main.Z_int")`: -42, `lookup("main.Z_int16") < 0`: true, `lookup("main.Z_uint32") + lookup("main.Z_uint32")`: uint32(2140341346), `lookup("main.Z_bool_true") || lookup("main.Z_bool_false")`: true, `lookup("main.Z_bool_true") && lookup("main.Z_bool_false")`: false, `lookup("main.Z_bool_false") || lookup("main.Z_bool_false")`: false, `!lookup("main.Z_bool_true")`: false, `!lookup("main.Z_bool_false")`: true, `lookup("main.Z_array")[2]`: int8(3), `lookup("main.Z_array")[1:3][1]`: int8(3), `lookup("main.Z_array")[0:4][2:3][0]`: int8(3), `lookup("main.Z_array_of_empties")[0]`: debug.Struct{}, `lookup("main.Z_complex128") * 10.0`: complex128(19.87654321 - 29.87654321i), `lookup("main.Z_complex64") * 0.1`: complex64(0.154321 + 0.254321i), `lookup("main.Z_float32") * 10.0`: float32(15.4321), `lookup("main.Z_float64") * 0.1`: float64(0.1987654321), `lookup("main.Z_int") + 1`: int(-20), `lookup("main.Z_int16") - 10`: int16(-32331), `lookup("main.Z_int32") / 10`: int32(-198765432), `lookup("main.Z_int64") / 10`: int64(-901234567898765432), `lookup("main.Z_int8") + 10`: int8(-111), `lookup("main.Z_map")[-21]`: float32(3.54321), `lookup("main.Z_map")[+21]`: float32(0), `lookup("main.Z_map_empty")[21]`: float32(0), `lookup("main.Z_slice")[1]`: uint8(108), `lookup("main.Z_slice_2")[1]`: int8(121), `lookup("main.Z_slice")[1:5][0:3][1]`: uint8('i'), `lookup("main.Z_array")[1:3:4]`: debug.Slice{debug.Array{42, 42, 2, 8}, 3}, `(&lookup("main.Z_array"))[1:3:4]`: debug.Slice{debug.Array{42, 42, 2, 8}, 3}, `lookup("main.Z_string") + "!"`: debug.String{13, `I'm a string!`}, `lookup("main.Z_struct").a`: 21, `(&lookup("main.Z_struct")).a`: 21, `lookup("main.Z_uint")/10`: uint(2), `lookup("main.Z_uint16")/10`: uint16(5432), `lookup("main.Z_uint32")/10`: uint32(321765432), `lookup("main.Z_uint64")/10`: uint64(1234567890098765432), `lookup("main.Z_uint8")/10`: uint8(23), `lookup("main.Z_pointer").a`: 21, `(*lookup("main.Z_pointer")).a`: 21, `(&*lookup("main.Z_pointer")).a`: 21, `lookup("main.Z_pointer").b`: debug.String{2, `hi`}, `(*lookup("main.Z_pointer")).b`: debug.String{2, `hi`}, `(&*lookup("main.Z_pointer")).b`: debug.String{2, `hi`}, `lookup("main.Z_map_nil")[32]`: float32(0), `&lookup("main.Z_int16")`: debug.Pointer{42, 42}, `&lookup("main.Z_array")[1]`: debug.Pointer{42, 42}, `&lookup("main.Z_slice")[1]`: debug.Pointer{42, 42}, `*&lookup("main.Z_int16")`: int16(-32321), `*&*&*&*&lookup("main.Z_int16")`: int16(-32321), `lookup("time.Local")`: debug.Pointer{42, 42}, `5 + false`: nil, ``: nil, `x + ""`: nil, `x / 0`: nil, `0 / 0`: nil, `'a' / ('a'-'a')`: nil, `0.0 / 0.0`: nil, `3i / 0.0`: nil, `x % 0`: nil, `0 % 0`: nil, `'a' % ('a'-'a')`: nil, `local_array[-2] + 1`: nil, `local_array[22] + 1`: nil, `local_slice[-2] + 1`: nil, `local_slice[22] + 1`: nil, `local_string[-2]`: nil, `local_string[22]`: nil, `"hello"[-2]`: nil, `"hello"[22]`: nil, `local_pointer_nil.a`: nil, `(local_struct).c`: nil, `(&local_struct).c`: nil, `(*local_pointer).c`: nil, `lookup("not a real symbol")`: nil, `lookup("x")`: nil, `lookup(x)`: nil, `lookup(42)`: nil, } func isHex(r uint8) bool { switch { case '0' <= r && r <= '9': return true case 'a' <= r && r <= 'f': return true case 'A' <= r && r <= 'F': return true default: return false } } // structRE is used by matches to remove 'struct ' from type names, which is not // output by every version of the compiler. var structRE = regexp.MustCompile("struct *") // Check s matches the pattern in p. // An 'X' in p greedily matches one or more hex characters in s. func matches(p, s string) bool { // Remove 'struct' and following spaces from s. s = structRE.ReplaceAllString(s, "") j := 0 for i := 0; i < len(p); i++ { if j == len(s) { return false } c := p[i] if c == 'X' { if !isHex(s[j]) { return false } for j < len(s) && isHex(s[j]) { j++ } continue } if c != s[j] { return false } j++ } return j == len(s) } const ( proxySrc = "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/cmd/debugproxy" traceeSrc = "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/tests/peek/testdata" ) var ( // Locations of the proxy and tracee executables. proxyBinary = "./debugproxy.out" traceeBinary = "./tracee.out" // Onces that ensure initProxy and initTracee are called at most once. proxyOnce sync.Once traceeOnce sync.Once // Flags for setting the location of the proxy and tracee, so they don't need to be built. proxyFlag = flag.String("proxy", "", "Location of debugproxy. If empty, proxy will be built.") traceeFlag = flag.String("target", "", "Location of target. If empty, target will be built.") // Executables this test has built, which will be removed on completion of the tests. filesToRemove []string ) func TestMain(m *testing.M) { flag.Parse() x := m.Run() for _, f := range filesToRemove { os.Remove(f) } os.Exit(x) } func run(name string, args ...string) error { cmd := exec.Command(name, args...) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr return cmd.Run() } func initProxy() { if *proxyFlag != "" { proxyBinary = *proxyFlag remote.DebugproxyCmd = proxyBinary return } if err := run("go", "build", "-o", proxyBinary, proxySrc); err != nil { log.Fatalf("couldn't build proxy: %v", err) } filesToRemove = append(filesToRemove, proxyBinary) remote.DebugproxyCmd = proxyBinary } func initTracee() { if *traceeFlag != "" { traceeBinary = *traceeFlag return } if err := run("go", "build", "-o", traceeBinary, traceeSrc); err != nil { log.Fatalf("couldn't build target: %v", err) } filesToRemove = append(filesToRemove, traceeBinary) } func TestLocalProgram(t *testing.T) { t.Skip("Fails looking for runtime.lessstack for some reason") traceeOnce.Do(initTracee) prog, err := local.New(traceeBinary) if err != nil { t.Fatal("local.New:", err) } testProgram(t, prog) } func TestRemoteProgram(t *testing.T) { t.Skip("Fails looking for runtime.lessstack for some reason") traceeOnce.Do(initTracee) proxyOnce.Do(initProxy) prog, err := remote.New("localhost", traceeBinary) if err != nil { t.Fatal("remote.New:", err) } testProgram(t, prog) } func testProgram(t *testing.T, prog debug.Program) { _, err := prog.Run("some", "arguments") if err != nil { log.Fatalf("Run: %v", err) } pcs, err := prog.BreakpointAtFunction("main.foo") if err != nil { log.Fatalf("BreakpointAtFunction: %v", err) } fmt.Printf("breakpoints set at %x\n", pcs) _, err = prog.Resume() if err != nil { log.Fatalf("Resume: %v", err) } gs, err := prog.Goroutines() if err != nil { t.Fatalf("Goroutines(): got error %s", err) } for _, g := range gs { fmt.Println(g) for _, f := range g.StackFrames { fmt.Println(f) } } frames, err := prog.Frames(100) if err != nil { log.Fatalf("prog.Frames error: %v", err) } fmt.Printf("%#v\n", frames) if len(frames) == 0 { t.Fatalf("no stack frames returned") } if frames[0].Function != "main.foo" { t.Errorf("function name: got %s expected main.foo", frames[0].Function) } if len(frames[0].Params) != 2 { t.Errorf("got %d parameters, expected 2", len(frames[0].Params)) } else { x := frames[0].Params[0] y := frames[0].Params[1] if x.Name != "x" { x, y = y, x } if x.Name != "x" { t.Errorf("parameter name: got %s expected x", x.Name) } if y.Name != "y" { t.Errorf("parameter name: got %s expected y", y.Name) } if val, err := prog.Value(x.Var); err != nil { t.Errorf("value of x: %s", err) } else if val != int16(42) { t.Errorf("value of x: got %T(%v) expected int16(42)", val, val) } if val, err := prog.Value(y.Var); err != nil { t.Errorf("value of y: %s", err) } else if val != float32(1.5) { t.Errorf("value of y: got %T(%v) expected float32(1.5)", val, val) } } varnames, err := prog.Eval(`re:main\.Z_.*`) if err != nil { log.Fatalf("prog.Eval error: %v", err) } // Evaluate each of the variables found above, and check they match // expectedVars. seen := make(map[string]bool) for _, v := range varnames { val, err := prog.Eval("val:" + v) if err != nil { log.Fatalf("prog.Eval error for %s: %v", v, err) } else { fmt.Printf("%s = %v\n", v, val) if seen[v] { log.Fatalf("repeated variable %s\n", v) } seen[v] = true if len(val) != 1 { log.Fatalf("should be one value for %s\n", v) } expected, ok := expectedVars[v] if !ok { log.Fatalf("unexpected variable %s\n", v) } else { if !matches(expected, val[0]) { log.Fatalf("expected %s = %s\n", v, expected) } } } } for v, e := range expectedVars { if !seen[v] { log.Fatalf("didn't get %s = %s\n", v, e) } } // Remove the breakpoint at main.foo. err = prog.DeleteBreakpoints(pcs) if err != nil { log.Fatalf("DeleteBreakpoints: %v", err) } // Set a breakpoint at line 125, resume, and check we stopped there. pcsLine125, err := prog.BreakpointAtLine("testdata/main.go", 125) if err != nil { t.Fatal("BreakpointAtLine:", err) } status, err := prog.Resume() if err != nil { log.Fatalf("Resume: %v", err) } stoppedAt := func(pcs []uint64) bool { for _, pc := range pcs { if status.PC == pc { return true } } return false } if !stoppedAt(pcsLine125) { t.Errorf("stopped at %X; expected one of %X.", status.PC, pcsLine125) } for k, v := range expectedEvaluate { val, err := prog.Evaluate(k) if v == nil { if err == nil { t.Errorf("got Evaluate(%s) = %v, expected error", k, val) } continue } if err != nil { t.Errorf("Evaluate(%s): got error %s, expected %v", k, err, v) continue } typ := reflect.TypeOf(v) if typ != reflect.TypeOf(val) && typ != reflect.TypeOf(int(0)) && typ != reflect.TypeOf(uint(0)) { t.Errorf("got Evaluate(%s) = %T(%v), expected %T(%v)", k, val, val, v, v) continue } // For types with fields like Address, TypeID, etc., we can't know the exact // value, so we only test whether those fields are zero or not. switch v := v.(type) { default: if v != val { t.Errorf("got Evaluate(%s) = %T(%v), expected %T(%v)", k, val, val, v, v) } case debug.Array: val := val.(debug.Array) if v.ElementTypeID == 0 && val.ElementTypeID != 0 { t.Errorf("got Evaluate(%s) = %+v, expected zero ElementTypeID", k, val) } if v.ElementTypeID != 0 && val.ElementTypeID == 0 { t.Errorf("got Evaluate(%s) = %+v, expected non-zero ElementTypeID", k, val) } if v.Address == 0 && val.Address != 0 { t.Errorf("got Evaluate(%s) = %+v, expected zero Address", k, val) } if v.Address != 0 && val.Address == 0 { t.Errorf("got Evaluate(%s) = %+v, expected non-zero Address", k, val) } case debug.Slice: val := val.(debug.Slice) if v.ElementTypeID == 0 && val.ElementTypeID != 0 { t.Errorf("got Evaluate(%s) = %+v, expected zero ElementTypeID", k, val) } if v.ElementTypeID != 0 && val.ElementTypeID == 0 { t.Errorf("got Evaluate(%s) = %+v, expected non-zero ElementTypeID", k, val) } if v.Address == 0 && val.Address != 0 { t.Errorf("got Evaluate(%s) = %+v, expected zero Address", k, val) } if v.Address != 0 && val.Address == 0 { t.Errorf("got Evaluate(%s) = %+v, expected non-zero Address", k, val) } case debug.Map: val := val.(debug.Map) if v.TypeID == 0 && val.TypeID != 0 { t.Errorf("got Evaluate(%s) = %+v, expected zero TypeID", k, val) } if v.TypeID != 0 && val.TypeID == 0 { t.Errorf("got Evaluate(%s) = %+v, expected non-zero TypeID", k, val) } if v.Address == 0 && val.Address != 0 { t.Errorf("got Evaluate(%s) = %+v, expected zero Address", k, val) } if v.Address != 0 && val.Address == 0 { t.Errorf("got Evaluate(%s) = %+v, expected non-zero Address", k, val) } case debug.Pointer: val := val.(debug.Pointer) if v.TypeID == 0 && val.TypeID != 0 { t.Errorf("got Evaluate(%s) = %+v, expected zero TypeID", k, val) } if v.TypeID != 0 && val.TypeID == 0 { t.Errorf("got Evaluate(%s) = %+v, expected non-zero TypeID", k, val) } if v.Address == 0 && val.Address != 0 { t.Errorf("got Evaluate(%s) = %+v, expected zero Address", k, val) } if v.Address != 0 && val.Address == 0 { t.Errorf("got Evaluate(%s) = %+v, expected non-zero Address", k, val) } case debug.Channel: val := val.(debug.Channel) if v.ElementTypeID == 0 && val.ElementTypeID != 0 { t.Errorf("got Evaluate(%s) = %+v, expected zero ElementTypeID", k, val) } if v.ElementTypeID != 0 && val.ElementTypeID == 0 { t.Errorf("got Evaluate(%s) = %+v, expected non-zero ElementTypeID", k, val) } if v.Address == 0 && val.Address != 0 { t.Errorf("got Evaluate(%s) = %+v, expected zero Address", k, val) } if v.Address != 0 && val.Address == 0 { t.Errorf("got Evaluate(%s) = %+v, expected non-zero Address", k, val) } if v.Buffer == 0 && val.Buffer != 0 { t.Errorf("got Evaluate(%s) = %+v, expected zero Buffer", k, val) } if v.Buffer != 0 && val.Buffer == 0 { t.Errorf("got Evaluate(%s) = %+v, expected non-zero Buffer", k, val) } case debug.Struct: val := val.(debug.Struct) if len(v.Fields) != len(val.Fields) { t.Errorf("got Evaluate(%s) = %T(%v), expected %T(%v)", k, val, val, v, v) break } for i := range v.Fields { a := v.Fields[i].Name b := val.Fields[i].Name if a != b { t.Errorf("Evaluate(%s): field name mismatch: %s vs %s", k, a, b) break } } case debug.Func: val := val.(debug.Func) if v.Address == 0 && val.Address != 0 { t.Errorf("got Evaluate(%s) = %+v, expected zero Address", k, val) } if v.Address != 0 && val.Address == 0 { t.Errorf("got Evaluate(%s) = %+v, expected non-zero Address", k, val) } case int: // ints in a remote program can be returned as int32 or int64 switch val := val.(type) { case int32: if val != int32(v) { t.Errorf("got Evaluate(%s) = %T(%v), expected %v", k, val, val, v) } case int64: if val != int64(v) { t.Errorf("got Evaluate(%s) = %T(%v), expected %v", k, val, val, v) } default: t.Errorf("got Evaluate(%s) = %T(%v), expected %T(%v)", k, val, val, v, v) } case uint: // uints in a remote program can be returned as uint32 or uint64 switch val := val.(type) { case uint32: if val != uint32(v) { t.Errorf("got Evaluate(%s) = %T(%v), expected %v", k, val, val, v) } case uint64: if val != uint64(v) { t.Errorf("got Evaluate(%s) = %T(%v), expected %v", k, val, val, v) } default: t.Errorf("got Evaluate(%s) = %T(%v), expected %T(%v)", k, val, val, v, v) } } } // Evaluate a struct. v := `lookup("main.Z_struct")` val, err := prog.Evaluate(v) if err != nil { t.Fatalf("Evaluate: %s", err) } s, ok := val.(debug.Struct) if !ok { t.Fatalf("got Evaluate(%q) = %T(%v), expected debug.Struct", v, val, val) } // Check the values of its fields. if len(s.Fields) != 2 { t.Fatalf("got Evaluate(%q) = %+v, expected 2 fields", v, s) } if v0, err := prog.Value(s.Fields[0].Var); err != nil { t.Errorf("Value: %s", err) } else if v0 != int32(21) && v0 != int64(21) { t.Errorf("Value: got %T(%v), expected 21", v0, v0) } if v1, err := prog.Value(s.Fields[1].Var); err != nil { t.Errorf("Value: %s", err) } else if v1 != (debug.String{2, "hi"}) { t.Errorf("Value: got %T(%v), expected `hi`", v1, v1) } // Remove the breakpoint at line 125, set a breakpoint at main.f1 and main.f2, // then delete the breakpoint at main.f1. Resume, then check we stopped at // main.f2. err = prog.DeleteBreakpoints(pcsLine125) if err != nil { log.Fatalf("DeleteBreakpoints: %v", err) } pcs1, err := prog.BreakpointAtFunction("main.f1") if err != nil { log.Fatalf("BreakpointAtFunction: %v", err) } pcs2, err := prog.BreakpointAtFunction("main.f2") if err != nil { log.Fatalf("BreakpointAtFunction: %v", err) } err = prog.DeleteBreakpoints(pcs1) if err != nil { log.Fatalf("DeleteBreakpoints: %v", err) } status, err = prog.Resume() if err != nil { log.Fatalf("Resume: %v", err) } if !stoppedAt(pcs2) { t.Errorf("stopped at %X; expected one of %X.", status.PC, pcs2) } // Check we get the expected results calling VarByName then Value // for the variables in expectedVarValues. for name, exp := range expectedVarValues { if v, err := prog.VarByName(name); err != nil { t.Errorf("VarByName(%s): %s", name, err) } else if val, err := prog.Value(v); err != nil { t.Errorf("value of %s: %s", name, err) } else if val != exp { t.Errorf("value of %s: got %T(%v) want %T(%v)", name, val, val, exp, exp) } } // Check some error cases for VarByName and Value. if _, err = prog.VarByName("not a real name"); err == nil { t.Error("VarByName for invalid name: expected error") } if _, err = prog.Value(debug.Var{}); err == nil { t.Error("value of invalid var: expected error") } if v, err := prog.VarByName("main.Z_int16"); err != nil { t.Error("VarByName(main.Z_int16) error:", err) } else { v.Address = 0 // v now has a valid type but a bad address. _, err = prog.Value(v) if err == nil { t.Error("value of invalid location: expected error") } } // checkValue tests that we can get a Var for a variable with the given name, // that we can then get the value of that Var, and that calling fn for that // value succeeds. checkValue := func(name string, fn func(val debug.Value) error) { if v, err := prog.VarByName(name); err != nil { t.Errorf("VarByName(%s): %s", name, err) } else if val, err := prog.Value(v); err != nil { t.Errorf("value of %s: %s", name, err) } else if err := fn(val); err != nil { t.Errorf("value of %s: %s", name, err) } } checkValue("main.Z_uintptr", func(val debug.Value) error { if val != uint32(21) && val != uint64(21) { // Z_uintptr should be an unsigned integer with size equal to the debugged // program's address size. return fmt.Errorf("got %T(%v) want 21", val, val) } return nil }) checkValue("main.Z_int", func(val debug.Value) error { if val != int32(-21) && val != int64(-21) { return fmt.Errorf("got %T(%v) want -21", val, val) } return nil }) checkValue("main.Z_uint", func(val debug.Value) error { if val != uint32(21) && val != uint64(21) { return fmt.Errorf("got %T(%v) want 21", val, val) } return nil }) checkValue("main.Z_pointer", func(val debug.Value) error { if _, ok := val.(debug.Pointer); !ok { return fmt.Errorf("got %T(%v) expected Pointer", val, val) } return nil }) checkValue("main.Z_pointer_nil", func(val debug.Value) error { if p, ok := val.(debug.Pointer); !ok { return fmt.Errorf("got %T(%v) expected Pointer", val, val) } else if p.Address != 0 { return fmt.Errorf("got %T(%v) expected nil pointer", val, val) } return nil }) checkValue("main.Z_array", func(val debug.Value) error { a, ok := val.(debug.Array) if !ok { return fmt.Errorf("got %T(%v) expected Array", val, val) } if a.Len() != 5 { return fmt.Errorf("got array length %d expected 5", a.Len()) } expected := [5]int8{-121, 121, 3, 2, 1} for i := uint64(0); i < 5; i++ { if v, err := prog.Value(a.Element(i)); err != nil { return fmt.Errorf("reading element %d: %s", i, err) } else if v != expected[i] { return fmt.Errorf("element %d: got %T(%v) want %T(%d)", i, v, v, expected[i], expected[i]) } } return nil }) checkValue("main.Z_slice", func(val debug.Value) error { s, ok := val.(debug.Slice) if !ok { return fmt.Errorf("got %T(%v) expected Slice", val, val) } if s.Len() != 5 { return fmt.Errorf("got slice length %d expected 5", s.Len()) } expected := []uint8{115, 108, 105, 99, 101} for i := uint64(0); i < 5; i++ { if v, err := prog.Value(s.Element(i)); err != nil { return fmt.Errorf("reading element %d: %s", i, err) } else if v != expected[i] { return fmt.Errorf("element %d: got %T(%v) want %T(%d)", i, v, v, expected[i], expected[i]) } } return nil }) checkValue("main.Z_map_empty", func(val debug.Value) error { m, ok := val.(debug.Map) if !ok { return fmt.Errorf("got %T(%v) expected Map", val, val) } if m.Length != 0 { return fmt.Errorf("got map length %d expected 0", m.Length) } return nil }) checkValue("main.Z_map_nil", func(val debug.Value) error { m, ok := val.(debug.Map) if !ok { return fmt.Errorf("got %T(%v) expected Map", val, val) } if m.Length != 0 { return fmt.Errorf("got map length %d expected 0", m.Length) } return nil }) checkValue("main.Z_map_3", func(val debug.Value) error { m, ok := val.(debug.Map) if !ok { return fmt.Errorf("got %T(%v) expected Map", val, val) } if m.Length != 2 { return fmt.Errorf("got map length %d expected 2", m.Length) } keyVar0, valVar0, err := prog.MapElement(m, 0) if err != nil { return err } keyVar1, valVar1, err := prog.MapElement(m, 1) if err != nil { return err } key0, err := prog.Value(keyVar0) if err != nil { return err } key1, err := prog.Value(keyVar1) if err != nil { return err } val0, err := prog.Value(valVar0) if err != nil { return err } val1, err := prog.Value(valVar1) if err != nil { return err } // The map should contain 1024,1 and 512,-1 in some order. ok1 := key0 == int16(1024) && val0 == int8(1) && key1 == int16(512) && val1 == int8(-1) ok2 := key1 == int16(1024) && val1 == int8(1) && key0 == int16(512) && val0 == int8(-1) if !ok1 && !ok2 { return fmt.Errorf("got values (%d,%d) and (%d,%d), expected (1024,1) and (512,-1) in some order", key0, val0, key1, val1) } _, _, err = prog.MapElement(m, 2) if err == nil { return fmt.Errorf("MapElement: reading at a bad index succeeded, expected error") } return nil }) checkValue("main.Z_string", func(val debug.Value) error { s, ok := val.(debug.String) if !ok { return fmt.Errorf("got %T(%v) expected String", val, val) } if s.Length != 12 { return fmt.Errorf("got string length %d expected 12", s.Length) } expected := "I'm a string" if s.String != expected { return fmt.Errorf("got %s expected %s", s.String, expected) } return nil }) checkValue("main.Z_channel", func(val debug.Value) error { c, ok := val.(debug.Channel) if !ok { return fmt.Errorf("got %T(%v) expected Channel", val, val) } if c.Buffer == 0 { return fmt.Errorf("got buffer address %d expected nonzero", c.Buffer) } if c.Length != 0 { return fmt.Errorf("got length %d expected 0", c.Length) } if c.Capacity != 0 { return fmt.Errorf("got capacity %d expected 0", c.Capacity) } return nil }) checkValue("main.Z_channel_2", func(val debug.Value) error { c, ok := val.(debug.Channel) if !ok { return fmt.Errorf("got %T(%v) expected Channel", val, val) } if c.Buffer == 0 { return fmt.Errorf("got buffer address %d expected nonzero", c.Buffer) } if c.Length != 0 { return fmt.Errorf("got length %d expected 0", c.Length) } if c.Capacity != 0 { return fmt.Errorf("got capacity %d expected 0", c.Capacity) } return nil }) checkValue("main.Z_channel_nil", func(val debug.Value) error { c, ok := val.(debug.Channel) if !ok { return fmt.Errorf("got %T(%v) expected Channel", val, val) } if c.Buffer != 0 { return fmt.Errorf("got buffer address %d expected 0", c.Buffer) } if c.Length != 0 { return fmt.Errorf("got length %d expected 0", c.Length) } if c.Capacity != 0 { return fmt.Errorf("got capacity %d expected 0", c.Capacity) } return nil }) checkValue("main.Z_channel_buffered", func(val debug.Value) error { c, ok := val.(debug.Channel) if !ok { return fmt.Errorf("got %T(%v) expected Channel", val, val) } if c.Buffer == 0 { return fmt.Errorf("got buffer address %d expected nonzero", c.Buffer) } if c.Length != 6 { return fmt.Errorf("got length %d expected 6", c.Length) } if c.Capacity != 10 { return fmt.Errorf("got capacity %d expected 10", c.Capacity) } if c.Stride != 2 { return fmt.Errorf("got stride %d expected 2", c.Stride) } expected := []int16{8, 9, 10, 11, 12, 13} for i := uint64(0); i < 6; i++ { if v, err := prog.Value(c.Element(i)); err != nil { return fmt.Errorf("reading element %d: %s", i, err) } else if v != expected[i] { return fmt.Errorf("element %d: got %T(%v) want %T(%d)", i, v, v, expected[i], expected[i]) } } v := c.Element(6) if v.Address != 0 { return fmt.Errorf("invalid element returned Var with address %d, expected 0", v.Address) } return nil }) checkValue("main.Z_func_bar", func(val debug.Value) error { f, ok := val.(debug.Func) if !ok { return fmt.Errorf("got %T(%v) expected Func", val, val) } if f.Address == 0 { return fmt.Errorf("got func address %d expected nonzero", f.Address) } return nil }) checkValue("main.Z_func_nil", func(val debug.Value) error { f, ok := val.(debug.Func) if !ok { return fmt.Errorf("got %T(%v) expected Func", val, val) } if f.Address != 0 { return fmt.Errorf("got func address %d expected zero", f.Address) } return nil }) } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/tests/peek/testdata/000077500000000000000000000000001356504100700300255ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/debug/tests/peek/testdata/main.go000066400000000000000000000175051356504100700313100ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package main import ( "fmt" "log" "os" "time" "unsafe" ) type FooInterface interface { Bar() } type FooStruct struct { a int b string } func (f *FooStruct) Bar() {} type myInt int16 var ( Z_bool_false bool = false Z_bool_true bool = true Z_int int = -21 Z_int8 int8 = -121 Z_int16 int16 = -32321 Z_int32 int32 = -1987654321 Z_int64 int64 = -9012345678987654321 Z_int_typedef myInt = 88 Z_uint uint = 21 Z_uint8 uint8 = 231 Z_uint16 uint16 = 54321 Z_uint32 uint32 = 3217654321 Z_uint64 uint64 = 12345678900987654321 Z_uintptr uintptr = 21 Z_float32 float32 = 1.54321 Z_float64 float64 = 1.987654321 Z_complex64 complex64 = 1.54321 + 2.54321i Z_complex128 complex128 = 1.987654321 - 2.987654321i Z_array [5]int8 = [5]int8{-121, 121, 3, 2, 1} Z_array_empty [0]int8 = [0]int8{} Z_array_of_empties [2]struct{} = [2]struct{}{{}, {}} Z_channel chan int16 = make(chan int16) Z_channel_2 chan int16 = make(chan int16) Z_channel_buffered chan int16 = make(chan int16, 10) Z_channel_nil chan int16 Z_func_bar = (*FooStruct).Bar Z_func_int8_r_int8 = func(x int8) int8 { return x + 1 } Z_func_int8_r_pint8 = func(x int8) *int8 { y := x + 1; return &y } Z_func_nil func(x int8) int8 = nil Z_interface FooInterface = &Z_struct Z_interface_typed_nil FooInterface = Z_pointer_nil Z_interface_nil FooInterface Z_map map[int8]float32 = map[int8]float32{-21: 3.54321} Z_map_2 map[int16]int8 = map[int16]int8{1024: 1} Z_map_3 map[int16]int8 = map[int16]int8{1024: 1, 512: -1} Z_map_empty map[int8]float32 = map[int8]float32{} Z_map_nil map[int8]float32 Z_pointer *FooStruct = &Z_struct Z_pointer_nil *FooStruct Z_slice []byte = []byte{'s', 'l', 'i', 'c', 'e'} Z_slice_2 []int8 = Z_array[0:2] Z_slice_nil []byte Z_string string = "I'm a string" Z_struct FooStruct = FooStruct{a: 21, b: "hi"} Z_unsafe_pointer unsafe.Pointer = unsafe.Pointer(&Z_uint) Z_unsafe_pointer_nil unsafe.Pointer ) func foo(x int16, y float32) { var ( local_array [5]int8 = [5]int8{-121, 121, 3, 2, 1} local_bool_false bool = false local_bool_true bool = true local_channel chan int16 = Z_channel local_channel_buffered chan int16 = Z_channel_buffered local_channel_nil chan int16 local_complex128 complex128 = 1.987654321 - 2.987654321i local_complex64 complex64 = 1.54321 + 2.54321i local_float32 float32 = 1.54321 local_float64 float64 = 1.987654321 local_func_bar = (*FooStruct).Bar local_func_int8_r_int8 = func(x int8) int8 { return x + 1 } local_func_int8_r_pint8 = func(x int8) *int8 { y := x + 1; return &y } local_func_nil func(x int8) int8 = nil local_int int = -21 local_int16 int16 = -32321 local_int32 int32 = -1987654321 local_int64 int64 = -9012345678987654321 local_int8 int8 = -121 local_int_typedef myInt = 88 local_interface FooInterface = &Z_struct local_interface_nil FooInterface local_interface_typed_nil FooInterface = Z_pointer_nil local_map map[int8]float32 = map[int8]float32{-21: 3.54321} local_map_2 map[int16]int8 = map[int16]int8{1024: 1} local_map_3 map[int16]int8 = map[int16]int8{1024: 1, 512: -1} local_map_empty map[int8]float32 = map[int8]float32{} local_map_nil map[int8]float32 local_pointer *FooStruct = &Z_struct local_pointer_nil *FooStruct local_slice []byte = []byte{'s', 'l', 'i', 'c', 'e'} local_slice_2 []int8 = Z_array[0:2] local_slice_nil []byte local_string string = "I'm a string" local_struct FooStruct = FooStruct{a: 21, b: "hi"} local_uint uint = 21 local_uint16 uint16 = 54321 local_uint32 uint32 = 3217654321 local_uint64 uint64 = 12345678900987654321 local_uint8 uint8 = 231 local_uintptr uintptr = 21 local_unsafe_pointer unsafe.Pointer = unsafe.Pointer(&Z_uint) local_unsafe_pointer_nil unsafe.Pointer ) fmt.Println(Z_bool_false, Z_bool_true) fmt.Println(Z_int, Z_int8, Z_int16, Z_int32, Z_int64, Z_int_typedef) fmt.Println(Z_uint, Z_uint8, Z_uint16, Z_uint32, Z_uint64, Z_uintptr) fmt.Println(Z_float32, Z_float64, Z_complex64, Z_complex128) fmt.Println(Z_array, Z_array_empty, Z_array_of_empties) fmt.Println(Z_channel, Z_channel_buffered, Z_channel_nil) fmt.Println(Z_func_bar, Z_func_int8_r_int8, Z_func_int8_r_pint8, Z_func_nil) fmt.Println(Z_interface, Z_interface_nil, Z_interface_typed_nil) fmt.Println(Z_map, Z_map_2, Z_map_3, Z_map_empty, Z_map_nil) fmt.Println(Z_pointer, Z_pointer_nil) fmt.Println(Z_slice, Z_slice_2, Z_slice_nil) fmt.Println(Z_string, Z_struct) fmt.Println(Z_unsafe_pointer, Z_unsafe_pointer_nil) fmt.Println(local_bool_false, local_bool_true) fmt.Println(local_int, local_int8, local_int16, local_int32, local_int64, local_int_typedef) fmt.Println(local_uint, local_uint8, local_uint16, local_uint32, local_uint64, local_uintptr) fmt.Println(local_float32, local_float64, local_complex64, local_complex128, local_array) fmt.Println(local_channel, local_channel_buffered, local_channel_nil) fmt.Println(local_func_bar, local_func_int8_r_int8, local_func_int8_r_pint8, local_func_nil) fmt.Println(local_interface, local_interface_nil, local_interface_typed_nil) fmt.Println(local_map, local_map_2, local_map_3, local_map_empty, local_map_nil) fmt.Println(local_pointer, local_pointer_nil) fmt.Println(local_slice, local_slice_2, local_slice_nil) fmt.Println(local_string, local_struct) fmt.Println(local_unsafe_pointer, local_unsafe_pointer_nil) f1() f2() } func f1() { fmt.Println() } func f2() { fmt.Println() } func bar() { foo(42, 1.5) fmt.Print() } func populateChannels() { go func() { Z_channel_2 <- 8 }() go func() { for i := int16(0); i < 14; i++ { Z_channel_buffered <- i } }() go func() { for i := 0; i < 8; i++ { <-Z_channel_buffered } }() time.Sleep(time.Second / 20) } func main() { args := os.Args[1:] expected := []string{"some", "arguments"} if len(args) != 2 || args[0] != expected[0] || args[1] != expected[1] { log.Fatalf("got command-line args %v, expected %v", args, expected) } populateChannels() for ; ; time.Sleep(2 * time.Second) { bar() } select {} } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/valuecollector/000077500000000000000000000000001356504100700260635ustar00rootroot00000000000000google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/valuecollector/valuecollector.go000066400000000000000000000342231356504100700314410ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package valuecollector is used to collect the values of variables in a program. package valuecollector import ( "bytes" "fmt" "strconv" "strings" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug" cd "google.golang.org/api/clouddebugger/v2" ) const ( maxArrayLength = 50 maxMapLength = 20 ) // Collector is given references to variables from a program being debugged // using AddVariable. Then when ReadValues is called, the Collector will fetch // the values of those variables. Any variables referred to by those values // will also be fetched; e.g. the targets of pointers, members of structs, // elements of slices, etc. This continues iteratively, building a graph of // values, until all the reachable values are fetched, or a size limit is // reached. // // Variables are passed to the Collector as debug.Var, which is used by x/debug // to represent references to variables. Values are returned as cd.Variable, // which is used by the Debuglet Controller to represent the graph of values. // // For example, if the program has a struct variable: // // foo := SomeStruct{a:42, b:"xyz"} // // and we call AddVariable with a reference to foo, we will get back a result // like: // // cd.Variable{Name:"foo", VarTableIndex:10} // // which denotes a variable named "foo" which will have its value stored in // element 10 of the table that will later be returned by ReadValues. That // element might be: // // out[10] = &cd.Variable{Members:{{Name:"a", VarTableIndex:11},{Name:"b", VarTableIndex:12}}} // // which denotes a struct with two members a and b, whose values are in elements // 11 and 12 of the output table: // // out[11] = &cd.Variable{Value:"42"} // out[12] = &cd.Variable{Value:"xyz"} type Collector struct { // prog is the program being debugged. prog debug.Program // limit is the maximum size of the output slice of values. limit int // index is a map from references (variables and map elements) to their // locations in the table. index map[reference]int // table contains the references, including those given to the // Collector directly and those the Collector itself found. // If VarTableIndex is set to 0 in a cd.Variable, it is ignored, so the first entry // of table can't be used. On initialization we put a dummy value there. table []reference } // reference represents a value which is in the queue to be read by the // collector. It is either a debug.Var, or a mapElement. type reference interface{} // mapElement represents an element of a map in the debugged program's memory. type mapElement struct { debug.Map index uint64 } // NewCollector returns a Collector for the given program and size limit. // The limit is the maximum size of the slice of values returned by ReadValues. func NewCollector(prog debug.Program, limit int) *Collector { return &Collector{ prog: prog, limit: limit, index: make(map[reference]int), table: []reference{debug.Var{}}, } } // AddVariable adds another variable to be collected. // The Collector doesn't get the value immediately; it returns a cd.Variable // that contains an index into the table which will later be returned by // ReadValues. func (c *Collector) AddVariable(lv debug.LocalVar) *cd.Variable { ret := &cd.Variable{Name: lv.Name} if index, ok := c.add(lv.Var); !ok { // If the add call failed, it's because we reached the size limit. // The Debuglet Controller's convention is to pass it a "Not Captured" error // in this case. ret.Status = statusMessage(messageNotCaptured, true, refersToVariableName) } else { ret.VarTableIndex = int64(index) } return ret } // add adds a reference to the set of values to be read from the // program. It returns the index in the output table that will contain the // corresponding value. It fails if the table has reached the size limit. // It deduplicates references, so the index may be the same as one that was // returned from an earlier add call. func (c *Collector) add(r reference) (outputIndex int, ok bool) { if i, ok := c.index[r]; ok { return i, true } i := len(c.table) if i >= c.limit { return 0, false } c.index[r] = i c.table = append(c.table, r) return i, true } func addMember(v *cd.Variable, name string) *cd.Variable { v2 := &cd.Variable{Name: name} v.Members = append(v.Members, v2) return v2 } // ReadValues fetches values of the variables that were passed to the Collector // with AddVariable. The values of any new variables found are also fetched, // e.g. the targets of pointers or the members of structs, until we reach the // size limit or we run out of values to fetch. // The results are output as a []*cd.Variable, which is the type we need to send // to the Debuglet Controller after we trigger a breakpoint. func (c *Collector) ReadValues() (out []*cd.Variable) { for i := 0; i < len(c.table); i++ { // Create a new cd.Variable for this value, and append it to the output. dcv := new(cd.Variable) out = append(out, dcv) if i == 0 { // The first element is unused. continue } switch x := c.table[i].(type) { case mapElement: key, value, err := c.prog.MapElement(x.Map, x.index) if err != nil { dcv.Status = statusMessage(err.Error(), true, refersToVariableValue) continue } // Add a member for the key. member := addMember(dcv, "key") if index, ok := c.add(key); !ok { // The table is full. member.Status = statusMessage(messageNotCaptured, true, refersToVariableName) continue } else { member.VarTableIndex = int64(index) } // Add a member for the value. member = addMember(dcv, "value") if index, ok := c.add(value); !ok { // The table is full. member.Status = statusMessage(messageNotCaptured, true, refersToVariableName) } else { member.VarTableIndex = int64(index) } case debug.Var: if v, err := c.prog.Value(x); err != nil { dcv.Status = statusMessage(err.Error(), true, refersToVariableValue) } else { c.FillValue(v, dcv) } } } return out } // indexable is an interface for arrays, slices and channels. type indexable interface { Len() uint64 Element(uint64) debug.Var } // channel implements indexable. type channel struct { debug.Channel } func (c channel) Len() uint64 { return c.Length } var ( _ indexable = debug.Array{} _ indexable = debug.Slice{} _ indexable = channel{} ) // FillValue copies a value into a cd.Variable. Any variables referred to by // that value, e.g. struct members and pointer targets, are added to the // collector's queue, to be fetched later by ReadValues. func (c *Collector) FillValue(v debug.Value, dcv *cd.Variable) { if c, ok := v.(debug.Channel); ok { // Convert to channel, which implements indexable. v = channel{c} } // Fill in dcv in a manner depending on the type of the value we got. switch val := v.(type) { case int8, int16, int32, int64, bool, uint8, uint16, uint32, uint64, float32, float64, complex64, complex128: // For simple types, we just print the value to dcv.Value. dcv.Value = fmt.Sprint(val) case string: // Put double quotes around strings. dcv.Value = strconv.Quote(val) case debug.String: if uint64(len(val.String)) < val.Length { // This string value was truncated. dcv.Value = strconv.Quote(val.String + "...") } else { dcv.Value = strconv.Quote(val.String) } case debug.Struct: // For structs, we add an entry to dcv.Members for each field in the // struct. // Each member will contain the name of the field, and the index in the // output table which will contain the value of that field. for _, f := range val.Fields { member := addMember(dcv, f.Name) if index, ok := c.add(f.Var); !ok { // The table is full. member.Status = statusMessage(messageNotCaptured, true, refersToVariableName) } else { member.VarTableIndex = int64(index) } } case debug.Map: dcv.Value = fmt.Sprintf("len = %d", val.Length) for i := uint64(0); i < val.Length; i++ { field := addMember(dcv, `âš«`) if i == maxMapLength { field.Name = "..." field.Status = statusMessage(messageTruncated, true, refersToVariableName) break } if index, ok := c.add(mapElement{val, i}); !ok { // The value table is full; add a member to contain the error message. field.Name = "..." field.Status = statusMessage(messageNotCaptured, true, refersToVariableName) break } else { field.VarTableIndex = int64(index) } } case debug.Pointer: if val.Address == 0 { dcv.Value = "" } else if val.TypeID == 0 { // We don't know the type of the pointer, so just output the address as // the value. dcv.Value = fmt.Sprintf("0x%X", val.Address) dcv.Status = statusMessage(messageUnknownPointerType, false, refersToVariableName) } else { // Adds the pointed-to variable to the table, and links this value to // that table entry through VarTableIndex. dcv.Value = fmt.Sprintf("0x%X", val.Address) target := addMember(dcv, "") if index, ok := c.add(debug.Var(val)); !ok { target.Status = statusMessage(messageNotCaptured, true, refersToVariableName) } else { target.VarTableIndex = int64(index) } } case indexable: // Arrays, slices and channels. dcv.Value = "len = " + fmt.Sprint(val.Len()) for j := uint64(0); j < val.Len(); j++ { field := addMember(dcv, fmt.Sprint(`[`, j, `]`)) if j == maxArrayLength { field.Name = "..." field.Status = statusMessage(messageTruncated, true, refersToVariableName) break } vr := val.Element(j) if index, ok := c.add(vr); !ok { // The value table is full; add a member to contain the error message. field.Name = "..." field.Status = statusMessage(messageNotCaptured, true, refersToVariableName) break } else { // Add a member with the index as the name. field.VarTableIndex = int64(index) } } default: dcv.Status = statusMessage(messageUnknownType, false, refersToVariableName) } } // statusMessage returns a *cd.StatusMessage with the given message, IsError // field and refersTo field. func statusMessage(msg string, isError bool, refersTo int) *cd.StatusMessage { return &cd.StatusMessage{ Description: &cd.FormatMessage{Format: "$0", Parameters: []string{msg}}, IsError: isError, RefersTo: refersToString[refersTo], } } // LogString produces a string for a logpoint, substituting in variable values // using evaluatedExpressions and varTable. func LogString(s string, evaluatedExpressions []*cd.Variable, varTable []*cd.Variable) string { var buf bytes.Buffer fmt.Fprintf(&buf, "LOGPOINT: ") seen := make(map[*cd.Variable]bool) for i := 0; i < len(s); { if s[i] == '$' { i++ if num, n, ok := parseToken(s[i:], len(evaluatedExpressions)-1); ok { // This token is one of $0, $1, etc. Write the corresponding expression. writeExpression(&buf, evaluatedExpressions[num], false, varTable, seen) i += n } else { // Something else, like $$. buf.WriteByte(s[i]) i++ } } else { buf.WriteByte(s[i]) i++ } } return buf.String() } func parseToken(s string, max int) (num int, bytesRead int, ok bool) { var i int for i < len(s) && s[i] >= '0' && s[i] <= '9' { i++ } num, err := strconv.Atoi(s[:i]) return num, i, err == nil && num <= max } // writeExpression recursively writes variables to buf, in a format suitable // for logging. If printName is true, writes the name of the variable. func writeExpression(buf *bytes.Buffer, v *cd.Variable, printName bool, varTable []*cd.Variable, seen map[*cd.Variable]bool) { if v == nil { // Shouldn't happen. return } name, value, status, members := v.Name, v.Value, v.Status, v.Members // If v.VarTableIndex is not zero, it refers to an element of varTable. // We merge its fields with the fields we got from v. var other *cd.Variable if idx := int(v.VarTableIndex); idx > 0 && idx < len(varTable) { other = varTable[idx] } if other != nil { if name == "" { name = other.Name } if value == "" { value = other.Value } if status == nil { status = other.Status } if len(members) == 0 { members = other.Members } } if printName && name != "" { buf.WriteString(name) buf.WriteByte(':') } // If we have seen this value before, write "..." rather than repeating it. if seen[v] { buf.WriteString("...") return } seen[v] = true if other != nil { if seen[other] { buf.WriteString("...") return } seen[other] = true } if value != "" && !strings.HasPrefix(value, "len = ") { // A plain value. buf.WriteString(value) } else if status != nil && status.Description != nil { // An error. for _, p := range status.Description.Parameters { buf.WriteByte('(') buf.WriteString(p) buf.WriteByte(')') } } else if name == `âš«` { // A map element. first := true for _, member := range members { if first { first = false } else { buf.WriteByte(':') } writeExpression(buf, member, false, varTable, seen) } } else { // A map, array, slice, channel, or struct. isStruct := value == "" first := true buf.WriteByte('{') for _, member := range members { if first { first = false } else { buf.WriteString(", ") } writeExpression(buf, member, isStruct, varTable, seen) } buf.WriteByte('}') } } const ( // Error messages for cd.StatusMessage messageNotCaptured = "Not captured" messageTruncated = "Truncated" messageUnknownPointerType = "Unknown pointer type" messageUnknownType = "Unknown type" // RefersTo values for cd.StatusMessage. refersToVariableName = iota refersToVariableValue ) // refersToString contains the strings for each refersTo value. // See the definition of StatusMessage in the v2/clouddebugger package. var refersToString = map[int]string{ refersToVariableName: "VARIABLE_NAME", refersToVariableValue: "VARIABLE_VALUE", } google-cloud-go-0.49.0/cmd/go-cloud-debug-agent/internal/valuecollector/valuecollector_test.go000066400000000000000000000243241356504100700325010ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package valuecollector import ( "fmt" "testing" "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug" "cloud.google.com/go/internal/testutil" cd "google.golang.org/api/clouddebugger/v2" ) const ( // Some arbitrary type IDs for the test, for use in debug.Var's TypeID field. // A TypeID of 0 means the type is unknown, so we start at 1. int16Type = iota + 1 stringType structType pointerType arrayType int32Type debugStringType mapType channelType sliceType ) func TestValueCollector(t *testing.T) { // Construct the collector. c := NewCollector(&Program{}, 26) // Add some variables of various types, whose values we want the collector to read. variablesToAdd := []debug.LocalVar{ {Name: "a", Var: debug.Var{TypeID: int16Type, Address: 0x1}}, {Name: "b", Var: debug.Var{TypeID: stringType, Address: 0x2}}, {Name: "c", Var: debug.Var{TypeID: structType, Address: 0x3}}, {Name: "d", Var: debug.Var{TypeID: pointerType, Address: 0x4}}, {Name: "e", Var: debug.Var{TypeID: arrayType, Address: 0x5}}, {Name: "f", Var: debug.Var{TypeID: debugStringType, Address: 0x6}}, {Name: "g", Var: debug.Var{TypeID: mapType, Address: 0x7}}, {Name: "h", Var: debug.Var{TypeID: channelType, Address: 0x8}}, {Name: "i", Var: debug.Var{TypeID: sliceType, Address: 0x9}}, } expectedResults := []*cd.Variable{ {Name: "a", VarTableIndex: 1}, {Name: "b", VarTableIndex: 2}, {Name: "c", VarTableIndex: 3}, {Name: "d", VarTableIndex: 4}, {Name: "e", VarTableIndex: 5}, {Name: "f", VarTableIndex: 6}, {Name: "g", VarTableIndex: 7}, {Name: "h", VarTableIndex: 8}, {Name: "i", VarTableIndex: 9}, } for i, v := range variablesToAdd { added := c.AddVariable(v) if !testutil.Equal(added, expectedResults[i]) { t.Errorf("AddVariable: got %+v want %+v", *added, *expectedResults[i]) } } // Read the values, compare the output to what we expect. v := c.ReadValues() expectedValues := []*cd.Variable{ {}, {Value: "1"}, {Value: `"hello"`}, { Members: []*cd.Variable{ {Name: "x", VarTableIndex: 1}, {Name: "y", VarTableIndex: 2}, }, }, { Members: []*cd.Variable{ {VarTableIndex: 1}, }, Value: "0x1", }, { Members: []*cd.Variable{ {Name: "[0]", VarTableIndex: 10}, {Name: "[1]", VarTableIndex: 11}, {Name: "[2]", VarTableIndex: 12}, {Name: "[3]", VarTableIndex: 13}, }, Value: "len = 4", }, {Value: `"world"`}, { Members: []*cd.Variable{ {Name: "âš«", VarTableIndex: 14}, {Name: "âš«", VarTableIndex: 15}, {Name: "âš«", VarTableIndex: 16}, }, Value: "len = 3", }, { Members: []*cd.Variable{ {Name: "[0]", VarTableIndex: 17}, {Name: "[1]", VarTableIndex: 18}, }, Value: "len = 2", }, { Members: []*cd.Variable{ {Name: "[0]", VarTableIndex: 19}, {Name: "[1]", VarTableIndex: 20}, }, Value: "len = 2", }, {Value: "100"}, {Value: "104"}, {Value: "108"}, {Value: "112"}, { Members: []*cd.Variable{ {Name: "key", VarTableIndex: 21}, {Name: "value", VarTableIndex: 22}, }, }, { Members: []*cd.Variable{ {Name: "key", VarTableIndex: 23}, {Name: "value", VarTableIndex: 24}, }, }, { Members: []*cd.Variable{ {Name: "key", VarTableIndex: 25}, { Name: "value", Status: &cd.StatusMessage{ Description: &cd.FormatMessage{ Format: "$0", Parameters: []string{"Not captured"}, }, IsError: true, RefersTo: "VARIABLE_NAME", }, }, }, }, {Value: "246"}, {Value: "210"}, {Value: "300"}, {Value: "304"}, {Value: "400"}, {Value: "404"}, {Value: "1400"}, {Value: "1404"}, {Value: "2400"}, } if !testutil.Equal(v, expectedValues) { t.Errorf("ReadValues: got %v want %v", v, expectedValues) // Do element-by-element comparisons, for more useful error messages. for i := range v { if i < len(expectedValues) && !testutil.Equal(v[i], expectedValues[i]) { t.Errorf("element %d: got %+v want %+v", i, *v[i], *expectedValues[i]) } } } } // Program implements the similarly-named interface in x/debug. // ValueCollector should only call its Value and MapElement methods. type Program struct { debug.Program } func (p *Program) Value(v debug.Var) (debug.Value, error) { // We determine what to return using v.TypeID. switch v.TypeID { case int16Type: // We use the address as the value, so that we're testing whether the right // address was calculated. return int16(v.Address), nil case stringType: // A string. return "hello", nil case structType: // A struct with two elements. return debug.Struct{ Fields: []debug.StructField{ { Name: "x", Var: debug.Var{TypeID: int16Type, Address: 0x1}, }, { Name: "y", Var: debug.Var{TypeID: stringType, Address: 0x2}, }, }, }, nil case pointerType: // A pointer to the first variable above. return debug.Pointer{TypeID: int16Type, Address: 0x1}, nil case arrayType: // An array of 4 32-bit-wide elements. return debug.Array{ ElementTypeID: int32Type, Address: 0x64, Length: 4, StrideBits: 32, }, nil case debugStringType: return debug.String{ Length: 5, String: "world", }, nil case mapType: return debug.Map{ TypeID: 99, Address: 0x100, Length: 3, }, nil case channelType: return debug.Channel{ ElementTypeID: int32Type, Address: 200, Buffer: 210, Length: 2, Capacity: 10, Stride: 4, BufferStart: 9, }, nil case sliceType: // A slice of 2 32-bit-wide elements. return debug.Slice{ Array: debug.Array{ ElementTypeID: int32Type, Address: 300, Length: 2, StrideBits: 32, }, Capacity: 50, }, nil case int32Type: // We use the address as the value, so that we're testing whether the right // address was calculated. return int32(v.Address), nil } return nil, fmt.Errorf("unexpected Value request") } func (p *Program) MapElement(m debug.Map, index uint64) (debug.Var, debug.Var, error) { return debug.Var{TypeID: int16Type, Address: 1000*index + 400}, debug.Var{TypeID: int32Type, Address: 1000*index + 404}, nil } func TestLogString(t *testing.T) { bp := cd.Breakpoint{ Action: "LOG", LogMessageFormat: "$0 hello, $$7world! $1 $2 $3 $4 $5$6 $7 $8", EvaluatedExpressions: []*cd.Variable{ {Name: "a", VarTableIndex: 1}, {Name: "b", VarTableIndex: 2}, {Name: "c", VarTableIndex: 3}, {Name: "d", VarTableIndex: 4}, {Name: "e", VarTableIndex: 5}, {Name: "f", VarTableIndex: 6}, {Name: "g", VarTableIndex: 7}, {Name: "h", VarTableIndex: 8}, {Name: "i", VarTableIndex: 9}, }, } varTable := []*cd.Variable{ {}, {Value: "1"}, {Value: `"hello"`}, { Members: []*cd.Variable{ {Name: "x", Value: "1"}, {Name: "y", Value: `"hello"`}, {Name: "z", VarTableIndex: 3}, }, }, { Members: []*cd.Variable{ {VarTableIndex: 1}, }, Value: "0x1", }, { Members: []*cd.Variable{ {Name: "[0]", VarTableIndex: 10}, {Name: "[1]", VarTableIndex: 11}, {Name: "[2]", VarTableIndex: 12}, {Name: "[3]", VarTableIndex: 13}, }, Value: "len = 4", }, {Value: `"world"`}, { Members: []*cd.Variable{ {Name: "âš«", VarTableIndex: 14}, {Name: "âš«", VarTableIndex: 15}, {Name: "âš«", VarTableIndex: 16}, }, Value: "len = 3", }, { Members: []*cd.Variable{ {Name: "[0]", VarTableIndex: 17}, {Name: "[1]", VarTableIndex: 18}, }, Value: "len = 2", }, { Members: []*cd.Variable{ {Name: "[0]", VarTableIndex: 19}, {Name: "[1]", VarTableIndex: 20}, }, Value: "len = 2", }, {Value: "100"}, {Value: "104"}, {Value: "108"}, {Value: "112"}, { Members: []*cd.Variable{ {Name: "key", VarTableIndex: 21}, {Name: "value", VarTableIndex: 22}, }, }, { Members: []*cd.Variable{ {Name: "key", VarTableIndex: 23}, {Name: "value", VarTableIndex: 24}, }, }, { Members: []*cd.Variable{ {Name: "key", VarTableIndex: 25}, { Name: "value", Status: &cd.StatusMessage{ Description: &cd.FormatMessage{ Format: "$0", Parameters: []string{"Not captured"}, }, IsError: true, RefersTo: "VARIABLE_NAME", }, }, }, }, {Value: "246"}, {Value: "210"}, {Value: "300"}, {Value: "304"}, {Value: "400"}, {Value: "404"}, {Value: "1400"}, {Value: "1404"}, {Value: "2400"}, } s := LogString(bp.LogMessageFormat, bp.EvaluatedExpressions, varTable) expected := `LOGPOINT: 1 hello, $7world! "hello" {x:1, y:"hello", z:...} ` + `0x1 {100, 104, 108, 112} "world"{400:404, 1400:1404, 2400:(Not captured)} ` + `{246, 210} {300, 304}` if s != expected { t.Errorf("LogString: got %q want %q", s, expected) } } func TestParseToken(t *testing.T) { for _, c := range []struct { s string max int num int n int ok bool }{ {"", 0, 0, 0, false}, {".", 0, 0, 0, false}, {"0", 0, 0, 1, true}, {"0", 1, 0, 1, true}, {"00", 0, 0, 2, true}, {"1.", 1, 1, 1, true}, {"1.", 0, 0, 0, false}, {"10", 10, 10, 2, true}, {"10..", 10, 10, 2, true}, {"10", 11, 10, 2, true}, {"10..", 11, 10, 2, true}, {"10", 9, 0, 0, false}, {"10..", 9, 0, 0, false}, {" 10", 10, 0, 0, false}, {"010", 10, 10, 3, true}, {"123456789", 123456789, 123456789, 9, true}, {"123456789", 123456788, 0, 0, false}, {"123456789123456789123456789", 999999999, 0, 0, false}, } { num, n, ok := parseToken(c.s, c.max) if ok != c.ok { t.Errorf("parseToken(%q, %d): got ok=%t want ok=%t", c.s, c.max, ok, c.ok) continue } if !ok { continue } if num != c.num || n != c.n { t.Errorf("parseToken(%q, %d): got %d,%d,%t want %d,%d,%t", c.s, c.max, num, n, ok, c.num, c.n, c.ok) } } } google-cloud-go-0.49.0/compute/000077500000000000000000000000001356504100700162445ustar00rootroot00000000000000google-cloud-go-0.49.0/compute/metadata/000077500000000000000000000000001356504100700200245ustar00rootroot00000000000000google-cloud-go-0.49.0/compute/metadata/.repo-metadata.json000066400000000000000000000007251356504100700235240ustar00rootroot00000000000000{ "name": "metadata", "name_pretty": "Google Compute Engine Metadata API", "product_documentation": "https://cloud.google.com/compute/docs/storing-retrieving-metadata", "client_documentation": "https://godoc.org/cloud.google.com/go/compute/metadata", "release_level": "ga", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go/compute/metadata", "api_id": "compute:metadata", "requires_billing": false } google-cloud-go-0.49.0/compute/metadata/examples_test.go000066400000000000000000000025571356504100700232410ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package metadata_test import ( "net/http" "cloud.google.com/go/compute/metadata" ) // This example demonstrates how to use your own transport when using this package. func ExampleNewClient() { c := metadata.NewClient(&http.Client{Transport: userAgentTransport{ userAgent: "my-user-agent", base: http.DefaultTransport, }}) p, err := c.ProjectID() if err != nil { // TODO: Handle error. } _ = p // TODO: Use p. } // userAgentTransport sets the User-Agent header before calling base. type userAgentTransport struct { userAgent string base http.RoundTripper } // RoundTrip implements the http.RoundTripper interface. func (t userAgentTransport) RoundTrip(req *http.Request) (*http.Response, error) { req.Header.Set("User-Agent", t.userAgent) return t.base.RoundTrip(req) } google-cloud-go-0.49.0/compute/metadata/metadata.go000066400000000000000000000403661356504100700221440ustar00rootroot00000000000000// Copyright 2014 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package metadata provides access to Google Compute Engine (GCE) // metadata and API service accounts. // // This package is a wrapper around the GCE metadata service, // as documented at https://developers.google.com/compute/docs/metadata. package metadata // import "cloud.google.com/go/compute/metadata" import ( "context" "encoding/json" "fmt" "io/ioutil" "net" "net/http" "net/url" "os" "runtime" "strings" "sync" "time" ) const ( // metadataIP is the documented metadata server IP address. metadataIP = "169.254.169.254" // metadataHostEnv is the environment variable specifying the // GCE metadata hostname. If empty, the default value of // metadataIP ("169.254.169.254") is used instead. // This is variable name is not defined by any spec, as far as // I know; it was made up for the Go package. metadataHostEnv = "GCE_METADATA_HOST" userAgent = "gcloud-golang/0.1" ) type cachedValue struct { k string trim bool mu sync.Mutex v string } var ( projID = &cachedValue{k: "project/project-id", trim: true} projNum = &cachedValue{k: "project/numeric-project-id", trim: true} instID = &cachedValue{k: "instance/id", trim: true} ) var ( defaultClient = &Client{hc: &http.Client{ Transport: &http.Transport{ Dial: (&net.Dialer{ Timeout: 2 * time.Second, KeepAlive: 30 * time.Second, }).Dial, ResponseHeaderTimeout: 2 * time.Second, }, }} subscribeClient = &Client{hc: &http.Client{ Transport: &http.Transport{ Dial: (&net.Dialer{ Timeout: 2 * time.Second, KeepAlive: 30 * time.Second, }).Dial, }, }} ) // NotDefinedError is returned when requested metadata is not defined. // // The underlying string is the suffix after "/computeMetadata/v1/". // // This error is not returned if the value is defined to be the empty // string. type NotDefinedError string func (suffix NotDefinedError) Error() string { return fmt.Sprintf("metadata: GCE metadata %q not defined", string(suffix)) } func (c *cachedValue) get(cl *Client) (v string, err error) { defer c.mu.Unlock() c.mu.Lock() if c.v != "" { return c.v, nil } if c.trim { v, err = cl.getTrimmed(c.k) } else { v, err = cl.Get(c.k) } if err == nil { c.v = v } return } var ( onGCEOnce sync.Once onGCE bool ) // OnGCE reports whether this process is running on Google Compute Engine. func OnGCE() bool { onGCEOnce.Do(initOnGCE) return onGCE } func initOnGCE() { onGCE = testOnGCE() } func testOnGCE() bool { // The user explicitly said they're on GCE, so trust them. if os.Getenv(metadataHostEnv) != "" { return true } ctx, cancel := context.WithCancel(context.Background()) defer cancel() resc := make(chan bool, 2) // Try two strategies in parallel. // See https://github.com/googleapis/google-cloud-go/issues/194 go func() { req, _ := http.NewRequest("GET", "http://"+metadataIP, nil) req.Header.Set("User-Agent", userAgent) res, err := defaultClient.hc.Do(req.WithContext(ctx)) if err != nil { resc <- false return } defer res.Body.Close() resc <- res.Header.Get("Metadata-Flavor") == "Google" }() go func() { addrs, err := net.LookupHost("metadata.google.internal") if err != nil || len(addrs) == 0 { resc <- false return } resc <- strsContains(addrs, metadataIP) }() tryHarder := systemInfoSuggestsGCE() if tryHarder { res := <-resc if res { // The first strategy succeeded, so let's use it. return true } // Wait for either the DNS or metadata server probe to // contradict the other one and say we are running on // GCE. Give it a lot of time to do so, since the system // info already suggests we're running on a GCE BIOS. timer := time.NewTimer(5 * time.Second) defer timer.Stop() select { case res = <-resc: return res case <-timer.C: // Too slow. Who knows what this system is. return false } } // There's no hint from the system info that we're running on // GCE, so use the first probe's result as truth, whether it's // true or false. The goal here is to optimize for speed for // users who are NOT running on GCE. We can't assume that // either a DNS lookup or an HTTP request to a blackholed IP // address is fast. Worst case this should return when the // metaClient's Transport.ResponseHeaderTimeout or // Transport.Dial.Timeout fires (in two seconds). return <-resc } // systemInfoSuggestsGCE reports whether the local system (without // doing network requests) suggests that we're running on GCE. If this // returns true, testOnGCE tries a bit harder to reach its metadata // server. func systemInfoSuggestsGCE() bool { if runtime.GOOS != "linux" { // We don't have any non-Linux clues available, at least yet. return false } slurp, _ := ioutil.ReadFile("/sys/class/dmi/id/product_name") name := strings.TrimSpace(string(slurp)) return name == "Google" || name == "Google Compute Engine" } // Subscribe calls Client.Subscribe on a client designed for subscribing (one with no // ResponseHeaderTimeout). func Subscribe(suffix string, fn func(v string, ok bool) error) error { return subscribeClient.Subscribe(suffix, fn) } // Get calls Client.Get on the default client. func Get(suffix string) (string, error) { return defaultClient.Get(suffix) } // ProjectID returns the current instance's project ID string. func ProjectID() (string, error) { return defaultClient.ProjectID() } // NumericProjectID returns the current instance's numeric project ID. func NumericProjectID() (string, error) { return defaultClient.NumericProjectID() } // InternalIP returns the instance's primary internal IP address. func InternalIP() (string, error) { return defaultClient.InternalIP() } // ExternalIP returns the instance's primary external (public) IP address. func ExternalIP() (string, error) { return defaultClient.ExternalIP() } // Email calls Client.Email on the default client. func Email(serviceAccount string) (string, error) { return defaultClient.Email(serviceAccount) } // Hostname returns the instance's hostname. This will be of the form // ".c..internal". func Hostname() (string, error) { return defaultClient.Hostname() } // InstanceTags returns the list of user-defined instance tags, // assigned when initially creating a GCE instance. func InstanceTags() ([]string, error) { return defaultClient.InstanceTags() } // InstanceID returns the current VM's numeric instance ID. func InstanceID() (string, error) { return defaultClient.InstanceID() } // InstanceName returns the current VM's instance ID string. func InstanceName() (string, error) { return defaultClient.InstanceName() } // Zone returns the current VM's zone, such as "us-central1-b". func Zone() (string, error) { return defaultClient.Zone() } // InstanceAttributes calls Client.InstanceAttributes on the default client. func InstanceAttributes() ([]string, error) { return defaultClient.InstanceAttributes() } // ProjectAttributes calls Client.ProjectAttributes on the default client. func ProjectAttributes() ([]string, error) { return defaultClient.ProjectAttributes() } // InstanceAttributeValue calls Client.InstanceAttributeValue on the default client. func InstanceAttributeValue(attr string) (string, error) { return defaultClient.InstanceAttributeValue(attr) } // ProjectAttributeValue calls Client.ProjectAttributeValue on the default client. func ProjectAttributeValue(attr string) (string, error) { return defaultClient.ProjectAttributeValue(attr) } // Scopes calls Client.Scopes on the default client. func Scopes(serviceAccount string) ([]string, error) { return defaultClient.Scopes(serviceAccount) } func strsContains(ss []string, s string) bool { for _, v := range ss { if v == s { return true } } return false } // A Client provides metadata. type Client struct { hc *http.Client } // NewClient returns a Client that can be used to fetch metadata. All HTTP requests // will use the given http.Client instead of the default client. func NewClient(c *http.Client) *Client { return &Client{hc: c} } // getETag returns a value from the metadata service as well as the associated ETag. // This func is otherwise equivalent to Get. func (c *Client) getETag(suffix string) (value, etag string, err error) { // Using a fixed IP makes it very difficult to spoof the metadata service in // a container, which is an important use-case for local testing of cloud // deployments. To enable spoofing of the metadata service, the environment // variable GCE_METADATA_HOST is first inspected to decide where metadata // requests shall go. host := os.Getenv(metadataHostEnv) if host == "" { // Using 169.254.169.254 instead of "metadata" here because Go // binaries built with the "netgo" tag and without cgo won't // know the search suffix for "metadata" is // ".google.internal", and this IP address is documented as // being stable anyway. host = metadataIP } u := "http://" + host + "/computeMetadata/v1/" + suffix req, _ := http.NewRequest("GET", u, nil) req.Header.Set("Metadata-Flavor", "Google") req.Header.Set("User-Agent", userAgent) res, err := c.hc.Do(req) if err != nil { return "", "", err } defer res.Body.Close() if res.StatusCode == http.StatusNotFound { return "", "", NotDefinedError(suffix) } all, err := ioutil.ReadAll(res.Body) if err != nil { return "", "", err } if res.StatusCode != 200 { return "", "", &Error{Code: res.StatusCode, Message: string(all)} } return string(all), res.Header.Get("Etag"), nil } // Get returns a value from the metadata service. // The suffix is appended to "http://${GCE_METADATA_HOST}/computeMetadata/v1/". // // If the GCE_METADATA_HOST environment variable is not defined, a default of // 169.254.169.254 will be used instead. // // If the requested metadata is not defined, the returned error will // be of type NotDefinedError. func (c *Client) Get(suffix string) (string, error) { val, _, err := c.getETag(suffix) return val, err } func (c *Client) getTrimmed(suffix string) (s string, err error) { s, err = c.Get(suffix) s = strings.TrimSpace(s) return } func (c *Client) lines(suffix string) ([]string, error) { j, err := c.Get(suffix) if err != nil { return nil, err } s := strings.Split(strings.TrimSpace(j), "\n") for i := range s { s[i] = strings.TrimSpace(s[i]) } return s, nil } // ProjectID returns the current instance's project ID string. func (c *Client) ProjectID() (string, error) { return projID.get(c) } // NumericProjectID returns the current instance's numeric project ID. func (c *Client) NumericProjectID() (string, error) { return projNum.get(c) } // InstanceID returns the current VM's numeric instance ID. func (c *Client) InstanceID() (string, error) { return instID.get(c) } // InternalIP returns the instance's primary internal IP address. func (c *Client) InternalIP() (string, error) { return c.getTrimmed("instance/network-interfaces/0/ip") } // Email returns the email address associated with the service account. // The account may be empty or the string "default" to use the instance's // main account. func (c *Client) Email(serviceAccount string) (string, error) { if serviceAccount == "" { serviceAccount = "default" } return c.getTrimmed("instance/service-accounts/" + serviceAccount + "/email") } // ExternalIP returns the instance's primary external (public) IP address. func (c *Client) ExternalIP() (string, error) { return c.getTrimmed("instance/network-interfaces/0/access-configs/0/external-ip") } // Hostname returns the instance's hostname. This will be of the form // ".c..internal". func (c *Client) Hostname() (string, error) { return c.getTrimmed("instance/hostname") } // InstanceTags returns the list of user-defined instance tags, // assigned when initially creating a GCE instance. func (c *Client) InstanceTags() ([]string, error) { var s []string j, err := c.Get("instance/tags") if err != nil { return nil, err } if err := json.NewDecoder(strings.NewReader(j)).Decode(&s); err != nil { return nil, err } return s, nil } // InstanceName returns the current VM's instance ID string. func (c *Client) InstanceName() (string, error) { host, err := c.Hostname() if err != nil { return "", err } return strings.Split(host, ".")[0], nil } // Zone returns the current VM's zone, such as "us-central1-b". func (c *Client) Zone() (string, error) { zone, err := c.getTrimmed("instance/zone") // zone is of the form "projects//zones/". if err != nil { return "", err } return zone[strings.LastIndex(zone, "/")+1:], nil } // InstanceAttributes returns the list of user-defined attributes, // assigned when initially creating a GCE VM instance. The value of an // attribute can be obtained with InstanceAttributeValue. func (c *Client) InstanceAttributes() ([]string, error) { return c.lines("instance/attributes/") } // ProjectAttributes returns the list of user-defined attributes // applying to the project as a whole, not just this VM. The value of // an attribute can be obtained with ProjectAttributeValue. func (c *Client) ProjectAttributes() ([]string, error) { return c.lines("project/attributes/") } // InstanceAttributeValue returns the value of the provided VM // instance attribute. // // If the requested attribute is not defined, the returned error will // be of type NotDefinedError. // // InstanceAttributeValue may return ("", nil) if the attribute was // defined to be the empty string. func (c *Client) InstanceAttributeValue(attr string) (string, error) { return c.Get("instance/attributes/" + attr) } // ProjectAttributeValue returns the value of the provided // project attribute. // // If the requested attribute is not defined, the returned error will // be of type NotDefinedError. // // ProjectAttributeValue may return ("", nil) if the attribute was // defined to be the empty string. func (c *Client) ProjectAttributeValue(attr string) (string, error) { return c.Get("project/attributes/" + attr) } // Scopes returns the service account scopes for the given account. // The account may be empty or the string "default" to use the instance's // main account. func (c *Client) Scopes(serviceAccount string) ([]string, error) { if serviceAccount == "" { serviceAccount = "default" } return c.lines("instance/service-accounts/" + serviceAccount + "/scopes") } // Subscribe subscribes to a value from the metadata service. // The suffix is appended to "http://${GCE_METADATA_HOST}/computeMetadata/v1/". // The suffix may contain query parameters. // // Subscribe calls fn with the latest metadata value indicated by the provided // suffix. If the metadata value is deleted, fn is called with the empty string // and ok false. Subscribe blocks until fn returns a non-nil error or the value // is deleted. Subscribe returns the error value returned from the last call to // fn, which may be nil when ok == false. func (c *Client) Subscribe(suffix string, fn func(v string, ok bool) error) error { const failedSubscribeSleep = time.Second * 5 // First check to see if the metadata value exists at all. val, lastETag, err := c.getETag(suffix) if err != nil { return err } if err := fn(val, true); err != nil { return err } ok := true if strings.ContainsRune(suffix, '?') { suffix += "&wait_for_change=true&last_etag=" } else { suffix += "?wait_for_change=true&last_etag=" } for { val, etag, err := c.getETag(suffix + url.QueryEscape(lastETag)) if err != nil { if _, deleted := err.(NotDefinedError); !deleted { time.Sleep(failedSubscribeSleep) continue // Retry on other errors. } ok = false } lastETag = etag if err := fn(val, ok); err != nil || !ok { return err } } } // Error contains an error response from the server. type Error struct { // Code is the HTTP response status code. Code int // Message is the server response message. Message string } func (e *Error) Error() string { return fmt.Sprintf("compute: Received %d `%s`", e.Code, e.Message) } google-cloud-go-0.49.0/compute/metadata/metadata_test.go000066400000000000000000000037221356504100700231760ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package metadata import ( "bytes" "io/ioutil" "net/http" "os" "sync" "testing" ) func TestOnGCE_Stress(t *testing.T) { if testing.Short() { t.Skip("skipping in -short mode") } var last bool for i := 0; i < 100; i++ { onGCEOnce = sync.Once{} now := OnGCE() if i > 0 && now != last { t.Errorf("%d. changed from %v to %v", i, last, now) } last = now } t.Logf("OnGCE() = %v", last) } func TestOnGCE_Force(t *testing.T) { onGCEOnce = sync.Once{} old := os.Getenv(metadataHostEnv) defer os.Setenv(metadataHostEnv, old) os.Setenv(metadataHostEnv, "127.0.0.1") if !OnGCE() { t.Error("OnGCE() = false; want true") } } func TestOverrideUserAgent(t *testing.T) { const userAgent = "my-user-agent" rt := &rrt{} c := NewClient(&http.Client{Transport: userAgentTransport{userAgent, rt}}) c.Get("foo") if got, want := rt.gotUserAgent, userAgent; got != want { t.Errorf("got %q, want %q", got, want) } } type userAgentTransport struct { userAgent string base http.RoundTripper } func (t userAgentTransport) RoundTrip(req *http.Request) (*http.Response, error) { req.Header.Set("User-Agent", t.userAgent) return t.base.RoundTrip(req) } type rrt struct { gotUserAgent string } func (r *rrt) RoundTrip(req *http.Request) (*http.Response, error) { r.gotUserAgent = req.Header.Get("User-Agent") return &http.Response{Body: ioutil.NopCloser(bytes.NewReader(nil))}, nil } google-cloud-go-0.49.0/container/000077500000000000000000000000001356504100700165525ustar00rootroot00000000000000google-cloud-go-0.49.0/container/.repo-metadata.json000066400000000000000000000006631356504100700222530ustar00rootroot00000000000000{ "name": "container", "name_pretty": "Kubernetes Engine API", "product_documentation": "https://cloud.google.com/kubernetes-engine", "client_documentation": "https://godoc.org/cloud.google.com/go/container", "release_level": "deprecated", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go/container", "api_id": "container.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/container/apiv1/000077500000000000000000000000001356504100700175725ustar00rootroot00000000000000google-cloud-go-0.49.0/container/apiv1/.repo-metadata.json000066400000000000000000000006521356504100700232710ustar00rootroot00000000000000{ "name": "container", "name_pretty": "Kubernetes Engine API", "product_documentation": "https://cloud.google.com/container-engine/", "client_documentation": "https://godoc.org/cloud.google.com/go/container/apiv1", "release_level": "alpha", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "container.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/container/apiv1/ListClusters_smoke_test.go000066400000000000000000000031701356504100700250170ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // AUTO-GENERATED CODE. DO NOT EDIT. package container import ( "context" "fmt" "strconv" "testing" "time" "cloud.google.com/go/internal/testutil" "google.golang.org/api/iterator" "google.golang.org/api/option" containerpb "google.golang.org/genproto/googleapis/container/v1" ) var _ = fmt.Sprintf var _ = iterator.Done var _ = strconv.FormatUint var _ = time.Now func TestClusterManagerSmoke(t *testing.T) { if testing.Short() { t.Skip("skipping smoke test in short mode") } ctx := context.Background() ts := testutil.TokenSource(ctx, DefaultAuthScopes()...) if ts == nil { t.Skip("Integration tests skipped. See CONTRIBUTING.md for details") } projectId := testutil.ProjID() _ = projectId c, err := NewClusterManagerClient(ctx, option.WithTokenSource(ts)) if err != nil { t.Fatal(err) } var projectId2 string = projectId var zone string = "us-central1-a" var request = &containerpb.ListClustersRequest{ ProjectId: projectId2, Zone: zone, } if _, err := c.ListClusters(ctx, request); err != nil { t.Error(err) } } google-cloud-go-0.49.0/container/apiv1/cluster_manager_client.go000066400000000000000000000711051356504100700246360ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // AUTO-GENERATED CODE. DO NOT EDIT. package container import ( "context" "time" "cloud.google.com/go/internal/version" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" "google.golang.org/api/transport" containerpb "google.golang.org/genproto/googleapis/container/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // ClusterManagerCallOptions contains the retry settings for each method of ClusterManagerClient. type ClusterManagerCallOptions struct { ListClusters []gax.CallOption GetCluster []gax.CallOption CreateCluster []gax.CallOption UpdateCluster []gax.CallOption UpdateNodePool []gax.CallOption SetNodePoolAutoscaling []gax.CallOption SetLoggingService []gax.CallOption SetMonitoringService []gax.CallOption SetAddonsConfig []gax.CallOption SetLocations []gax.CallOption UpdateMaster []gax.CallOption SetMasterAuth []gax.CallOption DeleteCluster []gax.CallOption ListOperations []gax.CallOption GetOperation []gax.CallOption CancelOperation []gax.CallOption GetServerConfig []gax.CallOption ListNodePools []gax.CallOption GetNodePool []gax.CallOption CreateNodePool []gax.CallOption DeleteNodePool []gax.CallOption RollbackNodePoolUpgrade []gax.CallOption SetNodePoolManagement []gax.CallOption SetLabels []gax.CallOption SetLegacyAbac []gax.CallOption StartIPRotation []gax.CallOption CompleteIPRotation []gax.CallOption SetNodePoolSize []gax.CallOption SetNetworkPolicy []gax.CallOption SetMaintenancePolicy []gax.CallOption } func defaultClusterManagerClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("container.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), } } func defaultClusterManagerCallOptions() *ClusterManagerCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &ClusterManagerCallOptions{ ListClusters: retry[[2]string{"default", "idempotent"}], GetCluster: retry[[2]string{"default", "idempotent"}], CreateCluster: retry[[2]string{"default", "non_idempotent"}], UpdateCluster: retry[[2]string{"default", "non_idempotent"}], UpdateNodePool: retry[[2]string{"default", "non_idempotent"}], SetNodePoolAutoscaling: retry[[2]string{"default", "non_idempotent"}], SetLoggingService: retry[[2]string{"default", "non_idempotent"}], SetMonitoringService: retry[[2]string{"default", "non_idempotent"}], SetAddonsConfig: retry[[2]string{"default", "non_idempotent"}], SetLocations: retry[[2]string{"default", "non_idempotent"}], UpdateMaster: retry[[2]string{"default", "non_idempotent"}], SetMasterAuth: retry[[2]string{"default", "non_idempotent"}], DeleteCluster: retry[[2]string{"default", "idempotent"}], ListOperations: retry[[2]string{"default", "idempotent"}], GetOperation: retry[[2]string{"default", "idempotent"}], CancelOperation: retry[[2]string{"default", "non_idempotent"}], GetServerConfig: retry[[2]string{"default", "idempotent"}], ListNodePools: retry[[2]string{"default", "idempotent"}], GetNodePool: retry[[2]string{"default", "idempotent"}], CreateNodePool: retry[[2]string{"default", "non_idempotent"}], DeleteNodePool: retry[[2]string{"default", "idempotent"}], RollbackNodePoolUpgrade: retry[[2]string{"default", "non_idempotent"}], SetNodePoolManagement: retry[[2]string{"default", "non_idempotent"}], SetLabels: retry[[2]string{"default", "non_idempotent"}], SetLegacyAbac: retry[[2]string{"default", "non_idempotent"}], StartIPRotation: retry[[2]string{"default", "non_idempotent"}], CompleteIPRotation: retry[[2]string{"default", "non_idempotent"}], SetNodePoolSize: retry[[2]string{"default", "non_idempotent"}], SetNetworkPolicy: retry[[2]string{"default", "non_idempotent"}], SetMaintenancePolicy: retry[[2]string{"default", "non_idempotent"}], } } // ClusterManagerClient is a client for interacting with Google Container Engine API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type ClusterManagerClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. clusterManagerClient containerpb.ClusterManagerClient // The call options for this service. CallOptions *ClusterManagerCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewClusterManagerClient creates a new cluster manager client. // // Google Container Engine Cluster Manager v1 func NewClusterManagerClient(ctx context.Context, opts ...option.ClientOption) (*ClusterManagerClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultClusterManagerClientOptions(), opts...)...) if err != nil { return nil, err } c := &ClusterManagerClient{ conn: conn, CallOptions: defaultClusterManagerCallOptions(), clusterManagerClient: containerpb.NewClusterManagerClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *ClusterManagerClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *ClusterManagerClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *ClusterManagerClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", version.Go()}, keyval...) kv = append(kv, "gapic", version.Repo, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // ListClusters lists all clusters owned by a project in either the specified zone or all // zones. func (c *ClusterManagerClient) ListClusters(ctx context.Context, req *containerpb.ListClustersRequest, opts ...gax.CallOption) (*containerpb.ListClustersResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.ListClusters[0:len(c.CallOptions.ListClusters):len(c.CallOptions.ListClusters)], opts...) var resp *containerpb.ListClustersResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterManagerClient.ListClusters(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetCluster gets the details of a specific cluster. func (c *ClusterManagerClient) GetCluster(ctx context.Context, req *containerpb.GetClusterRequest, opts ...gax.CallOption) (*containerpb.Cluster, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.GetCluster[0:len(c.CallOptions.GetCluster):len(c.CallOptions.GetCluster)], opts...) var resp *containerpb.Cluster err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterManagerClient.GetCluster(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateCluster creates a cluster, consisting of the specified number and type of Google // Compute Engine instances. // // By default, the cluster is created in the project's // default network (at /compute/docs/networks-and-firewalls#networks). // // One firewall is added for the cluster. After cluster creation, // the cluster creates routes for each node to allow the containers // on that node to communicate with all other instances in the // cluster. // // Finally, an entry is added to the project's global metadata indicating // which CIDR range is being used by the cluster. func (c *ClusterManagerClient) CreateCluster(ctx context.Context, req *containerpb.CreateClusterRequest, opts ...gax.CallOption) (*containerpb.Operation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.CreateCluster[0:len(c.CallOptions.CreateCluster):len(c.CallOptions.CreateCluster)], opts...) var resp *containerpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterManagerClient.CreateCluster(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateCluster updates the settings of a specific cluster. func (c *ClusterManagerClient) UpdateCluster(ctx context.Context, req *containerpb.UpdateClusterRequest, opts ...gax.CallOption) (*containerpb.Operation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.UpdateCluster[0:len(c.CallOptions.UpdateCluster):len(c.CallOptions.UpdateCluster)], opts...) var resp *containerpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterManagerClient.UpdateCluster(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateNodePool updates the version and/or image type of a specific node pool. func (c *ClusterManagerClient) UpdateNodePool(ctx context.Context, req *containerpb.UpdateNodePoolRequest, opts ...gax.CallOption) (*containerpb.Operation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.UpdateNodePool[0:len(c.CallOptions.UpdateNodePool):len(c.CallOptions.UpdateNodePool)], opts...) var resp *containerpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterManagerClient.UpdateNodePool(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // SetNodePoolAutoscaling sets the autoscaling settings of a specific node pool. func (c *ClusterManagerClient) SetNodePoolAutoscaling(ctx context.Context, req *containerpb.SetNodePoolAutoscalingRequest, opts ...gax.CallOption) (*containerpb.Operation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.SetNodePoolAutoscaling[0:len(c.CallOptions.SetNodePoolAutoscaling):len(c.CallOptions.SetNodePoolAutoscaling)], opts...) var resp *containerpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterManagerClient.SetNodePoolAutoscaling(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // SetLoggingService sets the logging service of a specific cluster. func (c *ClusterManagerClient) SetLoggingService(ctx context.Context, req *containerpb.SetLoggingServiceRequest, opts ...gax.CallOption) (*containerpb.Operation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.SetLoggingService[0:len(c.CallOptions.SetLoggingService):len(c.CallOptions.SetLoggingService)], opts...) var resp *containerpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterManagerClient.SetLoggingService(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // SetMonitoringService sets the monitoring service of a specific cluster. func (c *ClusterManagerClient) SetMonitoringService(ctx context.Context, req *containerpb.SetMonitoringServiceRequest, opts ...gax.CallOption) (*containerpb.Operation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.SetMonitoringService[0:len(c.CallOptions.SetMonitoringService):len(c.CallOptions.SetMonitoringService)], opts...) var resp *containerpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterManagerClient.SetMonitoringService(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // SetAddonsConfig sets the addons of a specific cluster. func (c *ClusterManagerClient) SetAddonsConfig(ctx context.Context, req *containerpb.SetAddonsConfigRequest, opts ...gax.CallOption) (*containerpb.Operation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.SetAddonsConfig[0:len(c.CallOptions.SetAddonsConfig):len(c.CallOptions.SetAddonsConfig)], opts...) var resp *containerpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterManagerClient.SetAddonsConfig(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // SetLocations sets the locations of a specific cluster. func (c *ClusterManagerClient) SetLocations(ctx context.Context, req *containerpb.SetLocationsRequest, opts ...gax.CallOption) (*containerpb.Operation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.SetLocations[0:len(c.CallOptions.SetLocations):len(c.CallOptions.SetLocations)], opts...) var resp *containerpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterManagerClient.SetLocations(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateMaster updates the master of a specific cluster. func (c *ClusterManagerClient) UpdateMaster(ctx context.Context, req *containerpb.UpdateMasterRequest, opts ...gax.CallOption) (*containerpb.Operation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.UpdateMaster[0:len(c.CallOptions.UpdateMaster):len(c.CallOptions.UpdateMaster)], opts...) var resp *containerpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterManagerClient.UpdateMaster(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // SetMasterAuth used to set master auth materials. Currently supports :- // Changing the admin password of a specific cluster. // This can be either via password generation or explicitly set the password. func (c *ClusterManagerClient) SetMasterAuth(ctx context.Context, req *containerpb.SetMasterAuthRequest, opts ...gax.CallOption) (*containerpb.Operation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.SetMasterAuth[0:len(c.CallOptions.SetMasterAuth):len(c.CallOptions.SetMasterAuth)], opts...) var resp *containerpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterManagerClient.SetMasterAuth(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteCluster deletes the cluster, including the Kubernetes endpoint and all worker // nodes. // // Firewalls and routes that were configured during cluster creation // are also deleted. // // Other Google Compute Engine resources that might be in use by the cluster // (e.g. load balancer resources) will not be deleted if they weren't present // at the initial create time. func (c *ClusterManagerClient) DeleteCluster(ctx context.Context, req *containerpb.DeleteClusterRequest, opts ...gax.CallOption) (*containerpb.Operation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.DeleteCluster[0:len(c.CallOptions.DeleteCluster):len(c.CallOptions.DeleteCluster)], opts...) var resp *containerpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterManagerClient.DeleteCluster(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListOperations lists all operations in a project in a specific zone or all zones. func (c *ClusterManagerClient) ListOperations(ctx context.Context, req *containerpb.ListOperationsRequest, opts ...gax.CallOption) (*containerpb.ListOperationsResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.ListOperations[0:len(c.CallOptions.ListOperations):len(c.CallOptions.ListOperations)], opts...) var resp *containerpb.ListOperationsResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterManagerClient.ListOperations(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetOperation gets the specified operation. func (c *ClusterManagerClient) GetOperation(ctx context.Context, req *containerpb.GetOperationRequest, opts ...gax.CallOption) (*containerpb.Operation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.GetOperation[0:len(c.CallOptions.GetOperation):len(c.CallOptions.GetOperation)], opts...) var resp *containerpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterManagerClient.GetOperation(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CancelOperation cancels the specified operation. func (c *ClusterManagerClient) CancelOperation(ctx context.Context, req *containerpb.CancelOperationRequest, opts ...gax.CallOption) error { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.CancelOperation[0:len(c.CallOptions.CancelOperation):len(c.CallOptions.CancelOperation)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.clusterManagerClient.CancelOperation(ctx, req, settings.GRPC...) return err }, opts...) return err } // GetServerConfig returns configuration info about the Container Engine service. func (c *ClusterManagerClient) GetServerConfig(ctx context.Context, req *containerpb.GetServerConfigRequest, opts ...gax.CallOption) (*containerpb.ServerConfig, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.GetServerConfig[0:len(c.CallOptions.GetServerConfig):len(c.CallOptions.GetServerConfig)], opts...) var resp *containerpb.ServerConfig err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterManagerClient.GetServerConfig(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListNodePools lists the node pools for a cluster. func (c *ClusterManagerClient) ListNodePools(ctx context.Context, req *containerpb.ListNodePoolsRequest, opts ...gax.CallOption) (*containerpb.ListNodePoolsResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.ListNodePools[0:len(c.CallOptions.ListNodePools):len(c.CallOptions.ListNodePools)], opts...) var resp *containerpb.ListNodePoolsResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterManagerClient.ListNodePools(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetNodePool retrieves the node pool requested. func (c *ClusterManagerClient) GetNodePool(ctx context.Context, req *containerpb.GetNodePoolRequest, opts ...gax.CallOption) (*containerpb.NodePool, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.GetNodePool[0:len(c.CallOptions.GetNodePool):len(c.CallOptions.GetNodePool)], opts...) var resp *containerpb.NodePool err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterManagerClient.GetNodePool(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateNodePool creates a node pool for a cluster. func (c *ClusterManagerClient) CreateNodePool(ctx context.Context, req *containerpb.CreateNodePoolRequest, opts ...gax.CallOption) (*containerpb.Operation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.CreateNodePool[0:len(c.CallOptions.CreateNodePool):len(c.CallOptions.CreateNodePool)], opts...) var resp *containerpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterManagerClient.CreateNodePool(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteNodePool deletes a node pool from a cluster. func (c *ClusterManagerClient) DeleteNodePool(ctx context.Context, req *containerpb.DeleteNodePoolRequest, opts ...gax.CallOption) (*containerpb.Operation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.DeleteNodePool[0:len(c.CallOptions.DeleteNodePool):len(c.CallOptions.DeleteNodePool)], opts...) var resp *containerpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterManagerClient.DeleteNodePool(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // RollbackNodePoolUpgrade roll back the previously Aborted or Failed NodePool upgrade. // This will be an no-op if the last upgrade successfully completed. func (c *ClusterManagerClient) RollbackNodePoolUpgrade(ctx context.Context, req *containerpb.RollbackNodePoolUpgradeRequest, opts ...gax.CallOption) (*containerpb.Operation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.RollbackNodePoolUpgrade[0:len(c.CallOptions.RollbackNodePoolUpgrade):len(c.CallOptions.RollbackNodePoolUpgrade)], opts...) var resp *containerpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterManagerClient.RollbackNodePoolUpgrade(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // SetNodePoolManagement sets the NodeManagement options for a node pool. func (c *ClusterManagerClient) SetNodePoolManagement(ctx context.Context, req *containerpb.SetNodePoolManagementRequest, opts ...gax.CallOption) (*containerpb.Operation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.SetNodePoolManagement[0:len(c.CallOptions.SetNodePoolManagement):len(c.CallOptions.SetNodePoolManagement)], opts...) var resp *containerpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterManagerClient.SetNodePoolManagement(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // SetLabels sets labels on a cluster. func (c *ClusterManagerClient) SetLabels(ctx context.Context, req *containerpb.SetLabelsRequest, opts ...gax.CallOption) (*containerpb.Operation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.SetLabels[0:len(c.CallOptions.SetLabels):len(c.CallOptions.SetLabels)], opts...) var resp *containerpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterManagerClient.SetLabels(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // SetLegacyAbac enables or disables the ABAC authorization mechanism on a cluster. func (c *ClusterManagerClient) SetLegacyAbac(ctx context.Context, req *containerpb.SetLegacyAbacRequest, opts ...gax.CallOption) (*containerpb.Operation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.SetLegacyAbac[0:len(c.CallOptions.SetLegacyAbac):len(c.CallOptions.SetLegacyAbac)], opts...) var resp *containerpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterManagerClient.SetLegacyAbac(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // StartIPRotation start master IP rotation. func (c *ClusterManagerClient) StartIPRotation(ctx context.Context, req *containerpb.StartIPRotationRequest, opts ...gax.CallOption) (*containerpb.Operation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.StartIPRotation[0:len(c.CallOptions.StartIPRotation):len(c.CallOptions.StartIPRotation)], opts...) var resp *containerpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterManagerClient.StartIPRotation(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CompleteIPRotation completes master IP rotation. func (c *ClusterManagerClient) CompleteIPRotation(ctx context.Context, req *containerpb.CompleteIPRotationRequest, opts ...gax.CallOption) (*containerpb.Operation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.CompleteIPRotation[0:len(c.CallOptions.CompleteIPRotation):len(c.CallOptions.CompleteIPRotation)], opts...) var resp *containerpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterManagerClient.CompleteIPRotation(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // SetNodePoolSize sets the size of a specific node pool. func (c *ClusterManagerClient) SetNodePoolSize(ctx context.Context, req *containerpb.SetNodePoolSizeRequest, opts ...gax.CallOption) (*containerpb.Operation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.SetNodePoolSize[0:len(c.CallOptions.SetNodePoolSize):len(c.CallOptions.SetNodePoolSize)], opts...) var resp *containerpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterManagerClient.SetNodePoolSize(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // SetNetworkPolicy enables/Disables Network Policy for a cluster. func (c *ClusterManagerClient) SetNetworkPolicy(ctx context.Context, req *containerpb.SetNetworkPolicyRequest, opts ...gax.CallOption) (*containerpb.Operation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.SetNetworkPolicy[0:len(c.CallOptions.SetNetworkPolicy):len(c.CallOptions.SetNetworkPolicy)], opts...) var resp *containerpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterManagerClient.SetNetworkPolicy(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // SetMaintenancePolicy sets the maintenance policy for a cluster. func (c *ClusterManagerClient) SetMaintenancePolicy(ctx context.Context, req *containerpb.SetMaintenancePolicyRequest, opts ...gax.CallOption) (*containerpb.Operation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.SetMaintenancePolicy[0:len(c.CallOptions.SetMaintenancePolicy):len(c.CallOptions.SetMaintenancePolicy)], opts...) var resp *containerpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterManagerClient.SetMaintenancePolicy(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } google-cloud-go-0.49.0/container/apiv1/cluster_manager_client_example_test.go000066400000000000000000000303001356504100700274000ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // AUTO-GENERATED CODE. DO NOT EDIT. package container_test import ( "context" container "cloud.google.com/go/container/apiv1" containerpb "google.golang.org/genproto/googleapis/container/v1" ) func ExampleNewClusterManagerClient() { ctx := context.Background() c, err := container.NewClusterManagerClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleClusterManagerClient_ListClusters() { ctx := context.Background() c, err := container.NewClusterManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &containerpb.ListClustersRequest{ // TODO: Fill request struct fields. } resp, err := c.ListClusters(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClusterManagerClient_GetCluster() { ctx := context.Background() c, err := container.NewClusterManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &containerpb.GetClusterRequest{ // TODO: Fill request struct fields. } resp, err := c.GetCluster(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClusterManagerClient_CreateCluster() { ctx := context.Background() c, err := container.NewClusterManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &containerpb.CreateClusterRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateCluster(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClusterManagerClient_UpdateCluster() { ctx := context.Background() c, err := container.NewClusterManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &containerpb.UpdateClusterRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateCluster(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClusterManagerClient_UpdateNodePool() { ctx := context.Background() c, err := container.NewClusterManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &containerpb.UpdateNodePoolRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateNodePool(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClusterManagerClient_SetNodePoolAutoscaling() { ctx := context.Background() c, err := container.NewClusterManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &containerpb.SetNodePoolAutoscalingRequest{ // TODO: Fill request struct fields. } resp, err := c.SetNodePoolAutoscaling(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClusterManagerClient_SetLoggingService() { ctx := context.Background() c, err := container.NewClusterManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &containerpb.SetLoggingServiceRequest{ // TODO: Fill request struct fields. } resp, err := c.SetLoggingService(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClusterManagerClient_SetMonitoringService() { ctx := context.Background() c, err := container.NewClusterManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &containerpb.SetMonitoringServiceRequest{ // TODO: Fill request struct fields. } resp, err := c.SetMonitoringService(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClusterManagerClient_SetAddonsConfig() { ctx := context.Background() c, err := container.NewClusterManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &containerpb.SetAddonsConfigRequest{ // TODO: Fill request struct fields. } resp, err := c.SetAddonsConfig(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClusterManagerClient_SetLocations() { ctx := context.Background() c, err := container.NewClusterManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &containerpb.SetLocationsRequest{ // TODO: Fill request struct fields. } resp, err := c.SetLocations(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClusterManagerClient_UpdateMaster() { ctx := context.Background() c, err := container.NewClusterManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &containerpb.UpdateMasterRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateMaster(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClusterManagerClient_SetMasterAuth() { ctx := context.Background() c, err := container.NewClusterManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &containerpb.SetMasterAuthRequest{ // TODO: Fill request struct fields. } resp, err := c.SetMasterAuth(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClusterManagerClient_DeleteCluster() { ctx := context.Background() c, err := container.NewClusterManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &containerpb.DeleteClusterRequest{ // TODO: Fill request struct fields. } resp, err := c.DeleteCluster(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClusterManagerClient_ListOperations() { ctx := context.Background() c, err := container.NewClusterManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &containerpb.ListOperationsRequest{ // TODO: Fill request struct fields. } resp, err := c.ListOperations(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClusterManagerClient_GetOperation() { ctx := context.Background() c, err := container.NewClusterManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &containerpb.GetOperationRequest{ // TODO: Fill request struct fields. } resp, err := c.GetOperation(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClusterManagerClient_CancelOperation() { ctx := context.Background() c, err := container.NewClusterManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &containerpb.CancelOperationRequest{ // TODO: Fill request struct fields. } err = c.CancelOperation(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleClusterManagerClient_GetServerConfig() { ctx := context.Background() c, err := container.NewClusterManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &containerpb.GetServerConfigRequest{ // TODO: Fill request struct fields. } resp, err := c.GetServerConfig(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClusterManagerClient_ListNodePools() { ctx := context.Background() c, err := container.NewClusterManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &containerpb.ListNodePoolsRequest{ // TODO: Fill request struct fields. } resp, err := c.ListNodePools(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClusterManagerClient_GetNodePool() { ctx := context.Background() c, err := container.NewClusterManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &containerpb.GetNodePoolRequest{ // TODO: Fill request struct fields. } resp, err := c.GetNodePool(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClusterManagerClient_CreateNodePool() { ctx := context.Background() c, err := container.NewClusterManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &containerpb.CreateNodePoolRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateNodePool(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClusterManagerClient_DeleteNodePool() { ctx := context.Background() c, err := container.NewClusterManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &containerpb.DeleteNodePoolRequest{ // TODO: Fill request struct fields. } resp, err := c.DeleteNodePool(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClusterManagerClient_RollbackNodePoolUpgrade() { ctx := context.Background() c, err := container.NewClusterManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &containerpb.RollbackNodePoolUpgradeRequest{ // TODO: Fill request struct fields. } resp, err := c.RollbackNodePoolUpgrade(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClusterManagerClient_SetNodePoolManagement() { ctx := context.Background() c, err := container.NewClusterManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &containerpb.SetNodePoolManagementRequest{ // TODO: Fill request struct fields. } resp, err := c.SetNodePoolManagement(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClusterManagerClient_SetLabels() { ctx := context.Background() c, err := container.NewClusterManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &containerpb.SetLabelsRequest{ // TODO: Fill request struct fields. } resp, err := c.SetLabels(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClusterManagerClient_SetLegacyAbac() { ctx := context.Background() c, err := container.NewClusterManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &containerpb.SetLegacyAbacRequest{ // TODO: Fill request struct fields. } resp, err := c.SetLegacyAbac(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClusterManagerClient_StartIPRotation() { ctx := context.Background() c, err := container.NewClusterManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &containerpb.StartIPRotationRequest{ // TODO: Fill request struct fields. } resp, err := c.StartIPRotation(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClusterManagerClient_CompleteIPRotation() { ctx := context.Background() c, err := container.NewClusterManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &containerpb.CompleteIPRotationRequest{ // TODO: Fill request struct fields. } resp, err := c.CompleteIPRotation(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClusterManagerClient_SetNodePoolSize() { ctx := context.Background() c, err := container.NewClusterManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &containerpb.SetNodePoolSizeRequest{ // TODO: Fill request struct fields. } resp, err := c.SetNodePoolSize(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClusterManagerClient_SetNetworkPolicy() { ctx := context.Background() c, err := container.NewClusterManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &containerpb.SetNetworkPolicyRequest{ // TODO: Fill request struct fields. } resp, err := c.SetNetworkPolicy(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClusterManagerClient_SetMaintenancePolicy() { ctx := context.Background() c, err := container.NewClusterManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &containerpb.SetMaintenancePolicyRequest{ // TODO: Fill request struct fields. } resp, err := c.SetMaintenancePolicy(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/container/apiv1/doc.go000066400000000000000000000030461356504100700206710ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // AUTO-GENERATED CODE. DO NOT EDIT. // Package container is an auto-generated package for the // Google Container Engine API. // // NOTE: This package is in alpha. It is not stable, and is likely to change. // // The Google Kubernetes Engine API is used for building and managing // container // based applications, powered by the open source Kubernetes technology. package container // import "cloud.google.com/go/container/apiv1" import ( "context" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", } } google-cloud-go-0.49.0/container/apiv1/mock_test.go000066400000000000000000002555701356504100700221270ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // AUTO-GENERATED CODE. DO NOT EDIT. package container import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" "google.golang.org/api/option" containerpb "google.golang.org/genproto/googleapis/container/v1" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockClusterManagerServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. containerpb.ClusterManagerServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockClusterManagerServer) ListClusters(ctx context.Context, req *containerpb.ListClustersRequest) (*containerpb.ListClustersResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*containerpb.ListClustersResponse), nil } func (s *mockClusterManagerServer) GetCluster(ctx context.Context, req *containerpb.GetClusterRequest) (*containerpb.Cluster, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*containerpb.Cluster), nil } func (s *mockClusterManagerServer) CreateCluster(ctx context.Context, req *containerpb.CreateClusterRequest) (*containerpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*containerpb.Operation), nil } func (s *mockClusterManagerServer) UpdateCluster(ctx context.Context, req *containerpb.UpdateClusterRequest) (*containerpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*containerpb.Operation), nil } func (s *mockClusterManagerServer) UpdateNodePool(ctx context.Context, req *containerpb.UpdateNodePoolRequest) (*containerpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*containerpb.Operation), nil } func (s *mockClusterManagerServer) SetNodePoolAutoscaling(ctx context.Context, req *containerpb.SetNodePoolAutoscalingRequest) (*containerpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*containerpb.Operation), nil } func (s *mockClusterManagerServer) SetLoggingService(ctx context.Context, req *containerpb.SetLoggingServiceRequest) (*containerpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*containerpb.Operation), nil } func (s *mockClusterManagerServer) SetMonitoringService(ctx context.Context, req *containerpb.SetMonitoringServiceRequest) (*containerpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*containerpb.Operation), nil } func (s *mockClusterManagerServer) SetAddonsConfig(ctx context.Context, req *containerpb.SetAddonsConfigRequest) (*containerpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*containerpb.Operation), nil } func (s *mockClusterManagerServer) SetLocations(ctx context.Context, req *containerpb.SetLocationsRequest) (*containerpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*containerpb.Operation), nil } func (s *mockClusterManagerServer) UpdateMaster(ctx context.Context, req *containerpb.UpdateMasterRequest) (*containerpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*containerpb.Operation), nil } func (s *mockClusterManagerServer) SetMasterAuth(ctx context.Context, req *containerpb.SetMasterAuthRequest) (*containerpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*containerpb.Operation), nil } func (s *mockClusterManagerServer) DeleteCluster(ctx context.Context, req *containerpb.DeleteClusterRequest) (*containerpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*containerpb.Operation), nil } func (s *mockClusterManagerServer) ListOperations(ctx context.Context, req *containerpb.ListOperationsRequest) (*containerpb.ListOperationsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*containerpb.ListOperationsResponse), nil } func (s *mockClusterManagerServer) GetOperation(ctx context.Context, req *containerpb.GetOperationRequest) (*containerpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*containerpb.Operation), nil } func (s *mockClusterManagerServer) CancelOperation(ctx context.Context, req *containerpb.CancelOperationRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockClusterManagerServer) GetServerConfig(ctx context.Context, req *containerpb.GetServerConfigRequest) (*containerpb.ServerConfig, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*containerpb.ServerConfig), nil } func (s *mockClusterManagerServer) ListNodePools(ctx context.Context, req *containerpb.ListNodePoolsRequest) (*containerpb.ListNodePoolsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*containerpb.ListNodePoolsResponse), nil } func (s *mockClusterManagerServer) GetNodePool(ctx context.Context, req *containerpb.GetNodePoolRequest) (*containerpb.NodePool, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*containerpb.NodePool), nil } func (s *mockClusterManagerServer) CreateNodePool(ctx context.Context, req *containerpb.CreateNodePoolRequest) (*containerpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*containerpb.Operation), nil } func (s *mockClusterManagerServer) DeleteNodePool(ctx context.Context, req *containerpb.DeleteNodePoolRequest) (*containerpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*containerpb.Operation), nil } func (s *mockClusterManagerServer) RollbackNodePoolUpgrade(ctx context.Context, req *containerpb.RollbackNodePoolUpgradeRequest) (*containerpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*containerpb.Operation), nil } func (s *mockClusterManagerServer) SetNodePoolManagement(ctx context.Context, req *containerpb.SetNodePoolManagementRequest) (*containerpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*containerpb.Operation), nil } func (s *mockClusterManagerServer) SetLabels(ctx context.Context, req *containerpb.SetLabelsRequest) (*containerpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*containerpb.Operation), nil } func (s *mockClusterManagerServer) SetLegacyAbac(ctx context.Context, req *containerpb.SetLegacyAbacRequest) (*containerpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*containerpb.Operation), nil } func (s *mockClusterManagerServer) StartIPRotation(ctx context.Context, req *containerpb.StartIPRotationRequest) (*containerpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*containerpb.Operation), nil } func (s *mockClusterManagerServer) CompleteIPRotation(ctx context.Context, req *containerpb.CompleteIPRotationRequest) (*containerpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*containerpb.Operation), nil } func (s *mockClusterManagerServer) SetNodePoolSize(ctx context.Context, req *containerpb.SetNodePoolSizeRequest) (*containerpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*containerpb.Operation), nil } func (s *mockClusterManagerServer) SetNetworkPolicy(ctx context.Context, req *containerpb.SetNetworkPolicyRequest) (*containerpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*containerpb.Operation), nil } func (s *mockClusterManagerServer) SetMaintenancePolicy(ctx context.Context, req *containerpb.SetMaintenancePolicyRequest) (*containerpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*containerpb.Operation), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockClusterManager mockClusterManagerServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() containerpb.RegisterClusterManagerServer(serv, &mockClusterManager) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestClusterManagerListClusters(t *testing.T) { var expectedResponse *containerpb.ListClustersResponse = &containerpb.ListClustersResponse{} mockClusterManager.err = nil mockClusterManager.reqs = nil mockClusterManager.resps = append(mockClusterManager.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var zone string = "zone3744684" var request = &containerpb.ListClustersRequest{ ProjectId: projectId, Zone: zone, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListClusters(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockClusterManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestClusterManagerListClustersError(t *testing.T) { errCode := codes.PermissionDenied mockClusterManager.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var zone string = "zone3744684" var request = &containerpb.ListClustersRequest{ ProjectId: projectId, Zone: zone, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListClusters(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestClusterManagerGetCluster(t *testing.T) { var name string = "name3373707" var description string = "description-1724546052" var initialNodeCount int32 = 1682564205 var loggingService string = "loggingService-1700501035" var monitoringService string = "monitoringService1469270462" var network string = "network1843485230" var clusterIpv4Cidr string = "clusterIpv4Cidr-141875831" var subnetwork string = "subnetwork-1302785042" var enableKubernetesAlpha bool = false var labelFingerprint string = "labelFingerprint714995737" var selfLink string = "selfLink-1691268851" var zone2 string = "zone2-696322977" var endpoint string = "endpoint1741102485" var initialClusterVersion string = "initialClusterVersion-276373352" var currentMasterVersion string = "currentMasterVersion-920953983" var currentNodeVersion string = "currentNodeVersion-407476063" var createTime string = "createTime-493574096" var statusMessage string = "statusMessage-239442758" var nodeIpv4CidrSize int32 = 1181176815 var servicesIpv4Cidr string = "servicesIpv4Cidr1966438125" var currentNodeCount int32 = 178977560 var expireTime string = "expireTime-96179731" var expectedResponse = &containerpb.Cluster{ Name: name, Description: description, InitialNodeCount: initialNodeCount, LoggingService: loggingService, MonitoringService: monitoringService, Network: network, ClusterIpv4Cidr: clusterIpv4Cidr, Subnetwork: subnetwork, EnableKubernetesAlpha: enableKubernetesAlpha, LabelFingerprint: labelFingerprint, SelfLink: selfLink, Zone: zone2, Endpoint: endpoint, InitialClusterVersion: initialClusterVersion, CurrentMasterVersion: currentMasterVersion, CurrentNodeVersion: currentNodeVersion, CreateTime: createTime, StatusMessage: statusMessage, NodeIpv4CidrSize: nodeIpv4CidrSize, ServicesIpv4Cidr: servicesIpv4Cidr, CurrentNodeCount: currentNodeCount, ExpireTime: expireTime, } mockClusterManager.err = nil mockClusterManager.reqs = nil mockClusterManager.resps = append(mockClusterManager.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var request = &containerpb.GetClusterRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetCluster(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockClusterManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestClusterManagerGetClusterError(t *testing.T) { errCode := codes.PermissionDenied mockClusterManager.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var request = &containerpb.GetClusterRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetCluster(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestClusterManagerCreateCluster(t *testing.T) { var name string = "name3373707" var zone2 string = "zone2-696322977" var detail string = "detail-1335224239" var statusMessage string = "statusMessage-239442758" var selfLink string = "selfLink-1691268851" var targetLink string = "targetLink-2084812312" var startTime string = "startTime-1573145462" var endTime string = "endTime1725551537" var expectedResponse = &containerpb.Operation{ Name: name, Zone: zone2, Detail: detail, StatusMessage: statusMessage, SelfLink: selfLink, TargetLink: targetLink, StartTime: startTime, EndTime: endTime, } mockClusterManager.err = nil mockClusterManager.reqs = nil mockClusterManager.resps = append(mockClusterManager.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var zone string = "zone3744684" var cluster *containerpb.Cluster = &containerpb.Cluster{} var request = &containerpb.CreateClusterRequest{ ProjectId: projectId, Zone: zone, Cluster: cluster, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateCluster(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockClusterManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestClusterManagerCreateClusterError(t *testing.T) { errCode := codes.PermissionDenied mockClusterManager.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var zone string = "zone3744684" var cluster *containerpb.Cluster = &containerpb.Cluster{} var request = &containerpb.CreateClusterRequest{ ProjectId: projectId, Zone: zone, Cluster: cluster, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateCluster(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestClusterManagerUpdateCluster(t *testing.T) { var name string = "name3373707" var zone2 string = "zone2-696322977" var detail string = "detail-1335224239" var statusMessage string = "statusMessage-239442758" var selfLink string = "selfLink-1691268851" var targetLink string = "targetLink-2084812312" var startTime string = "startTime-1573145462" var endTime string = "endTime1725551537" var expectedResponse = &containerpb.Operation{ Name: name, Zone: zone2, Detail: detail, StatusMessage: statusMessage, SelfLink: selfLink, TargetLink: targetLink, StartTime: startTime, EndTime: endTime, } mockClusterManager.err = nil mockClusterManager.reqs = nil mockClusterManager.resps = append(mockClusterManager.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var update *containerpb.ClusterUpdate = &containerpb.ClusterUpdate{} var request = &containerpb.UpdateClusterRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, Update: update, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateCluster(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockClusterManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestClusterManagerUpdateClusterError(t *testing.T) { errCode := codes.PermissionDenied mockClusterManager.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var update *containerpb.ClusterUpdate = &containerpb.ClusterUpdate{} var request = &containerpb.UpdateClusterRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, Update: update, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateCluster(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestClusterManagerUpdateNodePool(t *testing.T) { var name string = "name3373707" var zone2 string = "zone2-696322977" var detail string = "detail-1335224239" var statusMessage string = "statusMessage-239442758" var selfLink string = "selfLink-1691268851" var targetLink string = "targetLink-2084812312" var startTime string = "startTime-1573145462" var endTime string = "endTime1725551537" var expectedResponse = &containerpb.Operation{ Name: name, Zone: zone2, Detail: detail, StatusMessage: statusMessage, SelfLink: selfLink, TargetLink: targetLink, StartTime: startTime, EndTime: endTime, } mockClusterManager.err = nil mockClusterManager.reqs = nil mockClusterManager.resps = append(mockClusterManager.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var nodePoolId string = "nodePoolId1043384033" var nodeVersion string = "nodeVersion1790136219" var imageType string = "imageType-1442758754" var request = &containerpb.UpdateNodePoolRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, NodePoolId: nodePoolId, NodeVersion: nodeVersion, ImageType: imageType, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateNodePool(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockClusterManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestClusterManagerUpdateNodePoolError(t *testing.T) { errCode := codes.PermissionDenied mockClusterManager.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var nodePoolId string = "nodePoolId1043384033" var nodeVersion string = "nodeVersion1790136219" var imageType string = "imageType-1442758754" var request = &containerpb.UpdateNodePoolRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, NodePoolId: nodePoolId, NodeVersion: nodeVersion, ImageType: imageType, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateNodePool(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestClusterManagerSetNodePoolAutoscaling(t *testing.T) { var name string = "name3373707" var zone2 string = "zone2-696322977" var detail string = "detail-1335224239" var statusMessage string = "statusMessage-239442758" var selfLink string = "selfLink-1691268851" var targetLink string = "targetLink-2084812312" var startTime string = "startTime-1573145462" var endTime string = "endTime1725551537" var expectedResponse = &containerpb.Operation{ Name: name, Zone: zone2, Detail: detail, StatusMessage: statusMessage, SelfLink: selfLink, TargetLink: targetLink, StartTime: startTime, EndTime: endTime, } mockClusterManager.err = nil mockClusterManager.reqs = nil mockClusterManager.resps = append(mockClusterManager.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var nodePoolId string = "nodePoolId1043384033" var autoscaling *containerpb.NodePoolAutoscaling = &containerpb.NodePoolAutoscaling{} var request = &containerpb.SetNodePoolAutoscalingRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, NodePoolId: nodePoolId, Autoscaling: autoscaling, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetNodePoolAutoscaling(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockClusterManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestClusterManagerSetNodePoolAutoscalingError(t *testing.T) { errCode := codes.PermissionDenied mockClusterManager.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var nodePoolId string = "nodePoolId1043384033" var autoscaling *containerpb.NodePoolAutoscaling = &containerpb.NodePoolAutoscaling{} var request = &containerpb.SetNodePoolAutoscalingRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, NodePoolId: nodePoolId, Autoscaling: autoscaling, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetNodePoolAutoscaling(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestClusterManagerSetLoggingService(t *testing.T) { var name string = "name3373707" var zone2 string = "zone2-696322977" var detail string = "detail-1335224239" var statusMessage string = "statusMessage-239442758" var selfLink string = "selfLink-1691268851" var targetLink string = "targetLink-2084812312" var startTime string = "startTime-1573145462" var endTime string = "endTime1725551537" var expectedResponse = &containerpb.Operation{ Name: name, Zone: zone2, Detail: detail, StatusMessage: statusMessage, SelfLink: selfLink, TargetLink: targetLink, StartTime: startTime, EndTime: endTime, } mockClusterManager.err = nil mockClusterManager.reqs = nil mockClusterManager.resps = append(mockClusterManager.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var loggingService string = "loggingService-1700501035" var request = &containerpb.SetLoggingServiceRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, LoggingService: loggingService, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetLoggingService(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockClusterManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestClusterManagerSetLoggingServiceError(t *testing.T) { errCode := codes.PermissionDenied mockClusterManager.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var loggingService string = "loggingService-1700501035" var request = &containerpb.SetLoggingServiceRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, LoggingService: loggingService, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetLoggingService(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestClusterManagerSetMonitoringService(t *testing.T) { var name string = "name3373707" var zone2 string = "zone2-696322977" var detail string = "detail-1335224239" var statusMessage string = "statusMessage-239442758" var selfLink string = "selfLink-1691268851" var targetLink string = "targetLink-2084812312" var startTime string = "startTime-1573145462" var endTime string = "endTime1725551537" var expectedResponse = &containerpb.Operation{ Name: name, Zone: zone2, Detail: detail, StatusMessage: statusMessage, SelfLink: selfLink, TargetLink: targetLink, StartTime: startTime, EndTime: endTime, } mockClusterManager.err = nil mockClusterManager.reqs = nil mockClusterManager.resps = append(mockClusterManager.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var monitoringService string = "monitoringService1469270462" var request = &containerpb.SetMonitoringServiceRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, MonitoringService: monitoringService, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetMonitoringService(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockClusterManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestClusterManagerSetMonitoringServiceError(t *testing.T) { errCode := codes.PermissionDenied mockClusterManager.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var monitoringService string = "monitoringService1469270462" var request = &containerpb.SetMonitoringServiceRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, MonitoringService: monitoringService, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetMonitoringService(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestClusterManagerSetAddonsConfig(t *testing.T) { var name string = "name3373707" var zone2 string = "zone2-696322977" var detail string = "detail-1335224239" var statusMessage string = "statusMessage-239442758" var selfLink string = "selfLink-1691268851" var targetLink string = "targetLink-2084812312" var startTime string = "startTime-1573145462" var endTime string = "endTime1725551537" var expectedResponse = &containerpb.Operation{ Name: name, Zone: zone2, Detail: detail, StatusMessage: statusMessage, SelfLink: selfLink, TargetLink: targetLink, StartTime: startTime, EndTime: endTime, } mockClusterManager.err = nil mockClusterManager.reqs = nil mockClusterManager.resps = append(mockClusterManager.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var addonsConfig *containerpb.AddonsConfig = &containerpb.AddonsConfig{} var request = &containerpb.SetAddonsConfigRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, AddonsConfig: addonsConfig, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetAddonsConfig(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockClusterManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestClusterManagerSetAddonsConfigError(t *testing.T) { errCode := codes.PermissionDenied mockClusterManager.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var addonsConfig *containerpb.AddonsConfig = &containerpb.AddonsConfig{} var request = &containerpb.SetAddonsConfigRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, AddonsConfig: addonsConfig, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetAddonsConfig(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestClusterManagerSetLocations(t *testing.T) { var name string = "name3373707" var zone2 string = "zone2-696322977" var detail string = "detail-1335224239" var statusMessage string = "statusMessage-239442758" var selfLink string = "selfLink-1691268851" var targetLink string = "targetLink-2084812312" var startTime string = "startTime-1573145462" var endTime string = "endTime1725551537" var expectedResponse = &containerpb.Operation{ Name: name, Zone: zone2, Detail: detail, StatusMessage: statusMessage, SelfLink: selfLink, TargetLink: targetLink, StartTime: startTime, EndTime: endTime, } mockClusterManager.err = nil mockClusterManager.reqs = nil mockClusterManager.resps = append(mockClusterManager.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var locations []string = nil var request = &containerpb.SetLocationsRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, Locations: locations, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetLocations(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockClusterManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestClusterManagerSetLocationsError(t *testing.T) { errCode := codes.PermissionDenied mockClusterManager.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var locations []string = nil var request = &containerpb.SetLocationsRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, Locations: locations, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetLocations(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestClusterManagerUpdateMaster(t *testing.T) { var name string = "name3373707" var zone2 string = "zone2-696322977" var detail string = "detail-1335224239" var statusMessage string = "statusMessage-239442758" var selfLink string = "selfLink-1691268851" var targetLink string = "targetLink-2084812312" var startTime string = "startTime-1573145462" var endTime string = "endTime1725551537" var expectedResponse = &containerpb.Operation{ Name: name, Zone: zone2, Detail: detail, StatusMessage: statusMessage, SelfLink: selfLink, TargetLink: targetLink, StartTime: startTime, EndTime: endTime, } mockClusterManager.err = nil mockClusterManager.reqs = nil mockClusterManager.resps = append(mockClusterManager.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var masterVersion string = "masterVersion-2139460613" var request = &containerpb.UpdateMasterRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, MasterVersion: masterVersion, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateMaster(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockClusterManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestClusterManagerUpdateMasterError(t *testing.T) { errCode := codes.PermissionDenied mockClusterManager.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var masterVersion string = "masterVersion-2139460613" var request = &containerpb.UpdateMasterRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, MasterVersion: masterVersion, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateMaster(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestClusterManagerSetMasterAuth(t *testing.T) { var name string = "name3373707" var zone2 string = "zone2-696322977" var detail string = "detail-1335224239" var statusMessage string = "statusMessage-239442758" var selfLink string = "selfLink-1691268851" var targetLink string = "targetLink-2084812312" var startTime string = "startTime-1573145462" var endTime string = "endTime1725551537" var expectedResponse = &containerpb.Operation{ Name: name, Zone: zone2, Detail: detail, StatusMessage: statusMessage, SelfLink: selfLink, TargetLink: targetLink, StartTime: startTime, EndTime: endTime, } mockClusterManager.err = nil mockClusterManager.reqs = nil mockClusterManager.resps = append(mockClusterManager.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var action containerpb.SetMasterAuthRequest_Action = containerpb.SetMasterAuthRequest_UNKNOWN var update *containerpb.MasterAuth = &containerpb.MasterAuth{} var request = &containerpb.SetMasterAuthRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, Action: action, Update: update, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetMasterAuth(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockClusterManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestClusterManagerSetMasterAuthError(t *testing.T) { errCode := codes.PermissionDenied mockClusterManager.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var action containerpb.SetMasterAuthRequest_Action = containerpb.SetMasterAuthRequest_UNKNOWN var update *containerpb.MasterAuth = &containerpb.MasterAuth{} var request = &containerpb.SetMasterAuthRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, Action: action, Update: update, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetMasterAuth(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestClusterManagerDeleteCluster(t *testing.T) { var name string = "name3373707" var zone2 string = "zone2-696322977" var detail string = "detail-1335224239" var statusMessage string = "statusMessage-239442758" var selfLink string = "selfLink-1691268851" var targetLink string = "targetLink-2084812312" var startTime string = "startTime-1573145462" var endTime string = "endTime1725551537" var expectedResponse = &containerpb.Operation{ Name: name, Zone: zone2, Detail: detail, StatusMessage: statusMessage, SelfLink: selfLink, TargetLink: targetLink, StartTime: startTime, EndTime: endTime, } mockClusterManager.err = nil mockClusterManager.reqs = nil mockClusterManager.resps = append(mockClusterManager.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var request = &containerpb.DeleteClusterRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.DeleteCluster(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockClusterManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestClusterManagerDeleteClusterError(t *testing.T) { errCode := codes.PermissionDenied mockClusterManager.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var request = &containerpb.DeleteClusterRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.DeleteCluster(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestClusterManagerListOperations(t *testing.T) { var expectedResponse *containerpb.ListOperationsResponse = &containerpb.ListOperationsResponse{} mockClusterManager.err = nil mockClusterManager.reqs = nil mockClusterManager.resps = append(mockClusterManager.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var zone string = "zone3744684" var request = &containerpb.ListOperationsRequest{ ProjectId: projectId, Zone: zone, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListOperations(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockClusterManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestClusterManagerListOperationsError(t *testing.T) { errCode := codes.PermissionDenied mockClusterManager.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var zone string = "zone3744684" var request = &containerpb.ListOperationsRequest{ ProjectId: projectId, Zone: zone, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListOperations(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestClusterManagerGetOperation(t *testing.T) { var name string = "name3373707" var zone2 string = "zone2-696322977" var detail string = "detail-1335224239" var statusMessage string = "statusMessage-239442758" var selfLink string = "selfLink-1691268851" var targetLink string = "targetLink-2084812312" var startTime string = "startTime-1573145462" var endTime string = "endTime1725551537" var expectedResponse = &containerpb.Operation{ Name: name, Zone: zone2, Detail: detail, StatusMessage: statusMessage, SelfLink: selfLink, TargetLink: targetLink, StartTime: startTime, EndTime: endTime, } mockClusterManager.err = nil mockClusterManager.reqs = nil mockClusterManager.resps = append(mockClusterManager.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var zone string = "zone3744684" var operationId string = "operationId-274116877" var request = &containerpb.GetOperationRequest{ ProjectId: projectId, Zone: zone, OperationId: operationId, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetOperation(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockClusterManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestClusterManagerGetOperationError(t *testing.T) { errCode := codes.PermissionDenied mockClusterManager.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var zone string = "zone3744684" var operationId string = "operationId-274116877" var request = &containerpb.GetOperationRequest{ ProjectId: projectId, Zone: zone, OperationId: operationId, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetOperation(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestClusterManagerCancelOperation(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockClusterManager.err = nil mockClusterManager.reqs = nil mockClusterManager.resps = append(mockClusterManager.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var zone string = "zone3744684" var operationId string = "operationId-274116877" var request = &containerpb.CancelOperationRequest{ ProjectId: projectId, Zone: zone, OperationId: operationId, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.CancelOperation(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockClusterManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestClusterManagerCancelOperationError(t *testing.T) { errCode := codes.PermissionDenied mockClusterManager.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var zone string = "zone3744684" var operationId string = "operationId-274116877" var request = &containerpb.CancelOperationRequest{ ProjectId: projectId, Zone: zone, OperationId: operationId, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.CancelOperation(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestClusterManagerGetServerConfig(t *testing.T) { var defaultClusterVersion string = "defaultClusterVersion111003029" var defaultImageType string = "defaultImageType-918225828" var expectedResponse = &containerpb.ServerConfig{ DefaultClusterVersion: defaultClusterVersion, DefaultImageType: defaultImageType, } mockClusterManager.err = nil mockClusterManager.reqs = nil mockClusterManager.resps = append(mockClusterManager.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var zone string = "zone3744684" var request = &containerpb.GetServerConfigRequest{ ProjectId: projectId, Zone: zone, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetServerConfig(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockClusterManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestClusterManagerGetServerConfigError(t *testing.T) { errCode := codes.PermissionDenied mockClusterManager.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var zone string = "zone3744684" var request = &containerpb.GetServerConfigRequest{ ProjectId: projectId, Zone: zone, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetServerConfig(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestClusterManagerListNodePools(t *testing.T) { var expectedResponse *containerpb.ListNodePoolsResponse = &containerpb.ListNodePoolsResponse{} mockClusterManager.err = nil mockClusterManager.reqs = nil mockClusterManager.resps = append(mockClusterManager.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var request = &containerpb.ListNodePoolsRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListNodePools(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockClusterManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestClusterManagerListNodePoolsError(t *testing.T) { errCode := codes.PermissionDenied mockClusterManager.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var request = &containerpb.ListNodePoolsRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListNodePools(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestClusterManagerGetNodePool(t *testing.T) { var name string = "name3373707" var initialNodeCount int32 = 1682564205 var selfLink string = "selfLink-1691268851" var version string = "version351608024" var statusMessage string = "statusMessage-239442758" var expectedResponse = &containerpb.NodePool{ Name: name, InitialNodeCount: initialNodeCount, SelfLink: selfLink, Version: version, StatusMessage: statusMessage, } mockClusterManager.err = nil mockClusterManager.reqs = nil mockClusterManager.resps = append(mockClusterManager.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var nodePoolId string = "nodePoolId1043384033" var request = &containerpb.GetNodePoolRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, NodePoolId: nodePoolId, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetNodePool(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockClusterManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestClusterManagerGetNodePoolError(t *testing.T) { errCode := codes.PermissionDenied mockClusterManager.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var nodePoolId string = "nodePoolId1043384033" var request = &containerpb.GetNodePoolRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, NodePoolId: nodePoolId, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetNodePool(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestClusterManagerCreateNodePool(t *testing.T) { var name string = "name3373707" var zone2 string = "zone2-696322977" var detail string = "detail-1335224239" var statusMessage string = "statusMessage-239442758" var selfLink string = "selfLink-1691268851" var targetLink string = "targetLink-2084812312" var startTime string = "startTime-1573145462" var endTime string = "endTime1725551537" var expectedResponse = &containerpb.Operation{ Name: name, Zone: zone2, Detail: detail, StatusMessage: statusMessage, SelfLink: selfLink, TargetLink: targetLink, StartTime: startTime, EndTime: endTime, } mockClusterManager.err = nil mockClusterManager.reqs = nil mockClusterManager.resps = append(mockClusterManager.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var nodePool *containerpb.NodePool = &containerpb.NodePool{} var request = &containerpb.CreateNodePoolRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, NodePool: nodePool, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateNodePool(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockClusterManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestClusterManagerCreateNodePoolError(t *testing.T) { errCode := codes.PermissionDenied mockClusterManager.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var nodePool *containerpb.NodePool = &containerpb.NodePool{} var request = &containerpb.CreateNodePoolRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, NodePool: nodePool, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateNodePool(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestClusterManagerDeleteNodePool(t *testing.T) { var name string = "name3373707" var zone2 string = "zone2-696322977" var detail string = "detail-1335224239" var statusMessage string = "statusMessage-239442758" var selfLink string = "selfLink-1691268851" var targetLink string = "targetLink-2084812312" var startTime string = "startTime-1573145462" var endTime string = "endTime1725551537" var expectedResponse = &containerpb.Operation{ Name: name, Zone: zone2, Detail: detail, StatusMessage: statusMessage, SelfLink: selfLink, TargetLink: targetLink, StartTime: startTime, EndTime: endTime, } mockClusterManager.err = nil mockClusterManager.reqs = nil mockClusterManager.resps = append(mockClusterManager.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var nodePoolId string = "nodePoolId1043384033" var request = &containerpb.DeleteNodePoolRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, NodePoolId: nodePoolId, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.DeleteNodePool(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockClusterManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestClusterManagerDeleteNodePoolError(t *testing.T) { errCode := codes.PermissionDenied mockClusterManager.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var nodePoolId string = "nodePoolId1043384033" var request = &containerpb.DeleteNodePoolRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, NodePoolId: nodePoolId, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.DeleteNodePool(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestClusterManagerRollbackNodePoolUpgrade(t *testing.T) { var name string = "name3373707" var zone2 string = "zone2-696322977" var detail string = "detail-1335224239" var statusMessage string = "statusMessage-239442758" var selfLink string = "selfLink-1691268851" var targetLink string = "targetLink-2084812312" var startTime string = "startTime-1573145462" var endTime string = "endTime1725551537" var expectedResponse = &containerpb.Operation{ Name: name, Zone: zone2, Detail: detail, StatusMessage: statusMessage, SelfLink: selfLink, TargetLink: targetLink, StartTime: startTime, EndTime: endTime, } mockClusterManager.err = nil mockClusterManager.reqs = nil mockClusterManager.resps = append(mockClusterManager.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var nodePoolId string = "nodePoolId1043384033" var request = &containerpb.RollbackNodePoolUpgradeRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, NodePoolId: nodePoolId, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.RollbackNodePoolUpgrade(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockClusterManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestClusterManagerRollbackNodePoolUpgradeError(t *testing.T) { errCode := codes.PermissionDenied mockClusterManager.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var nodePoolId string = "nodePoolId1043384033" var request = &containerpb.RollbackNodePoolUpgradeRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, NodePoolId: nodePoolId, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.RollbackNodePoolUpgrade(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestClusterManagerSetNodePoolManagement(t *testing.T) { var name string = "name3373707" var zone2 string = "zone2-696322977" var detail string = "detail-1335224239" var statusMessage string = "statusMessage-239442758" var selfLink string = "selfLink-1691268851" var targetLink string = "targetLink-2084812312" var startTime string = "startTime-1573145462" var endTime string = "endTime1725551537" var expectedResponse = &containerpb.Operation{ Name: name, Zone: zone2, Detail: detail, StatusMessage: statusMessage, SelfLink: selfLink, TargetLink: targetLink, StartTime: startTime, EndTime: endTime, } mockClusterManager.err = nil mockClusterManager.reqs = nil mockClusterManager.resps = append(mockClusterManager.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var nodePoolId string = "nodePoolId1043384033" var management *containerpb.NodeManagement = &containerpb.NodeManagement{} var request = &containerpb.SetNodePoolManagementRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, NodePoolId: nodePoolId, Management: management, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetNodePoolManagement(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockClusterManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestClusterManagerSetNodePoolManagementError(t *testing.T) { errCode := codes.PermissionDenied mockClusterManager.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var nodePoolId string = "nodePoolId1043384033" var management *containerpb.NodeManagement = &containerpb.NodeManagement{} var request = &containerpb.SetNodePoolManagementRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, NodePoolId: nodePoolId, Management: management, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetNodePoolManagement(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestClusterManagerSetLabels(t *testing.T) { var name string = "name3373707" var zone2 string = "zone2-696322977" var detail string = "detail-1335224239" var statusMessage string = "statusMessage-239442758" var selfLink string = "selfLink-1691268851" var targetLink string = "targetLink-2084812312" var startTime string = "startTime-1573145462" var endTime string = "endTime1725551537" var expectedResponse = &containerpb.Operation{ Name: name, Zone: zone2, Detail: detail, StatusMessage: statusMessage, SelfLink: selfLink, TargetLink: targetLink, StartTime: startTime, EndTime: endTime, } mockClusterManager.err = nil mockClusterManager.reqs = nil mockClusterManager.resps = append(mockClusterManager.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var resourceLabels map[string]string = nil var labelFingerprint string = "labelFingerprint714995737" var request = &containerpb.SetLabelsRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, ResourceLabels: resourceLabels, LabelFingerprint: labelFingerprint, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetLabels(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockClusterManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestClusterManagerSetLabelsError(t *testing.T) { errCode := codes.PermissionDenied mockClusterManager.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var resourceLabels map[string]string = nil var labelFingerprint string = "labelFingerprint714995737" var request = &containerpb.SetLabelsRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, ResourceLabels: resourceLabels, LabelFingerprint: labelFingerprint, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetLabels(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestClusterManagerSetLegacyAbac(t *testing.T) { var name string = "name3373707" var zone2 string = "zone2-696322977" var detail string = "detail-1335224239" var statusMessage string = "statusMessage-239442758" var selfLink string = "selfLink-1691268851" var targetLink string = "targetLink-2084812312" var startTime string = "startTime-1573145462" var endTime string = "endTime1725551537" var expectedResponse = &containerpb.Operation{ Name: name, Zone: zone2, Detail: detail, StatusMessage: statusMessage, SelfLink: selfLink, TargetLink: targetLink, StartTime: startTime, EndTime: endTime, } mockClusterManager.err = nil mockClusterManager.reqs = nil mockClusterManager.resps = append(mockClusterManager.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var enabled bool = false var request = &containerpb.SetLegacyAbacRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, Enabled: enabled, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetLegacyAbac(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockClusterManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestClusterManagerSetLegacyAbacError(t *testing.T) { errCode := codes.PermissionDenied mockClusterManager.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var enabled bool = false var request = &containerpb.SetLegacyAbacRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, Enabled: enabled, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetLegacyAbac(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestClusterManagerStartIPRotation(t *testing.T) { var name string = "name3373707" var zone2 string = "zone2-696322977" var detail string = "detail-1335224239" var statusMessage string = "statusMessage-239442758" var selfLink string = "selfLink-1691268851" var targetLink string = "targetLink-2084812312" var startTime string = "startTime-1573145462" var endTime string = "endTime1725551537" var expectedResponse = &containerpb.Operation{ Name: name, Zone: zone2, Detail: detail, StatusMessage: statusMessage, SelfLink: selfLink, TargetLink: targetLink, StartTime: startTime, EndTime: endTime, } mockClusterManager.err = nil mockClusterManager.reqs = nil mockClusterManager.resps = append(mockClusterManager.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var request = &containerpb.StartIPRotationRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.StartIPRotation(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockClusterManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestClusterManagerStartIPRotationError(t *testing.T) { errCode := codes.PermissionDenied mockClusterManager.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var request = &containerpb.StartIPRotationRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.StartIPRotation(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestClusterManagerCompleteIPRotation(t *testing.T) { var name string = "name3373707" var zone2 string = "zone2-696322977" var detail string = "detail-1335224239" var statusMessage string = "statusMessage-239442758" var selfLink string = "selfLink-1691268851" var targetLink string = "targetLink-2084812312" var startTime string = "startTime-1573145462" var endTime string = "endTime1725551537" var expectedResponse = &containerpb.Operation{ Name: name, Zone: zone2, Detail: detail, StatusMessage: statusMessage, SelfLink: selfLink, TargetLink: targetLink, StartTime: startTime, EndTime: endTime, } mockClusterManager.err = nil mockClusterManager.reqs = nil mockClusterManager.resps = append(mockClusterManager.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var request = &containerpb.CompleteIPRotationRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CompleteIPRotation(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockClusterManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestClusterManagerCompleteIPRotationError(t *testing.T) { errCode := codes.PermissionDenied mockClusterManager.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var request = &containerpb.CompleteIPRotationRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CompleteIPRotation(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestClusterManagerSetNodePoolSize(t *testing.T) { var name string = "name3373707" var zone2 string = "zone2-696322977" var detail string = "detail-1335224239" var statusMessage string = "statusMessage-239442758" var selfLink string = "selfLink-1691268851" var targetLink string = "targetLink-2084812312" var startTime string = "startTime-1573145462" var endTime string = "endTime1725551537" var expectedResponse = &containerpb.Operation{ Name: name, Zone: zone2, Detail: detail, StatusMessage: statusMessage, SelfLink: selfLink, TargetLink: targetLink, StartTime: startTime, EndTime: endTime, } mockClusterManager.err = nil mockClusterManager.reqs = nil mockClusterManager.resps = append(mockClusterManager.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var nodePoolId string = "nodePoolId1043384033" var nodeCount int32 = 1539922066 var request = &containerpb.SetNodePoolSizeRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, NodePoolId: nodePoolId, NodeCount: nodeCount, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetNodePoolSize(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockClusterManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestClusterManagerSetNodePoolSizeError(t *testing.T) { errCode := codes.PermissionDenied mockClusterManager.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var nodePoolId string = "nodePoolId1043384033" var nodeCount int32 = 1539922066 var request = &containerpb.SetNodePoolSizeRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, NodePoolId: nodePoolId, NodeCount: nodeCount, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetNodePoolSize(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestClusterManagerSetNetworkPolicy(t *testing.T) { var name string = "name3373707" var zone2 string = "zone2-696322977" var detail string = "detail-1335224239" var statusMessage string = "statusMessage-239442758" var selfLink string = "selfLink-1691268851" var targetLink string = "targetLink-2084812312" var startTime string = "startTime-1573145462" var endTime string = "endTime1725551537" var expectedResponse = &containerpb.Operation{ Name: name, Zone: zone2, Detail: detail, StatusMessage: statusMessage, SelfLink: selfLink, TargetLink: targetLink, StartTime: startTime, EndTime: endTime, } mockClusterManager.err = nil mockClusterManager.reqs = nil mockClusterManager.resps = append(mockClusterManager.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var networkPolicy *containerpb.NetworkPolicy = &containerpb.NetworkPolicy{} var request = &containerpb.SetNetworkPolicyRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, NetworkPolicy: networkPolicy, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetNetworkPolicy(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockClusterManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestClusterManagerSetNetworkPolicyError(t *testing.T) { errCode := codes.PermissionDenied mockClusterManager.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var networkPolicy *containerpb.NetworkPolicy = &containerpb.NetworkPolicy{} var request = &containerpb.SetNetworkPolicyRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, NetworkPolicy: networkPolicy, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetNetworkPolicy(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestClusterManagerSetMaintenancePolicy(t *testing.T) { var name string = "name3373707" var zone2 string = "zone2-696322977" var detail string = "detail-1335224239" var statusMessage string = "statusMessage-239442758" var selfLink string = "selfLink-1691268851" var targetLink string = "targetLink-2084812312" var startTime string = "startTime-1573145462" var endTime string = "endTime1725551537" var expectedResponse = &containerpb.Operation{ Name: name, Zone: zone2, Detail: detail, StatusMessage: statusMessage, SelfLink: selfLink, TargetLink: targetLink, StartTime: startTime, EndTime: endTime, } mockClusterManager.err = nil mockClusterManager.reqs = nil mockClusterManager.resps = append(mockClusterManager.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var maintenancePolicy *containerpb.MaintenancePolicy = &containerpb.MaintenancePolicy{} var request = &containerpb.SetMaintenancePolicyRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, MaintenancePolicy: maintenancePolicy, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetMaintenancePolicy(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockClusterManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestClusterManagerSetMaintenancePolicyError(t *testing.T) { errCode := codes.PermissionDenied mockClusterManager.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var zone string = "zone3744684" var clusterId string = "clusterId240280960" var maintenancePolicy *containerpb.MaintenancePolicy = &containerpb.MaintenancePolicy{} var request = &containerpb.SetMaintenancePolicyRequest{ ProjectId: projectId, Zone: zone, ClusterId: clusterId, MaintenancePolicy: maintenancePolicy, } c, err := NewClusterManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetMaintenancePolicy(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/container/container.go000066400000000000000000000205321356504100700210650ustar00rootroot00000000000000// Copyright 2014 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package container contains a deprecated Google Container Engine client. // // Deprecated: Use cloud.google.com/go/container/apiv1 instead. package container // import "cloud.google.com/go/container" import ( "context" "errors" "fmt" "time" raw "google.golang.org/api/container/v1" "google.golang.org/api/option" htransport "google.golang.org/api/transport/http" ) // Type is the operation type. type Type string const ( // TypeCreate describes that the operation is "create cluster". TypeCreate = Type("createCluster") // TypeDelete describes that the operation is "delete cluster". TypeDelete = Type("deleteCluster") ) // Status is the current status of the operation or resource. type Status string const ( // StatusDone is a status indicating that the resource or operation is in done state. StatusDone = Status("done") // StatusPending is a status indicating that the resource or operation is in pending state. StatusPending = Status("pending") // StatusRunning is a status indicating that the resource or operation is in running state. StatusRunning = Status("running") // StatusError is a status indicating that the resource or operation is in error state. StatusError = Status("error") // StatusProvisioning is a status indicating that the resource or operation is in provisioning state. StatusProvisioning = Status("provisioning") // StatusStopping is a status indicating that the resource or operation is in stopping state. StatusStopping = Status("stopping") ) const prodAddr = "https://container.googleapis.com/" const userAgent = "gcloud-golang-container/20151008" // Client is a Google Container Engine client, which may be used to manage // clusters with a project. It must be constructed via NewClient. type Client struct { projectID string svc *raw.Service } // NewClient creates a new Google Container Engine client. func NewClient(ctx context.Context, projectID string, opts ...option.ClientOption) (*Client, error) { o := []option.ClientOption{ option.WithEndpoint(prodAddr), option.WithScopes(raw.CloudPlatformScope), option.WithUserAgent(userAgent), } o = append(o, opts...) httpClient, endpoint, err := htransport.NewClient(ctx, o...) if err != nil { return nil, fmt.Errorf("dialing: %v", err) } svc, err := raw.New(httpClient) if err != nil { return nil, fmt.Errorf("constructing container client: %v", err) } svc.BasePath = endpoint c := &Client{ projectID: projectID, svc: svc, } return c, nil } // Resource is a Google Container Engine cluster resource. type Resource struct { // Name is the name of this cluster. The name must be unique // within this project and zone, and can be up to 40 characters. Name string // Description is the description of the cluster. Optional. Description string // Zone is the Google Compute Engine zone in which the cluster resides. Zone string // Status is the current status of the cluster. It could either be // StatusError, StatusProvisioning, StatusRunning or StatusStopping. Status Status // Num is the number of the nodes in this cluster resource. Num int64 // APIVersion is the version of the Kubernetes master and kubelets running // in this cluster. Allowed value is 0.4.2, or leave blank to // pick up the latest stable release. APIVersion string // Endpoint is the IP address of this cluster's Kubernetes master. // The endpoint can be accessed at https://username:password@endpoint/. // See Username and Password fields for the username and password information. Endpoint string // Username is the username to use when accessing the Kubernetes master endpoint. Username string // Password is the password to use when accessing the Kubernetes master endpoint. Password string // ContainerIPv4CIDR is the IP addresses of the container pods in // this cluster, in CIDR notation (e.g. 1.2.3.4/29). ContainerIPv4CIDR string // ServicesIPv4CIDR is the IP addresses of the Kubernetes services in this // cluster, in CIDR notation (e.g. 1.2.3.4/29). Service addresses are // always in the 10.0.0.0/16 range. ServicesIPv4CIDR string // MachineType is a Google Compute Engine machine type (e.g. n1-standard-1). // If none set, the default type is used while creating a new cluster. MachineType string // This field is ignored. It was removed from the underlying container API in v1. SourceImage string // Created is the creation time of this cluster. Created time.Time } func resourceFromRaw(c *raw.Cluster) *Resource { if c == nil { return nil } r := &Resource{ Name: c.Name, Description: c.Description, Zone: c.Zone, Status: Status(c.Status), Num: c.CurrentNodeCount, APIVersion: c.InitialClusterVersion, Endpoint: c.Endpoint, Username: c.MasterAuth.Username, Password: c.MasterAuth.Password, ContainerIPv4CIDR: c.ClusterIpv4Cidr, ServicesIPv4CIDR: c.ServicesIpv4Cidr, MachineType: c.NodeConfig.MachineType, } r.Created, _ = time.Parse(time.RFC3339, c.CreateTime) return r } func resourcesFromRaw(c []*raw.Cluster) []*Resource { r := make([]*Resource, len(c)) for i, val := range c { r[i] = resourceFromRaw(val) } return r } // Op represents a Google Container Engine API operation. type Op struct { // Name is the name of the operation. Name string // Zone is the Google Compute Engine zone. Zone string // This field is ignored. It was removed from the underlying container API in v1. TargetURL string // Type is the operation type. It could be either be TypeCreate or TypeDelete. Type Type // Status is the current status of this operation. It could be either // OpDone or OpPending. Status Status } func opFromRaw(o *raw.Operation) *Op { if o == nil { return nil } return &Op{ Name: o.Name, Zone: o.Zone, Type: Type(o.OperationType), Status: Status(o.Status), } } func opsFromRaw(o []*raw.Operation) []*Op { ops := make([]*Op, len(o)) for i, val := range o { ops[i] = opFromRaw(val) } return ops } // Clusters returns a list of cluster resources from the specified zone. // If no zone is specified, it returns all clusters under the user project. func (c *Client) Clusters(ctx context.Context, zone string) ([]*Resource, error) { if zone == "" { zone = "-" } resp, err := c.svc.Projects.Zones.Clusters.List(c.projectID, zone).Do() if err != nil { return nil, err } return resourcesFromRaw(resp.Clusters), nil } // Cluster returns metadata about the specified cluster. func (c *Client) Cluster(ctx context.Context, zone, name string) (*Resource, error) { resp, err := c.svc.Projects.Zones.Clusters.Get(c.projectID, zone, name).Do() if err != nil { return nil, err } return resourceFromRaw(resp), nil } // DeleteCluster deletes a cluster. func (c *Client) DeleteCluster(ctx context.Context, zone, name string) error { _, err := c.svc.Projects.Zones.Clusters.Delete(c.projectID, zone, name).Do() return err } // Operations returns a list of operations from the specified zone. // If no zone is specified, it looks up for all of the operations // that are running under the user's project. func (c *Client) Operations(ctx context.Context, zone string) ([]*Op, error) { if zone == "" { resp, err := c.svc.Projects.Zones.Operations.List(c.projectID, "-").Do() if err != nil { return nil, err } return opsFromRaw(resp.Operations), nil } resp, err := c.svc.Projects.Zones.Operations.List(c.projectID, zone).Do() if err != nil { return nil, err } return opsFromRaw(resp.Operations), nil } // Operation returns an operation. func (c *Client) Operation(ctx context.Context, zone, name string) (*Op, error) { resp, err := c.svc.Projects.Zones.Operations.Get(c.projectID, zone, name).Do() if err != nil { return nil, err } if resp.StatusMessage != "" { return nil, errors.New(resp.StatusMessage) } return opFromRaw(resp), nil } google-cloud-go-0.49.0/containeranalysis/000077500000000000000000000000001356504100700203165ustar00rootroot00000000000000google-cloud-go-0.49.0/containeranalysis/apiv1/000077500000000000000000000000001356504100700213365ustar00rootroot00000000000000google-cloud-go-0.49.0/containeranalysis/apiv1/.repo-metadata.json000066400000000000000000000007331356504100700250350ustar00rootroot00000000000000{ "name": "containeranalysis", "name_pretty": "Container Analysis API", "product_documentation": "https://cloud.google.com/container-registry/docs/container-analysis", "client_documentation": "https://godoc.org/cloud.google.com/go/containeranalysis/apiv1", "release_level": "beta", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "containeranalysis.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/containeranalysis/apiv1/container_analysis_client.go000066400000000000000000000176071356504100700271230ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package containeranalysis import ( "context" "fmt" "net/url" grafeas "cloud.google.com/go/grafeas/apiv1" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" "google.golang.org/api/transport" containeranalysispb "google.golang.org/genproto/googleapis/devtools/containeranalysis/v1" iampb "google.golang.org/genproto/googleapis/iam/v1" "google.golang.org/grpc" "google.golang.org/grpc/metadata" ) // CallOptions contains the retry settings for each method of Client. type CallOptions struct { SetIamPolicy []gax.CallOption GetIamPolicy []gax.CallOption TestIamPermissions []gax.CallOption } func defaultClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("containeranalysis.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), } } func defaultCallOptions() *CallOptions { retry := map[[2]string][]gax.CallOption{} return &CallOptions{ SetIamPolicy: retry[[2]string{"default", "non_idempotent"}], GetIamPolicy: retry[[2]string{"default", "non_idempotent"}], TestIamPermissions: retry[[2]string{"default", "non_idempotent"}], } } // Client is a client for interacting with Container Analysis API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. client containeranalysispb.ContainerAnalysisClient // A pre-crearted grafeas client. grafeasClient *grafeas.Client // The call options for this service. CallOptions *CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewClient creates a new container analysis client. // // Retrieves analysis results of Cloud components such as Docker container // images. The Container Analysis API is an implementation of the // Grafeas (at https://grafeas.io) API. // // Analysis results are stored as a series of occurrences. An Occurrence // contains information about a specific analysis instance on a resource. An // occurrence refers to a Note. A note contains details describing the // analysis and is generally stored in a separate project, called a Provider. // Multiple occurrences can refer to the same note. // // For example, an SSL vulnerability could affect multiple images. In this case, // there would be one note for the vulnerability and an occurrence for each // image with the vulnerability referring to that note. func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultClientOptions(), opts...)...) if err != nil { return nil, err } gc, err := grafeas.NewClient(ctx, append(defaultClientOptions(), opts...)...) if err != nil { return nil, err } c := &Client{ conn: conn, CallOptions: defaultCallOptions(), client: containeranalysispb.NewContainerAnalysisClient(conn), grafeasClient: gc, } c.setGoogleClientInfo() return c, nil } // GetGrafeasClient returns a grafeas client connected to containeranalysis. // // Calling Close on either the grafeas or containeranalysis client will close // the shared connection in both. func (c *Client) GetGrafeasClient() *grafeas.Client { return c.grafeasClient } // Connection returns the client's connection to the API service. func (c *Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *Client) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *Client) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // SetIamPolicy sets the access control policy on the specified note or occurrence. // Requires containeranalysis.notes.setIamPolicy or // containeranalysis.occurrences.setIamPolicy permission if the resource is // a note or an occurrence, respectively. // // The resource takes the format projects/[PROJECT_ID]/notes/[NOTE_ID] for // notes and projects/[PROJECT_ID]/occurrences/[OCCURRENCE_ID] for // occurrences. func (c *Client) SetIamPolicy(ctx context.Context, req *iampb.SetIamPolicyRequest, opts ...gax.CallOption) (*iampb.Policy, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.SetIamPolicy[0:len(c.CallOptions.SetIamPolicy):len(c.CallOptions.SetIamPolicy)], opts...) var resp *iampb.Policy err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.SetIamPolicy(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetIamPolicy gets the access control policy for a note or an occurrence resource. // Requires containeranalysis.notes.setIamPolicy or // containeranalysis.occurrences.setIamPolicy permission if the resource is // a note or occurrence, respectively. // // The resource takes the format projects/[PROJECT_ID]/notes/[NOTE_ID] for // notes and projects/[PROJECT_ID]/occurrences/[OCCURRENCE_ID] for // occurrences. func (c *Client) GetIamPolicy(ctx context.Context, req *iampb.GetIamPolicyRequest, opts ...gax.CallOption) (*iampb.Policy, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetIamPolicy[0:len(c.CallOptions.GetIamPolicy):len(c.CallOptions.GetIamPolicy)], opts...) var resp *iampb.Policy err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetIamPolicy(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // TestIamPermissions returns the permissions that a caller has on the specified note or // occurrence. Requires list permission on the project (for example, // containeranalysis.notes.list). // // The resource takes the format projects/[PROJECT_ID]/notes/[NOTE_ID] for // notes and projects/[PROJECT_ID]/occurrences/[OCCURRENCE_ID] for // occurrences. func (c *Client) TestIamPermissions(ctx context.Context, req *iampb.TestIamPermissionsRequest, opts ...gax.CallOption) (*iampb.TestIamPermissionsResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.TestIamPermissions[0:len(c.CallOptions.TestIamPermissions):len(c.CallOptions.TestIamPermissions)], opts...) var resp *iampb.TestIamPermissionsResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.TestIamPermissions(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } google-cloud-go-0.49.0/containeranalysis/apiv1/container_analysis_client_example_test.go000066400000000000000000000040131356504100700316600ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package containeranalysis_test import ( "context" containeranalysis "cloud.google.com/go/containeranalysis/apiv1" iampb "google.golang.org/genproto/googleapis/iam/v1" ) func ExampleNewClient() { ctx := context.Background() c, err := containeranalysis.NewClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleClient_SetIamPolicy() { ctx := context.Background() c, err := containeranalysis.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &iampb.SetIamPolicyRequest{ // TODO: Fill request struct fields. } resp, err := c.SetIamPolicy(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_GetIamPolicy() { ctx := context.Background() c, err := containeranalysis.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &iampb.GetIamPolicyRequest{ // TODO: Fill request struct fields. } resp, err := c.GetIamPolicy(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_TestIamPermissions() { ctx := context.Background() c, err := containeranalysis.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &iampb.TestIamPermissionsRequest{ // TODO: Fill request struct fields. } resp, err := c.TestIamPermissions(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/containeranalysis/apiv1/doc.go000066400000000000000000000055221356504100700224360ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package containeranalysis is an auto-generated package for the // Container Analysis API. // // NOTE: This package is in beta. It is not stable, and may be subject to changes. // // An implementation of the Grafeas API, which stores, and enables querying // and retrieval of critical metadata about all of your software artifacts. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package containeranalysis // import "cloud.google.com/go/containeranalysis/apiv1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20190708" google-cloud-go-0.49.0/containeranalysis/apiv1/integration_test.go000066400000000000000000000040771356504100700252570ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package containeranalysis_test import ( "context" "fmt" "testing" containeranalysis "cloud.google.com/go/containeranalysis/apiv1" "cloud.google.com/go/internal/testutil" "google.golang.org/api/iterator" grafeaspb "google.golang.org/genproto/googleapis/grafeas/v1" iampb "google.golang.org/genproto/googleapis/iam/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) func TestIntegration(t *testing.T) { if testing.Short() { t.Skip("integration tests skipped in short mode") } ctx := context.Background() c, err := containeranalysis.NewClient(ctx) if err != nil { t.Fatal(err) } defer c.Close() _, err = c.GetIamPolicy(ctx, &iampb.GetIamPolicyRequest{Resource: "some-non-existent-resource"}) // We expect to get an InvalidArgument from the API. If things weren't // wired up properly, we would get something like Internal, Uknown, // Unathenticated, etc. if err != nil && status.Code(err) != codes.InvalidArgument { t.Fatal(err) } } func TestIntegration_GetGrafeasClient(t *testing.T) { if testing.Short() { t.Skip("integration tests skipped in short mode") } ctx := context.Background() cac, err := containeranalysis.NewClient(ctx) if err != nil { t.Fatal(err) } defer cac.Close() gc := cac.GetGrafeasClient() projID := testutil.ProjID() ni := gc.ListNotes(ctx, &grafeaspb.ListNotesRequest{ Parent: fmt.Sprintf("projects/%s", projID), }) for _, err := ni.Next(); err != iterator.Done; _, err = ni.Next() { if err != nil { t.Fatal(err) } } } google-cloud-go-0.49.0/containeranalysis/apiv1/mock_test.go000066400000000000000000000212541356504100700236610ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package containeranalysis import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" "google.golang.org/api/option" containeranalysispb "google.golang.org/genproto/googleapis/devtools/containeranalysis/v1" iampb "google.golang.org/genproto/googleapis/iam/v1" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockContainerAnalysisServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. containeranalysispb.ContainerAnalysisServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockContainerAnalysisServer) SetIamPolicy(ctx context.Context, req *iampb.SetIamPolicyRequest) (*iampb.Policy, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iampb.Policy), nil } func (s *mockContainerAnalysisServer) GetIamPolicy(ctx context.Context, req *iampb.GetIamPolicyRequest) (*iampb.Policy, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iampb.Policy), nil } func (s *mockContainerAnalysisServer) TestIamPermissions(ctx context.Context, req *iampb.TestIamPermissionsRequest) (*iampb.TestIamPermissionsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iampb.TestIamPermissionsResponse), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockContainerAnalysis mockContainerAnalysisServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() containeranalysispb.RegisterContainerAnalysisServer(serv, &mockContainerAnalysis) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestContainerAnalysisSetIamPolicy(t *testing.T) { var version int32 = 351608024 var etag []byte = []byte("21") var expectedResponse = &iampb.Policy{ Version: version, Etag: etag, } mockContainerAnalysis.err = nil mockContainerAnalysis.reqs = nil mockContainerAnalysis.resps = append(mockContainerAnalysis.resps[:0], expectedResponse) var formattedResource string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]") var policy *iampb.Policy = &iampb.Policy{} var request = &iampb.SetIamPolicyRequest{ Resource: formattedResource, Policy: policy, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetIamPolicy(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockContainerAnalysis.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestContainerAnalysisSetIamPolicyError(t *testing.T) { errCode := codes.PermissionDenied mockContainerAnalysis.err = gstatus.Error(errCode, "test error") var formattedResource string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]") var policy *iampb.Policy = &iampb.Policy{} var request = &iampb.SetIamPolicyRequest{ Resource: formattedResource, Policy: policy, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetIamPolicy(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestContainerAnalysisGetIamPolicy(t *testing.T) { var version int32 = 351608024 var etag []byte = []byte("21") var expectedResponse = &iampb.Policy{ Version: version, Etag: etag, } mockContainerAnalysis.err = nil mockContainerAnalysis.reqs = nil mockContainerAnalysis.resps = append(mockContainerAnalysis.resps[:0], expectedResponse) var formattedResource string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]") var request = &iampb.GetIamPolicyRequest{ Resource: formattedResource, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetIamPolicy(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockContainerAnalysis.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestContainerAnalysisGetIamPolicyError(t *testing.T) { errCode := codes.PermissionDenied mockContainerAnalysis.err = gstatus.Error(errCode, "test error") var formattedResource string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]") var request = &iampb.GetIamPolicyRequest{ Resource: formattedResource, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetIamPolicy(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestContainerAnalysisTestIamPermissions(t *testing.T) { var expectedResponse *iampb.TestIamPermissionsResponse = &iampb.TestIamPermissionsResponse{} mockContainerAnalysis.err = nil mockContainerAnalysis.reqs = nil mockContainerAnalysis.resps = append(mockContainerAnalysis.resps[:0], expectedResponse) var formattedResource string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]") var permissions []string = nil var request = &iampb.TestIamPermissionsRequest{ Resource: formattedResource, Permissions: permissions, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.TestIamPermissions(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockContainerAnalysis.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestContainerAnalysisTestIamPermissionsError(t *testing.T) { errCode := codes.PermissionDenied mockContainerAnalysis.err = gstatus.Error(errCode, "test error") var formattedResource string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]") var permissions []string = nil var request = &iampb.TestIamPermissionsRequest{ Resource: formattedResource, Permissions: permissions, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.TestIamPermissions(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/containeranalysis/apiv1beta1/000077500000000000000000000000001356504100700222535ustar00rootroot00000000000000google-cloud-go-0.49.0/containeranalysis/apiv1beta1/.repo-metadata.json000066400000000000000000000007621356504100700257540ustar00rootroot00000000000000{ "name": "containeranalysis", "name_pretty": "Container Analysis API", "product_documentation": "https://cloud.google.com/container-registry/docs/container-analysis", "client_documentation": "https://godoc.org/cloud.google.com/go/containeranalysis/apiv1beta1", "release_level": "beta", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go/containeranalysis", "api_id": "containeranalysis.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/containeranalysis/apiv1beta1/container_analysis_v1_beta1_client.go000066400000000000000000000330501356504100700315100ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package containeranalysis import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" containeranalysispb "google.golang.org/genproto/googleapis/devtools/containeranalysis/v1beta1" iampb "google.golang.org/genproto/googleapis/iam/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // ContainerAnalysisV1Beta1CallOptions contains the retry settings for each method of ContainerAnalysisV1Beta1Client. type ContainerAnalysisV1Beta1CallOptions struct { SetIamPolicy []gax.CallOption GetIamPolicy []gax.CallOption TestIamPermissions []gax.CallOption GetScanConfig []gax.CallOption ListScanConfigs []gax.CallOption UpdateScanConfig []gax.CallOption } func defaultContainerAnalysisV1Beta1ClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("containeranalysis.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultContainerAnalysisV1Beta1CallOptions() *ContainerAnalysisV1Beta1CallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &ContainerAnalysisV1Beta1CallOptions{ SetIamPolicy: retry[[2]string{"default", "non_idempotent"}], GetIamPolicy: retry[[2]string{"default", "non_idempotent"}], TestIamPermissions: retry[[2]string{"default", "non_idempotent"}], GetScanConfig: retry[[2]string{"default", "idempotent"}], ListScanConfigs: retry[[2]string{"default", "idempotent"}], UpdateScanConfig: retry[[2]string{"default", "non_idempotent"}], } } // ContainerAnalysisV1Beta1Client is a client for interacting with Container Analysis API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type ContainerAnalysisV1Beta1Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. containerAnalysisV1Beta1Client containeranalysispb.ContainerAnalysisV1Beta1Client // The call options for this service. CallOptions *ContainerAnalysisV1Beta1CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewContainerAnalysisV1Beta1Client creates a new container analysis v1 beta1 client. // // Retrieves analysis results of Cloud components such as Docker container // images. The Container Analysis API is an implementation of the // Grafeas (at grafeas.io) API. // // Analysis results are stored as a series of occurrences. An Occurrence // contains information about a specific analysis instance on a resource. An // occurrence refers to a Note. A note contains details describing the // analysis and is generally stored in a separate project, called a Provider. // Multiple occurrences can refer to the same note. // // For example, an SSL vulnerability could affect multiple images. In this case, // there would be one note for the vulnerability and an occurrence for each // image with the vulnerability referring to that note. func NewContainerAnalysisV1Beta1Client(ctx context.Context, opts ...option.ClientOption) (*ContainerAnalysisV1Beta1Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultContainerAnalysisV1Beta1ClientOptions(), opts...)...) if err != nil { return nil, err } c := &ContainerAnalysisV1Beta1Client{ conn: conn, CallOptions: defaultContainerAnalysisV1Beta1CallOptions(), containerAnalysisV1Beta1Client: containeranalysispb.NewContainerAnalysisV1Beta1Client(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *ContainerAnalysisV1Beta1Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *ContainerAnalysisV1Beta1Client) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *ContainerAnalysisV1Beta1Client) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // SetIamPolicy sets the access control policy on the specified note or occurrence. // Requires containeranalysis.notes.setIamPolicy or // containeranalysis.occurrences.setIamPolicy permission if the resource is // a note or an occurrence, respectively. // // The resource takes the format projects/[PROJECT_ID]/notes/[NOTE_ID] for // notes and projects/[PROJECT_ID]/occurrences/[OCCURRENCE_ID] for // occurrences. func (c *ContainerAnalysisV1Beta1Client) SetIamPolicy(ctx context.Context, req *iampb.SetIamPolicyRequest, opts ...gax.CallOption) (*iampb.Policy, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.SetIamPolicy[0:len(c.CallOptions.SetIamPolicy):len(c.CallOptions.SetIamPolicy)], opts...) var resp *iampb.Policy err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.containerAnalysisV1Beta1Client.SetIamPolicy(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetIamPolicy gets the access control policy for a note or an occurrence resource. // Requires containeranalysis.notes.setIamPolicy or // containeranalysis.occurrences.setIamPolicy permission if the resource is // a note or occurrence, respectively. // // The resource takes the format projects/[PROJECT_ID]/notes/[NOTE_ID] for // notes and projects/[PROJECT_ID]/occurrences/[OCCURRENCE_ID] for // occurrences. func (c *ContainerAnalysisV1Beta1Client) GetIamPolicy(ctx context.Context, req *iampb.GetIamPolicyRequest, opts ...gax.CallOption) (*iampb.Policy, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetIamPolicy[0:len(c.CallOptions.GetIamPolicy):len(c.CallOptions.GetIamPolicy)], opts...) var resp *iampb.Policy err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.containerAnalysisV1Beta1Client.GetIamPolicy(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // TestIamPermissions returns the permissions that a caller has on the specified note or // occurrence. Requires list permission on the project (for example, // containeranalysis.notes.list). // // The resource takes the format projects/[PROJECT_ID]/notes/[NOTE_ID] for // notes and projects/[PROJECT_ID]/occurrences/[OCCURRENCE_ID] for // occurrences. func (c *ContainerAnalysisV1Beta1Client) TestIamPermissions(ctx context.Context, req *iampb.TestIamPermissionsRequest, opts ...gax.CallOption) (*iampb.TestIamPermissionsResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.TestIamPermissions[0:len(c.CallOptions.TestIamPermissions):len(c.CallOptions.TestIamPermissions)], opts...) var resp *iampb.TestIamPermissionsResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.containerAnalysisV1Beta1Client.TestIamPermissions(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetScanConfig gets the specified scan configuration. func (c *ContainerAnalysisV1Beta1Client) GetScanConfig(ctx context.Context, req *containeranalysispb.GetScanConfigRequest, opts ...gax.CallOption) (*containeranalysispb.ScanConfig, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetScanConfig[0:len(c.CallOptions.GetScanConfig):len(c.CallOptions.GetScanConfig)], opts...) var resp *containeranalysispb.ScanConfig err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.containerAnalysisV1Beta1Client.GetScanConfig(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListScanConfigs lists scan configurations for the specified project. func (c *ContainerAnalysisV1Beta1Client) ListScanConfigs(ctx context.Context, req *containeranalysispb.ListScanConfigsRequest, opts ...gax.CallOption) *ScanConfigIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListScanConfigs[0:len(c.CallOptions.ListScanConfigs):len(c.CallOptions.ListScanConfigs)], opts...) it := &ScanConfigIterator{} req = proto.Clone(req).(*containeranalysispb.ListScanConfigsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*containeranalysispb.ScanConfig, string, error) { var resp *containeranalysispb.ListScanConfigsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.containerAnalysisV1Beta1Client.ListScanConfigs(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.ScanConfigs, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // UpdateScanConfig updates the specified scan configuration. func (c *ContainerAnalysisV1Beta1Client) UpdateScanConfig(ctx context.Context, req *containeranalysispb.UpdateScanConfigRequest, opts ...gax.CallOption) (*containeranalysispb.ScanConfig, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateScanConfig[0:len(c.CallOptions.UpdateScanConfig):len(c.CallOptions.UpdateScanConfig)], opts...) var resp *containeranalysispb.ScanConfig err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.containerAnalysisV1Beta1Client.UpdateScanConfig(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ScanConfigIterator manages a stream of *containeranalysispb.ScanConfig. type ScanConfigIterator struct { items []*containeranalysispb.ScanConfig pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*containeranalysispb.ScanConfig, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *ScanConfigIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *ScanConfigIterator) Next() (*containeranalysispb.ScanConfig, error) { var item *containeranalysispb.ScanConfig if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *ScanConfigIterator) bufLen() int { return len(it.items) } func (it *ScanConfigIterator) takeBuf() interface{} { b := it.items it.items = nil return b } container_analysis_v1_beta1_client_example_test.go000066400000000000000000000072101356504100700342020ustar00rootroot00000000000000google-cloud-go-0.49.0/containeranalysis/apiv1beta1// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package containeranalysis_test import ( "context" containeranalysis "cloud.google.com/go/containeranalysis/apiv1beta1" "google.golang.org/api/iterator" containeranalysispb "google.golang.org/genproto/googleapis/devtools/containeranalysis/v1beta1" iampb "google.golang.org/genproto/googleapis/iam/v1" ) func ExampleNewContainerAnalysisV1Beta1Client() { ctx := context.Background() c, err := containeranalysis.NewContainerAnalysisV1Beta1Client(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleContainerAnalysisV1Beta1Client_SetIamPolicy() { ctx := context.Background() c, err := containeranalysis.NewContainerAnalysisV1Beta1Client(ctx) if err != nil { // TODO: Handle error. } req := &iampb.SetIamPolicyRequest{ // TODO: Fill request struct fields. } resp, err := c.SetIamPolicy(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleContainerAnalysisV1Beta1Client_GetIamPolicy() { ctx := context.Background() c, err := containeranalysis.NewContainerAnalysisV1Beta1Client(ctx) if err != nil { // TODO: Handle error. } req := &iampb.GetIamPolicyRequest{ // TODO: Fill request struct fields. } resp, err := c.GetIamPolicy(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleContainerAnalysisV1Beta1Client_TestIamPermissions() { ctx := context.Background() c, err := containeranalysis.NewContainerAnalysisV1Beta1Client(ctx) if err != nil { // TODO: Handle error. } req := &iampb.TestIamPermissionsRequest{ // TODO: Fill request struct fields. } resp, err := c.TestIamPermissions(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleContainerAnalysisV1Beta1Client_GetScanConfig() { ctx := context.Background() c, err := containeranalysis.NewContainerAnalysisV1Beta1Client(ctx) if err != nil { // TODO: Handle error. } req := &containeranalysispb.GetScanConfigRequest{ // TODO: Fill request struct fields. } resp, err := c.GetScanConfig(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleContainerAnalysisV1Beta1Client_ListScanConfigs() { ctx := context.Background() c, err := containeranalysis.NewContainerAnalysisV1Beta1Client(ctx) if err != nil { // TODO: Handle error. } req := &containeranalysispb.ListScanConfigsRequest{ // TODO: Fill request struct fields. } it := c.ListScanConfigs(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleContainerAnalysisV1Beta1Client_UpdateScanConfig() { ctx := context.Background() c, err := containeranalysis.NewContainerAnalysisV1Beta1Client(ctx) if err != nil { // TODO: Handle error. } req := &containeranalysispb.UpdateScanConfigRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateScanConfig(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/containeranalysis/apiv1beta1/doc.go000066400000000000000000000055321356504100700233540ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package containeranalysis is an auto-generated package for the // Container Analysis API. // // NOTE: This package is in beta. It is not stable, and may be subject to changes. // // An implementation of the Grafeas API, which stores, and enables querying // and // retrieval of critical metadata about all of your software artifacts. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package containeranalysis // import "cloud.google.com/go/containeranalysis/apiv1beta1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191115" google-cloud-go-0.49.0/containeranalysis/apiv1beta1/grafeas_v1_beta1_client.go000066400000000000000000000566271356504100700272520ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package containeranalysis import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" grafeaspb "google.golang.org/genproto/googleapis/devtools/containeranalysis/v1beta1/grafeas" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // GrafeasV1Beta1CallOptions contains the retry settings for each method of GrafeasV1Beta1Client. type GrafeasV1Beta1CallOptions struct { GetOccurrence []gax.CallOption ListOccurrences []gax.CallOption DeleteOccurrence []gax.CallOption CreateOccurrence []gax.CallOption BatchCreateOccurrences []gax.CallOption UpdateOccurrence []gax.CallOption GetOccurrenceNote []gax.CallOption GetNote []gax.CallOption ListNotes []gax.CallOption DeleteNote []gax.CallOption CreateNote []gax.CallOption BatchCreateNotes []gax.CallOption UpdateNote []gax.CallOption ListNoteOccurrences []gax.CallOption GetVulnerabilityOccurrencesSummary []gax.CallOption } func defaultGrafeasV1Beta1ClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("containeranalysis.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultGrafeasV1Beta1CallOptions() *GrafeasV1Beta1CallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &GrafeasV1Beta1CallOptions{ GetOccurrence: retry[[2]string{"default", "idempotent"}], ListOccurrences: retry[[2]string{"default", "idempotent"}], DeleteOccurrence: retry[[2]string{"default", "idempotent"}], CreateOccurrence: retry[[2]string{"default", "non_idempotent"}], BatchCreateOccurrences: retry[[2]string{"default", "non_idempotent"}], UpdateOccurrence: retry[[2]string{"default", "non_idempotent"}], GetOccurrenceNote: retry[[2]string{"default", "idempotent"}], GetNote: retry[[2]string{"default", "idempotent"}], ListNotes: retry[[2]string{"default", "idempotent"}], DeleteNote: retry[[2]string{"default", "idempotent"}], CreateNote: retry[[2]string{"default", "non_idempotent"}], BatchCreateNotes: retry[[2]string{"default", "non_idempotent"}], UpdateNote: retry[[2]string{"default", "non_idempotent"}], ListNoteOccurrences: retry[[2]string{"default", "idempotent"}], GetVulnerabilityOccurrencesSummary: retry[[2]string{"default", "idempotent"}], } } // GrafeasV1Beta1Client is a client for interacting with Container Analysis API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type GrafeasV1Beta1Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. grafeasV1Beta1Client grafeaspb.GrafeasV1Beta1Client // The call options for this service. CallOptions *GrafeasV1Beta1CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewGrafeasV1Beta1Client creates a new grafeas v1 beta1 client. // // Grafeas (at grafeas.io) API. // // Retrieves analysis results of Cloud components such as Docker container // images. // // Analysis results are stored as a series of occurrences. An Occurrence // contains information about a specific analysis instance on a resource. An // occurrence refers to a Note. A note contains details describing the // analysis and is generally stored in a separate project, called a Provider. // Multiple occurrences can refer to the same note. // // For example, an SSL vulnerability could affect multiple images. In this case, // there would be one note for the vulnerability and an occurrence for each // image with the vulnerability referring to that note. func NewGrafeasV1Beta1Client(ctx context.Context, opts ...option.ClientOption) (*GrafeasV1Beta1Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultGrafeasV1Beta1ClientOptions(), opts...)...) if err != nil { return nil, err } c := &GrafeasV1Beta1Client{ conn: conn, CallOptions: defaultGrafeasV1Beta1CallOptions(), grafeasV1Beta1Client: grafeaspb.NewGrafeasV1Beta1Client(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *GrafeasV1Beta1Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *GrafeasV1Beta1Client) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *GrafeasV1Beta1Client) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // GetOccurrence gets the specified occurrence. func (c *GrafeasV1Beta1Client) GetOccurrence(ctx context.Context, req *grafeaspb.GetOccurrenceRequest, opts ...gax.CallOption) (*grafeaspb.Occurrence, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetOccurrence[0:len(c.CallOptions.GetOccurrence):len(c.CallOptions.GetOccurrence)], opts...) var resp *grafeaspb.Occurrence err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.grafeasV1Beta1Client.GetOccurrence(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListOccurrences lists occurrences for the specified project. func (c *GrafeasV1Beta1Client) ListOccurrences(ctx context.Context, req *grafeaspb.ListOccurrencesRequest, opts ...gax.CallOption) *OccurrenceIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListOccurrences[0:len(c.CallOptions.ListOccurrences):len(c.CallOptions.ListOccurrences)], opts...) it := &OccurrenceIterator{} req = proto.Clone(req).(*grafeaspb.ListOccurrencesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*grafeaspb.Occurrence, string, error) { var resp *grafeaspb.ListOccurrencesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.grafeasV1Beta1Client.ListOccurrences(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Occurrences, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // DeleteOccurrence deletes the specified occurrence. For example, use this method to delete an // occurrence when the occurrence is no longer applicable for the given // resource. func (c *GrafeasV1Beta1Client) DeleteOccurrence(ctx context.Context, req *grafeaspb.DeleteOccurrenceRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteOccurrence[0:len(c.CallOptions.DeleteOccurrence):len(c.CallOptions.DeleteOccurrence)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.grafeasV1Beta1Client.DeleteOccurrence(ctx, req, settings.GRPC...) return err }, opts...) return err } // CreateOccurrence creates a new occurrence. func (c *GrafeasV1Beta1Client) CreateOccurrence(ctx context.Context, req *grafeaspb.CreateOccurrenceRequest, opts ...gax.CallOption) (*grafeaspb.Occurrence, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateOccurrence[0:len(c.CallOptions.CreateOccurrence):len(c.CallOptions.CreateOccurrence)], opts...) var resp *grafeaspb.Occurrence err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.grafeasV1Beta1Client.CreateOccurrence(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // BatchCreateOccurrences creates new occurrences in batch. func (c *GrafeasV1Beta1Client) BatchCreateOccurrences(ctx context.Context, req *grafeaspb.BatchCreateOccurrencesRequest, opts ...gax.CallOption) (*grafeaspb.BatchCreateOccurrencesResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.BatchCreateOccurrences[0:len(c.CallOptions.BatchCreateOccurrences):len(c.CallOptions.BatchCreateOccurrences)], opts...) var resp *grafeaspb.BatchCreateOccurrencesResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.grafeasV1Beta1Client.BatchCreateOccurrences(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateOccurrence updates the specified occurrence. func (c *GrafeasV1Beta1Client) UpdateOccurrence(ctx context.Context, req *grafeaspb.UpdateOccurrenceRequest, opts ...gax.CallOption) (*grafeaspb.Occurrence, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateOccurrence[0:len(c.CallOptions.UpdateOccurrence):len(c.CallOptions.UpdateOccurrence)], opts...) var resp *grafeaspb.Occurrence err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.grafeasV1Beta1Client.UpdateOccurrence(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetOccurrenceNote gets the note attached to the specified occurrence. Consumer projects can // use this method to get a note that belongs to a provider project. func (c *GrafeasV1Beta1Client) GetOccurrenceNote(ctx context.Context, req *grafeaspb.GetOccurrenceNoteRequest, opts ...gax.CallOption) (*grafeaspb.Note, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetOccurrenceNote[0:len(c.CallOptions.GetOccurrenceNote):len(c.CallOptions.GetOccurrenceNote)], opts...) var resp *grafeaspb.Note err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.grafeasV1Beta1Client.GetOccurrenceNote(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetNote gets the specified note. func (c *GrafeasV1Beta1Client) GetNote(ctx context.Context, req *grafeaspb.GetNoteRequest, opts ...gax.CallOption) (*grafeaspb.Note, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetNote[0:len(c.CallOptions.GetNote):len(c.CallOptions.GetNote)], opts...) var resp *grafeaspb.Note err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.grafeasV1Beta1Client.GetNote(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListNotes lists notes for the specified project. func (c *GrafeasV1Beta1Client) ListNotes(ctx context.Context, req *grafeaspb.ListNotesRequest, opts ...gax.CallOption) *NoteIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListNotes[0:len(c.CallOptions.ListNotes):len(c.CallOptions.ListNotes)], opts...) it := &NoteIterator{} req = proto.Clone(req).(*grafeaspb.ListNotesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*grafeaspb.Note, string, error) { var resp *grafeaspb.ListNotesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.grafeasV1Beta1Client.ListNotes(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Notes, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // DeleteNote deletes the specified note. func (c *GrafeasV1Beta1Client) DeleteNote(ctx context.Context, req *grafeaspb.DeleteNoteRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteNote[0:len(c.CallOptions.DeleteNote):len(c.CallOptions.DeleteNote)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.grafeasV1Beta1Client.DeleteNote(ctx, req, settings.GRPC...) return err }, opts...) return err } // CreateNote creates a new note. func (c *GrafeasV1Beta1Client) CreateNote(ctx context.Context, req *grafeaspb.CreateNoteRequest, opts ...gax.CallOption) (*grafeaspb.Note, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateNote[0:len(c.CallOptions.CreateNote):len(c.CallOptions.CreateNote)], opts...) var resp *grafeaspb.Note err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.grafeasV1Beta1Client.CreateNote(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // BatchCreateNotes creates new notes in batch. func (c *GrafeasV1Beta1Client) BatchCreateNotes(ctx context.Context, req *grafeaspb.BatchCreateNotesRequest, opts ...gax.CallOption) (*grafeaspb.BatchCreateNotesResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.BatchCreateNotes[0:len(c.CallOptions.BatchCreateNotes):len(c.CallOptions.BatchCreateNotes)], opts...) var resp *grafeaspb.BatchCreateNotesResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.grafeasV1Beta1Client.BatchCreateNotes(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateNote updates the specified note. func (c *GrafeasV1Beta1Client) UpdateNote(ctx context.Context, req *grafeaspb.UpdateNoteRequest, opts ...gax.CallOption) (*grafeaspb.Note, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateNote[0:len(c.CallOptions.UpdateNote):len(c.CallOptions.UpdateNote)], opts...) var resp *grafeaspb.Note err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.grafeasV1Beta1Client.UpdateNote(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListNoteOccurrences lists occurrences referencing the specified note. Provider projects can use // this method to get all occurrences across consumer projects referencing the // specified note. func (c *GrafeasV1Beta1Client) ListNoteOccurrences(ctx context.Context, req *grafeaspb.ListNoteOccurrencesRequest, opts ...gax.CallOption) *OccurrenceIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListNoteOccurrences[0:len(c.CallOptions.ListNoteOccurrences):len(c.CallOptions.ListNoteOccurrences)], opts...) it := &OccurrenceIterator{} req = proto.Clone(req).(*grafeaspb.ListNoteOccurrencesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*grafeaspb.Occurrence, string, error) { var resp *grafeaspb.ListNoteOccurrencesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.grafeasV1Beta1Client.ListNoteOccurrences(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Occurrences, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetVulnerabilityOccurrencesSummary gets a summary of the number and severity of occurrences. func (c *GrafeasV1Beta1Client) GetVulnerabilityOccurrencesSummary(ctx context.Context, req *grafeaspb.GetVulnerabilityOccurrencesSummaryRequest, opts ...gax.CallOption) (*grafeaspb.VulnerabilityOccurrencesSummary, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetVulnerabilityOccurrencesSummary[0:len(c.CallOptions.GetVulnerabilityOccurrencesSummary):len(c.CallOptions.GetVulnerabilityOccurrencesSummary)], opts...) var resp *grafeaspb.VulnerabilityOccurrencesSummary err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.grafeasV1Beta1Client.GetVulnerabilityOccurrencesSummary(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // NoteIterator manages a stream of *grafeaspb.Note. type NoteIterator struct { items []*grafeaspb.Note pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*grafeaspb.Note, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *NoteIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *NoteIterator) Next() (*grafeaspb.Note, error) { var item *grafeaspb.Note if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *NoteIterator) bufLen() int { return len(it.items) } func (it *NoteIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // OccurrenceIterator manages a stream of *grafeaspb.Occurrence. type OccurrenceIterator struct { items []*grafeaspb.Occurrence pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*grafeaspb.Occurrence, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *OccurrenceIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *OccurrenceIterator) Next() (*grafeaspb.Occurrence, error) { var item *grafeaspb.Occurrence if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *OccurrenceIterator) bufLen() int { return len(it.items) } func (it *OccurrenceIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/containeranalysis/apiv1beta1/grafeas_v1_beta1_client_example_test.go000066400000000000000000000157261356504100700320170ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package containeranalysis_test import ( "context" containeranalysis "cloud.google.com/go/containeranalysis/apiv1beta1" "google.golang.org/api/iterator" grafeaspb "google.golang.org/genproto/googleapis/devtools/containeranalysis/v1beta1/grafeas" ) func ExampleNewGrafeasV1Beta1Client() { ctx := context.Background() c, err := containeranalysis.NewGrafeasV1Beta1Client(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleGrafeasV1Beta1Client_GetOccurrence() { ctx := context.Background() c, err := containeranalysis.NewGrafeasV1Beta1Client(ctx) if err != nil { // TODO: Handle error. } req := &grafeaspb.GetOccurrenceRequest{ // TODO: Fill request struct fields. } resp, err := c.GetOccurrence(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleGrafeasV1Beta1Client_ListOccurrences() { ctx := context.Background() c, err := containeranalysis.NewGrafeasV1Beta1Client(ctx) if err != nil { // TODO: Handle error. } req := &grafeaspb.ListOccurrencesRequest{ // TODO: Fill request struct fields. } it := c.ListOccurrences(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleGrafeasV1Beta1Client_DeleteOccurrence() { ctx := context.Background() c, err := containeranalysis.NewGrafeasV1Beta1Client(ctx) if err != nil { // TODO: Handle error. } req := &grafeaspb.DeleteOccurrenceRequest{ // TODO: Fill request struct fields. } err = c.DeleteOccurrence(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleGrafeasV1Beta1Client_CreateOccurrence() { ctx := context.Background() c, err := containeranalysis.NewGrafeasV1Beta1Client(ctx) if err != nil { // TODO: Handle error. } req := &grafeaspb.CreateOccurrenceRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateOccurrence(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleGrafeasV1Beta1Client_BatchCreateOccurrences() { ctx := context.Background() c, err := containeranalysis.NewGrafeasV1Beta1Client(ctx) if err != nil { // TODO: Handle error. } req := &grafeaspb.BatchCreateOccurrencesRequest{ // TODO: Fill request struct fields. } resp, err := c.BatchCreateOccurrences(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleGrafeasV1Beta1Client_UpdateOccurrence() { ctx := context.Background() c, err := containeranalysis.NewGrafeasV1Beta1Client(ctx) if err != nil { // TODO: Handle error. } req := &grafeaspb.UpdateOccurrenceRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateOccurrence(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleGrafeasV1Beta1Client_GetOccurrenceNote() { ctx := context.Background() c, err := containeranalysis.NewGrafeasV1Beta1Client(ctx) if err != nil { // TODO: Handle error. } req := &grafeaspb.GetOccurrenceNoteRequest{ // TODO: Fill request struct fields. } resp, err := c.GetOccurrenceNote(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleGrafeasV1Beta1Client_GetNote() { ctx := context.Background() c, err := containeranalysis.NewGrafeasV1Beta1Client(ctx) if err != nil { // TODO: Handle error. } req := &grafeaspb.GetNoteRequest{ // TODO: Fill request struct fields. } resp, err := c.GetNote(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleGrafeasV1Beta1Client_ListNotes() { ctx := context.Background() c, err := containeranalysis.NewGrafeasV1Beta1Client(ctx) if err != nil { // TODO: Handle error. } req := &grafeaspb.ListNotesRequest{ // TODO: Fill request struct fields. } it := c.ListNotes(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleGrafeasV1Beta1Client_DeleteNote() { ctx := context.Background() c, err := containeranalysis.NewGrafeasV1Beta1Client(ctx) if err != nil { // TODO: Handle error. } req := &grafeaspb.DeleteNoteRequest{ // TODO: Fill request struct fields. } err = c.DeleteNote(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleGrafeasV1Beta1Client_CreateNote() { ctx := context.Background() c, err := containeranalysis.NewGrafeasV1Beta1Client(ctx) if err != nil { // TODO: Handle error. } req := &grafeaspb.CreateNoteRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateNote(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleGrafeasV1Beta1Client_BatchCreateNotes() { ctx := context.Background() c, err := containeranalysis.NewGrafeasV1Beta1Client(ctx) if err != nil { // TODO: Handle error. } req := &grafeaspb.BatchCreateNotesRequest{ // TODO: Fill request struct fields. } resp, err := c.BatchCreateNotes(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleGrafeasV1Beta1Client_UpdateNote() { ctx := context.Background() c, err := containeranalysis.NewGrafeasV1Beta1Client(ctx) if err != nil { // TODO: Handle error. } req := &grafeaspb.UpdateNoteRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateNote(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleGrafeasV1Beta1Client_ListNoteOccurrences() { ctx := context.Background() c, err := containeranalysis.NewGrafeasV1Beta1Client(ctx) if err != nil { // TODO: Handle error. } req := &grafeaspb.ListNoteOccurrencesRequest{ // TODO: Fill request struct fields. } it := c.ListNoteOccurrences(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleGrafeasV1Beta1Client_GetVulnerabilityOccurrencesSummary() { ctx := context.Background() c, err := containeranalysis.NewGrafeasV1Beta1Client(ctx) if err != nil { // TODO: Handle error. } req := &grafeaspb.GetVulnerabilityOccurrencesSummaryRequest{ // TODO: Fill request struct fields. } resp, err := c.GetVulnerabilityOccurrencesSummary(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/containeranalysis/apiv1beta1/mock_test.go000066400000000000000000001461201356504100700245760ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package containeranalysis import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" "google.golang.org/api/option" containeranalysispb "google.golang.org/genproto/googleapis/devtools/containeranalysis/v1beta1" grafeaspb "google.golang.org/genproto/googleapis/devtools/containeranalysis/v1beta1/grafeas" iampb "google.golang.org/genproto/googleapis/iam/v1" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockContainerAnalysisV1Beta1Server struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. containeranalysispb.ContainerAnalysisV1Beta1Server reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockContainerAnalysisV1Beta1Server) SetIamPolicy(ctx context.Context, req *iampb.SetIamPolicyRequest) (*iampb.Policy, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iampb.Policy), nil } func (s *mockContainerAnalysisV1Beta1Server) GetIamPolicy(ctx context.Context, req *iampb.GetIamPolicyRequest) (*iampb.Policy, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iampb.Policy), nil } func (s *mockContainerAnalysisV1Beta1Server) TestIamPermissions(ctx context.Context, req *iampb.TestIamPermissionsRequest) (*iampb.TestIamPermissionsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iampb.TestIamPermissionsResponse), nil } func (s *mockContainerAnalysisV1Beta1Server) GetScanConfig(ctx context.Context, req *containeranalysispb.GetScanConfigRequest) (*containeranalysispb.ScanConfig, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*containeranalysispb.ScanConfig), nil } func (s *mockContainerAnalysisV1Beta1Server) ListScanConfigs(ctx context.Context, req *containeranalysispb.ListScanConfigsRequest) (*containeranalysispb.ListScanConfigsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*containeranalysispb.ListScanConfigsResponse), nil } func (s *mockContainerAnalysisV1Beta1Server) UpdateScanConfig(ctx context.Context, req *containeranalysispb.UpdateScanConfigRequest) (*containeranalysispb.ScanConfig, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*containeranalysispb.ScanConfig), nil } type mockGrafeasV1Beta1Server struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. grafeaspb.GrafeasV1Beta1Server reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockGrafeasV1Beta1Server) GetOccurrence(ctx context.Context, req *grafeaspb.GetOccurrenceRequest) (*grafeaspb.Occurrence, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*grafeaspb.Occurrence), nil } func (s *mockGrafeasV1Beta1Server) ListOccurrences(ctx context.Context, req *grafeaspb.ListOccurrencesRequest) (*grafeaspb.ListOccurrencesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*grafeaspb.ListOccurrencesResponse), nil } func (s *mockGrafeasV1Beta1Server) DeleteOccurrence(ctx context.Context, req *grafeaspb.DeleteOccurrenceRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockGrafeasV1Beta1Server) CreateOccurrence(ctx context.Context, req *grafeaspb.CreateOccurrenceRequest) (*grafeaspb.Occurrence, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*grafeaspb.Occurrence), nil } func (s *mockGrafeasV1Beta1Server) BatchCreateOccurrences(ctx context.Context, req *grafeaspb.BatchCreateOccurrencesRequest) (*grafeaspb.BatchCreateOccurrencesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*grafeaspb.BatchCreateOccurrencesResponse), nil } func (s *mockGrafeasV1Beta1Server) UpdateOccurrence(ctx context.Context, req *grafeaspb.UpdateOccurrenceRequest) (*grafeaspb.Occurrence, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*grafeaspb.Occurrence), nil } func (s *mockGrafeasV1Beta1Server) GetOccurrenceNote(ctx context.Context, req *grafeaspb.GetOccurrenceNoteRequest) (*grafeaspb.Note, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*grafeaspb.Note), nil } func (s *mockGrafeasV1Beta1Server) GetNote(ctx context.Context, req *grafeaspb.GetNoteRequest) (*grafeaspb.Note, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*grafeaspb.Note), nil } func (s *mockGrafeasV1Beta1Server) ListNotes(ctx context.Context, req *grafeaspb.ListNotesRequest) (*grafeaspb.ListNotesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*grafeaspb.ListNotesResponse), nil } func (s *mockGrafeasV1Beta1Server) DeleteNote(ctx context.Context, req *grafeaspb.DeleteNoteRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockGrafeasV1Beta1Server) CreateNote(ctx context.Context, req *grafeaspb.CreateNoteRequest) (*grafeaspb.Note, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*grafeaspb.Note), nil } func (s *mockGrafeasV1Beta1Server) BatchCreateNotes(ctx context.Context, req *grafeaspb.BatchCreateNotesRequest) (*grafeaspb.BatchCreateNotesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*grafeaspb.BatchCreateNotesResponse), nil } func (s *mockGrafeasV1Beta1Server) UpdateNote(ctx context.Context, req *grafeaspb.UpdateNoteRequest) (*grafeaspb.Note, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*grafeaspb.Note), nil } func (s *mockGrafeasV1Beta1Server) ListNoteOccurrences(ctx context.Context, req *grafeaspb.ListNoteOccurrencesRequest) (*grafeaspb.ListNoteOccurrencesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*grafeaspb.ListNoteOccurrencesResponse), nil } func (s *mockGrafeasV1Beta1Server) GetVulnerabilityOccurrencesSummary(ctx context.Context, req *grafeaspb.GetVulnerabilityOccurrencesSummaryRequest) (*grafeaspb.VulnerabilityOccurrencesSummary, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*grafeaspb.VulnerabilityOccurrencesSummary), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockContainerAnalysisV1Beta1 mockContainerAnalysisV1Beta1Server mockGrafeasV1Beta1 mockGrafeasV1Beta1Server ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() containeranalysispb.RegisterContainerAnalysisV1Beta1Server(serv, &mockContainerAnalysisV1Beta1) grafeaspb.RegisterGrafeasV1Beta1Server(serv, &mockGrafeasV1Beta1) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestContainerAnalysisV1Beta1SetIamPolicy(t *testing.T) { var version int32 = 351608024 var etag []byte = []byte("21") var expectedResponse = &iampb.Policy{ Version: version, Etag: etag, } mockContainerAnalysisV1Beta1.err = nil mockContainerAnalysisV1Beta1.reqs = nil mockContainerAnalysisV1Beta1.resps = append(mockContainerAnalysisV1Beta1.resps[:0], expectedResponse) var formattedResource string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]") var policy *iampb.Policy = &iampb.Policy{} var request = &iampb.SetIamPolicyRequest{ Resource: formattedResource, Policy: policy, } c, err := NewContainerAnalysisV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetIamPolicy(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockContainerAnalysisV1Beta1.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestContainerAnalysisV1Beta1SetIamPolicyError(t *testing.T) { errCode := codes.PermissionDenied mockContainerAnalysisV1Beta1.err = gstatus.Error(errCode, "test error") var formattedResource string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]") var policy *iampb.Policy = &iampb.Policy{} var request = &iampb.SetIamPolicyRequest{ Resource: formattedResource, Policy: policy, } c, err := NewContainerAnalysisV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetIamPolicy(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestContainerAnalysisV1Beta1GetIamPolicy(t *testing.T) { var version int32 = 351608024 var etag []byte = []byte("21") var expectedResponse = &iampb.Policy{ Version: version, Etag: etag, } mockContainerAnalysisV1Beta1.err = nil mockContainerAnalysisV1Beta1.reqs = nil mockContainerAnalysisV1Beta1.resps = append(mockContainerAnalysisV1Beta1.resps[:0], expectedResponse) var formattedResource string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]") var request = &iampb.GetIamPolicyRequest{ Resource: formattedResource, } c, err := NewContainerAnalysisV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetIamPolicy(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockContainerAnalysisV1Beta1.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestContainerAnalysisV1Beta1GetIamPolicyError(t *testing.T) { errCode := codes.PermissionDenied mockContainerAnalysisV1Beta1.err = gstatus.Error(errCode, "test error") var formattedResource string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]") var request = &iampb.GetIamPolicyRequest{ Resource: formattedResource, } c, err := NewContainerAnalysisV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetIamPolicy(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestContainerAnalysisV1Beta1TestIamPermissions(t *testing.T) { var expectedResponse *iampb.TestIamPermissionsResponse = &iampb.TestIamPermissionsResponse{} mockContainerAnalysisV1Beta1.err = nil mockContainerAnalysisV1Beta1.reqs = nil mockContainerAnalysisV1Beta1.resps = append(mockContainerAnalysisV1Beta1.resps[:0], expectedResponse) var formattedResource string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]") var permissions []string = nil var request = &iampb.TestIamPermissionsRequest{ Resource: formattedResource, Permissions: permissions, } c, err := NewContainerAnalysisV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.TestIamPermissions(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockContainerAnalysisV1Beta1.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestContainerAnalysisV1Beta1TestIamPermissionsError(t *testing.T) { errCode := codes.PermissionDenied mockContainerAnalysisV1Beta1.err = gstatus.Error(errCode, "test error") var formattedResource string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]") var permissions []string = nil var request = &iampb.TestIamPermissionsRequest{ Resource: formattedResource, Permissions: permissions, } c, err := NewContainerAnalysisV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.TestIamPermissions(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestContainerAnalysisV1Beta1GetScanConfig(t *testing.T) { var name2 string = "name2-1052831874" var description string = "description-1724546052" var enabled bool = false var expectedResponse = &containeranalysispb.ScanConfig{ Name: name2, Description: description, Enabled: enabled, } mockContainerAnalysisV1Beta1.err = nil mockContainerAnalysisV1Beta1.reqs = nil mockContainerAnalysisV1Beta1.resps = append(mockContainerAnalysisV1Beta1.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/scanConfigs/%s", "[PROJECT]", "[SCAN_CONFIG]") var request = &containeranalysispb.GetScanConfigRequest{ Name: formattedName, } c, err := NewContainerAnalysisV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetScanConfig(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockContainerAnalysisV1Beta1.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestContainerAnalysisV1Beta1GetScanConfigError(t *testing.T) { errCode := codes.PermissionDenied mockContainerAnalysisV1Beta1.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/scanConfigs/%s", "[PROJECT]", "[SCAN_CONFIG]") var request = &containeranalysispb.GetScanConfigRequest{ Name: formattedName, } c, err := NewContainerAnalysisV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetScanConfig(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestContainerAnalysisV1Beta1ListScanConfigs(t *testing.T) { var nextPageToken string = "" var scanConfigsElement *containeranalysispb.ScanConfig = &containeranalysispb.ScanConfig{} var scanConfigs = []*containeranalysispb.ScanConfig{scanConfigsElement} var expectedResponse = &containeranalysispb.ListScanConfigsResponse{ NextPageToken: nextPageToken, ScanConfigs: scanConfigs, } mockContainerAnalysisV1Beta1.err = nil mockContainerAnalysisV1Beta1.reqs = nil mockContainerAnalysisV1Beta1.resps = append(mockContainerAnalysisV1Beta1.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &containeranalysispb.ListScanConfigsRequest{ Parent: formattedParent, } c, err := NewContainerAnalysisV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListScanConfigs(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockContainerAnalysisV1Beta1.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.ScanConfigs[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestContainerAnalysisV1Beta1ListScanConfigsError(t *testing.T) { errCode := codes.PermissionDenied mockContainerAnalysisV1Beta1.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &containeranalysispb.ListScanConfigsRequest{ Parent: formattedParent, } c, err := NewContainerAnalysisV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListScanConfigs(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestContainerAnalysisV1Beta1UpdateScanConfig(t *testing.T) { var name2 string = "name2-1052831874" var description string = "description-1724546052" var enabled bool = false var expectedResponse = &containeranalysispb.ScanConfig{ Name: name2, Description: description, Enabled: enabled, } mockContainerAnalysisV1Beta1.err = nil mockContainerAnalysisV1Beta1.reqs = nil mockContainerAnalysisV1Beta1.resps = append(mockContainerAnalysisV1Beta1.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/scanConfigs/%s", "[PROJECT]", "[SCAN_CONFIG]") var scanConfig *containeranalysispb.ScanConfig = &containeranalysispb.ScanConfig{} var request = &containeranalysispb.UpdateScanConfigRequest{ Name: formattedName, ScanConfig: scanConfig, } c, err := NewContainerAnalysisV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateScanConfig(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockContainerAnalysisV1Beta1.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestContainerAnalysisV1Beta1UpdateScanConfigError(t *testing.T) { errCode := codes.PermissionDenied mockContainerAnalysisV1Beta1.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/scanConfigs/%s", "[PROJECT]", "[SCAN_CONFIG]") var scanConfig *containeranalysispb.ScanConfig = &containeranalysispb.ScanConfig{} var request = &containeranalysispb.UpdateScanConfigRequest{ Name: formattedName, ScanConfig: scanConfig, } c, err := NewContainerAnalysisV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateScanConfig(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestGrafeasV1Beta1GetOccurrence(t *testing.T) { var name2 string = "name2-1052831874" var noteName string = "noteName1780787896" var remediation string = "remediation779381797" var expectedResponse = &grafeaspb.Occurrence{ Name: name2, NoteName: noteName, Remediation: remediation, } mockGrafeasV1Beta1.err = nil mockGrafeasV1Beta1.reqs = nil mockGrafeasV1Beta1.resps = append(mockGrafeasV1Beta1.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/occurrences/%s", "[PROJECT]", "[OCCURRENCE]") var request = &grafeaspb.GetOccurrenceRequest{ Name: formattedName, } c, err := NewGrafeasV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetOccurrence(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockGrafeasV1Beta1.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestGrafeasV1Beta1GetOccurrenceError(t *testing.T) { errCode := codes.PermissionDenied mockGrafeasV1Beta1.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/occurrences/%s", "[PROJECT]", "[OCCURRENCE]") var request = &grafeaspb.GetOccurrenceRequest{ Name: formattedName, } c, err := NewGrafeasV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetOccurrence(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestGrafeasV1Beta1ListOccurrences(t *testing.T) { var nextPageToken string = "" var occurrencesElement *grafeaspb.Occurrence = &grafeaspb.Occurrence{} var occurrences = []*grafeaspb.Occurrence{occurrencesElement} var expectedResponse = &grafeaspb.ListOccurrencesResponse{ NextPageToken: nextPageToken, Occurrences: occurrences, } mockGrafeasV1Beta1.err = nil mockGrafeasV1Beta1.reqs = nil mockGrafeasV1Beta1.resps = append(mockGrafeasV1Beta1.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &grafeaspb.ListOccurrencesRequest{ Parent: formattedParent, } c, err := NewGrafeasV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListOccurrences(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockGrafeasV1Beta1.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Occurrences[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestGrafeasV1Beta1ListOccurrencesError(t *testing.T) { errCode := codes.PermissionDenied mockGrafeasV1Beta1.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &grafeaspb.ListOccurrencesRequest{ Parent: formattedParent, } c, err := NewGrafeasV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListOccurrences(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestGrafeasV1Beta1DeleteOccurrence(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockGrafeasV1Beta1.err = nil mockGrafeasV1Beta1.reqs = nil mockGrafeasV1Beta1.resps = append(mockGrafeasV1Beta1.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/occurrences/%s", "[PROJECT]", "[OCCURRENCE]") var request = &grafeaspb.DeleteOccurrenceRequest{ Name: formattedName, } c, err := NewGrafeasV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteOccurrence(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockGrafeasV1Beta1.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestGrafeasV1Beta1DeleteOccurrenceError(t *testing.T) { errCode := codes.PermissionDenied mockGrafeasV1Beta1.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/occurrences/%s", "[PROJECT]", "[OCCURRENCE]") var request = &grafeaspb.DeleteOccurrenceRequest{ Name: formattedName, } c, err := NewGrafeasV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteOccurrence(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestGrafeasV1Beta1CreateOccurrence(t *testing.T) { var name string = "name3373707" var noteName string = "noteName1780787896" var remediation string = "remediation779381797" var expectedResponse = &grafeaspb.Occurrence{ Name: name, NoteName: noteName, Remediation: remediation, } mockGrafeasV1Beta1.err = nil mockGrafeasV1Beta1.reqs = nil mockGrafeasV1Beta1.resps = append(mockGrafeasV1Beta1.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var occurrence *grafeaspb.Occurrence = &grafeaspb.Occurrence{} var request = &grafeaspb.CreateOccurrenceRequest{ Parent: formattedParent, Occurrence: occurrence, } c, err := NewGrafeasV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateOccurrence(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockGrafeasV1Beta1.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestGrafeasV1Beta1CreateOccurrenceError(t *testing.T) { errCode := codes.PermissionDenied mockGrafeasV1Beta1.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var occurrence *grafeaspb.Occurrence = &grafeaspb.Occurrence{} var request = &grafeaspb.CreateOccurrenceRequest{ Parent: formattedParent, Occurrence: occurrence, } c, err := NewGrafeasV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateOccurrence(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestGrafeasV1Beta1BatchCreateOccurrences(t *testing.T) { var expectedResponse *grafeaspb.BatchCreateOccurrencesResponse = &grafeaspb.BatchCreateOccurrencesResponse{} mockGrafeasV1Beta1.err = nil mockGrafeasV1Beta1.reqs = nil mockGrafeasV1Beta1.resps = append(mockGrafeasV1Beta1.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var occurrences []*grafeaspb.Occurrence = nil var request = &grafeaspb.BatchCreateOccurrencesRequest{ Parent: formattedParent, Occurrences: occurrences, } c, err := NewGrafeasV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.BatchCreateOccurrences(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockGrafeasV1Beta1.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestGrafeasV1Beta1BatchCreateOccurrencesError(t *testing.T) { errCode := codes.PermissionDenied mockGrafeasV1Beta1.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var occurrences []*grafeaspb.Occurrence = nil var request = &grafeaspb.BatchCreateOccurrencesRequest{ Parent: formattedParent, Occurrences: occurrences, } c, err := NewGrafeasV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.BatchCreateOccurrences(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestGrafeasV1Beta1UpdateOccurrence(t *testing.T) { var name2 string = "name2-1052831874" var noteName string = "noteName1780787896" var remediation string = "remediation779381797" var expectedResponse = &grafeaspb.Occurrence{ Name: name2, NoteName: noteName, Remediation: remediation, } mockGrafeasV1Beta1.err = nil mockGrafeasV1Beta1.reqs = nil mockGrafeasV1Beta1.resps = append(mockGrafeasV1Beta1.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/occurrences/%s", "[PROJECT]", "[OCCURRENCE]") var occurrence *grafeaspb.Occurrence = &grafeaspb.Occurrence{} var request = &grafeaspb.UpdateOccurrenceRequest{ Name: formattedName, Occurrence: occurrence, } c, err := NewGrafeasV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateOccurrence(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockGrafeasV1Beta1.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestGrafeasV1Beta1UpdateOccurrenceError(t *testing.T) { errCode := codes.PermissionDenied mockGrafeasV1Beta1.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/occurrences/%s", "[PROJECT]", "[OCCURRENCE]") var occurrence *grafeaspb.Occurrence = &grafeaspb.Occurrence{} var request = &grafeaspb.UpdateOccurrenceRequest{ Name: formattedName, Occurrence: occurrence, } c, err := NewGrafeasV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateOccurrence(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestGrafeasV1Beta1GetOccurrenceNote(t *testing.T) { var name2 string = "name2-1052831874" var shortDescription string = "shortDescription-235369287" var longDescription string = "longDescription-1747792199" var expectedResponse = &grafeaspb.Note{ Name: name2, ShortDescription: shortDescription, LongDescription: longDescription, } mockGrafeasV1Beta1.err = nil mockGrafeasV1Beta1.reqs = nil mockGrafeasV1Beta1.resps = append(mockGrafeasV1Beta1.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/occurrences/%s", "[PROJECT]", "[OCCURRENCE]") var request = &grafeaspb.GetOccurrenceNoteRequest{ Name: formattedName, } c, err := NewGrafeasV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetOccurrenceNote(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockGrafeasV1Beta1.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestGrafeasV1Beta1GetOccurrenceNoteError(t *testing.T) { errCode := codes.PermissionDenied mockGrafeasV1Beta1.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/occurrences/%s", "[PROJECT]", "[OCCURRENCE]") var request = &grafeaspb.GetOccurrenceNoteRequest{ Name: formattedName, } c, err := NewGrafeasV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetOccurrenceNote(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestGrafeasV1Beta1GetNote(t *testing.T) { var name2 string = "name2-1052831874" var shortDescription string = "shortDescription-235369287" var longDescription string = "longDescription-1747792199" var expectedResponse = &grafeaspb.Note{ Name: name2, ShortDescription: shortDescription, LongDescription: longDescription, } mockGrafeasV1Beta1.err = nil mockGrafeasV1Beta1.reqs = nil mockGrafeasV1Beta1.resps = append(mockGrafeasV1Beta1.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]") var request = &grafeaspb.GetNoteRequest{ Name: formattedName, } c, err := NewGrafeasV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetNote(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockGrafeasV1Beta1.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestGrafeasV1Beta1GetNoteError(t *testing.T) { errCode := codes.PermissionDenied mockGrafeasV1Beta1.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]") var request = &grafeaspb.GetNoteRequest{ Name: formattedName, } c, err := NewGrafeasV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetNote(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestGrafeasV1Beta1ListNotes(t *testing.T) { var nextPageToken string = "" var notesElement *grafeaspb.Note = &grafeaspb.Note{} var notes = []*grafeaspb.Note{notesElement} var expectedResponse = &grafeaspb.ListNotesResponse{ NextPageToken: nextPageToken, Notes: notes, } mockGrafeasV1Beta1.err = nil mockGrafeasV1Beta1.reqs = nil mockGrafeasV1Beta1.resps = append(mockGrafeasV1Beta1.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &grafeaspb.ListNotesRequest{ Parent: formattedParent, } c, err := NewGrafeasV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListNotes(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockGrafeasV1Beta1.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Notes[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestGrafeasV1Beta1ListNotesError(t *testing.T) { errCode := codes.PermissionDenied mockGrafeasV1Beta1.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &grafeaspb.ListNotesRequest{ Parent: formattedParent, } c, err := NewGrafeasV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListNotes(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestGrafeasV1Beta1DeleteNote(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockGrafeasV1Beta1.err = nil mockGrafeasV1Beta1.reqs = nil mockGrafeasV1Beta1.resps = append(mockGrafeasV1Beta1.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]") var request = &grafeaspb.DeleteNoteRequest{ Name: formattedName, } c, err := NewGrafeasV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteNote(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockGrafeasV1Beta1.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestGrafeasV1Beta1DeleteNoteError(t *testing.T) { errCode := codes.PermissionDenied mockGrafeasV1Beta1.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]") var request = &grafeaspb.DeleteNoteRequest{ Name: formattedName, } c, err := NewGrafeasV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteNote(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestGrafeasV1Beta1CreateNote(t *testing.T) { var name string = "name3373707" var shortDescription string = "shortDescription-235369287" var longDescription string = "longDescription-1747792199" var expectedResponse = &grafeaspb.Note{ Name: name, ShortDescription: shortDescription, LongDescription: longDescription, } mockGrafeasV1Beta1.err = nil mockGrafeasV1Beta1.reqs = nil mockGrafeasV1Beta1.resps = append(mockGrafeasV1Beta1.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var noteId string = "noteId2129224840" var note *grafeaspb.Note = &grafeaspb.Note{} var request = &grafeaspb.CreateNoteRequest{ Parent: formattedParent, NoteId: noteId, Note: note, } c, err := NewGrafeasV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateNote(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockGrafeasV1Beta1.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestGrafeasV1Beta1CreateNoteError(t *testing.T) { errCode := codes.PermissionDenied mockGrafeasV1Beta1.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var noteId string = "noteId2129224840" var note *grafeaspb.Note = &grafeaspb.Note{} var request = &grafeaspb.CreateNoteRequest{ Parent: formattedParent, NoteId: noteId, Note: note, } c, err := NewGrafeasV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateNote(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestGrafeasV1Beta1BatchCreateNotes(t *testing.T) { var expectedResponse *grafeaspb.BatchCreateNotesResponse = &grafeaspb.BatchCreateNotesResponse{} mockGrafeasV1Beta1.err = nil mockGrafeasV1Beta1.reqs = nil mockGrafeasV1Beta1.resps = append(mockGrafeasV1Beta1.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var notes map[string]*grafeaspb.Note = nil var request = &grafeaspb.BatchCreateNotesRequest{ Parent: formattedParent, Notes: notes, } c, err := NewGrafeasV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.BatchCreateNotes(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockGrafeasV1Beta1.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestGrafeasV1Beta1BatchCreateNotesError(t *testing.T) { errCode := codes.PermissionDenied mockGrafeasV1Beta1.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var notes map[string]*grafeaspb.Note = nil var request = &grafeaspb.BatchCreateNotesRequest{ Parent: formattedParent, Notes: notes, } c, err := NewGrafeasV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.BatchCreateNotes(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestGrafeasV1Beta1UpdateNote(t *testing.T) { var name2 string = "name2-1052831874" var shortDescription string = "shortDescription-235369287" var longDescription string = "longDescription-1747792199" var expectedResponse = &grafeaspb.Note{ Name: name2, ShortDescription: shortDescription, LongDescription: longDescription, } mockGrafeasV1Beta1.err = nil mockGrafeasV1Beta1.reqs = nil mockGrafeasV1Beta1.resps = append(mockGrafeasV1Beta1.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]") var note *grafeaspb.Note = &grafeaspb.Note{} var request = &grafeaspb.UpdateNoteRequest{ Name: formattedName, Note: note, } c, err := NewGrafeasV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateNote(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockGrafeasV1Beta1.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestGrafeasV1Beta1UpdateNoteError(t *testing.T) { errCode := codes.PermissionDenied mockGrafeasV1Beta1.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]") var note *grafeaspb.Note = &grafeaspb.Note{} var request = &grafeaspb.UpdateNoteRequest{ Name: formattedName, Note: note, } c, err := NewGrafeasV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateNote(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestGrafeasV1Beta1ListNoteOccurrences(t *testing.T) { var nextPageToken string = "" var occurrencesElement *grafeaspb.Occurrence = &grafeaspb.Occurrence{} var occurrences = []*grafeaspb.Occurrence{occurrencesElement} var expectedResponse = &grafeaspb.ListNoteOccurrencesResponse{ NextPageToken: nextPageToken, Occurrences: occurrences, } mockGrafeasV1Beta1.err = nil mockGrafeasV1Beta1.reqs = nil mockGrafeasV1Beta1.resps = append(mockGrafeasV1Beta1.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]") var request = &grafeaspb.ListNoteOccurrencesRequest{ Name: formattedName, } c, err := NewGrafeasV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListNoteOccurrences(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockGrafeasV1Beta1.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Occurrences[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestGrafeasV1Beta1ListNoteOccurrencesError(t *testing.T) { errCode := codes.PermissionDenied mockGrafeasV1Beta1.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]") var request = &grafeaspb.ListNoteOccurrencesRequest{ Name: formattedName, } c, err := NewGrafeasV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListNoteOccurrences(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestGrafeasV1Beta1GetVulnerabilityOccurrencesSummary(t *testing.T) { var expectedResponse *grafeaspb.VulnerabilityOccurrencesSummary = &grafeaspb.VulnerabilityOccurrencesSummary{} mockGrafeasV1Beta1.err = nil mockGrafeasV1Beta1.reqs = nil mockGrafeasV1Beta1.resps = append(mockGrafeasV1Beta1.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &grafeaspb.GetVulnerabilityOccurrencesSummaryRequest{ Parent: formattedParent, } c, err := NewGrafeasV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetVulnerabilityOccurrencesSummary(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockGrafeasV1Beta1.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestGrafeasV1Beta1GetVulnerabilityOccurrencesSummaryError(t *testing.T) { errCode := codes.PermissionDenied mockGrafeasV1Beta1.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &grafeaspb.GetVulnerabilityOccurrencesSummaryRequest{ Parent: formattedParent, } c, err := NewGrafeasV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetVulnerabilityOccurrencesSummary(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/dataproc/000077500000000000000000000000001356504100700163655ustar00rootroot00000000000000google-cloud-go-0.49.0/dataproc/apiv1/000077500000000000000000000000001356504100700174055ustar00rootroot00000000000000google-cloud-go-0.49.0/dataproc/apiv1/.repo-metadata.json000066400000000000000000000006661356504100700231110ustar00rootroot00000000000000{ "name": "dataproc", "name_pretty": "Cloud-native Apache Hadoop & Apache Spark API", "product_documentation": "https://cloud.google.com/dataproc", "client_documentation": "https://godoc.org/cloud.google.com/go/dataproc/apiv1", "release_level": "alpha", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "dataproc.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/dataproc/apiv1/ListClusters_smoke_test.go000066400000000000000000000032701356504100700246330ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package dataproc import ( "context" "fmt" "strconv" "testing" "time" "cloud.google.com/go/internal/testutil" "google.golang.org/api/iterator" "google.golang.org/api/option" dataprocpb "google.golang.org/genproto/googleapis/cloud/dataproc/v1" ) var _ = fmt.Sprintf var _ = iterator.Done var _ = strconv.FormatUint var _ = time.Now func TestClusterControllerSmoke(t *testing.T) { if testing.Short() { t.Skip("skipping smoke test in short mode") } ctx := context.Background() ts := testutil.TokenSource(ctx, DefaultAuthScopes()...) if ts == nil { t.Skip("Integration tests skipped. See CONTRIBUTING.md for details") } projectId := testutil.ProjID() _ = projectId c, err := NewClusterControllerClient(ctx, option.WithTokenSource(ts)) if err != nil { t.Fatal(err) } var projectId2 string = projectId var region string = "global" var request = &dataprocpb.ListClustersRequest{ ProjectId: projectId2, Region: region, } iter := c.ListClusters(ctx, request) if _, err := iter.Next(); err != nil && err != iterator.Done { t.Error(err) } } google-cloud-go-0.49.0/dataproc/apiv1/cluster_controller_client.go000066400000000000000000000565441356504100700252340ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package dataproc import ( "context" "math" "time" "cloud.google.com/go/longrunning" lroauto "cloud.google.com/go/longrunning/autogen" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" dataprocpb "google.golang.org/genproto/googleapis/cloud/dataproc/v1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // ClusterControllerCallOptions contains the retry settings for each method of ClusterControllerClient. type ClusterControllerCallOptions struct { CreateCluster []gax.CallOption UpdateCluster []gax.CallOption DeleteCluster []gax.CallOption GetCluster []gax.CallOption ListClusters []gax.CallOption DiagnoseCluster []gax.CallOption } func defaultClusterControllerClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("dataproc.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultClusterControllerCallOptions() *ClusterControllerCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Internal, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, {"default", "non_idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &ClusterControllerCallOptions{ CreateCluster: retry[[2]string{"default", "non_idempotent"}], UpdateCluster: retry[[2]string{"default", "non_idempotent"}], DeleteCluster: retry[[2]string{"default", "non_idempotent"}], GetCluster: retry[[2]string{"default", "idempotent"}], ListClusters: retry[[2]string{"default", "idempotent"}], DiagnoseCluster: retry[[2]string{"default", "non_idempotent"}], } } // ClusterControllerClient is a client for interacting with Google Cloud Dataproc API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type ClusterControllerClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. clusterControllerClient dataprocpb.ClusterControllerClient // LROClient is used internally to handle longrunning operations. // It is exposed so that its CallOptions can be modified if required. // Users should not Close this client. LROClient *lroauto.OperationsClient // The call options for this service. CallOptions *ClusterControllerCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewClusterControllerClient creates a new cluster controller client. // // The ClusterControllerService provides methods to manage clusters // of Compute Engine instances. func NewClusterControllerClient(ctx context.Context, opts ...option.ClientOption) (*ClusterControllerClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultClusterControllerClientOptions(), opts...)...) if err != nil { return nil, err } c := &ClusterControllerClient{ conn: conn, CallOptions: defaultClusterControllerCallOptions(), clusterControllerClient: dataprocpb.NewClusterControllerClient(conn), } c.setGoogleClientInfo() c.LROClient, err = lroauto.NewOperationsClient(ctx, option.WithGRPCConn(conn)) if err != nil { // This error "should not happen", since we are just reusing old connection // and never actually need to dial. // If this does happen, we could leak conn. However, we cannot close conn: // If the user invoked the function with option.WithGRPCConn, // we would close a connection that's still in use. // TODO(pongad): investigate error conditions. return nil, err } return c, nil } // Connection returns the client's connection to the API service. func (c *ClusterControllerClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *ClusterControllerClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *ClusterControllerClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // CreateCluster creates a cluster in a project. The returned // [Operation.metadata][google.longrunning.Operation.metadata] will be // ClusterOperationMetadata (at /dataproc/docs/reference/rpc/google.cloud.dataproc.v1#clusteroperationmetadata). func (c *ClusterControllerClient) CreateCluster(ctx context.Context, req *dataprocpb.CreateClusterRequest, opts ...gax.CallOption) (*CreateClusterOperation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.CreateCluster[0:len(c.CallOptions.CreateCluster):len(c.CallOptions.CreateCluster)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterControllerClient.CreateCluster(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &CreateClusterOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // UpdateCluster updates a cluster in a project. The returned // [Operation.metadata][google.longrunning.Operation.metadata] will be // ClusterOperationMetadata (at /dataproc/docs/reference/rpc/google.cloud.dataproc.v1#clusteroperationmetadata). func (c *ClusterControllerClient) UpdateCluster(ctx context.Context, req *dataprocpb.UpdateClusterRequest, opts ...gax.CallOption) (*UpdateClusterOperation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.UpdateCluster[0:len(c.CallOptions.UpdateCluster):len(c.CallOptions.UpdateCluster)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterControllerClient.UpdateCluster(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &UpdateClusterOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // DeleteCluster deletes a cluster in a project. The returned // [Operation.metadata][google.longrunning.Operation.metadata] will be // ClusterOperationMetadata (at /dataproc/docs/reference/rpc/google.cloud.dataproc.v1#clusteroperationmetadata). func (c *ClusterControllerClient) DeleteCluster(ctx context.Context, req *dataprocpb.DeleteClusterRequest, opts ...gax.CallOption) (*DeleteClusterOperation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.DeleteCluster[0:len(c.CallOptions.DeleteCluster):len(c.CallOptions.DeleteCluster)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterControllerClient.DeleteCluster(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &DeleteClusterOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // GetCluster gets the resource representation for a cluster in a project. func (c *ClusterControllerClient) GetCluster(ctx context.Context, req *dataprocpb.GetClusterRequest, opts ...gax.CallOption) (*dataprocpb.Cluster, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.GetCluster[0:len(c.CallOptions.GetCluster):len(c.CallOptions.GetCluster)], opts...) var resp *dataprocpb.Cluster err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterControllerClient.GetCluster(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListClusters lists all regions/{region}/clusters in a project. func (c *ClusterControllerClient) ListClusters(ctx context.Context, req *dataprocpb.ListClustersRequest, opts ...gax.CallOption) *ClusterIterator { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.ListClusters[0:len(c.CallOptions.ListClusters):len(c.CallOptions.ListClusters)], opts...) it := &ClusterIterator{} req = proto.Clone(req).(*dataprocpb.ListClustersRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*dataprocpb.Cluster, string, error) { var resp *dataprocpb.ListClustersResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterControllerClient.ListClusters(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Clusters, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // DiagnoseCluster gets cluster diagnostic information. The returned // [Operation.metadata][google.longrunning.Operation.metadata] will be // ClusterOperationMetadata (at /dataproc/docs/reference/rpc/google.cloud.dataproc.v1#clusteroperationmetadata). // After the operation completes, // [Operation.response][google.longrunning.Operation.response] // contains // DiagnoseClusterResults (at /dataproc/docs/reference/rpc/google.cloud.dataproc.v1#diagnoseclusterresults). func (c *ClusterControllerClient) DiagnoseCluster(ctx context.Context, req *dataprocpb.DiagnoseClusterRequest, opts ...gax.CallOption) (*DiagnoseClusterOperation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.DiagnoseCluster[0:len(c.CallOptions.DiagnoseCluster):len(c.CallOptions.DiagnoseCluster)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterControllerClient.DiagnoseCluster(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &DiagnoseClusterOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // ClusterIterator manages a stream of *dataprocpb.Cluster. type ClusterIterator struct { items []*dataprocpb.Cluster pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*dataprocpb.Cluster, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *ClusterIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *ClusterIterator) Next() (*dataprocpb.Cluster, error) { var item *dataprocpb.Cluster if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *ClusterIterator) bufLen() int { return len(it.items) } func (it *ClusterIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // CreateClusterOperation manages a long-running operation from CreateCluster. type CreateClusterOperation struct { lro *longrunning.Operation } // CreateClusterOperation returns a new CreateClusterOperation from a given name. // The name must be that of a previously created CreateClusterOperation, possibly from a different process. func (c *ClusterControllerClient) CreateClusterOperation(name string) *CreateClusterOperation { return &CreateClusterOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *CreateClusterOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*dataprocpb.Cluster, error) { var resp dataprocpb.Cluster if err := op.lro.WaitWithInterval(ctx, &resp, 10000*time.Millisecond, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *CreateClusterOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*dataprocpb.Cluster, error) { var resp dataprocpb.Cluster if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *CreateClusterOperation) Metadata() (*dataprocpb.ClusterOperationMetadata, error) { var meta dataprocpb.ClusterOperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *CreateClusterOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *CreateClusterOperation) Name() string { return op.lro.Name() } // DeleteClusterOperation manages a long-running operation from DeleteCluster. type DeleteClusterOperation struct { lro *longrunning.Operation } // DeleteClusterOperation returns a new DeleteClusterOperation from a given name. // The name must be that of a previously created DeleteClusterOperation, possibly from a different process. func (c *ClusterControllerClient) DeleteClusterOperation(name string) *DeleteClusterOperation { return &DeleteClusterOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning any error encountered. // // See documentation of Poll for error-handling information. func (op *DeleteClusterOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { return op.lro.WaitWithInterval(ctx, nil, 10000*time.Millisecond, opts...) } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, op.Done will return true. func (op *DeleteClusterOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Poll(ctx, nil, opts...) } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *DeleteClusterOperation) Metadata() (*dataprocpb.ClusterOperationMetadata, error) { var meta dataprocpb.ClusterOperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *DeleteClusterOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *DeleteClusterOperation) Name() string { return op.lro.Name() } // DiagnoseClusterOperation manages a long-running operation from DiagnoseCluster. type DiagnoseClusterOperation struct { lro *longrunning.Operation } // DiagnoseClusterOperation returns a new DiagnoseClusterOperation from a given name. // The name must be that of a previously created DiagnoseClusterOperation, possibly from a different process. func (c *ClusterControllerClient) DiagnoseClusterOperation(name string) *DiagnoseClusterOperation { return &DiagnoseClusterOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning any error encountered. // // See documentation of Poll for error-handling information. func (op *DiagnoseClusterOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { return op.lro.WaitWithInterval(ctx, nil, 10000*time.Millisecond, opts...) } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, op.Done will return true. func (op *DiagnoseClusterOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Poll(ctx, nil, opts...) } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *DiagnoseClusterOperation) Metadata() (*dataprocpb.DiagnoseClusterResults, error) { var meta dataprocpb.DiagnoseClusterResults if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *DiagnoseClusterOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *DiagnoseClusterOperation) Name() string { return op.lro.Name() } // UpdateClusterOperation manages a long-running operation from UpdateCluster. type UpdateClusterOperation struct { lro *longrunning.Operation } // UpdateClusterOperation returns a new UpdateClusterOperation from a given name. // The name must be that of a previously created UpdateClusterOperation, possibly from a different process. func (c *ClusterControllerClient) UpdateClusterOperation(name string) *UpdateClusterOperation { return &UpdateClusterOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *UpdateClusterOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*dataprocpb.Cluster, error) { var resp dataprocpb.Cluster if err := op.lro.WaitWithInterval(ctx, &resp, 10000*time.Millisecond, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *UpdateClusterOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*dataprocpb.Cluster, error) { var resp dataprocpb.Cluster if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *UpdateClusterOperation) Metadata() (*dataprocpb.ClusterOperationMetadata, error) { var meta dataprocpb.ClusterOperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *UpdateClusterOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *UpdateClusterOperation) Name() string { return op.lro.Name() } google-cloud-go-0.49.0/dataproc/apiv1/cluster_controller_client_example_test.go000066400000000000000000000067651356504100700300060ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package dataproc_test import ( "context" dataproc "cloud.google.com/go/dataproc/apiv1" "google.golang.org/api/iterator" dataprocpb "google.golang.org/genproto/googleapis/cloud/dataproc/v1" ) func ExampleNewClusterControllerClient() { ctx := context.Background() c, err := dataproc.NewClusterControllerClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleClusterControllerClient_CreateCluster() { ctx := context.Background() c, err := dataproc.NewClusterControllerClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.CreateClusterRequest{ // TODO: Fill request struct fields. } op, err := c.CreateCluster(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClusterControllerClient_UpdateCluster() { ctx := context.Background() c, err := dataproc.NewClusterControllerClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.UpdateClusterRequest{ // TODO: Fill request struct fields. } op, err := c.UpdateCluster(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClusterControllerClient_DeleteCluster() { ctx := context.Background() c, err := dataproc.NewClusterControllerClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.DeleteClusterRequest{ // TODO: Fill request struct fields. } op, err := c.DeleteCluster(ctx, req) if err != nil { // TODO: Handle error. } err = op.Wait(ctx) // TODO: Handle error. } func ExampleClusterControllerClient_GetCluster() { ctx := context.Background() c, err := dataproc.NewClusterControllerClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.GetClusterRequest{ // TODO: Fill request struct fields. } resp, err := c.GetCluster(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClusterControllerClient_ListClusters() { ctx := context.Background() c, err := dataproc.NewClusterControllerClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.ListClustersRequest{ // TODO: Fill request struct fields. } it := c.ListClusters(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClusterControllerClient_DiagnoseCluster() { ctx := context.Background() c, err := dataproc.NewClusterControllerClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.DiagnoseClusterRequest{ // TODO: Fill request struct fields. } op, err := c.DiagnoseCluster(ctx, req) if err != nil { // TODO: Handle error. } err = op.Wait(ctx) // TODO: Handle error. } google-cloud-go-0.49.0/dataproc/apiv1/doc.go000066400000000000000000000053401356504100700205030ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package dataproc is an auto-generated package for the // Google Cloud Dataproc API. // // NOTE: This package is in alpha. It is not stable, and is likely to change. // // Manages Hadoop-based clusters and jobs on Google Cloud Platform. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package dataproc // import "cloud.google.com/go/dataproc/apiv1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "UNKNOWN" google-cloud-go-0.49.0/dataproc/apiv1/job_controller_client.go000066400000000000000000000250471356504100700243170ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package dataproc import ( "context" "math" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" dataprocpb "google.golang.org/genproto/googleapis/cloud/dataproc/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // JobControllerCallOptions contains the retry settings for each method of JobControllerClient. type JobControllerCallOptions struct { SubmitJob []gax.CallOption GetJob []gax.CallOption ListJobs []gax.CallOption UpdateJob []gax.CallOption CancelJob []gax.CallOption DeleteJob []gax.CallOption } func defaultJobControllerClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("dataproc.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultJobControllerCallOptions() *JobControllerCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Internal, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, {"default", "non_idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &JobControllerCallOptions{ SubmitJob: retry[[2]string{"default", "non_idempotent"}], GetJob: retry[[2]string{"default", "idempotent"}], ListJobs: retry[[2]string{"default", "idempotent"}], UpdateJob: retry[[2]string{"default", "non_idempotent"}], CancelJob: retry[[2]string{"default", "idempotent"}], DeleteJob: retry[[2]string{"default", "non_idempotent"}], } } // JobControllerClient is a client for interacting with Google Cloud Dataproc API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type JobControllerClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. jobControllerClient dataprocpb.JobControllerClient // The call options for this service. CallOptions *JobControllerCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewJobControllerClient creates a new job controller client. // // The JobController provides methods to manage jobs. func NewJobControllerClient(ctx context.Context, opts ...option.ClientOption) (*JobControllerClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultJobControllerClientOptions(), opts...)...) if err != nil { return nil, err } c := &JobControllerClient{ conn: conn, CallOptions: defaultJobControllerCallOptions(), jobControllerClient: dataprocpb.NewJobControllerClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *JobControllerClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *JobControllerClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *JobControllerClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // SubmitJob submits a job to a cluster. func (c *JobControllerClient) SubmitJob(ctx context.Context, req *dataprocpb.SubmitJobRequest, opts ...gax.CallOption) (*dataprocpb.Job, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.SubmitJob[0:len(c.CallOptions.SubmitJob):len(c.CallOptions.SubmitJob)], opts...) var resp *dataprocpb.Job err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.jobControllerClient.SubmitJob(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetJob gets the resource representation for a job in a project. func (c *JobControllerClient) GetJob(ctx context.Context, req *dataprocpb.GetJobRequest, opts ...gax.CallOption) (*dataprocpb.Job, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.GetJob[0:len(c.CallOptions.GetJob):len(c.CallOptions.GetJob)], opts...) var resp *dataprocpb.Job err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.jobControllerClient.GetJob(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListJobs lists regions/{region}/jobs in a project. func (c *JobControllerClient) ListJobs(ctx context.Context, req *dataprocpb.ListJobsRequest, opts ...gax.CallOption) *JobIterator { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.ListJobs[0:len(c.CallOptions.ListJobs):len(c.CallOptions.ListJobs)], opts...) it := &JobIterator{} req = proto.Clone(req).(*dataprocpb.ListJobsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*dataprocpb.Job, string, error) { var resp *dataprocpb.ListJobsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.jobControllerClient.ListJobs(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Jobs, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // UpdateJob updates a job in a project. func (c *JobControllerClient) UpdateJob(ctx context.Context, req *dataprocpb.UpdateJobRequest, opts ...gax.CallOption) (*dataprocpb.Job, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.UpdateJob[0:len(c.CallOptions.UpdateJob):len(c.CallOptions.UpdateJob)], opts...) var resp *dataprocpb.Job err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.jobControllerClient.UpdateJob(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CancelJob starts a job cancellation request. To access the job resource // after cancellation, call // regions/{region}/jobs.list (at /dataproc/docs/reference/rest/v1/projects.regions.jobs/list) // or // regions/{region}/jobs.get (at /dataproc/docs/reference/rest/v1/projects.regions.jobs/get). func (c *JobControllerClient) CancelJob(ctx context.Context, req *dataprocpb.CancelJobRequest, opts ...gax.CallOption) (*dataprocpb.Job, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.CancelJob[0:len(c.CallOptions.CancelJob):len(c.CallOptions.CancelJob)], opts...) var resp *dataprocpb.Job err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.jobControllerClient.CancelJob(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteJob deletes the job from the project. If the job is active, the delete fails, // and the response returns FAILED_PRECONDITION. func (c *JobControllerClient) DeleteJob(ctx context.Context, req *dataprocpb.DeleteJobRequest, opts ...gax.CallOption) error { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.DeleteJob[0:len(c.CallOptions.DeleteJob):len(c.CallOptions.DeleteJob)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.jobControllerClient.DeleteJob(ctx, req, settings.GRPC...) return err }, opts...) return err } // JobIterator manages a stream of *dataprocpb.Job. type JobIterator struct { items []*dataprocpb.Job pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*dataprocpb.Job, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *JobIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *JobIterator) Next() (*dataprocpb.Job, error) { var item *dataprocpb.Job if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *JobIterator) bufLen() int { return len(it.items) } func (it *JobIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/dataproc/apiv1/job_controller_client_example_test.go000066400000000000000000000062421356504100700270650ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package dataproc_test import ( "context" dataproc "cloud.google.com/go/dataproc/apiv1" "google.golang.org/api/iterator" dataprocpb "google.golang.org/genproto/googleapis/cloud/dataproc/v1" ) func ExampleNewJobControllerClient() { ctx := context.Background() c, err := dataproc.NewJobControllerClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleJobControllerClient_SubmitJob() { ctx := context.Background() c, err := dataproc.NewJobControllerClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.SubmitJobRequest{ // TODO: Fill request struct fields. } resp, err := c.SubmitJob(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleJobControllerClient_GetJob() { ctx := context.Background() c, err := dataproc.NewJobControllerClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.GetJobRequest{ // TODO: Fill request struct fields. } resp, err := c.GetJob(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleJobControllerClient_ListJobs() { ctx := context.Background() c, err := dataproc.NewJobControllerClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.ListJobsRequest{ // TODO: Fill request struct fields. } it := c.ListJobs(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleJobControllerClient_UpdateJob() { ctx := context.Background() c, err := dataproc.NewJobControllerClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.UpdateJobRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateJob(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleJobControllerClient_CancelJob() { ctx := context.Background() c, err := dataproc.NewJobControllerClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.CancelJobRequest{ // TODO: Fill request struct fields. } resp, err := c.CancelJob(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleJobControllerClient_DeleteJob() { ctx := context.Background() c, err := dataproc.NewJobControllerClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.DeleteJobRequest{ // TODO: Fill request struct fields. } err = c.DeleteJob(ctx, req) if err != nil { // TODO: Handle error. } } google-cloud-go-0.49.0/dataproc/apiv1/longrunning.go000066400000000000000000000071311356504100700222760ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package dataproc import ( "context" gax "github.com/googleapis/gax-go/v2" ) // Cancel starts asynchronous cancellation on a long-running operation. // The server makes a best effort to cancel the operation, but success is not guaranteed. // Clients can use Poll or other methods to check whether the cancellation succeeded or whether the operation // completed despite cancellation. On successful cancellation, the operation is not deleted; // instead, op.Poll returns an error with code Canceled. func (op *InstantiateInlineWorkflowTemplateOperation) Cancel(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Cancel(ctx, opts...) } // Delete deletes a long-running operation. // This method indicates that the client is no longer interested in the operation result. // It does not cancel the operation. func (op *InstantiateInlineWorkflowTemplateOperation) Delete(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Delete(ctx, opts...) } // Cancel starts asynchronous cancellation on a long-running operation. // The server makes a best effort to cancel the operation, but success is not guaranteed. // Clients can use Poll or other methods to check whether the cancellation succeeded or whether the operation // completed despite cancellation. On successful cancellation, the operation is not deleted; // instead, op.Poll returns an error with code Canceled. func (op *InstantiateWorkflowTemplateOperation) Cancel(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Cancel(ctx, opts...) } // Delete deletes a long-running operation. // This method indicates that the client is no longer interested in the operation result. // It does not cancel the operation. func (op *InstantiateWorkflowTemplateOperation) Delete(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Delete(ctx, opts...) } // Delete deletes a long-running operation. // This method indicates that the client is no longer interested in the operation result. // It does not cancel the operation. func (op *CreateClusterOperation) Delete(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Delete(ctx, opts...) } // Delete deletes a long-running operation. // This method indicates that the client is no longer interested in the operation result. // It does not cancel the operation. func (op *DeleteClusterOperation) Delete(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Delete(ctx, opts...) } // Delete deletes a long-running operation. // This method indicates that the client is no longer interested in the operation result. // It does not cancel the operation. func (op *DiagnoseClusterOperation) Delete(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Delete(ctx, opts...) } // Delete deletes a long-running operation. // This method indicates that the client is no longer interested in the operation result. // It does not cancel the operation. func (op *UpdateClusterOperation) Delete(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Delete(ctx, opts...) } google-cloud-go-0.49.0/dataproc/apiv1/mock_test.go000066400000000000000000001467271356504100700217450ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package dataproc import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" "google.golang.org/api/option" dataprocpb "google.golang.org/genproto/googleapis/cloud/dataproc/v1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" field_maskpb "google.golang.org/genproto/protobuf/field_mask" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockClusterControllerServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. dataprocpb.ClusterControllerServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockClusterControllerServer) CreateCluster(ctx context.Context, req *dataprocpb.CreateClusterRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockClusterControllerServer) UpdateCluster(ctx context.Context, req *dataprocpb.UpdateClusterRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockClusterControllerServer) DeleteCluster(ctx context.Context, req *dataprocpb.DeleteClusterRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockClusterControllerServer) GetCluster(ctx context.Context, req *dataprocpb.GetClusterRequest) (*dataprocpb.Cluster, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dataprocpb.Cluster), nil } func (s *mockClusterControllerServer) ListClusters(ctx context.Context, req *dataprocpb.ListClustersRequest) (*dataprocpb.ListClustersResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dataprocpb.ListClustersResponse), nil } func (s *mockClusterControllerServer) DiagnoseCluster(ctx context.Context, req *dataprocpb.DiagnoseClusterRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } type mockJobControllerServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. dataprocpb.JobControllerServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockJobControllerServer) SubmitJob(ctx context.Context, req *dataprocpb.SubmitJobRequest) (*dataprocpb.Job, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dataprocpb.Job), nil } func (s *mockJobControllerServer) GetJob(ctx context.Context, req *dataprocpb.GetJobRequest) (*dataprocpb.Job, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dataprocpb.Job), nil } func (s *mockJobControllerServer) ListJobs(ctx context.Context, req *dataprocpb.ListJobsRequest) (*dataprocpb.ListJobsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dataprocpb.ListJobsResponse), nil } func (s *mockJobControllerServer) UpdateJob(ctx context.Context, req *dataprocpb.UpdateJobRequest) (*dataprocpb.Job, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dataprocpb.Job), nil } func (s *mockJobControllerServer) CancelJob(ctx context.Context, req *dataprocpb.CancelJobRequest) (*dataprocpb.Job, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dataprocpb.Job), nil } func (s *mockJobControllerServer) DeleteJob(ctx context.Context, req *dataprocpb.DeleteJobRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } type mockWorkflowTemplateServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. dataprocpb.WorkflowTemplateServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockWorkflowTemplateServer) CreateWorkflowTemplate(ctx context.Context, req *dataprocpb.CreateWorkflowTemplateRequest) (*dataprocpb.WorkflowTemplate, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dataprocpb.WorkflowTemplate), nil } func (s *mockWorkflowTemplateServer) GetWorkflowTemplate(ctx context.Context, req *dataprocpb.GetWorkflowTemplateRequest) (*dataprocpb.WorkflowTemplate, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dataprocpb.WorkflowTemplate), nil } func (s *mockWorkflowTemplateServer) InstantiateWorkflowTemplate(ctx context.Context, req *dataprocpb.InstantiateWorkflowTemplateRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockWorkflowTemplateServer) InstantiateInlineWorkflowTemplate(ctx context.Context, req *dataprocpb.InstantiateInlineWorkflowTemplateRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockWorkflowTemplateServer) UpdateWorkflowTemplate(ctx context.Context, req *dataprocpb.UpdateWorkflowTemplateRequest) (*dataprocpb.WorkflowTemplate, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dataprocpb.WorkflowTemplate), nil } func (s *mockWorkflowTemplateServer) ListWorkflowTemplates(ctx context.Context, req *dataprocpb.ListWorkflowTemplatesRequest) (*dataprocpb.ListWorkflowTemplatesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dataprocpb.ListWorkflowTemplatesResponse), nil } func (s *mockWorkflowTemplateServer) DeleteWorkflowTemplate(ctx context.Context, req *dataprocpb.DeleteWorkflowTemplateRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockClusterController mockClusterControllerServer mockJobController mockJobControllerServer mockWorkflowTemplate mockWorkflowTemplateServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() dataprocpb.RegisterClusterControllerServer(serv, &mockClusterController) dataprocpb.RegisterJobControllerServer(serv, &mockJobController) dataprocpb.RegisterWorkflowTemplateServiceServer(serv, &mockWorkflowTemplate) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestClusterControllerCreateCluster(t *testing.T) { var projectId2 string = "projectId2939242356" var clusterName string = "clusterName-1018081872" var clusterUuid string = "clusterUuid-1017854240" var expectedResponse = &dataprocpb.Cluster{ ProjectId: projectId2, ClusterName: clusterName, ClusterUuid: clusterUuid, } mockClusterController.err = nil mockClusterController.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockClusterController.resps = append(mockClusterController.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var projectId string = "projectId-1969970175" var region string = "region-934795532" var cluster *dataprocpb.Cluster = &dataprocpb.Cluster{} var request = &dataprocpb.CreateClusterRequest{ ProjectId: projectId, Region: region, Cluster: cluster, } c, err := NewClusterControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.CreateCluster(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockClusterController.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestClusterControllerCreateClusterError(t *testing.T) { errCode := codes.PermissionDenied mockClusterController.err = nil mockClusterController.resps = append(mockClusterController.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var projectId string = "projectId-1969970175" var region string = "region-934795532" var cluster *dataprocpb.Cluster = &dataprocpb.Cluster{} var request = &dataprocpb.CreateClusterRequest{ ProjectId: projectId, Region: region, Cluster: cluster, } c, err := NewClusterControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.CreateCluster(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestClusterControllerUpdateCluster(t *testing.T) { var projectId2 string = "projectId2939242356" var clusterName2 string = "clusterName2875867491" var clusterUuid string = "clusterUuid-1017854240" var expectedResponse = &dataprocpb.Cluster{ ProjectId: projectId2, ClusterName: clusterName2, ClusterUuid: clusterUuid, } mockClusterController.err = nil mockClusterController.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockClusterController.resps = append(mockClusterController.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var projectId string = "projectId-1969970175" var region string = "region-934795532" var clusterName string = "clusterName-1018081872" var cluster *dataprocpb.Cluster = &dataprocpb.Cluster{} var updateMask *field_maskpb.FieldMask = &field_maskpb.FieldMask{} var request = &dataprocpb.UpdateClusterRequest{ ProjectId: projectId, Region: region, ClusterName: clusterName, Cluster: cluster, UpdateMask: updateMask, } c, err := NewClusterControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.UpdateCluster(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockClusterController.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestClusterControllerUpdateClusterError(t *testing.T) { errCode := codes.PermissionDenied mockClusterController.err = nil mockClusterController.resps = append(mockClusterController.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var projectId string = "projectId-1969970175" var region string = "region-934795532" var clusterName string = "clusterName-1018081872" var cluster *dataprocpb.Cluster = &dataprocpb.Cluster{} var updateMask *field_maskpb.FieldMask = &field_maskpb.FieldMask{} var request = &dataprocpb.UpdateClusterRequest{ ProjectId: projectId, Region: region, ClusterName: clusterName, Cluster: cluster, UpdateMask: updateMask, } c, err := NewClusterControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.UpdateCluster(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestClusterControllerDeleteCluster(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockClusterController.err = nil mockClusterController.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockClusterController.resps = append(mockClusterController.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var projectId string = "projectId-1969970175" var region string = "region-934795532" var clusterName string = "clusterName-1018081872" var request = &dataprocpb.DeleteClusterRequest{ ProjectId: projectId, Region: region, ClusterName: clusterName, } c, err := NewClusterControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.DeleteCluster(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockClusterController.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestClusterControllerDeleteClusterError(t *testing.T) { errCode := codes.PermissionDenied mockClusterController.err = nil mockClusterController.resps = append(mockClusterController.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var projectId string = "projectId-1969970175" var region string = "region-934795532" var clusterName string = "clusterName-1018081872" var request = &dataprocpb.DeleteClusterRequest{ ProjectId: projectId, Region: region, ClusterName: clusterName, } c, err := NewClusterControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.DeleteCluster(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestClusterControllerGetCluster(t *testing.T) { var projectId2 string = "projectId2939242356" var clusterName2 string = "clusterName2875867491" var clusterUuid string = "clusterUuid-1017854240" var expectedResponse = &dataprocpb.Cluster{ ProjectId: projectId2, ClusterName: clusterName2, ClusterUuid: clusterUuid, } mockClusterController.err = nil mockClusterController.reqs = nil mockClusterController.resps = append(mockClusterController.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var region string = "region-934795532" var clusterName string = "clusterName-1018081872" var request = &dataprocpb.GetClusterRequest{ ProjectId: projectId, Region: region, ClusterName: clusterName, } c, err := NewClusterControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetCluster(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockClusterController.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestClusterControllerGetClusterError(t *testing.T) { errCode := codes.PermissionDenied mockClusterController.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var region string = "region-934795532" var clusterName string = "clusterName-1018081872" var request = &dataprocpb.GetClusterRequest{ ProjectId: projectId, Region: region, ClusterName: clusterName, } c, err := NewClusterControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetCluster(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestClusterControllerListClusters(t *testing.T) { var nextPageToken string = "" var clustersElement *dataprocpb.Cluster = &dataprocpb.Cluster{} var clusters = []*dataprocpb.Cluster{clustersElement} var expectedResponse = &dataprocpb.ListClustersResponse{ NextPageToken: nextPageToken, Clusters: clusters, } mockClusterController.err = nil mockClusterController.reqs = nil mockClusterController.resps = append(mockClusterController.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var region string = "region-934795532" var request = &dataprocpb.ListClustersRequest{ ProjectId: projectId, Region: region, } c, err := NewClusterControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListClusters(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockClusterController.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Clusters[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestClusterControllerListClustersError(t *testing.T) { errCode := codes.PermissionDenied mockClusterController.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var region string = "region-934795532" var request = &dataprocpb.ListClustersRequest{ ProjectId: projectId, Region: region, } c, err := NewClusterControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListClusters(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestClusterControllerDiagnoseCluster(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockClusterController.err = nil mockClusterController.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockClusterController.resps = append(mockClusterController.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var projectId string = "projectId-1969970175" var region string = "region-934795532" var clusterName string = "clusterName-1018081872" var request = &dataprocpb.DiagnoseClusterRequest{ ProjectId: projectId, Region: region, ClusterName: clusterName, } c, err := NewClusterControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.DiagnoseCluster(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockClusterController.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestClusterControllerDiagnoseClusterError(t *testing.T) { errCode := codes.PermissionDenied mockClusterController.err = nil mockClusterController.resps = append(mockClusterController.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var projectId string = "projectId-1969970175" var region string = "region-934795532" var clusterName string = "clusterName-1018081872" var request = &dataprocpb.DiagnoseClusterRequest{ ProjectId: projectId, Region: region, ClusterName: clusterName, } c, err := NewClusterControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.DiagnoseCluster(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestJobControllerSubmitJob(t *testing.T) { var driverOutputResourceUri string = "driverOutputResourceUri-542229086" var driverControlFilesUri string = "driverControlFilesUri207057643" var jobUuid string = "jobUuid-1615012099" var expectedResponse = &dataprocpb.Job{ DriverOutputResourceUri: driverOutputResourceUri, DriverControlFilesUri: driverControlFilesUri, JobUuid: jobUuid, } mockJobController.err = nil mockJobController.reqs = nil mockJobController.resps = append(mockJobController.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var region string = "region-934795532" var job *dataprocpb.Job = &dataprocpb.Job{} var request = &dataprocpb.SubmitJobRequest{ ProjectId: projectId, Region: region, Job: job, } c, err := NewJobControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SubmitJob(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockJobController.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestJobControllerSubmitJobError(t *testing.T) { errCode := codes.PermissionDenied mockJobController.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var region string = "region-934795532" var job *dataprocpb.Job = &dataprocpb.Job{} var request = &dataprocpb.SubmitJobRequest{ ProjectId: projectId, Region: region, Job: job, } c, err := NewJobControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SubmitJob(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestJobControllerGetJob(t *testing.T) { var driverOutputResourceUri string = "driverOutputResourceUri-542229086" var driverControlFilesUri string = "driverControlFilesUri207057643" var jobUuid string = "jobUuid-1615012099" var expectedResponse = &dataprocpb.Job{ DriverOutputResourceUri: driverOutputResourceUri, DriverControlFilesUri: driverControlFilesUri, JobUuid: jobUuid, } mockJobController.err = nil mockJobController.reqs = nil mockJobController.resps = append(mockJobController.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var region string = "region-934795532" var jobId string = "jobId-1154752291" var request = &dataprocpb.GetJobRequest{ ProjectId: projectId, Region: region, JobId: jobId, } c, err := NewJobControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetJob(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockJobController.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestJobControllerGetJobError(t *testing.T) { errCode := codes.PermissionDenied mockJobController.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var region string = "region-934795532" var jobId string = "jobId-1154752291" var request = &dataprocpb.GetJobRequest{ ProjectId: projectId, Region: region, JobId: jobId, } c, err := NewJobControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetJob(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestJobControllerListJobs(t *testing.T) { var nextPageToken string = "" var jobsElement *dataprocpb.Job = &dataprocpb.Job{} var jobs = []*dataprocpb.Job{jobsElement} var expectedResponse = &dataprocpb.ListJobsResponse{ NextPageToken: nextPageToken, Jobs: jobs, } mockJobController.err = nil mockJobController.reqs = nil mockJobController.resps = append(mockJobController.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var region string = "region-934795532" var request = &dataprocpb.ListJobsRequest{ ProjectId: projectId, Region: region, } c, err := NewJobControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListJobs(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockJobController.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Jobs[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestJobControllerListJobsError(t *testing.T) { errCode := codes.PermissionDenied mockJobController.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var region string = "region-934795532" var request = &dataprocpb.ListJobsRequest{ ProjectId: projectId, Region: region, } c, err := NewJobControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListJobs(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestJobControllerUpdateJob(t *testing.T) { var driverOutputResourceUri string = "driverOutputResourceUri-542229086" var driverControlFilesUri string = "driverControlFilesUri207057643" var jobUuid string = "jobUuid-1615012099" var expectedResponse = &dataprocpb.Job{ DriverOutputResourceUri: driverOutputResourceUri, DriverControlFilesUri: driverControlFilesUri, JobUuid: jobUuid, } mockJobController.err = nil mockJobController.reqs = nil mockJobController.resps = append(mockJobController.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var region string = "region-934795532" var jobId string = "jobId-1154752291" var job *dataprocpb.Job = &dataprocpb.Job{} var updateMask *field_maskpb.FieldMask = &field_maskpb.FieldMask{} var request = &dataprocpb.UpdateJobRequest{ ProjectId: projectId, Region: region, JobId: jobId, Job: job, UpdateMask: updateMask, } c, err := NewJobControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateJob(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockJobController.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestJobControllerUpdateJobError(t *testing.T) { errCode := codes.PermissionDenied mockJobController.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var region string = "region-934795532" var jobId string = "jobId-1154752291" var job *dataprocpb.Job = &dataprocpb.Job{} var updateMask *field_maskpb.FieldMask = &field_maskpb.FieldMask{} var request = &dataprocpb.UpdateJobRequest{ ProjectId: projectId, Region: region, JobId: jobId, Job: job, UpdateMask: updateMask, } c, err := NewJobControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateJob(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestJobControllerCancelJob(t *testing.T) { var driverOutputResourceUri string = "driverOutputResourceUri-542229086" var driverControlFilesUri string = "driverControlFilesUri207057643" var jobUuid string = "jobUuid-1615012099" var expectedResponse = &dataprocpb.Job{ DriverOutputResourceUri: driverOutputResourceUri, DriverControlFilesUri: driverControlFilesUri, JobUuid: jobUuid, } mockJobController.err = nil mockJobController.reqs = nil mockJobController.resps = append(mockJobController.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var region string = "region-934795532" var jobId string = "jobId-1154752291" var request = &dataprocpb.CancelJobRequest{ ProjectId: projectId, Region: region, JobId: jobId, } c, err := NewJobControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CancelJob(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockJobController.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestJobControllerCancelJobError(t *testing.T) { errCode := codes.PermissionDenied mockJobController.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var region string = "region-934795532" var jobId string = "jobId-1154752291" var request = &dataprocpb.CancelJobRequest{ ProjectId: projectId, Region: region, JobId: jobId, } c, err := NewJobControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CancelJob(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestJobControllerDeleteJob(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockJobController.err = nil mockJobController.reqs = nil mockJobController.resps = append(mockJobController.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var region string = "region-934795532" var jobId string = "jobId-1154752291" var request = &dataprocpb.DeleteJobRequest{ ProjectId: projectId, Region: region, JobId: jobId, } c, err := NewJobControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteJob(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockJobController.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestJobControllerDeleteJobError(t *testing.T) { errCode := codes.PermissionDenied mockJobController.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var region string = "region-934795532" var jobId string = "jobId-1154752291" var request = &dataprocpb.DeleteJobRequest{ ProjectId: projectId, Region: region, JobId: jobId, } c, err := NewJobControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteJob(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestWorkflowTemplateServiceCreateWorkflowTemplate(t *testing.T) { var id string = "id3355" var name string = "name3373707" var version int32 = 351608024 var expectedResponse = &dataprocpb.WorkflowTemplate{ Id: id, Name: name, Version: version, } mockWorkflowTemplate.err = nil mockWorkflowTemplate.reqs = nil mockWorkflowTemplate.resps = append(mockWorkflowTemplate.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/regions/%s", "[PROJECT]", "[REGION]") var template *dataprocpb.WorkflowTemplate = &dataprocpb.WorkflowTemplate{} var request = &dataprocpb.CreateWorkflowTemplateRequest{ Parent: formattedParent, Template: template, } c, err := NewWorkflowTemplateClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateWorkflowTemplate(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockWorkflowTemplate.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestWorkflowTemplateServiceCreateWorkflowTemplateError(t *testing.T) { errCode := codes.PermissionDenied mockWorkflowTemplate.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/regions/%s", "[PROJECT]", "[REGION]") var template *dataprocpb.WorkflowTemplate = &dataprocpb.WorkflowTemplate{} var request = &dataprocpb.CreateWorkflowTemplateRequest{ Parent: formattedParent, Template: template, } c, err := NewWorkflowTemplateClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateWorkflowTemplate(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestWorkflowTemplateServiceGetWorkflowTemplate(t *testing.T) { var id string = "id3355" var name2 string = "name2-1052831874" var version int32 = 351608024 var expectedResponse = &dataprocpb.WorkflowTemplate{ Id: id, Name: name2, Version: version, } mockWorkflowTemplate.err = nil mockWorkflowTemplate.reqs = nil mockWorkflowTemplate.resps = append(mockWorkflowTemplate.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/regions/%s/workflowTemplates/%s", "[PROJECT]", "[REGION]", "[WORKFLOW_TEMPLATE]") var request = &dataprocpb.GetWorkflowTemplateRequest{ Name: formattedName, } c, err := NewWorkflowTemplateClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetWorkflowTemplate(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockWorkflowTemplate.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestWorkflowTemplateServiceGetWorkflowTemplateError(t *testing.T) { errCode := codes.PermissionDenied mockWorkflowTemplate.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/regions/%s/workflowTemplates/%s", "[PROJECT]", "[REGION]", "[WORKFLOW_TEMPLATE]") var request = &dataprocpb.GetWorkflowTemplateRequest{ Name: formattedName, } c, err := NewWorkflowTemplateClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetWorkflowTemplate(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestWorkflowTemplateServiceInstantiateWorkflowTemplate(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockWorkflowTemplate.err = nil mockWorkflowTemplate.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockWorkflowTemplate.resps = append(mockWorkflowTemplate.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedName string = fmt.Sprintf("projects/%s/regions/%s/workflowTemplates/%s", "[PROJECT]", "[REGION]", "[WORKFLOW_TEMPLATE]") var request = &dataprocpb.InstantiateWorkflowTemplateRequest{ Name: formattedName, } c, err := NewWorkflowTemplateClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.InstantiateWorkflowTemplate(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockWorkflowTemplate.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestWorkflowTemplateServiceInstantiateWorkflowTemplateError(t *testing.T) { errCode := codes.PermissionDenied mockWorkflowTemplate.err = nil mockWorkflowTemplate.resps = append(mockWorkflowTemplate.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedName string = fmt.Sprintf("projects/%s/regions/%s/workflowTemplates/%s", "[PROJECT]", "[REGION]", "[WORKFLOW_TEMPLATE]") var request = &dataprocpb.InstantiateWorkflowTemplateRequest{ Name: formattedName, } c, err := NewWorkflowTemplateClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.InstantiateWorkflowTemplate(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestWorkflowTemplateServiceInstantiateInlineWorkflowTemplate(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockWorkflowTemplate.err = nil mockWorkflowTemplate.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockWorkflowTemplate.resps = append(mockWorkflowTemplate.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedParent string = fmt.Sprintf("projects/%s/regions/%s", "[PROJECT]", "[REGION]") var template *dataprocpb.WorkflowTemplate = &dataprocpb.WorkflowTemplate{} var request = &dataprocpb.InstantiateInlineWorkflowTemplateRequest{ Parent: formattedParent, Template: template, } c, err := NewWorkflowTemplateClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.InstantiateInlineWorkflowTemplate(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockWorkflowTemplate.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestWorkflowTemplateServiceInstantiateInlineWorkflowTemplateError(t *testing.T) { errCode := codes.PermissionDenied mockWorkflowTemplate.err = nil mockWorkflowTemplate.resps = append(mockWorkflowTemplate.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedParent string = fmt.Sprintf("projects/%s/regions/%s", "[PROJECT]", "[REGION]") var template *dataprocpb.WorkflowTemplate = &dataprocpb.WorkflowTemplate{} var request = &dataprocpb.InstantiateInlineWorkflowTemplateRequest{ Parent: formattedParent, Template: template, } c, err := NewWorkflowTemplateClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.InstantiateInlineWorkflowTemplate(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestWorkflowTemplateServiceUpdateWorkflowTemplate(t *testing.T) { var id string = "id3355" var name string = "name3373707" var version int32 = 351608024 var expectedResponse = &dataprocpb.WorkflowTemplate{ Id: id, Name: name, Version: version, } mockWorkflowTemplate.err = nil mockWorkflowTemplate.reqs = nil mockWorkflowTemplate.resps = append(mockWorkflowTemplate.resps[:0], expectedResponse) var template *dataprocpb.WorkflowTemplate = &dataprocpb.WorkflowTemplate{} var request = &dataprocpb.UpdateWorkflowTemplateRequest{ Template: template, } c, err := NewWorkflowTemplateClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateWorkflowTemplate(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockWorkflowTemplate.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestWorkflowTemplateServiceUpdateWorkflowTemplateError(t *testing.T) { errCode := codes.PermissionDenied mockWorkflowTemplate.err = gstatus.Error(errCode, "test error") var template *dataprocpb.WorkflowTemplate = &dataprocpb.WorkflowTemplate{} var request = &dataprocpb.UpdateWorkflowTemplateRequest{ Template: template, } c, err := NewWorkflowTemplateClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateWorkflowTemplate(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestWorkflowTemplateServiceListWorkflowTemplates(t *testing.T) { var nextPageToken string = "" var templatesElement *dataprocpb.WorkflowTemplate = &dataprocpb.WorkflowTemplate{} var templates = []*dataprocpb.WorkflowTemplate{templatesElement} var expectedResponse = &dataprocpb.ListWorkflowTemplatesResponse{ NextPageToken: nextPageToken, Templates: templates, } mockWorkflowTemplate.err = nil mockWorkflowTemplate.reqs = nil mockWorkflowTemplate.resps = append(mockWorkflowTemplate.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/regions/%s", "[PROJECT]", "[REGION]") var request = &dataprocpb.ListWorkflowTemplatesRequest{ Parent: formattedParent, } c, err := NewWorkflowTemplateClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListWorkflowTemplates(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockWorkflowTemplate.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Templates[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestWorkflowTemplateServiceListWorkflowTemplatesError(t *testing.T) { errCode := codes.PermissionDenied mockWorkflowTemplate.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/regions/%s", "[PROJECT]", "[REGION]") var request = &dataprocpb.ListWorkflowTemplatesRequest{ Parent: formattedParent, } c, err := NewWorkflowTemplateClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListWorkflowTemplates(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestWorkflowTemplateServiceDeleteWorkflowTemplate(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockWorkflowTemplate.err = nil mockWorkflowTemplate.reqs = nil mockWorkflowTemplate.resps = append(mockWorkflowTemplate.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/regions/%s/workflowTemplates/%s", "[PROJECT]", "[REGION]", "[WORKFLOW_TEMPLATE]") var request = &dataprocpb.DeleteWorkflowTemplateRequest{ Name: formattedName, } c, err := NewWorkflowTemplateClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteWorkflowTemplate(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockWorkflowTemplate.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestWorkflowTemplateServiceDeleteWorkflowTemplateError(t *testing.T) { errCode := codes.PermissionDenied mockWorkflowTemplate.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/regions/%s/workflowTemplates/%s", "[PROJECT]", "[REGION]", "[WORKFLOW_TEMPLATE]") var request = &dataprocpb.DeleteWorkflowTemplateRequest{ Name: formattedName, } c, err := NewWorkflowTemplateClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteWorkflowTemplate(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } google-cloud-go-0.49.0/dataproc/apiv1/workflow_template_client.go000066400000000000000000000534361356504100700250520ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package dataproc import ( "context" "fmt" "math" "net/url" "time" "cloud.google.com/go/longrunning" lroauto "cloud.google.com/go/longrunning/autogen" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" dataprocpb "google.golang.org/genproto/googleapis/cloud/dataproc/v1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // WorkflowTemplateCallOptions contains the retry settings for each method of WorkflowTemplateClient. type WorkflowTemplateCallOptions struct { CreateWorkflowTemplate []gax.CallOption GetWorkflowTemplate []gax.CallOption InstantiateWorkflowTemplate []gax.CallOption InstantiateInlineWorkflowTemplate []gax.CallOption UpdateWorkflowTemplate []gax.CallOption ListWorkflowTemplates []gax.CallOption DeleteWorkflowTemplate []gax.CallOption } func defaultWorkflowTemplateClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("dataproc.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultWorkflowTemplateCallOptions() *WorkflowTemplateCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Internal, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, {"default", "non_idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &WorkflowTemplateCallOptions{ CreateWorkflowTemplate: retry[[2]string{"default", "non_idempotent"}], GetWorkflowTemplate: retry[[2]string{"default", "idempotent"}], InstantiateWorkflowTemplate: retry[[2]string{"default", "non_idempotent"}], InstantiateInlineWorkflowTemplate: retry[[2]string{"default", "non_idempotent"}], UpdateWorkflowTemplate: retry[[2]string{"default", "non_idempotent"}], ListWorkflowTemplates: retry[[2]string{"default", "idempotent"}], DeleteWorkflowTemplate: retry[[2]string{"default", "non_idempotent"}], } } // WorkflowTemplateClient is a client for interacting with Google Cloud Dataproc API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type WorkflowTemplateClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. workflowTemplateClient dataprocpb.WorkflowTemplateServiceClient // LROClient is used internally to handle longrunning operations. // It is exposed so that its CallOptions can be modified if required. // Users should not Close this client. LROClient *lroauto.OperationsClient // The call options for this service. CallOptions *WorkflowTemplateCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewWorkflowTemplateClient creates a new workflow template service client. // // The API interface for managing Workflow Templates in the // Cloud Dataproc API. func NewWorkflowTemplateClient(ctx context.Context, opts ...option.ClientOption) (*WorkflowTemplateClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultWorkflowTemplateClientOptions(), opts...)...) if err != nil { return nil, err } c := &WorkflowTemplateClient{ conn: conn, CallOptions: defaultWorkflowTemplateCallOptions(), workflowTemplateClient: dataprocpb.NewWorkflowTemplateServiceClient(conn), } c.setGoogleClientInfo() c.LROClient, err = lroauto.NewOperationsClient(ctx, option.WithGRPCConn(conn)) if err != nil { // This error "should not happen", since we are just reusing old connection // and never actually need to dial. // If this does happen, we could leak conn. However, we cannot close conn: // If the user invoked the function with option.WithGRPCConn, // we would close a connection that's still in use. // TODO(pongad): investigate error conditions. return nil, err } return c, nil } // Connection returns the client's connection to the API service. func (c *WorkflowTemplateClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *WorkflowTemplateClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *WorkflowTemplateClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // CreateWorkflowTemplate creates new workflow template. func (c *WorkflowTemplateClient) CreateWorkflowTemplate(ctx context.Context, req *dataprocpb.CreateWorkflowTemplateRequest, opts ...gax.CallOption) (*dataprocpb.WorkflowTemplate, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateWorkflowTemplate[0:len(c.CallOptions.CreateWorkflowTemplate):len(c.CallOptions.CreateWorkflowTemplate)], opts...) var resp *dataprocpb.WorkflowTemplate err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.workflowTemplateClient.CreateWorkflowTemplate(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetWorkflowTemplate retrieves the latest workflow template. // // Can retrieve previously instantiated template by specifying optional // version parameter. func (c *WorkflowTemplateClient) GetWorkflowTemplate(ctx context.Context, req *dataprocpb.GetWorkflowTemplateRequest, opts ...gax.CallOption) (*dataprocpb.WorkflowTemplate, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetWorkflowTemplate[0:len(c.CallOptions.GetWorkflowTemplate):len(c.CallOptions.GetWorkflowTemplate)], opts...) var resp *dataprocpb.WorkflowTemplate err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.workflowTemplateClient.GetWorkflowTemplate(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // InstantiateWorkflowTemplate instantiates a template and begins execution. // // The returned Operation can be used to track execution of // workflow by polling // [operations.get][google.longrunning.Operations.GetOperation]. // The Operation will complete when entire workflow is finished. // // The running workflow can be aborted via // [operations.cancel][google.longrunning.Operations.CancelOperation]. // This will cause any inflight jobs to be cancelled and workflow-owned // clusters to be deleted. // // The [Operation.metadata][google.longrunning.Operation.metadata] will be // WorkflowMetadata (at /dataproc/docs/reference/rpc/google.cloud.dataproc.v1#workflowmetadata). // Also see Using // WorkflowMetadata (at /dataproc/docs/concepts/workflows/debugging#using_workflowmetadata). // // On successful completion, // [Operation.response][google.longrunning.Operation.response] will be // [Empty][google.protobuf.Empty]. func (c *WorkflowTemplateClient) InstantiateWorkflowTemplate(ctx context.Context, req *dataprocpb.InstantiateWorkflowTemplateRequest, opts ...gax.CallOption) (*InstantiateWorkflowTemplateOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.InstantiateWorkflowTemplate[0:len(c.CallOptions.InstantiateWorkflowTemplate):len(c.CallOptions.InstantiateWorkflowTemplate)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.workflowTemplateClient.InstantiateWorkflowTemplate(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &InstantiateWorkflowTemplateOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // InstantiateInlineWorkflowTemplate instantiates a template and begins execution. // // This method is equivalent to executing the sequence // [CreateWorkflowTemplate][google.cloud.dataproc.v1.WorkflowTemplateService.CreateWorkflowTemplate], [InstantiateWorkflowTemplate][google.cloud.dataproc.v1.WorkflowTemplateService.InstantiateWorkflowTemplate], // [DeleteWorkflowTemplate][google.cloud.dataproc.v1.WorkflowTemplateService.DeleteWorkflowTemplate]. // // The returned Operation can be used to track execution of // workflow by polling // [operations.get][google.longrunning.Operations.GetOperation]. // The Operation will complete when entire workflow is finished. // // The running workflow can be aborted via // [operations.cancel][google.longrunning.Operations.CancelOperation]. // This will cause any inflight jobs to be cancelled and workflow-owned // clusters to be deleted. // // The [Operation.metadata][google.longrunning.Operation.metadata] will be // WorkflowMetadata (at /dataproc/docs/reference/rpc/google.cloud.dataproc.v1#workflowmetadata). // Also see Using // WorkflowMetadata (at /dataproc/docs/concepts/workflows/debugging#using_workflowmetadata). // // On successful completion, // [Operation.response][google.longrunning.Operation.response] will be // [Empty][google.protobuf.Empty]. func (c *WorkflowTemplateClient) InstantiateInlineWorkflowTemplate(ctx context.Context, req *dataprocpb.InstantiateInlineWorkflowTemplateRequest, opts ...gax.CallOption) (*InstantiateInlineWorkflowTemplateOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.InstantiateInlineWorkflowTemplate[0:len(c.CallOptions.InstantiateInlineWorkflowTemplate):len(c.CallOptions.InstantiateInlineWorkflowTemplate)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.workflowTemplateClient.InstantiateInlineWorkflowTemplate(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &InstantiateInlineWorkflowTemplateOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // UpdateWorkflowTemplate updates (replaces) workflow template. The updated template // must contain version that matches the current server version. func (c *WorkflowTemplateClient) UpdateWorkflowTemplate(ctx context.Context, req *dataprocpb.UpdateWorkflowTemplateRequest, opts ...gax.CallOption) (*dataprocpb.WorkflowTemplate, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "template.name", url.QueryEscape(req.GetTemplate().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateWorkflowTemplate[0:len(c.CallOptions.UpdateWorkflowTemplate):len(c.CallOptions.UpdateWorkflowTemplate)], opts...) var resp *dataprocpb.WorkflowTemplate err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.workflowTemplateClient.UpdateWorkflowTemplate(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListWorkflowTemplates lists workflows that match the specified filter in the request. func (c *WorkflowTemplateClient) ListWorkflowTemplates(ctx context.Context, req *dataprocpb.ListWorkflowTemplatesRequest, opts ...gax.CallOption) *WorkflowTemplateIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListWorkflowTemplates[0:len(c.CallOptions.ListWorkflowTemplates):len(c.CallOptions.ListWorkflowTemplates)], opts...) it := &WorkflowTemplateIterator{} req = proto.Clone(req).(*dataprocpb.ListWorkflowTemplatesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*dataprocpb.WorkflowTemplate, string, error) { var resp *dataprocpb.ListWorkflowTemplatesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.workflowTemplateClient.ListWorkflowTemplates(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Templates, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // DeleteWorkflowTemplate deletes a workflow template. It does not cancel in-progress workflows. func (c *WorkflowTemplateClient) DeleteWorkflowTemplate(ctx context.Context, req *dataprocpb.DeleteWorkflowTemplateRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteWorkflowTemplate[0:len(c.CallOptions.DeleteWorkflowTemplate):len(c.CallOptions.DeleteWorkflowTemplate)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.workflowTemplateClient.DeleteWorkflowTemplate(ctx, req, settings.GRPC...) return err }, opts...) return err } // WorkflowTemplateIterator manages a stream of *dataprocpb.WorkflowTemplate. type WorkflowTemplateIterator struct { items []*dataprocpb.WorkflowTemplate pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*dataprocpb.WorkflowTemplate, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *WorkflowTemplateIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *WorkflowTemplateIterator) Next() (*dataprocpb.WorkflowTemplate, error) { var item *dataprocpb.WorkflowTemplate if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *WorkflowTemplateIterator) bufLen() int { return len(it.items) } func (it *WorkflowTemplateIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // InstantiateInlineWorkflowTemplateOperation manages a long-running operation from InstantiateInlineWorkflowTemplate. type InstantiateInlineWorkflowTemplateOperation struct { lro *longrunning.Operation } // InstantiateInlineWorkflowTemplateOperation returns a new InstantiateInlineWorkflowTemplateOperation from a given name. // The name must be that of a previously created InstantiateInlineWorkflowTemplateOperation, possibly from a different process. func (c *WorkflowTemplateClient) InstantiateInlineWorkflowTemplateOperation(name string) *InstantiateInlineWorkflowTemplateOperation { return &InstantiateInlineWorkflowTemplateOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning any error encountered. // // See documentation of Poll for error-handling information. func (op *InstantiateInlineWorkflowTemplateOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { return op.lro.WaitWithInterval(ctx, nil, 10000*time.Millisecond, opts...) } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, op.Done will return true. func (op *InstantiateInlineWorkflowTemplateOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Poll(ctx, nil, opts...) } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *InstantiateInlineWorkflowTemplateOperation) Metadata() (*dataprocpb.WorkflowMetadata, error) { var meta dataprocpb.WorkflowMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *InstantiateInlineWorkflowTemplateOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *InstantiateInlineWorkflowTemplateOperation) Name() string { return op.lro.Name() } // InstantiateWorkflowTemplateOperation manages a long-running operation from InstantiateWorkflowTemplate. type InstantiateWorkflowTemplateOperation struct { lro *longrunning.Operation } // InstantiateWorkflowTemplateOperation returns a new InstantiateWorkflowTemplateOperation from a given name. // The name must be that of a previously created InstantiateWorkflowTemplateOperation, possibly from a different process. func (c *WorkflowTemplateClient) InstantiateWorkflowTemplateOperation(name string) *InstantiateWorkflowTemplateOperation { return &InstantiateWorkflowTemplateOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning any error encountered. // // See documentation of Poll for error-handling information. func (op *InstantiateWorkflowTemplateOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { return op.lro.WaitWithInterval(ctx, nil, 10000*time.Millisecond, opts...) } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, op.Done will return true. func (op *InstantiateWorkflowTemplateOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Poll(ctx, nil, opts...) } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *InstantiateWorkflowTemplateOperation) Metadata() (*dataprocpb.WorkflowMetadata, error) { var meta dataprocpb.WorkflowMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *InstantiateWorkflowTemplateOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *InstantiateWorkflowTemplateOperation) Name() string { return op.lro.Name() } google-cloud-go-0.49.0/dataproc/apiv1/workflow_template_client_example_test.go000066400000000000000000000076301356504100700276170ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package dataproc_test import ( "context" dataproc "cloud.google.com/go/dataproc/apiv1" "google.golang.org/api/iterator" dataprocpb "google.golang.org/genproto/googleapis/cloud/dataproc/v1" ) func ExampleNewWorkflowTemplateClient() { ctx := context.Background() c, err := dataproc.NewWorkflowTemplateClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleWorkflowTemplateClient_CreateWorkflowTemplate() { ctx := context.Background() c, err := dataproc.NewWorkflowTemplateClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.CreateWorkflowTemplateRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateWorkflowTemplate(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleWorkflowTemplateClient_GetWorkflowTemplate() { ctx := context.Background() c, err := dataproc.NewWorkflowTemplateClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.GetWorkflowTemplateRequest{ // TODO: Fill request struct fields. } resp, err := c.GetWorkflowTemplate(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleWorkflowTemplateClient_InstantiateWorkflowTemplate() { ctx := context.Background() c, err := dataproc.NewWorkflowTemplateClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.InstantiateWorkflowTemplateRequest{ // TODO: Fill request struct fields. } op, err := c.InstantiateWorkflowTemplate(ctx, req) if err != nil { // TODO: Handle error. } err = op.Wait(ctx) // TODO: Handle error. } func ExampleWorkflowTemplateClient_InstantiateInlineWorkflowTemplate() { ctx := context.Background() c, err := dataproc.NewWorkflowTemplateClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.InstantiateInlineWorkflowTemplateRequest{ // TODO: Fill request struct fields. } op, err := c.InstantiateInlineWorkflowTemplate(ctx, req) if err != nil { // TODO: Handle error. } err = op.Wait(ctx) // TODO: Handle error. } func ExampleWorkflowTemplateClient_UpdateWorkflowTemplate() { ctx := context.Background() c, err := dataproc.NewWorkflowTemplateClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.UpdateWorkflowTemplateRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateWorkflowTemplate(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleWorkflowTemplateClient_ListWorkflowTemplates() { ctx := context.Background() c, err := dataproc.NewWorkflowTemplateClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.ListWorkflowTemplatesRequest{ // TODO: Fill request struct fields. } it := c.ListWorkflowTemplates(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleWorkflowTemplateClient_DeleteWorkflowTemplate() { ctx := context.Background() c, err := dataproc.NewWorkflowTemplateClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.DeleteWorkflowTemplateRequest{ // TODO: Fill request struct fields. } err = c.DeleteWorkflowTemplate(ctx, req) if err != nil { // TODO: Handle error. } } google-cloud-go-0.49.0/dataproc/apiv1beta2/000077500000000000000000000000001356504100700203235ustar00rootroot00000000000000google-cloud-go-0.49.0/dataproc/apiv1beta2/.repo-metadata.json000066400000000000000000000006721356504100700240240ustar00rootroot00000000000000{ "name": "dataproc", "name_pretty": "Cloud-native Apache Hadoop & Apache Spark API", "product_documentation": "https://cloud.google.com/dataproc", "client_documentation": "https://godoc.org/cloud.google.com/go/dataproc/apiv1beta2", "release_level": "beta", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "dataproc.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/dataproc/apiv1beta2/ListClusters_smoke_test.go000066400000000000000000000032751356504100700255560ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package dataproc import ( "context" "fmt" "strconv" "testing" "time" "cloud.google.com/go/internal/testutil" "google.golang.org/api/iterator" "google.golang.org/api/option" dataprocpb "google.golang.org/genproto/googleapis/cloud/dataproc/v1beta2" ) var _ = fmt.Sprintf var _ = iterator.Done var _ = strconv.FormatUint var _ = time.Now func TestClusterControllerSmoke(t *testing.T) { if testing.Short() { t.Skip("skipping smoke test in short mode") } ctx := context.Background() ts := testutil.TokenSource(ctx, DefaultAuthScopes()...) if ts == nil { t.Skip("Integration tests skipped. See CONTRIBUTING.md for details") } projectId := testutil.ProjID() _ = projectId c, err := NewClusterControllerClient(ctx, option.WithTokenSource(ts)) if err != nil { t.Fatal(err) } var projectId2 string = projectId var region string = "global" var request = &dataprocpb.ListClustersRequest{ ProjectId: projectId2, Region: region, } iter := c.ListClusters(ctx, request) if _, err := iter.Next(); err != nil && err != iterator.Done { t.Error(err) } } google-cloud-go-0.49.0/dataproc/apiv1beta2/autoscaling_policy_client.go000066400000000000000000000261341356504100700261060ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package dataproc import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" dataprocpb "google.golang.org/genproto/googleapis/cloud/dataproc/v1beta2" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // AutoscalingPolicyCallOptions contains the retry settings for each method of AutoscalingPolicyClient. type AutoscalingPolicyCallOptions struct { CreateAutoscalingPolicy []gax.CallOption UpdateAutoscalingPolicy []gax.CallOption GetAutoscalingPolicy []gax.CallOption ListAutoscalingPolicies []gax.CallOption DeleteAutoscalingPolicy []gax.CallOption } func defaultAutoscalingPolicyClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("dataproc.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultAutoscalingPolicyCallOptions() *AutoscalingPolicyCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &AutoscalingPolicyCallOptions{ CreateAutoscalingPolicy: retry[[2]string{"default", "non_idempotent"}], UpdateAutoscalingPolicy: retry[[2]string{"default", "idempotent"}], GetAutoscalingPolicy: retry[[2]string{"default", "idempotent"}], ListAutoscalingPolicies: retry[[2]string{"default", "idempotent"}], DeleteAutoscalingPolicy: retry[[2]string{"default", "non_idempotent"}], } } // AutoscalingPolicyClient is a client for interacting with Google Cloud Dataproc API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type AutoscalingPolicyClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. autoscalingPolicyClient dataprocpb.AutoscalingPolicyServiceClient // The call options for this service. CallOptions *AutoscalingPolicyCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewAutoscalingPolicyClient creates a new autoscaling policy service client. // // The API interface for managing autoscaling policies in the // Google Cloud Dataproc API. func NewAutoscalingPolicyClient(ctx context.Context, opts ...option.ClientOption) (*AutoscalingPolicyClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultAutoscalingPolicyClientOptions(), opts...)...) if err != nil { return nil, err } c := &AutoscalingPolicyClient{ conn: conn, CallOptions: defaultAutoscalingPolicyCallOptions(), autoscalingPolicyClient: dataprocpb.NewAutoscalingPolicyServiceClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *AutoscalingPolicyClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *AutoscalingPolicyClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *AutoscalingPolicyClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // CreateAutoscalingPolicy creates new autoscaling policy. func (c *AutoscalingPolicyClient) CreateAutoscalingPolicy(ctx context.Context, req *dataprocpb.CreateAutoscalingPolicyRequest, opts ...gax.CallOption) (*dataprocpb.AutoscalingPolicy, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateAutoscalingPolicy[0:len(c.CallOptions.CreateAutoscalingPolicy):len(c.CallOptions.CreateAutoscalingPolicy)], opts...) var resp *dataprocpb.AutoscalingPolicy err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.autoscalingPolicyClient.CreateAutoscalingPolicy(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateAutoscalingPolicy updates (replaces) autoscaling policy. // // Disabled check for update_mask, because all updates will be full // replacements. func (c *AutoscalingPolicyClient) UpdateAutoscalingPolicy(ctx context.Context, req *dataprocpb.UpdateAutoscalingPolicyRequest, opts ...gax.CallOption) (*dataprocpb.AutoscalingPolicy, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "policy.name", url.QueryEscape(req.GetPolicy().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateAutoscalingPolicy[0:len(c.CallOptions.UpdateAutoscalingPolicy):len(c.CallOptions.UpdateAutoscalingPolicy)], opts...) var resp *dataprocpb.AutoscalingPolicy err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.autoscalingPolicyClient.UpdateAutoscalingPolicy(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetAutoscalingPolicy retrieves autoscaling policy. func (c *AutoscalingPolicyClient) GetAutoscalingPolicy(ctx context.Context, req *dataprocpb.GetAutoscalingPolicyRequest, opts ...gax.CallOption) (*dataprocpb.AutoscalingPolicy, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetAutoscalingPolicy[0:len(c.CallOptions.GetAutoscalingPolicy):len(c.CallOptions.GetAutoscalingPolicy)], opts...) var resp *dataprocpb.AutoscalingPolicy err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.autoscalingPolicyClient.GetAutoscalingPolicy(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListAutoscalingPolicies lists autoscaling policies in the project. func (c *AutoscalingPolicyClient) ListAutoscalingPolicies(ctx context.Context, req *dataprocpb.ListAutoscalingPoliciesRequest, opts ...gax.CallOption) *AutoscalingPolicyIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListAutoscalingPolicies[0:len(c.CallOptions.ListAutoscalingPolicies):len(c.CallOptions.ListAutoscalingPolicies)], opts...) it := &AutoscalingPolicyIterator{} req = proto.Clone(req).(*dataprocpb.ListAutoscalingPoliciesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*dataprocpb.AutoscalingPolicy, string, error) { var resp *dataprocpb.ListAutoscalingPoliciesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.autoscalingPolicyClient.ListAutoscalingPolicies(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Policies, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // DeleteAutoscalingPolicy deletes an autoscaling policy. It is an error to delete an autoscaling // policy that is in use by one or more clusters. func (c *AutoscalingPolicyClient) DeleteAutoscalingPolicy(ctx context.Context, req *dataprocpb.DeleteAutoscalingPolicyRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteAutoscalingPolicy[0:len(c.CallOptions.DeleteAutoscalingPolicy):len(c.CallOptions.DeleteAutoscalingPolicy)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.autoscalingPolicyClient.DeleteAutoscalingPolicy(ctx, req, settings.GRPC...) return err }, opts...) return err } // AutoscalingPolicyIterator manages a stream of *dataprocpb.AutoscalingPolicy. type AutoscalingPolicyIterator struct { items []*dataprocpb.AutoscalingPolicy pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*dataprocpb.AutoscalingPolicy, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *AutoscalingPolicyIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *AutoscalingPolicyIterator) Next() (*dataprocpb.AutoscalingPolicy, error) { var item *dataprocpb.AutoscalingPolicy if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *AutoscalingPolicyIterator) bufLen() int { return len(it.items) } func (it *AutoscalingPolicyIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/dataproc/apiv1beta2/autoscaling_policy_client_example_test.go000066400000000000000000000061061356504100700306550ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package dataproc_test import ( "context" dataproc "cloud.google.com/go/dataproc/apiv1beta2" "google.golang.org/api/iterator" dataprocpb "google.golang.org/genproto/googleapis/cloud/dataproc/v1beta2" ) func ExampleNewAutoscalingPolicyClient() { ctx := context.Background() c, err := dataproc.NewAutoscalingPolicyClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleAutoscalingPolicyClient_CreateAutoscalingPolicy() { ctx := context.Background() c, err := dataproc.NewAutoscalingPolicyClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.CreateAutoscalingPolicyRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateAutoscalingPolicy(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleAutoscalingPolicyClient_UpdateAutoscalingPolicy() { ctx := context.Background() c, err := dataproc.NewAutoscalingPolicyClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.UpdateAutoscalingPolicyRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateAutoscalingPolicy(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleAutoscalingPolicyClient_GetAutoscalingPolicy() { ctx := context.Background() c, err := dataproc.NewAutoscalingPolicyClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.GetAutoscalingPolicyRequest{ // TODO: Fill request struct fields. } resp, err := c.GetAutoscalingPolicy(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleAutoscalingPolicyClient_ListAutoscalingPolicies() { ctx := context.Background() c, err := dataproc.NewAutoscalingPolicyClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.ListAutoscalingPoliciesRequest{ // TODO: Fill request struct fields. } it := c.ListAutoscalingPolicies(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleAutoscalingPolicyClient_DeleteAutoscalingPolicy() { ctx := context.Background() c, err := dataproc.NewAutoscalingPolicyClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.DeleteAutoscalingPolicyRequest{ // TODO: Fill request struct fields. } err = c.DeleteAutoscalingPolicy(ctx, req) if err != nil { // TODO: Handle error. } } google-cloud-go-0.49.0/dataproc/apiv1beta2/cluster_controller_client.go000066400000000000000000000564651356504100700261540ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package dataproc import ( "context" "math" "time" "cloud.google.com/go/longrunning" lroauto "cloud.google.com/go/longrunning/autogen" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" dataprocpb "google.golang.org/genproto/googleapis/cloud/dataproc/v1beta2" longrunningpb "google.golang.org/genproto/googleapis/longrunning" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // ClusterControllerCallOptions contains the retry settings for each method of ClusterControllerClient. type ClusterControllerCallOptions struct { CreateCluster []gax.CallOption UpdateCluster []gax.CallOption DeleteCluster []gax.CallOption GetCluster []gax.CallOption ListClusters []gax.CallOption DiagnoseCluster []gax.CallOption } func defaultClusterControllerClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("dataproc.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultClusterControllerCallOptions() *ClusterControllerCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Internal, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, {"default", "non_idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &ClusterControllerCallOptions{ CreateCluster: retry[[2]string{"default", "non_idempotent"}], UpdateCluster: retry[[2]string{"default", "non_idempotent"}], DeleteCluster: retry[[2]string{"default", "non_idempotent"}], GetCluster: retry[[2]string{"default", "idempotent"}], ListClusters: retry[[2]string{"default", "idempotent"}], DiagnoseCluster: retry[[2]string{"default", "non_idempotent"}], } } // ClusterControllerClient is a client for interacting with Google Cloud Dataproc API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type ClusterControllerClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. clusterControllerClient dataprocpb.ClusterControllerClient // LROClient is used internally to handle longrunning operations. // It is exposed so that its CallOptions can be modified if required. // Users should not Close this client. LROClient *lroauto.OperationsClient // The call options for this service. CallOptions *ClusterControllerCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewClusterControllerClient creates a new cluster controller client. // // The ClusterControllerService provides methods to manage clusters // of Compute Engine instances. func NewClusterControllerClient(ctx context.Context, opts ...option.ClientOption) (*ClusterControllerClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultClusterControllerClientOptions(), opts...)...) if err != nil { return nil, err } c := &ClusterControllerClient{ conn: conn, CallOptions: defaultClusterControllerCallOptions(), clusterControllerClient: dataprocpb.NewClusterControllerClient(conn), } c.setGoogleClientInfo() c.LROClient, err = lroauto.NewOperationsClient(ctx, option.WithGRPCConn(conn)) if err != nil { // This error "should not happen", since we are just reusing old connection // and never actually need to dial. // If this does happen, we could leak conn. However, we cannot close conn: // If the user invoked the function with option.WithGRPCConn, // we would close a connection that's still in use. // TODO(pongad): investigate error conditions. return nil, err } return c, nil } // Connection returns the client's connection to the API service. func (c *ClusterControllerClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *ClusterControllerClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *ClusterControllerClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // CreateCluster creates a cluster in a project. The returned // [Operation.metadata][google.longrunning.Operation.metadata] will be // ClusterOperationMetadata (at /dataproc/docs/reference/rpc/google.cloud.dataproc.v1beta2#clusteroperationmetadata). func (c *ClusterControllerClient) CreateCluster(ctx context.Context, req *dataprocpb.CreateClusterRequest, opts ...gax.CallOption) (*CreateClusterOperation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.CreateCluster[0:len(c.CallOptions.CreateCluster):len(c.CallOptions.CreateCluster)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterControllerClient.CreateCluster(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &CreateClusterOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // UpdateCluster updates a cluster in a project. The returned // [Operation.metadata][google.longrunning.Operation.metadata] will be // ClusterOperationMetadata (at /dataproc/docs/reference/rpc/google.cloud.dataproc.v1beta2#clusteroperationmetadata). func (c *ClusterControllerClient) UpdateCluster(ctx context.Context, req *dataprocpb.UpdateClusterRequest, opts ...gax.CallOption) (*UpdateClusterOperation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.UpdateCluster[0:len(c.CallOptions.UpdateCluster):len(c.CallOptions.UpdateCluster)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterControllerClient.UpdateCluster(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &UpdateClusterOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // DeleteCluster deletes a cluster in a project. The returned // [Operation.metadata][google.longrunning.Operation.metadata] will be // ClusterOperationMetadata (at /dataproc/docs/reference/rpc/google.cloud.dataproc.v1beta2#clusteroperationmetadata). func (c *ClusterControllerClient) DeleteCluster(ctx context.Context, req *dataprocpb.DeleteClusterRequest, opts ...gax.CallOption) (*DeleteClusterOperation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.DeleteCluster[0:len(c.CallOptions.DeleteCluster):len(c.CallOptions.DeleteCluster)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterControllerClient.DeleteCluster(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &DeleteClusterOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // GetCluster gets the resource representation for a cluster in a project. func (c *ClusterControllerClient) GetCluster(ctx context.Context, req *dataprocpb.GetClusterRequest, opts ...gax.CallOption) (*dataprocpb.Cluster, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.GetCluster[0:len(c.CallOptions.GetCluster):len(c.CallOptions.GetCluster)], opts...) var resp *dataprocpb.Cluster err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterControllerClient.GetCluster(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListClusters lists all regions/{region}/clusters in a project. func (c *ClusterControllerClient) ListClusters(ctx context.Context, req *dataprocpb.ListClustersRequest, opts ...gax.CallOption) *ClusterIterator { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.ListClusters[0:len(c.CallOptions.ListClusters):len(c.CallOptions.ListClusters)], opts...) it := &ClusterIterator{} req = proto.Clone(req).(*dataprocpb.ListClustersRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*dataprocpb.Cluster, string, error) { var resp *dataprocpb.ListClustersResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterControllerClient.ListClusters(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Clusters, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // DiagnoseCluster gets cluster diagnostic information. The returned // [Operation.metadata][google.longrunning.Operation.metadata] will be // ClusterOperationMetadata (at /dataproc/docs/reference/rpc/google.cloud.dataproc.v1beta2#clusteroperationmetadata). // After the operation completes, // [Operation.response][google.longrunning.Operation.response] // contains // Empty (at google.protobuf.Empty). func (c *ClusterControllerClient) DiagnoseCluster(ctx context.Context, req *dataprocpb.DiagnoseClusterRequest, opts ...gax.CallOption) (*DiagnoseClusterOperation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.DiagnoseCluster[0:len(c.CallOptions.DiagnoseCluster):len(c.CallOptions.DiagnoseCluster)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.clusterControllerClient.DiagnoseCluster(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &DiagnoseClusterOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // ClusterIterator manages a stream of *dataprocpb.Cluster. type ClusterIterator struct { items []*dataprocpb.Cluster pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*dataprocpb.Cluster, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *ClusterIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *ClusterIterator) Next() (*dataprocpb.Cluster, error) { var item *dataprocpb.Cluster if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *ClusterIterator) bufLen() int { return len(it.items) } func (it *ClusterIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // CreateClusterOperation manages a long-running operation from CreateCluster. type CreateClusterOperation struct { lro *longrunning.Operation } // CreateClusterOperation returns a new CreateClusterOperation from a given name. // The name must be that of a previously created CreateClusterOperation, possibly from a different process. func (c *ClusterControllerClient) CreateClusterOperation(name string) *CreateClusterOperation { return &CreateClusterOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *CreateClusterOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*dataprocpb.Cluster, error) { var resp dataprocpb.Cluster if err := op.lro.WaitWithInterval(ctx, &resp, 10000*time.Millisecond, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *CreateClusterOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*dataprocpb.Cluster, error) { var resp dataprocpb.Cluster if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *CreateClusterOperation) Metadata() (*dataprocpb.ClusterOperationMetadata, error) { var meta dataprocpb.ClusterOperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *CreateClusterOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *CreateClusterOperation) Name() string { return op.lro.Name() } // DeleteClusterOperation manages a long-running operation from DeleteCluster. type DeleteClusterOperation struct { lro *longrunning.Operation } // DeleteClusterOperation returns a new DeleteClusterOperation from a given name. // The name must be that of a previously created DeleteClusterOperation, possibly from a different process. func (c *ClusterControllerClient) DeleteClusterOperation(name string) *DeleteClusterOperation { return &DeleteClusterOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning any error encountered. // // See documentation of Poll for error-handling information. func (op *DeleteClusterOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { return op.lro.WaitWithInterval(ctx, nil, 10000*time.Millisecond, opts...) } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, op.Done will return true. func (op *DeleteClusterOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Poll(ctx, nil, opts...) } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *DeleteClusterOperation) Metadata() (*dataprocpb.ClusterOperationMetadata, error) { var meta dataprocpb.ClusterOperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *DeleteClusterOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *DeleteClusterOperation) Name() string { return op.lro.Name() } // DiagnoseClusterOperation manages a long-running operation from DiagnoseCluster. type DiagnoseClusterOperation struct { lro *longrunning.Operation } // DiagnoseClusterOperation returns a new DiagnoseClusterOperation from a given name. // The name must be that of a previously created DiagnoseClusterOperation, possibly from a different process. func (c *ClusterControllerClient) DiagnoseClusterOperation(name string) *DiagnoseClusterOperation { return &DiagnoseClusterOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning any error encountered. // // See documentation of Poll for error-handling information. func (op *DiagnoseClusterOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { return op.lro.WaitWithInterval(ctx, nil, 10000*time.Millisecond, opts...) } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, op.Done will return true. func (op *DiagnoseClusterOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Poll(ctx, nil, opts...) } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *DiagnoseClusterOperation) Metadata() (*dataprocpb.DiagnoseClusterResults, error) { var meta dataprocpb.DiagnoseClusterResults if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *DiagnoseClusterOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *DiagnoseClusterOperation) Name() string { return op.lro.Name() } // UpdateClusterOperation manages a long-running operation from UpdateCluster. type UpdateClusterOperation struct { lro *longrunning.Operation } // UpdateClusterOperation returns a new UpdateClusterOperation from a given name. // The name must be that of a previously created UpdateClusterOperation, possibly from a different process. func (c *ClusterControllerClient) UpdateClusterOperation(name string) *UpdateClusterOperation { return &UpdateClusterOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *UpdateClusterOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*dataprocpb.Cluster, error) { var resp dataprocpb.Cluster if err := op.lro.WaitWithInterval(ctx, &resp, 10000*time.Millisecond, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *UpdateClusterOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*dataprocpb.Cluster, error) { var resp dataprocpb.Cluster if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *UpdateClusterOperation) Metadata() (*dataprocpb.ClusterOperationMetadata, error) { var meta dataprocpb.ClusterOperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *UpdateClusterOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *UpdateClusterOperation) Name() string { return op.lro.Name() } google-cloud-go-0.49.0/dataproc/apiv1beta2/cluster_controller_client_example_test.go000066400000000000000000000067771356504100700307270ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package dataproc_test import ( "context" dataproc "cloud.google.com/go/dataproc/apiv1beta2" "google.golang.org/api/iterator" dataprocpb "google.golang.org/genproto/googleapis/cloud/dataproc/v1beta2" ) func ExampleNewClusterControllerClient() { ctx := context.Background() c, err := dataproc.NewClusterControllerClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleClusterControllerClient_CreateCluster() { ctx := context.Background() c, err := dataproc.NewClusterControllerClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.CreateClusterRequest{ // TODO: Fill request struct fields. } op, err := c.CreateCluster(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClusterControllerClient_UpdateCluster() { ctx := context.Background() c, err := dataproc.NewClusterControllerClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.UpdateClusterRequest{ // TODO: Fill request struct fields. } op, err := c.UpdateCluster(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClusterControllerClient_DeleteCluster() { ctx := context.Background() c, err := dataproc.NewClusterControllerClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.DeleteClusterRequest{ // TODO: Fill request struct fields. } op, err := c.DeleteCluster(ctx, req) if err != nil { // TODO: Handle error. } err = op.Wait(ctx) // TODO: Handle error. } func ExampleClusterControllerClient_GetCluster() { ctx := context.Background() c, err := dataproc.NewClusterControllerClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.GetClusterRequest{ // TODO: Fill request struct fields. } resp, err := c.GetCluster(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClusterControllerClient_ListClusters() { ctx := context.Background() c, err := dataproc.NewClusterControllerClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.ListClustersRequest{ // TODO: Fill request struct fields. } it := c.ListClusters(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClusterControllerClient_DiagnoseCluster() { ctx := context.Background() c, err := dataproc.NewClusterControllerClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.DiagnoseClusterRequest{ // TODO: Fill request struct fields. } op, err := c.DiagnoseCluster(ctx, req) if err != nil { // TODO: Handle error. } err = op.Wait(ctx) // TODO: Handle error. } google-cloud-go-0.49.0/dataproc/apiv1beta2/doc.go000066400000000000000000000053531356504100700214250ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package dataproc is an auto-generated package for the // Google Cloud Dataproc API. // // NOTE: This package is in beta. It is not stable, and may be subject to changes. // // Manages Hadoop-based clusters and jobs on Google Cloud Platform. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package dataproc // import "cloud.google.com/go/dataproc/apiv1beta2" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191115" google-cloud-go-0.49.0/dataproc/apiv1beta2/job_controller_client.go000066400000000000000000000250661356504100700252360ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package dataproc import ( "context" "math" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" dataprocpb "google.golang.org/genproto/googleapis/cloud/dataproc/v1beta2" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // JobControllerCallOptions contains the retry settings for each method of JobControllerClient. type JobControllerCallOptions struct { SubmitJob []gax.CallOption GetJob []gax.CallOption ListJobs []gax.CallOption UpdateJob []gax.CallOption CancelJob []gax.CallOption DeleteJob []gax.CallOption } func defaultJobControllerClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("dataproc.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultJobControllerCallOptions() *JobControllerCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Internal, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, {"default", "non_idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &JobControllerCallOptions{ SubmitJob: retry[[2]string{"default", "non_idempotent"}], GetJob: retry[[2]string{"default", "idempotent"}], ListJobs: retry[[2]string{"default", "idempotent"}], UpdateJob: retry[[2]string{"default", "non_idempotent"}], CancelJob: retry[[2]string{"default", "idempotent"}], DeleteJob: retry[[2]string{"default", "non_idempotent"}], } } // JobControllerClient is a client for interacting with Google Cloud Dataproc API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type JobControllerClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. jobControllerClient dataprocpb.JobControllerClient // The call options for this service. CallOptions *JobControllerCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewJobControllerClient creates a new job controller client. // // The JobController provides methods to manage jobs. func NewJobControllerClient(ctx context.Context, opts ...option.ClientOption) (*JobControllerClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultJobControllerClientOptions(), opts...)...) if err != nil { return nil, err } c := &JobControllerClient{ conn: conn, CallOptions: defaultJobControllerCallOptions(), jobControllerClient: dataprocpb.NewJobControllerClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *JobControllerClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *JobControllerClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *JobControllerClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // SubmitJob submits a job to a cluster. func (c *JobControllerClient) SubmitJob(ctx context.Context, req *dataprocpb.SubmitJobRequest, opts ...gax.CallOption) (*dataprocpb.Job, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.SubmitJob[0:len(c.CallOptions.SubmitJob):len(c.CallOptions.SubmitJob)], opts...) var resp *dataprocpb.Job err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.jobControllerClient.SubmitJob(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetJob gets the resource representation for a job in a project. func (c *JobControllerClient) GetJob(ctx context.Context, req *dataprocpb.GetJobRequest, opts ...gax.CallOption) (*dataprocpb.Job, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.GetJob[0:len(c.CallOptions.GetJob):len(c.CallOptions.GetJob)], opts...) var resp *dataprocpb.Job err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.jobControllerClient.GetJob(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListJobs lists regions/{region}/jobs in a project. func (c *JobControllerClient) ListJobs(ctx context.Context, req *dataprocpb.ListJobsRequest, opts ...gax.CallOption) *JobIterator { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.ListJobs[0:len(c.CallOptions.ListJobs):len(c.CallOptions.ListJobs)], opts...) it := &JobIterator{} req = proto.Clone(req).(*dataprocpb.ListJobsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*dataprocpb.Job, string, error) { var resp *dataprocpb.ListJobsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.jobControllerClient.ListJobs(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Jobs, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // UpdateJob updates a job in a project. func (c *JobControllerClient) UpdateJob(ctx context.Context, req *dataprocpb.UpdateJobRequest, opts ...gax.CallOption) (*dataprocpb.Job, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.UpdateJob[0:len(c.CallOptions.UpdateJob):len(c.CallOptions.UpdateJob)], opts...) var resp *dataprocpb.Job err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.jobControllerClient.UpdateJob(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CancelJob starts a job cancellation request. To access the job resource // after cancellation, call // regions/{region}/jobs.list (at /dataproc/docs/reference/rest/v1beta2/projects.regions.jobs/list) // or // regions/{region}/jobs.get (at /dataproc/docs/reference/rest/v1beta2/projects.regions.jobs/get). func (c *JobControllerClient) CancelJob(ctx context.Context, req *dataprocpb.CancelJobRequest, opts ...gax.CallOption) (*dataprocpb.Job, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.CancelJob[0:len(c.CallOptions.CancelJob):len(c.CallOptions.CancelJob)], opts...) var resp *dataprocpb.Job err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.jobControllerClient.CancelJob(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteJob deletes the job from the project. If the job is active, the delete fails, // and the response returns FAILED_PRECONDITION. func (c *JobControllerClient) DeleteJob(ctx context.Context, req *dataprocpb.DeleteJobRequest, opts ...gax.CallOption) error { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.DeleteJob[0:len(c.CallOptions.DeleteJob):len(c.CallOptions.DeleteJob)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.jobControllerClient.DeleteJob(ctx, req, settings.GRPC...) return err }, opts...) return err } // JobIterator manages a stream of *dataprocpb.Job. type JobIterator struct { items []*dataprocpb.Job pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*dataprocpb.Job, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *JobIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *JobIterator) Next() (*dataprocpb.Job, error) { var item *dataprocpb.Job if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *JobIterator) bufLen() int { return len(it.items) } func (it *JobIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/dataproc/apiv1beta2/job_controller_client_example_test.go000066400000000000000000000062541356504100700300060ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package dataproc_test import ( "context" dataproc "cloud.google.com/go/dataproc/apiv1beta2" "google.golang.org/api/iterator" dataprocpb "google.golang.org/genproto/googleapis/cloud/dataproc/v1beta2" ) func ExampleNewJobControllerClient() { ctx := context.Background() c, err := dataproc.NewJobControllerClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleJobControllerClient_SubmitJob() { ctx := context.Background() c, err := dataproc.NewJobControllerClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.SubmitJobRequest{ // TODO: Fill request struct fields. } resp, err := c.SubmitJob(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleJobControllerClient_GetJob() { ctx := context.Background() c, err := dataproc.NewJobControllerClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.GetJobRequest{ // TODO: Fill request struct fields. } resp, err := c.GetJob(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleJobControllerClient_ListJobs() { ctx := context.Background() c, err := dataproc.NewJobControllerClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.ListJobsRequest{ // TODO: Fill request struct fields. } it := c.ListJobs(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleJobControllerClient_UpdateJob() { ctx := context.Background() c, err := dataproc.NewJobControllerClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.UpdateJobRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateJob(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleJobControllerClient_CancelJob() { ctx := context.Background() c, err := dataproc.NewJobControllerClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.CancelJobRequest{ // TODO: Fill request struct fields. } resp, err := c.CancelJob(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleJobControllerClient_DeleteJob() { ctx := context.Background() c, err := dataproc.NewJobControllerClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.DeleteJobRequest{ // TODO: Fill request struct fields. } err = c.DeleteJob(ctx, req) if err != nil { // TODO: Handle error. } } google-cloud-go-0.49.0/dataproc/apiv1beta2/longrunning.go000066400000000000000000000071311356504100700232140ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package dataproc import ( "context" gax "github.com/googleapis/gax-go/v2" ) // Cancel starts asynchronous cancellation on a long-running operation. // The server makes a best effort to cancel the operation, but success is not guaranteed. // Clients can use Poll or other methods to check whether the cancellation succeeded or whether the operation // completed despite cancellation. On successful cancellation, the operation is not deleted; // instead, op.Poll returns an error with code Canceled. func (op *InstantiateInlineWorkflowTemplateOperation) Cancel(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Cancel(ctx, opts...) } // Delete deletes a long-running operation. // This method indicates that the client is no longer interested in the operation result. // It does not cancel the operation. func (op *InstantiateInlineWorkflowTemplateOperation) Delete(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Delete(ctx, opts...) } // Cancel starts asynchronous cancellation on a long-running operation. // The server makes a best effort to cancel the operation, but success is not guaranteed. // Clients can use Poll or other methods to check whether the cancellation succeeded or whether the operation // completed despite cancellation. On successful cancellation, the operation is not deleted; // instead, op.Poll returns an error with code Canceled. func (op *InstantiateWorkflowTemplateOperation) Cancel(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Cancel(ctx, opts...) } // Delete deletes a long-running operation. // This method indicates that the client is no longer interested in the operation result. // It does not cancel the operation. func (op *InstantiateWorkflowTemplateOperation) Delete(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Delete(ctx, opts...) } // Delete deletes a long-running operation. // This method indicates that the client is no longer interested in the operation result. // It does not cancel the operation. func (op *CreateClusterOperation) Delete(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Delete(ctx, opts...) } // Delete deletes a long-running operation. // This method indicates that the client is no longer interested in the operation result. // It does not cancel the operation. func (op *DeleteClusterOperation) Delete(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Delete(ctx, opts...) } // Delete deletes a long-running operation. // This method indicates that the client is no longer interested in the operation result. // It does not cancel the operation. func (op *DiagnoseClusterOperation) Delete(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Delete(ctx, opts...) } // Delete deletes a long-running operation. // This method indicates that the client is no longer interested in the operation result. // It does not cancel the operation. func (op *UpdateClusterOperation) Delete(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Delete(ctx, opts...) } google-cloud-go-0.49.0/dataproc/apiv1beta2/mock_test.go000066400000000000000000001776221356504100700226610ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package dataproc import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" "google.golang.org/api/option" dataprocpb "google.golang.org/genproto/googleapis/cloud/dataproc/v1beta2" longrunningpb "google.golang.org/genproto/googleapis/longrunning" field_maskpb "google.golang.org/genproto/protobuf/field_mask" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockAutoscalingPolicyServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. dataprocpb.AutoscalingPolicyServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockAutoscalingPolicyServer) CreateAutoscalingPolicy(ctx context.Context, req *dataprocpb.CreateAutoscalingPolicyRequest) (*dataprocpb.AutoscalingPolicy, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dataprocpb.AutoscalingPolicy), nil } func (s *mockAutoscalingPolicyServer) UpdateAutoscalingPolicy(ctx context.Context, req *dataprocpb.UpdateAutoscalingPolicyRequest) (*dataprocpb.AutoscalingPolicy, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dataprocpb.AutoscalingPolicy), nil } func (s *mockAutoscalingPolicyServer) GetAutoscalingPolicy(ctx context.Context, req *dataprocpb.GetAutoscalingPolicyRequest) (*dataprocpb.AutoscalingPolicy, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dataprocpb.AutoscalingPolicy), nil } func (s *mockAutoscalingPolicyServer) ListAutoscalingPolicies(ctx context.Context, req *dataprocpb.ListAutoscalingPoliciesRequest) (*dataprocpb.ListAutoscalingPoliciesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dataprocpb.ListAutoscalingPoliciesResponse), nil } func (s *mockAutoscalingPolicyServer) DeleteAutoscalingPolicy(ctx context.Context, req *dataprocpb.DeleteAutoscalingPolicyRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } type mockClusterControllerServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. dataprocpb.ClusterControllerServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockClusterControllerServer) CreateCluster(ctx context.Context, req *dataprocpb.CreateClusterRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockClusterControllerServer) UpdateCluster(ctx context.Context, req *dataprocpb.UpdateClusterRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockClusterControllerServer) DeleteCluster(ctx context.Context, req *dataprocpb.DeleteClusterRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockClusterControllerServer) GetCluster(ctx context.Context, req *dataprocpb.GetClusterRequest) (*dataprocpb.Cluster, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dataprocpb.Cluster), nil } func (s *mockClusterControllerServer) ListClusters(ctx context.Context, req *dataprocpb.ListClustersRequest) (*dataprocpb.ListClustersResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dataprocpb.ListClustersResponse), nil } func (s *mockClusterControllerServer) DiagnoseCluster(ctx context.Context, req *dataprocpb.DiagnoseClusterRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } type mockJobControllerServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. dataprocpb.JobControllerServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockJobControllerServer) SubmitJob(ctx context.Context, req *dataprocpb.SubmitJobRequest) (*dataprocpb.Job, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dataprocpb.Job), nil } func (s *mockJobControllerServer) GetJob(ctx context.Context, req *dataprocpb.GetJobRequest) (*dataprocpb.Job, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dataprocpb.Job), nil } func (s *mockJobControllerServer) ListJobs(ctx context.Context, req *dataprocpb.ListJobsRequest) (*dataprocpb.ListJobsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dataprocpb.ListJobsResponse), nil } func (s *mockJobControllerServer) UpdateJob(ctx context.Context, req *dataprocpb.UpdateJobRequest) (*dataprocpb.Job, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dataprocpb.Job), nil } func (s *mockJobControllerServer) CancelJob(ctx context.Context, req *dataprocpb.CancelJobRequest) (*dataprocpb.Job, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dataprocpb.Job), nil } func (s *mockJobControllerServer) DeleteJob(ctx context.Context, req *dataprocpb.DeleteJobRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } type mockWorkflowTemplateServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. dataprocpb.WorkflowTemplateServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockWorkflowTemplateServer) CreateWorkflowTemplate(ctx context.Context, req *dataprocpb.CreateWorkflowTemplateRequest) (*dataprocpb.WorkflowTemplate, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dataprocpb.WorkflowTemplate), nil } func (s *mockWorkflowTemplateServer) GetWorkflowTemplate(ctx context.Context, req *dataprocpb.GetWorkflowTemplateRequest) (*dataprocpb.WorkflowTemplate, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dataprocpb.WorkflowTemplate), nil } func (s *mockWorkflowTemplateServer) InstantiateWorkflowTemplate(ctx context.Context, req *dataprocpb.InstantiateWorkflowTemplateRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockWorkflowTemplateServer) InstantiateInlineWorkflowTemplate(ctx context.Context, req *dataprocpb.InstantiateInlineWorkflowTemplateRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockWorkflowTemplateServer) UpdateWorkflowTemplate(ctx context.Context, req *dataprocpb.UpdateWorkflowTemplateRequest) (*dataprocpb.WorkflowTemplate, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dataprocpb.WorkflowTemplate), nil } func (s *mockWorkflowTemplateServer) ListWorkflowTemplates(ctx context.Context, req *dataprocpb.ListWorkflowTemplatesRequest) (*dataprocpb.ListWorkflowTemplatesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dataprocpb.ListWorkflowTemplatesResponse), nil } func (s *mockWorkflowTemplateServer) DeleteWorkflowTemplate(ctx context.Context, req *dataprocpb.DeleteWorkflowTemplateRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockAutoscalingPolicy mockAutoscalingPolicyServer mockClusterController mockClusterControllerServer mockJobController mockJobControllerServer mockWorkflowTemplate mockWorkflowTemplateServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() dataprocpb.RegisterAutoscalingPolicyServiceServer(serv, &mockAutoscalingPolicy) dataprocpb.RegisterClusterControllerServer(serv, &mockClusterController) dataprocpb.RegisterJobControllerServer(serv, &mockJobController) dataprocpb.RegisterWorkflowTemplateServiceServer(serv, &mockWorkflowTemplate) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestAutoscalingPolicyServiceCreateAutoscalingPolicy(t *testing.T) { var id string = "id3355" var name string = "name3373707" var expectedResponse = &dataprocpb.AutoscalingPolicy{ Id: id, Name: name, } mockAutoscalingPolicy.err = nil mockAutoscalingPolicy.reqs = nil mockAutoscalingPolicy.resps = append(mockAutoscalingPolicy.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/regions/%s", "[PROJECT]", "[REGION]") var policy *dataprocpb.AutoscalingPolicy = &dataprocpb.AutoscalingPolicy{} var request = &dataprocpb.CreateAutoscalingPolicyRequest{ Parent: formattedParent, Policy: policy, } c, err := NewAutoscalingPolicyClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateAutoscalingPolicy(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockAutoscalingPolicy.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAutoscalingPolicyServiceCreateAutoscalingPolicyError(t *testing.T) { errCode := codes.PermissionDenied mockAutoscalingPolicy.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/regions/%s", "[PROJECT]", "[REGION]") var policy *dataprocpb.AutoscalingPolicy = &dataprocpb.AutoscalingPolicy{} var request = &dataprocpb.CreateAutoscalingPolicyRequest{ Parent: formattedParent, Policy: policy, } c, err := NewAutoscalingPolicyClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateAutoscalingPolicy(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAutoscalingPolicyServiceUpdateAutoscalingPolicy(t *testing.T) { var id string = "id3355" var name string = "name3373707" var expectedResponse = &dataprocpb.AutoscalingPolicy{ Id: id, Name: name, } mockAutoscalingPolicy.err = nil mockAutoscalingPolicy.reqs = nil mockAutoscalingPolicy.resps = append(mockAutoscalingPolicy.resps[:0], expectedResponse) var policy *dataprocpb.AutoscalingPolicy = &dataprocpb.AutoscalingPolicy{} var request = &dataprocpb.UpdateAutoscalingPolicyRequest{ Policy: policy, } c, err := NewAutoscalingPolicyClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateAutoscalingPolicy(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockAutoscalingPolicy.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAutoscalingPolicyServiceUpdateAutoscalingPolicyError(t *testing.T) { errCode := codes.PermissionDenied mockAutoscalingPolicy.err = gstatus.Error(errCode, "test error") var policy *dataprocpb.AutoscalingPolicy = &dataprocpb.AutoscalingPolicy{} var request = &dataprocpb.UpdateAutoscalingPolicyRequest{ Policy: policy, } c, err := NewAutoscalingPolicyClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateAutoscalingPolicy(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAutoscalingPolicyServiceGetAutoscalingPolicy(t *testing.T) { var id string = "id3355" var name2 string = "name2-1052831874" var expectedResponse = &dataprocpb.AutoscalingPolicy{ Id: id, Name: name2, } mockAutoscalingPolicy.err = nil mockAutoscalingPolicy.reqs = nil mockAutoscalingPolicy.resps = append(mockAutoscalingPolicy.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/regions/%s/autoscalingPolicies/%s", "[PROJECT]", "[REGION]", "[AUTOSCALING_POLICY]") var request = &dataprocpb.GetAutoscalingPolicyRequest{ Name: formattedName, } c, err := NewAutoscalingPolicyClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetAutoscalingPolicy(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockAutoscalingPolicy.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAutoscalingPolicyServiceGetAutoscalingPolicyError(t *testing.T) { errCode := codes.PermissionDenied mockAutoscalingPolicy.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/regions/%s/autoscalingPolicies/%s", "[PROJECT]", "[REGION]", "[AUTOSCALING_POLICY]") var request = &dataprocpb.GetAutoscalingPolicyRequest{ Name: formattedName, } c, err := NewAutoscalingPolicyClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetAutoscalingPolicy(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAutoscalingPolicyServiceListAutoscalingPolicies(t *testing.T) { var nextPageToken string = "" var policiesElement *dataprocpb.AutoscalingPolicy = &dataprocpb.AutoscalingPolicy{} var policies = []*dataprocpb.AutoscalingPolicy{policiesElement} var expectedResponse = &dataprocpb.ListAutoscalingPoliciesResponse{ NextPageToken: nextPageToken, Policies: policies, } mockAutoscalingPolicy.err = nil mockAutoscalingPolicy.reqs = nil mockAutoscalingPolicy.resps = append(mockAutoscalingPolicy.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/regions/%s", "[PROJECT]", "[REGION]") var request = &dataprocpb.ListAutoscalingPoliciesRequest{ Parent: formattedParent, } c, err := NewAutoscalingPolicyClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListAutoscalingPolicies(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockAutoscalingPolicy.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Policies[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAutoscalingPolicyServiceListAutoscalingPoliciesError(t *testing.T) { errCode := codes.PermissionDenied mockAutoscalingPolicy.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/regions/%s", "[PROJECT]", "[REGION]") var request = &dataprocpb.ListAutoscalingPoliciesRequest{ Parent: formattedParent, } c, err := NewAutoscalingPolicyClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListAutoscalingPolicies(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAutoscalingPolicyServiceDeleteAutoscalingPolicy(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockAutoscalingPolicy.err = nil mockAutoscalingPolicy.reqs = nil mockAutoscalingPolicy.resps = append(mockAutoscalingPolicy.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/regions/%s/autoscalingPolicies/%s", "[PROJECT]", "[REGION]", "[AUTOSCALING_POLICY]") var request = &dataprocpb.DeleteAutoscalingPolicyRequest{ Name: formattedName, } c, err := NewAutoscalingPolicyClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteAutoscalingPolicy(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockAutoscalingPolicy.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestAutoscalingPolicyServiceDeleteAutoscalingPolicyError(t *testing.T) { errCode := codes.PermissionDenied mockAutoscalingPolicy.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/regions/%s/autoscalingPolicies/%s", "[PROJECT]", "[REGION]", "[AUTOSCALING_POLICY]") var request = &dataprocpb.DeleteAutoscalingPolicyRequest{ Name: formattedName, } c, err := NewAutoscalingPolicyClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteAutoscalingPolicy(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestClusterControllerCreateCluster(t *testing.T) { var projectId2 string = "projectId2939242356" var clusterName string = "clusterName-1018081872" var clusterUuid string = "clusterUuid-1017854240" var expectedResponse = &dataprocpb.Cluster{ ProjectId: projectId2, ClusterName: clusterName, ClusterUuid: clusterUuid, } mockClusterController.err = nil mockClusterController.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockClusterController.resps = append(mockClusterController.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var projectId string = "projectId-1969970175" var region string = "region-934795532" var cluster *dataprocpb.Cluster = &dataprocpb.Cluster{} var request = &dataprocpb.CreateClusterRequest{ ProjectId: projectId, Region: region, Cluster: cluster, } c, err := NewClusterControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.CreateCluster(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockClusterController.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestClusterControllerCreateClusterError(t *testing.T) { errCode := codes.PermissionDenied mockClusterController.err = nil mockClusterController.resps = append(mockClusterController.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var projectId string = "projectId-1969970175" var region string = "region-934795532" var cluster *dataprocpb.Cluster = &dataprocpb.Cluster{} var request = &dataprocpb.CreateClusterRequest{ ProjectId: projectId, Region: region, Cluster: cluster, } c, err := NewClusterControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.CreateCluster(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestClusterControllerUpdateCluster(t *testing.T) { var projectId2 string = "projectId2939242356" var clusterName2 string = "clusterName2875867491" var clusterUuid string = "clusterUuid-1017854240" var expectedResponse = &dataprocpb.Cluster{ ProjectId: projectId2, ClusterName: clusterName2, ClusterUuid: clusterUuid, } mockClusterController.err = nil mockClusterController.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockClusterController.resps = append(mockClusterController.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var projectId string = "projectId-1969970175" var region string = "region-934795532" var clusterName string = "clusterName-1018081872" var cluster *dataprocpb.Cluster = &dataprocpb.Cluster{} var updateMask *field_maskpb.FieldMask = &field_maskpb.FieldMask{} var request = &dataprocpb.UpdateClusterRequest{ ProjectId: projectId, Region: region, ClusterName: clusterName, Cluster: cluster, UpdateMask: updateMask, } c, err := NewClusterControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.UpdateCluster(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockClusterController.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestClusterControllerUpdateClusterError(t *testing.T) { errCode := codes.PermissionDenied mockClusterController.err = nil mockClusterController.resps = append(mockClusterController.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var projectId string = "projectId-1969970175" var region string = "region-934795532" var clusterName string = "clusterName-1018081872" var cluster *dataprocpb.Cluster = &dataprocpb.Cluster{} var updateMask *field_maskpb.FieldMask = &field_maskpb.FieldMask{} var request = &dataprocpb.UpdateClusterRequest{ ProjectId: projectId, Region: region, ClusterName: clusterName, Cluster: cluster, UpdateMask: updateMask, } c, err := NewClusterControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.UpdateCluster(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestClusterControllerDeleteCluster(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockClusterController.err = nil mockClusterController.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockClusterController.resps = append(mockClusterController.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var projectId string = "projectId-1969970175" var region string = "region-934795532" var clusterName string = "clusterName-1018081872" var request = &dataprocpb.DeleteClusterRequest{ ProjectId: projectId, Region: region, ClusterName: clusterName, } c, err := NewClusterControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.DeleteCluster(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockClusterController.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestClusterControllerDeleteClusterError(t *testing.T) { errCode := codes.PermissionDenied mockClusterController.err = nil mockClusterController.resps = append(mockClusterController.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var projectId string = "projectId-1969970175" var region string = "region-934795532" var clusterName string = "clusterName-1018081872" var request = &dataprocpb.DeleteClusterRequest{ ProjectId: projectId, Region: region, ClusterName: clusterName, } c, err := NewClusterControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.DeleteCluster(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestClusterControllerGetCluster(t *testing.T) { var projectId2 string = "projectId2939242356" var clusterName2 string = "clusterName2875867491" var clusterUuid string = "clusterUuid-1017854240" var expectedResponse = &dataprocpb.Cluster{ ProjectId: projectId2, ClusterName: clusterName2, ClusterUuid: clusterUuid, } mockClusterController.err = nil mockClusterController.reqs = nil mockClusterController.resps = append(mockClusterController.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var region string = "region-934795532" var clusterName string = "clusterName-1018081872" var request = &dataprocpb.GetClusterRequest{ ProjectId: projectId, Region: region, ClusterName: clusterName, } c, err := NewClusterControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetCluster(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockClusterController.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestClusterControllerGetClusterError(t *testing.T) { errCode := codes.PermissionDenied mockClusterController.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var region string = "region-934795532" var clusterName string = "clusterName-1018081872" var request = &dataprocpb.GetClusterRequest{ ProjectId: projectId, Region: region, ClusterName: clusterName, } c, err := NewClusterControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetCluster(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestClusterControllerListClusters(t *testing.T) { var nextPageToken string = "" var clustersElement *dataprocpb.Cluster = &dataprocpb.Cluster{} var clusters = []*dataprocpb.Cluster{clustersElement} var expectedResponse = &dataprocpb.ListClustersResponse{ NextPageToken: nextPageToken, Clusters: clusters, } mockClusterController.err = nil mockClusterController.reqs = nil mockClusterController.resps = append(mockClusterController.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var region string = "region-934795532" var request = &dataprocpb.ListClustersRequest{ ProjectId: projectId, Region: region, } c, err := NewClusterControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListClusters(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockClusterController.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Clusters[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestClusterControllerListClustersError(t *testing.T) { errCode := codes.PermissionDenied mockClusterController.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var region string = "region-934795532" var request = &dataprocpb.ListClustersRequest{ ProjectId: projectId, Region: region, } c, err := NewClusterControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListClusters(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestClusterControllerDiagnoseCluster(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockClusterController.err = nil mockClusterController.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockClusterController.resps = append(mockClusterController.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var projectId string = "projectId-1969970175" var region string = "region-934795532" var clusterName string = "clusterName-1018081872" var request = &dataprocpb.DiagnoseClusterRequest{ ProjectId: projectId, Region: region, ClusterName: clusterName, } c, err := NewClusterControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.DiagnoseCluster(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockClusterController.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestClusterControllerDiagnoseClusterError(t *testing.T) { errCode := codes.PermissionDenied mockClusterController.err = nil mockClusterController.resps = append(mockClusterController.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var projectId string = "projectId-1969970175" var region string = "region-934795532" var clusterName string = "clusterName-1018081872" var request = &dataprocpb.DiagnoseClusterRequest{ ProjectId: projectId, Region: region, ClusterName: clusterName, } c, err := NewClusterControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.DiagnoseCluster(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestJobControllerSubmitJob(t *testing.T) { var submittedBy string = "submittedBy-2047729125" var driverOutputResourceUri string = "driverOutputResourceUri-542229086" var driverControlFilesUri string = "driverControlFilesUri207057643" var jobUuid string = "jobUuid-1615012099" var expectedResponse = &dataprocpb.Job{ SubmittedBy: submittedBy, DriverOutputResourceUri: driverOutputResourceUri, DriverControlFilesUri: driverControlFilesUri, JobUuid: jobUuid, } mockJobController.err = nil mockJobController.reqs = nil mockJobController.resps = append(mockJobController.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var region string = "region-934795532" var job *dataprocpb.Job = &dataprocpb.Job{} var request = &dataprocpb.SubmitJobRequest{ ProjectId: projectId, Region: region, Job: job, } c, err := NewJobControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SubmitJob(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockJobController.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestJobControllerSubmitJobError(t *testing.T) { errCode := codes.PermissionDenied mockJobController.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var region string = "region-934795532" var job *dataprocpb.Job = &dataprocpb.Job{} var request = &dataprocpb.SubmitJobRequest{ ProjectId: projectId, Region: region, Job: job, } c, err := NewJobControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SubmitJob(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestJobControllerGetJob(t *testing.T) { var submittedBy string = "submittedBy-2047729125" var driverOutputResourceUri string = "driverOutputResourceUri-542229086" var driverControlFilesUri string = "driverControlFilesUri207057643" var jobUuid string = "jobUuid-1615012099" var expectedResponse = &dataprocpb.Job{ SubmittedBy: submittedBy, DriverOutputResourceUri: driverOutputResourceUri, DriverControlFilesUri: driverControlFilesUri, JobUuid: jobUuid, } mockJobController.err = nil mockJobController.reqs = nil mockJobController.resps = append(mockJobController.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var region string = "region-934795532" var jobId string = "jobId-1154752291" var request = &dataprocpb.GetJobRequest{ ProjectId: projectId, Region: region, JobId: jobId, } c, err := NewJobControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetJob(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockJobController.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestJobControllerGetJobError(t *testing.T) { errCode := codes.PermissionDenied mockJobController.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var region string = "region-934795532" var jobId string = "jobId-1154752291" var request = &dataprocpb.GetJobRequest{ ProjectId: projectId, Region: region, JobId: jobId, } c, err := NewJobControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetJob(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestJobControllerListJobs(t *testing.T) { var nextPageToken string = "" var jobsElement *dataprocpb.Job = &dataprocpb.Job{} var jobs = []*dataprocpb.Job{jobsElement} var expectedResponse = &dataprocpb.ListJobsResponse{ NextPageToken: nextPageToken, Jobs: jobs, } mockJobController.err = nil mockJobController.reqs = nil mockJobController.resps = append(mockJobController.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var region string = "region-934795532" var request = &dataprocpb.ListJobsRequest{ ProjectId: projectId, Region: region, } c, err := NewJobControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListJobs(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockJobController.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Jobs[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestJobControllerListJobsError(t *testing.T) { errCode := codes.PermissionDenied mockJobController.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var region string = "region-934795532" var request = &dataprocpb.ListJobsRequest{ ProjectId: projectId, Region: region, } c, err := NewJobControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListJobs(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestJobControllerUpdateJob(t *testing.T) { var submittedBy string = "submittedBy-2047729125" var driverOutputResourceUri string = "driverOutputResourceUri-542229086" var driverControlFilesUri string = "driverControlFilesUri207057643" var jobUuid string = "jobUuid-1615012099" var expectedResponse = &dataprocpb.Job{ SubmittedBy: submittedBy, DriverOutputResourceUri: driverOutputResourceUri, DriverControlFilesUri: driverControlFilesUri, JobUuid: jobUuid, } mockJobController.err = nil mockJobController.reqs = nil mockJobController.resps = append(mockJobController.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var region string = "region-934795532" var jobId string = "jobId-1154752291" var job *dataprocpb.Job = &dataprocpb.Job{} var updateMask *field_maskpb.FieldMask = &field_maskpb.FieldMask{} var request = &dataprocpb.UpdateJobRequest{ ProjectId: projectId, Region: region, JobId: jobId, Job: job, UpdateMask: updateMask, } c, err := NewJobControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateJob(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockJobController.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestJobControllerUpdateJobError(t *testing.T) { errCode := codes.PermissionDenied mockJobController.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var region string = "region-934795532" var jobId string = "jobId-1154752291" var job *dataprocpb.Job = &dataprocpb.Job{} var updateMask *field_maskpb.FieldMask = &field_maskpb.FieldMask{} var request = &dataprocpb.UpdateJobRequest{ ProjectId: projectId, Region: region, JobId: jobId, Job: job, UpdateMask: updateMask, } c, err := NewJobControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateJob(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestJobControllerCancelJob(t *testing.T) { var submittedBy string = "submittedBy-2047729125" var driverOutputResourceUri string = "driverOutputResourceUri-542229086" var driverControlFilesUri string = "driverControlFilesUri207057643" var jobUuid string = "jobUuid-1615012099" var expectedResponse = &dataprocpb.Job{ SubmittedBy: submittedBy, DriverOutputResourceUri: driverOutputResourceUri, DriverControlFilesUri: driverControlFilesUri, JobUuid: jobUuid, } mockJobController.err = nil mockJobController.reqs = nil mockJobController.resps = append(mockJobController.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var region string = "region-934795532" var jobId string = "jobId-1154752291" var request = &dataprocpb.CancelJobRequest{ ProjectId: projectId, Region: region, JobId: jobId, } c, err := NewJobControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CancelJob(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockJobController.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestJobControllerCancelJobError(t *testing.T) { errCode := codes.PermissionDenied mockJobController.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var region string = "region-934795532" var jobId string = "jobId-1154752291" var request = &dataprocpb.CancelJobRequest{ ProjectId: projectId, Region: region, JobId: jobId, } c, err := NewJobControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CancelJob(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestJobControllerDeleteJob(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockJobController.err = nil mockJobController.reqs = nil mockJobController.resps = append(mockJobController.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var region string = "region-934795532" var jobId string = "jobId-1154752291" var request = &dataprocpb.DeleteJobRequest{ ProjectId: projectId, Region: region, JobId: jobId, } c, err := NewJobControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteJob(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockJobController.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestJobControllerDeleteJobError(t *testing.T) { errCode := codes.PermissionDenied mockJobController.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var region string = "region-934795532" var jobId string = "jobId-1154752291" var request = &dataprocpb.DeleteJobRequest{ ProjectId: projectId, Region: region, JobId: jobId, } c, err := NewJobControllerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteJob(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestWorkflowTemplateServiceCreateWorkflowTemplate(t *testing.T) { var id string = "id3355" var name string = "name3373707" var version int32 = 351608024 var expectedResponse = &dataprocpb.WorkflowTemplate{ Id: id, Name: name, Version: version, } mockWorkflowTemplate.err = nil mockWorkflowTemplate.reqs = nil mockWorkflowTemplate.resps = append(mockWorkflowTemplate.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/regions/%s", "[PROJECT]", "[REGION]") var template *dataprocpb.WorkflowTemplate = &dataprocpb.WorkflowTemplate{} var request = &dataprocpb.CreateWorkflowTemplateRequest{ Parent: formattedParent, Template: template, } c, err := NewWorkflowTemplateClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateWorkflowTemplate(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockWorkflowTemplate.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestWorkflowTemplateServiceCreateWorkflowTemplateError(t *testing.T) { errCode := codes.PermissionDenied mockWorkflowTemplate.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/regions/%s", "[PROJECT]", "[REGION]") var template *dataprocpb.WorkflowTemplate = &dataprocpb.WorkflowTemplate{} var request = &dataprocpb.CreateWorkflowTemplateRequest{ Parent: formattedParent, Template: template, } c, err := NewWorkflowTemplateClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateWorkflowTemplate(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestWorkflowTemplateServiceGetWorkflowTemplate(t *testing.T) { var id string = "id3355" var name2 string = "name2-1052831874" var version int32 = 351608024 var expectedResponse = &dataprocpb.WorkflowTemplate{ Id: id, Name: name2, Version: version, } mockWorkflowTemplate.err = nil mockWorkflowTemplate.reqs = nil mockWorkflowTemplate.resps = append(mockWorkflowTemplate.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/regions/%s/workflowTemplates/%s", "[PROJECT]", "[REGION]", "[WORKFLOW_TEMPLATE]") var request = &dataprocpb.GetWorkflowTemplateRequest{ Name: formattedName, } c, err := NewWorkflowTemplateClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetWorkflowTemplate(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockWorkflowTemplate.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestWorkflowTemplateServiceGetWorkflowTemplateError(t *testing.T) { errCode := codes.PermissionDenied mockWorkflowTemplate.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/regions/%s/workflowTemplates/%s", "[PROJECT]", "[REGION]", "[WORKFLOW_TEMPLATE]") var request = &dataprocpb.GetWorkflowTemplateRequest{ Name: formattedName, } c, err := NewWorkflowTemplateClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetWorkflowTemplate(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestWorkflowTemplateServiceInstantiateWorkflowTemplate(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockWorkflowTemplate.err = nil mockWorkflowTemplate.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockWorkflowTemplate.resps = append(mockWorkflowTemplate.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedName string = fmt.Sprintf("projects/%s/regions/%s/workflowTemplates/%s", "[PROJECT]", "[REGION]", "[WORKFLOW_TEMPLATE]") var request = &dataprocpb.InstantiateWorkflowTemplateRequest{ Name: formattedName, } c, err := NewWorkflowTemplateClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.InstantiateWorkflowTemplate(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockWorkflowTemplate.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestWorkflowTemplateServiceInstantiateWorkflowTemplateError(t *testing.T) { errCode := codes.PermissionDenied mockWorkflowTemplate.err = nil mockWorkflowTemplate.resps = append(mockWorkflowTemplate.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedName string = fmt.Sprintf("projects/%s/regions/%s/workflowTemplates/%s", "[PROJECT]", "[REGION]", "[WORKFLOW_TEMPLATE]") var request = &dataprocpb.InstantiateWorkflowTemplateRequest{ Name: formattedName, } c, err := NewWorkflowTemplateClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.InstantiateWorkflowTemplate(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestWorkflowTemplateServiceInstantiateInlineWorkflowTemplate(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockWorkflowTemplate.err = nil mockWorkflowTemplate.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockWorkflowTemplate.resps = append(mockWorkflowTemplate.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedParent string = fmt.Sprintf("projects/%s/regions/%s", "[PROJECT]", "[REGION]") var template *dataprocpb.WorkflowTemplate = &dataprocpb.WorkflowTemplate{} var request = &dataprocpb.InstantiateInlineWorkflowTemplateRequest{ Parent: formattedParent, Template: template, } c, err := NewWorkflowTemplateClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.InstantiateInlineWorkflowTemplate(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockWorkflowTemplate.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestWorkflowTemplateServiceInstantiateInlineWorkflowTemplateError(t *testing.T) { errCode := codes.PermissionDenied mockWorkflowTemplate.err = nil mockWorkflowTemplate.resps = append(mockWorkflowTemplate.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedParent string = fmt.Sprintf("projects/%s/regions/%s", "[PROJECT]", "[REGION]") var template *dataprocpb.WorkflowTemplate = &dataprocpb.WorkflowTemplate{} var request = &dataprocpb.InstantiateInlineWorkflowTemplateRequest{ Parent: formattedParent, Template: template, } c, err := NewWorkflowTemplateClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.InstantiateInlineWorkflowTemplate(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestWorkflowTemplateServiceUpdateWorkflowTemplate(t *testing.T) { var id string = "id3355" var name string = "name3373707" var version int32 = 351608024 var expectedResponse = &dataprocpb.WorkflowTemplate{ Id: id, Name: name, Version: version, } mockWorkflowTemplate.err = nil mockWorkflowTemplate.reqs = nil mockWorkflowTemplate.resps = append(mockWorkflowTemplate.resps[:0], expectedResponse) var template *dataprocpb.WorkflowTemplate = &dataprocpb.WorkflowTemplate{} var request = &dataprocpb.UpdateWorkflowTemplateRequest{ Template: template, } c, err := NewWorkflowTemplateClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateWorkflowTemplate(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockWorkflowTemplate.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestWorkflowTemplateServiceUpdateWorkflowTemplateError(t *testing.T) { errCode := codes.PermissionDenied mockWorkflowTemplate.err = gstatus.Error(errCode, "test error") var template *dataprocpb.WorkflowTemplate = &dataprocpb.WorkflowTemplate{} var request = &dataprocpb.UpdateWorkflowTemplateRequest{ Template: template, } c, err := NewWorkflowTemplateClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateWorkflowTemplate(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestWorkflowTemplateServiceListWorkflowTemplates(t *testing.T) { var nextPageToken string = "" var templatesElement *dataprocpb.WorkflowTemplate = &dataprocpb.WorkflowTemplate{} var templates = []*dataprocpb.WorkflowTemplate{templatesElement} var expectedResponse = &dataprocpb.ListWorkflowTemplatesResponse{ NextPageToken: nextPageToken, Templates: templates, } mockWorkflowTemplate.err = nil mockWorkflowTemplate.reqs = nil mockWorkflowTemplate.resps = append(mockWorkflowTemplate.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/regions/%s", "[PROJECT]", "[REGION]") var request = &dataprocpb.ListWorkflowTemplatesRequest{ Parent: formattedParent, } c, err := NewWorkflowTemplateClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListWorkflowTemplates(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockWorkflowTemplate.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Templates[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestWorkflowTemplateServiceListWorkflowTemplatesError(t *testing.T) { errCode := codes.PermissionDenied mockWorkflowTemplate.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/regions/%s", "[PROJECT]", "[REGION]") var request = &dataprocpb.ListWorkflowTemplatesRequest{ Parent: formattedParent, } c, err := NewWorkflowTemplateClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListWorkflowTemplates(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestWorkflowTemplateServiceDeleteWorkflowTemplate(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockWorkflowTemplate.err = nil mockWorkflowTemplate.reqs = nil mockWorkflowTemplate.resps = append(mockWorkflowTemplate.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/regions/%s/workflowTemplates/%s", "[PROJECT]", "[REGION]", "[WORKFLOW_TEMPLATE]") var request = &dataprocpb.DeleteWorkflowTemplateRequest{ Name: formattedName, } c, err := NewWorkflowTemplateClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteWorkflowTemplate(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockWorkflowTemplate.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestWorkflowTemplateServiceDeleteWorkflowTemplateError(t *testing.T) { errCode := codes.PermissionDenied mockWorkflowTemplate.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/regions/%s/workflowTemplates/%s", "[PROJECT]", "[REGION]", "[WORKFLOW_TEMPLATE]") var request = &dataprocpb.DeleteWorkflowTemplateRequest{ Name: formattedName, } c, err := NewWorkflowTemplateClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteWorkflowTemplate(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } google-cloud-go-0.49.0/dataproc/apiv1beta2/workflow_template_client.go000066400000000000000000000534671356504100700257740ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package dataproc import ( "context" "fmt" "math" "net/url" "time" "cloud.google.com/go/longrunning" lroauto "cloud.google.com/go/longrunning/autogen" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" dataprocpb "google.golang.org/genproto/googleapis/cloud/dataproc/v1beta2" longrunningpb "google.golang.org/genproto/googleapis/longrunning" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // WorkflowTemplateCallOptions contains the retry settings for each method of WorkflowTemplateClient. type WorkflowTemplateCallOptions struct { CreateWorkflowTemplate []gax.CallOption GetWorkflowTemplate []gax.CallOption InstantiateWorkflowTemplate []gax.CallOption InstantiateInlineWorkflowTemplate []gax.CallOption UpdateWorkflowTemplate []gax.CallOption ListWorkflowTemplates []gax.CallOption DeleteWorkflowTemplate []gax.CallOption } func defaultWorkflowTemplateClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("dataproc.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultWorkflowTemplateCallOptions() *WorkflowTemplateCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Internal, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, {"default", "non_idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &WorkflowTemplateCallOptions{ CreateWorkflowTemplate: retry[[2]string{"default", "non_idempotent"}], GetWorkflowTemplate: retry[[2]string{"default", "idempotent"}], InstantiateWorkflowTemplate: retry[[2]string{"default", "non_idempotent"}], InstantiateInlineWorkflowTemplate: retry[[2]string{"default", "non_idempotent"}], UpdateWorkflowTemplate: retry[[2]string{"default", "non_idempotent"}], ListWorkflowTemplates: retry[[2]string{"default", "idempotent"}], DeleteWorkflowTemplate: retry[[2]string{"default", "non_idempotent"}], } } // WorkflowTemplateClient is a client for interacting with Google Cloud Dataproc API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type WorkflowTemplateClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. workflowTemplateClient dataprocpb.WorkflowTemplateServiceClient // LROClient is used internally to handle longrunning operations. // It is exposed so that its CallOptions can be modified if required. // Users should not Close this client. LROClient *lroauto.OperationsClient // The call options for this service. CallOptions *WorkflowTemplateCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewWorkflowTemplateClient creates a new workflow template service client. // // The API interface for managing Workflow Templates in the // Cloud Dataproc API. func NewWorkflowTemplateClient(ctx context.Context, opts ...option.ClientOption) (*WorkflowTemplateClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultWorkflowTemplateClientOptions(), opts...)...) if err != nil { return nil, err } c := &WorkflowTemplateClient{ conn: conn, CallOptions: defaultWorkflowTemplateCallOptions(), workflowTemplateClient: dataprocpb.NewWorkflowTemplateServiceClient(conn), } c.setGoogleClientInfo() c.LROClient, err = lroauto.NewOperationsClient(ctx, option.WithGRPCConn(conn)) if err != nil { // This error "should not happen", since we are just reusing old connection // and never actually need to dial. // If this does happen, we could leak conn. However, we cannot close conn: // If the user invoked the function with option.WithGRPCConn, // we would close a connection that's still in use. // TODO(pongad): investigate error conditions. return nil, err } return c, nil } // Connection returns the client's connection to the API service. func (c *WorkflowTemplateClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *WorkflowTemplateClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *WorkflowTemplateClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // CreateWorkflowTemplate creates new workflow template. func (c *WorkflowTemplateClient) CreateWorkflowTemplate(ctx context.Context, req *dataprocpb.CreateWorkflowTemplateRequest, opts ...gax.CallOption) (*dataprocpb.WorkflowTemplate, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateWorkflowTemplate[0:len(c.CallOptions.CreateWorkflowTemplate):len(c.CallOptions.CreateWorkflowTemplate)], opts...) var resp *dataprocpb.WorkflowTemplate err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.workflowTemplateClient.CreateWorkflowTemplate(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetWorkflowTemplate retrieves the latest workflow template. // // Can retrieve previously instantiated template by specifying optional // version parameter. func (c *WorkflowTemplateClient) GetWorkflowTemplate(ctx context.Context, req *dataprocpb.GetWorkflowTemplateRequest, opts ...gax.CallOption) (*dataprocpb.WorkflowTemplate, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetWorkflowTemplate[0:len(c.CallOptions.GetWorkflowTemplate):len(c.CallOptions.GetWorkflowTemplate)], opts...) var resp *dataprocpb.WorkflowTemplate err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.workflowTemplateClient.GetWorkflowTemplate(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // InstantiateWorkflowTemplate instantiates a template and begins execution. // // The returned Operation can be used to track execution of // workflow by polling // [operations.get][google.longrunning.Operations.GetOperation]. // The Operation will complete when entire workflow is finished. // // The running workflow can be aborted via // [operations.cancel][google.longrunning.Operations.CancelOperation]. // This will cause any inflight jobs to be cancelled and workflow-owned // clusters to be deleted. // // The [Operation.metadata][google.longrunning.Operation.metadata] will be // WorkflowMetadata (at /dataproc/docs/reference/rpc/google.cloud.dataproc.v1beta2#workflowmetadata). // Also see Using // WorkflowMetadata (at /dataproc/docs/concepts/workflows/debugging#using_workflowmetadata). // // On successful completion, // [Operation.response][google.longrunning.Operation.response] will be // [Empty][google.protobuf.Empty]. func (c *WorkflowTemplateClient) InstantiateWorkflowTemplate(ctx context.Context, req *dataprocpb.InstantiateWorkflowTemplateRequest, opts ...gax.CallOption) (*InstantiateWorkflowTemplateOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.InstantiateWorkflowTemplate[0:len(c.CallOptions.InstantiateWorkflowTemplate):len(c.CallOptions.InstantiateWorkflowTemplate)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.workflowTemplateClient.InstantiateWorkflowTemplate(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &InstantiateWorkflowTemplateOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // InstantiateInlineWorkflowTemplate instantiates a template and begins execution. // // This method is equivalent to executing the sequence // [CreateWorkflowTemplate][google.cloud.dataproc.v1beta2.WorkflowTemplateService.CreateWorkflowTemplate], [InstantiateWorkflowTemplate][google.cloud.dataproc.v1beta2.WorkflowTemplateService.InstantiateWorkflowTemplate], // [DeleteWorkflowTemplate][google.cloud.dataproc.v1beta2.WorkflowTemplateService.DeleteWorkflowTemplate]. // // The returned Operation can be used to track execution of // workflow by polling // [operations.get][google.longrunning.Operations.GetOperation]. // The Operation will complete when entire workflow is finished. // // The running workflow can be aborted via // [operations.cancel][google.longrunning.Operations.CancelOperation]. // This will cause any inflight jobs to be cancelled and workflow-owned // clusters to be deleted. // // The [Operation.metadata][google.longrunning.Operation.metadata] will be // WorkflowMetadata (at /dataproc/docs/reference/rpc/google.cloud.dataproc.v1#workflowmetadata). // Also see Using // WorkflowMetadata (at /dataproc/docs/concepts/workflows/debugging#using_workflowmetadata). // // On successful completion, // [Operation.response][google.longrunning.Operation.response] will be // [Empty][google.protobuf.Empty]. func (c *WorkflowTemplateClient) InstantiateInlineWorkflowTemplate(ctx context.Context, req *dataprocpb.InstantiateInlineWorkflowTemplateRequest, opts ...gax.CallOption) (*InstantiateInlineWorkflowTemplateOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.InstantiateInlineWorkflowTemplate[0:len(c.CallOptions.InstantiateInlineWorkflowTemplate):len(c.CallOptions.InstantiateInlineWorkflowTemplate)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.workflowTemplateClient.InstantiateInlineWorkflowTemplate(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &InstantiateInlineWorkflowTemplateOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // UpdateWorkflowTemplate updates (replaces) workflow template. The updated template // must contain version that matches the current server version. func (c *WorkflowTemplateClient) UpdateWorkflowTemplate(ctx context.Context, req *dataprocpb.UpdateWorkflowTemplateRequest, opts ...gax.CallOption) (*dataprocpb.WorkflowTemplate, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "template.name", url.QueryEscape(req.GetTemplate().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateWorkflowTemplate[0:len(c.CallOptions.UpdateWorkflowTemplate):len(c.CallOptions.UpdateWorkflowTemplate)], opts...) var resp *dataprocpb.WorkflowTemplate err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.workflowTemplateClient.UpdateWorkflowTemplate(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListWorkflowTemplates lists workflows that match the specified filter in the request. func (c *WorkflowTemplateClient) ListWorkflowTemplates(ctx context.Context, req *dataprocpb.ListWorkflowTemplatesRequest, opts ...gax.CallOption) *WorkflowTemplateIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListWorkflowTemplates[0:len(c.CallOptions.ListWorkflowTemplates):len(c.CallOptions.ListWorkflowTemplates)], opts...) it := &WorkflowTemplateIterator{} req = proto.Clone(req).(*dataprocpb.ListWorkflowTemplatesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*dataprocpb.WorkflowTemplate, string, error) { var resp *dataprocpb.ListWorkflowTemplatesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.workflowTemplateClient.ListWorkflowTemplates(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Templates, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // DeleteWorkflowTemplate deletes a workflow template. It does not cancel in-progress workflows. func (c *WorkflowTemplateClient) DeleteWorkflowTemplate(ctx context.Context, req *dataprocpb.DeleteWorkflowTemplateRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteWorkflowTemplate[0:len(c.CallOptions.DeleteWorkflowTemplate):len(c.CallOptions.DeleteWorkflowTemplate)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.workflowTemplateClient.DeleteWorkflowTemplate(ctx, req, settings.GRPC...) return err }, opts...) return err } // WorkflowTemplateIterator manages a stream of *dataprocpb.WorkflowTemplate. type WorkflowTemplateIterator struct { items []*dataprocpb.WorkflowTemplate pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*dataprocpb.WorkflowTemplate, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *WorkflowTemplateIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *WorkflowTemplateIterator) Next() (*dataprocpb.WorkflowTemplate, error) { var item *dataprocpb.WorkflowTemplate if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *WorkflowTemplateIterator) bufLen() int { return len(it.items) } func (it *WorkflowTemplateIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // InstantiateInlineWorkflowTemplateOperation manages a long-running operation from InstantiateInlineWorkflowTemplate. type InstantiateInlineWorkflowTemplateOperation struct { lro *longrunning.Operation } // InstantiateInlineWorkflowTemplateOperation returns a new InstantiateInlineWorkflowTemplateOperation from a given name. // The name must be that of a previously created InstantiateInlineWorkflowTemplateOperation, possibly from a different process. func (c *WorkflowTemplateClient) InstantiateInlineWorkflowTemplateOperation(name string) *InstantiateInlineWorkflowTemplateOperation { return &InstantiateInlineWorkflowTemplateOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning any error encountered. // // See documentation of Poll for error-handling information. func (op *InstantiateInlineWorkflowTemplateOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { return op.lro.WaitWithInterval(ctx, nil, 10000*time.Millisecond, opts...) } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, op.Done will return true. func (op *InstantiateInlineWorkflowTemplateOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Poll(ctx, nil, opts...) } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *InstantiateInlineWorkflowTemplateOperation) Metadata() (*dataprocpb.WorkflowMetadata, error) { var meta dataprocpb.WorkflowMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *InstantiateInlineWorkflowTemplateOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *InstantiateInlineWorkflowTemplateOperation) Name() string { return op.lro.Name() } // InstantiateWorkflowTemplateOperation manages a long-running operation from InstantiateWorkflowTemplate. type InstantiateWorkflowTemplateOperation struct { lro *longrunning.Operation } // InstantiateWorkflowTemplateOperation returns a new InstantiateWorkflowTemplateOperation from a given name. // The name must be that of a previously created InstantiateWorkflowTemplateOperation, possibly from a different process. func (c *WorkflowTemplateClient) InstantiateWorkflowTemplateOperation(name string) *InstantiateWorkflowTemplateOperation { return &InstantiateWorkflowTemplateOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning any error encountered. // // See documentation of Poll for error-handling information. func (op *InstantiateWorkflowTemplateOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { return op.lro.WaitWithInterval(ctx, nil, 10000*time.Millisecond, opts...) } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, op.Done will return true. func (op *InstantiateWorkflowTemplateOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Poll(ctx, nil, opts...) } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *InstantiateWorkflowTemplateOperation) Metadata() (*dataprocpb.WorkflowMetadata, error) { var meta dataprocpb.WorkflowMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *InstantiateWorkflowTemplateOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *InstantiateWorkflowTemplateOperation) Name() string { return op.lro.Name() } google-cloud-go-0.49.0/dataproc/apiv1beta2/workflow_template_client_example_test.go000066400000000000000000000076421356504100700305400ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package dataproc_test import ( "context" dataproc "cloud.google.com/go/dataproc/apiv1beta2" "google.golang.org/api/iterator" dataprocpb "google.golang.org/genproto/googleapis/cloud/dataproc/v1beta2" ) func ExampleNewWorkflowTemplateClient() { ctx := context.Background() c, err := dataproc.NewWorkflowTemplateClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleWorkflowTemplateClient_CreateWorkflowTemplate() { ctx := context.Background() c, err := dataproc.NewWorkflowTemplateClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.CreateWorkflowTemplateRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateWorkflowTemplate(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleWorkflowTemplateClient_GetWorkflowTemplate() { ctx := context.Background() c, err := dataproc.NewWorkflowTemplateClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.GetWorkflowTemplateRequest{ // TODO: Fill request struct fields. } resp, err := c.GetWorkflowTemplate(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleWorkflowTemplateClient_InstantiateWorkflowTemplate() { ctx := context.Background() c, err := dataproc.NewWorkflowTemplateClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.InstantiateWorkflowTemplateRequest{ // TODO: Fill request struct fields. } op, err := c.InstantiateWorkflowTemplate(ctx, req) if err != nil { // TODO: Handle error. } err = op.Wait(ctx) // TODO: Handle error. } func ExampleWorkflowTemplateClient_InstantiateInlineWorkflowTemplate() { ctx := context.Background() c, err := dataproc.NewWorkflowTemplateClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.InstantiateInlineWorkflowTemplateRequest{ // TODO: Fill request struct fields. } op, err := c.InstantiateInlineWorkflowTemplate(ctx, req) if err != nil { // TODO: Handle error. } err = op.Wait(ctx) // TODO: Handle error. } func ExampleWorkflowTemplateClient_UpdateWorkflowTemplate() { ctx := context.Background() c, err := dataproc.NewWorkflowTemplateClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.UpdateWorkflowTemplateRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateWorkflowTemplate(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleWorkflowTemplateClient_ListWorkflowTemplates() { ctx := context.Background() c, err := dataproc.NewWorkflowTemplateClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.ListWorkflowTemplatesRequest{ // TODO: Fill request struct fields. } it := c.ListWorkflowTemplates(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleWorkflowTemplateClient_DeleteWorkflowTemplate() { ctx := context.Background() c, err := dataproc.NewWorkflowTemplateClient(ctx) if err != nil { // TODO: Handle error. } req := &dataprocpb.DeleteWorkflowTemplateRequest{ // TODO: Fill request struct fields. } err = c.DeleteWorkflowTemplate(ctx, req) if err != nil { // TODO: Handle error. } } google-cloud-go-0.49.0/datastore/000077500000000000000000000000001356504100700165565ustar00rootroot00000000000000google-cloud-go-0.49.0/datastore/.repo-metadata.json000066400000000000000000000006421356504100700222540ustar00rootroot00000000000000{ "name": "datastore", "name_pretty": "Cloud Datastore API", "product_documentation": "https://cloud.google.com/datastore/", "client_documentation": "https://godoc.org/cloud.google.com/go/datastore", "release_level": "ga", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go/datastore", "api_id": "datastore.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/datastore/CHANGES.md000066400000000000000000000003011356504100700201420ustar00rootroot00000000000000# Changes ## v1.0.0 This is the first tag to carve out datastore as its own module. See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository.google-cloud-go-0.49.0/datastore/README.md000066400000000000000000000023721356504100700200410ustar00rootroot00000000000000## Cloud Datastore [![GoDoc](https://godoc.org/cloud.google.com/go/datastore?status.svg)](https://godoc.org/cloud.google.com/go/datastore) - [About Cloud Datastore](https://cloud.google.com/datastore/) - [Activating the API for your project](https://cloud.google.com/datastore/docs/activate) - [API documentation](https://cloud.google.com/datastore/docs) - [Go client documentation](https://godoc.org/cloud.google.com/go/datastore) - [Complete sample program](https://github.com/GoogleCloudPlatform/golang-samples/tree/master/datastore/tasks) ### Example Usage First create a `datastore.Client` to use throughout your application: [snip]:# (datastore-1) ```go client, err := datastore.NewClient(ctx, "my-project-id") if err != nil { log.Fatal(err) } ``` Then use that client to interact with the API: [snip]:# (datastore-2) ```go type Post struct { Title string Body string `datastore:",noindex"` PublishedAt time.Time } keys := []*datastore.Key{ datastore.NameKey("Post", "post1", nil), datastore.NameKey("Post", "post2", nil), } posts := []*Post{ {Title: "Post 1", Body: "...", PublishedAt: time.Now()}, {Title: "Post 2", Body: "...", PublishedAt: time.Now()}, } if _, err := client.PutMulti(ctx, keys, posts); err != nil { log.Fatal(err) } ```google-cloud-go-0.49.0/datastore/client.go000066400000000000000000000075121356504100700203700ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package datastore import ( "context" "fmt" "time" "cloud.google.com/go/internal" "cloud.google.com/go/internal/version" gax "github.com/googleapis/gax-go/v2" pb "google.golang.org/genproto/googleapis/datastore/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" ) // datastoreClient is a wrapper for the pb.DatastoreClient that includes gRPC // metadata to be sent in each request for server-side traffic management. type datastoreClient struct { // Embed so we still implement the DatastoreClient interface, // if the interface adds more methods. pb.DatastoreClient c pb.DatastoreClient md metadata.MD } func newDatastoreClient(conn *grpc.ClientConn, projectID string) pb.DatastoreClient { return &datastoreClient{ c: pb.NewDatastoreClient(conn), md: metadata.Pairs( resourcePrefixHeader, "projects/"+projectID, "x-goog-api-client", fmt.Sprintf("gl-go/%s gccl/%s grpc/", version.Go(), version.Repo)), } } func (dc *datastoreClient) Lookup(ctx context.Context, in *pb.LookupRequest, opts ...grpc.CallOption) (res *pb.LookupResponse, err error) { err = dc.invoke(ctx, func(ctx context.Context) error { res, err = dc.c.Lookup(ctx, in, opts...) return err }) return res, err } func (dc *datastoreClient) RunQuery(ctx context.Context, in *pb.RunQueryRequest, opts ...grpc.CallOption) (res *pb.RunQueryResponse, err error) { err = dc.invoke(ctx, func(ctx context.Context) error { res, err = dc.c.RunQuery(ctx, in, opts...) return err }) return res, err } func (dc *datastoreClient) BeginTransaction(ctx context.Context, in *pb.BeginTransactionRequest, opts ...grpc.CallOption) (res *pb.BeginTransactionResponse, err error) { err = dc.invoke(ctx, func(ctx context.Context) error { res, err = dc.c.BeginTransaction(ctx, in, opts...) return err }) return res, err } func (dc *datastoreClient) Commit(ctx context.Context, in *pb.CommitRequest, opts ...grpc.CallOption) (res *pb.CommitResponse, err error) { err = dc.invoke(ctx, func(ctx context.Context) error { res, err = dc.c.Commit(ctx, in, opts...) return err }) return res, err } func (dc *datastoreClient) Rollback(ctx context.Context, in *pb.RollbackRequest, opts ...grpc.CallOption) (res *pb.RollbackResponse, err error) { err = dc.invoke(ctx, func(ctx context.Context) error { res, err = dc.c.Rollback(ctx, in, opts...) return err }) return res, err } func (dc *datastoreClient) AllocateIds(ctx context.Context, in *pb.AllocateIdsRequest, opts ...grpc.CallOption) (res *pb.AllocateIdsResponse, err error) { err = dc.invoke(ctx, func(ctx context.Context) error { res, err = dc.c.AllocateIds(ctx, in, opts...) return err }) return res, err } func (dc *datastoreClient) invoke(ctx context.Context, f func(ctx context.Context) error) error { ctx = metadata.NewOutgoingContext(ctx, dc.md) return internal.Retry(ctx, gax.Backoff{Initial: 100 * time.Millisecond}, func() (stop bool, err error) { err = f(ctx) return !shouldRetry(err), err }) } func shouldRetry(err error) bool { if err == nil { return false } s, ok := status.FromError(err) if !ok { return false } // See https://cloud.google.com/datastore/docs/concepts/errors. return s.Code() == codes.Unavailable || s.Code() == codes.DeadlineExceeded } google-cloud-go-0.49.0/datastore/datastore.go000066400000000000000000000475141356504100700211060ustar00rootroot00000000000000// Copyright 2014 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package datastore import ( "context" "errors" "fmt" "log" "os" "reflect" "cloud.google.com/go/internal/trace" "google.golang.org/api/option" "google.golang.org/api/transport" gtransport "google.golang.org/api/transport/grpc" pb "google.golang.org/genproto/googleapis/datastore/v1" "google.golang.org/grpc" ) const ( prodAddr = "datastore.googleapis.com:443" userAgent = "gcloud-golang-datastore/20160401" ) // ScopeDatastore grants permissions to view and/or manage datastore entities const ScopeDatastore = "https://www.googleapis.com/auth/datastore" // DetectProjectID is a sentinel value that instructs NewClient to detect the // project ID. It is given in place of the projectID argument. NewClient will // use the project ID from the given credentials or the default credentials // (https://developers.google.com/accounts/docs/application-default-credentials) // if no credentials were provided. When providing credentials, not all // options will allow NewClient to extract the project ID. Specifically a JWT // does not have the project ID encoded. const DetectProjectID = "*detect-project-id*" // resourcePrefixHeader is the name of the metadata header used to indicate // the resource being operated on. const resourcePrefixHeader = "google-cloud-resource-prefix" // Client is a client for reading and writing data in a datastore dataset. type Client struct { conn *grpc.ClientConn client pb.DatastoreClient dataset string // Called dataset by the datastore API, synonym for project ID. } // NewClient creates a new Client for a given dataset. If the project ID is // empty, it is derived from the DATASTORE_PROJECT_ID environment variable. // If the DATASTORE_EMULATOR_HOST environment variable is set, client will use // its value to connect to a locally-running datastore emulator. // DetectProjectID can be passed as the projectID argument to instruct // NewClient to detect the project ID from the credentials. func NewClient(ctx context.Context, projectID string, opts ...option.ClientOption) (*Client, error) { var o []option.ClientOption // Environment variables for gcd emulator: // https://cloud.google.com/datastore/docs/tools/datastore-emulator // If the emulator is available, dial it without passing any credentials. if addr := os.Getenv("DATASTORE_EMULATOR_HOST"); addr != "" { o = []option.ClientOption{ option.WithEndpoint(addr), option.WithoutAuthentication(), option.WithGRPCDialOption(grpc.WithInsecure()), } } else { o = []option.ClientOption{ option.WithEndpoint(prodAddr), option.WithScopes(ScopeDatastore), option.WithUserAgent(userAgent), } } // Warn if we see the legacy emulator environment variables. if os.Getenv("DATASTORE_HOST") != "" && os.Getenv("DATASTORE_EMULATOR_HOST") == "" { log.Print("WARNING: legacy environment variable DATASTORE_HOST is ignored. Use DATASTORE_EMULATOR_HOST instead.") } if os.Getenv("DATASTORE_DATASET") != "" && os.Getenv("DATASTORE_PROJECT_ID") == "" { log.Print("WARNING: legacy environment variable DATASTORE_DATASET is ignored. Use DATASTORE_PROJECT_ID instead.") } if projectID == "" { projectID = os.Getenv("DATASTORE_PROJECT_ID") } o = append(o, opts...) if projectID == DetectProjectID { creds, err := transport.Creds(ctx, o...) if err != nil { return nil, fmt.Errorf("fetching creds: %v", err) } if creds.ProjectID == "" { return nil, errors.New("datastore: see the docs on DetectProjectID") } projectID = creds.ProjectID } if projectID == "" { return nil, errors.New("datastore: missing project/dataset id") } conn, err := gtransport.Dial(ctx, o...) if err != nil { return nil, fmt.Errorf("dialing: %v", err) } return &Client{ conn: conn, client: newDatastoreClient(conn, projectID), dataset: projectID, }, nil } var ( // ErrInvalidEntityType is returned when functions like Get or Next are // passed a dst or src argument of invalid type. ErrInvalidEntityType = errors.New("datastore: invalid entity type") // ErrInvalidKey is returned when an invalid key is presented. ErrInvalidKey = errors.New("datastore: invalid key") // ErrNoSuchEntity is returned when no entity was found for a given key. ErrNoSuchEntity = errors.New("datastore: no such entity") ) type multiArgType int const ( multiArgTypeInvalid multiArgType = iota multiArgTypePropertyLoadSaver multiArgTypeStruct multiArgTypeStructPtr multiArgTypeInterface ) // ErrFieldMismatch is returned when a field is to be loaded into a different // type than the one it was stored from, or when a field is missing or // unexported in the destination struct. // StructType is the type of the struct pointed to by the destination argument // passed to Get or to Iterator.Next. type ErrFieldMismatch struct { StructType reflect.Type FieldName string Reason string } func (e *ErrFieldMismatch) Error() string { return fmt.Sprintf("datastore: cannot load field %q into a %q: %s", e.FieldName, e.StructType, e.Reason) } // GeoPoint represents a location as latitude/longitude in degrees. type GeoPoint struct { Lat, Lng float64 } // Valid returns whether a GeoPoint is within [-90, 90] latitude and [-180, 180] longitude. func (g GeoPoint) Valid() bool { return -90 <= g.Lat && g.Lat <= 90 && -180 <= g.Lng && g.Lng <= 180 } func keyToProto(k *Key) *pb.Key { if k == nil { return nil } var path []*pb.Key_PathElement for { el := &pb.Key_PathElement{Kind: k.Kind} if k.ID != 0 { el.IdType = &pb.Key_PathElement_Id{Id: k.ID} } else if k.Name != "" { el.IdType = &pb.Key_PathElement_Name{Name: k.Name} } path = append(path, el) if k.Parent == nil { break } k = k.Parent } // The path should be in order [grandparent, parent, child] // We did it backward above, so reverse back. for i := 0; i < len(path)/2; i++ { path[i], path[len(path)-i-1] = path[len(path)-i-1], path[i] } key := &pb.Key{Path: path} if k.Namespace != "" { key.PartitionId = &pb.PartitionId{ NamespaceId: k.Namespace, } } return key } // protoToKey decodes a protocol buffer representation of a key into an // equivalent *Key object. If the key is invalid, protoToKey will return the // invalid key along with ErrInvalidKey. func protoToKey(p *pb.Key) (*Key, error) { var key *Key var namespace string if partition := p.PartitionId; partition != nil { namespace = partition.NamespaceId } for _, el := range p.Path { key = &Key{ Namespace: namespace, Kind: el.Kind, ID: el.GetId(), Name: el.GetName(), Parent: key, } } if !key.valid() { // Also detects key == nil. return key, ErrInvalidKey } return key, nil } // multiKeyToProto is a batch version of keyToProto. func multiKeyToProto(keys []*Key) []*pb.Key { ret := make([]*pb.Key, len(keys)) for i, k := range keys { ret[i] = keyToProto(k) } return ret } // multiKeyToProto is a batch version of keyToProto. func multiProtoToKey(keys []*pb.Key) ([]*Key, error) { hasErr := false ret := make([]*Key, len(keys)) err := make(MultiError, len(keys)) for i, k := range keys { ret[i], err[i] = protoToKey(k) if err[i] != nil { hasErr = true } } if hasErr { return nil, err } return ret, nil } // multiValid is a batch version of Key.valid. It returns an error, not a // []bool. func multiValid(key []*Key) error { invalid := false for _, k := range key { if !k.valid() { invalid = true break } } if !invalid { return nil } err := make(MultiError, len(key)) for i, k := range key { if !k.valid() { err[i] = ErrInvalidKey } } return err } // checkMultiArg checks that v has type []S, []*S, []I, or []P, for some struct // type S, for some interface type I, or some non-interface non-pointer type P // such that P or *P implements PropertyLoadSaver. // // It returns what category the slice's elements are, and the reflect.Type // that represents S, I or P. // // As a special case, PropertyList is an invalid type for v. func checkMultiArg(v reflect.Value) (m multiArgType, elemType reflect.Type) { // TODO(djd): multiArg is very confusing. Fold this logic into the // relevant Put/Get methods to make the logic less opaque. if v.Kind() != reflect.Slice { return multiArgTypeInvalid, nil } if v.Type() == typeOfPropertyList { return multiArgTypeInvalid, nil } elemType = v.Type().Elem() if reflect.PtrTo(elemType).Implements(typeOfPropertyLoadSaver) { return multiArgTypePropertyLoadSaver, elemType } switch elemType.Kind() { case reflect.Struct: return multiArgTypeStruct, elemType case reflect.Interface: return multiArgTypeInterface, elemType case reflect.Ptr: elemType = elemType.Elem() if elemType.Kind() == reflect.Struct { return multiArgTypeStructPtr, elemType } } return multiArgTypeInvalid, nil } // Close closes the Client. func (c *Client) Close() error { return c.conn.Close() } // Get loads the entity stored for key into dst, which must be a struct pointer // or implement PropertyLoadSaver. If there is no such entity for the key, Get // returns ErrNoSuchEntity. // // The values of dst's unmatched struct fields are not modified, and matching // slice-typed fields are not reset before appending to them. In particular, it // is recommended to pass a pointer to a zero valued struct on each Get call. // // ErrFieldMismatch is returned when a field is to be loaded into a different // type than the one it was stored from, or when a field is missing or // unexported in the destination struct. ErrFieldMismatch is only returned if // dst is a struct pointer. func (c *Client) Get(ctx context.Context, key *Key, dst interface{}) (err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/datastore.Get") defer func() { trace.EndSpan(ctx, err) }() if dst == nil { // get catches nil interfaces; we need to catch nil ptr here return ErrInvalidEntityType } err = c.get(ctx, []*Key{key}, []interface{}{dst}, nil) if me, ok := err.(MultiError); ok { return me[0] } return err } // GetMulti is a batch version of Get. // // dst must be a []S, []*S, []I or []P, for some struct type S, some interface // type I, or some non-interface non-pointer type P such that P or *P // implements PropertyLoadSaver. If an []I, each element must be a valid dst // for Get: it must be a struct pointer or implement PropertyLoadSaver. // // As a special case, PropertyList is an invalid type for dst, even though a // PropertyList is a slice of structs. It is treated as invalid to avoid being // mistakenly passed when []PropertyList was intended. // // err may be a MultiError. See ExampleMultiError to check it. func (c *Client) GetMulti(ctx context.Context, keys []*Key, dst interface{}) (err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/datastore.GetMulti") defer func() { trace.EndSpan(ctx, err) }() return c.get(ctx, keys, dst, nil) } func (c *Client) get(ctx context.Context, keys []*Key, dst interface{}, opts *pb.ReadOptions) error { v := reflect.ValueOf(dst) multiArgType, _ := checkMultiArg(v) // Sanity checks if multiArgType == multiArgTypeInvalid { return errors.New("datastore: dst has invalid type") } if len(keys) != v.Len() { return errors.New("datastore: keys and dst slices have different length") } if len(keys) == 0 { return nil } // Go through keys, validate them, serialize then, and create a dict mapping them to their indices. // Equal keys are deduped. multiErr, any := make(MultiError, len(keys)), false keyMap := make(map[string][]int, len(keys)) pbKeys := make([]*pb.Key, 0, len(keys)) for i, k := range keys { if !k.valid() { multiErr[i] = ErrInvalidKey any = true } else if k.Incomplete() { multiErr[i] = fmt.Errorf("datastore: can't get the incomplete key: %v", k) any = true } else { ks := k.String() if _, ok := keyMap[ks]; !ok { pbKeys = append(pbKeys, keyToProto(k)) } keyMap[ks] = append(keyMap[ks], i) } } if any { return multiErr } req := &pb.LookupRequest{ ProjectId: c.dataset, Keys: pbKeys, ReadOptions: opts, } resp, err := c.client.Lookup(ctx, req) if err != nil { return err } found := resp.Found missing := resp.Missing // Upper bound 100 iterations to prevent infinite loop. // We choose 100 iterations somewhat logically: // Max number of Entities you can request from Datastore is 1,000. // Max size for a Datastore Entity is 1 MiB. // Max request size is 10 MiB, so we assume max response size is also 10 MiB. // 1,000 / 10 = 100. // Note that if ctx has a deadline, the deadline will probably // be hit before we reach 100 iterations. for i := 0; len(resp.Deferred) > 0 && i < 100; i++ { req.Keys = resp.Deferred resp, err = c.client.Lookup(ctx, req) if err != nil { return err } found = append(found, resp.Found...) missing = append(missing, resp.Missing...) } filled := 0 for _, e := range found { k, err := protoToKey(e.Entity.Key) if err != nil { return errors.New("datastore: internal error: server returned an invalid key") } filled += len(keyMap[k.String()]) for _, index := range keyMap[k.String()] { elem := v.Index(index) if multiArgType == multiArgTypePropertyLoadSaver || multiArgType == multiArgTypeStruct { elem = elem.Addr() } if multiArgType == multiArgTypeStructPtr && elem.IsNil() { elem.Set(reflect.New(elem.Type().Elem())) } if err := loadEntityProto(elem.Interface(), e.Entity); err != nil { multiErr[index] = err any = true } } } for _, e := range missing { k, err := protoToKey(e.Entity.Key) if err != nil { return errors.New("datastore: internal error: server returned an invalid key") } filled += len(keyMap[k.String()]) for _, index := range keyMap[k.String()] { multiErr[index] = ErrNoSuchEntity } any = true } if filled != len(keys) { return errors.New("datastore: internal error: server returned the wrong number of entities") } if any { return multiErr } return nil } // Put saves the entity src into the datastore with the given key. src must be // a struct pointer or implement PropertyLoadSaver; if the struct pointer has // any unexported fields they will be skipped. If the key is incomplete, the // returned key will be a unique key generated by the datastore. func (c *Client) Put(ctx context.Context, key *Key, src interface{}) (*Key, error) { k, err := c.PutMulti(ctx, []*Key{key}, []interface{}{src}) if err != nil { if me, ok := err.(MultiError); ok { return nil, me[0] } return nil, err } return k[0], nil } // PutMulti is a batch version of Put. // // src must satisfy the same conditions as the dst argument to GetMulti. // err may be a MultiError. See ExampleMultiError to check it. func (c *Client) PutMulti(ctx context.Context, keys []*Key, src interface{}) (ret []*Key, err error) { // TODO(jba): rewrite in terms of Mutate. ctx = trace.StartSpan(ctx, "cloud.google.com/go/datastore.PutMulti") defer func() { trace.EndSpan(ctx, err) }() mutations, err := putMutations(keys, src) if err != nil { return nil, err } // Make the request. req := &pb.CommitRequest{ ProjectId: c.dataset, Mutations: mutations, Mode: pb.CommitRequest_NON_TRANSACTIONAL, } resp, err := c.client.Commit(ctx, req) if err != nil { return nil, err } // Copy any newly minted keys into the returned keys. ret = make([]*Key, len(keys)) for i, key := range keys { if key.Incomplete() { // This key is in the mutation results. ret[i], err = protoToKey(resp.MutationResults[i].Key) if err != nil { return nil, errors.New("datastore: internal error: server returned an invalid key") } } else { ret[i] = key } } return ret, nil } func putMutations(keys []*Key, src interface{}) ([]*pb.Mutation, error) { v := reflect.ValueOf(src) multiArgType, _ := checkMultiArg(v) if multiArgType == multiArgTypeInvalid { return nil, errors.New("datastore: src has invalid type") } if len(keys) != v.Len() { return nil, errors.New("datastore: key and src slices have different length") } if len(keys) == 0 { return nil, nil } if err := multiValid(keys); err != nil { return nil, err } mutations := make([]*pb.Mutation, 0, len(keys)) multiErr := make(MultiError, len(keys)) hasErr := false for i, k := range keys { elem := v.Index(i) // Two cases where we need to take the address: // 1) multiArgTypePropertyLoadSaver => &elem implements PLS // 2) multiArgTypeStruct => saveEntity needs *struct if multiArgType == multiArgTypePropertyLoadSaver || multiArgType == multiArgTypeStruct { elem = elem.Addr() } p, err := saveEntity(k, elem.Interface()) if err != nil { multiErr[i] = err hasErr = true } var mut *pb.Mutation if k.Incomplete() { mut = &pb.Mutation{Operation: &pb.Mutation_Insert{Insert: p}} } else { mut = &pb.Mutation{Operation: &pb.Mutation_Upsert{Upsert: p}} } mutations = append(mutations, mut) } if hasErr { return nil, multiErr } return mutations, nil } // Delete deletes the entity for the given key. func (c *Client) Delete(ctx context.Context, key *Key) error { err := c.DeleteMulti(ctx, []*Key{key}) if me, ok := err.(MultiError); ok { return me[0] } return err } // DeleteMulti is a batch version of Delete. // // err may be a MultiError. See ExampleMultiError to check it. func (c *Client) DeleteMulti(ctx context.Context, keys []*Key) (err error) { // TODO(jba): rewrite in terms of Mutate. ctx = trace.StartSpan(ctx, "cloud.google.com/go/datastore.DeleteMulti") defer func() { trace.EndSpan(ctx, err) }() mutations, err := deleteMutations(keys) if err != nil { return err } req := &pb.CommitRequest{ ProjectId: c.dataset, Mutations: mutations, Mode: pb.CommitRequest_NON_TRANSACTIONAL, } _, err = c.client.Commit(ctx, req) return err } func deleteMutations(keys []*Key) ([]*pb.Mutation, error) { mutations := make([]*pb.Mutation, 0, len(keys)) set := make(map[string]bool, len(keys)) multiErr := make(MultiError, len(keys)) hasErr := false for i, k := range keys { if !k.valid() { multiErr[i] = ErrInvalidKey hasErr = true } else if k.Incomplete() { multiErr[i] = fmt.Errorf("datastore: can't delete the incomplete key: %v", k) hasErr = true } else { ks := k.String() if !set[ks] { mutations = append(mutations, &pb.Mutation{ Operation: &pb.Mutation_Delete{Delete: keyToProto(k)}, }) } set[ks] = true } } if hasErr { return nil, multiErr } return mutations, nil } // Mutate applies one or more mutations atomically. // It returns the keys of the argument Mutations, in the same order. // // If any of the mutations are invalid, Mutate returns a MultiError with the errors. // Mutate returns a MultiError in this case even if there is only one Mutation. // See ExampleMultiError to check it. func (c *Client) Mutate(ctx context.Context, muts ...*Mutation) (ret []*Key, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/datastore.Mutate") defer func() { trace.EndSpan(ctx, err) }() pmuts, err := mutationProtos(muts) if err != nil { return nil, err } req := &pb.CommitRequest{ ProjectId: c.dataset, Mutations: pmuts, Mode: pb.CommitRequest_NON_TRANSACTIONAL, } resp, err := c.client.Commit(ctx, req) if err != nil { return nil, err } // Copy any newly minted keys into the returned keys. ret = make([]*Key, len(muts)) for i, mut := range muts { if mut.key.Incomplete() { // This key is in the mutation results. ret[i], err = protoToKey(resp.MutationResults[i].Key) if err != nil { return nil, errors.New("datastore: internal error: server returned an invalid key") } } else { ret[i] = mut.key } } return ret, nil } google-cloud-go-0.49.0/datastore/datastore.replay000066400000000000000000163351161356504100700220020ustar00rootroot00000000000000RPCReplayL{"ProjectID":"dulcet-port-762","Time":"2019-08-11T16:06:43.131850927-04:00"}½%/google.datastore.v1.Datastore/Commit‘ 5type.googleapis.com/google.datastore.v1.CommitRequestX(2C"A  BasicsX IB SŠ99 T R ÓêÁêÀÍ»> UŠXBdulcet-port-762vp 6type.googleapis.com/google.datastore.v1.CommitResponse62' dulcet-port-762 BasicsX€€€Çú– ˆþ…’Ïûã (‹%/google.datastore.v1.Datastore/Lookup` 5type.googleapis.com/google.datastore.v1.LookupRequest' BasicsX€€€Çú– Bdulcet-port-762«¤ 6type.googleapis.com/google.datastore.v1.LookupResponsej h ] ' dulcet-port-762 BasicsX€€€Çú–  SŠ99 UŠX IB T R ÓêÁêÀÍ»> ˆþ…’Ïûã(%/google.datastore.v1.Datastore/Commitd 5type.googleapis.com/google.datastore.v1.CommitRequest+(2: BasicsX€€€Çú– Bdulcet-port-762MG 6type.googleapis.com/google.datastore.v1.CommitResponse  ¸Ê‘’Ïûã (­%/google.datastore.v1.Datastore/Commit 5type.googleapis.com/google.datastore.v1.CommitRequestH(2321  EntityWithKeymyent I  SŠabcdBdulcet-port-762KE 6type.googleapis.com/google.datastore.v1.CommitResponse  ø„´¼ùøÐ(%/google.datastore.v1.Datastore/Lookupd 5type.googleapis.com/google.datastore.v1.LookupRequest+ EntityWithKeymyentBdulcet-port-762’‹ 6type.googleapis.com/google.datastore.v1.LookupResponseQ O D + dulcet-port-762 EntityWithKeymyent SŠabcd I ø„´¼ùøÐ( ¦%/google.datastore.v1.Datastore/Commit{ 5type.googleapis.com/google.datastore.v1.CommitRequestB(2-"+  ListValue LJ  Šstring Bdulcet-port-762xr 6type.googleapis.com/google.datastore.v1.CommitResponse84) dulcet-port-762 ListValue€€€û°÷ Ðë­’Ïûã ( %/google.datastore.v1.Datastore/Lookupb 5type.googleapis.com/google.datastore.v1.LookupRequest) ListValue€€€û°÷ Bdulcet-port-762•Ž 6type.googleapis.com/google.datastore.v1.LookupResponseT R G ) dulcet-port-762 ListValue€€€û°÷  LJ  Šstring  Ðë­’Ïûã( ‘%/google.datastore.v1.Datastore/Commitf 5type.googleapis.com/google.datastore.v1.CommitRequest-(2: ListValue€€€û°÷ Bdulcet-port-762MG 6type.googleapis.com/google.datastore.v1.CommitResponse  ˜°¹’Ïûã (é%/google.datastore.v1.Datastore/Commit½ 5type.googleapis.com/google.datastore.v1.CommitRequestƒ(2624 ) Xx-t1565554003131850927 Xitem1 I2624 ) Xx-t1565554003131850927 Xitem4 IBdulcet-port-762XR 6type.googleapis.com/google.datastore.v1.CommitResponse ØÖÁ’Ïûã ØÖÁ’Ïûã (#%/google.datastore.v1.Datastore/Lookup÷ 5type.googleapis.com/google.datastore.v1.LookupRequest½) Xx-t1565554003131850927 Xitem1) Xx-t1565554003131850927 Xitem2) Xx-t1565554003131850927 Xitem3) Xx-t1565554003131850927 Xitem4Bdulcet-port-762€ù 6type.googleapis.com/google.datastore.v1.LookupResponse¾ R G < dulcet-port-762 Xx-t1565554003131850927 Xitem1 I ØÖÁ’Ïûã R G < dulcet-port-762 Xx-t1565554003131850927 Xitem4 I ØÖÁ’ÏûãI > < dulcet-port-762 Xx-t1565554003131850927 Xitem2 ØÖÁ’ÏûãI > < dulcet-port-762 Xx-t1565554003131850927 Xitem3 ØÖÁ’Ïûã(™%/google.datastore.v1.Datastore/Commití 5type.googleapis.com/google.datastore.v1.CommitRequest³ (2 "š  BasicsZæ Sà ŠÜ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx T˜Š P’ K˜’Bdulcet-port-762vp 6type.googleapis.com/google.datastore.v1.CommitResponse62' dulcet-port-762 BasicsZ€€€§ýЖ À¥Ô’Ïûã (™%/google.datastore.v1.Datastore/Commití 5type.googleapis.com/google.datastore.v1.CommitRequest³ (2 "š  BasicsZ K˜’ SŠé Tã ˜ŠÜ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx P’Bdulcet-port-762vp 6type.googleapis.com/google.datastore.v1.CommitResponse62' dulcet-port-762 BasicsZ€€€ç¬±™ Øçå’Ïûã (š%/google.datastore.v1.Datastore/Commitî 5type.googleapis.com/google.datastore.v1.CommitRequest´ (2ž "›  BasicsZ SŠê Tä ˜ŠÝ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx P’ K˜’Bdulcet-port-762vp 6type.googleapis.com/google.datastore.v1.CommitResponse62' dulcet-port-762 BasicsZ€€€Çú‰ž èŽó’Ïûã (™%/google.datastore.v1.Datastore/Commití 5type.googleapis.com/google.datastore.v1.CommitRequest³ (2 "š  BasicsZ T˜Šæ Pà ’Ü xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx K˜’ SŠBdulcet-port-762vp 6type.googleapis.com/google.datastore.v1.CommitResponse62' dulcet-port-762 BasicsZ€€€ç¬­„ ºü’Ïûã (™%/google.datastore.v1.Datastore/Commití 5type.googleapis.com/google.datastore.v1.CommitRequest³ (2 "š  BasicsZé Kã ˜’Ü xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx SŠ T˜Š P’Bdulcet-port-762vp 6type.googleapis.com/google.datastore.v1.CommitResponse62' dulcet-port-762 BasicsZ€€€ÇÙÔ‘ Ðׇ“Ïûã (š%/google.datastore.v1.Datastore/Commitî 5type.googleapis.com/google.datastore.v1.CommitRequest´ (2ž "›  BasicsZê Kä ˜’Ý xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx SŠ T˜Š P’Bdulcet-port-762vp 6type.googleapis.com/google.datastore.v1.CommitResponse62' dulcet-port-762 BasicsZ€€€û➈ ÀÜ•“Ïûã (Ÿ%/google.datastore.v1.Datastore/Committ 5type.googleapis.com/google.datastore.v1.CommitRequest;(2&"$  NilKey K* kindname0Bdulcet-port-762uo 6type.googleapis.com/google.datastore.v1.CommitResponse51& dulcet-port-762 NilKey€€€§âÜ” ¸ð«“Ïûã (!%/google.datastore.v1.Datastore/Commite 5type.googleapis.com/google.datastore.v1.CommitRequest,(2"  NilKey KXBdulcet-port-762uo 6type.googleapis.com/google.datastore.v1.CommitResponse51& dulcet-port-762 NilKey€€€§ˆú• ˜°¶“Ïûã (#1%/google.datastore.v1.Datastore/Commit… 5type.googleapis.com/google.datastore.v1.CommitRequestË(2u"s E8 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild I J TÓêÁê UÓêÁê2u"s E8 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild I J TÓêÁê UÓêÁê2u"s E8 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild I J TÓêÁê UÓêÁê2u"s E8 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild I J TÓêÁê UÓêÁê2u"s E8 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild UÓêÁê I J TÓêÁê2u"s E8 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild UÓêÁê I J TÓêÁê2u"s E8 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I2u"s E8 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild I J TÓêÁê UÓêÁêBdulcet-port-762µ® 6type.googleapis.com/google.datastore.v1.CommitResponseóla dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶“  ­Ä“Ïûãla dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶“  ­Ä“Ïûãla dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶“  ­Ä“Ïûãla dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó  ­Ä“Ïûãla dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó  ­Ä“Ïûãla dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó  ­Ä“Ïûãla dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó  ­Ä“Ïûãla dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶³  ­Ä“Ïûã ¨(% '/google.datastore.v1.Datastore/RunQueryß 7type.googleapis.com/google.datastore.v1.RunQueryRequest£Bdulcet-port-762 __key__ SQChild"u s TÓêÁê  IMK __key__ <*:8 SQParent,TestIntegration_Filters-t1565554003131850927þ÷ 8type.googleapis.com/google.datastore.v1.RunQueryResponseº · Û c a dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶“ t r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶“  Û c a dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ót r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó  Û c a dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó t r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó  Û c a dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó t r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó  Û c a dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó t r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó  Û c a dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶³t r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶³  "t r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶³  (8 ­Ä“Ïûã(''/google.datastore.v1.Datastore/RunQueryð 7type.googleapis.com/google.datastore.v1.RunQueryRequest´Bdulcet-port-762  __key__ SQChild"… ‚ TÓêÁê  I  IMK __key__ <*:8 SQParent,TestIntegration_Filters-t1565554003131850927dÝ 8type.googleapis.com/google.datastore.v1.RunQueryResponse  Û c a dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ót r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó  Û c a dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó t r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó  Û c a dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó t r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó  "t r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó  (8 ­Ä“Ïûã()'/google.datastore.v1.Datastore/RunQueryð 7type.googleapis.com/google.datastore.v1.RunQueryRequest´Bdulcet-port-762  __key__ SQChild"… ‚ TÓêÁê  I  IMK __key__ <*:8 SQParent,TestIntegration_Filters-t1565554003131850927NH 8type.googleapis.com/google.datastore.v1.RunQueryResponse " (8(+ '/google.datastore.v1.Datastore/RunQueryß 7type.googleapis.com/google.datastore.v1.RunQueryRequest£Bdulcet-port-762 __key__ SQChild"u s TÓêÁê  IMK __key__ <*:8 SQParent,TestIntegration_Filters-t1565554003131850927– 8type.googleapis.com/google.datastore.v1.RunQueryResponseÒ ÏÒ c a dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó k icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó  "k icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó  (8 ­Ä“Ïûã(-'/google.datastore.v1.Datastore/RunQueryÒ 7type.googleapis.com/google.datastore.v1.RunQueryRequest–Bdulcet-port-762‚ SQChild"u s TÓêÁê  IMK __key__ <*:8 SQParent,TestIntegration_Filters-t1565554003131850927B» 8type.googleapis.com/google.datastore.v1.RunQueryResponseþ û ‘  a dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶“  I TÓêÁê UÓêÁê Jt r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶“   ­Ä“Ïûã‘  a dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó TÓêÁê UÓêÁê J It r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó   ­Ä“Ïûã‘  a dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó  I TÓêÁê UÓêÁê Jt r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó   ­Ä“Ïûã‘  a dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó  I TÓêÁê UÓêÁê Jt r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó   ­Ä“Ïûã‘  a dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó  I TÓêÁê UÓêÁê Jt r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó   ­Ä“Ïûã‘  a dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶³ UÓêÁê J I TÓêÁêt r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶³   ­Ä“Ïûã"t r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶³  (8 ­Ä“Ïûã(/'/google.datastore.v1.Datastore/RunQueryã 7type.googleapis.com/google.datastore.v1.RunQueryRequest§Bdulcet-port-762“ SQChild"… ‚ TÓêÁê  I  IMK __key__ <*:8 SQParent,TestIntegration_Filters-t1565554003131850927ÿ 8type.googleapis.com/google.datastore.v1.RunQueryResponse ¿‘  a dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó I TÓêÁê UÓêÁê Jt r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó   ­Ä“Ïûã‘  a dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó  UÓêÁê J I TÓêÁêt r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó   ­Ä“Ïûã‘  a dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó  TÓêÁê UÓêÁê J It r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó   ­Ä“Ïûã"t r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó  (8 ­Ä“Ïûã(1'/google.datastore.v1.Datastore/RunQueryã 7type.googleapis.com/google.datastore.v1.RunQueryRequest§Bdulcet-port-762“ SQChild"… ‚ TÓêÁê  I  IMK __key__ <*:8 SQParent,TestIntegration_Filters-t1565554003131850927NH 8type.googleapis.com/google.datastore.v1.RunQueryResponse " (8(3'/google.datastore.v1.Datastore/RunQueryÒ 7type.googleapis.com/google.datastore.v1.RunQueryRequest–Bdulcet-port-762‚ SQChild"u s TÓêÁê  IMK __key__ <*:8 SQParent,TestIntegration_Filters-t1565554003131850927ÌÅ 8type.googleapis.com/google.datastore.v1.RunQueryResponseˆ …ˆ  a dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó  UÓêÁê J I TÓêÁêk icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó   ­Ä“Ïûã"k icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó  (8 ­Ä“Ïûã(5ù'/google.datastore.v1.Datastore/RunQueryË 7type.googleapis.com/google.datastore.v1.RunQueryRequestBdulcet-port-762| SQChild"f d TÓêÁêMK __key__ <*:8 SQParent,TestIntegration_Filters-t1565554003131850927* Ij ã 8type.googleapis.com/google.datastore.v1.RunQueryResponse¦ £‘  a dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶“  I TÓêÁê UÓêÁê Jt r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶“   ­Ä“Ïûã‘  a dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶“  UÓêÁê J I TÓêÁêt r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶“   ­Ä“Ïûã‘  a dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶“  I TÓêÁê UÓêÁê Jt r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶“   ­Ä“Ïûã‘  a dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó J I TÓêÁê UÓêÁêt r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó   ­Ä“Ïûã‘  a dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó  UÓêÁê J I TÓêÁêt r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó   ­Ä“Ïûã‘  a dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó  J I TÓêÁê UÓêÁêt r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó   ­Ä“Ïûã‘  a dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó  UÓêÁê J I TÓêÁêt r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó   ­Ä“Ïûã‘  a dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶³ UÓêÁê J I TÓêÁêt r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶³   ­Ä“Ïûã"t r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶³  (8 ­Ä“Ïûã(7ù'/google.datastore.v1.Datastore/RunQueryË 7type.googleapis.com/google.datastore.v1.RunQueryRequestBdulcet-port-762| SQChild"f d TÓêÁêMK __key__ <*:8 SQParent,TestIntegration_Filters-t1565554003131850927* Ij ã 8type.googleapis.com/google.datastore.v1.RunQueryResponse¦ £‘  a dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶³ UÓêÁê J I TÓêÁêt r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶³    ­Ä“Ïûã‘  a dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó  TÓêÁê UÓêÁê J It r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó    ­Ä“Ïûã‘  a dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó  UÓêÁê J I TÓêÁêt r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó    ­Ä“Ïûã‘  a dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó  UÓêÁê J I TÓêÁêt r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó    ­Ä“Ïûã‘  a dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó UÓêÁê J I TÓêÁêt r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó    ­Ä“Ïûã‘  a dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶“  TÓêÁê UÓêÁê J It r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶“    ­Ä“Ïûã‘  a dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶“  UÓêÁê J I TÓêÁêt r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶“    ­Ä“Ïûã‘  a dulcet-port-7628 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶“  TÓêÁê UÓêÁê J It r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶“    ­Ä“Ïûã"t r  Icjs~dulcet-port-762rN SQParent",TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶“  (8 ­Ä“Ïûã(9 %/google.datastore.v1.Datastore/CommitÝ 5type.googleapis.com/google.datastore.v1.CommitRequest£(2P:N8 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶“ 2P:N8 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶“ 2P:N8 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶“ 2P:N8 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó2P:N8 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó 2P:N8 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó 2P:N8 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶Ó 2P:N8 SQParent,TestIntegration_Filters-t1565554003131850927 SQChild€€€ûŸ¶³Bdulcet-port-762œ• 6type.googleapis.com/google.datastore.v1.CommitResponse[ ð—ú“Ïûã ð—ú“Ïûã ð—ú“Ïûã ð—ú“Ïûã ð—ú“Ïûã ð—ú“Ïûã ð—ú“Ïûã ð—ú“Ïûã ¨(;7ð%/google.datastore.v1.Datastore/CommitŠà 5type.googleapis.com/google.datastore.v1.CommitRequestÏß(2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I J2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I J2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I J2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I 2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I  J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I  J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I  J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I  J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I J2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I 2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I! J2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I" J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I# J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I$ J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I% J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I& J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I'2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I( J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I) J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I* J2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I+2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I, J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I- J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I. J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I/ J2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I0 J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I12x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I2 J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I3 J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I4 J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I5 J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I6 J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I72x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I8 J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I9 J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I: J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I; J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I< J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I= J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I> J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I? J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I@ J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IA J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IB J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IC J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê ID2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IE J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IF J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê IG J2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê IH2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê II J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IJ J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IK J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IL J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IM J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê IN2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IO J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IP J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê IQ2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê IR J2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IS J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê IT J2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IU J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IV J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê IW2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IX J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IY J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IZ J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I[2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I\2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I]2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I^ J2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I_ J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I` J2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Ia J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Ib J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Ic J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Id J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê Ie J2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild If J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Ig2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê Ih J2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Ii J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Ij J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Ik J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Il J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Im J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild In J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê Io J2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Ip J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Iq J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Ir J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Is J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê It2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iu J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Iv2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Iw2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Ix J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Iy J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Iz J TÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I{ J2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I| J2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I} J TÓêÁê UÓêÁê2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I~ J2x"v H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I€ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I‚ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê Iƒ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I„ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I… J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I† J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I‡ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iˆ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I‰ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê IŠ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I‹ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê IŒ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IŽ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I‘ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I’ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I“ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I” J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I• J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I– J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I— J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I˜ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I™2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Iš J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I› J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Iœ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iž J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IŸ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I  J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I¡ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I¢ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I£2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I¤2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I¥2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I¦ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I§ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I¨ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I© J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iª J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I« J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I¬ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I­2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I® J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I¯ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I° J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I± J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I² J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I³ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I´2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iµ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I¶ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I· J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I¸ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I¹ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iº J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I» J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I¼ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I½ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I¾ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I¿ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IÀ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÁ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Ià J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÄ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÅ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÆ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê IÇ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÈ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IÉ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÊ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IË J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê IÌ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IÍ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÎ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê IÏ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê IÐ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÑ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IÒ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IÓ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê IÔ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÕ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê IÖ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I× J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê IØ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê IÙ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê IÚ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IÛ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê IÜ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IÝ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê IÞ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Iß J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Ià J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Iá2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iâ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iã J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iä J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iå J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iæ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iç J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Iè J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Ié2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iê J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Ië J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Iì J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Ií2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iî J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê Iï J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Ið J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê Iñ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Iò J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Ió J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê Iô J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Iõ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Iö J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I÷2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iø J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê Iù J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iú J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê Iû J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê Iü J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iý J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iþ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iÿ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I€ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I‚ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iƒ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I„ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I… J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I† J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I‡ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iˆ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I‰ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IŠ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I‹2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IŒ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê IŽ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I‘ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I’ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I“ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I” J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I• J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I– J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I— J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I˜ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I™ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iš J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I› J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iœ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iž J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê IŸ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I  J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I¡ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I¢ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I£ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I¤ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I¥ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I¦ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I§2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I¨ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I© J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iª J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I«2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I¬ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I­ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I® J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I¯ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I° J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I± J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I² J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I³2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I´ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Iµ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I¶2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I· J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I¸2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I¹2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iº J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I» J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I¼ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I½ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I¾ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I¿ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÀ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IÁ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Ià J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÄ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IÅ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê IÆ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê IÇ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÈ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÉ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IÊ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IË J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê IÌ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IÍ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IÎ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÏ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê IÐ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÑ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê IÒ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÓ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÔ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IÕ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê IÖ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I×2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IØ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê IÙ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÚ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê IÛ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÜ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÝ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IÞ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iß J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Ià J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Iá J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Iâ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Iã2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iä J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Iå2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Iæ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê Iç J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Iè2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Ié J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iê J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Ië J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Iì2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Ií2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iî J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê Iï J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Ið J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Iñ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iò J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Ió J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iô J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iõ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê Iö J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I÷ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê Iø J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Iù2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Iú J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iû J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Iü J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Iý2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iþ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iÿ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I€ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I‚ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iƒ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I„ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I…2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I†2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I‡ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Iˆ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I‰ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê IŠ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I‹ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IŒ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê IŽ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I‘ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I’ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I“ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I”2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I• J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I– J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I— J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I˜ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I™ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iš J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I› J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iœ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Iž J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê IŸ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I 2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I¡ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I¢2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I£ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I¤ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I¥ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I¦ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I§ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I¨ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I© J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Iª2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I« J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I¬2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I­2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I® J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I¯ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I° J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I± J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I² J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I³ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I´2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Iµ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I¶ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I· J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I¸2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I¹ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Iº J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I»2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I¼ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I½ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I¾ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I¿2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÀ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÁ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê IÂ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Ià J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê IÄ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê IÅ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÆ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê IÇ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê IÈ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê IÉ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÊ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IË J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IÌ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÍ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê IÎ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÏ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÐ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IÑ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê IÒ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÓ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê IÔ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IÕ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IÖ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I×2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê IØ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÙ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÚ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IÛ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê IÜ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÝ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IÞ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iß J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Ià J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê Iá J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iâ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iã J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê Iä J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê Iå J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iæ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iç J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Iè2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Ié2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Iê J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Ië2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iì J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Ií J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iî J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iï J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Ið J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Iñ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Iò J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Ió J TÓêÁê UÓêÁêBdulcet-port-762ûÜó¹ 6type.googleapis.com/google.datastore.v1.CommitResponse·¹od dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€û㖠Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€û㖠Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€û㖠Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–РȆ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–РȆ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–РȆ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ΠȆ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ΠȆ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ΠȆ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€û㖠Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€û㖠Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€û㖠Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É È†’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–٠Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–٠Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–٠Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… Ȇ’”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Å Ȇ’”Ïûã ŒR(=Ÿ%/google.datastore.v1.Datastore/Commitò  5type.googleapis.com/google.datastore.v1.CommitRequest· (2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Iô2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê Iõ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Iö2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I÷ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Iø2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Iù2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iú J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Iû J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iü J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Iý2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iþ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê Iÿ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I€ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I‚ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iƒ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I„ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I… J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I†2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I‡ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Iˆ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I‰ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IŠ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I‹ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê IŒ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IŽ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I‘ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I’ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I“ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I”2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I• J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I– J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I— J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I˜ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I™ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Iš2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I› J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iœ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Iž J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê IŸ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I  J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I¡2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I¢ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I£ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I¤ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I¥ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I¦2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I§2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I¨2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I© J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iª J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I« J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I¬ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I­ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I® J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I¯ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I° J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I± J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I² J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I³ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I´ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Iµ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I¶2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I· J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I¸ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I¹2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iº J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I» J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I¼ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I½2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I¾ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I¿ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÀ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÁ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê Ià J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê IÄ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÅ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê IÆ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê IÇ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê IÈ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÉ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÊ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IË J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÌ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÍ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IÎ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÏ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÐ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÑ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IÒ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê IÓ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê IÔ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÕ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÖ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I× J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IØ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÙ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÚ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê IÛ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÜ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê IÝ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê IÞ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iß J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê Ià J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Iá J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Iâ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê Iã J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iä J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iå J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iæ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Iç J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iè J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Ié J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê Iê J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Ië2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iì J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Ií J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Iî2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê Iï J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Ið2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Iñ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iò J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Ió J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iô J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iõ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iö J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I÷ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iø J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iù J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iú J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iû J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iü J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Iý J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iþ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iÿ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I€ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I‚ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iƒ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I„ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I… J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I† J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I‡ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê Iˆ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I‰2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IŠ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I‹ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IŒ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IŽ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I‘ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I’ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I“ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I” J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I•2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I–2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I—2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I˜ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I™2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Iš2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I›2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Iœ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê Iž J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê IŸ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I  J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I¡2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I¢ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I£ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I¤ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I¥ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I¦ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I§ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I¨ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I© J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Iª2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I« J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I¬ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I­ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I® J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I¯ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I° J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I± J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I² J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I³ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I´2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iµ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I¶ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I· J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I¸ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I¹ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iº J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I» J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I¼ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I½ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I¾ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I¿ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÀ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê IÁ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Ià J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÄ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÅ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÆ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IÇ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÈ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê IÉ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê IÊ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IË J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê IÌ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÍ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÎ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê IÏ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê IÐ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÑ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê IÒ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê IÓ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÔ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÕ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê IÖ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I× J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IØ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÙ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IÚ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê IÛ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê IÜ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê IÝ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê IÞ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iß J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Ià J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê Iá J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iâ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Iã2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iä J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Iå J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Iæ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Iç2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iè J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Ié2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Iê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Ië J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iì J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê Ií J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê Iî J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê Iï J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê Ið J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê Iñ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iò J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê Ió J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iô J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Iõ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Iö J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I÷2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Iø J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iù J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Iú J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Iû J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê Iü J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê Iý J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê Iþ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iÿ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I€ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I‚ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild Iƒ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I„ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I… J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I† J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I‡ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê Iˆ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I‰ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IŠ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I‹ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IŒ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild IŽ J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I‘ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I’ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I“ J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I” J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I• J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê I– J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I— J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê I˜ J TÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I™2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild TÓêÁê UÓêÁê Iš J2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild I› J TÓêÁê UÓêÁê2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Iœ2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê I2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild J TÓêÁê UÓêÁê Iž2y"w H; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild UÓêÁê IŸ J TÓêÁêBdulcet-port-762³„«‰ 6type.googleapis.com/google.datastore.v1.CommitResponseïˆod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ Àó´”Ïûãod dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ Àó´”Ïûã  1(? '/google.datastore.v1.Datastore/RunQueryß 7type.googleapis.com/google.datastore.v1.RunQueryRequest£Bdulcet-port-762 __key__ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* IPè'/google.datastore.v1.Datastore/RunQueryà 7type.googleapis.com/google.datastore.v1.RunQueryRequest¤Bdulcet-port-762 __key__ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* Ibd '/google.datastore.v1.Datastore/RunQueryÞ 7type.googleapis.com/google.datastore.v1.RunQueryRequest¢Bdulcet-port-762Ž __key__ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* IPd '/google.datastore.v1.Datastore/RunQueryß 7type.googleapis.com/google.datastore.v1.RunQueryRequest£Bdulcet-port-762 __key__ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* IPô'/google.datastore.v1.Datastore/RunQueryá 7type.googleapis.com/google.datastore.v1.RunQueryRequest¥Bdulcet-port-762‘ __key__ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* Ibõ '/google.datastore.v1.Datastore/RunQueryß 7type.googleapis.com/google.datastore.v1.RunQueryRequest£Bdulcet-port-762 __key__ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* IP '/google.datastore.v1.Datastore/RunQueryá 7type.googleapis.com/google.datastore.v1.RunQueryRequest¥Bdulcet-port-762‘ __key__ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* Ib '/google.datastore.v1.Datastore/RunQueryâ 7type.googleapis.com/google.datastore.v1.RunQueryRequest¦Bdulcet-port-762’ __key__ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* IPdbd'/google.datastore.v1.Datastore/RunQueryá 7type.googleapis.com/google.datastore.v1.RunQueryRequest¥Bdulcet-port-762‘ __key__ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* IbÀ '/google.datastore.v1.Datastore/RunQueryã 7type.googleapis.com/google.datastore.v1.RunQueryRequest§Bdulcet-port-762“ __key__ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* IPdbè'/google.datastore.v1.Datastore/RunQueryà 7type.googleapis.com/google.datastore.v1.RunQueryRequest¤Bdulcet-port-762 __key__ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* Ib'/google.datastore.v1.Datastore/RunQueryà 7type.googleapis.com/google.datastore.v1.RunQueryRequest¤Bdulcet-port-762 __key__ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* Ib '/google.datastore.v1.Datastore/RunQueryÜ 7type.googleapis.com/google.datastore.v1.RunQueryRequest Bdulcet-port-762Œ __key__ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I'/google.datastore.v1.Datastore/RunQueryá 7type.googleapis.com/google.datastore.v1.RunQueryRequest¥Bdulcet-port-762‘ __key__ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* Ibè'/google.datastore.v1.Datastore/RunQueryä 7type.googleapis.com/google.datastore.v1.RunQueryRequest¨Bdulcet-port-762” __key__ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* IPôbô '/google.datastore.v1.Datastore/RunQueryÞ 7type.googleapis.com/google.datastore.v1.RunQueryRequest¢Bdulcet-port-762Ž __key__ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* IP '/google.datastore.v1.Datastore/RunQueryÜ 7type.googleapis.com/google.datastore.v1.RunQueryRequest Bdulcet-port-762Œ __key__ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I '/google.datastore.v1.Datastore/RunQueryÜ 7type.googleapis.com/google.datastore.v1.RunQueryRequest Bdulcet-port-762Œ __key__ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I '/google.datastore.v1.Datastore/RunQueryÜ 7type.googleapis.com/google.datastore.v1.RunQueryRequest Bdulcet-port-762Œ __key__ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I '/google.datastore.v1.Datastore/RunQueryß 7type.googleapis.com/google.datastore.v1.RunQueryRequest£Bdulcet-port-762 __key__ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* IPô'/google.datastore.v1.Datastore/RunQueryÓ 7type.googleapis.com/google.datastore.v1.RunQueryRequest—Bdulcet-port-762ƒ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* Ib '/google.datastore.v1.Datastore/RunQueryÞ 7type.googleapis.com/google.datastore.v1.RunQueryRequest¢Bdulcet-port-762Ž __key__ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* IPAº 8type.googleapis.com/google.datastore.v1.RunQueryResponseý ú á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  "w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  (8Àó´”Ïûã(Kz'/google.datastore.v1.Datastore/RunQueryÌ 7type.googleapis.com/google.datastore.v1.RunQueryRequestBdulcet-port-762ü SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I:w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  bAº 8type.googleapis.com/google.datastore.v1.RunQueryResponseý ú á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  "w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  (8Àó´”Ïûã(Lz'/google.datastore.v1.Datastore/RunQueryÌ 7type.googleapis.com/google.datastore.v1.RunQueryRequestBdulcet-port-762ü SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I:w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  bçà 8type.googleapis.com/google.datastore.v1.RunQueryResponse£  — ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  Ȇ’”Ïûã"w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  (8Àó´”Ïûã(UàYس 8type.googleapis.com/google.datastore.v1.RunQueryResponseš³ –³á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæíw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  I!fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  I"fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝw u  I#fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ w u  I$fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ w u  I%fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ w u  I&fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½w u  I'fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ w u  I(fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ w u  I)fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ w u  I*fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæýw u  I+fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý w u  I,fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý w u  I-fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý w u  I.fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒw u  I/fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ w u  I0fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ w u  I1fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ w u  I2fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃw u  I3fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ w u  I4fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ w u  I5fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ w u  I6fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£w u  I7fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ w u  I8fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ w u  I9fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ w u  I:fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæãw u  I;fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã w u  I<fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã w u  I=fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã w u  I>fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“w u  I?fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ w u  I@fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ w u  IAfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ w u  IBfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓw u  ICfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ w u  IDfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ w u  IEfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ w u  IFfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³w u  IGfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ w u  IHfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ w u  IIfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ w u  IJfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæów u  IKfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó w u  ILfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó w u  IMfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó w u  INfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹w u  IOfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ w u  IPfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ w u  IQfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ w u  IRfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæËw u  ISfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË w u  ITfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË w u  IUfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË w u  IVfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«w u  IWfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« w u  IXfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« w u  IYfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« w u  IZfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæëw u  I[fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë w u  I\fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë w u  I]fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë w u  I^fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›w u  I_fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› w u  I`fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› w u  Iafjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› w u  Ibfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛw u  Icfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  "w u  Icfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  (8Àó´”Ïûã(B'/google.datastore.v1.Datastore/RunQueryÓ 7type.googleapis.com/google.datastore.v1.RunQueryRequest—Bdulcet-port-762ƒ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* Ibd¤Zœµ 8type.googleapis.com/google.datastore.v1.RunQueryResponseÞ´ Ú´á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Idfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Iefjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Iffjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»w u  Igfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Ihfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Iifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Ijfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæûw u  Ikfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Ilfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Imfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Infjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡w u  Iofjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Ipfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Iqfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Irfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇw u  Isfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Itfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Iufjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Ivfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§w u  Iwfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Ixfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Iyfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Izfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæçw u  I{fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I|fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I}fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I~fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×x v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæïx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæßx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Àx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–àx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–x v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ðx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°x v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  w u  Icfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  "x v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  (0d8Àó´”Ïûã(H'/google.datastore.v1.Datastore/RunQueryÕ 7type.googleapis.com/google.datastore.v1.RunQueryRequest™Bdulcet-port-762… SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* IPdbd­ ¥™ 8type.googleapis.com/google.datastore.v1.RunQueryResponseç˜ ã˜á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæíw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  I!fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  I"fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝw u  I#fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ w u  I$fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ w u  I%fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ w u  I&fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½w u  I'fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ w u  I(fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ w u  I)fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ w u  I*fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæýw u  I+fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý w u  I,fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý w u  I-fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý w u  I.fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒw u  I/fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ w u  I0fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ w u  I1fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ w u  I2fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃw u  I3fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ w u  I4fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ w u  I5fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ w u  I6fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£w u  I7fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ w u  I8fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ w u  I9fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ w u  I:fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæãw u  I;fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã w u  I<fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã w u  I=fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã w u  I>fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“w u  I?fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ w u  I@fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ w u  IAfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ w u  IBfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓw u  ICfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ w u  IDfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ w u  IEfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ w u  IFfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³w u  IGfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ w u  IHfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ w u  IIfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ w u  IJfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæów u  IKfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó w u  ILfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó w u  IMfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó w u  INfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹w u  IOfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ w u  IPfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ w u  IQfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ w u  IRfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæËw u  ISfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË w u  ITfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË w u  IUfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË w u  IVfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«w u  IWfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« w u  IXfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« w u  IYfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« w u  IZfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæëw u  I[fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë w u  I\fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë w u  I]fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë w u  I^fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›w u  I_fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› w u  I`fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› w u  Iafjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› w u  Ibfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛw u  Icfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Idfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Iefjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Iffjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»w u  Igfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Ihfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Iifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Ijfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæûw u  Ikfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Ilfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Imfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Infjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡w u  Iofjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Ipfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Iqfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Irfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇw u  Isfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Itfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Iufjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Ivfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§w u  Iwfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Ixfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Iyfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Izfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæçw u  I{fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I|fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I}fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I~fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×x v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæïx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæßx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Àx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–àx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–x v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ðx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°x v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ðx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Èx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–èx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜x v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Øx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸x v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–øx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„x v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Äx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤x v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–äx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”x v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ôx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ôx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ìx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ìx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Üx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–üx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  "x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  (8Àó´”Ïûã(Q„'/google.datastore.v1.Datastore/RunQueryÖ 7type.googleapis.com/google.datastore.v1.RunQueryRequestšBdulcet-port-762† __key__ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I:x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  - ¥š 8type.googleapis.com/google.datastore.v1.RunQueryResponseç™ ã™á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæíw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  I!fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  I"fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝw u  I#fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ w u  I$fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ w u  I%fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ w u  I&fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½w u  I'fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ w u  I(fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ w u  I)fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ w u  I*fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæýw u  I+fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý w u  I,fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý w u  I-fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý w u  I.fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒw u  I/fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ w u  I0fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ w u  I1fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ w u  I2fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃw u  I3fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ w u  I4fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ w u  I5fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ w u  I6fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£w u  I7fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ w u  I8fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ w u  I9fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ w u  I:fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæãw u  I;fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã w u  I<fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã w u  I=fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã w u  I>fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“w u  I?fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ w u  I@fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ w u  IAfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ w u  IBfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓw u  ICfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ w u  IDfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ w u  IEfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ w u  IFfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³w u  IGfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ w u  IHfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ w u  IIfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ w u  IJfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæów u  IKfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó w u  ILfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó w u  IMfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó w u  INfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹w u  IOfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ w u  IPfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ w u  IQfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ w u  IRfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæËw u  ISfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË w u  ITfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË w u  IUfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË w u  IVfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«w u  IWfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« w u  IXfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« w u  IYfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« w u  IZfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæëw u  I[fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë w u  I\fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë w u  I]fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë w u  I^fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›w u  I_fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› w u  I`fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› w u  Iafjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› w u  Ibfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛw u  Icfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Idfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Iefjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Iffjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»w u  Igfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Ihfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Iifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Ijfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæûw u  Ikfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Ilfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Imfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Infjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡w u  Iofjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Ipfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Iqfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Irfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇw u  Isfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Itfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Iufjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Ivfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§w u  Iwfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Ixfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Iyfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Izfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæçw u  I{fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I|fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I}fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I~fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×x v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæïx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæßx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Àx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–àx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–x v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ðx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°x v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ðx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Èx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–èx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜x v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Øx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸x v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–øx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„x v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Äx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤x v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–äx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”x v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ôx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ôx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ìx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ìx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Üx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–üx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  "x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  (08Àó´”Ïûã(Vz'/google.datastore.v1.Datastore/RunQueryÌ 7type.googleapis.com/google.datastore.v1.RunQueryRequestBdulcet-port-762ü SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I:w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  bŒ „› 8type.googleapis.com/google.datastore.v1.RunQueryResponseÆš šá f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Idfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Iefjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Iffjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»w u  Igfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Ihfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Iifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Ijfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæûw u  Ikfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Ilfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Imfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Infjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡w u  Iofjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Ipfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Iqfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Irfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇw u  Isfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Itfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Iufjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Ivfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§w u  Iwfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Ixfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Iyfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Izfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæçw u  I{fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I|fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I}fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I~fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×x v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæïx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæßx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Àx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–àx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–x v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ðx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°x v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ðx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Èx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–èx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜x v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Øx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸x v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–øx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„x v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Äx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤x v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–äx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”x v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ôx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ôx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ìx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ìx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Üx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–üx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Âx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–âx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’x v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Òx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²x v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–òx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Šx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Êx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ªx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–êx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–šx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Úx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ºx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–úx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†x v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦x v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––x v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Öx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–öx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Žx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  w u  Icfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  "x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  (0d8Àó´”Ïûã(J‰'/google.datastore.v1.Datastore/RunQueryÛ 7type.googleapis.com/google.datastore.v1.RunQueryRequestŸBdulcet-port-762‹ __key__ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I:x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  b¼­ ¥™ 8type.googleapis.com/google.datastore.v1.RunQueryResponseç˜ ã˜á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæíw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  I!fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  I"fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝw u  I#fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ w u  I$fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ w u  I%fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ w u  I&fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½w u  I'fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ w u  I(fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ w u  I)fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ w u  I*fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæýw u  I+fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý w u  I,fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý w u  I-fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý w u  I.fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒw u  I/fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ w u  I0fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ w u  I1fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ w u  I2fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃw u  I3fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ w u  I4fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ w u  I5fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ w u  I6fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£w u  I7fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ w u  I8fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ w u  I9fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ w u  I:fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæãw u  I;fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã w u  I<fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã w u  I=fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã w u  I>fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“w u  I?fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ w u  I@fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ w u  IAfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ w u  IBfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓw u  ICfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ w u  IDfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ w u  IEfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ w u  IFfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³w u  IGfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ w u  IHfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ w u  IIfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ w u  IJfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæów u  IKfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó w u  ILfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó w u  IMfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó w u  INfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹w u  IOfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ w u  IPfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ w u  IQfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ w u  IRfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæËw u  ISfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË w u  ITfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË w u  IUfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË w u  IVfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«w u  IWfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« w u  IXfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« w u  IYfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« w u  IZfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæëw u  I[fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë w u  I\fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë w u  I]fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë w u  I^fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›w u  I_fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› w u  I`fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› w u  Iafjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› w u  Ibfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛw u  Icfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Idfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Iefjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Iffjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»w u  Igfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Ihfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Iifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Ijfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæûw u  Ikfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Ilfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Imfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Infjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡w u  Iofjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Ipfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Iqfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Irfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇw u  Isfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Itfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Iufjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Ivfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§w u  Iwfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Ixfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Iyfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Izfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæçw u  I{fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I|fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I}fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I~fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×x v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæïx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæßx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Àx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–àx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–x v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ðx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°x v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ðx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Èx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–èx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜x v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Øx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸x v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–øx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„x v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Äx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤x v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–äx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”x v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ôx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ôx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ìx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ìx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Üx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–üx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  "x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  (8Àó´”Ïûã(I‰'/google.datastore.v1.Datastore/RunQueryÛ 7type.googleapis.com/google.datastore.v1.RunQueryRequestŸBdulcet-port-762‹ __key__ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I:x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  b” ­ ¥™ 8type.googleapis.com/google.datastore.v1.RunQueryResponseç˜ ã˜á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæíw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  I!fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  I"fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝw u  I#fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ w u  I$fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ w u  I%fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ w u  I&fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½w u  I'fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ w u  I(fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ w u  I)fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ w u  I*fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæýw u  I+fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý w u  I,fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý w u  I-fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý w u  I.fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒw u  I/fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ w u  I0fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ w u  I1fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ w u  I2fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃw u  I3fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ w u  I4fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ w u  I5fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ w u  I6fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£w u  I7fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ w u  I8fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ w u  I9fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ w u  I:fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæãw u  I;fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã w u  I<fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã w u  I=fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã w u  I>fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“w u  I?fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ w u  I@fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ w u  IAfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ w u  IBfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓw u  ICfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ w u  IDfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ w u  IEfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ w u  IFfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³w u  IGfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ w u  IHfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ w u  IIfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ w u  IJfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæów u  IKfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó w u  ILfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó w u  IMfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó w u  INfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹w u  IOfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ w u  IPfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ w u  IQfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ w u  IRfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæËw u  ISfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË w u  ITfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË w u  IUfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË w u  IVfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«w u  IWfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« w u  IXfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« w u  IYfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« w u  IZfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæëw u  I[fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë w u  I\fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë w u  I]fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë w u  I^fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›w u  I_fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› w u  I`fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› w u  Iafjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› w u  Ibfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛw u  Icfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Idfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Iefjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Iffjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»w u  Igfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Ihfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Iifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Ijfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæûw u  Ikfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Ilfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Imfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Infjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡w u  Iofjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Ipfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Iqfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Irfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇw u  Isfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Itfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Iufjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Ivfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§w u  Iwfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Ixfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Iyfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Izfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæçw u  I{fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I|fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I}fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I~fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×x v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæïx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæßx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Àx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–àx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–x v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ðx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°x v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ðx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Èx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–èx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜x v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Øx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸x v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–øx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„x v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Äx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤x v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–äx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”x v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ôx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ôx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ìx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ìx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Üx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–üx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  "x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  (8Àó´”Ïûã(GŒ „› 8type.googleapis.com/google.datastore.v1.RunQueryResponseÆš šá f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Idfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Iefjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Iffjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»w u  Igfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Ihfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Iifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Ijfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæûw u  Ikfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Ilfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Imfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Infjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡w u  Iofjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Ipfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Iqfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Irfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇw u  Isfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Itfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Iufjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Ivfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§w u  Iwfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Ixfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Iyfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Izfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæçw u  I{fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I|fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I}fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I~fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×x v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæïx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæßx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Àx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–àx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–x v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ðx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°x v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ðx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Èx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–èx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜x v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Øx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸x v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–øx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„x v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Äx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤x v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–äx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”x v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ôx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ôx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ìx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ìx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Üx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–üx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Âx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–âx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’x v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Òx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²x v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–òx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Šx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Êx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ªx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–êx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–šx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Úx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ºx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–úx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†x v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦x v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––x v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Öx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–öx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Žx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  w u  Icfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  "x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  (0d8Àó´”Ïûã(C„'/google.datastore.v1.Datastore/RunQueryÖ 7type.googleapis.com/google.datastore.v1.RunQueryRequestšBdulcet-port-762† __key__ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I:x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  ­ ¥™ 8type.googleapis.com/google.datastore.v1.RunQueryResponseç˜ ã˜á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæíw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  I!fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  I"fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝw u  I#fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ w u  I$fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ w u  I%fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ w u  I&fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½w u  I'fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ w u  I(fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ w u  I)fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ w u  I*fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæýw u  I+fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý w u  I,fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý w u  I-fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý w u  I.fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒw u  I/fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ w u  I0fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ w u  I1fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ w u  I2fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃw u  I3fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ w u  I4fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ w u  I5fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ w u  I6fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£w u  I7fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ w u  I8fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ w u  I9fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ w u  I:fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæãw u  I;fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã w u  I<fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã w u  I=fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã w u  I>fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“w u  I?fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ w u  I@fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ w u  IAfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ w u  IBfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓw u  ICfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ w u  IDfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ w u  IEfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ w u  IFfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³w u  IGfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ w u  IHfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ w u  IIfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ w u  IJfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæów u  IKfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó w u  ILfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó w u  IMfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó w u  INfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹w u  IOfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ w u  IPfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ w u  IQfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ w u  IRfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæËw u  ISfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË w u  ITfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË w u  IUfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË w u  IVfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«w u  IWfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« w u  IXfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« w u  IYfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« w u  IZfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæëw u  I[fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë w u  I\fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë w u  I]fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë w u  I^fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›w u  I_fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› w u  I`fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› w u  Iafjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› w u  Ibfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛw u  Icfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Idfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Iefjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Iffjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»w u  Igfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Ihfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Iifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Ijfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæûw u  Ikfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Ilfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Imfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Infjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡w u  Iofjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Ipfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Iqfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Irfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇw u  Isfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Itfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Iufjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Ivfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§w u  Iwfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Ixfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Iyfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Izfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæçw u  I{fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I|fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I}fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I~fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×x v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæïx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæßx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Àx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–àx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–x v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ðx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°x v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ðx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Èx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–èx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜x v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Øx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸x v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–øx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„x v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Äx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤x v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–äx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”x v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ôx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ôx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ìx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ìx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Üx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–üx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  "x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  (8Àó´”Ïûã(S„'/google.datastore.v1.Datastore/RunQueryÖ 7type.googleapis.com/google.datastore.v1.RunQueryRequestšBdulcet-port-762† __key__ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I:x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  ‰'/google.datastore.v1.Datastore/RunQueryÛ 7type.googleapis.com/google.datastore.v1.RunQueryRequestŸBdulcet-port-762‹ __key__ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I:x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  bô­ ¥™ 8type.googleapis.com/google.datastore.v1.RunQueryResponseç˜ ã˜á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæíw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  I!fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  I"fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝw u  I#fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ w u  I$fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ w u  I%fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ w u  I&fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½w u  I'fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ w u  I(fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ w u  I)fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ w u  I*fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæýw u  I+fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý w u  I,fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý w u  I-fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý w u  I.fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒw u  I/fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ w u  I0fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ w u  I1fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ w u  I2fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃw u  I3fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ w u  I4fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ w u  I5fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ w u  I6fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£w u  I7fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ w u  I8fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ w u  I9fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ w u  I:fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæãw u  I;fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã w u  I<fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã w u  I=fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã w u  I>fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“w u  I?fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ w u  I@fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ w u  IAfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ w u  IBfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓw u  ICfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ w u  IDfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ w u  IEfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ w u  IFfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³w u  IGfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ w u  IHfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ w u  IIfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ w u  IJfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæów u  IKfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó w u  ILfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó w u  IMfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó w u  INfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹w u  IOfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ w u  IPfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ w u  IQfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ w u  IRfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæËw u  ISfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË w u  ITfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË w u  IUfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË w u  IVfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«w u  IWfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« w u  IXfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« w u  IYfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« w u  IZfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæëw u  I[fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë w u  I\fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë w u  I]fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë w u  I^fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›w u  I_fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› w u  I`fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› w u  Iafjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› w u  Ibfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛw u  Icfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Idfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Iefjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Iffjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»w u  Igfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Ihfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Iifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Ijfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæûw u  Ikfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Ilfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Imfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Infjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡w u  Iofjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Ipfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Iqfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Irfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇw u  Isfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Itfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Iufjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Ivfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§w u  Iwfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Ixfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Iyfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Izfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæçw u  I{fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I|fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I}fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I~fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×x v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæïx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæßx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Àx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–àx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–x v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ðx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°x v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ðx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Èx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–èx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜x v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Øx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸x v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–øx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„x v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Äx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤x v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–äx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”x v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ôx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ôx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ìx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ìx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Üx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–üx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  "x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  (8Àó´”Ïûã(Mz'/google.datastore.v1.Datastore/RunQueryÌ 7type.googleapis.com/google.datastore.v1.RunQueryRequestBdulcet-port-762ü SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I:w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  bKÄ 8type.googleapis.com/google.datastore.v1.RunQueryResponse‡ „x v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  "x v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  (0 8Àó´”Ïûã(Aª ¢› 8type.googleapis.com/google.datastore.v1.RunQueryResponseäš àšâ f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ëx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«x v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ëx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›x v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ûx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ûx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Çx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§x v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹çx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—x v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹x v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ïx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯x v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ïx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ßx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿x v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€x v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùàx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°x v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùðx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨x v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùèx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜x v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùøx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤x v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùäx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”x v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔx v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùôx v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬x v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùìx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼x v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùüx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚x v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÂx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢x v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’x v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²x v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùòx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùªx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùêx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùšx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùºx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùúx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦x v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  x v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Å  "x v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  (0ô8Àó´”Ïûã(T{'/google.datastore.v1.Datastore/RunQueryÍ 7type.googleapis.com/google.datastore.v1.RunQueryRequest‘Bdulcet-port-762ý SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I:x v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  b{'/google.datastore.v1.Datastore/RunQueryÍ 7type.googleapis.com/google.datastore.v1.RunQueryRequest‘Bdulcet-port-762ý SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I:x v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  b­ ¥™ 8type.googleapis.com/google.datastore.v1.RunQueryResponseç˜ ã˜á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæíw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  I!fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  I"fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝw u  I#fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ w u  I$fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ w u  I%fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ w u  I&fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½w u  I'fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ w u  I(fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ w u  I)fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ w u  I*fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæýw u  I+fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý w u  I,fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý w u  I-fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý w u  I.fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒw u  I/fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ w u  I0fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ w u  I1fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ w u  I2fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃw u  I3fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ w u  I4fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ w u  I5fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ w u  I6fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£w u  I7fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ w u  I8fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ w u  I9fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ w u  I:fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæãw u  I;fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã w u  I<fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã w u  I=fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã w u  I>fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“w u  I?fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ w u  I@fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ w u  IAfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ w u  IBfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓw u  ICfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ w u  IDfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ w u  IEfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ w u  IFfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³w u  IGfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ w u  IHfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ w u  IIfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ w u  IJfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæów u  IKfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó w u  ILfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó w u  IMfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó w u  INfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹w u  IOfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ w u  IPfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ w u  IQfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ w u  IRfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæËw u  ISfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË w u  ITfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË w u  IUfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË w u  IVfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«w u  IWfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« w u  IXfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« w u  IYfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« w u  IZfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæëw u  I[fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë w u  I\fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë w u  I]fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë w u  I^fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›w u  I_fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› w u  I`fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› w u  Iafjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› w u  Ibfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛw u  Icfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Idfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Iefjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Iffjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»w u  Igfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Ihfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Iifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Ijfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæûw u  Ikfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Ilfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Imfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Infjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡w u  Iofjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Ipfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Iqfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Irfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇw u  Isfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Itfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Iufjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Ivfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§w u  Iwfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Ixfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Iyfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Izfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæçw u  I{fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I|fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I}fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I~fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×x v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæïx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæßx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Àx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–àx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–x v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ðx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°x v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ðx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Èx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–èx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜x v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Øx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸x v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–øx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„x v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Äx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤x v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–äx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”x v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ôx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ôx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ìx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ìx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Üx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–üx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  "x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  (8Àó´”Ïûã(E‰'/google.datastore.v1.Datastore/RunQueryÛ 7type.googleapis.com/google.datastore.v1.RunQueryRequestŸBdulcet-port-762‹ __key__ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I:x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  bÉ- ¥š 8type.googleapis.com/google.datastore.v1.RunQueryResponseç™ ã™á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæíw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  I!fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  I"fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝw u  I#fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ w u  I$fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ w u  I%fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ w u  I&fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½w u  I'fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ w u  I(fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ w u  I)fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ w u  I*fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæýw u  I+fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý w u  I,fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý w u  I-fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý w u  I.fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒw u  I/fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ w u  I0fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ w u  I1fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ w u  I2fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃw u  I3fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ w u  I4fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ w u  I5fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ w u  I6fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£w u  I7fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ w u  I8fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ w u  I9fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ w u  I:fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæãw u  I;fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã w u  I<fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã w u  I=fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã w u  I>fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“w u  I?fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ w u  I@fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ w u  IAfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ w u  IBfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓw u  ICfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ w u  IDfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ w u  IEfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ w u  IFfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³w u  IGfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ w u  IHfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ w u  IIfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ w u  IJfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæów u  IKfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó w u  ILfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó w u  IMfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó w u  INfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹w u  IOfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ w u  IPfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ w u  IQfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ w u  IRfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæËw u  ISfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË w u  ITfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË w u  IUfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË w u  IVfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«w u  IWfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« w u  IXfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« w u  IYfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« w u  IZfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæëw u  I[fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë w u  I\fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë w u  I]fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë w u  I^fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›w u  I_fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› w u  I`fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› w u  Iafjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› w u  Ibfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛw u  Icfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Idfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Iefjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Iffjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»w u  Igfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Ihfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Iifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Ijfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæûw u  Ikfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Ilfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Imfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Infjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡w u  Iofjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Ipfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Iqfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Irfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇw u  Isfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Itfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Iufjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Ivfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§w u  Iwfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Ixfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Iyfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Izfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæçw u  I{fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I|fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I}fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I~fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×x v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæïx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæßx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Àx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–àx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–x v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ðx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°x v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ðx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Èx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–èx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜x v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Øx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸x v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–øx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„x v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Äx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤x v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–äx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”x v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ôx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ôx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ìx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ìx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Üx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–üx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  "x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  (08Àó´”Ïûã(Pz'/google.datastore.v1.Datastore/RunQueryÌ 7type.googleapis.com/google.datastore.v1.RunQueryRequestBdulcet-port-762ü SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I:w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  bª ¢› 8type.googleapis.com/google.datastore.v1.RunQueryResponseäš àšâ f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ëx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«x v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ëx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›x v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ûx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ûx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Çx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§x v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹çx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—x v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹x v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ïx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯x v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ïx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ßx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿x v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€x v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùàx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°x v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùðx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨x v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùèx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜x v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùøx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤x v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùäx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”x v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔx v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùôx v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬x v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùìx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼x v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùüx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚x v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÂx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢x v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’x v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²x v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùòx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùªx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùêx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùšx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùºx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùúx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦x v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  x v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Å  "x v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  (0ô8Àó´”Ïûã(O'/google.datastore.v1.Datastore/RunQuery× 7type.googleapis.com/google.datastore.v1.RunQueryRequest›Bdulcet-port-762‡ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* IPôbôª ¢› 8type.googleapis.com/google.datastore.v1.RunQueryResponseäš àšâ f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ëx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«x v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ëx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›x v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ûx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ûx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Çx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§x v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹çx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—x v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹x v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ïx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯x v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ïx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ßx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿x v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€x v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùàx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°x v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùðx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨x v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùèx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜x v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùøx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤x v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùäx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”x v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔx v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùôx v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬x v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùìx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼x v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùüx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚x v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÂx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢x v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’x v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²x v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùòx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùªx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùêx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùšx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùºx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùúx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦x v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  x v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Å  "x v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  (0ô8Àó´”Ïûã(D'/google.datastore.v1.Datastore/RunQueryÒ 7type.googleapis.com/google.datastore.v1.RunQueryRequest–Bdulcet-port-762‚ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* IPô­ ¥™ 8type.googleapis.com/google.datastore.v1.RunQueryResponseç˜ ã˜á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæíw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  I!fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  I"fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝw u  I#fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ w u  I$fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ w u  I%fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ w u  I&fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½w u  I'fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ w u  I(fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ w u  I)fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ w u  I*fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæýw u  I+fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý w u  I,fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý w u  I-fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý w u  I.fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒw u  I/fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ w u  I0fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ w u  I1fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ w u  I2fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃw u  I3fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ w u  I4fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ w u  I5fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ w u  I6fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£w u  I7fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ w u  I8fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ w u  I9fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ w u  I:fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæãw u  I;fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã w u  I<fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã w u  I=fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã w u  I>fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“w u  I?fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ w u  I@fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ w u  IAfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ w u  IBfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓw u  ICfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ w u  IDfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ w u  IEfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ w u  IFfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³w u  IGfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ w u  IHfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ w u  IIfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ w u  IJfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæów u  IKfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó w u  ILfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó w u  IMfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó w u  INfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹w u  IOfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ w u  IPfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ w u  IQfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ w u  IRfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæËw u  ISfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË w u  ITfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË w u  IUfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË w u  IVfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«w u  IWfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« w u  IXfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« w u  IYfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« w u  IZfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæëw u  I[fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë w u  I\fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë w u  I]fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë w u  I^fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›w u  I_fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› w u  I`fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› w u  Iafjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› w u  Ibfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛw u  Icfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Idfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Iefjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Iffjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»w u  Igfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Ihfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Iifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Ijfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæûw u  Ikfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Ilfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Imfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Infjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡w u  Iofjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Ipfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Iqfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Irfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇw u  Isfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Itfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Iufjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Ivfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§w u  Iwfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Ixfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Iyfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Izfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæçw u  I{fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I|fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I}fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I~fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×x v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæïx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæßx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Àx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–àx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–x v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ðx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°x v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ðx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Èx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–èx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜x v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Øx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸x v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–øx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„x v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Äx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤x v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–äx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”x v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ôx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ôx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ìx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ìx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Üx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–üx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  "x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  (8Àó´”Ïûã(N‰'/google.datastore.v1.Datastore/RunQueryÛ 7type.googleapis.com/google.datastore.v1.RunQueryRequestŸBdulcet-port-762‹ __key__ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I:x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  b¼çà 8type.googleapis.com/google.datastore.v1.RunQueryResponse£  — ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  J I TÓêÁê UÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  Ȇ’”Ïûã"w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  (8Àó´”Ïûã(Zçà 8type.googleapis.com/google.datastore.v1.RunQueryResponse£  — ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  TÓêÁê UÓêÁê J Iw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  Ȇ’”Ïûã"w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  (8Àó´”Ïûã(XKÄ 8type.googleapis.com/google.datastore.v1.RunQueryResponse‡ „x v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  "x v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  (0 8Àó´”Ïûã(F'/google.datastore.v1.Datastore/RunQueryÒ 7type.googleapis.com/google.datastore.v1.RunQueryRequest–Bdulcet-port-762‚ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* IP ÎÇ 8type.googleapis.com/google.datastore.v1.RunQueryResponseŠ ‡"x v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  (8Àó´”Ïûã(rêã 8type.googleapis.com/google.datastore.v1.RunQueryResponse¦ £™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  UÓêÁê J I¼ TÓêÁêx v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  Àó´”Ïûã"x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  (8Àó´”Ïûã(sçà 8type.googleapis.com/google.datastore.v1.RunQueryResponse£  — ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  I TÓêÁê UÓêÁê Jw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  Ȇ’”Ïûã"w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  (8Àó´”Ïûã(oçà 8type.googleapis.com/google.datastore.v1.RunQueryResponse£  — ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  I  TÓêÁê UÓêÁê Jw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  Ȇ’”Ïûã"w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  (8Àó´”Ïûã(c- ¥š 8type.googleapis.com/google.datastore.v1.RunQueryResponseç™ ã™â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Âx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–âx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’x v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Òx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²x v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–òx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Šx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Êx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ªx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–êx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–šx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Úx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ºx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–úx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†x v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦x v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––x v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Öx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–öx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Žx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Îx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–îx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–žx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Áx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–áx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘x v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±x v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰x v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Éx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–éx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™x v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ùx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹x v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ùx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…x v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Åx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Å  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ëx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«x v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ëx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›x v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ûx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ûx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Çx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§x v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹çx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—x v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹x v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ïx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯x v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ïx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ßx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿x v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€x v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  "x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  (8Àó´”Ïûã(a„'/google.datastore.v1.Datastore/RunQueryÖ 7type.googleapis.com/google.datastore.v1.RunQueryRequestšBdulcet-port-762† __key__ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I:x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  çà 8type.googleapis.com/google.datastore.v1.RunQueryResponse£  — ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  Ȇ’”Ïûã"w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  (8Àó´”Ïûã(wønðÝ 8type.googleapis.com/google.datastore.v1.RunQueryResponse²Ý ®Ý— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  TÓêÁê UÓêÁê J Iw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  I TÓêÁê UÓêÁê Jw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  J I TÓêÁê UÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  UÓêÁê J I  TÓêÁêw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  UÓêÁê J I  TÓêÁêw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ UÓêÁê J I  TÓêÁêw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  I  TÓêÁê UÓêÁê Jw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  UÓêÁê J I  TÓêÁêw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ J I TÓêÁê UÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  I TÓêÁê UÓêÁê Jw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  I TÓêÁê UÓêÁê Jw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  TÓêÁê UÓêÁê J Iw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ I TÓêÁê UÓêÁê Jw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  J I TÓêÁê UÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  I TÓêÁê UÓêÁê Jw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  J I TÓêÁê UÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  J I TÓêÁê UÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí TÓêÁê UÓêÁê J Iw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  I TÓêÁê UÓêÁê Jw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  J I TÓêÁê UÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  I TÓêÁê UÓêÁê Jw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ J I TÓêÁê UÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  UÓêÁê J I  TÓêÁêw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  UÓêÁê J I! TÓêÁêw u  I!fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  TÓêÁê UÓêÁê J I"w u  I"fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ I# TÓêÁê UÓêÁê Jw u  I#fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  J I$ TÓêÁê UÓêÁêw u  I$fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  I% TÓêÁê UÓêÁê Jw u  I%fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  UÓêÁê J I& TÓêÁêw u  I&fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ TÓêÁê UÓêÁê J I'w u  I'fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  TÓêÁê UÓêÁê J I(w u  I(fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  I) TÓêÁê UÓêÁê Jw u  I)fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  J I* TÓêÁê UÓêÁêw u  I*fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý J I+ TÓêÁê UÓêÁêw u  I+fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  TÓêÁê UÓêÁê J I,w u  I,fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  UÓêÁê J I- TÓêÁêw u  I-fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  UÓêÁê J I. TÓêÁêw u  I.fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ UÓêÁê J I/ TÓêÁêw u  I/fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  I0 TÓêÁê UÓêÁê Jw u  I0fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  I1 TÓêÁê UÓêÁê Jw u  I1fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  UÓêÁê J I2 TÓêÁêw u  I2fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ J I3 TÓêÁê UÓêÁêw u  I3fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  UÓêÁê J I4 TÓêÁêw u  I4fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  TÓêÁê UÓêÁê J I5w u  I5fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  UÓêÁê J I6 TÓêÁêw u  I6fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ UÓêÁê J I7 TÓêÁêw u  I7fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  UÓêÁê J I8 TÓêÁêw u  I8fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  UÓêÁê J I9 TÓêÁêw u  I9fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  UÓêÁê J I: TÓêÁêw u  I:fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã UÓêÁê J I; TÓêÁêw u  I;fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  J I< TÓêÁê UÓêÁêw u  I<fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  UÓêÁê J I= TÓêÁêw u  I=fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  J I> TÓêÁê UÓêÁêw u  I>fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ I? TÓêÁê UÓêÁê Jw u  I?fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  TÓêÁê UÓêÁê J I@w u  I@fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  J IA TÓêÁê UÓêÁêw u  IAfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  IB TÓêÁê UÓêÁê Jw u  IBfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ J IC TÓêÁê UÓêÁêw u  ICfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  TÓêÁê UÓêÁê J IDw u  IDfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  J IE TÓêÁê UÓêÁêw u  IEfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  UÓêÁê J IF TÓêÁêw u  IFfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ J IG TÓêÁê UÓêÁêw u  IGfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  J IH TÓêÁê UÓêÁêw u  IHfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  UÓêÁê J II TÓêÁêw u  IIfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  UÓêÁê J IJ TÓêÁêw u  IJfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó IK TÓêÁê UÓêÁê Jw u  IKfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  UÓêÁê J IL TÓêÁêw u  ILfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  J IM TÓêÁê UÓêÁêw u  IMfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  IN TÓêÁê UÓêÁê Jw u  INfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ TÓêÁê UÓêÁê J IOw u  IOfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  IP TÓêÁê UÓêÁê Jw u  IPfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  UÓêÁê J IQ TÓêÁêw u  IQfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  IR TÓêÁê UÓêÁê Jw u  IRfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË J IS TÓêÁê UÓêÁêw u  ISfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  UÓêÁê J IT TÓêÁêw u  ITfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  UÓêÁê J IU TÓêÁêw u  IUfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  UÓêÁê J IV TÓêÁêw u  IVfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« J IW TÓêÁê UÓêÁêw u  IWfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  UÓêÁê J IX TÓêÁêw u  IXfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  UÓêÁê J IY TÓêÁêw u  IYfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  TÓêÁê UÓêÁê J IZw u  IZfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë UÓêÁê J I[ TÓêÁêw u  I[fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  TÓêÁê UÓêÁê J I\w u  I\fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  TÓêÁê UÓêÁê J I]w u  I]fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  I^ TÓêÁê UÓêÁê Jw u  I^fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› UÓêÁê J I_ TÓêÁêw u  I_fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  J I` TÓêÁê UÓêÁêw u  I`fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  UÓêÁê J Ia TÓêÁêw u  Iafjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  Ib TÓêÁê UÓêÁê Jw u  Ibfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ Ic TÓêÁê UÓêÁê Jw u  Icfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  Ȇ’”Ïûã"w u  Icfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  (8Àó´”Ïûã(]püß 8type.googleapis.com/google.datastore.v1.RunQueryResponse¾ß ºß— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  Id TÓêÁê UÓêÁê Jw u  Idfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  Ie TÓêÁê UÓêÁê Jw u  Iefjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  TÓêÁê UÓêÁê J Ifw u  Iffjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» Ig TÓêÁê UÓêÁê Jw u  Igfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  Ih TÓêÁê UÓêÁê Jw u  Ihfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  Ii TÓêÁê UÓêÁê Jw u  Iifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  UÓêÁê J Ij TÓêÁêw u  Ijfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû Ik TÓêÁê UÓêÁê Jw u  Ikfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  TÓêÁê UÓêÁê J Ilw u  Ilfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  UÓêÁê J Im TÓêÁêw u  Imfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  UÓêÁê J In TÓêÁêw u  Infjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ TÓêÁê UÓêÁê J Iow u  Iofjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  UÓêÁê J Ip TÓêÁêw u  Ipfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  UÓêÁê J Iq TÓêÁêw u  Iqfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  Ir TÓêÁê UÓêÁê Jw u  Irfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ J Is TÓêÁê UÓêÁêw u  Isfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  J It TÓêÁê UÓêÁêw u  Itfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  TÓêÁê UÓêÁê J Iuw u  Iufjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  J Iv TÓêÁê UÓêÁêw u  Ivfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ UÓêÁê J Iw TÓêÁêw u  Iwfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  UÓêÁê J Ix TÓêÁêw u  Ixfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  Iy TÓêÁê UÓêÁê Jw u  Iyfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  Iz TÓêÁê UÓêÁê Jw u  Izfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç UÓêÁê J I{ TÓêÁêw u  I{fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  UÓêÁê J I| TÓêÁêw u  I|fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  J I} TÓêÁê UÓêÁêw u  I}fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  TÓêÁê UÓêÁê J I~w u  I~fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— I TÓêÁê UÓêÁê Jw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  TÓêÁê UÓêÁê J I€x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  UÓêÁê J I‚ TÓêÁêx v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× TÓêÁê UÓêÁê J Iƒx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  TÓêÁê UÓêÁê J I„x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  I… TÓêÁê UÓêÁê Jx v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  J I† TÓêÁê UÓêÁêx v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· J I‡ TÓêÁê UÓêÁêx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  J Iˆ TÓêÁê UÓêÁêx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  TÓêÁê UÓêÁê J I‰x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  TÓêÁê UÓêÁê J IŠx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ I‹ TÓêÁê UÓêÁê Jx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  J IŒ TÓêÁê UÓêÁêx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  TÓêÁê UÓêÁê J IŽx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  UÓêÁê J I‘ TÓêÁêx v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  UÓêÁê J I’ TÓêÁêx v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ UÓêÁê J I“ TÓêÁêx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  TÓêÁê UÓêÁê J I”x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  I• TÓêÁê UÓêÁê Jx v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  UÓêÁê J I– TÓêÁêx v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ UÓêÁê J I— TÓêÁêx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  TÓêÁê UÓêÁê J I˜x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  J I™ TÓêÁê UÓêÁêx v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  UÓêÁê J Iš TÓêÁêx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï J I› TÓêÁê UÓêÁêx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  UÓêÁê J Iœ TÓêÁêx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  UÓêÁê J Iž TÓêÁêx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ IŸ TÓêÁê UÓêÁê Jx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  UÓêÁê J I  TÓêÁêx v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  TÓêÁê UÓêÁê J I¡x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  I¢ TÓêÁê UÓêÁê Jx v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß UÓêÁê J I£ TÓêÁêx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  UÓêÁê J I¤ TÓêÁêx v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  J I¥ TÓêÁê UÓêÁêx v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  UÓêÁê J I¦ TÓêÁêx v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ J I§ TÓêÁê UÓêÁêx v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  J I¨ TÓêÁê UÓêÁêx v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  TÓêÁê UÓêÁê J I©x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  TÓêÁê UÓêÁê J Iªx v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ UÓêÁê J I« TÓêÁêx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  UÓêÁê J I¬ TÓêÁêx v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  J I­ TÓêÁê UÓêÁêx v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  TÓêÁê UÓêÁê J I®x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ I¯ TÓêÁê UÓêÁê Jx v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  I° TÓêÁê UÓêÁê Jx v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  TÓêÁê UÓêÁê J I±x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  I² TÓêÁê UÓêÁê Jx v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À UÓêÁê J I³ TÓêÁêx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  TÓêÁê UÓêÁê J I´x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  TÓêÁê UÓêÁê J Iµx v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  UÓêÁê J I¶ TÓêÁêx v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  UÓêÁê J I· TÓêÁêx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   J I¸ TÓêÁê UÓêÁêx v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   TÓêÁê UÓêÁê J I¹x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   TÓêÁê UÓêÁê J Iºx v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à TÓêÁê UÓêÁê J I»x v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  TÓêÁê UÓêÁê J I¼x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  J I½ TÓêÁê UÓêÁêx v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  UÓêÁê J I¾ TÓêÁêx v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– UÓêÁê J I¿ TÓêÁêx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  IÀ TÓêÁê UÓêÁê Jx v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  IÁ TÓêÁê UÓêÁê Jx v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  TÓêÁê UÓêÁê J IÂx v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð UÓêÁê J Ià TÓêÁêx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  UÓêÁê J IÄ TÓêÁêx v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  UÓêÁê J IÅ TÓêÁêx v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  UÓêÁê J IÆ TÓêÁêx v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° J IÇ TÓêÁê UÓêÁêx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  Ȇ’”Ïûãw u  Icfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  "x v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  (0d8Àó´”Ïûã(_- ¥š 8type.googleapis.com/google.datastore.v1.RunQueryResponseç™ ã™â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Âx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–âx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’x v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Òx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²x v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–òx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Šx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Êx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ªx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–êx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–šx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Úx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ºx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–úx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†x v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦x v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––x v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Öx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–öx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Žx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Îx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–îx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–žx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Áx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–áx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘x v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±x v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰x v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Éx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–éx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™x v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ùx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹x v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ùx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…x v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Åx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Å  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ëx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«x v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ëx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›x v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ûx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ûx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Çx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§x v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹çx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—x v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹x v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ïx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯x v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ïx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ßx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿x v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€x v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  "x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  (8Àó´”Ïûã(m‰'/google.datastore.v1.Datastore/RunQueryÛ 7type.googleapis.com/google.datastore.v1.RunQueryRequestŸBdulcet-port-762‹ __key__ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I:x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  bÈ- ¥š 8type.googleapis.com/google.datastore.v1.RunQueryResponseç™ ã™â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Îx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–îx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–žx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Áx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–áx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘x v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±x v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰x v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Éx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–éx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™x v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ùx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹x v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ùx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…x v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Åx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Å  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ëx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«x v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ëx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›x v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ûx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ûx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Çx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§x v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹çx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—x v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹x v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ïx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯x v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ïx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ßx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿x v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€x v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùàx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°x v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùðx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨x v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùèx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜x v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùøx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤x v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùäx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”x v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔx v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùôx v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬x v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  "x v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  (8Àó´”Ïûã(j„'/google.datastore.v1.Datastore/RunQueryÖ 7type.googleapis.com/google.datastore.v1.RunQueryRequestšBdulcet-port-762† __key__ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I:x v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  - ¥š 8type.googleapis.com/google.datastore.v1.RunQueryResponseç™ ã™â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Âx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–âx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’x v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Òx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²x v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–òx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Šx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Êx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ªx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–êx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–šx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Úx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ºx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–úx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†x v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦x v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––x v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Öx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–öx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Žx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Îx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–îx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–žx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Áx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–áx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘x v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±x v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰x v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Éx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–éx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™x v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ùx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹x v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ùx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…x v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Åx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Å  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ëx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«x v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ëx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›x v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ûx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ûx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Çx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§x v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹çx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—x v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹x v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ïx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯x v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ïx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ßx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿x v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€x v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  "x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  (8Àó´”Ïûã(g‰'/google.datastore.v1.Datastore/RunQueryÛ 7type.googleapis.com/google.datastore.v1.RunQueryRequestŸBdulcet-port-762‹ __key__ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I:x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  bè- ¥š 8type.googleapis.com/google.datastore.v1.RunQueryResponseç™ ã™â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Âx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–âx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’x v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Òx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²x v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–òx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Šx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Êx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ªx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–êx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–šx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Úx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ºx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–úx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†x v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦x v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––x v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Öx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–öx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Žx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Îx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–îx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–žx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Áx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–áx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘x v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±x v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰x v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Éx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–éx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™x v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ùx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹x v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ùx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…x v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Åx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Å  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ëx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«x v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ëx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›x v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ûx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ûx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Çx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§x v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹çx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—x v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹x v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ïx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯x v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ïx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ßx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿x v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€x v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  "x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  (8Àó´”Ïûã(l„'/google.datastore.v1.Datastore/RunQueryÖ 7type.googleapis.com/google.datastore.v1.RunQueryRequestšBdulcet-port-762† __key__ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I:x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  ­ ¥™ 8type.googleapis.com/google.datastore.v1.RunQueryResponseç˜ ã˜á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæíw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  I!fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ w u  I"fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝw u  I#fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ w u  I$fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ w u  I%fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ w u  I&fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½w u  I'fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ w u  I(fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ w u  I)fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ w u  I*fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæýw u  I+fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý w u  I,fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý w u  I-fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý w u  I.fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒw u  I/fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ w u  I0fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ w u  I1fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ w u  I2fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃw u  I3fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ w u  I4fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ w u  I5fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ w u  I6fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£w u  I7fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ w u  I8fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ w u  I9fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ w u  I:fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæãw u  I;fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã w u  I<fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã w u  I=fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã w u  I>fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“w u  I?fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ w u  I@fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ w u  IAfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ w u  IBfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓw u  ICfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ w u  IDfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ w u  IEfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ w u  IFfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³w u  IGfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ w u  IHfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ w u  IIfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ w u  IJfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæów u  IKfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó w u  ILfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó w u  IMfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó w u  INfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹w u  IOfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ w u  IPfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ w u  IQfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ w u  IRfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæËw u  ISfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË w u  ITfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË w u  IUfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË w u  IVfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«w u  IWfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« w u  IXfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« w u  IYfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« w u  IZfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæëw u  I[fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë w u  I\fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë w u  I]fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë w u  I^fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›w u  I_fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› w u  I`fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› w u  Iafjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› w u  Ibfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛw u  Icfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Idfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Iefjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ w u  Iffjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»w u  Igfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Ihfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Iifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» w u  Ijfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæûw u  Ikfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Ilfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Imfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû w u  Infjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡w u  Iofjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Ipfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Iqfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ w u  Irfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇw u  Isfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Itfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Iufjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ w u  Ivfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§w u  Iwfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Ixfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Iyfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ w u  Izfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæçw u  I{fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I|fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I}fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç w u  I~fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  á f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—w u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×x v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæïx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæßx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Àx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–àx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–x v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ðx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°x v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ðx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Èx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–èx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜x v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Øx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸x v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–øx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„x v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Äx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤x v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–äx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”x v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ôx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ôx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ìx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ìx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Üx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–üx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  "x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  (8Àó´”Ïûã(R„'/google.datastore.v1.Datastore/RunQueryÖ 7type.googleapis.com/google.datastore.v1.RunQueryRequestšBdulcet-port-762† __key__ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I:x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  - ¥š 8type.googleapis.com/google.datastore.v1.RunQueryResponseç™ ã™â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Îx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–îx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–žx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Áx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–áx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘x v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±x v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰x v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Éx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–éx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™x v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ùx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹x v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ùx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…x v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Åx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Å  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ëx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«x v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ëx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›x v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ûx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ûx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Çx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§x v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹çx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—x v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹x v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ïx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯x v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ïx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ßx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿x v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€x v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùàx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°x v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùðx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨x v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùèx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜x v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùøx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤x v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùäx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”x v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔx v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùôx v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬x v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  "x v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  (8Àó´”Ïûã(e‰'/google.datastore.v1.Datastore/RunQueryÛ 7type.googleapis.com/google.datastore.v1.RunQueryRequestŸBdulcet-port-762‹ __key__ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I:x v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  bž´–é 8type.googleapis.com/google.datastore.v1.RunQueryResponseØè Ôèâ f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Âx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–âx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’x v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Òx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²x v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–òx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Šx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Êx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ªx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–êx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–šx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Úx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ºx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–úx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†x v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦x v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––x v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Öx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–öx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Žx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Îx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–îx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–žx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Áx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–áx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘x v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±x v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰x v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Éx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–éx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™x v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ùx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹x v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ùx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…x v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Åx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Å  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  "x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  (8Àó´”Ïûã(u'/google.datastore.v1.Datastore/RunQueryÔ 7type.googleapis.com/google.datastore.v1.RunQueryRequest˜Bdulcet-port-762„ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* Ibõ- ¥š 8type.googleapis.com/google.datastore.v1.RunQueryResponseç™ ã™â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Âx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–âx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’x v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Òx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²x v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–òx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Šx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Êx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ªx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–êx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–šx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Úx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ºx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–úx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†x v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦x v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––x v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Öx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–öx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Žx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Îx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–îx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–žx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Áx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–áx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘x v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±x v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰x v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Éx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–éx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™x v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ùx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹x v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ùx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…x v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Åx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Å  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ëx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«x v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ëx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›x v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ûx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ûx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Çx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§x v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹çx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—x v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹x v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ïx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯x v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ïx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ßx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿x v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€x v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  "x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  (8Àó´”Ïûã(}‰'/google.datastore.v1.Datastore/RunQueryÛ 7type.googleapis.com/google.datastore.v1.RunQueryRequestŸBdulcet-port-762‹ __key__ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I:x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  bº³±ç 8type.googleapis.com/google.datastore.v1.RunQueryResponseóæ ïæâ f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùàx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°x v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùðx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨x v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùèx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜x v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùøx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤x v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùäx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”x v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔx v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùôx v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬x v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùìx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼x v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùüx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚x v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÂx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢x v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’x v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²x v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùòx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùªx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùêx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùšx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùºx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùúx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦x v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  "x v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  (8Àó´”Ïûã(‡{'/google.datastore.v1.Datastore/RunQueryÍ 7type.googleapis.com/google.datastore.v1.RunQueryRequest‘Bdulcet-port-762ý SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I:x v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  bFZ½´ 8type.googleapis.com/google.datastore.v1.RunQueryResponseÿ³ û³â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùìx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼x v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùüx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚x v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÂx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢x v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’x v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²x v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùòx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùªx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùêx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùšx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùºx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùúx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦x v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  "x v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  (8Àó´”Ïûã(Žÿ'/google.datastore.v1.Datastore/RunQueryÑ 7type.googleapis.com/google.datastore.v1.RunQueryRequest•Bdulcet-port-762 SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* IPdº³±ç 8type.googleapis.com/google.datastore.v1.RunQueryResponseóæ ïæâ f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùàx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°x v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùðx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨x v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùèx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜x v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùøx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤x v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùäx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”x v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔx v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùôx v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬x v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùìx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼x v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùüx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚x v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÂx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢x v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’x v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²x v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùòx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùªx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùêx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùšx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùºx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùúx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦x v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  "x v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  (8Àó´”Ïûã('/google.datastore.v1.Datastore/RunQueryÔ 7type.googleapis.com/google.datastore.v1.RunQueryRequest˜Bdulcet-port-762„ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* IbÀ º³±ç 8type.googleapis.com/google.datastore.v1.RunQueryResponseóæ ïæâ f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùàx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°x v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùðx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨x v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùèx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜x v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùøx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤x v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùäx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”x v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔx v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùôx v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬x v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùìx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼x v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùüx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚x v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÂx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢x v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’x v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²x v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùòx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùªx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùêx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùšx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùºx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùúx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦x v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  "x v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  (8Àó´”Ïûã(’ü'/google.datastore.v1.Datastore/RunQueryÎ 7type.googleapis.com/google.datastore.v1.RunQueryRequest’Bdulcet-port-762 SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* IFZ½´ 8type.googleapis.com/google.datastore.v1.RunQueryResponseÿ³ û³â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùìx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼x v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùüx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚x v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÂx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢x v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’x v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²x v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùòx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùªx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùêx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùšx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùºx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùúx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦x v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  "x v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  (8Àó´”Ïûã(–'/google.datastore.v1.Datastore/RunQueryÖ 7type.googleapis.com/google.datastore.v1.RunQueryRequestšBdulcet-port-762† SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* IPdb躳±ç 8type.googleapis.com/google.datastore.v1.RunQueryResponseóæ ïæâ f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùàx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°x v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùðx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨x v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùèx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜x v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùøx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤x v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùäx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”x v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔx v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùôx v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬x v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùìx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼x v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùüx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚x v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÂx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢x v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’x v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²x v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùòx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùªx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùêx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùšx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùºx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùúx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦x v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  "x v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  (8Àó´”Ïûã(Œ'/google.datastore.v1.Datastore/RunQueryÔ 7type.googleapis.com/google.datastore.v1.RunQueryRequest˜Bdulcet-port-762„ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* Ib N–œ 8type.googleapis.com/google.datastore.v1.RunQueryResponseØ› Ô›™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  TÓêÁê UÓêÁê J Iôx v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  UÓêÁê J Iõ TÓêÁêx v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  J Iö TÓêÁê UÓêÁêx v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë UÓêÁê J I÷ TÓêÁêx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  Iø TÓêÁê UÓêÁê Jx v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  J Iù TÓêÁê UÓêÁêx v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  UÓêÁê J Iú TÓêÁêx v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« Iû TÓêÁê UÓêÁê Jx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  J Iü TÓêÁê UÓêÁêx v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  Iý TÓêÁê UÓêÁê Jx v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  Iþ TÓêÁê UÓêÁê Jx v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë TÓêÁê UÓêÁê J Iÿx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  TÓêÁê UÓêÁê J I€x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  J I TÓêÁê UÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  J I‚ TÓêÁê UÓêÁêx v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› TÓêÁê UÓêÁê J Iƒx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  I„ TÓêÁê UÓêÁê Jx v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  UÓêÁê J I… TÓêÁêx v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  UÓêÁê J I† TÓêÁêx v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û J I‡ TÓêÁê UÓêÁêx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  J Iˆ TÓêÁê UÓêÁêx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  TÓêÁê UÓêÁê J I‰x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  UÓêÁê J IŠ TÓêÁêx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» TÓêÁê UÓêÁê J I‹x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  UÓêÁê J IŒ TÓêÁêx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  J I TÓêÁê UÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  UÓêÁê J IŽ TÓêÁêx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  J I TÓêÁê UÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  J I‘ TÓêÁê UÓêÁêx v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  I’ TÓêÁê UÓêÁê Jx v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ UÓêÁê J I“ TÓêÁêx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  UÓêÁê J I” TÓêÁêx v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  I• TÓêÁê UÓêÁê Jx v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  I– TÓêÁê UÓêÁê Jx v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç I— TÓêÁê UÓêÁê Jx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  TÓêÁê UÓêÁê J I˜x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  J I™ TÓêÁê UÓêÁêx v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  UÓêÁê J Iš TÓêÁêx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ UÓêÁê J I› TÓêÁêx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  UÓêÁê J Iœ TÓêÁêx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  UÓêÁê J Iž TÓêÁêx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç J IŸ TÓêÁê UÓêÁêx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  UÓêÁê J I  TÓêÁêx v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  TÓêÁê UÓêÁê J I¡x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  TÓêÁê UÓêÁê J I¢x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— J I£ TÓêÁê UÓêÁêx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  I¤ TÓêÁê UÓêÁê Jx v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  J I¥ TÓêÁê UÓêÁêx v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  I¦ TÓêÁê UÓêÁê Jx v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× I§ TÓêÁê UÓêÁê Jx v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  TÓêÁê UÓêÁê J I¨x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  TÓêÁê UÓêÁê J I©x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  TÓêÁê UÓêÁê J Iªx v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· J I« TÓêÁê UÓêÁêx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  J I¬ TÓêÁê UÓêÁêx v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  UÓêÁê J I­ TÓêÁêx v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  UÓêÁê J I® TÓêÁêx v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ TÓêÁê UÓêÁê J I¯x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  J I° TÓêÁê UÓêÁêx v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  I± TÓêÁê UÓêÁê Jx v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  I² TÓêÁê UÓêÁê Jx v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ UÓêÁê J I³ TÓêÁêx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  UÓêÁê J I´ TÓêÁêx v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  UÓêÁê J Iµ TÓêÁêx v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  UÓêÁê J I¶ TÓêÁêx v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï TÓêÁê UÓêÁê J I·x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  I¸ TÓêÁê UÓêÁê Jx v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  I¹ TÓêÁê UÓêÁê Jx v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  TÓêÁê UÓêÁê J Iºx v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ J I» TÓêÁê UÓêÁêx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  UÓêÁê J I¼ TÓêÁêx v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  I½ TÓêÁê UÓêÁê Jx v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  UÓêÁê J I¾ TÓêÁêx v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï UÓêÁê J I¿ TÓêÁêx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  UÓêÁê J IÀ TÓêÁêx v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  TÓêÁê UÓêÁê J IÁx v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  UÓêÁê J I TÓêÁêx v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ TÓêÁê UÓêÁê J IÃx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  IÄ TÓêÁê UÓêÁê Jx v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  UÓêÁê J IÅ TÓêÁêx v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  J IÆ TÓêÁê UÓêÁêx v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß UÓêÁê J IÇ TÓêÁêx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  UÓêÁê J IÈ TÓêÁêx v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  J IÉ TÓêÁê UÓêÁêx v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  UÓêÁê J IÊ TÓêÁêx v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ UÓêÁê J IË TÓêÁêx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  UÓêÁê J IÌ TÓêÁêx v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  UÓêÁê J IÍ TÓêÁêx v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  UÓêÁê J IÎ TÓêÁêx v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ IÏ TÓêÁê UÓêÁê Jx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  UÓêÁê J IÐ TÓêÁêx v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  J IÑ TÓêÁê UÓêÁêx v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  IÒ TÓêÁê UÓêÁê Jx v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ UÓêÁê J IÓ TÓêÁêx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  UÓêÁê J IÔ TÓêÁêx v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  UÓêÁê J IÕ TÓêÁêx v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  IÖ TÓêÁê UÓêÁê Jx v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ TÓêÁê UÓêÁê J I×x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  UÓêÁê J IØ TÓêÁêx v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  J IÙ TÓêÁê UÓêÁêx v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  TÓêÁê UÓêÁê J IÚx v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  UÓêÁê J IÛ TÓêÁêx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   UÓêÁê J IÜ TÓêÁêx v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   UÓêÁê J IÝ TÓêÁêx v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   UÓêÁê J IÞ TÓêÁêx v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà TÓêÁê UÓêÁê J Ißx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  Ià TÓêÁê UÓêÁê Jx v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  UÓêÁê J Iá TÓêÁêx v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  J Iâ TÓêÁê UÓêÁêx v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù Iã TÓêÁê UÓêÁê Jx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  UÓêÁê J Iä TÓêÁêx v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Iå TÓêÁê UÓêÁê Jx v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Iæ TÓêÁê UÓêÁê Jx v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ UÓêÁê J Iç TÓêÁêx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  TÓêÁê UÓêÁê J Ièx v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  Ié TÓêÁê UÓêÁê Jx v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  Iê TÓêÁê UÓêÁê Jx v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° TÓêÁê UÓêÁê J Iëx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  Iì TÓêÁê UÓêÁê Jx v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  TÓêÁê UÓêÁê J Iíx v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  Iî TÓêÁê UÓêÁê Jx v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð Iï TÓêÁê UÓêÁê Jx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Ið TÓêÁê UÓêÁê Jx v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  J Iñ TÓêÁê UÓêÁêx v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  UÓêÁê J Iò TÓêÁêx v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ UÓêÁê J Ió TÓêÁêx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  J Iô TÓêÁê UÓêÁêx v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  TÓêÁê UÓêÁê J Iõx v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  J Iö TÓêÁê UÓêÁêx v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ UÓêÁê J I÷ TÓêÁêx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  Iø TÓêÁê UÓêÁê Jx v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  TÓêÁê UÓêÁê J Iùx v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  UÓêÁê J Iú TÓêÁêx v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ UÓêÁê J Iû TÓêÁêx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  UÓêÁê J Iü TÓêÁêx v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  Iý TÓêÁê UÓêÁê Jx v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  J Iþ TÓêÁê UÓêÁêx v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè J Iÿ TÓêÁê UÓêÁêx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  I€ TÓêÁê UÓêÁê Jx v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  TÓêÁê UÓêÁê J I‚x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ Iƒ TÓêÁê UÓêÁê Jx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  UÓêÁê J I„ TÓêÁêx v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  TÓêÁê UÓêÁê J I…x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  J I† TÓêÁê UÓêÁêx v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ UÓêÁê J I‡ TÓêÁêx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  TÓêÁê UÓêÁê J Iˆx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  J I‰ TÓêÁê UÓêÁêx v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  J IŠ TÓêÁê UÓêÁêx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ TÓêÁê UÓêÁê J I‹x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  TÓêÁê UÓêÁê J IŒx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  UÓêÁê J IŽ TÓêÁêx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  UÓêÁê J I‘ TÓêÁêx v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  J I’ TÓêÁê UÓêÁêx v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ UÓêÁê J I“ TÓêÁêx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  I” TÓêÁê UÓêÁê Jx v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  I• TÓêÁê UÓêÁê Jx v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  UÓêÁê J I– TÓêÁêx v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ UÓêÁê J I— TÓêÁêx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  J I˜ TÓêÁê UÓêÁêx v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  TÓêÁê UÓêÁê J I™x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  Iš TÓêÁê UÓêÁê Jx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ I› TÓêÁê UÓêÁê Jx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  UÓêÁê J Iœ TÓêÁêx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  UÓêÁê J Iž TÓêÁêx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä UÓêÁê J IŸ TÓêÁêx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  I  TÓêÁê UÓêÁê Jx v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  I¡ TÓêÁê UÓêÁê Jx v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  UÓêÁê J I¢ TÓêÁêx v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” UÓêÁê J I£ TÓêÁêx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  UÓêÁê J I¤ TÓêÁêx v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  UÓêÁê J I¥ TÓêÁêx v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  J I¦ TÓêÁê UÓêÁêx v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ TÓêÁê UÓêÁê J I§x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  TÓêÁê UÓêÁê J I¨x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  I© TÓêÁê UÓêÁê Jx v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  Iª TÓêÁê UÓêÁê Jx v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ J I« TÓêÁê UÓêÁêx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  TÓêÁê UÓêÁê J I¬x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  J I­ TÓêÁê UÓêÁêx v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  UÓêÁê J I® TÓêÁêx v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô TÓêÁê UÓêÁê J I¯x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  J I° TÓêÁê UÓêÁêx v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  TÓêÁê UÓêÁê J I±x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  UÓêÁê J I² TÓêÁêx v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ I³ TÓêÁê UÓêÁê Jx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  UÓêÁê J I´ TÓêÁêx v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  UÓêÁê J Iµ TÓêÁêx v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  I¶ TÓêÁê UÓêÁê Jx v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ UÓêÁê J I· TÓêÁêx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  I¸ TÓêÁê UÓêÁê Jx v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  I¹ TÓêÁê UÓêÁê Jx v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  Iº TÓêÁê UÓêÁê Jx v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ J I» TÓêÁê UÓêÁêx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  I¼ TÓêÁê UÓêÁê Jx v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  TÓêÁê UÓêÁê J I½x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  UÓêÁê J I¾ TÓêÁêx v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì I¿ TÓêÁê UÓêÁê Jx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  UÓêÁê J IÀ TÓêÁêx v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  IÁ TÓêÁê UÓêÁê Jx v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  TÓêÁê UÓêÁê J IÂx v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ Ià TÓêÁê UÓêÁê Jx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  IÄ TÓêÁê UÓêÁê Jx v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  IÅ TÓêÁê UÓêÁê Jx v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  IÆ TÓêÁê UÓêÁê Jx v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ J IÇ TÓêÁê UÓêÁêx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  UÓêÁê J IÈ TÓêÁêx v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  UÓêÁê J IÉ TÓêÁêx v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  UÓêÁê J IÊ TÓêÁêx v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ J IË TÓêÁê UÓêÁêx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  UÓêÁê J IÌ TÓêÁêx v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  UÓêÁê J IÍ TÓêÁêx v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  J IÎ TÓêÁê UÓêÁêx v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü IÏ TÓêÁê UÓêÁê Jx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  TÓêÁê UÓêÁê J IÐx v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  UÓêÁê J IÑ TÓêÁêx v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  UÓêÁê J IÒ TÓêÁêx v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ IÓ TÓêÁê UÓêÁê Jx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  TÓêÁê UÓêÁê J IÔx v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  IÕ TÓêÁê UÓêÁê Jx v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  UÓêÁê J IÖ TÓêÁêx v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù UÓêÁê J I× TÓêÁêx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  IØ TÓêÁê UÓêÁê Jx v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  TÓêÁê UÓêÁê J IÙx v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  TÓêÁê UÓêÁê J IÚx v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ IÛ TÓêÁê UÓêÁê Jx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  UÓêÁê J IÜ TÓêÁêx v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  UÓêÁê J IÝ TÓêÁêx v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  IÞ TÓêÁê UÓêÁê Jx v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ Iß TÓêÁê UÓêÁê Jx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  TÓêÁê UÓêÁê J Iàx v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  Iá TÓêÁê UÓêÁê Jx v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  UÓêÁê J Iâ TÓêÁêx v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ Iã TÓêÁê UÓêÁê Jx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  UÓêÁê J Iä TÓêÁêx v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  TÓêÁê UÓêÁê J Iåx v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  J Iæ TÓêÁê UÓêÁêx v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ J Iç TÓêÁê UÓêÁêx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  UÓêÁê J Iè TÓêÁêx v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  Ié TÓêÁê UÓêÁê Jx v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  UÓêÁê J Iê TÓêÁêx v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² TÓêÁê UÓêÁê J Iëx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  Iì TÓêÁê UÓêÁê Jx v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  UÓêÁê J Ií TÓêÁêx v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  J Iî TÓêÁê UÓêÁêx v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò Iï TÓêÁê UÓêÁê Jx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  UÓêÁê J Ið TÓêÁêx v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  UÓêÁê J Iñ TÓêÁêx v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  Iò TÓêÁê UÓêÁê Jx v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ J Ió TÓêÁê UÓêÁêx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  UÓêÁê J Iô TÓêÁêx v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  TÓêÁê UÓêÁê J Iõx v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  J Iö TÓêÁê UÓêÁêx v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ TÓêÁê UÓêÁê J I÷x v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  UÓêÁê J Iø TÓêÁêx v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  TÓêÁê UÓêÁê J Iùx v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  J Iú TÓêÁê UÓêÁêx v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª J Iû TÓêÁê UÓêÁêx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  Iü TÓêÁê UÓêÁê Jx v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  UÓêÁê J Iý TÓêÁêx v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  TÓêÁê UÓêÁê J Iþx v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê UÓêÁê J Iÿ TÓêÁêx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  J I€ TÓêÁê UÓêÁêx v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  TÓêÁê UÓêÁê J I‚x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš J Iƒ TÓêÁê UÓêÁêx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  I„ TÓêÁê UÓêÁê Jx v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  TÓêÁê UÓêÁê J I…x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  UÓêÁê J I† TÓêÁêx v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ J I‡ TÓêÁê UÓêÁêx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  Iˆ TÓêÁê UÓêÁê Jx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  UÓêÁê J I‰ TÓêÁêx v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  J IŠ TÓêÁê UÓêÁêx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº J I‹ TÓêÁê UÓêÁêx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  UÓêÁê J IŒ TÓêÁêx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  J I TÓêÁê UÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  TÓêÁê UÓêÁê J IŽx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  UÓêÁê J I‘ TÓêÁêx v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  I’ TÓêÁê UÓêÁê Jx v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† UÓêÁê J I“ TÓêÁêx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  I” TÓêÁê UÓêÁê Jx v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  J I• TÓêÁê UÓêÁêx v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  I– TÓêÁê UÓêÁê Jx v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ UÓêÁê J I— TÓêÁêx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  UÓêÁê J I˜ TÓêÁêx v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  J I™ TÓêÁê UÓêÁêx v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  TÓêÁê UÓêÁê J Išx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ J I› TÓêÁê UÓêÁêx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  UÓêÁê J Iœ TÓêÁêx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  J I TÓêÁê UÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  J Iž TÓêÁê UÓêÁêx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ IŸ TÓêÁê UÓêÁê Jx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  Àó´”Ïûãx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Å  "x v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  (0ô8Àó´”Ïûã({º³±ç 8type.googleapis.com/google.datastore.v1.RunQueryResponseóæ ïæâ f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùàx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°x v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùðx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨x v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùèx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜x v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùøx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤x v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùäx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”x v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔx v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùôx v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬x v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùìx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼x v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùüx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚x v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÂx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢x v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’x v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²x v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùòx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùªx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùêx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùšx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùºx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùúx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦x v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  "x v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  (8Àó´”Ïûã(š{'/google.datastore.v1.Datastore/RunQueryÍ 7type.googleapis.com/google.datastore.v1.RunQueryRequest‘Bdulcet-port-762ý SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I:x v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  b. ¥š 8type.googleapis.com/google.datastore.v1.RunQueryResponseç™ ã™â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Âx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–âx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’x v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Òx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²x v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–òx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Šx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Êx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ªx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–êx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–šx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Úx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ºx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–úx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†x v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦x v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––x v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Öx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–öx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Žx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Îx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–îx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–žx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Áx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–áx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘x v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±x v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰x v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Éx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© x v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© x v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© x v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–éx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é x v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é x v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é x v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™x v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ x v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ x v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ x v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ùx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù x v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù x v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù x v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹x v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ x v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ x v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ x v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ùx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù x v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù x v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù x v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…x v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… x v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… x v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… x v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Åx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Å  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ x v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ x v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ëx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë x v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë x v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë x v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«x v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« x v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« x v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« x v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ëx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›x v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ûx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û x v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û x v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» x v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» x v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ûx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Çx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç x v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§x v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ x v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ x v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹çx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—x v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× x v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹x v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ x v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ïx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï x v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯x v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ïx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï x v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï x v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï x v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ x v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ x v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ x v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ßx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß x v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß x v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß x v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿x v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ x v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ x v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ x v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ x v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ x v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ x v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€x v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ x v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ x v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ x v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  â f d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  "x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  (8Àó´”Ïûã(”{'/google.datastore.v1.Datastore/RunQueryÍ 7type.googleapis.com/google.datastore.v1.RunQueryRequest‘Bdulcet-port-762ý SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I:x v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Å  bLÄ 8type.googleapis.com/google.datastore.v1.RunQueryResponse‡ „x v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  "x v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  (0 8Àó´”Ïûã(¢L™™ 8type.googleapis.com/google.datastore.v1.RunQueryResponseÛ˜ ט— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  I TÓêÁê UÓêÁê Jw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ I TÓêÁê UÓêÁê Jw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  J I TÓêÁê UÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  I TÓêÁê UÓêÁê Jw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  J I TÓêÁê UÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ I TÓêÁê UÓêÁê Jw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  TÓêÁê UÓêÁê J Iw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  UÓêÁê J I  TÓêÁêw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  J I  TÓêÁê UÓêÁêw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ J I  TÓêÁê UÓêÁêw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  UÓêÁê J I  TÓêÁêw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  I  TÓêÁê UÓêÁê Jw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  I TÓêÁê UÓêÁê Jw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ TÓêÁê UÓêÁê J Iw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  TÓêÁê UÓêÁê J Iw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  I TÓêÁê UÓêÁê Jw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  J I TÓêÁê UÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ TÓêÁê UÓêÁê J Iw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  I TÓêÁê UÓêÁê Jw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  I TÓêÁê UÓêÁê Jw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  I TÓêÁê UÓêÁê Jw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  J I TÓêÁê UÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  I TÓêÁê UÓêÁê Jw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  TÓêÁê UÓêÁê J I w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  I! TÓêÁê UÓêÁê Jw u  I!fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  TÓêÁê UÓêÁê J I"w u  I"fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ UÓêÁê J I# TÓêÁêw u  I#fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  I$ TÓêÁê UÓêÁê Jw u  I$fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  UÓêÁê J I% TÓêÁêw u  I%fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  I& TÓêÁê UÓêÁê Jw u  I&fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ UÓêÁê J I' TÓêÁêw u  I'fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  UÓêÁê J I( TÓêÁêw u  I(fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  UÓêÁê J I) TÓêÁêw u  I)fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  I* TÓêÁê UÓêÁê Jw u  I*fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý TÓêÁê UÓêÁê J I+w u  I+fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  I, TÓêÁê UÓêÁê Jw u  I,fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  TÓêÁê UÓêÁê J I-w u  I-fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  I. TÓêÁê UÓêÁê Jw u  I.fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ TÓêÁê UÓêÁê J I/w u  I/fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  I0 TÓêÁê UÓêÁê Jw u  I0fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  UÓêÁê J I1 TÓêÁêw u  I1fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  I2 TÓêÁê UÓêÁê Jw u  I2fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ UÓêÁê J I3 TÓêÁêw u  I3fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  J I4 TÓêÁê UÓêÁêw u  I4fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  J I5 TÓêÁê UÓêÁêw u  I5fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  TÓêÁê UÓêÁê J I6w u  I6fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ I7 TÓêÁê UÓêÁê Jw u  I7fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  I8 TÓêÁê UÓêÁê Jw u  I8fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  J I9 TÓêÁê UÓêÁêw u  I9fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  TÓêÁê UÓêÁê J I:w u  I:fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã UÓêÁê J I; TÓêÁêw u  I;fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  TÓêÁê UÓêÁê J I<w u  I<fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  J I= TÓêÁê UÓêÁêw u  I=fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  UÓêÁê J I> TÓêÁêw u  I>fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ I? TÓêÁê UÓêÁê Jw u  I?fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  J I@ TÓêÁê UÓêÁêw u  I@fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  J IA TÓêÁê UÓêÁêw u  IAfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  TÓêÁê UÓêÁê J IBw u  IBfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ UÓêÁê J IC TÓêÁêw u  ICfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  J ID TÓêÁê UÓêÁêw u  IDfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  IE TÓêÁê UÓêÁê Jw u  IEfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  IF TÓêÁê UÓêÁê Jw u  IFfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ TÓêÁê UÓêÁê J IGw u  IGfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  UÓêÁê J IH TÓêÁêw u  IHfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  TÓêÁê UÓêÁê J IIw u  IIfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  IJ TÓêÁê UÓêÁê Jw u  IJfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó UÓêÁê J IK TÓêÁêw u  IKfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  IL TÓêÁê UÓêÁê Jw u  ILfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  J IM TÓêÁê UÓêÁêw u  IMfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  UÓêÁê J IN TÓêÁêw u  INfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ J IO TÓêÁê UÓêÁêw u  IOfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  TÓêÁê UÓêÁê J IPw u  IPfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  UÓêÁê J IQ TÓêÁêw u  IQfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  IR TÓêÁê UÓêÁê Jw u  IRfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË UÓêÁê J IS TÓêÁêw u  ISfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  J IT TÓêÁê UÓêÁêw u  ITfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  IU TÓêÁê UÓêÁê Jw u  IUfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  IV TÓêÁê UÓêÁê Jw u  IVfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« J IW TÓêÁê UÓêÁêw u  IWfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  TÓêÁê UÓêÁê J IXw u  IXfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  UÓêÁê J IY TÓêÁêw u  IYfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  UÓêÁê J IZ TÓêÁêw u  IZfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë UÓêÁê J I[ TÓêÁêw u  I[fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  I\ TÓêÁê UÓêÁê Jw u  I\fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  I] TÓêÁê UÓêÁê Jw u  I]fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  TÓêÁê UÓêÁê J I^w u  I^fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› I_ TÓêÁê UÓêÁê Jw u  I_fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  J I` TÓêÁê UÓêÁêw u  I`fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  TÓêÁê UÓêÁê J Iaw u  Iafjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  J Ib TÓêÁê UÓêÁêw u  Ibfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ UÓêÁê J Ic TÓêÁêw u  Icfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  TÓêÁê UÓêÁê J Idw u  Idfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  Ie TÓêÁê UÓêÁê Jw u  Iefjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  UÓêÁê J If TÓêÁêw u  Iffjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» TÓêÁê UÓêÁê J Igw u  Igfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  Ih TÓêÁê UÓêÁê Jw u  Ihfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  TÓêÁê UÓêÁê J Iiw u  Iifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  J Ij TÓêÁê UÓêÁêw u  Ijfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû Ik TÓêÁê UÓêÁê Jw u  Ikfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  UÓêÁê J Il TÓêÁêw u  Ilfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  Im TÓêÁê UÓêÁê Jw u  Imfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  TÓêÁê UÓêÁê J Inw u  Infjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ Io TÓêÁê UÓêÁê Jw u  Iofjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  TÓêÁê UÓêÁê J Ipw u  Ipfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  J Iq TÓêÁê UÓêÁêw u  Iqfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  TÓêÁê UÓêÁê J Irw u  Irfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ TÓêÁê UÓêÁê J Isw u  Isfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  TÓêÁê UÓêÁê J Itw u  Itfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  UÓêÁê J Iu TÓêÁêw u  Iufjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  TÓêÁê UÓêÁê J Ivw u  Ivfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ UÓêÁê J Iw TÓêÁêw u  Iwfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  Ix TÓêÁê UÓêÁê Jw u  Ixfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  TÓêÁê UÓêÁê J Iyw u  Iyfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  TÓêÁê UÓêÁê J Izw u  Izfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç J I{ TÓêÁê UÓêÁêw u  I{fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  J I| TÓêÁê UÓêÁêw u  I|fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  J I} TÓêÁê UÓêÁêw u  I}fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  TÓêÁê UÓêÁê J I~w u  I~fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— I TÓêÁê UÓêÁê Jw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  UÓêÁê J I€ TÓêÁêx v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  I‚ TÓêÁê UÓêÁê Jx v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× UÓêÁê J Iƒ TÓêÁêx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  J I„ TÓêÁê UÓêÁêx v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  J I… TÓêÁê UÓêÁêx v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  UÓêÁê J I† TÓêÁêx v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· I‡ TÓêÁê UÓêÁê Jx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  Iˆ TÓêÁê UÓêÁê Jx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  TÓêÁê UÓêÁê J I‰x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  UÓêÁê J IŠ TÓêÁêx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ I‹ TÓêÁê UÓêÁê Jx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  TÓêÁê UÓêÁê J IŒx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  UÓêÁê J IŽ TÓêÁêx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ J I TÓêÁê UÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  UÓêÁê J I‘ TÓêÁêx v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  TÓêÁê UÓêÁê J I’x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ I“ TÓêÁê UÓêÁê Jx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  UÓêÁê J I” TÓêÁêx v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  I• TÓêÁê UÓêÁê Jx v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  UÓêÁê J I– TÓêÁêx v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ TÓêÁê UÓêÁê J I—x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  UÓêÁê J I˜ TÓêÁêx v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  TÓêÁê UÓêÁê J I™x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  UÓêÁê J Iš TÓêÁêx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï I› TÓêÁê UÓêÁê Jx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  J Iœ TÓêÁê UÓêÁêx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  UÓêÁê J Iž TÓêÁêx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ UÓêÁê J IŸ TÓêÁêx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  UÓêÁê J I  TÓêÁêx v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  J I¡ TÓêÁê UÓêÁêx v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  J I¢ TÓêÁê UÓêÁêx v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß UÓêÁê J I£ TÓêÁêx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  UÓêÁê J I¤ TÓêÁêx v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  TÓêÁê UÓêÁê J I¥x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  UÓêÁê J I¦ TÓêÁêx v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ UÓêÁê J I§ TÓêÁêx v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  I¨ TÓêÁê UÓêÁê Jx v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  UÓêÁê J I© TÓêÁêx v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  J Iª TÓêÁê UÓêÁêx v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ I« TÓêÁê UÓêÁê Jx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  I¬ TÓêÁê UÓêÁê Jx v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  UÓêÁê J I­ TÓêÁêx v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  UÓêÁê J I® TÓêÁêx v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ UÓêÁê J I¯ TÓêÁêx v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  UÓêÁê J I° TÓêÁêx v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  UÓêÁê J I± TÓêÁêx v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  UÓêÁê J I² TÓêÁêx v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À UÓêÁê J I³ TÓêÁêx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  J I´ TÓêÁê UÓêÁêx v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  TÓêÁê UÓêÁê J Iµx v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  UÓêÁê J I¶ TÓêÁêx v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  J I· TÓêÁê UÓêÁêx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   I¸ TÓêÁê UÓêÁê Jx v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   I¹ TÓêÁê UÓêÁê Jx v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   UÓêÁê J Iº TÓêÁêx v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à J I» TÓêÁê UÓêÁêx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  TÓêÁê UÓêÁê J I¼x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  UÓêÁê J I½ TÓêÁêx v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  I¾ TÓêÁê UÓêÁê Jx v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– UÓêÁê J I¿ TÓêÁêx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  TÓêÁê UÓêÁê J IÀx v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  IÁ TÓêÁê UÓêÁê Jx v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  J I TÓêÁê UÓêÁêx v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð UÓêÁê J Ià TÓêÁêx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  J IÄ TÓêÁê UÓêÁêx v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  UÓêÁê J IÅ TÓêÁêx v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  UÓêÁê J IÆ TÓêÁêx v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° J IÇ TÓêÁê UÓêÁêx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  UÓêÁê J IÈ TÓêÁêx v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  IÉ TÓêÁê UÓêÁê Jx v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  TÓêÁê UÓêÁê J IÊx v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð TÓêÁê UÓêÁê J IËx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  TÓêÁê UÓêÁê J IÌx v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  IÍ TÓêÁê UÓêÁê Jx v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  UÓêÁê J IÎ TÓêÁêx v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ IÏ TÓêÁê UÓêÁê Jx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  UÓêÁê J IÐ TÓêÁêx v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  UÓêÁê J IÑ TÓêÁêx v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  UÓêÁê J IÒ TÓêÁêx v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È UÓêÁê J IÓ TÓêÁêx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  IÔ TÓêÁê UÓêÁê Jx v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  UÓêÁê J IÕ TÓêÁêx v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  UÓêÁê J IÖ TÓêÁêx v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ TÓêÁê UÓêÁê J I×x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  J IØ TÓêÁê UÓêÁêx v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  J IÙ TÓêÁê UÓêÁêx v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  J IÚ TÓêÁê UÓêÁêx v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è UÓêÁê J IÛ TÓêÁêx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  J IÜ TÓêÁê UÓêÁêx v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  J IÝ TÓêÁê UÓêÁêx v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  J IÞ TÓêÁê UÓêÁêx v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ UÓêÁê J Iß TÓêÁêx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  UÓêÁê J Ià TÓêÁêx v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  Iá TÓêÁê UÓêÁê Jx v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  Iâ TÓêÁê UÓêÁê Jx v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø J Iã TÓêÁê UÓêÁêx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  UÓêÁê J Iä TÓêÁêx v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  UÓêÁê J Iå TÓêÁêx v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  UÓêÁê J Iæ TÓêÁêx v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ UÓêÁê J Iç TÓêÁêx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  Iè TÓêÁê UÓêÁê Jx v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  Ié TÓêÁê UÓêÁê Jx v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  UÓêÁê J Iê TÓêÁêx v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø Ië TÓêÁê UÓêÁê Jx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  Iì TÓêÁê UÓêÁê Jx v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  TÓêÁê UÓêÁê J Iíx v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  J Iî TÓêÁê UÓêÁêx v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ J Iï TÓêÁê UÓêÁêx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  Ið TÓêÁê UÓêÁê Jx v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  TÓêÁê UÓêÁê J Iñx v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  TÓêÁê UÓêÁê J Iòx v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä TÓêÁê UÓêÁê J Ióx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  J Iô TÓêÁê UÓêÁêx v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  TÓêÁê UÓêÁê J Iõx v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  UÓêÁê J Iö TÓêÁêx v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ J I÷ TÓêÁê UÓêÁêx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  J Iø TÓêÁê UÓêÁêx v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  UÓêÁê J Iù TÓêÁêx v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  UÓêÁê J Iú TÓêÁêx v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä UÓêÁê J Iû TÓêÁêx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  Iü TÓêÁê UÓêÁê Jx v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  UÓêÁê J Iý TÓêÁêx v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  UÓêÁê J Iþ TÓêÁêx v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” TÓêÁê UÓêÁê J Iÿx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  UÓêÁê J I€ TÓêÁêx v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  J I‚ TÓêÁê UÓêÁêx v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô UÓêÁê J Iƒ TÓêÁêx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  TÓêÁê UÓêÁê J I„x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  TÓêÁê UÓêÁê J I…x v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  I† TÓêÁê UÓêÁê Jx v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ UÓêÁê J I‡ TÓêÁêx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  UÓêÁê J Iˆ TÓêÁêx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  UÓêÁê J I‰ TÓêÁêx v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  UÓêÁê J IŠ TÓêÁêx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô J I‹ TÓêÁê UÓêÁêx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  UÓêÁê J IŒ TÓêÁêx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  UÓêÁê J IŽ TÓêÁêx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  J I‘ TÓêÁê UÓêÁêx v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  I’ TÓêÁê UÓêÁê Jx v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì TÓêÁê UÓêÁê J I“x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  TÓêÁê UÓêÁê J I”x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  UÓêÁê J I• TÓêÁêx v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  UÓêÁê J I– TÓêÁêx v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ I— TÓêÁê UÓêÁê Jx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  TÓêÁê UÓêÁê J I˜x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  I™ TÓêÁê UÓêÁê Jx v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  Iš TÓêÁê UÓêÁê Jx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì I› TÓêÁê UÓêÁê Jx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  TÓêÁê UÓêÁê J Iœx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  J Iž TÓêÁê UÓêÁêx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ UÓêÁê J IŸ TÓêÁêx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  J I  TÓêÁê UÓêÁêx v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  I¡ TÓêÁê UÓêÁê Jx v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  UÓêÁê J I¢ TÓêÁêx v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü I£ TÓêÁê UÓêÁê Jx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  UÓêÁê J I¤ TÓêÁêx v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  UÓêÁê J I¥ TÓêÁêx v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  J I¦ TÓêÁê UÓêÁêx v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ J I§ TÓêÁê UÓêÁêx v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  UÓêÁê J I¨ TÓêÁêx v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  UÓêÁê J I© TÓêÁêx v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  Iª TÓêÁê UÓêÁê Jx v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü TÓêÁê UÓêÁê J I«x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  Ȇ’”Ïûã"x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  (8Àó´”Ïûã(˜|'/google.datastore.v1.Datastore/RunQueryÎ 7type.googleapis.com/google.datastore.v1.RunQueryRequest’Bdulcet-port-762þ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I:x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  bÉÏÇ 8type.googleapis.com/google.datastore.v1.RunQueryResponseŠ ‡"x v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  (8Àó´”Ïûã(œÏÇ 8type.googleapis.com/google.datastore.v1.RunQueryResponseŠ ‡"x v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  (8Àó´”Ïûã(©¢L™™ 8type.googleapis.com/google.datastore.v1.RunQueryResponseÛ˜ ט— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  J I TÓêÁê UÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  I TÓêÁê UÓêÁê Jw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  UÓêÁê J I  TÓêÁêw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  UÓêÁê J I  TÓêÁêw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ UÓêÁê J I  TÓêÁêw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  J I  TÓêÁê UÓêÁêw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  J I  TÓêÁê UÓêÁêw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  TÓêÁê UÓêÁê J Iw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  TÓêÁê UÓêÁê J Iw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  TÓêÁê UÓêÁê J Iw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  I TÓêÁê UÓêÁê Jw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ TÓêÁê UÓêÁê J Iw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  TÓêÁê UÓêÁê J Iw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  J I TÓêÁê UÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí I TÓêÁê UÓêÁê Jw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  TÓêÁê UÓêÁê J Iw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  TÓêÁê UÓêÁê J Iw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  TÓêÁê UÓêÁê J Iw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  UÓêÁê J I  TÓêÁêw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  J I! TÓêÁê UÓêÁêw u  I!fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  J I" TÓêÁê UÓêÁêw u  I"fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ UÓêÁê J I# TÓêÁêw u  I#fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  J I$ TÓêÁê UÓêÁêw u  I$fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  UÓêÁê J I% TÓêÁêw u  I%fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  J I& TÓêÁê UÓêÁêw u  I&fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ TÓêÁê UÓêÁê J I'w u  I'fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  TÓêÁê UÓêÁê J I(w u  I(fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  UÓêÁê J I) TÓêÁêw u  I)fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  UÓêÁê J I* TÓêÁêw u  I*fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý UÓêÁê J I+ TÓêÁêw u  I+fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  UÓêÁê J I, TÓêÁêw u  I,fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  J I- TÓêÁê UÓêÁêw u  I-fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  UÓêÁê J I. TÓêÁêw u  I.fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ UÓêÁê J I/ TÓêÁêw u  I/fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  UÓêÁê J I0 TÓêÁêw u  I0fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  I1 TÓêÁê UÓêÁê Jw u  I1fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  I2 TÓêÁê UÓêÁê Jw u  I2fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ J I3 TÓêÁê UÓêÁêw u  I3fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  UÓêÁê J I4 TÓêÁêw u  I4fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  UÓêÁê J I5 TÓêÁêw u  I5fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  TÓêÁê UÓêÁê J I6w u  I6fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ TÓêÁê UÓêÁê J I7w u  I7fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  J I8 TÓêÁê UÓêÁêw u  I8fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  UÓêÁê J I9 TÓêÁêw u  I9fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  TÓêÁê UÓêÁê J I:w u  I:fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã UÓêÁê J I; TÓêÁêw u  I;fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  J I< TÓêÁê UÓêÁêw u  I<fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  J I= TÓêÁê UÓêÁêw u  I=fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  UÓêÁê J I> TÓêÁêw u  I>fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ I? TÓêÁê UÓêÁê Jw u  I?fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  I@ TÓêÁê UÓêÁê Jw u  I@fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  UÓêÁê J IA TÓêÁêw u  IAfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  TÓêÁê UÓêÁê J IBw u  IBfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ UÓêÁê J IC TÓêÁêw u  ICfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  UÓêÁê J ID TÓêÁêw u  IDfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  IE TÓêÁê UÓêÁê Jw u  IEfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  IF TÓêÁê UÓêÁê Jw u  IFfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ TÓêÁê UÓêÁê J IGw u  IGfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  IH TÓêÁê UÓêÁê Jw u  IHfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  II TÓêÁê UÓêÁê Jw u  IIfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  TÓêÁê UÓêÁê J IJw u  IJfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó IK TÓêÁê UÓêÁê Jw u  IKfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  TÓêÁê UÓêÁê J ILw u  ILfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  J IM TÓêÁê UÓêÁêw u  IMfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  UÓêÁê J IN TÓêÁêw u  INfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ J IO TÓêÁê UÓêÁêw u  IOfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  TÓêÁê UÓêÁê J IPw u  IPfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  UÓêÁê J IQ TÓêÁêw u  IQfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  UÓêÁê J IR TÓêÁêw u  IRfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË TÓêÁê UÓêÁê J ISw u  ISfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  J IT TÓêÁê UÓêÁêw u  ITfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  UÓêÁê J IU TÓêÁêw u  IUfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  UÓêÁê J IV TÓêÁêw u  IVfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« IW TÓêÁê UÓêÁê Jw u  IWfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  UÓêÁê J IX TÓêÁêw u  IXfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  IY TÓêÁê UÓêÁê Jw u  IYfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  UÓêÁê J IZ TÓêÁêw u  IZfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë I[ TÓêÁê UÓêÁê Jw u  I[fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  I\ TÓêÁê UÓêÁê Jw u  I\fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  UÓêÁê J I] TÓêÁêw u  I]fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  I^ TÓêÁê UÓêÁê Jw u  I^fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› UÓêÁê J I_ TÓêÁêw u  I_fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  UÓêÁê J I` TÓêÁêw u  I`fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  UÓêÁê J Ia TÓêÁêw u  Iafjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  UÓêÁê J Ib TÓêÁêw u  Ibfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ UÓêÁê J Ic TÓêÁêw u  Icfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  J Id TÓêÁê UÓêÁêw u  Idfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  UÓêÁê J Ie TÓêÁêw u  Iefjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  If TÓêÁê UÓêÁê Jw u  Iffjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» TÓêÁê UÓêÁê J Igw u  Igfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  TÓêÁê UÓêÁê J Ihw u  Ihfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  UÓêÁê J Ii TÓêÁêw u  Iifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  UÓêÁê J Ij TÓêÁêw u  Ijfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû Ik TÓêÁê UÓêÁê Jw u  Ikfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  Il TÓêÁê UÓêÁê Jw u  Ilfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  TÓêÁê UÓêÁê J Imw u  Imfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  J In TÓêÁê UÓêÁêw u  Infjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ TÓêÁê UÓêÁê J Iow u  Iofjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  TÓêÁê UÓêÁê J Ipw u  Ipfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  UÓêÁê J Iq TÓêÁêw u  Iqfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  J Ir TÓêÁê UÓêÁêw u  Irfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ UÓêÁê J Is TÓêÁêw u  Isfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  TÓêÁê UÓêÁê J Itw u  Itfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  TÓêÁê UÓêÁê J Iuw u  Iufjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  TÓêÁê UÓêÁê J Ivw u  Ivfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ UÓêÁê J Iw TÓêÁêw u  Iwfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  TÓêÁê UÓêÁê J Ixw u  Ixfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  TÓêÁê UÓêÁê J Iyw u  Iyfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  UÓêÁê J Iz TÓêÁêw u  Izfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç UÓêÁê J I{ TÓêÁêw u  I{fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  TÓêÁê UÓêÁê J I|w u  I|fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  I} TÓêÁê UÓêÁê Jw u  I}fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  I~ TÓêÁê UÓêÁê Jw u  I~fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  TÓêÁê UÓêÁê J I€x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  TÓêÁê UÓêÁê J I‚x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× Iƒ TÓêÁê UÓêÁê Jx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  TÓêÁê UÓêÁê J I„x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  J I… TÓêÁê UÓêÁêx v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  I† TÓêÁê UÓêÁê Jx v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· I‡ TÓêÁê UÓêÁê Jx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  TÓêÁê UÓêÁê J Iˆx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  UÓêÁê J I‰ TÓêÁêx v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  TÓêÁê UÓêÁê J IŠx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ UÓêÁê J I‹ TÓêÁêx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  UÓêÁê J IŒ TÓêÁêx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  UÓêÁê J IŽ TÓêÁêx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  I‘ TÓêÁê UÓêÁê Jx v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  J I’ TÓêÁê UÓêÁêx v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ UÓêÁê J I“ TÓêÁêx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  I” TÓêÁê UÓêÁê Jx v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  UÓêÁê J I• TÓêÁêx v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  I– TÓêÁê UÓêÁê Jx v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ UÓêÁê J I— TÓêÁêx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  TÓêÁê UÓêÁê J I˜x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  I™ TÓêÁê UÓêÁê Jx v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  UÓêÁê J Iš TÓêÁêx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï UÓêÁê J I› TÓêÁêx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  Iœ TÓêÁê UÓêÁê Jx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  UÓêÁê J Iž TÓêÁêx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ TÓêÁê UÓêÁê J IŸx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  UÓêÁê J I  TÓêÁêx v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  J I¡ TÓêÁê UÓêÁêx v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  UÓêÁê J I¢ TÓêÁêx v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß I£ TÓêÁê UÓêÁê Jx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  TÓêÁê UÓêÁê J I¤x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  UÓêÁê J I¥ TÓêÁêx v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  UÓêÁê J I¦ TÓêÁêx v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ I§ TÓêÁê UÓêÁê Jx v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  UÓêÁê J I¨ TÓêÁêx v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  J I© TÓêÁê UÓêÁêx v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  TÓêÁê UÓêÁê J Iªx v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ TÓêÁê UÓêÁê J I«x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  UÓêÁê J I¬ TÓêÁêx v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  UÓêÁê J I­ TÓêÁêx v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  UÓêÁê J I® TÓêÁêx v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ UÓêÁê J I¯ TÓêÁêx v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  UÓêÁê J I° TÓêÁêx v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  UÓêÁê J I± TÓêÁêx v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  TÓêÁê UÓêÁê J I²x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À J I³ TÓêÁê UÓêÁêx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  I´ TÓêÁê UÓêÁê Jx v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  Iµ TÓêÁê UÓêÁê Jx v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  UÓêÁê J I¶ TÓêÁêx v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  J I· TÓêÁê UÓêÁêx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   TÓêÁê UÓêÁê J I¸x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   I¹ TÓêÁê UÓêÁê Jx v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   UÓêÁê J Iº TÓêÁêx v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à J I» TÓêÁê UÓêÁêx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  I¼ TÓêÁê UÓêÁê Jx v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  I½ TÓêÁê UÓêÁê Jx v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  J I¾ TÓêÁê UÓêÁêx v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– TÓêÁê UÓêÁê J I¿x v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  UÓêÁê J IÀ TÓêÁêx v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  J IÁ TÓêÁê UÓêÁêx v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  I TÓêÁê UÓêÁê Jx v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð UÓêÁê J Ià TÓêÁêx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  UÓêÁê J IÄ TÓêÁêx v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  UÓêÁê J IÅ TÓêÁêx v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  UÓêÁê J IÆ TÓêÁêx v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° UÓêÁê J IÇ TÓêÁêx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  UÓêÁê J IÈ TÓêÁêx v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  UÓêÁê J IÉ TÓêÁêx v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  J IÊ TÓêÁê UÓêÁêx v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð IË TÓêÁê UÓêÁê Jx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  UÓêÁê J IÌ TÓêÁêx v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  UÓêÁê J IÍ TÓêÁêx v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  UÓêÁê J IÎ TÓêÁêx v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ J IÏ TÓêÁê UÓêÁêx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  TÓêÁê UÓêÁê J IÐx v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  IÑ TÓêÁê UÓêÁê Jx v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  J IÒ TÓêÁê UÓêÁêx v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È UÓêÁê J IÓ TÓêÁêx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  IÔ TÓêÁê UÓêÁê Jx v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  J IÕ TÓêÁê UÓêÁêx v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  UÓêÁê J IÖ TÓêÁêx v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ TÓêÁê UÓêÁê J I×x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  J IØ TÓêÁê UÓêÁêx v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  UÓêÁê J IÙ TÓêÁêx v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  TÓêÁê UÓêÁê J IÚx v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è UÓêÁê J IÛ TÓêÁêx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  UÓêÁê J IÜ TÓêÁêx v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  UÓêÁê J IÝ TÓêÁêx v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  IÞ TÓêÁê UÓêÁê Jx v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ UÓêÁê J Iß TÓêÁêx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  Ià TÓêÁê UÓêÁê Jx v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  UÓêÁê J Iá TÓêÁêx v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  UÓêÁê J Iâ TÓêÁêx v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø UÓêÁê J Iã TÓêÁêx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  UÓêÁê J Iä TÓêÁêx v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  UÓêÁê J Iå TÓêÁêx v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  UÓêÁê J Iæ TÓêÁêx v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ UÓêÁê J Iç TÓêÁêx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  UÓêÁê J Iè TÓêÁêx v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  Ié TÓêÁê UÓêÁê Jx v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  UÓêÁê J Iê TÓêÁêx v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø UÓêÁê J Ië TÓêÁêx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  TÓêÁê UÓêÁê J Iìx v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  TÓêÁê UÓêÁê J Iíx v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  Iî TÓêÁê UÓêÁê Jx v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ J Iï TÓêÁê UÓêÁêx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  TÓêÁê UÓêÁê J Iðx v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  TÓêÁê UÓêÁê J Iñx v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  UÓêÁê J Iò TÓêÁêx v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä TÓêÁê UÓêÁê J Ióx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  Iô TÓêÁê UÓêÁê Jx v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  Iõ TÓêÁê UÓêÁê Jx v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  TÓêÁê UÓêÁê J Iöx v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ UÓêÁê J I÷ TÓêÁêx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  UÓêÁê J Iø TÓêÁêx v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  J Iù TÓêÁê UÓêÁêx v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  Iú TÓêÁê UÓêÁê Jx v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä J Iû TÓêÁê UÓêÁêx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  J Iü TÓêÁê UÓêÁêx v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  UÓêÁê J Iý TÓêÁêx v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  TÓêÁê UÓêÁê J Iþx v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” Iÿ TÓêÁê UÓêÁê Jx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  J I€ TÓêÁê UÓêÁêx v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  J I TÓêÁê UÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  TÓêÁê UÓêÁê J I‚x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô UÓêÁê J Iƒ TÓêÁêx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  UÓêÁê J I„ TÓêÁêx v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  I… TÓêÁê UÓêÁê Jx v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  UÓêÁê J I† TÓêÁêx v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ UÓêÁê J I‡ TÓêÁêx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  J Iˆ TÓêÁê UÓêÁêx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  UÓêÁê J I‰ TÓêÁêx v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  IŠ TÓêÁê UÓêÁê Jx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô J I‹ TÓêÁê UÓêÁêx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  IŒ TÓêÁê UÓêÁê Jx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  UÓêÁê J IŽ TÓêÁêx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  J I TÓêÁê UÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  UÓêÁê J I‘ TÓêÁêx v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  UÓêÁê J I’ TÓêÁêx v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì UÓêÁê J I“ TÓêÁêx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  I” TÓêÁê UÓêÁê Jx v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  J I• TÓêÁê UÓêÁêx v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  I– TÓêÁê UÓêÁê Jx v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ UÓêÁê J I— TÓêÁêx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  UÓêÁê J I˜ TÓêÁêx v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  I™ TÓêÁê UÓêÁê Jx v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  UÓêÁê J Iš TÓêÁêx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì UÓêÁê J I› TÓêÁêx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  J Iœ TÓêÁê UÓêÁêx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  TÓêÁê UÓêÁê J Ižx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ UÓêÁê J IŸ TÓêÁêx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  UÓêÁê J I  TÓêÁêx v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  UÓêÁê J I¡ TÓêÁêx v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  TÓêÁê UÓêÁê J I¢x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü J I£ TÓêÁê UÓêÁêx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  UÓêÁê J I¤ TÓêÁêx v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  UÓêÁê J I¥ TÓêÁêx v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  I¦ TÓêÁê UÓêÁê Jx v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ TÓêÁê UÓêÁê J I§x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  UÓêÁê J I¨ TÓêÁêx v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  UÓêÁê J I© TÓêÁêx v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  Iª TÓêÁê UÓêÁê Jx v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü J I« TÓêÁê UÓêÁêx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  Ȇ’”Ïûã"x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  (8Àó´”Ïûã(¢w'/google.datastore.v1.Datastore/RunQueryÉ 7type.googleapis.com/google.datastore.v1.RunQueryRequestBdulcet-port-762ù SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I:x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  ¢L™™ 8type.googleapis.com/google.datastore.v1.RunQueryResponseÛ˜ ט— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  J I TÓêÁê UÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  TÓêÁê UÓêÁê J Iw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  TÓêÁê UÓêÁê J Iw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ I TÓêÁê UÓêÁê Jw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  TÓêÁê UÓêÁê J Iw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  I TÓêÁê UÓêÁê Jw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ J I TÓêÁê UÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  J I TÓêÁê UÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  TÓêÁê UÓêÁê J I w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  I  TÓêÁê UÓêÁê Jw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ I  TÓêÁê UÓêÁê Jw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  TÓêÁê UÓêÁê J I w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  UÓêÁê J I  TÓêÁêw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  I TÓêÁê UÓêÁê Jw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  I TÓêÁê UÓêÁê Jw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  TÓêÁê UÓêÁê J Iw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  TÓêÁê UÓêÁê J Iw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  TÓêÁê UÓêÁê J Iw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  TÓêÁê UÓêÁê J Iw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ J I TÓêÁê UÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  J I  TÓêÁê UÓêÁêw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  J I! TÓêÁê UÓêÁêw u  I!fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  J I" TÓêÁê UÓêÁêw u  I"fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ I# TÓêÁê UÓêÁê Jw u  I#fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  I$ TÓêÁê UÓêÁê Jw u  I$fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  TÓêÁê UÓêÁê J I%w u  I%fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  I& TÓêÁê UÓêÁê Jw u  I&fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ TÓêÁê UÓêÁê J I'w u  I'fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  UÓêÁê J I( TÓêÁêw u  I(fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  I) TÓêÁê UÓêÁê Jw u  I)fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  UÓêÁê J I* TÓêÁêw u  I*fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý UÓêÁê J I+ TÓêÁêw u  I+fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  I, TÓêÁê UÓêÁê Jw u  I,fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  UÓêÁê J I- TÓêÁêw u  I-fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  UÓêÁê J I. TÓêÁêw u  I.fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ TÓêÁê UÓêÁê J I/w u  I/fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  J I0 TÓêÁê UÓêÁêw u  I0fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  UÓêÁê J I1 TÓêÁêw u  I1fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  TÓêÁê UÓêÁê J I2w u  I2fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ I3 TÓêÁê UÓêÁê Jw u  I3fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  TÓêÁê UÓêÁê J I4w u  I4fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  J I5 TÓêÁê UÓêÁêw u  I5fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  UÓêÁê J I6 TÓêÁêw u  I6fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ UÓêÁê J I7 TÓêÁêw u  I7fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  J I8 TÓêÁê UÓêÁêw u  I8fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  J I9 TÓêÁê UÓêÁêw u  I9fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  J I: TÓêÁê UÓêÁêw u  I:fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã J I; TÓêÁê UÓêÁêw u  I;fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  I< TÓêÁê UÓêÁê Jw u  I<fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  TÓêÁê UÓêÁê J I=w u  I=fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  UÓêÁê J I> TÓêÁêw u  I>fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ I? TÓêÁê UÓêÁê Jw u  I?fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  I@ TÓêÁê UÓêÁê Jw u  I@fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  IA TÓêÁê UÓêÁê Jw u  IAfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  J IB TÓêÁê UÓêÁêw u  IBfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ UÓêÁê J IC TÓêÁêw u  ICfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  UÓêÁê J ID TÓêÁêw u  IDfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  J IE TÓêÁê UÓêÁêw u  IEfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  TÓêÁê UÓêÁê J IFw u  IFfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ IG TÓêÁê UÓêÁê Jw u  IGfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  UÓêÁê J IH TÓêÁêw u  IHfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  J II TÓêÁê UÓêÁêw u  IIfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  UÓêÁê J IJ TÓêÁêw u  IJfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó UÓêÁê J IK TÓêÁêw u  IKfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  IL TÓêÁê UÓêÁê Jw u  ILfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  TÓêÁê UÓêÁê J IMw u  IMfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  J IN TÓêÁê UÓêÁêw u  INfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ TÓêÁê UÓêÁê J IOw u  IOfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  UÓêÁê J IP TÓêÁêw u  IPfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  IQ TÓêÁê UÓêÁê Jw u  IQfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  IR TÓêÁê UÓêÁê Jw u  IRfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË IS TÓêÁê UÓêÁê Jw u  ISfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  UÓêÁê J IT TÓêÁêw u  ITfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  TÓêÁê UÓêÁê J IUw u  IUfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  UÓêÁê J IV TÓêÁêw u  IVfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« IW TÓêÁê UÓêÁê Jw u  IWfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  UÓêÁê J IX TÓêÁêw u  IXfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  IY TÓêÁê UÓêÁê Jw u  IYfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  UÓêÁê J IZ TÓêÁêw u  IZfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë I[ TÓêÁê UÓêÁê Jw u  I[fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  J I\ TÓêÁê UÓêÁêw u  I\fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  TÓêÁê UÓêÁê J I]w u  I]fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  UÓêÁê J I^ TÓêÁêw u  I^fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› J I_ TÓêÁê UÓêÁêw u  I_fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  TÓêÁê UÓêÁê J I`w u  I`fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  UÓêÁê J Ia TÓêÁêw u  Iafjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  TÓêÁê UÓêÁê J Ibw u  Ibfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ Ic TÓêÁê UÓêÁê Jw u  Icfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  J Id TÓêÁê UÓêÁêw u  Idfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  J Ie TÓêÁê UÓêÁêw u  Iefjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  UÓêÁê J If TÓêÁêw u  Iffjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» TÓêÁê UÓêÁê J Igw u  Igfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  TÓêÁê UÓêÁê J Ihw u  Ihfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  UÓêÁê J Ii TÓêÁêw u  Iifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  UÓêÁê J Ij TÓêÁêw u  Ijfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû Ik TÓêÁê UÓêÁê Jw u  Ikfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  UÓêÁê J Il TÓêÁêw u  Ilfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  TÓêÁê UÓêÁê J Imw u  Imfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  TÓêÁê UÓêÁê J Inw u  Infjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ UÓêÁê J Io TÓêÁêw u  Iofjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  J Ip TÓêÁê UÓêÁêw u  Ipfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  TÓêÁê UÓêÁê J Iqw u  Iqfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  Ir TÓêÁê UÓêÁê Jw u  Irfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ Is TÓêÁê UÓêÁê Jw u  Isfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  It TÓêÁê UÓêÁê Jw u  Itfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  UÓêÁê J Iu TÓêÁêw u  Iufjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  UÓêÁê J Iv TÓêÁêw u  Ivfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ J Iw TÓêÁê UÓêÁêw u  Iwfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  UÓêÁê J Ix TÓêÁêw u  Ixfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  TÓêÁê UÓêÁê J Iyw u  Iyfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  J Iz TÓêÁê UÓêÁêw u  Izfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç UÓêÁê J I{ TÓêÁêw u  I{fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  I| TÓêÁê UÓêÁê Jw u  I|fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  TÓêÁê UÓêÁê J I}w u  I}fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  J I~ TÓêÁê UÓêÁêw u  I~fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  TÓêÁê UÓêÁê J I€x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  J I‚ TÓêÁê UÓêÁêx v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× UÓêÁê J Iƒ TÓêÁêx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  I„ TÓêÁê UÓêÁê Jx v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  UÓêÁê J I… TÓêÁêx v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  UÓêÁê J I† TÓêÁêx v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· J I‡ TÓêÁê UÓêÁêx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  UÓêÁê J Iˆ TÓêÁêx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  UÓêÁê J I‰ TÓêÁêx v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  UÓêÁê J IŠ TÓêÁêx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ UÓêÁê J I‹ TÓêÁêx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  TÓêÁê UÓêÁê J IŒx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  TÓêÁê UÓêÁê J IŽx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  UÓêÁê J I‘ TÓêÁêx v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  I’ TÓêÁê UÓêÁê Jx v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ J I“ TÓêÁê UÓêÁêx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  I” TÓêÁê UÓêÁê Jx v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  I• TÓêÁê UÓêÁê Jx v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  J I– TÓêÁê UÓêÁêx v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ UÓêÁê J I— TÓêÁêx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  UÓêÁê J I˜ TÓêÁêx v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  I™ TÓêÁê UÓêÁê Jx v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  UÓêÁê J Iš TÓêÁêx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï TÓêÁê UÓêÁê J I›x v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  UÓêÁê J Iœ TÓêÁêx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  J Iž TÓêÁê UÓêÁêx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ J IŸ TÓêÁê UÓêÁêx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  J I  TÓêÁê UÓêÁêx v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  UÓêÁê J I¡ TÓêÁêx v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  J I¢ TÓêÁê UÓêÁêx v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß TÓêÁê UÓêÁê J I£x v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  J I¤ TÓêÁê UÓêÁêx v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  TÓêÁê UÓêÁê J I¥x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  UÓêÁê J I¦ TÓêÁêx v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ UÓêÁê J I§ TÓêÁêx v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  TÓêÁê UÓêÁê J I¨x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  I© TÓêÁê UÓêÁê Jx v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  TÓêÁê UÓêÁê J Iªx v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ I« TÓêÁê UÓêÁê Jx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  TÓêÁê UÓêÁê J I¬x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  I­ TÓêÁê UÓêÁê Jx v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  UÓêÁê J I® TÓêÁêx v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ I¯ TÓêÁê UÓêÁê Jx v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  J I° TÓêÁê UÓêÁêx v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  TÓêÁê UÓêÁê J I±x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  I² TÓêÁê UÓêÁê Jx v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À UÓêÁê J I³ TÓêÁêx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  TÓêÁê UÓêÁê J I´x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  J Iµ TÓêÁê UÓêÁêx v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  TÓêÁê UÓêÁê J I¶x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  I· TÓêÁê UÓêÁê Jx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   I¸ TÓêÁê UÓêÁê Jx v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   TÓêÁê UÓêÁê J I¹x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   UÓêÁê J Iº TÓêÁêx v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à UÓêÁê J I» TÓêÁêx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  UÓêÁê J I¼ TÓêÁêx v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  UÓêÁê J I½ TÓêÁêx v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  UÓêÁê J I¾ TÓêÁêx v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– J I¿ TÓêÁê UÓêÁêx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  TÓêÁê UÓêÁê J IÀx v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  TÓêÁê UÓêÁê J IÁx v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  UÓêÁê J I TÓêÁêx v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð UÓêÁê J Ià TÓêÁêx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  UÓêÁê J IÄ TÓêÁêx v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  UÓêÁê J IÅ TÓêÁêx v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  UÓêÁê J IÆ TÓêÁêx v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° IÇ TÓêÁê UÓêÁê Jx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  IÈ TÓêÁê UÓêÁê Jx v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  UÓêÁê J IÉ TÓêÁêx v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  UÓêÁê J IÊ TÓêÁêx v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð TÓêÁê UÓêÁê J IËx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  IÌ TÓêÁê UÓêÁê Jx v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  UÓêÁê J IÍ TÓêÁêx v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  UÓêÁê J IÎ TÓêÁêx v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ IÏ TÓêÁê UÓêÁê Jx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  TÓêÁê UÓêÁê J IÐx v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  J IÑ TÓêÁê UÓêÁêx v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  TÓêÁê UÓêÁê J IÒx v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È IÓ TÓêÁê UÓêÁê Jx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  UÓêÁê J IÔ TÓêÁêx v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  TÓêÁê UÓêÁê J IÕx v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  IÖ TÓêÁê UÓêÁê Jx v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ I× TÓêÁê UÓêÁê Jx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  UÓêÁê J IØ TÓêÁêx v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  TÓêÁê UÓêÁê J IÙx v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  J IÚ TÓêÁê UÓêÁêx v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è IÛ TÓêÁê UÓêÁê Jx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  J IÜ TÓêÁê UÓêÁêx v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  J IÝ TÓêÁê UÓêÁêx v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  UÓêÁê J IÞ TÓêÁêx v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ UÓêÁê J Iß TÓêÁêx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  UÓêÁê J Ià TÓêÁêx v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  UÓêÁê J Iá TÓêÁêx v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  UÓêÁê J Iâ TÓêÁêx v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø J Iã TÓêÁê UÓêÁêx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  Iä TÓêÁê UÓêÁê Jx v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  Iå TÓêÁê UÓêÁê Jx v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  Iæ TÓêÁê UÓêÁê Jx v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ UÓêÁê J Iç TÓêÁêx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  J Iè TÓêÁê UÓêÁêx v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  TÓêÁê UÓêÁê J Iéx v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  UÓêÁê J Iê TÓêÁêx v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø UÓêÁê J Ië TÓêÁêx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  Iì TÓêÁê UÓêÁê Jx v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  UÓêÁê J Ií TÓêÁêx v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  Iî TÓêÁê UÓêÁê Jx v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ UÓêÁê J Iï TÓêÁêx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  TÓêÁê UÓêÁê J Iðx v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  Iñ TÓêÁê UÓêÁê Jx v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  UÓêÁê J Iò TÓêÁêx v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä J Ió TÓêÁê UÓêÁêx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  Iô TÓêÁê UÓêÁê Jx v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  UÓêÁê J Iõ TÓêÁêx v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  Iö TÓêÁê UÓêÁê Jx v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ UÓêÁê J I÷ TÓêÁêx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  Iø TÓêÁê UÓêÁê Jx v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  UÓêÁê J Iù TÓêÁêx v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  UÓêÁê J Iú TÓêÁêx v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä J Iû TÓêÁê UÓêÁêx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  J Iü TÓêÁê UÓêÁêx v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  J Iý TÓêÁê UÓêÁêx v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  UÓêÁê J Iþ TÓêÁêx v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” UÓêÁê J Iÿ TÓêÁêx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  UÓêÁê J I€ TÓêÁêx v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  UÓêÁê J I‚ TÓêÁêx v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô UÓêÁê J Iƒ TÓêÁêx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  TÓêÁê UÓêÁê J I„x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  UÓêÁê J I… TÓêÁêx v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  UÓêÁê J I† TÓêÁêx v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ J I‡ TÓêÁê UÓêÁêx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  J Iˆ TÓêÁê UÓêÁêx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  UÓêÁê J I‰ TÓêÁêx v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  J IŠ TÓêÁê UÓêÁêx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô TÓêÁê UÓêÁê J I‹x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  TÓêÁê UÓêÁê J IŒx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  IŽ TÓêÁê UÓêÁê Jx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ J I TÓêÁê UÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  TÓêÁê UÓêÁê J I‘x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  J I’ TÓêÁê UÓêÁêx v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì UÓêÁê J I“ TÓêÁêx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  I” TÓêÁê UÓêÁê Jx v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  UÓêÁê J I• TÓêÁêx v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  UÓêÁê J I– TÓêÁêx v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ UÓêÁê J I— TÓêÁêx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  J I˜ TÓêÁê UÓêÁêx v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  TÓêÁê UÓêÁê J I™x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  TÓêÁê UÓêÁê J Išx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì UÓêÁê J I› TÓêÁêx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  UÓêÁê J Iœ TÓêÁêx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  J Iž TÓêÁê UÓêÁêx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ IŸ TÓêÁê UÓêÁê Jx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  I  TÓêÁê UÓêÁê Jx v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  J I¡ TÓêÁê UÓêÁêx v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  UÓêÁê J I¢ TÓêÁêx v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü UÓêÁê J I£ TÓêÁêx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  TÓêÁê UÓêÁê J I¤x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  UÓêÁê J I¥ TÓêÁêx v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  I¦ TÓêÁê UÓêÁê Jx v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ I§ TÓêÁê UÓêÁê Jx v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  TÓêÁê UÓêÁê J I¨x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  J I© TÓêÁê UÓêÁêx v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  Iª TÓêÁê UÓêÁê Jx v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü UÓêÁê J I« TÓêÁêx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  Ȇ’”Ïûã"x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  (8Àó´”Ïûã(¦|'/google.datastore.v1.Datastore/RunQueryÎ 7type.googleapis.com/google.datastore.v1.RunQueryRequest’Bdulcet-port-762þ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I:x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  bôåMÜ› 8type.googleapis.com/google.datastore.v1.RunQueryResponsež› š›— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  UÓêÁê J Id TÓêÁêw u  Idfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  UÓêÁê J Ie TÓêÁêw u  Iefjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  If TÓêÁê UÓêÁê Jw u  Iffjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» TÓêÁê UÓêÁê J Igw u  Igfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  J Ih TÓêÁê UÓêÁêw u  Ihfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  J Ii TÓêÁê UÓêÁêw u  Iifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  UÓêÁê J Ij TÓêÁêw u  Ijfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû UÓêÁê J Ik TÓêÁêw u  Ikfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  UÓêÁê J Il TÓêÁêw u  Ilfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  UÓêÁê J Im TÓêÁêw u  Imfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  UÓêÁê J In TÓêÁêw u  Infjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ UÓêÁê J Io TÓêÁêw u  Iofjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  UÓêÁê J Ip TÓêÁêw u  Ipfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  J Iq TÓêÁê UÓêÁêw u  Iqfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  UÓêÁê J Ir TÓêÁêw u  Irfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ UÓêÁê J Is TÓêÁêw u  Isfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  J It TÓêÁê UÓêÁêw u  Itfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  Iu TÓêÁê UÓêÁê Jw u  Iufjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  UÓêÁê J Iv TÓêÁêw u  Ivfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ UÓêÁê J Iw TÓêÁêw u  Iwfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  UÓêÁê J Ix TÓêÁêw u  Ixfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  Iy TÓêÁê UÓêÁê Jw u  Iyfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  J Iz TÓêÁê UÓêÁêw u  Izfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç UÓêÁê J I{ TÓêÁêw u  I{fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  TÓêÁê UÓêÁê J I|w u  I|fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  I} TÓêÁê UÓêÁê Jw u  I}fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  TÓêÁê UÓêÁê J I~w u  I~fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  UÓêÁê J I€ TÓêÁêx v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  TÓêÁê UÓêÁê J I‚x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× J Iƒ TÓêÁê UÓêÁêx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  TÓêÁê UÓêÁê J I„x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  J I… TÓêÁê UÓêÁêx v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  I† TÓêÁê UÓêÁê Jx v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· UÓêÁê J I‡ TÓêÁêx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  UÓêÁê J Iˆ TÓêÁêx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  J I‰ TÓêÁê UÓêÁêx v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  J IŠ TÓêÁê UÓêÁêx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ UÓêÁê J I‹ TÓêÁêx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  UÓêÁê J IŒ TÓêÁêx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  UÓêÁê J IŽ TÓêÁêx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  I‘ TÓêÁê UÓêÁê Jx v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  TÓêÁê UÓêÁê J I’x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ UÓêÁê J I“ TÓêÁêx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  TÓêÁê UÓêÁê J I”x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  UÓêÁê J I• TÓêÁêx v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  UÓêÁê J I– TÓêÁêx v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ J I— TÓêÁê UÓêÁêx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  J I˜ TÓêÁê UÓêÁêx v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  I™ TÓêÁê UÓêÁê Jx v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  TÓêÁê UÓêÁê J Išx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï UÓêÁê J I› TÓêÁêx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  UÓêÁê J Iœ TÓêÁêx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  UÓêÁê J Iž TÓêÁêx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ IŸ TÓêÁê UÓêÁê Jx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  UÓêÁê J I  TÓêÁêx v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  UÓêÁê J I¡ TÓêÁêx v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  J I¢ TÓêÁê UÓêÁêx v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß I£ TÓêÁê UÓêÁê Jx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  J I¤ TÓêÁê UÓêÁêx v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  I¥ TÓêÁê UÓêÁê Jx v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  I¦ TÓêÁê UÓêÁê Jx v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ I§ TÓêÁê UÓêÁê Jx v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  J I¨ TÓêÁê UÓêÁêx v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  J I© TÓêÁê UÓêÁêx v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  Iª TÓêÁê UÓêÁê Jx v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ J I« TÓêÁê UÓêÁêx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  UÓêÁê J I¬ TÓêÁêx v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  I­ TÓêÁê UÓêÁê Jx v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  TÓêÁê UÓêÁê J I®x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ TÓêÁê UÓêÁê J I¯x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  I° TÓêÁê UÓêÁê Jx v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  I± TÓêÁê UÓêÁê Jx v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  I² TÓêÁê UÓêÁê Jx v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À I³ TÓêÁê UÓêÁê Jx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  UÓêÁê J I´ TÓêÁêx v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  UÓêÁê J Iµ TÓêÁêx v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  UÓêÁê J I¶ TÓêÁêx v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  TÓêÁê UÓêÁê J I·x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   I¸ TÓêÁê UÓêÁê Jx v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   TÓêÁê UÓêÁê J I¹x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   TÓêÁê UÓêÁê J Iºx v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à J I» TÓêÁê UÓêÁêx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  UÓêÁê J I¼ TÓêÁêx v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  UÓêÁê J I½ TÓêÁêx v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  UÓêÁê J I¾ TÓêÁêx v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– UÓêÁê J I¿ TÓêÁêx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  TÓêÁê UÓêÁê J IÀx v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  UÓêÁê J IÁ TÓêÁêx v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  I TÓêÁê UÓêÁê Jx v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð UÓêÁê J Ià TÓêÁêx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  J IÄ TÓêÁê UÓêÁêx v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  J IÅ TÓêÁê UÓêÁêx v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  IÆ TÓêÁê UÓêÁê Jx v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° IÇ TÓêÁê UÓêÁê Jx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  TÓêÁê UÓêÁê J IÈx v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  UÓêÁê J IÉ TÓêÁêx v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  IÊ TÓêÁê UÓêÁê Jx v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð TÓêÁê UÓêÁê J IËx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  TÓêÁê UÓêÁê J IÌx v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  IÍ TÓêÁê UÓêÁê Jx v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  UÓêÁê J IÎ TÓêÁêx v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ J IÏ TÓêÁê UÓêÁêx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  IÐ TÓêÁê UÓêÁê Jx v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  UÓêÁê J IÑ TÓêÁêx v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  IÒ TÓêÁê UÓêÁê Jx v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È UÓêÁê J IÓ TÓêÁêx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  UÓêÁê J IÔ TÓêÁêx v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  UÓêÁê J IÕ TÓêÁêx v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  J IÖ TÓêÁê UÓêÁêx v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ UÓêÁê J I× TÓêÁêx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  TÓêÁê UÓêÁê J IØx v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  J IÙ TÓêÁê UÓêÁêx v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  J IÚ TÓêÁê UÓêÁêx v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è UÓêÁê J IÛ TÓêÁêx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  IÜ TÓêÁê UÓêÁê Jx v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  UÓêÁê J IÝ TÓêÁêx v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  UÓêÁê J IÞ TÓêÁêx v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ J Iß TÓêÁê UÓêÁêx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  Ià TÓêÁê UÓêÁê Jx v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  J Iá TÓêÁê UÓêÁêx v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  UÓêÁê J Iâ TÓêÁêx v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø UÓêÁê J Iã TÓêÁêx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  Iä TÓêÁê UÓêÁê Jx v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  J Iå TÓêÁê UÓêÁêx v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  TÓêÁê UÓêÁê J Iæx v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ UÓêÁê J Iç TÓêÁêx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  TÓêÁê UÓêÁê J Ièx v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  J Ié TÓêÁê UÓêÁêx v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  UÓêÁê J Iê TÓêÁêx v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø Ië TÓêÁê UÓêÁê Jx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  UÓêÁê J Iì TÓêÁêx v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  Ií TÓêÁê UÓêÁê Jx v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  Iî TÓêÁê UÓêÁê Jx v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ UÓêÁê J Iï TÓêÁêx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  UÓêÁê J Ið TÓêÁêx v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  Iñ TÓêÁê UÓêÁê Jx v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  UÓêÁê J Iò TÓêÁêx v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä UÓêÁê J Ió TÓêÁêx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  J Iô TÓêÁê UÓêÁêx v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  J Iõ TÓêÁê UÓêÁêx v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  UÓêÁê J Iö TÓêÁêx v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ UÓêÁê J I÷ TÓêÁêx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  TÓêÁê UÓêÁê J Iøx v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  Iù TÓêÁê UÓêÁê Jx v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  UÓêÁê J Iú TÓêÁêx v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä UÓêÁê J Iû TÓêÁêx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  J Iü TÓêÁê UÓêÁêx v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  Iý TÓêÁê UÓêÁê Jx v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  J Iþ TÓêÁê UÓêÁêx v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” TÓêÁê UÓêÁê J Iÿx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  UÓêÁê J I€ TÓêÁêx v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  J I TÓêÁê UÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  TÓêÁê UÓêÁê J I‚x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô Iƒ TÓêÁê UÓêÁê Jx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  I„ TÓêÁê UÓêÁê Jx v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  UÓêÁê J I… TÓêÁêx v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  I† TÓêÁê UÓêÁê Jx v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ TÓêÁê UÓêÁê J I‡x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  Iˆ TÓêÁê UÓêÁê Jx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  UÓêÁê J I‰ TÓêÁêx v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  IŠ TÓêÁê UÓêÁê Jx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô I‹ TÓêÁê UÓêÁê Jx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  UÓêÁê J IŒ TÓêÁêx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  IŽ TÓêÁê UÓêÁê Jx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  I‘ TÓêÁê UÓêÁê Jx v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  J I’ TÓêÁê UÓêÁêx v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì J I“ TÓêÁê UÓêÁêx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  I” TÓêÁê UÓêÁê Jx v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  UÓêÁê J I• TÓêÁêx v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  TÓêÁê UÓêÁê J I–x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ J I— TÓêÁê UÓêÁêx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  J I˜ TÓêÁê UÓêÁêx v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  UÓêÁê J I™ TÓêÁêx v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  Iš TÓêÁê UÓêÁê Jx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì TÓêÁê UÓêÁê J I›x v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  J Iœ TÓêÁê UÓêÁêx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  TÓêÁê UÓêÁê J Ižx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ IŸ TÓêÁê UÓêÁê Jx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  UÓêÁê J I  TÓêÁêx v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  TÓêÁê UÓêÁê J I¡x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  UÓêÁê J I¢ TÓêÁêx v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü UÓêÁê J I£ TÓêÁêx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  I¤ TÓêÁê UÓêÁê Jx v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  UÓêÁê J I¥ TÓêÁêx v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  I¦ TÓêÁê UÓêÁê Jx v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ UÓêÁê J I§ TÓêÁêx v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  J I¨ TÓêÁê UÓêÁêx v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  UÓêÁê J I© TÓêÁêx v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  Iª TÓêÁê UÓêÁê Jx v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü UÓêÁê J I« TÓêÁêx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  J I¬ TÓêÁê UÓêÁêx v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  UÓêÁê J I­ TÓêÁêx v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  UÓêÁê J I® TÓêÁêx v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ J I¯ TÓêÁê UÓêÁêx v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  I° TÓêÁê UÓêÁê Jx v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  TÓêÁê UÓêÁê J I±x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  UÓêÁê J I² TÓêÁêx v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– I³ TÓêÁê UÓêÁê Jx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  I´ TÓêÁê UÓêÁê Jx v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  UÓêÁê J Iµ TÓêÁêx v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  I¶ TÓêÁê UÓêÁê Jx v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ UÓêÁê J I· TÓêÁêx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  TÓêÁê UÓêÁê J I¸x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  J I¹ TÓêÁê UÓêÁêx v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  TÓêÁê UÓêÁê J Iºx v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â I» TÓêÁê UÓêÁê Jx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  UÓêÁê J I¼ TÓêÁêx v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  UÓêÁê J I½ TÓêÁêx v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  UÓêÁê J I¾ TÓêÁêx v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ UÓêÁê J I¿ TÓêÁêx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  TÓêÁê UÓêÁê J IÀx v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  IÁ TÓêÁê UÓêÁê Jx v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  TÓêÁê UÓêÁê J IÂx v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò J Ià TÓêÁê UÓêÁêx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  UÓêÁê J IÄ TÓêÁêx v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  TÓêÁê UÓêÁê J IÅx v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  UÓêÁê J IÆ TÓêÁêx v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² J IÇ TÓêÁê UÓêÁêx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  IÈ TÓêÁê UÓêÁê Jx v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  IÉ TÓêÁê UÓêÁê Jx v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  UÓêÁê J IÊ TÓêÁêx v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò UÓêÁê J IË TÓêÁêx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  TÓêÁê UÓêÁê J IÌx v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  IÍ TÓêÁê UÓêÁê Jx v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  UÓêÁê J IÎ TÓêÁêx v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š UÓêÁê J IÏ TÓêÁêx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  IÐ TÓêÁê UÓêÁê Jx v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  J IÑ TÓêÁê UÓêÁêx v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  TÓêÁê UÓêÁê J IÒx v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê TÓêÁê UÓêÁê J IÓx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  UÓêÁê J IÔ TÓêÁêx v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  TÓêÁê UÓêÁê J IÕx v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  IÖ TÓêÁê UÓêÁê Jx v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª J I× TÓêÁê UÓêÁêx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  J IØ TÓêÁê UÓêÁêx v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  J IÙ TÓêÁê UÓêÁêx v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  UÓêÁê J IÚ TÓêÁêx v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê TÓêÁê UÓêÁê J IÛx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  IÜ TÓêÁê UÓêÁê Jx v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  UÓêÁê J IÝ TÓêÁêx v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  IÞ TÓêÁê UÓêÁê Jx v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š UÓêÁê J Iß TÓêÁêx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  TÓêÁê UÓêÁê J Iàx v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  TÓêÁê UÓêÁê J Iáx v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  Iâ TÓêÁê UÓêÁê Jx v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú J Iã TÓêÁê UÓêÁêx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  UÓêÁê J Iä TÓêÁêx v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  Iå TÓêÁê UÓêÁê Jx v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  UÓêÁê J Iæ TÓêÁêx v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º J Iç TÓêÁê UÓêÁêx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  TÓêÁê UÓêÁê J Ièx v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  UÓêÁê J Ié TÓêÁêx v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  Iê TÓêÁê UÓêÁê Jx v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú UÓêÁê J Ië TÓêÁêx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  J Iì TÓêÁê UÓêÁêx v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  J Ií TÓêÁê UÓêÁêx v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  Iî TÓêÁê UÓêÁê Jx v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† Iï TÓêÁê UÓêÁê Jx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  Ið TÓêÁê UÓêÁê Jx v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  J Iñ TÓêÁê UÓêÁêx v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  J Iò TÓêÁê UÓêÁêx v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ TÓêÁê UÓêÁê J Ióx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  UÓêÁê J Iô TÓêÁêx v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  J Iõ TÓêÁê UÓêÁêx v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  Iö TÓêÁê UÓêÁê Jx v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ UÓêÁê J I÷ TÓêÁêx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  Iø TÓêÁê UÓêÁê Jx v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  J Iù TÓêÁê UÓêÁêx v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  Iú TÓêÁê UÓêÁê Jx v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ Iû TÓêÁê UÓêÁê Jx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  Iü TÓêÁê UÓêÁê Jx v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  TÓêÁê UÓêÁê J Iýx v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  Iþ TÓêÁê UÓêÁê Jx v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– UÓêÁê J Iÿ TÓêÁêx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  I€ TÓêÁê UÓêÁê Jx v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  UÓêÁê J I‚ TÓêÁêx v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö UÓêÁê J Iƒ TÓêÁêx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  UÓêÁê J I„ TÓêÁêx v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  I… TÓêÁê UÓêÁê Jx v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  TÓêÁê UÓêÁê J I†x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ I‡ TÓêÁê UÓêÁê Jx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  J Iˆ TÓêÁê UÓêÁêx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  TÓêÁê UÓêÁê J I‰x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  TÓêÁê UÓêÁê J IŠx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö TÓêÁê UÓêÁê J I‹x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  J IŒ TÓêÁê UÓêÁêx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  IŽ TÓêÁê UÓêÁê Jx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  Ȇ’”Ïûãw u  Icfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  "x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  (0d8Àó´”Ïûã(žw'/google.datastore.v1.Datastore/RunQueryÉ 7type.googleapis.com/google.datastore.v1.RunQueryRequestBdulcet-port-762ù SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I:x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  ¢L™™ 8type.googleapis.com/google.datastore.v1.RunQueryResponseÛ˜ ט— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  J I TÓêÁê UÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  TÓêÁê UÓêÁê J Iw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ•  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ TÓêÁê UÓêÁê J Iw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  J I TÓêÁê UÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  J I TÓêÁê UÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ J I TÓêÁê UÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  TÓêÁê UÓêÁê J Iw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  I  TÓêÁê UÓêÁê Jw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  UÓêÁê J I  TÓêÁêw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ TÓêÁê UÓêÁê J I w u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  UÓêÁê J I  TÓêÁêw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  UÓêÁê J I  TÓêÁêw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  I TÓêÁê UÓêÁê Jw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ I TÓêÁê UÓêÁê Jw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  I TÓêÁê UÓêÁê Jw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  I TÓêÁê UÓêÁê Jw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  I TÓêÁê UÓêÁê Jw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  I TÓêÁê UÓêÁê Jw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ TÓêÁê UÓêÁê J Iw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  TÓêÁê UÓêÁê J Iw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí TÓêÁê UÓêÁê J Iw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  I TÓêÁê UÓêÁê Jw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  J I TÓêÁê UÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  UÓêÁê J I  TÓêÁêw u  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  J I! TÓêÁê UÓêÁêw u  I!fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  UÓêÁê J I" TÓêÁêw u  I"fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ TÓêÁê UÓêÁê J I#w u  I#fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  J I$ TÓêÁê UÓêÁêw u  I$fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  I% TÓêÁê UÓêÁê Jw u  I%fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  UÓêÁê J I& TÓêÁêw u  I&fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ TÓêÁê UÓêÁê J I'w u  I'fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  UÓêÁê J I( TÓêÁêw u  I(fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  UÓêÁê J I) TÓêÁêw u  I)fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  I* TÓêÁê UÓêÁê Jw u  I*fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý J I+ TÓêÁê UÓêÁêw u  I+fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  UÓêÁê J I, TÓêÁêw u  I,fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  TÓêÁê UÓêÁê J I-w u  I-fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  TÓêÁê UÓêÁê J I.w u  I.fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ J I/ TÓêÁê UÓêÁêw u  I/fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  TÓêÁê UÓêÁê J I0w u  I0fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  I1 TÓêÁê UÓêÁê Jw u  I1fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  TÓêÁê UÓêÁê J I2w u  I2fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ UÓêÁê J I3 TÓêÁêw u  I3fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  TÓêÁê UÓêÁê J I4w u  I4fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  TÓêÁê UÓêÁê J I5w u  I5fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  TÓêÁê UÓêÁê J I6w u  I6fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ J I7 TÓêÁê UÓêÁêw u  I7fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  UÓêÁê J I8 TÓêÁêw u  I8fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  TÓêÁê UÓêÁê J I9w u  I9fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  I: TÓêÁê UÓêÁê Jw u  I:fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã I; TÓêÁê UÓêÁê Jw u  I;fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  TÓêÁê UÓêÁê J I<w u  I<fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  TÓêÁê UÓêÁê J I=w u  I=fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  UÓêÁê J I> TÓêÁêw u  I>fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ I? TÓêÁê UÓêÁê Jw u  I?fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  UÓêÁê J I@ TÓêÁêw u  I@fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  J IA TÓêÁê UÓêÁêw u  IAfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  J IB TÓêÁê UÓêÁêw u  IBfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ J IC TÓêÁê UÓêÁêw u  ICfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  UÓêÁê J ID TÓêÁêw u  IDfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  IE TÓêÁê UÓêÁê Jw u  IEfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  UÓêÁê J IF TÓêÁêw u  IFfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ TÓêÁê UÓêÁê J IGw u  IGfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  IH TÓêÁê UÓêÁê Jw u  IHfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  II TÓêÁê UÓêÁê Jw u  IIfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  UÓêÁê J IJ TÓêÁêw u  IJfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó UÓêÁê J IK TÓêÁêw u  IKfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  IL TÓêÁê UÓêÁê Jw u  ILfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  IM TÓêÁê UÓêÁê Jw u  IMfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  UÓêÁê J IN TÓêÁêw u  INfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ UÓêÁê J IO TÓêÁêw u  IOfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  UÓêÁê J IP TÓêÁêw u  IPfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  IQ TÓêÁê UÓêÁê Jw u  IQfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  J IR TÓêÁê UÓêÁêw u  IRfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË IS TÓêÁê UÓêÁê Jw u  ISfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  IT TÓêÁê UÓêÁê Jw u  ITfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  UÓêÁê J IU TÓêÁêw u  IUfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  UÓêÁê J IV TÓêÁêw u  IVfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« UÓêÁê J IW TÓêÁêw u  IWfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  IX TÓêÁê UÓêÁê Jw u  IXfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  J IY TÓêÁê UÓêÁêw u  IYfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  UÓêÁê J IZ TÓêÁêw u  IZfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë I[ TÓêÁê UÓêÁê Jw u  I[fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  J I\ TÓêÁê UÓêÁêw u  I\fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  TÓêÁê UÓêÁê J I]w u  I]fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  I^ TÓêÁê UÓêÁê Jw u  I^fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› TÓêÁê UÓêÁê J I_w u  I_fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  UÓêÁê J I` TÓêÁêw u  I`fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  UÓêÁê J Ia TÓêÁêw u  Iafjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  TÓêÁê UÓêÁê J Ibw u  Ibfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ Ic TÓêÁê UÓêÁê Jw u  Icfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  J Id TÓêÁê UÓêÁêw u  Idfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  Ie TÓêÁê UÓêÁê Jw u  Iefjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  TÓêÁê UÓêÁê J Ifw u  Iffjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» UÓêÁê J Ig TÓêÁêw u  Igfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  UÓêÁê J Ih TÓêÁêw u  Ihfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  Ii TÓêÁê UÓêÁê Jw u  Iifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  UÓêÁê J Ij TÓêÁêw u  Ijfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû Ik TÓêÁê UÓêÁê Jw u  Ikfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  J Il TÓêÁê UÓêÁêw u  Ilfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  UÓêÁê J Im TÓêÁêw u  Imfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  In TÓêÁê UÓêÁê Jw u  Infjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ UÓêÁê J Io TÓêÁêw u  Iofjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  Ip TÓêÁê UÓêÁê Jw u  Ipfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  UÓêÁê J Iq TÓêÁêw u  Iqfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  UÓêÁê J Ir TÓêÁêw u  Irfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ TÓêÁê UÓêÁê J Isw u  Isfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  UÓêÁê J It TÓêÁêw u  Itfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  Iu TÓêÁê UÓêÁê Jw u  Iufjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  TÓêÁê UÓêÁê J Ivw u  Ivfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ UÓêÁê J Iw TÓêÁêw u  Iwfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  Ix TÓêÁê UÓêÁê Jw u  Ixfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  UÓêÁê J Iy TÓêÁêw u  Iyfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  UÓêÁê J Iz TÓêÁêw u  Izfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç J I{ TÓêÁê UÓêÁêw u  I{fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  UÓêÁê J I| TÓêÁêw u  I|fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  I} TÓêÁê UÓêÁê Jw u  I}fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  TÓêÁê UÓêÁê J I~w u  I~fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— I TÓêÁê UÓêÁê Jw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  I€ TÓêÁê UÓêÁê Jx v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  I‚ TÓêÁê UÓêÁê Jx v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× Iƒ TÓêÁê UÓêÁê Jx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  I„ TÓêÁê UÓêÁê Jx v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  UÓêÁê J I… TÓêÁêx v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  I† TÓêÁê UÓêÁê Jx v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· J I‡ TÓêÁê UÓêÁêx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  Iˆ TÓêÁê UÓêÁê Jx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  J I‰ TÓêÁê UÓêÁêx v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  IŠ TÓêÁê UÓêÁê Jx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ J I‹ TÓêÁê UÓêÁêx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  UÓêÁê J IŒ TÓêÁêx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  TÓêÁê UÓêÁê J IŽx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  J I‘ TÓêÁê UÓêÁêx v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  UÓêÁê J I’ TÓêÁêx v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ UÓêÁê J I“ TÓêÁêx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  UÓêÁê J I” TÓêÁêx v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  TÓêÁê UÓêÁê J I•x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  I– TÓêÁê UÓêÁê Jx v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ J I— TÓêÁê UÓêÁêx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  TÓêÁê UÓêÁê J I˜x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  UÓêÁê J I™ TÓêÁêx v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  UÓêÁê J Iš TÓêÁêx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï UÓêÁê J I› TÓêÁêx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  Iœ TÓêÁê UÓêÁê Jx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  J I TÓêÁê UÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  Iž TÓêÁê UÓêÁê Jx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ J IŸ TÓêÁê UÓêÁêx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  I  TÓêÁê UÓêÁê Jx v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  I¡ TÓêÁê UÓêÁê Jx v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  UÓêÁê J I¢ TÓêÁêx v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß J I£ TÓêÁê UÓêÁêx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  I¤ TÓêÁê UÓêÁê Jx v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  J I¥ TÓêÁê UÓêÁêx v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  UÓêÁê J I¦ TÓêÁêx v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ UÓêÁê J I§ TÓêÁêx v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  TÓêÁê UÓêÁê J I¨x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  UÓêÁê J I© TÓêÁêx v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  UÓêÁê J Iª TÓêÁêx v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ I« TÓêÁê UÓêÁê Jx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  I¬ TÓêÁê UÓêÁê Jx v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  I­ TÓêÁê UÓêÁê Jx v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  I® TÓêÁê UÓêÁê Jx v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ J I¯ TÓêÁê UÓêÁêx v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  TÓêÁê UÓêÁê J I°x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  UÓêÁê J I± TÓêÁêx v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  UÓêÁê J I² TÓêÁêx v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À I³ TÓêÁê UÓêÁê Jx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  I´ TÓêÁê UÓêÁê Jx v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  UÓêÁê J Iµ TÓêÁêx v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  UÓêÁê J I¶ TÓêÁêx v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  J I· TÓêÁê UÓêÁêx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   I¸ TÓêÁê UÓêÁê Jx v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   UÓêÁê J I¹ TÓêÁêx v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   J Iº TÓêÁê UÓêÁêx v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à UÓêÁê J I» TÓêÁêx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  I¼ TÓêÁê UÓêÁê Jx v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  TÓêÁê UÓêÁê J I½x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  UÓêÁê J I¾ TÓêÁêx v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– J I¿ TÓêÁê UÓêÁêx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  UÓêÁê J IÀ TÓêÁêx v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  UÓêÁê J IÁ TÓêÁêx v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  TÓêÁê UÓêÁê J IÂx v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð UÓêÁê J Ià TÓêÁêx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  J IÄ TÓêÁê UÓêÁêx v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  TÓêÁê UÓêÁê J IÅx v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  UÓêÁê J IÆ TÓêÁêx v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° TÓêÁê UÓêÁê J IÇx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  TÓêÁê UÓêÁê J IÈx v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  TÓêÁê UÓêÁê J IÉx v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  J IÊ TÓêÁê UÓêÁêx v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð TÓêÁê UÓêÁê J IËx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  UÓêÁê J IÌ TÓêÁêx v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  IÍ TÓêÁê UÓêÁê Jx v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  J IÎ TÓêÁê UÓêÁêx v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ UÓêÁê J IÏ TÓêÁêx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  UÓêÁê J IÐ TÓêÁêx v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  TÓêÁê UÓêÁê J IÑx v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  TÓêÁê UÓêÁê J IÒx v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È J IÓ TÓêÁê UÓêÁêx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  TÓêÁê UÓêÁê J IÔx v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  TÓêÁê UÓêÁê J IÕx v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  IÖ TÓêÁê UÓêÁê Jx v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ I× TÓêÁê UÓêÁê Jx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  TÓêÁê UÓêÁê J IØx v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  J IÙ TÓêÁê UÓêÁêx v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  UÓêÁê J IÚ TÓêÁêx v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è IÛ TÓêÁê UÓêÁê Jx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  UÓêÁê J IÜ TÓêÁêx v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  TÓêÁê UÓêÁê J IÝx v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  UÓêÁê J IÞ TÓêÁêx v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ UÓêÁê J Iß TÓêÁêx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  UÓêÁê J Ià TÓêÁêx v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  UÓêÁê J Iá TÓêÁêx v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  Iâ TÓêÁê UÓêÁê Jx v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø UÓêÁê J Iã TÓêÁêx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  UÓêÁê J Iä TÓêÁêx v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  Iå TÓêÁê UÓêÁê Jx v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  TÓêÁê UÓêÁê J Iæx v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ J Iç TÓêÁê UÓêÁêx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  UÓêÁê J Iè TÓêÁêx v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  TÓêÁê UÓêÁê J Iéx v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  J Iê TÓêÁê UÓêÁêx v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø J Ië TÓêÁê UÓêÁêx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  UÓêÁê J Iì TÓêÁêx v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  UÓêÁê J Ií TÓêÁêx v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  TÓêÁê UÓêÁê J Iîx v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ UÓêÁê J Iï TÓêÁêx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  Ið TÓêÁê UÓêÁê Jx v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  TÓêÁê UÓêÁê J Iñx v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  Iò TÓêÁê UÓêÁê Jx v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä UÓêÁê J Ió TÓêÁêx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  J Iô TÓêÁê UÓêÁêx v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  TÓêÁê UÓêÁê J Iõx v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  TÓêÁê UÓêÁê J Iöx v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ UÓêÁê J I÷ TÓêÁêx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  UÓêÁê J Iø TÓêÁêx v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  J Iù TÓêÁê UÓêÁêx v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  UÓêÁê J Iú TÓêÁêx v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä UÓêÁê J Iû TÓêÁêx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  UÓêÁê J Iü TÓêÁêx v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  J Iý TÓêÁê UÓêÁêx v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  Iþ TÓêÁê UÓêÁê Jx v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” TÓêÁê UÓêÁê J Iÿx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  TÓêÁê UÓêÁê J I€x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  UÓêÁê J I‚ TÓêÁêx v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô TÓêÁê UÓêÁê J Iƒx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  J I„ TÓêÁê UÓêÁêx v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  I… TÓêÁê UÓêÁê Jx v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  J I† TÓêÁê UÓêÁêx v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ UÓêÁê J I‡ TÓêÁêx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  UÓêÁê J Iˆ TÓêÁêx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  UÓêÁê J I‰ TÓêÁêx v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  UÓêÁê J IŠ TÓêÁêx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô I‹ TÓêÁê UÓêÁê Jx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  IŒ TÓêÁê UÓêÁê Jx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  UÓêÁê J IŽ TÓêÁêx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  TÓêÁê UÓêÁê J I‘x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  TÓêÁê UÓêÁê J I’x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì TÓêÁê UÓêÁê J I“x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  J I” TÓêÁê UÓêÁêx v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  TÓêÁê UÓêÁê J I•x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  UÓêÁê J I– TÓêÁêx v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ UÓêÁê J I— TÓêÁêx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  TÓêÁê UÓêÁê J I˜x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  TÓêÁê UÓêÁê J I™x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  UÓêÁê J Iš TÓêÁêx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì UÓêÁê J I› TÓêÁêx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  J Iœ TÓêÁê UÓêÁêx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  J I TÓêÁê UÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  UÓêÁê J Iž TÓêÁêx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ J IŸ TÓêÁê UÓêÁêx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  I  TÓêÁê UÓêÁê Jx v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  TÓêÁê UÓêÁê J I¡x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  TÓêÁê UÓêÁê J I¢x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü TÓêÁê UÓêÁê J I£x v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  I¤ TÓêÁê UÓêÁê Jx v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  TÓêÁê UÓêÁê J I¥x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  TÓêÁê UÓêÁê J I¦x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ J I§ TÓêÁê UÓêÁêx v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  TÓêÁê UÓêÁê J I¨x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  I© TÓêÁê UÓêÁê Jx v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  J Iª TÓêÁê UÓêÁêx v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü I« TÓêÁê UÓêÁê Jx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  Ȇ’”Ïûã"x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  (8Àó´”Ïûã( ëã 8type.googleapis.com/google.datastore.v1.RunQueryResponse¦ £™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  Iô TÓêÁê UÓêÁê Jx v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  Àó´”Ïûã"x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  (8Àó´”Ïûã(«|'/google.datastore.v1.Datastore/RunQueryÎ 7type.googleapis.com/google.datastore.v1.RunQueryRequest’Bdulcet-port-762þ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I:x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  b” åMÜ› 8type.googleapis.com/google.datastore.v1.RunQueryResponsež› š›— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  J Id TÓêÁê UÓêÁêw u  Idfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  UÓêÁê J Ie TÓêÁêw u  Iefjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  UÓêÁê J If TÓêÁêw u  Iffjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» UÓêÁê J Ig TÓêÁêw u  Igfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  UÓêÁê J Ih TÓêÁêw u  Ihfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  Ii TÓêÁê UÓêÁê Jw u  Iifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  TÓêÁê UÓêÁê J Ijw u  Ijfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû UÓêÁê J Ik TÓêÁêw u  Ikfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  TÓêÁê UÓêÁê J Ilw u  Ilfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  UÓêÁê J Im TÓêÁêw u  Imfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  J In TÓêÁê UÓêÁêw u  Infjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ UÓêÁê J Io TÓêÁêw u  Iofjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  Ip TÓêÁê UÓêÁê Jw u  Ipfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  UÓêÁê J Iq TÓêÁêw u  Iqfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  UÓêÁê J Ir TÓêÁêw u  Irfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ UÓêÁê J Is TÓêÁêw u  Isfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  It TÓêÁê UÓêÁê Jw u  Itfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  UÓêÁê J Iu TÓêÁêw u  Iufjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  TÓêÁê UÓêÁê J Ivw u  Ivfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ J Iw TÓêÁê UÓêÁêw u  Iwfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  Ix TÓêÁê UÓêÁê Jw u  Ixfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  J Iy TÓêÁê UÓêÁêw u  Iyfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  UÓêÁê J Iz TÓêÁêw u  Izfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç I{ TÓêÁê UÓêÁê Jw u  I{fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  UÓêÁê J I| TÓêÁêw u  I|fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  TÓêÁê UÓêÁê J I}w u  I}fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  UÓêÁê J I~ TÓêÁêw u  I~fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç  Ȇ’”Ïûã— ’ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— UÓêÁê J I TÓêÁêw u  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  UÓêÁê J I€ TÓêÁêx v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  UÓêÁê J I‚ TÓêÁêx v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× UÓêÁê J Iƒ TÓêÁêx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  TÓêÁê UÓêÁê J I„x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  UÓêÁê J I… TÓêÁêx v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  I† TÓêÁê UÓêÁê Jx v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· I‡ TÓêÁê UÓêÁê Jx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  UÓêÁê J Iˆ TÓêÁêx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  I‰ TÓêÁê UÓêÁê Jx v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  IŠ TÓêÁê UÓêÁê Jx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ J I‹ TÓêÁê UÓêÁêx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  UÓêÁê J IŒ TÓêÁêx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  IŽ TÓêÁê UÓêÁê Jx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  J I TÓêÁê UÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  I‘ TÓêÁê UÓêÁê Jx v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  UÓêÁê J I’ TÓêÁêx v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ TÓêÁê UÓêÁê J I“x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  I” TÓêÁê UÓêÁê Jx v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  UÓêÁê J I• TÓêÁêx v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  J I– TÓêÁê UÓêÁêx v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ UÓêÁê J I— TÓêÁêx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  J I˜ TÓêÁê UÓêÁêx v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  TÓêÁê UÓêÁê J I™x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  TÓêÁê UÓêÁê J Išx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï UÓêÁê J I› TÓêÁêx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  Iœ TÓêÁê UÓêÁê Jx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  UÓêÁê J Iž TÓêÁêx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ IŸ TÓêÁê UÓêÁê Jx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  UÓêÁê J I  TÓêÁêx v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  UÓêÁê J I¡ TÓêÁêx v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  I¢ TÓêÁê UÓêÁê Jx v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß J I£ TÓêÁê UÓêÁêx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  J I¤ TÓêÁê UÓêÁêx v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  J I¥ TÓêÁê UÓêÁêx v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  UÓêÁê J I¦ TÓêÁêx v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ J I§ TÓêÁê UÓêÁêx v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  TÓêÁê UÓêÁê J I¨x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  UÓêÁê J I© TÓêÁêx v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  J Iª TÓêÁê UÓêÁêx v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ TÓêÁê UÓêÁê J I«x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  I¬ TÓêÁê UÓêÁê Jx v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  UÓêÁê J I­ TÓêÁêx v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  J I® TÓêÁê UÓêÁêx v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ I¯ TÓêÁê UÓêÁê Jx v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  TÓêÁê UÓêÁê J I°x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  TÓêÁê UÓêÁê J I±x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  J I² TÓêÁê UÓêÁêx v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À I³ TÓêÁê UÓêÁê Jx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  TÓêÁê UÓêÁê J I´x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  TÓêÁê UÓêÁê J Iµx v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  UÓêÁê J I¶ TÓêÁêx v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  UÓêÁê J I· TÓêÁêx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   TÓêÁê UÓêÁê J I¸x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   TÓêÁê UÓêÁê J I¹x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   UÓêÁê J Iº TÓêÁêx v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–   Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à J I» TÓêÁê UÓêÁêx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  J I¼ TÓêÁê UÓêÁêx v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  TÓêÁê UÓêÁê J I½x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  UÓêÁê J I¾ TÓêÁêx v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– UÓêÁê J I¿ TÓêÁêx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  IÀ TÓêÁê UÓêÁê Jx v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  IÁ TÓêÁê UÓêÁê Jx v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  UÓêÁê J I TÓêÁêx v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð Ià TÓêÁê UÓêÁê Jx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  IÄ TÓêÁê UÓêÁê Jx v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  J IÅ TÓêÁê UÓêÁêx v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  UÓêÁê J IÆ TÓêÁêx v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° J IÇ TÓêÁê UÓêÁêx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  IÈ TÓêÁê UÓêÁê Jx v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  IÉ TÓêÁê UÓêÁê Jx v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  J IÊ TÓêÁê UÓêÁêx v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð IË TÓêÁê UÓêÁê Jx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  TÓêÁê UÓêÁê J IÌx v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  IÍ TÓêÁê UÓêÁê Jx v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  UÓêÁê J IÎ TÓêÁêx v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ J IÏ TÓêÁê UÓêÁêx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  J IÐ TÓêÁê UÓêÁêx v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  IÑ TÓêÁê UÓêÁê Jx v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  UÓêÁê J IÒ TÓêÁêx v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È IÓ TÓêÁê UÓêÁê Jx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  TÓêÁê UÓêÁê J IÔx v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  TÓêÁê UÓêÁê J IÕx v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  J IÖ TÓêÁê UÓêÁêx v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ J I× TÓêÁê UÓêÁêx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  J IØ TÓêÁê UÓêÁêx v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  IÙ TÓêÁê UÓêÁê Jx v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  UÓêÁê J IÚ TÓêÁêx v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è J IÛ TÓêÁê UÓêÁêx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  UÓêÁê J IÜ TÓêÁêx v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  UÓêÁê J IÝ TÓêÁêx v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  IÞ TÓêÁê UÓêÁê Jx v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ Iß TÓêÁê UÓêÁê Jx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  Ià TÓêÁê UÓêÁê Jx v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  J Iá TÓêÁê UÓêÁêx v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  J Iâ TÓêÁê UÓêÁêx v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø Iã TÓêÁê UÓêÁê Jx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  Iä TÓêÁê UÓêÁê Jx v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  TÓêÁê UÓêÁê J Iåx v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  UÓêÁê J Iæ TÓêÁêx v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ UÓêÁê J Iç TÓêÁêx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  J Iè TÓêÁê UÓêÁêx v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  UÓêÁê J Ié TÓêÁêx v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  Iê TÓêÁê UÓêÁê Jx v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø UÓêÁê J Ië TÓêÁêx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  J Iì TÓêÁê UÓêÁêx v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  TÓêÁê UÓêÁê J Iíx v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  J Iî TÓêÁê UÓêÁêx v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ J Iï TÓêÁê UÓêÁêx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  UÓêÁê J Ið TÓêÁêx v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  UÓêÁê J Iñ TÓêÁêx v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  UÓêÁê J Iò TÓêÁêx v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä J Ió TÓêÁê UÓêÁêx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  UÓêÁê J Iô TÓêÁêx v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  UÓêÁê J Iõ TÓêÁêx v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  J Iö TÓêÁê UÓêÁêx v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ UÓêÁê J I÷ TÓêÁêx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  UÓêÁê J Iø TÓêÁêx v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  J Iù TÓêÁê UÓêÁêx v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  UÓêÁê J Iú TÓêÁêx v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä J Iû TÓêÁê UÓêÁêx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  Iü TÓêÁê UÓêÁê Jx v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  Iý TÓêÁê UÓêÁê Jx v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  UÓêÁê J Iþ TÓêÁêx v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” UÓêÁê J Iÿ TÓêÁêx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  J I€ TÓêÁê UÓêÁêx v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  J I‚ TÓêÁê UÓêÁêx v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô J Iƒ TÓêÁê UÓêÁêx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  TÓêÁê UÓêÁê J I„x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  UÓêÁê J I… TÓêÁêx v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  UÓêÁê J I† TÓêÁêx v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ UÓêÁê J I‡ TÓêÁêx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  Iˆ TÓêÁê UÓêÁê Jx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  UÓêÁê J I‰ TÓêÁêx v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  TÓêÁê UÓêÁê J IŠx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô UÓêÁê J I‹ TÓêÁêx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  UÓêÁê J IŒ TÓêÁêx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  IŽ TÓêÁê UÓêÁê Jx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  TÓêÁê UÓêÁê J I‘x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  I’ TÓêÁê UÓêÁê Jx v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì TÓêÁê UÓêÁê J I“x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  I” TÓêÁê UÓêÁê Jx v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  UÓêÁê J I• TÓêÁêx v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  I– TÓêÁê UÓêÁê Jx v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ TÓêÁê UÓêÁê J I—x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  UÓêÁê J I˜ TÓêÁêx v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  I™ TÓêÁê UÓêÁê Jx v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  Iš TÓêÁê UÓêÁê Jx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì UÓêÁê J I› TÓêÁêx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  UÓêÁê J Iœ TÓêÁêx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  J I TÓêÁê UÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  UÓêÁê J Iž TÓêÁêx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ TÓêÁê UÓêÁê J IŸx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  J I  TÓêÁê UÓêÁêx v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  UÓêÁê J I¡ TÓêÁêx v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  I¢ TÓêÁê UÓêÁê Jx v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü UÓêÁê J I£ TÓêÁêx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  TÓêÁê UÓêÁê J I¤x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  J I¥ TÓêÁê UÓêÁêx v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  I¦ TÓêÁê UÓêÁê Jx v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ J I§ TÓêÁê UÓêÁêx v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  I¨ TÓêÁê UÓêÁê Jx v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  UÓêÁê J I© TÓêÁêx v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  UÓêÁê J Iª TÓêÁêx v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü J I« TÓêÁê UÓêÁêx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  J I¬ TÓêÁê UÓêÁêx v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  TÓêÁê UÓêÁê J I­x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  I® TÓêÁê UÓêÁê Jx v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ UÓêÁê J I¯ TÓêÁêx v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  TÓêÁê UÓêÁê J I°x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  TÓêÁê UÓêÁê J I±x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  J I² TÓêÁê UÓêÁêx v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– J I³ TÓêÁê UÓêÁêx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  J I´ TÓêÁê UÓêÁêx v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Iµ TÓêÁê UÓêÁê Jx v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  TÓêÁê UÓêÁê J I¶x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ J I· TÓêÁê UÓêÁêx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  UÓêÁê J I¸ TÓêÁêx v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  J I¹ TÓêÁê UÓêÁêx v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  UÓêÁê J Iº TÓêÁêx v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â J I» TÓêÁê UÓêÁêx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  I¼ TÓêÁê UÓêÁê Jx v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  UÓêÁê J I½ TÓêÁêx v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  UÓêÁê J I¾ TÓêÁêx v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ I¿ TÓêÁê UÓêÁê Jx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  UÓêÁê J IÀ TÓêÁêx v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  UÓêÁê J IÁ TÓêÁêx v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  TÓêÁê UÓêÁê J IÂx v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò Ià TÓêÁê UÓêÁê Jx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  UÓêÁê J IÄ TÓêÁêx v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  IÅ TÓêÁê UÓêÁê Jx v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  J IÆ TÓêÁê UÓêÁêx v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² IÇ TÓêÁê UÓêÁê Jx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  TÓêÁê UÓêÁê J IÈx v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  UÓêÁê J IÉ TÓêÁêx v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  J IÊ TÓêÁê UÓêÁêx v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò UÓêÁê J IË TÓêÁêx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  UÓêÁê J IÌ TÓêÁêx v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  UÓêÁê J IÍ TÓêÁêx v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  TÓêÁê UÓêÁê J IÎx v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š IÏ TÓêÁê UÓêÁê Jx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  J IÐ TÓêÁê UÓêÁêx v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  J IÑ TÓêÁê UÓêÁêx v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  UÓêÁê J IÒ TÓêÁêx v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê UÓêÁê J IÓ TÓêÁêx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  IÔ TÓêÁê UÓêÁê Jx v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  UÓêÁê J IÕ TÓêÁêx v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  IÖ TÓêÁê UÓêÁê Jx v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª TÓêÁê UÓêÁê J I×x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  UÓêÁê J IØ TÓêÁêx v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  TÓêÁê UÓêÁê J IÙx v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  UÓêÁê J IÚ TÓêÁêx v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê UÓêÁê J IÛ TÓêÁêx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  TÓêÁê UÓêÁê J IÜx v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  UÓêÁê J IÝ TÓêÁêx v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  UÓêÁê J IÞ TÓêÁêx v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š UÓêÁê J Iß TÓêÁêx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  UÓêÁê J Ià TÓêÁêx v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  TÓêÁê UÓêÁê J Iáx v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  Iâ TÓêÁê UÓêÁê Jx v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú TÓêÁê UÓêÁê J Iãx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  TÓêÁê UÓêÁê J Iäx v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  UÓêÁê J Iå TÓêÁêx v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  J Iæ TÓêÁê UÓêÁêx v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º TÓêÁê UÓêÁê J Içx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  UÓêÁê J Iè TÓêÁêx v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  UÓêÁê J Ié TÓêÁêx v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  UÓêÁê J Iê TÓêÁêx v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú J Ië TÓêÁê UÓêÁêx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  TÓêÁê UÓêÁê J Iìx v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  Ií TÓêÁê UÓêÁê Jx v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  TÓêÁê UÓêÁê J Iîx v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† UÓêÁê J Iï TÓêÁêx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  J Ið TÓêÁê UÓêÁêx v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  Iñ TÓêÁê UÓêÁê Jx v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  UÓêÁê J Iò TÓêÁêx v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ J Ió TÓêÁê UÓêÁêx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  J Iô TÓêÁê UÓêÁêx v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  Iõ TÓêÁê UÓêÁê Jx v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  Iö TÓêÁê UÓêÁê Jx v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ I÷ TÓêÁê UÓêÁê Jx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  UÓêÁê J Iø TÓêÁêx v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  UÓêÁê J Iù TÓêÁêx v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  J Iú TÓêÁê UÓêÁêx v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ UÓêÁê J Iû TÓêÁêx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  J Iü TÓêÁê UÓêÁêx v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  J Iý TÓêÁê UÓêÁêx v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  Iþ TÓêÁê UÓêÁê Jx v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– UÓêÁê J Iÿ TÓêÁêx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  UÓêÁê J I€ TÓêÁêx v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  UÓêÁê J I‚ TÓêÁêx v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö J Iƒ TÓêÁê UÓêÁêx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  TÓêÁê UÓêÁê J I„x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  UÓêÁê J I… TÓêÁêx v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  TÓêÁê UÓêÁê J I†x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ TÓêÁê UÓêÁê J I‡x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  TÓêÁê UÓêÁê J Iˆx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  J I‰ TÓêÁê UÓêÁêx v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  UÓêÁê J IŠ TÓêÁêx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö UÓêÁê J I‹ TÓêÁêx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  J IŒ TÓêÁê UÓêÁêx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  TÓêÁê UÓêÁê J IŽx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž J I TÓêÁê UÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  Ȇ’”Ïûãw u  Icfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ  "x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  (0d8Àó´”Ïûã(¤|'/google.datastore.v1.Datastore/RunQueryÎ 7type.googleapis.com/google.datastore.v1.RunQueryRequest’Bdulcet-port-762þ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I:x v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  b¼N–œ 8type.googleapis.com/google.datastore.v1.RunQueryResponseØ› Ô›™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  TÓêÁê UÓêÁê J Iôx v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  UÓêÁê J Iõ TÓêÁêx v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  Iö TÓêÁê UÓêÁê Jx v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë I÷ TÓêÁê UÓêÁê Jx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  UÓêÁê J Iø TÓêÁêx v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  J Iù TÓêÁê UÓêÁêx v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  J Iú TÓêÁê UÓêÁêx v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« Iû TÓêÁê UÓêÁê Jx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  J Iü TÓêÁê UÓêÁêx v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  J Iý TÓêÁê UÓêÁêx v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  UÓêÁê J Iþ TÓêÁêx v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë UÓêÁê J Iÿ TÓêÁêx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  J I€ TÓêÁê UÓêÁêx v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  I‚ TÓêÁê UÓêÁê Jx v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› UÓêÁê J Iƒ TÓêÁêx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  UÓêÁê J I„ TÓêÁêx v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  I… TÓêÁê UÓêÁê Jx v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  I† TÓêÁê UÓêÁê Jx v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û UÓêÁê J I‡ TÓêÁêx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  J Iˆ TÓêÁê UÓêÁêx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  UÓêÁê J I‰ TÓêÁêx v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  IŠ TÓêÁê UÓêÁê Jx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» TÓêÁê UÓêÁê J I‹x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  TÓêÁê UÓêÁê J IŒx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  IŽ TÓêÁê UÓêÁê Jx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  J I TÓêÁê UÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  J I‘ TÓêÁê UÓêÁêx v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  J I’ TÓêÁê UÓêÁêx v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ UÓêÁê J I“ TÓêÁêx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  UÓêÁê J I” TÓêÁêx v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  J I• TÓêÁê UÓêÁêx v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  UÓêÁê J I– TÓêÁêx v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç J I— TÓêÁê UÓêÁêx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  TÓêÁê UÓêÁê J I˜x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  TÓêÁê UÓêÁê J I™x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  UÓêÁê J Iš TÓêÁêx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ J I› TÓêÁê UÓêÁêx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  UÓêÁê J Iœ TÓêÁêx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  TÓêÁê UÓêÁê J Ižx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç IŸ TÓêÁê UÓêÁê Jx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  J I  TÓêÁê UÓêÁêx v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  J I¡ TÓêÁê UÓêÁêx v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  TÓêÁê UÓêÁê J I¢x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— TÓêÁê UÓêÁê J I£x v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  I¤ TÓêÁê UÓêÁê Jx v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  J I¥ TÓêÁê UÓêÁêx v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  UÓêÁê J I¦ TÓêÁêx v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× UÓêÁê J I§ TÓêÁêx v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  UÓêÁê J I¨ TÓêÁêx v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  UÓêÁê J I© TÓêÁêx v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  UÓêÁê J Iª TÓêÁêx v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· UÓêÁê J I« TÓêÁêx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  UÓêÁê J I¬ TÓêÁêx v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  UÓêÁê J I­ TÓêÁêx v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  J I® TÓêÁê UÓêÁêx v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ J I¯ TÓêÁê UÓêÁêx v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  TÓêÁê UÓêÁê J I°x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  I± TÓêÁê UÓêÁê Jx v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  I² TÓêÁê UÓêÁê Jx v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ I³ TÓêÁê UÓêÁê Jx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  TÓêÁê UÓêÁê J I´x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  Iµ TÓêÁê UÓêÁê Jx v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  UÓêÁê J I¶ TÓêÁêx v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï TÓêÁê UÓêÁê J I·x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  UÓêÁê J I¸ TÓêÁêx v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  I¹ TÓêÁê UÓêÁê Jx v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  Iº TÓêÁê UÓêÁê Jx v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ UÓêÁê J I» TÓêÁêx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  I¼ TÓêÁê UÓêÁê Jx v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  I½ TÓêÁê UÓêÁê Jx v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  J I¾ TÓêÁê UÓêÁêx v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï UÓêÁê J I¿ TÓêÁêx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  J IÀ TÓêÁê UÓêÁêx v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  TÓêÁê UÓêÁê J IÁx v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  I TÓêÁê UÓêÁê Jx v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ Ià TÓêÁê UÓêÁê Jx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  TÓêÁê UÓêÁê J IÄx v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  UÓêÁê J IÅ TÓêÁêx v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  TÓêÁê UÓêÁê J IÆx v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß UÓêÁê J IÇ TÓêÁêx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  TÓêÁê UÓêÁê J IÈx v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  TÓêÁê UÓêÁê J IÉx v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  J IÊ TÓêÁê UÓêÁêx v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ UÓêÁê J IË TÓêÁêx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  J IÌ TÓêÁê UÓêÁêx v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  UÓêÁê J IÍ TÓêÁêx v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  UÓêÁê J IÎ TÓêÁêx v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ IÏ TÓêÁê UÓêÁê Jx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  IÐ TÓêÁê UÓêÁê Jx v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  TÓêÁê UÓêÁê J IÑx v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  J IÒ TÓêÁê UÓêÁêx v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ J IÓ TÓêÁê UÓêÁêx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  J IÔ TÓêÁê UÓêÁêx v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  UÓêÁê J IÕ TÓêÁêx v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  IÖ TÓêÁê UÓêÁê Jx v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ UÓêÁê J I× TÓêÁêx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  IØ TÓêÁê UÓêÁê Jx v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  J IÙ TÓêÁê UÓêÁêx v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  TÓêÁê UÓêÁê J IÚx v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  UÓêÁê J IÛ TÓêÁêx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   UÓêÁê J IÜ TÓêÁêx v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   TÓêÁê UÓêÁê J IÝx v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   UÓêÁê J IÞ TÓêÁêx v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà Iß TÓêÁê UÓêÁê Jx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  TÓêÁê UÓêÁê J Iàx v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  TÓêÁê UÓêÁê J Iáx v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  J Iâ TÓêÁê UÓêÁêx v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù J Iã TÓêÁê UÓêÁêx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  UÓêÁê J Iä TÓêÁêx v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  UÓêÁê J Iå TÓêÁêx v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  TÓêÁê UÓêÁê J Iæx v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ UÓêÁê J Iç TÓêÁêx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  UÓêÁê J Iè TÓêÁêx v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  UÓêÁê J Ié TÓêÁêx v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  Iê TÓêÁê UÓêÁê Jx v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° Ië TÓêÁê UÓêÁê Jx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  UÓêÁê J Iì TÓêÁêx v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  J Ií TÓêÁê UÓêÁêx v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  UÓêÁê J Iî TÓêÁêx v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð UÓêÁê J Iï TÓêÁêx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  J Ið TÓêÁê UÓêÁêx v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  UÓêÁê J Iñ TÓêÁêx v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Iò TÓêÁê UÓêÁê Jx v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ UÓêÁê J Ió TÓêÁêx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  UÓêÁê J Iô TÓêÁêx v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  UÓêÁê J Iõ TÓêÁêx v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  Iö TÓêÁê UÓêÁê Jx v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ I÷ TÓêÁê UÓêÁê Jx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  TÓêÁê UÓêÁê J Iøx v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  TÓêÁê UÓêÁê J Iùx v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  J Iú TÓêÁê UÓêÁêx v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ UÓêÁê J Iû TÓêÁêx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  TÓêÁê UÓêÁê J Iüx v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  UÓêÁê J Iý TÓêÁêx v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  J Iþ TÓêÁê UÓêÁêx v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè UÓêÁê J Iÿ TÓêÁêx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  I€ TÓêÁê UÓêÁê Jx v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  UÓêÁê J I‚ TÓêÁêx v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ Iƒ TÓêÁê UÓêÁê Jx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  I„ TÓêÁê UÓêÁê Jx v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  I… TÓêÁê UÓêÁê Jx v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  I† TÓêÁê UÓêÁê Jx v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ I‡ TÓêÁê UÓêÁê Jx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  TÓêÁê UÓêÁê J Iˆx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  UÓêÁê J I‰ TÓêÁêx v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  TÓêÁê UÓêÁê J IŠx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ UÓêÁê J I‹ TÓêÁêx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  UÓêÁê J IŒ TÓêÁêx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  TÓêÁê UÓêÁê J IŽx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  TÓêÁê UÓêÁê J I‘x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  UÓêÁê J I’ TÓêÁêx v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ I“ TÓêÁê UÓêÁê Jx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  TÓêÁê UÓêÁê J I”x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  I• TÓêÁê UÓêÁê Jx v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  TÓêÁê UÓêÁê J I–x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ TÓêÁê UÓêÁê J I—x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  UÓêÁê J I˜ TÓêÁêx v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  J I™ TÓêÁê UÓêÁêx v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  J Iš TÓêÁê UÓêÁêx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ I› TÓêÁê UÓêÁê Jx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  J Iœ TÓêÁê UÓêÁêx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  J I TÓêÁê UÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  Iž TÓêÁê UÓêÁê Jx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä IŸ TÓêÁê UÓêÁê Jx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  J I  TÓêÁê UÓêÁêx v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  UÓêÁê J I¡ TÓêÁêx v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  TÓêÁê UÓêÁê J I¢x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” J I£ TÓêÁê UÓêÁêx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  I¤ TÓêÁê UÓêÁê Jx v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  UÓêÁê J I¥ TÓêÁêx v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  TÓêÁê UÓêÁê J I¦x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ I§ TÓêÁê UÓêÁê Jx v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  TÓêÁê UÓêÁê J I¨x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  J I© TÓêÁê UÓêÁêx v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  UÓêÁê J Iª TÓêÁêx v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ UÓêÁê J I« TÓêÁêx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  UÓêÁê J I¬ TÓêÁêx v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  TÓêÁê UÓêÁê J I­x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  I® TÓêÁê UÓêÁê Jx v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô I¯ TÓêÁê UÓêÁê Jx v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  J I° TÓêÁê UÓêÁêx v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  UÓêÁê J I± TÓêÁêx v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  J I² TÓêÁê UÓêÁêx v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ J I³ TÓêÁê UÓêÁêx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  UÓêÁê J I´ TÓêÁêx v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  UÓêÁê J Iµ TÓêÁêx v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  I¶ TÓêÁê UÓêÁê Jx v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ TÓêÁê UÓêÁê J I·x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  I¸ TÓêÁê UÓêÁê Jx v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  J I¹ TÓêÁê UÓêÁêx v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  UÓêÁê J Iº TÓêÁêx v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ UÓêÁê J I» TÓêÁêx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  I¼ TÓêÁê UÓêÁê Jx v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  I½ TÓêÁê UÓêÁê Jx v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  UÓêÁê J I¾ TÓêÁêx v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì UÓêÁê J I¿ TÓêÁêx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  UÓêÁê J IÀ TÓêÁêx v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  TÓêÁê UÓêÁê J IÁx v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  J I TÓêÁê UÓêÁêx v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ UÓêÁê J Ià TÓêÁêx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  J IÄ TÓêÁê UÓêÁêx v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  UÓêÁê J IÅ TÓêÁêx v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  UÓêÁê J IÆ TÓêÁêx v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ UÓêÁê J IÇ TÓêÁêx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  UÓêÁê J IÈ TÓêÁêx v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  J IÉ TÓêÁê UÓêÁêx v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  IÊ TÓêÁê UÓêÁê Jx v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ IË TÓêÁê UÓêÁê Jx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  IÌ TÓêÁê UÓêÁê Jx v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  IÍ TÓêÁê UÓêÁê Jx v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  UÓêÁê J IÎ TÓêÁêx v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü IÏ TÓêÁê UÓêÁê Jx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  J IÐ TÓêÁê UÓêÁêx v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  IÑ TÓêÁê UÓêÁê Jx v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  IÒ TÓêÁê UÓêÁê Jx v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ TÓêÁê UÓêÁê J IÓx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  UÓêÁê J IÔ TÓêÁêx v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  TÓêÁê UÓêÁê J IÕx v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  J IÖ TÓêÁê UÓêÁêx v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù J I× TÓêÁê UÓêÁêx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  J IØ TÓêÁê UÓêÁêx v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  UÓêÁê J IÙ TÓêÁêx v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  TÓêÁê UÓêÁê J IÚx v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ IÛ TÓêÁê UÓêÁê Jx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  J IÜ TÓêÁê UÓêÁêx v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  UÓêÁê J IÝ TÓêÁêx v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  J IÞ TÓêÁê UÓêÁêx v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ TÓêÁê UÓêÁê J Ißx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  Ià TÓêÁê UÓêÁê Jx v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  J Iá TÓêÁê UÓêÁêx v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  TÓêÁê UÓêÁê J Iâx v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ TÓêÁê UÓêÁê J Iãx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  UÓêÁê J Iä TÓêÁêx v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  Iå TÓêÁê UÓêÁê Jx v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  J Iæ TÓêÁê UÓêÁêx v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ TÓêÁê UÓêÁê J Içx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  UÓêÁê J Iè TÓêÁêx v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  Ié TÓêÁê UÓêÁê Jx v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  TÓêÁê UÓêÁê J Iêx v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² Ië TÓêÁê UÓêÁê Jx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  J Iì TÓêÁê UÓêÁêx v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  J Ií TÓêÁê UÓêÁêx v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  UÓêÁê J Iî TÓêÁêx v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò Iï TÓêÁê UÓêÁê Jx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  UÓêÁê J Ið TÓêÁêx v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  TÓêÁê UÓêÁê J Iñx v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  UÓêÁê J Iò TÓêÁêx v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ UÓêÁê J Ió TÓêÁêx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  UÓêÁê J Iô TÓêÁêx v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  UÓêÁê J Iõ TÓêÁêx v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  J Iö TÓêÁê UÓêÁêx v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ UÓêÁê J I÷ TÓêÁêx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  Iø TÓêÁê UÓêÁê Jx v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  TÓêÁê UÓêÁê J Iùx v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  UÓêÁê J Iú TÓêÁêx v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª UÓêÁê J Iû TÓêÁêx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  J Iü TÓêÁê UÓêÁêx v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  UÓêÁê J Iý TÓêÁêx v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  J Iþ TÓêÁê UÓêÁêx v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê UÓêÁê J Iÿ TÓêÁêx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  TÓêÁê UÓêÁê J I€x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  UÓêÁê J I‚ TÓêÁêx v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš TÓêÁê UÓêÁê J Iƒx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  UÓêÁê J I„ TÓêÁêx v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  I… TÓêÁê UÓêÁê Jx v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  UÓêÁê J I† TÓêÁêx v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ J I‡ TÓêÁê UÓêÁêx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  Iˆ TÓêÁê UÓêÁê Jx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  UÓêÁê J I‰ TÓêÁêx v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  IŠ TÓêÁê UÓêÁê Jx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº UÓêÁê J I‹ TÓêÁêx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  J IŒ TÓêÁê UÓêÁêx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  IŽ TÓêÁê UÓêÁê Jx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  UÓêÁê J I‘ TÓêÁêx v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  J I’ TÓêÁê UÓêÁêx v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† J I“ TÓêÁê UÓêÁêx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  I” TÓêÁê UÓêÁê Jx v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  J I• TÓêÁê UÓêÁêx v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  J I– TÓêÁê UÓêÁêx v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ J I— TÓêÁê UÓêÁêx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  UÓêÁê J I˜ TÓêÁêx v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  J I™ TÓêÁê UÓêÁêx v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  J Iš TÓêÁê UÓêÁêx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ UÓêÁê J I› TÓêÁêx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  UÓêÁê J Iœ TÓêÁêx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  UÓêÁê J Iž TÓêÁêx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ UÓêÁê J IŸ TÓêÁêx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  Àó´”Ïûãx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Å  "x v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  (0ô8Àó´”Ïûã(yÎßÅ¿ 8type.googleapis.com/google.datastore.v1.RunQueryResponse‡¿ ƒ¿™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  TÓêÁê UÓêÁê J I¬x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  TÓêÁê UÓêÁê J I­x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  TÓêÁê UÓêÁê J I®x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ TÓêÁê UÓêÁê J I¯x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  TÓêÁê UÓêÁê J I°x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  J I± TÓêÁê UÓêÁêx v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  TÓêÁê UÓêÁê J I²x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– J I³ TÓêÁê UÓêÁêx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  TÓêÁê UÓêÁê J I´x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  UÓêÁê J Iµ TÓêÁêx v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  I¶ TÓêÁê UÓêÁê Jx v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ UÓêÁê J I· TÓêÁêx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  TÓêÁê UÓêÁê J I¸x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  UÓêÁê J I¹ TÓêÁêx v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  J Iº TÓêÁê UÓêÁêx v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â UÓêÁê J I» TÓêÁêx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  TÓêÁê UÓêÁê J I¼x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  TÓêÁê UÓêÁê J I½x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  J I¾ TÓêÁê UÓêÁêx v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ UÓêÁê J I¿ TÓêÁêx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  J IÀ TÓêÁê UÓêÁêx v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  UÓêÁê J IÁ TÓêÁêx v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  TÓêÁê UÓêÁê J IÂx v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò UÓêÁê J Ià TÓêÁêx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  TÓêÁê UÓêÁê J IÄx v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  UÓêÁê J IÅ TÓêÁêx v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  TÓêÁê UÓêÁê J IÆx v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² IÇ TÓêÁê UÓêÁê Jx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  TÓêÁê UÓêÁê J IÈx v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  IÉ TÓêÁê UÓêÁê Jx v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  IÊ TÓêÁê UÓêÁê Jx v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò UÓêÁê J IË TÓêÁêx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  IÌ TÓêÁê UÓêÁê Jx v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  UÓêÁê J IÍ TÓêÁêx v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  J IÎ TÓêÁê UÓêÁêx v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š IÏ TÓêÁê UÓêÁê Jx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  IÐ TÓêÁê UÓêÁê Jx v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  IÑ TÓêÁê UÓêÁê Jx v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  TÓêÁê UÓêÁê J IÒx v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê IÓ TÓêÁê UÓêÁê Jx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  UÓêÁê J IÔ TÓêÁêx v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  IÕ TÓêÁê UÓêÁê Jx v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  IÖ TÓêÁê UÓêÁê Jx v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª UÓêÁê J I× TÓêÁêx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  J IØ TÓêÁê UÓêÁêx v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  IÙ TÓêÁê UÓêÁê Jx v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  IÚ TÓêÁê UÓêÁê Jx v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê IÛ TÓêÁê UÓêÁê Jx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  UÓêÁê J IÜ TÓêÁêx v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  TÓêÁê UÓêÁê J IÝx v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  UÓêÁê J IÞ TÓêÁêx v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š UÓêÁê J Iß TÓêÁêx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  TÓêÁê UÓêÁê J Iàx v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  Iá TÓêÁê UÓêÁê Jx v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  Iâ TÓêÁê UÓêÁê Jx v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú J Iã TÓêÁê UÓêÁêx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  TÓêÁê UÓêÁê J Iäx v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  Iå TÓêÁê UÓêÁê Jx v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  Iæ TÓêÁê UÓêÁê Jx v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º TÓêÁê UÓêÁê J Içx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  J Iè TÓêÁê UÓêÁêx v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  UÓêÁê J Ié TÓêÁêx v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  TÓêÁê UÓêÁê J Iêx v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú Ië TÓêÁê UÓêÁê Jx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  Iì TÓêÁê UÓêÁê Jx v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  Ií TÓêÁê UÓêÁê Jx v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  Iî TÓêÁê UÓêÁê Jx v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† TÓêÁê UÓêÁê J Iïx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  Ið TÓêÁê UÓêÁê Jx v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  TÓêÁê UÓêÁê J Iñx v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  TÓêÁê UÓêÁê J Iòx v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ UÓêÁê J Ió TÓêÁêx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  Iô TÓêÁê UÓêÁê Jx v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  J Iõ TÓêÁê UÓêÁêx v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  J Iö TÓêÁê UÓêÁêx v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ TÓêÁê UÓêÁê J I÷x v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  Iø TÓêÁê UÓêÁê Jx v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  TÓêÁê UÓêÁê J Iùx v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  UÓêÁê J Iú TÓêÁêx v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ Iû TÓêÁê UÓêÁê Jx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  UÓêÁê J Iü TÓêÁêx v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  TÓêÁê UÓêÁê J Iýx v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  J Iþ TÓêÁê UÓêÁêx v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– Iÿ TÓêÁê UÓêÁê Jx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  J I€ TÓêÁê UÓêÁêx v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  I‚ TÓêÁê UÓêÁê Jx v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö UÓêÁê J Iƒ TÓêÁêx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  J I„ TÓêÁê UÓêÁêx v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  I… TÓêÁê UÓêÁê Jx v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  UÓêÁê J I† TÓêÁêx v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ TÓêÁê UÓêÁê J I‡x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  UÓêÁê J Iˆ TÓêÁêx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  J I‰ TÓêÁê UÓêÁêx v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  IŠ TÓêÁê UÓêÁê Jx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö J I‹ TÓêÁê UÓêÁêx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  UÓêÁê J IŒ TÓêÁêx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  IŽ TÓêÁê UÓêÁê Jx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  J I‘ TÓêÁê UÓêÁêx v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  TÓêÁê UÓêÁê J I’x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î I“ TÓêÁê UÓêÁê Jx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  I” TÓêÁê UÓêÁê Jx v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  UÓêÁê J I• TÓêÁêx v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  UÓêÁê J I– TÓêÁêx v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® I— TÓêÁê UÓêÁê Jx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  I˜ TÓêÁê UÓêÁê Jx v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  UÓêÁê J I™ TÓêÁêx v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  UÓêÁê J Iš TÓêÁêx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î I› TÓêÁê UÓêÁê Jx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  Iœ TÓêÁê UÓêÁê Jx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  Iž TÓêÁê UÓêÁê Jx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž UÓêÁê J IŸ TÓêÁêx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  J I  TÓêÁê UÓêÁêx v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  TÓêÁê UÓêÁê J I¡x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  TÓêÁê UÓêÁê J I¢x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ UÓêÁê J I£ TÓêÁêx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  I¤ TÓêÁê UÓêÁê Jx v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  UÓêÁê J I¥ TÓêÁêx v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  J I¦ TÓêÁê UÓêÁêx v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ J I§ TÓêÁê UÓêÁêx v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  UÓêÁê J I¨ TÓêÁêx v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  UÓêÁê J I© TÓêÁêx v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  Iª TÓêÁê UÓêÁê Jx v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ I« TÓêÁê UÓêÁê Jx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  I¬ TÓêÁê UÓêÁê Jx v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  UÓêÁê J I­ TÓêÁêx v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  TÓêÁê UÓêÁê J I®x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– UÓêÁê J I¯ TÓêÁêx v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  UÓêÁê J I° TÓêÁêx v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  J I± TÓêÁê UÓêÁêx v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  J I² TÓêÁê UÓêÁêx v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á J I³ TÓêÁê UÓêÁêx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  UÓêÁê J I´ TÓêÁêx v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  Iµ TÓêÁê UÓêÁê Jx v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  TÓêÁê UÓêÁê J I¶x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ J I· TÓêÁê UÓêÁêx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  I¸ TÓêÁê UÓêÁê Jx v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  TÓêÁê UÓêÁê J I¹x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  TÓêÁê UÓêÁê J Iºx v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á TÓêÁê UÓêÁê J I»x v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  J I¼ TÓêÁê UÓêÁêx v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  TÓêÁê UÓêÁê J I½x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  UÓêÁê J I¾ TÓêÁêx v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ J I¿ TÓêÁê UÓêÁêx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  UÓêÁê J IÀ TÓêÁêx v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  UÓêÁê J IÁ TÓêÁêx v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  I TÓêÁê UÓêÁê Jx v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ UÓêÁê J Ià TÓêÁêx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  J IÄ TÓêÁê UÓêÁêx v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  UÓêÁê J IÅ TÓêÁêx v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  TÓêÁê UÓêÁê J IÆx v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± UÓêÁê J IÇ TÓêÁêx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  J IÈ TÓêÁê UÓêÁêx v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  TÓêÁê UÓêÁê J IÉx v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  IÊ TÓêÁê UÓêÁê Jx v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ UÓêÁê J IË TÓêÁêx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  IÌ TÓêÁê UÓêÁê Jx v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  UÓêÁê J IÍ TÓêÁêx v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  UÓêÁê J IÎ TÓêÁêx v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ J IÏ TÓêÁê UÓêÁêx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  UÓêÁê J IÐ TÓêÁêx v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  TÓêÁê UÓêÁê J IÑx v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  UÓêÁê J IÒ TÓêÁêx v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É TÓêÁê UÓêÁê J IÓx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  J IÔ TÓêÁê UÓêÁêx v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  IÕ TÓêÁê UÓêÁê Jx v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  J IÖ TÓêÁê UÓêÁêx v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© UÓêÁê J I× TÓêÁêx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  UÓêÁê J IØ TÓêÁêx v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  TÓêÁê UÓêÁê J IÙx v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  TÓêÁê UÓêÁê J IÚx v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é UÓêÁê J IÛ TÓêÁêx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  UÓêÁê J IÜ TÓêÁêx v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  UÓêÁê J IÝ TÓêÁêx v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  IÞ TÓêÁê UÓêÁê Jx v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ TÓêÁê UÓêÁê J Ißx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  UÓêÁê J Ià TÓêÁêx v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  Iá TÓêÁê UÓêÁê Jx v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  UÓêÁê J Iâ TÓêÁêx v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù UÓêÁê J Iã TÓêÁêx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  Iä TÓêÁê UÓêÁê Jx v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  Iå TÓêÁê UÓêÁê Jx v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  UÓêÁê J Iæ TÓêÁêx v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ J Iç TÓêÁê UÓêÁêx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  Iè TÓêÁê UÓêÁê Jx v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  UÓêÁê J Ié TÓêÁêx v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  UÓêÁê J Iê TÓêÁêx v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù UÓêÁê J Ië TÓêÁêx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  Iì TÓêÁê UÓêÁê Jx v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  TÓêÁê UÓêÁê J Iíx v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  UÓêÁê J Iî TÓêÁêx v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… TÓêÁê UÓêÁê J Iïx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  TÓêÁê UÓêÁê J Iðx v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  Iñ TÓêÁê UÓêÁê Jx v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  J Iò TÓêÁê UÓêÁêx v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Å J Ió TÓêÁê UÓêÁêx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Å  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  Iô TÓêÁê UÓêÁê Jx v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  Àó´”Ïûã"x v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  (8Àó´”Ïûã(®¢M™› 8type.googleapis.com/google.datastore.v1.RunQueryResponseÛš ך™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  J I¬ TÓêÁê UÓêÁêx v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  UÓêÁê J I­ TÓêÁêx v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  TÓêÁê UÓêÁê J I®x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ J I¯ TÓêÁê UÓêÁêx v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  TÓêÁê UÓêÁê J I°x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  I± TÓêÁê UÓêÁê Jx v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  J I² TÓêÁê UÓêÁêx v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– UÓêÁê J I³ TÓêÁêx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  UÓêÁê J I´ TÓêÁêx v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  J Iµ TÓêÁê UÓêÁêx v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  UÓêÁê J I¶ TÓêÁêx v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ TÓêÁê UÓêÁê J I·x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  J I¸ TÓêÁê UÓêÁêx v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  J I¹ TÓêÁê UÓêÁêx v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  TÓêÁê UÓêÁê J Iºx v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â TÓêÁê UÓêÁê J I»x v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  UÓêÁê J I¼ TÓêÁêx v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  UÓêÁê J I½ TÓêÁêx v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  UÓêÁê J I¾ TÓêÁêx v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ UÓêÁê J I¿ TÓêÁêx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  IÀ TÓêÁê UÓêÁê Jx v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  IÁ TÓêÁê UÓêÁê Jx v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  UÓêÁê J I TÓêÁêx v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò UÓêÁê J Ià TÓêÁêx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  TÓêÁê UÓêÁê J IÄx v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  UÓêÁê J IÅ TÓêÁêx v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  TÓêÁê UÓêÁê J IÆx v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² TÓêÁê UÓêÁê J IÇx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  J IÈ TÓêÁê UÓêÁêx v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  TÓêÁê UÓêÁê J IÉx v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  IÊ TÓêÁê UÓêÁê Jx v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò UÓêÁê J IË TÓêÁêx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  J IÌ TÓêÁê UÓêÁêx v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  TÓêÁê UÓêÁê J IÍx v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  UÓêÁê J IÎ TÓêÁêx v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š UÓêÁê J IÏ TÓêÁêx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  UÓêÁê J IÐ TÓêÁêx v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  IÑ TÓêÁê UÓêÁê Jx v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  J IÒ TÓêÁê UÓêÁêx v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê UÓêÁê J IÓ TÓêÁêx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  UÓêÁê J IÔ TÓêÁêx v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  IÕ TÓêÁê UÓêÁê Jx v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  IÖ TÓêÁê UÓêÁê Jx v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª UÓêÁê J I× TÓêÁêx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  J IØ TÓêÁê UÓêÁêx v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  IÙ TÓêÁê UÓêÁê Jx v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  TÓêÁê UÓêÁê J IÚx v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê TÓêÁê UÓêÁê J IÛx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  J IÜ TÓêÁê UÓêÁêx v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  IÝ TÓêÁê UÓêÁê Jx v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  J IÞ TÓêÁê UÓêÁêx v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š Iß TÓêÁê UÓêÁê Jx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  UÓêÁê J Ià TÓêÁêx v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  UÓêÁê J Iá TÓêÁêx v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  TÓêÁê UÓêÁê J Iâx v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú Iã TÓêÁê UÓêÁê Jx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  UÓêÁê J Iä TÓêÁêx v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  TÓêÁê UÓêÁê J Iåx v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  Iæ TÓêÁê UÓêÁê Jx v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º UÓêÁê J Iç TÓêÁêx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  UÓêÁê J Iè TÓêÁêx v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  UÓêÁê J Ié TÓêÁêx v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  TÓêÁê UÓêÁê J Iêx v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú TÓêÁê UÓêÁê J Iëx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  J Iì TÓêÁê UÓêÁêx v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  UÓêÁê J Ií TÓêÁêx v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  UÓêÁê J Iî TÓêÁêx v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† TÓêÁê UÓêÁê J Iïx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  Ið TÓêÁê UÓêÁê Jx v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  UÓêÁê J Iñ TÓêÁêx v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  Iò TÓêÁê UÓêÁê Jx v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ TÓêÁê UÓêÁê J Ióx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  Iô TÓêÁê UÓêÁê Jx v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  Iõ TÓêÁê UÓêÁê Jx v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  TÓêÁê UÓêÁê J Iöx v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ UÓêÁê J I÷ TÓêÁêx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  UÓêÁê J Iø TÓêÁêx v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  UÓêÁê J Iù TÓêÁêx v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  TÓêÁê UÓêÁê J Iúx v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ J Iû TÓêÁê UÓêÁêx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  Iü TÓêÁê UÓêÁê Jx v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  J Iý TÓêÁê UÓêÁêx v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  UÓêÁê J Iþ TÓêÁêx v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– J Iÿ TÓêÁê UÓêÁêx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  I€ TÓêÁê UÓêÁê Jx v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  UÓêÁê J I‚ TÓêÁêx v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö Iƒ TÓêÁê UÓêÁê Jx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  I„ TÓêÁê UÓêÁê Jx v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  I… TÓêÁê UÓêÁê Jx v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  I† TÓêÁê UÓêÁê Jx v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ TÓêÁê UÓêÁê J I‡x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  UÓêÁê J Iˆ TÓêÁêx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  UÓêÁê J I‰ TÓêÁêx v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  J IŠ TÓêÁê UÓêÁêx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö TÓêÁê UÓêÁê J I‹x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  J IŒ TÓêÁê UÓêÁêx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  TÓêÁê UÓêÁê J IŽx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  J I TÓêÁê UÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  J I‘ TÓêÁê UÓêÁêx v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  J I’ TÓêÁê UÓêÁêx v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î UÓêÁê J I“ TÓêÁêx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  I” TÓêÁê UÓêÁê Jx v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  UÓêÁê J I• TÓêÁêx v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  J I– TÓêÁê UÓêÁêx v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® TÓêÁê UÓêÁê J I—x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  TÓêÁê UÓêÁê J I˜x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  UÓêÁê J I™ TÓêÁêx v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  UÓêÁê J Iš TÓêÁêx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î UÓêÁê J I› TÓêÁêx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  UÓêÁê J Iœ TÓêÁêx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  Iž TÓêÁê UÓêÁê Jx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž IŸ TÓêÁê UÓêÁê Jx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  I  TÓêÁê UÓêÁê Jx v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  TÓêÁê UÓêÁê J I¡x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  UÓêÁê J I¢ TÓêÁêx v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ I£ TÓêÁê UÓêÁê Jx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  I¤ TÓêÁê UÓêÁê Jx v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  I¥ TÓêÁê UÓêÁê Jx v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  J I¦ TÓêÁê UÓêÁêx v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ TÓêÁê UÓêÁê J I§x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  I¨ TÓêÁê UÓêÁê Jx v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  I© TÓêÁê UÓêÁê Jx v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  UÓêÁê J Iª TÓêÁêx v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ UÓêÁê J I« TÓêÁêx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  UÓêÁê J I¬ TÓêÁêx v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  TÓêÁê UÓêÁê J I­x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  I® TÓêÁê UÓêÁê Jx v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– J I¯ TÓêÁê UÓêÁêx v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  I° TÓêÁê UÓêÁê Jx v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  I± TÓêÁê UÓêÁê Jx v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  J I² TÓêÁê UÓêÁêx v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á TÓêÁê UÓêÁê J I³x v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  UÓêÁê J I´ TÓêÁêx v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  UÓêÁê J Iµ TÓêÁêx v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  UÓêÁê J I¶ TÓêÁêx v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ UÓêÁê J I· TÓêÁêx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  TÓêÁê UÓêÁê J I¸x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  J I¹ TÓêÁê UÓêÁêx v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  Iº TÓêÁê UÓêÁê Jx v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á I» TÓêÁê UÓêÁê Jx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  I¼ TÓêÁê UÓêÁê Jx v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  J I½ TÓêÁê UÓêÁêx v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  TÓêÁê UÓêÁê J I¾x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ I¿ TÓêÁê UÓêÁê Jx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  IÀ TÓêÁê UÓêÁê Jx v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  IÁ TÓêÁê UÓêÁê Jx v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  UÓêÁê J I TÓêÁêx v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ J Ià TÓêÁê UÓêÁêx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  UÓêÁê J IÄ TÓêÁêx v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  TÓêÁê UÓêÁê J IÅx v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  UÓêÁê J IÆ TÓêÁêx v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± UÓêÁê J IÇ TÓêÁêx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  IÈ TÓêÁê UÓêÁê Jx v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  IÉ TÓêÁê UÓêÁê Jx v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  UÓêÁê J IÊ TÓêÁêx v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ UÓêÁê J IË TÓêÁêx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  IÌ TÓêÁê UÓêÁê Jx v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  UÓêÁê J IÍ TÓêÁêx v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  IÎ TÓêÁê UÓêÁê Jx v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ IÏ TÓêÁê UÓêÁê Jx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  UÓêÁê J IÐ TÓêÁêx v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  J IÑ TÓêÁê UÓêÁêx v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  UÓêÁê J IÒ TÓêÁêx v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É IÓ TÓêÁê UÓêÁê Jx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  IÔ TÓêÁê UÓêÁê Jx v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  J IÕ TÓêÁê UÓêÁêx v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  IÖ TÓêÁê UÓêÁê Jx v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© UÓêÁê J I× TÓêÁêx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  TÓêÁê UÓêÁê J IØx v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  UÓêÁê J IÙ TÓêÁêx v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  UÓêÁê J IÚ TÓêÁêx v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é TÓêÁê UÓêÁê J IÛx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  IÜ TÓêÁê UÓêÁê Jx v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  IÝ TÓêÁê UÓêÁê Jx v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  UÓêÁê J IÞ TÓêÁêx v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ Iß TÓêÁê UÓêÁê Jx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  Ià TÓêÁê UÓêÁê Jx v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  UÓêÁê J Iá TÓêÁêx v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  Iâ TÓêÁê UÓêÁê Jx v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù TÓêÁê UÓêÁê J Iãx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  UÓêÁê J Iä TÓêÁêx v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  Iå TÓêÁê UÓêÁê Jx v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  Iæ TÓêÁê UÓêÁê Jx v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ UÓêÁê J Iç TÓêÁêx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  UÓêÁê J Iè TÓêÁêx v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  Ié TÓêÁê UÓêÁê Jx v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  UÓêÁê J Iê TÓêÁêx v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù Ië TÓêÁê UÓêÁê Jx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  TÓêÁê UÓêÁê J Iìx v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  UÓêÁê J Ií TÓêÁêx v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  UÓêÁê J Iî TÓêÁêx v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… UÓêÁê J Iï TÓêÁêx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  J Ið TÓêÁê UÓêÁêx v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  J Iñ TÓêÁê UÓêÁêx v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  Iò TÓêÁê UÓêÁê Jx v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Å UÓêÁê J Ió TÓêÁêx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Å  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  Iô TÓêÁê UÓêÁê Jx v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  J Iõ TÓêÁê UÓêÁêx v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  Iö TÓêÁê UÓêÁê Jx v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë J I÷ TÓêÁê UÓêÁêx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  Iø TÓêÁê UÓêÁê Jx v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  UÓêÁê J Iù TÓêÁêx v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  TÓêÁê UÓêÁê J Iúx v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« Iû TÓêÁê UÓêÁê Jx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  Iü TÓêÁê UÓêÁê Jx v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  J Iý TÓêÁê UÓêÁêx v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  UÓêÁê J Iþ TÓêÁêx v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë UÓêÁê J Iÿ TÓêÁêx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  UÓêÁê J I€ TÓêÁêx v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  TÓêÁê UÓêÁê J I‚x v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› Iƒ TÓêÁê UÓêÁê Jx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  J I„ TÓêÁê UÓêÁêx v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  UÓêÁê J I… TÓêÁêx v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  J I† TÓêÁê UÓêÁêx v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û TÓêÁê UÓêÁê J I‡x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  UÓêÁê J Iˆ TÓêÁêx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  UÓêÁê J I‰ TÓêÁêx v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  IŠ TÓêÁê UÓêÁê Jx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» I‹ TÓêÁê UÓêÁê Jx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  IŒ TÓêÁê UÓêÁê Jx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  J IŽ TÓêÁê UÓêÁêx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  I‘ TÓêÁê UÓêÁê Jx v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  UÓêÁê J I’ TÓêÁêx v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ J I“ TÓêÁê UÓêÁêx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  UÓêÁê J I” TÓêÁêx v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  TÓêÁê UÓêÁê J I•x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  I– TÓêÁê UÓêÁê Jx v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç J I— TÓêÁê UÓêÁêx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  I˜ TÓêÁê UÓêÁê Jx v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  TÓêÁê UÓêÁê J I™x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  Iš TÓêÁê UÓêÁê Jx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ I› TÓêÁê UÓêÁê Jx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  Iœ TÓêÁê UÓêÁê Jx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  Iž TÓêÁê UÓêÁê Jx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç UÓêÁê J IŸ TÓêÁêx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  I  TÓêÁê UÓêÁê Jx v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  I¡ TÓêÁê UÓêÁê Jx v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  TÓêÁê UÓêÁê J I¢x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— J I£ TÓêÁê UÓêÁêx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  UÓêÁê J I¤ TÓêÁêx v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  J I¥ TÓêÁê UÓêÁêx v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  UÓêÁê J I¦ TÓêÁêx v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× UÓêÁê J I§ TÓêÁêx v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  UÓêÁê J I¨ TÓêÁêx v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  UÓêÁê J I© TÓêÁêx v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  J Iª TÓêÁê UÓêÁêx v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· I« TÓêÁê UÓêÁê Jx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  TÓêÁê UÓêÁê J I¬x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  UÓêÁê J I­ TÓêÁêx v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  TÓêÁê UÓêÁê J I®x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ TÓêÁê UÓêÁê J I¯x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  I° TÓêÁê UÓêÁê Jx v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  UÓêÁê J I± TÓêÁêx v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  TÓêÁê UÓêÁê J I²x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ TÓêÁê UÓêÁê J I³x v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  TÓêÁê UÓêÁê J I´x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  Iµ TÓêÁê UÓêÁê Jx v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  TÓêÁê UÓêÁê J I¶x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï I· TÓêÁê UÓêÁê Jx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  TÓêÁê UÓêÁê J I¸x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  J I¹ TÓêÁê UÓêÁêx v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  UÓêÁê J Iº TÓêÁêx v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ I» TÓêÁê UÓêÁê Jx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  TÓêÁê UÓêÁê J I¼x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  J I½ TÓêÁê UÓêÁêx v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  TÓêÁê UÓêÁê J I¾x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï J I¿ TÓêÁê UÓêÁêx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  TÓêÁê UÓêÁê J IÀx v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  UÓêÁê J IÁ TÓêÁêx v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  J I TÓêÁê UÓêÁêx v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ Ià TÓêÁê UÓêÁê Jx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  IÄ TÓêÁê UÓêÁê Jx v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  IÅ TÓêÁê UÓêÁê Jx v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  J IÆ TÓêÁê UÓêÁêx v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß UÓêÁê J IÇ TÓêÁêx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  IÈ TÓêÁê UÓêÁê Jx v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  IÉ TÓêÁê UÓêÁê Jx v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  UÓêÁê J IÊ TÓêÁêx v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ J IË TÓêÁê UÓêÁêx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  IÌ TÓêÁê UÓêÁê Jx v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  IÍ TÓêÁê UÓêÁê Jx v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  IÎ TÓêÁê UÓêÁê Jx v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ IÏ TÓêÁê UÓêÁê Jx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  IÐ TÓêÁê UÓêÁê Jx v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  UÓêÁê J IÑ TÓêÁêx v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  UÓêÁê J IÒ TÓêÁêx v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ UÓêÁê J IÓ TÓêÁêx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  TÓêÁê UÓêÁê J IÔx v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  TÓêÁê UÓêÁê J IÕx v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  TÓêÁê UÓêÁê J IÖx v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ UÓêÁê J I× TÓêÁêx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  Àó´”Ïûã"x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  (8Àó´”Ïûã(²w'/google.datastore.v1.Datastore/RunQueryÉ 7type.googleapis.com/google.datastore.v1.RunQueryRequestBdulcet-port-762ù SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I:x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  ¢M™› 8type.googleapis.com/google.datastore.v1.RunQueryResponseÛš ך™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  UÓêÁê J I¬ TÓêÁêx v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  UÓêÁê J I­ TÓêÁêx v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  I® TÓêÁê UÓêÁê Jx v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ TÓêÁê UÓêÁê J I¯x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  UÓêÁê J I° TÓêÁêx v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  TÓêÁê UÓêÁê J I±x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  I² TÓêÁê UÓêÁê Jx v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– UÓêÁê J I³ TÓêÁêx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  J I´ TÓêÁê UÓêÁêx v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  UÓêÁê J Iµ TÓêÁêx v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  J I¶ TÓêÁê UÓêÁêx v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ UÓêÁê J I· TÓêÁêx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  UÓêÁê J I¸ TÓêÁêx v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  TÓêÁê UÓêÁê J I¹x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  UÓêÁê J Iº TÓêÁêx v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â UÓêÁê J I» TÓêÁêx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  TÓêÁê UÓêÁê J I¼x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  TÓêÁê UÓêÁê J I½x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  UÓêÁê J I¾ TÓêÁêx v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ UÓêÁê J I¿ TÓêÁêx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  UÓêÁê J IÀ TÓêÁêx v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  J IÁ TÓêÁê UÓêÁêx v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  J I TÓêÁê UÓêÁêx v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò UÓêÁê J Ià TÓêÁêx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  UÓêÁê J IÄ TÓêÁêx v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  IÅ TÓêÁê UÓêÁê Jx v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  J IÆ TÓêÁê UÓêÁêx v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² J IÇ TÓêÁê UÓêÁêx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  J IÈ TÓêÁê UÓêÁêx v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  IÉ TÓêÁê UÓêÁê Jx v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  IÊ TÓêÁê UÓêÁê Jx v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò J IË TÓêÁê UÓêÁêx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  J IÌ TÓêÁê UÓêÁêx v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  UÓêÁê J IÍ TÓêÁêx v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  IÎ TÓêÁê UÓêÁê Jx v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š TÓêÁê UÓêÁê J IÏx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  IÐ TÓêÁê UÓêÁê Jx v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  J IÑ TÓêÁê UÓêÁêx v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  J IÒ TÓêÁê UÓêÁêx v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê UÓêÁê J IÓ TÓêÁêx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  IÔ TÓêÁê UÓêÁê Jx v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  IÕ TÓêÁê UÓêÁê Jx v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  J IÖ TÓêÁê UÓêÁêx v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª UÓêÁê J I× TÓêÁêx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  J IØ TÓêÁê UÓêÁêx v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  TÓêÁê UÓêÁê J IÙx v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  UÓêÁê J IÚ TÓêÁêx v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê J IÛ TÓêÁê UÓêÁêx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  TÓêÁê UÓêÁê J IÜx v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  IÝ TÓêÁê UÓêÁê Jx v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  TÓêÁê UÓêÁê J IÞx v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š Iß TÓêÁê UÓêÁê Jx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  UÓêÁê J Ià TÓêÁêx v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  TÓêÁê UÓêÁê J Iáx v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  UÓêÁê J Iâ TÓêÁêx v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú UÓêÁê J Iã TÓêÁêx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  J Iä TÓêÁê UÓêÁêx v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  UÓêÁê J Iå TÓêÁêx v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  J Iæ TÓêÁê UÓêÁêx v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º TÓêÁê UÓêÁê J Içx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  UÓêÁê J Iè TÓêÁêx v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  UÓêÁê J Ié TÓêÁêx v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  Iê TÓêÁê UÓêÁê Jx v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú J Ië TÓêÁê UÓêÁêx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  UÓêÁê J Iì TÓêÁêx v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  J Ií TÓêÁê UÓêÁêx v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  UÓêÁê J Iî TÓêÁêx v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† J Iï TÓêÁê UÓêÁêx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  Ið TÓêÁê UÓêÁê Jx v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  UÓêÁê J Iñ TÓêÁêx v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  TÓêÁê UÓêÁê J Iòx v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ J Ió TÓêÁê UÓêÁêx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  Iô TÓêÁê UÓêÁê Jx v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  UÓêÁê J Iõ TÓêÁêx v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  UÓêÁê J Iö TÓêÁêx v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ I÷ TÓêÁê UÓêÁê Jx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  TÓêÁê UÓêÁê J Iøx v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  Iù TÓêÁê UÓêÁê Jx v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  UÓêÁê J Iú TÓêÁêx v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ J Iû TÓêÁê UÓêÁêx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  Iü TÓêÁê UÓêÁê Jx v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  TÓêÁê UÓêÁê J Iýx v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  UÓêÁê J Iþ TÓêÁêx v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– UÓêÁê J Iÿ TÓêÁêx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  I€ TÓêÁê UÓêÁê Jx v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  UÓêÁê J I‚ TÓêÁêx v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö Iƒ TÓêÁê UÓêÁê Jx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  UÓêÁê J I„ TÓêÁêx v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  UÓêÁê J I… TÓêÁêx v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  TÓêÁê UÓêÁê J I†x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ TÓêÁê UÓêÁê J I‡x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  Iˆ TÓêÁê UÓêÁê Jx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  I‰ TÓêÁê UÓêÁê Jx v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  UÓêÁê J IŠ TÓêÁêx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö UÓêÁê J I‹ TÓêÁêx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  IŒ TÓêÁê UÓêÁê Jx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  UÓêÁê J IŽ TÓêÁêx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  I‘ TÓêÁê UÓêÁê Jx v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  J I’ TÓêÁê UÓêÁêx v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î I“ TÓêÁê UÓêÁê Jx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  J I” TÓêÁê UÓêÁêx v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  J I• TÓêÁê UÓêÁêx v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  UÓêÁê J I– TÓêÁêx v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® TÓêÁê UÓêÁê J I—x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  UÓêÁê J I˜ TÓêÁêx v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  I™ TÓêÁê UÓêÁê Jx v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  J Iš TÓêÁê UÓêÁêx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î UÓêÁê J I› TÓêÁêx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  J Iœ TÓêÁê UÓêÁêx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  Iž TÓêÁê UÓêÁê Jx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž IŸ TÓêÁê UÓêÁê Jx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  TÓêÁê UÓêÁê J I x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  J I¡ TÓêÁê UÓêÁêx v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  TÓêÁê UÓêÁê J I¢x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ I£ TÓêÁê UÓêÁê Jx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  UÓêÁê J I¤ TÓêÁêx v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  UÓêÁê J I¥ TÓêÁêx v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  UÓêÁê J I¦ TÓêÁêx v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ TÓêÁê UÓêÁê J I§x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  J I¨ TÓêÁê UÓêÁêx v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  I© TÓêÁê UÓêÁê Jx v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  UÓêÁê J Iª TÓêÁêx v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ UÓêÁê J I« TÓêÁêx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  TÓêÁê UÓêÁê J I¬x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  UÓêÁê J I­ TÓêÁêx v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  TÓêÁê UÓêÁê J I®x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– UÓêÁê J I¯ TÓêÁêx v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  TÓêÁê UÓêÁê J I°x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  TÓêÁê UÓêÁê J I±x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  UÓêÁê J I² TÓêÁêx v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á I³ TÓêÁê UÓêÁê Jx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  UÓêÁê J I´ TÓêÁêx v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  TÓêÁê UÓêÁê J Iµx v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  UÓêÁê J I¶ TÓêÁêx v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ UÓêÁê J I· TÓêÁêx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  I¸ TÓêÁê UÓêÁê Jx v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  UÓêÁê J I¹ TÓêÁêx v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  J Iº TÓêÁê UÓêÁêx v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á J I» TÓêÁê UÓêÁêx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  I¼ TÓêÁê UÓêÁê Jx v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  UÓêÁê J I½ TÓêÁêx v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  UÓêÁê J I¾ TÓêÁêx v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ UÓêÁê J I¿ TÓêÁêx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  TÓêÁê UÓêÁê J IÀx v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  IÁ TÓêÁê UÓêÁê Jx v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  UÓêÁê J I TÓêÁêx v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ Ià TÓêÁê UÓêÁê Jx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  UÓêÁê J IÄ TÓêÁêx v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  IÅ TÓêÁê UÓêÁê Jx v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  J IÆ TÓêÁê UÓêÁêx v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± J IÇ TÓêÁê UÓêÁêx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  IÈ TÓêÁê UÓêÁê Jx v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  IÉ TÓêÁê UÓêÁê Jx v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  UÓêÁê J IÊ TÓêÁêx v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ UÓêÁê J IË TÓêÁêx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  IÌ TÓêÁê UÓêÁê Jx v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  TÓêÁê UÓêÁê J IÍx v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  J IÎ TÓêÁê UÓêÁêx v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ UÓêÁê J IÏ TÓêÁêx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  UÓêÁê J IÐ TÓêÁêx v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  UÓêÁê J IÑ TÓêÁêx v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  J IÒ TÓêÁê UÓêÁêx v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É UÓêÁê J IÓ TÓêÁêx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  J IÔ TÓêÁê UÓêÁêx v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  UÓêÁê J IÕ TÓêÁêx v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  IÖ TÓêÁê UÓêÁê Jx v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© UÓêÁê J I× TÓêÁêx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  IØ TÓêÁê UÓêÁê Jx v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  UÓêÁê J IÙ TÓêÁêx v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  UÓêÁê J IÚ TÓêÁêx v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é UÓêÁê J IÛ TÓêÁêx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  IÜ TÓêÁê UÓêÁê Jx v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  UÓêÁê J IÝ TÓêÁêx v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  UÓêÁê J IÞ TÓêÁêx v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ UÓêÁê J Iß TÓêÁêx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  UÓêÁê J Ià TÓêÁêx v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  TÓêÁê UÓêÁê J Iáx v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  TÓêÁê UÓêÁê J Iâx v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù J Iã TÓêÁê UÓêÁêx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  J Iä TÓêÁê UÓêÁêx v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  TÓêÁê UÓêÁê J Iåx v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  UÓêÁê J Iæ TÓêÁêx v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ Iç TÓêÁê UÓêÁê Jx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  J Iè TÓêÁê UÓêÁêx v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  UÓêÁê J Ié TÓêÁêx v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  J Iê TÓêÁê UÓêÁêx v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù J Ië TÓêÁê UÓêÁêx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  TÓêÁê UÓêÁê J Iìx v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  UÓêÁê J Ií TÓêÁêx v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  UÓêÁê J Iî TÓêÁêx v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… J Iï TÓêÁê UÓêÁêx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  TÓêÁê UÓêÁê J Iðx v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  Iñ TÓêÁê UÓêÁê Jx v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  J Iò TÓêÁê UÓêÁêx v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Å UÓêÁê J Ió TÓêÁêx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Å  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  UÓêÁê J Iô TÓêÁêx v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  TÓêÁê UÓêÁê J Iõx v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  Iö TÓêÁê UÓêÁê Jx v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë TÓêÁê UÓêÁê J I÷x v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  J Iø TÓêÁê UÓêÁêx v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  Iù TÓêÁê UÓêÁê Jx v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  TÓêÁê UÓêÁê J Iúx v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« TÓêÁê UÓêÁê J Iûx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  UÓêÁê J Iü TÓêÁêx v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  TÓêÁê UÓêÁê J Iýx v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  UÓêÁê J Iþ TÓêÁêx v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë UÓêÁê J Iÿ TÓêÁêx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  UÓêÁê J I€ TÓêÁêx v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  J I TÓêÁê UÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  UÓêÁê J I‚ TÓêÁêx v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› UÓêÁê J Iƒ TÓêÁêx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  TÓêÁê UÓêÁê J I„x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  J I… TÓêÁê UÓêÁêx v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  UÓêÁê J I† TÓêÁêx v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û TÓêÁê UÓêÁê J I‡x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  UÓêÁê J Iˆ TÓêÁêx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  UÓêÁê J I‰ TÓêÁêx v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  IŠ TÓêÁê UÓêÁê Jx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» UÓêÁê J I‹ TÓêÁêx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  UÓêÁê J IŒ TÓêÁêx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  J IŽ TÓêÁê UÓêÁêx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û J I TÓêÁê UÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  UÓêÁê J I‘ TÓêÁêx v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  J I’ TÓêÁê UÓêÁêx v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ TÓêÁê UÓêÁê J I“x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  I” TÓêÁê UÓêÁê Jx v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  TÓêÁê UÓêÁê J I•x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  I– TÓêÁê UÓêÁê Jx v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç J I— TÓêÁê UÓêÁêx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  UÓêÁê J I˜ TÓêÁêx v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  I™ TÓêÁê UÓêÁê Jx v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  Iš TÓêÁê UÓêÁê Jx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ TÓêÁê UÓêÁê J I›x v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  Iœ TÓêÁê UÓêÁê Jx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  UÓêÁê J Iž TÓêÁêx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç UÓêÁê J IŸ TÓêÁêx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  UÓêÁê J I  TÓêÁêx v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  I¡ TÓêÁê UÓêÁê Jx v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  UÓêÁê J I¢ TÓêÁêx v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— TÓêÁê UÓêÁê J I£x v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  TÓêÁê UÓêÁê J I¤x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  TÓêÁê UÓêÁê J I¥x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  UÓêÁê J I¦ TÓêÁêx v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× TÓêÁê UÓêÁê J I§x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  UÓêÁê J I¨ TÓêÁêx v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  TÓêÁê UÓêÁê J I©x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  Iª TÓêÁê UÓêÁê Jx v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· TÓêÁê UÓêÁê J I«x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  UÓêÁê J I¬ TÓêÁêx v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  I­ TÓêÁê UÓêÁê Jx v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  TÓêÁê UÓêÁê J I®x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ UÓêÁê J I¯ TÓêÁêx v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  UÓêÁê J I° TÓêÁêx v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  TÓêÁê UÓêÁê J I±x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  I² TÓêÁê UÓêÁê Jx v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ I³ TÓêÁê UÓêÁê Jx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  I´ TÓêÁê UÓêÁê Jx v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  UÓêÁê J Iµ TÓêÁêx v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  UÓêÁê J I¶ TÓêÁêx v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï UÓêÁê J I· TÓêÁêx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  I¸ TÓêÁê UÓêÁê Jx v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  I¹ TÓêÁê UÓêÁê Jx v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  UÓêÁê J Iº TÓêÁêx v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ I» TÓêÁê UÓêÁê Jx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  UÓêÁê J I¼ TÓêÁêx v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  UÓêÁê J I½ TÓêÁêx v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  TÓêÁê UÓêÁê J I¾x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï TÓêÁê UÓêÁê J I¿x v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  UÓêÁê J IÀ TÓêÁêx v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  UÓêÁê J IÁ TÓêÁêx v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  I TÓêÁê UÓêÁê Jx v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ UÓêÁê J Ià TÓêÁêx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  TÓêÁê UÓêÁê J IÄx v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  J IÅ TÓêÁê UÓêÁêx v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  J IÆ TÓêÁê UÓêÁêx v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß TÓêÁê UÓêÁê J IÇx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  IÈ TÓêÁê UÓêÁê Jx v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  IÉ TÓêÁê UÓêÁê Jx v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  TÓêÁê UÓêÁê J IÊx v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ TÓêÁê UÓêÁê J IËx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  J IÌ TÓêÁê UÓêÁêx v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  UÓêÁê J IÍ TÓêÁêx v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  J IÎ TÓêÁê UÓêÁêx v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ UÓêÁê J IÏ TÓêÁêx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  IÐ TÓêÁê UÓêÁê Jx v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  TÓêÁê UÓêÁê J IÑx v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  UÓêÁê J IÒ TÓêÁêx v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ J IÓ TÓêÁê UÓêÁêx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  TÓêÁê UÓêÁê J IÔx v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  UÓêÁê J IÕ TÓêÁêx v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  IÖ TÓêÁê UÓêÁê Jx v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ TÓêÁê UÓêÁê J I×x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  Àó´”Ïûã"x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  (8Àó´”Ïûã(´|'/google.datastore.v1.Datastore/RunQueryÎ 7type.googleapis.com/google.datastore.v1.RunQueryRequest’Bdulcet-port-762þ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I:x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  bÈ¢M™› 8type.googleapis.com/google.datastore.v1.RunQueryResponseÛš ך™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  J I‘ TÓêÁê UÓêÁêx v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  UÓêÁê J I’ TÓêÁêx v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î J I“ TÓêÁê UÓêÁêx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  TÓêÁê UÓêÁê J I”x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  J I• TÓêÁê UÓêÁêx v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  J I– TÓêÁê UÓêÁêx v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® UÓêÁê J I— TÓêÁêx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  UÓêÁê J I˜ TÓêÁêx v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  I™ TÓêÁê UÓêÁê Jx v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  J Iš TÓêÁê UÓêÁêx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î I› TÓêÁê UÓêÁê Jx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  TÓêÁê UÓêÁê J Iœx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  Iž TÓêÁê UÓêÁê Jx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž UÓêÁê J IŸ TÓêÁêx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  I  TÓêÁê UÓêÁê Jx v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  UÓêÁê J I¡ TÓêÁêx v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  UÓêÁê J I¢ TÓêÁêx v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ J I£ TÓêÁê UÓêÁêx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  TÓêÁê UÓêÁê J I¤x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  UÓêÁê J I¥ TÓêÁêx v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  J I¦ TÓêÁê UÓêÁêx v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ I§ TÓêÁê UÓêÁê Jx v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  J I¨ TÓêÁê UÓêÁêx v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  TÓêÁê UÓêÁê J I©x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  UÓêÁê J Iª TÓêÁêx v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ I« TÓêÁê UÓêÁê Jx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  I¬ TÓêÁê UÓêÁê Jx v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  TÓêÁê UÓêÁê J I­x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  UÓêÁê J I® TÓêÁêx v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– UÓêÁê J I¯ TÓêÁêx v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  I° TÓêÁê UÓêÁê Jx v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  UÓêÁê J I± TÓêÁêx v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  TÓêÁê UÓêÁê J I²x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á I³ TÓêÁê UÓêÁê Jx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  UÓêÁê J I´ TÓêÁêx v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  J Iµ TÓêÁê UÓêÁêx v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  I¶ TÓêÁê UÓêÁê Jx v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ J I· TÓêÁê UÓêÁêx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  I¸ TÓêÁê UÓêÁê Jx v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  TÓêÁê UÓêÁê J I¹x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  Iº TÓêÁê UÓêÁê Jx v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á UÓêÁê J I» TÓêÁêx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  J I¼ TÓêÁê UÓêÁêx v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  UÓêÁê J I½ TÓêÁêx v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  I¾ TÓêÁê UÓêÁê Jx v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ UÓêÁê J I¿ TÓêÁêx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  TÓêÁê UÓêÁê J IÀx v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  UÓêÁê J IÁ TÓêÁêx v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  UÓêÁê J I TÓêÁêx v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ UÓêÁê J Ià TÓêÁêx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  IÄ TÓêÁê UÓêÁê Jx v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  TÓêÁê UÓêÁê J IÅx v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  IÆ TÓêÁê UÓêÁê Jx v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± UÓêÁê J IÇ TÓêÁêx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  TÓêÁê UÓêÁê J IÈx v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  TÓêÁê UÓêÁê J IÉx v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  UÓêÁê J IÊ TÓêÁêx v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ TÓêÁê UÓêÁê J IËx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  UÓêÁê J IÌ TÓêÁêx v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  UÓêÁê J IÍ TÓêÁêx v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  J IÎ TÓêÁê UÓêÁêx v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ UÓêÁê J IÏ TÓêÁêx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  IÐ TÓêÁê UÓêÁê Jx v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  IÑ TÓêÁê UÓêÁê Jx v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  UÓêÁê J IÒ TÓêÁêx v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É J IÓ TÓêÁê UÓêÁêx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  UÓêÁê J IÔ TÓêÁêx v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  J IÕ TÓêÁê UÓêÁêx v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  IÖ TÓêÁê UÓêÁê Jx v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© I× TÓêÁê UÓêÁê Jx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  IØ TÓêÁê UÓêÁê Jx v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  J IÙ TÓêÁê UÓêÁêx v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  J IÚ TÓêÁê UÓêÁêx v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é UÓêÁê J IÛ TÓêÁêx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  UÓêÁê J IÜ TÓêÁêx v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  IÝ TÓêÁê UÓêÁê Jx v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  TÓêÁê UÓêÁê J IÞx v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ UÓêÁê J Iß TÓêÁêx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  UÓêÁê J Ià TÓêÁêx v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  J Iá TÓêÁê UÓêÁêx v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  Iâ TÓêÁê UÓêÁê Jx v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù Iã TÓêÁê UÓêÁê Jx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  UÓêÁê J Iä TÓêÁêx v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  J Iå TÓêÁê UÓêÁêx v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  TÓêÁê UÓêÁê J Iæx v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ J Iç TÓêÁê UÓêÁêx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  J Iè TÓêÁê UÓêÁêx v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  TÓêÁê UÓêÁê J Iéx v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  UÓêÁê J Iê TÓêÁêx v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù UÓêÁê J Ië TÓêÁêx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  UÓêÁê J Iì TÓêÁêx v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  Ií TÓêÁê UÓêÁê Jx v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  J Iî TÓêÁê UÓêÁêx v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… UÓêÁê J Iï TÓêÁêx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  Ið TÓêÁê UÓêÁê Jx v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  J Iñ TÓêÁê UÓêÁêx v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  TÓêÁê UÓêÁê J Iòx v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Å UÓêÁê J Ió TÓêÁêx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Å  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  UÓêÁê J Iô TÓêÁêx v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  UÓêÁê J Iõ TÓêÁêx v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  J Iö TÓêÁê UÓêÁêx v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë I÷ TÓêÁê UÓêÁê Jx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  TÓêÁê UÓêÁê J Iøx v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  UÓêÁê J Iù TÓêÁêx v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  UÓêÁê J Iú TÓêÁêx v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« UÓêÁê J Iû TÓêÁêx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  UÓêÁê J Iü TÓêÁêx v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  Iý TÓêÁê UÓêÁê Jx v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  UÓêÁê J Iþ TÓêÁêx v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë TÓêÁê UÓêÁê J Iÿx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  I€ TÓêÁê UÓêÁê Jx v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  J I TÓêÁê UÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  J I‚ TÓêÁê UÓêÁêx v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› Iƒ TÓêÁê UÓêÁê Jx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  UÓêÁê J I„ TÓêÁêx v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  UÓêÁê J I… TÓêÁêx v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  UÓêÁê J I† TÓêÁêx v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û I‡ TÓêÁê UÓêÁê Jx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  UÓêÁê J Iˆ TÓêÁêx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  UÓêÁê J I‰ TÓêÁêx v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  UÓêÁê J IŠ TÓêÁêx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» I‹ TÓêÁê UÓêÁê Jx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  J IŒ TÓêÁê UÓêÁêx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  IŽ TÓêÁê UÓêÁê Jx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  UÓêÁê J I‘ TÓêÁêx v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  I’ TÓêÁê UÓêÁê Jx v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ J I“ TÓêÁê UÓêÁêx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  UÓêÁê J I” TÓêÁêx v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  UÓêÁê J I• TÓêÁêx v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  UÓêÁê J I– TÓêÁêx v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç TÓêÁê UÓêÁê J I—x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  J I˜ TÓêÁê UÓêÁêx v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  UÓêÁê J I™ TÓêÁêx v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  Iš TÓêÁê UÓêÁê Jx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ UÓêÁê J I› TÓêÁêx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  TÓêÁê UÓêÁê J Iœx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  UÓêÁê J Iž TÓêÁêx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç TÓêÁê UÓêÁê J IŸx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  UÓêÁê J I  TÓêÁêx v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  UÓêÁê J I¡ TÓêÁêx v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  UÓêÁê J I¢ TÓêÁêx v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— J I£ TÓêÁê UÓêÁêx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  UÓêÁê J I¤ TÓêÁêx v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  TÓêÁê UÓêÁê J I¥x v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  TÓêÁê UÓêÁê J I¦x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× UÓêÁê J I§ TÓêÁêx v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  I¨ TÓêÁê UÓêÁê Jx v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  I© TÓêÁê UÓêÁê Jx v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  Iª TÓêÁê UÓêÁê Jx v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· I« TÓêÁê UÓêÁê Jx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  TÓêÁê UÓêÁê J I¬x v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  TÓêÁê UÓêÁê J I­x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  I® TÓêÁê UÓêÁê Jx v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ UÓêÁê J I¯ TÓêÁêx v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  J I° TÓêÁê UÓêÁêx v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  I± TÓêÁê UÓêÁê Jx v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  J I² TÓêÁê UÓêÁêx v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ UÓêÁê J I³ TÓêÁêx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  TÓêÁê UÓêÁê J I´x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  Iµ TÓêÁê UÓêÁê Jx v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  UÓêÁê J I¶ TÓêÁêx v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï I· TÓêÁê UÓêÁê Jx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  TÓêÁê UÓêÁê J I¸x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  I¹ TÓêÁê UÓêÁê Jx v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  J Iº TÓêÁê UÓêÁêx v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ J I» TÓêÁê UÓêÁêx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  I¼ TÓêÁê UÓêÁê Jx v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  I½ TÓêÁê UÓêÁê Jx v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  UÓêÁê J I¾ TÓêÁêx v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï UÓêÁê J I¿ TÓêÁêx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  UÓêÁê J IÀ TÓêÁêx v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  J IÁ TÓêÁê UÓêÁêx v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  TÓêÁê UÓêÁê J IÂx v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ UÓêÁê J Ià TÓêÁêx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  UÓêÁê J IÄ TÓêÁêx v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  IÅ TÓêÁê UÓêÁê Jx v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  J IÆ TÓêÁê UÓêÁêx v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß UÓêÁê J IÇ TÓêÁêx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  IÈ TÓêÁê UÓêÁê Jx v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  J IÉ TÓêÁê UÓêÁêx v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  J IÊ TÓêÁê UÓêÁêx v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ IË TÓêÁê UÓêÁê Jx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  UÓêÁê J IÌ TÓêÁêx v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  TÓêÁê UÓêÁê J IÍx v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  UÓêÁê J IÎ TÓêÁêx v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ IÏ TÓêÁê UÓêÁê Jx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  IÐ TÓêÁê UÓêÁê Jx v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  UÓêÁê J IÑ TÓêÁêx v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  J IÒ TÓêÁê UÓêÁêx v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ J IÓ TÓêÁê UÓêÁêx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  TÓêÁê UÓêÁê J IÔx v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  J IÕ TÓêÁê UÓêÁêx v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  UÓêÁê J IÖ TÓêÁêx v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ TÓêÁê UÓêÁê J I×x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  IØ TÓêÁê UÓêÁê Jx v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  UÓêÁê J IÙ TÓêÁêx v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  UÓêÁê J IÚ TÓêÁêx v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  TÓêÁê UÓêÁê J IÛx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   UÓêÁê J IÜ TÓêÁêx v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   J IÝ TÓêÁê UÓêÁêx v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   UÓêÁê J IÞ TÓêÁêx v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà Iß TÓêÁê UÓêÁê Jx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  Ià TÓêÁê UÓêÁê Jx v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  UÓêÁê J Iá TÓêÁêx v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  J Iâ TÓêÁê UÓêÁêx v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù TÓêÁê UÓêÁê J Iãx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  UÓêÁê J Iä TÓêÁêx v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  UÓêÁê J Iå TÓêÁêx v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  J Iæ TÓêÁê UÓêÁêx v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ Iç TÓêÁê UÓêÁê Jx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  TÓêÁê UÓêÁê J Ièx v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  UÓêÁê J Ié TÓêÁêx v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  Iê TÓêÁê UÓêÁê Jx v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° TÓêÁê UÓêÁê J Iëx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  TÓêÁê UÓêÁê J Iìx v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  Ií TÓêÁê UÓêÁê Jx v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  TÓêÁê UÓêÁê J Iîx v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð TÓêÁê UÓêÁê J Iïx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Ið TÓêÁê UÓêÁê Jx v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  UÓêÁê J Iñ TÓêÁêx v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Iò TÓêÁê UÓêÁê Jx v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ Ió TÓêÁê UÓêÁê Jx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  Iô TÓêÁê UÓêÁê Jx v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  UÓêÁê J Iõ TÓêÁêx v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  Iö TÓêÁê UÓêÁê Jx v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ UÓêÁê J I÷ TÓêÁêx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  J Iø TÓêÁê UÓêÁêx v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  UÓêÁê J Iù TÓêÁêx v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  J Iú TÓêÁê UÓêÁêx v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ UÓêÁê J Iû TÓêÁêx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  UÓêÁê J Iü TÓêÁêx v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  UÓêÁê J Iý TÓêÁêx v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  UÓêÁê J Iþ TÓêÁêx v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè Iÿ TÓêÁê UÓêÁê Jx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  J I€ TÓêÁê UÓêÁêx v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  I‚ TÓêÁê UÓêÁê Jx v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ J Iƒ TÓêÁê UÓêÁêx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  UÓêÁê J I„ TÓêÁêx v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  I… TÓêÁê UÓêÁê Jx v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  UÓêÁê J I† TÓêÁêx v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ UÓêÁê J I‡ TÓêÁêx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  J Iˆ TÓêÁê UÓêÁêx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  TÓêÁê UÓêÁê J I‰x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  UÓêÁê J IŠ TÓêÁêx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ UÓêÁê J I‹ TÓêÁêx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  UÓêÁê J IŒ TÓêÁêx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  UÓêÁê J IŽ TÓêÁêx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø J I TÓêÁê UÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  UÓêÁê J I‘ TÓêÁêx v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  UÓêÁê J I’ TÓêÁêx v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ TÓêÁê UÓêÁê J I“x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  I” TÓêÁê UÓêÁê Jx v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  I• TÓêÁê UÓêÁê Jx v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  UÓêÁê J I– TÓêÁêx v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ I— TÓêÁê UÓêÁê Jx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  UÓêÁê J I˜ TÓêÁêx v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  TÓêÁê UÓêÁê J I™x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  UÓêÁê J Iš TÓêÁêx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ TÓêÁê UÓêÁê J I›x v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  UÓêÁê J Iœ TÓêÁêx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  TÓêÁê UÓêÁê J Ižx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä IŸ TÓêÁê UÓêÁê Jx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  UÓêÁê J I  TÓêÁêx v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  TÓêÁê UÓêÁê J I¡x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  I¢ TÓêÁê UÓêÁê Jx v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” UÓêÁê J I£ TÓêÁêx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  UÓêÁê J I¤ TÓêÁêx v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  I¥ TÓêÁê UÓêÁê Jx v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  I¦ TÓêÁê UÓêÁê Jx v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ J I§ TÓêÁê UÓêÁêx v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  TÓêÁê UÓêÁê J I¨x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  UÓêÁê J I© TÓêÁêx v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  Iª TÓêÁê UÓêÁê Jx v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ UÓêÁê J I« TÓêÁêx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  I¬ TÓêÁê UÓêÁê Jx v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  UÓêÁê J I­ TÓêÁêx v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  UÓêÁê J I® TÓêÁêx v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô UÓêÁê J I¯ TÓêÁêx v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  I° TÓêÁê UÓêÁê Jx v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  UÓêÁê J I± TÓêÁêx v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  J I² TÓêÁê UÓêÁêx v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ I³ TÓêÁê UÓêÁê Jx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  I´ TÓêÁê UÓêÁê Jx v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  TÓêÁê UÓêÁê J Iµx v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  I¶ TÓêÁê UÓêÁê Jx v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ UÓêÁê J I· TÓêÁêx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  I¸ TÓêÁê UÓêÁê Jx v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  UÓêÁê J I¹ TÓêÁêx v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  Iº TÓêÁê UÓêÁê Jx v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ UÓêÁê J I» TÓêÁêx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  Àó´”Ïûã"x v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  (8Àó´”Ïûã(»¢M™› 8type.googleapis.com/google.datastore.v1.RunQueryResponseÛš ך™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  I‘ TÓêÁê UÓêÁê Jx v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  TÓêÁê UÓêÁê J I’x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î TÓêÁê UÓêÁê J I“x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  TÓêÁê UÓêÁê J I”x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  UÓêÁê J I• TÓêÁêx v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  TÓêÁê UÓêÁê J I–x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® J I— TÓêÁê UÓêÁêx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  UÓêÁê J I˜ TÓêÁêx v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  TÓêÁê UÓêÁê J I™x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  TÓêÁê UÓêÁê J Išx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î J I› TÓêÁê UÓêÁêx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  Iœ TÓêÁê UÓêÁê Jx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  Iž TÓêÁê UÓêÁê Jx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž J IŸ TÓêÁê UÓêÁêx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  TÓêÁê UÓêÁê J I x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  UÓêÁê J I¡ TÓêÁêx v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  TÓêÁê UÓêÁê J I¢x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ UÓêÁê J I£ TÓêÁêx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  UÓêÁê J I¤ TÓêÁêx v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  J I¥ TÓêÁê UÓêÁêx v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  I¦ TÓêÁê UÓêÁê Jx v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ I§ TÓêÁê UÓêÁê Jx v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  I¨ TÓêÁê UÓêÁê Jx v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  J I© TÓêÁê UÓêÁêx v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  UÓêÁê J Iª TÓêÁêx v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ I« TÓêÁê UÓêÁê Jx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  I¬ TÓêÁê UÓêÁê Jx v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  TÓêÁê UÓêÁê J I­x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  I® TÓêÁê UÓêÁê Jx v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– J I¯ TÓêÁê UÓêÁêx v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  UÓêÁê J I° TÓêÁêx v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  UÓêÁê J I± TÓêÁêx v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  J I² TÓêÁê UÓêÁêx v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á UÓêÁê J I³ TÓêÁêx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  UÓêÁê J I´ TÓêÁêx v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  UÓêÁê J Iµ TÓêÁêx v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  I¶ TÓêÁê UÓêÁê Jx v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ J I· TÓêÁê UÓêÁêx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  TÓêÁê UÓêÁê J I¸x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  TÓêÁê UÓêÁê J I¹x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  Iº TÓêÁê UÓêÁê Jx v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á UÓêÁê J I» TÓêÁêx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  TÓêÁê UÓêÁê J I¼x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  UÓêÁê J I½ TÓêÁêx v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  I¾ TÓêÁê UÓêÁê Jx v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ UÓêÁê J I¿ TÓêÁêx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  IÀ TÓêÁê UÓêÁê Jx v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  IÁ TÓêÁê UÓêÁê Jx v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  J I TÓêÁê UÓêÁêx v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ UÓêÁê J Ià TÓêÁêx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  J IÄ TÓêÁê UÓêÁêx v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  UÓêÁê J IÅ TÓêÁêx v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  IÆ TÓêÁê UÓêÁê Jx v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± TÓêÁê UÓêÁê J IÇx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  J IÈ TÓêÁê UÓêÁêx v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  UÓêÁê J IÉ TÓêÁêx v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  UÓêÁê J IÊ TÓêÁêx v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ UÓêÁê J IË TÓêÁêx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  IÌ TÓêÁê UÓêÁê Jx v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  J IÍ TÓêÁê UÓêÁêx v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  UÓêÁê J IÎ TÓêÁêx v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ IÏ TÓêÁê UÓêÁê Jx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  TÓêÁê UÓêÁê J IÐx v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  TÓêÁê UÓêÁê J IÑx v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  UÓêÁê J IÒ TÓêÁêx v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É UÓêÁê J IÓ TÓêÁêx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  TÓêÁê UÓêÁê J IÔx v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  UÓêÁê J IÕ TÓêÁêx v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  UÓêÁê J IÖ TÓêÁêx v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© J I× TÓêÁê UÓêÁêx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  IØ TÓêÁê UÓêÁê Jx v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  J IÙ TÓêÁê UÓêÁêx v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  UÓêÁê J IÚ TÓêÁêx v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é J IÛ TÓêÁê UÓêÁêx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  UÓêÁê J IÜ TÓêÁêx v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  UÓêÁê J IÝ TÓêÁêx v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  IÞ TÓêÁê UÓêÁê Jx v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ J Iß TÓêÁê UÓêÁêx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  UÓêÁê J Ià TÓêÁêx v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  J Iá TÓêÁê UÓêÁêx v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  Iâ TÓêÁê UÓêÁê Jx v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù TÓêÁê UÓêÁê J Iãx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  UÓêÁê J Iä TÓêÁêx v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  J Iå TÓêÁê UÓêÁêx v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  TÓêÁê UÓêÁê J Iæx v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ UÓêÁê J Iç TÓêÁêx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  UÓêÁê J Iè TÓêÁêx v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  UÓêÁê J Ié TÓêÁêx v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  UÓêÁê J Iê TÓêÁêx v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù UÓêÁê J Ië TÓêÁêx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  Iì TÓêÁê UÓêÁê Jx v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  J Ií TÓêÁê UÓêÁêx v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  TÓêÁê UÓêÁê J Iîx v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… UÓêÁê J Iï TÓêÁêx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  UÓêÁê J Ið TÓêÁêx v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  Iñ TÓêÁê UÓêÁê Jx v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  TÓêÁê UÓêÁê J Iòx v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Å Ió TÓêÁê UÓêÁê Jx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Å  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  TÓêÁê UÓêÁê J Iôx v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  Iõ TÓêÁê UÓêÁê Jx v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  UÓêÁê J Iö TÓêÁêx v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë UÓêÁê J I÷ TÓêÁêx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  Iø TÓêÁê UÓêÁê Jx v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  Iù TÓêÁê UÓêÁê Jx v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  Iú TÓêÁê UÓêÁê Jx v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« J Iû TÓêÁê UÓêÁêx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  J Iü TÓêÁê UÓêÁêx v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  TÓêÁê UÓêÁê J Iýx v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  J Iþ TÓêÁê UÓêÁêx v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë UÓêÁê J Iÿ TÓêÁêx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  J I€ TÓêÁê UÓêÁêx v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  I‚ TÓêÁê UÓêÁê Jx v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› J Iƒ TÓêÁê UÓêÁêx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  UÓêÁê J I„ TÓêÁêx v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  J I… TÓêÁê UÓêÁêx v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  UÓêÁê J I† TÓêÁêx v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û TÓêÁê UÓêÁê J I‡x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  UÓêÁê J Iˆ TÓêÁêx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  I‰ TÓêÁê UÓêÁê Jx v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  IŠ TÓêÁê UÓêÁê Jx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» J I‹ TÓêÁê UÓêÁêx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  UÓêÁê J IŒ TÓêÁêx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  J IŽ TÓêÁê UÓêÁêx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û J I TÓêÁê UÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  J I TÓêÁê UÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  UÓêÁê J I‘ TÓêÁêx v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  J I’ TÓêÁê UÓêÁêx v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ TÓêÁê UÓêÁê J I“x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  J I” TÓêÁê UÓêÁêx v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  UÓêÁê J I• TÓêÁêx v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  J I– TÓêÁê UÓêÁêx v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç J I— TÓêÁê UÓêÁêx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  UÓêÁê J I˜ TÓêÁêx v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  UÓêÁê J I™ TÓêÁêx v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  Iš TÓêÁê UÓêÁê Jx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ TÓêÁê UÓêÁê J I›x v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  Iœ TÓêÁê UÓêÁê Jx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  J Iž TÓêÁê UÓêÁêx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç UÓêÁê J IŸ TÓêÁêx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  J I  TÓêÁê UÓêÁêx v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  I¡ TÓêÁê UÓêÁê Jx v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  I¢ TÓêÁê UÓêÁê Jx v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— UÓêÁê J I£ TÓêÁêx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  TÓêÁê UÓêÁê J I¤x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  I¥ TÓêÁê UÓêÁê Jx v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  I¦ TÓêÁê UÓêÁê Jx v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× TÓêÁê UÓêÁê J I§x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  UÓêÁê J I¨ TÓêÁêx v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  TÓêÁê UÓêÁê J I©x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  TÓêÁê UÓêÁê J Iªx v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· TÓêÁê UÓêÁê J I«x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  UÓêÁê J I¬ TÓêÁêx v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  TÓêÁê UÓêÁê J I­x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  UÓêÁê J I® TÓêÁêx v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ TÓêÁê UÓêÁê J I¯x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  I° TÓêÁê UÓêÁê Jx v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  I± TÓêÁê UÓêÁê Jx v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  I² TÓêÁê UÓêÁê Jx v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ UÓêÁê J I³ TÓêÁêx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  I´ TÓêÁê UÓêÁê Jx v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  Iµ TÓêÁê UÓêÁê Jx v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  UÓêÁê J I¶ TÓêÁêx v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï J I· TÓêÁê UÓêÁêx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  I¸ TÓêÁê UÓêÁê Jx v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  TÓêÁê UÓêÁê J I¹x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  TÓêÁê UÓêÁê J Iºx v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ J I» TÓêÁê UÓêÁêx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  I¼ TÓêÁê UÓêÁê Jx v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  I½ TÓêÁê UÓêÁê Jx v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  TÓêÁê UÓêÁê J I¾x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï UÓêÁê J I¿ TÓêÁêx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  IÀ TÓêÁê UÓêÁê Jx v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  IÁ TÓêÁê UÓêÁê Jx v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  J I TÓêÁê UÓêÁêx v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ UÓêÁê J Ià TÓêÁêx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  TÓêÁê UÓêÁê J IÄx v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  UÓêÁê J IÅ TÓêÁêx v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  IÆ TÓêÁê UÓêÁê Jx v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß J IÇ TÓêÁê UÓêÁêx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  UÓêÁê J IÈ TÓêÁêx v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  J IÉ TÓêÁê UÓêÁêx v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  J IÊ TÓêÁê UÓêÁêx v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ IË TÓêÁê UÓêÁê Jx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  IÌ TÓêÁê UÓêÁê Jx v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  J IÍ TÓêÁê UÓêÁêx v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  IÎ TÓêÁê UÓêÁê Jx v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ IÏ TÓêÁê UÓêÁê Jx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  UÓêÁê J IÐ TÓêÁêx v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  TÓêÁê UÓêÁê J IÑx v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  J IÒ TÓêÁê UÓêÁêx v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ J IÓ TÓêÁê UÓêÁêx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  UÓêÁê J IÔ TÓêÁêx v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  UÓêÁê J IÕ TÓêÁêx v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  TÓêÁê UÓêÁê J IÖx v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ I× TÓêÁê UÓêÁê Jx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  TÓêÁê UÓêÁê J IØx v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  IÙ TÓêÁê UÓêÁê Jx v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  UÓêÁê J IÚ TÓêÁêx v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  IÛ TÓêÁê UÓêÁê Jx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   IÜ TÓêÁê UÓêÁê Jx v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   TÓêÁê UÓêÁê J IÝx v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   UÓêÁê J IÞ TÓêÁêx v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà UÓêÁê J Iß TÓêÁêx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  Ià TÓêÁê UÓêÁê Jx v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  UÓêÁê J Iá TÓêÁêx v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  TÓêÁê UÓêÁê J Iâx v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù Iã TÓêÁê UÓêÁê Jx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Iä TÓêÁê UÓêÁê Jx v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  TÓêÁê UÓêÁê J Iåx v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  J Iæ TÓêÁê UÓêÁêx v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ UÓêÁê J Iç TÓêÁêx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  Iè TÓêÁê UÓêÁê Jx v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  UÓêÁê J Ié TÓêÁêx v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  UÓêÁê J Iê TÓêÁêx v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° TÓêÁê UÓêÁê J Iëx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  J Iì TÓêÁê UÓêÁêx v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  TÓêÁê UÓêÁê J Iíx v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  TÓêÁê UÓêÁê J Iîx v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð UÓêÁê J Iï TÓêÁêx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  TÓêÁê UÓêÁê J Iðx v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Iñ TÓêÁê UÓêÁê Jx v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  TÓêÁê UÓêÁê J Iòx v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ Ió TÓêÁê UÓêÁê Jx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  Iô TÓêÁê UÓêÁê Jx v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  TÓêÁê UÓêÁê J Iõx v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  UÓêÁê J Iö TÓêÁêx v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ UÓêÁê J I÷ TÓêÁêx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  J Iø TÓêÁê UÓêÁêx v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  J Iù TÓêÁê UÓêÁêx v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  UÓêÁê J Iú TÓêÁêx v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ UÓêÁê J Iû TÓêÁêx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  Iü TÓêÁê UÓêÁê Jx v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  UÓêÁê J Iý TÓêÁêx v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  UÓêÁê J Iþ TÓêÁêx v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè TÓêÁê UÓêÁê J Iÿx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  I€ TÓêÁê UÓêÁê Jx v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  I‚ TÓêÁê UÓêÁê Jx v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ Iƒ TÓêÁê UÓêÁê Jx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  I„ TÓêÁê UÓêÁê Jx v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  I… TÓêÁê UÓêÁê Jx v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  J I† TÓêÁê UÓêÁêx v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ J I‡ TÓêÁê UÓêÁêx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  UÓêÁê J Iˆ TÓêÁêx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  UÓêÁê J I‰ TÓêÁêx v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  UÓêÁê J IŠ TÓêÁêx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ TÓêÁê UÓêÁê J I‹x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  TÓêÁê UÓêÁê J IŒx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  UÓêÁê J IŽ TÓêÁêx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø J I TÓêÁê UÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  J I‘ TÓêÁê UÓêÁêx v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  I’ TÓêÁê UÓêÁê Jx v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ J I“ TÓêÁê UÓêÁêx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  I” TÓêÁê UÓêÁê Jx v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  UÓêÁê J I• TÓêÁêx v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  UÓêÁê J I– TÓêÁêx v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ TÓêÁê UÓêÁê J I—x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  TÓêÁê UÓêÁê J I˜x v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  TÓêÁê UÓêÁê J I™x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  TÓêÁê UÓêÁê J Išx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ UÓêÁê J I› TÓêÁêx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  Iœ TÓêÁê UÓêÁê Jx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  UÓêÁê J Iž TÓêÁêx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä TÓêÁê UÓêÁê J IŸx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  I  TÓêÁê UÓêÁê Jx v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  J I¡ TÓêÁê UÓêÁêx v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  TÓêÁê UÓêÁê J I¢x v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” UÓêÁê J I£ TÓêÁêx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  UÓêÁê J I¤ TÓêÁêx v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  UÓêÁê J I¥ TÓêÁêx v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  I¦ TÓêÁê UÓêÁê Jx v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ TÓêÁê UÓêÁê J I§x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  UÓêÁê J I¨ TÓêÁêx v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  J I© TÓêÁê UÓêÁêx v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  UÓêÁê J Iª TÓêÁêx v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ TÓêÁê UÓêÁê J I«x v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  UÓêÁê J I¬ TÓêÁêx v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  TÓêÁê UÓêÁê J I­x v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  UÓêÁê J I® TÓêÁêx v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô TÓêÁê UÓêÁê J I¯x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  UÓêÁê J I° TÓêÁêx v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  UÓêÁê J I± TÓêÁêx v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  I² TÓêÁê UÓêÁê Jx v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ I³ TÓêÁê UÓêÁê Jx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  UÓêÁê J I´ TÓêÁêx v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  UÓêÁê J Iµ TÓêÁêx v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  I¶ TÓêÁê UÓêÁê Jx v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ J I· TÓêÁê UÓêÁêx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  UÓêÁê J I¸ TÓêÁêx v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  I¹ TÓêÁê UÓêÁê Jx v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  UÓêÁê J Iº TÓêÁêx v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ I» TÓêÁê UÓêÁê Jx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  Àó´”Ïûã"x v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  (8Àó´”Ïûã(¶|'/google.datastore.v1.Datastore/RunQueryÎ 7type.googleapis.com/google.datastore.v1.RunQueryRequest’Bdulcet-port-762þ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I:x v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  bw'/google.datastore.v1.Datastore/RunQueryÉ 7type.googleapis.com/google.datastore.v1.RunQueryRequestBdulcet-port-762ù SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I:x v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  ¢M™› 8type.googleapis.com/google.datastore.v1.RunQueryResponseÛš ך™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  UÓêÁê J I¬ TÓêÁêx v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  I­ TÓêÁê UÓêÁê Jx v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  UÓêÁê J I® TÓêÁêx v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ UÓêÁê J I¯ TÓêÁêx v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  TÓêÁê UÓêÁê J I°x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  UÓêÁê J I± TÓêÁêx v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  J I² TÓêÁê UÓêÁêx v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– UÓêÁê J I³ TÓêÁêx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  UÓêÁê J I´ TÓêÁêx v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  TÓêÁê UÓêÁê J Iµx v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  I¶ TÓêÁê UÓêÁê Jx v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ TÓêÁê UÓêÁê J I·x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  UÓêÁê J I¸ TÓêÁêx v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  UÓêÁê J I¹ TÓêÁêx v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  UÓêÁê J Iº TÓêÁêx v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â I» TÓêÁê UÓêÁê Jx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  I¼ TÓêÁê UÓêÁê Jx v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  UÓêÁê J I½ TÓêÁêx v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  I¾ TÓêÁê UÓêÁê Jx v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ I¿ TÓêÁê UÓêÁê Jx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  IÀ TÓêÁê UÓêÁê Jx v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  IÁ TÓêÁê UÓêÁê Jx v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  UÓêÁê J I TÓêÁêx v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò TÓêÁê UÓêÁê J IÃx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  IÄ TÓêÁê UÓêÁê Jx v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  IÅ TÓêÁê UÓêÁê Jx v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  J IÆ TÓêÁê UÓêÁêx v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² UÓêÁê J IÇ TÓêÁêx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  UÓêÁê J IÈ TÓêÁêx v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  J IÉ TÓêÁê UÓêÁêx v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  TÓêÁê UÓêÁê J IÊx v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò TÓêÁê UÓêÁê J IËx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  IÌ TÓêÁê UÓêÁê Jx v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  IÍ TÓêÁê UÓêÁê Jx v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  UÓêÁê J IÎ TÓêÁêx v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š J IÏ TÓêÁê UÓêÁêx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  UÓêÁê J IÐ TÓêÁêx v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  TÓêÁê UÓêÁê J IÑx v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  UÓêÁê J IÒ TÓêÁêx v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê TÓêÁê UÓêÁê J IÓx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  IÔ TÓêÁê UÓêÁê Jx v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  UÓêÁê J IÕ TÓêÁêx v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  J IÖ TÓêÁê UÓêÁêx v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª I× TÓêÁê UÓêÁê Jx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  UÓêÁê J IØ TÓêÁêx v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  IÙ TÓêÁê UÓêÁê Jx v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  J IÚ TÓêÁê UÓêÁêx v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê J IÛ TÓêÁê UÓêÁêx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  TÓêÁê UÓêÁê J IÜx v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  J IÝ TÓêÁê UÓêÁêx v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  UÓêÁê J IÞ TÓêÁêx v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š TÓêÁê UÓêÁê J Ißx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  Ià TÓêÁê UÓêÁê Jx v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  Iá TÓêÁê UÓêÁê Jx v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  TÓêÁê UÓêÁê J Iâx v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú J Iã TÓêÁê UÓêÁêx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  UÓêÁê J Iä TÓêÁêx v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  Iå TÓêÁê UÓêÁê Jx v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  TÓêÁê UÓêÁê J Iæx v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º J Iç TÓêÁê UÓêÁêx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  J Iè TÓêÁê UÓêÁêx v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  UÓêÁê J Ié TÓêÁêx v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  UÓêÁê J Iê TÓêÁêx v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú J Ië TÓêÁê UÓêÁêx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  UÓêÁê J Iì TÓêÁêx v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  UÓêÁê J Ií TÓêÁêx v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  UÓêÁê J Iî TÓêÁêx v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† Iï TÓêÁê UÓêÁê Jx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  J Ið TÓêÁê UÓêÁêx v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  UÓêÁê J Iñ TÓêÁêx v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  J Iò TÓêÁê UÓêÁêx v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ UÓêÁê J Ió TÓêÁêx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  UÓêÁê J Iô TÓêÁêx v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  UÓêÁê J Iõ TÓêÁêx v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  UÓêÁê J Iö TÓêÁêx v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ J I÷ TÓêÁê UÓêÁêx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  UÓêÁê J Iø TÓêÁêx v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  Iù TÓêÁê UÓêÁê Jx v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  UÓêÁê J Iú TÓêÁêx v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ Iû TÓêÁê UÓêÁê Jx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  Iü TÓêÁê UÓêÁê Jx v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  UÓêÁê J Iý TÓêÁêx v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  TÓêÁê UÓêÁê J Iþx v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– Iÿ TÓêÁê UÓêÁê Jx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  TÓêÁê UÓêÁê J I€x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  I‚ TÓêÁê UÓêÁê Jx v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö UÓêÁê J Iƒ TÓêÁêx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  UÓêÁê J I„ TÓêÁêx v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  UÓêÁê J I… TÓêÁêx v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  I† TÓêÁê UÓêÁê Jx v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ UÓêÁê J I‡ TÓêÁêx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  J Iˆ TÓêÁê UÓêÁêx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  I‰ TÓêÁê UÓêÁê Jx v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  IŠ TÓêÁê UÓêÁê Jx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö J I‹ TÓêÁê UÓêÁêx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  IŒ TÓêÁê UÓêÁê Jx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  IŽ TÓêÁê UÓêÁê Jx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  UÓêÁê J I‘ TÓêÁêx v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  UÓêÁê J I’ TÓêÁêx v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î UÓêÁê J I“ TÓêÁêx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  J I” TÓêÁê UÓêÁêx v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  TÓêÁê UÓêÁê J I•x v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  I– TÓêÁê UÓêÁê Jx v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® I— TÓêÁê UÓêÁê Jx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  I˜ TÓêÁê UÓêÁê Jx v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  J I™ TÓêÁê UÓêÁêx v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  Iš TÓêÁê UÓêÁê Jx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î J I› TÓêÁê UÓêÁêx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  Iœ TÓêÁê UÓêÁê Jx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  Iž TÓêÁê UÓêÁê Jx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž TÓêÁê UÓêÁê J IŸx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  UÓêÁê J I  TÓêÁêx v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  UÓêÁê J I¡ TÓêÁêx v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  UÓêÁê J I¢ TÓêÁêx v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ UÓêÁê J I£ TÓêÁêx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  TÓêÁê UÓêÁê J I¤x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  I¥ TÓêÁê UÓêÁê Jx v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  J I¦ TÓêÁê UÓêÁêx v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ J I§ TÓêÁê UÓêÁêx v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  UÓêÁê J I¨ TÓêÁêx v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  UÓêÁê J I© TÓêÁêx v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  TÓêÁê UÓêÁê J Iªx v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ J I« TÓêÁê UÓêÁêx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  I¬ TÓêÁê UÓêÁê Jx v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  UÓêÁê J I­ TÓêÁêx v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  TÓêÁê UÓêÁê J I®x v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– TÓêÁê UÓêÁê J I¯x v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  UÓêÁê J I° TÓêÁêx v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  I± TÓêÁê UÓêÁê Jx v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  TÓêÁê UÓêÁê J I²x v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á I³ TÓêÁê UÓêÁê Jx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  I´ TÓêÁê UÓêÁê Jx v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  Iµ TÓêÁê UÓêÁê Jx v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  UÓêÁê J I¶ TÓêÁêx v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ UÓêÁê J I· TÓêÁêx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  UÓêÁê J I¸ TÓêÁêx v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  TÓêÁê UÓêÁê J I¹x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  Iº TÓêÁê UÓêÁê Jx v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á TÓêÁê UÓêÁê J I»x v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  J I¼ TÓêÁê UÓêÁêx v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  TÓêÁê UÓêÁê J I½x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  TÓêÁê UÓêÁê J I¾x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ UÓêÁê J I¿ TÓêÁêx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  J IÀ TÓêÁê UÓêÁêx v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  IÁ TÓêÁê UÓêÁê Jx v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  I TÓêÁê UÓêÁê Jx v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ TÓêÁê UÓêÁê J IÃx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  TÓêÁê UÓêÁê J IÄx v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  IÅ TÓêÁê UÓêÁê Jx v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  TÓêÁê UÓêÁê J IÆx v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± UÓêÁê J IÇ TÓêÁêx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  UÓêÁê J IÈ TÓêÁêx v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  UÓêÁê J IÉ TÓêÁêx v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  TÓêÁê UÓêÁê J IÊx v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ UÓêÁê J IË TÓêÁêx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  IÌ TÓêÁê UÓêÁê Jx v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  IÍ TÓêÁê UÓêÁê Jx v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  TÓêÁê UÓêÁê J IÎx v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ UÓêÁê J IÏ TÓêÁêx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  IÐ TÓêÁê UÓêÁê Jx v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  TÓêÁê UÓêÁê J IÑx v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  IÒ TÓêÁê UÓêÁê Jx v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É UÓêÁê J IÓ TÓêÁêx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  TÓêÁê UÓêÁê J IÔx v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  UÓêÁê J IÕ TÓêÁêx v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  TÓêÁê UÓêÁê J IÖx v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© UÓêÁê J I× TÓêÁêx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  UÓêÁê J IØ TÓêÁêx v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  UÓêÁê J IÙ TÓêÁêx v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  UÓêÁê J IÚ TÓêÁêx v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é J IÛ TÓêÁê UÓêÁêx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  J IÜ TÓêÁê UÓêÁêx v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  TÓêÁê UÓêÁê J IÝx v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  J IÞ TÓêÁê UÓêÁêx v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ Iß TÓêÁê UÓêÁê Jx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  J Ià TÓêÁê UÓêÁêx v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  J Iá TÓêÁê UÓêÁêx v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  Iâ TÓêÁê UÓêÁê Jx v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù J Iã TÓêÁê UÓêÁêx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  UÓêÁê J Iä TÓêÁêx v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  Iå TÓêÁê UÓêÁê Jx v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  UÓêÁê J Iæ TÓêÁêx v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ UÓêÁê J Iç TÓêÁêx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  UÓêÁê J Iè TÓêÁêx v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  UÓêÁê J Ié TÓêÁêx v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  J Iê TÓêÁê UÓêÁêx v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù UÓêÁê J Ië TÓêÁêx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  UÓêÁê J Iì TÓêÁêx v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  UÓêÁê J Ií TÓêÁêx v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  Iî TÓêÁê UÓêÁê Jx v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… UÓêÁê J Iï TÓêÁêx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  TÓêÁê UÓêÁê J Iðx v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  UÓêÁê J Iñ TÓêÁêx v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  TÓêÁê UÓêÁê J Iòx v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Å TÓêÁê UÓêÁê J Ióx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Å  Ȇ’”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  UÓêÁê J Iô TÓêÁêx v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  UÓêÁê J Iõ TÓêÁêx v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  Iö TÓêÁê UÓêÁê Jx v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë TÓêÁê UÓêÁê J I÷x v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  J Iø TÓêÁê UÓêÁêx v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  UÓêÁê J Iù TÓêÁêx v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  UÓêÁê J Iú TÓêÁêx v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« J Iû TÓêÁê UÓêÁêx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  Iü TÓêÁê UÓêÁê Jx v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  UÓêÁê J Iý TÓêÁêx v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  UÓêÁê J Iþ TÓêÁêx v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë UÓêÁê J Iÿ TÓêÁêx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  I€ TÓêÁê UÓêÁê Jx v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  UÓêÁê J I‚ TÓêÁêx v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› Iƒ TÓêÁê UÓêÁê Jx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  UÓêÁê J I„ TÓêÁêx v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  I… TÓêÁê UÓêÁê Jx v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  I† TÓêÁê UÓêÁê Jx v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û TÓêÁê UÓêÁê J I‡x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  UÓêÁê J Iˆ TÓêÁêx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  I‰ TÓêÁê UÓêÁê Jx v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  J IŠ TÓêÁê UÓêÁêx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» UÓêÁê J I‹ TÓêÁêx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  UÓêÁê J IŒ TÓêÁêx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  J I TÓêÁê UÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  IŽ TÓêÁê UÓêÁê Jx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  J I TÓêÁê UÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  I‘ TÓêÁê UÓêÁê Jx v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  I’ TÓêÁê UÓêÁê Jx v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ UÓêÁê J I“ TÓêÁêx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  I” TÓêÁê UÓêÁê Jx v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  UÓêÁê J I• TÓêÁêx v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  J I– TÓêÁê UÓêÁêx v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç UÓêÁê J I— TÓêÁêx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  UÓêÁê J I˜ TÓêÁêx v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  J I™ TÓêÁê UÓêÁêx v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  UÓêÁê J Iš TÓêÁêx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ J I› TÓêÁê UÓêÁêx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  UÓêÁê J Iœ TÓêÁêx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  TÓêÁê UÓêÁê J Ižx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç UÓêÁê J IŸ TÓêÁêx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  J I  TÓêÁê UÓêÁêx v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  TÓêÁê UÓêÁê J I¡x v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  J I¢ TÓêÁê UÓêÁêx v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— UÓêÁê J I£ TÓêÁêx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  UÓêÁê J I¤ TÓêÁêx v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  UÓêÁê J I¥ TÓêÁêx v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  TÓêÁê UÓêÁê J I¦x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× UÓêÁê J I§ TÓêÁêx v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  UÓêÁê J I¨ TÓêÁêx v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  J I© TÓêÁê UÓêÁêx v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  UÓêÁê J Iª TÓêÁêx v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· I« TÓêÁê UÓêÁê Jx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  J I¬ TÓêÁê UÓêÁêx v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  J I­ TÓêÁê UÓêÁêx v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  I® TÓêÁê UÓêÁê Jx v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ J I¯ TÓêÁê UÓêÁêx v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  TÓêÁê UÓêÁê J I°x v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  UÓêÁê J I± TÓêÁêx v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  J I² TÓêÁê UÓêÁêx v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ UÓêÁê J I³ TÓêÁêx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  J I´ TÓêÁê UÓêÁêx v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  J Iµ TÓêÁê UÓêÁêx v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  I¶ TÓêÁê UÓêÁê Jx v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï UÓêÁê J I· TÓêÁêx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  I¸ TÓêÁê UÓêÁê Jx v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  UÓêÁê J I¹ TÓêÁêx v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  TÓêÁê UÓêÁê J Iºx v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ TÓêÁê UÓêÁê J I»x v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  TÓêÁê UÓêÁê J I¼x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  I½ TÓêÁê UÓêÁê Jx v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  J I¾ TÓêÁê UÓêÁêx v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï UÓêÁê J I¿ TÓêÁêx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  TÓêÁê UÓêÁê J IÀx v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  UÓêÁê J IÁ TÓêÁêx v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  I TÓêÁê UÓêÁê Jx v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ UÓêÁê J Ià TÓêÁêx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  UÓêÁê J IÄ TÓêÁêx v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  TÓêÁê UÓêÁê J IÅx v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  IÆ TÓêÁê UÓêÁê Jx v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß UÓêÁê J IÇ TÓêÁêx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  UÓêÁê J IÈ TÓêÁêx v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  UÓêÁê J IÉ TÓêÁêx v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  UÓêÁê J IÊ TÓêÁêx v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ IË TÓêÁê UÓêÁê Jx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  J IÌ TÓêÁê UÓêÁêx v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  IÍ TÓêÁê UÓêÁê Jx v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  UÓêÁê J IÎ TÓêÁêx v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ UÓêÁê J IÏ TÓêÁêx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  UÓêÁê J IÐ TÓêÁêx v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  UÓêÁê J IÑ TÓêÁêx v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  UÓêÁê J IÒ TÓêÁêx v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ TÓêÁê UÓêÁê J IÓx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  IÔ TÓêÁê UÓêÁê Jx v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  UÓêÁê J IÕ TÓêÁêx v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  IÖ TÓêÁê UÓêÁê Jx v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ UÓêÁê J I× TÓêÁêx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  Àó´”Ïûã"x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  (8Àó´”Ïûã(¹|'/google.datastore.v1.Datastore/RunQueryÎ 7type.googleapis.com/google.datastore.v1.RunQueryRequest’Bdulcet-port-762þ SQChild"i g TÓêÁêPN __key__ ?*=; LQParent/TestIntegration_LargeQuery-t1565554003131850927* I:x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  bèÂo¹ß 8type.googleapis.com/google.datastore.v1.RunQueryResponseûÞ ÷Þ™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  I¼ TÓêÁê UÓêÁê Jx v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  TÓêÁê UÓêÁê J I½x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  TÓêÁê UÓêÁê J I¾x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì UÓêÁê J I¿ TÓêÁêx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  UÓêÁê J IÀ TÓêÁêx v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  UÓêÁê J IÁ TÓêÁêx v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  UÓêÁê J I TÓêÁêx v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ J Ià TÓêÁê UÓêÁêx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  IÄ TÓêÁê UÓêÁê Jx v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  TÓêÁê UÓêÁê J IÅx v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  J IÆ TÓêÁê UÓêÁêx v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ UÓêÁê J IÇ TÓêÁêx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  J IÈ TÓêÁê UÓêÁêx v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  J IÉ TÓêÁê UÓêÁêx v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  IÊ TÓêÁê UÓêÁê Jx v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ TÓêÁê UÓêÁê J IËx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  UÓêÁê J IÌ TÓêÁêx v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  UÓêÁê J IÍ TÓêÁêx v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  IÎ TÓêÁê UÓêÁê Jx v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü J IÏ TÓêÁê UÓêÁêx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  TÓêÁê UÓêÁê J IÐx v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  UÓêÁê J IÑ TÓêÁêx v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  UÓêÁê J IÒ TÓêÁêx v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ TÓêÁê UÓêÁê J IÓx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  UÓêÁê J IÔ TÓêÁêx v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  UÓêÁê J IÕ TÓêÁêx v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  IÖ TÓêÁê UÓêÁê Jx v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù J I× TÓêÁê UÓêÁêx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  UÓêÁê J IØ TÓêÁêx v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  TÓêÁê UÓêÁê J IÙx v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  UÓêÁê J IÚ TÓêÁêx v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ IÛ TÓêÁê UÓêÁê Jx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  J IÜ TÓêÁê UÓêÁêx v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  IÝ TÓêÁê UÓêÁê Jx v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  UÓêÁê J IÞ TÓêÁêx v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ J Iß TÓêÁê UÓêÁêx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  J Ià TÓêÁê UÓêÁêx v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  UÓêÁê J Iá TÓêÁêx v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  J Iâ TÓêÁê UÓêÁêx v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ UÓêÁê J Iã TÓêÁêx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  Iä TÓêÁê UÓêÁê Jx v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  UÓêÁê J Iå TÓêÁêx v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  Iæ TÓêÁê UÓêÁê Jx v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ Iç TÓêÁê UÓêÁê Jx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  Iè TÓêÁê UÓêÁê Jx v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  TÓêÁê UÓêÁê J Iéx v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  J Iê TÓêÁê UÓêÁêx v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² UÓêÁê J Ië TÓêÁêx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  J Iì TÓêÁê UÓêÁêx v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  J Ií TÓêÁê UÓêÁêx v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  TÓêÁê UÓêÁê J Iîx v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò UÓêÁê J Iï TÓêÁêx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  Ið TÓêÁê UÓêÁê Jx v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  UÓêÁê J Iñ TÓêÁêx v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  Iò TÓêÁê UÓêÁê Jx v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ TÓêÁê UÓêÁê J Ióx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  J Iô TÓêÁê UÓêÁêx v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  TÓêÁê UÓêÁê J Iõx v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  Iö TÓêÁê UÓêÁê Jx v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ J I÷ TÓêÁê UÓêÁêx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  UÓêÁê J Iø TÓêÁêx v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  UÓêÁê J Iù TÓêÁêx v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  UÓêÁê J Iú TÓêÁêx v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª J Iû TÓêÁê UÓêÁêx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  J Iü TÓêÁê UÓêÁêx v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  J Iý TÓêÁê UÓêÁêx v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  Iþ TÓêÁê UÓêÁê Jx v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê Iÿ TÓêÁê UÓêÁê Jx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  I€ TÓêÁê UÓêÁê Jx v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  I‚ TÓêÁê UÓêÁê Jx v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš J Iƒ TÓêÁê UÓêÁêx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  UÓêÁê J I„ TÓêÁêx v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  I… TÓêÁê UÓêÁê Jx v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  J I† TÓêÁê UÓêÁêx v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ TÓêÁê UÓêÁê J I‡x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  TÓêÁê UÓêÁê J Iˆx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  UÓêÁê J I‰ TÓêÁêx v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  UÓêÁê J IŠ TÓêÁêx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº J I‹ TÓêÁê UÓêÁêx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  IŒ TÓêÁê UÓêÁê Jx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  TÓêÁê UÓêÁê J IŽx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  TÓêÁê UÓêÁê J I‘x v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  J I’ TÓêÁê UÓêÁêx v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† UÓêÁê J I“ TÓêÁêx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  TÓêÁê UÓêÁê J I”x v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  I• TÓêÁê UÓêÁê Jx v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  UÓêÁê J I– TÓêÁêx v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ UÓêÁê J I— TÓêÁêx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  UÓêÁê J I˜ TÓêÁêx v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  J I™ TÓêÁê UÓêÁêx v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  Iš TÓêÁê UÓêÁê Jx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ I› TÓêÁê UÓêÁê Jx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  UÓêÁê J Iœ TÓêÁêx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  Iž TÓêÁê UÓêÁê Jx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ IŸ TÓêÁê UÓêÁê Jx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  Àó´”Ïûã"x v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  (8Àó´”Ïûã(Ųީ½ 8type.googleapis.com/google.datastore.v1.RunQueryResponseë¼ ç¼™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  UÓêÁê J IØ TÓêÁêx v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  IÙ TÓêÁê UÓêÁê Jx v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  TÓêÁê UÓêÁê J IÚx v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  IÛ TÓêÁê UÓêÁê Jx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   UÓêÁê J IÜ TÓêÁêx v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   IÝ TÓêÁê UÓêÁê Jx v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   TÓêÁê UÓêÁê J IÞx v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà UÓêÁê J Iß TÓêÁêx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  Ià TÓêÁê UÓêÁê Jx v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  TÓêÁê UÓêÁê J Iáx v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  TÓêÁê UÓêÁê J Iâx v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù TÓêÁê UÓêÁê J Iãx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  UÓêÁê J Iä TÓêÁêx v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Iå TÓêÁê UÓêÁê Jx v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  UÓêÁê J Iæ TÓêÁêx v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ Iç TÓêÁê UÓêÁê Jx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  J Iè TÓêÁê UÓêÁêx v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  UÓêÁê J Ié TÓêÁêx v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  Iê TÓêÁê UÓêÁê Jx v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° UÓêÁê J Ië TÓêÁêx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  Iì TÓêÁê UÓêÁê Jx v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  UÓêÁê J Ií TÓêÁêx v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  UÓêÁê J Iî TÓêÁêx v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð UÓêÁê J Iï TÓêÁêx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  UÓêÁê J Ið TÓêÁêx v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Iñ TÓêÁê UÓêÁê Jx v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Iò TÓêÁê UÓêÁê Jx v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ Ió TÓêÁê UÓêÁê Jx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  Iô TÓêÁê UÓêÁê Jx v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  UÓêÁê J Iõ TÓêÁêx v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  UÓêÁê J Iö TÓêÁêx v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ UÓêÁê J I÷ TÓêÁêx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  J Iø TÓêÁê UÓêÁêx v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  Iù TÓêÁê UÓêÁê Jx v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  Iú TÓêÁê UÓêÁê Jx v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ UÓêÁê J Iû TÓêÁêx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  UÓêÁê J Iü TÓêÁêx v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  UÓêÁê J Iý TÓêÁêx v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  Iþ TÓêÁê UÓêÁê Jx v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè TÓêÁê UÓêÁê J Iÿx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  I€ TÓêÁê UÓêÁê Jx v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  UÓêÁê J I‚ TÓêÁêx v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ TÓêÁê UÓêÁê J Iƒx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  UÓêÁê J I„ TÓêÁêx v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  UÓêÁê J I… TÓêÁêx v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  UÓêÁê J I† TÓêÁêx v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ UÓêÁê J I‡ TÓêÁêx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  Iˆ TÓêÁê UÓêÁê Jx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  UÓêÁê J I‰ TÓêÁêx v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  IŠ TÓêÁê UÓêÁê Jx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ I‹ TÓêÁê UÓêÁê Jx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  J IŒ TÓêÁê UÓêÁêx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  J I TÓêÁê UÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  UÓêÁê J IŽ TÓêÁêx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  J I‘ TÓêÁê UÓêÁêx v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  I’ TÓêÁê UÓêÁê Jx v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ I“ TÓêÁê UÓêÁê Jx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  I” TÓêÁê UÓêÁê Jx v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  J I• TÓêÁê UÓêÁêx v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  I– TÓêÁê UÓêÁê Jx v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ UÓêÁê J I— TÓêÁêx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  I˜ TÓêÁê UÓêÁê Jx v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  TÓêÁê UÓêÁê J I™x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  Iš TÓêÁê UÓêÁê Jx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ I› TÓêÁê UÓêÁê Jx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  TÓêÁê UÓêÁê J Iœx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  J I TÓêÁê UÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  J Iž TÓêÁê UÓêÁêx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä TÓêÁê UÓêÁê J IŸx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  UÓêÁê J I  TÓêÁêx v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  J I¡ TÓêÁê UÓêÁêx v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  UÓêÁê J I¢ TÓêÁêx v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” I£ TÓêÁê UÓêÁê Jx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  TÓêÁê UÓêÁê J I¤x v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  UÓêÁê J I¥ TÓêÁêx v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  TÓêÁê UÓêÁê J I¦x v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ TÓêÁê UÓêÁê J I§x v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  TÓêÁê UÓêÁê J I¨x v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  TÓêÁê UÓêÁê J I©x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  Iª TÓêÁê UÓêÁê Jx v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ J I« TÓêÁê UÓêÁêx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  I¬ TÓêÁê UÓêÁê Jx v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  I­ TÓêÁê UÓêÁê Jx v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  UÓêÁê J I® TÓêÁêx v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô UÓêÁê J I¯ TÓêÁêx v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  I° TÓêÁê UÓêÁê Jx v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  I± TÓêÁê UÓêÁê Jx v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  J I² TÓêÁê UÓêÁêx v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ I³ TÓêÁê UÓêÁê Jx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  I´ TÓêÁê UÓêÁê Jx v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  J Iµ TÓêÁê UÓêÁêx v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  J I¶ TÓêÁê UÓêÁêx v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ TÓêÁê UÓêÁê J I·x v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  I¸ TÓêÁê UÓêÁê Jx v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  UÓêÁê J I¹ TÓêÁêx v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  TÓêÁê UÓêÁê J Iºx v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ UÓêÁê J I» TÓêÁêx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  TÓêÁê UÓêÁê J I¼x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  J I½ TÓêÁê UÓêÁêx v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  J I¾ TÓêÁê UÓêÁêx v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì I¿ TÓêÁê UÓêÁê Jx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  UÓêÁê J IÀ TÓêÁêx v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  UÓêÁê J IÁ TÓêÁêx v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  UÓêÁê J I TÓêÁêx v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ Ià TÓêÁê UÓêÁê Jx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  J IÄ TÓêÁê UÓêÁêx v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  J IÅ TÓêÁê UÓêÁêx v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  IÆ TÓêÁê UÓêÁê Jx v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ J IÇ TÓêÁê UÓêÁêx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  IÈ TÓêÁê UÓêÁê Jx v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  IÉ TÓêÁê UÓêÁê Jx v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  UÓêÁê J IÊ TÓêÁêx v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ UÓêÁê J IË TÓêÁêx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  TÓêÁê UÓêÁê J IÌx v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  J IÍ TÓêÁê UÓêÁêx v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  UÓêÁê J IÎ TÓêÁêx v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü IÏ TÓêÁê UÓêÁê Jx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  IÐ TÓêÁê UÓêÁê Jx v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  UÓêÁê J IÑ TÓêÁêx v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  IÒ TÓêÁê UÓêÁê Jx v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ TÓêÁê UÓêÁê J IÓx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  UÓêÁê J IÔ TÓêÁêx v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  J IÕ TÓêÁê UÓêÁêx v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  IÖ TÓêÁê UÓêÁê Jx v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù TÓêÁê UÓêÁê J I×x v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  UÓêÁê J IØ TÓêÁêx v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  UÓêÁê J IÙ TÓêÁêx v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  IÚ TÓêÁê UÓêÁê Jx v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ UÓêÁê J IÛ TÓêÁêx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  UÓêÁê J IÜ TÓêÁêx v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  UÓêÁê J IÝ TÓêÁêx v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  IÞ TÓêÁê UÓêÁê Jx v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ UÓêÁê J Iß TÓêÁêx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  Ià TÓêÁê UÓêÁê Jx v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  Iá TÓêÁê UÓêÁê Jx v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  UÓêÁê J Iâ TÓêÁêx v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ J Iã TÓêÁê UÓêÁêx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  Iä TÓêÁê UÓêÁê Jx v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  Iå TÓêÁê UÓêÁê Jx v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  UÓêÁê J Iæ TÓêÁêx v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ Iç TÓêÁê UÓêÁê Jx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  Iè TÓêÁê UÓêÁê Jx v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  UÓêÁê J Ié TÓêÁêx v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  TÓêÁê UÓêÁê J Iêx v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² UÓêÁê J Ië TÓêÁêx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  J Iì TÓêÁê UÓêÁêx v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  J Ií TÓêÁê UÓêÁêx v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  Iî TÓêÁê UÓêÁê Jx v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò UÓêÁê J Iï TÓêÁêx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  J Ið TÓêÁê UÓêÁêx v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  TÓêÁê UÓêÁê J Iñx v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  Iò TÓêÁê UÓêÁê Jx v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ Ió TÓêÁê UÓêÁê Jx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  UÓêÁê J Iô TÓêÁêx v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  Iõ TÓêÁê UÓêÁê Jx v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  UÓêÁê J Iö TÓêÁêx v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ UÓêÁê J I÷ TÓêÁêx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  UÓêÁê J Iø TÓêÁêx v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  Iù TÓêÁê UÓêÁê Jx v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  Iú TÓêÁê UÓêÁê Jx v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª Iû TÓêÁê UÓêÁê Jx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  TÓêÁê UÓêÁê J Iüx v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  J Iý TÓêÁê UÓêÁêx v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  TÓêÁê UÓêÁê J Iþx v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê TÓêÁê UÓêÁê J Iÿx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  UÓêÁê J I€ TÓêÁêx v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  J I TÓêÁê UÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  I‚ TÓêÁê UÓêÁê Jx v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš UÓêÁê J Iƒ TÓêÁêx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  J I„ TÓêÁê UÓêÁêx v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  UÓêÁê J I… TÓêÁêx v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  UÓêÁê J I† TÓêÁêx v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ TÓêÁê UÓêÁê J I‡x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  Iˆ TÓêÁê UÓêÁê Jx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  J I‰ TÓêÁê UÓêÁêx v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  J IŠ TÓêÁê UÓêÁêx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº TÓêÁê UÓêÁê J I‹x v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  J IŒ TÓêÁê UÓêÁêx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  J I TÓêÁê UÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  UÓêÁê J IŽ TÓêÁêx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  UÓêÁê J I‘ TÓêÁêx v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  UÓêÁê J I’ TÓêÁêx v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† J I“ TÓêÁê UÓêÁêx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  UÓêÁê J I” TÓêÁêx v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  UÓêÁê J I• TÓêÁêx v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  J I– TÓêÁê UÓêÁêx v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ TÓêÁê UÓêÁê J I—x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  I˜ TÓêÁê UÓêÁê Jx v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  UÓêÁê J I™ TÓêÁêx v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  TÓêÁê UÓêÁê J Išx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ J I› TÓêÁê UÓêÁêx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  UÓêÁê J Iœ TÓêÁêx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  UÓêÁê J Iž TÓêÁêx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ TÓêÁê UÓêÁê J IŸx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  Àó´”Ïûã"x v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  (8Àó´”Ïûã(¿²Þ©½ 8type.googleapis.com/google.datastore.v1.RunQueryResponseë¼ ç¼™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  TÓêÁê UÓêÁê J IØx v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  J IÙ TÓêÁê UÓêÁêx v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  IÚ TÓêÁê UÓêÁê Jx v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  TÓêÁê UÓêÁê J IÛx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   UÓêÁê J IÜ TÓêÁêx v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   TÓêÁê UÓêÁê J IÝx v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   UÓêÁê J IÞ TÓêÁêx v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà TÓêÁê UÓêÁê J Ißx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  UÓêÁê J Ià TÓêÁêx v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  Iá TÓêÁê UÓêÁê Jx v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  UÓêÁê J Iâ TÓêÁêx v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù TÓêÁê UÓêÁê J Iãx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  TÓêÁê UÓêÁê J Iäx v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  UÓêÁê J Iå TÓêÁêx v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  J Iæ TÓêÁê UÓêÁêx v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ Iç TÓêÁê UÓêÁê Jx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  UÓêÁê J Iè TÓêÁêx v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  TÓêÁê UÓêÁê J Iéx v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  TÓêÁê UÓêÁê J Iêx v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° TÓêÁê UÓêÁê J Iëx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  Iì TÓêÁê UÓêÁê Jx v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  J Ií TÓêÁê UÓêÁêx v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  UÓêÁê J Iî TÓêÁêx v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð J Iï TÓêÁê UÓêÁêx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  J Ið TÓêÁê UÓêÁêx v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Iñ TÓêÁê UÓêÁê Jx v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Iò TÓêÁê UÓêÁê Jx v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ Ió TÓêÁê UÓêÁê Jx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  J Iô TÓêÁê UÓêÁêx v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  UÓêÁê J Iõ TÓêÁêx v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  Iö TÓêÁê UÓêÁê Jx v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ I÷ TÓêÁê UÓêÁê Jx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  J Iø TÓêÁê UÓêÁêx v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  J Iù TÓêÁê UÓêÁêx v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  TÓêÁê UÓêÁê J Iúx v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ J Iû TÓêÁê UÓêÁêx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  TÓêÁê UÓêÁê J Iüx v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  Iý TÓêÁê UÓêÁê Jx v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  Iþ TÓêÁê UÓêÁê Jx v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè TÓêÁê UÓêÁê J Iÿx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  TÓêÁê UÓêÁê J I€x v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  J I‚ TÓêÁê UÓêÁêx v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ Iƒ TÓêÁê UÓêÁê Jx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  TÓêÁê UÓêÁê J I„x v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  I… TÓêÁê UÓêÁê Jx v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  J I† TÓêÁê UÓêÁêx v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ J I‡ TÓêÁê UÓêÁêx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  Iˆ TÓêÁê UÓêÁê Jx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  TÓêÁê UÓêÁê J I‰x v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  J IŠ TÓêÁê UÓêÁêx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ I‹ TÓêÁê UÓêÁê Jx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  IŒ TÓêÁê UÓêÁê Jx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  UÓêÁê J IŽ TÓêÁêx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  UÓêÁê J I‘ TÓêÁêx v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  J I’ TÓêÁê UÓêÁêx v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ I“ TÓêÁê UÓêÁê Jx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  J I” TÓêÁê UÓêÁêx v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  I• TÓêÁê UÓêÁê Jx v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  J I– TÓêÁê UÓêÁêx v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ I— TÓêÁê UÓêÁê Jx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  I˜ TÓêÁê UÓêÁê Jx v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  J I™ TÓêÁê UÓêÁêx v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  UÓêÁê J Iš TÓêÁêx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ I› TÓêÁê UÓêÁê Jx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  UÓêÁê J Iœ TÓêÁêx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  UÓêÁê J Iž TÓêÁêx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä UÓêÁê J IŸ TÓêÁêx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  I  TÓêÁê UÓêÁê Jx v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  J I¡ TÓêÁê UÓêÁêx v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  UÓêÁê J I¢ TÓêÁêx v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” TÓêÁê UÓêÁê J I£x v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  UÓêÁê J I¤ TÓêÁêx v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  J I¥ TÓêÁê UÓêÁêx v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  J I¦ TÓêÁê UÓêÁêx v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ J I§ TÓêÁê UÓêÁêx v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  UÓêÁê J I¨ TÓêÁêx v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  TÓêÁê UÓêÁê J I©x v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  Iª TÓêÁê UÓêÁê Jx v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ UÓêÁê J I« TÓêÁêx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  UÓêÁê J I¬ TÓêÁêx v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  I­ TÓêÁê UÓêÁê Jx v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  UÓêÁê J I® TÓêÁêx v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô I¯ TÓêÁê UÓêÁê Jx v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  J I° TÓêÁê UÓêÁêx v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  TÓêÁê UÓêÁê J I±x v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  I² TÓêÁê UÓêÁê Jx v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ I³ TÓêÁê UÓêÁê Jx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  I´ TÓêÁê UÓêÁê Jx v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  J Iµ TÓêÁê UÓêÁêx v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  TÓêÁê UÓêÁê J I¶x v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ UÓêÁê J I· TÓêÁêx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  UÓêÁê J I¸ TÓêÁêx v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  UÓêÁê J I¹ TÓêÁêx v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  Iº TÓêÁê UÓêÁê Jx v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ TÓêÁê UÓêÁê J I»x v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  UÓêÁê J I¼ TÓêÁêx v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  I½ TÓêÁê UÓêÁê Jx v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  TÓêÁê UÓêÁê J I¾x v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì I¿ TÓêÁê UÓêÁê Jx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  J IÀ TÓêÁê UÓêÁêx v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  IÁ TÓêÁê UÓêÁê Jx v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  TÓêÁê UÓêÁê J IÂx v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ Ià TÓêÁê UÓêÁê Jx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  J IÄ TÓêÁê UÓêÁêx v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  TÓêÁê UÓêÁê J IÅx v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  TÓêÁê UÓêÁê J IÆx v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ IÇ TÓêÁê UÓêÁê Jx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  TÓêÁê UÓêÁê J IÈx v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  J IÉ TÓêÁê UÓêÁêx v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  UÓêÁê J IÊ TÓêÁêx v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ TÓêÁê UÓêÁê J IËx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  UÓêÁê J IÌ TÓêÁêx v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  J IÍ TÓêÁê UÓêÁêx v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  IÎ TÓêÁê UÓêÁê Jx v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü IÏ TÓêÁê UÓêÁê Jx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  UÓêÁê J IÐ TÓêÁêx v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  J IÑ TÓêÁê UÓêÁêx v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  TÓêÁê UÓêÁê J IÒx v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ J IÓ TÓêÁê UÓêÁêx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  IÔ TÓêÁê UÓêÁê Jx v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  UÓêÁê J IÕ TÓêÁêx v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  J IÖ TÓêÁê UÓêÁêx v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù UÓêÁê J I× TÓêÁêx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  J IØ TÓêÁê UÓêÁêx v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  UÓêÁê J IÙ TÓêÁêx v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  IÚ TÓêÁê UÓêÁê Jx v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ UÓêÁê J IÛ TÓêÁêx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  UÓêÁê J IÜ TÓêÁêx v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  UÓêÁê J IÝ TÓêÁêx v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  UÓêÁê J IÞ TÓêÁêx v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ Iß TÓêÁê UÓêÁê Jx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  UÓêÁê J Ià TÓêÁêx v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  J Iá TÓêÁê UÓêÁêx v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  Iâ TÓêÁê UÓêÁê Jx v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ TÓêÁê UÓêÁê J Iãx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  J Iä TÓêÁê UÓêÁêx v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  Iå TÓêÁê UÓêÁê Jx v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  Iæ TÓêÁê UÓêÁê Jx v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ Iç TÓêÁê UÓêÁê Jx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  UÓêÁê J Iè TÓêÁêx v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  Ié TÓêÁê UÓêÁê Jx v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  UÓêÁê J Iê TÓêÁêx v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² Ië TÓêÁê UÓêÁê Jx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  Iì TÓêÁê UÓêÁê Jx v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  Ií TÓêÁê UÓêÁê Jx v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  UÓêÁê J Iî TÓêÁêx v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò Iï TÓêÁê UÓêÁê Jx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  J Ið TÓêÁê UÓêÁêx v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  TÓêÁê UÓêÁê J Iñx v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  Iò TÓêÁê UÓêÁê Jx v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ TÓêÁê UÓêÁê J Ióx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  Iô TÓêÁê UÓêÁê Jx v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  Iõ TÓêÁê UÓêÁê Jx v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  UÓêÁê J Iö TÓêÁêx v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ I÷ TÓêÁê UÓêÁê Jx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  UÓêÁê J Iø TÓêÁêx v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  Iù TÓêÁê UÓêÁê Jx v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  Iú TÓêÁê UÓêÁê Jx v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª Iû TÓêÁê UÓêÁê Jx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  UÓêÁê J Iü TÓêÁêx v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  UÓêÁê J Iý TÓêÁêx v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  J Iþ TÓêÁê UÓêÁêx v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê UÓêÁê J Iÿ TÓêÁêx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  J I€ TÓêÁê UÓêÁêx v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  UÓêÁê J I‚ TÓêÁêx v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš TÓêÁê UÓêÁê J Iƒx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  I„ TÓêÁê UÓêÁê Jx v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  I… TÓêÁê UÓêÁê Jx v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  TÓêÁê UÓêÁê J I†x v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ J I‡ TÓêÁê UÓêÁêx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  UÓêÁê J Iˆ TÓêÁêx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  UÓêÁê J I‰ TÓêÁêx v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  J IŠ TÓêÁê UÓêÁêx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº J I‹ TÓêÁê UÓêÁêx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  IŒ TÓêÁê UÓêÁê Jx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  UÓêÁê J IŽ TÓêÁêx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  I‘ TÓêÁê UÓêÁê Jx v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  I’ TÓêÁê UÓêÁê Jx v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† UÓêÁê J I“ TÓêÁêx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  J I” TÓêÁê UÓêÁêx v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  UÓêÁê J I• TÓêÁêx v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  UÓêÁê J I– TÓêÁêx v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ TÓêÁê UÓêÁê J I—x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  UÓêÁê J I˜ TÓêÁêx v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  TÓêÁê UÓêÁê J I™x v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  Iš TÓêÁê UÓêÁê Jx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ UÓêÁê J I› TÓêÁêx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  J Iœ TÓêÁê UÓêÁêx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  UÓêÁê J Iž TÓêÁêx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ UÓêÁê J IŸ TÓêÁêx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  Àó´”Ïûã"x v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  (8Àó´”Ïûã(ÁÂo¹ß 8type.googleapis.com/google.datastore.v1.RunQueryResponseûÞ ÷Þ™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  TÓêÁê UÓêÁê J I¼x v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  J I½ TÓêÁê UÓêÁêx v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  J I¾ TÓêÁê UÓêÁêx v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì J I¿ TÓêÁê UÓêÁêx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  IÀ TÓêÁê UÓêÁê Jx v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  J IÁ TÓêÁê UÓêÁêx v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  J I TÓêÁê UÓêÁêx v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ Ià TÓêÁê UÓêÁê Jx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  IÄ TÓêÁê UÓêÁê Jx v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  TÓêÁê UÓêÁê J IÅx v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  J IÆ TÓêÁê UÓêÁêx v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ TÓêÁê UÓêÁê J IÇx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  UÓêÁê J IÈ TÓêÁêx v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  UÓêÁê J IÉ TÓêÁêx v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  UÓêÁê J IÊ TÓêÁêx v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ J IË TÓêÁê UÓêÁêx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  TÓêÁê UÓêÁê J IÌx v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  TÓêÁê UÓêÁê J IÍx v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  UÓêÁê J IÎ TÓêÁêx v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü J IÏ TÓêÁê UÓêÁêx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  UÓêÁê J IÐ TÓêÁêx v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  UÓêÁê J IÑ TÓêÁêx v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  IÒ TÓêÁê UÓêÁê Jx v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ UÓêÁê J IÓ TÓêÁêx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  J IÔ TÓêÁê UÓêÁêx v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  IÕ TÓêÁê UÓêÁê Jx v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  TÓêÁê UÓêÁê J IÖx v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù UÓêÁê J I× TÓêÁêx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  UÓêÁê J IØ TÓêÁêx v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  UÓêÁê J IÙ TÓêÁêx v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  UÓêÁê J IÚ TÓêÁêx v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ UÓêÁê J IÛ TÓêÁêx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  IÜ TÓêÁê UÓêÁê Jx v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  J IÝ TÓêÁê UÓêÁêx v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  J IÞ TÓêÁê UÓêÁêx v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ Iß TÓêÁê UÓêÁê Jx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  Ià TÓêÁê UÓêÁê Jx v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  UÓêÁê J Iá TÓêÁêx v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  UÓêÁê J Iâ TÓêÁêx v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ UÓêÁê J Iã TÓêÁêx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  UÓêÁê J Iä TÓêÁêx v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  UÓêÁê J Iå TÓêÁêx v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  UÓêÁê J Iæ TÓêÁêx v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ UÓêÁê J Iç TÓêÁêx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  J Iè TÓêÁê UÓêÁêx v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  TÓêÁê UÓêÁê J Iéx v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  J Iê TÓêÁê UÓêÁêx v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² Ië TÓêÁê UÓêÁê Jx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  J Iì TÓêÁê UÓêÁêx v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  TÓêÁê UÓêÁê J Iíx v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  UÓêÁê J Iî TÓêÁêx v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò Iï TÓêÁê UÓêÁê Jx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  UÓêÁê J Ið TÓêÁêx v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  J Iñ TÓêÁê UÓêÁêx v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  UÓêÁê J Iò TÓêÁêx v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ UÓêÁê J Ió TÓêÁêx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  TÓêÁê UÓêÁê J Iôx v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  TÓêÁê UÓêÁê J Iõx v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  TÓêÁê UÓêÁê J Iöx v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ J I÷ TÓêÁê UÓêÁêx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  J Iø TÓêÁê UÓêÁêx v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  UÓêÁê J Iù TÓêÁêx v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  Iú TÓêÁê UÓêÁê Jx v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª Iû TÓêÁê UÓêÁê Jx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  UÓêÁê J Iü TÓêÁêx v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  UÓêÁê J Iý TÓêÁêx v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  J Iþ TÓêÁê UÓêÁêx v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê J Iÿ TÓêÁê UÓêÁêx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  UÓêÁê J I€ TÓêÁêx v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  I‚ TÓêÁê UÓêÁê Jx v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš UÓêÁê J Iƒ TÓêÁêx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  I„ TÓêÁê UÓêÁê Jx v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  UÓêÁê J I… TÓêÁêx v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  I† TÓêÁê UÓêÁê Jx v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ J I‡ TÓêÁê UÓêÁêx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  TÓêÁê UÓêÁê J Iˆx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  I‰ TÓêÁê UÓêÁê Jx v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  UÓêÁê J IŠ TÓêÁêx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº I‹ TÓêÁê UÓêÁê Jx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  TÓêÁê UÓêÁê J IŒx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  UÓêÁê J IŽ TÓêÁêx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  UÓêÁê J I‘ TÓêÁêx v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  J I’ TÓêÁê UÓêÁêx v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† UÓêÁê J I“ TÓêÁêx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  UÓêÁê J I” TÓêÁêx v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  UÓêÁê J I• TÓêÁêx v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  UÓêÁê J I– TÓêÁêx v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ I— TÓêÁê UÓêÁê Jx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  J I˜ TÓêÁê UÓêÁêx v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  UÓêÁê J I™ TÓêÁêx v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  TÓêÁê UÓêÁê J Išx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ J I› TÓêÁê UÓêÁêx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  Iœ TÓêÁê UÓêÁê Jx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  UÓêÁê J Iž TÓêÁêx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ UÓêÁê J IŸ TÓêÁêx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  Àó´”Ïûã"x v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  (8Àó´”Ïûã(IJީ½ 8type.googleapis.com/google.datastore.v1.RunQueryResponseë¼ ç¼™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  UÓêÁê J IØ TÓêÁêx v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  UÓêÁê J IÙ TÓêÁêx v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  TÓêÁê UÓêÁê J IÚx v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  UÓêÁê J IÛ TÓêÁêx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   IÜ TÓêÁê UÓêÁê Jx v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   IÝ TÓêÁê UÓêÁê Jx v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   J IÞ TÓêÁê UÓêÁêx v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù   Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà UÓêÁê J Iß TÓêÁêx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  J Ià TÓêÁê UÓêÁêx v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  UÓêÁê J Iá TÓêÁêx v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  Iâ TÓêÁê UÓêÁê Jx v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù J Iã TÓêÁê UÓêÁêx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  UÓêÁê J Iä TÓêÁêx v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  J Iå TÓêÁê UÓêÁêx v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  UÓêÁê J Iæ TÓêÁêx v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ Iç TÓêÁê UÓêÁê Jx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  TÓêÁê UÓêÁê J Ièx v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  UÓêÁê J Ié TÓêÁêx v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  J Iê TÓêÁê UÓêÁêx v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° J Ië TÓêÁê UÓêÁêx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  J Iì TÓêÁê UÓêÁêx v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  Ií TÓêÁê UÓêÁê Jx v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  UÓêÁê J Iî TÓêÁêx v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð UÓêÁê J Iï TÓêÁêx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Ið TÓêÁê UÓêÁê Jx v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  J Iñ TÓêÁê UÓêÁêx v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  TÓêÁê UÓêÁê J Iòx v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ TÓêÁê UÓêÁê J Ióx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  Iô TÓêÁê UÓêÁê Jx v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  UÓêÁê J Iõ TÓêÁêx v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  Iö TÓêÁê UÓêÁê Jx v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ UÓêÁê J I÷ TÓêÁêx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  Iø TÓêÁê UÓêÁê Jx v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  UÓêÁê J Iù TÓêÁêx v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  UÓêÁê J Iú TÓêÁêx v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ TÓêÁê UÓêÁê J Iûx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  TÓêÁê UÓêÁê J Iüx v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  J Iý TÓêÁê UÓêÁêx v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  TÓêÁê UÓêÁê J Iþx v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè J Iÿ TÓêÁê UÓêÁêx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  I€ TÓêÁê UÓêÁê Jx v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  J I TÓêÁê UÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  UÓêÁê J I‚ TÓêÁêx v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ UÓêÁê J Iƒ TÓêÁêx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  J I„ TÓêÁê UÓêÁêx v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  UÓêÁê J I… TÓêÁêx v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  UÓêÁê J I† TÓêÁêx v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ TÓêÁê UÓêÁê J I‡x v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  UÓêÁê J Iˆ TÓêÁêx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  UÓêÁê J I‰ TÓêÁêx v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  UÓêÁê J IŠ TÓêÁêx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ J I‹ TÓêÁê UÓêÁêx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  TÓêÁê UÓêÁê J IŒx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  IŽ TÓêÁê UÓêÁê Jx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø TÓêÁê UÓêÁê J Ix v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  UÓêÁê J I‘ TÓêÁêx v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  UÓêÁê J I’ TÓêÁêx v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ TÓêÁê UÓêÁê J I“x v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  I” TÓêÁê UÓêÁê Jx v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  I• TÓêÁê UÓêÁê Jx v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  TÓêÁê UÓêÁê J I–x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ J I— TÓêÁê UÓêÁêx v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  I˜ TÓêÁê UÓêÁê Jx v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  I™ TÓêÁê UÓêÁê Jx v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  J Iš TÓêÁê UÓêÁêx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ I› TÓêÁê UÓêÁê Jx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  Iœ TÓêÁê UÓêÁê Jx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  Iž TÓêÁê UÓêÁê Jx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä IŸ TÓêÁê UÓêÁê Jx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  TÓêÁê UÓêÁê J I x v  I fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  J I¡ TÓêÁê UÓêÁêx v  I¡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  I¢ TÓêÁê UÓêÁê Jx v  I¢fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” UÓêÁê J I£ TÓêÁêx v  I£fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  I¤ TÓêÁê UÓêÁê Jx v  I¤fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  UÓêÁê J I¥ TÓêÁêx v  I¥fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  UÓêÁê J I¦ TÓêÁêx v  I¦fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ J I§ TÓêÁê UÓêÁêx v  I§fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  I¨ TÓêÁê UÓêÁê Jx v  I¨fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  J I© TÓêÁê UÓêÁêx v  I©fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  Iª TÓêÁê UÓêÁê Jx v  Iªfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ J I« TÓêÁê UÓêÁêx v  I«fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  UÓêÁê J I¬ TÓêÁêx v  I¬fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  J I­ TÓêÁê UÓêÁêx v  I­fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  UÓêÁê J I® TÓêÁêx v  I®fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô UÓêÁê J I¯ TÓêÁêx v  I¯fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  J I° TÓêÁê UÓêÁêx v  I°fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  UÓêÁê J I± TÓêÁêx v  I±fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  J I² TÓêÁê UÓêÁêx v  I²fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ J I³ TÓêÁê UÓêÁêx v  I³fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  TÓêÁê UÓêÁê J I´x v  I´fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  Iµ TÓêÁê UÓêÁê Jx v  Iµfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  J I¶ TÓêÁê UÓêÁêx v  I¶fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ I· TÓêÁê UÓêÁê Jx v  I·fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  TÓêÁê UÓêÁê J I¸x v  I¸fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  TÓêÁê UÓêÁê J I¹x v  I¹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  UÓêÁê J Iº TÓêÁêx v  Iºfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ I» TÓêÁê UÓêÁê Jx v  I»fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  UÓêÁê J I¼ TÓêÁêx v  I¼fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  TÓêÁê UÓêÁê J I½x v  I½fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  UÓêÁê J I¾ TÓêÁêx v  I¾fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì UÓêÁê J I¿ TÓêÁêx v  I¿fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  IÀ TÓêÁê UÓêÁê Jx v  IÀfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  IÁ TÓêÁê UÓêÁê Jx v  IÁfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  UÓêÁê J I TÓêÁêx v  IÂfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ J Ià TÓêÁê UÓêÁêx v  IÃfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  UÓêÁê J IÄ TÓêÁêx v  IÄfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  TÓêÁê UÓêÁê J IÅx v  IÅfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  UÓêÁê J IÆ TÓêÁêx v  IÆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ IÇ TÓêÁê UÓêÁê Jx v  IÇfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  TÓêÁê UÓêÁê J IÈx v  IÈfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  TÓêÁê UÓêÁê J IÉx v  IÉfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  UÓêÁê J IÊ TÓêÁêx v  IÊfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ UÓêÁê J IË TÓêÁêx v  IËfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  TÓêÁê UÓêÁê J IÌx v  IÌfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  IÍ TÓêÁê UÓêÁê Jx v  IÍfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  UÓêÁê J IÎ TÓêÁêx v  IÎfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü IÏ TÓêÁê UÓêÁê Jx v  IÏfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  TÓêÁê UÓêÁê J IÐx v  IÐfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  TÓêÁê UÓêÁê J IÑx v  IÑfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  TÓêÁê UÓêÁê J IÒx v  IÒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ UÓêÁê J IÓ TÓêÁêx v  IÓfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  IÔ TÓêÁê UÓêÁê Jx v  IÔfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  J IÕ TÓêÁê UÓêÁêx v  IÕfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  TÓêÁê UÓêÁê J IÖx v  IÖfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù I× TÓêÁê UÓêÁê Jx v  I×fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  J IØ TÓêÁê UÓêÁêx v  IØfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  IÙ TÓêÁê UÓêÁê Jx v  IÙfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  J IÚ TÓêÁê UÓêÁêx v  IÚfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ UÓêÁê J IÛ TÓêÁêx v  IÛfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  UÓêÁê J IÜ TÓêÁêx v  IÜfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  UÓêÁê J IÝ TÓêÁêx v  IÝfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  UÓêÁê J IÞ TÓêÁêx v  IÞfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ J Iß TÓêÁê UÓêÁêx v  Ißfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  TÓêÁê UÓêÁê J Iàx v  Iàfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  TÓêÁê UÓêÁê J Iáx v  Iáfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  Iâ TÓêÁê UÓêÁê Jx v  Iâfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ UÓêÁê J Iã TÓêÁêx v  Iãfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  UÓêÁê J Iä TÓêÁêx v  Iäfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  TÓêÁê UÓêÁê J Iåx v  Iåfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  TÓêÁê UÓêÁê J Iæx v  Iæfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ J Iç TÓêÁê UÓêÁêx v  Içfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  UÓêÁê J Iè TÓêÁêx v  Ièfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  UÓêÁê J Ié TÓêÁêx v  Iéfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  TÓêÁê UÓêÁê J Iêx v  Iêfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² Ië TÓêÁê UÓêÁê Jx v  Iëfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  J Iì TÓêÁê UÓêÁêx v  Iìfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  TÓêÁê UÓêÁê J Iíx v  Iífjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  TÓêÁê UÓêÁê J Iîx v  Iîfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò TÓêÁê UÓêÁê J Iïx v  Iïfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  TÓêÁê UÓêÁê J Iðx v  Iðfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  UÓêÁê J Iñ TÓêÁêx v  Iñfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  TÓêÁê UÓêÁê J Iòx v  Iòfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ Ió TÓêÁê UÓêÁê Jx v  Iófjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  UÓêÁê J Iô TÓêÁêx v  Iôfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  TÓêÁê UÓêÁê J Iõx v  Iõfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  Iö TÓêÁê UÓêÁê Jx v  Iöfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ UÓêÁê J I÷ TÓêÁêx v  I÷fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  Iø TÓêÁê UÓêÁê Jx v  Iøfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  J Iù TÓêÁê UÓêÁêx v  Iùfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  TÓêÁê UÓêÁê J Iúx v  Iúfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª UÓêÁê J Iû TÓêÁêx v  Iûfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  Iü TÓêÁê UÓêÁê Jx v  Iüfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  Iý TÓêÁê UÓêÁê Jx v  Iýfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  TÓêÁê UÓêÁê J Iþx v  Iþfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê UÓêÁê J Iÿ TÓêÁêx v  Iÿfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  UÓêÁê J I€ TÓêÁêx v  I€fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  J I‚ TÓêÁê UÓêÁêx v  I‚fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš TÓêÁê UÓêÁê J Iƒx v  Iƒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  UÓêÁê J I„ TÓêÁêx v  I„fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  UÓêÁê J I… TÓêÁêx v  I…fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  I† TÓêÁê UÓêÁê Jx v  I†fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ UÓêÁê J I‡ TÓêÁêx v  I‡fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  UÓêÁê J Iˆ TÓêÁêx v  Iˆfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  I‰ TÓêÁê UÓêÁê Jx v  I‰fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  TÓêÁê UÓêÁê J IŠx v  IŠfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº UÓêÁê J I‹ TÓêÁêx v  I‹fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  J IŒ TÓêÁê UÓêÁêx v  IŒfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  TÓêÁê UÓêÁê J IŽx v  IŽfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú UÓêÁê J I TÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  J I TÓêÁê UÓêÁêx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  UÓêÁê J I‘ TÓêÁêx v  I‘fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  TÓêÁê UÓêÁê J I’x v  I’fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† UÓêÁê J I“ TÓêÁêx v  I“fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  UÓêÁê J I” TÓêÁêx v  I”fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  UÓêÁê J I• TÓêÁêx v  I•fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  TÓêÁê UÓêÁê J I–x v  I–fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ TÓêÁê UÓêÁê J I—x v  I—fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  I˜ TÓêÁê UÓêÁê Jx v  I˜fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  I™ TÓêÁê UÓêÁê Jx v  I™fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  UÓêÁê J Iš TÓêÁêx v  Išfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ UÓêÁê J I› TÓêÁêx v  I›fjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  UÓêÁê J Iœ TÓêÁêx v  Iœfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  I TÓêÁê UÓêÁê Jx v  Ifjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  UÓêÁê J Iž TÓêÁêx v  Ižfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦  Àó´”Ïûã™ “ d dulcet-port-762; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ IŸ TÓêÁê UÓêÁê Jx v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  Àó´”Ïûã"x v  IŸfjs~dulcet-port-762rQ LQParent"/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùæ  (8Àó´”Ïûã(Çd%/google.datastore.v1.Datastore/CommitêÇ 5type.googleapis.com/google.datastore.v1.CommitRequest¯Ç(2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‹ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ë 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹«2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹« 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ë 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹›2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹› 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Û 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹»2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹» 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹û 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹‡ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ç 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹§ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ç 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹—2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹— 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹×2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹× 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹·2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹· 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹÷ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ï 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¯ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ï 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹Ÿ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ß 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹¿ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Î¹ÿ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù€ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÀ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù  2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùà 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÐ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù°2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù° 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùð 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùˆ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÈ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¨ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùè 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù˜ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùØ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¸ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùø 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù„ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÄ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¤ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùä 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù”2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù” 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÔ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù´ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùô 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŒ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÌ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¬ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùì 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùœ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÜ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¼ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùü 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù‚ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÂ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¢ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùâ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù’ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÒ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù²2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù² 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùò 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùŠ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÊ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùª 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùê 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùš 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÚ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùº 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îùú 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù†2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù† 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùÆ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡Îù¦ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€‡ÎùæBdulcet-port-762* ¢ 6type.googleapis.com/google.datastore.v1.CommitResponseç ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã ¨ö‰•Ïûã  1(ͦ%/google.datastore.v1.Datastore/CommitÒÌ 5type.googleapis.com/google.datastore.v1.CommitRequest—Ì(2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ• 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÕ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæµ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæõ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÍ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ­ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæí 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÝ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ½ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæý 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæƒ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÃ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ£ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæã 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ“ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÓ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ³ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæó 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‹ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæË 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ«2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ« 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæë 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ›2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ› 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÛ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ»2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ» 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæû 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ‡ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÇ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ§ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæç 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ—2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ— 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ×2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ× 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ·2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ· 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ÷ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÏ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¯ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæï 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæŸ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæß 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæ¿ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûãæÿ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–€ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–À 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–  2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–à 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ð 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–°2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–° 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ð 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ˆ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–È 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¨ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–è 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–˜ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ø 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¸ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ø 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–„ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ä 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¤ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ä 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–”2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–” 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ô 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–´ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ô 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Œ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ì 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¬ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ì 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–œ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ü 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¼ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ü 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‚ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Â2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¢ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–â 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–’ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ò 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–²2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–² 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ò 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Š 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ê 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ª 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ê 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–š 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ú 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–º 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ú 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–†2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–† 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Æ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¦ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–æ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã––2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–– 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ö 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¶ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ö 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ž 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Î 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–®2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–® 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–î 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ž 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Þ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¾ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–þ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã– 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Á 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¡ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–á 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‘ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ñ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–±2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–± 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ñ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–‰ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–É 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–©2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–© 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–é 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–™ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–Ù 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–¹ 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ù 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–…2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–… 2S:Q; LQParent/TestIntegration_LargeQuery-t1565554003131850927 SQChild€€€ûã–ÅBdulcet-port-762º+ 6type.googleapis.com/google.datastore.v1.CommitResponseÿ* ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ࢕Ïûã ŒR(Ï%/google.datastore.v1.Datastore/CommitÙ 5type.googleapis.com/google.datastore.v1.CommitRequestŸ(2" QD SQParent8TestIntegration_EventualConsistency-t1565554003131850927 SQChild TÓêÁê UÓêÁê I J2" QD SQParent8TestIntegration_EventualConsistency-t1565554003131850927 SQChild I J TÓêÁê UÓêÁê2" QD SQParent8TestIntegration_EventualConsistency-t1565554003131850927 SQChild UÓêÁê I J TÓêÁêBdulcet-port-762³« 6type.googleapis.com/google.datastore.v1.CommitResponseðxm dulcet-port-762D SQParent8TestIntegration_EventualConsistency-t1565554003131850927 SQChild€€€§ˆáŒ ˜µØ•Ïûãxm dulcet-port-762D SQParent8TestIntegration_EventualConsistency-t1565554003131850927 SQChild€€€§ˆáŒ ˜µØ•Ïûãxm dulcet-port-762D SQParent8TestIntegration_EventualConsistency-t1565554003131850927 SQChild€€€§ˆáŒ ˜µØ•Ïûã ?(Ñ'/google.datastore.v1.Datastore/RunQueryà 7type.googleapis.com/google.datastore.v1.RunQueryRequest¤ Bdulcet-port-762Œ __key__ SQChild"r p TÓêÁêYW __key__ H*FD SQParent8TestIntegration_EventualConsistency-t1565554003131850927MF 8type.googleapis.com/google.datastore.v1.RunQueryResponse " ((Ó“%/google.datastore.v1.Datastore/Commitç 5type.googleapis.com/google.datastore.v1.CommitRequest­(2\:ZD SQParent8TestIntegration_EventualConsistency-t1565554003131850927 SQChild€€€§ˆáŒ 2\:ZD SQParent8TestIntegration_EventualConsistency-t1565554003131850927 SQChild€€€§ˆáŒ 2\:ZD SQParent8TestIntegration_EventualConsistency-t1565554003131850927 SQChild€€€§ˆáŒ Bdulcet-port-762d] 6type.googleapis.com/google.datastore.v1.CommitResponse# ØÆç•Ïûã ØÆç•Ïûã ØÆç•Ïûã ?(ÕÞ%/google.datastore.v1.Datastore/Commit² 5type.googleapis.com/google.datastore.v1.CommitRequestø(2x"v H; SQParent/TestIntegration_Projection-t1565554003131850927 SQChild I Jd TÓêÁê UÓêÁê2x"v H; SQParent/TestIntegration_Projection-t1565554003131850927 SQChild TÓêÁê UÓêÁê I Jd2y"w H; SQParent/TestIntegration_Projection-t1565554003131850927 SQChild I JÈ TÓêÁê UÓêÁê2y"w H; SQParent/TestIntegration_Projection-t1565554003131850927 SQChild UÓêÁê I J¬ TÓêÁê2y"w H; SQParent/TestIntegration_Projection-t1565554003131850927 SQChild TÓêÁê UÓêÁê I J¬Bdulcet-port-762zò 6type.googleapis.com/google.datastore.v1.CommitResponse·od dulcet-port-762; SQParent/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³ ˜áó•Ïûãod dulcet-port-762; SQParent/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³ ˜áó•Ïûãod dulcet-port-762; SQParent/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³ ˜áó•Ïûãod dulcet-port-762; SQParent/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³Ð ˜áó•Ïûãod dulcet-port-762; SQParent/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³Ð ˜áó•Ïûã i(× '/google.datastore.v1.Datastore/RunQueryÝ 7type.googleapis.com/google.datastore.v1.RunQueryRequest¡Bdulcet-port-762 J SQChild"y w TÓêÁê J–PN __key__ ?*=; SQParent/TestIntegration_Projection-t1565554003131850927¢š 8type.googleapis.com/google.datastore.v1.RunQueryResponseÝ Úî r d dulcet-port-762; SQParent/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³  JpÈx v  JÈfjs~dulcet-port-762rQ SQParent"/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³  î r d dulcet-port-762; SQParent/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³Ð Jp¬x v  J¬fjs~dulcet-port-762rQ SQParent"/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³Ð  î r d dulcet-port-762; SQParent/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³Ð  Jp¬x v  J¬fjs~dulcet-port-762rQ SQParent"/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³Ð  "x v  J¬fjs~dulcet-port-762rQ SQParent"/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³Ð  (8˜áó•Ïûã(Ù'/google.datastore.v1.Datastore/RunQueryâ 7type.googleapis.com/google.datastore.v1.RunQueryRequest¦Bdulcet-port-762’ J SQChild"y w TÓêÁê J–PN __key__ ?*=; SQParent/TestIntegration_Projection-t15655540031318509272Jyñ 8type.googleapis.com/google.datastore.v1.RunQueryResponse´ ±† r d dulcet-port-762; SQParent/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³  JpÈ   JÈ † r d dulcet-port-762; SQParent/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³Ð Jp¬   J¬ "   J¬ (8˜áó•Ïûã(Û'/google.datastore.v1.Datastore/RunQueryâ 7type.googleapis.com/google.datastore.v1.RunQueryRequest¦Bdulcet-port-762’ J SQChild"y w TÓêÁê J–PN __key__ ?*=; SQParent/TestIntegration_Projection-t15655540031318509272Jyñ 8type.googleapis.com/google.datastore.v1.RunQueryResponse´ ±† r d dulcet-port-762; SQParent/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³  JpÈ   JÈ † r d dulcet-port-762; SQParent/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³Ð Jp¬   J¬ "   J¬ (8˜áó•Ïûã(Ý '/google.datastore.v1.Datastore/RunQueryÝ 7type.googleapis.com/google.datastore.v1.RunQueryRequest¡Bdulcet-port-762 U SQChild"y w TÓêÁê J–PN __key__ ?*=; SQParent/TestIntegration_Projection-t1565554003131850927çß 8type.googleapis.com/google.datastore.v1.RunQueryResponse¢ Ÿ€ u d dulcet-port-762; SQParent/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³  UpÓêÁê† ƒ  JÈ UÓêÁêfjs~dulcet-port-762rQ SQParent"/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³  € u d dulcet-port-762; SQParent/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³Ð UpÓêÁê† ƒ  J¬ UÓêÁêfjs~dulcet-port-762rQ SQParent"/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³Ð  € u d dulcet-port-762; SQParent/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³Ð  UpÓêÁê† ƒ  J¬ UÓêÁêfjs~dulcet-port-762rQ SQParent"/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³Ð  "† ƒ  J¬ UÓêÁêfjs~dulcet-port-762rQ SQParent"/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³Ð  (8˜áó•Ïûã(ß '/google.datastore.v1.Datastore/RunQueryÝ 7type.googleapis.com/google.datastore.v1.RunQueryRequest¡Bdulcet-port-762 J SQChild"y w TÓêÁê J–PN __key__ ?*=; SQParent/TestIntegration_Projection-t1565554003131850927¢š 8type.googleapis.com/google.datastore.v1.RunQueryResponseÝ Úî r d dulcet-port-762; SQParent/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³  JpÈx v  JÈfjs~dulcet-port-762rQ SQParent"/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³  î r d dulcet-port-762; SQParent/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³Ð Jp¬x v  J¬fjs~dulcet-port-762rQ SQParent"/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³Ð  î r d dulcet-port-762; SQParent/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³Ð  Jp¬x v  J¬fjs~dulcet-port-762rQ SQParent"/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³Ð  "x v  J¬fjs~dulcet-port-762rQ SQParent"/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³Ð  (8˜áó•Ïûã(á'/google.datastore.v1.Datastore/RunQueryâ 7type.googleapis.com/google.datastore.v1.RunQueryRequest¦Bdulcet-port-762’ J SQChild"y w TÓêÁê J–PN __key__ ?*=; SQParent/TestIntegration_Projection-t15655540031318509272Jyñ 8type.googleapis.com/google.datastore.v1.RunQueryResponse´ ±† r d dulcet-port-762; SQParent/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³  JpÈ   JÈ † r d dulcet-port-762; SQParent/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³Ð Jp¬   J¬ "   J¬ (8˜áó•Ïûã(ã'/google.datastore.v1.Datastore/RunQueryâ 7type.googleapis.com/google.datastore.v1.RunQueryRequest¦Bdulcet-port-762’ J SQChild"y w TÓêÁê J–PN __key__ ?*=; SQParent/TestIntegration_Projection-t15655540031318509272Jyñ 8type.googleapis.com/google.datastore.v1.RunQueryResponse´ ±† r d dulcet-port-762; SQParent/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³  JpÈ   JÈ † r d dulcet-port-762; SQParent/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³Ð Jp¬   J¬ "   J¬ (8˜áó•Ïûã(å '/google.datastore.v1.Datastore/RunQueryÝ 7type.googleapis.com/google.datastore.v1.RunQueryRequest¡Bdulcet-port-762 U SQChild"y w TÓêÁê J–PN __key__ ?*=; SQParent/TestIntegration_Projection-t1565554003131850927çß 8type.googleapis.com/google.datastore.v1.RunQueryResponse¢ Ÿ€ u d dulcet-port-762; SQParent/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³  UpÓêÁê† ƒ  JÈ UÓêÁêfjs~dulcet-port-762rQ SQParent"/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³  € u d dulcet-port-762; SQParent/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³Ð UpÓêÁê† ƒ  J¬ UÓêÁêfjs~dulcet-port-762rQ SQParent"/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³Ð  € u d dulcet-port-762; SQParent/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³Ð  UpÓêÁê† ƒ  J¬ UÓêÁêfjs~dulcet-port-762rQ SQParent"/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³Ð  "† ƒ  J¬ UÓêÁêfjs~dulcet-port-762rQ SQParent"/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³Ð  (8˜áó•Ïûã(ç"%/google.datastore.v1.Datastore/Commitö 5type.googleapis.com/google.datastore.v1.CommitRequest¼(2S:Q; SQParent/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³ 2S:Q; SQParent/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³ 2S:Q; SQParent/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³ 2S:Q; SQParent/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³Ð2S:Q; SQParent/TestIntegration_Projection-t1565554003131850927 SQChild€€€§‘³Ð Bdulcet-port-762zs 6type.googleapis.com/google.datastore.v1.CommitResponse9 èã¡–Ïûã èã¡–Ïûã èã¡–Ïûã èã¡–Ïûã èã¡–Ïûã i(éÁ*/google.datastore.v1.Datastore/AllocateIds :type.googleapis.com/google.datastore.v1.AllocateIdsRequestR  AllocID  AllocID  AllocID  AllocID  AllocIDBdulcet-port-762 ;type.googleapis.com/google.datastore.v1.AllocateIdsResponseÍ ' dulcet-port-762 AllocID€€€Ç´Ñš ' dulcet-port-762 AllocID€€€Ç´Ñš ' dulcet-port-762 AllocID€€€Ç´Ñš ' dulcet-port-762 AllocID€€€Ç´ÑÚ ' dulcet-port-762 AllocID€€€Ç´ÑÚ (ëì%/google.datastore.v1.Datastore/CommitÀ 5type.googleapis.com/google.datastore.v1.CommitRequest†(2q2o [H SQParent¶ 8type.googleapis.com/google.datastore.v1.RunQueryResponseù ö¢ K I dulcet-port-762' Tweedletweedle-t1565554003131850927 Deedee0S QKjs~dulcet-port-762r6 Tweedle"tweedle-t1565554003131850927 Dee"dee0  ¢ K I dulcet-port-762' Tweedletweedle-t1565554003131850927 Dumdum1S QKjs~dulcet-port-762r6 Tweedle"tweedle-t1565554003131850927 Dum"dum1  ¢ K I dulcet-port-762' Tweedletweedle-t1565554003131850927 Dumdum2S QKjs~dulcet-port-762r6 Tweedle"tweedle-t1565554003131850927 Dum"dum2  ¢ K I dulcet-port-762' Tweedletweedle-t1565554003131850927 Dumdum3S QKjs~dulcet-port-762r6 Tweedle"tweedle-t1565554003131850927 Dum"dum3  "S QKjs~dulcet-port-762r6 Tweedle"tweedle-t1565554003131850927 Dum"dum3  (8˜ÊΖÏûã(ƒº'/google.datastore.v1.Datastore/RunQueryŒ 7type.googleapis.com/google.datastore.v1.RunQueryRequestQBdulcet-port-762>"<: __key__ +*)' Tweedletweedle-t1565554003131850927äÜ 8type.googleapis.com/google.datastore.v1.RunQueryResponseŸ œÊ j I dulcet-port-762' Tweedletweedle-t1565554003131850927 Deedee0 Why Š binary0001 IS QKjs~dulcet-port-762r6 Tweedle"tweedle-t1565554003131850927 Dee"dee0  ˜ÊΖÏûãÌ l I dulcet-port-762' Tweedletweedle-t1565554003131850927 Dumdum1 Pling Š binary0010 IS QKjs~dulcet-port-762r6 Tweedle"tweedle-t1565554003131850927 Dum"dum1  ˜ÊΖÏûãÌ l I dulcet-port-762' Tweedletweedle-t1565554003131850927 Dumdum2 I Pling Š binary0100S QKjs~dulcet-port-762r6 Tweedle"tweedle-t1565554003131850927 Dum"dum2  ˜ÊΖÏûãÌ l I dulcet-port-762' Tweedletweedle-t1565554003131850927 Dumdum3 I Pling Š binary1000S QKjs~dulcet-port-762r6 Tweedle"tweedle-t1565554003131850927 Dum"dum3  ˜ÊΖÏûã"S QKjs~dulcet-port-762r6 Tweedle"tweedle-t1565554003131850927 Dum"dum3  (8˜ÊΖÏûã(…'/google.datastore.v1.Datastore/RunQueryî 7type.googleapis.com/google.datastore.v1.RunQueryRequest²Bdulcet-port-762ž __key__"Ž ‹IG __key__8*6' Tweedletweedle-t1565554003131850927 Dumdum2<: __key__ +*)' Tweedletweedle-t1565554003131850927OÇ 8type.googleapis.com/google.datastore.v1.RunQueryResponseŠ ‡¢ K I dulcet-port-762' Tweedletweedle-t1565554003131850927 Dumdum2S QKjs~dulcet-port-762r6 Tweedle"tweedle-t1565554003131850927 Dum"dum2  "S QKjs~dulcet-port-762r6 Tweedle"tweedle-t1565554003131850927 Dum"dum2  (8˜ÊΖÏûã(‡'/google.datastore.v1.Datastore/RunQueryá 7type.googleapis.com/google.datastore.v1.RunQueryRequest¥Bdulcet-port-762‘"Ž ‹IG __key__8*6' Tweedletweedle-t1565554003131850927 Dumdum2<: __key__ +*)' Tweedletweedle-t1565554003131850927yñ 8type.googleapis.com/google.datastore.v1.RunQueryResponse´ ±Ì l I dulcet-port-762' Tweedletweedle-t1565554003131850927 Dumdum2 Pling Š binary0100 IS QKjs~dulcet-port-762r6 Tweedle"tweedle-t1565554003131850927 Dum"dum2  ˜ÊΖÏûã"S QKjs~dulcet-port-762r6 Tweedle"tweedle-t1565554003131850927 Dum"dum2  (8˜ÊΖÏûã(‰Ö'/google.datastore.v1.Datastore/RunQuery¨ 7type.googleapis.com/google.datastore.v1.RunQueryRequestmBdulcet-port-762Z __key__"<: __key__ +*)' Tweedletweedle-t1565554003131850927* __key__>¶ 8type.googleapis.com/google.datastore.v1.RunQueryResponseù ö¢ K I dulcet-port-762' Tweedletweedle-t1565554003131850927 Deedee0S QKjs~dulcet-port-762r6 Tweedle"tweedle-t1565554003131850927 Dee"dee0  ¢ K I dulcet-port-762' Tweedletweedle-t1565554003131850927 Dumdum1S QKjs~dulcet-port-762r6 Tweedle"tweedle-t1565554003131850927 Dum"dum1  ¢ K I dulcet-port-762' Tweedletweedle-t1565554003131850927 Dumdum2S QKjs~dulcet-port-762r6 Tweedle"tweedle-t1565554003131850927 Dum"dum2  ¢ K I dulcet-port-762' Tweedletweedle-t1565554003131850927 Dumdum3S QKjs~dulcet-port-762r6 Tweedle"tweedle-t1565554003131850927 Dum"dum3  "S QKjs~dulcet-port-762r6 Tweedle"tweedle-t1565554003131850927 Dum"dum3  (8˜ÊΖÏûã(‹É'/google.datastore.v1.Datastore/RunQuery› 7type.googleapis.com/google.datastore.v1.RunQueryRequest`Bdulcet-port-762M"<: __key__ +*)' Tweedletweedle-t1565554003131850927* __key__äÜ 8type.googleapis.com/google.datastore.v1.RunQueryResponseŸ œÊ j I dulcet-port-762' Tweedletweedle-t1565554003131850927 Deedee0 Why Š binary0001 IS QKjs~dulcet-port-762r6 Tweedle"tweedle-t1565554003131850927 Dee"dee0  ˜ÊΖÏûãÌ l I dulcet-port-762' Tweedletweedle-t1565554003131850927 Dumdum1 I Pling Š binary0010S QKjs~dulcet-port-762r6 Tweedle"tweedle-t1565554003131850927 Dum"dum1  ˜ÊΖÏûãÌ l I dulcet-port-762' Tweedletweedle-t1565554003131850927 Dumdum2 I Pling Š binary0100S QKjs~dulcet-port-762r6 Tweedle"tweedle-t1565554003131850927 Dum"dum2  ˜ÊΖÏûãÌ l I dulcet-port-762' Tweedletweedle-t1565554003131850927 Dumdum3 I Pling Š binary1000S QKjs~dulcet-port-762r6 Tweedle"tweedle-t1565554003131850927 Dum"dum3  ˜ÊΖÏûã"S QKjs~dulcet-port-762r6 Tweedle"tweedle-t1565554003131850927 Dum"dum3  (8˜ÊΖÏûã(Ü'/google.datastore.v1.Datastore/RunQuery® 7type.googleapis.com/google.datastore.v1.RunQueryRequestsBdulcet-port-762` __key__"Q O  I<: __key__ +*)' Tweedletweedle-t1565554003131850927TK %type.googleapis.com/google.rpc.Status"kind is required for filter: I (Ö'/google.datastore.v1.Datastore/RunQuery¨ 7type.googleapis.com/google.datastore.v1.RunQueryRequestmBdulcet-port-762Z __key__"<: __key__ +*)' Tweedletweedle-t1565554003131850927* __key__ne %type.googleapis.com/google.rpc.Status<8kind is required for all orders except __key__ ascending (‘ª%/google.datastore.v1.Datastore/Commit 5type.googleapis.com/google.datastore.v1.CommitRequestF(21"/  TransCounter N  T R ÓêÁê¯Åï>Bdulcet-port-762|u 6type.googleapis.com/google.datastore.v1.CommitResponse;7, dulcet-port-762 TransCounter€€€§ýŒ ¸ —Ïûã (“‰//google.datastore.v1.Datastore/BeginTransactionT ?type.googleapis.com/google.datastore.v1.BeginTransactionRequestBdulcet-port-762²ª @type.googleapis.com/google.datastore.v1.BeginTransactionResponsef d:ÖbÆÜî¿"Y#¢Ä­[°Jí§’XˆÜèÑˉ¸ãÍù¥²Ÿ.}923ú[[žaéÞF.Œ„ú›±y 8ÓÜØÔ³své>åï8»õc}ºõÙ#Ãø£Ô¡m‰å<• ’ªbþÞ(•ú%/google.datastore.v1.Datastore/LookupÎ 5type.googleapis.com/google.datastore.v1.LookupRequest” fd:ÖbÆÜî¿"Y#¢Ä­[°Jí§’XˆÜèÑˉ¸ãÍù¥²Ÿ.}923ú[[žaéÞF.Œ„ú›±y 8ÓÜØÔ³své>åï8»õc}ºõÙ#Ãø£Ô¡m‰å<• ’ªbþÞ TransCounter€€€§ýŒ Bdulcet-port-762š’ 6type.googleapis.com/google.datastore.v1.LookupResponseX V K , dulcet-port-762 TransCounter€€€§ýŒ  N  T R ÓêÁê¾ï> ¸ —Ïûã(—%/google.datastore.v1.Datastore/Commitï 5type.googleapis.com/google.datastore.v1.CommitRequestµ(2:28  TransCounter€€€§ýŒ  T R ÓêÁê¾ï> N Bdulcet-port-762 d:ÖbÆÜî¿"Y#¢Ä­[°Jí§’XˆÜèÑˉ¸ãÍù¥²Ÿ.}923ú[[žaéÞF.Œ„ú›±y 8ÓÜØÔ³své>åï8»õc}ºõÙ#Ãø£Ô¡m‰å<• ’ªbþÞWP 6type.googleapis.com/google.datastore.v1.CommitResponse °Ã¡—Ïûã (°Ã¡—Ïûã(™%/google.datastore.v1.Datastore/Lookupe 5type.googleapis.com/google.datastore.v1.LookupRequest, TransCounter€€€§ýŒ Bdulcet-port-762š’ 6type.googleapis.com/google.datastore.v1.LookupResponseX V K , dulcet-port-762 TransCounter€€€§ýŒ  T R ÓêÁê¾ï> N °Ã¡—Ïûã(›”%/google.datastore.v1.Datastore/Commiti 5type.googleapis.com/google.datastore.v1.CommitRequest0(2: TransCounter€€€§ýŒ Bdulcet-port-762NG 6type.googleapis.com/google.datastore.v1.CommitResponse  ˜’´—Ïûã (ª%/google.datastore.v1.Datastore/Commit 5type.googleapis.com/google.datastore.v1.CommitRequestF(21"/  TransCounter N  T R ÓêÁê¯Åï>Bdulcet-port-762|u 6type.googleapis.com/google.datastore.v1.CommitResponse;7, dulcet-port-762 TransCounter€€€§‘ω 茻—Ïûã (Ÿ‰//google.datastore.v1.Datastore/BeginTransactionT ?type.googleapis.com/google.datastore.v1.BeginTransactionRequestBdulcet-port-762²ª @type.googleapis.com/google.datastore.v1.BeginTransactionResponsef d'÷üs+¹%"Y#¢Ägý#Â>ØÂúJG§¿yA²è‹¼2Yâ+Ã̘ÿ¨Z@ÂpÎàv+Y}¾3Œé|ªpcQï¶ÿ²{ ¨Åáã°Ãm ¬dÔϦ‹ìM³(¡ú%/google.datastore.v1.Datastore/LookupÎ 5type.googleapis.com/google.datastore.v1.LookupRequest” fd'÷üs+¹%"Y#¢Ägý#Â>ØÂúJG§¿yA²è‹¼2Yâ+Ã̘ÿ¨Z@ÂpÎàv+Y}¾3Œé|ªpcQï¶ÿ²{ ¨Åáã°Ãm ¬dÔϦ‹ìM³ TransCounter€€€§‘ω Bdulcet-port-762š’ 6type.googleapis.com/google.datastore.v1.LookupResponseX V K , dulcet-port-762 TransCounter€€€§‘ω  N  T R ÓêÁê¾ï> 茻—Ïûã(£à'/google.datastore.v1.Datastore/Rollback² 7type.googleapis.com/google.datastore.v1.RollbackRequestw d'÷üs+¹%"Y#¢Ägý#Â>ØÂúJG§¿yA²è‹¼2Yâ+Ã̘ÿ¨Z@ÂpÎàv+Y}¾3Œé|ªpcQï¶ÿ²{ ¨Åáã°Ãm ¬dÔϦ‹ìM³Bdulcet-port-762A: 8type.googleapis.com/google.datastore.v1.RollbackResponse(¥”%/google.datastore.v1.Datastore/Commiti 5type.googleapis.com/google.datastore.v1.CommitRequest0(2: TransCounter€€€§‘ω Bdulcet-port-762NG 6type.googleapis.com/google.datastore.v1.CommitResponse  ÀÂå—Ïûã (§ª%/google.datastore.v1.Datastore/Commit 5type.googleapis.com/google.datastore.v1.CommitRequestF(21"/  TransCounter N  T R ÓêÁê¯Åï>Bdulcet-port-762|u 6type.googleapis.com/google.datastore.v1.CommitResponse;7, dulcet-port-762 TransCounter€€€ÇÙʈ °Öî—Ïûã (©‰//google.datastore.v1.Datastore/BeginTransactionT ?type.googleapis.com/google.datastore.v1.BeginTransactionRequestBdulcet-port-762²ª @type.googleapis.com/google.datastore.v1.BeginTransactionResponsef d¢^ß$‚Í"Y#¢ÄUßÀ`\Å-³o–4X@Íþ«ÿ¶ZKÇ{vvι•#^[’dJÉA;'1 =>&WýÄüøzWÛ*]…‡ l‰ e•k¤-ž#º}¯¤ßwÝ ±&þðã(«ú%/google.datastore.v1.Datastore/LookupÎ 5type.googleapis.com/google.datastore.v1.LookupRequest” fd¢^ß$‚Í"Y#¢ÄUßÀ`\Å-³o–4X@Íþ«ÿ¶ZKÇ{vvι•#^[’dJÉA;'1 =>&WýÄüøzWÛ*]…‡ l‰ e•k¤-ž#º}¯¤ßwÝ ±&þðã TransCounter€€€ÇÙʈ Bdulcet-port-762š’ 6type.googleapis.com/google.datastore.v1.LookupResponseX V K , dulcet-port-762 TransCounter€€€ÇÙʈ  N  T R ÓêÁê¾ï> °Öî—Ïûã(­´%/google.datastore.v1.Datastore/Commitˆ 5type.googleapis.com/google.datastore.v1.CommitRequestO(2:28  TransCounter€€€ÇÙʈ  N  T R ÓêÁê¾ï>Bdulcet-port-762NG 6type.googleapis.com/google.datastore.v1.CommitResponse  °‹‡˜Ïûã (¯%/google.datastore.v1.Datastore/Commitï 5type.googleapis.com/google.datastore.v1.CommitRequestµ(2:28  TransCounter€€€ÇÙʈ  N  T R ÓêÁê¾ï>Bdulcet-port-762 d¢^ß$‚Í"Y#¢ÄUßÀ`\Å-³o–4X@Íþ«ÿ¶ZKÇ{vvι•#^[’dJÉA;'1 =>&WýÄüøzWÛ*]…‡ l‰ e•k¤-ž#º}¯¤ßwÝ ±&þðãĺ %type.googleapis.com/google.rpc.Status ‹too much contention on these datastore entities. please try again. entity groups: [(app=s~dulcet-port-762, TransCounter, 5667250566594560)] (±ô//google.datastore.v1.Datastore/BeginTransaction¾ ?type.googleapis.com/google.datastore.v1.BeginTransactionRequest{Bdulcet-port-762Rh f d¢^ß$‚Í"Y#¢ÄUßÀ`\Å-³o–4X@Íþ«ÿ¶ZKÇ{vvι•#^[’dJÉA;'1 =>&WýÄüøzWÛ*]…‡ l‰ e•k¤-ž#º}¯¤ßwÝ ±&þð㲪 @type.googleapis.com/google.datastore.v1.BeginTransactionResponsef dÞvLŸ­½ê"Y#¢ÄÍ‹BiP~ Ál8,rÕ_´W‰2ýƒÄ„a¶~2\A. Í]³zÃu¢ç –xwH´9ºP~¦`!¨w2à6‡?ûÐ=ïwœxè€3€XffMyÃ(³ú%/google.datastore.v1.Datastore/LookupÎ 5type.googleapis.com/google.datastore.v1.LookupRequest” fdÞvLŸ­½ê"Y#¢ÄÍ‹BiP~ Ál8,rÕ_´W‰2ýƒÄ„a¶~2\A. Í]³zÃu¢ç –xwH´9ºP~¦`!¨w2à6‡?ûÐ=ïwœxè€3€XffMyà TransCounter€€€ÇÙʈ Bdulcet-port-762š’ 6type.googleapis.com/google.datastore.v1.LookupResponseX V K , dulcet-port-762 TransCounter€€€ÇÙʈ  N  T R ÓêÁê¾ï> °‹‡˜Ïûã(µ%/google.datastore.v1.Datastore/Commitï 5type.googleapis.com/google.datastore.v1.CommitRequestµ(2:28  TransCounter€€€ÇÙʈ  N  T R ÓêÁê¾ï>Bdulcet-port-762 dÞvLŸ­½ê"Y#¢ÄÍ‹BiP~ Ál8,rÕ_´W‰2ýƒÄ„a¶~2\A. Í]³zÃu¢ç –xwH´9ºP~¦`!¨w2à6‡?ûÐ=ïwœxè€3€XffMyÃWP 6type.googleapis.com/google.datastore.v1.CommitResponse ÐÁ©˜Ïûã (ÐÁ©˜Ïûã(·%/google.datastore.v1.Datastore/Lookupe 5type.googleapis.com/google.datastore.v1.LookupRequest, TransCounter€€€ÇÙʈ Bdulcet-port-762š’ 6type.googleapis.com/google.datastore.v1.LookupResponseX V K , dulcet-port-762 TransCounter€€€ÇÙʈ  N  T R ÓêÁê¾ï> ÐÁ©˜Ïûã(¹”%/google.datastore.v1.Datastore/Commiti 5type.googleapis.com/google.datastore.v1.CommitRequest0(2: TransCounter€€€ÇÙʈ Bdulcet-port-762NG 6type.googleapis.com/google.datastore.v1.CommitResponse  èú½˜Ïûã (»ª%/google.datastore.v1.Datastore/Commit 5type.googleapis.com/google.datastore.v1.CommitRequestF(21"/  TransCounter N  T R ÓêÁê¯Åï>Bdulcet-port-762|u 6type.googleapis.com/google.datastore.v1.CommitResponse;7, dulcet-port-762 TransCounter€€€§Ñؘ  ýĘÏûã (½‰//google.datastore.v1.Datastore/BeginTransactionT ?type.googleapis.com/google.datastore.v1.BeginTransactionRequestBdulcet-port-762²ª @type.googleapis.com/google.datastore.v1.BeginTransactionResponsef dE¢fêƒ"Y#¢Äi<fùkÆ@NªAAhç-$O÷# I8ÿIë¯ÐìäY{ÔJ©Ð[V퇷£—Sêr)×á‰Jþ†ƒQ+„ýÀT_Jz¦Ë‡;¤I&áY½b ,(¿ú%/google.datastore.v1.Datastore/LookupÎ 5type.googleapis.com/google.datastore.v1.LookupRequest” fdE¢fêƒ"Y#¢Äi<fùkÆ@NªAAhç-$O÷# I8ÿIë¯ÐìäY{ÔJ©Ð[V퇷£—Sêr)×á‰Jþ†ƒQ+„ýÀT_Jz¦Ë‡;¤I&áY½b , TransCounter€€€§Ñؘ Bdulcet-port-762š’ 6type.googleapis.com/google.datastore.v1.LookupResponseX V K , dulcet-port-762 TransCounter€€€§Ñؘ  N  T R ÓêÁê¾ï>  ýĘÏûã(Á´%/google.datastore.v1.Datastore/Commitˆ 5type.googleapis.com/google.datastore.v1.CommitRequestO(2:28  TransCounter€€€§Ñؘ  N  T R ÓêÁê¾ï>Bdulcet-port-762NG 6type.googleapis.com/google.datastore.v1.CommitResponse  ¨åÙ˜Ïûã (Ã%/google.datastore.v1.Datastore/Commitï 5type.googleapis.com/google.datastore.v1.CommitRequestµ(2:28  TransCounter€€€§Ñؘ  N  T R ÓêÁê¾ï>Bdulcet-port-762 dE¢fêƒ"Y#¢Äi<fùkÆ@NªAAhç-$O÷# I8ÿIë¯ÐìäY{ÔJ©Ð[V퇷£—Sêr)×á‰Jþ†ƒQ+„ýÀT_Jz¦Ë‡;¤I&áY½b ,ĺ %type.googleapis.com/google.rpc.Status ‹too much contention on these datastore entities. please try again. entity groups: [(app=s~dulcet-port-762, TransCounter, 5738098132516864)] (Åô//google.datastore.v1.Datastore/BeginTransaction¾ ?type.googleapis.com/google.datastore.v1.BeginTransactionRequest{Bdulcet-port-762Rh f dE¢fêƒ"Y#¢Äi<fùkÆ@NªAAhç-$O÷# I8ÿIë¯ÐìäY{ÔJ©Ð[V퇷£—Sêr)×á‰Jþ†ƒQ+„ýÀT_Jz¦Ë‡;¤I&áY½b ,²ª @type.googleapis.com/google.datastore.v1.BeginTransactionResponsef d5Ë{áÍØ "Y#¢Äô¢pl%GÑö!;G˜øß©í%ÛKUò´`áôp,.w[ƒYì;Õ<Ƚ¥vçïWÕz0¯°8˜<âì&5ë —…ÊÜ嬮dÅ@ŠÿA%.-ˉ²ø(Çú%/google.datastore.v1.Datastore/LookupÎ 5type.googleapis.com/google.datastore.v1.LookupRequest” fd5Ë{áÍØ "Y#¢Äô¢pl%GÑö!;G˜øß©í%ÛKUò´`áôp,.w[ƒYì;Õ<Ƚ¥vçïWÕz0¯°8˜<âì&5ë —…ÊÜ嬮dÅ@ŠÿA%.-ˉ²ø TransCounter€€€§Ñؘ Bdulcet-port-762š’ 6type.googleapis.com/google.datastore.v1.LookupResponseX V K , dulcet-port-762 TransCounter€€€§Ñؘ  T R ÓêÁê¾ï> N ¨åÙ˜Ïûã(É´%/google.datastore.v1.Datastore/Commitˆ 5type.googleapis.com/google.datastore.v1.CommitRequestO(2:28  TransCounter€€€§Ñؘ  N T R ÓêÁê¾ï>Bdulcet-port-762NG 6type.googleapis.com/google.datastore.v1.CommitResponse  ðÕ€™Ïûã (Ë%/google.datastore.v1.Datastore/Commitï 5type.googleapis.com/google.datastore.v1.CommitRequestµ(2:28  TransCounter€€€§Ñؘ  T R ÓêÁê¾ï> N Bdulcet-port-762 d5Ë{áÍØ "Y#¢Äô¢pl%GÑö!;G˜øß©í%ÛKUò´`áôp,.w[ƒYì;Õ<Ƚ¥vçïWÕz0¯°8˜<âì&5ë —…ÊÜ嬮dÅ@ŠÿA%.-ˉ²øÄº %type.googleapis.com/google.rpc.Status ‹too much contention on these datastore entities. please try again. entity groups: [(app=s~dulcet-port-762, TransCounter, 5738098132516864)] (Íô//google.datastore.v1.Datastore/BeginTransaction¾ ?type.googleapis.com/google.datastore.v1.BeginTransactionRequest{Bdulcet-port-762Rh f d5Ë{áÍØ "Y#¢Äô¢pl%GÑö!;G˜øß©í%ÛKUò´`áôp,.w[ƒYì;Õ<Ƚ¥vçïWÕz0¯°8˜<âì&5ë —…ÊÜ嬮dÅ@ŠÿA%.-ˉ²ø²ª @type.googleapis.com/google.datastore.v1.BeginTransactionResponsef džþ^47†w"Y#¢Ä#]ç47Kˆ˜ã^YEM£QVkÚÙ¹U×ëBú#,õøc–Njˆ ¡¿ôo땇E}ï·?™±°pþ¹’£¦olØsl©eÆ:uRFÇ Öù~”(Ïú%/google.datastore.v1.Datastore/LookupÎ 5type.googleapis.com/google.datastore.v1.LookupRequest” fdžþ^47†w"Y#¢Ä#]ç47Kˆ˜ã^YEM£QVkÚÙ¹U×ëBú#,õøc–Njˆ ¡¿ôo땇E}ï·?™±°pþ¹’£¦olØsl©eÆ:uRFÇ Öù~” TransCounter€€€§Ñؘ Bdulcet-port-762š’ 6type.googleapis.com/google.datastore.v1.LookupResponseX V K , dulcet-port-762 TransCounter€€€§Ñؘ  N T R ÓêÁê¾ï> ðÕ€™Ïûã(Ñ´%/google.datastore.v1.Datastore/Commitˆ 5type.googleapis.com/google.datastore.v1.CommitRequestO(2:28  TransCounter€€€§Ñؘ  N T R ÓêÁê¾ï>Bdulcet-port-762NG 6type.googleapis.com/google.datastore.v1.CommitResponse  ¨¤™Ïûã (Ó%/google.datastore.v1.Datastore/Commitï 5type.googleapis.com/google.datastore.v1.CommitRequestµ(2:28  TransCounter€€€§Ñؘ  T R ÓêÁê¾ï> NBdulcet-port-762 džþ^47†w"Y#¢Ä#]ç47Kˆ˜ã^YEM£QVkÚÙ¹U×ëBú#,õøc–Njˆ ¡¿ôo땇E}ï·?™±°pþ¹’£¦olØsl©eÆ:uRFÇ Öù~”ĺ %type.googleapis.com/google.rpc.Status ‹too much contention on these datastore entities. please try again. entity groups: [(app=s~dulcet-port-762, TransCounter, 5738098132516864)] (Õ”%/google.datastore.v1.Datastore/Commiti 5type.googleapis.com/google.datastore.v1.CommitRequest0(2: TransCounter€€€§Ñؘ Bdulcet-port-762NG 6type.googleapis.com/google.datastore.v1.CommitResponse  àè³™Ïûã (ׯ%/google.datastore.v1.Datastore/Commitƒ 5type.googleapis.com/google.datastore.v1.CommitRequestJ(2"  NilX SŠzero2"  NilX SŠoneBdulcet-port-762¦ž 6type.googleapis.com/google.datastore.v1.CommitResponsed/$ dulcet-port-762 NilX€€€§ˆµ ˆæõ™Ïûã/$ dulcet-port-762 NilX€€€§ˆµ ˆæõ™Ïûã (Ù›%/google.datastore.v1.Datastore/Lookupp 5type.googleapis.com/google.datastore.v1.LookupRequest7 NilX€€€§ˆµ  NilX€€€§ˆµ Bdulcet-port-762ļ 6type.googleapis.com/google.datastore.v1.LookupResponse > 3 $ dulcet-port-762 NilX€€€§ˆµ  SŠone ˆæõ™Ïûã ? 4 $ dulcet-port-762 NilX€€€§ˆµ  SŠzero ˆæõ™Ïûã(Ûˆ%/google.datastore.v1.Datastore/Lookup] 5type.googleapis.com/google.datastore.v1.LookupRequest$ NilX€€€§ˆµ Bdulcet-port-762‚{ 6type.googleapis.com/google.datastore.v1.LookupResponseA ? 4 $ dulcet-port-762 NilX€€€§ˆµ  SŠzero ˆæõ™Ïûã(Ý¡%/google.datastore.v1.Datastore/Commitv 5type.googleapis.com/google.datastore.v1.CommitRequest=(2: NilX€€€§ˆµ 2: NilX€€€§ˆµ Bdulcet-port-762YR 6type.googleapis.com/google.datastore.v1.CommitResponse ˆ¹„šÏûã ˆ¹„šÏûã (ßÜ%/google.datastore.v1.Datastore/Commit° 5type.googleapis.com/google.datastore.v1.CommitRequestö(2à2Ý '% NestedNested-t1565554003131850927± Config¦J£ &2$ NameŠshort Value˜Ša ø2õ NameŠlongá ValueטŠÐaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBdulcet-port-762NG 6type.googleapis.com/google.datastore.v1.CommitResponse  °Ø‘šÏûã (á¢%/google.datastore.v1.Datastore/Commitw 5type.googleapis.com/google.datastore.v1.CommitRequest>(2):'% NestedNested-t1565554003131850927Bdulcet-port-762NG 6type.googleapis.com/google.datastore.v1.CommitResponse  ð„˜šÏûã (ãÙ%/google.datastore.v1.Datastore/Commit­ 5type.googleapis.com/google.datastore.v1.CommitRequestt(2_"]  pointers PgB Pt R €’¸Ã˜þÿÿÿ Pi PsŠ Pb Pf Bdulcet-port-762xq 6type.googleapis.com/google.datastore.v1.CommitResponse73( dulcet-port-762 pointers€€€‡§ë ˜­¢šÏûã (åŒ%/google.datastore.v1.Datastore/Lookupa 5type.googleapis.com/google.datastore.v1.LookupRequest( pointers€€€‡§ë Bdulcet-port-762Ê 6type.googleapis.com/google.datastore.v1.LookupResponse‡ „ y ( dulcet-port-762 pointers€€€‡§ë  Pt R €’¸Ã˜þÿÿÿ Pi Pf  PsŠ PgB Pb ˜­¢šÏûã(çŸ%/google.datastore.v1.Datastore/Committ 5type.googleapis.com/google.datastore.v1.CommitRequest;(2"  t I22  t IBdulcet-port-762 ˜ 6type.googleapis.com/google.datastore.v1.CommitResponse^,! dulcet-port-762 t€€€Ç´‡  ­¯šÏûã,! dulcet-port-762 t€€€Ç´‡  ­¯šÏûã (é…%/google.datastore.v1.Datastore/LookupZ 5type.googleapis.com/google.datastore.v1.LookupRequest! t€€€Ç´‡ Bdulcet-port-762zs 6type.googleapis.com/google.datastore.v1.LookupResponse9 7 , ! dulcet-port-762 t€€€Ç´‡  I  ­¯šÏûã(ë…%/google.datastore.v1.Datastore/LookupZ 5type.googleapis.com/google.datastore.v1.LookupRequest! t€€€Ç´‡ Bdulcet-port-762zs 6type.googleapis.com/google.datastore.v1.LookupResponse9 7 , ! dulcet-port-762 t€€€Ç´‡  I  ­¯šÏûã(í¦%/google.datastore.v1.Datastore/Commit{ 5type.googleapis.com/google.datastore.v1.CommitRequestB(2*  t€€€Ç´‡  I2: t€€€Ç´‡ Bdulcet-port-762YR 6type.googleapis.com/google.datastore.v1.CommitResponse Ðí¾šÏûã Ðí¾šÏûã (ï…%/google.datastore.v1.Datastore/LookupZ 5type.googleapis.com/google.datastore.v1.LookupRequest! t€€€Ç´‡ Bdulcet-port-762zs 6type.googleapis.com/google.datastore.v1.LookupResponse9 7 , ! dulcet-port-762 t€€€Ç´‡  I Ðí¾šÏûã(ñ…%/google.datastore.v1.Datastore/LookupZ 5type.googleapis.com/google.datastore.v1.LookupRequest! t€€€Ç´‡ Bdulcet-port-762qj 6type.googleapis.com/google.datastore.v1.LookupResponse0. # ! dulcet-port-762 t€€€Ç´‡ Ðí¾šÏûã(ó”%/google.datastore.v1.Datastore/Commiti 5type.googleapis.com/google.datastore.v1.CommitRequest0(2"  t€€€Ç´‡  IBdulcet-port-762§ %type.googleapis.com/google.rpc.Statustpentity already exists: app: "s~dulcet-port-762" path < Element { type: "t" id: 0x141c6b48e00000 } > (õ”%/google.datastore.v1.Datastore/Commiti 5type.googleapis.com/google.datastore.v1.CommitRequest0(2*  t€€€Ç´‡  IBdulcet-port-762¥› %type.googleapis.com/google.rpc.Statusrnno entity to update: app: "s~dulcet-port-762" path < Element { type: "t" id: 0x121c6b48e00000 } > (÷‰//google.datastore.v1.Datastore/BeginTransactionT ?type.googleapis.com/google.datastore.v1.BeginTransactionRequestBdulcet-port-762²ª @type.googleapis.com/google.datastore.v1.BeginTransactionResponsef d&€@]Ê9A"Y#¢Ä¬§2ŒôîËf?:ëŠKŽŒíV^J˜£,¾]ý5Á¬P䃹Á ê sÐ1ÿMö ˆ{X±s` AXç ¯qЛÇ_ßäm·3< 95­ò£²(ù%/google.datastore.v1.Datastore/CommitÛ 5type.googleapis.com/google.datastore.v1.CommitRequest¡(2"  t I22  t IBdulcet-port-762 d&€@]Ê9A"Y#¢Ä¬§2ŒôîËf?:ëŠKŽŒíV^J˜£,¾]ý5Á¬P䃹Á ê sÐ1ÿMö ˆ{X±s` AXç ¯qЛÇ_ßäm·3< 95­ò£²©¡ 6type.googleapis.com/google.datastore.v1.CommitResponseg,! dulcet-port-762 t€€€ûâù™ ð âšÏûã,! dulcet-port-762 t€€€ûâù™ ð âšÏûã (ð âšÏûã(û…%/google.datastore.v1.Datastore/LookupZ 5type.googleapis.com/google.datastore.v1.LookupRequest! t€€€ûâù™ Bdulcet-port-762zs 6type.googleapis.com/google.datastore.v1.LookupResponse9 7 , ! dulcet-port-762 t€€€ûâù™  I ð âšÏûã(ý…%/google.datastore.v1.Datastore/LookupZ 5type.googleapis.com/google.datastore.v1.LookupRequest! t€€€ûâù™ Bdulcet-port-762zs 6type.googleapis.com/google.datastore.v1.LookupResponse9 7 , ! dulcet-port-762 t€€€ûâù™  I ð âšÏûã(ÿ‰//google.datastore.v1.Datastore/BeginTransactionT ?type.googleapis.com/google.datastore.v1.BeginTransactionRequestBdulcet-port-762²ª @type.googleapis.com/google.datastore.v1.BeginTransactionResponsef dÔ»< ö!·"Y#¢ÄÂ;måï•gÃ^íÌáá×wR,à˜FÍàº]N‘ÊÕ•,¡J®*.a 2ÿÿ‰%»&ˆ*í‡ÕÊë¦ã?¢½ßÃõ“2Ä­q9Ì;(¹ÝY5n(%/google.datastore.v1.Datastore/Commitâ 5type.googleapis.com/google.datastore.v1.CommitRequest¨(2*  t€€€ûâù™  I2: t€€€ûâù™ Bdulcet-port-762 dÔ»< ö!·"Y#¢ÄÂ;måï•gÃ^íÌáá×wR,à˜FÍàº]N‘ÊÕ•,¡J®*.a 2ÿÿ‰%»&ˆ*í‡ÕÊë¦ã?¢½ßÃõ“2Ä­q9Ì;(¹ÝY5nb[ 6type.googleapis.com/google.datastore.v1.CommitResponse! è™›Ïûã è™›Ïûã (è™›Ïûã(ƒ…%/google.datastore.v1.Datastore/LookupZ 5type.googleapis.com/google.datastore.v1.LookupRequest! t€€€ûâù™ Bdulcet-port-762zs 6type.googleapis.com/google.datastore.v1.LookupResponse9 7 , ! dulcet-port-762 t€€€ûâù™  I è™›Ïûã(……%/google.datastore.v1.Datastore/LookupZ 5type.googleapis.com/google.datastore.v1.LookupRequest! t€€€ûâù™ Bdulcet-port-762qj 6type.googleapis.com/google.datastore.v1.LookupResponse0. # ! dulcet-port-762 t€€€ûâù™ è™›Ïûã(‡‰//google.datastore.v1.Datastore/BeginTransactionT ?type.googleapis.com/google.datastore.v1.BeginTransactionRequestBdulcet-port-762²ª @type.googleapis.com/google.datastore.v1.BeginTransactionResponsef dòD;{4ó"Y#¢ÄÝ1È ¸Òq½%'µÏïõ(\tT¹ô›ùÝ.÷˜ë¦<‚{Åwè(lŠ$›,x[g¦ps{Dbݳ«‘ÛˆoÏ×%™Æbº ü(‰ü%/google.datastore.v1.Datastore/CommitÐ 5type.googleapis.com/google.datastore.v1.CommitRequest–(2"  t€€€ûâù™  IBdulcet-port-762 dòD;{4ó"Y#¢ÄÝ1È ¸Òq½%'µÏïõ(\tT¹ô›ùÝ.÷˜ë¦<‚{Åwè(lŠ$›,x[g¦ps{Dbݳ«‘ÛˆoÏ×%™Æbº ü§ %type.googleapis.com/google.rpc.Statustpentity already exists: app: "s~dulcet-port-762" path < Element { type: "t" id: 0x1467ce2f600000 } > (‹‰//google.datastore.v1.Datastore/BeginTransactionT ?type.googleapis.com/google.datastore.v1.BeginTransactionRequestBdulcet-port-762²ª @type.googleapis.com/google.datastore.v1.BeginTransactionResponsef d’ÂHøpÉ"Y#¢ÄÛg&"2g~‚ ´¬=<ÁûggïòÍìŽËê!˜¹|[™52>Ògo@Ùå¢ÿpÞ|@‚ËÆo-}u­ž@ìštpçCÁ+kÖZ—œÈ=-ž(ü%/google.datastore.v1.Datastore/CommitÐ 5type.googleapis.com/google.datastore.v1.CommitRequest–(2*  t€€€ûâù™  IBdulcet-port-762 d’ÂHøpÉ"Y#¢ÄÛg&"2g~‚ ´¬=<ÁûggïòÍìŽËê!˜¹|[™52>Ògo@Ùå¢ÿpÞ|@‚ËÆo-}u­ž@ìštpçCÁ+kÖZ—œÈ=-ž¥› %type.googleapis.com/google.rpc.Statusrnno entity to update: app: "s~dulcet-port-762" path < Element { type: "t" id: 0x1267ce2f600000 } > (•%/google.datastore.v1.Datastore/Commitj 5type.googleapis.com/google.datastore.v1.CommitRequest1(2"  SomeKey SŠfooBdulcet-port-762wp 6type.googleapis.com/google.datastore.v1.CommitResponse62' dulcet-port-762 SomeKey€€€‡¬Ó àñª›Ïûã (‘google-cloud-go-0.49.0/datastore/datastore_test.go000066400000000000000000002203461356504100700221410ustar00rootroot00000000000000// Copyright 2014 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package datastore import ( "context" "encoding/json" "errors" "fmt" "reflect" "sort" "strings" "testing" "time" "cloud.google.com/go/internal/testutil" "github.com/golang/protobuf/proto" "github.com/google/go-cmp/cmp" pb "google.golang.org/genproto/googleapis/datastore/v1" "google.golang.org/grpc" ) type ( myBlob []byte myByte byte myString string ) func makeMyByteSlice(n int) []myByte { b := make([]myByte, n) for i := range b { b[i] = myByte(i) } return b } func makeInt8Slice(n int) []int8 { b := make([]int8, n) for i := range b { b[i] = int8(i) } return b } func makeUint8Slice(n int) []uint8 { b := make([]uint8, n) for i := range b { b[i] = uint8(i) } return b } func newKey(stringID string, parent *Key) *Key { return NameKey("kind", stringID, parent) } var ( testKey0 = newKey("name0", nil) testKey1a = newKey("name1", nil) testKey1b = newKey("name1", nil) testKey2a = newKey("name2", testKey0) testKey2b = newKey("name2", testKey0) testGeoPt0 = GeoPoint{Lat: 1.2, Lng: 3.4} testGeoPt1 = GeoPoint{Lat: 5, Lng: 10} testBadGeoPt = GeoPoint{Lat: 1000, Lng: 34} ts = time.Unix(1e9, 0).UTC() ) type B0 struct { B []byte `datastore:",noindex"` } type B1 struct { B []int8 } type B2 struct { B myBlob `datastore:",noindex"` } type B3 struct { B []myByte `datastore:",noindex"` } type B4 struct { B [][]byte } type C0 struct { I int C chan int } type C1 struct { I int C *chan int } type C2 struct { I int C []chan int } type C3 struct { C string } type c4 struct { C string } type E struct{} type G0 struct { G GeoPoint } type G1 struct { G []GeoPoint } type K0 struct { K *Key } type K1 struct { K []*Key } type S struct { St string } type NoOmit struct { A string B int `datastore:"Bb"` C bool `datastore:",noindex"` } type OmitAll struct { A string `datastore:",omitempty"` B int `datastore:"Bb,omitempty"` C bool `datastore:",omitempty,noindex"` D time.Time `datastore:",omitempty"` F []int `datastore:",omitempty"` } type Omit struct { A string `datastore:",omitempty"` B int `datastore:"Bb,omitempty"` C bool `datastore:",omitempty,noindex"` D time.Time `datastore:",omitempty"` F []int `datastore:",omitempty"` S `datastore:",omitempty"` } type NoOmits struct { No []NoOmit `datastore:",omitempty"` S `datastore:",omitempty"` Ss S `datastore:",omitempty"` } type N0 struct { X0 Nonymous X0 Ignore string `datastore:"-"` Other string } type N1 struct { X0 Nonymous []X0 Ignore string `datastore:"-"` Other string } type N2 struct { N1 `datastore:"red"` Green N1 `datastore:"green"` Blue N1 White N1 `datastore:"-"` } type N3 struct { C3 `datastore:"red"` } type N4 struct { c4 } type N5 struct { c4 `datastore:"red"` } type O0 struct { I int64 } type O1 struct { I int32 } type U0 struct { U uint } type U1 struct { U string } type T struct { T time.Time } type X0 struct { S string I int i int } type X1 struct { S myString I int32 J int64 } type X2 struct { Z string } type X3 struct { S bool I int } type Y0 struct { B bool F []float64 G []float64 } type Y1 struct { B bool F float64 } type Y2 struct { B bool F []int64 } type Pointers struct { Pi *int Ps *string Pb *bool Pf *float64 Pg *GeoPoint Pt *time.Time } type PointersOmitEmpty struct { Pi *int `datastore:",omitempty"` Ps *string `datastore:",omitempty"` Pb *bool `datastore:",omitempty"` Pf *float64 `datastore:",omitempty"` Pg *GeoPoint `datastore:",omitempty"` Pt *time.Time `datastore:",omitempty"` } func populatedPointers() *Pointers { var ( i int s string b bool f float64 g GeoPoint t time.Time ) return &Pointers{ Pi: &i, Ps: &s, Pb: &b, Pf: &f, Pg: &g, Pt: &t, } } type Tagged struct { A int `datastore:"a,noindex"` B []int `datastore:"b"` C int `datastore:",noindex"` D int `datastore:""` E int I int `datastore:"-"` J int `datastore:",noindex" json:"j"` Y0 `datastore:"-"` Z chan int `datastore:"-"` } type InvalidTagged1 struct { I int `datastore:"\t"` } type InvalidTagged2 struct { I int J int `datastore:"I"` } type InvalidTagged3 struct { X string `datastore:"-,noindex"` } type InvalidTagged4 struct { X string `datastore:",garbage"` } type Inner1 struct { W int32 X string } type Inner2 struct { Y float64 } type Inner3 struct { Z bool } type Inner5 struct { WW int } type Inner4 struct { X Inner5 } type Outer struct { A int16 I []Inner1 J Inner2 Inner3 } type OuterFlatten struct { A int16 I []Inner1 `datastore:",flatten"` J Inner2 `datastore:",flatten,noindex"` Inner3 `datastore:",flatten"` K Inner4 `datastore:",flatten"` L *Inner2 `datastore:",flatten"` } type OuterEquivalent struct { A int16 IDotW []int32 `datastore:"I.W"` IDotX []string `datastore:"I.X"` JDotY float64 `datastore:"J.Y"` Z bool } type Dotted struct { A DottedA `datastore:"A0.A1.A2"` } type DottedA struct { B DottedB `datastore:"B3"` } type DottedB struct { C int `datastore:"C4.C5"` } type SliceOfSlices struct { I int S []struct { J int F []float64 } `datastore:",flatten"` } type Recursive struct { I int R []Recursive } type MutuallyRecursive0 struct { I int R []MutuallyRecursive1 } type MutuallyRecursive1 struct { I int R []MutuallyRecursive0 } type EntityWithKey struct { I int S string K *Key `datastore:"__key__"` } type WithNestedEntityWithKey struct { N EntityWithKey } type WithNonKeyField struct { I int K string `datastore:"__key__"` } type NestedWithNonKeyField struct { N WithNonKeyField } type Basic struct { A string } type PtrToStructField struct { B *Basic C *Basic `datastore:"c,noindex"` *Basic D []*Basic } type EmbeddedTime struct { time.Time } type SpecialTime struct { MyTime EmbeddedTime } type Doubler struct { S string I int64 B bool } type Repeat struct { Key string Value []byte } type Repeated struct { Repeats []Repeat } func (d *Doubler) Load(props []Property) error { return LoadStruct(d, props) } func (d *Doubler) Save() ([]Property, error) { // Save the default Property slice to an in-memory buffer (a PropertyList). props, err := SaveStruct(d) if err != nil { return nil, err } var list PropertyList if err := list.Load(props); err != nil { return nil, err } // Edit that PropertyList, and send it on. for i := range list { switch v := list[i].Value.(type) { case string: // + means string concatenation. list[i].Value = v + v case int64: // + means integer addition. list[i].Value = v + v } } return list.Save() } var _ PropertyLoadSaver = (*Doubler)(nil) type Deriver struct { S, Derived, Ignored string } func (e *Deriver) Load(props []Property) error { for _, p := range props { if p.Name != "S" { continue } e.S = p.Value.(string) e.Derived = "derived+" + e.S } return nil } func (e *Deriver) Save() ([]Property, error) { return []Property{ { Name: "S", Value: e.S, }, }, nil } var _ PropertyLoadSaver = (*Deriver)(nil) type BadMultiPropEntity struct{} func (e *BadMultiPropEntity) Load(props []Property) error { return errors.New("unimplemented") } func (e *BadMultiPropEntity) Save() ([]Property, error) { // Write multiple properties with the same name "I". var props []Property for i := 0; i < 3; i++ { props = append(props, Property{ Name: "I", Value: int64(i), }) } return props, nil } var _ PropertyLoadSaver = (*BadMultiPropEntity)(nil) type testCase struct { desc string src interface{} want interface{} putErr string getErr string } var testCases = []testCase{ { "chan save fails", &C0{I: -1}, &E{}, "unsupported struct field", "", }, { "*chan save fails", &C1{I: -1}, &E{}, "unsupported struct field", "", }, { "[]chan save fails", &C2{I: -1, C: make([]chan int, 8)}, &E{}, "unsupported struct field", "", }, { "chan load fails", &C3{C: "not a chan"}, &C0{}, "", "type mismatch", }, { "*chan load fails", &C3{C: "not a *chan"}, &C1{}, "", "type mismatch", }, { "[]chan load fails", &C3{C: "not a []chan"}, &C2{}, "", "type mismatch", }, { "empty struct", &E{}, &E{}, "", "", }, { "geopoint", &G0{G: testGeoPt0}, &G0{G: testGeoPt0}, "", "", }, { "geopoint invalid", &G0{G: testBadGeoPt}, &G0{}, "invalid GeoPoint value", "", }, { "geopoint as props", &G0{G: testGeoPt0}, &PropertyList{ Property{Name: "G", Value: testGeoPt0, NoIndex: false}, }, "", "", }, { "geopoint slice", &G1{G: []GeoPoint{testGeoPt0, testGeoPt1}}, &G1{G: []GeoPoint{testGeoPt0, testGeoPt1}}, "", "", }, { "omit empty, all", &OmitAll{}, new(PropertyList), "", "", }, { "omit empty", &Omit{}, &PropertyList{ Property{Name: "St", Value: "", NoIndex: false}, }, "", "", }, { "omit empty, fields populated", &Omit{ A: "a", B: 10, C: true, F: []int{11}, }, &PropertyList{ Property{Name: "A", Value: "a", NoIndex: false}, Property{Name: "Bb", Value: int64(10), NoIndex: false}, Property{Name: "C", Value: true, NoIndex: true}, Property{Name: "F", Value: []interface{}{int64(11)}, NoIndex: false}, Property{Name: "St", Value: "", NoIndex: false}, }, "", "", }, { "omit empty, fields populated", &Omit{ A: "a", B: 10, C: true, F: []int{11}, S: S{St: "string"}, }, &PropertyList{ Property{Name: "A", Value: "a", NoIndex: false}, Property{Name: "Bb", Value: int64(10), NoIndex: false}, Property{Name: "C", Value: true, NoIndex: true}, Property{Name: "F", Value: []interface{}{int64(11)}, NoIndex: false}, Property{Name: "St", Value: "string", NoIndex: false}, }, "", "", }, { "omit empty does not propagate", &NoOmits{ No: []NoOmit{ {}, }, S: S{}, Ss: S{}, }, &PropertyList{ Property{Name: "No", Value: []interface{}{ &Entity{ Properties: []Property{ {Name: "A", Value: "", NoIndex: false}, {Name: "Bb", Value: int64(0), NoIndex: false}, {Name: "C", Value: false, NoIndex: true}, }, }, }, NoIndex: false}, Property{Name: "Ss", Value: &Entity{ Properties: []Property{ {Name: "St", Value: "", NoIndex: false}, }, }, NoIndex: false}, Property{Name: "St", Value: "", NoIndex: false}, }, "", "", }, { "key", &K0{K: testKey1a}, &K0{K: testKey1b}, "", "", }, { "key with parent", &K0{K: testKey2a}, &K0{K: testKey2b}, "", "", }, { "nil key", &K0{}, &K0{}, "", "", }, { "all nil keys in slice", &K1{[]*Key{nil, nil}}, &K1{[]*Key{nil, nil}}, "", "", }, { "some nil keys in slice", &K1{[]*Key{testKey1a, nil, testKey2a}}, &K1{[]*Key{testKey1b, nil, testKey2b}}, "", "", }, { "overflow", &O0{I: 1 << 48}, &O1{}, "", "overflow", }, { "time", &T{T: time.Unix(1e9, 0)}, &T{T: time.Unix(1e9, 0)}, "", "", }, { "time as props", &T{T: time.Unix(1e9, 0)}, &PropertyList{ Property{Name: "T", Value: time.Unix(1e9, 0), NoIndex: false}, }, "", "", }, { "uint save", &U0{U: 1}, &U0{}, "unsupported struct field", "", }, { "uint load", &U1{U: "not a uint"}, &U0{}, "", "type mismatch", }, { "zero", &X0{}, &X0{}, "", "", }, { "basic", &X0{S: "one", I: 2, i: 3}, &X0{S: "one", I: 2}, "", "", }, { "save string/int load myString/int32", &X0{S: "one", I: 2, i: 3}, &X1{S: "one", I: 2}, "", "", }, { "missing fields", &X0{S: "one", I: 2, i: 3}, &X2{}, "", "no such struct field", }, { "save string load bool", &X0{S: "one", I: 2, i: 3}, &X3{I: 2}, "", "type mismatch", }, { "basic slice", &Y0{B: true, F: []float64{7, 8, 9}}, &Y0{B: true, F: []float64{7, 8, 9}}, "", "", }, { "save []float64 load float64", &Y0{B: true, F: []float64{7, 8, 9}}, &Y1{B: true}, "", "requires a slice", }, { "save []float64 load []int64", &Y0{B: true, F: []float64{7, 8, 9}}, &Y2{B: true}, "", "type mismatch", }, { "single slice is too long", &Y0{F: make([]float64, maxIndexedProperties+1)}, &Y0{}, "too many indexed properties", "", }, { "two slices are too long", &Y0{F: make([]float64, maxIndexedProperties), G: make([]float64, maxIndexedProperties)}, &Y0{}, "too many indexed properties", "", }, { "one slice and one scalar are too long", &Y0{F: make([]float64, maxIndexedProperties), B: true}, &Y0{}, "too many indexed properties", "", }, { "slice of slices of bytes", &Repeated{ Repeats: []Repeat{ { Key: "key 1", Value: []byte("value 1"), }, { Key: "key 2", Value: []byte("value 2"), }, }, }, &Repeated{ Repeats: []Repeat{ { Key: "key 1", Value: []byte("value 1"), }, { Key: "key 2", Value: []byte("value 2"), }, }, }, "", "", }, { "long blob", &B0{B: makeUint8Slice(maxIndexedProperties + 1)}, &B0{B: makeUint8Slice(maxIndexedProperties + 1)}, "", "", }, { "long []int8 is too long", &B1{B: makeInt8Slice(maxIndexedProperties + 1)}, &B1{}, "too many indexed properties", "", }, { "short []int8", &B1{B: makeInt8Slice(3)}, &B1{B: makeInt8Slice(3)}, "", "", }, { "long myBlob", &B2{B: makeUint8Slice(maxIndexedProperties + 1)}, &B2{B: makeUint8Slice(maxIndexedProperties + 1)}, "", "", }, { "short myBlob", &B2{B: makeUint8Slice(3)}, &B2{B: makeUint8Slice(3)}, "", "", }, { "long []myByte", &B3{B: makeMyByteSlice(maxIndexedProperties + 1)}, &B3{B: makeMyByteSlice(maxIndexedProperties + 1)}, "", "", }, { "short []myByte", &B3{B: makeMyByteSlice(3)}, &B3{B: makeMyByteSlice(3)}, "", "", }, { "slice of blobs", &B4{B: [][]byte{ makeUint8Slice(3), makeUint8Slice(4), makeUint8Slice(5), }}, &B4{B: [][]byte{ makeUint8Slice(3), makeUint8Slice(4), makeUint8Slice(5), }}, "", "", }, { "[]byte must be noindex", &PropertyList{ Property{Name: "B", Value: makeUint8Slice(1501), NoIndex: false}, }, nil, "[]byte property too long to index", "", }, { "string must be noindex", &PropertyList{ Property{Name: "B", Value: strings.Repeat("x", 1501), NoIndex: false}, }, nil, "string property too long to index", "", }, { "slice of []byte must be noindex", &PropertyList{ Property{Name: "B", Value: []interface{}{ []byte("short"), makeUint8Slice(1501), }, NoIndex: false}, }, nil, "[]byte property too long to index", "", }, { "slice of string must be noindex", &PropertyList{ Property{Name: "B", Value: []interface{}{ "short", strings.Repeat("x", 1501), }, NoIndex: false}, }, nil, "string property too long to index", "", }, { "save tagged load props", &Tagged{A: 1, B: []int{21, 22, 23}, C: 3, D: 4, E: 5, I: 6, J: 7}, &PropertyList{ // A and B are renamed to a and b; A and C are noindex, I is ignored. // Order is sorted as per byName. Property{Name: "C", Value: int64(3), NoIndex: true}, Property{Name: "D", Value: int64(4), NoIndex: false}, Property{Name: "E", Value: int64(5), NoIndex: false}, Property{Name: "J", Value: int64(7), NoIndex: true}, Property{Name: "a", Value: int64(1), NoIndex: true}, Property{Name: "b", Value: []interface{}{int64(21), int64(22), int64(23)}, NoIndex: false}, }, "", "", }, { "save tagged load tagged", &Tagged{A: 1, B: []int{21, 22, 23}, C: 3, D: 4, E: 5, I: 6, J: 7}, &Tagged{A: 1, B: []int{21, 22, 23}, C: 3, D: 4, E: 5, J: 7}, "", "", }, { "invalid tagged1", &InvalidTagged1{I: 1}, &InvalidTagged1{}, "struct tag has invalid property name", "", }, { "invalid tagged2", &InvalidTagged2{I: 1, J: 2}, &InvalidTagged2{J: 2}, "", "", }, { "invalid tagged3", &InvalidTagged3{X: "hello"}, &InvalidTagged3{}, "struct tag has invalid property name: \"-\"", "", }, { "invalid tagged4", &InvalidTagged4{X: "hello"}, &InvalidTagged4{}, "struct tag has invalid option: \"garbage\"", "", }, { "doubler", &Doubler{S: "s", I: 1, B: true}, &Doubler{S: "ss", I: 2, B: true}, "", "", }, { "save struct load props", &X0{S: "s", I: 1}, &PropertyList{ Property{Name: "I", Value: int64(1), NoIndex: false}, Property{Name: "S", Value: "s", NoIndex: false}, }, "", "", }, { "save props load struct", &PropertyList{ Property{Name: "I", Value: int64(1), NoIndex: false}, Property{Name: "S", Value: "s", NoIndex: false}, }, &X0{S: "s", I: 1}, "", "", }, { "nil-value props", &PropertyList{ Property{Name: "I", Value: nil, NoIndex: false}, Property{Name: "B", Value: nil, NoIndex: false}, Property{Name: "S", Value: nil, NoIndex: false}, Property{Name: "F", Value: nil, NoIndex: false}, Property{Name: "K", Value: nil, NoIndex: false}, Property{Name: "T", Value: nil, NoIndex: false}, Property{Name: "J", Value: []interface{}{nil, int64(7), nil}, NoIndex: false}, }, &struct { I int64 B bool S string F float64 K *Key T time.Time J []int64 }{ J: []int64{0, 7, 0}, }, "", "", }, { "save outer load props flatten", &OuterFlatten{ A: 1, I: []Inner1{ {10, "ten"}, {20, "twenty"}, {30, "thirty"}, }, J: Inner2{ Y: 3.14, }, Inner3: Inner3{ Z: true, }, K: Inner4{ X: Inner5{ WW: 12, }, }, L: &Inner2{ Y: 2.71, }, }, &PropertyList{ Property{Name: "A", Value: int64(1), NoIndex: false}, Property{Name: "I.W", Value: []interface{}{int64(10), int64(20), int64(30)}, NoIndex: false}, Property{Name: "I.X", Value: []interface{}{"ten", "twenty", "thirty"}, NoIndex: false}, Property{Name: "J.Y", Value: float64(3.14), NoIndex: true}, Property{Name: "K.X.WW", Value: int64(12), NoIndex: false}, Property{Name: "L.Y", Value: float64(2.71), NoIndex: false}, Property{Name: "Z", Value: true, NoIndex: false}, }, "", "", }, { "load outer props flatten", &PropertyList{ Property{Name: "A", Value: int64(1), NoIndex: false}, Property{Name: "I.W", Value: []interface{}{int64(10), int64(20), int64(30)}, NoIndex: false}, Property{Name: "I.X", Value: []interface{}{"ten", "twenty", "thirty"}, NoIndex: false}, Property{Name: "J.Y", Value: float64(3.14), NoIndex: true}, Property{Name: "L.Y", Value: float64(2.71), NoIndex: false}, Property{Name: "Z", Value: true, NoIndex: false}, }, &OuterFlatten{ A: 1, I: []Inner1{ {10, "ten"}, {20, "twenty"}, {30, "thirty"}, }, J: Inner2{ Y: 3.14, }, Inner3: Inner3{ Z: true, }, L: &Inner2{ Y: 2.71, }, }, "", "", }, { "save outer load props", &Outer{ A: 1, I: []Inner1{ {10, "ten"}, {20, "twenty"}, {30, "thirty"}, }, J: Inner2{ Y: 3.14, }, Inner3: Inner3{ Z: true, }, }, &PropertyList{ Property{Name: "A", Value: int64(1), NoIndex: false}, Property{Name: "I", Value: []interface{}{ &Entity{ Properties: []Property{ {Name: "W", Value: int64(10), NoIndex: false}, {Name: "X", Value: "ten", NoIndex: false}, }, }, &Entity{ Properties: []Property{ {Name: "W", Value: int64(20), NoIndex: false}, {Name: "X", Value: "twenty", NoIndex: false}, }, }, &Entity{ Properties: []Property{ {Name: "W", Value: int64(30), NoIndex: false}, {Name: "X", Value: "thirty", NoIndex: false}, }, }, }, NoIndex: false}, Property{Name: "J", Value: &Entity{ Properties: []Property{ {Name: "Y", Value: float64(3.14), NoIndex: false}, }, }, NoIndex: false}, Property{Name: "Z", Value: true, NoIndex: false}, }, "", "", }, { "save props load outer-equivalent", &PropertyList{ Property{Name: "A", Value: int64(1), NoIndex: false}, Property{Name: "I.W", Value: []interface{}{int64(10), int64(20), int64(30)}, NoIndex: false}, Property{Name: "I.X", Value: []interface{}{"ten", "twenty", "thirty"}, NoIndex: false}, Property{Name: "J.Y", Value: float64(3.14), NoIndex: false}, Property{Name: "Z", Value: true, NoIndex: false}, }, &OuterEquivalent{ A: 1, IDotW: []int32{10, 20, 30}, IDotX: []string{"ten", "twenty", "thirty"}, JDotY: 3.14, Z: true, }, "", "", }, { "dotted names save", &Dotted{A: DottedA{B: DottedB{C: 88}}}, &PropertyList{ Property{Name: "A0.A1.A2", Value: &Entity{ Properties: []Property{ {Name: "B3", Value: &Entity{ Properties: []Property{ {Name: "C4.C5", Value: int64(88), NoIndex: false}, }, }, NoIndex: false}, }, }, NoIndex: false}, }, "", "", }, { "dotted names load", &PropertyList{ Property{Name: "A0.A1.A2", Value: &Entity{ Properties: []Property{ {Name: "B3", Value: &Entity{ Properties: []Property{ {Name: "C4.C5", Value: 99, NoIndex: false}, }, }, NoIndex: false}, }, }, NoIndex: false}, }, &Dotted{A: DottedA{B: DottedB{C: 99}}}, "", "", }, { "save struct load deriver", &X0{S: "s", I: 1}, &Deriver{S: "s", Derived: "derived+s"}, "", "", }, { "save deriver load struct", &Deriver{S: "s", Derived: "derived+s", Ignored: "ignored"}, &X0{S: "s"}, "", "", }, { "zero time.Time", &T{T: time.Time{}}, &T{T: time.Time{}}, "", "", }, { "time.Time near Unix zero time", &T{T: time.Unix(0, 4e3)}, &T{T: time.Unix(0, 4e3)}, "", "", }, { "time.Time, far in the future", &T{T: time.Date(99999, 1, 1, 0, 0, 0, 0, time.UTC)}, &T{T: time.Date(99999, 1, 1, 0, 0, 0, 0, time.UTC)}, "", "", }, { "time.Time, very far in the past", &T{T: time.Date(-300000, 1, 1, 0, 0, 0, 0, time.UTC)}, &T{}, "time value out of range", "", }, { "time.Time, very far in the future", &T{T: time.Date(294248, 1, 1, 0, 0, 0, 0, time.UTC)}, &T{}, "time value out of range", "", }, { "structs", &N0{ X0: X0{S: "one", I: 2, i: 3}, Nonymous: X0{S: "four", I: 5, i: 6}, Ignore: "ignore", Other: "other", }, &N0{ X0: X0{S: "one", I: 2}, Nonymous: X0{S: "four", I: 5}, Other: "other", }, "", "", }, { "slice of structs", &N1{ X0: X0{S: "one", I: 2, i: 3}, Nonymous: []X0{ {S: "four", I: 5, i: 6}, {S: "seven", I: 8, i: 9}, {S: "ten", I: 11, i: 12}, {S: "thirteen", I: 14, i: 15}, }, Ignore: "ignore", Other: "other", }, &N1{ X0: X0{S: "one", I: 2}, Nonymous: []X0{ {S: "four", I: 5}, {S: "seven", I: 8}, {S: "ten", I: 11}, {S: "thirteen", I: 14}, }, Other: "other", }, "", "", }, { "structs with slices of structs", &N2{ N1: N1{ X0: X0{S: "rouge"}, Nonymous: []X0{ {S: "rosso0"}, {S: "rosso1"}, }, }, Green: N1{ X0: X0{S: "vert"}, Nonymous: []X0{ {S: "verde0"}, {S: "verde1"}, {S: "verde2"}, }, }, Blue: N1{ X0: X0{S: "bleu"}, Nonymous: []X0{ {S: "blu0"}, {S: "blu1"}, {S: "blu2"}, {S: "blu3"}, }, }, }, &N2{ N1: N1{ X0: X0{S: "rouge"}, Nonymous: []X0{ {S: "rosso0"}, {S: "rosso1"}, }, }, Green: N1{ X0: X0{S: "vert"}, Nonymous: []X0{ {S: "verde0"}, {S: "verde1"}, {S: "verde2"}, }, }, Blue: N1{ X0: X0{S: "bleu"}, Nonymous: []X0{ {S: "blu0"}, {S: "blu1"}, {S: "blu2"}, {S: "blu3"}, }, }, }, "", "", }, { "save structs load props", &N2{ N1: N1{ X0: X0{S: "rouge"}, Nonymous: []X0{ {S: "rosso0"}, {S: "rosso1"}, }, }, Green: N1{ X0: X0{S: "vert"}, Nonymous: []X0{ {S: "verde0"}, {S: "verde1"}, {S: "verde2"}, }, }, Blue: N1{ X0: X0{S: "bleu"}, Nonymous: []X0{ {S: "blu0"}, {S: "blu1"}, {S: "blu2"}, {S: "blu3"}, }, }, }, &PropertyList{ Property{Name: "Blue", Value: &Entity{ Properties: []Property{ {Name: "I", Value: int64(0), NoIndex: false}, {Name: "Nonymous", Value: []interface{}{ &Entity{ Properties: []Property{ {Name: "I", Value: int64(0), NoIndex: false}, {Name: "S", Value: "blu0", NoIndex: false}, }, }, &Entity{ Properties: []Property{ {Name: "I", Value: int64(0), NoIndex: false}, {Name: "S", Value: "blu1", NoIndex: false}, }, }, &Entity{ Properties: []Property{ {Name: "I", Value: int64(0), NoIndex: false}, {Name: "S", Value: "blu2", NoIndex: false}, }, }, &Entity{ Properties: []Property{ {Name: "I", Value: int64(0), NoIndex: false}, {Name: "S", Value: "blu3", NoIndex: false}, }, }, }, NoIndex: false}, {Name: "Other", Value: "", NoIndex: false}, {Name: "S", Value: "bleu", NoIndex: false}, }, }, NoIndex: false}, Property{Name: "green", Value: &Entity{ Properties: []Property{ {Name: "I", Value: int64(0), NoIndex: false}, {Name: "Nonymous", Value: []interface{}{ &Entity{ Properties: []Property{ {Name: "I", Value: int64(0), NoIndex: false}, {Name: "S", Value: "verde0", NoIndex: false}, }, }, &Entity{ Properties: []Property{ {Name: "I", Value: int64(0), NoIndex: false}, {Name: "S", Value: "verde1", NoIndex: false}, }, }, &Entity{ Properties: []Property{ {Name: "I", Value: int64(0), NoIndex: false}, {Name: "S", Value: "verde2", NoIndex: false}, }, }, }, NoIndex: false}, {Name: "Other", Value: "", NoIndex: false}, {Name: "S", Value: "vert", NoIndex: false}, }, }, NoIndex: false}, Property{Name: "red", Value: &Entity{ Properties: []Property{ {Name: "I", Value: int64(0), NoIndex: false}, {Name: "Nonymous", Value: []interface{}{ &Entity{ Properties: []Property{ {Name: "I", Value: int64(0), NoIndex: false}, {Name: "S", Value: "rosso0", NoIndex: false}, }, }, &Entity{ Properties: []Property{ {Name: "I", Value: int64(0), NoIndex: false}, {Name: "S", Value: "rosso1", NoIndex: false}, }, }, }, NoIndex: false}, {Name: "Other", Value: "", NoIndex: false}, {Name: "S", Value: "rouge", NoIndex: false}, }, }, NoIndex: false}, }, "", "", }, { "nested entity with key", &WithNestedEntityWithKey{ N: EntityWithKey{ I: 12, S: "abcd", K: testKey0, }, }, &WithNestedEntityWithKey{ N: EntityWithKey{ I: 12, S: "abcd", K: testKey0, }, }, "", "", }, { "entity with key at top level", &EntityWithKey{ I: 12, S: "abc", K: testKey0, }, &EntityWithKey{ I: 12, S: "abc", K: testKey0, }, "", "", }, { "entity with key at top level (key is populated on load)", &EntityWithKey{ I: 12, S: "abc", }, &EntityWithKey{ I: 12, S: "abc", K: testKey0, }, "", "", }, { "__key__ field not a *Key", &NestedWithNonKeyField{ N: WithNonKeyField{ I: 12, K: "abcd", }, }, &NestedWithNonKeyField{ N: WithNonKeyField{ I: 12, K: "abcd", }, }, "datastore: __key__ field on struct datastore.WithNonKeyField is not a *datastore.Key", "", }, { "save struct with ptr to struct fields", &PtrToStructField{ &Basic{ A: "b", }, &Basic{ A: "c", }, &Basic{ A: "anon", }, []*Basic{ { A: "slice0", }, { A: "slice1", }, }, }, &PropertyList{ Property{Name: "A", Value: "anon", NoIndex: false}, Property{Name: "B", Value: &Entity{ Properties: []Property{ {Name: "A", Value: "b", NoIndex: false}, }, }}, Property{Name: "D", Value: []interface{}{ &Entity{ Properties: []Property{ {Name: "A", Value: "slice0", NoIndex: false}, }, }, &Entity{ Properties: []Property{ {Name: "A", Value: "slice1", NoIndex: false}, }, }, }, NoIndex: false}, Property{Name: "c", Value: &Entity{ Properties: []Property{ {Name: "A", Value: "c", NoIndex: true}, }, }, NoIndex: true}, }, "", "", }, { "save and load struct with ptr to struct fields", &PtrToStructField{ &Basic{ A: "b", }, &Basic{ A: "c", }, &Basic{ A: "anon", }, []*Basic{ { A: "slice0", }, { A: "slice1", }, }, }, &PtrToStructField{ &Basic{ A: "b", }, &Basic{ A: "c", }, &Basic{ A: "anon", }, []*Basic{ { A: "slice0", }, { A: "slice1", }, }, }, "", "", }, { "struct with nil ptr to struct fields", &PtrToStructField{ nil, nil, nil, nil, }, new(PropertyList), "", "", }, { "nested load entity with key", &WithNestedEntityWithKey{ N: EntityWithKey{ I: 12, S: "abcd", K: testKey0, }, }, &PropertyList{ Property{Name: "N", Value: &Entity{ Key: testKey0, Properties: []Property{ {Name: "I", Value: int64(12), NoIndex: false}, {Name: "S", Value: "abcd", NoIndex: false}, }, }, NoIndex: false}, }, "", "", }, { "nested save entity with key", &PropertyList{ Property{Name: "N", Value: &Entity{ Key: testKey0, Properties: []Property{ {Name: "I", Value: int64(12), NoIndex: false}, {Name: "S", Value: "abcd", NoIndex: false}, }, }, NoIndex: false}, }, &WithNestedEntityWithKey{ N: EntityWithKey{ I: 12, S: "abcd", K: testKey0, }, }, "", "", }, { "anonymous field with tag", &N3{ C3: C3{C: "s"}, }, &PropertyList{ Property{Name: "red", Value: &Entity{ Properties: []Property{ {Name: "C", Value: "s", NoIndex: false}, }, }, NoIndex: false}, }, "", "", }, { "unexported anonymous field", &N4{ c4: c4{C: "s"}, }, &PropertyList{ Property{Name: "C", Value: "s", NoIndex: false}, }, "", "", }, { "unexported anonymous field with tag", &N5{ c4: c4{C: "s"}, }, new(PropertyList), "", "", }, { "save props load structs with ragged fields", &PropertyList{ Property{Name: "red.S", Value: "rot", NoIndex: false}, Property{Name: "green.Nonymous.I", Value: []interface{}{int64(10), int64(11), int64(12), int64(13)}, NoIndex: false}, Property{Name: "Blue.Nonymous.I", Value: []interface{}{int64(20), int64(21)}, NoIndex: false}, Property{Name: "Blue.Nonymous.S", Value: []interface{}{"blau0", "blau1", "blau2"}, NoIndex: false}, }, &N2{ N1: N1{ X0: X0{S: "rot"}, }, Green: N1{ Nonymous: []X0{ {I: 10}, {I: 11}, {I: 12}, {I: 13}, }, }, Blue: N1{ Nonymous: []X0{ {S: "blau0", I: 20}, {S: "blau1", I: 21}, {S: "blau2"}, }, }, }, "", "", }, { "save structs with noindex tags", &struct { A struct { X string `datastore:",noindex"` Y string } `datastore:",noindex"` B struct { X string `datastore:",noindex"` Y string } }{}, &PropertyList{ Property{Name: "A", Value: &Entity{ Properties: []Property{ {Name: "X", Value: "", NoIndex: true}, {Name: "Y", Value: "", NoIndex: true}, }, }, NoIndex: true}, Property{Name: "B", Value: &Entity{ Properties: []Property{ {Name: "X", Value: "", NoIndex: true}, {Name: "Y", Value: "", NoIndex: false}, }, }, NoIndex: false}, }, "", "", }, { "embedded struct with name override", &struct { Inner1 `datastore:"foo"` }{}, &PropertyList{ Property{Name: "foo", Value: &Entity{ Properties: []Property{ {Name: "W", Value: int64(0), NoIndex: false}, {Name: "X", Value: "", NoIndex: false}, }, }, NoIndex: false}, }, "", "", }, { "slice of slices", &SliceOfSlices{}, nil, "flattening nested structs leads to a slice of slices", "", }, { "recursive struct", &Recursive{}, &Recursive{}, "", "", }, { "mutually recursive struct", &MutuallyRecursive0{}, &MutuallyRecursive0{}, "", "", }, { "non-exported struct fields", &struct { i, J int64 }{i: 1, J: 2}, &PropertyList{ Property{Name: "J", Value: int64(2), NoIndex: false}, }, "", "", }, { "json.RawMessage", &struct { J json.RawMessage }{ J: json.RawMessage("rawr"), }, &PropertyList{ Property{Name: "J", Value: []byte("rawr"), NoIndex: false}, }, "", "", }, { "json.RawMessage to myBlob", &struct { B json.RawMessage }{ B: json.RawMessage("rawr"), }, &B2{B: myBlob("rawr")}, "", "", }, { "repeated property names", &PropertyList{ Property{Name: "A", Value: ""}, Property{Name: "A", Value: ""}, }, nil, "duplicate Property", "", }, { "embedded time field", &SpecialTime{MyTime: EmbeddedTime{ts}}, &SpecialTime{MyTime: EmbeddedTime{ts}}, "", "", }, { "embedded time load", &PropertyList{ Property{Name: "MyTime.Time", Value: ts}, }, &SpecialTime{MyTime: EmbeddedTime{ts}}, "", "", }, { "pointer fields: nil", &Pointers{}, &Pointers{}, "", "", }, { "pointer fields: populated with zeroes", populatedPointers(), populatedPointers(), "", "", }, } // checkErr returns the empty string if either both want and err are zero, // or if want is a non-empty substring of err's string representation. func checkErr(want string, err error) string { if err != nil { got := err.Error() if want == "" || !strings.Contains(got, want) { return got } } else if want != "" { return fmt.Sprintf("want error %q", want) } return "" } func TestRoundTrip(t *testing.T) { for _, tc := range testCases { p, err := saveEntity(testKey0, tc.src) if s := checkErr(tc.putErr, err); s != "" { t.Errorf("%s: save: %s", tc.desc, s) continue } if p == nil { continue } var got interface{} if _, ok := tc.want.(*PropertyList); ok { got = new(PropertyList) } else { got = reflect.New(reflect.TypeOf(tc.want).Elem()).Interface() } err = loadEntityProto(got, p) if s := checkErr(tc.getErr, err); s != "" { t.Errorf("%s: load: %s", tc.desc, s) continue } if pl, ok := got.(*PropertyList); ok { // Sort by name to make sure we have a deterministic order. sortPL(*pl) } if !testutil.Equal(got, tc.want, cmp.AllowUnexported(X0{}, X2{})) { t.Errorf("%s: compare:\ngot: %+#v\nwant: %+#v", tc.desc, got, tc.want) continue } } } type aPtrPLS struct { Count int } func (pls *aPtrPLS) Load([]Property) error { pls.Count++ return nil } func (pls *aPtrPLS) Save() ([]Property, error) { return []Property{{Name: "Count", Value: 4}}, nil } type aValuePLS struct { Count int } func (pls aValuePLS) Load([]Property) error { pls.Count += 2 return nil } func (pls aValuePLS) Save() ([]Property, error) { return []Property{{Name: "Count", Value: 8}}, nil } type aValuePtrPLS struct { Count int } func (pls *aValuePtrPLS) Load([]Property) error { pls.Count = 11 return nil } func (pls *aValuePtrPLS) Save() ([]Property, error) { return []Property{{Name: "Count", Value: 12}}, nil } type aNotPLS struct { Count int } type plsString string func (s *plsString) Load([]Property) error { *s = "LOADED" return nil } func (s *plsString) Save() ([]Property, error) { return []Property{{Name: "SS", Value: "SAVED"}}, nil } func ptrToplsString(s string) *plsString { plsStr := plsString(s) return &plsStr } type aSubPLS struct { Foo string Bar *aPtrPLS Baz aValuePtrPLS S plsString } type aSubNotPLS struct { Foo string Bar *aNotPLS } type aSubPLSErr struct { Foo string Bar aValuePLS } type aSubPLSNoErr struct { Foo string Bar aPtrPLS } type GrandparentFlatten struct { Parent Parent `datastore:",flatten"` } type GrandparentOfPtrFlatten struct { Parent ParentOfPtr `datastore:",flatten"` } type GrandparentOfSlice struct { Parent ParentOfSlice } type GrandparentOfSlicePtrs struct { Parent ParentOfSlicePtrs } type GrandparentOfSliceFlatten struct { Parent ParentOfSlice `datastore:",flatten"` } type GrandparentOfSlicePtrsFlatten struct { Parent ParentOfSlicePtrs `datastore:",flatten"` } type Grandparent struct { Parent Parent } type Parent struct { Child Child String plsString } type ParentOfPtr struct { Child *Child String *plsString } type ParentOfSlice struct { Children []Child Strings []plsString } type ParentOfSlicePtrs struct { Children []*Child Strings []*plsString } type Child struct { I int Grandchild Grandchild } type Grandchild struct { S string } func (c *Child) Load(props []Property) error { for _, p := range props { if p.Name == "I" { c.I++ } else if p.Name == "Grandchild.S" { c.Grandchild.S = "grandchild loaded" } } return nil } func (c *Child) Save() ([]Property, error) { v := c.I + 1 return []Property{ {Name: "I", Value: v}, {Name: "Grandchild.S", Value: fmt.Sprintf("grandchild saved %d", v)}, }, nil } func TestLoadSavePLS(t *testing.T) { type testCase struct { desc string src interface{} wantSave *pb.Entity wantLoad interface{} saveErr string loadErr string } testCases := []testCase{ { desc: "non-struct implements PLS (top-level)", src: ptrToplsString("hello"), wantSave: &pb.Entity{ Key: keyToProto(testKey0), Properties: map[string]*pb.Value{ "SS": {ValueType: &pb.Value_StringValue{StringValue: "SAVED"}}, }, }, wantLoad: ptrToplsString("LOADED"), }, { desc: "substructs do implement PLS", src: &aSubPLS{Foo: "foo", Bar: &aPtrPLS{Count: 2}, Baz: aValuePtrPLS{Count: 15}, S: "something"}, wantSave: &pb.Entity{ Key: keyToProto(testKey0), Properties: map[string]*pb.Value{ "Foo": {ValueType: &pb.Value_StringValue{StringValue: "foo"}}, "Bar": {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Properties: map[string]*pb.Value{ "Count": {ValueType: &pb.Value_IntegerValue{IntegerValue: 4}}, }, }, }}, "Baz": {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Properties: map[string]*pb.Value{ "Count": {ValueType: &pb.Value_IntegerValue{IntegerValue: 12}}, }, }, }}, "S": {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Properties: map[string]*pb.Value{ "SS": {ValueType: &pb.Value_StringValue{StringValue: "SAVED"}}, }, }, }}, }, }, wantLoad: &aSubPLS{Foo: "foo", Bar: &aPtrPLS{Count: 1}, Baz: aValuePtrPLS{Count: 11}, S: "LOADED"}, }, { desc: "substruct (ptr) does implement PLS, nil valued substruct", src: &aSubPLS{Foo: "foo", S: "something"}, wantSave: &pb.Entity{ Key: keyToProto(testKey0), Properties: map[string]*pb.Value{ "Foo": {ValueType: &pb.Value_StringValue{StringValue: "foo"}}, "Baz": {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Properties: map[string]*pb.Value{ "Count": {ValueType: &pb.Value_IntegerValue{IntegerValue: 12}}, }, }, }}, "S": {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Properties: map[string]*pb.Value{ "SS": {ValueType: &pb.Value_StringValue{StringValue: "SAVED"}}, }, }, }}, }, }, wantLoad: &aSubPLS{Foo: "foo", Baz: aValuePtrPLS{Count: 11}, S: "LOADED"}, }, { desc: "substruct (ptr) does not implement PLS", src: &aSubNotPLS{Foo: "foo", Bar: &aNotPLS{Count: 2}}, wantSave: &pb.Entity{ Key: keyToProto(testKey0), Properties: map[string]*pb.Value{ "Foo": {ValueType: &pb.Value_StringValue{StringValue: "foo"}}, "Bar": {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Properties: map[string]*pb.Value{ "Count": {ValueType: &pb.Value_IntegerValue{IntegerValue: 2}}, }, }, }}, }, }, wantLoad: &aSubNotPLS{Foo: "foo", Bar: &aNotPLS{Count: 2}}, }, { desc: "substruct (value) does implement PLS, error on save", src: &aSubPLSErr{Foo: "foo", Bar: aValuePLS{Count: 2}}, wantSave: (*pb.Entity)(nil), wantLoad: &aSubPLSErr{}, saveErr: "PropertyLoadSaver methods must be implemented on a pointer", }, { desc: "substruct (value) does implement PLS, error on load", src: &aSubPLSNoErr{Foo: "foo", Bar: aPtrPLS{Count: 2}}, wantSave: &pb.Entity{ Key: keyToProto(testKey0), Properties: map[string]*pb.Value{ "Foo": {ValueType: &pb.Value_StringValue{StringValue: "foo"}}, "Bar": {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Properties: map[string]*pb.Value{ "Count": {ValueType: &pb.Value_IntegerValue{IntegerValue: 4}}, }, }, }}, }, }, wantLoad: &aSubPLSErr{}, loadErr: "PropertyLoadSaver methods must be implemented on a pointer", }, { desc: "parent does not have flatten option, child impl PLS", src: &Grandparent{ Parent: Parent{ Child: Child{ I: 9, Grandchild: Grandchild{ S: "BAD", }, }, String: plsString("something"), }, }, wantSave: &pb.Entity{ Key: keyToProto(testKey0), Properties: map[string]*pb.Value{ "Parent": {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Properties: map[string]*pb.Value{ "Child": {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Properties: map[string]*pb.Value{ "I": {ValueType: &pb.Value_IntegerValue{IntegerValue: 10}}, "Grandchild.S": {ValueType: &pb.Value_StringValue{StringValue: "grandchild saved 10"}}, }, }, }}, "String": {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Properties: map[string]*pb.Value{ "SS": {ValueType: &pb.Value_StringValue{StringValue: "SAVED"}}, }, }, }}, }, }, }}, }, }, wantLoad: &Grandparent{ Parent: Parent{ Child: Child{ I: 1, Grandchild: Grandchild{ S: "grandchild loaded", }, }, String: "LOADED", }, }, }, { desc: "parent has flatten option enabled, child impl PLS", src: &GrandparentFlatten{ Parent: Parent{ Child: Child{ I: 7, Grandchild: Grandchild{ S: "BAD", }, }, String: plsString("something"), }, }, wantSave: &pb.Entity{ Key: keyToProto(testKey0), Properties: map[string]*pb.Value{ "Parent.Child.I": {ValueType: &pb.Value_IntegerValue{IntegerValue: 8}}, "Parent.Child.Grandchild.S": {ValueType: &pb.Value_StringValue{StringValue: "grandchild saved 8"}}, "Parent.String.SS": {ValueType: &pb.Value_StringValue{StringValue: "SAVED"}}, }, }, wantLoad: &GrandparentFlatten{ Parent: Parent{ Child: Child{ I: 1, Grandchild: Grandchild{ S: "grandchild loaded", }, }, String: "LOADED", }, }, }, { desc: "parent has flatten option enabled, child (ptr to) impl PLS", src: &GrandparentOfPtrFlatten{ Parent: ParentOfPtr{ Child: &Child{ I: 7, Grandchild: Grandchild{ S: "BAD", }, }, String: ptrToplsString("something"), }, }, wantSave: &pb.Entity{ Key: keyToProto(testKey0), Properties: map[string]*pb.Value{ "Parent.Child.I": {ValueType: &pb.Value_IntegerValue{IntegerValue: 8}}, "Parent.Child.Grandchild.S": {ValueType: &pb.Value_StringValue{StringValue: "grandchild saved 8"}}, "Parent.String.SS": {ValueType: &pb.Value_StringValue{StringValue: "SAVED"}}, }, }, wantLoad: &GrandparentOfPtrFlatten{ Parent: ParentOfPtr{ Child: &Child{ I: 1, Grandchild: Grandchild{ S: "grandchild loaded", }, }, String: ptrToplsString("LOADED"), }, }, }, { desc: "children (slice of) impl PLS", src: &GrandparentOfSlice{ Parent: ParentOfSlice{ Children: []Child{ { I: 7, Grandchild: Grandchild{ S: "BAD", }, }, { I: 9, Grandchild: Grandchild{ S: "BAD2", }, }, }, Strings: []plsString{ "something1", "something2", }, }, }, wantSave: &pb.Entity{ Key: keyToProto(testKey0), Properties: map[string]*pb.Value{ "Parent": {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Properties: map[string]*pb.Value{ "Children": {ValueType: &pb.Value_ArrayValue{ ArrayValue: &pb.ArrayValue{Values: []*pb.Value{ {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Properties: map[string]*pb.Value{ "I": {ValueType: &pb.Value_IntegerValue{IntegerValue: 8}}, "Grandchild.S": {ValueType: &pb.Value_StringValue{StringValue: "grandchild saved 8"}}, }, }, }}, {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Properties: map[string]*pb.Value{ "I": {ValueType: &pb.Value_IntegerValue{IntegerValue: 10}}, "Grandchild.S": {ValueType: &pb.Value_StringValue{StringValue: "grandchild saved 10"}}, }, }, }}, }}, }}, "Strings": {ValueType: &pb.Value_ArrayValue{ ArrayValue: &pb.ArrayValue{Values: []*pb.Value{ {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Properties: map[string]*pb.Value{ "SS": {ValueType: &pb.Value_StringValue{StringValue: "SAVED"}}, }, }, }}, {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Properties: map[string]*pb.Value{ "SS": {ValueType: &pb.Value_StringValue{StringValue: "SAVED"}}, }, }, }}, }}, }}, }, }, }}, }, }, wantLoad: &GrandparentOfSlice{ Parent: ParentOfSlice{ Children: []Child{ { I: 1, Grandchild: Grandchild{ S: "grandchild loaded", }, }, { I: 1, Grandchild: Grandchild{ S: "grandchild loaded", }, }, }, Strings: []plsString{ "LOADED", "LOADED", }, }, }, }, { desc: "children (slice of ptrs) impl PLS", src: &GrandparentOfSlicePtrs{ Parent: ParentOfSlicePtrs{ Children: []*Child{ { I: 7, Grandchild: Grandchild{ S: "BAD", }, }, { I: 9, Grandchild: Grandchild{ S: "BAD2", }, }, }, Strings: []*plsString{ ptrToplsString("something1"), ptrToplsString("something2"), }, }, }, wantSave: &pb.Entity{ Key: keyToProto(testKey0), Properties: map[string]*pb.Value{ "Parent": {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Properties: map[string]*pb.Value{ "Children": {ValueType: &pb.Value_ArrayValue{ ArrayValue: &pb.ArrayValue{Values: []*pb.Value{ {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Properties: map[string]*pb.Value{ "I": {ValueType: &pb.Value_IntegerValue{IntegerValue: 8}}, "Grandchild.S": {ValueType: &pb.Value_StringValue{StringValue: "grandchild saved 8"}}, }, }, }}, {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Properties: map[string]*pb.Value{ "I": {ValueType: &pb.Value_IntegerValue{IntegerValue: 10}}, "Grandchild.S": {ValueType: &pb.Value_StringValue{StringValue: "grandchild saved 10"}}, }, }, }}, }}, }}, "Strings": {ValueType: &pb.Value_ArrayValue{ ArrayValue: &pb.ArrayValue{Values: []*pb.Value{ {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Properties: map[string]*pb.Value{ "SS": {ValueType: &pb.Value_StringValue{StringValue: "SAVED"}}, }, }, }}, {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Properties: map[string]*pb.Value{ "SS": {ValueType: &pb.Value_StringValue{StringValue: "SAVED"}}, }, }, }}, }}, }}, }, }, }}, }, }, wantLoad: &GrandparentOfSlicePtrs{ Parent: ParentOfSlicePtrs{ Children: []*Child{ { I: 1, Grandchild: Grandchild{ S: "grandchild loaded", }, }, { I: 1, Grandchild: Grandchild{ S: "grandchild loaded", }, }, }, Strings: []*plsString{ ptrToplsString("LOADED"), ptrToplsString("LOADED"), }, }, }, }, { desc: "parent has flatten option, children (slice of) impl PLS", src: &GrandparentOfSliceFlatten{ Parent: ParentOfSlice{ Children: []Child{ { I: 7, Grandchild: Grandchild{ S: "BAD", }, }, { I: 9, Grandchild: Grandchild{ S: "BAD2", }, }, }, Strings: []plsString{ "something1", "something2", }, }, }, wantSave: &pb.Entity{ Key: keyToProto(testKey0), Properties: map[string]*pb.Value{ "Parent.Children.I": {ValueType: &pb.Value_ArrayValue{ArrayValue: &pb.ArrayValue{ Values: []*pb.Value{ {ValueType: &pb.Value_IntegerValue{IntegerValue: 8}}, {ValueType: &pb.Value_IntegerValue{IntegerValue: 10}}, }, }, }}, "Parent.Children.Grandchild.S": {ValueType: &pb.Value_ArrayValue{ArrayValue: &pb.ArrayValue{ Values: []*pb.Value{ {ValueType: &pb.Value_StringValue{StringValue: "grandchild saved 8"}}, {ValueType: &pb.Value_StringValue{StringValue: "grandchild saved 10"}}, }, }, }}, "Parent.Strings.SS": {ValueType: &pb.Value_ArrayValue{ArrayValue: &pb.ArrayValue{ Values: []*pb.Value{ {ValueType: &pb.Value_StringValue{StringValue: "SAVED"}}, {ValueType: &pb.Value_StringValue{StringValue: "SAVED"}}, }, }, }}, }, }, wantLoad: &GrandparentOfSliceFlatten{ Parent: ParentOfSlice{ Children: []Child{ { I: 1, Grandchild: Grandchild{ S: "grandchild loaded", }, }, { I: 1, Grandchild: Grandchild{ S: "grandchild loaded", }, }, }, Strings: []plsString{ "LOADED", "LOADED", }, }, }, }, { desc: "parent has flatten option, children (slice of ptrs) impl PLS", src: &GrandparentOfSlicePtrsFlatten{ Parent: ParentOfSlicePtrs{ Children: []*Child{ { I: 7, Grandchild: Grandchild{ S: "BAD", }, }, { I: 9, Grandchild: Grandchild{ S: "BAD2", }, }, }, Strings: []*plsString{ ptrToplsString("something1"), ptrToplsString("something1"), }, }, }, wantSave: &pb.Entity{ Key: keyToProto(testKey0), Properties: map[string]*pb.Value{ "Parent.Children.I": {ValueType: &pb.Value_ArrayValue{ArrayValue: &pb.ArrayValue{ Values: []*pb.Value{ {ValueType: &pb.Value_IntegerValue{IntegerValue: 8}}, {ValueType: &pb.Value_IntegerValue{IntegerValue: 10}}, }, }, }}, "Parent.Children.Grandchild.S": {ValueType: &pb.Value_ArrayValue{ArrayValue: &pb.ArrayValue{ Values: []*pb.Value{ {ValueType: &pb.Value_StringValue{StringValue: "grandchild saved 8"}}, {ValueType: &pb.Value_StringValue{StringValue: "grandchild saved 10"}}, }, }, }}, "Parent.Strings.SS": {ValueType: &pb.Value_ArrayValue{ArrayValue: &pb.ArrayValue{ Values: []*pb.Value{ {ValueType: &pb.Value_StringValue{StringValue: "SAVED"}}, {ValueType: &pb.Value_StringValue{StringValue: "SAVED"}}, }, }, }}, }, }, wantLoad: &GrandparentOfSlicePtrsFlatten{ Parent: ParentOfSlicePtrs{ Children: []*Child{ { I: 1, Grandchild: Grandchild{ S: "grandchild loaded", }, }, { I: 1, Grandchild: Grandchild{ S: "grandchild loaded", }, }, }, Strings: []*plsString{ ptrToplsString("LOADED"), ptrToplsString("LOADED"), }, }, }, }, } for _, tc := range testCases { e, err := saveEntity(testKey0, tc.src) if tc.saveErr == "" { // Want no error. if err != nil { t.Errorf("%s: save: %v", tc.desc, err) continue } if !testutil.Equal(e, tc.wantSave) { t.Errorf("%s: save: \ngot: %+v\nwant: %+v", tc.desc, e, tc.wantSave) continue } } else { // Want error. if err == nil { t.Errorf("%s: save: want err", tc.desc) continue } if !strings.Contains(err.Error(), tc.saveErr) { t.Errorf("%s: save: \ngot err '%s'\nwant err '%s'", tc.desc, err.Error(), tc.saveErr) } continue } gota := reflect.New(reflect.TypeOf(tc.wantLoad).Elem()).Interface() err = loadEntityProto(gota, e) if tc.loadErr == "" { // Want no error. if err != nil { t.Errorf("%s: load: %v", tc.desc, err) continue } if !testutil.Equal(gota, tc.wantLoad) { t.Errorf("%s: load: \ngot: %+v\nwant: %+v", tc.desc, gota, tc.wantLoad) continue } } else { // Want error. if err == nil { t.Errorf("%s: load: want err", tc.desc) continue } if !strings.Contains(err.Error(), tc.loadErr) { t.Errorf("%s: load: \ngot err '%s'\nwant err '%s'", tc.desc, err.Error(), tc.loadErr) } } } } func TestQueryConstruction(t *testing.T) { tests := []struct { q, exp *Query err string }{ { q: NewQuery("Foo"), exp: &Query{ kind: "Foo", limit: -1, }, }, { // Regular filtered query with standard spacing. q: NewQuery("Foo").Filter("foo >", 7), exp: &Query{ kind: "Foo", filter: []filter{ { FieldName: "foo", Op: greaterThan, Value: 7, }, }, limit: -1, }, }, { // Filtered query with no spacing. q: NewQuery("Foo").Filter("foo=", 6), exp: &Query{ kind: "Foo", filter: []filter{ { FieldName: "foo", Op: equal, Value: 6, }, }, limit: -1, }, }, { // Filtered query with funky spacing. q: NewQuery("Foo").Filter(" foo< ", 8), exp: &Query{ kind: "Foo", filter: []filter{ { FieldName: "foo", Op: lessThan, Value: 8, }, }, limit: -1, }, }, { // Filtered query with multicharacter op. q: NewQuery("Foo").Filter("foo >=", 9), exp: &Query{ kind: "Foo", filter: []filter{ { FieldName: "foo", Op: greaterEq, Value: 9, }, }, limit: -1, }, }, { // Query with ordering. q: NewQuery("Foo").Order("bar"), exp: &Query{ kind: "Foo", order: []order{ { FieldName: "bar", Direction: ascending, }, }, limit: -1, }, }, { // Query with reverse ordering, and funky spacing. q: NewQuery("Foo").Order(" - bar"), exp: &Query{ kind: "Foo", order: []order{ { FieldName: "bar", Direction: descending, }, }, limit: -1, }, }, { // Query with an empty ordering. q: NewQuery("Foo").Order(""), err: "empty order", }, { // Query with a + ordering. q: NewQuery("Foo").Order("+bar"), err: "invalid order", }, } for i, test := range tests { if test.q.err != nil { got := test.q.err.Error() if !strings.Contains(got, test.err) { t.Errorf("%d: error mismatch: got %q want something containing %q", i, got, test.err) } continue } if !testutil.Equal(test.q, test.exp, cmp.AllowUnexported(Query{})) { t.Errorf("%d: mismatch: got %v want %v", i, test.q, test.exp) } } } func TestPutMultiTypes(t *testing.T) { ctx := context.Background() type S struct { A int B string } testCases := []struct { desc string src interface{} wantErr bool }{ // Test cases to check each of the valid input types for src. // Each case has the same elements. { desc: "type []struct", src: []S{ {1, "one"}, {2, "two"}, }, }, { desc: "type []*struct", src: []*S{ {1, "one"}, {2, "two"}, }, }, { desc: "type []interface{} with PLS elems", src: []interface{}{ &PropertyList{Property{Name: "A", Value: 1}, Property{Name: "B", Value: "one"}}, &PropertyList{Property{Name: "A", Value: 2}, Property{Name: "B", Value: "two"}}, }, }, { desc: "type []interface{} with struct ptr elems", src: []interface{}{ &S{1, "one"}, &S{2, "two"}, }, }, { desc: "type []PropertyLoadSaver{}", src: []PropertyLoadSaver{ &PropertyList{Property{Name: "A", Value: 1}, Property{Name: "B", Value: "one"}}, &PropertyList{Property{Name: "A", Value: 2}, Property{Name: "B", Value: "two"}}, }, }, { desc: "type []P (non-pointer, *P implements PropertyLoadSaver)", src: []PropertyList{ {Property{Name: "A", Value: 1}, Property{Name: "B", Value: "one"}}, {Property{Name: "A", Value: 2}, Property{Name: "B", Value: "two"}}, }, }, // Test some invalid cases. { desc: "type []interface{} with struct elems", src: []interface{}{ S{1, "one"}, S{2, "two"}, }, wantErr: true, }, { desc: "PropertyList", src: PropertyList{ Property{Name: "A", Value: 1}, Property{Name: "B", Value: "one"}, }, wantErr: true, }, { desc: "type []int", src: []int{1, 2}, wantErr: true, }, { desc: "not a slice", src: S{1, "one"}, wantErr: true, }, } // Use the same keys and expected entities for all tests. keys := []*Key{ NameKey("testKind", "first", nil), NameKey("testKind", "second", nil), } want := []*pb.Mutation{ {Operation: &pb.Mutation_Upsert{ Upsert: &pb.Entity{ Key: keyToProto(keys[0]), Properties: map[string]*pb.Value{ "A": {ValueType: &pb.Value_IntegerValue{IntegerValue: 1}}, "B": {ValueType: &pb.Value_StringValue{StringValue: "one"}}, }, }}}, {Operation: &pb.Mutation_Upsert{ Upsert: &pb.Entity{ Key: keyToProto(keys[1]), Properties: map[string]*pb.Value{ "A": {ValueType: &pb.Value_IntegerValue{IntegerValue: 2}}, "B": {ValueType: &pb.Value_StringValue{StringValue: "two"}}, }, }}}, } for _, tt := range testCases { // Set up a fake client which captures upserts. var got []*pb.Mutation client := &Client{ client: &fakeClient{ commitFn: func(req *pb.CommitRequest) (*pb.CommitResponse, error) { got = req.Mutations return &pb.CommitResponse{}, nil }, }, } _, err := client.PutMulti(ctx, keys, tt.src) if err != nil { if !tt.wantErr { t.Errorf("%s: error %v", tt.desc, err) } continue } if tt.wantErr { t.Errorf("%s: wanted error, but none returned", tt.desc) continue } if len(got) != len(want) { t.Errorf("%s: got %d entities, want %d", tt.desc, len(got), len(want)) continue } for i, e := range got { if !proto.Equal(e, want[i]) { t.Logf("%s: entity %d doesn't match\ngot: %v\nwant: %v", tt.desc, i, e, want[i]) } } } } func TestNoIndexOnSliceProperties(t *testing.T) { // Check that ExcludeFromIndexes is set on the inner elements, // rather than the top-level ArrayValue value. pl := PropertyList{ Property{ Name: "repeated", Value: []interface{}{ 123, false, "short", strings.Repeat("a", 1503), }, NoIndex: true, }, } key := NameKey("dummy", "dummy", nil) entity, err := saveEntity(key, &pl) if err != nil { t.Fatalf("saveEntity: %v", err) } want := &pb.Value{ ValueType: &pb.Value_ArrayValue{ArrayValue: &pb.ArrayValue{Values: []*pb.Value{ {ValueType: &pb.Value_IntegerValue{IntegerValue: 123}, ExcludeFromIndexes: true}, {ValueType: &pb.Value_BooleanValue{BooleanValue: false}, ExcludeFromIndexes: true}, {ValueType: &pb.Value_StringValue{StringValue: "short"}, ExcludeFromIndexes: true}, {ValueType: &pb.Value_StringValue{StringValue: strings.Repeat("a", 1503)}, ExcludeFromIndexes: true}, }}}, } if got := entity.Properties["repeated"]; !proto.Equal(got, want) { t.Errorf("Entity proto differs\ngot: %v\nwant: %v", got, want) } } type byName PropertyList func (s byName) Len() int { return len(s) } func (s byName) Less(i, j int) bool { return s[i].Name < s[j].Name } func (s byName) Swap(i, j int) { s[i], s[j] = s[j], s[i] } // sortPL sorts the property list by property name, and // recursively sorts any nested property lists, or nested slices of // property lists. func sortPL(pl PropertyList) { sort.Stable(byName(pl)) for _, p := range pl { switch p.Value.(type) { case *Entity: sortPL(p.Value.(*Entity).Properties) case []interface{}: for _, p2 := range p.Value.([]interface{}) { if nent, ok := p2.(*Entity); ok { sortPL(nent.Properties) } } } } } func TestValidGeoPoint(t *testing.T) { testCases := []struct { desc string pt GeoPoint want bool }{ { "valid", GeoPoint{67.21, 13.37}, true, }, { "high lat", GeoPoint{-90.01, 13.37}, false, }, { "low lat", GeoPoint{90.01, 13.37}, false, }, { "high lng", GeoPoint{67.21, 182}, false, }, { "low lng", GeoPoint{67.21, -181}, false, }, } for _, tc := range testCases { if got := tc.pt.Valid(); got != tc.want { t.Errorf("%s: got %v, want %v", tc.desc, got, tc.want) } } } func TestPutInvalidEntity(t *testing.T) { // Test that trying to put an invalid entity always returns the correct error // type. // Fake client that can pretend to start a transaction. fakeClient := &fakeDatastoreClient{ beginTransaction: func(*pb.BeginTransactionRequest) (*pb.BeginTransactionResponse, error) { return &pb.BeginTransactionResponse{ Transaction: []byte("deadbeef"), }, nil }, } client := &Client{ client: fakeClient, } ctx := context.Background() key := IncompleteKey("kind", nil) _, err := client.Put(ctx, key, "invalid entity") if err != ErrInvalidEntityType { t.Errorf("client.Put returned err %v, want %v", err, ErrInvalidEntityType) } _, err = client.PutMulti(ctx, []*Key{key}, []interface{}{"invalid entity"}) if me, ok := err.(MultiError); !ok { t.Errorf("client.PutMulti returned err %v, want MultiError type", err) } else if len(me) != 1 || me[0] != ErrInvalidEntityType { t.Errorf("client.PutMulti returned err %v, want MulitError{ErrInvalidEntityType}", err) } client.RunInTransaction(ctx, func(tx *Transaction) error { _, err := tx.Put(key, "invalid entity") if err != ErrInvalidEntityType { t.Errorf("tx.Put returned err %v, want %v", err, ErrInvalidEntityType) } _, err = tx.PutMulti([]*Key{key}, []interface{}{"invalid entity"}) if me, ok := err.(MultiError); !ok { t.Errorf("tx.PutMulti returned err %v, want MultiError type", err) } else if len(me) != 1 || me[0] != ErrInvalidEntityType { t.Errorf("tx.PutMulti returned err %v, want MulitError{ErrInvalidEntityType}", err) } return errors.New("bang") // Return error: we don't actually want to commit. }) } func TestDeferred(t *testing.T) { type Ent struct { A int B string } keys := []*Key{ NameKey("testKind", "first", nil), NameKey("testKind", "second", nil), } entity1 := &pb.Entity{ Key: keyToProto(keys[0]), Properties: map[string]*pb.Value{ "A": {ValueType: &pb.Value_IntegerValue{IntegerValue: 1}}, "B": {ValueType: &pb.Value_StringValue{StringValue: "one"}}, }, } entity2 := &pb.Entity{ Key: keyToProto(keys[1]), Properties: map[string]*pb.Value{ "A": {ValueType: &pb.Value_IntegerValue{IntegerValue: 2}}, "B": {ValueType: &pb.Value_StringValue{StringValue: "two"}}, }, } // count keeps track of the number of times fakeClient.lookup has been // called. var count int // Fake client that will return Deferred keys in resp on the first call. fakeClient := &fakeDatastoreClient{ lookup: func(*pb.LookupRequest) (*pb.LookupResponse, error) { count++ // On the first call, we return deferred keys. if count == 1 { return &pb.LookupResponse{ Found: []*pb.EntityResult{ { Entity: entity1, Version: 1, }, }, Deferred: []*pb.Key{ keyToProto(keys[1]), }, }, nil } // On the second call, we do not return any more deferred keys. return &pb.LookupResponse{ Found: []*pb.EntityResult{ { Entity: entity2, Version: 1, }, }, }, nil }, } client := &Client{ client: fakeClient, } ctx := context.Background() dst := make([]Ent, len(keys)) err := client.GetMulti(ctx, keys, dst) if err != nil { t.Fatalf("client.Get: %v", err) } if count != 2 { t.Fatalf("expected client.lookup to be called 2 times. Got %d", count) } if len(dst) != 2 { t.Fatalf("expected 2 entities returned, got %d", len(dst)) } for _, e := range dst { if e.A == 1 { if e.B != "one" { t.Fatalf("unexpected entity %+v", e) } } else if e.A == 2 { if e.B != "two" { t.Fatalf("unexpected entity %+v", e) } } else { t.Fatalf("unexpected entity %+v", e) } } } type KeyLoaderEnt struct { A int K *Key } func (e *KeyLoaderEnt) Load(p []Property) error { e.A = 2 return nil } func (e *KeyLoaderEnt) LoadKey(k *Key) error { e.K = k return nil } func (e *KeyLoaderEnt) Save() ([]Property, error) { return []Property{{Name: "A", Value: int64(3)}}, nil } func TestKeyLoaderEndToEnd(t *testing.T) { keys := []*Key{ NameKey("testKind", "first", nil), NameKey("testKind", "second", nil), } entity1 := &pb.Entity{ Key: keyToProto(keys[0]), Properties: map[string]*pb.Value{ "A": {ValueType: &pb.Value_IntegerValue{IntegerValue: 1}}, "B": {ValueType: &pb.Value_StringValue{StringValue: "one"}}, }, } entity2 := &pb.Entity{ Key: keyToProto(keys[1]), Properties: map[string]*pb.Value{ "A": {ValueType: &pb.Value_IntegerValue{IntegerValue: 2}}, "B": {ValueType: &pb.Value_StringValue{StringValue: "two"}}, }, } fakeClient := &fakeDatastoreClient{ lookup: func(*pb.LookupRequest) (*pb.LookupResponse, error) { return &pb.LookupResponse{ Found: []*pb.EntityResult{ { Entity: entity1, Version: 1, }, { Entity: entity2, Version: 1, }, }, }, nil }, } client := &Client{ client: fakeClient, } ctx := context.Background() dst := make([]*KeyLoaderEnt, len(keys)) err := client.GetMulti(ctx, keys, dst) if err != nil { t.Fatalf("client.Get: %v", err) } for i := range dst { if !testutil.Equal(dst[i].K, keys[i]) { t.Fatalf("unexpected entity %d to have key %+v, got %+v", i, keys[i], dst[i].K) } } } func TestDeferredMissing(t *testing.T) { type Ent struct { A int B string } keys := []*Key{ NameKey("testKind", "first", nil), NameKey("testKind", "second", nil), } entity1 := &pb.Entity{ Key: keyToProto(keys[0]), } entity2 := &pb.Entity{ Key: keyToProto(keys[1]), } var count int fakeClient := &fakeDatastoreClient{ lookup: func(*pb.LookupRequest) (*pb.LookupResponse, error) { count++ if count == 1 { return &pb.LookupResponse{ Missing: []*pb.EntityResult{ { Entity: entity1, Version: 1, }, }, Deferred: []*pb.Key{ keyToProto(keys[1]), }, }, nil } return &pb.LookupResponse{ Missing: []*pb.EntityResult{ { Entity: entity2, Version: 1, }, }, }, nil }, } client := &Client{ client: fakeClient, } ctx := context.Background() dst := make([]Ent, len(keys)) err := client.GetMulti(ctx, keys, dst) errs, ok := err.(MultiError) if !ok { t.Fatalf("expected error returns to be MultiError; got %v", err) } if len(errs) != 2 { t.Fatalf("expected 2 errors returns, got %d", len(errs)) } if errs[0] != ErrNoSuchEntity { t.Fatalf("expected error to be ErrNoSuchEntity; got %v", errs[0]) } if errs[1] != ErrNoSuchEntity { t.Fatalf("expected error to be ErrNoSuchEntity; got %v", errs[1]) } if count != 2 { t.Fatalf("expected client.lookup to be called 2 times. Got %d", count) } if len(dst) != 2 { t.Fatalf("expected 2 entities returned, got %d", len(dst)) } for _, e := range dst { if e.A != 0 || e.B != "" { t.Fatalf("unexpected entity %+v", e) } } } func TestGetWithNilKey(t *testing.T) { client := &Client{} err := client.Get(context.Background(), nil, []Property{}) if err != ErrInvalidKey { t.Fatalf("want ErrInvalidKey, got %v", err) } } func TestGetMultiWithNilKey(t *testing.T) { client := &Client{} dest := make([]PropertyList, 1) err := client.GetMulti(context.Background(), []*Key{nil}, dest) if me, ok := err.(MultiError); !ok { t.Fatalf("want MultiError, got %v", err) } else if len(me) != 1 || me[0] != ErrInvalidKey { t.Fatalf("want MultiError{ErrInvalidKey}, got %v", me) } } func TestGetWithIncompleteKey(t *testing.T) { client := &Client{} err := client.Get(context.Background(), &Key{Kind: "testKind"}, []Property{}) if err == nil { t.Fatalf("want err, got nil") } } func TestGetMultiWithIncompleteKey(t *testing.T) { client := &Client{} dest := make([]PropertyList, 1) err := client.GetMulti(context.Background(), []*Key{{Kind: "testKind"}}, dest) if me, ok := err.(MultiError); !ok { t.Fatalf("want MultiError, got %v", err) } else if len(me) != 1 || me[0] == nil { t.Fatalf("want MultiError{err}, got %v", me) } } func TestDeleteWithNilKey(t *testing.T) { client := &Client{} err := client.Delete(context.Background(), nil) if err != ErrInvalidKey { t.Fatalf("want ErrInvalidKey, got %v", err) } } func TestDeleteMultiWithNilKey(t *testing.T) { client := &Client{} err := client.DeleteMulti(context.Background(), []*Key{nil}) if me, ok := err.(MultiError); !ok { t.Fatalf("want MultiError, got %v", err) } else if len(me) != 1 || me[0] != ErrInvalidKey { t.Fatalf("want MultiError{ErrInvalidKey}, got %v", me) } } func TestDeleteWithIncompleteKey(t *testing.T) { client := &Client{} err := client.Delete(context.Background(), &Key{Kind: "testKind"}) if err == nil { t.Fatalf("want err, got nil") } } func TestDeleteMultiWithIncompleteKey(t *testing.T) { client := &Client{} err := client.DeleteMulti(context.Background(), []*Key{{Kind: "testKind"}}) if me, ok := err.(MultiError); !ok { t.Fatalf("want MultiError, got %v", err) } else if len(me) != 1 || me[0] == nil { t.Fatalf("want MultiError{err}, got %v", me) } } type fakeDatastoreClient struct { pb.DatastoreClient // Optional handlers for the datastore methods. // Any handlers left undefined will return an error. lookup func(*pb.LookupRequest) (*pb.LookupResponse, error) runQuery func(*pb.RunQueryRequest) (*pb.RunQueryResponse, error) beginTransaction func(*pb.BeginTransactionRequest) (*pb.BeginTransactionResponse, error) commit func(*pb.CommitRequest) (*pb.CommitResponse, error) rollback func(*pb.RollbackRequest) (*pb.RollbackResponse, error) allocateIds func(*pb.AllocateIdsRequest) (*pb.AllocateIdsResponse, error) } func (c *fakeDatastoreClient) Lookup(ctx context.Context, in *pb.LookupRequest, opts ...grpc.CallOption) (*pb.LookupResponse, error) { if c.lookup == nil { return nil, errors.New("no lookup handler defined") } return c.lookup(in) } func (c *fakeDatastoreClient) RunQuery(ctx context.Context, in *pb.RunQueryRequest, opts ...grpc.CallOption) (*pb.RunQueryResponse, error) { if c.runQuery == nil { return nil, errors.New("no runQuery handler defined") } return c.runQuery(in) } func (c *fakeDatastoreClient) BeginTransaction(ctx context.Context, in *pb.BeginTransactionRequest, opts ...grpc.CallOption) (*pb.BeginTransactionResponse, error) { if c.beginTransaction == nil { return nil, errors.New("no beginTransaction handler defined") } return c.beginTransaction(in) } func (c *fakeDatastoreClient) Commit(ctx context.Context, in *pb.CommitRequest, opts ...grpc.CallOption) (*pb.CommitResponse, error) { if c.commit == nil { return nil, errors.New("no commit handler defined") } return c.commit(in) } func (c *fakeDatastoreClient) Rollback(ctx context.Context, in *pb.RollbackRequest, opts ...grpc.CallOption) (*pb.RollbackResponse, error) { if c.rollback == nil { return nil, errors.New("no rollback handler defined") } return c.rollback(in) } func (c *fakeDatastoreClient) AllocateIds(ctx context.Context, in *pb.AllocateIdsRequest, opts ...grpc.CallOption) (*pb.AllocateIdsResponse, error) { if c.allocateIds == nil { return nil, errors.New("no allocateIds handler defined") } return c.allocateIds(in) } google-cloud-go-0.49.0/datastore/doc.go000066400000000000000000000371361356504100700176640ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. /* Package datastore provides a client for Google Cloud Datastore. See https://godoc.org/cloud.google.com/go for authentication, timeouts, connection pooling and similar aspects of this package. Basic Operations Entities are the unit of storage and are associated with a key. A key consists of an optional parent key, a string application ID, a string kind (also known as an entity type), and either a StringID or an IntID. A StringID is also known as an entity name or key name. It is valid to create a key with a zero StringID and a zero IntID; this is called an incomplete key, and does not refer to any saved entity. Putting an entity into the datastore under an incomplete key will cause a unique key to be generated for that entity, with a non-zero IntID. An entity's contents are a mapping from case-sensitive field names to values. Valid value types are: - Signed integers (int, int8, int16, int32 and int64) - bool - string - float32 and float64 - []byte (up to 1 megabyte in length) - Any type whose underlying type is one of the above predeclared types - *Key - GeoPoint - time.Time (stored with microsecond precision, retrieved as local time) - Structs whose fields are all valid value types - Pointers to structs whose fields are all valid value types - Slices of any of the above - Pointers to a signed integer, bool, string, float32, or float64 Slices of structs are valid, as are structs that contain slices. The Get and Put functions load and save an entity's contents. An entity's contents are typically represented by a struct pointer. Example code: type Entity struct { Value string } func main() { ctx := context.Background() // Create a datastore client. In a typical application, you would create // a single client which is reused for every datastore operation. dsClient, err := datastore.NewClient(ctx, "my-project") if err != nil { // Handle error. } k := datastore.NameKey("Entity", "stringID", nil) e := new(Entity) if err := dsClient.Get(ctx, k, e); err != nil { // Handle error. } old := e.Value e.Value = "Hello World!" if _, err := dsClient.Put(ctx, k, e); err != nil { // Handle error. } fmt.Printf("Updated value from %q to %q\n", old, e.Value) } GetMulti, PutMulti and DeleteMulti are batch versions of the Get, Put and Delete functions. They take a []*Key instead of a *Key, and may return a datastore.MultiError when encountering partial failure. Mutate generalizes PutMulti and DeleteMulti to a sequence of any Datastore mutations. It takes a series of mutations created with NewInsert, NewUpdate, NewUpsert and NewDelete and applies them atomically. Properties An entity's contents can be represented by a variety of types. These are typically struct pointers, but can also be any type that implements the PropertyLoadSaver interface. If using a struct pointer, you do not have to explicitly implement the PropertyLoadSaver interface; the datastore will automatically convert via reflection. If a struct pointer does implement PropertyLoadSaver then those methods will be used in preference to the default behavior for struct pointers. Struct pointers are more strongly typed and are easier to use; PropertyLoadSavers are more flexible. The actual types passed do not have to match between Get and Put calls or even across different calls to datastore. It is valid to put a *PropertyList and get that same entity as a *myStruct, or put a *myStruct0 and get a *myStruct1. Conceptually, any entity is saved as a sequence of properties, and is loaded into the destination value on a property-by-property basis. When loading into a struct pointer, an entity that cannot be completely represented (such as a missing field) will result in an ErrFieldMismatch error but it is up to the caller whether this error is fatal, recoverable or ignorable. By default, for struct pointers, all properties are potentially indexed, and the property name is the same as the field name (and hence must start with an upper case letter). Fields may have a `datastore:"name,options"` tag. The tag name is the property name, which must be one or more valid Go identifiers joined by ".", but may start with a lower case letter. An empty tag name means to just use the field name. A "-" tag name means that the datastore will ignore that field. The only valid options are "omitempty", "noindex" and "flatten". If the options include "omitempty" and the value of the field is a zero value, then the field will be omitted on Save. Zero values are best defined in the golang spec (https://golang.org/ref/spec#The_zero_value). Struct field values will never be empty, except for nil pointers. If options include "noindex" then the field will not be indexed. All fields are indexed by default. Strings or byte slices longer than 1500 bytes cannot be indexed; fields used to store long strings and byte slices must be tagged with "noindex" or they will cause Put operations to fail. For a nested struct field, the options may also include "flatten". This indicates that the immediate fields and any nested substruct fields of the nested struct should be flattened. See below for examples. To use multiple options together, separate them by a comma. The order does not matter. If the options is "" then the comma may be omitted. Example code: // A and B are renamed to a and b. // A, C and J are not indexed. // D's tag is equivalent to having no tag at all (E). // I is ignored entirely by the datastore. // J has tag information for both the datastore and json packages. type TaggedStruct struct { A int `datastore:"a,noindex"` B int `datastore:"b"` C int `datastore:",noindex"` D int `datastore:""` E int I int `datastore:"-"` J int `datastore:",noindex" json:"j"` } Slice Fields A field of slice type corresponds to a Datastore array property, except for []byte, which corresponds to a Datastore blob. Zero-length slice fields are not saved. Slice fields of length 1 or greater are saved as Datastore arrays. When a zero-length Datastore array is loaded into a slice field, the slice field remains unchanged. If a non-array value is loaded into a slice field, the result will be a slice with one element, containing the value. Loading Nulls Loading a Datastore Null into a basic type (int, float, etc.) results in a zero value. Loading a Null into a slice of basic type results in a slice of size 1 containing the zero value. Loading a Null into a pointer field results in nil. Loading a Null into a field of struct type is an error. Pointer Fields A struct field can be a pointer to a signed integer, floating-point number, string or bool. Putting a non-nil pointer will store its dereferenced value. Putting a nil pointer will store a Datastore Null property, unless the field is marked omitempty, in which case no property will be stored. Loading a Null into a pointer field sets the pointer to nil. Loading any other value allocates new storage with the value, and sets the field to point to it. Key Field If the struct contains a *datastore.Key field tagged with the name "__key__", its value will be ignored on Put. When reading the Entity back into the Go struct, the field will be populated with the *datastore.Key value used to query for the Entity. Example code: type MyEntity struct { A int K *datastore.Key `datastore:"__key__"` } func main() { ctx := context.Background() dsClient, err := datastore.NewClient(ctx, "my-project") if err != nil { // Handle error. } k := datastore.NameKey("Entity", "stringID", nil) e := MyEntity{A: 12} if _, err := dsClient.Put(ctx, k, &e); err != nil { // Handle error. } var entities []MyEntity q := datastore.NewQuery("Entity").Filter("A =", 12).Limit(1) if _, err := dsClient.GetAll(ctx, q, &entities); err != nil { // Handle error } log.Println(entities[0]) // Prints {12 /Entity,stringID} } Structured Properties If the struct pointed to contains other structs, then the nested or embedded structs are themselves saved as Entity values. For example, given these definitions: type Inner struct { W int32 X string } type Outer struct { I Inner } then an Outer would have one property, Inner, encoded as an Entity value. If an outer struct is tagged "noindex" then all of its implicit flattened fields are effectively "noindex". If the Inner struct contains a *Key field with the name "__key__", like so: type Inner struct { W int32 X string K *datastore.Key `datastore:"__key__"` } type Outer struct { I Inner } then the value of K will be used as the Key for Inner, represented as an Entity value in datastore. If any nested struct fields should be flattened, instead of encoded as Entity values, the nested struct field should be tagged with the "flatten" option. For example, given the following: type Inner1 struct { W int32 X string } type Inner2 struct { Y float64 } type Inner3 struct { Z bool } type Inner4 struct { WW int } type Inner5 struct { X Inner4 } type Outer struct { A int16 I []Inner1 `datastore:",flatten"` J Inner2 `datastore:",flatten"` K Inner5 `datastore:",flatten"` Inner3 `datastore:",flatten"` } an Outer's properties would be equivalent to those of: type OuterEquivalent struct { A int16 IDotW []int32 `datastore:"I.W"` IDotX []string `datastore:"I.X"` JDotY float64 `datastore:"J.Y"` KDotXDotWW int `datastore:"K.X.WW"` Z bool } Note that the "flatten" option cannot be used for Entity value fields or PropertyLoadSaver implementers. The server will reject any dotted field names for an Entity value. The PropertyLoadSaver Interface An entity's contents can also be represented by any type that implements the PropertyLoadSaver interface. This type may be a struct pointer, but it does not have to be. The datastore package will call Load when getting the entity's contents, and Save when putting the entity's contents. Possible uses include deriving non-stored fields, verifying fields, or indexing a field only if its value is positive. Example code: type CustomPropsExample struct { I, J int // Sum is not stored, but should always be equal to I + J. Sum int `datastore:"-"` } func (x *CustomPropsExample) Load(ps []datastore.Property) error { // Load I and J as usual. if err := datastore.LoadStruct(x, ps); err != nil { return err } // Derive the Sum field. x.Sum = x.I + x.J return nil } func (x *CustomPropsExample) Save() ([]datastore.Property, error) { // Validate the Sum field. if x.Sum != x.I + x.J { return nil, errors.New("CustomPropsExample has inconsistent sum") } // Save I and J as usual. The code below is equivalent to calling // "return datastore.SaveStruct(x)", but is done manually for // demonstration purposes. return []datastore.Property{ { Name: "I", Value: int64(x.I), }, { Name: "J", Value: int64(x.J), }, }, nil } The *PropertyList type implements PropertyLoadSaver, and can therefore hold an arbitrary entity's contents. The KeyLoader Interface If a type implements the PropertyLoadSaver interface, it may also want to implement the KeyLoader interface. The KeyLoader interface exists to allow implementations of PropertyLoadSaver to also load an Entity's Key into the Go type. This type may be a struct pointer, but it does not have to be. The datastore package will call LoadKey when getting the entity's contents, after calling Load. Example code: type WithKeyExample struct { I int Key *datastore.Key } func (x *WithKeyExample) LoadKey(k *datastore.Key) error { x.Key = k return nil } func (x *WithKeyExample) Load(ps []datastore.Property) error { // Load I as usual. return datastore.LoadStruct(x, ps) } func (x *WithKeyExample) Save() ([]datastore.Property, error) { // Save I as usual. return datastore.SaveStruct(x) } To load a Key into a struct which does not implement the PropertyLoadSaver interface, see the "Key Field" section above. Queries Queries retrieve entities based on their properties or key's ancestry. Running a query yields an iterator of results: either keys or (key, entity) pairs. Queries are re-usable and it is safe to call Query.Run from concurrent goroutines. Iterators are not safe for concurrent use. Queries are immutable, and are either created by calling NewQuery, or derived from an existing query by calling a method like Filter or Order that returns a new query value. A query is typically constructed by calling NewQuery followed by a chain of zero or more such methods. These methods are: - Ancestor and Filter constrain the entities returned by running a query. - Order affects the order in which they are returned. - Project constrains the fields returned. - Distinct de-duplicates projected entities. - KeysOnly makes the iterator return only keys, not (key, entity) pairs. - Start, End, Offset and Limit define which sub-sequence of matching entities to return. Start and End take cursors, Offset and Limit take integers. Start and Offset affect the first result, End and Limit affect the last result. If both Start and Offset are set, then the offset is relative to Start. If both End and Limit are set, then the earliest constraint wins. Limit is relative to Start+Offset, not relative to End. As a special case, a negative limit means unlimited. Example code: type Widget struct { Description string Price int } func printWidgets(ctx context.Context, client *datastore.Client) { q := datastore.NewQuery("Widget"). Filter("Price <", 1000). Order("-Price") t := client.Run(ctx, q) for { var x Widget key, err := t.Next(&x) if err == iterator.Done { break } if err != nil { // Handle error. } fmt.Printf("Key=%v\nWidget=%#v\n\n", key, x) } } Transactions Client.RunInTransaction runs a function in a transaction. Example code: type Counter struct { Count int } func incCount(ctx context.Context, client *datastore.Client) { var count int key := datastore.NameKey("Counter", "singleton", nil) _, err := client.RunInTransaction(ctx, func(tx *datastore.Transaction) error { var x Counter if err := tx.Get(key, &x); err != nil && err != datastore.ErrNoSuchEntity { return err } x.Count++ if _, err := tx.Put(key, &x); err != nil { return err } count = x.Count return nil }) if err != nil { // Handle error. } // The value of count is only valid once the transaction is successful // (RunInTransaction has returned nil). fmt.Printf("Count=%d\n", count) } Pass the ReadOnly option to RunInTransaction if your transaction is used only for Get, GetMulti or queries. Read-only transactions are more efficient. Google Cloud Datastore Emulator This package supports the Cloud Datastore emulator, which is useful for testing and development. Environment variables are used to indicate that datastore traffic should be directed to the emulator instead of the production Datastore service. To install and set up the emulator and its environment variables, see the documentation at https://cloud.google.com/datastore/docs/tools/datastore-emulator. */ package datastore // import "cloud.google.com/go/datastore" google-cloud-go-0.49.0/datastore/errors.go000066400000000000000000000023371356504100700204260ustar00rootroot00000000000000// Copyright 2014 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // This file provides error functions for common API failure modes. package datastore import ( "fmt" ) // MultiError is returned by batch operations when there are errors with // particular elements. Errors will be in a one-to-one correspondence with // the input elements; successful elements will have a nil entry. type MultiError []error func (m MultiError) Error() string { s, n := "", 0 for _, e := range m { if e != nil { if n == 0 { s = e.Error() } n++ } } switch n { case 0: return "(0 errors)" case 1: return s case 2: return s + " (and 1 other error)" } return fmt.Sprintf("%s (and %d other errors)", s, n-1) } google-cloud-go-0.49.0/datastore/example_test.go000066400000000000000000000334341356504100700216060ustar00rootroot00000000000000// Copyright 2014 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package datastore_test import ( "context" "fmt" "log" "time" "cloud.google.com/go/datastore" "google.golang.org/api/iterator" ) func ExampleNewClient() { ctx := context.Background() client, err := datastore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } _ = client // TODO: Use client. } func ExampleClient_Get() { ctx := context.Background() client, err := datastore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } type Article struct { Title string Description string Body string `datastore:",noindex"` Author *datastore.Key PublishedAt time.Time } key := datastore.NameKey("Article", "articled1", nil) article := &Article{} if err := client.Get(ctx, key, article); err != nil { // TODO: Handle error. } } func ExampleClient_Put() { ctx := context.Background() client, err := datastore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } type Article struct { Title string Description string Body string `datastore:",noindex"` Author *datastore.Key PublishedAt time.Time } newKey := datastore.IncompleteKey("Article", nil) _, err = client.Put(ctx, newKey, &Article{ Title: "The title of the article", Description: "The description of the article...", Body: "...", Author: datastore.NameKey("Author", "jbd", nil), PublishedAt: time.Now(), }) if err != nil { // TODO: Handle error. } } func ExampleClient_Put_flatten() { ctx := context.Background() client, err := datastore.NewClient(ctx, "project-id") if err != nil { log.Fatal(err) } type Animal struct { Name string Type string Breed string } type Human struct { Name string Height int Pet Animal `datastore:",flatten"` } newKey := datastore.IncompleteKey("Human", nil) _, err = client.Put(ctx, newKey, &Human{ Name: "Susan", Height: 67, Pet: Animal{ Name: "Fluffy", Type: "Cat", Breed: "Sphynx", }, }) if err != nil { log.Fatal(err) } } func ExampleClient_Delete() { ctx := context.Background() client, err := datastore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } key := datastore.NameKey("Article", "articled1", nil) if err := client.Delete(ctx, key); err != nil { // TODO: Handle error. } } func ExampleClient_DeleteMulti() { ctx := context.Background() client, err := datastore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } var keys []*datastore.Key for i := 1; i <= 10; i++ { keys = append(keys, datastore.IDKey("Article", int64(i), nil)) } if err := client.DeleteMulti(ctx, keys); err != nil { // TODO: Handle error. } } type Post struct { Title string PublishedAt time.Time Comments int } func ExampleClient_GetMulti() { ctx := context.Background() client, err := datastore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } keys := []*datastore.Key{ datastore.NameKey("Post", "post1", nil), datastore.NameKey("Post", "post2", nil), datastore.NameKey("Post", "post3", nil), } posts := make([]Post, 3) if err := client.GetMulti(ctx, keys, posts); err != nil { // TODO: Handle error. } } func ExampleMultiError() { ctx := context.Background() client, err := datastore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } keys := []*datastore.Key{ datastore.NameKey("bad-key", "bad-key", nil), } posts := make([]Post, 1) if err := client.GetMulti(ctx, keys, posts); err != nil { if merr, ok := err.(datastore.MultiError); ok { for _, err := range merr { // TODO: Handle error. _ = err } } else { // TODO: Handle error. } } } func ExampleClient_PutMulti_slice() { ctx := context.Background() client, err := datastore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } keys := []*datastore.Key{ datastore.NameKey("Post", "post1", nil), datastore.NameKey("Post", "post2", nil), } // PutMulti with a Post slice. posts := []*Post{ {Title: "Post 1", PublishedAt: time.Now()}, {Title: "Post 2", PublishedAt: time.Now()}, } if _, err := client.PutMulti(ctx, keys, posts); err != nil { // TODO: Handle error. } } func ExampleClient_PutMulti_interfaceSlice() { ctx := context.Background() client, err := datastore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } keys := []*datastore.Key{ datastore.NameKey("Post", "post1", nil), datastore.NameKey("Post", "post2", nil), } // PutMulti with an empty interface slice. posts := []interface{}{ &Post{Title: "Post 1", PublishedAt: time.Now()}, &Post{Title: "Post 2", PublishedAt: time.Now()}, } if _, err := client.PutMulti(ctx, keys, posts); err != nil { // TODO: Handle error. } } func ExampleNewQuery() { // Query for Post entities. q := datastore.NewQuery("Post") _ = q // TODO: Use the query with Client.Run. } func ExampleNewQuery_options() { // Query to order the posts by the number of comments they have received. q := datastore.NewQuery("Post").Order("-Comments") // Start listing from an offset and limit the results. q = q.Offset(20).Limit(10) _ = q // TODO: Use the query. } func ExampleClient_Count() { ctx := context.Background() client, err := datastore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } // Count the number of the post entities. q := datastore.NewQuery("Post") n, err := client.Count(ctx, q) if err != nil { // TODO: Handle error. } fmt.Printf("There are %d posts.", n) } func ExampleClient_Run() { ctx := context.Background() client, err := datastore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } // List the posts published since yesterday. yesterday := time.Now().Add(-24 * time.Hour) q := datastore.NewQuery("Post").Filter("PublishedAt >", yesterday) it := client.Run(ctx, q) _ = it // TODO: iterate using Next. } func ExampleClient_NewTransaction() { ctx := context.Background() client, err := datastore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } const retries = 3 // Increment a counter. // See https://cloud.google.com/appengine/articles/sharding_counters for // a more scalable solution. type Counter struct { Count int } key := datastore.NameKey("counter", "CounterA", nil) var tx *datastore.Transaction for i := 0; i < retries; i++ { tx, err = client.NewTransaction(ctx) if err != nil { break } var c Counter if err = tx.Get(key, &c); err != nil && err != datastore.ErrNoSuchEntity { break } c.Count++ if _, err = tx.Put(key, &c); err != nil { break } // Attempt to commit the transaction. If there's a conflict, try again. if _, err = tx.Commit(); err != datastore.ErrConcurrentTransaction { break } } if err != nil { // TODO: Handle error. } } func ExampleClient_RunInTransaction() { ctx := context.Background() client, err := datastore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } // Increment a counter. // See https://cloud.google.com/appengine/articles/sharding_counters for // a more scalable solution. type Counter struct { Count int } var count int key := datastore.NameKey("Counter", "singleton", nil) _, err = client.RunInTransaction(ctx, func(tx *datastore.Transaction) error { var x Counter if err := tx.Get(key, &x); err != nil && err != datastore.ErrNoSuchEntity { return err } x.Count++ if _, err := tx.Put(key, &x); err != nil { return err } count = x.Count return nil }) if err != nil { // TODO: Handle error. } // The value of count is only valid once the transaction is successful // (RunInTransaction has returned nil). fmt.Printf("Count=%d\n", count) } func ExampleClient_AllocateIDs() { ctx := context.Background() client, err := datastore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } var keys []*datastore.Key for i := 0; i < 10; i++ { keys = append(keys, datastore.IncompleteKey("Article", nil)) } keys, err = client.AllocateIDs(ctx, keys) if err != nil { // TODO: Handle error. } _ = keys // TODO: Use keys. } func ExampleKey_Encode() { key := datastore.IDKey("Article", 1, nil) encoded := key.Encode() fmt.Println(encoded) // Output: EgsKB0FydGljbGUQAQ } func ExampleDecodeKey() { const encoded = "EgsKB0FydGljbGUQAQ" key, err := datastore.DecodeKey(encoded) if err != nil { // TODO: Handle error. } fmt.Println(key) // Output: /Article,1 } func ExampleIDKey() { // Key with numeric ID. k := datastore.IDKey("Article", 1, nil) _ = k // TODO: Use key. } func ExampleNameKey() { // Key with string ID. k := datastore.NameKey("Article", "article8", nil) _ = k // TODO: Use key. } func ExampleIncompleteKey() { k := datastore.IncompleteKey("Article", nil) _ = k // TODO: Use incomplete key. } func ExampleClient_GetAll() { ctx := context.Background() client, err := datastore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } var posts []*Post keys, err := client.GetAll(ctx, datastore.NewQuery("Post"), &posts) if err != nil { // TODO: Handle error. } for i, key := range keys { fmt.Println(key) fmt.Println(posts[i]) } } func ExampleClient_Mutate() { ctx := context.Background() client, err := datastore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } key1 := datastore.NameKey("Post", "post1", nil) key2 := datastore.NameKey("Post", "post2", nil) key3 := datastore.NameKey("Post", "post3", nil) key4 := datastore.NameKey("Post", "post4", nil) _, err = client.Mutate(ctx, datastore.NewInsert(key1, Post{Title: "Post 1"}), datastore.NewUpsert(key2, Post{Title: "Post 2"}), datastore.NewUpdate(key3, Post{Title: "Post 3"}), datastore.NewDelete(key4)) if err != nil { // TODO: Handle error. } } func ExampleCommit_Key() { ctx := context.Background() client, err := datastore.NewClient(ctx, "") if err != nil { // TODO: Handle error. } var pk1, pk2 *datastore.PendingKey // Create two posts in a single transaction. commit, err := client.RunInTransaction(ctx, func(tx *datastore.Transaction) error { var err error pk1, err = tx.Put(datastore.IncompleteKey("Post", nil), &Post{Title: "Post 1", PublishedAt: time.Now()}) if err != nil { return err } pk2, err = tx.Put(datastore.IncompleteKey("Post", nil), &Post{Title: "Post 2", PublishedAt: time.Now()}) if err != nil { return err } return nil }) if err != nil { // TODO: Handle error. } // Now pk1, pk2 are valid PendingKeys. Let's convert them into real keys // using the Commit object. k1 := commit.Key(pk1) k2 := commit.Key(pk2) fmt.Println(k1, k2) } func ExampleIterator_Next() { ctx := context.Background() client, err := datastore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } it := client.Run(ctx, datastore.NewQuery("Post")) for { var p Post key, err := it.Next(&p) if err == iterator.Done { break } if err != nil { // TODO: Handle error. } fmt.Println(key, p) } } func ExampleIterator_Cursor() { ctx := context.Background() client, err := datastore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } it := client.Run(ctx, datastore.NewQuery("Post")) for { var p Post _, err := it.Next(&p) if err == iterator.Done { break } if err != nil { // TODO: Handle error. } fmt.Println(p) cursor, err := it.Cursor() if err != nil { // TODO: Handle error. } // When printed, a cursor will display as a string that can be passed // to datastore.NewCursor. fmt.Printf("to resume with this post, use cursor %s\n", cursor) } } func ExampleDecodeCursor() { // See Query.Start for a fuller example of DecodeCursor. // getCursor represents a function that returns a cursor from a previous // iteration in string form. cursorString := getCursor() cursor, err := datastore.DecodeCursor(cursorString) if err != nil { // TODO: Handle error. } _ = cursor // TODO: Use the cursor with Query.Start or Query.End. } func getCursor() string { return "" } func ExampleQuery_Start() { // This example demonstrates how to use cursors and Query.Start // to resume an iteration. ctx := context.Background() client, err := datastore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } // getCursor represents a function that returns a cursor from a previous // iteration in string form. cursorString := getCursor() cursor, err := datastore.DecodeCursor(cursorString) if err != nil { // TODO: Handle error. } it := client.Run(ctx, datastore.NewQuery("Post").Start(cursor)) _ = it // TODO: Use iterator. } func ExampleLoadStruct() { type Player struct { User string Score int } // Normally LoadStruct would only be used inside a custom implementation of // PropertyLoadSaver; this is for illustrative purposes only. props := []datastore.Property{ {Name: "User", Value: "Alice"}, {Name: "Score", Value: int64(97)}, } var p Player if err := datastore.LoadStruct(&p, props); err != nil { // TODO: Handle error. } fmt.Println(p) // Output: {Alice 97} } func ExampleSaveStruct() { type Player struct { User string Score int } p := &Player{ User: "Alice", Score: 97, } props, err := datastore.SaveStruct(p) if err != nil { // TODO: Handle error. } fmt.Println(props) // TODO(jba): make this output stable: Output: [{User Alice false} {Score 97 false}] } google-cloud-go-0.49.0/datastore/go.mod000066400000000000000000000010701356504100700176620ustar00rootroot00000000000000module cloud.google.com/go/datastore go 1.11 require ( cloud.google.com/go v0.46.3 cloud.google.com/go/storage v1.0.0 // indirect github.com/golang/protobuf v1.3.2 github.com/google/go-cmp v0.3.0 github.com/googleapis/gax-go/v2 v2.0.5 golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136 // indirect golang.org/x/lint v0.0.0-20190930215403-16217165b5de // indirect golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2 // indirect google.golang.org/api v0.14.0 google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9 google.golang.org/grpc v1.21.1 ) google-cloud-go-0.49.0/datastore/go.sum000066400000000000000000000422061356504100700177150ustar00rootroot00000000000000cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1 h1:7gXaI3V/b4DRaK++rTqhRajcT7z8gtP0qKMZTXqlySM= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3 h1:AVXDdKsrtX33oR9fbCMu/+c1o8Ofjq6Ku/MInaLVg5Y= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go/bigquery v1.0.1 h1:hL+ycaJpVE9M7nLoiXb/Pn10ENE2u+oddxbD8uu0ZVU= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/pubsub v1.0.1 h1:W9tAK3E57P75u0XLLR82LZyw8VpAnhmyTOxW9qzmyj8= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/storage v1.0.0 h1:VV2nUM3wwLLGh9lSABFgZMjInyUbJeaRSE64WuAIQ+4= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024 h1:rBMNdlhTLzJjJSDIjNEXX1Pz3Hmwmz91v+zycvx9PJc= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522 h1:OeRHuibLsmZkFj773W4LcfAGsSxJgfPONhr8cmO+eLA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979 h1:Agxu5KLo8o7Bb634SVDnhIfpTvxmzUwhbYAzBvXt6h4= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136 h1:A1gGSx58LAGVHUUsOf7IiR0u8Xb6W51gRwfDBhkdcaw= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422 h1:QzoH/1pFpZguR8NrRHLcO6jKqfv2zpuSqZLgdm7ZmjI= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac h1:8R1esu+8QioDxo4E4mX6bFztO+dMTM49DNAaWfO5OeY= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0 h1:HyfiK1WMnHj5FXFXatD+Qs1A/xC2Run6RzeW1SyHxpc= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0 h1:Dh6fw+p6FyRl5x/FvNswO1ji0lIGzm3KP8Y9VkS9PTE= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff h1:On1qIo75ByTwFJ4/W2bIqHcwJ9XAqtSWUs8GwRrIhtc= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2 h1:EtTFh6h4SAKemS+CURDMTDIANuduG5zKEXShyy18bGA= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0 h1:VGGbLNyPF7dvYHhcUGYBBGCRDDK0RRJAI6KCvo0CL+E= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0 h1:jbyannxz0XFD3zdjgrSUsaJbgpH4eTrkdhRChkHPfO8= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.14.0 h1:uMf5uLi4eQMRrMKhCplNik4U4H8Z6C1br3zOtAa/aDE= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64 h1:iKtrH9Y8mcbADOP0YFaEMth7OfuHY9xHOwNj4znpM1A= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51 h1:Ex1mq5jaJof+kRnYi3SlYJ8KKa9Ao3NHyIT5XJ1gF6U= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9 h1:6XzpBoANz1NqMNfDXzc2QmHmbb1vyMsvRfoP5rM+K1I= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1 h1:j6XxA85m/6txkUCHvzlV5f+HBNl/1r5cZ2A/3IEFOO8= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a h1:LJwr7TCTghdatWv40WobzlKXc9c4s8oGa7QKJUtHhWA= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= google-cloud-go-0.49.0/datastore/go_mod_tidy_hack.go000066400000000000000000000016301356504100700223700ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // This file, and the cloud.google.com/go import, won't actually become part of // the resultant binary. // +build modhack package datastore // Necessary for safely adding multi-module repo. See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository import _ "cloud.google.com/go" google-cloud-go-0.49.0/datastore/integration_test.go000066400000000000000000001014251356504100700224720ustar00rootroot00000000000000// Copyright 2014 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package datastore import ( "context" "encoding/json" "errors" "flag" "fmt" "log" "os" "reflect" "sort" "strings" "sync" "testing" "time" "cloud.google.com/go/internal/testutil" "cloud.google.com/go/internal/uid" "cloud.google.com/go/rpcreplay" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) // TODO(djd): Make test entity clean up more robust: some test entities may // be left behind if tests are aborted, the transport fails, etc. var timeNow = time.Now() // suffix is a timestamp-based suffix which is appended to key names, // particularly for the root keys of entity groups. This reduces flakiness // when the tests are run in parallel. var suffix string const replayFilename = "datastore.replay" type replayInfo struct { ProjectID string Time time.Time } var ( record = flag.Bool("record", false, "record RPCs") newTestClient = func(ctx context.Context, t *testing.T) *Client { return newClient(ctx, t, nil) } ) func TestMain(m *testing.M) { os.Exit(testMain(m)) } func testMain(m *testing.M) int { flag.Parse() if testing.Short() { if *record { log.Fatal("cannot combine -short and -record") } if testutil.CanReplay(replayFilename) { initReplay() } } else if *record { if testutil.ProjID() == "" { log.Fatal("must record with a project ID") } b, err := json.Marshal(replayInfo{ ProjectID: testutil.ProjID(), Time: timeNow, }) if err != nil { log.Fatal(err) } rec, err := rpcreplay.NewRecorder(replayFilename, b) if err != nil { log.Fatal(err) } defer func() { if err := rec.Close(); err != nil { log.Fatalf("closing recorder: %v", err) } }() newTestClient = func(ctx context.Context, t *testing.T) *Client { return newClient(ctx, t, rec.DialOptions()) } log.Printf("recording to %s", replayFilename) } suffix = fmt.Sprintf("-t%d", timeNow.UnixNano()) return m.Run() } func initReplay() { rep, err := rpcreplay.NewReplayer(replayFilename) if err != nil { log.Fatal(err) } defer rep.Close() var ri replayInfo if err := json.Unmarshal(rep.Initial(), &ri); err != nil { log.Fatalf("unmarshaling initial replay info: %v", err) } timeNow = ri.Time.In(time.Local) conn, err := rep.Connection() if err != nil { log.Fatal(err) } newTestClient = func(ctx context.Context, t *testing.T) *Client { grpcHeadersEnforcer := &testutil.HeadersEnforcer{ OnFailure: t.Fatalf, Checkers: []*testutil.HeaderChecker{ testutil.XGoogClientHeaderChecker, }, } opts := append(grpcHeadersEnforcer.CallOptions(), option.WithGRPCConn(conn)) client, err := NewClient(ctx, ri.ProjectID, opts...) if err != nil { t.Fatalf("NewClient: %v", err) } return client } log.Printf("replaying from %s", replayFilename) } func newClient(ctx context.Context, t *testing.T, dialOpts []grpc.DialOption) *Client { if testing.Short() { t.Skip("Integration tests skipped in short mode") } ts := testutil.TokenSource(ctx, ScopeDatastore) if ts == nil { t.Skip("Integration tests skipped. See CONTRIBUTING.md for details") } grpcHeadersEnforcer := &testutil.HeadersEnforcer{ OnFailure: t.Fatalf, Checkers: []*testutil.HeaderChecker{ testutil.XGoogClientHeaderChecker, }, } opts := append(grpcHeadersEnforcer.CallOptions(), option.WithTokenSource(ts)) for _, opt := range dialOpts { opts = append(opts, option.WithGRPCDialOption(opt)) } client, err := NewClient(ctx, testutil.ProjID(), opts...) if err != nil { t.Fatalf("NewClient: %v", err) } return client } func TestIntegration_Basics(t *testing.T) { ctx, _ := context.WithTimeout(context.Background(), time.Second*20) client := newTestClient(ctx, t) defer client.Close() type X struct { I int S string T time.Time U interface{} } x0 := X{66, "99", timeNow.Truncate(time.Millisecond), "X"} k, err := client.Put(ctx, IncompleteKey("BasicsX", nil), &x0) if err != nil { t.Fatalf("client.Put: %v", err) } x1 := X{} err = client.Get(ctx, k, &x1) if err != nil { t.Errorf("client.Get: %v", err) } err = client.Delete(ctx, k) if err != nil { t.Errorf("client.Delete: %v", err) } if !testutil.Equal(x0, x1) { t.Errorf("compare: x0=%v, x1=%v", x0, x1) } } func TestIntegration_TopLevelKeyLoaded(t *testing.T) { ctx, _ := context.WithTimeout(context.Background(), time.Second*20) client := newTestClient(ctx, t) defer client.Close() completeKey := NameKey("EntityWithKey", "myent", nil) type EntityWithKey struct { I int S string K *Key `datastore:"__key__"` } in := &EntityWithKey{ I: 12, S: "abcd", } k, err := client.Put(ctx, completeKey, in) if err != nil { t.Fatalf("client.Put: %v", err) } var e EntityWithKey err = client.Get(ctx, k, &e) if err != nil { t.Fatalf("client.Get: %v", err) } // The two keys should be absolutely identical. if !testutil.Equal(e.K, k) { t.Fatalf("e.K not equal to k; got %#v, want %#v", e.K, k) } } func TestIntegration_ListValues(t *testing.T) { ctx := context.Background() client := newTestClient(ctx, t) defer client.Close() p0 := PropertyList{ {Name: "L", Value: []interface{}{int64(12), "string", true}}, } k, err := client.Put(ctx, IncompleteKey("ListValue", nil), &p0) if err != nil { t.Fatalf("client.Put: %v", err) } var p1 PropertyList if err := client.Get(ctx, k, &p1); err != nil { t.Errorf("client.Get: %v", err) } if !testutil.Equal(p0, p1) { t.Errorf("compare:\np0=%v\np1=%#v", p0, p1) } if err = client.Delete(ctx, k); err != nil { t.Errorf("client.Delete: %v", err) } } func TestIntegration_GetMulti(t *testing.T) { ctx := context.Background() client := newTestClient(ctx, t) defer client.Close() type X struct { I int } p := NameKey("X", "x"+suffix, nil) cases := []struct { key *Key put bool }{ {key: NameKey("X", "item1", p), put: true}, {key: NameKey("X", "item2", p), put: false}, {key: NameKey("X", "item3", p), put: false}, {key: NameKey("X", "item3", p), put: false}, {key: NameKey("X", "item4", p), put: true}, } var src, dst []*X var srcKeys, dstKeys []*Key for _, c := range cases { dst = append(dst, &X{}) dstKeys = append(dstKeys, c.key) if c.put { src = append(src, &X{}) srcKeys = append(srcKeys, c.key) } } if _, err := client.PutMulti(ctx, srcKeys, src); err != nil { t.Error(err) } err := client.GetMulti(ctx, dstKeys, dst) if err == nil { t.Errorf("client.GetMulti got %v, expected error", err) } e, ok := err.(MultiError) if !ok { t.Errorf("client.GetMulti got %T, expected MultiError", err) } for i, err := range e { got, want := err, (error)(nil) if !cases[i].put { got, want = err, ErrNoSuchEntity } if got != want { t.Errorf("MultiError[%d] == %v, want %v", i, got, want) } } } type Z struct { S string T string `datastore:",noindex"` P []byte K []byte `datastore:",noindex"` } func (z Z) String() string { var lens []string v := reflect.ValueOf(z) for i := 0; i < v.NumField(); i++ { if l := v.Field(i).Len(); l > 0 { lens = append(lens, fmt.Sprintf("len(%s)=%d", v.Type().Field(i).Name, l)) } } return fmt.Sprintf("Z{ %s }", strings.Join(lens, ",")) } func TestIntegration_UnindexableValues(t *testing.T) { ctx := context.Background() client := newTestClient(ctx, t) defer client.Close() x1500 := strings.Repeat("x", 1500) x1501 := strings.Repeat("x", 1501) testCases := []struct { in Z wantErr bool }{ {in: Z{S: x1500}, wantErr: false}, {in: Z{S: x1501}, wantErr: true}, {in: Z{T: x1500}, wantErr: false}, {in: Z{T: x1501}, wantErr: false}, {in: Z{P: []byte(x1500)}, wantErr: false}, {in: Z{P: []byte(x1501)}, wantErr: true}, {in: Z{K: []byte(x1500)}, wantErr: false}, {in: Z{K: []byte(x1501)}, wantErr: false}, } for _, tt := range testCases { _, err := client.Put(ctx, IncompleteKey("BasicsZ", nil), &tt.in) if (err != nil) != tt.wantErr { t.Errorf("client.Put %s got err %v, want err %t", tt.in, err, tt.wantErr) } } } func TestIntegration_NilKey(t *testing.T) { ctx := context.Background() client := newTestClient(ctx, t) defer client.Close() testCases := []struct { in K0 wantErr bool }{ {in: K0{K: testKey0}, wantErr: false}, {in: K0{}, wantErr: false}, } for _, tt := range testCases { _, err := client.Put(ctx, IncompleteKey("NilKey", nil), &tt.in) if (err != nil) != tt.wantErr { t.Errorf("client.Put %s got err %v, want err %t", tt.in, err, tt.wantErr) } } } type SQChild struct { I, J int T, U int64 } type SQTestCase struct { desc string q *Query wantCount int wantSum int } func testSmallQueries(ctx context.Context, t *testing.T, client *Client, parent *Key, children []*SQChild, testCases []SQTestCase, extraTests ...func()) { keys := make([]*Key, len(children)) for i := range keys { keys[i] = IncompleteKey("SQChild", parent) } keys, err := client.PutMulti(ctx, keys, children) if err != nil { t.Fatalf("client.PutMulti: %v", err) } defer func() { err := client.DeleteMulti(ctx, keys) if err != nil { t.Errorf("client.DeleteMulti: %v", err) } }() for _, tc := range testCases { count, err := client.Count(ctx, tc.q) if err != nil { t.Errorf("Count %q: %v", tc.desc, err) continue } if count != tc.wantCount { t.Errorf("Count %q: got %d want %d", tc.desc, count, tc.wantCount) continue } } for _, tc := range testCases { var got []SQChild _, err := client.GetAll(ctx, tc.q, &got) if err != nil { t.Errorf("client.GetAll %q: %v", tc.desc, err) continue } sum := 0 for _, c := range got { sum += c.I + c.J } if sum != tc.wantSum { t.Errorf("sum %q: got %d want %d", tc.desc, sum, tc.wantSum) continue } } for _, x := range extraTests { x() } } func TestIntegration_Filters(t *testing.T) { ctx := context.Background() client := newTestClient(ctx, t) defer client.Close() parent := NameKey("SQParent", "TestIntegration_Filters"+suffix, nil) now := timeNow.Truncate(time.Millisecond).Unix() children := []*SQChild{ {I: 0, T: now, U: now}, {I: 1, T: now, U: now}, {I: 2, T: now, U: now}, {I: 3, T: now, U: now}, {I: 4, T: now, U: now}, {I: 5, T: now, U: now}, {I: 6, T: now, U: now}, {I: 7, T: now, U: now}, } baseQuery := NewQuery("SQChild").Ancestor(parent).Filter("T=", now) testSmallQueries(ctx, t, client, parent, children, []SQTestCase{ { "I>1", baseQuery.Filter("I>", 1), 6, 2 + 3 + 4 + 5 + 6 + 7, }, { "I>2 AND I<=5", baseQuery.Filter("I>", 2).Filter("I<=", 5), 3, 3 + 4 + 5, }, { "I>=3 AND I<3", baseQuery.Filter("I>=", 3).Filter("I<", 3), 0, 0, }, { "I=4", baseQuery.Filter("I=", 4), 1, 4, }, }, func() { got := []*SQChild{} want := []*SQChild{ {I: 0, T: now, U: now}, {I: 1, T: now, U: now}, {I: 2, T: now, U: now}, {I: 3, T: now, U: now}, {I: 4, T: now, U: now}, {I: 5, T: now, U: now}, {I: 6, T: now, U: now}, {I: 7, T: now, U: now}, } _, err := client.GetAll(ctx, baseQuery.Order("I"), &got) if err != nil { t.Errorf("client.GetAll: %v", err) } if !testutil.Equal(got, want) { t.Errorf("compare: got=%v, want=%v", got, want) } }, func() { got := []*SQChild{} want := []*SQChild{ {I: 7, T: now, U: now}, {I: 6, T: now, U: now}, {I: 5, T: now, U: now}, {I: 4, T: now, U: now}, {I: 3, T: now, U: now}, {I: 2, T: now, U: now}, {I: 1, T: now, U: now}, {I: 0, T: now, U: now}, } _, err := client.GetAll(ctx, baseQuery.Order("-I"), &got) if err != nil { t.Errorf("client.GetAll: %v", err) } if !testutil.Equal(got, want) { t.Errorf("compare: got=%v, want=%v", got, want) } }) } type ckey struct{} func TestIntegration_LargeQuery(t *testing.T) { ctx := context.Background() client := newTestClient(ctx, t) defer client.Close() parent := NameKey("LQParent", "TestIntegration_LargeQuery"+suffix, nil) now := timeNow.Truncate(time.Millisecond).Unix() // Make a large number of children entities. const n = 800 children := make([]*SQChild, 0, n) keys := make([]*Key, 0, n) for i := 0; i < n; i++ { children = append(children, &SQChild{I: i, T: now, U: now}) keys = append(keys, IncompleteKey("SQChild", parent)) } // Store using PutMulti in batches. const batchSize = 500 for i := 0; i < n; i = i + 500 { j := i + batchSize if j > n { j = n } fullKeys, err := client.PutMulti(ctx, keys[i:j], children[i:j]) if err != nil { t.Fatalf("PutMulti(%d, %d): %v", i, j, err) } defer func() { err := client.DeleteMulti(ctx, fullKeys) if err != nil { t.Errorf("client.DeleteMulti: %v", err) } }() } q := NewQuery("SQChild").Ancestor(parent).Filter("T=", now).Order("I") // Wait group to allow us to run query tests in parallel below. var wg sync.WaitGroup // Check we get the expected count and results for various limits/offsets. queryTests := []struct { limit, offset, want int }{ // Just limit. {limit: 0, want: 0}, {limit: 100, want: 100}, {limit: 501, want: 501}, {limit: n, want: n}, {limit: n * 2, want: n}, {limit: -1, want: n}, // Just offset. {limit: -1, offset: 100, want: n - 100}, {limit: -1, offset: 500, want: n - 500}, {limit: -1, offset: n, want: 0}, // Limit and offset. {limit: 100, offset: 100, want: 100}, {limit: 1000, offset: 100, want: n - 100}, {limit: 500, offset: 500, want: n - 500}, } for _, tt := range queryTests { q := q.Limit(tt.limit).Offset(tt.offset) wg.Add(1) go func(limit, offset, want int) { defer wg.Done() // Check Count returns the expected number of results. count, err := client.Count(ctx, q) if err != nil { t.Errorf("client.Count(limit=%d offset=%d): %v", limit, offset, err) return } if count != want { t.Errorf("Count(limit=%d offset=%d) returned %d, want %d", limit, offset, count, want) } var got []SQChild _, err = client.GetAll(ctx, q, &got) if err != nil { t.Errorf("client.GetAll(limit=%d offset=%d): %v", limit, offset, err) return } if len(got) != want { t.Errorf("GetAll(limit=%d offset=%d) returned %d, want %d", limit, offset, len(got), want) } for i, child := range got { if got, want := child.I, i+offset; got != want { t.Errorf("GetAll(limit=%d offset=%d) got[%d].I == %d; want %d", limit, offset, i, got, want) break } } }(tt.limit, tt.offset, tt.want) } // Also check iterator cursor behaviour. cursorTests := []struct { limit, offset int // Query limit and offset. count int // The number of times to call "next" want int // The I value of the desired element, -1 for "Done". }{ // No limits. {count: 0, limit: -1, want: 0}, {count: 5, limit: -1, want: 5}, {count: 500, limit: -1, want: 500}, {count: 1000, limit: -1, want: -1}, // No more results. // Limits. {count: 5, limit: 5, want: 5}, {count: 500, limit: 5, want: 5}, {count: 1000, limit: 1000, want: -1}, // No more results. // Offsets. {count: 0, offset: 5, limit: -1, want: 5}, {count: 5, offset: 5, limit: -1, want: 10}, {count: 200, offset: 500, limit: -1, want: 700}, {count: 200, offset: 1000, limit: -1, want: -1}, // No more results. } for _, tt := range cursorTests { wg.Add(1) go func(count, limit, offset, want int) { defer wg.Done() ctx := context.WithValue(ctx, ckey{}, fmt.Sprintf("c=%d,l=%d,o=%d", count, limit, offset)) // Run iterator through count calls to Next. it := client.Run(ctx, q.Limit(limit).Offset(offset).KeysOnly()) for i := 0; i < count; i++ { _, err := it.Next(nil) if err == iterator.Done { break } if err != nil { t.Errorf("count=%d, limit=%d, offset=%d: it.Next failed at i=%d", count, limit, offset, i) return } } // Grab the cursor. cursor, err := it.Cursor() if err != nil { t.Errorf("count=%d, limit=%d, offset=%d: it.Cursor: %v", count, limit, offset, err) return } // Make a request for the next element. it = client.Run(ctx, q.Limit(1).Start(cursor)) var entity SQChild _, err = it.Next(&entity) switch { case want == -1: if err != iterator.Done { t.Errorf("count=%d, limit=%d, offset=%d: it.Next from cursor %v, want Done", count, limit, offset, err) } case err != nil: t.Errorf("count=%d, limit=%d, offset=%d: it.Next from cursor: %v, want nil", count, limit, offset, err) case entity.I != want: t.Errorf("count=%d, limit=%d, offset=%d: got.I = %d, want %d", count, limit, offset, entity.I, want) } }(tt.count, tt.limit, tt.offset, tt.want) } wg.Wait() } func TestIntegration_EventualConsistency(t *testing.T) { // TODO(jba): either make this actually test eventual consistency, or // delete it. Currently it behaves the same with or without the // EventualConsistency call. ctx := context.Background() client := newTestClient(ctx, t) defer client.Close() parent := NameKey("SQParent", "TestIntegration_EventualConsistency"+suffix, nil) now := timeNow.Truncate(time.Millisecond).Unix() children := []*SQChild{ {I: 0, T: now, U: now}, {I: 1, T: now, U: now}, {I: 2, T: now, U: now}, } query := NewQuery("SQChild").Ancestor(parent).Filter("T =", now).EventualConsistency() testSmallQueries(ctx, t, client, parent, children, nil, func() { got, err := client.Count(ctx, query) if err != nil { t.Fatalf("Count: %v", err) } if got < 0 || 3 < got { t.Errorf("Count: got %d, want [0,3]", got) } }) } func TestIntegration_Projection(t *testing.T) { ctx := context.Background() client := newTestClient(ctx, t) defer client.Close() parent := NameKey("SQParent", "TestIntegration_Projection"+suffix, nil) now := timeNow.Truncate(time.Millisecond).Unix() children := []*SQChild{ {I: 1 << 0, J: 100, T: now, U: now}, {I: 1 << 1, J: 100, T: now, U: now}, {I: 1 << 2, J: 200, T: now, U: now}, {I: 1 << 3, J: 300, T: now, U: now}, {I: 1 << 4, J: 300, T: now, U: now}, } baseQuery := NewQuery("SQChild").Ancestor(parent).Filter("T=", now).Filter("J>", 150) testSmallQueries(ctx, t, client, parent, children, []SQTestCase{ { "project", baseQuery.Project("J"), 3, 200 + 300 + 300, }, { "distinct", baseQuery.Project("J").Distinct(), 2, 200 + 300, }, { "distinct on", baseQuery.Project("J").DistinctOn("J"), 2, 200 + 300, }, { "project on meaningful (GD_WHEN) field", baseQuery.Project("U"), 3, 0, }, }) } func TestIntegration_AllocateIDs(t *testing.T) { ctx := context.Background() client := newTestClient(ctx, t) defer client.Close() keys := make([]*Key, 5) for i := range keys { keys[i] = IncompleteKey("AllocID", nil) } keys, err := client.AllocateIDs(ctx, keys) if err != nil { t.Errorf("AllocID #0 failed: %v", err) } if want := len(keys); want != 5 { t.Errorf("Expected to allocate 5 keys, %d keys are found", want) } for _, k := range keys { if k.Incomplete() { t.Errorf("Unexpeceted incomplete key found: %v", k) } } } func TestIntegration_GetAllWithFieldMismatch(t *testing.T) { ctx := context.Background() client := newTestClient(ctx, t) defer client.Close() type Fat struct { X, Y int } type Thin struct { X int } // Ancestor queries (those within an entity group) are strongly consistent // by default, which prevents a test from being flaky. // See https://cloud.google.com/appengine/docs/go/datastore/queries#Go_Data_consistency // for more information. parent := NameKey("SQParent", "TestIntegration_GetAllWithFieldMismatch"+suffix, nil) putKeys := make([]*Key, 3) for i := range putKeys { putKeys[i] = IDKey("GetAllThing", int64(10+i), parent) _, err := client.Put(ctx, putKeys[i], &Fat{X: 20 + i, Y: 30 + i}) if err != nil { t.Fatalf("client.Put: %v", err) } } var got []Thin want := []Thin{ {X: 20}, {X: 21}, {X: 22}, } getKeys, err := client.GetAll(ctx, NewQuery("GetAllThing").Ancestor(parent), &got) if len(getKeys) != 3 && !testutil.Equal(getKeys, putKeys) { t.Errorf("client.GetAll: keys differ\ngetKeys=%v\nputKeys=%v", getKeys, putKeys) } if !testutil.Equal(got, want) { t.Errorf("client.GetAll: entities differ\ngot =%v\nwant=%v", got, want) } if _, ok := err.(*ErrFieldMismatch); !ok { t.Errorf("client.GetAll: got err=%v, want ErrFieldMismatch", err) } } func TestIntegration_KindlessQueries(t *testing.T) { ctx := context.Background() client := newTestClient(ctx, t) defer client.Close() type Dee struct { I int Why string } type Dum struct { I int Pling string } parent := NameKey("Tweedle", "tweedle"+suffix, nil) keys := []*Key{ NameKey("Dee", "dee0", parent), NameKey("Dum", "dum1", parent), NameKey("Dum", "dum2", parent), NameKey("Dum", "dum3", parent), } src := []interface{}{ &Dee{1, "binary0001"}, &Dum{2, "binary0010"}, &Dum{4, "binary0100"}, &Dum{8, "binary1000"}, } keys, err := client.PutMulti(ctx, keys, src) if err != nil { t.Fatalf("put: %v", err) } testCases := []struct { desc string query *Query want []int wantErr string }{ { desc: "Dee", query: NewQuery("Dee"), want: []int{1}, }, { desc: "Doh", query: NewQuery("Doh"), want: nil}, { desc: "Dum", query: NewQuery("Dum"), want: []int{2, 4, 8}, }, { desc: "", query: NewQuery(""), want: []int{1, 2, 4, 8}, }, { desc: "Kindless filter", query: NewQuery("").Filter("__key__ =", keys[2]), want: []int{4}, }, { desc: "Kindless order", query: NewQuery("").Order("__key__"), want: []int{1, 2, 4, 8}, }, { desc: "Kindless bad filter", query: NewQuery("").Filter("I =", 4), wantErr: "kind is required", }, { desc: "Kindless bad order", query: NewQuery("").Order("-__key__"), wantErr: "kind is required for all orders except __key__ ascending", }, } for _, test := range testCases { t.Run(test.desc, func(t *testing.T) { q := test.query.Ancestor(parent) gotCount, err := client.Count(ctx, q) if err != nil { if test.wantErr == "" || !strings.Contains(err.Error(), test.wantErr) { t.Fatalf("count %q: err %v, want err %q", test.desc, err, test.wantErr) } return } if test.wantErr != "" { t.Fatalf("count %q: want err %q", test.desc, test.wantErr) } if gotCount != len(test.want) { t.Fatalf("count %q: got %d want %d", test.desc, gotCount, len(test.want)) } var got []int for iter := client.Run(ctx, q); ; { var dst struct { I int Why, Pling string } _, err := iter.Next(&dst) if err == iterator.Done { break } if err != nil { t.Fatalf("iter.Next %q: %v", test.desc, err) } got = append(got, dst.I) } sort.Ints(got) if !testutil.Equal(got, test.want) { t.Fatalf("elems %q: got %+v want %+v", test.desc, got, test.want) } }) } } func TestIntegration_Transaction(t *testing.T) { ctx := context.Background() client := newTestClient(ctx, t) defer client.Close() type Counter struct { N int T time.Time } bangErr := errors.New("bang") tests := []struct { desc string causeConflict []bool retErr []error want int wantErr error }{ { desc: "3 attempts, no conflicts", causeConflict: []bool{false}, retErr: []error{nil}, want: 11, }, { desc: "1 attempt, user error", causeConflict: []bool{false}, retErr: []error{bangErr}, wantErr: bangErr, }, { desc: "2 attempts, 1 conflict", causeConflict: []bool{true, false}, retErr: []error{nil, nil}, want: 13, // Each conflict increments by 2. }, { desc: "3 attempts, 3 conflicts", causeConflict: []bool{true, true, true}, retErr: []error{nil, nil, nil}, wantErr: ErrConcurrentTransaction, }, } for i, test := range tests { t.Run(test.desc, func(t *testing.T) { // Put a new counter. c := &Counter{N: 10, T: timeNow} key, err := client.Put(ctx, IncompleteKey("TransCounter", nil), c) if err != nil { t.Fatal(err) } defer client.Delete(ctx, key) // Increment the counter in a transaction. // The test case can manually cause a conflict or return an // error at each attempt. var attempts int _, err = client.RunInTransaction(ctx, func(tx *Transaction) error { attempts++ if attempts > len(test.causeConflict) { return fmt.Errorf("too many attempts. Got %d, max %d", attempts, len(test.causeConflict)) } var c Counter if err := tx.Get(key, &c); err != nil { return err } c.N++ if _, err := tx.Put(key, &c); err != nil { return err } if test.causeConflict[attempts-1] { c.N++ if _, err := client.Put(ctx, key, &c); err != nil { return err } } return test.retErr[attempts-1] }, MaxAttempts(i)) // Check the error returned by RunInTransaction. if err != test.wantErr { t.Fatalf("got err %v, want %v", err, test.wantErr) } if test.wantErr != nil { // If we were expecting an error, this is where the test ends. return } // Check the final value of the counter. if err := client.Get(ctx, key, c); err != nil { t.Fatal(err) } if c.N != test.want { t.Fatalf("counter N=%d, want N=%d", c.N, test.want) } }) } } func TestIntegration_ReadOnlyTransaction(t *testing.T) { if testing.Short() { t.Skip("Integration tests skipped in short mode") } ctx := context.Background() client := newClient(ctx, t, nil) defer client.Close() type value struct{ N int } // Put a value. const n = 5 v := &value{N: n} key, err := client.Put(ctx, IncompleteKey("roTxn", nil), v) if err != nil { t.Fatal(err) } defer client.Delete(ctx, key) // Read it from a read-only transaction. _, err = client.RunInTransaction(ctx, func(tx *Transaction) error { if err := tx.Get(key, v); err != nil { return err } return nil }, ReadOnly) if err != nil { t.Fatal(err) } if v.N != n { t.Fatalf("got %d, want %d", v.N, n) } // Attempting to write from a read-only transaction is an error. _, err = client.RunInTransaction(ctx, func(tx *Transaction) error { if _, err := tx.Put(key, v); err != nil { return err } return nil }, ReadOnly) if err == nil { t.Fatal("got nil, want error") } } func TestIntegration_NilPointers(t *testing.T) { ctx := context.Background() client := newTestClient(ctx, t) defer client.Close() type X struct { S string } src := []*X{{"zero"}, {"one"}} keys := []*Key{IncompleteKey("NilX", nil), IncompleteKey("NilX", nil)} keys, err := client.PutMulti(ctx, keys, src) if err != nil { t.Fatalf("PutMulti: %v", err) } // It's okay to store into a slice of nil *X. xs := make([]*X, 2) if err := client.GetMulti(ctx, keys, xs); err != nil { t.Errorf("GetMulti: %v", err) } else if !testutil.Equal(xs, src) { t.Errorf("GetMulti fetched %v, want %v", xs, src) } // It isn't okay to store into a single nil *X. var x0 *X if err, want := client.Get(ctx, keys[0], x0), ErrInvalidEntityType; err != want { t.Errorf("Get: err %v; want %v", err, want) } // Test that deleting with duplicate keys work. keys = append(keys, keys...) if err := client.DeleteMulti(ctx, keys); err != nil { t.Errorf("Delete: %v", err) } } func TestIntegration_NestedRepeatedElementNoIndex(t *testing.T) { ctx := context.Background() client := newTestClient(ctx, t) defer client.Close() type Inner struct { Name string Value string `datastore:",noindex"` } type Outer struct { Config []Inner } m := &Outer{ Config: []Inner{ {Name: "short", Value: "a"}, {Name: "long", Value: strings.Repeat("a", 2000)}, }, } key := NameKey("Nested", "Nested"+suffix, nil) if _, err := client.Put(ctx, key, m); err != nil { t.Fatalf("client.Put: %v", err) } if err := client.Delete(ctx, key); err != nil { t.Fatalf("client.Delete: %v", err) } } func TestIntegration_PointerFields(t *testing.T) { ctx := context.Background() client := newTestClient(ctx, t) defer client.Close() want := populatedPointers() key, err := client.Put(ctx, IncompleteKey("pointers", nil), want) if err != nil { t.Fatal(err) } var got Pointers if err := client.Get(ctx, key, &got); err != nil { t.Fatal(err) } if got.Pi == nil || *got.Pi != *want.Pi { t.Errorf("Pi: got %v, want %v", got.Pi, *want.Pi) } if got.Ps == nil || *got.Ps != *want.Ps { t.Errorf("Ps: got %v, want %v", got.Ps, *want.Ps) } if got.Pb == nil || *got.Pb != *want.Pb { t.Errorf("Pb: got %v, want %v", got.Pb, *want.Pb) } if got.Pf == nil || *got.Pf != *want.Pf { t.Errorf("Pf: got %v, want %v", got.Pf, *want.Pf) } if got.Pg == nil || *got.Pg != *want.Pg { t.Errorf("Pg: got %v, want %v", got.Pg, *want.Pg) } if got.Pt == nil || !got.Pt.Equal(*want.Pt) { t.Errorf("Pt: got %v, want %v", got.Pt, *want.Pt) } } func TestIntegration_Mutate(t *testing.T) { // test Client.Mutate testMutate(t, func(ctx context.Context, client *Client, muts ...*Mutation) ([]*Key, error) { return client.Mutate(ctx, muts...) }) // test Transaction.Mutate testMutate(t, func(ctx context.Context, client *Client, muts ...*Mutation) ([]*Key, error) { var pkeys []*PendingKey commit, err := client.RunInTransaction(ctx, func(tx *Transaction) error { var err error pkeys, err = tx.Mutate(muts...) return err }) if err != nil { return nil, err } var keys []*Key for _, pk := range pkeys { keys = append(keys, commit.Key(pk)) } return keys, nil }) } func testMutate(t *testing.T, mutate func(ctx context.Context, client *Client, muts ...*Mutation) ([]*Key, error)) { ctx := context.Background() client := newTestClient(ctx, t) defer client.Close() type T struct{ I int } check := func(k *Key, want interface{}) { var x T err := client.Get(ctx, k, &x) switch want := want.(type) { case error: if err != want { t.Errorf("key %s: got error %v, want %v", k, err, want) } case int: if err != nil { t.Fatalf("key %s: %v", k, err) } if x.I != want { t.Errorf("key %s: got %d, want %d", k, x.I, want) } default: panic("check: bad arg") } } keys, err := mutate(ctx, client, NewInsert(IncompleteKey("t", nil), &T{1}), NewUpsert(IncompleteKey("t", nil), &T{2}), ) if err != nil { t.Fatal(err) } check(keys[0], 1) check(keys[1], 2) _, err = mutate(ctx, client, NewUpdate(keys[0], &T{3}), NewDelete(keys[1]), ) if err != nil { t.Fatal(err) } check(keys[0], 3) check(keys[1], ErrNoSuchEntity) _, err = mutate(ctx, client, NewInsert(keys[0], &T{4})) if got, want := status.Code(err), codes.AlreadyExists; got != want { t.Errorf("Insert existing key: got %s, want %s", got, want) } _, err = mutate(ctx, client, NewUpdate(keys[1], &T{4})) if got, want := status.Code(err), codes.NotFound; got != want { t.Errorf("Update non-existing key: got %s, want %s", got, want) } } func TestIntegration_DetectProjectID(t *testing.T) { if testing.Short() { t.Skip("Integration tests skipped in short mode") } ctx := context.Background() creds := testutil.Credentials(ctx, ScopeDatastore) if creds == nil { t.Skip("Integration tests skipped. See CONTRIBUTING.md for details") } // Use creds with project ID. if _, err := NewClient(ctx, DetectProjectID, option.WithCredentials(creds)); err != nil { t.Errorf("NewClient: %v", err) } ts := testutil.ErroringTokenSource{} // Try to use creds without project ID. _, err := NewClient(ctx, DetectProjectID, option.WithTokenSource(ts)) if err == nil || err.Error() != "datastore: see the docs on DetectProjectID" { t.Errorf("expected an error while using TokenSource that does not have a project ID") } } var genKeyName = uid.NewSpace("datastore-integration", nil) func TestIntegration_Project_TimestampStoreAndRetrieve(t *testing.T) { ctx := context.Background() client := newTestClient(ctx, t) defer client.Close() type T struct{ Created time.Time } keyName := genKeyName.New() now := time.Now() k, err := client.Put(ctx, IncompleteKey(keyName, nil), &T{Created: now}) if err != nil { t.Fatal(err) } defer func() { if err := client.Delete(ctx, k); err != nil { log.Println(err) } }() // Without .Ancestor, this query is eventually consistent (so this test // would be flakey). Ancestor queries, however, are strongly consistent. // See more at https://cloud.google.com/datastore/docs/articles/balancing-strong-and-eventual-consistency-with-google-cloud-datastore/. q := NewQuery(k.Kind).Ancestor(k) res := []T{} if _, err := client.GetAll(ctx, q, &res); err != nil { t.Fatal(err) } if len(res) != 1 { t.Fatalf("expected 1 result, got %d", len(res)) } if got, want := res[0].Created.Unix(), now.Unix(); got != want { t.Fatalf("got %v, want %v", got, want) } } google-cloud-go-0.49.0/datastore/internal/000077500000000000000000000000001356504100700203725ustar00rootroot00000000000000google-cloud-go-0.49.0/datastore/internal/gaepb/000077500000000000000000000000001356504100700214505ustar00rootroot00000000000000google-cloud-go-0.49.0/datastore/internal/gaepb/datastore_v3.pb.go000066400000000000000000000741261356504100700250070ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package gaepb is a subset of protobufs, copied from google.golang.org/appengine/internal/datastore. // It includes the Reference, Path, and Path_Element protos. // // They are copied here to provide compatibility to decode keys generated by the google.golang.org/appengine/datastore package. // Copying the minimal amount of protos to support key decoding means we don't need to add a dependency on the appengine/datastore package. package gaepb import "github.com/golang/protobuf/proto" type Path struct { Element []*Path_Element `protobuf:"group,1,rep,name=Element,json=element" json:"element,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *Path) Reset() { *m = Path{} } func (m *Path) String() string { return proto.CompactTextString(m) } func (*Path) ProtoMessage() {} func (*Path) Descriptor() ([]byte, []int) { return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{3} } func (m *Path) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Path.Unmarshal(m, b) } func (m *Path) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Path.Marshal(b, m, deterministic) } func (dst *Path) XXX_Merge(src proto.Message) { xxx_messageInfo_Path.Merge(dst, src) } func (m *Path) XXX_Size() int { return xxx_messageInfo_Path.Size(m) } func (m *Path) XXX_DiscardUnknown() { xxx_messageInfo_Path.DiscardUnknown(m) } var xxx_messageInfo_Path proto.InternalMessageInfo func (m *Path) GetElement() []*Path_Element { if m != nil { return m.Element } return nil } type Path_Element struct { Type *string `protobuf:"bytes,2,req,name=type" json:"type,omitempty"` Id *int64 `protobuf:"varint,3,opt,name=id" json:"id,omitempty"` Name *string `protobuf:"bytes,4,opt,name=name" json:"name,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *Path_Element) Reset() { *m = Path_Element{} } func (m *Path_Element) String() string { return proto.CompactTextString(m) } func (*Path_Element) ProtoMessage() {} func (*Path_Element) Descriptor() ([]byte, []int) { return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{3, 0} } func (m *Path_Element) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Path_Element.Unmarshal(m, b) } func (m *Path_Element) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Path_Element.Marshal(b, m, deterministic) } func (dst *Path_Element) XXX_Merge(src proto.Message) { xxx_messageInfo_Path_Element.Merge(dst, src) } func (m *Path_Element) XXX_Size() int { return xxx_messageInfo_Path_Element.Size(m) } func (m *Path_Element) XXX_DiscardUnknown() { xxx_messageInfo_Path_Element.DiscardUnknown(m) } var xxx_messageInfo_Path_Element proto.InternalMessageInfo func (m *Path_Element) GetType() string { if m != nil && m.Type != nil { return *m.Type } return "" } func (m *Path_Element) GetId() int64 { if m != nil && m.Id != nil { return *m.Id } return 0 } func (m *Path_Element) GetName() string { if m != nil && m.Name != nil { return *m.Name } return "" } type Reference struct { App *string `protobuf:"bytes,13,req,name=app" json:"app,omitempty"` NameSpace *string `protobuf:"bytes,20,opt,name=name_space,json=nameSpace" json:"name_space,omitempty"` Path *Path `protobuf:"bytes,14,req,name=path" json:"path,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *Reference) Reset() { *m = Reference{} } func (m *Reference) String() string { return proto.CompactTextString(m) } func (*Reference) ProtoMessage() {} func (*Reference) Descriptor() ([]byte, []int) { return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{4} } func (m *Reference) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Reference.Unmarshal(m, b) } func (m *Reference) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Reference.Marshal(b, m, deterministic) } func (dst *Reference) XXX_Merge(src proto.Message) { xxx_messageInfo_Reference.Merge(dst, src) } func (m *Reference) XXX_Size() int { return xxx_messageInfo_Reference.Size(m) } func (m *Reference) XXX_DiscardUnknown() { xxx_messageInfo_Reference.DiscardUnknown(m) } var xxx_messageInfo_Reference proto.InternalMessageInfo func (m *Reference) GetApp() string { if m != nil && m.App != nil { return *m.App } return "" } func (m *Reference) GetNameSpace() string { if m != nil && m.NameSpace != nil { return *m.NameSpace } return "" } func (m *Reference) GetPath() *Path { if m != nil { return m.Path } return nil } var fileDescriptor_datastore_v3_83b17b80c34f6179 = []byte{ // 4156 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5a, 0xcd, 0x73, 0xe3, 0x46, 0x76, 0x37, 0xc1, 0xef, 0x47, 0x89, 0x82, 0x5a, 0xf3, 0xc1, 0xa1, 0x3f, 0x46, 0xc6, 0xac, 0x6d, 0xd9, 0x6b, 0x73, 0x6c, 0xf9, 0x23, 0x5b, 0x4a, 0x76, 0x1d, 0x4a, 0xc4, 0x68, 0x90, 0xa1, 0x48, 0xb9, 0x09, 0xd9, 0x9e, 0x5c, 0x50, 0x18, 0xa2, 0x29, 0x21, 0x43, 0x02, 0x30, 0x00, 0x6a, 0x46, 0x93, 0xe4, 0x90, 0x4b, 0x2a, 0x55, 0x5b, 0xa9, 0x1c, 0x92, 0x4a, 0x25, 0xf9, 0x07, 0x72, 0xc8, 0x39, 0x95, 0xaa, 0x54, 0xf6, 0x98, 0x5b, 0x0e, 0x7b, 0xc9, 0x31, 0x95, 0x73, 0xf2, 0x27, 0x24, 0x39, 0xa4, 0xfa, 0x75, 0x03, 0x02, 0x28, 0x4a, 0x23, 0x6d, 0xf6, 0x90, 0x13, 0xd1, 0xef, 0xfd, 0xba, 0xf1, 0xfa, 0xf5, 0xfb, 0x6c, 0x10, 0xba, 0xc7, 0xbe, 0x7f, 0x3c, 0x65, 0x9d, 0x63, 0x7f, 0x6a, 0x7b, 0xc7, 0x1d, 0x3f, 0x3c, 0x7e, 0x68, 0x07, 0x01, 0xf3, 0x8e, 0x5d, 0x8f, 0x3d, 0x74, 0xbd, 0x98, 0x85, 0x9e, 0x3d, 0x7d, 0xe8, 0xd8, 0xb1, 0x1d, 0xc5, 0x7e, 0xc8, 0xce, 0x9f, 0xac, 0xd3, 0xcf, 0x3b, 0x41, 0xe8, 0xc7, 0x3e, 0xa9, 0xa7, 0x13, 0xb4, 0x1a, 0x54, 0xba, 0xe3, 0xd8, 0xf5, 0x3d, 0xed, 0x1f, 0x2b, 0xb0, 0x7a, 0x18, 0xfa, 0x01, 0x0b, 0xe3, 0xb3, 0x6f, 0xed, 0xe9, 0x9c, 0x91, 0x77, 0x00, 0x5c, 0x2f, 0xfe, 0xea, 0x0b, 0x1c, 0xb5, 0x0a, 0x9b, 0x85, 0xad, 0x22, 0xcd, 0x50, 0x88, 0x06, 0x2b, 0xcf, 0x7c, 0x7f, 0xca, 0x6c, 0x4f, 0x20, 0x94, 0xcd, 0xc2, 0x56, 0x8d, 0xe6, 0x68, 0x64, 0x13, 0x1a, 0x51, 0x1c, 0xba, 0xde, 0xb1, 0x80, 0x14, 0x37, 0x0b, 0x5b, 0x75, 0x9a, 0x25, 0x71, 0x84, 0xe3, 0xcf, 0x9f, 0x4d, 0x99, 0x40, 0x94, 0x36, 0x0b, 0x5b, 0x05, 0x9a, 0x25, 0x91, 0x3d, 0x80, 0xc0, 0x77, 0xbd, 0xf8, 0x14, 0x01, 0xe5, 0xcd, 0xc2, 0x16, 0x6c, 0x3f, 0xe8, 0xa4, 0x7b, 0xe8, 0xe4, 0xa4, 0xee, 0x1c, 0x72, 0x28, 0x3e, 0xd2, 0xcc, 0x34, 0xf2, 0xdb, 0x50, 0x9f, 0x47, 0x2c, 0x14, 0x6b, 0xd4, 0x70, 0x0d, 0xed, 0xd2, 0x35, 0x8e, 0x22, 0x16, 0x8a, 0x25, 0xce, 0x27, 0x91, 0x21, 0x34, 0x43, 0x36, 0x61, 0x21, 0xf3, 0xc6, 0x4c, 0x2c, 0xb3, 0x82, 0xcb, 0x7c, 0x70, 0xe9, 0x32, 0x34, 0x81, 0x8b, 0xb5, 0x16, 0xa6, 0xb7, 0xb7, 0x00, 0xce, 0x85, 0x25, 0x2b, 0x50, 0x78, 0xd9, 0xaa, 0x6c, 0x2a, 0x5b, 0x05, 0x5a, 0x78, 0xc9, 0x47, 0x67, 0xad, 0xaa, 0x18, 0x9d, 0xb5, 0xff, 0xa9, 0x00, 0xf5, 0x54, 0x26, 0x72, 0x0b, 0xca, 0x6c, 0x66, 0xbb, 0xd3, 0x56, 0x7d, 0x53, 0xd9, 0xaa, 0x53, 0x31, 0x20, 0xf7, 0xa1, 0x61, 0xcf, 0xe3, 0x13, 0xcb, 0xf1, 0x67, 0xb6, 0xeb, 0xb5, 0x00, 0x79, 0xc0, 0x49, 0x3d, 0xa4, 0x90, 0x36, 0xd4, 0x3c, 0x77, 0xfc, 0xdc, 0xb3, 0x67, 0xac, 0xd5, 0xc0, 0x73, 0x48, 0xc7, 0xe4, 0x13, 0x20, 0x13, 0xe6, 0xb0, 0xd0, 0x8e, 0x99, 0x63, 0xb9, 0x0e, 0xf3, 0x62, 0x37, 0x3e, 0x6b, 0xdd, 0x46, 0xd4, 0x7a, 0xca, 0x31, 0x24, 0x23, 0x0f, 0x0f, 0x42, 0xff, 0xd4, 0x75, 0x58, 0xd8, 0xba, 0xb3, 0x00, 0x3f, 0x94, 0x8c, 0xf6, 0xbf, 0x17, 0xa0, 0x99, 0xd7, 0x05, 0x51, 0xa1, 0x68, 0x07, 0x41, 0x6b, 0x15, 0xa5, 0xe4, 0x8f, 0xe4, 0x6d, 0x00, 0x2e, 0x8a, 0x15, 0x05, 0xf6, 0x98, 0xb5, 0x6e, 0xe1, 0x5a, 0x75, 0x4e, 0x19, 0x71, 0x02, 0x39, 0x82, 0x46, 0x60, 0xc7, 0x27, 0x6c, 0xca, 0x66, 0xcc, 0x8b, 0x5b, 0xcd, 0xcd, 0xe2, 0x16, 0x6c, 0x7f, 0x7e, 0x4d, 0xd5, 0x77, 0x0e, 0xed, 0xf8, 0x44, 0x17, 0x53, 0x69, 0x76, 0x9d, 0xb6, 0x0e, 0x8d, 0x0c, 0x8f, 0x10, 0x28, 0xc5, 0x67, 0x01, 0x6b, 0xad, 0xa1, 0x5c, 0xf8, 0x4c, 0x9a, 0xa0, 0xb8, 0x4e, 0x4b, 0x45, 0xf3, 0x57, 0x5c, 0x87, 0x63, 0x50, 0x87, 0xeb, 0x28, 0x22, 0x3e, 0x6b, 0xff, 0x51, 0x86, 0x5a, 0x22, 0x00, 0xe9, 0x42, 0x75, 0xc6, 0x6c, 0xcf, 0xf5, 0x8e, 0xd1, 0x69, 0x9a, 0xdb, 0x6f, 0x2e, 0x11, 0xb3, 0x73, 0x20, 0x20, 0x3b, 0x30, 0x18, 0x5a, 0x07, 0x7a, 0x77, 0x60, 0x0c, 0xf6, 0x69, 0x32, 0x8f, 0x1f, 0xa6, 0x7c, 0xb4, 0xe6, 0xa1, 0x8b, 0x9e, 0x55, 0xa7, 0x20, 0x49, 0x47, 0xa1, 0x9b, 0x0a, 0x51, 0x14, 0x82, 0xe2, 0x21, 0x76, 0xa0, 0x9c, 0xb8, 0x88, 0xb2, 0xd5, 0xd8, 0x6e, 0x5d, 0xa6, 0x1c, 0x2a, 0x60, 0xdc, 0x20, 0x66, 0xf3, 0x69, 0xec, 0x06, 0x53, 0xee, 0x76, 0xca, 0x56, 0x8d, 0xa6, 0x63, 0xf2, 0x1e, 0x40, 0xc4, 0xec, 0x70, 0x7c, 0x62, 0x3f, 0x9b, 0xb2, 0x56, 0x85, 0x7b, 0xf6, 0x4e, 0x79, 0x62, 0x4f, 0x23, 0x46, 0x33, 0x0c, 0x62, 0xc3, 0xdd, 0x49, 0x1c, 0x59, 0xb1, 0xff, 0x9c, 0x79, 0xee, 0x2b, 0x9b, 0x07, 0x12, 0xcb, 0x0f, 0xf8, 0x0f, 0xfa, 0x58, 0x73, 0xfb, 0xc3, 0x65, 0x5b, 0x7f, 0x14, 0x47, 0x66, 0x66, 0xc6, 0x10, 0x27, 0xd0, 0xdb, 0x93, 0x65, 0x64, 0xd2, 0x86, 0xca, 0xd4, 0x1f, 0xdb, 0x53, 0xd6, 0xaa, 0x73, 0x2d, 0xec, 0x28, 0xcc, 0xa3, 0x92, 0xa2, 0xfd, 0xb3, 0x02, 0x55, 0xa9, 0x47, 0xd2, 0x84, 0x8c, 0x26, 0xd5, 0x37, 0x48, 0x0d, 0x4a, 0xbb, 0xfd, 0xe1, 0xae, 0xda, 0xe4, 0x4f, 0xa6, 0xfe, 0xbd, 0xa9, 0xae, 0x71, 0xcc, 0xee, 0x53, 0x53, 0x1f, 0x99, 0x94, 0x63, 0x54, 0xb2, 0x0e, 0xab, 0x5d, 0x73, 0x78, 0x60, 0xed, 0x75, 0x4d, 0x7d, 0x7f, 0x48, 0x9f, 0xaa, 0x05, 0xb2, 0x0a, 0x75, 0x24, 0xf5, 0x8d, 0xc1, 0x13, 0x55, 0xe1, 0x33, 0x70, 0x68, 0x1a, 0x66, 0x5f, 0x57, 0x8b, 0x44, 0x85, 0x15, 0x31, 0x63, 0x38, 0x30, 0xf5, 0x81, 0xa9, 0x96, 0x52, 0xca, 0xe8, 0xe8, 0xe0, 0xa0, 0x4b, 0x9f, 0xaa, 0x65, 0xb2, 0x06, 0x0d, 0xa4, 0x74, 0x8f, 0xcc, 0xc7, 0x43, 0xaa, 0x56, 0x48, 0x03, 0xaa, 0xfb, 0x3d, 0xeb, 0xbb, 0xc7, 0xfa, 0x40, 0xad, 0x92, 0x15, 0xa8, 0xed, 0xf7, 0x2c, 0xfd, 0xa0, 0x6b, 0xf4, 0xd5, 0x1a, 0x9f, 0xbd, 0xaf, 0x0f, 0xe9, 0x68, 0x64, 0x1d, 0x0e, 0x8d, 0x81, 0xa9, 0xd6, 0x49, 0x1d, 0xca, 0xfb, 0x3d, 0xcb, 0x38, 0x50, 0x81, 0x10, 0x68, 0xee, 0xf7, 0xac, 0xc3, 0xc7, 0xc3, 0x81, 0x3e, 0x38, 0x3a, 0xd8, 0xd5, 0xa9, 0xda, 0x20, 0xb7, 0x40, 0xe5, 0xb4, 0xe1, 0xc8, 0xec, 0xf6, 0xbb, 0xbd, 0x1e, 0xd5, 0x47, 0x23, 0x75, 0x85, 0x4b, 0xbd, 0xdf, 0xb3, 0x68, 0xd7, 0xe4, 0xfb, 0x5a, 0xe5, 0x2f, 0xe4, 0x7b, 0x7f, 0xa2, 0x3f, 0x55, 0xd7, 0xf9, 0x2b, 0xf4, 0x81, 0x69, 0x98, 0x4f, 0xad, 0x43, 0x3a, 0x34, 0x87, 0xea, 0x06, 0x17, 0xd0, 0x18, 0xf4, 0xf4, 0xef, 0xad, 0x6f, 0xbb, 0xfd, 0x23, 0x5d, 0x25, 0xda, 0x8f, 0xe1, 0xf6, 0xd2, 0x33, 0xe1, 0xaa, 0x7b, 0x6c, 0x1e, 0xf4, 0xd5, 0x02, 0x7f, 0xe2, 0x9b, 0x52, 0x15, 0xed, 0x0f, 0xa0, 0xc4, 0x5d, 0x86, 0x7c, 0x06, 0xd5, 0xc4, 0x1b, 0x0b, 0xe8, 0x8d, 0x77, 0xb3, 0x67, 0x6d, 0xc7, 0x27, 0x9d, 0xc4, 0xe3, 0x12, 0x5c, 0xbb, 0x0b, 0xd5, 0x45, 0x4f, 0x53, 0x2e, 0x78, 0x5a, 0xf1, 0x82, 0xa7, 0x95, 0x32, 0x9e, 0x66, 0x43, 0x3d, 0xf5, 0xed, 0x9b, 0x47, 0x91, 0x07, 0x50, 0xe2, 0xde, 0xdf, 0x6a, 0xa2, 0x87, 0xac, 0x2d, 0x08, 0x4c, 0x91, 0xa9, 0xfd, 0x43, 0x01, 0x4a, 0x3c, 0xda, 0x9e, 0x07, 0xda, 0xc2, 0x15, 0x81, 0x56, 0xb9, 0x32, 0xd0, 0x16, 0xaf, 0x15, 0x68, 0x2b, 0x37, 0x0b, 0xb4, 0xd5, 0x4b, 0x02, 0xad, 0xf6, 0x67, 0x45, 0x68, 0xe8, 0x38, 0xf3, 0x10, 0x13, 0xfd, 0xfb, 0x50, 0x7c, 0xce, 0xce, 0x50, 0x3f, 0x8d, 0xed, 0x5b, 0x99, 0xdd, 0xa6, 0x2a, 0xa4, 0x1c, 0x40, 0xb6, 0x61, 0x45, 0xbc, 0xd0, 0x3a, 0x0e, 0xfd, 0x79, 0xd0, 0x52, 0x97, 0xab, 0xa7, 0x21, 0x40, 0xfb, 0x1c, 0x43, 0xde, 0x83, 0xb2, 0xff, 0xc2, 0x63, 0x21, 0xc6, 0xc1, 0x3c, 0x98, 0x2b, 0x8f, 0x0a, 0x2e, 0x79, 0x08, 0xa5, 0xe7, 0xae, 0xe7, 0xe0, 0x19, 0xe6, 0x23, 0x61, 0x46, 0xd0, 0xce, 0x13, 0xd7, 0x73, 0x28, 0x02, 0xc9, 0x3d, 0xa8, 0xf1, 0x5f, 0x8c, 0x7b, 0x65, 0xdc, 0x68, 0x95, 0x8f, 0x79, 0xd0, 0x7b, 0x08, 0xb5, 0x40, 0xc6, 0x10, 0x4c, 0x00, 0x8d, 0xed, 0x8d, 0x25, 0xe1, 0x85, 0xa6, 0x20, 0xf2, 0x15, 0xac, 0x84, 0xf6, 0x0b, 0x2b, 0x9d, 0xb4, 0x76, 0xf9, 0xa4, 0x46, 0x68, 0xbf, 0x48, 0x23, 0x38, 0x81, 0x52, 0x68, 0x7b, 0xcf, 0x5b, 0x64, 0xb3, 0xb0, 0x55, 0xa6, 0xf8, 0xac, 0x7d, 0x01, 0x25, 0x2e, 0x25, 0x8f, 0x08, 0xfb, 0x3d, 0xf4, 0xff, 0xee, 0x9e, 0xa9, 0x16, 0x12, 0x7f, 0xfe, 0x96, 0x47, 0x03, 0x45, 0x72, 0x0f, 0xf4, 0xd1, 0xa8, 0xbb, 0xaf, 0xab, 0x45, 0xad, 0x07, 0xeb, 0x7b, 0xfe, 0x2c, 0xf0, 0x23, 0x37, 0x66, 0xe9, 0xf2, 0xf7, 0xa0, 0xe6, 0x7a, 0x0e, 0x7b, 0x69, 0xb9, 0x0e, 0x9a, 0x56, 0x91, 0x56, 0x71, 0x6c, 0x38, 0xdc, 0xe4, 0x4e, 0x65, 0x31, 0x55, 0xe4, 0x26, 0x87, 0x03, 0xed, 0x2f, 0x15, 0x28, 0x1b, 0x1c, 0xc1, 0x8d, 0x4f, 0x9e, 0x14, 0x7a, 0x8f, 0x30, 0x4c, 0x10, 0x24, 0x93, 0xfb, 0x50, 0x1b, 0x6a, 0xb6, 0x37, 0x66, 0xbc, 0xe2, 0xc3, 0x3c, 0x50, 0xa3, 0xe9, 0x98, 0x7c, 0x99, 0xd1, 0x9f, 0x82, 0x2e, 0x7b, 0x2f, 0xa3, 0x0a, 0x7c, 0xc1, 0x12, 0x2d, 0xb6, 0xff, 0xaa, 0x90, 0x49, 0x6e, 0xcb, 0x12, 0x4f, 0x1f, 0xea, 0x8e, 0x1b, 0x32, 0xac, 0x23, 0xe5, 0x41, 0x3f, 0xb8, 0x74, 0xe1, 0x4e, 0x2f, 0x81, 0xee, 0xd4, 0xbb, 0xa3, 0x3d, 0x7d, 0xd0, 0xe3, 0x99, 0xef, 0x7c, 0x01, 0xed, 0x23, 0xa8, 0xa7, 0x10, 0x0c, 0xc7, 0x09, 0x48, 0x2d, 0x70, 0xf5, 0xf6, 0xf4, 0x74, 0xac, 0x68, 0x7f, 0xad, 0x40, 0x33, 0xd5, 0xaf, 0xd0, 0xd0, 0x6d, 0xa8, 0xd8, 0x41, 0x90, 0xa8, 0xb6, 0x4e, 0xcb, 0x76, 0x10, 0x18, 0x8e, 0x8c, 0x2d, 0x0a, 0x6a, 0x9b, 0xc7, 0x96, 0x4f, 0x01, 0x1c, 0x36, 0x71, 0x3d, 0x17, 0x85, 0x2e, 0xa2, 0xc1, 0xab, 0x8b, 0x42, 0xd3, 0x0c, 0x86, 0x7c, 0x09, 0xe5, 0x28, 0xb6, 0x63, 0x91, 0x2b, 0x9b, 0xdb, 0xf7, 0x33, 0xe0, 0xbc, 0x08, 0x9d, 0x11, 0x87, 0x51, 0x81, 0x26, 0x5f, 0xc1, 0x2d, 0xdf, 0x9b, 0x9e, 0x59, 0xf3, 0x88, 0x59, 0xee, 0xc4, 0x0a, 0xd9, 0x0f, 0x73, 0x37, 0x64, 0x4e, 0x3e, 0xa7, 0xae, 0x73, 0xc8, 0x51, 0xc4, 0x8c, 0x09, 0x95, 0x7c, 0xed, 0x6b, 0x28, 0xe3, 0x3a, 0x7c, 0xcf, 0xdf, 0x51, 0xc3, 0xd4, 0xad, 0xe1, 0xa0, 0xff, 0x54, 0xe8, 0x80, 0xea, 0xdd, 0x9e, 0x85, 0x44, 0x55, 0xe1, 0xc1, 0xbe, 0xa7, 0xf7, 0x75, 0x53, 0xef, 0xa9, 0x45, 0x9e, 0x3d, 0x74, 0x4a, 0x87, 0x54, 0x2d, 0x69, 0xff, 0x53, 0x80, 0x15, 0x94, 0xe7, 0xd0, 0x8f, 0xe2, 0x89, 0xfb, 0x92, 0xec, 0x41, 0x43, 0x98, 0xdd, 0xa9, 0x2c, 0xe8, 0xb9, 0x33, 0x68, 0x8b, 0x7b, 0x96, 0x68, 0x31, 0x90, 0x75, 0xb4, 0x9b, 0x3e, 0x27, 0x21, 0x45, 0x41, 0xa7, 0xbf, 0x22, 0xa4, 0xbc, 0x05, 0x95, 0x67, 0x6c, 0xe2, 0x87, 0x22, 0x04, 0xd6, 0x76, 0x4a, 0x71, 0x38, 0x67, 0x54, 0xd2, 0xda, 0x36, 0xc0, 0xf9, 0xfa, 0xe4, 0x01, 0xac, 0x26, 0xc6, 0x66, 0xa1, 0x71, 0x89, 0x93, 0x5b, 0x49, 0x88, 0x83, 0x5c, 0x75, 0xa3, 0x5c, 0xab, 0xba, 0xd1, 0xbe, 0x86, 0xd5, 0x64, 0x3f, 0xe2, 0xfc, 0x54, 0x21, 0x79, 0x01, 0x63, 0xca, 0x82, 0x8c, 0xca, 0x45, 0x19, 0xb5, 0x9f, 0x41, 0x6d, 0xe4, 0xd9, 0x41, 0x74, 0xe2, 0xc7, 0xdc, 0x7a, 0xe2, 0x48, 0xfa, 0xaa, 0x12, 0x47, 0x9a, 0x06, 0x15, 0x7e, 0x38, 0xf3, 0x88, 0xbb, 0xbf, 0x31, 0xe8, 0xee, 0x99, 0xc6, 0xb7, 0xba, 0xfa, 0x06, 0x01, 0xa8, 0xc8, 0xe7, 0x82, 0xa6, 0x41, 0xd3, 0x90, 0xed, 0xd8, 0x63, 0x66, 0x3b, 0x2c, 0xe4, 0x12, 0xfc, 0xe0, 0x47, 0x89, 0x04, 0x3f, 0xf8, 0x91, 0xf6, 0x17, 0x05, 0x68, 0x98, 0xa1, 0xed, 0x45, 0xb6, 0x30, 0xf7, 0xcf, 0xa0, 0x72, 0x82, 0x58, 0x74, 0xa3, 0xc6, 0x82, 0x7f, 0x66, 0x17, 0xa3, 0x12, 0x48, 0xee, 0x40, 0xe5, 0xc4, 0xf6, 0x9c, 0xa9, 0xd0, 0x5a, 0x85, 0xca, 0x51, 0x92, 0x1b, 0x95, 0xf3, 0xdc, 0xb8, 0x05, 0x2b, 0x33, 0x3b, 0x7c, 0x6e, 0x8d, 0x4f, 0x6c, 0xef, 0x98, 0x45, 0xf2, 0x60, 0xa4, 0x05, 0x36, 0x38, 0x6b, 0x4f, 0x70, 0xb4, 0xbf, 0x5f, 0x81, 0xf2, 0x37, 0x73, 0x16, 0x9e, 0x65, 0x04, 0xfa, 0xe0, 0xba, 0x02, 0xc9, 0x17, 0x17, 0x2e, 0x4b, 0xca, 0x6f, 0x2f, 0x26, 0x65, 0x22, 0x53, 0x84, 0xc8, 0x95, 0x22, 0x0b, 0x7c, 0x9a, 0x09, 0x63, 0xeb, 0x57, 0xd8, 0xda, 0x79, 0x70, 0x7b, 0x08, 0x95, 0x89, 0x3b, 0x8d, 0x51, 0x75, 0x8b, 0xd5, 0x08, 0xee, 0xa5, 0xf3, 0x08, 0xd9, 0x54, 0xc2, 0xc8, 0xbb, 0xb0, 0x22, 0x2a, 0x59, 0xeb, 0x07, 0xce, 0xc6, 0x82, 0x95, 0xf7, 0xa6, 0x48, 0x13, 0xbb, 0xff, 0x18, 0xca, 0x7e, 0xc8, 0x37, 0x5f, 0xc7, 0x25, 0xef, 0x5c, 0x58, 0x72, 0xc8, 0xb9, 0x54, 0x80, 0xc8, 0x87, 0x50, 0x3a, 0x71, 0xbd, 0x18, 0xb3, 0x46, 0x73, 0xfb, 0xf6, 0x05, 0xf0, 0x63, 0xd7, 0x8b, 0x29, 0x42, 0x78, 0x98, 0x1f, 0xfb, 0x73, 0x2f, 0x6e, 0xdd, 0xc5, 0x0c, 0x23, 0x06, 0xe4, 0x1e, 0x54, 0xfc, 0xc9, 0x24, 0x62, 0x31, 0x76, 0x96, 0xe5, 0x9d, 0xc2, 0xa7, 0x54, 0x12, 0xf8, 0x84, 0xa9, 0x3b, 0x73, 0x63, 0xec, 0x43, 0xca, 0x54, 0x0c, 0xc8, 0x2e, 0xac, 0x8d, 0xfd, 0x59, 0xe0, 0x4e, 0x99, 0x63, 0x8d, 0xe7, 0x61, 0xe4, 0x87, 0xad, 0x77, 0x2e, 0x1c, 0xd3, 0x9e, 0x44, 0xec, 0x21, 0x80, 0x36, 0xc7, 0xb9, 0x31, 0x31, 0x60, 0x83, 0x79, 0x8e, 0xb5, 0xb8, 0xce, 0xfd, 0xd7, 0xad, 0xb3, 0xce, 0x3c, 0x27, 0x4f, 0x4a, 0xc4, 0xc1, 0x48, 0x68, 0x61, 0xcc, 0x68, 0x6d, 0x60, 0x90, 0xb9, 0x77, 0x69, 0xac, 0x14, 0xe2, 0x64, 0xc2, 0xf7, 0x6f, 0xc0, 0x2d, 0x19, 0x22, 0xad, 0x80, 0x85, 0x13, 0x36, 0x8e, 0xad, 0x60, 0x6a, 0x7b, 0x58, 0xca, 0xa5, 0xc6, 0x4a, 0x24, 0xe4, 0x50, 0x20, 0x0e, 0xa7, 0xb6, 0x47, 0x34, 0xa8, 0x3f, 0x67, 0x67, 0x91, 0xc5, 0x23, 0x29, 0x76, 0xae, 0x29, 0xba, 0xc6, 0xe9, 0x43, 0x6f, 0x7a, 0x46, 0x7e, 0x02, 0x8d, 0xf8, 0xdc, 0xdb, 0xb0, 0x61, 0x6d, 0xe4, 0x4e, 0x35, 0xe3, 0x8b, 0x34, 0x0b, 0x25, 0xf7, 0xa1, 0x2a, 0x35, 0xd4, 0xba, 0x97, 0x5d, 0x3b, 0xa1, 0xf2, 0xc4, 0x3c, 0xb1, 0xdd, 0xa9, 0x7f, 0xca, 0x42, 0x6b, 0x16, 0xb5, 0xda, 0xe2, 0xb6, 0x24, 0x21, 0x1d, 0x44, 0xdc, 0x4f, 0xa3, 0x38, 0xf4, 0xbd, 0xe3, 0xd6, 0x26, 0xde, 0x93, 0xc8, 0xd1, 0xc5, 0xe0, 0xf7, 0x2e, 0x66, 0xfe, 0x7c, 0xf0, 0xfb, 0x1c, 0xee, 0x60, 0x65, 0x66, 0x3d, 0x3b, 0xb3, 0xf2, 0x68, 0x0d, 0xd1, 0x1b, 0xc8, 0xdd, 0x3d, 0x3b, 0xcc, 0x4e, 0x6a, 0x43, 0xcd, 0x71, 0xa3, 0xd8, 0xf5, 0xc6, 0x71, 0xab, 0x85, 0xef, 0x4c, 0xc7, 0xe4, 0x33, 0xb8, 0x3d, 0x73, 0x3d, 0x2b, 0xb2, 0x27, 0xcc, 0x8a, 0x5d, 0xee, 0x9b, 0x6c, 0xec, 0x7b, 0x4e, 0xd4, 0x7a, 0x80, 0x82, 0x93, 0x99, 0xeb, 0x8d, 0xec, 0x09, 0x33, 0xdd, 0x19, 0x1b, 0x09, 0x0e, 0xf9, 0x08, 0xd6, 0x11, 0x1e, 0xb2, 0x60, 0xea, 0x8e, 0x6d, 0xf1, 0xfa, 0x1f, 0xe1, 0xeb, 0xd7, 0x38, 0x83, 0x0a, 0x3a, 0xbe, 0xfa, 0x63, 0x68, 0x06, 0x2c, 0x8c, 0xdc, 0x28, 0xb6, 0xa4, 0x45, 0xbf, 0x97, 0xd5, 0xda, 0xaa, 0x64, 0x0e, 0x91, 0xd7, 0xfe, 0xcf, 0x02, 0x54, 0x84, 0x73, 0x92, 0x4f, 0x41, 0xf1, 0x03, 0xbc, 0x06, 0x69, 0x6e, 0x6f, 0x5e, 0xe2, 0xc1, 0x9d, 0x61, 0xc0, 0xeb, 0x5e, 0x3f, 0xa4, 0x8a, 0x1f, 0xdc, 0xb8, 0x28, 0xd4, 0xfe, 0x10, 0x6a, 0xc9, 0x02, 0xbc, 0xbc, 0xe8, 0xeb, 0xa3, 0x91, 0x65, 0x3e, 0xee, 0x0e, 0xd4, 0x02, 0xb9, 0x03, 0x24, 0x1d, 0x5a, 0x43, 0x6a, 0xe9, 0xdf, 0x1c, 0x75, 0xfb, 0xaa, 0x82, 0x5d, 0x1a, 0xd5, 0xbb, 0xa6, 0x4e, 0x05, 0xb2, 0x48, 0xee, 0xc1, 0xed, 0x2c, 0xe5, 0x1c, 0x5c, 0xc2, 0x14, 0x8c, 0x8f, 0x65, 0x52, 0x01, 0xc5, 0x18, 0xa8, 0x15, 0x9e, 0x16, 0xf4, 0xef, 0x8d, 0x91, 0x39, 0x52, 0xab, 0xed, 0xbf, 0x29, 0x40, 0x19, 0xc3, 0x06, 0x3f, 0x9f, 0x54, 0x72, 0x71, 0x5d, 0x73, 0x5e, 0xb9, 0x1a, 0xd9, 0x92, 0xaa, 0x81, 0x01, 0x65, 0x73, 0x79, 0xf4, 0xf9, 0xb5, 0xd6, 0x53, 0x3f, 0x85, 0x12, 0x8f, 0x52, 0xbc, 0x43, 0x1c, 0xd2, 0x9e, 0x4e, 0xad, 0x47, 0x06, 0x1d, 0xf1, 0x2a, 0x97, 0x40, 0xb3, 0x3b, 0xd8, 0xd3, 0x47, 0xe6, 0x30, 0xa1, 0xa1, 0x56, 0x1e, 0x19, 0x7d, 0x33, 0x45, 0x15, 0xb5, 0x9f, 0xd7, 0x60, 0x35, 0x89, 0x09, 0x22, 0x82, 0x3e, 0x82, 0x46, 0x10, 0xba, 0x33, 0x3b, 0x3c, 0x8b, 0xc6, 0xb6, 0x87, 0x49, 0x01, 0xb6, 0x7f, 0xb4, 0x24, 0xaa, 0x88, 0x1d, 0x1d, 0x0a, 0xec, 0x68, 0x6c, 0x7b, 0x34, 0x3b, 0x91, 0xf4, 0x61, 0x75, 0xc6, 0xc2, 0x63, 0xf6, 0x7b, 0xbe, 0xeb, 0xe1, 0x4a, 0x55, 0x8c, 0xc8, 0xef, 0x5f, 0xba, 0xd2, 0x01, 0x47, 0xff, 0x8e, 0xef, 0x7a, 0xb8, 0x56, 0x7e, 0x32, 0xf9, 0x04, 0xea, 0xa2, 0x12, 0x72, 0xd8, 0x04, 0x63, 0xc5, 0xb2, 0xda, 0x4f, 0xd4, 0xe8, 0x3d, 0x36, 0xc9, 0xc4, 0x65, 0xb8, 0x34, 0x2e, 0x37, 0xb2, 0x71, 0xf9, 0xcd, 0x6c, 0x2c, 0x5a, 0x11, 0x55, 0x78, 0x1a, 0x84, 0x2e, 0x38, 0x7c, 0x6b, 0x89, 0xc3, 0x77, 0x60, 0x23, 0xf1, 0x55, 0xcb, 0xf5, 0x26, 0xee, 0x4b, 0x2b, 0x72, 0x5f, 0x89, 0xd8, 0x53, 0xa6, 0xeb, 0x09, 0xcb, 0xe0, 0x9c, 0x91, 0xfb, 0x8a, 0x11, 0x23, 0xe9, 0xe0, 0x64, 0x0e, 0x5c, 0xc5, 0xab, 0xc9, 0xf7, 0x2e, 0x55, 0x8f, 0x68, 0xbe, 0x64, 0x46, 0xcc, 0x4d, 0x6d, 0xff, 0x52, 0x81, 0x46, 0xe6, 0x1c, 0x78, 0xf6, 0x16, 0xca, 0x42, 0x61, 0xc5, 0x55, 0x94, 0x50, 0x1f, 0x4a, 0xfa, 0x26, 0xd4, 0xa3, 0xd8, 0x0e, 0x63, 0x8b, 0x17, 0x57, 0xb2, 0xdd, 0x45, 0xc2, 0x13, 0x76, 0x46, 0x3e, 0x80, 0x35, 0xc1, 0x74, 0xbd, 0xf1, 0x74, 0x1e, 0xb9, 0xa7, 0xa2, 0x99, 0xaf, 0xd1, 0x26, 0x92, 0x8d, 0x84, 0x4a, 0xee, 0x42, 0x95, 0x67, 0x21, 0xbe, 0x86, 0x68, 0xfa, 0x2a, 0xcc, 0x73, 0xf8, 0x0a, 0x0f, 0x60, 0x95, 0x33, 0xce, 0xe7, 0x57, 0xc4, 0x2d, 0x33, 0xf3, 0x9c, 0xf3, 0xd9, 0x1d, 0xd8, 0x10, 0xaf, 0x09, 0x44, 0xf1, 0x2a, 0x2b, 0xdc, 0x3b, 0xa8, 0xd8, 0x75, 0x64, 0xc9, 0xb2, 0x56, 0x14, 0x9c, 0x1f, 0x01, 0xcf, 0x5e, 0x0b, 0xe8, 0xbb, 0x22, 0x94, 0x31, 0xcf, 0xc9, 0x61, 0x77, 0xe1, 0x1d, 0x8e, 0x9d, 0x7b, 0x76, 0x10, 0x4c, 0x5d, 0xe6, 0x58, 0x53, 0xff, 0x18, 0x43, 0x66, 0x14, 0xdb, 0xb3, 0xc0, 0x9a, 0x47, 0xad, 0x0d, 0x0c, 0x99, 0x6d, 0xe6, 0x39, 0x47, 0x09, 0xa8, 0xef, 0x1f, 0x9b, 0x09, 0xe4, 0x28, 0x6a, 0xff, 0x3e, 0xac, 0xe6, 0xec, 0x71, 0x41, 0xa7, 0x35, 0x74, 0xfe, 0x8c, 0x4e, 0xdf, 0x85, 0x95, 0x20, 0x64, 0xe7, 0xa2, 0xd5, 0x51, 0xb4, 0x86, 0xa0, 0x09, 0xb1, 0xb6, 0x60, 0x05, 0x79, 0x96, 0x20, 0xe6, 0xf3, 0x63, 0x03, 0x59, 0x87, 0xc8, 0x69, 0xbf, 0x80, 0x95, 0xec, 0x69, 0x93, 0x77, 0x33, 0x69, 0xa1, 0x99, 0xcb, 0x93, 0x69, 0x76, 0x48, 0x2a, 0xb2, 0xf5, 0x4b, 0x2a, 0x32, 0x72, 0x9d, 0x8a, 0x4c, 0xfb, 0x2f, 0xd9, 0x9c, 0x65, 0x2a, 0x84, 0x9f, 0x41, 0x2d, 0x90, 0xf5, 0x38, 0x5a, 0x52, 0xfe, 0x12, 0x3e, 0x0f, 0xee, 0x24, 0x95, 0x3b, 0x4d, 0xe7, 0xb4, 0xff, 0x56, 0x81, 0x5a, 0x5a, 0xd0, 0xe7, 0x2c, 0xef, 0xcd, 0x05, 0xcb, 0x3b, 0x90, 0x1a, 0x16, 0x0a, 0x7c, 0x1b, 0xa3, 0xc5, 0x27, 0xaf, 0x7f, 0xd7, 0xc5, 0xb6, 0xe7, 0x34, 0xdb, 0xf6, 0x6c, 0xbe, 0xae, 0xed, 0xf9, 0xe4, 0xa2, 0xc1, 0xbf, 0x95, 0xe9, 0x2d, 0x16, 0xcc, 0xbe, 0xfd, 0x7d, 0xae, 0x0f, 0xca, 0x26, 0x84, 0x77, 0xc4, 0x7e, 0xd2, 0x84, 0x90, 0xb6, 0x3f, 0xf7, 0xaf, 0xd7, 0xfe, 0x6c, 0x43, 0x45, 0xea, 0xfc, 0x0e, 0x54, 0x64, 0x4d, 0x27, 0x1b, 0x04, 0x31, 0x3a, 0x6f, 0x10, 0x0a, 0xb2, 0x4e, 0xd7, 0x7e, 0xae, 0x40, 0x59, 0x0f, 0x43, 0x3f, 0xd4, 0xfe, 0x48, 0x81, 0x3a, 0x3e, 0xed, 0xf9, 0x0e, 0xe3, 0xd9, 0x60, 0xb7, 0xdb, 0xb3, 0xa8, 0xfe, 0xcd, 0x91, 0x8e, 0xd9, 0xa0, 0x0d, 0x77, 0xf6, 0x86, 0x83, 0xbd, 0x23, 0x4a, 0xf5, 0x81, 0x69, 0x99, 0xb4, 0x3b, 0x18, 0xf1, 0xb6, 0x67, 0x38, 0x50, 0x15, 0x9e, 0x29, 0x8c, 0x81, 0xa9, 0xd3, 0x41, 0xb7, 0x6f, 0x89, 0x56, 0xb4, 0x88, 0x77, 0xb3, 0xba, 0xde, 0xb3, 0xf0, 0xd6, 0x51, 0x2d, 0xf1, 0x96, 0xd5, 0x34, 0x0e, 0xf4, 0xe1, 0x91, 0xa9, 0x96, 0xc9, 0x6d, 0x58, 0x3f, 0xd4, 0xe9, 0x81, 0x31, 0x1a, 0x19, 0xc3, 0x81, 0xd5, 0xd3, 0x07, 0x86, 0xde, 0x53, 0x2b, 0x7c, 0x9d, 0x5d, 0x63, 0xdf, 0xec, 0xee, 0xf6, 0x75, 0xb9, 0x4e, 0x95, 0x6c, 0xc2, 0x5b, 0x7b, 0xc3, 0x83, 0x03, 0xc3, 0x34, 0xf5, 0x9e, 0xb5, 0x7b, 0x64, 0x5a, 0x23, 0xd3, 0xe8, 0xf7, 0xad, 0xee, 0xe1, 0x61, 0xff, 0x29, 0x4f, 0x60, 0x35, 0x72, 0x17, 0x36, 0xf6, 0xba, 0x87, 0xdd, 0x5d, 0xa3, 0x6f, 0x98, 0x4f, 0xad, 0x9e, 0x31, 0xe2, 0xf3, 0x7b, 0x6a, 0x9d, 0x27, 0x6c, 0x93, 0x3e, 0xb5, 0xba, 0x7d, 0x14, 0xcd, 0xd4, 0xad, 0xdd, 0xee, 0xde, 0x13, 0x7d, 0xd0, 0x53, 0x81, 0x0b, 0x30, 0xea, 0x3e, 0xd2, 0x2d, 0x2e, 0x92, 0x65, 0x0e, 0x87, 0xd6, 0xb0, 0xdf, 0x53, 0x1b, 0xda, 0xbf, 0x14, 0xa1, 0xb4, 0xe7, 0x47, 0x31, 0xf7, 0x46, 0xe1, 0xac, 0x2f, 0x42, 0x37, 0x66, 0xa2, 0x7f, 0x2b, 0x53, 0xd1, 0x4b, 0x7f, 0x87, 0x24, 0x1e, 0x50, 0x32, 0x10, 0xeb, 0xd9, 0x19, 0xc7, 0x29, 0x88, 0x5b, 0x3b, 0xc7, 0xed, 0x72, 0xb2, 0x88, 0x68, 0x78, 0x85, 0x23, 0xd7, 0x2b, 0x22, 0x4e, 0x06, 0x61, 0xb9, 0xe0, 0xc7, 0x40, 0xb2, 0x20, 0xb9, 0x62, 0x09, 0x91, 0x6a, 0x06, 0x29, 0x96, 0xdc, 0x01, 0x18, 0xfb, 0xb3, 0x99, 0x1b, 0x8f, 0xfd, 0x28, 0x96, 0x5f, 0xc8, 0xda, 0x39, 0x63, 0x8f, 0x62, 0x6e, 0xf1, 0x33, 0x37, 0xe6, 0x8f, 0x34, 0x83, 0x26, 0x3b, 0x70, 0xcf, 0x0e, 0x82, 0xd0, 0x7f, 0xe9, 0xce, 0xec, 0x98, 0x59, 0xdc, 0x73, 0xed, 0x63, 0x66, 0x39, 0x6c, 0x1a, 0xdb, 0xd8, 0x13, 0x95, 0xe9, 0xdd, 0x0c, 0x60, 0x24, 0xf8, 0x3d, 0xce, 0xe6, 0x71, 0xd7, 0x75, 0xac, 0x88, 0xfd, 0x30, 0xe7, 0x1e, 0x60, 0xcd, 0x03, 0xc7, 0xe6, 0x62, 0xd6, 0x45, 0x96, 0x72, 0x9d, 0x91, 0xe4, 0x1c, 0x09, 0x46, 0xfb, 0x15, 0xc0, 0xb9, 0x14, 0x64, 0x1b, 0x6e, 0xf3, 0x3a, 0x9e, 0x45, 0x31, 0x73, 0x2c, 0xb9, 0xdb, 0x60, 0x1e, 0x47, 0x18, 0xe2, 0xcb, 0x74, 0x23, 0x65, 0xca, 0x9b, 0xc2, 0x79, 0x1c, 0x91, 0x9f, 0x40, 0xeb, 0xc2, 0x1c, 0x87, 0x4d, 0x19, 0x7f, 0x6d, 0x15, 0xa7, 0xdd, 0x59, 0x98, 0xd6, 0x13, 0x5c, 0xed, 0x4f, 0x14, 0x80, 0x7d, 0x16, 0x53, 0xc1, 0xcd, 0x34, 0xb6, 0x95, 0xeb, 0x36, 0xb6, 0xef, 0x27, 0x17, 0x08, 0xc5, 0xab, 0x63, 0xc0, 0x42, 0x97, 0xa1, 0xdc, 0xa4, 0xcb, 0xc8, 0x35, 0x11, 0xc5, 0x2b, 0x9a, 0x88, 0x52, 0xae, 0x89, 0xf8, 0x18, 0x9a, 0xf6, 0x74, 0xea, 0xbf, 0xe0, 0x05, 0x0d, 0x0b, 0x43, 0xe6, 0xa0, 0x11, 0x9c, 0xd7, 0xdb, 0xc8, 0xec, 0x49, 0x9e, 0xf6, 0xe7, 0x0a, 0x34, 0x50, 0x15, 0x51, 0xe0, 0x7b, 0x11, 0x23, 0x5f, 0x42, 0x45, 0x5e, 0x44, 0x8b, 0x8b, 0xfc, 0xb7, 0x33, 0xb2, 0x66, 0x70, 0xb2, 0x68, 0xa0, 0x12, 0xcc, 0x33, 0x42, 0xe6, 0x75, 0x97, 0x2b, 0x25, 0x45, 0x91, 0xfb, 0x50, 0x73, 0x3d, 0x4b, 0xb4, 0xd4, 0x95, 0x4c, 0x58, 0xac, 0xba, 0x1e, 0xd6, 0xb2, 0xed, 0x57, 0x50, 0x11, 0x2f, 0x21, 0x9d, 0x54, 0xa6, 0x8b, 0xfa, 0xcb, 0xdc, 0x1c, 0xa7, 0xc2, 0xc8, 0xc3, 0x29, 0xbd, 0x2e, 0x40, 0xb7, 0xa0, 0x7a, 0xca, 0x9b, 0x0f, 0xbc, 0xf4, 0xe3, 0xea, 0x4d, 0x86, 0xda, 0x1f, 0x97, 0x00, 0x0e, 0xe7, 0x4b, 0x0c, 0xa4, 0x71, 0x5d, 0x03, 0xe9, 0xe4, 0xf4, 0xf8, 0x7a, 0x99, 0x7f, 0x75, 0x43, 0x59, 0xd2, 0x69, 0x17, 0x6f, 0xda, 0x69, 0xdf, 0x87, 0x6a, 0x1c, 0xce, 0xb9, 0xa3, 0x08, 0x63, 0x4a, 0x5b, 0x5a, 0x49, 0x25, 0x6f, 0x42, 0x79, 0xe2, 0x87, 0x63, 0x86, 0x8e, 0x95, 0xb2, 0x05, 0xed, 0xc2, 0x65, 0x52, 0xed, 0xb2, 0xcb, 0x24, 0xde, 0xa0, 0x45, 0xf2, 0x1e, 0x0d, 0x0b, 0x99, 0x7c, 0x83, 0x96, 0x5c, 0xb1, 0xd1, 0x14, 0x44, 0xbe, 0x81, 0xa6, 0x3d, 0x8f, 0x7d, 0xcb, 0xe5, 0x15, 0xda, 0xd4, 0x1d, 0x9f, 0x61, 0xd9, 0xdd, 0xcc, 0x7f, 0xaf, 0x4f, 0x0f, 0xaa, 0xd3, 0x9d, 0xc7, 0xbe, 0xe1, 0x1c, 0x22, 0x72, 0xa7, 0x2a, 0x93, 0x12, 0x5d, 0xb1, 0x33, 0x64, 0xed, 0xc7, 0xb0, 0x92, 0x85, 0xf1, 0x04, 0x24, 0x81, 0xea, 0x1b, 0x3c, 0x3b, 0x8d, 0x78, 0x6a, 0x1b, 0x98, 0x46, 0xb7, 0xaf, 0x16, 0xb4, 0x18, 0x1a, 0xb8, 0xbc, 0xf4, 0x8e, 0xeb, 0xba, 0xfd, 0x03, 0x28, 0x61, 0xf8, 0x55, 0x2e, 0x7c, 0x0f, 0xc1, 0x98, 0x8b, 0xcc, 0xbc, 0xf9, 0x15, 0xb3, 0xe6, 0xf7, 0xdf, 0x05, 0x58, 0x31, 0xfd, 0xf9, 0xf8, 0xe4, 0xa2, 0x01, 0xc2, 0xaf, 0x3b, 0x42, 0x2d, 0x31, 0x1f, 0xe5, 0xa6, 0xe6, 0x93, 0x5a, 0x47, 0x71, 0x89, 0x75, 0xdc, 0xf4, 0xcc, 0xb5, 0x2f, 0x60, 0x55, 0x6e, 0x5e, 0x6a, 0x3d, 0xd1, 0x66, 0xe1, 0x0a, 0x6d, 0x6a, 0xbf, 0x50, 0x60, 0x55, 0xc4, 0xf7, 0xff, 0xbb, 0xd2, 0x2a, 0x37, 0x0c, 0xeb, 0xe5, 0x1b, 0x5d, 0x1e, 0xfd, 0xbf, 0xf4, 0x34, 0x6d, 0x08, 0xcd, 0x44, 0x7d, 0x37, 0x50, 0xfb, 0x15, 0x46, 0xfc, 0x8b, 0x02, 0x34, 0x06, 0xec, 0xe5, 0x92, 0x20, 0x5a, 0xbe, 0xee, 0x71, 0x7c, 0x98, 0x2b, 0x57, 0x1b, 0xdb, 0xeb, 0x59, 0x19, 0xc4, 0xd5, 0x63, 0x52, 0xc1, 0xa6, 0xb7, 0xa8, 0xca, 0xf2, 0x5b, 0xd4, 0xd2, 0x62, 0xb7, 0x9e, 0xb9, 0xc5, 0x2b, 0x2e, 0xbb, 0xc5, 0xd3, 0xfe, 0xad, 0x08, 0x0d, 0x6c, 0x90, 0x29, 0x8b, 0xe6, 0xd3, 0x38, 0x27, 0x4c, 0xe1, 0x6a, 0x61, 0x3a, 0x50, 0x09, 0x71, 0x92, 0x74, 0xa5, 0x4b, 0x83, 0xbf, 0x40, 0x61, 0x6b, 0xfc, 0xdc, 0x0d, 0x02, 0xe6, 0x58, 0x82, 0x92, 0x14, 0x30, 0x4d, 0x49, 0x16, 0x22, 0x44, 0xbc, 0xfc, 0x9c, 0xf9, 0x21, 0x4b, 0x51, 0x45, 0xbc, 0x4f, 0x68, 0x70, 0x5a, 0x02, 0xc9, 0xdd, 0x37, 0x88, 0xca, 0xe0, 0xfc, 0xbe, 0x21, 0xed, 0x35, 0x91, 0x5b, 0x47, 0xae, 0xe8, 0x35, 0x91, 0xcd, 0xbb, 0xa8, 0x99, 0x3d, 0x9d, 0x5a, 0x7e, 0x10, 0xa1, 0xd3, 0xd4, 0x68, 0x0d, 0x09, 0xc3, 0x20, 0x22, 0x5f, 0x43, 0x7a, 0x5d, 0x2c, 0x6f, 0xc9, 0xc5, 0x39, 0xb6, 0x2e, 0xbb, 0x58, 0xa0, 0xab, 0xe3, 0xdc, 0xfd, 0xcf, 0x92, 0x1b, 0xea, 0xca, 0x4d, 0x6f, 0xa8, 0x1f, 0x42, 0x59, 0xc4, 0xa8, 0xda, 0xeb, 0x62, 0x94, 0xc0, 0x65, 0xed, 0xb3, 0x91, 0xb7, 0xcf, 0x5f, 0x16, 0x80, 0x74, 0xa7, 0x53, 0x7f, 0x6c, 0xc7, 0xcc, 0x70, 0xa2, 0x8b, 0x66, 0x7a, 0xed, 0xcf, 0x2e, 0x9f, 0x41, 0x7d, 0xe6, 0x3b, 0x6c, 0x6a, 0x25, 0xdf, 0x94, 0x2e, 0xad, 0x7e, 0x10, 0xc6, 0x5b, 0x52, 0x02, 0x25, 0xbc, 0xc4, 0x51, 0xb0, 0xee, 0xc0, 0x67, 0xde, 0x84, 0xcd, 0xec, 0x97, 0xb2, 0x14, 0xe1, 0x8f, 0xa4, 0x03, 0xd5, 0x90, 0x45, 0x2c, 0x3c, 0x65, 0x57, 0x16, 0x55, 0x09, 0x48, 0x7b, 0x06, 0x1b, 0xb9, 0x1d, 0x49, 0x47, 0xbe, 0x85, 0x5f, 0x2b, 0xc3, 0x58, 0x7e, 0xb4, 0x12, 0x03, 0xfe, 0x3a, 0xe6, 0x25, 0x9f, 0x41, 0xf9, 0x63, 0xea, 0xf0, 0xc5, 0xab, 0xe2, 0xec, 0x1e, 0xa8, 0x59, 0x4d, 0xbb, 0x63, 0x0c, 0x36, 0xf2, 0x54, 0x0a, 0xd7, 0x3b, 0x15, 0xed, 0xef, 0x0a, 0xb0, 0xde, 0x75, 0x1c, 0xf1, 0x77, 0xc3, 0x25, 0xaa, 0x2f, 0x5e, 0x57, 0xf5, 0x0b, 0x81, 0x58, 0x84, 0x89, 0x6b, 0x05, 0xe2, 0x0f, 0xa1, 0x92, 0xd6, 0x5a, 0xc5, 0x05, 0x77, 0x16, 0x72, 0x51, 0x09, 0xd0, 0x6e, 0x01, 0xc9, 0x0a, 0x2b, 0xb4, 0xaa, 0xfd, 0x69, 0x11, 0xee, 0xee, 0xb2, 0x63, 0xd7, 0xcb, 0xbe, 0xe2, 0x57, 0xdf, 0xc9, 0xc5, 0x4f, 0x65, 0x9f, 0xc1, 0xba, 0x28, 0xe4, 0x93, 0x7f, 0x62, 0x59, 0xec, 0x58, 0x7e, 0x9d, 0x94, 0xb1, 0x6a, 0x0d, 0xf9, 0x07, 0x92, 0xad, 0xe3, 0x7f, 0xc5, 0x1c, 0x3b, 0xb6, 0x9f, 0xd9, 0x11, 0xb3, 0x5c, 0x47, 0xfe, 0x59, 0x06, 0x12, 0x92, 0xe1, 0x90, 0x21, 0x94, 0xb8, 0x0d, 0xa2, 0xeb, 0x36, 0xb7, 0xb7, 0x33, 0x62, 0x5d, 0xb2, 0x95, 0xac, 0x02, 0x0f, 0x7c, 0x87, 0xed, 0x54, 0x8f, 0x06, 0x4f, 0x06, 0xc3, 0xef, 0x06, 0x14, 0x17, 0x22, 0x06, 0xdc, 0x0a, 0x42, 0x76, 0xea, 0xfa, 0xf3, 0xc8, 0xca, 0x9e, 0x44, 0xf5, 0xca, 0x94, 0xb8, 0x91, 0xcc, 0xc9, 0x10, 0xb5, 0x9f, 0xc2, 0xda, 0xc2, 0xcb, 0x78, 0x6d, 0x26, 0x5f, 0xa7, 0xbe, 0x41, 0x56, 0xa1, 0x8e, 0x1f, 0xbb, 0x97, 0x7f, 0xfb, 0xd6, 0xfe, 0xb5, 0x80, 0x57, 0x4c, 0x33, 0x37, 0xbe, 0x59, 0x06, 0xfb, 0xcd, 0x7c, 0x06, 0x83, 0xed, 0x77, 0xf3, 0xe6, 0x9b, 0x59, 0xb0, 0xf3, 0xad, 0x00, 0xa6, 0x41, 0xa4, 0x6d, 0x43, 0x55, 0xd2, 0xc8, 0x6f, 0xc1, 0x5a, 0xe8, 0xfb, 0x71, 0xd2, 0x89, 0x8a, 0x0e, 0xe4, 0xf2, 0x3f, 0xdb, 0xac, 0x72, 0xb0, 0x48, 0x06, 0x4f, 0xf2, 0xbd, 0x48, 0x59, 0xfc, 0x0d, 0x44, 0x0e, 0x77, 0x1b, 0xbf, 0x5b, 0x4f, 0xff, 0xb7, 0xfb, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x35, 0x9f, 0x30, 0x98, 0xf2, 0x2b, 0x00, 0x00, } google-cloud-go-0.49.0/datastore/key.go000066400000000000000000000157301356504100700177030ustar00rootroot00000000000000// Copyright 2014 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package datastore import ( "bytes" "context" "encoding/base64" "encoding/gob" "errors" "strconv" "strings" "github.com/golang/protobuf/proto" pb "google.golang.org/genproto/googleapis/datastore/v1" ) // Key represents the datastore key for a stored entity. type Key struct { // Kind cannot be empty. Kind string // Either ID or Name must be zero for the Key to be valid. // If both are zero, the Key is incomplete. ID int64 Name string // Parent must either be a complete Key or nil. Parent *Key // Namespace provides the ability to partition your data for multiple // tenants. In most cases, it is not necessary to specify a namespace. // See docs on datastore multitenancy for details: // https://cloud.google.com/datastore/docs/concepts/multitenancy Namespace string } // Incomplete reports whether the key does not refer to a stored entity. func (k *Key) Incomplete() bool { return k.Name == "" && k.ID == 0 } // valid returns whether the key is valid. func (k *Key) valid() bool { if k == nil { return false } for ; k != nil; k = k.Parent { if k.Kind == "" { return false } if k.Name != "" && k.ID != 0 { return false } if k.Parent != nil { if k.Parent.Incomplete() { return false } if k.Parent.Namespace != k.Namespace { return false } } } return true } // Equal reports whether two keys are equal. Two keys are equal if they are // both nil, or if their kinds, IDs, names, namespaces and parents are equal. func (k *Key) Equal(o *Key) bool { for { if k == nil || o == nil { return k == o // if either is nil, both must be nil } if k.Namespace != o.Namespace || k.Name != o.Name || k.ID != o.ID || k.Kind != o.Kind { return false } if k.Parent == nil && o.Parent == nil { return true } k = k.Parent o = o.Parent } } // marshal marshals the key's string representation to the buffer. func (k *Key) marshal(b *bytes.Buffer) { if k.Parent != nil { k.Parent.marshal(b) } b.WriteByte('/') b.WriteString(k.Kind) b.WriteByte(',') if k.Name != "" { b.WriteString(k.Name) } else { b.WriteString(strconv.FormatInt(k.ID, 10)) } } // String returns a string representation of the key. func (k *Key) String() string { if k == nil { return "" } b := bytes.NewBuffer(make([]byte, 0, 512)) k.marshal(b) return b.String() } // Note: Fields not renamed compared to appengine gobKey struct // This ensures gobs created by appengine can be read here, and vice/versa type gobKey struct { Kind string StringID string IntID int64 Parent *gobKey AppID string Namespace string } func keyToGobKey(k *Key) *gobKey { if k == nil { return nil } return &gobKey{ Kind: k.Kind, StringID: k.Name, IntID: k.ID, Parent: keyToGobKey(k.Parent), Namespace: k.Namespace, } } func gobKeyToKey(gk *gobKey) *Key { if gk == nil { return nil } return &Key{ Kind: gk.Kind, Name: gk.StringID, ID: gk.IntID, Parent: gobKeyToKey(gk.Parent), Namespace: gk.Namespace, } } // GobEncode marshals the key into a sequence of bytes // using an encoding/gob.Encoder. func (k *Key) GobEncode() ([]byte, error) { buf := new(bytes.Buffer) if err := gob.NewEncoder(buf).Encode(keyToGobKey(k)); err != nil { return nil, err } return buf.Bytes(), nil } // GobDecode unmarshals a sequence of bytes using an encoding/gob.Decoder. func (k *Key) GobDecode(buf []byte) error { gk := new(gobKey) if err := gob.NewDecoder(bytes.NewBuffer(buf)).Decode(gk); err != nil { return err } *k = *gobKeyToKey(gk) return nil } // MarshalJSON marshals the key into JSON. func (k *Key) MarshalJSON() ([]byte, error) { return []byte(`"` + k.Encode() + `"`), nil } // UnmarshalJSON unmarshals a key JSON object into a Key. func (k *Key) UnmarshalJSON(buf []byte) error { if len(buf) < 2 || buf[0] != '"' || buf[len(buf)-1] != '"' { return errors.New("datastore: bad JSON key") } k2, err := DecodeKey(string(buf[1 : len(buf)-1])) if err != nil { return err } *k = *k2 return nil } // Encode returns an opaque representation of the key // suitable for use in HTML and URLs. // This is compatible with the Python and Java runtimes. func (k *Key) Encode() string { pKey := keyToProto(k) b, err := proto.Marshal(pKey) if err != nil { panic(err) } // Trailing padding is stripped. return strings.TrimRight(base64.URLEncoding.EncodeToString(b), "=") } // DecodeKey decodes a key from the opaque representation returned by Encode. func DecodeKey(encoded string) (*Key, error) { k, err := decodeCloudKey(encoded) if err != nil { // Couldn't decode it as a Cloud Datastore key, try decoding it as a key encoded by google.golang.org/appengine/datastore. if k := decodeGAEKey(encoded); k != nil { return k, nil } // Return original error. return nil, err } return k, nil } func decodeCloudKey(encoded string) (*Key, error) { // Re-add padding. if m := len(encoded) % 4; m != 0 { encoded += strings.Repeat("=", 4-m) } b, err := base64.URLEncoding.DecodeString(encoded) if err != nil { return nil, err } pKey := new(pb.Key) if err := proto.Unmarshal(b, pKey); err != nil { return nil, err } return protoToKey(pKey) } // AllocateIDs accepts a slice of incomplete keys and returns a // slice of complete keys that are guaranteed to be valid in the datastore. func (c *Client) AllocateIDs(ctx context.Context, keys []*Key) ([]*Key, error) { if keys == nil { return nil, nil } req := &pb.AllocateIdsRequest{ ProjectId: c.dataset, Keys: multiKeyToProto(keys), } resp, err := c.client.AllocateIds(ctx, req) if err != nil { return nil, err } return multiProtoToKey(resp.Keys) } // IncompleteKey creates a new incomplete key. // The supplied kind cannot be empty. // The namespace of the new key is empty. func IncompleteKey(kind string, parent *Key) *Key { return &Key{ Kind: kind, Parent: parent, } } // NameKey creates a new key with a name. // The supplied kind cannot be empty. // The supplied parent must either be a complete key or nil. // The namespace of the new key is empty. func NameKey(kind, name string, parent *Key) *Key { return &Key{ Kind: kind, Name: name, Parent: parent, } } // IDKey creates a new key with an ID. // The supplied kind cannot be empty. // The supplied parent must either be a complete key or nil. // The namespace of the new key is empty. func IDKey(kind string, id int64, parent *Key) *Key { return &Key{ Kind: kind, ID: id, Parent: parent, } } google-cloud-go-0.49.0/datastore/key_test.go000066400000000000000000000116401356504100700207360ustar00rootroot00000000000000// Copyright 2014 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package datastore import ( "bytes" "encoding/gob" "encoding/json" "testing" ) func TestEqual(t *testing.T) { testCases := []struct { x, y *Key equal bool }{ { x: nil, y: nil, equal: true, }, { x: &Key{Kind: "kindA"}, y: &Key{Kind: "kindA"}, equal: true, }, { x: &Key{Kind: "kindA", Name: "nameA"}, y: &Key{Kind: "kindA", Name: "nameA"}, equal: true, }, { x: &Key{Kind: "kindA", Name: "nameA", Namespace: "gopherspace"}, y: &Key{Kind: "kindA", Name: "nameA", Namespace: "gopherspace"}, equal: true, }, { x: &Key{Kind: "kindA", ID: 1337, Parent: &Key{Kind: "kindX", Name: "nameX"}}, y: &Key{Kind: "kindA", ID: 1337, Parent: &Key{Kind: "kindX", Name: "nameX"}}, equal: true, }, { x: &Key{Kind: "kindA", Name: "nameA"}, y: &Key{Kind: "kindB", Name: "nameA"}, equal: false, }, { x: &Key{Kind: "kindA", Name: "nameA"}, y: &Key{Kind: "kindA", Name: "nameB"}, equal: false, }, { x: &Key{Kind: "kindA", Name: "nameA"}, y: &Key{Kind: "kindA", ID: 1337}, equal: false, }, { x: &Key{Kind: "kindA", Name: "nameA"}, y: &Key{Kind: "kindA", Name: "nameA", Namespace: "gopherspace"}, equal: false, }, { x: &Key{Kind: "kindA", ID: 1337, Parent: &Key{Kind: "kindX", Name: "nameX"}}, y: &Key{Kind: "kindA", ID: 1337, Parent: &Key{Kind: "kindY", Name: "nameX"}}, equal: false, }, { x: &Key{Kind: "kindA", ID: 1337, Parent: &Key{Kind: "kindX", Name: "nameX"}}, y: &Key{Kind: "kindA", ID: 1337}, equal: false, }, } for _, tt := range testCases { if got := tt.x.Equal(tt.y); got != tt.equal { t.Errorf("Equal(%v, %v) = %t; want %t", tt.x, tt.y, got, tt.equal) } if got := tt.y.Equal(tt.x); got != tt.equal { t.Errorf("Equal(%v, %v) = %t; want %t", tt.y, tt.x, got, tt.equal) } } } func TestEncoding(t *testing.T) { testCases := []struct { k *Key valid bool }{ { k: nil, valid: false, }, { k: &Key{}, valid: false, }, { k: &Key{Kind: "kindA"}, valid: true, }, { k: &Key{Kind: "kindA", Namespace: "gopherspace"}, valid: true, }, { k: &Key{Kind: "kindA", Name: "nameA"}, valid: true, }, { k: &Key{Kind: "kindA", ID: 1337}, valid: true, }, { k: &Key{Kind: "kindA", Name: "nameA", ID: 1337}, valid: false, }, { k: &Key{Kind: "kindA", Parent: &Key{Kind: "kindB", Name: "nameB"}}, valid: true, }, { k: &Key{Kind: "kindA", Parent: &Key{Kind: "kindB"}}, valid: false, }, { k: &Key{Kind: "kindA", Parent: &Key{Kind: "kindB", Name: "nameB", Namespace: "gopherspace"}}, valid: false, }, } for _, tt := range testCases { if got := tt.k.valid(); got != tt.valid { t.Errorf("valid(%v) = %t; want %t", tt.k, got, tt.valid) } // Check encoding/decoding for valid keys. if !tt.valid { continue } enc := tt.k.Encode() dec, err := DecodeKey(enc) if err != nil { t.Errorf("DecodeKey(%q) from %v: %v", enc, tt.k, err) continue } if !tt.k.Equal(dec) { t.Logf("Proto: %s", keyToProto(tt.k)) t.Errorf("Decoded key %v not equal to %v", dec, tt.k) } b, err := json.Marshal(tt.k) if err != nil { t.Errorf("json.Marshal(%v): %v", tt.k, err) continue } key := &Key{} if err := json.Unmarshal(b, key); err != nil { t.Errorf("json.Unmarshal(%s) for key %v: %v", b, tt.k, err) continue } if !tt.k.Equal(key) { t.Errorf("JSON decoded key %v not equal to %v", dec, tt.k) } buf := &bytes.Buffer{} gobEnc := gob.NewEncoder(buf) if err := gobEnc.Encode(tt.k); err != nil { t.Errorf("gobEnc.Encode(%v): %v", tt.k, err) continue } gobDec := gob.NewDecoder(buf) key = &Key{} if err := gobDec.Decode(key); err != nil { t.Errorf("gobDec.Decode() for key %v: %v", tt.k, err) } if !tt.k.Equal(key) { t.Errorf("gob decoded key %v not equal to %v", dec, tt.k) } } } func TestInvalidKeyDecode(t *testing.T) { // Check that decoding an invalid key returns an err and doesn't panic. enc := NameKey("Kind", "Foo", nil).Encode() invalid := []string{ "", "Laboratorio", enc + "Junk", enc[:len(enc)-4], } for _, enc := range invalid { key, err := DecodeKey(enc) if err == nil || key != nil { t.Errorf("DecodeKey(%q) = %v, %v; want nil, error", enc, key, err) } } } google-cloud-go-0.49.0/datastore/keycompat.go000066400000000000000000000035361356504100700211100ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package datastore import ( "encoding/base64" "strings" "cloud.google.com/go/datastore/internal/gaepb" "github.com/golang/protobuf/proto" ) // decodeGAEKey attempts to decode the given encoded key generated by the // GAE Datastore package (google.golang.org/appengine/datastore), returning nil // if the key couldn't be decoded. func decodeGAEKey(encoded string) *Key { // Re-add padding. if m := len(encoded) % 4; m != 0 { encoded += strings.Repeat("=", 4-m) } b, err := base64.URLEncoding.DecodeString(encoded) if err != nil { return nil } ref := new(gaepb.Reference) if err := proto.Unmarshal(b, ref); err != nil { return nil } return gaeProtoToKey(ref) } // gaeProtoToKey accepts a GAE Datastore key and converts it to a Cloud Datastore key. // This is adapted from the "protoToKey" function in the appengine/datastore package. // // NOTE(cbro): this is a lossy operation, as GAE Datastore keys include the project/app ID, // but Cloud Datastore keys do not. func gaeProtoToKey(r *gaepb.Reference) *Key { namespace := r.GetNameSpace() var k *Key for _, e := range r.Path.Element { k = &Key{ Kind: e.GetType(), Name: e.GetName(), ID: e.GetId(), Parent: k, Namespace: namespace, } } if !k.valid() { return nil } return k } google-cloud-go-0.49.0/datastore/keycompat_test.go000066400000000000000000000033241356504100700221420ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package datastore import ( "testing" ) func TestKeyConversion(t *testing.T) { tests := []struct { desc string gaeKey string wantEncoded string wantName string }{ { desc: "A GAE key with a Name ID.", // Generated by: https://play.golang.org/p/00fNVEKSmBX gaeKey: "agdmb28tYXBwchwLEgh0ZXN0S2luZCIOZm9vYmFyc3RyaW5naWQM", wantEncoded: "EhoKCHRlc3RLaW5kGg5mb29iYXJzdHJpbmdpZA", wantName: "foobarstringid", }, { desc: "Another GAE key with a Name ID", gaeKey: "ag1wfnBlbmRvLWV4YW1wcjkLEg90ZXN0U3RyaW5nS2V5czIiJDdlNDA2YTNkLTUyNTItMTFlOS05MTMyLTdmNjUyMzg3YThlYgw", wantEncoded: "EjcKD3Rlc3RTdHJpbmdLZXlzMhokN2U0MDZhM2QtNTI1Mi0xMWU5LTkxMzItN2Y2NTIzODdhOGVi", wantName: "7e406a3d-5252-11e9-9132-7f652387a8eb", }, } for _, tc := range tests { k, err := DecodeKey(tc.gaeKey) if err != nil { t.Fatalf("DecodeKey(%s): %v", tc.desc, err) } if k.Name != tc.wantName { t.Errorf("Name(%s): got %+v, want %+v", tc.desc, k.Name, tc.wantName) } if enc := k.Encode(); enc != tc.wantEncoded { t.Errorf("Encode(%s): got %+v, want %+v", tc.desc, enc, tc.wantEncoded) } } } google-cloud-go-0.49.0/datastore/load.go000066400000000000000000000352271356504100700200350ustar00rootroot00000000000000// Copyright 2014 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package datastore import ( "fmt" "reflect" "strings" "time" "cloud.google.com/go/internal/fields" pb "google.golang.org/genproto/googleapis/datastore/v1" ) var ( typeOfByteSlice = reflect.TypeOf([]byte(nil)) typeOfTime = reflect.TypeOf(time.Time{}) typeOfGeoPoint = reflect.TypeOf(GeoPoint{}) typeOfKeyPtr = reflect.TypeOf(&Key{}) ) // typeMismatchReason returns a string explaining why the property p could not // be stored in an entity field of type v.Type(). func typeMismatchReason(p Property, v reflect.Value) string { entityType := "empty" switch p.Value.(type) { case int64: entityType = "int" case bool: entityType = "bool" case string: entityType = "string" case float64: entityType = "float" case *Key: entityType = "*datastore.Key" case *Entity: entityType = "*datastore.Entity" case GeoPoint: entityType = "GeoPoint" case time.Time: entityType = "time.Time" case []byte: entityType = "[]byte" } return fmt.Sprintf("type mismatch: %s versus %v", entityType, v.Type()) } func overflowReason(x interface{}, v reflect.Value) string { return fmt.Sprintf("value %v overflows struct field of type %v", x, v.Type()) } type propertyLoader struct { // m holds the number of times a substruct field like "Foo.Bar.Baz" has // been seen so far. The map is constructed lazily. m map[string]int } func (l *propertyLoader) load(codec fields.List, structValue reflect.Value, p Property, prev map[string]struct{}) string { sl, ok := p.Value.([]interface{}) if !ok { return l.loadOneElement(codec, structValue, p, prev) } for _, val := range sl { p.Value = val if errStr := l.loadOneElement(codec, structValue, p, prev); errStr != "" { return errStr } } return "" } // loadOneElement loads the value of Property p into structValue based on the provided // codec. codec is used to find the field in structValue into which p should be loaded. // prev is the set of property names already seen for structValue. func (l *propertyLoader) loadOneElement(codec fields.List, structValue reflect.Value, p Property, prev map[string]struct{}) string { var sliceOk bool var sliceIndex int var v reflect.Value name := p.Name fieldNames := strings.Split(name, ".") for len(fieldNames) > 0 { var field *fields.Field // Start by trying to find a field with name. If none found, // cut off the last field (delimited by ".") and find its parent // in the codec. // eg. for name "A.B.C.D", split off "A.B.C" and try to // find a field in the codec with this name. // Loop again with "A.B", etc. for i := len(fieldNames); i > 0; i-- { parent := strings.Join(fieldNames[:i], ".") field = codec.Match(parent) if field != nil { fieldNames = fieldNames[i:] break } } // If we never found a matching field in the codec, return // error message. if field == nil { return "no such struct field" } v = initField(structValue, field.Index) if !v.IsValid() { return "no such struct field" } if !v.CanSet() { return "cannot set struct field" } // If field implements PLS, we delegate loading to the PLS's Load early, // and stop iterating through fields. ok, err := plsFieldLoad(v, p, fieldNames) if err != nil { return err.Error() } if ok { return "" } if field.Type.Kind() == reflect.Ptr && field.Type.Elem().Kind() == reflect.Struct { codec, err = structCache.Fields(field.Type.Elem()) if err != nil { return err.Error() } // Init value if its nil if v.IsNil() { v.Set(reflect.New(field.Type.Elem())) } structValue = v.Elem() } if field.Type.Kind() == reflect.Struct { codec, err = structCache.Fields(field.Type) if err != nil { return err.Error() } structValue = v } // If the element is a slice, we need to accommodate it. if v.Kind() == reflect.Slice && v.Type() != typeOfByteSlice { if l.m == nil { l.m = make(map[string]int) } sliceIndex = l.m[p.Name] l.m[p.Name] = sliceIndex + 1 for v.Len() <= sliceIndex { v.Set(reflect.Append(v, reflect.New(v.Type().Elem()).Elem())) } structValue = v.Index(sliceIndex) // If structValue implements PLS, we delegate loading to the PLS's // Load early, and stop iterating through fields. ok, err := plsFieldLoad(structValue, p, fieldNames) if err != nil { return err.Error() } if ok { return "" } if structValue.Type().Kind() == reflect.Struct { codec, err = structCache.Fields(structValue.Type()) if err != nil { return err.Error() } } sliceOk = true } } var slice reflect.Value if v.Kind() == reflect.Slice && v.Type().Elem().Kind() != reflect.Uint8 { slice = v v = reflect.New(v.Type().Elem()).Elem() } else if _, ok := prev[p.Name]; ok && !sliceOk { // Zero the field back out that was set previously, turns out // it's a slice and we don't know what to do with it v.Set(reflect.Zero(v.Type())) return "multiple-valued property requires a slice field type" } prev[p.Name] = struct{}{} if errReason := setVal(v, p); errReason != "" { // Set the slice back to its zero value. if slice.IsValid() { slice.Set(reflect.Zero(slice.Type())) } return errReason } if slice.IsValid() { slice.Index(sliceIndex).Set(v) } return "" } // plsFieldLoad first tries to converts v's value to a PLS, then v's addressed // value to a PLS. If neither succeeds, plsFieldLoad returns false for first return // value. Otherwise, the first return value will be true. // If v is successfully converted to a PLS, plsFieldLoad will then try to Load // the property p into v (by way of the PLS's Load method). // // If the field v has been flattened, the Property's name must be altered // before calling Load to reflect the field v. // For example, if our original field name was "A.B.C.D", // and at this point in iteration we had initialized the field // corresponding to "A" and have moved into the struct, so that now // v corresponds to the field named "B", then we want to let the // PLS handle this field (B)'s subfields ("C", "D"), // so we send the property to the PLS's Load, renamed to "C.D". // // If subfields are present, the field v has been flattened. func plsFieldLoad(v reflect.Value, p Property, subfields []string) (ok bool, err error) { vpls, err := plsForLoad(v) if err != nil { return false, err } if vpls == nil { return false, nil } // If Entity, load properties as well as key. if e, ok := p.Value.(*Entity); ok { err = loadEntity(vpls, e) return true, err } // If flattened, we must alter the property's name to reflect // the field v. if len(subfields) > 0 { p.Name = strings.Join(subfields, ".") } return true, vpls.Load([]Property{p}) } // setVal sets 'v' to the value of the Property 'p'. func setVal(v reflect.Value, p Property) (s string) { pValue := p.Value switch v.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: x, ok := pValue.(int64) if !ok && pValue != nil { return typeMismatchReason(p, v) } if v.OverflowInt(x) { return overflowReason(x, v) } v.SetInt(x) case reflect.Bool: x, ok := pValue.(bool) if !ok && pValue != nil { return typeMismatchReason(p, v) } v.SetBool(x) case reflect.String: x, ok := pValue.(string) if !ok && pValue != nil { return typeMismatchReason(p, v) } v.SetString(x) case reflect.Float32, reflect.Float64: x, ok := pValue.(float64) if !ok && pValue != nil { return typeMismatchReason(p, v) } if v.OverflowFloat(x) { return overflowReason(x, v) } v.SetFloat(x) case reflect.Interface: if !v.CanSet() { return fmt.Sprintf("%v is unsettable", v.Type()) } rpValue := reflect.ValueOf(pValue) if !rpValue.Type().AssignableTo(v.Type()) { return fmt.Sprintf("%q is not assignable to %q", rpValue.Type(), v.Type()) } v.Set(rpValue) case reflect.Ptr: // v must be a pointer to either a Key, an Entity, or one of the supported basic types. if v.Type() != typeOfKeyPtr && v.Type().Elem().Kind() != reflect.Struct && !isValidPointerType(v.Type().Elem()) { return typeMismatchReason(p, v) } if pValue == nil { // If v is populated already, set it to nil. if !v.IsNil() { v.Set(reflect.New(v.Type()).Elem()) } return "" } if x, ok := p.Value.(*Key); ok { if _, ok := v.Interface().(*Key); !ok { return typeMismatchReason(p, v) } v.Set(reflect.ValueOf(x)) return "" } if v.IsNil() { v.Set(reflect.New(v.Type().Elem())) } switch x := pValue.(type) { case *Entity: err := loadEntity(v.Interface(), x) if err != nil { return err.Error() } case int64: if v.Elem().OverflowInt(x) { return overflowReason(x, v.Elem()) } v.Elem().SetInt(x) case float64: if v.Elem().OverflowFloat(x) { return overflowReason(x, v.Elem()) } v.Elem().SetFloat(x) case bool: v.Elem().SetBool(x) case string: v.Elem().SetString(x) case GeoPoint, time.Time: v.Elem().Set(reflect.ValueOf(x)) default: return typeMismatchReason(p, v) } case reflect.Struct: switch v.Type() { case typeOfTime: // Some time values are converted into microsecond integer values // (for example when used with projects). So, here we check first // whether this value is an int64, and next whether it's time. // // See more at https://cloud.google.com/datastore/docs/concepts/queries#limitations_on_projections micros, ok := pValue.(int64) if ok { s := micros / 1e6 ns := micros % 1e6 v.Set(reflect.ValueOf(time.Unix(s, ns))) break } x, ok := pValue.(time.Time) if !ok && pValue != nil { return typeMismatchReason(p, v) } v.Set(reflect.ValueOf(x)) case typeOfGeoPoint: x, ok := pValue.(GeoPoint) if !ok && pValue != nil { return typeMismatchReason(p, v) } v.Set(reflect.ValueOf(x)) default: ent, ok := pValue.(*Entity) if !ok { return typeMismatchReason(p, v) } err := loadEntity(v.Addr().Interface(), ent) if err != nil { return err.Error() } } case reflect.Slice: x, ok := pValue.([]byte) if !ok && pValue != nil { return typeMismatchReason(p, v) } if v.Type().Elem().Kind() != reflect.Uint8 { return typeMismatchReason(p, v) } v.SetBytes(x) default: return typeMismatchReason(p, v) } return "" } // initField is similar to reflect's Value.FieldByIndex, in that it // returns the nested struct field corresponding to index, but it // initialises any nil pointers encountered when traversing the structure. func initField(val reflect.Value, index []int) reflect.Value { for _, i := range index[:len(index)-1] { val = val.Field(i) if val.Kind() == reflect.Ptr { if val.IsNil() { val.Set(reflect.New(val.Type().Elem())) } val = val.Elem() } } return val.Field(index[len(index)-1]) } // loadEntityProto loads an EntityProto into PropertyLoadSaver or struct pointer. func loadEntityProto(dst interface{}, src *pb.Entity) error { ent, err := protoToEntity(src) if err != nil { return err } return loadEntity(dst, ent) } func loadEntity(dst interface{}, ent *Entity) error { if pls, ok := dst.(PropertyLoadSaver); ok { // Load both key and properties. Try to load as much as possible, even // if an error occurs during loading loading either the key or the // properties. var keyLoadErr error if e, ok := dst.(KeyLoader); ok { keyLoadErr = e.LoadKey(ent.Key) } loadErr := pls.Load(ent.Properties) // Let any error returned by LoadKey prevail above any error from Load. if keyLoadErr != nil { return keyLoadErr } return loadErr } return loadEntityToStruct(dst, ent) } func loadEntityToStruct(dst interface{}, ent *Entity) error { pls, err := newStructPLS(dst) if err != nil { return err } // Try and load key. keyField := pls.codec.Match(keyFieldName) if keyField != nil && ent.Key != nil { pls.v.FieldByIndex(keyField.Index).Set(reflect.ValueOf(ent.Key)) } // Load properties. return pls.Load(ent.Properties) } func (s structPLS) Load(props []Property) error { var fieldName, errReason string var l propertyLoader prev := make(map[string]struct{}) for _, p := range props { if errStr := l.load(s.codec, s.v, p, prev); errStr != "" { // We don't return early, as we try to load as many properties as possible. // It is valid to load an entity into a struct that cannot fully represent it. // That case returns an error, but the caller is free to ignore it. fieldName, errReason = p.Name, errStr } } if errReason != "" { return &ErrFieldMismatch{ StructType: s.v.Type(), FieldName: fieldName, Reason: errReason, } } return nil } func protoToEntity(src *pb.Entity) (*Entity, error) { props := make([]Property, 0, len(src.Properties)) for name, val := range src.Properties { v, err := propToValue(val) if err != nil { return nil, err } props = append(props, Property{ Name: name, Value: v, NoIndex: val.ExcludeFromIndexes, }) } var key *Key if src.Key != nil { // Ignore any error, since nested entity values // are allowed to have an invalid key. key, _ = protoToKey(src.Key) } return &Entity{key, props}, nil } // propToValue returns a Go value that represents the PropertyValue. For // example, a TimestampValue becomes a time.Time. func propToValue(v *pb.Value) (interface{}, error) { switch v := v.ValueType.(type) { case *pb.Value_NullValue: return nil, nil case *pb.Value_BooleanValue: return v.BooleanValue, nil case *pb.Value_IntegerValue: return v.IntegerValue, nil case *pb.Value_DoubleValue: return v.DoubleValue, nil case *pb.Value_TimestampValue: return time.Unix(v.TimestampValue.Seconds, int64(v.TimestampValue.Nanos)), nil case *pb.Value_KeyValue: return protoToKey(v.KeyValue) case *pb.Value_StringValue: return v.StringValue, nil case *pb.Value_BlobValue: return []byte(v.BlobValue), nil case *pb.Value_GeoPointValue: return GeoPoint{Lat: v.GeoPointValue.Latitude, Lng: v.GeoPointValue.Longitude}, nil case *pb.Value_EntityValue: return protoToEntity(v.EntityValue) case *pb.Value_ArrayValue: arr := make([]interface{}, 0, len(v.ArrayValue.Values)) for _, v := range v.ArrayValue.Values { vv, err := propToValue(v) if err != nil { return nil, err } arr = append(arr, vv) } return arr, nil default: return nil, nil } } google-cloud-go-0.49.0/datastore/load_test.go000066400000000000000000000616631356504100700210770ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package datastore import ( "fmt" "reflect" "testing" "time" "cloud.google.com/go/internal/testutil" pb "google.golang.org/genproto/googleapis/datastore/v1" ) type Simple struct { I int64 } type SimpleWithTag struct { I int64 `datastore:"II"` } type NestedSimpleWithTag struct { A SimpleWithTag `datastore:"AA"` } type NestedSliceOfSimple struct { A []Simple } type SimpleTwoFields struct { S string SS string } type NestedSimpleAnonymous struct { Simple X string } type NestedSimple struct { A Simple I int } type NestedSimple1 struct { A Simple X string } type NestedSimple2X struct { AA NestedSimple A SimpleTwoFields S string } type BDotB struct { B string `datastore:"B.B"` } type ABDotB struct { A BDotB } type MultiAnonymous struct { Simple SimpleTwoFields X string } func TestLoadEntityNestedLegacy(t *testing.T) { testCases := []struct { desc string src *pb.Entity want interface{} }{ { desc: "nested", src: &pb.Entity{ Key: keyToProto(testKey0), Properties: map[string]*pb.Value{ "X": {ValueType: &pb.Value_StringValue{StringValue: "two"}}, "A.I": {ValueType: &pb.Value_IntegerValue{IntegerValue: 2}}, }, }, want: &NestedSimple1{ A: Simple{I: 2}, X: "two", }, }, { desc: "nested with tag", src: &pb.Entity{ Key: keyToProto(testKey0), Properties: map[string]*pb.Value{ "AA.II": {ValueType: &pb.Value_IntegerValue{IntegerValue: 2}}, }, }, want: &NestedSimpleWithTag{ A: SimpleWithTag{I: 2}, }, }, { desc: "nested with anonymous struct field", src: &pb.Entity{ Key: keyToProto(testKey0), Properties: map[string]*pb.Value{ "X": {ValueType: &pb.Value_StringValue{StringValue: "two"}}, "I": {ValueType: &pb.Value_IntegerValue{IntegerValue: 2}}, }, }, want: &NestedSimpleAnonymous{ Simple: Simple{I: 2}, X: "two", }, }, { desc: "nested with dotted field tag", src: &pb.Entity{ Key: keyToProto(testKey0), Properties: map[string]*pb.Value{ "A.B.B": {ValueType: &pb.Value_StringValue{StringValue: "bb"}}, }, }, want: &ABDotB{ A: BDotB{ B: "bb", }, }, }, { desc: "nested with multiple anonymous fields", src: &pb.Entity{ Key: keyToProto(testKey0), Properties: map[string]*pb.Value{ "I": {ValueType: &pb.Value_IntegerValue{IntegerValue: 3}}, "S": {ValueType: &pb.Value_StringValue{StringValue: "S"}}, "SS": {ValueType: &pb.Value_StringValue{StringValue: "s"}}, "X": {ValueType: &pb.Value_StringValue{StringValue: "s"}}, }, }, want: &MultiAnonymous{ Simple: Simple{I: 3}, SimpleTwoFields: SimpleTwoFields{S: "S", SS: "s"}, X: "s", }, }, } for _, tc := range testCases { dst := reflect.New(reflect.TypeOf(tc.want).Elem()).Interface() err := loadEntityProto(dst, tc.src) if err != nil { t.Errorf("loadEntityProto: %s: %v", tc.desc, err) continue } if !testutil.Equal(tc.want, dst) { t.Errorf("%s: compare:\ngot: %#v\nwant: %#v", tc.desc, dst, tc.want) } } } type WithKey struct { X string I int K *Key `datastore:"__key__"` } type NestedWithKey struct { Y string N WithKey } var ( incompleteKey = newKey("", nil) invalidKey = newKey("s", incompleteKey) ) func TestLoadEntityNested(t *testing.T) { testCases := []struct { desc string src *pb.Entity want interface{} }{ { desc: "nested basic", src: &pb.Entity{ Properties: map[string]*pb.Value{ "A": {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Properties: map[string]*pb.Value{ "I": {ValueType: &pb.Value_IntegerValue{IntegerValue: 3}}, }, }, }}, "I": {ValueType: &pb.Value_IntegerValue{IntegerValue: 10}}, }, }, want: &NestedSimple{ A: Simple{I: 3}, I: 10, }, }, { desc: "nested with struct tags", src: &pb.Entity{ Properties: map[string]*pb.Value{ "AA": {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Properties: map[string]*pb.Value{ "II": {ValueType: &pb.Value_IntegerValue{IntegerValue: 1}}, }, }, }}, }, }, want: &NestedSimpleWithTag{ A: SimpleWithTag{I: 1}, }, }, { desc: "nested 2x", src: &pb.Entity{ Properties: map[string]*pb.Value{ "AA": {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Properties: map[string]*pb.Value{ "A": {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Properties: map[string]*pb.Value{ "I": {ValueType: &pb.Value_IntegerValue{IntegerValue: 3}}, }, }, }}, "I": {ValueType: &pb.Value_IntegerValue{IntegerValue: 1}}, }, }, }}, "A": {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Properties: map[string]*pb.Value{ "S": {ValueType: &pb.Value_StringValue{StringValue: "S"}}, "SS": {ValueType: &pb.Value_StringValue{StringValue: "s"}}, }, }, }}, "S": {ValueType: &pb.Value_StringValue{StringValue: "SS"}}, }, }, want: &NestedSimple2X{ AA: NestedSimple{ A: Simple{I: 3}, I: 1, }, A: SimpleTwoFields{S: "S", SS: "s"}, S: "SS", }, }, { desc: "nested anonymous", src: &pb.Entity{ Properties: map[string]*pb.Value{ "I": {ValueType: &pb.Value_IntegerValue{IntegerValue: 3}}, "X": {ValueType: &pb.Value_StringValue{StringValue: "SomeX"}}, }, }, want: &NestedSimpleAnonymous{ Simple: Simple{I: 3}, X: "SomeX", }, }, { desc: "nested simple with slice", src: &pb.Entity{ Properties: map[string]*pb.Value{ "A": {ValueType: &pb.Value_ArrayValue{ ArrayValue: &pb.ArrayValue{ Values: []*pb.Value{ {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Properties: map[string]*pb.Value{ "I": {ValueType: &pb.Value_IntegerValue{IntegerValue: 3}}, }, }, }}, {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Properties: map[string]*pb.Value{ "I": {ValueType: &pb.Value_IntegerValue{IntegerValue: 4}}, }, }, }}, }, }, }}, }, }, want: &NestedSliceOfSimple{ A: []Simple{{I: 3}, {I: 4}}, }, }, { desc: "nested with multiple anonymous fields", src: &pb.Entity{ Properties: map[string]*pb.Value{ "I": {ValueType: &pb.Value_IntegerValue{IntegerValue: 3}}, "S": {ValueType: &pb.Value_StringValue{StringValue: "S"}}, "SS": {ValueType: &pb.Value_StringValue{StringValue: "s"}}, "X": {ValueType: &pb.Value_StringValue{StringValue: "ss"}}, }, }, want: &MultiAnonymous{ Simple: Simple{I: 3}, SimpleTwoFields: SimpleTwoFields{S: "S", SS: "s"}, X: "ss", }, }, { desc: "nested with dotted field tag", src: &pb.Entity{ Properties: map[string]*pb.Value{ "A": {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Properties: map[string]*pb.Value{ "B.B": {ValueType: &pb.Value_StringValue{StringValue: "bb"}}, }, }, }}, }, }, want: &ABDotB{ A: BDotB{ B: "bb", }, }, }, { desc: "nested entity with key", src: &pb.Entity{ Key: keyToProto(testKey0), Properties: map[string]*pb.Value{ "Y": {ValueType: &pb.Value_StringValue{StringValue: "yyy"}}, "N": {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Key: keyToProto(testKey1a), Properties: map[string]*pb.Value{ "X": {ValueType: &pb.Value_StringValue{StringValue: "two"}}, "I": {ValueType: &pb.Value_IntegerValue{IntegerValue: 2}}, }, }, }}, }, }, want: &NestedWithKey{ Y: "yyy", N: WithKey{ X: "two", I: 2, K: testKey1a, }, }, }, { desc: "nested entity with invalid key", src: &pb.Entity{ Key: keyToProto(testKey0), Properties: map[string]*pb.Value{ "Y": {ValueType: &pb.Value_StringValue{StringValue: "yyy"}}, "N": {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Key: keyToProto(invalidKey), Properties: map[string]*pb.Value{ "X": {ValueType: &pb.Value_StringValue{StringValue: "two"}}, "I": {ValueType: &pb.Value_IntegerValue{IntegerValue: 2}}, }, }, }}, }, }, want: &NestedWithKey{ Y: "yyy", N: WithKey{ X: "two", I: 2, K: invalidKey, }, }, }, } for _, tc := range testCases { dst := reflect.New(reflect.TypeOf(tc.want).Elem()).Interface() err := loadEntityProto(dst, tc.src) if err != nil { t.Errorf("loadEntityProto: %s: %v", tc.desc, err) continue } if !testutil.Equal(tc.want, dst) { t.Errorf("%s: compare:\ngot: %#v\nwant: %#v", tc.desc, dst, tc.want) } } } type NestedStructPtrs struct { *SimpleTwoFields Nest *SimpleTwoFields TwiceNest *NestedSimple2 I int } type NestedSimple2 struct { A *Simple I int U interface{} } type withTypedInterface struct { Field fmt.Stringer } type withUntypedInterface struct { Field interface{} } func TestLoadToInterface(t *testing.T) { testCases := []struct { name string src *pb.Entity dst interface{} want interface{} wantErr string }{ { name: "Typed interface", src: &pb.Entity{ Key: keyToProto(testKey0), Properties: map[string]*pb.Value{ "Field": {ValueType: &pb.Value_StringValue{ StringValue: "Foo", }}, }, }, dst: &withTypedInterface{}, wantErr: `datastore: cannot load field "Field" into a "datastore.withTypedInterface": "string" is not assignable to "fmt.Stringer"`, }, { name: "Untyped interface, fresh struct", src: &pb.Entity{ Key: keyToProto(testKey0), Properties: map[string]*pb.Value{ "Field": {ValueType: &pb.Value_StringValue{ StringValue: "Foo", }}, }, }, dst: &withUntypedInterface{}, want: &withUntypedInterface{Field: "Foo"}, }, { name: "Untyped interface, already set", src: &pb.Entity{ Key: keyToProto(testKey0), Properties: map[string]*pb.Value{ "Field": {ValueType: &pb.Value_StringValue{ StringValue: "Newly set", }}, }, }, dst: &withUntypedInterface{Field: 1e9}, want: &withUntypedInterface{Field: "Newly set"}, }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { err := loadEntityProto(tc.dst, tc.src) if tc.wantErr != "" { if err == nil || err.Error() != tc.wantErr { t.Fatalf("Error mismatch\nGot: %s\nWant: %s", err, tc.wantErr) } } else { if err != nil { t.Fatalf("loadEntityProto: %v", err) } if diff := testutil.Diff(tc.dst, tc.want); diff != "" { t.Fatalf("Mismatch: got - want +\n%s", diff) } } }) } } func TestAlreadyPopulatedDst(t *testing.T) { testCases := []struct { desc string src *pb.Entity dst interface{} want interface{} }{ { desc: "simple already populated, nil properties", src: &pb.Entity{ Key: keyToProto(testKey0), Properties: map[string]*pb.Value{ "I": {ValueType: &pb.Value_NullValue{}}, }, }, dst: &Simple{ I: 12, }, want: &Simple{}, }, { desc: "nested structs already populated", src: &pb.Entity{ Key: keyToProto(testKey0), Properties: map[string]*pb.Value{ "SS": {ValueType: &pb.Value_StringValue{StringValue: "world"}}, }, }, dst: &SimpleTwoFields{S: "hello" /* SS: "" */}, want: &SimpleTwoFields{S: "hello", SS: "world"}, }, { desc: "nested structs already populated, pValues nil", src: &pb.Entity{ Key: keyToProto(testKey0), Properties: map[string]*pb.Value{ "S": {ValueType: &pb.Value_NullValue{}}, "SS": {ValueType: &pb.Value_StringValue{StringValue: "ss hello"}}, "Nest": {ValueType: &pb.Value_NullValue{}}, "TwiceNest": {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Properties: map[string]*pb.Value{ "A": {ValueType: &pb.Value_NullValue{}}, "I": {ValueType: &pb.Value_IntegerValue{IntegerValue: 2}}, "U": {ValueType: &pb.Value_StringValue{StringValue: "replaced"}}, }, }, }}, "I": {ValueType: &pb.Value_IntegerValue{IntegerValue: 5}}, }, }, dst: &NestedStructPtrs{ &SimpleTwoFields{S: "hello" /* SS: "" */}, &SimpleTwoFields{ /* S: "" */ SS: "twice hello"}, &NestedSimple2{ A: &Simple{I: 2}, /* I: 0 */ U: 1e9, }, 0, }, want: &NestedStructPtrs{ &SimpleTwoFields{ /* S: "" */ SS: "ss hello"}, nil, &NestedSimple2{ /* A: nil, */ I: 2, U: "replaced", }, 5, }, }, } for _, tc := range testCases { err := loadEntityProto(tc.dst, tc.src) if err != nil { t.Errorf("loadEntityProto: %s: %v", tc.desc, err) continue } if !testutil.Equal(tc.want, tc.dst) { t.Errorf("%s: compare:\ngot: %#v\nwant: %#v", tc.desc, tc.dst, tc.want) } } } type PLS0 struct { A string } func (p *PLS0) Load(props []Property) error { for _, pp := range props { if pp.Name == "A" { p.A = pp.Value.(string) } } return nil } func (p *PLS0) Save() (props []Property, err error) { return []Property{{Name: "A", Value: p.A}}, nil } type KeyLoader1 struct { A string K *Key } func (kl *KeyLoader1) Load(props []Property) error { for _, pp := range props { if pp.Name == "A" { kl.A = pp.Value.(string) } } return nil } func (kl *KeyLoader1) Save() (props []Property, err error) { return []Property{{Name: "A", Value: kl.A}}, nil } func (kl *KeyLoader1) LoadKey(k *Key) error { kl.K = k return nil } type KeyLoader2 struct { B int Key *Key } func (kl *KeyLoader2) Load(props []Property) error { for _, pp := range props { if pp.Name == "B" { kl.B = int(pp.Value.(int64)) } } return nil } func (kl *KeyLoader2) Save() (props []Property, err error) { return []Property{{Name: "B", Value: int64(kl.B)}}, nil } func (kl *KeyLoader2) LoadKey(k *Key) error { kl.Key = k return nil } type KeyLoader3 struct { C bool K *Key } func (kl *KeyLoader3) Load(props []Property) error { for _, pp := range props { if pp.Name == "C" { kl.C = pp.Value.(bool) } } return nil } func (kl *KeyLoader3) Save() (props []Property, err error) { return []Property{{Name: "C", Value: kl.C}}, nil } func (kl *KeyLoader3) LoadKey(k *Key) error { kl.K = k return nil } type KeyLoader4 struct { PLS0 K *Key } func (kl *KeyLoader4) LoadKey(k *Key) error { kl.K = k return nil } type PLS1 struct { A string } func (p *PLS1) Load(props []Property) error { for _, pp := range props { if pp.Name == "A" { p.A = pp.Value.(string) } } return nil } func (p *PLS1) Save() (props []Property, err error) { return []Property{{Name: "A", Value: p.A}}, nil } type KeyLoader6 struct { A string B string K *Key } func (kl *KeyLoader6) Load(props []Property) error { for _, pp := range props { if pp.Name == "A" { kl.A = pp.Value.(string) } } return &ErrFieldMismatch{ StructType: reflect.TypeOf(kl), FieldName: "B", Reason: "no value found", } } func (kl *KeyLoader6) LoadKey(k *Key) error { kl.K = k return nil } func (kl *KeyLoader6) Save() (props []Property, err error) { return []Property{{}}, nil } type KeyLoader7 struct { A string K *Key } func (kl *KeyLoader7) Load(props []Property) error { for _, pp := range props { if pp.Name == "A" { kl.A = pp.Value.(string) } } return nil } func (kl *KeyLoader7) LoadKey(k *Key) error { return &ErrFieldMismatch{ StructType: reflect.TypeOf(kl), FieldName: "key", Reason: "no value found", } } func (kl *KeyLoader7) Save() (props []Property, err error) { return []Property{{}}, nil } type KeyLoader8 struct { A string B string K *Key } type customLoadError struct{} func (e *customLoadError) Error() string { return "custom load error" } func (kl *KeyLoader8) Load(props []Property) error { for _, pp := range props { if pp.Name == "A" { kl.A = pp.Value.(string) } } return &customLoadError{} } func (kl *KeyLoader8) LoadKey(k *Key) error { return &ErrFieldMismatch{ StructType: reflect.TypeOf(kl), FieldName: "key", Reason: "no value found", } } func (kl *KeyLoader8) Save() (props []Property, err error) { return []Property{{}}, nil } type NotKeyLoader struct { A string K *Key } func (p *NotKeyLoader) Load(props []Property) error { for _, pp := range props { if pp.Name == "A" { p.A = pp.Value.(string) } } return nil } func (p *NotKeyLoader) Save() (props []Property, err error) { return []Property{{Name: "A", Value: p.A}}, nil } type NotPLSKeyLoader struct { A string K *Key `datastore:"__key__"` } type NestedKeyLoaders struct { Two *KeyLoader2 Three []*KeyLoader3 Four *KeyLoader4 PLS *NotKeyLoader } func TestKeyLoader(t *testing.T) { testCases := []struct { desc string src *pb.Entity dst interface{} want interface{} }{ { desc: "simple key loader", src: &pb.Entity{ Key: keyToProto(testKey0), Properties: map[string]*pb.Value{ "A": {ValueType: &pb.Value_StringValue{StringValue: "hello"}}, }, }, dst: &KeyLoader1{}, want: &KeyLoader1{ A: "hello", K: testKey0, }, }, { desc: "simple key loader with unmatched properties", src: &pb.Entity{ Key: keyToProto(testKey0), Properties: map[string]*pb.Value{ "A": {ValueType: &pb.Value_StringValue{StringValue: "hello"}}, "B": {ValueType: &pb.Value_StringValue{StringValue: "unmatched"}}, }, }, dst: &NotPLSKeyLoader{}, want: &NotPLSKeyLoader{ A: "hello", K: testKey0, }, }, { desc: "embedded PLS key loader", src: &pb.Entity{ Key: keyToProto(testKey0), Properties: map[string]*pb.Value{ "A": {ValueType: &pb.Value_StringValue{StringValue: "hello"}}, }, }, dst: &KeyLoader4{}, want: &KeyLoader4{ PLS0: PLS0{A: "hello"}, K: testKey0, }, }, { desc: "nested key loaders", src: &pb.Entity{ Key: keyToProto(testKey0), Properties: map[string]*pb.Value{ "Two": {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Properties: map[string]*pb.Value{ "B": {ValueType: &pb.Value_IntegerValue{IntegerValue: 12}}, }, Key: keyToProto(testKey1a), }, }}, "Three": {ValueType: &pb.Value_ArrayValue{ ArrayValue: &pb.ArrayValue{ Values: []*pb.Value{ {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Properties: map[string]*pb.Value{ "C": {ValueType: &pb.Value_BooleanValue{BooleanValue: true}}, }, Key: keyToProto(testKey1b), }, }}, {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Properties: map[string]*pb.Value{ "C": {ValueType: &pb.Value_BooleanValue{BooleanValue: false}}, }, Key: keyToProto(testKey0), }, }}, }, }, }}, "Four": {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Properties: map[string]*pb.Value{ "A": {ValueType: &pb.Value_StringValue{StringValue: "testing"}}, }, Key: keyToProto(testKey2a), }, }}, "PLS": {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Properties: map[string]*pb.Value{ "A": {ValueType: &pb.Value_StringValue{StringValue: "something"}}, }, Key: keyToProto(testKey1a), }, }}, }, }, dst: &NestedKeyLoaders{}, want: &NestedKeyLoaders{ Two: &KeyLoader2{B: 12, Key: testKey1a}, Three: []*KeyLoader3{ { C: true, K: testKey1b, }, { C: false, K: testKey0, }, }, Four: &KeyLoader4{ PLS0: PLS0{A: "testing"}, K: testKey2a, }, PLS: &NotKeyLoader{A: "something"}, }, }, { desc: "simple key loader with ErrFieldMismatch error", src: &pb.Entity{ Key: keyToProto(testKey0), Properties: map[string]*pb.Value{ "A": {ValueType: &pb.Value_StringValue{StringValue: "hello"}}, }, }, dst: &KeyLoader6{}, want: &KeyLoader6{ A: "hello", B: "", K: testKey0, }, }, { desc: "simple key loader with ErrFieldMismatch during key load", src: &pb.Entity{ Key: keyToProto(testKey0), Properties: map[string]*pb.Value{ "A": {ValueType: &pb.Value_StringValue{StringValue: "hello"}}, }, }, dst: &KeyLoader7{}, want: &KeyLoader7{ A: "hello", K: nil, }, }, { desc: "simple key loader with other error during Load and ErrFieldMismatch during KeyLoad", src: &pb.Entity{ Key: keyToProto(testKey0), Properties: map[string]*pb.Value{ "A": {ValueType: &pb.Value_StringValue{StringValue: "hello"}}, }, }, dst: &KeyLoader8{}, want: &KeyLoader8{ A: "hello", B: "", K: nil, }, }, } for _, tc := range testCases { err := loadEntityProto(tc.dst, tc.src) if err != nil { // While loadEntityProto may return an error, if that error is // ErrFieldMismatch, then there is still data in tc.dst to compare. if _, ok := err.(*ErrFieldMismatch); !ok { t.Errorf("loadEntityProto: %s: %v", tc.desc, err) continue } } if !testutil.Equal(tc.want, tc.dst) { t.Errorf("%s: compare:\ngot: %+v\nwant: %+v", tc.desc, tc.dst, tc.want) } } } func TestLoadPointers(t *testing.T) { for _, test := range []struct { desc string in []Property want Pointers }{ { desc: "nil properties load as nil pointers", in: []Property{ {Name: "Pi", Value: nil}, {Name: "Ps", Value: nil}, {Name: "Pb", Value: nil}, {Name: "Pf", Value: nil}, {Name: "Pg", Value: nil}, {Name: "Pt", Value: nil}, }, want: Pointers{}, }, { desc: "missing properties load as nil pointers", in: []Property(nil), want: Pointers{}, }, { desc: "non-nil properties load as the appropriate values", in: []Property{ {Name: "Pi", Value: int64(1)}, {Name: "Ps", Value: "x"}, {Name: "Pb", Value: true}, {Name: "Pf", Value: 3.14}, {Name: "Pg", Value: GeoPoint{Lat: 1, Lng: 2}}, {Name: "Pt", Value: time.Unix(100, 0)}, }, want: func() Pointers { p := populatedPointers() *p.Pi = 1 *p.Ps = "x" *p.Pb = true *p.Pf = 3.14 *p.Pg = GeoPoint{Lat: 1, Lng: 2} *p.Pt = time.Unix(100, 0) return *p }(), }, } { var got Pointers if err := LoadStruct(&got, test.in); err != nil { t.Fatalf("%s: %v", test.desc, err) } if !testutil.Equal(got, test.want) { t.Errorf("%s:\ngot %+v\nwant %+v", test.desc, got, test.want) } } } func TestLoadNonArrayIntoSlice(t *testing.T) { // Loading a non-array value into a slice field results in a slice of size 1. var got struct{ S []string } if err := LoadStruct(&got, []Property{{Name: "S", Value: "x"}}); err != nil { t.Fatal(err) } if want := []string{"x"}; !testutil.Equal(got.S, want) { t.Errorf("got %#v, want %#v", got.S, want) } } func TestLoadEmptyArrayIntoSlice(t *testing.T) { // Loading an empty array into a slice field is a no-op. var got = struct{ S []string }{[]string{"x"}} if err := LoadStruct(&got, []Property{{Name: "S", Value: []interface{}{}}}); err != nil { t.Fatal(err) } if want := []string{"x"}; !testutil.Equal(got.S, want) { t.Errorf("got %#v, want %#v", got.S, want) } } func TestLoadNull(t *testing.T) { // Loading a Datastore Null into a basic type (int, float, etc.) results in a zero value. // Loading a Null into a slice of basic type results in a slice of size 1 containing the zero value. // (As expected from the behavior of slices and nulls with basic types.) type S struct { I int64 F float64 S string B bool A []string } got := S{ I: 1, F: 1.0, S: "1", B: true, A: []string{"X"}, } want := S{A: []string{""}} props := []Property{{Name: "I"}, {Name: "F"}, {Name: "S"}, {Name: "B"}, {Name: "A"}} if err := LoadStruct(&got, props); err != nil { t.Fatal(err) } if !testutil.Equal(got, want) { t.Errorf("got %+v, want %+v", got, want) } // Loading a Null into a pointer to struct field results in a nil field. got2 := struct{ X *S }{X: &S{}} if err := LoadStruct(&got2, []Property{{Name: "X"}}); err != nil { t.Fatal(err) } if got2.X != nil { t.Errorf("got %v, want nil", got2.X) } // Loading a Null into a struct field is an error. got3 := struct{ X S }{} err := LoadStruct(&got3, []Property{{Name: "X"}}) if err == nil { t.Error("got nil, want error") } } // var got2 struct{ S []Pet } // if err := LoadStruct(&got2, []Property{{Name: "S", Value: nil}}); err != nil { // t.Fatal(err) // } // } google-cloud-go-0.49.0/datastore/mutation.go000066400000000000000000000066231356504100700207540ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package datastore import ( "fmt" pb "google.golang.org/genproto/googleapis/datastore/v1" ) // A Mutation represents a change to a Datastore entity. type Mutation struct { key *Key // needed for transaction PendingKeys and to dedup deletions mut *pb.Mutation err error } func (m *Mutation) isDelete() bool { _, ok := m.mut.Operation.(*pb.Mutation_Delete) return ok } // NewInsert creates a mutation that will save the entity src into the datastore with // key k, returning an error if k already exists. // See Client.Put for valid values of src. func NewInsert(k *Key, src interface{}) *Mutation { if !k.valid() { return &Mutation{err: ErrInvalidKey} } p, err := saveEntity(k, src) if err != nil { return &Mutation{err: err} } return &Mutation{ key: k, mut: &pb.Mutation{Operation: &pb.Mutation_Insert{Insert: p}}, } } // NewUpsert creates a mutation that saves the entity src into the datastore with key // k, whether or not k exists. See Client.Put for valid values of src. func NewUpsert(k *Key, src interface{}) *Mutation { if !k.valid() { return &Mutation{err: ErrInvalidKey} } p, err := saveEntity(k, src) if err != nil { return &Mutation{err: err} } return &Mutation{ key: k, mut: &pb.Mutation{Operation: &pb.Mutation_Upsert{Upsert: p}}, } } // NewUpdate creates a mutation that replaces the entity in the datastore with key k, // returning an error if k does not exist. See Client.Put for valid values of src. func NewUpdate(k *Key, src interface{}) *Mutation { if !k.valid() { return &Mutation{err: ErrInvalidKey} } if k.Incomplete() { return &Mutation{err: fmt.Errorf("datastore: can't update the incomplete key: %v", k)} } p, err := saveEntity(k, src) if err != nil { return &Mutation{err: err} } return &Mutation{ key: k, mut: &pb.Mutation{Operation: &pb.Mutation_Update{Update: p}}, } } // NewDelete creates a mutation that deletes the entity with key k. func NewDelete(k *Key) *Mutation { if !k.valid() { return &Mutation{err: ErrInvalidKey} } if k.Incomplete() { return &Mutation{err: fmt.Errorf("datastore: can't delete the incomplete key: %v", k)} } return &Mutation{ key: k, mut: &pb.Mutation{Operation: &pb.Mutation_Delete{Delete: keyToProto(k)}}, } } func mutationProtos(muts []*Mutation) ([]*pb.Mutation, error) { // If any of the mutations have errors, collect and return them. var merr MultiError for i, m := range muts { if m.err != nil { if merr == nil { merr = make(MultiError, len(muts)) } merr[i] = m.err } } if merr != nil { return nil, merr } var protos []*pb.Mutation // Collect protos. Remove duplicate deletions (see deleteMutations). seen := map[string]bool{} for _, m := range muts { if m.isDelete() { ks := m.key.String() if seen[ks] { continue } seen[ks] = true } protos = append(protos, m.mut) } return protos, nil } google-cloud-go-0.49.0/datastore/mutation_test.go000066400000000000000000000070431356504100700220100ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package datastore import ( "testing" "cloud.google.com/go/internal/testutil" pb "google.golang.org/genproto/googleapis/datastore/v1" ) func TestMutationProtos(t *testing.T) { var keys []*Key for i := 1; i <= 4; i++ { k := IDKey("kind", int64(i), nil) keys = append(keys, k) } entity := &PropertyList{{Name: "n", Value: "v"}} entityForKey := func(k *Key) *pb.Entity { return &pb.Entity{ Key: keyToProto(k), Properties: map[string]*pb.Value{ "n": {ValueType: &pb.Value_StringValue{StringValue: "v"}}, }, } } for _, test := range []struct { desc string in []*Mutation want []*pb.Mutation }{ { desc: "nil", in: nil, want: nil, }, { desc: "empty", in: []*Mutation{}, want: nil, }, { desc: "various", in: []*Mutation{ NewInsert(keys[0], entity), NewUpsert(keys[1], entity), NewUpdate(keys[2], entity), NewDelete(keys[3]), }, want: []*pb.Mutation{ {Operation: &pb.Mutation_Insert{Insert: entityForKey(keys[0])}}, {Operation: &pb.Mutation_Upsert{Upsert: entityForKey(keys[1])}}, {Operation: &pb.Mutation_Update{Update: entityForKey(keys[2])}}, {Operation: &pb.Mutation_Delete{Delete: keyToProto(keys[3])}}, }, }, { desc: "duplicate deletes", in: []*Mutation{ NewDelete(keys[0]), NewInsert(keys[1], entity), NewDelete(keys[0]), NewDelete(keys[2]), NewDelete(keys[0]), }, want: []*pb.Mutation{ {Operation: &pb.Mutation_Delete{Delete: keyToProto(keys[0])}}, {Operation: &pb.Mutation_Insert{Insert: entityForKey(keys[1])}}, {Operation: &pb.Mutation_Delete{Delete: keyToProto(keys[2])}}, }, }, } { got, err := mutationProtos(test.in) if err != nil { t.Errorf("%s: %v", test.desc, err) continue } if diff := testutil.Diff(got, test.want); diff != "" { t.Errorf("%s: %s", test.desc, diff) } } } func TestMutationProtosErrors(t *testing.T) { entity := &PropertyList{{Name: "n", Value: "v"}} k := IDKey("kind", 1, nil) ik := IncompleteKey("kind", nil) for _, test := range []struct { desc string in []*Mutation want []int // non-nil indexes of MultiError }{ { desc: "invalid key", in: []*Mutation{ NewInsert(nil, entity), NewUpdate(nil, entity), NewUpsert(nil, entity), NewDelete(nil), }, want: []int{0, 1, 2, 3}, }, { desc: "incomplete key", in: []*Mutation{ NewInsert(ik, entity), NewUpdate(ik, entity), NewUpsert(ik, entity), NewDelete(ik), }, want: []int{1, 3}, }, { desc: "bad entity", in: []*Mutation{ NewInsert(k, 1), NewUpdate(k, 2), NewUpsert(k, 3), }, want: []int{0, 1, 2}, }, } { _, err := mutationProtos(test.in) if err == nil { t.Errorf("%s: got nil, want error", test.desc) continue } var got []int for i, err := range err.(MultiError) { if err != nil { got = append(got, i) } } if !testutil.Equal(got, test.want) { t.Errorf("%s: got errors at %v, want at %v", test.desc, got, test.want) } } } google-cloud-go-0.49.0/datastore/oc_test.go000066400000000000000000000021441356504100700205460ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package datastore import ( "context" "testing" "cloud.google.com/go/internal/testutil" ) func TestOCTracing(t *testing.T) { ctx := context.Background() client := newTestClient(ctx, t) defer client.Close() te := testutil.NewTestExporter() defer te.Unregister() type SomeValue struct { S string } _, err := client.Put(ctx, IncompleteKey("SomeKey", nil), &SomeValue{"foo"}) if err != nil { t.Fatalf("client.Put: %v", err) } if len(te.Spans) == 0 { t.Fatalf("Expected some span to be created, but got %d", 0) } } google-cloud-go-0.49.0/datastore/prop.go000066400000000000000000000230151356504100700200660ustar00rootroot00000000000000// Copyright 2014 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package datastore import ( "fmt" "reflect" "strings" "unicode" "cloud.google.com/go/internal/fields" ) // Entities with more than this many indexed properties will not be saved. const maxIndexedProperties = 20000 // Property is a name/value pair plus some metadata. A datastore entity's // contents are loaded and saved as a sequence of Properties. Each property // name must be unique within an entity. type Property struct { // Name is the property name. Name string // Value is the property value. The valid types are: // - int64 // - bool // - string // - float64 // - *Key // - time.Time (retrieved as local time) // - GeoPoint // - []byte (up to 1 megabyte in length) // - *Entity (representing a nested struct) // Value can also be: // - []interface{} where each element is one of the above types // This set is smaller than the set of valid struct field types that the // datastore can load and save. A Value's type must be explicitly on // the list above; it is not sufficient for the underlying type to be // on that list. For example, a Value of "type myInt64 int64" is // invalid. Smaller-width integers and floats are also invalid. Again, // this is more restrictive than the set of valid struct field types. // // A Value will have an opaque type when loading entities from an index, // such as via a projection query. Load entities into a struct instead // of a PropertyLoadSaver when using a projection query. // // A Value may also be the nil interface value; this is equivalent to // Python's None but not directly representable by a Go struct. Loading // a nil-valued property into a struct will set that field to the zero // value. Value interface{} // NoIndex is whether the datastore cannot index this property. // If NoIndex is set to false, []byte and string values are limited to // 1500 bytes. NoIndex bool } // An Entity is the value type for a nested struct. // This type is only used for a Property's Value. type Entity struct { Key *Key Properties []Property } // PropertyLoadSaver can be converted from and to a slice of Properties. type PropertyLoadSaver interface { Load([]Property) error Save() ([]Property, error) } // KeyLoader can store a Key. type KeyLoader interface { // PropertyLoadSaver is embedded because a KeyLoader // must also always implement PropertyLoadSaver. PropertyLoadSaver LoadKey(k *Key) error } // PropertyList converts a []Property to implement PropertyLoadSaver. type PropertyList []Property var ( typeOfPropertyLoadSaver = reflect.TypeOf((*PropertyLoadSaver)(nil)).Elem() typeOfPropertyList = reflect.TypeOf(PropertyList(nil)) ) // Load loads all of the provided properties into l. // It does not first reset *l to an empty slice. func (l *PropertyList) Load(p []Property) error { *l = append(*l, p...) return nil } // Save saves all of l's properties as a slice of Properties. func (l *PropertyList) Save() ([]Property, error) { return *l, nil } // validPropertyName returns whether name consists of one or more valid Go // identifiers joined by ".". func validPropertyName(name string) bool { if name == "" { return false } for _, s := range strings.Split(name, ".") { if s == "" { return false } first := true for _, c := range s { if first { first = false if c != '_' && !unicode.IsLetter(c) { return false } } else { if c != '_' && !unicode.IsLetter(c) && !unicode.IsDigit(c) { return false } } } } return true } // parseTag interprets datastore struct field tags func parseTag(t reflect.StructTag) (name string, keep bool, other interface{}, err error) { s := t.Get("datastore") parts := strings.Split(s, ",") if parts[0] == "-" && len(parts) == 1 { return "", false, nil, nil } if parts[0] != "" && !validPropertyName(parts[0]) { err = fmt.Errorf("datastore: struct tag has invalid property name: %q", parts[0]) return "", false, nil, err } var opts saveOpts if len(parts) > 1 { for _, p := range parts[1:] { switch p { case "flatten": opts.flatten = true case "omitempty": opts.omitEmpty = true case "noindex": opts.noIndex = true default: err = fmt.Errorf("datastore: struct tag has invalid option: %q", p) return "", false, nil, err } } other = opts } return parts[0], true, other, nil } func validateType(t reflect.Type) error { if t.Kind() != reflect.Struct { return fmt.Errorf("datastore: validate called with non-struct type %s", t) } return validateChildType(t, "", false, false, map[reflect.Type]bool{}) } // validateChildType is a recursion helper func for validateType func validateChildType(t reflect.Type, fieldName string, flatten, prevSlice bool, prevTypes map[reflect.Type]bool) error { if prevTypes[t] { return nil } prevTypes[t] = true switch t.Kind() { case reflect.Slice: if flatten && prevSlice { return fmt.Errorf("datastore: flattening nested structs leads to a slice of slices: field %q", fieldName) } return validateChildType(t.Elem(), fieldName, flatten, true, prevTypes) case reflect.Struct: if t == typeOfTime || t == typeOfGeoPoint { return nil } for i := 0; i < t.NumField(); i++ { f := t.Field(i) // If a named field is unexported, ignore it. An anonymous // unexported field is processed, because it may contain // exported fields, which are visible. exported := (f.PkgPath == "") if !exported && !f.Anonymous { continue } _, keep, other, err := parseTag(f.Tag) // Handle error from parseTag now instead of later (in cache.Fields call). if err != nil { return err } if !keep { continue } if other != nil { opts := other.(saveOpts) flatten = flatten || opts.flatten } if err := validateChildType(f.Type, f.Name, flatten, prevSlice, prevTypes); err != nil { return err } } case reflect.Ptr: if t == typeOfKeyPtr { return nil } return validateChildType(t.Elem(), fieldName, flatten, prevSlice, prevTypes) } return nil } // isLeafType determines whether or not a type is a 'leaf type' // and should not be recursed into, but considered one field. func isLeafType(t reflect.Type) bool { return t == typeOfTime || t == typeOfGeoPoint } // structCache collects the structs whose fields have already been calculated. var structCache = fields.NewCache(parseTag, validateType, isLeafType) // structPLS adapts a struct to be a PropertyLoadSaver. type structPLS struct { v reflect.Value codec fields.List } // newStructPLS returns a structPLS, which implements the // PropertyLoadSaver interface, for the struct pointer p. func newStructPLS(p interface{}) (*structPLS, error) { v := reflect.ValueOf(p) if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct { return nil, ErrInvalidEntityType } v = v.Elem() f, err := structCache.Fields(v.Type()) if err != nil { return nil, err } return &structPLS{v, f}, nil } // LoadStruct loads the properties from p to dst. // dst must be a struct pointer. // // The values of dst's unmatched struct fields are not modified, // and matching slice-typed fields are not reset before appending to // them. In particular, it is recommended to pass a pointer to a zero // valued struct on each LoadStruct call. func LoadStruct(dst interface{}, p []Property) error { x, err := newStructPLS(dst) if err != nil { return err } return x.Load(p) } // SaveStruct returns the properties from src as a slice of Properties. // src must be a struct pointer. func SaveStruct(src interface{}) ([]Property, error) { x, err := newStructPLS(src) if err != nil { return nil, err } return x.Save() } // plsForLoad tries to convert v to a PropertyLoadSaver. // If successful, plsForLoad returns a settable v as a PropertyLoadSaver. // // plsForLoad is intended to be used with nested struct fields which // may implement PropertyLoadSaver. // // v must be settable. func plsForLoad(v reflect.Value) (PropertyLoadSaver, error) { var nilPtr bool if v.Kind() == reflect.Ptr && v.IsNil() { nilPtr = true v.Set(reflect.New(v.Type().Elem())) } vpls, err := pls(v) if nilPtr && (vpls == nil || err != nil) { // unset v v.Set(reflect.Zero(v.Type())) } return vpls, err } // plsForSave tries to convert v to a PropertyLoadSaver. // If successful, plsForSave returns v as a PropertyLoadSaver. // // plsForSave is intended to be used with nested struct fields which // may implement PropertyLoadSaver. // // v must be settable. func plsForSave(v reflect.Value) (PropertyLoadSaver, error) { switch v.Kind() { case reflect.Ptr, reflect.Slice, reflect.Map, reflect.Interface, reflect.Chan, reflect.Func: // If v is nil, return early. v contains no data to save. if v.IsNil() { return nil, nil } } return pls(v) } func pls(v reflect.Value) (PropertyLoadSaver, error) { if v.Kind() != reflect.Ptr { if _, ok := v.Interface().(PropertyLoadSaver); ok { return nil, fmt.Errorf("datastore: PropertyLoadSaver methods must be implemented on a pointer to %T", v.Interface()) } v = v.Addr() } vpls, _ := v.Interface().(PropertyLoadSaver) return vpls, nil } google-cloud-go-0.49.0/datastore/query.go000066400000000000000000000550471356504100700202650ustar00rootroot00000000000000// Copyright 2014 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package datastore import ( "context" "encoding/base64" "errors" "fmt" "math" "reflect" "strconv" "strings" "cloud.google.com/go/internal/trace" wrapperspb "github.com/golang/protobuf/ptypes/wrappers" "google.golang.org/api/iterator" pb "google.golang.org/genproto/googleapis/datastore/v1" ) type operator int const ( lessThan operator = iota + 1 lessEq equal greaterEq greaterThan keyFieldName = "__key__" ) var operatorToProto = map[operator]pb.PropertyFilter_Operator{ lessThan: pb.PropertyFilter_LESS_THAN, lessEq: pb.PropertyFilter_LESS_THAN_OR_EQUAL, equal: pb.PropertyFilter_EQUAL, greaterEq: pb.PropertyFilter_GREATER_THAN_OR_EQUAL, greaterThan: pb.PropertyFilter_GREATER_THAN, } // filter is a conditional filter on query results. type filter struct { FieldName string Op operator Value interface{} } type sortDirection bool const ( ascending sortDirection = false descending sortDirection = true ) var sortDirectionToProto = map[sortDirection]pb.PropertyOrder_Direction{ ascending: pb.PropertyOrder_ASCENDING, descending: pb.PropertyOrder_DESCENDING, } // order is a sort order on query results. type order struct { FieldName string Direction sortDirection } // NewQuery creates a new Query for a specific entity kind. // // An empty kind means to return all entities, including entities created and // managed by other App Engine features, and is called a kindless query. // Kindless queries cannot include filters or sort orders on property values. func NewQuery(kind string) *Query { return &Query{ kind: kind, limit: -1, } } // Query represents a datastore query. type Query struct { kind string ancestor *Key filter []filter order []order projection []string distinct bool distinctOn []string keysOnly bool eventual bool limit int32 offset int32 start []byte end []byte namespace string trans *Transaction err error } func (q *Query) clone() *Query { x := *q // Copy the contents of the slice-typed fields to a new backing store. if len(q.filter) > 0 { x.filter = make([]filter, len(q.filter)) copy(x.filter, q.filter) } if len(q.order) > 0 { x.order = make([]order, len(q.order)) copy(x.order, q.order) } return &x } // Ancestor returns a derivative query with an ancestor filter. // The ancestor should not be nil. func (q *Query) Ancestor(ancestor *Key) *Query { q = q.clone() if ancestor == nil { q.err = errors.New("datastore: nil query ancestor") return q } q.ancestor = ancestor return q } // EventualConsistency returns a derivative query that returns eventually // consistent results. // It only has an effect on ancestor queries. func (q *Query) EventualConsistency() *Query { q = q.clone() q.eventual = true return q } // Namespace returns a derivative query that is associated with the given // namespace. // // A namespace may be used to partition data for multi-tenant applications. // For details, see https://cloud.google.com/datastore/docs/concepts/multitenancy. func (q *Query) Namespace(ns string) *Query { q = q.clone() q.namespace = ns return q } // Transaction returns a derivative query that is associated with the given // transaction. // // All reads performed as part of the transaction will come from a single // consistent snapshot. Furthermore, if the transaction is set to a // serializable isolation level, another transaction cannot concurrently modify // the data that is read or modified by this transaction. func (q *Query) Transaction(t *Transaction) *Query { q = q.clone() q.trans = t return q } // Filter returns a derivative query with a field-based filter. // The filterStr argument must be a field name followed by optional space, // followed by an operator, one of ">", "<", ">=", "<=", or "=". // Fields are compared against the provided value using the operator. // Multiple filters are AND'ed together. // Field names which contain spaces, quote marks, or operator characters // should be passed as quoted Go string literals as returned by strconv.Quote // or the fmt package's %q verb. func (q *Query) Filter(filterStr string, value interface{}) *Query { q = q.clone() filterStr = strings.TrimSpace(filterStr) if filterStr == "" { q.err = fmt.Errorf("datastore: invalid filter %q", filterStr) return q } f := filter{ FieldName: strings.TrimRight(filterStr, " ><=!"), Value: value, } switch op := strings.TrimSpace(filterStr[len(f.FieldName):]); op { case "<=": f.Op = lessEq case ">=": f.Op = greaterEq case "<": f.Op = lessThan case ">": f.Op = greaterThan case "=": f.Op = equal default: q.err = fmt.Errorf("datastore: invalid operator %q in filter %q", op, filterStr) return q } var err error f.FieldName, err = unquote(f.FieldName) if err != nil { q.err = fmt.Errorf("datastore: invalid syntax for quoted field name %q", f.FieldName) return q } q.filter = append(q.filter, f) return q } // Order returns a derivative query with a field-based sort order. Orders are // applied in the order they are added. The default order is ascending; to sort // in descending order prefix the fieldName with a minus sign (-). // Field names which contain spaces, quote marks, or the minus sign // should be passed as quoted Go string literals as returned by strconv.Quote // or the fmt package's %q verb. func (q *Query) Order(fieldName string) *Query { q = q.clone() fieldName, dir := strings.TrimSpace(fieldName), ascending if strings.HasPrefix(fieldName, "-") { fieldName, dir = strings.TrimSpace(fieldName[1:]), descending } else if strings.HasPrefix(fieldName, "+") { q.err = fmt.Errorf("datastore: invalid order: %q", fieldName) return q } fieldName, err := unquote(fieldName) if err != nil { q.err = fmt.Errorf("datastore: invalid syntax for quoted field name %q", fieldName) return q } if fieldName == "" { q.err = errors.New("datastore: empty order") return q } q.order = append(q.order, order{ Direction: dir, FieldName: fieldName, }) return q } // unquote optionally interprets s as a double-quoted or backquoted Go // string literal if it begins with the relevant character. func unquote(s string) (string, error) { if s == "" || (s[0] != '`' && s[0] != '"') { return s, nil } return strconv.Unquote(s) } // Project returns a derivative query that yields only the given fields. It // cannot be used with KeysOnly. func (q *Query) Project(fieldNames ...string) *Query { q = q.clone() q.projection = append([]string(nil), fieldNames...) return q } // Distinct returns a derivative query that yields de-duplicated entities with // respect to the set of projected fields. It is only used for projection // queries. Distinct cannot be used with DistinctOn. func (q *Query) Distinct() *Query { q = q.clone() q.distinct = true return q } // DistinctOn returns a derivative query that yields de-duplicated entities with // respect to the set of the specified fields. It is only used for projection // queries. The field list should be a subset of the projected field list. // DistinctOn cannot be used with Distinct. func (q *Query) DistinctOn(fieldNames ...string) *Query { q = q.clone() q.distinctOn = fieldNames return q } // KeysOnly returns a derivative query that yields only keys, not keys and // entities. It cannot be used with projection queries. func (q *Query) KeysOnly() *Query { q = q.clone() q.keysOnly = true return q } // Limit returns a derivative query that has a limit on the number of results // returned. A negative value means unlimited. func (q *Query) Limit(limit int) *Query { q = q.clone() if limit < math.MinInt32 || limit > math.MaxInt32 { q.err = errors.New("datastore: query limit overflow") return q } q.limit = int32(limit) return q } // Offset returns a derivative query that has an offset of how many keys to // skip over before returning results. A negative value is invalid. func (q *Query) Offset(offset int) *Query { q = q.clone() if offset < 0 { q.err = errors.New("datastore: negative query offset") return q } if offset > math.MaxInt32 { q.err = errors.New("datastore: query offset overflow") return q } q.offset = int32(offset) return q } // Start returns a derivative query with the given start point. func (q *Query) Start(c Cursor) *Query { q = q.clone() q.start = c.cc return q } // End returns a derivative query with the given end point. func (q *Query) End(c Cursor) *Query { q = q.clone() q.end = c.cc return q } // toProto converts the query to a protocol buffer. func (q *Query) toProto(req *pb.RunQueryRequest) error { if len(q.projection) != 0 && q.keysOnly { return errors.New("datastore: query cannot both project and be keys-only") } if len(q.distinctOn) != 0 && q.distinct { return errors.New("datastore: query cannot be both distinct and distinct-on") } dst := &pb.Query{} if q.kind != "" { dst.Kind = []*pb.KindExpression{{Name: q.kind}} } if q.projection != nil { for _, propertyName := range q.projection { dst.Projection = append(dst.Projection, &pb.Projection{Property: &pb.PropertyReference{Name: propertyName}}) } for _, propertyName := range q.distinctOn { dst.DistinctOn = append(dst.DistinctOn, &pb.PropertyReference{Name: propertyName}) } if q.distinct { for _, propertyName := range q.projection { dst.DistinctOn = append(dst.DistinctOn, &pb.PropertyReference{Name: propertyName}) } } } if q.keysOnly { dst.Projection = []*pb.Projection{{Property: &pb.PropertyReference{Name: keyFieldName}}} } var filters []*pb.Filter for _, qf := range q.filter { if qf.FieldName == "" { return errors.New("datastore: empty query filter field name") } v, err := interfaceToProto(reflect.ValueOf(qf.Value).Interface(), false) if err != nil { return fmt.Errorf("datastore: bad query filter value type: %v", err) } op, ok := operatorToProto[qf.Op] if !ok { return errors.New("datastore: unknown query filter operator") } xf := &pb.PropertyFilter{ Op: op, Property: &pb.PropertyReference{Name: qf.FieldName}, Value: v, } filters = append(filters, &pb.Filter{ FilterType: &pb.Filter_PropertyFilter{PropertyFilter: xf}, }) } if q.ancestor != nil { filters = append(filters, &pb.Filter{ FilterType: &pb.Filter_PropertyFilter{PropertyFilter: &pb.PropertyFilter{ Property: &pb.PropertyReference{Name: keyFieldName}, Op: pb.PropertyFilter_HAS_ANCESTOR, Value: &pb.Value{ValueType: &pb.Value_KeyValue{KeyValue: keyToProto(q.ancestor)}}, }}}) } if len(filters) == 1 { dst.Filter = filters[0] } else if len(filters) > 1 { dst.Filter = &pb.Filter{FilterType: &pb.Filter_CompositeFilter{CompositeFilter: &pb.CompositeFilter{ Op: pb.CompositeFilter_AND, Filters: filters, }}} } for _, qo := range q.order { if qo.FieldName == "" { return errors.New("datastore: empty query order field name") } xo := &pb.PropertyOrder{ Property: &pb.PropertyReference{Name: qo.FieldName}, Direction: sortDirectionToProto[qo.Direction], } dst.Order = append(dst.Order, xo) } if q.limit >= 0 { dst.Limit = &wrapperspb.Int32Value{Value: q.limit} } dst.Offset = q.offset dst.StartCursor = q.start dst.EndCursor = q.end if t := q.trans; t != nil { if t.id == nil { return errExpiredTransaction } if q.eventual { return errors.New("datastore: cannot use EventualConsistency query in a transaction") } req.ReadOptions = &pb.ReadOptions{ ConsistencyType: &pb.ReadOptions_Transaction{Transaction: t.id}, } } if q.eventual { req.ReadOptions = &pb.ReadOptions{ConsistencyType: &pb.ReadOptions_ReadConsistency_{ReadConsistency: pb.ReadOptions_EVENTUAL}} } req.QueryType = &pb.RunQueryRequest_Query{Query: dst} return nil } // Count returns the number of results for the given query. // // The running time and number of API calls made by Count scale linearly with // the sum of the query's offset and limit. Unless the result count is // expected to be small, it is best to specify a limit; otherwise Count will // continue until it finishes counting or the provided context expires. func (c *Client) Count(ctx context.Context, q *Query) (n int, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/datastore.Query.Count") defer func() { trace.EndSpan(ctx, err) }() // Check that the query is well-formed. if q.err != nil { return 0, q.err } // Create a copy of the query, with keysOnly true (if we're not a projection, // since the two are incompatible). newQ := q.clone() newQ.keysOnly = len(newQ.projection) == 0 // Create an iterator and use it to walk through the batches of results // directly. it := c.Run(ctx, newQ) for { err := it.nextBatch() if err == iterator.Done { return n, nil } if err != nil { return 0, err } n += len(it.results) } } // GetAll runs the provided query in the given context and returns all keys // that match that query, as well as appending the values to dst. // // dst must have type *[]S or *[]*S or *[]P, for some struct type S or some non- // interface, non-pointer type P such that P or *P implements PropertyLoadSaver. // // As a special case, *PropertyList is an invalid type for dst, even though a // PropertyList is a slice of structs. It is treated as invalid to avoid being // mistakenly passed when *[]PropertyList was intended. // // The keys returned by GetAll will be in a 1-1 correspondence with the entities // added to dst. // // If q is a ``keys-only'' query, GetAll ignores dst and only returns the keys. // // The running time and number of API calls made by GetAll scale linearly with // with the sum of the query's offset and limit. Unless the result count is // expected to be small, it is best to specify a limit; otherwise GetAll will // continue until it finishes collecting results or the provided context // expires. func (c *Client) GetAll(ctx context.Context, q *Query, dst interface{}) (keys []*Key, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/datastore.Query.GetAll") defer func() { trace.EndSpan(ctx, err) }() var ( dv reflect.Value mat multiArgType elemType reflect.Type errFieldMismatch error ) if !q.keysOnly { dv = reflect.ValueOf(dst) if dv.Kind() != reflect.Ptr || dv.IsNil() { return nil, ErrInvalidEntityType } dv = dv.Elem() mat, elemType = checkMultiArg(dv) if mat == multiArgTypeInvalid || mat == multiArgTypeInterface { return nil, ErrInvalidEntityType } } for t := c.Run(ctx, q); ; { k, e, err := t.next() if err == iterator.Done { break } if err != nil { return keys, err } if !q.keysOnly { ev := reflect.New(elemType) if elemType.Kind() == reflect.Map { // This is a special case. The zero values of a map type are // not immediately useful; they have to be make'd. // // Funcs and channels are similar, in that a zero value is not useful, // but even a freshly make'd channel isn't useful: there's no fixed // channel buffer size that is always going to be large enough, and // there's no goroutine to drain the other end. Theoretically, these // types could be supported, for example by sniffing for a constructor // method or requiring prior registration, but for now it's not a // frequent enough concern to be worth it. Programmers can work around // it by explicitly using Iterator.Next instead of the Query.GetAll // convenience method. x := reflect.MakeMap(elemType) ev.Elem().Set(x) } if err = loadEntityProto(ev.Interface(), e); err != nil { if _, ok := err.(*ErrFieldMismatch); ok { // We continue loading entities even in the face of field mismatch errors. // If we encounter any other error, that other error is returned. Otherwise, // an ErrFieldMismatch is returned. errFieldMismatch = err } else { return keys, err } } if mat != multiArgTypeStructPtr { ev = ev.Elem() } dv.Set(reflect.Append(dv, ev)) } keys = append(keys, k) } return keys, errFieldMismatch } // Run runs the given query in the given context. func (c *Client) Run(ctx context.Context, q *Query) *Iterator { if q.err != nil { return &Iterator{err: q.err} } t := &Iterator{ ctx: ctx, client: c, limit: q.limit, offset: q.offset, keysOnly: q.keysOnly, pageCursor: q.start, entityCursor: q.start, req: &pb.RunQueryRequest{ ProjectId: c.dataset, }, } if q.namespace != "" { t.req.PartitionId = &pb.PartitionId{ NamespaceId: q.namespace, } } if err := q.toProto(t.req); err != nil { t.err = err } return t } // Iterator is the result of running a query. // // It is not safe for concurrent use. type Iterator struct { ctx context.Context client *Client err error // results is the list of EntityResults still to be iterated over from the // most recent API call. It will be nil if no requests have yet been issued. results []*pb.EntityResult // req is the request to send. It may be modified and used multiple times. req *pb.RunQueryRequest // limit is the limit on the number of results this iterator should return. // The zero value is used to prevent further fetches from the server. // A negative value means unlimited. limit int32 // offset is the number of results that still need to be skipped. offset int32 // keysOnly records whether the query was keys-only (skip entity loading). keysOnly bool // pageCursor is the compiled cursor for the next batch/page of result. // TODO(djd): Can we delete this in favour of paging with the last // entityCursor from each batch? pageCursor []byte // entityCursor is the compiled cursor of the next result. entityCursor []byte } // Next returns the key of the next result. When there are no more results, // iterator.Done is returned as the error. // // If the query is not keys only and dst is non-nil, it also loads the entity // stored for that key into the struct pointer or PropertyLoadSaver dst, with // the same semantics and possible errors as for the Get function. func (t *Iterator) Next(dst interface{}) (k *Key, err error) { k, e, err := t.next() if err != nil { return nil, err } if dst != nil && !t.keysOnly { err = loadEntityProto(dst, e) } return k, err } func (t *Iterator) next() (*Key, *pb.Entity, error) { // Fetch additional batches while there are no more results. for t.err == nil && len(t.results) == 0 { t.err = t.nextBatch() } if t.err != nil { return nil, nil, t.err } // Extract the next result, update cursors, and parse the entity's key. e := t.results[0] t.results = t.results[1:] t.entityCursor = e.Cursor if len(t.results) == 0 { t.entityCursor = t.pageCursor // At the end of the batch. } if e.Entity.Key == nil { return nil, nil, errors.New("datastore: internal error: server did not return a key") } k, err := protoToKey(e.Entity.Key) if err != nil || k.Incomplete() { return nil, nil, errors.New("datastore: internal error: server returned an invalid key") } return k, e.Entity, nil } // nextBatch makes a single call to the server for a batch of results. func (t *Iterator) nextBatch() error { if t.err != nil { return t.err } if t.limit == 0 { return iterator.Done // Short-circuits the zero-item response. } // Adjust the query with the latest start cursor, limit and offset. q := t.req.GetQuery() q.StartCursor = t.pageCursor q.Offset = t.offset if t.limit >= 0 { q.Limit = &wrapperspb.Int32Value{Value: t.limit} } else { q.Limit = nil } // Run the query. resp, err := t.client.client.RunQuery(t.ctx, t.req) if err != nil { return err } // Adjust any offset from skipped results. skip := resp.Batch.SkippedResults if skip < 0 { return errors.New("datastore: internal error: negative number of skipped_results") } t.offset -= skip if t.offset < 0 { return errors.New("datastore: internal error: query skipped too many results") } if t.offset > 0 && len(resp.Batch.EntityResults) > 0 { return errors.New("datastore: internal error: query returned results before requested offset") } // Adjust the limit. if t.limit >= 0 { t.limit -= int32(len(resp.Batch.EntityResults)) if t.limit < 0 { return errors.New("datastore: internal error: query returned more results than the limit") } } // If there are no more results available, set limit to zero to prevent // further fetches. Otherwise, check that there is a next page cursor available. if resp.Batch.MoreResults != pb.QueryResultBatch_NOT_FINISHED { t.limit = 0 } else if resp.Batch.EndCursor == nil { return errors.New("datastore: internal error: server did not return a cursor") } // Update cursors. // If any results were skipped, use the SkippedCursor as the next entity cursor. if skip > 0 { t.entityCursor = resp.Batch.SkippedCursor } else { t.entityCursor = q.StartCursor } t.pageCursor = resp.Batch.EndCursor t.results = resp.Batch.EntityResults return nil } // Cursor returns a cursor for the iterator's current location. func (t *Iterator) Cursor() (c Cursor, err error) { t.ctx = trace.StartSpan(t.ctx, "cloud.google.com/go/datastore.Query.Cursor") defer func() { trace.EndSpan(t.ctx, err) }() // If there is still an offset, we need to the skip those results first. for t.err == nil && t.offset > 0 { t.err = t.nextBatch() } if t.err != nil && t.err != iterator.Done { return Cursor{}, t.err } return Cursor{t.entityCursor}, nil } // Cursor is an iterator's position. It can be converted to and from an opaque // string. A cursor can be used from different HTTP requests, but only with a // query with the same kind, ancestor, filter and order constraints. // // The zero Cursor can be used to indicate that there is no start and/or end // constraint for a query. type Cursor struct { cc []byte } // String returns a base-64 string representation of a cursor. func (c Cursor) String() string { if c.cc == nil { return "" } return strings.TrimRight(base64.URLEncoding.EncodeToString(c.cc), "=") } // DecodeCursor decodes a cursor from its base-64 string representation. func DecodeCursor(s string) (Cursor, error) { if s == "" { return Cursor{}, nil } if n := len(s) % 4; n != 0 { s += strings.Repeat("=", 4-n) } b, err := base64.URLEncoding.DecodeString(s) if err != nil { return Cursor{}, err } return Cursor{b}, nil } google-cloud-go-0.49.0/datastore/query_test.go000066400000000000000000000344531356504100700213220ustar00rootroot00000000000000// Copyright 2014 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package datastore import ( "context" "errors" "fmt" "reflect" "sort" "testing" "cloud.google.com/go/internal/testutil" "github.com/golang/protobuf/proto" "github.com/google/go-cmp/cmp" pb "google.golang.org/genproto/googleapis/datastore/v1" "google.golang.org/grpc" ) var ( key1 = &pb.Key{ Path: []*pb.Key_PathElement{ { Kind: "Gopher", IdType: &pb.Key_PathElement_Id{Id: 6}, }, }, } key2 = &pb.Key{ Path: []*pb.Key_PathElement{ { Kind: "Gopher", IdType: &pb.Key_PathElement_Id{Id: 6}, }, { Kind: "Gopher", IdType: &pb.Key_PathElement_Id{Id: 8}, }, }, } ) type fakeClient struct { pb.DatastoreClient queryFn func(*pb.RunQueryRequest) (*pb.RunQueryResponse, error) commitFn func(*pb.CommitRequest) (*pb.CommitResponse, error) } func (c *fakeClient) RunQuery(_ context.Context, req *pb.RunQueryRequest, _ ...grpc.CallOption) (*pb.RunQueryResponse, error) { return c.queryFn(req) } func (c *fakeClient) Commit(_ context.Context, req *pb.CommitRequest, _ ...grpc.CallOption) (*pb.CommitResponse, error) { return c.commitFn(req) } func fakeRunQuery(in *pb.RunQueryRequest) (*pb.RunQueryResponse, error) { expectedIn := &pb.RunQueryRequest{ QueryType: &pb.RunQueryRequest_Query{Query: &pb.Query{ Kind: []*pb.KindExpression{{Name: "Gopher"}}, }}, } if !proto.Equal(in, expectedIn) { return nil, fmt.Errorf("unsupported argument: got %v want %v", in, expectedIn) } return &pb.RunQueryResponse{ Batch: &pb.QueryResultBatch{ MoreResults: pb.QueryResultBatch_NO_MORE_RESULTS, EntityResultType: pb.EntityResult_FULL, EntityResults: []*pb.EntityResult{ { Entity: &pb.Entity{ Key: key1, Properties: map[string]*pb.Value{ "Name": {ValueType: &pb.Value_StringValue{StringValue: "George"}}, "Height": {ValueType: &pb.Value_IntegerValue{IntegerValue: 32}}, }, }, }, { Entity: &pb.Entity{ Key: key2, Properties: map[string]*pb.Value{ "Name": {ValueType: &pb.Value_StringValue{StringValue: "Rufus"}}, // No height for Rufus. }, }, }, }, }, }, nil } type StructThatImplementsPLS struct{} func (StructThatImplementsPLS) Load(p []Property) error { return nil } func (StructThatImplementsPLS) Save() ([]Property, error) { return nil, nil } var _ PropertyLoadSaver = StructThatImplementsPLS{} type StructPtrThatImplementsPLS struct{} func (*StructPtrThatImplementsPLS) Load(p []Property) error { return nil } func (*StructPtrThatImplementsPLS) Save() ([]Property, error) { return nil, nil } var _ PropertyLoadSaver = &StructPtrThatImplementsPLS{} type PropertyMap map[string]Property func (m PropertyMap) Load(props []Property) error { for _, p := range props { m[p.Name] = p } return nil } func (m PropertyMap) Save() ([]Property, error) { props := make([]Property, 0, len(m)) for _, p := range m { props = append(props, p) } return props, nil } var _ PropertyLoadSaver = PropertyMap{} type Gopher struct { Name string Height int } // typeOfEmptyInterface is the type of interface{}, but we can't use // reflect.TypeOf((interface{})(nil)) directly because TypeOf takes an // interface{}. var typeOfEmptyInterface = reflect.TypeOf((*interface{})(nil)).Elem() func TestCheckMultiArg(t *testing.T) { testCases := []struct { v interface{} mat multiArgType elemType reflect.Type }{ // Invalid cases. {nil, multiArgTypeInvalid, nil}, {Gopher{}, multiArgTypeInvalid, nil}, {&Gopher{}, multiArgTypeInvalid, nil}, {PropertyList{}, multiArgTypeInvalid, nil}, // This is a special case. {PropertyMap{}, multiArgTypeInvalid, nil}, {[]*PropertyList(nil), multiArgTypeInvalid, nil}, {[]*PropertyMap(nil), multiArgTypeInvalid, nil}, {[]**Gopher(nil), multiArgTypeInvalid, nil}, {[]*interface{}(nil), multiArgTypeInvalid, nil}, // Valid cases. { []PropertyList(nil), multiArgTypePropertyLoadSaver, reflect.TypeOf(PropertyList{}), }, { []PropertyMap(nil), multiArgTypePropertyLoadSaver, reflect.TypeOf(PropertyMap{}), }, { []StructThatImplementsPLS(nil), multiArgTypePropertyLoadSaver, reflect.TypeOf(StructThatImplementsPLS{}), }, { []StructPtrThatImplementsPLS(nil), multiArgTypePropertyLoadSaver, reflect.TypeOf(StructPtrThatImplementsPLS{}), }, { []Gopher(nil), multiArgTypeStruct, reflect.TypeOf(Gopher{}), }, { []*Gopher(nil), multiArgTypeStructPtr, reflect.TypeOf(Gopher{}), }, { []interface{}(nil), multiArgTypeInterface, typeOfEmptyInterface, }, } for _, tc := range testCases { mat, elemType := checkMultiArg(reflect.ValueOf(tc.v)) if mat != tc.mat || elemType != tc.elemType { t.Errorf("checkMultiArg(%T): got %v, %v want %v, %v", tc.v, mat, elemType, tc.mat, tc.elemType) } } } func TestSimpleQuery(t *testing.T) { struct1 := Gopher{Name: "George", Height: 32} struct2 := Gopher{Name: "Rufus"} pList1 := PropertyList{ { Name: "Height", Value: int64(32), }, { Name: "Name", Value: "George", }, } pList2 := PropertyList{ { Name: "Name", Value: "Rufus", }, } pMap1 := PropertyMap{ "Name": Property{ Name: "Name", Value: "George", }, "Height": Property{ Name: "Height", Value: int64(32), }, } pMap2 := PropertyMap{ "Name": Property{ Name: "Name", Value: "Rufus", }, } testCases := []struct { dst interface{} want interface{} }{ // The destination must have type *[]P, *[]S or *[]*S, for some non-interface // type P such that *P implements PropertyLoadSaver, or for some struct type S. {new([]Gopher), &[]Gopher{struct1, struct2}}, {new([]*Gopher), &[]*Gopher{&struct1, &struct2}}, {new([]PropertyList), &[]PropertyList{pList1, pList2}}, {new([]PropertyMap), &[]PropertyMap{pMap1, pMap2}}, // Any other destination type is invalid. {0, nil}, {Gopher{}, nil}, {PropertyList{}, nil}, {PropertyMap{}, nil}, {[]int{}, nil}, {[]Gopher{}, nil}, {[]PropertyList{}, nil}, {new(int), nil}, {new(Gopher), nil}, {new(PropertyList), nil}, // This is a special case. {new(PropertyMap), nil}, {new([]int), nil}, {new([]map[int]int), nil}, {new([]map[string]Property), nil}, {new([]map[string]interface{}), nil}, {new([]*int), nil}, {new([]*map[int]int), nil}, {new([]*map[string]Property), nil}, {new([]*map[string]interface{}), nil}, {new([]**Gopher), nil}, {new([]*PropertyList), nil}, {new([]*PropertyMap), nil}, } for _, tc := range testCases { nCall := 0 client := &Client{ client: &fakeClient{ queryFn: func(req *pb.RunQueryRequest) (*pb.RunQueryResponse, error) { nCall++ return fakeRunQuery(req) }, }, } ctx := context.Background() var ( expectedErr error expectedNCall int ) if tc.want == nil { expectedErr = ErrInvalidEntityType } else { expectedNCall = 1 } keys, err := client.GetAll(ctx, NewQuery("Gopher"), tc.dst) if err != expectedErr { t.Errorf("dst type %T: got error %v, want %v", tc.dst, err, expectedErr) continue } if nCall != expectedNCall { t.Errorf("dst type %T: Context.Call was called an incorrect number of times: got %d want %d", tc.dst, nCall, expectedNCall) continue } if err != nil { continue } key1 := IDKey("Gopher", 6, nil) expectedKeys := []*Key{ key1, IDKey("Gopher", 8, key1), } if l1, l2 := len(keys), len(expectedKeys); l1 != l2 { t.Errorf("dst type %T: got %d keys, want %d keys", tc.dst, l1, l2) continue } for i, key := range keys { if !keysEqual(key, expectedKeys[i]) { t.Errorf("dst type %T: got key #%d %v, want %v", tc.dst, i, key, expectedKeys[i]) continue } } // Make sure we sort any PropertyList items (the order is not deterministic). if pLists, ok := tc.dst.(*[]PropertyList); ok { for _, p := range *pLists { sort.Sort(byName(p)) } } if !testutil.Equal(tc.dst, tc.want) { t.Errorf("dst type %T: Entities\ngot %+v\nwant %+v", tc.dst, tc.dst, tc.want) continue } } } // keysEqual is like (*Key).Equal, but ignores the App ID. func keysEqual(a, b *Key) bool { for a != nil && b != nil { if a.Kind != b.Kind || a.Name != b.Name || a.ID != b.ID { return false } a, b = a.Parent, b.Parent } return a == b } func TestQueriesAreImmutable(t *testing.T) { // Test that deriving q2 from q1 does not modify q1. q0 := NewQuery("foo") q1 := NewQuery("foo") q2 := q1.Offset(2) if !testutil.Equal(q0, q1, cmp.AllowUnexported(Query{})) { t.Errorf("q0 and q1 were not equal") } if testutil.Equal(q1, q2, cmp.AllowUnexported(Query{})) { t.Errorf("q1 and q2 were equal") } // Test that deriving from q4 twice does not conflict, even though // q4 has a long list of order clauses. This tests that the arrays // backed by a query's slice of orders are not shared. f := func() *Query { q := NewQuery("bar") // 47 is an ugly number that is unlikely to be near a re-allocation // point in repeated append calls. For example, it's not near a power // of 2 or a multiple of 10. for i := 0; i < 47; i++ { q = q.Order(fmt.Sprintf("x%d", i)) } return q } q3 := f().Order("y") q4 := f() q5 := q4.Order("y") q6 := q4.Order("z") if !testutil.Equal(q3, q5, cmp.AllowUnexported(Query{})) { t.Errorf("q3 and q5 were not equal") } if testutil.Equal(q5, q6, cmp.AllowUnexported(Query{})) { t.Errorf("q5 and q6 were equal") } } func TestFilterParser(t *testing.T) { testCases := []struct { filterStr string wantOK bool wantFieldName string wantOp operator }{ // Supported ops. {"x<", true, "x", lessThan}, {"x <", true, "x", lessThan}, {"x <", true, "x", lessThan}, {" x < ", true, "x", lessThan}, {"x <=", true, "x", lessEq}, {"x =", true, "x", equal}, {"x >=", true, "x", greaterEq}, {"x >", true, "x", greaterThan}, {"in >", true, "in", greaterThan}, {"in>", true, "in", greaterThan}, // Valid but (currently) unsupported ops. {"x!=", false, "", 0}, {"x !=", false, "", 0}, {" x != ", false, "", 0}, {"x IN", false, "", 0}, {"x in", false, "", 0}, // Invalid ops. {"x EQ", false, "", 0}, {"x lt", false, "", 0}, {"x <>", false, "", 0}, {"x >>", false, "", 0}, {"x ==", false, "", 0}, {"x =<", false, "", 0}, {"x =>", false, "", 0}, {"x !", false, "", 0}, {"x ", false, "", 0}, {"x", false, "", 0}, // Quoted and interesting field names. {"x > y =", true, "x > y", equal}, {"` x ` =", true, " x ", equal}, {`" x " =`, true, " x ", equal}, {`" \"x " =`, true, ` "x `, equal}, {`" x =`, false, "", 0}, {`" x ="`, false, "", 0}, {"` x \" =", false, "", 0}, } for _, tc := range testCases { q := NewQuery("foo").Filter(tc.filterStr, 42) if ok := q.err == nil; ok != tc.wantOK { t.Errorf("%q: ok=%t, want %t", tc.filterStr, ok, tc.wantOK) continue } if !tc.wantOK { continue } if len(q.filter) != 1 { t.Errorf("%q: len=%d, want %d", tc.filterStr, len(q.filter), 1) continue } got, want := q.filter[0], filter{tc.wantFieldName, tc.wantOp, 42} if got != want { t.Errorf("%q: got %v, want %v", tc.filterStr, got, want) continue } } } func TestNamespaceQuery(t *testing.T) { gotNamespace := make(chan string, 1) ctx := context.Background() client := &Client{ client: &fakeClient{ queryFn: func(req *pb.RunQueryRequest) (*pb.RunQueryResponse, error) { if part := req.PartitionId; part != nil { gotNamespace <- part.NamespaceId } else { gotNamespace <- "" } return nil, errors.New("not implemented") }, }, } var gs []Gopher // Ignore errors for the rest of this test. client.GetAll(ctx, NewQuery("gopher"), &gs) if got, want := <-gotNamespace, ""; got != want { t.Errorf("GetAll: got namespace %q, want %q", got, want) } client.Count(ctx, NewQuery("gopher")) if got, want := <-gotNamespace, ""; got != want { t.Errorf("Count: got namespace %q, want %q", got, want) } const ns = "not_default" client.GetAll(ctx, NewQuery("gopher").Namespace(ns), &gs) if got, want := <-gotNamespace, ns; got != want { t.Errorf("GetAll: got namespace %q, want %q", got, want) } client.Count(ctx, NewQuery("gopher").Namespace(ns)) if got, want := <-gotNamespace, ns; got != want { t.Errorf("Count: got namespace %q, want %q", got, want) } } func TestReadOptions(t *testing.T) { tid := []byte{1} for _, test := range []struct { q *Query want *pb.ReadOptions }{ { q: NewQuery(""), want: nil, }, { q: NewQuery("").Transaction(nil), want: nil, }, { q: NewQuery("").Transaction(&Transaction{id: tid}), want: &pb.ReadOptions{ ConsistencyType: &pb.ReadOptions_Transaction{ Transaction: tid, }, }, }, { q: NewQuery("").EventualConsistency(), want: &pb.ReadOptions{ ConsistencyType: &pb.ReadOptions_ReadConsistency_{ ReadConsistency: pb.ReadOptions_EVENTUAL, }, }, }, } { req := &pb.RunQueryRequest{} if err := test.q.toProto(req); err != nil { t.Fatalf("%+v: got %v, want no error", test.q, err) } if got := req.ReadOptions; !proto.Equal(got, test.want) { t.Errorf("%+v:\ngot %+v\nwant %+v", test.q, got, test.want) } } // Test errors. for _, q := range []*Query{ NewQuery("").Transaction(&Transaction{id: nil}), NewQuery("").Transaction(&Transaction{id: tid}).EventualConsistency(), } { req := &pb.RunQueryRequest{} if err := q.toProto(req); err == nil { t.Errorf("%+v: got nil, wanted error", q) } } } func TestInvalidFilters(t *testing.T) { client := &Client{ client: &fakeClient{ queryFn: func(req *pb.RunQueryRequest) (*pb.RunQueryResponse, error) { return fakeRunQuery(req) }, }, } // Used for an invalid type type MyType int var v MyType = 1 for _, q := range []*Query{ NewQuery("SomeKey").Filter("", 0), NewQuery("SomeKey").Filter("fld=", v), } { if _, err := client.Count(context.Background(), q); err == nil { t.Errorf("%+v: got nil, wanted error", q) } } } google-cloud-go-0.49.0/datastore/save.go000066400000000000000000000324131356504100700200460ustar00rootroot00000000000000// Copyright 2014 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package datastore import ( "errors" "fmt" "reflect" "time" "unicode/utf8" timepb "github.com/golang/protobuf/ptypes/timestamp" pb "google.golang.org/genproto/googleapis/datastore/v1" llpb "google.golang.org/genproto/googleapis/type/latlng" ) type saveOpts struct { noIndex bool flatten bool omitEmpty bool } // saveEntity saves an EntityProto into a PropertyLoadSaver or struct pointer. func saveEntity(key *Key, src interface{}) (*pb.Entity, error) { var err error var props []Property if e, ok := src.(PropertyLoadSaver); ok { props, err = e.Save() } else { props, err = SaveStruct(src) } if err != nil { return nil, err } return propertiesToProto(key, props) } // reflectFieldSave extracts the underlying value of v by reflection, // and tries to extract a Property that'll be appended to props. func reflectFieldSave(props *[]Property, p Property, name string, opts saveOpts, v reflect.Value) error { switch x := v.Interface().(type) { case *Key, time.Time, GeoPoint: p.Value = x default: switch v.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: p.Value = v.Int() case reflect.Bool: p.Value = v.Bool() case reflect.String: p.Value = v.String() case reflect.Float32, reflect.Float64: p.Value = v.Float() case reflect.Interface: // Extract the interface's underlying value and then retry the save. // See issue https://github.com/googleapis/google-cloud-go/issues/1474. v = v.Elem() return reflectFieldSave(props, p, name, opts, v) case reflect.Slice: if v.Type().Elem().Kind() == reflect.Uint8 { p.Value = v.Bytes() } else { return saveSliceProperty(props, name, opts, v) } case reflect.Ptr: if isValidPointerType(v.Type().Elem()) { if v.IsNil() { // Nil pointer becomes a nil property value (unless omitempty, handled above). p.Value = nil *props = append(*props, p) return nil } // When we recurse on the derefenced pointer, omitempty no longer applies: // we already know the pointer is not empty, it doesn't matter if its referent // is empty or not. opts.omitEmpty = false return saveStructProperty(props, name, opts, v.Elem()) } if v.Type().Elem().Kind() != reflect.Struct { return fmt.Errorf("datastore: unsupported struct field type: %s", v.Type()) } // Pointer to struct is a special case. if v.IsNil() { return nil } v = v.Elem() fallthrough case reflect.Struct: if !v.CanAddr() { return fmt.Errorf("datastore: unsupported struct field: value is unaddressable") } vi := v.Addr().Interface() sub, err := newStructPLS(vi) if err != nil { return fmt.Errorf("datastore: unsupported struct field: %v", err) } if opts.flatten { return sub.save(props, opts, name+".") } var subProps []Property err = sub.save(&subProps, opts, "") if err != nil { return err } subKey, err := sub.key(v) if err != nil { return err } p.Value = &Entity{ Key: subKey, Properties: subProps, } } } if p.Value == nil { return fmt.Errorf("datastore: unsupported struct field type: %v", v.Type()) } *props = append(*props, p) return nil } // TODO(djd): Convert this and below to return ([]Property, error). func saveStructProperty(props *[]Property, name string, opts saveOpts, v reflect.Value) error { p := Property{ Name: name, NoIndex: opts.noIndex, } if opts.omitEmpty && isEmptyValue(v) { return nil } // First check if field type implements PLS. If so, use PLS to // save. ok, err := plsFieldSave(props, p, name, opts, v) if err != nil { return err } if ok { return nil } return reflectFieldSave(props, p, name, opts, v) } // plsFieldSave first tries to converts v's value to a PLS, then v's addressed // value to a PLS. If neither succeeds, plsFieldSave returns false for first return // value. // If v is successfully converted to a PLS, plsFieldSave will then add the // Value to property p by way of the PLS's Save method, and append it to props. // // If the flatten option is present in opts, name must be prepended to each property's // name before it is appended to props. Eg. if name were "A" and a subproperty's name // were "B", the resultant name of the property to be appended to props would be "A.B". func plsFieldSave(props *[]Property, p Property, name string, opts saveOpts, v reflect.Value) (ok bool, err error) { vpls, err := plsForSave(v) if err != nil { return false, err } if vpls == nil { return false, nil } subProps, err := vpls.Save() if err != nil { return true, err } if opts.flatten { for _, subp := range subProps { subp.Name = name + "." + subp.Name *props = append(*props, subp) } return true, nil } p.Value = &Entity{Properties: subProps} *props = append(*props, p) return true, nil } // key extracts the *Key struct field from struct v based on the structCodec of s. func (s structPLS) key(v reflect.Value) (*Key, error) { if v.Kind() != reflect.Struct { return nil, errors.New("datastore: cannot save key of non-struct type") } keyField := s.codec.Match(keyFieldName) if keyField == nil { return nil, nil } f := v.FieldByIndex(keyField.Index) k, ok := f.Interface().(*Key) if !ok { return nil, fmt.Errorf("datastore: %s field on struct %T is not a *datastore.Key", keyFieldName, v.Interface()) } return k, nil } func saveSliceProperty(props *[]Property, name string, opts saveOpts, v reflect.Value) error { // Easy case: if the slice is empty, we're done. if v.Len() == 0 { return nil } // Work out the properties generated by the first element in the slice. This will // usually be a single property, but will be more if this is a slice of structs. var headProps []Property if err := saveStructProperty(&headProps, name, opts, v.Index(0)); err != nil { return err } // Convert the first element's properties into slice properties, and // keep track of the values in a map. values := make(map[string][]interface{}, len(headProps)) for _, p := range headProps { values[p.Name] = append(make([]interface{}, 0, v.Len()), p.Value) } // Find the elements for the subsequent elements. for i := 1; i < v.Len(); i++ { elemProps := make([]Property, 0, len(headProps)) if err := saveStructProperty(&elemProps, name, opts, v.Index(i)); err != nil { return err } for _, p := range elemProps { v, ok := values[p.Name] if !ok { return fmt.Errorf("datastore: unexpected property %q in elem %d of slice", p.Name, i) } values[p.Name] = append(v, p.Value) } } // Convert to the final properties. for _, p := range headProps { p.Value = values[p.Name] *props = append(*props, p) } return nil } func (s structPLS) Save() ([]Property, error) { var props []Property if err := s.save(&props, saveOpts{}, ""); err != nil { return nil, err } return props, nil } func (s structPLS) save(props *[]Property, opts saveOpts, prefix string) error { for _, f := range s.codec { name := prefix + f.Name v := getField(s.v, f.Index) if !v.IsValid() || !v.CanSet() { continue } var tagOpts saveOpts if f.ParsedTag != nil { tagOpts = f.ParsedTag.(saveOpts) } var opts1 saveOpts opts1.noIndex = opts.noIndex || tagOpts.noIndex opts1.flatten = opts.flatten || tagOpts.flatten opts1.omitEmpty = tagOpts.omitEmpty // don't propagate if err := saveStructProperty(props, name, opts1, v); err != nil { return err } } return nil } // getField returns the field from v at the given index path. // If it encounters a nil-valued field in the path, getField // stops and returns a zero-valued reflect.Value, preventing the // panic that would have been caused by reflect's FieldByIndex. func getField(v reflect.Value, index []int) reflect.Value { var zero reflect.Value if v.Type().Kind() != reflect.Struct { return zero } for _, i := range index { if v.Kind() == reflect.Ptr && v.Type().Elem().Kind() == reflect.Struct { if v.IsNil() { return zero } v = v.Elem() } v = v.Field(i) } return v } func propertiesToProto(key *Key, props []Property) (*pb.Entity, error) { e := &pb.Entity{ Key: keyToProto(key), Properties: map[string]*pb.Value{}, } indexedProps := 0 for _, p := range props { // Do not send a Key value a field to datastore. if p.Name == keyFieldName { continue } val, err := interfaceToProto(p.Value, p.NoIndex) if err != nil { return nil, fmt.Errorf("datastore: %v for a Property with Name %q", err, p.Name) } if !p.NoIndex { rVal := reflect.ValueOf(p.Value) if rVal.Kind() == reflect.Slice && rVal.Type().Elem().Kind() != reflect.Uint8 { indexedProps += rVal.Len() } else { indexedProps++ } } if indexedProps > maxIndexedProperties { return nil, errors.New("datastore: too many indexed properties") } if _, ok := e.Properties[p.Name]; ok { return nil, fmt.Errorf("datastore: duplicate Property with Name %q", p.Name) } e.Properties[p.Name] = val } return e, nil } func interfaceToProto(iv interface{}, noIndex bool) (*pb.Value, error) { val := &pb.Value{ExcludeFromIndexes: noIndex} switch v := iv.(type) { case int: val.ValueType = &pb.Value_IntegerValue{IntegerValue: int64(v)} case int32: val.ValueType = &pb.Value_IntegerValue{IntegerValue: int64(v)} case int64: val.ValueType = &pb.Value_IntegerValue{IntegerValue: v} case bool: val.ValueType = &pb.Value_BooleanValue{BooleanValue: v} case string: if len(v) > 1500 && !noIndex { return nil, errors.New("string property too long to index") } if !utf8.ValidString(v) { return nil, fmt.Errorf("string is not valid utf8: %q", v) } val.ValueType = &pb.Value_StringValue{StringValue: v} case float32: val.ValueType = &pb.Value_DoubleValue{DoubleValue: float64(v)} case float64: val.ValueType = &pb.Value_DoubleValue{DoubleValue: v} case *Key: if v == nil { val.ValueType = &pb.Value_NullValue{} } else { val.ValueType = &pb.Value_KeyValue{KeyValue: keyToProto(v)} } case GeoPoint: if !v.Valid() { return nil, errors.New("invalid GeoPoint value") } val.ValueType = &pb.Value_GeoPointValue{GeoPointValue: &llpb.LatLng{ Latitude: v.Lat, Longitude: v.Lng, }} case time.Time: if v.Before(minTime) || v.After(maxTime) { return nil, errors.New("time value out of range") } val.ValueType = &pb.Value_TimestampValue{TimestampValue: &timepb.Timestamp{ Seconds: v.Unix(), Nanos: int32(v.Nanosecond()), }} case []byte: if len(v) > 1500 && !noIndex { return nil, errors.New("[]byte property too long to index") } val.ValueType = &pb.Value_BlobValue{BlobValue: v} case *Entity: e, err := propertiesToProto(v.Key, v.Properties) if err != nil { return nil, err } val.ValueType = &pb.Value_EntityValue{EntityValue: e} case []interface{}: arr := make([]*pb.Value, 0, len(v)) for i, v := range v { elem, err := interfaceToProto(v, noIndex) if err != nil { return nil, fmt.Errorf("%v at index %d", err, i) } arr = append(arr, elem) } val.ValueType = &pb.Value_ArrayValue{ArrayValue: &pb.ArrayValue{Values: arr}} // ArrayValues have ExcludeFromIndexes set on the individual items, rather // than the top-level value. val.ExcludeFromIndexes = false default: rv := reflect.ValueOf(iv) if !rv.IsValid() { val.ValueType = &pb.Value_NullValue{} } else if rv.Kind() == reflect.Ptr { // non-nil pointer: dereference if rv.IsNil() { val.ValueType = &pb.Value_NullValue{} return val, nil } return interfaceToProto(rv.Elem().Interface(), noIndex) } else { return nil, fmt.Errorf("invalid Value type %T", iv) } } // TODO(jbd): Support EntityValue. return val, nil } // isEmptyValue is taken from the encoding/json package in the // standard library. func isEmptyValue(v reflect.Value) bool { switch v.Kind() { case reflect.Array, reflect.Map, reflect.Slice, reflect.String: return v.Len() == 0 case reflect.Bool: return !v.Bool() case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return v.Int() == 0 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: return v.Uint() == 0 case reflect.Float32, reflect.Float64: return v.Float() == 0 case reflect.Interface, reflect.Ptr: return v.IsNil() case reflect.Struct: if t, ok := v.Interface().(time.Time); ok { return t.IsZero() } } return false } // isValidPointerType reports whether a struct field can be a pointer to type t // for the purposes of saving and loading. func isValidPointerType(t reflect.Type) bool { if t == typeOfTime || t == typeOfGeoPoint { return true } switch t.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return true case reflect.Bool: return true case reflect.String: return true case reflect.Float32, reflect.Float64: return true } return false } google-cloud-go-0.49.0/datastore/save_test.go000066400000000000000000000200101356504100700210730ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package datastore import ( "testing" "time" "cloud.google.com/go/internal/testutil" pb "google.golang.org/genproto/googleapis/datastore/v1" ) func TestInterfaceToProtoNil(t *testing.T) { // A nil *Key, or a nil value of any other pointer type, should convert to a NullValue. for _, in := range []interface{}{ (*Key)(nil), (*int)(nil), (*string)(nil), (*bool)(nil), (*float64)(nil), (*GeoPoint)(nil), (*time.Time)(nil), } { got, err := interfaceToProto(in, false) if err != nil { t.Fatalf("%T: %v", in, err) } _, ok := got.ValueType.(*pb.Value_NullValue) if !ok { t.Errorf("%T: got: %T\nwant: %T", in, got.ValueType, &pb.Value_NullValue{}) } } } func TestSaveEntityNested(t *testing.T) { type WithKey struct { X string I int K *Key `datastore:"__key__"` } type NestedWithKey struct { Y string N WithKey } type WithoutKey struct { X string I int } type NestedWithoutKey struct { Y string N WithoutKey } type a struct { S string } type UnexpAnonym struct { a } testCases := []struct { desc string src interface{} key *Key want *pb.Entity }{ { desc: "nested entity with key", src: &NestedWithKey{ Y: "yyy", N: WithKey{ X: "two", I: 2, K: testKey1a, }, }, key: testKey0, want: &pb.Entity{ Key: keyToProto(testKey0), Properties: map[string]*pb.Value{ "Y": {ValueType: &pb.Value_StringValue{StringValue: "yyy"}}, "N": {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Key: keyToProto(testKey1a), Properties: map[string]*pb.Value{ "X": {ValueType: &pb.Value_StringValue{StringValue: "two"}}, "I": {ValueType: &pb.Value_IntegerValue{IntegerValue: 2}}, }, }, }}, }, }, }, { desc: "nested entity with incomplete key", src: &NestedWithKey{ Y: "yyy", N: WithKey{ X: "two", I: 2, K: incompleteKey, }, }, key: testKey0, want: &pb.Entity{ Key: keyToProto(testKey0), Properties: map[string]*pb.Value{ "Y": {ValueType: &pb.Value_StringValue{StringValue: "yyy"}}, "N": {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Key: keyToProto(incompleteKey), Properties: map[string]*pb.Value{ "X": {ValueType: &pb.Value_StringValue{StringValue: "two"}}, "I": {ValueType: &pb.Value_IntegerValue{IntegerValue: 2}}, }, }, }}, }, }, }, { desc: "nested entity without key", src: &NestedWithoutKey{ Y: "yyy", N: WithoutKey{ X: "two", I: 2, }, }, key: testKey0, want: &pb.Entity{ Key: keyToProto(testKey0), Properties: map[string]*pb.Value{ "Y": {ValueType: &pb.Value_StringValue{StringValue: "yyy"}}, "N": {ValueType: &pb.Value_EntityValue{ EntityValue: &pb.Entity{ Properties: map[string]*pb.Value{ "X": {ValueType: &pb.Value_StringValue{StringValue: "two"}}, "I": {ValueType: &pb.Value_IntegerValue{IntegerValue: 2}}, }, }, }}, }, }, }, { desc: "key at top level", src: &WithKey{ X: "three", I: 3, K: testKey0, }, key: testKey0, want: &pb.Entity{ Key: keyToProto(testKey0), Properties: map[string]*pb.Value{ "X": {ValueType: &pb.Value_StringValue{StringValue: "three"}}, "I": {ValueType: &pb.Value_IntegerValue{IntegerValue: 3}}, }, }, }, { desc: "nested unexported anonymous struct field", src: &UnexpAnonym{ a{S: "hello"}, }, key: testKey0, want: &pb.Entity{ Key: keyToProto(testKey0), Properties: map[string]*pb.Value{ "S": {ValueType: &pb.Value_StringValue{StringValue: "hello"}}, }, }, }, } for _, tc := range testCases { got, err := saveEntity(tc.key, tc.src) if err != nil { t.Errorf("saveEntity: %s: %v", tc.desc, err) continue } if !testutil.Equal(tc.want, got) { t.Errorf("%s: compare:\ngot: %#v\nwant: %#v", tc.desc, got, tc.want) } } } func TestSavePointers(t *testing.T) { for _, test := range []struct { desc string in interface{} want []Property }{ { desc: "nil pointers save as nil-valued properties", in: &Pointers{}, want: []Property{ {Name: "Pi", Value: nil}, {Name: "Ps", Value: nil}, {Name: "Pb", Value: nil}, {Name: "Pf", Value: nil}, {Name: "Pg", Value: nil}, {Name: "Pt", Value: nil}, }, }, { desc: "nil omitempty pointers not saved", in: &PointersOmitEmpty{}, want: []Property(nil), }, { desc: "non-nil omitempty zero-valued pointers are saved", in: func() *PointersOmitEmpty { pi := 0; return &PointersOmitEmpty{Pi: &pi} }(), want: []Property{{Name: "Pi", Value: int64(0)}}, }, { desc: "non-nil zero-valued pointers save as zero values", in: populatedPointers(), want: []Property{ {Name: "Pi", Value: int64(0)}, {Name: "Ps", Value: ""}, {Name: "Pb", Value: false}, {Name: "Pf", Value: 0.0}, {Name: "Pg", Value: GeoPoint{}}, {Name: "Pt", Value: time.Time{}}, }, }, { desc: "non-nil non-zero-valued pointers save as the appropriate values", in: func() *Pointers { p := populatedPointers() *p.Pi = 1 *p.Ps = "x" *p.Pb = true *p.Pf = 3.14 *p.Pg = GeoPoint{Lat: 1, Lng: 2} *p.Pt = time.Unix(100, 0) return p }(), want: []Property{ {Name: "Pi", Value: int64(1)}, {Name: "Ps", Value: "x"}, {Name: "Pb", Value: true}, {Name: "Pf", Value: 3.14}, {Name: "Pg", Value: GeoPoint{Lat: 1, Lng: 2}}, {Name: "Pt", Value: time.Unix(100, 0)}, }, }, } { got, err := SaveStruct(test.in) if err != nil { t.Fatalf("%s: %v", test.desc, err) } if !testutil.Equal(got, test.want) { t.Errorf("%s\ngot %#v\nwant %#v\n", test.desc, got, test.want) } } } func TestSaveEmptySlice(t *testing.T) { // Zero-length slice fields are not saved. for _, slice := range [][]string{nil, {}} { got, err := SaveStruct(&struct{ S []string }{S: slice}) if err != nil { t.Fatal(err) } if len(got) != 0 { t.Errorf("%#v: got %d properties, wanted zero", slice, len(got)) } } } func TestSaveFieldsWithInterface(t *testing.T) { // We should be able to extract the underlying value behind an interface. // See issue https://github.com/googleapis/google-cloud-go/issues/1474. type n1 struct { Inner interface{} } type n2 struct { Inner2 *n1 } type n3 struct { N2 interface{} } cases := []struct { name string in interface{} want []Property }{ { name: "Non-Nil value", in: &struct { Value interface{} ID int key interface{} }{ Value: "this is a string", ID: 17, key: "key1", }, want: []Property{ {Name: "Value", Value: "this is a string"}, {Name: "ID", Value: int64(17)}, }, }, { name: "Nil value", in: &struct { foo interface{} }{ foo: (*string)(nil), }, want: nil, }, { name: "Nested", in: &n3{ N2: &n2{ Inner2: &n1{ Inner: "Innest", }, }, }, want: []Property{ { Name: "N2", Value: &Entity{ Properties: []Property{{ Name: "Inner2", Value: &Entity{ Properties: []Property{{ Name: "Inner", Value: "Innest", }}, }, }}, }, }, }, }, } for _, tt := range cases { t.Run(tt.name, func(t *testing.T) { got, err := SaveStruct(tt.in) if err != nil { t.Fatal(err) } if diff := testutil.Diff(got, tt.want); diff != "" { t.Fatalf("got - want +\n%s", diff) } }) } } google-cloud-go-0.49.0/datastore/testdata/000077500000000000000000000000001356504100700203675ustar00rootroot00000000000000google-cloud-go-0.49.0/datastore/testdata/index.yaml000066400000000000000000000007521356504100700223660ustar00rootroot00000000000000indexes: - kind: SQChild ancestor: yes properties: - name: T - name: I - kind: SQChild ancestor: yes properties: - name: T - name: I direction: desc - kind: SQChild ancestor: yes properties: - name: I - name: T - name: U - kind: SQChild ancestor: yes properties: - name: I - name: T - name: U - kind: SQChild ancestor: yes properties: - name: T - name: J - kind: SQChild ancestor: yes properties: - name: T - name: J - name: Ugoogle-cloud-go-0.49.0/datastore/time.go000066400000000000000000000022531356504100700200450ustar00rootroot00000000000000// Copyright 2014 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package datastore import ( "math" "time" ) var ( minTime = time.Unix(int64(math.MinInt64)/1e6, (int64(math.MinInt64)%1e6)*1e3) maxTime = time.Unix(int64(math.MaxInt64)/1e6, (int64(math.MaxInt64)%1e6)*1e3) ) func toUnixMicro(t time.Time) int64 { // We cannot use t.UnixNano() / 1e3 because we want to handle times more than // 2^63 nanoseconds (which is about 292 years) away from 1970, and those cannot // be represented in the numerator of a single int64 divide. return t.Unix()*1e6 + int64(t.Nanosecond()/1e3) } func fromUnixMicro(t int64) time.Time { return time.Unix(t/1e6, (t%1e6)*1e3) } google-cloud-go-0.49.0/datastore/time_test.go000066400000000000000000000045551356504100700211130ustar00rootroot00000000000000// Copyright 2014 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package datastore import ( "testing" "time" ) func TestUnixMicro(t *testing.T) { // Test that all these time.Time values survive a round trip to unix micros. testCases := []time.Time{ {}, time.Date(2, 1, 1, 0, 0, 0, 0, time.UTC), time.Date(23, 1, 1, 0, 0, 0, 0, time.UTC), time.Date(234, 1, 1, 0, 0, 0, 0, time.UTC), time.Date(1000, 1, 1, 0, 0, 0, 0, time.UTC), time.Date(1600, 1, 1, 0, 0, 0, 0, time.UTC), time.Date(1700, 1, 1, 0, 0, 0, 0, time.UTC), time.Date(1800, 1, 1, 0, 0, 0, 0, time.UTC), time.Date(1900, 1, 1, 0, 0, 0, 0, time.UTC), time.Unix(-1e6, -1000), time.Unix(-1e6, 0), time.Unix(-1e6, +1000), time.Unix(-60, -1000), time.Unix(-60, 0), time.Unix(-60, +1000), time.Unix(-1, -1000), time.Unix(-1, 0), time.Unix(-1, +1000), time.Unix(0, -3000), time.Unix(0, -2000), time.Unix(0, -1000), time.Unix(0, 0), time.Unix(0, +1000), time.Unix(0, +2000), time.Unix(+60, -1000), time.Unix(+60, 0), time.Unix(+60, +1000), time.Unix(+1e6, -1000), time.Unix(+1e6, 0), time.Unix(+1e6, +1000), time.Date(1999, 12, 31, 23, 59, 59, 999000, time.UTC), time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC), time.Date(2006, 1, 2, 15, 4, 5, 678000, time.UTC), time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC), time.Date(3456, 1, 1, 0, 0, 0, 0, time.UTC), } for _, tc := range testCases { got := fromUnixMicro(toUnixMicro(tc)) if !got.Equal(tc) { t.Errorf("got %q, want %q", got, tc) } } // Test that a time.Time that isn't an integral number of microseconds // is not perfectly reconstructed after a round trip. t0 := time.Unix(0, 123) t1 := fromUnixMicro(toUnixMicro(t0)) if t1.Nanosecond()%1000 != 0 || t0.Nanosecond()%1000 == 0 { t.Errorf("quantization to µs: got %q with %d ns, started with %d ns", t1, t1.Nanosecond(), t0.Nanosecond()) } } google-cloud-go-0.49.0/datastore/transaction.go000066400000000000000000000310561356504100700214370ustar00rootroot00000000000000// Copyright 2014 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package datastore import ( "context" "errors" "cloud.google.com/go/internal/trace" pb "google.golang.org/genproto/googleapis/datastore/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) // ErrConcurrentTransaction is returned when a transaction is rolled back due // to a conflict with a concurrent transaction. var ErrConcurrentTransaction = errors.New("datastore: concurrent transaction") var errExpiredTransaction = errors.New("datastore: transaction expired") type transactionSettings struct { attempts int readOnly bool prevID []byte // ID of the transaction to retry } // newTransactionSettings creates a transactionSettings with a given TransactionOption slice. // Unconfigured options will be set to default values. func newTransactionSettings(opts []TransactionOption) *transactionSettings { s := &transactionSettings{attempts: 3} for _, o := range opts { o.apply(s) } return s } // TransactionOption configures the way a transaction is executed. type TransactionOption interface { apply(*transactionSettings) } // MaxAttempts returns a TransactionOption that overrides the default 3 attempt times. func MaxAttempts(attempts int) TransactionOption { return maxAttempts(attempts) } type maxAttempts int func (w maxAttempts) apply(s *transactionSettings) { if w > 0 { s.attempts = int(w) } } // ReadOnly is a TransactionOption that marks the transaction as read-only. var ReadOnly TransactionOption func init() { ReadOnly = readOnly{} } type readOnly struct{} func (readOnly) apply(s *transactionSettings) { s.readOnly = true } // Transaction represents a set of datastore operations to be committed atomically. // // Operations are enqueued by calling the Put and Delete methods on Transaction // (or their Multi-equivalents). These operations are only committed when the // Commit method is invoked. To ensure consistency, reads must be performed by // using Transaction's Get method or by using the Transaction method when // building a query. // // A Transaction must be committed or rolled back exactly once. type Transaction struct { id []byte client *Client ctx context.Context mutations []*pb.Mutation // The mutations to apply. pending map[int]*PendingKey // Map from mutation index to incomplete keys pending transaction completion. } // NewTransaction starts a new transaction. func (c *Client) NewTransaction(ctx context.Context, opts ...TransactionOption) (t *Transaction, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/datastore.NewTransaction") defer func() { trace.EndSpan(ctx, err) }() for _, o := range opts { if _, ok := o.(maxAttempts); ok { return nil, errors.New("datastore: NewTransaction does not accept MaxAttempts option") } } return c.newTransaction(ctx, newTransactionSettings(opts)) } func (c *Client) newTransaction(ctx context.Context, s *transactionSettings) (*Transaction, error) { req := &pb.BeginTransactionRequest{ProjectId: c.dataset} if s.readOnly { req.TransactionOptions = &pb.TransactionOptions{ Mode: &pb.TransactionOptions_ReadOnly_{ReadOnly: &pb.TransactionOptions_ReadOnly{}}, } } else if s.prevID != nil { req.TransactionOptions = &pb.TransactionOptions{ Mode: &pb.TransactionOptions_ReadWrite_{ReadWrite: &pb.TransactionOptions_ReadWrite{ PreviousTransaction: s.prevID, }}, } } resp, err := c.client.BeginTransaction(ctx, req) if err != nil { return nil, err } return &Transaction{ id: resp.Transaction, ctx: ctx, client: c, mutations: nil, pending: make(map[int]*PendingKey), }, nil } // RunInTransaction runs f in a transaction. f is invoked with a Transaction // that f should use for all the transaction's datastore operations. // // f must not call Commit or Rollback on the provided Transaction. // // If f returns nil, RunInTransaction commits the transaction, // returning the Commit and a nil error if it succeeds. If the commit fails due // to a conflicting transaction, RunInTransaction retries f with a new // Transaction. It gives up and returns ErrConcurrentTransaction after three // failed attempts (or as configured with MaxAttempts). // // If f returns non-nil, then the transaction will be rolled back and // RunInTransaction will return the same error. The function f is not retried. // // Note that when f returns, the transaction is not committed. Calling code // must not assume that any of f's changes have been committed until // RunInTransaction returns nil. // // Since f may be called multiple times, f should usually be idempotent – that // is, it should have the same result when called multiple times. Note that // Transaction.Get will append when unmarshalling slice fields, so it is not // necessarily idempotent. func (c *Client) RunInTransaction(ctx context.Context, f func(tx *Transaction) error, opts ...TransactionOption) (cmt *Commit, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/datastore.RunInTransaction") defer func() { trace.EndSpan(ctx, err) }() settings := newTransactionSettings(opts) for n := 0; n < settings.attempts; n++ { tx, err := c.newTransaction(ctx, settings) if err != nil { return nil, err } if err := f(tx); err != nil { _ = tx.Rollback() return nil, err } if cmt, err := tx.Commit(); err != ErrConcurrentTransaction { return cmt, err } // Pass this transaction's ID to the retry transaction to preserve // transaction priority. if !settings.readOnly { settings.prevID = tx.id } } return nil, ErrConcurrentTransaction } // Commit applies the enqueued operations atomically. func (t *Transaction) Commit() (c *Commit, err error) { t.ctx = trace.StartSpan(t.ctx, "cloud.google.com/go/datastore.Transaction.Commit") defer func() { trace.EndSpan(t.ctx, err) }() if t.id == nil { return nil, errExpiredTransaction } req := &pb.CommitRequest{ ProjectId: t.client.dataset, TransactionSelector: &pb.CommitRequest_Transaction{Transaction: t.id}, Mutations: t.mutations, Mode: pb.CommitRequest_TRANSACTIONAL, } resp, err := t.client.client.Commit(t.ctx, req) if status.Code(err) == codes.Aborted { return nil, ErrConcurrentTransaction } t.id = nil // mark the transaction as expired if err != nil { return nil, err } // Copy any newly minted keys into the returned keys. for i, p := range t.pending { if i >= len(resp.MutationResults) || resp.MutationResults[i].Key == nil { return nil, errors.New("datastore: internal error: server returned the wrong mutation results") } key, err := protoToKey(resp.MutationResults[i].Key) if err != nil { return nil, errors.New("datastore: internal error: server returned an invalid key") } p.key = key p.commit = c } return c, nil } // Rollback abandons a pending transaction. func (t *Transaction) Rollback() (err error) { t.ctx = trace.StartSpan(t.ctx, "cloud.google.com/go/datastore.Transaction.Rollback") defer func() { trace.EndSpan(t.ctx, err) }() if t.id == nil { return errExpiredTransaction } id := t.id t.id = nil _, err = t.client.client.Rollback(t.ctx, &pb.RollbackRequest{ ProjectId: t.client.dataset, Transaction: id, }) return err } // Get is the transaction-specific version of the package function Get. // All reads performed during the transaction will come from a single consistent // snapshot. Furthermore, if the transaction is set to a serializable isolation // level, another transaction cannot concurrently modify the data that is read // or modified by this transaction. func (t *Transaction) Get(key *Key, dst interface{}) (err error) { t.ctx = trace.StartSpan(t.ctx, "cloud.google.com/go/datastore.Transaction.Get") defer func() { trace.EndSpan(t.ctx, err) }() opts := &pb.ReadOptions{ ConsistencyType: &pb.ReadOptions_Transaction{Transaction: t.id}, } err = t.client.get(t.ctx, []*Key{key}, []interface{}{dst}, opts) if me, ok := err.(MultiError); ok { return me[0] } return err } // GetMulti is a batch version of Get. func (t *Transaction) GetMulti(keys []*Key, dst interface{}) (err error) { t.ctx = trace.StartSpan(t.ctx, "cloud.google.com/go/datastore.Transaction.GetMulti") defer func() { trace.EndSpan(t.ctx, err) }() if t.id == nil { return errExpiredTransaction } opts := &pb.ReadOptions{ ConsistencyType: &pb.ReadOptions_Transaction{Transaction: t.id}, } return t.client.get(t.ctx, keys, dst, opts) } // Put is the transaction-specific version of the package function Put. // // Put returns a PendingKey which can be resolved into a Key using the // return value from a successful Commit. If key is an incomplete key, the // returned pending key will resolve to a unique key generated by the // datastore. func (t *Transaction) Put(key *Key, src interface{}) (*PendingKey, error) { h, err := t.PutMulti([]*Key{key}, []interface{}{src}) if err != nil { if me, ok := err.(MultiError); ok { return nil, me[0] } return nil, err } return h[0], nil } // PutMulti is a batch version of Put. One PendingKey is returned for each // element of src in the same order. // TODO(jba): rewrite in terms of Mutate. func (t *Transaction) PutMulti(keys []*Key, src interface{}) (ret []*PendingKey, err error) { if t.id == nil { return nil, errExpiredTransaction } mutations, err := putMutations(keys, src) if err != nil { return nil, err } origin := len(t.mutations) t.mutations = append(t.mutations, mutations...) // Prepare the returned handles, pre-populating where possible. ret = make([]*PendingKey, len(keys)) for i, key := range keys { p := &PendingKey{} if key.Incomplete() { // This key will be in the final commit result. t.pending[origin+i] = p } else { p.key = key } ret[i] = p } return ret, nil } // Delete is the transaction-specific version of the package function Delete. // Delete enqueues the deletion of the entity for the given key, to be // committed atomically upon calling Commit. func (t *Transaction) Delete(key *Key) error { err := t.DeleteMulti([]*Key{key}) if me, ok := err.(MultiError); ok { return me[0] } return err } // DeleteMulti is a batch version of Delete. // TODO(jba): rewrite in terms of Mutate. func (t *Transaction) DeleteMulti(keys []*Key) (err error) { if t.id == nil { return errExpiredTransaction } mutations, err := deleteMutations(keys) if err != nil { return err } t.mutations = append(t.mutations, mutations...) return nil } // Mutate adds the mutations to the transaction. They will all be applied atomically // upon calling Commit. Mutate returns a PendingKey for each Mutation in the argument // list, in the same order. PendingKeys for Delete mutations are always nil. // // If any of the mutations are invalid, Mutate returns a MultiError with the errors. // Mutate returns a MultiError in this case even if there is only one Mutation. // // For an example, see Client.Mutate. func (t *Transaction) Mutate(muts ...*Mutation) ([]*PendingKey, error) { if t.id == nil { return nil, errExpiredTransaction } pmuts, err := mutationProtos(muts) if err != nil { return nil, err } origin := len(t.mutations) t.mutations = append(t.mutations, pmuts...) // Prepare the returned handles, pre-populating where possible. ret := make([]*PendingKey, len(muts)) for i, mut := range muts { if mut.isDelete() { continue } p := &PendingKey{} if mut.key.Incomplete() { // This key will be in the final commit result. t.pending[origin+i] = p } else { p.key = mut.key } ret[i] = p } return ret, nil } // Commit represents the result of a committed transaction. type Commit struct{} // Key resolves a pending key handle into a final key. func (c *Commit) Key(p *PendingKey) *Key { if p == nil { // if called on a *PendingKey from a Delete mutation return nil } // If p.commit is nil, the PendingKey did not come from an incomplete key, // so p.key is valid. if p.commit != nil && c != p.commit { panic("PendingKey was not created by corresponding transaction") } return p.key } // PendingKey represents the key for newly-inserted entity. It can be // resolved into a Key by calling the Key method of Commit. type PendingKey struct { key *Key commit *Commit } google-cloud-go-0.49.0/datastore/transaction_test.go000066400000000000000000000041121356504100700224670ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package datastore import ( "context" "testing" "github.com/golang/protobuf/proto" pb "google.golang.org/genproto/googleapis/datastore/v1" ) func TestNewTransaction(t *testing.T) { var got *pb.BeginTransactionRequest client := &Client{ dataset: "project", client: &fakeDatastoreClient{ beginTransaction: func(req *pb.BeginTransactionRequest) (*pb.BeginTransactionResponse, error) { got = req return &pb.BeginTransactionResponse{ Transaction: []byte("tid"), }, nil }, }, } ctx := context.Background() for _, test := range []struct { settings *transactionSettings want *pb.BeginTransactionRequest }{ { &transactionSettings{}, &pb.BeginTransactionRequest{ProjectId: "project"}, }, { &transactionSettings{readOnly: true}, &pb.BeginTransactionRequest{ ProjectId: "project", TransactionOptions: &pb.TransactionOptions{ Mode: &pb.TransactionOptions_ReadOnly_{ReadOnly: &pb.TransactionOptions_ReadOnly{}}, }, }, }, { &transactionSettings{prevID: []byte("tid")}, &pb.BeginTransactionRequest{ ProjectId: "project", TransactionOptions: &pb.TransactionOptions{ Mode: &pb.TransactionOptions_ReadWrite_{ReadWrite: &pb.TransactionOptions_ReadWrite{ PreviousTransaction: []byte("tid"), }, }, }, }, }, } { _, err := client.newTransaction(ctx, test.settings) if err != nil { t.Fatal(err) } if !proto.Equal(got, test.want) { t.Errorf("%+v:\ngot %+v\nwant %+v", test.settings, got, test.want) } } } google-cloud-go-0.49.0/debugger/000077500000000000000000000000001356504100700163545ustar00rootroot00000000000000google-cloud-go-0.49.0/debugger/apiv2/000077500000000000000000000000001356504100700173755ustar00rootroot00000000000000google-cloud-go-0.49.0/debugger/apiv2/.repo-metadata.json000066400000000000000000000006421356504100700230730ustar00rootroot00000000000000{ "name": "debugger", "name_pretty": "Stackdriver Debugger", "product_documentation": "https://cloud.google.com/debugger", "client_documentation": "https://godoc.org/cloud.google.com/go/debugger/apiv2", "release_level": "alpha", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "clouddebugger.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/debugger/apiv2/controller2_client.go000066400000000000000000000220551356504100700235330ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package debugger import ( "context" "fmt" "math" "net/url" "time" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" "google.golang.org/api/transport" clouddebuggerpb "google.golang.org/genproto/googleapis/devtools/clouddebugger/v2" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // Controller2CallOptions contains the retry settings for each method of Controller2Client. type Controller2CallOptions struct { UpdateActiveBreakpoint []gax.CallOption RegisterDebuggee []gax.CallOption ListActiveBreakpoints []gax.CallOption } func defaultController2ClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("clouddebugger.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultController2CallOptions() *Controller2CallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &Controller2CallOptions{ UpdateActiveBreakpoint: retry[[2]string{"default", "idempotent"}], RegisterDebuggee: retry[[2]string{"default", "non_idempotent"}], ListActiveBreakpoints: retry[[2]string{"default", "idempotent"}], } } // Controller2Client is a client for interacting with Stackdriver Debugger API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type Controller2Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. controller2Client clouddebuggerpb.Controller2Client // The call options for this service. CallOptions *Controller2CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewController2Client creates a new controller2 client. // // The Controller service provides the API for orchestrating a collection of // debugger agents to perform debugging tasks. These agents are each attached // to a process of an application which may include one or more replicas. // // The debugger agents register with the Controller to identify the application // being debugged, the Debuggee. All agents that register with the same data, // represent the same Debuggee, and are assigned the same debuggee_id. // // The debugger agents call the Controller to retrieve the list of active // Breakpoints. Agents with the same debuggee_id get the same breakpoints // list. An agent that can fulfill the breakpoint request updates the // Controller with the breakpoint result. The controller selects the first // result received and discards the rest of the results. // Agents that poll again for active breakpoints will no longer have // the completed breakpoint in the list and should remove that breakpoint from // their attached process. // // The Controller service does not provide a way to retrieve the results of // a completed breakpoint. This functionality is available using the Debugger // service. func NewController2Client(ctx context.Context, opts ...option.ClientOption) (*Controller2Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultController2ClientOptions(), opts...)...) if err != nil { return nil, err } c := &Controller2Client{ conn: conn, CallOptions: defaultController2CallOptions(), controller2Client: clouddebuggerpb.NewController2Client(conn), } c.SetGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *Controller2Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *Controller2Client) Close() error { return c.conn.Close() } // SetGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *Controller2Client) SetGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // UpdateActiveBreakpoint updates the breakpoint state or mutable fields. // The entire Breakpoint message must be sent back to the controller service. // // Updates to active breakpoint fields are only allowed if the new value // does not change the breakpoint specification. Updates to the location, // condition and expressions fields should not alter the breakpoint // semantics. These may only make changes such as canonicalizing a value // or snapping the location to the correct line of code. func (c *Controller2Client) UpdateActiveBreakpoint(ctx context.Context, req *clouddebuggerpb.UpdateActiveBreakpointRequest, opts ...gax.CallOption) (*clouddebuggerpb.UpdateActiveBreakpointResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.UpdateActiveBreakpoint[0:len(c.CallOptions.UpdateActiveBreakpoint):len(c.CallOptions.UpdateActiveBreakpoint)], opts...) var resp *clouddebuggerpb.UpdateActiveBreakpointResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.controller2Client.UpdateActiveBreakpoint(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // RegisterDebuggee registers the debuggee with the controller service. // // All agents attached to the same application must call this method with // exactly the same request content to get back the same stable debuggee_id. // Agents should call this method again whenever google.rpc.Code.NOT_FOUND // is returned from any controller method. // // This protocol allows the controller service to disable debuggees, recover // from data loss, or change the debuggee_id format. Agents must handle // debuggee_id value changing upon re-registration. func (c *Controller2Client) RegisterDebuggee(ctx context.Context, req *clouddebuggerpb.RegisterDebuggeeRequest, opts ...gax.CallOption) (*clouddebuggerpb.RegisterDebuggeeResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.RegisterDebuggee[0:len(c.CallOptions.RegisterDebuggee):len(c.CallOptions.RegisterDebuggee)], opts...) var resp *clouddebuggerpb.RegisterDebuggeeResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.controller2Client.RegisterDebuggee(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListActiveBreakpoints returns the list of all active breakpoints for the debuggee. // // The breakpoint specification (location, condition, and expressions // fields) is semantically immutable, although the field values may // change. For example, an agent may update the location line number // to reflect the actual line where the breakpoint was set, but this // doesn't change the breakpoint semantics. // // This means that an agent does not need to check if a breakpoint has changed // when it encounters the same breakpoint on a successive call. // Moreover, an agent should remember the breakpoints that are completed // until the controller removes them from the active list to avoid // setting those breakpoints again. func (c *Controller2Client) ListActiveBreakpoints(ctx context.Context, req *clouddebuggerpb.ListActiveBreakpointsRequest, opts ...gax.CallOption) (*clouddebuggerpb.ListActiveBreakpointsResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "debuggee_id", url.QueryEscape(req.GetDebuggeeId()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListActiveBreakpoints[0:len(c.CallOptions.ListActiveBreakpoints):len(c.CallOptions.ListActiveBreakpoints)], opts...) var resp *clouddebuggerpb.ListActiveBreakpointsResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.controller2Client.ListActiveBreakpoints(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } google-cloud-go-0.49.0/debugger/apiv2/controller2_client_example_test.go000066400000000000000000000042221356504100700263010ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package debugger_test import ( "context" debugger "cloud.google.com/go/debugger/apiv2" clouddebuggerpb "google.golang.org/genproto/googleapis/devtools/clouddebugger/v2" ) func ExampleNewController2Client() { ctx := context.Background() c, err := debugger.NewController2Client(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleController2Client_UpdateActiveBreakpoint() { ctx := context.Background() c, err := debugger.NewController2Client(ctx) if err != nil { // TODO: Handle error. } req := &clouddebuggerpb.UpdateActiveBreakpointRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateActiveBreakpoint(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleController2Client_RegisterDebuggee() { ctx := context.Background() c, err := debugger.NewController2Client(ctx) if err != nil { // TODO: Handle error. } req := &clouddebuggerpb.RegisterDebuggeeRequest{ // TODO: Fill request struct fields. } resp, err := c.RegisterDebuggee(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleController2Client_ListActiveBreakpoints() { ctx := context.Background() c, err := debugger.NewController2Client(ctx) if err != nil { // TODO: Handle error. } req := &clouddebuggerpb.ListActiveBreakpointsRequest{ // TODO: Fill request struct fields. } resp, err := c.ListActiveBreakpoints(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/debugger/apiv2/debugger2_client.go000066400000000000000000000206441356504100700231360ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package debugger import ( "context" "fmt" "math" "net/url" "time" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" "google.golang.org/api/transport" clouddebuggerpb "google.golang.org/genproto/googleapis/devtools/clouddebugger/v2" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // Debugger2CallOptions contains the retry settings for each method of Debugger2Client. type Debugger2CallOptions struct { DeleteBreakpoint []gax.CallOption SetBreakpoint []gax.CallOption GetBreakpoint []gax.CallOption ListBreakpoints []gax.CallOption ListDebuggees []gax.CallOption } func defaultDebugger2ClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("clouddebugger.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultDebugger2CallOptions() *Debugger2CallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &Debugger2CallOptions{ DeleteBreakpoint: retry[[2]string{"default", "idempotent"}], SetBreakpoint: retry[[2]string{"default", "non_idempotent"}], GetBreakpoint: retry[[2]string{"default", "idempotent"}], ListBreakpoints: retry[[2]string{"default", "idempotent"}], ListDebuggees: retry[[2]string{"default", "idempotent"}], } } // Debugger2Client is a client for interacting with Stackdriver Debugger API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type Debugger2Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. debugger2Client clouddebuggerpb.Debugger2Client // The call options for this service. CallOptions *Debugger2CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewDebugger2Client creates a new debugger2 client. // // The Debugger service provides the API that allows users to collect run-time // information from a running application, without stopping or slowing it down // and without modifying its state. An application may include one or // more replicated processes performing the same work. // // A debugged application is represented using the Debuggee concept. The // Debugger service provides a way to query for available debuggees, but does // not provide a way to create one. A debuggee is created using the Controller // service, usually by running a debugger agent with the application. // // The Debugger service enables the client to set one or more Breakpoints on a // Debuggee and collect the results of the set Breakpoints. func NewDebugger2Client(ctx context.Context, opts ...option.ClientOption) (*Debugger2Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultDebugger2ClientOptions(), opts...)...) if err != nil { return nil, err } c := &Debugger2Client{ conn: conn, CallOptions: defaultDebugger2CallOptions(), debugger2Client: clouddebuggerpb.NewDebugger2Client(conn), } c.SetGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *Debugger2Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *Debugger2Client) Close() error { return c.conn.Close() } // SetGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *Debugger2Client) SetGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // DeleteBreakpoint deletes the breakpoint from the debuggee. func (c *Debugger2Client) DeleteBreakpoint(ctx context.Context, req *clouddebuggerpb.DeleteBreakpointRequest, opts ...gax.CallOption) error { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.DeleteBreakpoint[0:len(c.CallOptions.DeleteBreakpoint):len(c.CallOptions.DeleteBreakpoint)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.debugger2Client.DeleteBreakpoint(ctx, req, settings.GRPC...) return err }, opts...) return err } // SetBreakpoint sets the breakpoint to the debuggee. func (c *Debugger2Client) SetBreakpoint(ctx context.Context, req *clouddebuggerpb.SetBreakpointRequest, opts ...gax.CallOption) (*clouddebuggerpb.SetBreakpointResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "debuggee_id", url.QueryEscape(req.GetDebuggeeId()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.SetBreakpoint[0:len(c.CallOptions.SetBreakpoint):len(c.CallOptions.SetBreakpoint)], opts...) var resp *clouddebuggerpb.SetBreakpointResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.debugger2Client.SetBreakpoint(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetBreakpoint gets breakpoint information. func (c *Debugger2Client) GetBreakpoint(ctx context.Context, req *clouddebuggerpb.GetBreakpointRequest, opts ...gax.CallOption) (*clouddebuggerpb.GetBreakpointResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.GetBreakpoint[0:len(c.CallOptions.GetBreakpoint):len(c.CallOptions.GetBreakpoint)], opts...) var resp *clouddebuggerpb.GetBreakpointResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.debugger2Client.GetBreakpoint(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListBreakpoints lists all breakpoints for the debuggee. func (c *Debugger2Client) ListBreakpoints(ctx context.Context, req *clouddebuggerpb.ListBreakpointsRequest, opts ...gax.CallOption) (*clouddebuggerpb.ListBreakpointsResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "debuggee_id", url.QueryEscape(req.GetDebuggeeId()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListBreakpoints[0:len(c.CallOptions.ListBreakpoints):len(c.CallOptions.ListBreakpoints)], opts...) var resp *clouddebuggerpb.ListBreakpointsResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.debugger2Client.ListBreakpoints(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListDebuggees lists all the debuggees that the user has access to. func (c *Debugger2Client) ListDebuggees(ctx context.Context, req *clouddebuggerpb.ListDebuggeesRequest, opts ...gax.CallOption) (*clouddebuggerpb.ListDebuggeesResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.ListDebuggees[0:len(c.CallOptions.ListDebuggees):len(c.CallOptions.ListDebuggees)], opts...) var resp *clouddebuggerpb.ListDebuggeesResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.debugger2Client.ListDebuggees(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } google-cloud-go-0.49.0/debugger/apiv2/debugger2_client_example_test.go000066400000000000000000000054301356504100700257040ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package debugger_test import ( "context" debugger "cloud.google.com/go/debugger/apiv2" clouddebuggerpb "google.golang.org/genproto/googleapis/devtools/clouddebugger/v2" ) func ExampleNewDebugger2Client() { ctx := context.Background() c, err := debugger.NewDebugger2Client(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleDebugger2Client_DeleteBreakpoint() { ctx := context.Background() c, err := debugger.NewDebugger2Client(ctx) if err != nil { // TODO: Handle error. } req := &clouddebuggerpb.DeleteBreakpointRequest{ // TODO: Fill request struct fields. } err = c.DeleteBreakpoint(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleDebugger2Client_SetBreakpoint() { ctx := context.Background() c, err := debugger.NewDebugger2Client(ctx) if err != nil { // TODO: Handle error. } req := &clouddebuggerpb.SetBreakpointRequest{ // TODO: Fill request struct fields. } resp, err := c.SetBreakpoint(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleDebugger2Client_GetBreakpoint() { ctx := context.Background() c, err := debugger.NewDebugger2Client(ctx) if err != nil { // TODO: Handle error. } req := &clouddebuggerpb.GetBreakpointRequest{ // TODO: Fill request struct fields. } resp, err := c.GetBreakpoint(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleDebugger2Client_ListBreakpoints() { ctx := context.Background() c, err := debugger.NewDebugger2Client(ctx) if err != nil { // TODO: Handle error. } req := &clouddebuggerpb.ListBreakpointsRequest{ // TODO: Fill request struct fields. } resp, err := c.ListBreakpoints(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleDebugger2Client_ListDebuggees() { ctx := context.Background() c, err := debugger.NewDebugger2Client(ctx) if err != nil { // TODO: Handle error. } req := &clouddebuggerpb.ListDebuggeesRequest{ // TODO: Fill request struct fields. } resp, err := c.ListDebuggees(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/debugger/apiv2/doc.go000066400000000000000000000056261356504100700205020ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package debugger is an auto-generated package for the // Stackdriver Debugger API. // // NOTE: This package is in alpha. It is not stable, and is likely to change. // // Examines the call stack and variables of a running application without // stopping or slowing it down. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. // // Use the client at cloud.google.com/go/cmd/go-cloud-debug-agent in preference to this. package debugger // import "cloud.google.com/go/debugger/apiv2" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/cloud_debugger", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191115" google-cloud-go-0.49.0/debugger/apiv2/mock_test.go000066400000000000000000000502541356504100700217220ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package debugger import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" "google.golang.org/api/option" clouddebuggerpb "google.golang.org/genproto/googleapis/devtools/clouddebugger/v2" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockDebugger2Server struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. clouddebuggerpb.Debugger2Server reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockDebugger2Server) SetBreakpoint(ctx context.Context, req *clouddebuggerpb.SetBreakpointRequest) (*clouddebuggerpb.SetBreakpointResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*clouddebuggerpb.SetBreakpointResponse), nil } func (s *mockDebugger2Server) GetBreakpoint(ctx context.Context, req *clouddebuggerpb.GetBreakpointRequest) (*clouddebuggerpb.GetBreakpointResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*clouddebuggerpb.GetBreakpointResponse), nil } func (s *mockDebugger2Server) DeleteBreakpoint(ctx context.Context, req *clouddebuggerpb.DeleteBreakpointRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockDebugger2Server) ListBreakpoints(ctx context.Context, req *clouddebuggerpb.ListBreakpointsRequest) (*clouddebuggerpb.ListBreakpointsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*clouddebuggerpb.ListBreakpointsResponse), nil } func (s *mockDebugger2Server) ListDebuggees(ctx context.Context, req *clouddebuggerpb.ListDebuggeesRequest) (*clouddebuggerpb.ListDebuggeesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*clouddebuggerpb.ListDebuggeesResponse), nil } type mockController2Server struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. clouddebuggerpb.Controller2Server reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockController2Server) RegisterDebuggee(ctx context.Context, req *clouddebuggerpb.RegisterDebuggeeRequest) (*clouddebuggerpb.RegisterDebuggeeResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*clouddebuggerpb.RegisterDebuggeeResponse), nil } func (s *mockController2Server) ListActiveBreakpoints(ctx context.Context, req *clouddebuggerpb.ListActiveBreakpointsRequest) (*clouddebuggerpb.ListActiveBreakpointsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*clouddebuggerpb.ListActiveBreakpointsResponse), nil } func (s *mockController2Server) UpdateActiveBreakpoint(ctx context.Context, req *clouddebuggerpb.UpdateActiveBreakpointRequest) (*clouddebuggerpb.UpdateActiveBreakpointResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*clouddebuggerpb.UpdateActiveBreakpointResponse), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockDebugger2 mockDebugger2Server mockController2 mockController2Server ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() clouddebuggerpb.RegisterDebugger2Server(serv, &mockDebugger2) clouddebuggerpb.RegisterController2Server(serv, &mockController2) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestDebugger2DeleteBreakpoint(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockDebugger2.err = nil mockDebugger2.reqs = nil mockDebugger2.resps = append(mockDebugger2.resps[:0], expectedResponse) var debuggeeId string = "debuggeeId-997255898" var breakpointId string = "breakpointId498424873" var clientVersion string = "clientVersion-1506231196" var request = &clouddebuggerpb.DeleteBreakpointRequest{ DebuggeeId: debuggeeId, BreakpointId: breakpointId, ClientVersion: clientVersion, } c, err := NewDebugger2Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteBreakpoint(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDebugger2.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestDebugger2DeleteBreakpointError(t *testing.T) { errCode := codes.PermissionDenied mockDebugger2.err = gstatus.Error(errCode, "test error") var debuggeeId string = "debuggeeId-997255898" var breakpointId string = "breakpointId498424873" var clientVersion string = "clientVersion-1506231196" var request = &clouddebuggerpb.DeleteBreakpointRequest{ DebuggeeId: debuggeeId, BreakpointId: breakpointId, ClientVersion: clientVersion, } c, err := NewDebugger2Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteBreakpoint(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestDebugger2SetBreakpoint(t *testing.T) { var expectedResponse *clouddebuggerpb.SetBreakpointResponse = &clouddebuggerpb.SetBreakpointResponse{} mockDebugger2.err = nil mockDebugger2.reqs = nil mockDebugger2.resps = append(mockDebugger2.resps[:0], expectedResponse) var debuggeeId string = "debuggeeId-997255898" var breakpoint *clouddebuggerpb.Breakpoint = &clouddebuggerpb.Breakpoint{} var clientVersion string = "clientVersion-1506231196" var request = &clouddebuggerpb.SetBreakpointRequest{ DebuggeeId: debuggeeId, Breakpoint: breakpoint, ClientVersion: clientVersion, } c, err := NewDebugger2Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetBreakpoint(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDebugger2.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDebugger2SetBreakpointError(t *testing.T) { errCode := codes.PermissionDenied mockDebugger2.err = gstatus.Error(errCode, "test error") var debuggeeId string = "debuggeeId-997255898" var breakpoint *clouddebuggerpb.Breakpoint = &clouddebuggerpb.Breakpoint{} var clientVersion string = "clientVersion-1506231196" var request = &clouddebuggerpb.SetBreakpointRequest{ DebuggeeId: debuggeeId, Breakpoint: breakpoint, ClientVersion: clientVersion, } c, err := NewDebugger2Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetBreakpoint(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDebugger2GetBreakpoint(t *testing.T) { var expectedResponse *clouddebuggerpb.GetBreakpointResponse = &clouddebuggerpb.GetBreakpointResponse{} mockDebugger2.err = nil mockDebugger2.reqs = nil mockDebugger2.resps = append(mockDebugger2.resps[:0], expectedResponse) var debuggeeId string = "debuggeeId-997255898" var breakpointId string = "breakpointId498424873" var clientVersion string = "clientVersion-1506231196" var request = &clouddebuggerpb.GetBreakpointRequest{ DebuggeeId: debuggeeId, BreakpointId: breakpointId, ClientVersion: clientVersion, } c, err := NewDebugger2Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetBreakpoint(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDebugger2.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDebugger2GetBreakpointError(t *testing.T) { errCode := codes.PermissionDenied mockDebugger2.err = gstatus.Error(errCode, "test error") var debuggeeId string = "debuggeeId-997255898" var breakpointId string = "breakpointId498424873" var clientVersion string = "clientVersion-1506231196" var request = &clouddebuggerpb.GetBreakpointRequest{ DebuggeeId: debuggeeId, BreakpointId: breakpointId, ClientVersion: clientVersion, } c, err := NewDebugger2Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetBreakpoint(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDebugger2ListBreakpoints(t *testing.T) { var nextWaitToken string = "nextWaitToken1006864251" var expectedResponse = &clouddebuggerpb.ListBreakpointsResponse{ NextWaitToken: nextWaitToken, } mockDebugger2.err = nil mockDebugger2.reqs = nil mockDebugger2.resps = append(mockDebugger2.resps[:0], expectedResponse) var debuggeeId string = "debuggeeId-997255898" var clientVersion string = "clientVersion-1506231196" var request = &clouddebuggerpb.ListBreakpointsRequest{ DebuggeeId: debuggeeId, ClientVersion: clientVersion, } c, err := NewDebugger2Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListBreakpoints(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDebugger2.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDebugger2ListBreakpointsError(t *testing.T) { errCode := codes.PermissionDenied mockDebugger2.err = gstatus.Error(errCode, "test error") var debuggeeId string = "debuggeeId-997255898" var clientVersion string = "clientVersion-1506231196" var request = &clouddebuggerpb.ListBreakpointsRequest{ DebuggeeId: debuggeeId, ClientVersion: clientVersion, } c, err := NewDebugger2Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListBreakpoints(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDebugger2ListDebuggees(t *testing.T) { var expectedResponse *clouddebuggerpb.ListDebuggeesResponse = &clouddebuggerpb.ListDebuggeesResponse{} mockDebugger2.err = nil mockDebugger2.reqs = nil mockDebugger2.resps = append(mockDebugger2.resps[:0], expectedResponse) var project string = "project-309310695" var clientVersion string = "clientVersion-1506231196" var request = &clouddebuggerpb.ListDebuggeesRequest{ Project: project, ClientVersion: clientVersion, } c, err := NewDebugger2Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListDebuggees(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDebugger2.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDebugger2ListDebuggeesError(t *testing.T) { errCode := codes.PermissionDenied mockDebugger2.err = gstatus.Error(errCode, "test error") var project string = "project-309310695" var clientVersion string = "clientVersion-1506231196" var request = &clouddebuggerpb.ListDebuggeesRequest{ Project: project, ClientVersion: clientVersion, } c, err := NewDebugger2Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListDebuggees(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestController2UpdateActiveBreakpoint(t *testing.T) { var expectedResponse *clouddebuggerpb.UpdateActiveBreakpointResponse = &clouddebuggerpb.UpdateActiveBreakpointResponse{} mockController2.err = nil mockController2.reqs = nil mockController2.resps = append(mockController2.resps[:0], expectedResponse) var debuggeeId string = "debuggeeId-997255898" var breakpoint *clouddebuggerpb.Breakpoint = &clouddebuggerpb.Breakpoint{} var request = &clouddebuggerpb.UpdateActiveBreakpointRequest{ DebuggeeId: debuggeeId, Breakpoint: breakpoint, } c, err := NewController2Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateActiveBreakpoint(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockController2.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestController2UpdateActiveBreakpointError(t *testing.T) { errCode := codes.PermissionDenied mockController2.err = gstatus.Error(errCode, "test error") var debuggeeId string = "debuggeeId-997255898" var breakpoint *clouddebuggerpb.Breakpoint = &clouddebuggerpb.Breakpoint{} var request = &clouddebuggerpb.UpdateActiveBreakpointRequest{ DebuggeeId: debuggeeId, Breakpoint: breakpoint, } c, err := NewController2Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateActiveBreakpoint(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestController2RegisterDebuggee(t *testing.T) { var expectedResponse *clouddebuggerpb.RegisterDebuggeeResponse = &clouddebuggerpb.RegisterDebuggeeResponse{} mockController2.err = nil mockController2.reqs = nil mockController2.resps = append(mockController2.resps[:0], expectedResponse) var debuggee *clouddebuggerpb.Debuggee = &clouddebuggerpb.Debuggee{} var request = &clouddebuggerpb.RegisterDebuggeeRequest{ Debuggee: debuggee, } c, err := NewController2Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.RegisterDebuggee(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockController2.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestController2RegisterDebuggeeError(t *testing.T) { errCode := codes.PermissionDenied mockController2.err = gstatus.Error(errCode, "test error") var debuggee *clouddebuggerpb.Debuggee = &clouddebuggerpb.Debuggee{} var request = &clouddebuggerpb.RegisterDebuggeeRequest{ Debuggee: debuggee, } c, err := NewController2Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.RegisterDebuggee(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestController2ListActiveBreakpoints(t *testing.T) { var nextWaitToken string = "nextWaitToken1006864251" var waitExpired bool = false var expectedResponse = &clouddebuggerpb.ListActiveBreakpointsResponse{ NextWaitToken: nextWaitToken, WaitExpired: waitExpired, } mockController2.err = nil mockController2.reqs = nil mockController2.resps = append(mockController2.resps[:0], expectedResponse) var debuggeeId string = "debuggeeId-997255898" var request = &clouddebuggerpb.ListActiveBreakpointsRequest{ DebuggeeId: debuggeeId, } c, err := NewController2Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListActiveBreakpoints(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockController2.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestController2ListActiveBreakpointsError(t *testing.T) { errCode := codes.PermissionDenied mockController2.err = gstatus.Error(errCode, "test error") var debuggeeId string = "debuggeeId-997255898" var request = &clouddebuggerpb.ListActiveBreakpointsRequest{ DebuggeeId: debuggeeId, } c, err := NewController2Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListActiveBreakpoints(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/dialogflow/000077500000000000000000000000001356504100700167175ustar00rootroot00000000000000google-cloud-go-0.49.0/dialogflow/apiv2/000077500000000000000000000000001356504100700177405ustar00rootroot00000000000000google-cloud-go-0.49.0/dialogflow/apiv2/.repo-metadata.json000066400000000000000000000006331356504100700234360ustar00rootroot00000000000000{ "name": "dialogflow", "name_pretty": "Dialogflow", "product_documentation": "https://cloud.google.com/dialogflow", "client_documentation": "https://godoc.org/cloud.google.com/go/dialogflow/apiv2", "release_level": "alpha", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "dialogflow.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/dialogflow/apiv2/agents_client.go000066400000000000000000000627151356504100700231210ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package dialogflow import ( "context" "fmt" "math" "net/url" "time" "cloud.google.com/go/longrunning" lroauto "cloud.google.com/go/longrunning/autogen" "github.com/golang/protobuf/proto" structpbpb "github.com/golang/protobuf/ptypes/struct" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" dialogflowpb "google.golang.org/genproto/googleapis/cloud/dialogflow/v2" longrunningpb "google.golang.org/genproto/googleapis/longrunning" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // AgentsCallOptions contains the retry settings for each method of AgentsClient. type AgentsCallOptions struct { SetAgent []gax.CallOption DeleteAgent []gax.CallOption GetAgent []gax.CallOption SearchAgents []gax.CallOption TrainAgent []gax.CallOption ExportAgent []gax.CallOption ImportAgent []gax.CallOption RestoreAgent []gax.CallOption } func defaultAgentsClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("dialogflow.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultAgentsCallOptions() *AgentsCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &AgentsCallOptions{ SetAgent: retry[[2]string{"default", "idempotent"}], DeleteAgent: retry[[2]string{"default", "idempotent"}], GetAgent: retry[[2]string{"default", "idempotent"}], SearchAgents: retry[[2]string{"default", "idempotent"}], TrainAgent: retry[[2]string{"default", "idempotent"}], ExportAgent: retry[[2]string{"default", "idempotent"}], ImportAgent: retry[[2]string{"default", "non_idempotent"}], RestoreAgent: retry[[2]string{"default", "idempotent"}], } } // AgentsClient is a client for interacting with Dialogflow API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type AgentsClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. agentsClient dialogflowpb.AgentsClient // LROClient is used internally to handle longrunning operations. // It is exposed so that its CallOptions can be modified if required. // Users should not Close this client. LROClient *lroauto.OperationsClient // The call options for this service. CallOptions *AgentsCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewAgentsClient creates a new agents client. // // Agents are best described as Natural Language Understanding (NLU) modules // that transform user requests into actionable data. You can include agents // in your app, product, or service to determine user intent and respond to the // user in a natural way. // // After you create an agent, you can add [Intents][google.cloud.dialogflow.v2.Intents], [Contexts][google.cloud.dialogflow.v2.Contexts], // [Entity Types][google.cloud.dialogflow.v2.EntityTypes], [Webhooks][google.cloud.dialogflow.v2.WebhookRequest], and so on to // manage the flow of a conversation and match user input to predefined intents // and actions. // // You can create an agent using both Dialogflow Standard Edition and // Dialogflow Enterprise Edition. For details, see // Dialogflow // Editions (at https://cloud.google.com/dialogflow/docs/editions). // // You can save your agent for backup or versioning by exporting the agent by // using the [ExportAgent][google.cloud.dialogflow.v2.Agents.ExportAgent] method. You can import a saved // agent by using the [ImportAgent][google.cloud.dialogflow.v2.Agents.ImportAgent] method. // // Dialogflow provides several // prebuilt // agents (at https://cloud.google.com/dialogflow/docs/agents-prebuilt) // for common conversation scenarios such as determining a date and time, // converting currency, and so on. // // For more information about agents, see the // Dialogflow // documentation (at https://cloud.google.com/dialogflow/docs/agents-overview). func NewAgentsClient(ctx context.Context, opts ...option.ClientOption) (*AgentsClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultAgentsClientOptions(), opts...)...) if err != nil { return nil, err } c := &AgentsClient{ conn: conn, CallOptions: defaultAgentsCallOptions(), agentsClient: dialogflowpb.NewAgentsClient(conn), } c.setGoogleClientInfo() c.LROClient, err = lroauto.NewOperationsClient(ctx, option.WithGRPCConn(conn)) if err != nil { // This error "should not happen", since we are just reusing old connection // and never actually need to dial. // If this does happen, we could leak conn. However, we cannot close conn: // If the user invoked the function with option.WithGRPCConn, // we would close a connection that's still in use. // TODO(pongad): investigate error conditions. return nil, err } return c, nil } // Connection returns the client's connection to the API service. func (c *AgentsClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *AgentsClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *AgentsClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // SetAgent creates/updates the specified agent. func (c *AgentsClient) SetAgent(ctx context.Context, req *dialogflowpb.SetAgentRequest, opts ...gax.CallOption) (*dialogflowpb.Agent, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "agent.parent", url.QueryEscape(req.GetAgent().GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.SetAgent[0:len(c.CallOptions.SetAgent):len(c.CallOptions.SetAgent)], opts...) var resp *dialogflowpb.Agent err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.agentsClient.SetAgent(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteAgent deletes the specified agent. func (c *AgentsClient) DeleteAgent(ctx context.Context, req *dialogflowpb.DeleteAgentRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteAgent[0:len(c.CallOptions.DeleteAgent):len(c.CallOptions.DeleteAgent)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.agentsClient.DeleteAgent(ctx, req, settings.GRPC...) return err }, opts...) return err } // GetAgent retrieves the specified agent. func (c *AgentsClient) GetAgent(ctx context.Context, req *dialogflowpb.GetAgentRequest, opts ...gax.CallOption) (*dialogflowpb.Agent, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetAgent[0:len(c.CallOptions.GetAgent):len(c.CallOptions.GetAgent)], opts...) var resp *dialogflowpb.Agent err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.agentsClient.GetAgent(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // SearchAgents returns the list of agents. // // Since there is at most one conversational agent per project, this method is // useful primarily for listing all agents across projects the caller has // access to. One can achieve that with a wildcard project collection id "-". // Refer to List // Sub-Collections (at https://cloud.google.com/apis/design/design_patterns#list_sub-collections). func (c *AgentsClient) SearchAgents(ctx context.Context, req *dialogflowpb.SearchAgentsRequest, opts ...gax.CallOption) *AgentIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.SearchAgents[0:len(c.CallOptions.SearchAgents):len(c.CallOptions.SearchAgents)], opts...) it := &AgentIterator{} req = proto.Clone(req).(*dialogflowpb.SearchAgentsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*dialogflowpb.Agent, string, error) { var resp *dialogflowpb.SearchAgentsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.agentsClient.SearchAgents(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Agents, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // TrainAgent trains the specified agent. // // Operation func (c *AgentsClient) TrainAgent(ctx context.Context, req *dialogflowpb.TrainAgentRequest, opts ...gax.CallOption) (*TrainAgentOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.TrainAgent[0:len(c.CallOptions.TrainAgent):len(c.CallOptions.TrainAgent)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.agentsClient.TrainAgent(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &TrainAgentOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // ExportAgent exports the specified agent to a ZIP file. // // Operation func (c *AgentsClient) ExportAgent(ctx context.Context, req *dialogflowpb.ExportAgentRequest, opts ...gax.CallOption) (*ExportAgentOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ExportAgent[0:len(c.CallOptions.ExportAgent):len(c.CallOptions.ExportAgent)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.agentsClient.ExportAgent(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &ExportAgentOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // ImportAgent imports the specified agent from a ZIP file. // // Uploads new intents and entity types without deleting the existing ones. // Intents and entity types with the same name are replaced with the new // versions from ImportAgentRequest. // // Operation func (c *AgentsClient) ImportAgent(ctx context.Context, req *dialogflowpb.ImportAgentRequest, opts ...gax.CallOption) (*ImportAgentOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ImportAgent[0:len(c.CallOptions.ImportAgent):len(c.CallOptions.ImportAgent)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.agentsClient.ImportAgent(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &ImportAgentOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // RestoreAgent restores the specified agent from a ZIP file. // // Replaces the current agent version with a new one. All the intents and // entity types in the older version are deleted. // // Operation func (c *AgentsClient) RestoreAgent(ctx context.Context, req *dialogflowpb.RestoreAgentRequest, opts ...gax.CallOption) (*RestoreAgentOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.RestoreAgent[0:len(c.CallOptions.RestoreAgent):len(c.CallOptions.RestoreAgent)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.agentsClient.RestoreAgent(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &RestoreAgentOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // AgentIterator manages a stream of *dialogflowpb.Agent. type AgentIterator struct { items []*dialogflowpb.Agent pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*dialogflowpb.Agent, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *AgentIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *AgentIterator) Next() (*dialogflowpb.Agent, error) { var item *dialogflowpb.Agent if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *AgentIterator) bufLen() int { return len(it.items) } func (it *AgentIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // ExportAgentOperation manages a long-running operation from ExportAgent. type ExportAgentOperation struct { lro *longrunning.Operation } // ExportAgentOperation returns a new ExportAgentOperation from a given name. // The name must be that of a previously created ExportAgentOperation, possibly from a different process. func (c *AgentsClient) ExportAgentOperation(name string) *ExportAgentOperation { return &ExportAgentOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *ExportAgentOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*dialogflowpb.ExportAgentResponse, error) { var resp dialogflowpb.ExportAgentResponse if err := op.lro.WaitWithInterval(ctx, &resp, 5000*time.Millisecond, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *ExportAgentOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*dialogflowpb.ExportAgentResponse, error) { var resp dialogflowpb.ExportAgentResponse if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *ExportAgentOperation) Metadata() (*structpbpb.Struct, error) { var meta structpbpb.Struct if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *ExportAgentOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *ExportAgentOperation) Name() string { return op.lro.Name() } // ImportAgentOperation manages a long-running operation from ImportAgent. type ImportAgentOperation struct { lro *longrunning.Operation } // ImportAgentOperation returns a new ImportAgentOperation from a given name. // The name must be that of a previously created ImportAgentOperation, possibly from a different process. func (c *AgentsClient) ImportAgentOperation(name string) *ImportAgentOperation { return &ImportAgentOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning any error encountered. // // See documentation of Poll for error-handling information. func (op *ImportAgentOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { return op.lro.WaitWithInterval(ctx, nil, 5000*time.Millisecond, opts...) } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, op.Done will return true. func (op *ImportAgentOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Poll(ctx, nil, opts...) } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *ImportAgentOperation) Metadata() (*structpbpb.Struct, error) { var meta structpbpb.Struct if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *ImportAgentOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *ImportAgentOperation) Name() string { return op.lro.Name() } // RestoreAgentOperation manages a long-running operation from RestoreAgent. type RestoreAgentOperation struct { lro *longrunning.Operation } // RestoreAgentOperation returns a new RestoreAgentOperation from a given name. // The name must be that of a previously created RestoreAgentOperation, possibly from a different process. func (c *AgentsClient) RestoreAgentOperation(name string) *RestoreAgentOperation { return &RestoreAgentOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning any error encountered. // // See documentation of Poll for error-handling information. func (op *RestoreAgentOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { return op.lro.WaitWithInterval(ctx, nil, 5000*time.Millisecond, opts...) } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, op.Done will return true. func (op *RestoreAgentOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Poll(ctx, nil, opts...) } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *RestoreAgentOperation) Metadata() (*structpbpb.Struct, error) { var meta structpbpb.Struct if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *RestoreAgentOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *RestoreAgentOperation) Name() string { return op.lro.Name() } // TrainAgentOperation manages a long-running operation from TrainAgent. type TrainAgentOperation struct { lro *longrunning.Operation } // TrainAgentOperation returns a new TrainAgentOperation from a given name. // The name must be that of a previously created TrainAgentOperation, possibly from a different process. func (c *AgentsClient) TrainAgentOperation(name string) *TrainAgentOperation { return &TrainAgentOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning any error encountered. // // See documentation of Poll for error-handling information. func (op *TrainAgentOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { return op.lro.WaitWithInterval(ctx, nil, 5000*time.Millisecond, opts...) } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, op.Done will return true. func (op *TrainAgentOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Poll(ctx, nil, opts...) } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *TrainAgentOperation) Metadata() (*structpbpb.Struct, error) { var meta structpbpb.Struct if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *TrainAgentOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *TrainAgentOperation) Name() string { return op.lro.Name() } google-cloud-go-0.49.0/dialogflow/apiv2/agents_client_example_test.go000066400000000000000000000077011356504100700256650ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package dialogflow_test import ( "context" dialogflow "cloud.google.com/go/dialogflow/apiv2" "google.golang.org/api/iterator" dialogflowpb "google.golang.org/genproto/googleapis/cloud/dialogflow/v2" ) func ExampleNewAgentsClient() { ctx := context.Background() c, err := dialogflow.NewAgentsClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleAgentsClient_SetAgent() { ctx := context.Background() c, err := dialogflow.NewAgentsClient(ctx) if err != nil { // TODO: Handle error. } req := &dialogflowpb.SetAgentRequest{ // TODO: Fill request struct fields. } resp, err := c.SetAgent(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleAgentsClient_DeleteAgent() { ctx := context.Background() c, err := dialogflow.NewAgentsClient(ctx) if err != nil { // TODO: Handle error. } req := &dialogflowpb.DeleteAgentRequest{ // TODO: Fill request struct fields. } err = c.DeleteAgent(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleAgentsClient_GetAgent() { ctx := context.Background() c, err := dialogflow.NewAgentsClient(ctx) if err != nil { // TODO: Handle error. } req := &dialogflowpb.GetAgentRequest{ // TODO: Fill request struct fields. } resp, err := c.GetAgent(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleAgentsClient_SearchAgents() { ctx := context.Background() c, err := dialogflow.NewAgentsClient(ctx) if err != nil { // TODO: Handle error. } req := &dialogflowpb.SearchAgentsRequest{ // TODO: Fill request struct fields. } it := c.SearchAgents(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleAgentsClient_TrainAgent() { ctx := context.Background() c, err := dialogflow.NewAgentsClient(ctx) if err != nil { // TODO: Handle error. } req := &dialogflowpb.TrainAgentRequest{ // TODO: Fill request struct fields. } op, err := c.TrainAgent(ctx, req) if err != nil { // TODO: Handle error. } err = op.Wait(ctx) // TODO: Handle error. } func ExampleAgentsClient_ExportAgent() { ctx := context.Background() c, err := dialogflow.NewAgentsClient(ctx) if err != nil { // TODO: Handle error. } req := &dialogflowpb.ExportAgentRequest{ // TODO: Fill request struct fields. } op, err := c.ExportAgent(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleAgentsClient_ImportAgent() { ctx := context.Background() c, err := dialogflow.NewAgentsClient(ctx) if err != nil { // TODO: Handle error. } req := &dialogflowpb.ImportAgentRequest{ // TODO: Fill request struct fields. } op, err := c.ImportAgent(ctx, req) if err != nil { // TODO: Handle error. } err = op.Wait(ctx) // TODO: Handle error. } func ExampleAgentsClient_RestoreAgent() { ctx := context.Background() c, err := dialogflow.NewAgentsClient(ctx) if err != nil { // TODO: Handle error. } req := &dialogflowpb.RestoreAgentRequest{ // TODO: Fill request struct fields. } op, err := c.RestoreAgent(ctx, req) if err != nil { // TODO: Handle error. } err = op.Wait(ctx) // TODO: Handle error. } google-cloud-go-0.49.0/dialogflow/apiv2/contexts_client.go000066400000000000000000000275141356504100700235050ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package dialogflow import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" dialogflowpb "google.golang.org/genproto/googleapis/cloud/dialogflow/v2" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // ContextsCallOptions contains the retry settings for each method of ContextsClient. type ContextsCallOptions struct { ListContexts []gax.CallOption GetContext []gax.CallOption CreateContext []gax.CallOption UpdateContext []gax.CallOption DeleteContext []gax.CallOption DeleteAllContexts []gax.CallOption } func defaultContextsClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("dialogflow.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultContextsCallOptions() *ContextsCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &ContextsCallOptions{ ListContexts: retry[[2]string{"default", "idempotent"}], GetContext: retry[[2]string{"default", "idempotent"}], CreateContext: retry[[2]string{"default", "non_idempotent"}], UpdateContext: retry[[2]string{"default", "non_idempotent"}], DeleteContext: retry[[2]string{"default", "idempotent"}], DeleteAllContexts: retry[[2]string{"default", "idempotent"}], } } // ContextsClient is a client for interacting with Dialogflow API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type ContextsClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. contextsClient dialogflowpb.ContextsClient // The call options for this service. CallOptions *ContextsCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewContextsClient creates a new contexts client. // // A context represents additional information included with user input or with // an intent returned by the Dialogflow API. Contexts are helpful for // differentiating user input which may be vague or have a different meaning // depending on additional details from your application such as user setting // and preferences, previous user input, where the user is in your application, // geographic location, and so on. // // You can include contexts as input parameters of a // [DetectIntent][google.cloud.dialogflow.v2.Sessions.DetectIntent] (or // [StreamingDetectIntent][google.cloud.dialogflow.v2.Sessions.StreamingDetectIntent]) request, // or as output contexts included in the returned intent. // Contexts expire when an intent is matched, after the number of DetectIntent // requests specified by the lifespan_count parameter, or after 20 minutes // if no intents are matched for a DetectIntent request. // // For more information about contexts, see the // Dialogflow // documentation (at https://cloud.google.com/dialogflow/docs/contexts-overview). func NewContextsClient(ctx context.Context, opts ...option.ClientOption) (*ContextsClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultContextsClientOptions(), opts...)...) if err != nil { return nil, err } c := &ContextsClient{ conn: conn, CallOptions: defaultContextsCallOptions(), contextsClient: dialogflowpb.NewContextsClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *ContextsClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *ContextsClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *ContextsClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // ListContexts returns the list of all contexts in the specified session. func (c *ContextsClient) ListContexts(ctx context.Context, req *dialogflowpb.ListContextsRequest, opts ...gax.CallOption) *ContextIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListContexts[0:len(c.CallOptions.ListContexts):len(c.CallOptions.ListContexts)], opts...) it := &ContextIterator{} req = proto.Clone(req).(*dialogflowpb.ListContextsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*dialogflowpb.Context, string, error) { var resp *dialogflowpb.ListContextsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.contextsClient.ListContexts(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Contexts, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetContext retrieves the specified context. func (c *ContextsClient) GetContext(ctx context.Context, req *dialogflowpb.GetContextRequest, opts ...gax.CallOption) (*dialogflowpb.Context, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetContext[0:len(c.CallOptions.GetContext):len(c.CallOptions.GetContext)], opts...) var resp *dialogflowpb.Context err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.contextsClient.GetContext(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateContext creates a context. // // If the specified context already exists, overrides the context. func (c *ContextsClient) CreateContext(ctx context.Context, req *dialogflowpb.CreateContextRequest, opts ...gax.CallOption) (*dialogflowpb.Context, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateContext[0:len(c.CallOptions.CreateContext):len(c.CallOptions.CreateContext)], opts...) var resp *dialogflowpb.Context err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.contextsClient.CreateContext(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateContext updates the specified context. func (c *ContextsClient) UpdateContext(ctx context.Context, req *dialogflowpb.UpdateContextRequest, opts ...gax.CallOption) (*dialogflowpb.Context, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "context.name", url.QueryEscape(req.GetContext().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateContext[0:len(c.CallOptions.UpdateContext):len(c.CallOptions.UpdateContext)], opts...) var resp *dialogflowpb.Context err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.contextsClient.UpdateContext(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteContext deletes the specified context. func (c *ContextsClient) DeleteContext(ctx context.Context, req *dialogflowpb.DeleteContextRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteContext[0:len(c.CallOptions.DeleteContext):len(c.CallOptions.DeleteContext)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.contextsClient.DeleteContext(ctx, req, settings.GRPC...) return err }, opts...) return err } // DeleteAllContexts deletes all active contexts in the specified session. func (c *ContextsClient) DeleteAllContexts(ctx context.Context, req *dialogflowpb.DeleteAllContextsRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteAllContexts[0:len(c.CallOptions.DeleteAllContexts):len(c.CallOptions.DeleteAllContexts)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.contextsClient.DeleteAllContexts(ctx, req, settings.GRPC...) return err }, opts...) return err } // ContextIterator manages a stream of *dialogflowpb.Context. type ContextIterator struct { items []*dialogflowpb.Context pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*dialogflowpb.Context, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *ContextIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *ContextIterator) Next() (*dialogflowpb.Context, error) { var item *dialogflowpb.Context if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *ContextIterator) bufLen() int { return len(it.items) } func (it *ContextIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/dialogflow/apiv2/contexts_client_example_test.go000066400000000000000000000062571356504100700262600ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package dialogflow_test import ( "context" dialogflow "cloud.google.com/go/dialogflow/apiv2" "google.golang.org/api/iterator" dialogflowpb "google.golang.org/genproto/googleapis/cloud/dialogflow/v2" ) func ExampleNewContextsClient() { ctx := context.Background() c, err := dialogflow.NewContextsClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleContextsClient_ListContexts() { ctx := context.Background() c, err := dialogflow.NewContextsClient(ctx) if err != nil { // TODO: Handle error. } req := &dialogflowpb.ListContextsRequest{ // TODO: Fill request struct fields. } it := c.ListContexts(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleContextsClient_GetContext() { ctx := context.Background() c, err := dialogflow.NewContextsClient(ctx) if err != nil { // TODO: Handle error. } req := &dialogflowpb.GetContextRequest{ // TODO: Fill request struct fields. } resp, err := c.GetContext(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleContextsClient_CreateContext() { ctx := context.Background() c, err := dialogflow.NewContextsClient(ctx) if err != nil { // TODO: Handle error. } req := &dialogflowpb.CreateContextRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateContext(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleContextsClient_UpdateContext() { ctx := context.Background() c, err := dialogflow.NewContextsClient(ctx) if err != nil { // TODO: Handle error. } req := &dialogflowpb.UpdateContextRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateContext(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleContextsClient_DeleteContext() { ctx := context.Background() c, err := dialogflow.NewContextsClient(ctx) if err != nil { // TODO: Handle error. } req := &dialogflowpb.DeleteContextRequest{ // TODO: Fill request struct fields. } err = c.DeleteContext(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleContextsClient_DeleteAllContexts() { ctx := context.Background() c, err := dialogflow.NewContextsClient(ctx) if err != nil { // TODO: Handle error. } req := &dialogflowpb.DeleteAllContextsRequest{ // TODO: Fill request struct fields. } err = c.DeleteAllContexts(ctx, req) if err != nil { // TODO: Handle error. } } google-cloud-go-0.49.0/dialogflow/apiv2/doc.go000066400000000000000000000054541356504100700210440ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package dialogflow is an auto-generated package for the // Dialogflow API. // // NOTE: This package is in alpha. It is not stable, and is likely to change. // // Builds conversational interfaces (for example, chatbots, and voice-powered // apps and devices). // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package dialogflow // import "cloud.google.com/go/dialogflow/apiv2" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/dialogflow", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191115" google-cloud-go-0.49.0/dialogflow/apiv2/entity_types_client.go000066400000000000000000000760041356504100700243740ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package dialogflow import ( "context" "fmt" "math" "net/url" "time" "cloud.google.com/go/longrunning" lroauto "cloud.google.com/go/longrunning/autogen" "github.com/golang/protobuf/proto" structpbpb "github.com/golang/protobuf/ptypes/struct" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" dialogflowpb "google.golang.org/genproto/googleapis/cloud/dialogflow/v2" longrunningpb "google.golang.org/genproto/googleapis/longrunning" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // EntityTypesCallOptions contains the retry settings for each method of EntityTypesClient. type EntityTypesCallOptions struct { ListEntityTypes []gax.CallOption GetEntityType []gax.CallOption CreateEntityType []gax.CallOption UpdateEntityType []gax.CallOption DeleteEntityType []gax.CallOption BatchUpdateEntityTypes []gax.CallOption BatchDeleteEntityTypes []gax.CallOption BatchCreateEntities []gax.CallOption BatchUpdateEntities []gax.CallOption BatchDeleteEntities []gax.CallOption } func defaultEntityTypesClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("dialogflow.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultEntityTypesCallOptions() *EntityTypesCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &EntityTypesCallOptions{ ListEntityTypes: retry[[2]string{"default", "idempotent"}], GetEntityType: retry[[2]string{"default", "idempotent"}], CreateEntityType: retry[[2]string{"default", "non_idempotent"}], UpdateEntityType: retry[[2]string{"default", "non_idempotent"}], DeleteEntityType: retry[[2]string{"default", "idempotent"}], BatchUpdateEntityTypes: retry[[2]string{"default", "non_idempotent"}], BatchDeleteEntityTypes: retry[[2]string{"default", "idempotent"}], BatchCreateEntities: retry[[2]string{"default", "non_idempotent"}], BatchUpdateEntities: retry[[2]string{"default", "non_idempotent"}], BatchDeleteEntities: retry[[2]string{"default", "idempotent"}], } } // EntityTypesClient is a client for interacting with Dialogflow API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type EntityTypesClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. entityTypesClient dialogflowpb.EntityTypesClient // LROClient is used internally to handle longrunning operations. // It is exposed so that its CallOptions can be modified if required. // Users should not Close this client. LROClient *lroauto.OperationsClient // The call options for this service. CallOptions *EntityTypesCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewEntityTypesClient creates a new entity types client. // // Entities are extracted from user input and represent parameters that are // meaningful to your application. For example, a date range, a proper name // such as a geographic location or landmark, and so on. Entities represent // actionable data for your application. // // When you define an entity, you can also include synonyms that all map to // that entity. For example, "soft drink", "soda", "pop", and so on. // // There are three types of entities: // // * **System** - entities that are defined by the Dialogflow API for common // data types such as date, time, currency, and so on. A system entity is // represented by the `EntityType` type. // // * **Developer** - entities that are defined by you that represent // actionable data that is meaningful to your application. For example, // you could define a `pizza.sauce` entity for red or white pizza sauce, // a `pizza.cheese` entity for the different types of cheese on a pizza, // a `pizza.topping` entity for different toppings, and so on. A developer // entity is represented by the `EntityType` type. // // * **User** - entities that are built for an individual user such as // favorites, preferences, playlists, and so on. A user entity is // represented by the [SessionEntityType][google.cloud.dialogflow.v2.SessionEntityType] type. // // For more information about entity types, see the // [Dialogflow // documentation](https://cloud.google.com/dialogflow/docs/entities-overview). func NewEntityTypesClient(ctx context.Context, opts ...option.ClientOption) (*EntityTypesClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultEntityTypesClientOptions(), opts...)...) if err != nil { return nil, err } c := &EntityTypesClient{ conn: conn, CallOptions: defaultEntityTypesCallOptions(), entityTypesClient: dialogflowpb.NewEntityTypesClient(conn), } c.setGoogleClientInfo() c.LROClient, err = lroauto.NewOperationsClient(ctx, option.WithGRPCConn(conn)) if err != nil { // This error "should not happen", since we are just reusing old connection // and never actually need to dial. // If this does happen, we could leak conn. However, we cannot close conn: // If the user invoked the function with option.WithGRPCConn, // we would close a connection that's still in use. // TODO(pongad): investigate error conditions. return nil, err } return c, nil } // Connection returns the client's connection to the API service. func (c *EntityTypesClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *EntityTypesClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *EntityTypesClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // ListEntityTypes returns the list of all entity types in the specified agent. func (c *EntityTypesClient) ListEntityTypes(ctx context.Context, req *dialogflowpb.ListEntityTypesRequest, opts ...gax.CallOption) *EntityTypeIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListEntityTypes[0:len(c.CallOptions.ListEntityTypes):len(c.CallOptions.ListEntityTypes)], opts...) it := &EntityTypeIterator{} req = proto.Clone(req).(*dialogflowpb.ListEntityTypesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*dialogflowpb.EntityType, string, error) { var resp *dialogflowpb.ListEntityTypesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.entityTypesClient.ListEntityTypes(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.EntityTypes, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetEntityType retrieves the specified entity type. func (c *EntityTypesClient) GetEntityType(ctx context.Context, req *dialogflowpb.GetEntityTypeRequest, opts ...gax.CallOption) (*dialogflowpb.EntityType, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetEntityType[0:len(c.CallOptions.GetEntityType):len(c.CallOptions.GetEntityType)], opts...) var resp *dialogflowpb.EntityType err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.entityTypesClient.GetEntityType(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateEntityType creates an entity type in the specified agent. func (c *EntityTypesClient) CreateEntityType(ctx context.Context, req *dialogflowpb.CreateEntityTypeRequest, opts ...gax.CallOption) (*dialogflowpb.EntityType, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateEntityType[0:len(c.CallOptions.CreateEntityType):len(c.CallOptions.CreateEntityType)], opts...) var resp *dialogflowpb.EntityType err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.entityTypesClient.CreateEntityType(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateEntityType updates the specified entity type. func (c *EntityTypesClient) UpdateEntityType(ctx context.Context, req *dialogflowpb.UpdateEntityTypeRequest, opts ...gax.CallOption) (*dialogflowpb.EntityType, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "entity_type.name", url.QueryEscape(req.GetEntityType().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateEntityType[0:len(c.CallOptions.UpdateEntityType):len(c.CallOptions.UpdateEntityType)], opts...) var resp *dialogflowpb.EntityType err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.entityTypesClient.UpdateEntityType(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteEntityType deletes the specified entity type. func (c *EntityTypesClient) DeleteEntityType(ctx context.Context, req *dialogflowpb.DeleteEntityTypeRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteEntityType[0:len(c.CallOptions.DeleteEntityType):len(c.CallOptions.DeleteEntityType)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.entityTypesClient.DeleteEntityType(ctx, req, settings.GRPC...) return err }, opts...) return err } // BatchUpdateEntityTypes updates/Creates multiple entity types in the specified agent. // // Operation func (c *EntityTypesClient) BatchUpdateEntityTypes(ctx context.Context, req *dialogflowpb.BatchUpdateEntityTypesRequest, opts ...gax.CallOption) (*BatchUpdateEntityTypesOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.BatchUpdateEntityTypes[0:len(c.CallOptions.BatchUpdateEntityTypes):len(c.CallOptions.BatchUpdateEntityTypes)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.entityTypesClient.BatchUpdateEntityTypes(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &BatchUpdateEntityTypesOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // BatchDeleteEntityTypes deletes entity types in the specified agent. // // Operation func (c *EntityTypesClient) BatchDeleteEntityTypes(ctx context.Context, req *dialogflowpb.BatchDeleteEntityTypesRequest, opts ...gax.CallOption) (*BatchDeleteEntityTypesOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.BatchDeleteEntityTypes[0:len(c.CallOptions.BatchDeleteEntityTypes):len(c.CallOptions.BatchDeleteEntityTypes)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.entityTypesClient.BatchDeleteEntityTypes(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &BatchDeleteEntityTypesOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // BatchCreateEntities creates multiple new entities in the specified entity type. // // Operation func (c *EntityTypesClient) BatchCreateEntities(ctx context.Context, req *dialogflowpb.BatchCreateEntitiesRequest, opts ...gax.CallOption) (*BatchCreateEntitiesOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.BatchCreateEntities[0:len(c.CallOptions.BatchCreateEntities):len(c.CallOptions.BatchCreateEntities)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.entityTypesClient.BatchCreateEntities(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &BatchCreateEntitiesOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // BatchUpdateEntities updates or creates multiple entities in the specified entity type. This // method does not affect entities in the entity type that aren't explicitly // specified in the request. // // Operation func (c *EntityTypesClient) BatchUpdateEntities(ctx context.Context, req *dialogflowpb.BatchUpdateEntitiesRequest, opts ...gax.CallOption) (*BatchUpdateEntitiesOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.BatchUpdateEntities[0:len(c.CallOptions.BatchUpdateEntities):len(c.CallOptions.BatchUpdateEntities)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.entityTypesClient.BatchUpdateEntities(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &BatchUpdateEntitiesOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // BatchDeleteEntities deletes entities in the specified entity type. // // Operation func (c *EntityTypesClient) BatchDeleteEntities(ctx context.Context, req *dialogflowpb.BatchDeleteEntitiesRequest, opts ...gax.CallOption) (*BatchDeleteEntitiesOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.BatchDeleteEntities[0:len(c.CallOptions.BatchDeleteEntities):len(c.CallOptions.BatchDeleteEntities)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.entityTypesClient.BatchDeleteEntities(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &BatchDeleteEntitiesOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // EntityTypeIterator manages a stream of *dialogflowpb.EntityType. type EntityTypeIterator struct { items []*dialogflowpb.EntityType pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*dialogflowpb.EntityType, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *EntityTypeIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *EntityTypeIterator) Next() (*dialogflowpb.EntityType, error) { var item *dialogflowpb.EntityType if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *EntityTypeIterator) bufLen() int { return len(it.items) } func (it *EntityTypeIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // BatchCreateEntitiesOperation manages a long-running operation from BatchCreateEntities. type BatchCreateEntitiesOperation struct { lro *longrunning.Operation } // BatchCreateEntitiesOperation returns a new BatchCreateEntitiesOperation from a given name. // The name must be that of a previously created BatchCreateEntitiesOperation, possibly from a different process. func (c *EntityTypesClient) BatchCreateEntitiesOperation(name string) *BatchCreateEntitiesOperation { return &BatchCreateEntitiesOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning any error encountered. // // See documentation of Poll for error-handling information. func (op *BatchCreateEntitiesOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { return op.lro.WaitWithInterval(ctx, nil, 5000*time.Millisecond, opts...) } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, op.Done will return true. func (op *BatchCreateEntitiesOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Poll(ctx, nil, opts...) } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *BatchCreateEntitiesOperation) Metadata() (*structpbpb.Struct, error) { var meta structpbpb.Struct if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *BatchCreateEntitiesOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *BatchCreateEntitiesOperation) Name() string { return op.lro.Name() } // BatchDeleteEntitiesOperation manages a long-running operation from BatchDeleteEntities. type BatchDeleteEntitiesOperation struct { lro *longrunning.Operation } // BatchDeleteEntitiesOperation returns a new BatchDeleteEntitiesOperation from a given name. // The name must be that of a previously created BatchDeleteEntitiesOperation, possibly from a different process. func (c *EntityTypesClient) BatchDeleteEntitiesOperation(name string) *BatchDeleteEntitiesOperation { return &BatchDeleteEntitiesOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning any error encountered. // // See documentation of Poll for error-handling information. func (op *BatchDeleteEntitiesOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { return op.lro.WaitWithInterval(ctx, nil, 5000*time.Millisecond, opts...) } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, op.Done will return true. func (op *BatchDeleteEntitiesOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Poll(ctx, nil, opts...) } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *BatchDeleteEntitiesOperation) Metadata() (*structpbpb.Struct, error) { var meta structpbpb.Struct if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *BatchDeleteEntitiesOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *BatchDeleteEntitiesOperation) Name() string { return op.lro.Name() } // BatchDeleteEntityTypesOperation manages a long-running operation from BatchDeleteEntityTypes. type BatchDeleteEntityTypesOperation struct { lro *longrunning.Operation } // BatchDeleteEntityTypesOperation returns a new BatchDeleteEntityTypesOperation from a given name. // The name must be that of a previously created BatchDeleteEntityTypesOperation, possibly from a different process. func (c *EntityTypesClient) BatchDeleteEntityTypesOperation(name string) *BatchDeleteEntityTypesOperation { return &BatchDeleteEntityTypesOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning any error encountered. // // See documentation of Poll for error-handling information. func (op *BatchDeleteEntityTypesOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { return op.lro.WaitWithInterval(ctx, nil, 5000*time.Millisecond, opts...) } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, op.Done will return true. func (op *BatchDeleteEntityTypesOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Poll(ctx, nil, opts...) } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *BatchDeleteEntityTypesOperation) Metadata() (*structpbpb.Struct, error) { var meta structpbpb.Struct if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *BatchDeleteEntityTypesOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *BatchDeleteEntityTypesOperation) Name() string { return op.lro.Name() } // BatchUpdateEntitiesOperation manages a long-running operation from BatchUpdateEntities. type BatchUpdateEntitiesOperation struct { lro *longrunning.Operation } // BatchUpdateEntitiesOperation returns a new BatchUpdateEntitiesOperation from a given name. // The name must be that of a previously created BatchUpdateEntitiesOperation, possibly from a different process. func (c *EntityTypesClient) BatchUpdateEntitiesOperation(name string) *BatchUpdateEntitiesOperation { return &BatchUpdateEntitiesOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning any error encountered. // // See documentation of Poll for error-handling information. func (op *BatchUpdateEntitiesOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { return op.lro.WaitWithInterval(ctx, nil, 5000*time.Millisecond, opts...) } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, op.Done will return true. func (op *BatchUpdateEntitiesOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Poll(ctx, nil, opts...) } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *BatchUpdateEntitiesOperation) Metadata() (*structpbpb.Struct, error) { var meta structpbpb.Struct if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *BatchUpdateEntitiesOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *BatchUpdateEntitiesOperation) Name() string { return op.lro.Name() } // BatchUpdateEntityTypesOperation manages a long-running operation from BatchUpdateEntityTypes. type BatchUpdateEntityTypesOperation struct { lro *longrunning.Operation } // BatchUpdateEntityTypesOperation returns a new BatchUpdateEntityTypesOperation from a given name. // The name must be that of a previously created BatchUpdateEntityTypesOperation, possibly from a different process. func (c *EntityTypesClient) BatchUpdateEntityTypesOperation(name string) *BatchUpdateEntityTypesOperation { return &BatchUpdateEntityTypesOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *BatchUpdateEntityTypesOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*dialogflowpb.BatchUpdateEntityTypesResponse, error) { var resp dialogflowpb.BatchUpdateEntityTypesResponse if err := op.lro.WaitWithInterval(ctx, &resp, 5000*time.Millisecond, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *BatchUpdateEntityTypesOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*dialogflowpb.BatchUpdateEntityTypesResponse, error) { var resp dialogflowpb.BatchUpdateEntityTypesResponse if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *BatchUpdateEntityTypesOperation) Metadata() (*structpbpb.Struct, error) { var meta structpbpb.Struct if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *BatchUpdateEntityTypesOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *BatchUpdateEntityTypesOperation) Name() string { return op.lro.Name() } google-cloud-go-0.49.0/dialogflow/apiv2/entity_types_client_example_test.go000066400000000000000000000117421356504100700271440ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package dialogflow_test import ( "context" dialogflow "cloud.google.com/go/dialogflow/apiv2" "google.golang.org/api/iterator" dialogflowpb "google.golang.org/genproto/googleapis/cloud/dialogflow/v2" ) func ExampleNewEntityTypesClient() { ctx := context.Background() c, err := dialogflow.NewEntityTypesClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleEntityTypesClient_ListEntityTypes() { ctx := context.Background() c, err := dialogflow.NewEntityTypesClient(ctx) if err != nil { // TODO: Handle error. } req := &dialogflowpb.ListEntityTypesRequest{ // TODO: Fill request struct fields. } it := c.ListEntityTypes(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleEntityTypesClient_GetEntityType() { ctx := context.Background() c, err := dialogflow.NewEntityTypesClient(ctx) if err != nil { // TODO: Handle error. } req := &dialogflowpb.GetEntityTypeRequest{ // TODO: Fill request struct fields. } resp, err := c.GetEntityType(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleEntityTypesClient_CreateEntityType() { ctx := context.Background() c, err := dialogflow.NewEntityTypesClient(ctx) if err != nil { // TODO: Handle error. } req := &dialogflowpb.CreateEntityTypeRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateEntityType(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleEntityTypesClient_UpdateEntityType() { ctx := context.Background() c, err := dialogflow.NewEntityTypesClient(ctx) if err != nil { // TODO: Handle error. } req := &dialogflowpb.UpdateEntityTypeRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateEntityType(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleEntityTypesClient_DeleteEntityType() { ctx := context.Background() c, err := dialogflow.NewEntityTypesClient(ctx) if err != nil { // TODO: Handle error. } req := &dialogflowpb.DeleteEntityTypeRequest{ // TODO: Fill request struct fields. } err = c.DeleteEntityType(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleEntityTypesClient_BatchUpdateEntityTypes() { ctx := context.Background() c, err := dialogflow.NewEntityTypesClient(ctx) if err != nil { // TODO: Handle error. } req := &dialogflowpb.BatchUpdateEntityTypesRequest{ // TODO: Fill request struct fields. } op, err := c.BatchUpdateEntityTypes(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleEntityTypesClient_BatchDeleteEntityTypes() { ctx := context.Background() c, err := dialogflow.NewEntityTypesClient(ctx) if err != nil { // TODO: Handle error. } req := &dialogflowpb.BatchDeleteEntityTypesRequest{ // TODO: Fill request struct fields. } op, err := c.BatchDeleteEntityTypes(ctx, req) if err != nil { // TODO: Handle error. } err = op.Wait(ctx) // TODO: Handle error. } func ExampleEntityTypesClient_BatchCreateEntities() { ctx := context.Background() c, err := dialogflow.NewEntityTypesClient(ctx) if err != nil { // TODO: Handle error. } req := &dialogflowpb.BatchCreateEntitiesRequest{ // TODO: Fill request struct fields. } op, err := c.BatchCreateEntities(ctx, req) if err != nil { // TODO: Handle error. } err = op.Wait(ctx) // TODO: Handle error. } func ExampleEntityTypesClient_BatchUpdateEntities() { ctx := context.Background() c, err := dialogflow.NewEntityTypesClient(ctx) if err != nil { // TODO: Handle error. } req := &dialogflowpb.BatchUpdateEntitiesRequest{ // TODO: Fill request struct fields. } op, err := c.BatchUpdateEntities(ctx, req) if err != nil { // TODO: Handle error. } err = op.Wait(ctx) // TODO: Handle error. } func ExampleEntityTypesClient_BatchDeleteEntities() { ctx := context.Background() c, err := dialogflow.NewEntityTypesClient(ctx) if err != nil { // TODO: Handle error. } req := &dialogflowpb.BatchDeleteEntitiesRequest{ // TODO: Fill request struct fields. } op, err := c.BatchDeleteEntities(ctx, req) if err != nil { // TODO: Handle error. } err = op.Wait(ctx) // TODO: Handle error. } google-cloud-go-0.49.0/dialogflow/apiv2/intents_client.go000066400000000000000000000500111356504100700233060ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package dialogflow import ( "context" "fmt" "math" "net/url" "time" "cloud.google.com/go/longrunning" lroauto "cloud.google.com/go/longrunning/autogen" "github.com/golang/protobuf/proto" structpbpb "github.com/golang/protobuf/ptypes/struct" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" dialogflowpb "google.golang.org/genproto/googleapis/cloud/dialogflow/v2" longrunningpb "google.golang.org/genproto/googleapis/longrunning" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // IntentsCallOptions contains the retry settings for each method of IntentsClient. type IntentsCallOptions struct { ListIntents []gax.CallOption GetIntent []gax.CallOption CreateIntent []gax.CallOption UpdateIntent []gax.CallOption DeleteIntent []gax.CallOption BatchUpdateIntents []gax.CallOption BatchDeleteIntents []gax.CallOption } func defaultIntentsClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("dialogflow.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultIntentsCallOptions() *IntentsCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &IntentsCallOptions{ ListIntents: retry[[2]string{"default", "idempotent"}], GetIntent: retry[[2]string{"default", "idempotent"}], CreateIntent: retry[[2]string{"default", "non_idempotent"}], UpdateIntent: retry[[2]string{"default", "non_idempotent"}], DeleteIntent: retry[[2]string{"default", "idempotent"}], BatchUpdateIntents: retry[[2]string{"default", "non_idempotent"}], BatchDeleteIntents: retry[[2]string{"default", "idempotent"}], } } // IntentsClient is a client for interacting with Dialogflow API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type IntentsClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. intentsClient dialogflowpb.IntentsClient // LROClient is used internally to handle longrunning operations. // It is exposed so that its CallOptions can be modified if required. // Users should not Close this client. LROClient *lroauto.OperationsClient // The call options for this service. CallOptions *IntentsCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewIntentsClient creates a new intents client. // // An intent represents a mapping between input from a user and an action to // be taken by your application. When you pass user input to the // [DetectIntent][google.cloud.dialogflow.v2.Sessions.DetectIntent] (or // [StreamingDetectIntent][google.cloud.dialogflow.v2.Sessions.StreamingDetectIntent]) method, the // Dialogflow API analyzes the input and searches // for a matching intent. If no match is found, the Dialogflow API returns a // fallback intent (`is_fallback` = true). // // You can provide additional information for the Dialogflow API to use to // match user input to an intent by adding the following to your intent. // // * **Contexts** - provide additional context for intent analysis. For // example, if an intent is related to an object in your application that // plays music, you can provide a context to determine when to match the // intent if the user input is "turn it off". You can include a context // that matches the intent when there is previous user input of // "play music", and not when there is previous user input of // "turn on the light". // // * **Events** - allow for matching an intent by using an event name // instead of user input. Your application can provide an event name and // related parameters to the Dialogflow API to match an intent. For // example, when your application starts, you can send a welcome event // with a user name parameter to the Dialogflow API to match an intent with // a personalized welcome message for the user. // // * **Training phrases** - provide examples of user input to train the // Dialogflow API agent to better match intents. // // For more information about intents, see the // [Dialogflow // documentation](https://cloud.google.com/dialogflow/docs/intents-overview). func NewIntentsClient(ctx context.Context, opts ...option.ClientOption) (*IntentsClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultIntentsClientOptions(), opts...)...) if err != nil { return nil, err } c := &IntentsClient{ conn: conn, CallOptions: defaultIntentsCallOptions(), intentsClient: dialogflowpb.NewIntentsClient(conn), } c.setGoogleClientInfo() c.LROClient, err = lroauto.NewOperationsClient(ctx, option.WithGRPCConn(conn)) if err != nil { // This error "should not happen", since we are just reusing old connection // and never actually need to dial. // If this does happen, we could leak conn. However, we cannot close conn: // If the user invoked the function with option.WithGRPCConn, // we would close a connection that's still in use. // TODO(pongad): investigate error conditions. return nil, err } return c, nil } // Connection returns the client's connection to the API service. func (c *IntentsClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *IntentsClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *IntentsClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // ListIntents returns the list of all intents in the specified agent. func (c *IntentsClient) ListIntents(ctx context.Context, req *dialogflowpb.ListIntentsRequest, opts ...gax.CallOption) *IntentIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListIntents[0:len(c.CallOptions.ListIntents):len(c.CallOptions.ListIntents)], opts...) it := &IntentIterator{} req = proto.Clone(req).(*dialogflowpb.ListIntentsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*dialogflowpb.Intent, string, error) { var resp *dialogflowpb.ListIntentsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.intentsClient.ListIntents(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Intents, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetIntent retrieves the specified intent. func (c *IntentsClient) GetIntent(ctx context.Context, req *dialogflowpb.GetIntentRequest, opts ...gax.CallOption) (*dialogflowpb.Intent, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetIntent[0:len(c.CallOptions.GetIntent):len(c.CallOptions.GetIntent)], opts...) var resp *dialogflowpb.Intent err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.intentsClient.GetIntent(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateIntent creates an intent in the specified agent. func (c *IntentsClient) CreateIntent(ctx context.Context, req *dialogflowpb.CreateIntentRequest, opts ...gax.CallOption) (*dialogflowpb.Intent, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateIntent[0:len(c.CallOptions.CreateIntent):len(c.CallOptions.CreateIntent)], opts...) var resp *dialogflowpb.Intent err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.intentsClient.CreateIntent(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateIntent updates the specified intent. func (c *IntentsClient) UpdateIntent(ctx context.Context, req *dialogflowpb.UpdateIntentRequest, opts ...gax.CallOption) (*dialogflowpb.Intent, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "intent.name", url.QueryEscape(req.GetIntent().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateIntent[0:len(c.CallOptions.UpdateIntent):len(c.CallOptions.UpdateIntent)], opts...) var resp *dialogflowpb.Intent err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.intentsClient.UpdateIntent(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteIntent deletes the specified intent and its direct or indirect followup intents. func (c *IntentsClient) DeleteIntent(ctx context.Context, req *dialogflowpb.DeleteIntentRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteIntent[0:len(c.CallOptions.DeleteIntent):len(c.CallOptions.DeleteIntent)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.intentsClient.DeleteIntent(ctx, req, settings.GRPC...) return err }, opts...) return err } // BatchUpdateIntents updates/Creates multiple intents in the specified agent. // // Operation func (c *IntentsClient) BatchUpdateIntents(ctx context.Context, req *dialogflowpb.BatchUpdateIntentsRequest, opts ...gax.CallOption) (*BatchUpdateIntentsOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.BatchUpdateIntents[0:len(c.CallOptions.BatchUpdateIntents):len(c.CallOptions.BatchUpdateIntents)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.intentsClient.BatchUpdateIntents(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &BatchUpdateIntentsOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // BatchDeleteIntents deletes intents in the specified agent. // // Operation func (c *IntentsClient) BatchDeleteIntents(ctx context.Context, req *dialogflowpb.BatchDeleteIntentsRequest, opts ...gax.CallOption) (*BatchDeleteIntentsOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.BatchDeleteIntents[0:len(c.CallOptions.BatchDeleteIntents):len(c.CallOptions.BatchDeleteIntents)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.intentsClient.BatchDeleteIntents(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &BatchDeleteIntentsOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // IntentIterator manages a stream of *dialogflowpb.Intent. type IntentIterator struct { items []*dialogflowpb.Intent pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*dialogflowpb.Intent, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *IntentIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *IntentIterator) Next() (*dialogflowpb.Intent, error) { var item *dialogflowpb.Intent if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *IntentIterator) bufLen() int { return len(it.items) } func (it *IntentIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // BatchDeleteIntentsOperation manages a long-running operation from BatchDeleteIntents. type BatchDeleteIntentsOperation struct { lro *longrunning.Operation } // BatchDeleteIntentsOperation returns a new BatchDeleteIntentsOperation from a given name. // The name must be that of a previously created BatchDeleteIntentsOperation, possibly from a different process. func (c *IntentsClient) BatchDeleteIntentsOperation(name string) *BatchDeleteIntentsOperation { return &BatchDeleteIntentsOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning any error encountered. // // See documentation of Poll for error-handling information. func (op *BatchDeleteIntentsOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { return op.lro.WaitWithInterval(ctx, nil, 5000*time.Millisecond, opts...) } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, op.Done will return true. func (op *BatchDeleteIntentsOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Poll(ctx, nil, opts...) } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *BatchDeleteIntentsOperation) Metadata() (*structpbpb.Struct, error) { var meta structpbpb.Struct if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *BatchDeleteIntentsOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *BatchDeleteIntentsOperation) Name() string { return op.lro.Name() } // BatchUpdateIntentsOperation manages a long-running operation from BatchUpdateIntents. type BatchUpdateIntentsOperation struct { lro *longrunning.Operation } // BatchUpdateIntentsOperation returns a new BatchUpdateIntentsOperation from a given name. // The name must be that of a previously created BatchUpdateIntentsOperation, possibly from a different process. func (c *IntentsClient) BatchUpdateIntentsOperation(name string) *BatchUpdateIntentsOperation { return &BatchUpdateIntentsOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *BatchUpdateIntentsOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*dialogflowpb.BatchUpdateIntentsResponse, error) { var resp dialogflowpb.BatchUpdateIntentsResponse if err := op.lro.WaitWithInterval(ctx, &resp, 5000*time.Millisecond, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *BatchUpdateIntentsOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*dialogflowpb.BatchUpdateIntentsResponse, error) { var resp dialogflowpb.BatchUpdateIntentsResponse if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *BatchUpdateIntentsOperation) Metadata() (*structpbpb.Struct, error) { var meta structpbpb.Struct if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *BatchUpdateIntentsOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *BatchUpdateIntentsOperation) Name() string { return op.lro.Name() } google-cloud-go-0.49.0/dialogflow/apiv2/intents_client_example_test.go000066400000000000000000000072141356504100700260670ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package dialogflow_test import ( "context" dialogflow "cloud.google.com/go/dialogflow/apiv2" "google.golang.org/api/iterator" dialogflowpb "google.golang.org/genproto/googleapis/cloud/dialogflow/v2" ) func ExampleNewIntentsClient() { ctx := context.Background() c, err := dialogflow.NewIntentsClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleIntentsClient_ListIntents() { ctx := context.Background() c, err := dialogflow.NewIntentsClient(ctx) if err != nil { // TODO: Handle error. } req := &dialogflowpb.ListIntentsRequest{ // TODO: Fill request struct fields. } it := c.ListIntents(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleIntentsClient_GetIntent() { ctx := context.Background() c, err := dialogflow.NewIntentsClient(ctx) if err != nil { // TODO: Handle error. } req := &dialogflowpb.GetIntentRequest{ // TODO: Fill request struct fields. } resp, err := c.GetIntent(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIntentsClient_CreateIntent() { ctx := context.Background() c, err := dialogflow.NewIntentsClient(ctx) if err != nil { // TODO: Handle error. } req := &dialogflowpb.CreateIntentRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateIntent(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIntentsClient_UpdateIntent() { ctx := context.Background() c, err := dialogflow.NewIntentsClient(ctx) if err != nil { // TODO: Handle error. } req := &dialogflowpb.UpdateIntentRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateIntent(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIntentsClient_DeleteIntent() { ctx := context.Background() c, err := dialogflow.NewIntentsClient(ctx) if err != nil { // TODO: Handle error. } req := &dialogflowpb.DeleteIntentRequest{ // TODO: Fill request struct fields. } err = c.DeleteIntent(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleIntentsClient_BatchUpdateIntents() { ctx := context.Background() c, err := dialogflow.NewIntentsClient(ctx) if err != nil { // TODO: Handle error. } req := &dialogflowpb.BatchUpdateIntentsRequest{ // TODO: Fill request struct fields. } op, err := c.BatchUpdateIntents(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIntentsClient_BatchDeleteIntents() { ctx := context.Background() c, err := dialogflow.NewIntentsClient(ctx) if err != nil { // TODO: Handle error. } req := &dialogflowpb.BatchDeleteIntentsRequest{ // TODO: Fill request struct fields. } op, err := c.BatchDeleteIntents(ctx, req) if err != nil { // TODO: Handle error. } err = op.Wait(ctx) // TODO: Handle error. } google-cloud-go-0.49.0/dialogflow/apiv2/mock_test.go000066400000000000000000002746751356504100700223040ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package dialogflow import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" "google.golang.org/api/option" dialogflowpb "google.golang.org/genproto/googleapis/cloud/dialogflow/v2" longrunningpb "google.golang.org/genproto/googleapis/longrunning" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockAgentsServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. dialogflowpb.AgentsServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockAgentsServer) GetAgent(ctx context.Context, req *dialogflowpb.GetAgentRequest) (*dialogflowpb.Agent, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dialogflowpb.Agent), nil } func (s *mockAgentsServer) SetAgent(ctx context.Context, req *dialogflowpb.SetAgentRequest) (*dialogflowpb.Agent, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dialogflowpb.Agent), nil } func (s *mockAgentsServer) DeleteAgent(ctx context.Context, req *dialogflowpb.DeleteAgentRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockAgentsServer) SearchAgents(ctx context.Context, req *dialogflowpb.SearchAgentsRequest) (*dialogflowpb.SearchAgentsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dialogflowpb.SearchAgentsResponse), nil } func (s *mockAgentsServer) TrainAgent(ctx context.Context, req *dialogflowpb.TrainAgentRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockAgentsServer) ExportAgent(ctx context.Context, req *dialogflowpb.ExportAgentRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockAgentsServer) ImportAgent(ctx context.Context, req *dialogflowpb.ImportAgentRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockAgentsServer) RestoreAgent(ctx context.Context, req *dialogflowpb.RestoreAgentRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } type mockContextsServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. dialogflowpb.ContextsServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockContextsServer) ListContexts(ctx context.Context, req *dialogflowpb.ListContextsRequest) (*dialogflowpb.ListContextsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dialogflowpb.ListContextsResponse), nil } func (s *mockContextsServer) GetContext(ctx context.Context, req *dialogflowpb.GetContextRequest) (*dialogflowpb.Context, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dialogflowpb.Context), nil } func (s *mockContextsServer) CreateContext(ctx context.Context, req *dialogflowpb.CreateContextRequest) (*dialogflowpb.Context, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dialogflowpb.Context), nil } func (s *mockContextsServer) UpdateContext(ctx context.Context, req *dialogflowpb.UpdateContextRequest) (*dialogflowpb.Context, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dialogflowpb.Context), nil } func (s *mockContextsServer) DeleteContext(ctx context.Context, req *dialogflowpb.DeleteContextRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockContextsServer) DeleteAllContexts(ctx context.Context, req *dialogflowpb.DeleteAllContextsRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } type mockEntityTypesServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. dialogflowpb.EntityTypesServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockEntityTypesServer) ListEntityTypes(ctx context.Context, req *dialogflowpb.ListEntityTypesRequest) (*dialogflowpb.ListEntityTypesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dialogflowpb.ListEntityTypesResponse), nil } func (s *mockEntityTypesServer) GetEntityType(ctx context.Context, req *dialogflowpb.GetEntityTypeRequest) (*dialogflowpb.EntityType, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dialogflowpb.EntityType), nil } func (s *mockEntityTypesServer) CreateEntityType(ctx context.Context, req *dialogflowpb.CreateEntityTypeRequest) (*dialogflowpb.EntityType, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dialogflowpb.EntityType), nil } func (s *mockEntityTypesServer) UpdateEntityType(ctx context.Context, req *dialogflowpb.UpdateEntityTypeRequest) (*dialogflowpb.EntityType, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dialogflowpb.EntityType), nil } func (s *mockEntityTypesServer) DeleteEntityType(ctx context.Context, req *dialogflowpb.DeleteEntityTypeRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockEntityTypesServer) BatchUpdateEntityTypes(ctx context.Context, req *dialogflowpb.BatchUpdateEntityTypesRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockEntityTypesServer) BatchDeleteEntityTypes(ctx context.Context, req *dialogflowpb.BatchDeleteEntityTypesRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockEntityTypesServer) BatchCreateEntities(ctx context.Context, req *dialogflowpb.BatchCreateEntitiesRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockEntityTypesServer) BatchUpdateEntities(ctx context.Context, req *dialogflowpb.BatchUpdateEntitiesRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockEntityTypesServer) BatchDeleteEntities(ctx context.Context, req *dialogflowpb.BatchDeleteEntitiesRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } type mockIntentsServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. dialogflowpb.IntentsServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockIntentsServer) ListIntents(ctx context.Context, req *dialogflowpb.ListIntentsRequest) (*dialogflowpb.ListIntentsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dialogflowpb.ListIntentsResponse), nil } func (s *mockIntentsServer) GetIntent(ctx context.Context, req *dialogflowpb.GetIntentRequest) (*dialogflowpb.Intent, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dialogflowpb.Intent), nil } func (s *mockIntentsServer) CreateIntent(ctx context.Context, req *dialogflowpb.CreateIntentRequest) (*dialogflowpb.Intent, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dialogflowpb.Intent), nil } func (s *mockIntentsServer) UpdateIntent(ctx context.Context, req *dialogflowpb.UpdateIntentRequest) (*dialogflowpb.Intent, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dialogflowpb.Intent), nil } func (s *mockIntentsServer) DeleteIntent(ctx context.Context, req *dialogflowpb.DeleteIntentRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockIntentsServer) BatchUpdateIntents(ctx context.Context, req *dialogflowpb.BatchUpdateIntentsRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockIntentsServer) BatchDeleteIntents(ctx context.Context, req *dialogflowpb.BatchDeleteIntentsRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } type mockSessionEntityTypesServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. dialogflowpb.SessionEntityTypesServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockSessionEntityTypesServer) ListSessionEntityTypes(ctx context.Context, req *dialogflowpb.ListSessionEntityTypesRequest) (*dialogflowpb.ListSessionEntityTypesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dialogflowpb.ListSessionEntityTypesResponse), nil } func (s *mockSessionEntityTypesServer) GetSessionEntityType(ctx context.Context, req *dialogflowpb.GetSessionEntityTypeRequest) (*dialogflowpb.SessionEntityType, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dialogflowpb.SessionEntityType), nil } func (s *mockSessionEntityTypesServer) CreateSessionEntityType(ctx context.Context, req *dialogflowpb.CreateSessionEntityTypeRequest) (*dialogflowpb.SessionEntityType, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dialogflowpb.SessionEntityType), nil } func (s *mockSessionEntityTypesServer) UpdateSessionEntityType(ctx context.Context, req *dialogflowpb.UpdateSessionEntityTypeRequest) (*dialogflowpb.SessionEntityType, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dialogflowpb.SessionEntityType), nil } func (s *mockSessionEntityTypesServer) DeleteSessionEntityType(ctx context.Context, req *dialogflowpb.DeleteSessionEntityTypeRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } type mockSessionsServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. dialogflowpb.SessionsServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockSessionsServer) DetectIntent(ctx context.Context, req *dialogflowpb.DetectIntentRequest) (*dialogflowpb.DetectIntentResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dialogflowpb.DetectIntentResponse), nil } func (s *mockSessionsServer) StreamingDetectIntent(stream dialogflowpb.Sessions_StreamingDetectIntentServer) error { md, _ := metadata.FromIncomingContext(stream.Context()) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } for { if req, err := stream.Recv(); err == io.EOF { break } else if err != nil { return err } else { s.reqs = append(s.reqs, req) } } if s.err != nil { return s.err } for _, v := range s.resps { if err := stream.Send(v.(*dialogflowpb.StreamingDetectIntentResponse)); err != nil { return err } } return nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockAgents mockAgentsServer mockContexts mockContextsServer mockEntityTypes mockEntityTypesServer mockIntents mockIntentsServer mockSessionEntityTypes mockSessionEntityTypesServer mockSessions mockSessionsServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() dialogflowpb.RegisterAgentsServer(serv, &mockAgents) dialogflowpb.RegisterContextsServer(serv, &mockContexts) dialogflowpb.RegisterEntityTypesServer(serv, &mockEntityTypes) dialogflowpb.RegisterIntentsServer(serv, &mockIntents) dialogflowpb.RegisterSessionEntityTypesServer(serv, &mockSessionEntityTypes) dialogflowpb.RegisterSessionsServer(serv, &mockSessions) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestAgentsSetAgent(t *testing.T) { var parent string = "parent-995424086" var displayName string = "displayName1615086568" var defaultLanguageCode string = "defaultLanguageCode856575222" var timeZone string = "timeZone36848094" var description string = "description-1724546052" var avatarUri string = "avatarUri-402824826" var enableLogging bool = false var classificationThreshold float32 = 1.11581064e8 var expectedResponse = &dialogflowpb.Agent{ Parent: parent, DisplayName: displayName, DefaultLanguageCode: defaultLanguageCode, TimeZone: timeZone, Description: description, AvatarUri: avatarUri, EnableLogging: enableLogging, ClassificationThreshold: classificationThreshold, } mockAgents.err = nil mockAgents.reqs = nil mockAgents.resps = append(mockAgents.resps[:0], expectedResponse) var agent *dialogflowpb.Agent = &dialogflowpb.Agent{} var request = &dialogflowpb.SetAgentRequest{ Agent: agent, } c, err := NewAgentsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetAgent(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockAgents.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAgentsSetAgentError(t *testing.T) { errCode := codes.PermissionDenied mockAgents.err = gstatus.Error(errCode, "test error") var agent *dialogflowpb.Agent = &dialogflowpb.Agent{} var request = &dialogflowpb.SetAgentRequest{ Agent: agent, } c, err := NewAgentsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetAgent(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAgentsDeleteAgent(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockAgents.err = nil mockAgents.reqs = nil mockAgents.resps = append(mockAgents.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &dialogflowpb.DeleteAgentRequest{ Parent: formattedParent, } c, err := NewAgentsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteAgent(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockAgents.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestAgentsDeleteAgentError(t *testing.T) { errCode := codes.PermissionDenied mockAgents.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &dialogflowpb.DeleteAgentRequest{ Parent: formattedParent, } c, err := NewAgentsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteAgent(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestAgentsGetAgent(t *testing.T) { var parent2 string = "parent21175163357" var displayName string = "displayName1615086568" var defaultLanguageCode string = "defaultLanguageCode856575222" var timeZone string = "timeZone36848094" var description string = "description-1724546052" var avatarUri string = "avatarUri-402824826" var enableLogging bool = false var classificationThreshold float32 = 1.11581064e8 var expectedResponse = &dialogflowpb.Agent{ Parent: parent2, DisplayName: displayName, DefaultLanguageCode: defaultLanguageCode, TimeZone: timeZone, Description: description, AvatarUri: avatarUri, EnableLogging: enableLogging, ClassificationThreshold: classificationThreshold, } mockAgents.err = nil mockAgents.reqs = nil mockAgents.resps = append(mockAgents.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &dialogflowpb.GetAgentRequest{ Parent: formattedParent, } c, err := NewAgentsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetAgent(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockAgents.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAgentsGetAgentError(t *testing.T) { errCode := codes.PermissionDenied mockAgents.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &dialogflowpb.GetAgentRequest{ Parent: formattedParent, } c, err := NewAgentsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetAgent(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAgentsSearchAgents(t *testing.T) { var nextPageToken string = "" var agentsElement *dialogflowpb.Agent = &dialogflowpb.Agent{} var agents = []*dialogflowpb.Agent{agentsElement} var expectedResponse = &dialogflowpb.SearchAgentsResponse{ NextPageToken: nextPageToken, Agents: agents, } mockAgents.err = nil mockAgents.reqs = nil mockAgents.resps = append(mockAgents.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &dialogflowpb.SearchAgentsRequest{ Parent: formattedParent, } c, err := NewAgentsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SearchAgents(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockAgents.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Agents[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAgentsSearchAgentsError(t *testing.T) { errCode := codes.PermissionDenied mockAgents.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &dialogflowpb.SearchAgentsRequest{ Parent: formattedParent, } c, err := NewAgentsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SearchAgents(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAgentsTrainAgent(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockAgents.err = nil mockAgents.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockAgents.resps = append(mockAgents.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &dialogflowpb.TrainAgentRequest{ Parent: formattedParent, } c, err := NewAgentsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.TrainAgent(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockAgents.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestAgentsTrainAgentError(t *testing.T) { errCode := codes.PermissionDenied mockAgents.err = nil mockAgents.resps = append(mockAgents.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &dialogflowpb.TrainAgentRequest{ Parent: formattedParent, } c, err := NewAgentsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.TrainAgent(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestAgentsExportAgent(t *testing.T) { var agentUri string = "agentUri-1700713166" var expectedResponse = &dialogflowpb.ExportAgentResponse{ Agent: &dialogflowpb.ExportAgentResponse_AgentUri{ AgentUri: agentUri, }, } mockAgents.err = nil mockAgents.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockAgents.resps = append(mockAgents.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &dialogflowpb.ExportAgentRequest{ Parent: formattedParent, } c, err := NewAgentsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.ExportAgent(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockAgents.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAgentsExportAgentError(t *testing.T) { errCode := codes.PermissionDenied mockAgents.err = nil mockAgents.resps = append(mockAgents.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &dialogflowpb.ExportAgentRequest{ Parent: formattedParent, } c, err := NewAgentsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.ExportAgent(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAgentsImportAgent(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockAgents.err = nil mockAgents.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockAgents.resps = append(mockAgents.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &dialogflowpb.ImportAgentRequest{ Parent: formattedParent, } c, err := NewAgentsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.ImportAgent(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockAgents.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestAgentsImportAgentError(t *testing.T) { errCode := codes.PermissionDenied mockAgents.err = nil mockAgents.resps = append(mockAgents.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &dialogflowpb.ImportAgentRequest{ Parent: formattedParent, } c, err := NewAgentsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.ImportAgent(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestAgentsRestoreAgent(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockAgents.err = nil mockAgents.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockAgents.resps = append(mockAgents.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &dialogflowpb.RestoreAgentRequest{ Parent: formattedParent, } c, err := NewAgentsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.RestoreAgent(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockAgents.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestAgentsRestoreAgentError(t *testing.T) { errCode := codes.PermissionDenied mockAgents.err = nil mockAgents.resps = append(mockAgents.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &dialogflowpb.RestoreAgentRequest{ Parent: formattedParent, } c, err := NewAgentsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.RestoreAgent(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestContextsListContexts(t *testing.T) { var nextPageToken string = "" var contextsElement *dialogflowpb.Context = &dialogflowpb.Context{} var contexts = []*dialogflowpb.Context{contextsElement} var expectedResponse = &dialogflowpb.ListContextsResponse{ NextPageToken: nextPageToken, Contexts: contexts, } mockContexts.err = nil mockContexts.reqs = nil mockContexts.resps = append(mockContexts.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/agent/sessions/%s", "[PROJECT]", "[SESSION]") var request = &dialogflowpb.ListContextsRequest{ Parent: formattedParent, } c, err := NewContextsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListContexts(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockContexts.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Contexts[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestContextsListContextsError(t *testing.T) { errCode := codes.PermissionDenied mockContexts.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/agent/sessions/%s", "[PROJECT]", "[SESSION]") var request = &dialogflowpb.ListContextsRequest{ Parent: formattedParent, } c, err := NewContextsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListContexts(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestContextsGetContext(t *testing.T) { var name2 string = "name2-1052831874" var lifespanCount int32 = 1178775510 var expectedResponse = &dialogflowpb.Context{ Name: name2, LifespanCount: lifespanCount, } mockContexts.err = nil mockContexts.reqs = nil mockContexts.resps = append(mockContexts.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/agent/sessions/%s/contexts/%s", "[PROJECT]", "[SESSION]", "[CONTEXT]") var request = &dialogflowpb.GetContextRequest{ Name: formattedName, } c, err := NewContextsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetContext(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockContexts.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestContextsGetContextError(t *testing.T) { errCode := codes.PermissionDenied mockContexts.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/agent/sessions/%s/contexts/%s", "[PROJECT]", "[SESSION]", "[CONTEXT]") var request = &dialogflowpb.GetContextRequest{ Name: formattedName, } c, err := NewContextsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetContext(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestContextsCreateContext(t *testing.T) { var name string = "name3373707" var lifespanCount int32 = 1178775510 var expectedResponse = &dialogflowpb.Context{ Name: name, LifespanCount: lifespanCount, } mockContexts.err = nil mockContexts.reqs = nil mockContexts.resps = append(mockContexts.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/agent/sessions/%s", "[PROJECT]", "[SESSION]") var context_ *dialogflowpb.Context = &dialogflowpb.Context{} var request = &dialogflowpb.CreateContextRequest{ Parent: formattedParent, Context: context_, } c, err := NewContextsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateContext(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockContexts.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestContextsCreateContextError(t *testing.T) { errCode := codes.PermissionDenied mockContexts.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/agent/sessions/%s", "[PROJECT]", "[SESSION]") var context_ *dialogflowpb.Context = &dialogflowpb.Context{} var request = &dialogflowpb.CreateContextRequest{ Parent: formattedParent, Context: context_, } c, err := NewContextsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateContext(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestContextsUpdateContext(t *testing.T) { var name string = "name3373707" var lifespanCount int32 = 1178775510 var expectedResponse = &dialogflowpb.Context{ Name: name, LifespanCount: lifespanCount, } mockContexts.err = nil mockContexts.reqs = nil mockContexts.resps = append(mockContexts.resps[:0], expectedResponse) var context_ *dialogflowpb.Context = &dialogflowpb.Context{} var request = &dialogflowpb.UpdateContextRequest{ Context: context_, } c, err := NewContextsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateContext(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockContexts.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestContextsUpdateContextError(t *testing.T) { errCode := codes.PermissionDenied mockContexts.err = gstatus.Error(errCode, "test error") var context_ *dialogflowpb.Context = &dialogflowpb.Context{} var request = &dialogflowpb.UpdateContextRequest{ Context: context_, } c, err := NewContextsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateContext(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestContextsDeleteContext(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockContexts.err = nil mockContexts.reqs = nil mockContexts.resps = append(mockContexts.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/agent/sessions/%s/contexts/%s", "[PROJECT]", "[SESSION]", "[CONTEXT]") var request = &dialogflowpb.DeleteContextRequest{ Name: formattedName, } c, err := NewContextsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteContext(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockContexts.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestContextsDeleteContextError(t *testing.T) { errCode := codes.PermissionDenied mockContexts.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/agent/sessions/%s/contexts/%s", "[PROJECT]", "[SESSION]", "[CONTEXT]") var request = &dialogflowpb.DeleteContextRequest{ Name: formattedName, } c, err := NewContextsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteContext(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestContextsDeleteAllContexts(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockContexts.err = nil mockContexts.reqs = nil mockContexts.resps = append(mockContexts.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/agent/sessions/%s", "[PROJECT]", "[SESSION]") var request = &dialogflowpb.DeleteAllContextsRequest{ Parent: formattedParent, } c, err := NewContextsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteAllContexts(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockContexts.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestContextsDeleteAllContextsError(t *testing.T) { errCode := codes.PermissionDenied mockContexts.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/agent/sessions/%s", "[PROJECT]", "[SESSION]") var request = &dialogflowpb.DeleteAllContextsRequest{ Parent: formattedParent, } c, err := NewContextsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteAllContexts(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestEntityTypesListEntityTypes(t *testing.T) { var nextPageToken string = "" var entityTypesElement *dialogflowpb.EntityType = &dialogflowpb.EntityType{} var entityTypes = []*dialogflowpb.EntityType{entityTypesElement} var expectedResponse = &dialogflowpb.ListEntityTypesResponse{ NextPageToken: nextPageToken, EntityTypes: entityTypes, } mockEntityTypes.err = nil mockEntityTypes.reqs = nil mockEntityTypes.resps = append(mockEntityTypes.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/agent", "[PROJECT]") var request = &dialogflowpb.ListEntityTypesRequest{ Parent: formattedParent, } c, err := NewEntityTypesClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListEntityTypes(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockEntityTypes.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.EntityTypes[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestEntityTypesListEntityTypesError(t *testing.T) { errCode := codes.PermissionDenied mockEntityTypes.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/agent", "[PROJECT]") var request = &dialogflowpb.ListEntityTypesRequest{ Parent: formattedParent, } c, err := NewEntityTypesClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListEntityTypes(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestEntityTypesGetEntityType(t *testing.T) { var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var enableFuzzyExtraction bool = true var expectedResponse = &dialogflowpb.EntityType{ Name: name2, DisplayName: displayName, EnableFuzzyExtraction: enableFuzzyExtraction, } mockEntityTypes.err = nil mockEntityTypes.reqs = nil mockEntityTypes.resps = append(mockEntityTypes.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/agent/entityTypes/%s", "[PROJECT]", "[ENTITY_TYPE]") var request = &dialogflowpb.GetEntityTypeRequest{ Name: formattedName, } c, err := NewEntityTypesClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetEntityType(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockEntityTypes.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestEntityTypesGetEntityTypeError(t *testing.T) { errCode := codes.PermissionDenied mockEntityTypes.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/agent/entityTypes/%s", "[PROJECT]", "[ENTITY_TYPE]") var request = &dialogflowpb.GetEntityTypeRequest{ Name: formattedName, } c, err := NewEntityTypesClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetEntityType(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestEntityTypesCreateEntityType(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var enableFuzzyExtraction bool = true var expectedResponse = &dialogflowpb.EntityType{ Name: name, DisplayName: displayName, EnableFuzzyExtraction: enableFuzzyExtraction, } mockEntityTypes.err = nil mockEntityTypes.reqs = nil mockEntityTypes.resps = append(mockEntityTypes.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/agent", "[PROJECT]") var entityType *dialogflowpb.EntityType = &dialogflowpb.EntityType{} var request = &dialogflowpb.CreateEntityTypeRequest{ Parent: formattedParent, EntityType: entityType, } c, err := NewEntityTypesClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateEntityType(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockEntityTypes.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestEntityTypesCreateEntityTypeError(t *testing.T) { errCode := codes.PermissionDenied mockEntityTypes.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/agent", "[PROJECT]") var entityType *dialogflowpb.EntityType = &dialogflowpb.EntityType{} var request = &dialogflowpb.CreateEntityTypeRequest{ Parent: formattedParent, EntityType: entityType, } c, err := NewEntityTypesClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateEntityType(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestEntityTypesUpdateEntityType(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var enableFuzzyExtraction bool = true var expectedResponse = &dialogflowpb.EntityType{ Name: name, DisplayName: displayName, EnableFuzzyExtraction: enableFuzzyExtraction, } mockEntityTypes.err = nil mockEntityTypes.reqs = nil mockEntityTypes.resps = append(mockEntityTypes.resps[:0], expectedResponse) var entityType *dialogflowpb.EntityType = &dialogflowpb.EntityType{} var request = &dialogflowpb.UpdateEntityTypeRequest{ EntityType: entityType, } c, err := NewEntityTypesClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateEntityType(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockEntityTypes.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestEntityTypesUpdateEntityTypeError(t *testing.T) { errCode := codes.PermissionDenied mockEntityTypes.err = gstatus.Error(errCode, "test error") var entityType *dialogflowpb.EntityType = &dialogflowpb.EntityType{} var request = &dialogflowpb.UpdateEntityTypeRequest{ EntityType: entityType, } c, err := NewEntityTypesClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateEntityType(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestEntityTypesDeleteEntityType(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockEntityTypes.err = nil mockEntityTypes.reqs = nil mockEntityTypes.resps = append(mockEntityTypes.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/agent/entityTypes/%s", "[PROJECT]", "[ENTITY_TYPE]") var request = &dialogflowpb.DeleteEntityTypeRequest{ Name: formattedName, } c, err := NewEntityTypesClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteEntityType(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockEntityTypes.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestEntityTypesDeleteEntityTypeError(t *testing.T) { errCode := codes.PermissionDenied mockEntityTypes.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/agent/entityTypes/%s", "[PROJECT]", "[ENTITY_TYPE]") var request = &dialogflowpb.DeleteEntityTypeRequest{ Name: formattedName, } c, err := NewEntityTypesClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteEntityType(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestEntityTypesBatchUpdateEntityTypes(t *testing.T) { var expectedResponse *dialogflowpb.BatchUpdateEntityTypesResponse = &dialogflowpb.BatchUpdateEntityTypesResponse{} mockEntityTypes.err = nil mockEntityTypes.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockEntityTypes.resps = append(mockEntityTypes.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedParent string = fmt.Sprintf("projects/%s/agent", "[PROJECT]") var request = &dialogflowpb.BatchUpdateEntityTypesRequest{ Parent: formattedParent, } c, err := NewEntityTypesClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.BatchUpdateEntityTypes(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockEntityTypes.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestEntityTypesBatchUpdateEntityTypesError(t *testing.T) { errCode := codes.PermissionDenied mockEntityTypes.err = nil mockEntityTypes.resps = append(mockEntityTypes.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedParent string = fmt.Sprintf("projects/%s/agent", "[PROJECT]") var request = &dialogflowpb.BatchUpdateEntityTypesRequest{ Parent: formattedParent, } c, err := NewEntityTypesClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.BatchUpdateEntityTypes(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestEntityTypesBatchDeleteEntityTypes(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockEntityTypes.err = nil mockEntityTypes.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockEntityTypes.resps = append(mockEntityTypes.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedParent string = fmt.Sprintf("projects/%s/agent", "[PROJECT]") var entityTypeNames []string = nil var request = &dialogflowpb.BatchDeleteEntityTypesRequest{ Parent: formattedParent, EntityTypeNames: entityTypeNames, } c, err := NewEntityTypesClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.BatchDeleteEntityTypes(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockEntityTypes.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestEntityTypesBatchDeleteEntityTypesError(t *testing.T) { errCode := codes.PermissionDenied mockEntityTypes.err = nil mockEntityTypes.resps = append(mockEntityTypes.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedParent string = fmt.Sprintf("projects/%s/agent", "[PROJECT]") var entityTypeNames []string = nil var request = &dialogflowpb.BatchDeleteEntityTypesRequest{ Parent: formattedParent, EntityTypeNames: entityTypeNames, } c, err := NewEntityTypesClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.BatchDeleteEntityTypes(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestEntityTypesBatchCreateEntities(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockEntityTypes.err = nil mockEntityTypes.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockEntityTypes.resps = append(mockEntityTypes.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedParent string = fmt.Sprintf("projects/%s/agent/entityTypes/%s", "[PROJECT]", "[ENTITY_TYPE]") var entities []*dialogflowpb.EntityType_Entity = nil var request = &dialogflowpb.BatchCreateEntitiesRequest{ Parent: formattedParent, Entities: entities, } c, err := NewEntityTypesClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.BatchCreateEntities(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockEntityTypes.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestEntityTypesBatchCreateEntitiesError(t *testing.T) { errCode := codes.PermissionDenied mockEntityTypes.err = nil mockEntityTypes.resps = append(mockEntityTypes.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedParent string = fmt.Sprintf("projects/%s/agent/entityTypes/%s", "[PROJECT]", "[ENTITY_TYPE]") var entities []*dialogflowpb.EntityType_Entity = nil var request = &dialogflowpb.BatchCreateEntitiesRequest{ Parent: formattedParent, Entities: entities, } c, err := NewEntityTypesClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.BatchCreateEntities(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestEntityTypesBatchUpdateEntities(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockEntityTypes.err = nil mockEntityTypes.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockEntityTypes.resps = append(mockEntityTypes.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedParent string = fmt.Sprintf("projects/%s/agent/entityTypes/%s", "[PROJECT]", "[ENTITY_TYPE]") var entities []*dialogflowpb.EntityType_Entity = nil var request = &dialogflowpb.BatchUpdateEntitiesRequest{ Parent: formattedParent, Entities: entities, } c, err := NewEntityTypesClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.BatchUpdateEntities(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockEntityTypes.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestEntityTypesBatchUpdateEntitiesError(t *testing.T) { errCode := codes.PermissionDenied mockEntityTypes.err = nil mockEntityTypes.resps = append(mockEntityTypes.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedParent string = fmt.Sprintf("projects/%s/agent/entityTypes/%s", "[PROJECT]", "[ENTITY_TYPE]") var entities []*dialogflowpb.EntityType_Entity = nil var request = &dialogflowpb.BatchUpdateEntitiesRequest{ Parent: formattedParent, Entities: entities, } c, err := NewEntityTypesClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.BatchUpdateEntities(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestEntityTypesBatchDeleteEntities(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockEntityTypes.err = nil mockEntityTypes.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockEntityTypes.resps = append(mockEntityTypes.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedParent string = fmt.Sprintf("projects/%s/agent/entityTypes/%s", "[PROJECT]", "[ENTITY_TYPE]") var entityValues []string = nil var request = &dialogflowpb.BatchDeleteEntitiesRequest{ Parent: formattedParent, EntityValues: entityValues, } c, err := NewEntityTypesClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.BatchDeleteEntities(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockEntityTypes.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestEntityTypesBatchDeleteEntitiesError(t *testing.T) { errCode := codes.PermissionDenied mockEntityTypes.err = nil mockEntityTypes.resps = append(mockEntityTypes.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedParent string = fmt.Sprintf("projects/%s/agent/entityTypes/%s", "[PROJECT]", "[ENTITY_TYPE]") var entityValues []string = nil var request = &dialogflowpb.BatchDeleteEntitiesRequest{ Parent: formattedParent, EntityValues: entityValues, } c, err := NewEntityTypesClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.BatchDeleteEntities(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestIntentsListIntents(t *testing.T) { var nextPageToken string = "" var intentsElement *dialogflowpb.Intent = &dialogflowpb.Intent{} var intents = []*dialogflowpb.Intent{intentsElement} var expectedResponse = &dialogflowpb.ListIntentsResponse{ NextPageToken: nextPageToken, Intents: intents, } mockIntents.err = nil mockIntents.reqs = nil mockIntents.resps = append(mockIntents.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/agent", "[PROJECT]") var request = &dialogflowpb.ListIntentsRequest{ Parent: formattedParent, } c, err := NewIntentsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListIntents(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockIntents.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Intents[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIntentsListIntentsError(t *testing.T) { errCode := codes.PermissionDenied mockIntents.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/agent", "[PROJECT]") var request = &dialogflowpb.ListIntentsRequest{ Parent: formattedParent, } c, err := NewIntentsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListIntents(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIntentsGetIntent(t *testing.T) { var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var priority int32 = 1165461084 var isFallback bool = false var mlDisabled bool = true var action string = "action-1422950858" var resetContexts bool = true var rootFollowupIntentName string = "rootFollowupIntentName402253784" var parentFollowupIntentName string = "parentFollowupIntentName-1131901680" var expectedResponse = &dialogflowpb.Intent{ Name: name2, DisplayName: displayName, Priority: priority, IsFallback: isFallback, MlDisabled: mlDisabled, Action: action, ResetContexts: resetContexts, RootFollowupIntentName: rootFollowupIntentName, ParentFollowupIntentName: parentFollowupIntentName, } mockIntents.err = nil mockIntents.reqs = nil mockIntents.resps = append(mockIntents.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/agent/intents/%s", "[PROJECT]", "[INTENT]") var request = &dialogflowpb.GetIntentRequest{ Name: formattedName, } c, err := NewIntentsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetIntent(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIntents.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIntentsGetIntentError(t *testing.T) { errCode := codes.PermissionDenied mockIntents.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/agent/intents/%s", "[PROJECT]", "[INTENT]") var request = &dialogflowpb.GetIntentRequest{ Name: formattedName, } c, err := NewIntentsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetIntent(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIntentsCreateIntent(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var priority int32 = 1165461084 var isFallback bool = false var mlDisabled bool = true var action string = "action-1422950858" var resetContexts bool = true var rootFollowupIntentName string = "rootFollowupIntentName402253784" var parentFollowupIntentName string = "parentFollowupIntentName-1131901680" var expectedResponse = &dialogflowpb.Intent{ Name: name, DisplayName: displayName, Priority: priority, IsFallback: isFallback, MlDisabled: mlDisabled, Action: action, ResetContexts: resetContexts, RootFollowupIntentName: rootFollowupIntentName, ParentFollowupIntentName: parentFollowupIntentName, } mockIntents.err = nil mockIntents.reqs = nil mockIntents.resps = append(mockIntents.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/agent", "[PROJECT]") var intent *dialogflowpb.Intent = &dialogflowpb.Intent{} var request = &dialogflowpb.CreateIntentRequest{ Parent: formattedParent, Intent: intent, } c, err := NewIntentsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateIntent(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIntents.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIntentsCreateIntentError(t *testing.T) { errCode := codes.PermissionDenied mockIntents.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/agent", "[PROJECT]") var intent *dialogflowpb.Intent = &dialogflowpb.Intent{} var request = &dialogflowpb.CreateIntentRequest{ Parent: formattedParent, Intent: intent, } c, err := NewIntentsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateIntent(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIntentsUpdateIntent(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var priority int32 = 1165461084 var isFallback bool = false var mlDisabled bool = true var action string = "action-1422950858" var resetContexts bool = true var rootFollowupIntentName string = "rootFollowupIntentName402253784" var parentFollowupIntentName string = "parentFollowupIntentName-1131901680" var expectedResponse = &dialogflowpb.Intent{ Name: name, DisplayName: displayName, Priority: priority, IsFallback: isFallback, MlDisabled: mlDisabled, Action: action, ResetContexts: resetContexts, RootFollowupIntentName: rootFollowupIntentName, ParentFollowupIntentName: parentFollowupIntentName, } mockIntents.err = nil mockIntents.reqs = nil mockIntents.resps = append(mockIntents.resps[:0], expectedResponse) var intent *dialogflowpb.Intent = &dialogflowpb.Intent{} var languageCode string = "languageCode-412800396" var request = &dialogflowpb.UpdateIntentRequest{ Intent: intent, LanguageCode: languageCode, } c, err := NewIntentsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateIntent(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIntents.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIntentsUpdateIntentError(t *testing.T) { errCode := codes.PermissionDenied mockIntents.err = gstatus.Error(errCode, "test error") var intent *dialogflowpb.Intent = &dialogflowpb.Intent{} var languageCode string = "languageCode-412800396" var request = &dialogflowpb.UpdateIntentRequest{ Intent: intent, LanguageCode: languageCode, } c, err := NewIntentsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateIntent(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIntentsDeleteIntent(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockIntents.err = nil mockIntents.reqs = nil mockIntents.resps = append(mockIntents.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/agent/intents/%s", "[PROJECT]", "[INTENT]") var request = &dialogflowpb.DeleteIntentRequest{ Name: formattedName, } c, err := NewIntentsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteIntent(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIntents.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestIntentsDeleteIntentError(t *testing.T) { errCode := codes.PermissionDenied mockIntents.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/agent/intents/%s", "[PROJECT]", "[INTENT]") var request = &dialogflowpb.DeleteIntentRequest{ Name: formattedName, } c, err := NewIntentsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteIntent(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestIntentsBatchUpdateIntents(t *testing.T) { var expectedResponse *dialogflowpb.BatchUpdateIntentsResponse = &dialogflowpb.BatchUpdateIntentsResponse{} mockIntents.err = nil mockIntents.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockIntents.resps = append(mockIntents.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedParent string = fmt.Sprintf("projects/%s/agent", "[PROJECT]") var languageCode string = "languageCode-412800396" var request = &dialogflowpb.BatchUpdateIntentsRequest{ Parent: formattedParent, LanguageCode: languageCode, } c, err := NewIntentsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.BatchUpdateIntents(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockIntents.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIntentsBatchUpdateIntentsError(t *testing.T) { errCode := codes.PermissionDenied mockIntents.err = nil mockIntents.resps = append(mockIntents.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedParent string = fmt.Sprintf("projects/%s/agent", "[PROJECT]") var languageCode string = "languageCode-412800396" var request = &dialogflowpb.BatchUpdateIntentsRequest{ Parent: formattedParent, LanguageCode: languageCode, } c, err := NewIntentsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.BatchUpdateIntents(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIntentsBatchDeleteIntents(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockIntents.err = nil mockIntents.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockIntents.resps = append(mockIntents.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedParent string = fmt.Sprintf("projects/%s/agent", "[PROJECT]") var intents []*dialogflowpb.Intent = nil var request = &dialogflowpb.BatchDeleteIntentsRequest{ Parent: formattedParent, Intents: intents, } c, err := NewIntentsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.BatchDeleteIntents(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockIntents.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestIntentsBatchDeleteIntentsError(t *testing.T) { errCode := codes.PermissionDenied mockIntents.err = nil mockIntents.resps = append(mockIntents.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedParent string = fmt.Sprintf("projects/%s/agent", "[PROJECT]") var intents []*dialogflowpb.Intent = nil var request = &dialogflowpb.BatchDeleteIntentsRequest{ Parent: formattedParent, Intents: intents, } c, err := NewIntentsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.BatchDeleteIntents(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestSessionEntityTypesListSessionEntityTypes(t *testing.T) { var nextPageToken string = "" var sessionEntityTypesElement *dialogflowpb.SessionEntityType = &dialogflowpb.SessionEntityType{} var sessionEntityTypes = []*dialogflowpb.SessionEntityType{sessionEntityTypesElement} var expectedResponse = &dialogflowpb.ListSessionEntityTypesResponse{ NextPageToken: nextPageToken, SessionEntityTypes: sessionEntityTypes, } mockSessionEntityTypes.err = nil mockSessionEntityTypes.reqs = nil mockSessionEntityTypes.resps = append(mockSessionEntityTypes.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/agent/sessions/%s", "[PROJECT]", "[SESSION]") var request = &dialogflowpb.ListSessionEntityTypesRequest{ Parent: formattedParent, } c, err := NewSessionEntityTypesClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListSessionEntityTypes(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockSessionEntityTypes.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.SessionEntityTypes[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSessionEntityTypesListSessionEntityTypesError(t *testing.T) { errCode := codes.PermissionDenied mockSessionEntityTypes.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/agent/sessions/%s", "[PROJECT]", "[SESSION]") var request = &dialogflowpb.ListSessionEntityTypesRequest{ Parent: formattedParent, } c, err := NewSessionEntityTypesClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListSessionEntityTypes(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSessionEntityTypesGetSessionEntityType(t *testing.T) { var name2 string = "name2-1052831874" var expectedResponse = &dialogflowpb.SessionEntityType{ Name: name2, } mockSessionEntityTypes.err = nil mockSessionEntityTypes.reqs = nil mockSessionEntityTypes.resps = append(mockSessionEntityTypes.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/agent/sessions/%s/entityTypes/%s", "[PROJECT]", "[SESSION]", "[ENTITY_TYPE]") var request = &dialogflowpb.GetSessionEntityTypeRequest{ Name: formattedName, } c, err := NewSessionEntityTypesClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetSessionEntityType(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSessionEntityTypes.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSessionEntityTypesGetSessionEntityTypeError(t *testing.T) { errCode := codes.PermissionDenied mockSessionEntityTypes.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/agent/sessions/%s/entityTypes/%s", "[PROJECT]", "[SESSION]", "[ENTITY_TYPE]") var request = &dialogflowpb.GetSessionEntityTypeRequest{ Name: formattedName, } c, err := NewSessionEntityTypesClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetSessionEntityType(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSessionEntityTypesCreateSessionEntityType(t *testing.T) { var name string = "name3373707" var expectedResponse = &dialogflowpb.SessionEntityType{ Name: name, } mockSessionEntityTypes.err = nil mockSessionEntityTypes.reqs = nil mockSessionEntityTypes.resps = append(mockSessionEntityTypes.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/agent/sessions/%s", "[PROJECT]", "[SESSION]") var sessionEntityType *dialogflowpb.SessionEntityType = &dialogflowpb.SessionEntityType{} var request = &dialogflowpb.CreateSessionEntityTypeRequest{ Parent: formattedParent, SessionEntityType: sessionEntityType, } c, err := NewSessionEntityTypesClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateSessionEntityType(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSessionEntityTypes.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSessionEntityTypesCreateSessionEntityTypeError(t *testing.T) { errCode := codes.PermissionDenied mockSessionEntityTypes.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/agent/sessions/%s", "[PROJECT]", "[SESSION]") var sessionEntityType *dialogflowpb.SessionEntityType = &dialogflowpb.SessionEntityType{} var request = &dialogflowpb.CreateSessionEntityTypeRequest{ Parent: formattedParent, SessionEntityType: sessionEntityType, } c, err := NewSessionEntityTypesClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateSessionEntityType(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSessionEntityTypesUpdateSessionEntityType(t *testing.T) { var name string = "name3373707" var expectedResponse = &dialogflowpb.SessionEntityType{ Name: name, } mockSessionEntityTypes.err = nil mockSessionEntityTypes.reqs = nil mockSessionEntityTypes.resps = append(mockSessionEntityTypes.resps[:0], expectedResponse) var sessionEntityType *dialogflowpb.SessionEntityType = &dialogflowpb.SessionEntityType{} var request = &dialogflowpb.UpdateSessionEntityTypeRequest{ SessionEntityType: sessionEntityType, } c, err := NewSessionEntityTypesClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateSessionEntityType(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSessionEntityTypes.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSessionEntityTypesUpdateSessionEntityTypeError(t *testing.T) { errCode := codes.PermissionDenied mockSessionEntityTypes.err = gstatus.Error(errCode, "test error") var sessionEntityType *dialogflowpb.SessionEntityType = &dialogflowpb.SessionEntityType{} var request = &dialogflowpb.UpdateSessionEntityTypeRequest{ SessionEntityType: sessionEntityType, } c, err := NewSessionEntityTypesClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateSessionEntityType(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSessionEntityTypesDeleteSessionEntityType(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockSessionEntityTypes.err = nil mockSessionEntityTypes.reqs = nil mockSessionEntityTypes.resps = append(mockSessionEntityTypes.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/agent/sessions/%s/entityTypes/%s", "[PROJECT]", "[SESSION]", "[ENTITY_TYPE]") var request = &dialogflowpb.DeleteSessionEntityTypeRequest{ Name: formattedName, } c, err := NewSessionEntityTypesClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteSessionEntityType(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSessionEntityTypes.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestSessionEntityTypesDeleteSessionEntityTypeError(t *testing.T) { errCode := codes.PermissionDenied mockSessionEntityTypes.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/agent/sessions/%s/entityTypes/%s", "[PROJECT]", "[SESSION]", "[ENTITY_TYPE]") var request = &dialogflowpb.DeleteSessionEntityTypeRequest{ Name: formattedName, } c, err := NewSessionEntityTypesClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteSessionEntityType(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestSessionsDetectIntent(t *testing.T) { var responseId string = "responseId1847552473" var outputAudio []byte = []byte("24") var expectedResponse = &dialogflowpb.DetectIntentResponse{ ResponseId: responseId, OutputAudio: outputAudio, } mockSessions.err = nil mockSessions.reqs = nil mockSessions.resps = append(mockSessions.resps[:0], expectedResponse) var formattedSession string = fmt.Sprintf("projects/%s/agent/sessions/%s", "[PROJECT]", "[SESSION]") var queryInput *dialogflowpb.QueryInput = &dialogflowpb.QueryInput{} var request = &dialogflowpb.DetectIntentRequest{ Session: formattedSession, QueryInput: queryInput, } c, err := NewSessionsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.DetectIntent(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSessions.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSessionsDetectIntentError(t *testing.T) { errCode := codes.PermissionDenied mockSessions.err = gstatus.Error(errCode, "test error") var formattedSession string = fmt.Sprintf("projects/%s/agent/sessions/%s", "[PROJECT]", "[SESSION]") var queryInput *dialogflowpb.QueryInput = &dialogflowpb.QueryInput{} var request = &dialogflowpb.DetectIntentRequest{ Session: formattedSession, QueryInput: queryInput, } c, err := NewSessionsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.DetectIntent(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSessionsStreamingDetectIntent(t *testing.T) { var responseId string = "responseId1847552473" var outputAudio []byte = []byte("24") var expectedResponse = &dialogflowpb.StreamingDetectIntentResponse{ ResponseId: responseId, OutputAudio: outputAudio, } mockSessions.err = nil mockSessions.reqs = nil mockSessions.resps = append(mockSessions.resps[:0], expectedResponse) var session string = "session1984987798" var queryInput *dialogflowpb.QueryInput = &dialogflowpb.QueryInput{} var request = &dialogflowpb.StreamingDetectIntentRequest{ Session: session, QueryInput: queryInput, } c, err := NewSessionsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } stream, err := c.StreamingDetectIntent(context.Background()) if err != nil { t.Fatal(err) } if err := stream.Send(request); err != nil { t.Fatal(err) } if err := stream.CloseSend(); err != nil { t.Fatal(err) } resp, err := stream.Recv() if err != nil { t.Fatal(err) } if want, got := request, mockSessions.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSessionsStreamingDetectIntentError(t *testing.T) { errCode := codes.PermissionDenied mockSessions.err = gstatus.Error(errCode, "test error") var session string = "session1984987798" var queryInput *dialogflowpb.QueryInput = &dialogflowpb.QueryInput{} var request = &dialogflowpb.StreamingDetectIntentRequest{ Session: session, QueryInput: queryInput, } c, err := NewSessionsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } stream, err := c.StreamingDetectIntent(context.Background()) if err != nil { t.Fatal(err) } if err := stream.Send(request); err != nil { t.Fatal(err) } if err := stream.CloseSend(); err != nil { t.Fatal(err) } resp, err := stream.Recv() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/dialogflow/apiv2/session_entity_types_client.go000066400000000000000000000313201356504100700261270ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package dialogflow import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" dialogflowpb "google.golang.org/genproto/googleapis/cloud/dialogflow/v2" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // SessionEntityTypesCallOptions contains the retry settings for each method of SessionEntityTypesClient. type SessionEntityTypesCallOptions struct { ListSessionEntityTypes []gax.CallOption GetSessionEntityType []gax.CallOption CreateSessionEntityType []gax.CallOption UpdateSessionEntityType []gax.CallOption DeleteSessionEntityType []gax.CallOption } func defaultSessionEntityTypesClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("dialogflow.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultSessionEntityTypesCallOptions() *SessionEntityTypesCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &SessionEntityTypesCallOptions{ ListSessionEntityTypes: retry[[2]string{"default", "idempotent"}], GetSessionEntityType: retry[[2]string{"default", "idempotent"}], CreateSessionEntityType: retry[[2]string{"default", "non_idempotent"}], UpdateSessionEntityType: retry[[2]string{"default", "non_idempotent"}], DeleteSessionEntityType: retry[[2]string{"default", "idempotent"}], } } // SessionEntityTypesClient is a client for interacting with Dialogflow API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type SessionEntityTypesClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. sessionEntityTypesClient dialogflowpb.SessionEntityTypesClient // The call options for this service. CallOptions *SessionEntityTypesCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewSessionEntityTypesClient creates a new session entity types client. // // Entities are extracted from user input and represent parameters that are // meaningful to your application. For example, a date range, a proper name // such as a geographic location or landmark, and so on. Entities represent // actionable data for your application. // // Session entity types are referred to as **User** entity types and are // entities that are built for an individual user such as // favorites, preferences, playlists, and so on. You can redefine a session // entity type at the session level. // // Session entity methods do not work with Google Assistant integration. // Contact Dialogflow support if you need to use session entities // with Google Assistant integration. // // For more information about entity types, see the // [Dialogflow // documentation](https://cloud.google.com/dialogflow/docs/entities-overview). func NewSessionEntityTypesClient(ctx context.Context, opts ...option.ClientOption) (*SessionEntityTypesClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultSessionEntityTypesClientOptions(), opts...)...) if err != nil { return nil, err } c := &SessionEntityTypesClient{ conn: conn, CallOptions: defaultSessionEntityTypesCallOptions(), sessionEntityTypesClient: dialogflowpb.NewSessionEntityTypesClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *SessionEntityTypesClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *SessionEntityTypesClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *SessionEntityTypesClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // ListSessionEntityTypes returns the list of all session entity types in the specified session. // // This method doesn't work with Google Assistant integration. // Contact Dialogflow support if you need to use session entities // with Google Assistant integration. func (c *SessionEntityTypesClient) ListSessionEntityTypes(ctx context.Context, req *dialogflowpb.ListSessionEntityTypesRequest, opts ...gax.CallOption) *SessionEntityTypeIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListSessionEntityTypes[0:len(c.CallOptions.ListSessionEntityTypes):len(c.CallOptions.ListSessionEntityTypes)], opts...) it := &SessionEntityTypeIterator{} req = proto.Clone(req).(*dialogflowpb.ListSessionEntityTypesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*dialogflowpb.SessionEntityType, string, error) { var resp *dialogflowpb.ListSessionEntityTypesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.sessionEntityTypesClient.ListSessionEntityTypes(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.SessionEntityTypes, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetSessionEntityType retrieves the specified session entity type. // // This method doesn't work with Google Assistant integration. // Contact Dialogflow support if you need to use session entities // with Google Assistant integration. func (c *SessionEntityTypesClient) GetSessionEntityType(ctx context.Context, req *dialogflowpb.GetSessionEntityTypeRequest, opts ...gax.CallOption) (*dialogflowpb.SessionEntityType, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetSessionEntityType[0:len(c.CallOptions.GetSessionEntityType):len(c.CallOptions.GetSessionEntityType)], opts...) var resp *dialogflowpb.SessionEntityType err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.sessionEntityTypesClient.GetSessionEntityType(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateSessionEntityType creates a session entity type. // // If the specified session entity type already exists, overrides the session // entity type. // // This method doesn't work with Google Assistant integration. // Contact Dialogflow support if you need to use session entities // with Google Assistant integration. func (c *SessionEntityTypesClient) CreateSessionEntityType(ctx context.Context, req *dialogflowpb.CreateSessionEntityTypeRequest, opts ...gax.CallOption) (*dialogflowpb.SessionEntityType, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateSessionEntityType[0:len(c.CallOptions.CreateSessionEntityType):len(c.CallOptions.CreateSessionEntityType)], opts...) var resp *dialogflowpb.SessionEntityType err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.sessionEntityTypesClient.CreateSessionEntityType(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateSessionEntityType updates the specified session entity type. // // This method doesn't work with Google Assistant integration. // Contact Dialogflow support if you need to use session entities // with Google Assistant integration. func (c *SessionEntityTypesClient) UpdateSessionEntityType(ctx context.Context, req *dialogflowpb.UpdateSessionEntityTypeRequest, opts ...gax.CallOption) (*dialogflowpb.SessionEntityType, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "session_entity_type.name", url.QueryEscape(req.GetSessionEntityType().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateSessionEntityType[0:len(c.CallOptions.UpdateSessionEntityType):len(c.CallOptions.UpdateSessionEntityType)], opts...) var resp *dialogflowpb.SessionEntityType err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.sessionEntityTypesClient.UpdateSessionEntityType(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteSessionEntityType deletes the specified session entity type. // // This method doesn't work with Google Assistant integration. // Contact Dialogflow support if you need to use session entities // with Google Assistant integration. func (c *SessionEntityTypesClient) DeleteSessionEntityType(ctx context.Context, req *dialogflowpb.DeleteSessionEntityTypeRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteSessionEntityType[0:len(c.CallOptions.DeleteSessionEntityType):len(c.CallOptions.DeleteSessionEntityType)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.sessionEntityTypesClient.DeleteSessionEntityType(ctx, req, settings.GRPC...) return err }, opts...) return err } // SessionEntityTypeIterator manages a stream of *dialogflowpb.SessionEntityType. type SessionEntityTypeIterator struct { items []*dialogflowpb.SessionEntityType pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*dialogflowpb.SessionEntityType, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *SessionEntityTypeIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *SessionEntityTypeIterator) Next() (*dialogflowpb.SessionEntityType, error) { var item *dialogflowpb.SessionEntityType if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *SessionEntityTypeIterator) bufLen() int { return len(it.items) } func (it *SessionEntityTypeIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/dialogflow/apiv2/session_entity_types_client_example_test.go000066400000000000000000000061451356504100700307100ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package dialogflow_test import ( "context" dialogflow "cloud.google.com/go/dialogflow/apiv2" "google.golang.org/api/iterator" dialogflowpb "google.golang.org/genproto/googleapis/cloud/dialogflow/v2" ) func ExampleNewSessionEntityTypesClient() { ctx := context.Background() c, err := dialogflow.NewSessionEntityTypesClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleSessionEntityTypesClient_ListSessionEntityTypes() { ctx := context.Background() c, err := dialogflow.NewSessionEntityTypesClient(ctx) if err != nil { // TODO: Handle error. } req := &dialogflowpb.ListSessionEntityTypesRequest{ // TODO: Fill request struct fields. } it := c.ListSessionEntityTypes(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleSessionEntityTypesClient_GetSessionEntityType() { ctx := context.Background() c, err := dialogflow.NewSessionEntityTypesClient(ctx) if err != nil { // TODO: Handle error. } req := &dialogflowpb.GetSessionEntityTypeRequest{ // TODO: Fill request struct fields. } resp, err := c.GetSessionEntityType(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleSessionEntityTypesClient_CreateSessionEntityType() { ctx := context.Background() c, err := dialogflow.NewSessionEntityTypesClient(ctx) if err != nil { // TODO: Handle error. } req := &dialogflowpb.CreateSessionEntityTypeRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateSessionEntityType(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleSessionEntityTypesClient_UpdateSessionEntityType() { ctx := context.Background() c, err := dialogflow.NewSessionEntityTypesClient(ctx) if err != nil { // TODO: Handle error. } req := &dialogflowpb.UpdateSessionEntityTypeRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateSessionEntityType(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleSessionEntityTypesClient_DeleteSessionEntityType() { ctx := context.Background() c, err := dialogflow.NewSessionEntityTypesClient(ctx) if err != nil { // TODO: Handle error. } req := &dialogflowpb.DeleteSessionEntityTypeRequest{ // TODO: Fill request struct fields. } err = c.DeleteSessionEntityType(ctx, req) if err != nil { // TODO: Handle error. } } google-cloud-go-0.49.0/dialogflow/apiv2/sessions_client.go000066400000000000000000000131251356504100700234750ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package dialogflow import ( "context" "fmt" "math" "net/url" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" "google.golang.org/api/transport" dialogflowpb "google.golang.org/genproto/googleapis/cloud/dialogflow/v2" "google.golang.org/grpc" "google.golang.org/grpc/metadata" ) // SessionsCallOptions contains the retry settings for each method of SessionsClient. type SessionsCallOptions struct { DetectIntent []gax.CallOption StreamingDetectIntent []gax.CallOption } func defaultSessionsClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("dialogflow.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultSessionsCallOptions() *SessionsCallOptions { retry := map[[2]string][]gax.CallOption{} return &SessionsCallOptions{ DetectIntent: retry[[2]string{"default", "non_idempotent"}], StreamingDetectIntent: retry[[2]string{"default", "non_idempotent"}], } } // SessionsClient is a client for interacting with Dialogflow API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type SessionsClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. sessionsClient dialogflowpb.SessionsClient // The call options for this service. CallOptions *SessionsCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewSessionsClient creates a new sessions client. // // A session represents an interaction with a user. You retrieve user input // and pass it to the [DetectIntent][google.cloud.dialogflow.v2.Sessions.DetectIntent] (or // [StreamingDetectIntent][google.cloud.dialogflow.v2.Sessions.StreamingDetectIntent]) method to determine // user intent and respond. func NewSessionsClient(ctx context.Context, opts ...option.ClientOption) (*SessionsClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultSessionsClientOptions(), opts...)...) if err != nil { return nil, err } c := &SessionsClient{ conn: conn, CallOptions: defaultSessionsCallOptions(), sessionsClient: dialogflowpb.NewSessionsClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *SessionsClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *SessionsClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *SessionsClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // DetectIntent processes a natural language query and returns structured, actionable data // as a result. This method is not idempotent, because it may cause contexts // and session entity types to be updated, which in turn might affect // results of future queries. func (c *SessionsClient) DetectIntent(ctx context.Context, req *dialogflowpb.DetectIntentRequest, opts ...gax.CallOption) (*dialogflowpb.DetectIntentResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "session", url.QueryEscape(req.GetSession()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DetectIntent[0:len(c.CallOptions.DetectIntent):len(c.CallOptions.DetectIntent)], opts...) var resp *dialogflowpb.DetectIntentResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.sessionsClient.DetectIntent(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // StreamingDetectIntent processes a natural language query in audio format in a streaming fashion // and returns structured, actionable data as a result. This method is only // available via the gRPC API (not REST). func (c *SessionsClient) StreamingDetectIntent(ctx context.Context, opts ...gax.CallOption) (dialogflowpb.Sessions_StreamingDetectIntentClient, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.StreamingDetectIntent[0:len(c.CallOptions.StreamingDetectIntent):len(c.CallOptions.StreamingDetectIntent)], opts...) var resp dialogflowpb.Sessions_StreamingDetectIntentClient err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.sessionsClient.StreamingDetectIntent(ctx, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } google-cloud-go-0.49.0/dialogflow/apiv2/sessions_client_example_test.go000066400000000000000000000037521356504100700262540ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package dialogflow_test import ( "context" "io" dialogflow "cloud.google.com/go/dialogflow/apiv2" dialogflowpb "google.golang.org/genproto/googleapis/cloud/dialogflow/v2" ) func ExampleNewSessionsClient() { ctx := context.Background() c, err := dialogflow.NewSessionsClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleSessionsClient_DetectIntent() { ctx := context.Background() c, err := dialogflow.NewSessionsClient(ctx) if err != nil { // TODO: Handle error. } req := &dialogflowpb.DetectIntentRequest{ // TODO: Fill request struct fields. } resp, err := c.DetectIntent(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleSessionsClient_StreamingDetectIntent() { ctx := context.Background() c, err := dialogflow.NewSessionsClient(ctx) if err != nil { // TODO: Handle error. } stream, err := c.StreamingDetectIntent(ctx) if err != nil { // TODO: Handle error. } go func() { reqs := []*dialogflowpb.StreamingDetectIntentRequest{ // TODO: Create requests. } for _, req := range reqs { if err := stream.Send(req); err != nil { // TODO: Handle error. } } stream.CloseSend() }() for { resp, err := stream.Recv() if err == io.EOF { break } if err != nil { // TODO: handle error. } // TODO: Use resp. _ = resp } } google-cloud-go-0.49.0/dlp/000077500000000000000000000000001356504100700153475ustar00rootroot00000000000000google-cloud-go-0.49.0/dlp/apiv2/000077500000000000000000000000001356504100700163705ustar00rootroot00000000000000google-cloud-go-0.49.0/dlp/apiv2/.repo-metadata.json000066400000000000000000000006201356504100700220620ustar00rootroot00000000000000{ "name": "dlp", "name_pretty": "Cloud Data Loss Prevention", "product_documentation": "https://cloud.google.com/dlp", "client_documentation": "https://godoc.org/cloud.google.com/go/dlp/apiv2", "release_level": "ga", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go/dlp", "api_id": "dlp.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/dlp/apiv2/dlp_client.go000066400000000000000000001315751356504100700210500ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package dlp import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" dlppb "google.golang.org/genproto/googleapis/privacy/dlp/v2" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // CallOptions contains the retry settings for each method of Client. type CallOptions struct { InspectContent []gax.CallOption RedactImage []gax.CallOption DeidentifyContent []gax.CallOption ReidentifyContent []gax.CallOption ListInfoTypes []gax.CallOption CreateInspectTemplate []gax.CallOption UpdateInspectTemplate []gax.CallOption GetInspectTemplate []gax.CallOption ListInspectTemplates []gax.CallOption DeleteInspectTemplate []gax.CallOption CreateDeidentifyTemplate []gax.CallOption UpdateDeidentifyTemplate []gax.CallOption GetDeidentifyTemplate []gax.CallOption ListDeidentifyTemplates []gax.CallOption DeleteDeidentifyTemplate []gax.CallOption CreateDlpJob []gax.CallOption ListDlpJobs []gax.CallOption GetDlpJob []gax.CallOption DeleteDlpJob []gax.CallOption CancelDlpJob []gax.CallOption ListJobTriggers []gax.CallOption GetJobTrigger []gax.CallOption DeleteJobTrigger []gax.CallOption UpdateJobTrigger []gax.CallOption CreateJobTrigger []gax.CallOption CreateStoredInfoType []gax.CallOption UpdateStoredInfoType []gax.CallOption GetStoredInfoType []gax.CallOption ListStoredInfoTypes []gax.CallOption DeleteStoredInfoType []gax.CallOption } func defaultClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("dlp.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultCallOptions() *CallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &CallOptions{ InspectContent: retry[[2]string{"default", "idempotent"}], RedactImage: retry[[2]string{"default", "idempotent"}], DeidentifyContent: retry[[2]string{"default", "idempotent"}], ReidentifyContent: retry[[2]string{"default", "idempotent"}], ListInfoTypes: retry[[2]string{"default", "idempotent"}], CreateInspectTemplate: retry[[2]string{"default", "non_idempotent"}], UpdateInspectTemplate: retry[[2]string{"default", "non_idempotent"}], GetInspectTemplate: retry[[2]string{"default", "idempotent"}], ListInspectTemplates: retry[[2]string{"default", "idempotent"}], DeleteInspectTemplate: retry[[2]string{"default", "idempotent"}], CreateDeidentifyTemplate: retry[[2]string{"default", "non_idempotent"}], UpdateDeidentifyTemplate: retry[[2]string{"default", "non_idempotent"}], GetDeidentifyTemplate: retry[[2]string{"default", "idempotent"}], ListDeidentifyTemplates: retry[[2]string{"default", "idempotent"}], DeleteDeidentifyTemplate: retry[[2]string{"default", "idempotent"}], CreateDlpJob: retry[[2]string{"default", "non_idempotent"}], ListDlpJobs: retry[[2]string{"default", "idempotent"}], GetDlpJob: retry[[2]string{"default", "idempotent"}], DeleteDlpJob: retry[[2]string{"default", "idempotent"}], CancelDlpJob: retry[[2]string{"default", "non_idempotent"}], ListJobTriggers: retry[[2]string{"default", "idempotent"}], GetJobTrigger: retry[[2]string{"default", "idempotent"}], DeleteJobTrigger: retry[[2]string{"default", "idempotent"}], UpdateJobTrigger: retry[[2]string{"default", "non_idempotent"}], CreateJobTrigger: retry[[2]string{"default", "non_idempotent"}], CreateStoredInfoType: retry[[2]string{"default", "non_idempotent"}], UpdateStoredInfoType: retry[[2]string{"default", "non_idempotent"}], GetStoredInfoType: retry[[2]string{"default", "idempotent"}], ListStoredInfoTypes: retry[[2]string{"default", "idempotent"}], DeleteStoredInfoType: retry[[2]string{"default", "idempotent"}], } } // Client is a client for interacting with Cloud Data Loss Prevention (DLP) API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. client dlppb.DlpServiceClient // The call options for this service. CallOptions *CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewClient creates a new dlp service client. // // The Cloud Data Loss Prevention (DLP) API is a service that allows clients // to detect the presence of Personally Identifiable Information (PII) and other // privacy-sensitive data in user-supplied, unstructured data streams, like text // blocks or images. // The service also includes methods for sensitive data redaction and // scheduling of data scans on Google Cloud Platform based data sets. // // To learn more about concepts and find how-to guides see // https://cloud.google.com/dlp/docs/. func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultClientOptions(), opts...)...) if err != nil { return nil, err } c := &Client{ conn: conn, CallOptions: defaultCallOptions(), client: dlppb.NewDlpServiceClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *Client) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *Client) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // InspectContent finds potentially sensitive info in content. // This method has limits on input size, processing time, and output size. // // When no InfoTypes or CustomInfoTypes are specified in this request, the // system will automatically choose what detectors to run. By default this may // be all types, but may change over time as detectors are updated. // // For how to guides, see https://cloud.google.com/dlp/docs/inspecting-images // and https://cloud.google.com/dlp/docs/inspecting-text, func (c *Client) InspectContent(ctx context.Context, req *dlppb.InspectContentRequest, opts ...gax.CallOption) (*dlppb.InspectContentResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.InspectContent[0:len(c.CallOptions.InspectContent):len(c.CallOptions.InspectContent)], opts...) var resp *dlppb.InspectContentResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.InspectContent(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // RedactImage redacts potentially sensitive info from an image. // This method has limits on input size, processing time, and output size. // See https://cloud.google.com/dlp/docs/redacting-sensitive-data-images to // learn more. // // When no InfoTypes or CustomInfoTypes are specified in this request, the // system will automatically choose what detectors to run. By default this may // be all types, but may change over time as detectors are updated. func (c *Client) RedactImage(ctx context.Context, req *dlppb.RedactImageRequest, opts ...gax.CallOption) (*dlppb.RedactImageResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.RedactImage[0:len(c.CallOptions.RedactImage):len(c.CallOptions.RedactImage)], opts...) var resp *dlppb.RedactImageResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.RedactImage(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeidentifyContent de-identifies potentially sensitive info from a ContentItem. // This method has limits on input size and output size. // See https://cloud.google.com/dlp/docs/deidentify-sensitive-data to // learn more. // // When no InfoTypes or CustomInfoTypes are specified in this request, the // system will automatically choose what detectors to run. By default this may // be all types, but may change over time as detectors are updated. func (c *Client) DeidentifyContent(ctx context.Context, req *dlppb.DeidentifyContentRequest, opts ...gax.CallOption) (*dlppb.DeidentifyContentResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeidentifyContent[0:len(c.CallOptions.DeidentifyContent):len(c.CallOptions.DeidentifyContent)], opts...) var resp *dlppb.DeidentifyContentResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.DeidentifyContent(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ReidentifyContent re-identifies content that has been de-identified. // See // https://cloud.google.com/dlp/docs/pseudonymization#re-identification_in_free_text_code_example // to learn more. func (c *Client) ReidentifyContent(ctx context.Context, req *dlppb.ReidentifyContentRequest, opts ...gax.CallOption) (*dlppb.ReidentifyContentResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ReidentifyContent[0:len(c.CallOptions.ReidentifyContent):len(c.CallOptions.ReidentifyContent)], opts...) var resp *dlppb.ReidentifyContentResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ReidentifyContent(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListInfoTypes returns a list of the sensitive information types that the DLP API // supports. See https://cloud.google.com/dlp/docs/infotypes-reference to // learn more. func (c *Client) ListInfoTypes(ctx context.Context, req *dlppb.ListInfoTypesRequest, opts ...gax.CallOption) (*dlppb.ListInfoTypesResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.ListInfoTypes[0:len(c.CallOptions.ListInfoTypes):len(c.CallOptions.ListInfoTypes)], opts...) var resp *dlppb.ListInfoTypesResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListInfoTypes(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateInspectTemplate creates an InspectTemplate for re-using frequently used configuration // for inspecting content, images, and storage. // See https://cloud.google.com/dlp/docs/creating-templates to learn more. func (c *Client) CreateInspectTemplate(ctx context.Context, req *dlppb.CreateInspectTemplateRequest, opts ...gax.CallOption) (*dlppb.InspectTemplate, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateInspectTemplate[0:len(c.CallOptions.CreateInspectTemplate):len(c.CallOptions.CreateInspectTemplate)], opts...) var resp *dlppb.InspectTemplate err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CreateInspectTemplate(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateInspectTemplate updates the InspectTemplate. // See https://cloud.google.com/dlp/docs/creating-templates to learn more. func (c *Client) UpdateInspectTemplate(ctx context.Context, req *dlppb.UpdateInspectTemplateRequest, opts ...gax.CallOption) (*dlppb.InspectTemplate, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateInspectTemplate[0:len(c.CallOptions.UpdateInspectTemplate):len(c.CallOptions.UpdateInspectTemplate)], opts...) var resp *dlppb.InspectTemplate err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.UpdateInspectTemplate(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetInspectTemplate gets an InspectTemplate. // See https://cloud.google.com/dlp/docs/creating-templates to learn more. func (c *Client) GetInspectTemplate(ctx context.Context, req *dlppb.GetInspectTemplateRequest, opts ...gax.CallOption) (*dlppb.InspectTemplate, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetInspectTemplate[0:len(c.CallOptions.GetInspectTemplate):len(c.CallOptions.GetInspectTemplate)], opts...) var resp *dlppb.InspectTemplate err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetInspectTemplate(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListInspectTemplates lists InspectTemplates. // See https://cloud.google.com/dlp/docs/creating-templates to learn more. func (c *Client) ListInspectTemplates(ctx context.Context, req *dlppb.ListInspectTemplatesRequest, opts ...gax.CallOption) *InspectTemplateIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListInspectTemplates[0:len(c.CallOptions.ListInspectTemplates):len(c.CallOptions.ListInspectTemplates)], opts...) it := &InspectTemplateIterator{} req = proto.Clone(req).(*dlppb.ListInspectTemplatesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*dlppb.InspectTemplate, string, error) { var resp *dlppb.ListInspectTemplatesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListInspectTemplates(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.InspectTemplates, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // DeleteInspectTemplate deletes an InspectTemplate. // See https://cloud.google.com/dlp/docs/creating-templates to learn more. func (c *Client) DeleteInspectTemplate(ctx context.Context, req *dlppb.DeleteInspectTemplateRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteInspectTemplate[0:len(c.CallOptions.DeleteInspectTemplate):len(c.CallOptions.DeleteInspectTemplate)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.client.DeleteInspectTemplate(ctx, req, settings.GRPC...) return err }, opts...) return err } // CreateDeidentifyTemplate creates a DeidentifyTemplate for re-using frequently used configuration // for de-identifying content, images, and storage. // See https://cloud.google.com/dlp/docs/creating-templates-deid to learn // more. func (c *Client) CreateDeidentifyTemplate(ctx context.Context, req *dlppb.CreateDeidentifyTemplateRequest, opts ...gax.CallOption) (*dlppb.DeidentifyTemplate, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateDeidentifyTemplate[0:len(c.CallOptions.CreateDeidentifyTemplate):len(c.CallOptions.CreateDeidentifyTemplate)], opts...) var resp *dlppb.DeidentifyTemplate err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CreateDeidentifyTemplate(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateDeidentifyTemplate updates the DeidentifyTemplate. // See https://cloud.google.com/dlp/docs/creating-templates-deid to learn // more. func (c *Client) UpdateDeidentifyTemplate(ctx context.Context, req *dlppb.UpdateDeidentifyTemplateRequest, opts ...gax.CallOption) (*dlppb.DeidentifyTemplate, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateDeidentifyTemplate[0:len(c.CallOptions.UpdateDeidentifyTemplate):len(c.CallOptions.UpdateDeidentifyTemplate)], opts...) var resp *dlppb.DeidentifyTemplate err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.UpdateDeidentifyTemplate(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetDeidentifyTemplate gets a DeidentifyTemplate. // See https://cloud.google.com/dlp/docs/creating-templates-deid to learn // more. func (c *Client) GetDeidentifyTemplate(ctx context.Context, req *dlppb.GetDeidentifyTemplateRequest, opts ...gax.CallOption) (*dlppb.DeidentifyTemplate, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetDeidentifyTemplate[0:len(c.CallOptions.GetDeidentifyTemplate):len(c.CallOptions.GetDeidentifyTemplate)], opts...) var resp *dlppb.DeidentifyTemplate err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetDeidentifyTemplate(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListDeidentifyTemplates lists DeidentifyTemplates. // See https://cloud.google.com/dlp/docs/creating-templates-deid to learn // more. func (c *Client) ListDeidentifyTemplates(ctx context.Context, req *dlppb.ListDeidentifyTemplatesRequest, opts ...gax.CallOption) *DeidentifyTemplateIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListDeidentifyTemplates[0:len(c.CallOptions.ListDeidentifyTemplates):len(c.CallOptions.ListDeidentifyTemplates)], opts...) it := &DeidentifyTemplateIterator{} req = proto.Clone(req).(*dlppb.ListDeidentifyTemplatesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*dlppb.DeidentifyTemplate, string, error) { var resp *dlppb.ListDeidentifyTemplatesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListDeidentifyTemplates(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.DeidentifyTemplates, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // DeleteDeidentifyTemplate deletes a DeidentifyTemplate. // See https://cloud.google.com/dlp/docs/creating-templates-deid to learn // more. func (c *Client) DeleteDeidentifyTemplate(ctx context.Context, req *dlppb.DeleteDeidentifyTemplateRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteDeidentifyTemplate[0:len(c.CallOptions.DeleteDeidentifyTemplate):len(c.CallOptions.DeleteDeidentifyTemplate)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.client.DeleteDeidentifyTemplate(ctx, req, settings.GRPC...) return err }, opts...) return err } // CreateDlpJob creates a new job to inspect storage or calculate risk metrics. // See https://cloud.google.com/dlp/docs/inspecting-storage and // https://cloud.google.com/dlp/docs/compute-risk-analysis to learn more. // // When no InfoTypes or CustomInfoTypes are specified in inspect jobs, the // system will automatically choose what detectors to run. By default this may // be all types, but may change over time as detectors are updated. func (c *Client) CreateDlpJob(ctx context.Context, req *dlppb.CreateDlpJobRequest, opts ...gax.CallOption) (*dlppb.DlpJob, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateDlpJob[0:len(c.CallOptions.CreateDlpJob):len(c.CallOptions.CreateDlpJob)], opts...) var resp *dlppb.DlpJob err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CreateDlpJob(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListDlpJobs lists DlpJobs that match the specified filter in the request. // See https://cloud.google.com/dlp/docs/inspecting-storage and // https://cloud.google.com/dlp/docs/compute-risk-analysis to learn more. func (c *Client) ListDlpJobs(ctx context.Context, req *dlppb.ListDlpJobsRequest, opts ...gax.CallOption) *DlpJobIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListDlpJobs[0:len(c.CallOptions.ListDlpJobs):len(c.CallOptions.ListDlpJobs)], opts...) it := &DlpJobIterator{} req = proto.Clone(req).(*dlppb.ListDlpJobsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*dlppb.DlpJob, string, error) { var resp *dlppb.ListDlpJobsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListDlpJobs(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Jobs, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetDlpJob gets the latest state of a long-running DlpJob. // See https://cloud.google.com/dlp/docs/inspecting-storage and // https://cloud.google.com/dlp/docs/compute-risk-analysis to learn more. func (c *Client) GetDlpJob(ctx context.Context, req *dlppb.GetDlpJobRequest, opts ...gax.CallOption) (*dlppb.DlpJob, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetDlpJob[0:len(c.CallOptions.GetDlpJob):len(c.CallOptions.GetDlpJob)], opts...) var resp *dlppb.DlpJob err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetDlpJob(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteDlpJob deletes a long-running DlpJob. This method indicates that the client is // no longer interested in the DlpJob result. The job will be cancelled if // possible. // See https://cloud.google.com/dlp/docs/inspecting-storage and // https://cloud.google.com/dlp/docs/compute-risk-analysis to learn more. func (c *Client) DeleteDlpJob(ctx context.Context, req *dlppb.DeleteDlpJobRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteDlpJob[0:len(c.CallOptions.DeleteDlpJob):len(c.CallOptions.DeleteDlpJob)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.client.DeleteDlpJob(ctx, req, settings.GRPC...) return err }, opts...) return err } // CancelDlpJob starts asynchronous cancellation on a long-running DlpJob. The server // makes a best effort to cancel the DlpJob, but success is not // guaranteed. // See https://cloud.google.com/dlp/docs/inspecting-storage and // https://cloud.google.com/dlp/docs/compute-risk-analysis to learn more. func (c *Client) CancelDlpJob(ctx context.Context, req *dlppb.CancelDlpJobRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CancelDlpJob[0:len(c.CallOptions.CancelDlpJob):len(c.CallOptions.CancelDlpJob)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.client.CancelDlpJob(ctx, req, settings.GRPC...) return err }, opts...) return err } // ListJobTriggers lists job triggers. // See https://cloud.google.com/dlp/docs/creating-job-triggers to learn more. func (c *Client) ListJobTriggers(ctx context.Context, req *dlppb.ListJobTriggersRequest, opts ...gax.CallOption) *JobTriggerIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListJobTriggers[0:len(c.CallOptions.ListJobTriggers):len(c.CallOptions.ListJobTriggers)], opts...) it := &JobTriggerIterator{} req = proto.Clone(req).(*dlppb.ListJobTriggersRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*dlppb.JobTrigger, string, error) { var resp *dlppb.ListJobTriggersResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListJobTriggers(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.JobTriggers, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetJobTrigger gets a job trigger. // See https://cloud.google.com/dlp/docs/creating-job-triggers to learn more. func (c *Client) GetJobTrigger(ctx context.Context, req *dlppb.GetJobTriggerRequest, opts ...gax.CallOption) (*dlppb.JobTrigger, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetJobTrigger[0:len(c.CallOptions.GetJobTrigger):len(c.CallOptions.GetJobTrigger)], opts...) var resp *dlppb.JobTrigger err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetJobTrigger(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteJobTrigger deletes a job trigger. // See https://cloud.google.com/dlp/docs/creating-job-triggers to learn more. func (c *Client) DeleteJobTrigger(ctx context.Context, req *dlppb.DeleteJobTriggerRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteJobTrigger[0:len(c.CallOptions.DeleteJobTrigger):len(c.CallOptions.DeleteJobTrigger)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.client.DeleteJobTrigger(ctx, req, settings.GRPC...) return err }, opts...) return err } // UpdateJobTrigger updates a job trigger. // See https://cloud.google.com/dlp/docs/creating-job-triggers to learn more. func (c *Client) UpdateJobTrigger(ctx context.Context, req *dlppb.UpdateJobTriggerRequest, opts ...gax.CallOption) (*dlppb.JobTrigger, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateJobTrigger[0:len(c.CallOptions.UpdateJobTrigger):len(c.CallOptions.UpdateJobTrigger)], opts...) var resp *dlppb.JobTrigger err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.UpdateJobTrigger(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateJobTrigger creates a job trigger to run DLP actions such as scanning storage for // sensitive information on a set schedule. // See https://cloud.google.com/dlp/docs/creating-job-triggers to learn more. func (c *Client) CreateJobTrigger(ctx context.Context, req *dlppb.CreateJobTriggerRequest, opts ...gax.CallOption) (*dlppb.JobTrigger, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateJobTrigger[0:len(c.CallOptions.CreateJobTrigger):len(c.CallOptions.CreateJobTrigger)], opts...) var resp *dlppb.JobTrigger err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CreateJobTrigger(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateStoredInfoType creates a pre-built stored infoType to be used for inspection. // See https://cloud.google.com/dlp/docs/creating-stored-infotypes to // learn more. func (c *Client) CreateStoredInfoType(ctx context.Context, req *dlppb.CreateStoredInfoTypeRequest, opts ...gax.CallOption) (*dlppb.StoredInfoType, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateStoredInfoType[0:len(c.CallOptions.CreateStoredInfoType):len(c.CallOptions.CreateStoredInfoType)], opts...) var resp *dlppb.StoredInfoType err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CreateStoredInfoType(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateStoredInfoType updates the stored infoType by creating a new version. The existing version // will continue to be used until the new version is ready. // See https://cloud.google.com/dlp/docs/creating-stored-infotypes to // learn more. func (c *Client) UpdateStoredInfoType(ctx context.Context, req *dlppb.UpdateStoredInfoTypeRequest, opts ...gax.CallOption) (*dlppb.StoredInfoType, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateStoredInfoType[0:len(c.CallOptions.UpdateStoredInfoType):len(c.CallOptions.UpdateStoredInfoType)], opts...) var resp *dlppb.StoredInfoType err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.UpdateStoredInfoType(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetStoredInfoType gets a stored infoType. // See https://cloud.google.com/dlp/docs/creating-stored-infotypes to // learn more. func (c *Client) GetStoredInfoType(ctx context.Context, req *dlppb.GetStoredInfoTypeRequest, opts ...gax.CallOption) (*dlppb.StoredInfoType, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetStoredInfoType[0:len(c.CallOptions.GetStoredInfoType):len(c.CallOptions.GetStoredInfoType)], opts...) var resp *dlppb.StoredInfoType err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetStoredInfoType(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListStoredInfoTypes lists stored infoTypes. // See https://cloud.google.com/dlp/docs/creating-stored-infotypes to // learn more. func (c *Client) ListStoredInfoTypes(ctx context.Context, req *dlppb.ListStoredInfoTypesRequest, opts ...gax.CallOption) *StoredInfoTypeIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListStoredInfoTypes[0:len(c.CallOptions.ListStoredInfoTypes):len(c.CallOptions.ListStoredInfoTypes)], opts...) it := &StoredInfoTypeIterator{} req = proto.Clone(req).(*dlppb.ListStoredInfoTypesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*dlppb.StoredInfoType, string, error) { var resp *dlppb.ListStoredInfoTypesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListStoredInfoTypes(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.StoredInfoTypes, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // DeleteStoredInfoType deletes a stored infoType. // See https://cloud.google.com/dlp/docs/creating-stored-infotypes to // learn more. func (c *Client) DeleteStoredInfoType(ctx context.Context, req *dlppb.DeleteStoredInfoTypeRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteStoredInfoType[0:len(c.CallOptions.DeleteStoredInfoType):len(c.CallOptions.DeleteStoredInfoType)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.client.DeleteStoredInfoType(ctx, req, settings.GRPC...) return err }, opts...) return err } // DeidentifyTemplateIterator manages a stream of *dlppb.DeidentifyTemplate. type DeidentifyTemplateIterator struct { items []*dlppb.DeidentifyTemplate pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*dlppb.DeidentifyTemplate, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *DeidentifyTemplateIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *DeidentifyTemplateIterator) Next() (*dlppb.DeidentifyTemplate, error) { var item *dlppb.DeidentifyTemplate if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *DeidentifyTemplateIterator) bufLen() int { return len(it.items) } func (it *DeidentifyTemplateIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // DlpJobIterator manages a stream of *dlppb.DlpJob. type DlpJobIterator struct { items []*dlppb.DlpJob pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*dlppb.DlpJob, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *DlpJobIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *DlpJobIterator) Next() (*dlppb.DlpJob, error) { var item *dlppb.DlpJob if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *DlpJobIterator) bufLen() int { return len(it.items) } func (it *DlpJobIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // InspectTemplateIterator manages a stream of *dlppb.InspectTemplate. type InspectTemplateIterator struct { items []*dlppb.InspectTemplate pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*dlppb.InspectTemplate, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *InspectTemplateIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *InspectTemplateIterator) Next() (*dlppb.InspectTemplate, error) { var item *dlppb.InspectTemplate if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *InspectTemplateIterator) bufLen() int { return len(it.items) } func (it *InspectTemplateIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // JobTriggerIterator manages a stream of *dlppb.JobTrigger. type JobTriggerIterator struct { items []*dlppb.JobTrigger pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*dlppb.JobTrigger, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *JobTriggerIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *JobTriggerIterator) Next() (*dlppb.JobTrigger, error) { var item *dlppb.JobTrigger if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *JobTriggerIterator) bufLen() int { return len(it.items) } func (it *JobTriggerIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // StoredInfoTypeIterator manages a stream of *dlppb.StoredInfoType. type StoredInfoTypeIterator struct { items []*dlppb.StoredInfoType pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*dlppb.StoredInfoType, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *StoredInfoTypeIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *StoredInfoTypeIterator) Next() (*dlppb.StoredInfoType, error) { var item *dlppb.StoredInfoType if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *StoredInfoTypeIterator) bufLen() int { return len(it.items) } func (it *StoredInfoTypeIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/dlp/apiv2/dlp_client_example_test.go000066400000000000000000000266341356504100700236210ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package dlp_test import ( "context" dlp "cloud.google.com/go/dlp/apiv2" "google.golang.org/api/iterator" dlppb "google.golang.org/genproto/googleapis/privacy/dlp/v2" ) func ExampleNewClient() { ctx := context.Background() c, err := dlp.NewClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleClient_InspectContent() { ctx := context.Background() c, err := dlp.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &dlppb.InspectContentRequest{ // TODO: Fill request struct fields. } resp, err := c.InspectContent(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_RedactImage() { ctx := context.Background() c, err := dlp.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &dlppb.RedactImageRequest{ // TODO: Fill request struct fields. } resp, err := c.RedactImage(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_DeidentifyContent() { ctx := context.Background() c, err := dlp.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &dlppb.DeidentifyContentRequest{ // TODO: Fill request struct fields. } resp, err := c.DeidentifyContent(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ReidentifyContent() { ctx := context.Background() c, err := dlp.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &dlppb.ReidentifyContentRequest{ // TODO: Fill request struct fields. } resp, err := c.ReidentifyContent(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ListInfoTypes() { ctx := context.Background() c, err := dlp.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &dlppb.ListInfoTypesRequest{ // TODO: Fill request struct fields. } resp, err := c.ListInfoTypes(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_CreateInspectTemplate() { ctx := context.Background() c, err := dlp.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &dlppb.CreateInspectTemplateRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateInspectTemplate(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_UpdateInspectTemplate() { ctx := context.Background() c, err := dlp.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &dlppb.UpdateInspectTemplateRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateInspectTemplate(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_GetInspectTemplate() { ctx := context.Background() c, err := dlp.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &dlppb.GetInspectTemplateRequest{ // TODO: Fill request struct fields. } resp, err := c.GetInspectTemplate(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ListInspectTemplates() { ctx := context.Background() c, err := dlp.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &dlppb.ListInspectTemplatesRequest{ // TODO: Fill request struct fields. } it := c.ListInspectTemplates(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_DeleteInspectTemplate() { ctx := context.Background() c, err := dlp.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &dlppb.DeleteInspectTemplateRequest{ // TODO: Fill request struct fields. } err = c.DeleteInspectTemplate(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleClient_CreateDeidentifyTemplate() { ctx := context.Background() c, err := dlp.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &dlppb.CreateDeidentifyTemplateRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateDeidentifyTemplate(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_UpdateDeidentifyTemplate() { ctx := context.Background() c, err := dlp.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &dlppb.UpdateDeidentifyTemplateRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateDeidentifyTemplate(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_GetDeidentifyTemplate() { ctx := context.Background() c, err := dlp.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &dlppb.GetDeidentifyTemplateRequest{ // TODO: Fill request struct fields. } resp, err := c.GetDeidentifyTemplate(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ListDeidentifyTemplates() { ctx := context.Background() c, err := dlp.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &dlppb.ListDeidentifyTemplatesRequest{ // TODO: Fill request struct fields. } it := c.ListDeidentifyTemplates(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_DeleteDeidentifyTemplate() { ctx := context.Background() c, err := dlp.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &dlppb.DeleteDeidentifyTemplateRequest{ // TODO: Fill request struct fields. } err = c.DeleteDeidentifyTemplate(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleClient_CreateDlpJob() { ctx := context.Background() c, err := dlp.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &dlppb.CreateDlpJobRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateDlpJob(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ListDlpJobs() { ctx := context.Background() c, err := dlp.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &dlppb.ListDlpJobsRequest{ // TODO: Fill request struct fields. } it := c.ListDlpJobs(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_GetDlpJob() { ctx := context.Background() c, err := dlp.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &dlppb.GetDlpJobRequest{ // TODO: Fill request struct fields. } resp, err := c.GetDlpJob(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_DeleteDlpJob() { ctx := context.Background() c, err := dlp.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &dlppb.DeleteDlpJobRequest{ // TODO: Fill request struct fields. } err = c.DeleteDlpJob(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleClient_CancelDlpJob() { ctx := context.Background() c, err := dlp.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &dlppb.CancelDlpJobRequest{ // TODO: Fill request struct fields. } err = c.CancelDlpJob(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleClient_ListJobTriggers() { ctx := context.Background() c, err := dlp.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &dlppb.ListJobTriggersRequest{ // TODO: Fill request struct fields. } it := c.ListJobTriggers(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_GetJobTrigger() { ctx := context.Background() c, err := dlp.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &dlppb.GetJobTriggerRequest{ // TODO: Fill request struct fields. } resp, err := c.GetJobTrigger(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_DeleteJobTrigger() { ctx := context.Background() c, err := dlp.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &dlppb.DeleteJobTriggerRequest{ // TODO: Fill request struct fields. } err = c.DeleteJobTrigger(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleClient_UpdateJobTrigger() { ctx := context.Background() c, err := dlp.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &dlppb.UpdateJobTriggerRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateJobTrigger(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_CreateJobTrigger() { ctx := context.Background() c, err := dlp.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &dlppb.CreateJobTriggerRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateJobTrigger(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_CreateStoredInfoType() { ctx := context.Background() c, err := dlp.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &dlppb.CreateStoredInfoTypeRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateStoredInfoType(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_UpdateStoredInfoType() { ctx := context.Background() c, err := dlp.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &dlppb.UpdateStoredInfoTypeRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateStoredInfoType(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_GetStoredInfoType() { ctx := context.Background() c, err := dlp.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &dlppb.GetStoredInfoTypeRequest{ // TODO: Fill request struct fields. } resp, err := c.GetStoredInfoType(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ListStoredInfoTypes() { ctx := context.Background() c, err := dlp.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &dlppb.ListStoredInfoTypesRequest{ // TODO: Fill request struct fields. } it := c.ListStoredInfoTypes(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_DeleteStoredInfoType() { ctx := context.Background() c, err := dlp.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &dlppb.DeleteStoredInfoTypeRequest{ // TODO: Fill request struct fields. } err = c.DeleteStoredInfoType(ctx, req) if err != nil { // TODO: Handle error. } } google-cloud-go-0.49.0/dlp/apiv2/doc.go000066400000000000000000000053651356504100700174750ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package dlp is an auto-generated package for the // Cloud Data Loss Prevention (DLP) API. // // Provides methods for detection, risk analysis, and de-identification of // privacy-sensitive fragments in text, images, and Google Cloud Platform // storage repositories. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package dlp // import "cloud.google.com/go/dlp/apiv2" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191115" google-cloud-go-0.49.0/dlp/apiv2/mock_test.go000066400000000000000000001761421356504100700207220ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package dlp import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" "google.golang.org/api/option" dlppb "google.golang.org/genproto/googleapis/privacy/dlp/v2" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockDlpServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. dlppb.DlpServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockDlpServer) InspectContent(ctx context.Context, req *dlppb.InspectContentRequest) (*dlppb.InspectContentResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dlppb.InspectContentResponse), nil } func (s *mockDlpServer) RedactImage(ctx context.Context, req *dlppb.RedactImageRequest) (*dlppb.RedactImageResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dlppb.RedactImageResponse), nil } func (s *mockDlpServer) DeidentifyContent(ctx context.Context, req *dlppb.DeidentifyContentRequest) (*dlppb.DeidentifyContentResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dlppb.DeidentifyContentResponse), nil } func (s *mockDlpServer) ReidentifyContent(ctx context.Context, req *dlppb.ReidentifyContentRequest) (*dlppb.ReidentifyContentResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dlppb.ReidentifyContentResponse), nil } func (s *mockDlpServer) ListInfoTypes(ctx context.Context, req *dlppb.ListInfoTypesRequest) (*dlppb.ListInfoTypesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dlppb.ListInfoTypesResponse), nil } func (s *mockDlpServer) CreateInspectTemplate(ctx context.Context, req *dlppb.CreateInspectTemplateRequest) (*dlppb.InspectTemplate, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dlppb.InspectTemplate), nil } func (s *mockDlpServer) UpdateInspectTemplate(ctx context.Context, req *dlppb.UpdateInspectTemplateRequest) (*dlppb.InspectTemplate, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dlppb.InspectTemplate), nil } func (s *mockDlpServer) GetInspectTemplate(ctx context.Context, req *dlppb.GetInspectTemplateRequest) (*dlppb.InspectTemplate, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dlppb.InspectTemplate), nil } func (s *mockDlpServer) ListInspectTemplates(ctx context.Context, req *dlppb.ListInspectTemplatesRequest) (*dlppb.ListInspectTemplatesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dlppb.ListInspectTemplatesResponse), nil } func (s *mockDlpServer) DeleteInspectTemplate(ctx context.Context, req *dlppb.DeleteInspectTemplateRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockDlpServer) CreateDeidentifyTemplate(ctx context.Context, req *dlppb.CreateDeidentifyTemplateRequest) (*dlppb.DeidentifyTemplate, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dlppb.DeidentifyTemplate), nil } func (s *mockDlpServer) UpdateDeidentifyTemplate(ctx context.Context, req *dlppb.UpdateDeidentifyTemplateRequest) (*dlppb.DeidentifyTemplate, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dlppb.DeidentifyTemplate), nil } func (s *mockDlpServer) GetDeidentifyTemplate(ctx context.Context, req *dlppb.GetDeidentifyTemplateRequest) (*dlppb.DeidentifyTemplate, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dlppb.DeidentifyTemplate), nil } func (s *mockDlpServer) ListDeidentifyTemplates(ctx context.Context, req *dlppb.ListDeidentifyTemplatesRequest) (*dlppb.ListDeidentifyTemplatesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dlppb.ListDeidentifyTemplatesResponse), nil } func (s *mockDlpServer) DeleteDeidentifyTemplate(ctx context.Context, req *dlppb.DeleteDeidentifyTemplateRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockDlpServer) CreateJobTrigger(ctx context.Context, req *dlppb.CreateJobTriggerRequest) (*dlppb.JobTrigger, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dlppb.JobTrigger), nil } func (s *mockDlpServer) UpdateJobTrigger(ctx context.Context, req *dlppb.UpdateJobTriggerRequest) (*dlppb.JobTrigger, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dlppb.JobTrigger), nil } func (s *mockDlpServer) GetJobTrigger(ctx context.Context, req *dlppb.GetJobTriggerRequest) (*dlppb.JobTrigger, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dlppb.JobTrigger), nil } func (s *mockDlpServer) ListJobTriggers(ctx context.Context, req *dlppb.ListJobTriggersRequest) (*dlppb.ListJobTriggersResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dlppb.ListJobTriggersResponse), nil } func (s *mockDlpServer) DeleteJobTrigger(ctx context.Context, req *dlppb.DeleteJobTriggerRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockDlpServer) CreateDlpJob(ctx context.Context, req *dlppb.CreateDlpJobRequest) (*dlppb.DlpJob, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dlppb.DlpJob), nil } func (s *mockDlpServer) ListDlpJobs(ctx context.Context, req *dlppb.ListDlpJobsRequest) (*dlppb.ListDlpJobsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dlppb.ListDlpJobsResponse), nil } func (s *mockDlpServer) GetDlpJob(ctx context.Context, req *dlppb.GetDlpJobRequest) (*dlppb.DlpJob, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dlppb.DlpJob), nil } func (s *mockDlpServer) DeleteDlpJob(ctx context.Context, req *dlppb.DeleteDlpJobRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockDlpServer) CancelDlpJob(ctx context.Context, req *dlppb.CancelDlpJobRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockDlpServer) CreateStoredInfoType(ctx context.Context, req *dlppb.CreateStoredInfoTypeRequest) (*dlppb.StoredInfoType, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dlppb.StoredInfoType), nil } func (s *mockDlpServer) UpdateStoredInfoType(ctx context.Context, req *dlppb.UpdateStoredInfoTypeRequest) (*dlppb.StoredInfoType, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dlppb.StoredInfoType), nil } func (s *mockDlpServer) GetStoredInfoType(ctx context.Context, req *dlppb.GetStoredInfoTypeRequest) (*dlppb.StoredInfoType, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dlppb.StoredInfoType), nil } func (s *mockDlpServer) ListStoredInfoTypes(ctx context.Context, req *dlppb.ListStoredInfoTypesRequest) (*dlppb.ListStoredInfoTypesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*dlppb.ListStoredInfoTypesResponse), nil } func (s *mockDlpServer) DeleteStoredInfoType(ctx context.Context, req *dlppb.DeleteStoredInfoTypeRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockDlp mockDlpServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() dlppb.RegisterDlpServiceServer(serv, &mockDlp) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestDlpServiceInspectContent(t *testing.T) { var expectedResponse *dlppb.InspectContentResponse = &dlppb.InspectContentResponse{} mockDlp.err = nil mockDlp.reqs = nil mockDlp.resps = append(mockDlp.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &dlppb.InspectContentRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.InspectContent(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDlpServiceInspectContentError(t *testing.T) { errCode := codes.PermissionDenied mockDlp.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &dlppb.InspectContentRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.InspectContent(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDlpServiceRedactImage(t *testing.T) { var redactedImage []byte = []byte("28") var extractedText string = "extractedText998260012" var expectedResponse = &dlppb.RedactImageResponse{ RedactedImage: redactedImage, ExtractedText: extractedText, } mockDlp.err = nil mockDlp.reqs = nil mockDlp.resps = append(mockDlp.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &dlppb.RedactImageRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.RedactImage(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDlpServiceRedactImageError(t *testing.T) { errCode := codes.PermissionDenied mockDlp.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &dlppb.RedactImageRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.RedactImage(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDlpServiceDeidentifyContent(t *testing.T) { var expectedResponse *dlppb.DeidentifyContentResponse = &dlppb.DeidentifyContentResponse{} mockDlp.err = nil mockDlp.reqs = nil mockDlp.resps = append(mockDlp.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &dlppb.DeidentifyContentRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.DeidentifyContent(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDlpServiceDeidentifyContentError(t *testing.T) { errCode := codes.PermissionDenied mockDlp.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &dlppb.DeidentifyContentRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.DeidentifyContent(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDlpServiceReidentifyContent(t *testing.T) { var expectedResponse *dlppb.ReidentifyContentResponse = &dlppb.ReidentifyContentResponse{} mockDlp.err = nil mockDlp.reqs = nil mockDlp.resps = append(mockDlp.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &dlppb.ReidentifyContentRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ReidentifyContent(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDlpServiceReidentifyContentError(t *testing.T) { errCode := codes.PermissionDenied mockDlp.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &dlppb.ReidentifyContentRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ReidentifyContent(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDlpServiceListInfoTypes(t *testing.T) { var expectedResponse *dlppb.ListInfoTypesResponse = &dlppb.ListInfoTypesResponse{} mockDlp.err = nil mockDlp.reqs = nil mockDlp.resps = append(mockDlp.resps[:0], expectedResponse) var request *dlppb.ListInfoTypesRequest = &dlppb.ListInfoTypesRequest{} c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListInfoTypes(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDlpServiceListInfoTypesError(t *testing.T) { errCode := codes.PermissionDenied mockDlp.err = gstatus.Error(errCode, "test error") var request *dlppb.ListInfoTypesRequest = &dlppb.ListInfoTypesRequest{} c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListInfoTypes(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDlpServiceCreateInspectTemplate(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var description string = "description-1724546052" var expectedResponse = &dlppb.InspectTemplate{ Name: name, DisplayName: displayName, Description: description, } mockDlp.err = nil mockDlp.reqs = nil mockDlp.resps = append(mockDlp.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]") var request = &dlppb.CreateInspectTemplateRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateInspectTemplate(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDlpServiceCreateInspectTemplateError(t *testing.T) { errCode := codes.PermissionDenied mockDlp.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]") var request = &dlppb.CreateInspectTemplateRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateInspectTemplate(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDlpServiceUpdateInspectTemplate(t *testing.T) { var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var description string = "description-1724546052" var expectedResponse = &dlppb.InspectTemplate{ Name: name2, DisplayName: displayName, Description: description, } mockDlp.err = nil mockDlp.reqs = nil mockDlp.resps = append(mockDlp.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("organizations/%s/inspectTemplates/%s", "[ORGANIZATION]", "[INSPECT_TEMPLATE]") var request = &dlppb.UpdateInspectTemplateRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateInspectTemplate(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDlpServiceUpdateInspectTemplateError(t *testing.T) { errCode := codes.PermissionDenied mockDlp.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("organizations/%s/inspectTemplates/%s", "[ORGANIZATION]", "[INSPECT_TEMPLATE]") var request = &dlppb.UpdateInspectTemplateRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateInspectTemplate(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDlpServiceGetInspectTemplate(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var description string = "description-1724546052" var expectedResponse = &dlppb.InspectTemplate{ Name: name, DisplayName: displayName, Description: description, } mockDlp.err = nil mockDlp.reqs = nil mockDlp.resps = append(mockDlp.resps[:0], expectedResponse) var request *dlppb.GetInspectTemplateRequest = &dlppb.GetInspectTemplateRequest{} c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetInspectTemplate(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDlpServiceGetInspectTemplateError(t *testing.T) { errCode := codes.PermissionDenied mockDlp.err = gstatus.Error(errCode, "test error") var request *dlppb.GetInspectTemplateRequest = &dlppb.GetInspectTemplateRequest{} c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetInspectTemplate(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDlpServiceListInspectTemplates(t *testing.T) { var nextPageToken string = "" var inspectTemplatesElement *dlppb.InspectTemplate = &dlppb.InspectTemplate{} var inspectTemplates = []*dlppb.InspectTemplate{inspectTemplatesElement} var expectedResponse = &dlppb.ListInspectTemplatesResponse{ NextPageToken: nextPageToken, InspectTemplates: inspectTemplates, } mockDlp.err = nil mockDlp.reqs = nil mockDlp.resps = append(mockDlp.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]") var request = &dlppb.ListInspectTemplatesRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListInspectTemplates(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.InspectTemplates[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDlpServiceListInspectTemplatesError(t *testing.T) { errCode := codes.PermissionDenied mockDlp.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]") var request = &dlppb.ListInspectTemplatesRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListInspectTemplates(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDlpServiceDeleteInspectTemplate(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockDlp.err = nil mockDlp.reqs = nil mockDlp.resps = append(mockDlp.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("organizations/%s/inspectTemplates/%s", "[ORGANIZATION]", "[INSPECT_TEMPLATE]") var request = &dlppb.DeleteInspectTemplateRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteInspectTemplate(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestDlpServiceDeleteInspectTemplateError(t *testing.T) { errCode := codes.PermissionDenied mockDlp.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("organizations/%s/inspectTemplates/%s", "[ORGANIZATION]", "[INSPECT_TEMPLATE]") var request = &dlppb.DeleteInspectTemplateRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteInspectTemplate(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestDlpServiceCreateDeidentifyTemplate(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var description string = "description-1724546052" var expectedResponse = &dlppb.DeidentifyTemplate{ Name: name, DisplayName: displayName, Description: description, } mockDlp.err = nil mockDlp.reqs = nil mockDlp.resps = append(mockDlp.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]") var request = &dlppb.CreateDeidentifyTemplateRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateDeidentifyTemplate(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDlpServiceCreateDeidentifyTemplateError(t *testing.T) { errCode := codes.PermissionDenied mockDlp.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]") var request = &dlppb.CreateDeidentifyTemplateRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateDeidentifyTemplate(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDlpServiceUpdateDeidentifyTemplate(t *testing.T) { var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var description string = "description-1724546052" var expectedResponse = &dlppb.DeidentifyTemplate{ Name: name2, DisplayName: displayName, Description: description, } mockDlp.err = nil mockDlp.reqs = nil mockDlp.resps = append(mockDlp.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("organizations/%s/deidentifyTemplates/%s", "[ORGANIZATION]", "[DEIDENTIFY_TEMPLATE]") var request = &dlppb.UpdateDeidentifyTemplateRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateDeidentifyTemplate(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDlpServiceUpdateDeidentifyTemplateError(t *testing.T) { errCode := codes.PermissionDenied mockDlp.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("organizations/%s/deidentifyTemplates/%s", "[ORGANIZATION]", "[DEIDENTIFY_TEMPLATE]") var request = &dlppb.UpdateDeidentifyTemplateRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateDeidentifyTemplate(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDlpServiceGetDeidentifyTemplate(t *testing.T) { var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var description string = "description-1724546052" var expectedResponse = &dlppb.DeidentifyTemplate{ Name: name2, DisplayName: displayName, Description: description, } mockDlp.err = nil mockDlp.reqs = nil mockDlp.resps = append(mockDlp.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("organizations/%s/deidentifyTemplates/%s", "[ORGANIZATION]", "[DEIDENTIFY_TEMPLATE]") var request = &dlppb.GetDeidentifyTemplateRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetDeidentifyTemplate(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDlpServiceGetDeidentifyTemplateError(t *testing.T) { errCode := codes.PermissionDenied mockDlp.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("organizations/%s/deidentifyTemplates/%s", "[ORGANIZATION]", "[DEIDENTIFY_TEMPLATE]") var request = &dlppb.GetDeidentifyTemplateRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetDeidentifyTemplate(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDlpServiceListDeidentifyTemplates(t *testing.T) { var nextPageToken string = "" var deidentifyTemplatesElement *dlppb.DeidentifyTemplate = &dlppb.DeidentifyTemplate{} var deidentifyTemplates = []*dlppb.DeidentifyTemplate{deidentifyTemplatesElement} var expectedResponse = &dlppb.ListDeidentifyTemplatesResponse{ NextPageToken: nextPageToken, DeidentifyTemplates: deidentifyTemplates, } mockDlp.err = nil mockDlp.reqs = nil mockDlp.resps = append(mockDlp.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]") var request = &dlppb.ListDeidentifyTemplatesRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListDeidentifyTemplates(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.DeidentifyTemplates[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDlpServiceListDeidentifyTemplatesError(t *testing.T) { errCode := codes.PermissionDenied mockDlp.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]") var request = &dlppb.ListDeidentifyTemplatesRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListDeidentifyTemplates(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDlpServiceDeleteDeidentifyTemplate(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockDlp.err = nil mockDlp.reqs = nil mockDlp.resps = append(mockDlp.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("organizations/%s/deidentifyTemplates/%s", "[ORGANIZATION]", "[DEIDENTIFY_TEMPLATE]") var request = &dlppb.DeleteDeidentifyTemplateRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteDeidentifyTemplate(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestDlpServiceDeleteDeidentifyTemplateError(t *testing.T) { errCode := codes.PermissionDenied mockDlp.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("organizations/%s/deidentifyTemplates/%s", "[ORGANIZATION]", "[DEIDENTIFY_TEMPLATE]") var request = &dlppb.DeleteDeidentifyTemplateRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteDeidentifyTemplate(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestDlpServiceCreateDlpJob(t *testing.T) { var name string = "name3373707" var jobTriggerName string = "jobTriggerName1819490804" var expectedResponse = &dlppb.DlpJob{ Name: name, JobTriggerName: jobTriggerName, } mockDlp.err = nil mockDlp.reqs = nil mockDlp.resps = append(mockDlp.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &dlppb.CreateDlpJobRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateDlpJob(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDlpServiceCreateDlpJobError(t *testing.T) { errCode := codes.PermissionDenied mockDlp.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &dlppb.CreateDlpJobRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateDlpJob(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDlpServiceListDlpJobs(t *testing.T) { var nextPageToken string = "" var jobsElement *dlppb.DlpJob = &dlppb.DlpJob{} var jobs = []*dlppb.DlpJob{jobsElement} var expectedResponse = &dlppb.ListDlpJobsResponse{ NextPageToken: nextPageToken, Jobs: jobs, } mockDlp.err = nil mockDlp.reqs = nil mockDlp.resps = append(mockDlp.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &dlppb.ListDlpJobsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListDlpJobs(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Jobs[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDlpServiceListDlpJobsError(t *testing.T) { errCode := codes.PermissionDenied mockDlp.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &dlppb.ListDlpJobsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListDlpJobs(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDlpServiceGetDlpJob(t *testing.T) { var name2 string = "name2-1052831874" var jobTriggerName string = "jobTriggerName1819490804" var expectedResponse = &dlppb.DlpJob{ Name: name2, JobTriggerName: jobTriggerName, } mockDlp.err = nil mockDlp.reqs = nil mockDlp.resps = append(mockDlp.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/dlpJobs/%s", "[PROJECT]", "[DLP_JOB]") var request = &dlppb.GetDlpJobRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetDlpJob(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDlpServiceGetDlpJobError(t *testing.T) { errCode := codes.PermissionDenied mockDlp.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/dlpJobs/%s", "[PROJECT]", "[DLP_JOB]") var request = &dlppb.GetDlpJobRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetDlpJob(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDlpServiceDeleteDlpJob(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockDlp.err = nil mockDlp.reqs = nil mockDlp.resps = append(mockDlp.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/dlpJobs/%s", "[PROJECT]", "[DLP_JOB]") var request = &dlppb.DeleteDlpJobRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteDlpJob(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestDlpServiceDeleteDlpJobError(t *testing.T) { errCode := codes.PermissionDenied mockDlp.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/dlpJobs/%s", "[PROJECT]", "[DLP_JOB]") var request = &dlppb.DeleteDlpJobRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteDlpJob(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestDlpServiceCancelDlpJob(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockDlp.err = nil mockDlp.reqs = nil mockDlp.resps = append(mockDlp.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/dlpJobs/%s", "[PROJECT]", "[DLP_JOB]") var request = &dlppb.CancelDlpJobRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.CancelDlpJob(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestDlpServiceCancelDlpJobError(t *testing.T) { errCode := codes.PermissionDenied mockDlp.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/dlpJobs/%s", "[PROJECT]", "[DLP_JOB]") var request = &dlppb.CancelDlpJobRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.CancelDlpJob(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestDlpServiceListJobTriggers(t *testing.T) { var nextPageToken string = "" var jobTriggersElement *dlppb.JobTrigger = &dlppb.JobTrigger{} var jobTriggers = []*dlppb.JobTrigger{jobTriggersElement} var expectedResponse = &dlppb.ListJobTriggersResponse{ NextPageToken: nextPageToken, JobTriggers: jobTriggers, } mockDlp.err = nil mockDlp.reqs = nil mockDlp.resps = append(mockDlp.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &dlppb.ListJobTriggersRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListJobTriggers(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.JobTriggers[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDlpServiceListJobTriggersError(t *testing.T) { errCode := codes.PermissionDenied mockDlp.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &dlppb.ListJobTriggersRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListJobTriggers(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDlpServiceGetJobTrigger(t *testing.T) { var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var description string = "description-1724546052" var expectedResponse = &dlppb.JobTrigger{ Name: name2, DisplayName: displayName, Description: description, } mockDlp.err = nil mockDlp.reqs = nil mockDlp.resps = append(mockDlp.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/jobTriggers/%s", "[PROJECT]", "[JOB_TRIGGER]") var request = &dlppb.GetJobTriggerRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetJobTrigger(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDlpServiceGetJobTriggerError(t *testing.T) { errCode := codes.PermissionDenied mockDlp.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/jobTriggers/%s", "[PROJECT]", "[JOB_TRIGGER]") var request = &dlppb.GetJobTriggerRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetJobTrigger(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDlpServiceDeleteJobTrigger(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockDlp.err = nil mockDlp.reqs = nil mockDlp.resps = append(mockDlp.resps[:0], expectedResponse) var name string = "name3373707" var request = &dlppb.DeleteJobTriggerRequest{ Name: name, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteJobTrigger(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestDlpServiceDeleteJobTriggerError(t *testing.T) { errCode := codes.PermissionDenied mockDlp.err = gstatus.Error(errCode, "test error") var name string = "name3373707" var request = &dlppb.DeleteJobTriggerRequest{ Name: name, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteJobTrigger(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestDlpServiceUpdateJobTrigger(t *testing.T) { var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var description string = "description-1724546052" var expectedResponse = &dlppb.JobTrigger{ Name: name2, DisplayName: displayName, Description: description, } mockDlp.err = nil mockDlp.reqs = nil mockDlp.resps = append(mockDlp.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/jobTriggers/%s", "[PROJECT]", "[JOB_TRIGGER]") var request = &dlppb.UpdateJobTriggerRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateJobTrigger(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDlpServiceUpdateJobTriggerError(t *testing.T) { errCode := codes.PermissionDenied mockDlp.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/jobTriggers/%s", "[PROJECT]", "[JOB_TRIGGER]") var request = &dlppb.UpdateJobTriggerRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateJobTrigger(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDlpServiceCreateJobTrigger(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var description string = "description-1724546052" var expectedResponse = &dlppb.JobTrigger{ Name: name, DisplayName: displayName, Description: description, } mockDlp.err = nil mockDlp.reqs = nil mockDlp.resps = append(mockDlp.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &dlppb.CreateJobTriggerRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateJobTrigger(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDlpServiceCreateJobTriggerError(t *testing.T) { errCode := codes.PermissionDenied mockDlp.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &dlppb.CreateJobTriggerRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateJobTrigger(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDlpServiceCreateStoredInfoType(t *testing.T) { var name string = "name3373707" var expectedResponse = &dlppb.StoredInfoType{ Name: name, } mockDlp.err = nil mockDlp.reqs = nil mockDlp.resps = append(mockDlp.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]") var request = &dlppb.CreateStoredInfoTypeRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateStoredInfoType(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDlpServiceCreateStoredInfoTypeError(t *testing.T) { errCode := codes.PermissionDenied mockDlp.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]") var request = &dlppb.CreateStoredInfoTypeRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateStoredInfoType(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDlpServiceUpdateStoredInfoType(t *testing.T) { var name2 string = "name2-1052831874" var expectedResponse = &dlppb.StoredInfoType{ Name: name2, } mockDlp.err = nil mockDlp.reqs = nil mockDlp.resps = append(mockDlp.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("organizations/%s/storedInfoTypes/%s", "[ORGANIZATION]", "[STORED_INFO_TYPE]") var request = &dlppb.UpdateStoredInfoTypeRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateStoredInfoType(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDlpServiceUpdateStoredInfoTypeError(t *testing.T) { errCode := codes.PermissionDenied mockDlp.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("organizations/%s/storedInfoTypes/%s", "[ORGANIZATION]", "[STORED_INFO_TYPE]") var request = &dlppb.UpdateStoredInfoTypeRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateStoredInfoType(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDlpServiceGetStoredInfoType(t *testing.T) { var name2 string = "name2-1052831874" var expectedResponse = &dlppb.StoredInfoType{ Name: name2, } mockDlp.err = nil mockDlp.reqs = nil mockDlp.resps = append(mockDlp.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("organizations/%s/storedInfoTypes/%s", "[ORGANIZATION]", "[STORED_INFO_TYPE]") var request = &dlppb.GetStoredInfoTypeRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetStoredInfoType(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDlpServiceGetStoredInfoTypeError(t *testing.T) { errCode := codes.PermissionDenied mockDlp.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("organizations/%s/storedInfoTypes/%s", "[ORGANIZATION]", "[STORED_INFO_TYPE]") var request = &dlppb.GetStoredInfoTypeRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetStoredInfoType(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDlpServiceListStoredInfoTypes(t *testing.T) { var nextPageToken string = "" var storedInfoTypesElement *dlppb.StoredInfoType = &dlppb.StoredInfoType{} var storedInfoTypes = []*dlppb.StoredInfoType{storedInfoTypesElement} var expectedResponse = &dlppb.ListStoredInfoTypesResponse{ NextPageToken: nextPageToken, StoredInfoTypes: storedInfoTypes, } mockDlp.err = nil mockDlp.reqs = nil mockDlp.resps = append(mockDlp.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]") var request = &dlppb.ListStoredInfoTypesRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListStoredInfoTypes(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.StoredInfoTypes[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDlpServiceListStoredInfoTypesError(t *testing.T) { errCode := codes.PermissionDenied mockDlp.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]") var request = &dlppb.ListStoredInfoTypesRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListStoredInfoTypes(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDlpServiceDeleteStoredInfoType(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockDlp.err = nil mockDlp.reqs = nil mockDlp.resps = append(mockDlp.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("organizations/%s/storedInfoTypes/%s", "[ORGANIZATION]", "[STORED_INFO_TYPE]") var request = &dlppb.DeleteStoredInfoTypeRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteStoredInfoType(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestDlpServiceDeleteStoredInfoTypeError(t *testing.T) { errCode := codes.PermissionDenied mockDlp.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("organizations/%s/storedInfoTypes/%s", "[ORGANIZATION]", "[STORED_INFO_TYPE]") var request = &dlppb.DeleteStoredInfoTypeRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteStoredInfoType(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } google-cloud-go-0.49.0/doc.go000066400000000000000000000073661356504100700157000ustar00rootroot00000000000000// Copyright 2014 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. /* Package cloud is the root of the packages used to access Google Cloud Services. See https://godoc.org/cloud.google.com/go for a full list of sub-packages. Client Options All clients in sub-packages are configurable via client options. These options are described here: https://godoc.org/google.golang.org/api/option. Authentication and Authorization All the clients in sub-packages support authentication via Google Application Default Credentials (see https://cloud.google.com/docs/authentication/production), or by providing a JSON key file for a Service Account. See the authentication examples in this package for details. Timeouts and Cancellation By default, all requests in sub-packages will run indefinitely, retrying on transient errors when correctness allows. To set timeouts or arrange for cancellation, use contexts. See the examples for details. Do not attempt to control the initial connection (dialing) of a service by setting a timeout on the context passed to NewClient. Dialing is non-blocking, so timeouts would be ineffective and would only interfere with credential refreshing, which uses the same context. Connection Pooling Connection pooling differs in clients based on their transport. Cloud clients either rely on HTTP or gRPC transports to communicate with Google Cloud. Cloud clients that use HTTP (bigquery, compute, storage, and translate) rely on the underlying HTTP transport to cache connections for later re-use. These are cached to the default http.MaxIdleConns and http.MaxIdleConnsPerHost settings in http.DefaultTransport. For gRPC clients (all others in this repo), connection pooling is configurable. Users of cloud client libraries may specify option.WithGRPCConnectionPool(n) as a client option to NewClient calls. This configures the underlying gRPC connections to be pooled and addressed in a round robin fashion. Using the Libraries with Docker Minimal docker images like Alpine lack CA certificates. This causes RPCs to appear to hang, because gRPC retries indefinitely. See https://github.com/googleapis/google-cloud-go/issues/928 for more information. Debugging To see gRPC logs, set the environment variable GRPC_GO_LOG_SEVERITY_LEVEL. See https://godoc.org/google.golang.org/grpc/grpclog for more information. For HTTP logging, set the GODEBUG environment variable to "http2debug=1" or "http2debug=2". Client Stability Clients in this repository are considered alpha or beta unless otherwise marked as stable in the README.md. Semver is not used to communicate stability of clients. Alpha and beta clients may change or go away without notice. Clients marked stable will maintain compatibility with future versions for as long as we can reasonably sustain. Incompatible changes might be made in some situations, including: - Security bugs may prompt backwards-incompatible changes. - Situations in which components are no longer feasible to maintain without making breaking changes, including removal. - Parts of the client surface may be outright unstable and subject to change. These parts of the surface will be labeled with the note, "It is EXPERIMENTAL and subject to change or removal without notice." */ package cloud // import "cloud.google.com/go" google-cloud-go-0.49.0/errorreporting/000077500000000000000000000000001356504100700176535ustar00rootroot00000000000000google-cloud-go-0.49.0/errorreporting/.repo-metadata.json000066400000000000000000000006741356504100700233560ustar00rootroot00000000000000{ "name": "errorreporting", "name_pretty": "Stackdriver Error Reporting", "product_documentation": "https://cloud.google.com/error-reporting", "client_documentation": "https://godoc.org/cloud.google.com/go/errorreporting", "release_level": "alpha", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "clouderrorreporting.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/errorreporting/apiv1beta1/000077500000000000000000000000001356504100700216105ustar00rootroot00000000000000google-cloud-go-0.49.0/errorreporting/apiv1beta1/.repo-metadata.json000066400000000000000000000007061356504100700253070ustar00rootroot00000000000000{ "name": "errorreporting", "name_pretty": "Stackdriver Error Reporting", "product_documentation": "https://cloud.google.com/error-reporting", "client_documentation": "https://godoc.org/cloud.google.com/go/errorreporting/apiv1beta1", "release_level": "beta", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "clouderrorreporting.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/errorreporting/apiv1beta1/ReportErrorEvent_smoke_test.go000066400000000000000000000045371356504100700276740ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package errorreporting import ( "context" "fmt" "strconv" "testing" "time" "cloud.google.com/go/internal/testutil" "google.golang.org/api/iterator" "google.golang.org/api/option" clouderrorreportingpb "google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1" ) var _ = fmt.Sprintf var _ = iterator.Done var _ = strconv.FormatUint var _ = time.Now func TestReportErrorsServiceSmoke(t *testing.T) { if testing.Short() { t.Skip("skipping smoke test in short mode") } ctx := context.Background() ts := testutil.TokenSource(ctx, DefaultAuthScopes()...) if ts == nil { t.Skip("Integration tests skipped. See CONTRIBUTING.md for details") } projectId := testutil.ProjID() _ = projectId c, err := NewReportErrorsClient(ctx, option.WithTokenSource(ts)) if err != nil { t.Fatal(err) } var formattedProjectName string = fmt.Sprintf("projects/%s", projectId) var message string = "[MESSAGE]" var service string = "[SERVICE]" var serviceContext = &clouderrorreportingpb.ServiceContext{ Service: service, } var filePath string = "path/to/file.lang" var lineNumber int32 = 42 var functionName string = "meaningOfLife" var reportLocation = &clouderrorreportingpb.SourceLocation{ FilePath: filePath, LineNumber: lineNumber, FunctionName: functionName, } var context_ = &clouderrorreportingpb.ErrorContext{ ReportLocation: reportLocation, } var event = &clouderrorreportingpb.ReportedErrorEvent{ Message: message, ServiceContext: serviceContext, Context: context_, } var request = &clouderrorreportingpb.ReportErrorEventRequest{ ProjectName: formattedProjectName, Event: event, } if _, err := c.ReportErrorEvent(ctx, request); err != nil { t.Error(err) } } google-cloud-go-0.49.0/errorreporting/apiv1beta1/doc.go000066400000000000000000000057611356504100700227150ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package errorreporting is an auto-generated package for the // Stackdriver Error Reporting API. // // NOTE: This package is in beta. It is not stable, and may be subject to changes. // // Stackdriver Error Reporting groups and counts similar errors from cloud // services. The Stackdriver Error Reporting API provides a way to report new // errors and read access to error groups and their associated errors. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. // // Use the client at cloud.google.com/go/errorreporting in preference to this. package errorreporting // import "cloud.google.com/go/errorreporting/apiv1beta1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191115" google-cloud-go-0.49.0/errorreporting/apiv1beta1/error_group_client.go000066400000000000000000000130411356504100700260410ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package errorreporting import ( "context" "fmt" "math" "net/url" "time" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" "google.golang.org/api/transport" clouderrorreportingpb "google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // ErrorGroupCallOptions contains the retry settings for each method of ErrorGroupClient. type ErrorGroupCallOptions struct { GetGroup []gax.CallOption UpdateGroup []gax.CallOption } func defaultErrorGroupClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("clouderrorreporting.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultErrorGroupCallOptions() *ErrorGroupCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &ErrorGroupCallOptions{ GetGroup: retry[[2]string{"default", "idempotent"}], UpdateGroup: retry[[2]string{"default", "idempotent"}], } } // ErrorGroupClient is a client for interacting with Stackdriver Error Reporting API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type ErrorGroupClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. errorGroupClient clouderrorreportingpb.ErrorGroupServiceClient // The call options for this service. CallOptions *ErrorGroupCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewErrorGroupClient creates a new error group service client. // // Service for retrieving and updating individual error groups. func NewErrorGroupClient(ctx context.Context, opts ...option.ClientOption) (*ErrorGroupClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultErrorGroupClientOptions(), opts...)...) if err != nil { return nil, err } c := &ErrorGroupClient{ conn: conn, CallOptions: defaultErrorGroupCallOptions(), errorGroupClient: clouderrorreportingpb.NewErrorGroupServiceClient(conn), } c.SetGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *ErrorGroupClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *ErrorGroupClient) Close() error { return c.conn.Close() } // SetGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *ErrorGroupClient) SetGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // GetGroup get the specified group. func (c *ErrorGroupClient) GetGroup(ctx context.Context, req *clouderrorreportingpb.GetGroupRequest, opts ...gax.CallOption) (*clouderrorreportingpb.ErrorGroup, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "group_name", url.QueryEscape(req.GetGroupName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetGroup[0:len(c.CallOptions.GetGroup):len(c.CallOptions.GetGroup)], opts...) var resp *clouderrorreportingpb.ErrorGroup err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.errorGroupClient.GetGroup(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateGroup replace the data for the specified group. // Fails if the group does not exist. func (c *ErrorGroupClient) UpdateGroup(ctx context.Context, req *clouderrorreportingpb.UpdateGroupRequest, opts ...gax.CallOption) (*clouderrorreportingpb.ErrorGroup, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "group.name", url.QueryEscape(req.GetGroup().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateGroup[0:len(c.CallOptions.UpdateGroup):len(c.CallOptions.UpdateGroup)], opts...) var resp *clouderrorreportingpb.ErrorGroup err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.errorGroupClient.UpdateGroup(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } google-cloud-go-0.49.0/errorreporting/apiv1beta1/error_group_client_example_test.go000066400000000000000000000034111356504100700306130ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package errorreporting_test import ( "context" errorreporting "cloud.google.com/go/errorreporting/apiv1beta1" clouderrorreportingpb "google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1" ) func ExampleNewErrorGroupClient() { ctx := context.Background() c, err := errorreporting.NewErrorGroupClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleErrorGroupClient_GetGroup() { ctx := context.Background() c, err := errorreporting.NewErrorGroupClient(ctx) if err != nil { // TODO: Handle error. } req := &clouderrorreportingpb.GetGroupRequest{ // TODO: Fill request struct fields. } resp, err := c.GetGroup(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleErrorGroupClient_UpdateGroup() { ctx := context.Background() c, err := errorreporting.NewErrorGroupClient(ctx) if err != nil { // TODO: Handle error. } req := &clouderrorreportingpb.UpdateGroupRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateGroup(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/errorreporting/apiv1beta1/error_stats_client.go000066400000000000000000000260141356504100700260470ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package errorreporting import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" clouderrorreportingpb "google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // ErrorStatsCallOptions contains the retry settings for each method of ErrorStatsClient. type ErrorStatsCallOptions struct { ListGroupStats []gax.CallOption ListEvents []gax.CallOption DeleteEvents []gax.CallOption } func defaultErrorStatsClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("clouderrorreporting.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultErrorStatsCallOptions() *ErrorStatsCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &ErrorStatsCallOptions{ ListGroupStats: retry[[2]string{"default", "idempotent"}], ListEvents: retry[[2]string{"default", "idempotent"}], DeleteEvents: retry[[2]string{"default", "idempotent"}], } } // ErrorStatsClient is a client for interacting with Stackdriver Error Reporting API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type ErrorStatsClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. errorStatsClient clouderrorreportingpb.ErrorStatsServiceClient // The call options for this service. CallOptions *ErrorStatsCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewErrorStatsClient creates a new error stats service client. // // An API for retrieving and managing error statistics as well as data for // individual events. func NewErrorStatsClient(ctx context.Context, opts ...option.ClientOption) (*ErrorStatsClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultErrorStatsClientOptions(), opts...)...) if err != nil { return nil, err } c := &ErrorStatsClient{ conn: conn, CallOptions: defaultErrorStatsCallOptions(), errorStatsClient: clouderrorreportingpb.NewErrorStatsServiceClient(conn), } c.SetGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *ErrorStatsClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *ErrorStatsClient) Close() error { return c.conn.Close() } // SetGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *ErrorStatsClient) SetGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // ListGroupStats lists the specified groups. func (c *ErrorStatsClient) ListGroupStats(ctx context.Context, req *clouderrorreportingpb.ListGroupStatsRequest, opts ...gax.CallOption) *ErrorGroupStatsIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "project_name", url.QueryEscape(req.GetProjectName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListGroupStats[0:len(c.CallOptions.ListGroupStats):len(c.CallOptions.ListGroupStats)], opts...) it := &ErrorGroupStatsIterator{} req = proto.Clone(req).(*clouderrorreportingpb.ListGroupStatsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*clouderrorreportingpb.ErrorGroupStats, string, error) { var resp *clouderrorreportingpb.ListGroupStatsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.errorStatsClient.ListGroupStats(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.ErrorGroupStats, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // ListEvents lists the specified events. func (c *ErrorStatsClient) ListEvents(ctx context.Context, req *clouderrorreportingpb.ListEventsRequest, opts ...gax.CallOption) *ErrorEventIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "project_name", url.QueryEscape(req.GetProjectName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListEvents[0:len(c.CallOptions.ListEvents):len(c.CallOptions.ListEvents)], opts...) it := &ErrorEventIterator{} req = proto.Clone(req).(*clouderrorreportingpb.ListEventsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*clouderrorreportingpb.ErrorEvent, string, error) { var resp *clouderrorreportingpb.ListEventsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.errorStatsClient.ListEvents(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.ErrorEvents, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // DeleteEvents deletes all error events of a given project. func (c *ErrorStatsClient) DeleteEvents(ctx context.Context, req *clouderrorreportingpb.DeleteEventsRequest, opts ...gax.CallOption) (*clouderrorreportingpb.DeleteEventsResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "project_name", url.QueryEscape(req.GetProjectName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteEvents[0:len(c.CallOptions.DeleteEvents):len(c.CallOptions.DeleteEvents)], opts...) var resp *clouderrorreportingpb.DeleteEventsResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.errorStatsClient.DeleteEvents(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ErrorEventIterator manages a stream of *clouderrorreportingpb.ErrorEvent. type ErrorEventIterator struct { items []*clouderrorreportingpb.ErrorEvent pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*clouderrorreportingpb.ErrorEvent, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *ErrorEventIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *ErrorEventIterator) Next() (*clouderrorreportingpb.ErrorEvent, error) { var item *clouderrorreportingpb.ErrorEvent if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *ErrorEventIterator) bufLen() int { return len(it.items) } func (it *ErrorEventIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // ErrorGroupStatsIterator manages a stream of *clouderrorreportingpb.ErrorGroupStats. type ErrorGroupStatsIterator struct { items []*clouderrorreportingpb.ErrorGroupStats pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*clouderrorreportingpb.ErrorGroupStats, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *ErrorGroupStatsIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *ErrorGroupStatsIterator) Next() (*clouderrorreportingpb.ErrorGroupStats, error) { var item *clouderrorreportingpb.ErrorGroupStats if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *ErrorGroupStatsIterator) bufLen() int { return len(it.items) } func (it *ErrorGroupStatsIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/errorreporting/apiv1beta1/error_stats_client_example_test.go000066400000000000000000000045151356504100700306230ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package errorreporting_test import ( "context" errorreporting "cloud.google.com/go/errorreporting/apiv1beta1" "google.golang.org/api/iterator" clouderrorreportingpb "google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1" ) func ExampleNewErrorStatsClient() { ctx := context.Background() c, err := errorreporting.NewErrorStatsClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleErrorStatsClient_ListGroupStats() { ctx := context.Background() c, err := errorreporting.NewErrorStatsClient(ctx) if err != nil { // TODO: Handle error. } req := &clouderrorreportingpb.ListGroupStatsRequest{ // TODO: Fill request struct fields. } it := c.ListGroupStats(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleErrorStatsClient_ListEvents() { ctx := context.Background() c, err := errorreporting.NewErrorStatsClient(ctx) if err != nil { // TODO: Handle error. } req := &clouderrorreportingpb.ListEventsRequest{ // TODO: Fill request struct fields. } it := c.ListEvents(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleErrorStatsClient_DeleteEvents() { ctx := context.Background() c, err := errorreporting.NewErrorStatsClient(ctx) if err != nil { // TODO: Handle error. } req := &clouderrorreportingpb.DeleteEventsRequest{ // TODO: Fill request struct fields. } resp, err := c.DeleteEvents(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/errorreporting/apiv1beta1/mock_test.go000066400000000000000000000422141356504100700241320ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package errorreporting import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" "google.golang.org/api/option" clouderrorreportingpb "google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockErrorGroupServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. clouderrorreportingpb.ErrorGroupServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockErrorGroupServer) GetGroup(ctx context.Context, req *clouderrorreportingpb.GetGroupRequest) (*clouderrorreportingpb.ErrorGroup, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*clouderrorreportingpb.ErrorGroup), nil } func (s *mockErrorGroupServer) UpdateGroup(ctx context.Context, req *clouderrorreportingpb.UpdateGroupRequest) (*clouderrorreportingpb.ErrorGroup, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*clouderrorreportingpb.ErrorGroup), nil } type mockErrorStatsServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. clouderrorreportingpb.ErrorStatsServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockErrorStatsServer) ListGroupStats(ctx context.Context, req *clouderrorreportingpb.ListGroupStatsRequest) (*clouderrorreportingpb.ListGroupStatsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*clouderrorreportingpb.ListGroupStatsResponse), nil } func (s *mockErrorStatsServer) ListEvents(ctx context.Context, req *clouderrorreportingpb.ListEventsRequest) (*clouderrorreportingpb.ListEventsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*clouderrorreportingpb.ListEventsResponse), nil } func (s *mockErrorStatsServer) DeleteEvents(ctx context.Context, req *clouderrorreportingpb.DeleteEventsRequest) (*clouderrorreportingpb.DeleteEventsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*clouderrorreportingpb.DeleteEventsResponse), nil } type mockReportErrorsServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. clouderrorreportingpb.ReportErrorsServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockReportErrorsServer) ReportErrorEvent(ctx context.Context, req *clouderrorreportingpb.ReportErrorEventRequest) (*clouderrorreportingpb.ReportErrorEventResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*clouderrorreportingpb.ReportErrorEventResponse), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockErrorGroup mockErrorGroupServer mockErrorStats mockErrorStatsServer mockReportErrors mockReportErrorsServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() clouderrorreportingpb.RegisterErrorGroupServiceServer(serv, &mockErrorGroup) clouderrorreportingpb.RegisterErrorStatsServiceServer(serv, &mockErrorStats) clouderrorreportingpb.RegisterReportErrorsServiceServer(serv, &mockReportErrors) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestErrorGroupServiceGetGroup(t *testing.T) { var name string = "name3373707" var groupId string = "groupId506361563" var expectedResponse = &clouderrorreportingpb.ErrorGroup{ Name: name, GroupId: groupId, } mockErrorGroup.err = nil mockErrorGroup.reqs = nil mockErrorGroup.resps = append(mockErrorGroup.resps[:0], expectedResponse) var formattedGroupName string = fmt.Sprintf("projects/%s/groups/%s", "[PROJECT]", "[GROUP]") var request = &clouderrorreportingpb.GetGroupRequest{ GroupName: formattedGroupName, } c, err := NewErrorGroupClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetGroup(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockErrorGroup.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestErrorGroupServiceGetGroupError(t *testing.T) { errCode := codes.PermissionDenied mockErrorGroup.err = gstatus.Error(errCode, "test error") var formattedGroupName string = fmt.Sprintf("projects/%s/groups/%s", "[PROJECT]", "[GROUP]") var request = &clouderrorreportingpb.GetGroupRequest{ GroupName: formattedGroupName, } c, err := NewErrorGroupClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetGroup(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestErrorGroupServiceUpdateGroup(t *testing.T) { var name string = "name3373707" var groupId string = "groupId506361563" var expectedResponse = &clouderrorreportingpb.ErrorGroup{ Name: name, GroupId: groupId, } mockErrorGroup.err = nil mockErrorGroup.reqs = nil mockErrorGroup.resps = append(mockErrorGroup.resps[:0], expectedResponse) var group *clouderrorreportingpb.ErrorGroup = &clouderrorreportingpb.ErrorGroup{} var request = &clouderrorreportingpb.UpdateGroupRequest{ Group: group, } c, err := NewErrorGroupClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateGroup(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockErrorGroup.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestErrorGroupServiceUpdateGroupError(t *testing.T) { errCode := codes.PermissionDenied mockErrorGroup.err = gstatus.Error(errCode, "test error") var group *clouderrorreportingpb.ErrorGroup = &clouderrorreportingpb.ErrorGroup{} var request = &clouderrorreportingpb.UpdateGroupRequest{ Group: group, } c, err := NewErrorGroupClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateGroup(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestErrorStatsServiceListGroupStats(t *testing.T) { var nextPageToken string = "" var errorGroupStatsElement *clouderrorreportingpb.ErrorGroupStats = &clouderrorreportingpb.ErrorGroupStats{} var errorGroupStats = []*clouderrorreportingpb.ErrorGroupStats{errorGroupStatsElement} var expectedResponse = &clouderrorreportingpb.ListGroupStatsResponse{ NextPageToken: nextPageToken, ErrorGroupStats: errorGroupStats, } mockErrorStats.err = nil mockErrorStats.reqs = nil mockErrorStats.resps = append(mockErrorStats.resps[:0], expectedResponse) var formattedProjectName string = fmt.Sprintf("projects/%s", "[PROJECT]") var timeRange *clouderrorreportingpb.QueryTimeRange = &clouderrorreportingpb.QueryTimeRange{} var request = &clouderrorreportingpb.ListGroupStatsRequest{ ProjectName: formattedProjectName, TimeRange: timeRange, } c, err := NewErrorStatsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListGroupStats(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockErrorStats.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.ErrorGroupStats[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestErrorStatsServiceListGroupStatsError(t *testing.T) { errCode := codes.PermissionDenied mockErrorStats.err = gstatus.Error(errCode, "test error") var formattedProjectName string = fmt.Sprintf("projects/%s", "[PROJECT]") var timeRange *clouderrorreportingpb.QueryTimeRange = &clouderrorreportingpb.QueryTimeRange{} var request = &clouderrorreportingpb.ListGroupStatsRequest{ ProjectName: formattedProjectName, TimeRange: timeRange, } c, err := NewErrorStatsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListGroupStats(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestErrorStatsServiceListEvents(t *testing.T) { var nextPageToken string = "" var errorEventsElement *clouderrorreportingpb.ErrorEvent = &clouderrorreportingpb.ErrorEvent{} var errorEvents = []*clouderrorreportingpb.ErrorEvent{errorEventsElement} var expectedResponse = &clouderrorreportingpb.ListEventsResponse{ NextPageToken: nextPageToken, ErrorEvents: errorEvents, } mockErrorStats.err = nil mockErrorStats.reqs = nil mockErrorStats.resps = append(mockErrorStats.resps[:0], expectedResponse) var formattedProjectName string = fmt.Sprintf("projects/%s", "[PROJECT]") var groupId string = "groupId506361563" var request = &clouderrorreportingpb.ListEventsRequest{ ProjectName: formattedProjectName, GroupId: groupId, } c, err := NewErrorStatsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListEvents(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockErrorStats.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.ErrorEvents[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestErrorStatsServiceListEventsError(t *testing.T) { errCode := codes.PermissionDenied mockErrorStats.err = gstatus.Error(errCode, "test error") var formattedProjectName string = fmt.Sprintf("projects/%s", "[PROJECT]") var groupId string = "groupId506361563" var request = &clouderrorreportingpb.ListEventsRequest{ ProjectName: formattedProjectName, GroupId: groupId, } c, err := NewErrorStatsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListEvents(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestErrorStatsServiceDeleteEvents(t *testing.T) { var expectedResponse *clouderrorreportingpb.DeleteEventsResponse = &clouderrorreportingpb.DeleteEventsResponse{} mockErrorStats.err = nil mockErrorStats.reqs = nil mockErrorStats.resps = append(mockErrorStats.resps[:0], expectedResponse) var formattedProjectName string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &clouderrorreportingpb.DeleteEventsRequest{ ProjectName: formattedProjectName, } c, err := NewErrorStatsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.DeleteEvents(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockErrorStats.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestErrorStatsServiceDeleteEventsError(t *testing.T) { errCode := codes.PermissionDenied mockErrorStats.err = gstatus.Error(errCode, "test error") var formattedProjectName string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &clouderrorreportingpb.DeleteEventsRequest{ ProjectName: formattedProjectName, } c, err := NewErrorStatsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.DeleteEvents(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestReportErrorsServiceReportErrorEvent(t *testing.T) { var expectedResponse *clouderrorreportingpb.ReportErrorEventResponse = &clouderrorreportingpb.ReportErrorEventResponse{} mockReportErrors.err = nil mockReportErrors.reqs = nil mockReportErrors.resps = append(mockReportErrors.resps[:0], expectedResponse) var formattedProjectName string = fmt.Sprintf("projects/%s", "[PROJECT]") var event *clouderrorreportingpb.ReportedErrorEvent = &clouderrorreportingpb.ReportedErrorEvent{} var request = &clouderrorreportingpb.ReportErrorEventRequest{ ProjectName: formattedProjectName, Event: event, } c, err := NewReportErrorsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ReportErrorEvent(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockReportErrors.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestReportErrorsServiceReportErrorEventError(t *testing.T) { errCode := codes.PermissionDenied mockReportErrors.err = gstatus.Error(errCode, "test error") var formattedProjectName string = fmt.Sprintf("projects/%s", "[PROJECT]") var event *clouderrorreportingpb.ReportedErrorEvent = &clouderrorreportingpb.ReportedErrorEvent{} var request = &clouderrorreportingpb.ReportErrorEventRequest{ ProjectName: formattedProjectName, Event: event, } c, err := NewReportErrorsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ReportErrorEvent(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/errorreporting/apiv1beta1/path_funcs.go000066400000000000000000000024701356504100700242740ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package errorreporting // ResultPath returns the path for the result resource. // // Deprecated: Use // fmt.Sprintf("inspect/results/%s", result) // instead. func ResultPath(result string) string { return "" + "inspect/results/" + result + "" } // ErrorStatsProjectPath returns the path for the project resource. // // Deprecated: Use // fmt.Sprintf("projects/%s", project) // instead. func ErrorStatsProjectPath(project string) string { return "" + "projects/" + project + "" } // ReportErrorsProjectPath returns the path for the project resource. // // Deprecated: Use // fmt.Sprintf("projects/%s", project) // instead. func ReportErrorsProjectPath(project string) string { return "" + "projects/" + project + "" } google-cloud-go-0.49.0/errorreporting/apiv1beta1/report_errors_client.go000066400000000000000000000114511356504100700264060ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package errorreporting import ( "context" "fmt" "math" "net/url" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" "google.golang.org/api/transport" clouderrorreportingpb "google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1" "google.golang.org/grpc" "google.golang.org/grpc/metadata" ) // ReportErrorsCallOptions contains the retry settings for each method of ReportErrorsClient. type ReportErrorsCallOptions struct { ReportErrorEvent []gax.CallOption } func defaultReportErrorsClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("clouderrorreporting.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultReportErrorsCallOptions() *ReportErrorsCallOptions { retry := map[[2]string][]gax.CallOption{} return &ReportErrorsCallOptions{ ReportErrorEvent: retry[[2]string{"default", "non_idempotent"}], } } // ReportErrorsClient is a client for interacting with Stackdriver Error Reporting API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type ReportErrorsClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. reportErrorsClient clouderrorreportingpb.ReportErrorsServiceClient // The call options for this service. CallOptions *ReportErrorsCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewReportErrorsClient creates a new report errors service client. // // An API for reporting error events. func NewReportErrorsClient(ctx context.Context, opts ...option.ClientOption) (*ReportErrorsClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultReportErrorsClientOptions(), opts...)...) if err != nil { return nil, err } c := &ReportErrorsClient{ conn: conn, CallOptions: defaultReportErrorsCallOptions(), reportErrorsClient: clouderrorreportingpb.NewReportErrorsServiceClient(conn), } c.SetGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *ReportErrorsClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *ReportErrorsClient) Close() error { return c.conn.Close() } // SetGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *ReportErrorsClient) SetGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // ReportErrorEvent report an individual error event. // // This endpoint accepts either an OAuth token, // or an // API key // for authentication. To use an API key, append it to the URL as the value of // a key parameter. For example:
POST
// https://clouderrorreporting.googleapis.com/v1beta1/projects/example-project/events:report?key=123ABC456
func (c *ReportErrorsClient) ReportErrorEvent(ctx context.Context, req *clouderrorreportingpb.ReportErrorEventRequest, opts ...gax.CallOption) (*clouderrorreportingpb.ReportErrorEventResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "project_name", url.QueryEscape(req.GetProjectName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ReportErrorEvent[0:len(c.CallOptions.ReportErrorEvent):len(c.CallOptions.ReportErrorEvent)], opts...) var resp *clouderrorreportingpb.ReportErrorEventResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.reportErrorsClient.ReportErrorEvent(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } google-cloud-go-0.49.0/errorreporting/apiv1beta1/report_errors_client_example_test.go000066400000000000000000000026551356504100700311660ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package errorreporting_test import ( "context" errorreporting "cloud.google.com/go/errorreporting/apiv1beta1" clouderrorreportingpb "google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1" ) func ExampleNewReportErrorsClient() { ctx := context.Background() c, err := errorreporting.NewReportErrorsClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleReportErrorsClient_ReportErrorEvent() { ctx := context.Background() c, err := errorreporting.NewReportErrorsClient(ctx) if err != nil { // TODO: Handle error. } req := &clouderrorreportingpb.ReportErrorEventRequest{ // TODO: Fill request struct fields. } resp, err := c.ReportErrorEvent(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/errorreporting/errors.go000066400000000000000000000160371356504100700215250ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package errorreporting is a Google Stackdriver Error Reporting library. // // Any provided stacktraces must match the format produced by https://golang.org/pkg/runtime/#Stack // or as per https://cloud.google.com/error-reporting/reference/rest/v1beta1/projects.events/report#ReportedErrorEvent // for language specific stacktrace formats. // // This package is still experimental and subject to change. // // See https://cloud.google.com/error-reporting/ for more information. package errorreporting // import "cloud.google.com/go/errorreporting" import ( "bytes" "context" "fmt" "log" "net/http" "runtime" "time" vkit "cloud.google.com/go/errorreporting/apiv1beta1" "cloud.google.com/go/internal/version" "github.com/golang/protobuf/ptypes" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" "google.golang.org/api/support/bundler" pb "google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1" ) // Config is additional configuration for Client. type Config struct { // ServiceName identifies the running program and is included in the error reports. // Optional. ServiceName string // ServiceVersion identifies the version of the running program and is // included in the error reports. // Optional. ServiceVersion string // OnError is the function to call if any background // tasks errored. By default, errors are logged. OnError func(err error) } // Entry holds information about the reported error. type Entry struct { Error error Req *http.Request // if error is associated with a request. User string // an identifier for the user affected by the error // Stack specifies the stacktrace and call sequence correlated with // the error. Stack's content must match the format specified by // https://cloud.google.com/error-reporting/reference/rest/v1beta1/projects.events/report#ReportedErrorEvent.message // or at least for Go programs, it must match the format produced // by https://golang.org/pkg/runtime/debug/#Stack. // // If Stack is blank, the result of runtime.Stack will be used instead. Stack []byte } // Client represents a Google Cloud Error Reporting client. type Client struct { projectName string apiClient client serviceContext *pb.ServiceContext bundler *bundler.Bundler onErrorFn func(err error) } var newClient = func(ctx context.Context, opts ...option.ClientOption) (client, error) { client, err := vkit.NewReportErrorsClient(ctx, opts...) if err != nil { return nil, err } client.SetGoogleClientInfo("gccl", version.Repo) return client, nil } // NewClient returns a new error reporting client. Generally you will want // to create a client on program initialization and use it through the lifetime // of the process. func NewClient(ctx context.Context, projectID string, cfg Config, opts ...option.ClientOption) (*Client, error) { if cfg.ServiceName == "" { cfg.ServiceName = "goapp" } c, err := newClient(ctx, opts...) if err != nil { return nil, fmt.Errorf("creating client: %v", err) } client := &Client{ apiClient: c, projectName: "projects/" + projectID, serviceContext: &pb.ServiceContext{ Service: cfg.ServiceName, Version: cfg.ServiceVersion, }, onErrorFn: cfg.OnError, } bundler := bundler.NewBundler((*pb.ReportErrorEventRequest)(nil), func(bundle interface{}) { reqs := bundle.([]*pb.ReportErrorEventRequest) for _, req := range reqs { _, err = client.apiClient.ReportErrorEvent(ctx, req) if err != nil { client.onError(err) } } }) // TODO(jbd): Optimize bundler limits. bundler.DelayThreshold = 2 * time.Second bundler.BundleCountThreshold = 100 bundler.BundleByteThreshold = 1000 bundler.BundleByteLimit = 1000 bundler.BufferedByteLimit = 10000 client.bundler = bundler return client, nil } func (c *Client) onError(err error) { if c.onErrorFn != nil { c.onErrorFn(err) return } log.Println(err) } // Close calls Flush, then closes any resources held by the client. // Close should be called when the client is no longer needed. func (c *Client) Close() error { c.Flush() return c.apiClient.Close() } // Report writes an error report. It doesn't block. Errors in // writing the error report can be handled via Config.OnError. func (c *Client) Report(e Entry) { c.bundler.Add(c.newRequest(e), 1) } // ReportSync writes an error report. It blocks until the entry is written. func (c *Client) ReportSync(ctx context.Context, e Entry) error { _, err := c.apiClient.ReportErrorEvent(ctx, c.newRequest(e)) return err } // Flush blocks until all currently buffered error reports are sent. // // If any errors occurred since the last call to Flush, or the // creation of the client if this is the first call, then Flush reports the // error via the Config.OnError handler. func (c *Client) Flush() { c.bundler.Flush() } func (c *Client) newRequest(e Entry) *pb.ReportErrorEventRequest { var stack string if e.Stack != nil { stack = string(e.Stack) } else { // limit the stack trace to 16k. var buf [16 * 1024]byte stack = chopStack(buf[0:runtime.Stack(buf[:], false)]) } message := e.Error.Error() + "\n" + stack var errorContext *pb.ErrorContext if r := e.Req; r != nil { errorContext = &pb.ErrorContext{ HttpRequest: &pb.HttpRequestContext{ Method: r.Method, Url: r.Host + r.RequestURI, UserAgent: r.UserAgent(), Referrer: r.Referer(), RemoteIp: r.RemoteAddr, }, } } if e.User != "" { if errorContext == nil { errorContext = &pb.ErrorContext{} } errorContext.User = e.User } return &pb.ReportErrorEventRequest{ ProjectName: c.projectName, Event: &pb.ReportedErrorEvent{ EventTime: ptypes.TimestampNow(), ServiceContext: c.serviceContext, Message: message, Context: errorContext, }, } } // chopStack trims a stack trace so that the function which panics or calls // Report is first. func chopStack(s []byte) string { f := []byte("cloud.google.com/go/errorreporting.(*Client).Report") lfFirst := bytes.IndexByte(s, '\n') if lfFirst == -1 { return string(s) } stack := s[lfFirst:] panicLine := bytes.Index(stack, f) if panicLine == -1 { return string(s) } stack = stack[panicLine+1:] for i := 0; i < 2; i++ { nextLine := bytes.IndexByte(stack, '\n') if nextLine == -1 { return string(s) } stack = stack[nextLine+1:] } return string(s[:lfFirst+1]) + string(stack) } type client interface { ReportErrorEvent(ctx context.Context, req *pb.ReportErrorEventRequest, opts ...gax.CallOption) (*pb.ReportErrorEventResponse, error) Close() error } google-cloud-go-0.49.0/errorreporting/errors_test.go000066400000000000000000000113521356504100700225570ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package errorreporting import ( "context" "errors" "strings" "testing" "time" "cloud.google.com/go/internal/testutil" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" pb "google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1" ) type fakeReportErrorsClient struct { req *pb.ReportErrorEventRequest fail bool doneCh chan struct{} } func (c *fakeReportErrorsClient) ReportErrorEvent(ctx context.Context, req *pb.ReportErrorEventRequest, _ ...gax.CallOption) (*pb.ReportErrorEventResponse, error) { defer close(c.doneCh) if c.fail { return nil, errors.New("request failed") } c.req = req return &pb.ReportErrorEventResponse{}, nil } func (c *fakeReportErrorsClient) Close() error { return nil } var defaultConfig = Config{ ServiceName: "myservice", ServiceVersion: "v1.0", } func newFakeReportErrorsClient() *fakeReportErrorsClient { c := &fakeReportErrorsClient{} c.doneCh = make(chan struct{}) return c } func newTestClient(c *fakeReportErrorsClient, cfg Config) *Client { newClient = func(ctx context.Context, opts ...option.ClientOption) (client, error) { return c, nil } t, err := NewClient(context.Background(), testutil.ProjID(), cfg) if err != nil { panic(err) } return t } func commonChecks(t *testing.T, req *pb.ReportErrorEventRequest, fn string) { if req.Event.ServiceContext.Service != "myservice" { t.Errorf("error report didn't contain service name") } if req.Event.ServiceContext.Version != "v1.0" { t.Errorf("error report didn't contain version name") } if !strings.Contains(req.Event.Message, "error") { t.Errorf("error report didn't contain message") } if !strings.Contains(req.Event.Message, fn) { t.Errorf("error report didn't contain stack trace") } if got, want := req.Event.Context.User, "user"; got != want { t.Errorf("got %q, want %q", got, want) } } func TestReport(t *testing.T) { fc := newFakeReportErrorsClient() c := newTestClient(fc, defaultConfig) c.Report(Entry{Error: errors.New("error"), User: "user"}) c.Flush() <-fc.doneCh r := fc.req if r == nil { t.Fatalf("got no error report, expected one") } commonChecks(t, r, "errorreporting.TestReport") } func TestReportSync(t *testing.T) { ctx := context.Background() fc := newFakeReportErrorsClient() c := newTestClient(fc, defaultConfig) if err := c.ReportSync(ctx, Entry{Error: errors.New("error"), User: "user"}); err != nil { t.Fatalf("cannot upload errors: %v", err) } <-fc.doneCh r := fc.req if r == nil { t.Fatalf("got no error report, expected one") } commonChecks(t, r, "errorreporting.TestReport") } func TestOnError(t *testing.T) { fc := newFakeReportErrorsClient() fc.fail = true cfg := defaultConfig errc := make(chan error, 1) cfg.OnError = func(err error) { errc <- err } c := newTestClient(fc, cfg) c.Report(Entry{Error: errors.New("error")}) c.Flush() <-fc.doneCh select { case err := <-errc: if err == nil { t.Error("got nil, want error") } case <-time.After(5 * time.Second): t.Error("timeout") } } func TestChopStack(t *testing.T) { for _, test := range []struct { name string in []byte expected string }{ { name: "Report", in: []byte(` goroutine 39 [running]: runtime/debug.Stack() /gopath/runtime/debug/stack.go:24 +0x79 cloud.google.com/go/errorreporting.(*Client).logInternal() /gopath/cloud.google.com/go/errorreporting/errors.go:259 +0x18b cloud.google.com/go/errorreporting.(*Client).Report() /gopath/cloud.google.com/go/errorreporting/errors.go:248 +0x4ed cloud.google.com/go/errorreporting.TestReport() /gopath/cloud.google.com/go/errorreporting/errors_test.go:137 +0x2a1 testing.tRunner() /gopath/testing/testing.go:610 +0x81 created by testing.(*T).Run /gopath/testing/testing.go:646 +0x2ec `), expected: ` goroutine 39 [running]: cloud.google.com/go/errorreporting.TestReport() /gopath/cloud.google.com/go/errorreporting/errors_test.go:137 +0x2a1 testing.tRunner() /gopath/testing/testing.go:610 +0x81 created by testing.(*T).Run /gopath/testing/testing.go:646 +0x2ec `, }, } { out := chopStack(test.in) if out != test.expected { t.Errorf("case %q: chopStack(%q): got %q want %q", test.name, test.in, out, test.expected) } } } google-cloud-go-0.49.0/errorreporting/example_test.go000066400000000000000000000023711356504100700226770ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package errorreporting_test import ( "context" "errors" "log" "cloud.google.com/go/errorreporting" ) func Example() { // Create the client. ctx := context.Background() ec, err := errorreporting.NewClient(ctx, "my-gcp-project", errorreporting.Config{ ServiceName: "myservice", ServiceVersion: "v1.0", }) if err != nil { // TODO: handle error } defer func() { if err := ec.Close(); err != nil { log.Printf("failed to report errors to Stackdriver: %v", err) } }() // Report an error. err = doSomething() if err != nil { ec.Report(errorreporting.Entry{ Error: err, }) } } func doSomething() error { return errors.New("something went wrong") } google-cloud-go-0.49.0/examples_test.go000066400000000000000000000101501356504100700177710ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package cloud_test import ( "context" "time" "cloud.google.com/go/bigquery" "cloud.google.com/go/datastore" "cloud.google.com/go/pubsub" "golang.org/x/oauth2/google" "google.golang.org/api/option" ) // To set a timeout for an RPC, use context.WithTimeout. func Example_timeout() { ctx := context.Background() // Do not set a timeout on the context passed to NewClient: dialing happens // asynchronously, and the context is used to refresh credentials in the // background. client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: handle error. } // Time out if it takes more than 10 seconds to create a dataset. tctx, cancel := context.WithTimeout(ctx, 10*time.Second) defer cancel() // Always call cancel. if err := client.Dataset("new-dataset").Create(tctx, nil); err != nil { // TODO: handle error. } } // To arrange for an RPC to be canceled, use context.WithCancel. func Example_cancellation() { ctx := context.Background() // Do not cancel the context passed to NewClient: dialing happens asynchronously, // and the context is used to refresh credentials in the background. client, err := bigquery.NewClient(ctx, "project-id") if err != nil { // TODO: handle error. } cctx, cancel := context.WithCancel(ctx) defer cancel() // Always call cancel. // TODO: Make the cancel function available to whatever might want to cancel the // call--perhaps a GUI button. if err := client.Dataset("new-dataset").Create(cctx, nil); err != nil { // TODO: handle error. } } // Google Application Default Credentials is the recommended way to authorize // and authenticate clients. // // For information on how to create and obtain Application Default Credentials, see // https://developers.google.com/identity/protocols/application-default-credentials. func Example_applicationDefaultCredentials() { client, err := datastore.NewClient(context.Background(), "project-id") if err != nil { // TODO: handle error. } _ = client // Use the client. } // You can use a file with credentials to authenticate and authorize, such as a JSON // key file associated with a Google service account. Service Account keys can be // created and downloaded from // https://console.developers.google.com/permissions/serviceaccounts. // // This example uses the Datastore client, but the same steps apply to // the other client libraries underneath this package. func Example_credentialsFile() { client, err := datastore.NewClient(context.Background(), "project-id", option.WithCredentialsFile("/path/to/service-account-key.json")) if err != nil { // TODO: handle error. } _ = client // Use the client. } // In some cases (for instance, you don't want to store secrets on disk), you can // create credentials from in-memory JSON and use the WithCredentials option. // // The google package in this example is at golang.org/x/oauth2/google. // // This example uses the PubSub client, but the same steps apply to // the other client libraries underneath this package. Note that scopes can be // found at https://developers.google.com/identity/protocols/googlescopes, and // are also provided in all auto-generated libraries: for example, // cloud.google.com/go/pubsub/apiv1 provides DefaultAuthScopes. func Example_credentialsFromJSON() { ctx := context.Background() creds, err := google.CredentialsFromJSON(ctx, []byte("JSON creds"), pubsub.ScopePubSub) if err != nil { // TODO: handle error. } client, err := pubsub.NewClient(ctx, "project-id", option.WithCredentials(creds)) if err != nil { // TODO: handle error. } _ = client // Use the client. } google-cloud-go-0.49.0/expr/000077500000000000000000000000001356504100700155465ustar00rootroot00000000000000google-cloud-go-0.49.0/expr/apiv1alpha1/000077500000000000000000000000001356504100700176555ustar00rootroot00000000000000google-cloud-go-0.49.0/expr/apiv1alpha1/.repo-metadata.json000066400000000000000000000006041356504100700233510ustar00rootroot00000000000000{ "name": "expr", "name_pretty": "Common Expression Language API", "product_documentation": "", "client_documentation": "https://godoc.org/cloud.google.com/go/expr/apiv1alpha1", "release_level": "alpha", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go/expr", "api_id": "cel.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/expr/apiv1alpha1/cel_client.go000066400000000000000000000130051356504100700223040ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package expr import ( "context" "math" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" "google.golang.org/api/transport" exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" "google.golang.org/grpc" "google.golang.org/grpc/metadata" ) // CelCallOptions contains the retry settings for each method of CelClient. type CelCallOptions struct { Parse []gax.CallOption Check []gax.CallOption Eval []gax.CallOption } func defaultCelClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("cel.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultCelCallOptions() *CelCallOptions { retry := map[[2]string][]gax.CallOption{} return &CelCallOptions{ Parse: retry[[2]string{"default", "non_idempotent"}], Check: retry[[2]string{"default", "non_idempotent"}], Eval: retry[[2]string{"default", "non_idempotent"}], } } // CelClient is a client for interacting with Common Expression Language. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type CelClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. celClient exprpb.CelServiceClient // The call options for this service. CallOptions *CelCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewCelClient creates a new cel service client. // // Access a CEL implementation from another process or machine. // A CEL implementation is decomposed as a parser, a static checker, // and an evaluator. Every CEL implementation is expected to provide // a server for this API. The API will be used for conformance testing, // utilities, and execution as a service. func NewCelClient(ctx context.Context, opts ...option.ClientOption) (*CelClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultCelClientOptions(), opts...)...) if err != nil { return nil, err } c := &CelClient{ conn: conn, CallOptions: defaultCelCallOptions(), celClient: exprpb.NewCelServiceClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *CelClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *CelClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *CelClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // Parse transforms CEL source text into a parsed representation. func (c *CelClient) Parse(ctx context.Context, req *exprpb.ParseRequest, opts ...gax.CallOption) (*exprpb.ParseResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.Parse[0:len(c.CallOptions.Parse):len(c.CallOptions.Parse)], opts...) var resp *exprpb.ParseResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.celClient.Parse(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // Check runs static checks on a parsed CEL representation and return // an annotated representation, or a set of issues. func (c *CelClient) Check(ctx context.Context, req *exprpb.CheckRequest, opts ...gax.CallOption) (*exprpb.CheckResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.Check[0:len(c.CallOptions.Check):len(c.CallOptions.Check)], opts...) var resp *exprpb.CheckResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.celClient.Check(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // Eval evaluates a parsed or annotation CEL representation given // values of external bindings. func (c *CelClient) Eval(ctx context.Context, req *exprpb.EvalRequest, opts ...gax.CallOption) (*exprpb.EvalResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.Eval[0:len(c.CallOptions.Eval):len(c.CallOptions.Eval)], opts...) var resp *exprpb.EvalResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.celClient.Eval(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } google-cloud-go-0.49.0/expr/apiv1alpha1/cel_client_example_test.go000066400000000000000000000036111356504100700250600ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package expr_test import ( "context" expr "cloud.google.com/go/expr/apiv1alpha1" exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" ) func ExampleNewCelClient() { ctx := context.Background() c, err := expr.NewCelClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleCelClient_Parse() { ctx := context.Background() c, err := expr.NewCelClient(ctx) if err != nil { // TODO: Handle error. } req := &exprpb.ParseRequest{ // TODO: Fill request struct fields. } resp, err := c.Parse(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleCelClient_Check() { ctx := context.Background() c, err := expr.NewCelClient(ctx) if err != nil { // TODO: Handle error. } req := &exprpb.CheckRequest{ // TODO: Fill request struct fields. } resp, err := c.Check(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleCelClient_Eval() { ctx := context.Background() c, err := expr.NewCelClient(ctx) if err != nil { // TODO: Handle error. } req := &exprpb.EvalRequest{ // TODO: Fill request struct fields. } resp, err := c.Eval(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/expr/apiv1alpha1/conformance_client.go000066400000000000000000000133421356504100700240370ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package expr import ( "context" "math" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" "google.golang.org/api/transport" exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" "google.golang.org/grpc" "google.golang.org/grpc/metadata" ) // ConformanceCallOptions contains the retry settings for each method of ConformanceClient. type ConformanceCallOptions struct { Parse []gax.CallOption Check []gax.CallOption Eval []gax.CallOption } func defaultConformanceClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("cel.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultConformanceCallOptions() *ConformanceCallOptions { retry := map[[2]string][]gax.CallOption{} return &ConformanceCallOptions{ Parse: retry[[2]string{"default", "non_idempotent"}], Check: retry[[2]string{"default", "non_idempotent"}], Eval: retry[[2]string{"default", "non_idempotent"}], } } // ConformanceClient is a client for interacting with Common Expression Language. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type ConformanceClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. conformanceClient exprpb.ConformanceServiceClient // The call options for this service. CallOptions *ConformanceCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewConformanceClient creates a new conformance service client. // // Access a CEL implementation from another process or machine. // A CEL implementation is decomposed as a parser, a static checker, // and an evaluator. Every CEL implementation is expected to provide // a server for this API. The API will be used for conformance testing // and other utilities. func NewConformanceClient(ctx context.Context, opts ...option.ClientOption) (*ConformanceClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultConformanceClientOptions(), opts...)...) if err != nil { return nil, err } c := &ConformanceClient{ conn: conn, CallOptions: defaultConformanceCallOptions(), conformanceClient: exprpb.NewConformanceServiceClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *ConformanceClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *ConformanceClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *ConformanceClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // Parse transforms CEL source text into a parsed representation. func (c *ConformanceClient) Parse(ctx context.Context, req *exprpb.ParseRequest, opts ...gax.CallOption) (*exprpb.ParseResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.Parse[0:len(c.CallOptions.Parse):len(c.CallOptions.Parse)], opts...) var resp *exprpb.ParseResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.conformanceClient.Parse(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // Check runs static checks on a parsed CEL representation and return // an annotated representation, or a set of issues. func (c *ConformanceClient) Check(ctx context.Context, req *exprpb.CheckRequest, opts ...gax.CallOption) (*exprpb.CheckResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.Check[0:len(c.CallOptions.Check):len(c.CallOptions.Check)], opts...) var resp *exprpb.CheckResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.conformanceClient.Check(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // Eval evaluates a parsed or annotation CEL representation given // values of external bindings. func (c *ConformanceClient) Eval(ctx context.Context, req *exprpb.EvalRequest, opts ...gax.CallOption) (*exprpb.EvalResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.Eval[0:len(c.CallOptions.Eval):len(c.CallOptions.Eval)], opts...) var resp *exprpb.EvalResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.conformanceClient.Eval(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } google-cloud-go-0.49.0/expr/apiv1alpha1/conformance_client_example_test.go000066400000000000000000000037111356504100700266100ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package expr_test import ( "context" expr "cloud.google.com/go/expr/apiv1alpha1" exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" ) func ExampleNewConformanceClient() { ctx := context.Background() c, err := expr.NewConformanceClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleConformanceClient_Parse() { ctx := context.Background() c, err := expr.NewConformanceClient(ctx) if err != nil { // TODO: Handle error. } req := &exprpb.ParseRequest{ // TODO: Fill request struct fields. } resp, err := c.Parse(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleConformanceClient_Check() { ctx := context.Background() c, err := expr.NewConformanceClient(ctx) if err != nil { // TODO: Handle error. } req := &exprpb.CheckRequest{ // TODO: Fill request struct fields. } resp, err := c.Check(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleConformanceClient_Eval() { ctx := context.Background() c, err := expr.NewConformanceClient(ctx) if err != nil { // TODO: Handle error. } req := &exprpb.EvalRequest{ // TODO: Fill request struct fields. } resp, err := c.Eval(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/expr/apiv1alpha1/doc.go000066400000000000000000000052361356504100700207570ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package expr is an auto-generated package for the // Common Expression Language. // // NOTE: This package is in alpha. It is not stable, and is likely to change. // // Defines common types for the Common Expression Language. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package expr // import "cloud.google.com/go/expr/apiv1alpha1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{} } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191115" google-cloud-go-0.49.0/expr/apiv1alpha1/mock_test.go000066400000000000000000000320531356504100700221770ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package expr import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" "google.golang.org/api/option" exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockConformanceServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. exprpb.ConformanceServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockConformanceServer) Parse(ctx context.Context, req *exprpb.ParseRequest) (*exprpb.ParseResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*exprpb.ParseResponse), nil } func (s *mockConformanceServer) Check(ctx context.Context, req *exprpb.CheckRequest) (*exprpb.CheckResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*exprpb.CheckResponse), nil } func (s *mockConformanceServer) Eval(ctx context.Context, req *exprpb.EvalRequest) (*exprpb.EvalResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*exprpb.EvalResponse), nil } type mockCelServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. exprpb.CelServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockCelServer) Parse(ctx context.Context, req *exprpb.ParseRequest) (*exprpb.ParseResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*exprpb.ParseResponse), nil } func (s *mockCelServer) Check(ctx context.Context, req *exprpb.CheckRequest) (*exprpb.CheckResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*exprpb.CheckResponse), nil } func (s *mockCelServer) Eval(ctx context.Context, req *exprpb.EvalRequest) (*exprpb.EvalResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*exprpb.EvalResponse), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockConformance mockConformanceServer mockCel mockCelServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() exprpb.RegisterConformanceServiceServer(serv, &mockConformance) exprpb.RegisterCelServiceServer(serv, &mockCel) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestConformanceServiceParse(t *testing.T) { var expectedResponse *exprpb.ParseResponse = &exprpb.ParseResponse{} mockConformance.err = nil mockConformance.reqs = nil mockConformance.resps = append(mockConformance.resps[:0], expectedResponse) var celSource string = "celSource912645552" var request = &exprpb.ParseRequest{ CelSource: celSource, } c, err := NewConformanceClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Parse(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockConformance.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestConformanceServiceParseError(t *testing.T) { errCode := codes.PermissionDenied mockConformance.err = gstatus.Error(errCode, "test error") var celSource string = "celSource912645552" var request = &exprpb.ParseRequest{ CelSource: celSource, } c, err := NewConformanceClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Parse(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestConformanceServiceCheck(t *testing.T) { var expectedResponse *exprpb.CheckResponse = &exprpb.CheckResponse{} mockConformance.err = nil mockConformance.reqs = nil mockConformance.resps = append(mockConformance.resps[:0], expectedResponse) var parsedExpr *exprpb.ParsedExpr = &exprpb.ParsedExpr{} var request = &exprpb.CheckRequest{ ParsedExpr: parsedExpr, } c, err := NewConformanceClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Check(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockConformance.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestConformanceServiceCheckError(t *testing.T) { errCode := codes.PermissionDenied mockConformance.err = gstatus.Error(errCode, "test error") var parsedExpr *exprpb.ParsedExpr = &exprpb.ParsedExpr{} var request = &exprpb.CheckRequest{ ParsedExpr: parsedExpr, } c, err := NewConformanceClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Check(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestConformanceServiceEval(t *testing.T) { var expectedResponse *exprpb.EvalResponse = &exprpb.EvalResponse{} mockConformance.err = nil mockConformance.reqs = nil mockConformance.resps = append(mockConformance.resps[:0], expectedResponse) var request *exprpb.EvalRequest = &exprpb.EvalRequest{} c, err := NewConformanceClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Eval(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockConformance.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestConformanceServiceEvalError(t *testing.T) { errCode := codes.PermissionDenied mockConformance.err = gstatus.Error(errCode, "test error") var request *exprpb.EvalRequest = &exprpb.EvalRequest{} c, err := NewConformanceClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Eval(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCelServiceParse(t *testing.T) { var expectedResponse *exprpb.ParseResponse = &exprpb.ParseResponse{} mockCel.err = nil mockCel.reqs = nil mockCel.resps = append(mockCel.resps[:0], expectedResponse) var celSource string = "celSource912645552" var request = &exprpb.ParseRequest{ CelSource: celSource, } c, err := NewCelClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Parse(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCel.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCelServiceParseError(t *testing.T) { errCode := codes.PermissionDenied mockCel.err = gstatus.Error(errCode, "test error") var celSource string = "celSource912645552" var request = &exprpb.ParseRequest{ CelSource: celSource, } c, err := NewCelClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Parse(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCelServiceCheck(t *testing.T) { var expectedResponse *exprpb.CheckResponse = &exprpb.CheckResponse{} mockCel.err = nil mockCel.reqs = nil mockCel.resps = append(mockCel.resps[:0], expectedResponse) var parsedExpr *exprpb.ParsedExpr = &exprpb.ParsedExpr{} var request = &exprpb.CheckRequest{ ParsedExpr: parsedExpr, } c, err := NewCelClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Check(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCel.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCelServiceCheckError(t *testing.T) { errCode := codes.PermissionDenied mockCel.err = gstatus.Error(errCode, "test error") var parsedExpr *exprpb.ParsedExpr = &exprpb.ParsedExpr{} var request = &exprpb.CheckRequest{ ParsedExpr: parsedExpr, } c, err := NewCelClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Check(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCelServiceEval(t *testing.T) { var expectedResponse *exprpb.EvalResponse = &exprpb.EvalResponse{} mockCel.err = nil mockCel.reqs = nil mockCel.resps = append(mockCel.resps[:0], expectedResponse) var request *exprpb.EvalRequest = &exprpb.EvalRequest{} c, err := NewCelClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Eval(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCel.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCelServiceEvalError(t *testing.T) { errCode := codes.PermissionDenied mockCel.err = gstatus.Error(errCode, "test error") var request *exprpb.EvalRequest = &exprpb.EvalRequest{} c, err := NewCelClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Eval(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/firestore/000077500000000000000000000000001356504100700165725ustar00rootroot00000000000000google-cloud-go-0.49.0/firestore/.repo-metadata.json000066400000000000000000000006411356504100700222670ustar00rootroot00000000000000{ "name": "firestore", "name_pretty": "Cloud Firestore API", "product_documentation": "https://cloud.google.com/firestore", "client_documentation": "https://godoc.org/cloud.google.com/go/firestore", "release_level": "ga", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go/firestore", "api_id": "firestore.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/firestore/CHANGES.md000066400000000000000000000004161356504100700201650ustar00rootroot00000000000000# Changes ## v1.1.0 - Add support for `in` and `array-contains-any` query operators. ## v1.0.0 This is the first tag to carve out firestore as its own module. See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository.google-cloud-go-0.49.0/firestore/Makefile000066400000000000000000000006141356504100700202330ustar00rootroot00000000000000# Copy textproto files in this directory from the source of truth. SRC=$(GOPATH)/src/github.com/GoogleCloudPlatform/google-cloud-common/testing/firestore .PHONY: refresh-tests refresh-tests: -rm genproto/*.pb.go cp $(SRC)/genproto/*.pb.go genproto -rm testdata/*.textproto cp $(SRC)/testdata/*.textproto testdata openssl dgst -sha1 $(SRC)/testdata/test-suite.binproto > testdata/VERSION google-cloud-go-0.49.0/firestore/apiv1/000077500000000000000000000000001356504100700176125ustar00rootroot00000000000000google-cloud-go-0.49.0/firestore/apiv1/.repo-metadata.json000066400000000000000000000006371356504100700233140ustar00rootroot00000000000000{ "name": "firestore", "name_pretty": "Cloud Firestore API", "product_documentation": "https://cloud.google.com/firestore", "client_documentation": "https://godoc.org/cloud.google.com/go/firestore/apiv1", "release_level": "beta", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "firestore.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/firestore/apiv1/admin/000077500000000000000000000000001356504100700207025ustar00rootroot00000000000000google-cloud-go-0.49.0/firestore/apiv1/admin/doc.go000066400000000000000000000055231356504100700220030ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package apiv1 is an auto-generated package for the // Google Cloud Firestore Admin API. // // NOTE: This package is in alpha. It is not stable, and is likely to change. // // Accesses the NoSQL document database built for automatic scaling, high // performance, and ease of application development. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package apiv1 // import "cloud.google.com/go/firestore/apiv1/admin" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/datastore", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191115" google-cloud-go-0.49.0/firestore/apiv1/admin/firestore_admin_client.go000066400000000000000000000434561356504100700257550ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package apiv1 import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" adminpb "google.golang.org/genproto/googleapis/firestore/admin/v1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // FirestoreAdminCallOptions contains the retry settings for each method of FirestoreAdminClient. type FirestoreAdminCallOptions struct { CreateIndex []gax.CallOption ListIndexes []gax.CallOption GetIndex []gax.CallOption DeleteIndex []gax.CallOption ImportDocuments []gax.CallOption ExportDocuments []gax.CallOption GetField []gax.CallOption ListFields []gax.CallOption UpdateField []gax.CallOption } func defaultFirestoreAdminClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("firestore.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultFirestoreAdminCallOptions() *FirestoreAdminCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Internal, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &FirestoreAdminCallOptions{ CreateIndex: retry[[2]string{"default", "non_idempotent"}], ListIndexes: retry[[2]string{"default", "idempotent"}], GetIndex: retry[[2]string{"default", "idempotent"}], DeleteIndex: retry[[2]string{"default", "idempotent"}], ImportDocuments: retry[[2]string{"default", "non_idempotent"}], ExportDocuments: retry[[2]string{"default", "non_idempotent"}], GetField: retry[[2]string{"default", "idempotent"}], ListFields: retry[[2]string{"default", "idempotent"}], UpdateField: retry[[2]string{"default", "non_idempotent"}], } } // FirestoreAdminClient is a client for interacting with Google Cloud Firestore Admin API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type FirestoreAdminClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. firestoreAdminClient adminpb.FirestoreAdminClient // The call options for this service. CallOptions *FirestoreAdminCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewFirestoreAdminClient creates a new firestore admin client. // // Operations are created by service FirestoreAdmin, but are accessed via // service google.longrunning.Operations. func NewFirestoreAdminClient(ctx context.Context, opts ...option.ClientOption) (*FirestoreAdminClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultFirestoreAdminClientOptions(), opts...)...) if err != nil { return nil, err } c := &FirestoreAdminClient{ conn: conn, CallOptions: defaultFirestoreAdminCallOptions(), firestoreAdminClient: adminpb.NewFirestoreAdminClient(conn), } c.SetGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *FirestoreAdminClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *FirestoreAdminClient) Close() error { return c.conn.Close() } // SetGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *FirestoreAdminClient) SetGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // CreateIndex creates a composite index. This returns a [google.longrunning.Operation][google.longrunning.Operation] // which may be used to track the status of the creation. The metadata for // the operation will be the type [IndexOperationMetadata][google.firestore.admin.v1.IndexOperationMetadata]. func (c *FirestoreAdminClient) CreateIndex(ctx context.Context, req *adminpb.CreateIndexRequest, opts ...gax.CallOption) (*longrunningpb.Operation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateIndex[0:len(c.CallOptions.CreateIndex):len(c.CallOptions.CreateIndex)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.firestoreAdminClient.CreateIndex(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListIndexes lists composite indexes. func (c *FirestoreAdminClient) ListIndexes(ctx context.Context, req *adminpb.ListIndexesRequest, opts ...gax.CallOption) *IndexIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListIndexes[0:len(c.CallOptions.ListIndexes):len(c.CallOptions.ListIndexes)], opts...) it := &IndexIterator{} req = proto.Clone(req).(*adminpb.ListIndexesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*adminpb.Index, string, error) { var resp *adminpb.ListIndexesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.firestoreAdminClient.ListIndexes(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Indexes, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetIndex gets a composite index. func (c *FirestoreAdminClient) GetIndex(ctx context.Context, req *adminpb.GetIndexRequest, opts ...gax.CallOption) (*adminpb.Index, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetIndex[0:len(c.CallOptions.GetIndex):len(c.CallOptions.GetIndex)], opts...) var resp *adminpb.Index err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.firestoreAdminClient.GetIndex(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteIndex deletes a composite index. func (c *FirestoreAdminClient) DeleteIndex(ctx context.Context, req *adminpb.DeleteIndexRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteIndex[0:len(c.CallOptions.DeleteIndex):len(c.CallOptions.DeleteIndex)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.firestoreAdminClient.DeleteIndex(ctx, req, settings.GRPC...) return err }, opts...) return err } // ImportDocuments imports documents into Google Cloud Firestore. Existing documents with the // same name are overwritten. The import occurs in the background and its // progress can be monitored and managed via the Operation resource that is // created. If an ImportDocuments operation is cancelled, it is possible // that a subset of the data has already been imported to Cloud Firestore. func (c *FirestoreAdminClient) ImportDocuments(ctx context.Context, req *adminpb.ImportDocumentsRequest, opts ...gax.CallOption) (*longrunningpb.Operation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ImportDocuments[0:len(c.CallOptions.ImportDocuments):len(c.CallOptions.ImportDocuments)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.firestoreAdminClient.ImportDocuments(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ExportDocuments exports a copy of all or a subset of documents from Google Cloud Firestore // to another storage system, such as Google Cloud Storage. Recent updates to // documents may not be reflected in the export. The export occurs in the // background and its progress can be monitored and managed via the // Operation resource that is created. The output of an export may only be // used once the associated operation is done. If an export operation is // cancelled before completion it may leave partial data behind in Google // Cloud Storage. func (c *FirestoreAdminClient) ExportDocuments(ctx context.Context, req *adminpb.ExportDocumentsRequest, opts ...gax.CallOption) (*longrunningpb.Operation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ExportDocuments[0:len(c.CallOptions.ExportDocuments):len(c.CallOptions.ExportDocuments)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.firestoreAdminClient.ExportDocuments(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetField gets the metadata and configuration for a Field. func (c *FirestoreAdminClient) GetField(ctx context.Context, req *adminpb.GetFieldRequest, opts ...gax.CallOption) (*adminpb.Field, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetField[0:len(c.CallOptions.GetField):len(c.CallOptions.GetField)], opts...) var resp *adminpb.Field err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.firestoreAdminClient.GetField(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListFields lists the field configuration and metadata for this database. // // Currently, [FirestoreAdmin.ListFields][google.firestore.admin.v1.FirestoreAdmin.ListFields] only supports listing fields // that have been explicitly overridden. To issue this query, call // [FirestoreAdmin.ListFields][google.firestore.admin.v1.FirestoreAdmin.ListFields] with the filter set to // indexConfig.usesAncestorConfig:false. func (c *FirestoreAdminClient) ListFields(ctx context.Context, req *adminpb.ListFieldsRequest, opts ...gax.CallOption) *FieldIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListFields[0:len(c.CallOptions.ListFields):len(c.CallOptions.ListFields)], opts...) it := &FieldIterator{} req = proto.Clone(req).(*adminpb.ListFieldsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*adminpb.Field, string, error) { var resp *adminpb.ListFieldsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.firestoreAdminClient.ListFields(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Fields, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // UpdateField updates a field configuration. Currently, field updates apply only to // single field index configuration. However, calls to // [FirestoreAdmin.UpdateField][google.firestore.admin.v1.FirestoreAdmin.UpdateField] should provide a field mask to avoid // changing any configuration that the caller isn't aware of. The field mask // should be specified as: { paths: "index_config" }. // // This call returns a [google.longrunning.Operation][google.longrunning.Operation] which may be used to // track the status of the field update. The metadata for // the operation will be the type [FieldOperationMetadata][google.firestore.admin.v1.FieldOperationMetadata]. // // To configure the default field settings for the database, use // the special Field with resource name: // projects/{project_id}/databases/{database_id}/collectionGroups/__default__/fields/*. func (c *FirestoreAdminClient) UpdateField(ctx context.Context, req *adminpb.UpdateFieldRequest, opts ...gax.CallOption) (*longrunningpb.Operation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "field.name", url.QueryEscape(req.GetField().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateField[0:len(c.CallOptions.UpdateField):len(c.CallOptions.UpdateField)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.firestoreAdminClient.UpdateField(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // FieldIterator manages a stream of *adminpb.Field. type FieldIterator struct { items []*adminpb.Field pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*adminpb.Field, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *FieldIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *FieldIterator) Next() (*adminpb.Field, error) { var item *adminpb.Field if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *FieldIterator) bufLen() int { return len(it.items) } func (it *FieldIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // IndexIterator manages a stream of *adminpb.Index. type IndexIterator struct { items []*adminpb.Index pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*adminpb.Index, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *IndexIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *IndexIterator) Next() (*adminpb.Index, error) { var item *adminpb.Index if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *IndexIterator) bufLen() int { return len(it.items) } func (it *IndexIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/firestore/apiv1/admin/firestore_admin_client_example_test.go000066400000000000000000000105141356504100700305140ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package apiv1_test import ( "context" apiv1 "cloud.google.com/go/firestore/apiv1/admin" "google.golang.org/api/iterator" adminpb "google.golang.org/genproto/googleapis/firestore/admin/v1" ) func ExampleNewFirestoreAdminClient() { ctx := context.Background() c, err := apiv1.NewFirestoreAdminClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleFirestoreAdminClient_CreateIndex() { ctx := context.Background() c, err := apiv1.NewFirestoreAdminClient(ctx) if err != nil { // TODO: Handle error. } req := &adminpb.CreateIndexRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateIndex(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleFirestoreAdminClient_ListIndexes() { ctx := context.Background() c, err := apiv1.NewFirestoreAdminClient(ctx) if err != nil { // TODO: Handle error. } req := &adminpb.ListIndexesRequest{ // TODO: Fill request struct fields. } it := c.ListIndexes(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleFirestoreAdminClient_GetIndex() { ctx := context.Background() c, err := apiv1.NewFirestoreAdminClient(ctx) if err != nil { // TODO: Handle error. } req := &adminpb.GetIndexRequest{ // TODO: Fill request struct fields. } resp, err := c.GetIndex(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleFirestoreAdminClient_DeleteIndex() { ctx := context.Background() c, err := apiv1.NewFirestoreAdminClient(ctx) if err != nil { // TODO: Handle error. } req := &adminpb.DeleteIndexRequest{ // TODO: Fill request struct fields. } err = c.DeleteIndex(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleFirestoreAdminClient_ImportDocuments() { ctx := context.Background() c, err := apiv1.NewFirestoreAdminClient(ctx) if err != nil { // TODO: Handle error. } req := &adminpb.ImportDocumentsRequest{ // TODO: Fill request struct fields. } resp, err := c.ImportDocuments(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleFirestoreAdminClient_ExportDocuments() { ctx := context.Background() c, err := apiv1.NewFirestoreAdminClient(ctx) if err != nil { // TODO: Handle error. } req := &adminpb.ExportDocumentsRequest{ // TODO: Fill request struct fields. } resp, err := c.ExportDocuments(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleFirestoreAdminClient_GetField() { ctx := context.Background() c, err := apiv1.NewFirestoreAdminClient(ctx) if err != nil { // TODO: Handle error. } req := &adminpb.GetFieldRequest{ // TODO: Fill request struct fields. } resp, err := c.GetField(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleFirestoreAdminClient_ListFields() { ctx := context.Background() c, err := apiv1.NewFirestoreAdminClient(ctx) if err != nil { // TODO: Handle error. } req := &adminpb.ListFieldsRequest{ // TODO: Fill request struct fields. } it := c.ListFields(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleFirestoreAdminClient_UpdateField() { ctx := context.Background() c, err := apiv1.NewFirestoreAdminClient(ctx) if err != nil { // TODO: Handle error. } req := &adminpb.UpdateFieldRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateField(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/firestore/apiv1/admin/mock_test.go000066400000000000000000000533671356504100700232370ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package apiv1 import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" "google.golang.org/api/option" adminpb "google.golang.org/genproto/googleapis/firestore/admin/v1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockFirestoreAdminServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. adminpb.FirestoreAdminServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockFirestoreAdminServer) CreateIndex(ctx context.Context, req *adminpb.CreateIndexRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockFirestoreAdminServer) ListIndexes(ctx context.Context, req *adminpb.ListIndexesRequest) (*adminpb.ListIndexesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*adminpb.ListIndexesResponse), nil } func (s *mockFirestoreAdminServer) GetIndex(ctx context.Context, req *adminpb.GetIndexRequest) (*adminpb.Index, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*adminpb.Index), nil } func (s *mockFirestoreAdminServer) DeleteIndex(ctx context.Context, req *adminpb.DeleteIndexRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockFirestoreAdminServer) GetField(ctx context.Context, req *adminpb.GetFieldRequest) (*adminpb.Field, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*adminpb.Field), nil } func (s *mockFirestoreAdminServer) UpdateField(ctx context.Context, req *adminpb.UpdateFieldRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockFirestoreAdminServer) ListFields(ctx context.Context, req *adminpb.ListFieldsRequest) (*adminpb.ListFieldsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*adminpb.ListFieldsResponse), nil } func (s *mockFirestoreAdminServer) ExportDocuments(ctx context.Context, req *adminpb.ExportDocumentsRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockFirestoreAdminServer) ImportDocuments(ctx context.Context, req *adminpb.ImportDocumentsRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockFirestoreAdmin mockFirestoreAdminServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() adminpb.RegisterFirestoreAdminServer(serv, &mockFirestoreAdmin) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestFirestoreAdminCreateIndex(t *testing.T) { var name string = "name3373707" var done bool = true var expectedResponse = &longrunningpb.Operation{ Name: name, Done: done, } mockFirestoreAdmin.err = nil mockFirestoreAdmin.reqs = nil mockFirestoreAdmin.resps = append(mockFirestoreAdmin.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/databases/%s/collectionGroups/%s", "[PROJECT]", "[DATABASE]", "[COLLECTION_ID]") var index *adminpb.Index = &adminpb.Index{} var request = &adminpb.CreateIndexRequest{ Parent: formattedParent, Index: index, } c, err := NewFirestoreAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateIndex(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockFirestoreAdmin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestFirestoreAdminCreateIndexError(t *testing.T) { errCode := codes.PermissionDenied mockFirestoreAdmin.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/databases/%s/collectionGroups/%s", "[PROJECT]", "[DATABASE]", "[COLLECTION_ID]") var index *adminpb.Index = &adminpb.Index{} var request = &adminpb.CreateIndexRequest{ Parent: formattedParent, Index: index, } c, err := NewFirestoreAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateIndex(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestFirestoreAdminListIndexes(t *testing.T) { var nextPageToken string = "" var indexesElement *adminpb.Index = &adminpb.Index{} var indexes = []*adminpb.Index{indexesElement} var expectedResponse = &adminpb.ListIndexesResponse{ NextPageToken: nextPageToken, Indexes: indexes, } mockFirestoreAdmin.err = nil mockFirestoreAdmin.reqs = nil mockFirestoreAdmin.resps = append(mockFirestoreAdmin.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/databases/%s/collectionGroups/%s", "[PROJECT]", "[DATABASE]", "[COLLECTION_ID]") var request = &adminpb.ListIndexesRequest{ Parent: formattedParent, } c, err := NewFirestoreAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListIndexes(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockFirestoreAdmin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Indexes[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestFirestoreAdminListIndexesError(t *testing.T) { errCode := codes.PermissionDenied mockFirestoreAdmin.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/databases/%s/collectionGroups/%s", "[PROJECT]", "[DATABASE]", "[COLLECTION_ID]") var request = &adminpb.ListIndexesRequest{ Parent: formattedParent, } c, err := NewFirestoreAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListIndexes(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestFirestoreAdminGetIndex(t *testing.T) { var name2 string = "name2-1052831874" var expectedResponse = &adminpb.Index{ Name: name2, } mockFirestoreAdmin.err = nil mockFirestoreAdmin.reqs = nil mockFirestoreAdmin.resps = append(mockFirestoreAdmin.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/databases/%s/collectionGroups/%s/indexes/%s", "[PROJECT]", "[DATABASE]", "[COLLECTION_ID]", "[INDEX_ID]") var request = &adminpb.GetIndexRequest{ Name: formattedName, } c, err := NewFirestoreAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetIndex(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockFirestoreAdmin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestFirestoreAdminGetIndexError(t *testing.T) { errCode := codes.PermissionDenied mockFirestoreAdmin.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/databases/%s/collectionGroups/%s/indexes/%s", "[PROJECT]", "[DATABASE]", "[COLLECTION_ID]", "[INDEX_ID]") var request = &adminpb.GetIndexRequest{ Name: formattedName, } c, err := NewFirestoreAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetIndex(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestFirestoreAdminDeleteIndex(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockFirestoreAdmin.err = nil mockFirestoreAdmin.reqs = nil mockFirestoreAdmin.resps = append(mockFirestoreAdmin.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/databases/%s/collectionGroups/%s/indexes/%s", "[PROJECT]", "[DATABASE]", "[COLLECTION_ID]", "[INDEX_ID]") var request = &adminpb.DeleteIndexRequest{ Name: formattedName, } c, err := NewFirestoreAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteIndex(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockFirestoreAdmin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestFirestoreAdminDeleteIndexError(t *testing.T) { errCode := codes.PermissionDenied mockFirestoreAdmin.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/databases/%s/collectionGroups/%s/indexes/%s", "[PROJECT]", "[DATABASE]", "[COLLECTION_ID]", "[INDEX_ID]") var request = &adminpb.DeleteIndexRequest{ Name: formattedName, } c, err := NewFirestoreAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteIndex(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestFirestoreAdminImportDocuments(t *testing.T) { var name2 string = "name2-1052831874" var done bool = true var expectedResponse = &longrunningpb.Operation{ Name: name2, Done: done, } mockFirestoreAdmin.err = nil mockFirestoreAdmin.reqs = nil mockFirestoreAdmin.resps = append(mockFirestoreAdmin.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/databases/%s", "[PROJECT]", "[DATABASE]") var request = &adminpb.ImportDocumentsRequest{ Name: formattedName, } c, err := NewFirestoreAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ImportDocuments(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockFirestoreAdmin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestFirestoreAdminImportDocumentsError(t *testing.T) { errCode := codes.PermissionDenied mockFirestoreAdmin.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/databases/%s", "[PROJECT]", "[DATABASE]") var request = &adminpb.ImportDocumentsRequest{ Name: formattedName, } c, err := NewFirestoreAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ImportDocuments(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestFirestoreAdminExportDocuments(t *testing.T) { var name2 string = "name2-1052831874" var done bool = true var expectedResponse = &longrunningpb.Operation{ Name: name2, Done: done, } mockFirestoreAdmin.err = nil mockFirestoreAdmin.reqs = nil mockFirestoreAdmin.resps = append(mockFirestoreAdmin.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/databases/%s", "[PROJECT]", "[DATABASE]") var request = &adminpb.ExportDocumentsRequest{ Name: formattedName, } c, err := NewFirestoreAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ExportDocuments(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockFirestoreAdmin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestFirestoreAdminExportDocumentsError(t *testing.T) { errCode := codes.PermissionDenied mockFirestoreAdmin.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/databases/%s", "[PROJECT]", "[DATABASE]") var request = &adminpb.ExportDocumentsRequest{ Name: formattedName, } c, err := NewFirestoreAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ExportDocuments(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestFirestoreAdminGetField(t *testing.T) { var name2 string = "name2-1052831874" var expectedResponse = &adminpb.Field{ Name: name2, } mockFirestoreAdmin.err = nil mockFirestoreAdmin.reqs = nil mockFirestoreAdmin.resps = append(mockFirestoreAdmin.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/databases/%s/collectionGroups/%s/fields/%s", "[PROJECT]", "[DATABASE]", "[COLLECTION_ID]", "[FIELD_ID]") var request = &adminpb.GetFieldRequest{ Name: formattedName, } c, err := NewFirestoreAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetField(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockFirestoreAdmin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestFirestoreAdminGetFieldError(t *testing.T) { errCode := codes.PermissionDenied mockFirestoreAdmin.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/databases/%s/collectionGroups/%s/fields/%s", "[PROJECT]", "[DATABASE]", "[COLLECTION_ID]", "[FIELD_ID]") var request = &adminpb.GetFieldRequest{ Name: formattedName, } c, err := NewFirestoreAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetField(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestFirestoreAdminListFields(t *testing.T) { var nextPageToken string = "" var fieldsElement *adminpb.Field = &adminpb.Field{} var fields = []*adminpb.Field{fieldsElement} var expectedResponse = &adminpb.ListFieldsResponse{ NextPageToken: nextPageToken, Fields: fields, } mockFirestoreAdmin.err = nil mockFirestoreAdmin.reqs = nil mockFirestoreAdmin.resps = append(mockFirestoreAdmin.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/databases/%s/collectionGroups/%s", "[PROJECT]", "[DATABASE]", "[COLLECTION_ID]") var request = &adminpb.ListFieldsRequest{ Parent: formattedParent, } c, err := NewFirestoreAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListFields(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockFirestoreAdmin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Fields[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestFirestoreAdminListFieldsError(t *testing.T) { errCode := codes.PermissionDenied mockFirestoreAdmin.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/databases/%s/collectionGroups/%s", "[PROJECT]", "[DATABASE]", "[COLLECTION_ID]") var request = &adminpb.ListFieldsRequest{ Parent: formattedParent, } c, err := NewFirestoreAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListFields(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestFirestoreAdminUpdateField(t *testing.T) { var name string = "name3373707" var done bool = true var expectedResponse = &longrunningpb.Operation{ Name: name, Done: done, } mockFirestoreAdmin.err = nil mockFirestoreAdmin.reqs = nil mockFirestoreAdmin.resps = append(mockFirestoreAdmin.resps[:0], expectedResponse) var field *adminpb.Field = &adminpb.Field{} var request = &adminpb.UpdateFieldRequest{ Field: field, } c, err := NewFirestoreAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateField(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockFirestoreAdmin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestFirestoreAdminUpdateFieldError(t *testing.T) { errCode := codes.PermissionDenied mockFirestoreAdmin.err = gstatus.Error(errCode, "test error") var field *adminpb.Field = &adminpb.Field{} var request = &adminpb.UpdateFieldRequest{ Field: field, } c, err := NewFirestoreAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateField(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/firestore/apiv1/doc.go000066400000000000000000000045761356504100700207220ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package firestore is an auto-generated package for the // Google Cloud Firestore API. // // NOTE: This package is in beta. It is not stable, and may be subject to changes. // // // Use the client at cloud.google.com/go/firestore in preference to this. package firestore // import "cloud.google.com/go/firestore/apiv1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/datastore", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20190910" google-cloud-go-0.49.0/firestore/apiv1/firestore_client.go000066400000000000000000000436341356504100700235130ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package firestore import ( "context" "math" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" firestorepb "google.golang.org/genproto/googleapis/firestore/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // CallOptions contains the retry settings for each method of Client. type CallOptions struct { GetDocument []gax.CallOption ListDocuments []gax.CallOption CreateDocument []gax.CallOption UpdateDocument []gax.CallOption DeleteDocument []gax.CallOption BatchGetDocuments []gax.CallOption BeginTransaction []gax.CallOption Commit []gax.CallOption Rollback []gax.CallOption RunQuery []gax.CallOption Write []gax.CallOption Listen []gax.CallOption ListCollectionIds []gax.CallOption } func defaultClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("firestore.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), } } func defaultCallOptions() *CallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, {"streaming", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &CallOptions{ GetDocument: retry[[2]string{"default", "idempotent"}], ListDocuments: retry[[2]string{"default", "idempotent"}], CreateDocument: retry[[2]string{"default", "non_idempotent"}], UpdateDocument: retry[[2]string{"default", "non_idempotent"}], DeleteDocument: retry[[2]string{"default", "idempotent"}], BatchGetDocuments: retry[[2]string{"streaming", "idempotent"}], BeginTransaction: retry[[2]string{"default", "idempotent"}], Commit: retry[[2]string{"default", "non_idempotent"}], Rollback: retry[[2]string{"default", "idempotent"}], RunQuery: retry[[2]string{"streaming", "idempotent"}], Write: retry[[2]string{"streaming", "non_idempotent"}], Listen: retry[[2]string{"streaming", "idempotent"}], ListCollectionIds: retry[[2]string{"default", "idempotent"}], } } // Client is a client for interacting with Google Cloud Firestore API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. client firestorepb.FirestoreClient // The call options for this service. CallOptions *CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewClient creates a new firestore client. // // The Cloud Firestore service. // // This service exposes several types of comparable timestamps: // // create_time - The time at which a document was created. Changes only // when a document is deleted, then re-created. Increases in a strict // monotonic fashion. // // update_time - The time at which a document was last updated. Changes // every time a document is modified. Does not change when a write results // in no modifications. Increases in a strict monotonic fashion. // // read_time - The time at which a particular state was observed. Used // to denote a consistent snapshot of the database or the time at which a // Document was observed to not exist. // // commit_time - The time at which the writes in a transaction were // committed. Any read with an equal or greater read_time is guaranteed // to see the effects of the transaction. func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultClientOptions(), opts...)...) if err != nil { return nil, err } c := &Client{ conn: conn, CallOptions: defaultCallOptions(), client: firestorepb.NewFirestoreClient(conn), } c.SetGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *Client) Close() error { return c.conn.Close() } // SetGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *Client) SetGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // GetDocument gets a single document. func (c *Client) GetDocument(ctx context.Context, req *firestorepb.GetDocumentRequest, opts ...gax.CallOption) (*firestorepb.Document, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.GetDocument[0:len(c.CallOptions.GetDocument):len(c.CallOptions.GetDocument)], opts...) var resp *firestorepb.Document err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetDocument(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListDocuments lists documents. func (c *Client) ListDocuments(ctx context.Context, req *firestorepb.ListDocumentsRequest, opts ...gax.CallOption) *DocumentIterator { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.ListDocuments[0:len(c.CallOptions.ListDocuments):len(c.CallOptions.ListDocuments)], opts...) it := &DocumentIterator{} req = proto.Clone(req).(*firestorepb.ListDocumentsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*firestorepb.Document, string, error) { var resp *firestorepb.ListDocumentsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListDocuments(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Documents, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) return it } // CreateDocument creates a new document. func (c *Client) CreateDocument(ctx context.Context, req *firestorepb.CreateDocumentRequest, opts ...gax.CallOption) (*firestorepb.Document, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.CreateDocument[0:len(c.CallOptions.CreateDocument):len(c.CallOptions.CreateDocument)], opts...) var resp *firestorepb.Document err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CreateDocument(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateDocument updates or inserts a document. func (c *Client) UpdateDocument(ctx context.Context, req *firestorepb.UpdateDocumentRequest, opts ...gax.CallOption) (*firestorepb.Document, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.UpdateDocument[0:len(c.CallOptions.UpdateDocument):len(c.CallOptions.UpdateDocument)], opts...) var resp *firestorepb.Document err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.UpdateDocument(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteDocument deletes a document. func (c *Client) DeleteDocument(ctx context.Context, req *firestorepb.DeleteDocumentRequest, opts ...gax.CallOption) error { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.DeleteDocument[0:len(c.CallOptions.DeleteDocument):len(c.CallOptions.DeleteDocument)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.client.DeleteDocument(ctx, req, settings.GRPC...) return err }, opts...) return err } // BatchGetDocuments gets multiple documents. // // Documents returned by this method are not guaranteed to be returned in the // same order that they were requested. func (c *Client) BatchGetDocuments(ctx context.Context, req *firestorepb.BatchGetDocumentsRequest, opts ...gax.CallOption) (firestorepb.Firestore_BatchGetDocumentsClient, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.BatchGetDocuments[0:len(c.CallOptions.BatchGetDocuments):len(c.CallOptions.BatchGetDocuments)], opts...) var resp firestorepb.Firestore_BatchGetDocumentsClient err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.BatchGetDocuments(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // BeginTransaction starts a new transaction. func (c *Client) BeginTransaction(ctx context.Context, req *firestorepb.BeginTransactionRequest, opts ...gax.CallOption) (*firestorepb.BeginTransactionResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.BeginTransaction[0:len(c.CallOptions.BeginTransaction):len(c.CallOptions.BeginTransaction)], opts...) var resp *firestorepb.BeginTransactionResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.BeginTransaction(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // Commit commits a transaction, while optionally updating documents. func (c *Client) Commit(ctx context.Context, req *firestorepb.CommitRequest, opts ...gax.CallOption) (*firestorepb.CommitResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.Commit[0:len(c.CallOptions.Commit):len(c.CallOptions.Commit)], opts...) var resp *firestorepb.CommitResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.Commit(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // Rollback rolls back a transaction. func (c *Client) Rollback(ctx context.Context, req *firestorepb.RollbackRequest, opts ...gax.CallOption) error { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.Rollback[0:len(c.CallOptions.Rollback):len(c.CallOptions.Rollback)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.client.Rollback(ctx, req, settings.GRPC...) return err }, opts...) return err } // RunQuery runs a query. func (c *Client) RunQuery(ctx context.Context, req *firestorepb.RunQueryRequest, opts ...gax.CallOption) (firestorepb.Firestore_RunQueryClient, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.RunQuery[0:len(c.CallOptions.RunQuery):len(c.CallOptions.RunQuery)], opts...) var resp firestorepb.Firestore_RunQueryClient err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.RunQuery(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // Write streams batches of document updates and deletes, in order. func (c *Client) Write(ctx context.Context, opts ...gax.CallOption) (firestorepb.Firestore_WriteClient, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.Write[0:len(c.CallOptions.Write):len(c.CallOptions.Write)], opts...) var resp firestorepb.Firestore_WriteClient err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.Write(ctx, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // Listen listens to changes. func (c *Client) Listen(ctx context.Context, opts ...gax.CallOption) (firestorepb.Firestore_ListenClient, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.Listen[0:len(c.CallOptions.Listen):len(c.CallOptions.Listen)], opts...) var resp firestorepb.Firestore_ListenClient err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.Listen(ctx, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListCollectionIds lists all the collection IDs underneath a document. func (c *Client) ListCollectionIds(ctx context.Context, req *firestorepb.ListCollectionIdsRequest, opts ...gax.CallOption) *StringIterator { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.ListCollectionIds[0:len(c.CallOptions.ListCollectionIds):len(c.CallOptions.ListCollectionIds)], opts...) it := &StringIterator{} req = proto.Clone(req).(*firestorepb.ListCollectionIdsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]string, string, error) { var resp *firestorepb.ListCollectionIdsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListCollectionIds(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.CollectionIds, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) return it } // DocumentIterator manages a stream of *firestorepb.Document. type DocumentIterator struct { items []*firestorepb.Document pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*firestorepb.Document, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *DocumentIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *DocumentIterator) Next() (*firestorepb.Document, error) { var item *firestorepb.Document if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *DocumentIterator) bufLen() int { return len(it.items) } func (it *DocumentIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // StringIterator manages a stream of string. type StringIterator struct { items []string pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []string, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *StringIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *StringIterator) Next() (string, error) { var item string if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *StringIterator) bufLen() int { return len(it.items) } func (it *StringIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/firestore/apiv1/firestore_client_example_test.go000066400000000000000000000143321356504100700262560ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package firestore_test import ( "context" "io" firestore "cloud.google.com/go/firestore/apiv1" "google.golang.org/api/iterator" firestorepb "google.golang.org/genproto/googleapis/firestore/v1" ) func ExampleNewClient() { ctx := context.Background() c, err := firestore.NewClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleClient_GetDocument() { ctx := context.Background() c, err := firestore.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &firestorepb.GetDocumentRequest{ // TODO: Fill request struct fields. } resp, err := c.GetDocument(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ListDocuments() { ctx := context.Background() c, err := firestore.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &firestorepb.ListDocumentsRequest{ // TODO: Fill request struct fields. } it := c.ListDocuments(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_CreateDocument() { ctx := context.Background() c, err := firestore.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &firestorepb.CreateDocumentRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateDocument(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_UpdateDocument() { ctx := context.Background() c, err := firestore.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &firestorepb.UpdateDocumentRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateDocument(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_DeleteDocument() { ctx := context.Background() c, err := firestore.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &firestorepb.DeleteDocumentRequest{ // TODO: Fill request struct fields. } err = c.DeleteDocument(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleClient_BatchGetDocuments() { ctx := context.Background() c, err := firestore.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &firestorepb.BatchGetDocumentsRequest{ // TODO: Fill request struct fields. } stream, err := c.BatchGetDocuments(ctx, req) if err != nil { // TODO: Handle error. } for { resp, err := stream.Recv() if err == io.EOF { break } if err != nil { // TODO: handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_BeginTransaction() { ctx := context.Background() c, err := firestore.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &firestorepb.BeginTransactionRequest{ // TODO: Fill request struct fields. } resp, err := c.BeginTransaction(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_Commit() { ctx := context.Background() c, err := firestore.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &firestorepb.CommitRequest{ // TODO: Fill request struct fields. } resp, err := c.Commit(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_Rollback() { ctx := context.Background() c, err := firestore.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &firestorepb.RollbackRequest{ // TODO: Fill request struct fields. } err = c.Rollback(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleClient_RunQuery() { ctx := context.Background() c, err := firestore.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &firestorepb.RunQueryRequest{ // TODO: Fill request struct fields. } stream, err := c.RunQuery(ctx, req) if err != nil { // TODO: Handle error. } for { resp, err := stream.Recv() if err == io.EOF { break } if err != nil { // TODO: handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_Write() { ctx := context.Background() c, err := firestore.NewClient(ctx) if err != nil { // TODO: Handle error. } stream, err := c.Write(ctx) if err != nil { // TODO: Handle error. } go func() { reqs := []*firestorepb.WriteRequest{ // TODO: Create requests. } for _, req := range reqs { if err := stream.Send(req); err != nil { // TODO: Handle error. } } stream.CloseSend() }() for { resp, err := stream.Recv() if err == io.EOF { break } if err != nil { // TODO: handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_Listen() { ctx := context.Background() c, err := firestore.NewClient(ctx) if err != nil { // TODO: Handle error. } stream, err := c.Listen(ctx) if err != nil { // TODO: Handle error. } go func() { reqs := []*firestorepb.ListenRequest{ // TODO: Create requests. } for _, req := range reqs { if err := stream.Send(req); err != nil { // TODO: Handle error. } } stream.CloseSend() }() for { resp, err := stream.Recv() if err == io.EOF { break } if err != nil { // TODO: handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_ListCollectionIds() { ctx := context.Background() c, err := firestore.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &firestorepb.ListCollectionIdsRequest{ // TODO: Fill request struct fields. } it := c.ListCollectionIds(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } google-cloud-go-0.49.0/firestore/apiv1/mock_test.go000066400000000000000000000776621356504100700221530ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package firestore import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" "google.golang.org/api/option" firestorepb "google.golang.org/genproto/googleapis/firestore/v1" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockFirestoreServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. firestorepb.FirestoreServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockFirestoreServer) GetDocument(ctx context.Context, req *firestorepb.GetDocumentRequest) (*firestorepb.Document, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*firestorepb.Document), nil } func (s *mockFirestoreServer) ListDocuments(ctx context.Context, req *firestorepb.ListDocumentsRequest) (*firestorepb.ListDocumentsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*firestorepb.ListDocumentsResponse), nil } func (s *mockFirestoreServer) CreateDocument(ctx context.Context, req *firestorepb.CreateDocumentRequest) (*firestorepb.Document, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*firestorepb.Document), nil } func (s *mockFirestoreServer) UpdateDocument(ctx context.Context, req *firestorepb.UpdateDocumentRequest) (*firestorepb.Document, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*firestorepb.Document), nil } func (s *mockFirestoreServer) DeleteDocument(ctx context.Context, req *firestorepb.DeleteDocumentRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockFirestoreServer) BatchGetDocuments(req *firestorepb.BatchGetDocumentsRequest, stream firestorepb.Firestore_BatchGetDocumentsServer) error { md, _ := metadata.FromIncomingContext(stream.Context()) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return s.err } for _, v := range s.resps { if err := stream.Send(v.(*firestorepb.BatchGetDocumentsResponse)); err != nil { return err } } return nil } func (s *mockFirestoreServer) BeginTransaction(ctx context.Context, req *firestorepb.BeginTransactionRequest) (*firestorepb.BeginTransactionResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*firestorepb.BeginTransactionResponse), nil } func (s *mockFirestoreServer) Commit(ctx context.Context, req *firestorepb.CommitRequest) (*firestorepb.CommitResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*firestorepb.CommitResponse), nil } func (s *mockFirestoreServer) Rollback(ctx context.Context, req *firestorepb.RollbackRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockFirestoreServer) RunQuery(req *firestorepb.RunQueryRequest, stream firestorepb.Firestore_RunQueryServer) error { md, _ := metadata.FromIncomingContext(stream.Context()) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return s.err } for _, v := range s.resps { if err := stream.Send(v.(*firestorepb.RunQueryResponse)); err != nil { return err } } return nil } func (s *mockFirestoreServer) Write(stream firestorepb.Firestore_WriteServer) error { md, _ := metadata.FromIncomingContext(stream.Context()) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } for { if req, err := stream.Recv(); err == io.EOF { break } else if err != nil { return err } else { s.reqs = append(s.reqs, req) } } if s.err != nil { return s.err } for _, v := range s.resps { if err := stream.Send(v.(*firestorepb.WriteResponse)); err != nil { return err } } return nil } func (s *mockFirestoreServer) Listen(stream firestorepb.Firestore_ListenServer) error { md, _ := metadata.FromIncomingContext(stream.Context()) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } for { if req, err := stream.Recv(); err == io.EOF { break } else if err != nil { return err } else { s.reqs = append(s.reqs, req) } } if s.err != nil { return s.err } for _, v := range s.resps { if err := stream.Send(v.(*firestorepb.ListenResponse)); err != nil { return err } } return nil } func (s *mockFirestoreServer) ListCollectionIds(ctx context.Context, req *firestorepb.ListCollectionIdsRequest) (*firestorepb.ListCollectionIdsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*firestorepb.ListCollectionIdsResponse), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockFirestore mockFirestoreServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() firestorepb.RegisterFirestoreServer(serv, &mockFirestore) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestFirestoreGetDocument(t *testing.T) { var name2 string = "name2-1052831874" var expectedResponse = &firestorepb.Document{ Name: name2, } mockFirestore.err = nil mockFirestore.reqs = nil mockFirestore.resps = append(mockFirestore.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/databases/%s/documents/%s/%s", "[PROJECT]", "[DATABASE]", "[DOCUMENT]", "[ANY_PATH]") var request = &firestorepb.GetDocumentRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetDocument(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockFirestore.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestFirestoreGetDocumentError(t *testing.T) { errCode := codes.PermissionDenied mockFirestore.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/databases/%s/documents/%s/%s", "[PROJECT]", "[DATABASE]", "[DOCUMENT]", "[ANY_PATH]") var request = &firestorepb.GetDocumentRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetDocument(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestFirestoreListDocuments(t *testing.T) { var nextPageToken string = "" var documentsElement *firestorepb.Document = &firestorepb.Document{} var documents = []*firestorepb.Document{documentsElement} var expectedResponse = &firestorepb.ListDocumentsResponse{ NextPageToken: nextPageToken, Documents: documents, } mockFirestore.err = nil mockFirestore.reqs = nil mockFirestore.resps = append(mockFirestore.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/databases/%s/documents/%s/%s", "[PROJECT]", "[DATABASE]", "[DOCUMENT]", "[ANY_PATH]") var collectionId string = "collectionId-821242276" var request = &firestorepb.ListDocumentsRequest{ Parent: formattedParent, CollectionId: collectionId, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListDocuments(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockFirestore.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Documents[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestFirestoreListDocumentsError(t *testing.T) { errCode := codes.PermissionDenied mockFirestore.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/databases/%s/documents/%s/%s", "[PROJECT]", "[DATABASE]", "[DOCUMENT]", "[ANY_PATH]") var collectionId string = "collectionId-821242276" var request = &firestorepb.ListDocumentsRequest{ Parent: formattedParent, CollectionId: collectionId, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListDocuments(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestFirestoreCreateDocument(t *testing.T) { var name string = "name3373707" var expectedResponse = &firestorepb.Document{ Name: name, } mockFirestore.err = nil mockFirestore.reqs = nil mockFirestore.resps = append(mockFirestore.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/databases/%s/documents/%s/%s", "[PROJECT]", "[DATABASE]", "[DOCUMENT]", "[ANY_PATH]") var collectionId string = "collectionId-821242276" var documentId string = "documentId506676927" var document *firestorepb.Document = &firestorepb.Document{} var request = &firestorepb.CreateDocumentRequest{ Parent: formattedParent, CollectionId: collectionId, DocumentId: documentId, Document: document, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateDocument(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockFirestore.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestFirestoreCreateDocumentError(t *testing.T) { errCode := codes.PermissionDenied mockFirestore.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/databases/%s/documents/%s/%s", "[PROJECT]", "[DATABASE]", "[DOCUMENT]", "[ANY_PATH]") var collectionId string = "collectionId-821242276" var documentId string = "documentId506676927" var document *firestorepb.Document = &firestorepb.Document{} var request = &firestorepb.CreateDocumentRequest{ Parent: formattedParent, CollectionId: collectionId, DocumentId: documentId, Document: document, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateDocument(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestFirestoreUpdateDocument(t *testing.T) { var name string = "name3373707" var expectedResponse = &firestorepb.Document{ Name: name, } mockFirestore.err = nil mockFirestore.reqs = nil mockFirestore.resps = append(mockFirestore.resps[:0], expectedResponse) var document *firestorepb.Document = &firestorepb.Document{} var updateMask *firestorepb.DocumentMask = &firestorepb.DocumentMask{} var request = &firestorepb.UpdateDocumentRequest{ Document: document, UpdateMask: updateMask, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateDocument(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockFirestore.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestFirestoreUpdateDocumentError(t *testing.T) { errCode := codes.PermissionDenied mockFirestore.err = gstatus.Error(errCode, "test error") var document *firestorepb.Document = &firestorepb.Document{} var updateMask *firestorepb.DocumentMask = &firestorepb.DocumentMask{} var request = &firestorepb.UpdateDocumentRequest{ Document: document, UpdateMask: updateMask, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateDocument(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestFirestoreDeleteDocument(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockFirestore.err = nil mockFirestore.reqs = nil mockFirestore.resps = append(mockFirestore.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/databases/%s/documents/%s/%s", "[PROJECT]", "[DATABASE]", "[DOCUMENT]", "[ANY_PATH]") var request = &firestorepb.DeleteDocumentRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteDocument(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockFirestore.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestFirestoreDeleteDocumentError(t *testing.T) { errCode := codes.PermissionDenied mockFirestore.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/databases/%s/documents/%s/%s", "[PROJECT]", "[DATABASE]", "[DOCUMENT]", "[ANY_PATH]") var request = &firestorepb.DeleteDocumentRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteDocument(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestFirestoreBatchGetDocuments(t *testing.T) { var missing string = "missing1069449574" var transaction []byte = []byte("-34") var expectedResponse = &firestorepb.BatchGetDocumentsResponse{ Result: &firestorepb.BatchGetDocumentsResponse_Missing{ Missing: missing, }, Transaction: transaction, } mockFirestore.err = nil mockFirestore.reqs = nil mockFirestore.resps = append(mockFirestore.resps[:0], expectedResponse) var formattedDatabase string = fmt.Sprintf("projects/%s/databases/%s", "[PROJECT]", "[DATABASE]") var documents []string = nil var request = &firestorepb.BatchGetDocumentsRequest{ Database: formattedDatabase, Documents: documents, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } stream, err := c.BatchGetDocuments(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := stream.Recv() if err != nil { t.Fatal(err) } if want, got := request, mockFirestore.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestFirestoreBatchGetDocumentsError(t *testing.T) { errCode := codes.PermissionDenied mockFirestore.err = gstatus.Error(errCode, "test error") var formattedDatabase string = fmt.Sprintf("projects/%s/databases/%s", "[PROJECT]", "[DATABASE]") var documents []string = nil var request = &firestorepb.BatchGetDocumentsRequest{ Database: formattedDatabase, Documents: documents, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } stream, err := c.BatchGetDocuments(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := stream.Recv() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestFirestoreBeginTransaction(t *testing.T) { var transaction []byte = []byte("-34") var expectedResponse = &firestorepb.BeginTransactionResponse{ Transaction: transaction, } mockFirestore.err = nil mockFirestore.reqs = nil mockFirestore.resps = append(mockFirestore.resps[:0], expectedResponse) var formattedDatabase string = fmt.Sprintf("projects/%s/databases/%s", "[PROJECT]", "[DATABASE]") var request = &firestorepb.BeginTransactionRequest{ Database: formattedDatabase, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.BeginTransaction(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockFirestore.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestFirestoreBeginTransactionError(t *testing.T) { errCode := codes.PermissionDenied mockFirestore.err = gstatus.Error(errCode, "test error") var formattedDatabase string = fmt.Sprintf("projects/%s/databases/%s", "[PROJECT]", "[DATABASE]") var request = &firestorepb.BeginTransactionRequest{ Database: formattedDatabase, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.BeginTransaction(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestFirestoreCommit(t *testing.T) { var expectedResponse *firestorepb.CommitResponse = &firestorepb.CommitResponse{} mockFirestore.err = nil mockFirestore.reqs = nil mockFirestore.resps = append(mockFirestore.resps[:0], expectedResponse) var formattedDatabase string = fmt.Sprintf("projects/%s/databases/%s", "[PROJECT]", "[DATABASE]") var writes []*firestorepb.Write = nil var request = &firestorepb.CommitRequest{ Database: formattedDatabase, Writes: writes, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Commit(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockFirestore.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestFirestoreCommitError(t *testing.T) { errCode := codes.PermissionDenied mockFirestore.err = gstatus.Error(errCode, "test error") var formattedDatabase string = fmt.Sprintf("projects/%s/databases/%s", "[PROJECT]", "[DATABASE]") var writes []*firestorepb.Write = nil var request = &firestorepb.CommitRequest{ Database: formattedDatabase, Writes: writes, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Commit(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestFirestoreRollback(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockFirestore.err = nil mockFirestore.reqs = nil mockFirestore.resps = append(mockFirestore.resps[:0], expectedResponse) var formattedDatabase string = fmt.Sprintf("projects/%s/databases/%s", "[PROJECT]", "[DATABASE]") var transaction []byte = []byte("-34") var request = &firestorepb.RollbackRequest{ Database: formattedDatabase, Transaction: transaction, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.Rollback(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockFirestore.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestFirestoreRollbackError(t *testing.T) { errCode := codes.PermissionDenied mockFirestore.err = gstatus.Error(errCode, "test error") var formattedDatabase string = fmt.Sprintf("projects/%s/databases/%s", "[PROJECT]", "[DATABASE]") var transaction []byte = []byte("-34") var request = &firestorepb.RollbackRequest{ Database: formattedDatabase, Transaction: transaction, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.Rollback(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestFirestoreRunQuery(t *testing.T) { var transaction []byte = []byte("-34") var skippedResults int32 = 880286183 var expectedResponse = &firestorepb.RunQueryResponse{ Transaction: transaction, SkippedResults: skippedResults, } mockFirestore.err = nil mockFirestore.reqs = nil mockFirestore.resps = append(mockFirestore.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/databases/%s/documents/%s/%s", "[PROJECT]", "[DATABASE]", "[DOCUMENT]", "[ANY_PATH]") var request = &firestorepb.RunQueryRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } stream, err := c.RunQuery(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := stream.Recv() if err != nil { t.Fatal(err) } if want, got := request, mockFirestore.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestFirestoreRunQueryError(t *testing.T) { errCode := codes.PermissionDenied mockFirestore.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/databases/%s/documents/%s/%s", "[PROJECT]", "[DATABASE]", "[DOCUMENT]", "[ANY_PATH]") var request = &firestorepb.RunQueryRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } stream, err := c.RunQuery(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := stream.Recv() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestFirestoreWrite(t *testing.T) { var streamId string = "streamId-315624902" var streamToken []byte = []byte("122") var expectedResponse = &firestorepb.WriteResponse{ StreamId: streamId, StreamToken: streamToken, } mockFirestore.err = nil mockFirestore.reqs = nil mockFirestore.resps = append(mockFirestore.resps[:0], expectedResponse) var formattedDatabase string = fmt.Sprintf("projects/%s/databases/%s", "[PROJECT]", "[DATABASE]") var request = &firestorepb.WriteRequest{ Database: formattedDatabase, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } stream, err := c.Write(context.Background()) if err != nil { t.Fatal(err) } if err := stream.Send(request); err != nil { t.Fatal(err) } if err := stream.CloseSend(); err != nil { t.Fatal(err) } resp, err := stream.Recv() if err != nil { t.Fatal(err) } if want, got := request, mockFirestore.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestFirestoreWriteError(t *testing.T) { errCode := codes.PermissionDenied mockFirestore.err = gstatus.Error(errCode, "test error") var formattedDatabase string = fmt.Sprintf("projects/%s/databases/%s", "[PROJECT]", "[DATABASE]") var request = &firestorepb.WriteRequest{ Database: formattedDatabase, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } stream, err := c.Write(context.Background()) if err != nil { t.Fatal(err) } if err := stream.Send(request); err != nil { t.Fatal(err) } if err := stream.CloseSend(); err != nil { t.Fatal(err) } resp, err := stream.Recv() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestFirestoreListen(t *testing.T) { var expectedResponse *firestorepb.ListenResponse = &firestorepb.ListenResponse{} mockFirestore.err = nil mockFirestore.reqs = nil mockFirestore.resps = append(mockFirestore.resps[:0], expectedResponse) var formattedDatabase string = fmt.Sprintf("projects/%s/databases/%s", "[PROJECT]", "[DATABASE]") var request = &firestorepb.ListenRequest{ Database: formattedDatabase, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } stream, err := c.Listen(context.Background()) if err != nil { t.Fatal(err) } if err := stream.Send(request); err != nil { t.Fatal(err) } if err := stream.CloseSend(); err != nil { t.Fatal(err) } resp, err := stream.Recv() if err != nil { t.Fatal(err) } if want, got := request, mockFirestore.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestFirestoreListenError(t *testing.T) { errCode := codes.PermissionDenied mockFirestore.err = gstatus.Error(errCode, "test error") var formattedDatabase string = fmt.Sprintf("projects/%s/databases/%s", "[PROJECT]", "[DATABASE]") var request = &firestorepb.ListenRequest{ Database: formattedDatabase, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } stream, err := c.Listen(context.Background()) if err != nil { t.Fatal(err) } if err := stream.Send(request); err != nil { t.Fatal(err) } if err := stream.CloseSend(); err != nil { t.Fatal(err) } resp, err := stream.Recv() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestFirestoreListCollectionIds(t *testing.T) { var nextPageToken string = "" var collectionIdsElement string = "collectionIdsElement1368994900" var collectionIds = []string{collectionIdsElement} var expectedResponse = &firestorepb.ListCollectionIdsResponse{ NextPageToken: nextPageToken, CollectionIds: collectionIds, } mockFirestore.err = nil mockFirestore.reqs = nil mockFirestore.resps = append(mockFirestore.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/databases/%s/documents/%s/%s", "[PROJECT]", "[DATABASE]", "[DOCUMENT]", "[ANY_PATH]") var request = &firestorepb.ListCollectionIdsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListCollectionIds(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockFirestore.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.CollectionIds[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestFirestoreListCollectionIdsError(t *testing.T) { errCode := codes.PermissionDenied mockFirestore.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/databases/%s/documents/%s/%s", "[PROJECT]", "[DATABASE]", "[DOCUMENT]", "[ANY_PATH]") var request = &firestorepb.ListCollectionIdsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListCollectionIds(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/firestore/apiv1beta1/000077500000000000000000000000001356504100700205275ustar00rootroot00000000000000google-cloud-go-0.49.0/firestore/apiv1beta1/.repo-metadata.json000066400000000000000000000006441356504100700242270ustar00rootroot00000000000000{ "name": "firestore", "name_pretty": "Cloud Firestore API", "product_documentation": "https://cloud.google.com/firestore", "client_documentation": "https://godoc.org/cloud.google.com/go/firestore/apiv1beta1", "release_level": "beta", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "firestore.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/firestore/apiv1beta1/doc.go000066400000000000000000000054471356504100700216350ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package firestore is an auto-generated package for the // Google Cloud Firestore API. // // NOTE: This package is in beta. It is not stable, and may be subject to changes. // // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. // // Use the client at cloud.google.com/go/firestore in preference to this. package firestore // import "cloud.google.com/go/firestore/apiv1beta1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/datastore", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191115" google-cloud-go-0.49.0/firestore/apiv1beta1/firestore_client.go000066400000000000000000000462271356504100700244310ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package firestore import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" firestorepb "google.golang.org/genproto/googleapis/firestore/v1beta1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // CallOptions contains the retry settings for each method of Client. type CallOptions struct { GetDocument []gax.CallOption ListDocuments []gax.CallOption CreateDocument []gax.CallOption UpdateDocument []gax.CallOption DeleteDocument []gax.CallOption BatchGetDocuments []gax.CallOption BeginTransaction []gax.CallOption Commit []gax.CallOption Rollback []gax.CallOption RunQuery []gax.CallOption Write []gax.CallOption Listen []gax.CallOption ListCollectionIds []gax.CallOption } func defaultClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("firestore.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultCallOptions() *CallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, {"streaming", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &CallOptions{ GetDocument: retry[[2]string{"default", "idempotent"}], ListDocuments: retry[[2]string{"default", "idempotent"}], CreateDocument: retry[[2]string{"default", "non_idempotent"}], UpdateDocument: retry[[2]string{"default", "non_idempotent"}], DeleteDocument: retry[[2]string{"default", "idempotent"}], BatchGetDocuments: retry[[2]string{"streaming", "idempotent"}], BeginTransaction: retry[[2]string{"default", "idempotent"}], Commit: retry[[2]string{"default", "non_idempotent"}], Rollback: retry[[2]string{"default", "idempotent"}], RunQuery: retry[[2]string{"streaming", "idempotent"}], Write: retry[[2]string{"streaming", "non_idempotent"}], Listen: retry[[2]string{"streaming", "idempotent"}], ListCollectionIds: retry[[2]string{"default", "idempotent"}], } } // Client is a client for interacting with Google Cloud Firestore API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. client firestorepb.FirestoreClient // The call options for this service. CallOptions *CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewClient creates a new firestore client. // // The Cloud Firestore service. // // This service exposes several types of comparable timestamps: // // create_time - The time at which a document was created. Changes only // when a document is deleted, then re-created. Increases in a strict // monotonic fashion. // // update_time - The time at which a document was last updated. Changes // every time a document is modified. Does not change when a write results // in no modifications. Increases in a strict monotonic fashion. // // read_time - The time at which a particular state was observed. Used // to denote a consistent snapshot of the database or the time at which a // Document was observed to not exist. // // commit_time - The time at which the writes in a transaction were // committed. Any read with an equal or greater read_time is guaranteed // to see the effects of the transaction. func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultClientOptions(), opts...)...) if err != nil { return nil, err } c := &Client{ conn: conn, CallOptions: defaultCallOptions(), client: firestorepb.NewFirestoreClient(conn), } c.SetGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *Client) Close() error { return c.conn.Close() } // SetGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *Client) SetGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // GetDocument gets a single document. func (c *Client) GetDocument(ctx context.Context, req *firestorepb.GetDocumentRequest, opts ...gax.CallOption) (*firestorepb.Document, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetDocument[0:len(c.CallOptions.GetDocument):len(c.CallOptions.GetDocument)], opts...) var resp *firestorepb.Document err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetDocument(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListDocuments lists documents. func (c *Client) ListDocuments(ctx context.Context, req *firestorepb.ListDocumentsRequest, opts ...gax.CallOption) *DocumentIterator { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.ListDocuments[0:len(c.CallOptions.ListDocuments):len(c.CallOptions.ListDocuments)], opts...) it := &DocumentIterator{} req = proto.Clone(req).(*firestorepb.ListDocumentsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*firestorepb.Document, string, error) { var resp *firestorepb.ListDocumentsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListDocuments(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Documents, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // CreateDocument creates a new document. func (c *Client) CreateDocument(ctx context.Context, req *firestorepb.CreateDocumentRequest, opts ...gax.CallOption) (*firestorepb.Document, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.CreateDocument[0:len(c.CallOptions.CreateDocument):len(c.CallOptions.CreateDocument)], opts...) var resp *firestorepb.Document err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CreateDocument(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateDocument updates or inserts a document. func (c *Client) UpdateDocument(ctx context.Context, req *firestorepb.UpdateDocumentRequest, opts ...gax.CallOption) (*firestorepb.Document, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "document.name", url.QueryEscape(req.GetDocument().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateDocument[0:len(c.CallOptions.UpdateDocument):len(c.CallOptions.UpdateDocument)], opts...) var resp *firestorepb.Document err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.UpdateDocument(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteDocument deletes a document. func (c *Client) DeleteDocument(ctx context.Context, req *firestorepb.DeleteDocumentRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteDocument[0:len(c.CallOptions.DeleteDocument):len(c.CallOptions.DeleteDocument)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.client.DeleteDocument(ctx, req, settings.GRPC...) return err }, opts...) return err } // BatchGetDocuments gets multiple documents. // // Documents returned by this method are not guaranteed to be returned in the // same order that they were requested. func (c *Client) BatchGetDocuments(ctx context.Context, req *firestorepb.BatchGetDocumentsRequest, opts ...gax.CallOption) (firestorepb.Firestore_BatchGetDocumentsClient, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "database", url.QueryEscape(req.GetDatabase()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.BatchGetDocuments[0:len(c.CallOptions.BatchGetDocuments):len(c.CallOptions.BatchGetDocuments)], opts...) var resp firestorepb.Firestore_BatchGetDocumentsClient err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.BatchGetDocuments(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // BeginTransaction starts a new transaction. func (c *Client) BeginTransaction(ctx context.Context, req *firestorepb.BeginTransactionRequest, opts ...gax.CallOption) (*firestorepb.BeginTransactionResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "database", url.QueryEscape(req.GetDatabase()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.BeginTransaction[0:len(c.CallOptions.BeginTransaction):len(c.CallOptions.BeginTransaction)], opts...) var resp *firestorepb.BeginTransactionResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.BeginTransaction(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // Commit commits a transaction, while optionally updating documents. func (c *Client) Commit(ctx context.Context, req *firestorepb.CommitRequest, opts ...gax.CallOption) (*firestorepb.CommitResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "database", url.QueryEscape(req.GetDatabase()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.Commit[0:len(c.CallOptions.Commit):len(c.CallOptions.Commit)], opts...) var resp *firestorepb.CommitResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.Commit(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // Rollback rolls back a transaction. func (c *Client) Rollback(ctx context.Context, req *firestorepb.RollbackRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "database", url.QueryEscape(req.GetDatabase()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.Rollback[0:len(c.CallOptions.Rollback):len(c.CallOptions.Rollback)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.client.Rollback(ctx, req, settings.GRPC...) return err }, opts...) return err } // RunQuery runs a query. func (c *Client) RunQuery(ctx context.Context, req *firestorepb.RunQueryRequest, opts ...gax.CallOption) (firestorepb.Firestore_RunQueryClient, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.RunQuery[0:len(c.CallOptions.RunQuery):len(c.CallOptions.RunQuery)], opts...) var resp firestorepb.Firestore_RunQueryClient err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.RunQuery(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // Write streams batches of document updates and deletes, in order. func (c *Client) Write(ctx context.Context, opts ...gax.CallOption) (firestorepb.Firestore_WriteClient, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.Write[0:len(c.CallOptions.Write):len(c.CallOptions.Write)], opts...) var resp firestorepb.Firestore_WriteClient err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.Write(ctx, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // Listen listens to changes. func (c *Client) Listen(ctx context.Context, opts ...gax.CallOption) (firestorepb.Firestore_ListenClient, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.Listen[0:len(c.CallOptions.Listen):len(c.CallOptions.Listen)], opts...) var resp firestorepb.Firestore_ListenClient err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.Listen(ctx, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListCollectionIds lists all the collection IDs underneath a document. func (c *Client) ListCollectionIds(ctx context.Context, req *firestorepb.ListCollectionIdsRequest, opts ...gax.CallOption) *StringIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListCollectionIds[0:len(c.CallOptions.ListCollectionIds):len(c.CallOptions.ListCollectionIds)], opts...) it := &StringIterator{} req = proto.Clone(req).(*firestorepb.ListCollectionIdsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]string, string, error) { var resp *firestorepb.ListCollectionIdsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListCollectionIds(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.CollectionIds, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // DocumentIterator manages a stream of *firestorepb.Document. type DocumentIterator struct { items []*firestorepb.Document pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*firestorepb.Document, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *DocumentIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *DocumentIterator) Next() (*firestorepb.Document, error) { var item *firestorepb.Document if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *DocumentIterator) bufLen() int { return len(it.items) } func (it *DocumentIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // StringIterator manages a stream of string. type StringIterator struct { items []string pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []string, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *StringIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *StringIterator) Next() (string, error) { var item string if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *StringIterator) bufLen() int { return len(it.items) } func (it *StringIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/firestore/apiv1beta1/firestore_client_example_test.go000066400000000000000000000143441356504100700271760ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package firestore_test import ( "context" "io" firestore "cloud.google.com/go/firestore/apiv1beta1" "google.golang.org/api/iterator" firestorepb "google.golang.org/genproto/googleapis/firestore/v1beta1" ) func ExampleNewClient() { ctx := context.Background() c, err := firestore.NewClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleClient_GetDocument() { ctx := context.Background() c, err := firestore.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &firestorepb.GetDocumentRequest{ // TODO: Fill request struct fields. } resp, err := c.GetDocument(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ListDocuments() { ctx := context.Background() c, err := firestore.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &firestorepb.ListDocumentsRequest{ // TODO: Fill request struct fields. } it := c.ListDocuments(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_CreateDocument() { ctx := context.Background() c, err := firestore.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &firestorepb.CreateDocumentRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateDocument(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_UpdateDocument() { ctx := context.Background() c, err := firestore.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &firestorepb.UpdateDocumentRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateDocument(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_DeleteDocument() { ctx := context.Background() c, err := firestore.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &firestorepb.DeleteDocumentRequest{ // TODO: Fill request struct fields. } err = c.DeleteDocument(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleClient_BatchGetDocuments() { ctx := context.Background() c, err := firestore.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &firestorepb.BatchGetDocumentsRequest{ // TODO: Fill request struct fields. } stream, err := c.BatchGetDocuments(ctx, req) if err != nil { // TODO: Handle error. } for { resp, err := stream.Recv() if err == io.EOF { break } if err != nil { // TODO: handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_BeginTransaction() { ctx := context.Background() c, err := firestore.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &firestorepb.BeginTransactionRequest{ // TODO: Fill request struct fields. } resp, err := c.BeginTransaction(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_Commit() { ctx := context.Background() c, err := firestore.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &firestorepb.CommitRequest{ // TODO: Fill request struct fields. } resp, err := c.Commit(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_Rollback() { ctx := context.Background() c, err := firestore.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &firestorepb.RollbackRequest{ // TODO: Fill request struct fields. } err = c.Rollback(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleClient_RunQuery() { ctx := context.Background() c, err := firestore.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &firestorepb.RunQueryRequest{ // TODO: Fill request struct fields. } stream, err := c.RunQuery(ctx, req) if err != nil { // TODO: Handle error. } for { resp, err := stream.Recv() if err == io.EOF { break } if err != nil { // TODO: handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_Write() { ctx := context.Background() c, err := firestore.NewClient(ctx) if err != nil { // TODO: Handle error. } stream, err := c.Write(ctx) if err != nil { // TODO: Handle error. } go func() { reqs := []*firestorepb.WriteRequest{ // TODO: Create requests. } for _, req := range reqs { if err := stream.Send(req); err != nil { // TODO: Handle error. } } stream.CloseSend() }() for { resp, err := stream.Recv() if err == io.EOF { break } if err != nil { // TODO: handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_Listen() { ctx := context.Background() c, err := firestore.NewClient(ctx) if err != nil { // TODO: Handle error. } stream, err := c.Listen(ctx) if err != nil { // TODO: Handle error. } go func() { reqs := []*firestorepb.ListenRequest{ // TODO: Create requests. } for _, req := range reqs { if err := stream.Send(req); err != nil { // TODO: Handle error. } } stream.CloseSend() }() for { resp, err := stream.Recv() if err == io.EOF { break } if err != nil { // TODO: handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_ListCollectionIds() { ctx := context.Background() c, err := firestore.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &firestorepb.ListCollectionIdsRequest{ // TODO: Fill request struct fields. } it := c.ListCollectionIds(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } google-cloud-go-0.49.0/firestore/apiv1beta1/mock_test.go000066400000000000000000000776671356504100700230750ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package firestore import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" "google.golang.org/api/option" firestorepb "google.golang.org/genproto/googleapis/firestore/v1beta1" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockFirestoreServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. firestorepb.FirestoreServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockFirestoreServer) GetDocument(ctx context.Context, req *firestorepb.GetDocumentRequest) (*firestorepb.Document, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*firestorepb.Document), nil } func (s *mockFirestoreServer) ListDocuments(ctx context.Context, req *firestorepb.ListDocumentsRequest) (*firestorepb.ListDocumentsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*firestorepb.ListDocumentsResponse), nil } func (s *mockFirestoreServer) CreateDocument(ctx context.Context, req *firestorepb.CreateDocumentRequest) (*firestorepb.Document, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*firestorepb.Document), nil } func (s *mockFirestoreServer) UpdateDocument(ctx context.Context, req *firestorepb.UpdateDocumentRequest) (*firestorepb.Document, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*firestorepb.Document), nil } func (s *mockFirestoreServer) DeleteDocument(ctx context.Context, req *firestorepb.DeleteDocumentRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockFirestoreServer) BatchGetDocuments(req *firestorepb.BatchGetDocumentsRequest, stream firestorepb.Firestore_BatchGetDocumentsServer) error { md, _ := metadata.FromIncomingContext(stream.Context()) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return s.err } for _, v := range s.resps { if err := stream.Send(v.(*firestorepb.BatchGetDocumentsResponse)); err != nil { return err } } return nil } func (s *mockFirestoreServer) BeginTransaction(ctx context.Context, req *firestorepb.BeginTransactionRequest) (*firestorepb.BeginTransactionResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*firestorepb.BeginTransactionResponse), nil } func (s *mockFirestoreServer) Commit(ctx context.Context, req *firestorepb.CommitRequest) (*firestorepb.CommitResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*firestorepb.CommitResponse), nil } func (s *mockFirestoreServer) Rollback(ctx context.Context, req *firestorepb.RollbackRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockFirestoreServer) RunQuery(req *firestorepb.RunQueryRequest, stream firestorepb.Firestore_RunQueryServer) error { md, _ := metadata.FromIncomingContext(stream.Context()) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return s.err } for _, v := range s.resps { if err := stream.Send(v.(*firestorepb.RunQueryResponse)); err != nil { return err } } return nil } func (s *mockFirestoreServer) Write(stream firestorepb.Firestore_WriteServer) error { md, _ := metadata.FromIncomingContext(stream.Context()) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } for { if req, err := stream.Recv(); err == io.EOF { break } else if err != nil { return err } else { s.reqs = append(s.reqs, req) } } if s.err != nil { return s.err } for _, v := range s.resps { if err := stream.Send(v.(*firestorepb.WriteResponse)); err != nil { return err } } return nil } func (s *mockFirestoreServer) Listen(stream firestorepb.Firestore_ListenServer) error { md, _ := metadata.FromIncomingContext(stream.Context()) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } for { if req, err := stream.Recv(); err == io.EOF { break } else if err != nil { return err } else { s.reqs = append(s.reqs, req) } } if s.err != nil { return s.err } for _, v := range s.resps { if err := stream.Send(v.(*firestorepb.ListenResponse)); err != nil { return err } } return nil } func (s *mockFirestoreServer) ListCollectionIds(ctx context.Context, req *firestorepb.ListCollectionIdsRequest) (*firestorepb.ListCollectionIdsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*firestorepb.ListCollectionIdsResponse), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockFirestore mockFirestoreServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() firestorepb.RegisterFirestoreServer(serv, &mockFirestore) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestFirestoreGetDocument(t *testing.T) { var name2 string = "name2-1052831874" var expectedResponse = &firestorepb.Document{ Name: name2, } mockFirestore.err = nil mockFirestore.reqs = nil mockFirestore.resps = append(mockFirestore.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/databases/%s/documents/%s/%s", "[PROJECT]", "[DATABASE]", "[DOCUMENT]", "[ANY_PATH]") var request = &firestorepb.GetDocumentRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetDocument(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockFirestore.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestFirestoreGetDocumentError(t *testing.T) { errCode := codes.PermissionDenied mockFirestore.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/databases/%s/documents/%s/%s", "[PROJECT]", "[DATABASE]", "[DOCUMENT]", "[ANY_PATH]") var request = &firestorepb.GetDocumentRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetDocument(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestFirestoreListDocuments(t *testing.T) { var nextPageToken string = "" var documentsElement *firestorepb.Document = &firestorepb.Document{} var documents = []*firestorepb.Document{documentsElement} var expectedResponse = &firestorepb.ListDocumentsResponse{ NextPageToken: nextPageToken, Documents: documents, } mockFirestore.err = nil mockFirestore.reqs = nil mockFirestore.resps = append(mockFirestore.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/databases/%s/documents/%s/%s", "[PROJECT]", "[DATABASE]", "[DOCUMENT]", "[ANY_PATH]") var collectionId string = "collectionId-821242276" var request = &firestorepb.ListDocumentsRequest{ Parent: formattedParent, CollectionId: collectionId, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListDocuments(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockFirestore.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Documents[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestFirestoreListDocumentsError(t *testing.T) { errCode := codes.PermissionDenied mockFirestore.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/databases/%s/documents/%s/%s", "[PROJECT]", "[DATABASE]", "[DOCUMENT]", "[ANY_PATH]") var collectionId string = "collectionId-821242276" var request = &firestorepb.ListDocumentsRequest{ Parent: formattedParent, CollectionId: collectionId, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListDocuments(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestFirestoreCreateDocument(t *testing.T) { var name string = "name3373707" var expectedResponse = &firestorepb.Document{ Name: name, } mockFirestore.err = nil mockFirestore.reqs = nil mockFirestore.resps = append(mockFirestore.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/databases/%s/documents/%s/%s", "[PROJECT]", "[DATABASE]", "[DOCUMENT]", "[ANY_PATH]") var collectionId string = "collectionId-821242276" var documentId string = "documentId506676927" var document *firestorepb.Document = &firestorepb.Document{} var request = &firestorepb.CreateDocumentRequest{ Parent: formattedParent, CollectionId: collectionId, DocumentId: documentId, Document: document, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateDocument(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockFirestore.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestFirestoreCreateDocumentError(t *testing.T) { errCode := codes.PermissionDenied mockFirestore.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/databases/%s/documents/%s/%s", "[PROJECT]", "[DATABASE]", "[DOCUMENT]", "[ANY_PATH]") var collectionId string = "collectionId-821242276" var documentId string = "documentId506676927" var document *firestorepb.Document = &firestorepb.Document{} var request = &firestorepb.CreateDocumentRequest{ Parent: formattedParent, CollectionId: collectionId, DocumentId: documentId, Document: document, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateDocument(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestFirestoreUpdateDocument(t *testing.T) { var name string = "name3373707" var expectedResponse = &firestorepb.Document{ Name: name, } mockFirestore.err = nil mockFirestore.reqs = nil mockFirestore.resps = append(mockFirestore.resps[:0], expectedResponse) var document *firestorepb.Document = &firestorepb.Document{} var updateMask *firestorepb.DocumentMask = &firestorepb.DocumentMask{} var request = &firestorepb.UpdateDocumentRequest{ Document: document, UpdateMask: updateMask, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateDocument(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockFirestore.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestFirestoreUpdateDocumentError(t *testing.T) { errCode := codes.PermissionDenied mockFirestore.err = gstatus.Error(errCode, "test error") var document *firestorepb.Document = &firestorepb.Document{} var updateMask *firestorepb.DocumentMask = &firestorepb.DocumentMask{} var request = &firestorepb.UpdateDocumentRequest{ Document: document, UpdateMask: updateMask, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateDocument(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestFirestoreDeleteDocument(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockFirestore.err = nil mockFirestore.reqs = nil mockFirestore.resps = append(mockFirestore.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/databases/%s/documents/%s/%s", "[PROJECT]", "[DATABASE]", "[DOCUMENT]", "[ANY_PATH]") var request = &firestorepb.DeleteDocumentRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteDocument(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockFirestore.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestFirestoreDeleteDocumentError(t *testing.T) { errCode := codes.PermissionDenied mockFirestore.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/databases/%s/documents/%s/%s", "[PROJECT]", "[DATABASE]", "[DOCUMENT]", "[ANY_PATH]") var request = &firestorepb.DeleteDocumentRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteDocument(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestFirestoreBatchGetDocuments(t *testing.T) { var missing string = "missing1069449574" var transaction []byte = []byte("-34") var expectedResponse = &firestorepb.BatchGetDocumentsResponse{ Result: &firestorepb.BatchGetDocumentsResponse_Missing{ Missing: missing, }, Transaction: transaction, } mockFirestore.err = nil mockFirestore.reqs = nil mockFirestore.resps = append(mockFirestore.resps[:0], expectedResponse) var formattedDatabase string = fmt.Sprintf("projects/%s/databases/%s", "[PROJECT]", "[DATABASE]") var documents []string = nil var request = &firestorepb.BatchGetDocumentsRequest{ Database: formattedDatabase, Documents: documents, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } stream, err := c.BatchGetDocuments(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := stream.Recv() if err != nil { t.Fatal(err) } if want, got := request, mockFirestore.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestFirestoreBatchGetDocumentsError(t *testing.T) { errCode := codes.PermissionDenied mockFirestore.err = gstatus.Error(errCode, "test error") var formattedDatabase string = fmt.Sprintf("projects/%s/databases/%s", "[PROJECT]", "[DATABASE]") var documents []string = nil var request = &firestorepb.BatchGetDocumentsRequest{ Database: formattedDatabase, Documents: documents, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } stream, err := c.BatchGetDocuments(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := stream.Recv() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestFirestoreBeginTransaction(t *testing.T) { var transaction []byte = []byte("-34") var expectedResponse = &firestorepb.BeginTransactionResponse{ Transaction: transaction, } mockFirestore.err = nil mockFirestore.reqs = nil mockFirestore.resps = append(mockFirestore.resps[:0], expectedResponse) var formattedDatabase string = fmt.Sprintf("projects/%s/databases/%s", "[PROJECT]", "[DATABASE]") var request = &firestorepb.BeginTransactionRequest{ Database: formattedDatabase, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.BeginTransaction(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockFirestore.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestFirestoreBeginTransactionError(t *testing.T) { errCode := codes.PermissionDenied mockFirestore.err = gstatus.Error(errCode, "test error") var formattedDatabase string = fmt.Sprintf("projects/%s/databases/%s", "[PROJECT]", "[DATABASE]") var request = &firestorepb.BeginTransactionRequest{ Database: formattedDatabase, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.BeginTransaction(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestFirestoreCommit(t *testing.T) { var expectedResponse *firestorepb.CommitResponse = &firestorepb.CommitResponse{} mockFirestore.err = nil mockFirestore.reqs = nil mockFirestore.resps = append(mockFirestore.resps[:0], expectedResponse) var formattedDatabase string = fmt.Sprintf("projects/%s/databases/%s", "[PROJECT]", "[DATABASE]") var writes []*firestorepb.Write = nil var request = &firestorepb.CommitRequest{ Database: formattedDatabase, Writes: writes, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Commit(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockFirestore.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestFirestoreCommitError(t *testing.T) { errCode := codes.PermissionDenied mockFirestore.err = gstatus.Error(errCode, "test error") var formattedDatabase string = fmt.Sprintf("projects/%s/databases/%s", "[PROJECT]", "[DATABASE]") var writes []*firestorepb.Write = nil var request = &firestorepb.CommitRequest{ Database: formattedDatabase, Writes: writes, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Commit(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestFirestoreRollback(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockFirestore.err = nil mockFirestore.reqs = nil mockFirestore.resps = append(mockFirestore.resps[:0], expectedResponse) var formattedDatabase string = fmt.Sprintf("projects/%s/databases/%s", "[PROJECT]", "[DATABASE]") var transaction []byte = []byte("-34") var request = &firestorepb.RollbackRequest{ Database: formattedDatabase, Transaction: transaction, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.Rollback(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockFirestore.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestFirestoreRollbackError(t *testing.T) { errCode := codes.PermissionDenied mockFirestore.err = gstatus.Error(errCode, "test error") var formattedDatabase string = fmt.Sprintf("projects/%s/databases/%s", "[PROJECT]", "[DATABASE]") var transaction []byte = []byte("-34") var request = &firestorepb.RollbackRequest{ Database: formattedDatabase, Transaction: transaction, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.Rollback(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestFirestoreRunQuery(t *testing.T) { var transaction []byte = []byte("-34") var skippedResults int32 = 880286183 var expectedResponse = &firestorepb.RunQueryResponse{ Transaction: transaction, SkippedResults: skippedResults, } mockFirestore.err = nil mockFirestore.reqs = nil mockFirestore.resps = append(mockFirestore.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/databases/%s/documents/%s/%s", "[PROJECT]", "[DATABASE]", "[DOCUMENT]", "[ANY_PATH]") var request = &firestorepb.RunQueryRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } stream, err := c.RunQuery(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := stream.Recv() if err != nil { t.Fatal(err) } if want, got := request, mockFirestore.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestFirestoreRunQueryError(t *testing.T) { errCode := codes.PermissionDenied mockFirestore.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/databases/%s/documents/%s/%s", "[PROJECT]", "[DATABASE]", "[DOCUMENT]", "[ANY_PATH]") var request = &firestorepb.RunQueryRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } stream, err := c.RunQuery(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := stream.Recv() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestFirestoreWrite(t *testing.T) { var streamId string = "streamId-315624902" var streamToken []byte = []byte("122") var expectedResponse = &firestorepb.WriteResponse{ StreamId: streamId, StreamToken: streamToken, } mockFirestore.err = nil mockFirestore.reqs = nil mockFirestore.resps = append(mockFirestore.resps[:0], expectedResponse) var formattedDatabase string = fmt.Sprintf("projects/%s/databases/%s", "[PROJECT]", "[DATABASE]") var request = &firestorepb.WriteRequest{ Database: formattedDatabase, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } stream, err := c.Write(context.Background()) if err != nil { t.Fatal(err) } if err := stream.Send(request); err != nil { t.Fatal(err) } if err := stream.CloseSend(); err != nil { t.Fatal(err) } resp, err := stream.Recv() if err != nil { t.Fatal(err) } if want, got := request, mockFirestore.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestFirestoreWriteError(t *testing.T) { errCode := codes.PermissionDenied mockFirestore.err = gstatus.Error(errCode, "test error") var formattedDatabase string = fmt.Sprintf("projects/%s/databases/%s", "[PROJECT]", "[DATABASE]") var request = &firestorepb.WriteRequest{ Database: formattedDatabase, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } stream, err := c.Write(context.Background()) if err != nil { t.Fatal(err) } if err := stream.Send(request); err != nil { t.Fatal(err) } if err := stream.CloseSend(); err != nil { t.Fatal(err) } resp, err := stream.Recv() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestFirestoreListen(t *testing.T) { var expectedResponse *firestorepb.ListenResponse = &firestorepb.ListenResponse{} mockFirestore.err = nil mockFirestore.reqs = nil mockFirestore.resps = append(mockFirestore.resps[:0], expectedResponse) var formattedDatabase string = fmt.Sprintf("projects/%s/databases/%s", "[PROJECT]", "[DATABASE]") var request = &firestorepb.ListenRequest{ Database: formattedDatabase, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } stream, err := c.Listen(context.Background()) if err != nil { t.Fatal(err) } if err := stream.Send(request); err != nil { t.Fatal(err) } if err := stream.CloseSend(); err != nil { t.Fatal(err) } resp, err := stream.Recv() if err != nil { t.Fatal(err) } if want, got := request, mockFirestore.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestFirestoreListenError(t *testing.T) { errCode := codes.PermissionDenied mockFirestore.err = gstatus.Error(errCode, "test error") var formattedDatabase string = fmt.Sprintf("projects/%s/databases/%s", "[PROJECT]", "[DATABASE]") var request = &firestorepb.ListenRequest{ Database: formattedDatabase, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } stream, err := c.Listen(context.Background()) if err != nil { t.Fatal(err) } if err := stream.Send(request); err != nil { t.Fatal(err) } if err := stream.CloseSend(); err != nil { t.Fatal(err) } resp, err := stream.Recv() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestFirestoreListCollectionIds(t *testing.T) { var nextPageToken string = "" var collectionIdsElement string = "collectionIdsElement1368994900" var collectionIds = []string{collectionIdsElement} var expectedResponse = &firestorepb.ListCollectionIdsResponse{ NextPageToken: nextPageToken, CollectionIds: collectionIds, } mockFirestore.err = nil mockFirestore.reqs = nil mockFirestore.resps = append(mockFirestore.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/databases/%s/documents/%s/%s", "[PROJECT]", "[DATABASE]", "[DOCUMENT]", "[ANY_PATH]") var request = &firestorepb.ListCollectionIdsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListCollectionIds(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockFirestore.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.CollectionIds[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestFirestoreListCollectionIdsError(t *testing.T) { errCode := codes.PermissionDenied mockFirestore.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/databases/%s/documents/%s/%s", "[PROJECT]", "[DATABASE]", "[DOCUMENT]", "[ANY_PATH]") var request = &firestorepb.ListCollectionIdsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListCollectionIds(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/firestore/client.go000066400000000000000000000251001356504100700203750ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package firestore import ( "context" "errors" "fmt" "io" "os" "strings" "time" vkit "cloud.google.com/go/firestore/apiv1" "cloud.google.com/go/internal/trace" "cloud.google.com/go/internal/version" "github.com/golang/protobuf/ptypes" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" pb "google.golang.org/genproto/googleapis/firestore/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" ) // resourcePrefixHeader is the name of the metadata header used to indicate // the resource being operated on. const resourcePrefixHeader = "google-cloud-resource-prefix" // DetectProjectID is a sentinel value that instructs NewClient to detect the // project ID. It is given in place of the projectID argument. NewClient will // use the project ID from the given credentials or the default credentials // (https://developers.google.com/accounts/docs/application-default-credentials) // if no credentials were provided. When providing credentials, not all // options will allow NewClient to extract the project ID. Specifically a JWT // does not have the project ID encoded. const DetectProjectID = "*detect-project-id*" // A Client provides access to the Firestore service. type Client struct { c *vkit.Client projectID string databaseID string // A client is tied to a single database. } // NewClient creates a new Firestore client that uses the given project. func NewClient(ctx context.Context, projectID string, opts ...option.ClientOption) (*Client, error) { var o []option.ClientOption // If this environment variable is defined, configure the client to talk to the emulator. if addr := os.Getenv("FIRESTORE_EMULATOR_HOST"); addr != "" { conn, err := grpc.Dial(addr, grpc.WithInsecure(), grpc.WithPerRPCCredentials(emulatorCreds{})) if err != nil { return nil, fmt.Errorf("firestore: dialing address from env var FIRESTORE_EMULATOR_HOST: %s", err) } o = []option.ClientOption{option.WithGRPCConn(conn)} } o = append(o, opts...) if projectID == DetectProjectID { creds, err := transport.Creds(ctx, o...) if err != nil { return nil, fmt.Errorf("fetching creds: %v", err) } if creds.ProjectID == "" { return nil, errors.New("firestore: see the docs on DetectProjectID") } projectID = creds.ProjectID } vc, err := vkit.NewClient(ctx, o...) if err != nil { return nil, err } vc.SetGoogleClientInfo("gccl", version.Repo) c := &Client{ c: vc, projectID: projectID, databaseID: "(default)", // always "(default)", for now } return c, nil } // Close closes any resources held by the client. // // Close need not be called at program exit. func (c *Client) Close() error { return c.c.Close() } func (c *Client) path() string { return fmt.Sprintf("projects/%s/databases/%s", c.projectID, c.databaseID) } func withResourceHeader(ctx context.Context, resource string) context.Context { md, _ := metadata.FromOutgoingContext(ctx) md = md.Copy() md[resourcePrefixHeader] = []string{resource} return metadata.NewOutgoingContext(ctx, md) } // Collection creates a reference to a collection with the given path. // A path is a sequence of IDs separated by slashes. // // Collection returns nil if path contains an even number of IDs or any ID is empty. func (c *Client) Collection(path string) *CollectionRef { coll, _ := c.idsToRef(strings.Split(path, "/"), c.path()) return coll } // Doc creates a reference to a document with the given path. // A path is a sequence of IDs separated by slashes. // // Doc returns nil if path contains an odd number of IDs or any ID is empty. func (c *Client) Doc(path string) *DocumentRef { _, doc := c.idsToRef(strings.Split(path, "/"), c.path()) return doc } // CollectionGroup creates a reference to a group of collections that include // the given ID, regardless of parent document. // // For example, consider: // France/Cities/Paris = {population: 100} // Canada/Cities/Montreal = {population: 90} // // CollectionGroup can be used to query across all "Cities" regardless of // its parent "Countries". See ExampleCollectionGroup for a complete example. func (c *Client) CollectionGroup(collectionID string) *CollectionGroupRef { return newCollectionGroupRef(c, c.path(), collectionID) } func (c *Client) idsToRef(IDs []string, dbPath string) (*CollectionRef, *DocumentRef) { if len(IDs) == 0 { return nil, nil } for _, id := range IDs { if id == "" { return nil, nil } } coll := newTopLevelCollRef(c, dbPath, IDs[0]) i := 1 for i < len(IDs) { doc := newDocRef(coll, IDs[i]) i++ if i == len(IDs) { return nil, doc } coll = newCollRefWithParent(c, doc, IDs[i]) i++ } return coll, nil } // GetAll retrieves multiple documents with a single call. The // DocumentSnapshots are returned in the order of the given DocumentRefs. // The return value will always contain the same number of DocumentSnapshots // as the number of DocumentRefs in the input. // // If the same DocumentRef is specified multiple times in the input, the return // value will contain the same number of DocumentSnapshots referencing the same // document. // // If a document is not present, the corresponding DocumentSnapshot's Exists // method will return false. func (c *Client) GetAll(ctx context.Context, docRefs []*DocumentRef) (_ []*DocumentSnapshot, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/firestore.GetAll") defer func() { trace.EndSpan(ctx, err) }() return c.getAll(ctx, docRefs, nil) } func (c *Client) getAll(ctx context.Context, docRefs []*DocumentRef, tid []byte) ([]*DocumentSnapshot, error) { var docNames []string docIndices := map[string][]int{} // doc name to positions in docRefs for i, dr := range docRefs { if dr == nil { return nil, errNilDocRef } docNames = append(docNames, dr.Path) docIndices[dr.Path] = append(docIndices[dr.Path], i) } req := &pb.BatchGetDocumentsRequest{ Database: c.path(), Documents: docNames, } if tid != nil { req.ConsistencySelector = &pb.BatchGetDocumentsRequest_Transaction{tid} } streamClient, err := c.c.BatchGetDocuments(withResourceHeader(ctx, req.Database), req) if err != nil { return nil, err } // Read and remember all results from the stream. var resps []*pb.BatchGetDocumentsResponse for { resp, err := streamClient.Recv() if err == io.EOF { break } if err != nil { return nil, err } resps = append(resps, resp) } // Results may arrive out of order. Put each at the right indices. docs := make([]*DocumentSnapshot, len(docNames)) for _, resp := range resps { var ( indices []int doc *pb.Document err error ) switch r := resp.Result.(type) { case *pb.BatchGetDocumentsResponse_Found: indices = docIndices[r.Found.Name] doc = r.Found case *pb.BatchGetDocumentsResponse_Missing: indices = docIndices[r.Missing] doc = nil default: return nil, errors.New("firestore: unknown BatchGetDocumentsResponse result type") } for _, index := range indices { if docs[index] != nil { return nil, fmt.Errorf("firestore: %q seen twice", docRefs[index].Path) } docs[index], err = newDocumentSnapshot(docRefs[index], doc, c, resp.ReadTime) if err != nil { return nil, err } } } return docs, nil } // Collections returns an interator over the top-level collections. func (c *Client) Collections(ctx context.Context) *CollectionIterator { it := &CollectionIterator{ client: c, it: c.c.ListCollectionIds( withResourceHeader(ctx, c.path()), &pb.ListCollectionIdsRequest{Parent: c.path() + "/documents"}), } it.pageInfo, it.nextFunc = iterator.NewPageInfo( it.fetch, func() int { return len(it.items) }, func() interface{} { b := it.items; it.items = nil; return b }) return it } // Batch returns a WriteBatch. func (c *Client) Batch() *WriteBatch { return &WriteBatch{c: c} } // commit calls the Commit RPC outside of a transaction. func (c *Client) commit(ctx context.Context, ws []*pb.Write) ([]*WriteResult, error) { req := &pb.CommitRequest{ Database: c.path(), Writes: ws, } res, err := c.c.Commit(withResourceHeader(ctx, req.Database), req) if err != nil { return nil, err } if len(res.WriteResults) == 0 { return nil, errors.New("firestore: missing WriteResult") } var wrs []*WriteResult for _, pwr := range res.WriteResults { wr, err := writeResultFromProto(pwr) if err != nil { return nil, err } wrs = append(wrs, wr) } return wrs, nil } func (c *Client) commit1(ctx context.Context, ws []*pb.Write) (*WriteResult, error) { wrs, err := c.commit(ctx, ws) if err != nil { return nil, err } return wrs[0], nil } // A WriteResult is returned by methods that write documents. type WriteResult struct { // The time at which the document was updated, or created if it did not // previously exist. Writes that do not actually change the document do // not change the update time. UpdateTime time.Time } func writeResultFromProto(wr *pb.WriteResult) (*WriteResult, error) { t, err := ptypes.Timestamp(wr.UpdateTime) if err != nil { t = time.Time{} // TODO(jba): Follow up if Delete is supposed to return a nil timestamp. } return &WriteResult{UpdateTime: t}, nil } func sleep(ctx context.Context, dur time.Duration) error { switch err := gax.Sleep(ctx, dur); err { case context.Canceled: return status.Error(codes.Canceled, "context canceled") case context.DeadlineExceeded: return status.Error(codes.DeadlineExceeded, "context deadline exceeded") default: return err } } // emulatorCreds is an instance of grpc.PerRPCCredentials that will configure a // client to act as an admin for the Firestore emulator. It always hardcodes // the "authorization" metadata field to contain "Bearer owner", which the // Firestore emulator accepts as valid admin credentials. type emulatorCreds struct{} func (ec emulatorCreds) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) { return map[string]string{"authorization": "Bearer owner"}, nil } func (ec emulatorCreds) RequireTransportSecurity() bool { return false } google-cloud-go-0.49.0/firestore/client_test.go000066400000000000000000000216311356504100700214410ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package firestore import ( "context" "testing" tspb "github.com/golang/protobuf/ptypes/timestamp" pb "google.golang.org/genproto/googleapis/firestore/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) var testClient = &Client{ projectID: "projectID", databaseID: "(default)", } func TestClientCollectionAndDoc(t *testing.T) { coll1 := testClient.Collection("X") db := "projects/projectID/databases/(default)" wantc1 := &CollectionRef{ c: testClient, parentPath: db + "/documents", selfPath: "X", Parent: nil, ID: "X", Path: "projects/projectID/databases/(default)/documents/X", Query: Query{ c: testClient, collectionID: "X", path: "projects/projectID/databases/(default)/documents/X", parentPath: db + "/documents", }, } if !testEqual(coll1, wantc1) { t.Fatalf("got\n%+v\nwant\n%+v", coll1, wantc1) } doc1 := testClient.Doc("X/a") wantd1 := &DocumentRef{ Parent: coll1, ID: "a", Path: "projects/projectID/databases/(default)/documents/X/a", shortPath: "X/a", } if !testEqual(doc1, wantd1) { t.Fatalf("got %+v, want %+v", doc1, wantd1) } coll2 := testClient.Collection("X/a/Y") parentPath := "projects/projectID/databases/(default)/documents/X/a" wantc2 := &CollectionRef{ c: testClient, parentPath: parentPath, selfPath: "X/a/Y", Parent: doc1, ID: "Y", Path: "projects/projectID/databases/(default)/documents/X/a/Y", Query: Query{ c: testClient, collectionID: "Y", parentPath: parentPath, path: "projects/projectID/databases/(default)/documents/X/a/Y", }, } if !testEqual(coll2, wantc2) { t.Fatalf("\ngot %+v\nwant %+v", coll2, wantc2) } doc2 := testClient.Doc("X/a/Y/b") wantd2 := &DocumentRef{ Parent: coll2, ID: "b", Path: "projects/projectID/databases/(default)/documents/X/a/Y/b", shortPath: "X/a/Y/b", } if !testEqual(doc2, wantd2) { t.Fatalf("got %+v, want %+v", doc2, wantd2) } } func TestClientCollDocErrors(t *testing.T) { for _, badColl := range []string{"", "/", "/a/", "/a/b", "a/b/", "a//b"} { coll := testClient.Collection(badColl) if coll != nil { t.Errorf("coll path %q: got %+v, want nil", badColl, coll) } } for _, badDoc := range []string{"", "a", "/", "/a", "a/", "a/b/c", "a//b/c"} { doc := testClient.Doc(badDoc) if doc != nil { t.Errorf("doc path %q: got %+v, want nil", badDoc, doc) } } } func TestGetAll(t *testing.T) { c, srv, cleanup := newMock(t) defer cleanup() const dbPath = "projects/projectID/databases/(default)" req := &pb.BatchGetDocumentsRequest{ Database: dbPath, Documents: []string{ dbPath + "/documents/C/a", dbPath + "/documents/C/b", dbPath + "/documents/C/c", }, } testGetAll(t, c, srv, dbPath, func(drs []*DocumentRef) ([]*DocumentSnapshot, error) { return c.GetAll(context.Background(), drs) }, req) } func testGetAll(t *testing.T, c *Client, srv *mockServer, dbPath string, getAll func([]*DocumentRef) ([]*DocumentSnapshot, error), req *pb.BatchGetDocumentsRequest) { wantPBDocs := []*pb.Document{ { Name: dbPath + "/documents/C/a", CreateTime: aTimestamp, UpdateTime: aTimestamp, Fields: map[string]*pb.Value{"f": intval(2)}, }, nil, { Name: dbPath + "/documents/C/c", CreateTime: aTimestamp, UpdateTime: aTimestamp, Fields: map[string]*pb.Value{"f": intval(1)}, }, } wantReadTimes := []*tspb.Timestamp{aTimestamp, aTimestamp2, aTimestamp3} srv.addRPC(req, []interface{}{ // deliberately put these out of order &pb.BatchGetDocumentsResponse{ Result: &pb.BatchGetDocumentsResponse_Found{wantPBDocs[2]}, ReadTime: aTimestamp3, }, &pb.BatchGetDocumentsResponse{ Result: &pb.BatchGetDocumentsResponse_Found{wantPBDocs[0]}, ReadTime: aTimestamp, }, &pb.BatchGetDocumentsResponse{ Result: &pb.BatchGetDocumentsResponse_Missing{dbPath + "/documents/C/b"}, ReadTime: aTimestamp2, }, }, ) coll := c.Collection("C") var docRefs []*DocumentRef for _, name := range []string{"a", "b", "c"} { docRefs = append(docRefs, coll.Doc(name)) } docs, err := getAll(docRefs) if err != nil { t.Fatal(err) } if got, want := len(docs), len(wantPBDocs); got != want { t.Errorf("got %d docs, wanted %d", got, want) } for i, got := range docs { want, err := newDocumentSnapshot(docRefs[i], wantPBDocs[i], c, wantReadTimes[i]) if err != nil { t.Fatal(err) } if diff := testDiff(got, want); diff != "" { t.Errorf("#%d: got=--, want==++\n%s", i, diff) } } } func TestGetAllWithEqualRefs(t *testing.T) { c, srv, cleanup := newMock(t) defer cleanup() const dbPath = "projects/projectID/databases/(default)" req := &pb.BatchGetDocumentsRequest{ Database: dbPath, Documents: []string{ dbPath + "/documents/C/a", dbPath + "/documents/C/a", dbPath + "/documents/C/c", dbPath + "/documents/C/a", dbPath + "/documents/C/b", dbPath + "/documents/C/c", dbPath + "/documents/C/b", }, } testGetAllWithEqualRefs(t, c, srv, dbPath, func(drs []*DocumentRef) ([]*DocumentSnapshot, error) { return c.GetAll(context.Background(), drs) }, req) } func testGetAllWithEqualRefs(t *testing.T, c *Client, srv *mockServer, dbPath string, getAll func([]*DocumentRef) ([]*DocumentSnapshot, error), req *pb.BatchGetDocumentsRequest) { wantPBDocs := []*pb.Document{ { Name: dbPath + "/documents/C/a", CreateTime: aTimestamp, UpdateTime: aTimestamp, Fields: map[string]*pb.Value{"f": intval(2)}, }, { Name: dbPath + "/documents/C/c", CreateTime: aTimestamp, UpdateTime: aTimestamp, Fields: map[string]*pb.Value{"f": intval(1)}, }, nil, } srv.addRPC(req, []interface{}{ // deliberately put these out of order &pb.BatchGetDocumentsResponse{ Result: &pb.BatchGetDocumentsResponse_Found{wantPBDocs[1]}, ReadTime: aTimestamp3, }, &pb.BatchGetDocumentsResponse{ Result: &pb.BatchGetDocumentsResponse_Found{wantPBDocs[0]}, ReadTime: aTimestamp, }, &pb.BatchGetDocumentsResponse{ Result: &pb.BatchGetDocumentsResponse_Missing{dbPath + "/documents/C/b"}, ReadTime: aTimestamp2, }, }, ) coll := c.Collection("C") var docRefs []*DocumentRef for _, name := range []string{"a", "a", "c", "a", "b", "c", "b"} { docRefs = append(docRefs, coll.Doc(name)) } // GetAll should return the same number of document snapshots as the // number of document references in the input range, even when that means // that the same document snapshot is referenced multiple times in the // returned collection. docs, err := getAll(docRefs) if err != nil { t.Fatal(err) } wantDocsIndices := []int{0, 0, 1, 0, 2, 1, 2} wantReadTimes := []*tspb.Timestamp{aTimestamp, aTimestamp, aTimestamp3, aTimestamp, aTimestamp2, aTimestamp3, aTimestamp2} if got, want := len(docs), len(wantDocsIndices); got != want { t.Errorf("got %d docs, wanted %d", got, want) } for i, got := range docs { want, err := newDocumentSnapshot(docRefs[i], wantPBDocs[wantDocsIndices[i]], c, wantReadTimes[i]) if err != nil { t.Fatal(err) } if diff := testDiff(got, want); diff != "" { t.Errorf("#%d: got=--, want==++\n%s", i, diff) } } } func TestGetAllErrors(t *testing.T) { ctx := context.Background() c, srv, cleanup := newMock(t) defer cleanup() const dbPath = "projects/projectID/databases/(default)" const docPath = dbPath + "/documents/C/a" if _, err := c.GetAll(ctx, []*DocumentRef{nil}); err != errNilDocRef { t.Errorf("got %v, want errNilDocRef", err) } // Internal server error. srv.addRPC( &pb.BatchGetDocumentsRequest{ Database: dbPath, Documents: []string{docPath}, }, []interface{}{status.Errorf(codes.Internal, "")}, ) _, err := c.GetAll(ctx, []*DocumentRef{c.Doc("C/a")}) codeEq(t, "GetAll #1", codes.Internal, err) // Doc appears as both found and missing (server bug). srv.reset() srv.addRPC( &pb.BatchGetDocumentsRequest{ Database: dbPath, Documents: []string{docPath}, }, []interface{}{ &pb.BatchGetDocumentsResponse{ Result: &pb.BatchGetDocumentsResponse_Found{&pb.Document{Name: docPath}}, ReadTime: aTimestamp, }, &pb.BatchGetDocumentsResponse{ Result: &pb.BatchGetDocumentsResponse_Missing{docPath}, ReadTime: aTimestamp, }, }, ) if _, err := c.GetAll(ctx, []*DocumentRef{c.Doc("C/a")}); err == nil { t.Error("got nil, want error") } } google-cloud-go-0.49.0/firestore/collgroupref.go000066400000000000000000000021561356504100700216300ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package firestore // A CollectionGroupRef is a reference to a group of collections sharing the // same ID. type CollectionGroupRef struct { c *Client // Use the methods of Query on a CollectionGroupRef to create and run queries. Query } func newCollectionGroupRef(c *Client, dbPath, collectionID string) *CollectionGroupRef { return &CollectionGroupRef{ c: c, Query: Query{ c: c, collectionID: collectionID, path: dbPath, parentPath: dbPath + "/documents", allDescendants: true, }, } } google-cloud-go-0.49.0/firestore/collref.go000066400000000000000000000076371356504100700205640ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package firestore import ( "context" "crypto/rand" "encoding/base64" "fmt" ) // A CollectionRef is a reference to Firestore collection. type CollectionRef struct { c *Client // The full resource path of the collection's parent. Typically Parent.Path, // or c.path if Parent is nil. May be different if this CollectionRef was // created from a stored reference to a different project/DB. Always // includes /documents - that is, the parent is minimally considered to be // "/documents". // // For example, "projects/P/databases/D/documents/coll-1/doc-1". parentPath string // The shorter resource path of the collection. A collection "coll-2" in // document "doc-1" in collection "coll-1" would be: "coll-1/doc-1/coll-2". selfPath string // Parent is the document of which this collection is a part. It is // nil for top-level collections. Parent *DocumentRef // The full resource path of the collection: "projects/P/databases/D/documents..." Path string // ID is the collection identifier. ID string // Use the methods of Query on a CollectionRef to create and run queries. Query } func newTopLevelCollRef(c *Client, dbPath, id string) *CollectionRef { return &CollectionRef{ c: c, ID: id, parentPath: dbPath + "/documents", selfPath: id, Path: dbPath + "/documents/" + id, Query: Query{ c: c, collectionID: id, path: dbPath + "/documents/" + id, parentPath: dbPath + "/documents", }, } } func newCollRefWithParent(c *Client, parent *DocumentRef, id string) *CollectionRef { selfPath := parent.shortPath + "/" + id return &CollectionRef{ c: c, Parent: parent, ID: id, parentPath: parent.Path, selfPath: selfPath, Path: parent.Path + "/" + id, Query: Query{ c: c, collectionID: id, path: parent.Path + "/" + id, parentPath: parent.Path, }, } } // Doc returns a DocumentRef that refers to the document in the collection with the // given identifier. func (c *CollectionRef) Doc(id string) *DocumentRef { if c == nil { return nil } return newDocRef(c, id) } // NewDoc returns a DocumentRef with a uniquely generated ID. // // NewDoc will panic if crypto/rand cannot generate enough bytes to make a new // doc ID. func (c *CollectionRef) NewDoc() *DocumentRef { return c.Doc(uniqueID()) } // Add generates a DocumentRef with a unique ID. It then creates the document // with the given data, which can be a map[string]interface{}, a struct or a // pointer to a struct. // // Add returns an error in the unlikely event that a document with the same ID // already exists. func (c *CollectionRef) Add(ctx context.Context, data interface{}) (*DocumentRef, *WriteResult, error) { d := c.NewDoc() wr, err := d.Create(ctx, data) if err != nil { return nil, nil, err } return d, wr, nil } // DocumentRefs returns references to all the documents in the collection, including // missing documents. A missing document is a document that does not exist but has // sub-documents. func (c *CollectionRef) DocumentRefs(ctx context.Context) *DocumentRefIterator { return newDocumentRefIterator(ctx, c, nil) } func uniqueID() string { b := make([]byte, 32) if _, err := rand.Read(b); err != nil { panic(fmt.Sprintf("firestore: crypto/rand.Read error: %v", err)) } return base64.RawURLEncoding.EncodeToString(b) } google-cloud-go-0.49.0/firestore/collref_test.go000066400000000000000000000055051356504100700216130ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package firestore import ( "context" "encoding/base64" "testing" "github.com/golang/protobuf/proto" pb "google.golang.org/genproto/googleapis/firestore/v1" ) func TestDoc(t *testing.T) { coll := testClient.Collection("C") got := coll.Doc("d") want := &DocumentRef{ Parent: coll, ID: "d", Path: "projects/projectID/databases/(default)/documents/C/d", shortPath: "C/d", } if !testEqual(got, want) { t.Errorf("got %+v, want %+v", got, want) } } func TestNewDoc(t *testing.T) { c := &Client{} coll := c.Collection("C") got := coll.NewDoc() if got.Parent != coll { t.Errorf("NewDoc got %v, want %v", got.Parent, coll) } b, err := base64.RawURLEncoding.DecodeString(got.ID) if err != nil { t.Fatalf("NewDoc DecodeToString(%q) got err: %v", got.ID, err) } if len(b) != 32 { t.Errorf("NewDoc got %d-byte ID, wanted 32", len(b)) } got2 := coll.NewDoc() if got.ID == got2.ID { t.Error("got same ID") } } func TestAdd(t *testing.T) { ctx := context.Background() c, srv, cleanup := newMock(t) defer cleanup() wantReq := commitRequestForSet() w := wantReq.Writes[0] w.CurrentDocument = &pb.Precondition{ ConditionType: &pb.Precondition_Exists{false}, } srv.addRPCAdjust(wantReq, commitResponseForSet, func(gotReq proto.Message) { // We can't know the doc ID before Add is called, so we take it from // the request. w.Operation.(*pb.Write_Update).Update.Name = gotReq.(*pb.CommitRequest).Writes[0].Operation.(*pb.Write_Update).Update.Name }) _, wr, err := c.Collection("C").Add(ctx, testData) if err != nil { t.Fatal(err) } if !testEqual(wr, writeResultForSet) { t.Errorf("got %v, want %v", wr, writeResultForSet) } } func TestNilErrors(t *testing.T) { ctx := context.Background() c, _, cleanup := newMock(t) defer cleanup() // Test that a nil CollectionRef results in a nil DocumentRef and errors // where possible. coll := c.Collection("a/b") // nil because "a/b" denotes a doc. if coll != nil { t.Fatal("collection not nil") } if got := coll.Doc("d"); got != nil { t.Fatalf("got %v, want nil", got) } if got := coll.NewDoc(); got != nil { t.Fatalf("got %v, want nil", got) } if _, _, err := coll.Add(ctx, testData); err != errNilDocRef { t.Fatalf("got <%v>, want <%v>", err, errNilDocRef) } } google-cloud-go-0.49.0/firestore/conformance_test.go000066400000000000000000000275531356504100700224660ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // A runner for the conformance tests. package firestore import ( "bytes" "context" "encoding/json" "errors" "fmt" "io/ioutil" "math" "path" "path/filepath" "strings" "testing" "time" pb "cloud.google.com/go/firestore/internal/conformance" "github.com/golang/protobuf/jsonpb" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" ts "github.com/golang/protobuf/ptypes/timestamp" "github.com/google/go-cmp/cmp" "google.golang.org/api/iterator" fspb "google.golang.org/genproto/googleapis/firestore/v1" ) func TestConformance(t *testing.T) { dir := "internal/conformance/testdata" files, err := ioutil.ReadDir(dir) if err != nil { t.Fatal(err) } wtid := watchTargetID watchTargetID = 1 defer func() { watchTargetID = wtid }() for _, f := range files { if !strings.Contains(f.Name(), ".json") { continue } inBytes, err := ioutil.ReadFile(filepath.Join(dir, f.Name())) if err != nil { t.Fatalf("%s: %v", f.Name(), err) } var tf pb.TestFile if err := jsonpb.Unmarshal(bytes.NewReader(inBytes), &tf); err != nil { t.Fatalf("unmarshalling %s: %v", f.Name(), err) } for _, tc := range tf.Tests { t.Run(tc.Description, func(t *testing.T) { c, srv, cleanup := newMock(t) defer cleanup() if err := runTest(tc, c, srv); err != nil { t.Fatal(err) } }) } } } func runTest(test *pb.Test, c *Client, srv *mockServer) error { check := func(gotErr error, wantErr bool) error { if wantErr && gotErr == nil { return errors.New("got nil, want error") } if !wantErr && gotErr != nil { return gotErr } return nil } ctx := context.Background() switch typedTestcase := test.Test.(type) { case *pb.Test_Get: req := &fspb.BatchGetDocumentsRequest{ Database: c.path(), Documents: []string{typedTestcase.Get.DocRefPath}, } srv.addRPC(req, []interface{}{ &fspb.BatchGetDocumentsResponse{ Result: &fspb.BatchGetDocumentsResponse_Found{&fspb.Document{ Name: typedTestcase.Get.DocRefPath, CreateTime: &ts.Timestamp{}, UpdateTime: &ts.Timestamp{}, }}, ReadTime: &ts.Timestamp{}, }, }) ref := docRefFromPath(typedTestcase.Get.DocRefPath, c) _, err := ref.Get(ctx) if err != nil { return err } // Checking response would just be testing the function converting a Document // proto to a DocumentSnapshot, hence uninteresting. case *pb.Test_Create: srv.addRPC(typedTestcase.Create.Request, commitResponseForSet) ref := docRefFromPath(typedTestcase.Create.DocRefPath, c) data, err := convertData(typedTestcase.Create.JsonData) if err != nil { return err } _, checkErr := ref.Create(ctx, data) if err := check(checkErr, typedTestcase.Create.IsError); err != nil { return err } case *pb.Test_Set: srv.addRPC(typedTestcase.Set.Request, commitResponseForSet) ref := docRefFromPath(typedTestcase.Set.DocRefPath, c) data, err := convertData(typedTestcase.Set.JsonData) if err != nil { return err } var opts []SetOption if typedTestcase.Set.Option != nil { opts = []SetOption{convertSetOption(typedTestcase.Set.Option)} } _, checkErr := ref.Set(ctx, data, opts...) if err := check(checkErr, typedTestcase.Set.IsError); err != nil { return err } case *pb.Test_Update: // Ignore Update test because we only support UpdatePaths. // Not to worry, every Update test has a corresponding UpdatePaths test. case *pb.Test_UpdatePaths: srv.addRPC(typedTestcase.UpdatePaths.Request, commitResponseForSet) ref := docRefFromPath(typedTestcase.UpdatePaths.DocRefPath, c) preconds, err := convertPrecondition(typedTestcase.UpdatePaths.Precondition) if err != nil { return err } paths := convertFieldPaths(typedTestcase.UpdatePaths.FieldPaths) var ups []Update for i, p := range paths { val, err := convertJSONValue(typedTestcase.UpdatePaths.JsonValues[i]) if err != nil { return err } ups = append(ups, Update{ FieldPath: p, Value: val, }) } _, checkErr := ref.Update(ctx, ups, preconds...) if err := check(checkErr, typedTestcase.UpdatePaths.IsError); err != nil { return err } case *pb.Test_Delete: srv.addRPC(typedTestcase.Delete.Request, commitResponseForSet) ref := docRefFromPath(typedTestcase.Delete.DocRefPath, c) preconds, err := convertPrecondition(typedTestcase.Delete.Precondition) if err != nil { return err } _, checkErr := ref.Delete(ctx, preconds...) if err := check(checkErr, typedTestcase.Delete.IsError); err != nil { return err } case *pb.Test_Query: q, err := convertQuery(typedTestcase.Query) if err != nil { return err } got, checkErr := q.toProto() if err := check(checkErr, typedTestcase.Query.IsError); err == nil && checkErr == nil { if want := typedTestcase.Query.Query; !proto.Equal(got, want) { return fmt.Errorf("got: %s\nwant: %s", proto.MarshalTextString(got), proto.MarshalTextString(want)) } } case *pb.Test_Listen: ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() iter := c.Collection("C").OrderBy("a", Asc).Snapshots(ctx) var rs []interface{} for _, r := range typedTestcase.Listen.Responses { rs = append(rs, r) } srv.addRPC(&fspb.ListenRequest{ Database: "projects/projectID/databases/(default)", TargetChange: &fspb.ListenRequest_AddTarget{iter.ws.target}, }, rs) got, err := nSnapshots(iter, len(typedTestcase.Listen.Snapshots)) if err != nil { return err } else if diff := cmp.Diff(got, typedTestcase.Listen.Snapshots); diff != "" { return errors.New(diff) } if typedTestcase.Listen.IsError { _, err := iter.Next() if err == nil { return fmt.Errorf("got nil, want error") } } default: return fmt.Errorf("unknown test type %T", typedTestcase) } return nil } func nSnapshots(iter *QuerySnapshotIterator, n int) ([]*pb.Snapshot, error) { var snaps []*pb.Snapshot for i := 0; i < n; i++ { qsnap, err := iter.Next() if err != nil { return snaps, err } s := &pb.Snapshot{ReadTime: mustTimestampProto(qsnap.ReadTime)} for { doc, err := qsnap.Documents.Next() if err == iterator.Done { break } if err != nil { return snaps, err } s.Docs = append(s.Docs, doc.proto) } for _, c := range qsnap.Changes { var k pb.DocChange_Kind switch c.Kind { case DocumentAdded: k = pb.DocChange_ADDED case DocumentRemoved: k = pb.DocChange_REMOVED case DocumentModified: k = pb.DocChange_MODIFIED default: panic("bad kind") } s.Changes = append(s.Changes, &pb.DocChange{ Kind: k, Doc: c.Doc.proto, OldIndex: int32(c.OldIndex), NewIndex: int32(c.NewIndex), }) } snaps = append(snaps, s) } return snaps, nil } func docRefFromPath(p string, c *Client) *DocumentRef { return &DocumentRef{ Path: p, ID: path.Base(p), Parent: &CollectionRef{c: c}, } } func convertJSONValue(jv string) (interface{}, error) { var val interface{} if err := json.Unmarshal([]byte(jv), &val); err != nil { return nil, err } return convertTestValue(val), nil } func convertData(jsonData string) (map[string]interface{}, error) { var m map[string]interface{} if err := json.Unmarshal([]byte(jsonData), &m); err != nil { return nil, err } return convertTestMap(m), nil } func convertTestMap(m map[string]interface{}) map[string]interface{} { for k, v := range m { m[k] = convertTestValue(v) } return m } func convertTestValue(v interface{}) interface{} { switch v := v.(type) { case string: switch v { case "ServerTimestamp": return ServerTimestamp case "Delete": return Delete case "NaN": return math.NaN() default: return v } case float64: if v == float64(int(v)) { return int(v) } return v case []interface{}: if len(v) > 0 { if fv, ok := v[0].(string); ok { if fv == "ArrayUnion" { return ArrayUnion(convertTestValue(v[1:]).([]interface{})...) } if fv == "ArrayRemove" { return ArrayRemove(convertTestValue(v[1:]).([]interface{})...) } } } for i, e := range v { v[i] = convertTestValue(e) } return v case map[string]interface{}: return convertTestMap(v) default: return v } } func convertSetOption(opt *pb.SetOption) SetOption { if opt.All { return MergeAll } return Merge(convertFieldPaths(opt.Fields)...) } func convertFieldPaths(fps []*pb.FieldPath) []FieldPath { var res []FieldPath for _, fp := range fps { res = append(res, fp.Field) } return res } func convertPrecondition(fp *fspb.Precondition) ([]Precondition, error) { if fp == nil { return nil, nil } var pc Precondition switch fp := fp.ConditionType.(type) { case *fspb.Precondition_Exists: pc = exists(fp.Exists) case *fspb.Precondition_UpdateTime: tm, err := ptypes.Timestamp(fp.UpdateTime) if err != nil { return nil, err } pc = LastUpdateTime(tm) default: return nil, fmt.Errorf("unknown precondition type %T", fp) } return []Precondition{pc}, nil } func convertQuery(qt *pb.QueryTest) (*Query, error) { parts := strings.Split(qt.CollPath, "/") q := Query{ parentPath: strings.Join(parts[:len(parts)-2], "/"), collectionID: parts[len(parts)-1], path: qt.CollPath, } for _, c := range qt.Clauses { switch c := c.Clause.(type) { case *pb.Clause_Select: q = q.SelectPaths(convertFieldPaths(c.Select.Fields)...) case *pb.Clause_OrderBy: var dir Direction switch c.OrderBy.Direction { case "asc": dir = Asc case "desc": dir = Desc default: return nil, fmt.Errorf("bad direction: %q", c.OrderBy.Direction) } q = q.OrderByPath(FieldPath(c.OrderBy.Path.Field), dir) case *pb.Clause_Where: val, err := convertJSONValue(c.Where.JsonValue) if err != nil { return nil, err } q = q.WherePath(FieldPath(c.Where.Path.Field), c.Where.Op, val) case *pb.Clause_Offset: q = q.Offset(int(c.Offset)) case *pb.Clause_Limit: q = q.Limit(int(c.Limit)) case *pb.Clause_StartAt: cs, err := convertCursor(c.StartAt) if err != nil { return nil, err } q = q.StartAt(cs...) case *pb.Clause_StartAfter: cs, err := convertCursor(c.StartAfter) if err != nil { return nil, err } q = q.StartAfter(cs...) case *pb.Clause_EndAt: cs, err := convertCursor(c.EndAt) if err != nil { return nil, err } q = q.EndAt(cs...) case *pb.Clause_EndBefore: cs, err := convertCursor(c.EndBefore) if err != nil { return nil, err } q = q.EndBefore(cs...) default: return nil, fmt.Errorf("bad clause type %T", c) } } return &q, nil } // Returns args to a cursor method (StartAt, etc.). func convertCursor(c *pb.Cursor) ([]interface{}, error) { if c.DocSnapshot != nil { ds, err := convertDocSnapshot(c.DocSnapshot) if err != nil { return nil, err } return []interface{}{ds}, nil } var vals []interface{} for _, jv := range c.JsonValues { v, err := convertJSONValue(jv) if err != nil { return nil, err } vals = append(vals, v) } return vals, nil } func convertDocSnapshot(ds *pb.DocSnapshot) (*DocumentSnapshot, error) { data, err := convertData(ds.JsonData) if err != nil { return nil, err } doc, transformPaths, err := toProtoDocument(data) if err != nil { return nil, err } if len(transformPaths) > 0 { return nil, errors.New("saw transform paths in DocSnapshot") } return &DocumentSnapshot{ Ref: &DocumentRef{ Path: ds.Path, Parent: &CollectionRef{Path: path.Dir(ds.Path)}, }, proto: doc, }, nil } google-cloud-go-0.49.0/firestore/doc.go000066400000000000000000000156011356504100700176710ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // DO NOT EDIT doc.go. Modify internal/doc.template, then run make -C internal. /* Package firestore provides a client for reading and writing to a Cloud Firestore database. See https://cloud.google.com/firestore/docs for an introduction to Cloud Firestore and additional help on using the Firestore API. See https://godoc.org/cloud.google.com/go for authentication, timeouts, connection pooling and similar aspects of this package. Note: you can't use both Cloud Firestore and Cloud Datastore in the same project. Creating a Client To start working with this package, create a client with a project ID: ctx := context.Background() client, err := firestore.NewClient(ctx, "projectID") if err != nil { // TODO: Handle error. } CollectionRefs and DocumentRefs In Firestore, documents are sets of key-value pairs, and collections are groups of documents. A Firestore database consists of a hierarchy of alternating collections and documents, referred to by slash-separated paths like "States/California/Cities/SanFrancisco". This client is built around references to collections and documents. CollectionRefs and DocumentRefs are lightweight values that refer to the corresponding database entities. Creating a ref does not involve any network traffic. states := client.Collection("States") ny := states.Doc("NewYork") // Or, in a single call: ny = client.Doc("States/NewYork") Reading Use DocumentRef.Get to read a document. The result is a DocumentSnapshot. Call its Data method to obtain the entire document contents as a map. docsnap, err := ny.Get(ctx) if err != nil { // TODO: Handle error. } dataMap := docsnap.Data() fmt.Println(dataMap) You can also obtain a single field with DataAt, or extract the data into a struct with DataTo. With the type definition type State struct { Capital string `firestore:"capital"` Population float64 `firestore:"pop"` // in millions } we can extract the document's data into a value of type State: var nyData State if err := docsnap.DataTo(&nyData); err != nil { // TODO: Handle error. } Note that this client supports struct tags beginning with "firestore:" that work like the tags of the encoding/json package, letting you rename fields, ignore them, or omit their values when empty. To retrieve multiple documents from their references in a single call, use Client.GetAll. docsnaps, err := client.GetAll(ctx, []*firestore.DocumentRef{ states.Doc("Wisconsin"), states.Doc("Ohio"), }) if err != nil { // TODO: Handle error. } for _, ds := range docsnaps { _ = ds // TODO: Use ds. } Writing For writing individual documents, use the methods on DocumentReference. Create creates a new document. wr, err := ny.Create(ctx, State{ Capital: "Albany", Population: 19.8, }) if err != nil { // TODO: Handle error. } fmt.Println(wr) The first return value is a WriteResult, which contains the time at which the document was updated. Create fails if the document exists. Another method, Set, either replaces an existing document or creates a new one. ca := states.Doc("California") _, err = ca.Set(ctx, State{ Capital: "Sacramento", Population: 39.14, }) To update some fields of an existing document, use Update. It takes a list of paths to update and their corresponding values. _, err = ca.Update(ctx, []firestore.Update{{Path: "capital", Value: "Sacramento"}}) Use DocumentRef.Delete to delete a document. _, err = ny.Delete(ctx) Preconditions You can condition Deletes or Updates on when a document was last changed. Specify these preconditions as an option to a Delete or Update method. The check and the write happen atomically with a single RPC. docsnap, err = ca.Get(ctx) if err != nil { // TODO: Handle error. } _, err = ca.Update(ctx, []firestore.Update{{Path: "capital", Value: "Sacramento"}}, firestore.LastUpdateTime(docsnap.UpdateTime)) Here we update a doc only if it hasn't changed since we read it. You could also do this with a transaction. To perform multiple writes at once, use a WriteBatch. Its methods chain for convenience. WriteBatch.Commit sends the collected writes to the server, where they happen atomically. writeResults, err := client.Batch(). Create(ny, State{Capital: "Albany"}). Update(ca, []firestore.Update{{Path: "capital", Value: "Sacramento"}}). Delete(client.Doc("States/WestDakota")). Commit(ctx) Queries You can use SQL to select documents from a collection. Begin with the collection, and build up a query using Select, Where and other methods of Query. q := states.Where("pop", ">", 10).OrderBy("pop", firestore.Desc) Supported operators include '<', '<=', '>', '>=', '==', 'in', 'array-contains', and 'array-contains-any'. Call the Query's Documents method to get an iterator, and use it like the other Google Cloud Client iterators. iter := q.Documents(ctx) defer iter.Stop() for { doc, err := iter.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } fmt.Println(doc.Data()) } To get all the documents in a collection, you can use the collection itself as a query. iter = client.Collection("States").Documents(ctx) Transactions Use a transaction to execute reads and writes atomically. All reads must happen before any writes. Transaction creation, commit, rollback and retry are handled for you by the Client.RunTransaction method; just provide a function and use the read and write methods of the Transaction passed to it. ny := client.Doc("States/NewYork") err := client.RunTransaction(ctx, func(ctx context.Context, tx *firestore.Transaction) error { doc, err := tx.Get(ny) // tx.Get, NOT ny.Get! if err != nil { return err } pop, err := doc.DataAt("pop") if err != nil { return err } return tx.Update(ny, []firestore.Update{{Path: "pop", Value: pop.(float64) + 0.2}}) }) if err != nil { // TODO: Handle error. } Google Cloud Firestore Emulator This package supports the Cloud Firestore emulator, which is useful for testing and development. Environment variables are used to indicate that Firestore traffic should be directed to the emulator instead of the production Firestore service. To install and run the emulator and its environment variables, see the documentation at https://cloud.google.com/sdk/gcloud/reference/beta/emulators/firestore/. Once the emulator is running, set FIRESTORE_EMULATOR_HOST to the API endpoint. */ package firestore google-cloud-go-0.49.0/firestore/docref.go000066400000000000000000000554721356504100700204000ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package firestore import ( "context" "errors" "fmt" "io" "reflect" "sort" vkit "cloud.google.com/go/firestore/apiv1" "cloud.google.com/go/internal/trace" "google.golang.org/api/iterator" pb "google.golang.org/genproto/googleapis/firestore/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) var errNilDocRef = errors.New("firestore: nil DocumentRef") // A DocumentRef is a reference to a Firestore document. type DocumentRef struct { // The CollectionRef that this document is a part of. Never nil. Parent *CollectionRef // The full resource path of the document. A document "doc-1" in collection // "coll-1" would be: "projects/P/databases/D/documents/coll-1/doc-1". Path string // The shorter resource path of the document. A document "doc-1" in // collection "coll-1" would be: "coll-1/doc-1". shortPath string // The ID of the document: the last component of the resource path. ID string } func newDocRef(parent *CollectionRef, id string) *DocumentRef { return &DocumentRef{ Parent: parent, ID: id, Path: parent.Path + "/" + id, shortPath: parent.selfPath + "/" + id, } } // Collection returns a reference to sub-collection of this document. func (d *DocumentRef) Collection(id string) *CollectionRef { return newCollRefWithParent(d.Parent.c, d, id) } // Get retrieves the document. If the document does not exist, Get return a NotFound error, which // can be checked with // status.Code(err) == codes.NotFound // In that case, Get returns a non-nil DocumentSnapshot whose Exists method return false and whose // ReadTime is the time of the failed read operation. func (d *DocumentRef) Get(ctx context.Context) (_ *DocumentSnapshot, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/firestore.DocumentRef.Get") defer func() { trace.EndSpan(ctx, err) }() if d == nil { return nil, errNilDocRef } docsnaps, err := d.Parent.c.getAll(ctx, []*DocumentRef{d}, nil) if err != nil { return nil, err } ds := docsnaps[0] if !ds.Exists() { return ds, status.Errorf(codes.NotFound, "%q not found", d.Path) } return ds, nil } // Create creates the document with the given data. // It returns an error if a document with the same ID already exists. // // The data argument can be a map with string keys, a struct, or a pointer to a // struct. The map keys or exported struct fields become the fields of the firestore // document. // The values of data are converted to Firestore values as follows: // // - bool converts to Bool. // - string converts to String. // - int, int8, int16, int32 and int64 convert to Integer. // - uint8, uint16 and uint32 convert to Integer. uint, uint64 and uintptr are disallowed, // because they may be able to represent values that cannot be represented in an int64, // which is the underlying type of a Integer. // - float32 and float64 convert to Double. // - []byte converts to Bytes. // - time.Time and *ts.Timestamp convert to Timestamp. ts is the package // "github.com/golang/protobuf/ptypes/timestamp". // - *latlng.LatLng converts to GeoPoint. latlng is the package // "google.golang.org/genproto/googleapis/type/latlng". You should always use // a pointer to a LatLng. // - Slices convert to Array. // - *firestore.DocumentRef converts to Reference. // - Maps and structs convert to Map. // - nils of any type convert to Null. // // Pointers and interface{} are also permitted, and their elements processed // recursively. // // Struct fields can have tags like those used by the encoding/json package. Tags // begin with "firestore:" and are followed by "-", meaning "ignore this field," or // an alternative name for the field. Following the name, these comma-separated // options may be provided: // // - omitempty: Do not encode this field if it is empty. A value is empty // if it is a zero value, or an array, slice or map of length zero. // - serverTimestamp: The field must be of type time.Time. When writing, if // the field has the zero value, the server will populate the stored document with // the time that the request is processed. func (d *DocumentRef) Create(ctx context.Context, data interface{}) (_ *WriteResult, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/firestore.DocumentRef.Create") defer func() { trace.EndSpan(ctx, err) }() ws, err := d.newCreateWrites(data) if err != nil { return nil, err } return d.Parent.c.commit1(ctx, ws) } func (d *DocumentRef) newCreateWrites(data interface{}) ([]*pb.Write, error) { if d == nil { return nil, errNilDocRef } doc, transforms, err := toProtoDocument(data) if err != nil { return nil, err } doc.Name = d.Path pc, err := exists(false).preconditionProto() if err != nil { return nil, err } return d.newUpdateWithTransform(doc, nil, pc, transforms, false), nil } // Set creates or overwrites the document with the given data. See DocumentRef.Create // for the acceptable values of data. Without options, Set overwrites the document // completely. Specify one of the Merge options to preserve an existing document's // fields. To delete some fields, use a Merge option with firestore.Delete as the // field value. func (d *DocumentRef) Set(ctx context.Context, data interface{}, opts ...SetOption) (_ *WriteResult, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/firestore.DocumentRef.Set") defer func() { trace.EndSpan(ctx, err) }() ws, err := d.newSetWrites(data, opts) if err != nil { return nil, err } return d.Parent.c.commit1(ctx, ws) } func (d *DocumentRef) newSetWrites(data interface{}, opts []SetOption) ([]*pb.Write, error) { if d == nil { return nil, errNilDocRef } if data == nil { return nil, errors.New("firestore: nil document contents") } if len(opts) == 0 { // Set without merge doc, serverTimestampPaths, err := toProtoDocument(data) if err != nil { return nil, err } doc.Name = d.Path return d.newUpdateWithTransform(doc, nil, nil, serverTimestampPaths, true), nil } // Set with merge. // This is just like Update, except for the existence precondition. // So we turn data into a list of (FieldPath, interface{}) pairs (fpv's), as we do // for Update. fieldPaths, allPaths, err := processSetOptions(opts) if err != nil { return nil, err } var fpvs []fpv v := reflect.ValueOf(data) if allPaths { // Set with MergeAll. Collect all the leaves of the map. if v.Kind() != reflect.Map { return nil, errors.New("firestore: MergeAll can only be specified with map data") } if v.Len() == 0 { // Special case: MergeAll with an empty map. return d.newUpdateWithTransform(&pb.Document{Name: d.Path}, []FieldPath{}, nil, nil, true), nil } fpvsFromData(v, nil, &fpvs) } else { // Set with merge paths. Collect only the values at the given paths. for _, fp := range fieldPaths { val, err := getAtPath(v, fp) if err != nil { return nil, err } fpvs = append(fpvs, fpv{fp, val}) } } return d.fpvsToWrites(fpvs, nil) } // fpvsFromData converts v into a list of (FieldPath, value) pairs. func fpvsFromData(v reflect.Value, prefix FieldPath, fpvs *[]fpv) { switch v.Kind() { case reflect.Map: for _, k := range v.MapKeys() { fpvsFromData(v.MapIndex(k), prefix.with(k.String()), fpvs) } case reflect.Interface: fpvsFromData(v.Elem(), prefix, fpvs) default: var val interface{} if v.IsValid() { val = v.Interface() } *fpvs = append(*fpvs, fpv{prefix, val}) } } // Delete deletes the document. If the document doesn't exist, it does nothing // and returns no error. func (d *DocumentRef) Delete(ctx context.Context, preconds ...Precondition) (_ *WriteResult, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/firestore.DocumentRef.Delete") defer func() { trace.EndSpan(ctx, err) }() ws, err := d.newDeleteWrites(preconds) if err != nil { return nil, err } return d.Parent.c.commit1(ctx, ws) } func (d *DocumentRef) newDeleteWrites(preconds []Precondition) ([]*pb.Write, error) { if d == nil { return nil, errNilDocRef } pc, err := processPreconditionsForDelete(preconds) if err != nil { return nil, err } return []*pb.Write{{ Operation: &pb.Write_Delete{d.Path}, CurrentDocument: pc, }}, nil } func (d *DocumentRef) newUpdatePathWrites(updates []Update, preconds []Precondition) ([]*pb.Write, error) { if len(updates) == 0 { return nil, errors.New("firestore: no paths to update") } var fpvs []fpv for _, u := range updates { v, err := u.process() if err != nil { return nil, err } fpvs = append(fpvs, v) } pc, err := processPreconditionsForUpdate(preconds) if err != nil { return nil, err } return d.fpvsToWrites(fpvs, pc) } func (d *DocumentRef) fpvsToWrites(fpvs []fpv, pc *pb.Precondition) ([]*pb.Write, error) { // Make sure there are no duplications or prefixes among the field paths. var fps []FieldPath for _, fpv := range fpvs { fps = append(fps, fpv.fieldPath) } if err := checkNoDupOrPrefix(fps); err != nil { return nil, err } // Process each fpv. var updatePaths []FieldPath var transforms []*pb.DocumentTransform_FieldTransform doc := &pb.Document{ Name: d.Path, Fields: map[string]*pb.Value{}, } for _, fpv := range fpvs { switch fpv.value.(type) { case arrayUnion: au := fpv.value.(arrayUnion) t, err := arrayUnionTransform(au, fpv.fieldPath) if err != nil { return nil, err } transforms = append(transforms, t) case arrayRemove: ar := fpv.value.(arrayRemove) t, err := arrayRemoveTransform(ar, fpv.fieldPath) if err != nil { return nil, err } transforms = append(transforms, t) case increment: t, err := incrementTransform(fpv.value.(increment), fpv.fieldPath) if err != nil { return nil, err } transforms = append(transforms, t) default: switch fpv.value { case Delete: // Send the field path without a corresponding value. updatePaths = append(updatePaths, fpv.fieldPath) case ServerTimestamp: // Use the path in a transform operation. transforms = append(transforms, serverTimestamp(fpv.fieldPath.toServiceFieldPath())) default: updatePaths = append(updatePaths, fpv.fieldPath) // Convert the value to a proto and put it into the document. v := reflect.ValueOf(fpv.value) pv, _, err := toProtoValue(v) if err != nil { return nil, err } setAtPath(doc.Fields, fpv.fieldPath, pv) // Also accumulate any transforms within the value. ts, err := extractTransforms(v, fpv.fieldPath) if err != nil { return nil, err } transforms = append(transforms, ts...) } } } return d.newUpdateWithTransform(doc, updatePaths, pc, transforms, false), nil } // newUpdateWithTransform constructs operations for a commit. Most generally, it // returns an update operation followed by a transform. // // If there are no serverTimestampPaths, the transform is omitted. // // If doc.Fields is empty, there are no updatePaths, and there is no precondition, // the update is omitted, unless updateOnEmpty is true. func (d *DocumentRef) newUpdateWithTransform(doc *pb.Document, updatePaths []FieldPath, pc *pb.Precondition, transforms []*pb.DocumentTransform_FieldTransform, updateOnEmpty bool) []*pb.Write { var ws []*pb.Write if updateOnEmpty || len(doc.Fields) > 0 || len(updatePaths) > 0 || (pc != nil && len(transforms) == 0) { var mask *pb.DocumentMask if updatePaths != nil { sfps := toServiceFieldPaths(updatePaths) sort.Strings(sfps) // TODO(jba): make tests pass without this mask = &pb.DocumentMask{FieldPaths: sfps} } w := &pb.Write{ Operation: &pb.Write_Update{doc}, UpdateMask: mask, CurrentDocument: pc, } ws = append(ws, w) pc = nil // If the precondition is in the write, we don't need it in the transform. } if len(transforms) > 0 || pc != nil { ws = append(ws, &pb.Write{ Operation: &pb.Write_Transform{ Transform: &pb.DocumentTransform{ Document: d.Path, FieldTransforms: transforms, }, }, CurrentDocument: pc, }) } return ws } // arrayUnion is a special type in firestore. It instructs the server to add its // elements to whatever array already exists, or to create an array if no value // exists. type arrayUnion struct { elems []interface{} } // ArrayUnion specifies elements to be added to whatever array already exists in // the server, or to create an array if no value exists. // // If a value exists and it's an array, values are appended to it. Any duplicate // value is ignored. // If a value exists and it's not an array, the value is replaced by an array of // the values in the ArrayUnion. // If a value does not exist, an array of the values in the ArrayUnion is created. // // ArrayUnion must be the value of a field directly; it cannot appear in // array or struct values, or in any value that is itself inside an array or // struct. func ArrayUnion(elems ...interface{}) arrayUnion { return arrayUnion{elems: elems} } // This helper converts an arrayUnion into a proto object. func arrayUnionTransform(au arrayUnion, fp FieldPath) (*pb.DocumentTransform_FieldTransform, error) { var elems []*pb.Value for _, v := range au.elems { pv, _, err := toProtoValue(reflect.ValueOf(v)) if err != nil { return nil, err } elems = append(elems, pv) } return &pb.DocumentTransform_FieldTransform{ FieldPath: fp.toServiceFieldPath(), TransformType: &pb.DocumentTransform_FieldTransform_AppendMissingElements{ AppendMissingElements: &pb.ArrayValue{Values: elems}, }, }, nil } // arrayRemove is a special type in firestore. It instructs the server to remove // the specified values. type arrayRemove struct { elems []interface{} } // ArrayRemove specifies elements to be removed from whatever array already // exists in the server. // // If a value exists and it's an array, values are removed from it. All // duplicate values are removed. // If a value exists and it's not an array, the value is replaced by an empty // array. // If a value does not exist, an empty array is created. // // ArrayRemove must be the value of a field directly; it cannot appear in // array or struct values, or in any value that is itself inside an array or // struct. func ArrayRemove(elems ...interface{}) arrayRemove { return arrayRemove{elems: elems} } // This helper converts an arrayRemove into a proto object. func arrayRemoveTransform(ar arrayRemove, fp FieldPath) (*pb.DocumentTransform_FieldTransform, error) { var elems []*pb.Value for _, v := range ar.elems { // ServerTimestamp cannot occur in an array, so we ignore transformations here. pv, _, err := toProtoValue(reflect.ValueOf(v)) if err != nil { return nil, err } elems = append(elems, pv) } return &pb.DocumentTransform_FieldTransform{ FieldPath: fp.toServiceFieldPath(), TransformType: &pb.DocumentTransform_FieldTransform_RemoveAllFromArray{ RemoveAllFromArray: &pb.ArrayValue{Values: elems}, }, }, nil } type increment struct { n interface{} } // Increment returns a special value that can be used with Set, Create, or // Update that tells the server to increment the field's current value // by the given value. // // The supported values are: // // int, int8, int16, int32, int64 // uint8, uint16, uint32 // float32, float64 // // If the field does not yet exist, the transformation will set the field to // the given value. func Increment(n interface{}) increment { return increment{n: n} } func incrementTransform(ar increment, fp FieldPath) (*pb.DocumentTransform_FieldTransform, error) { switch ar.n.(type) { case int, int8, int16, int32, int64, uint8, uint16, uint32, float32, float64: default: return nil, fmt.Errorf("unsupported type %T for Increment; supported values include int, int8, int16, int32, int64, uint8, uint16, uint32, float32, float64", ar.n) } v, _, err := toProtoValue(reflect.ValueOf(ar.n)) if err != nil { return nil, err } return &pb.DocumentTransform_FieldTransform{ FieldPath: fp.toServiceFieldPath(), TransformType: &pb.DocumentTransform_FieldTransform_Increment{ Increment: v, }, }, nil } type sentinel int const ( // Delete is used as a value in a call to Update or Set with merge to indicate // that the corresponding key should be deleted. Delete sentinel = iota // ServerTimestamp is used as a value in a call to Update to indicate that the // key's value should be set to the time at which the server processed // the request. // // ServerTimestamp must be the value of a field directly; it cannot appear in // array or struct values, or in any value that is itself inside an array or // struct. ServerTimestamp ) func (s sentinel) String() string { switch s { case Delete: return "Delete" case ServerTimestamp: return "ServerTimestamp" default: return "" } } // An Update describes an update to a value referred to by a path. // An Update should have either a non-empty Path or a non-empty FieldPath, // but not both. // // See DocumentRef.Create for acceptable values. // To delete a field, specify firestore.Delete as the value. type Update struct { Path string // Will be split on dots, and must not contain any of "Ëœ*/[]". FieldPath FieldPath Value interface{} } // An fpv is a pair of validated FieldPath and value. type fpv struct { fieldPath FieldPath value interface{} } func (u *Update) process() (fpv, error) { if (u.Path != "") == (u.FieldPath != nil) { return fpv{}, fmt.Errorf("firestore: update %+v should have exactly one of Path or FieldPath", u) } fp := u.FieldPath var err error if fp == nil { fp, err = parseDotSeparatedString(u.Path) if err != nil { return fpv{}, err } } if err := fp.validate(); err != nil { return fpv{}, err } return fpv{fp, u.Value}, nil } // Update updates the document. The values at the given // field paths are replaced, but other fields of the stored document are untouched. func (d *DocumentRef) Update(ctx context.Context, updates []Update, preconds ...Precondition) (_ *WriteResult, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/firestore.DocumentRef.Update") defer func() { trace.EndSpan(ctx, err) }() ws, err := d.newUpdatePathWrites(updates, preconds) if err != nil { return nil, err } return d.Parent.c.commit1(ctx, ws) } // Collections returns an iterator over the immediate sub-collections of the document. func (d *DocumentRef) Collections(ctx context.Context) *CollectionIterator { client := d.Parent.c it := &CollectionIterator{ client: client, parent: d, it: client.c.ListCollectionIds( withResourceHeader(ctx, client.path()), &pb.ListCollectionIdsRequest{Parent: d.Path}), } it.pageInfo, it.nextFunc = iterator.NewPageInfo( it.fetch, func() int { return len(it.items) }, func() interface{} { b := it.items; it.items = nil; return b }) return it } // CollectionIterator is an iterator over sub-collections of a document. type CollectionIterator struct { client *Client parent *DocumentRef it *vkit.StringIterator pageInfo *iterator.PageInfo nextFunc func() error items []*CollectionRef err error } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *CollectionIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there // are no more results. Once Next returns Done, all subsequent calls will return // Done. func (it *CollectionIterator) Next() (*CollectionRef, error) { if err := it.nextFunc(); err != nil { return nil, err } item := it.items[0] it.items = it.items[1:] return item, nil } func (it *CollectionIterator) fetch(pageSize int, pageToken string) (string, error) { if it.err != nil { return "", it.err } return iterFetch(pageSize, pageToken, it.it.PageInfo(), func() error { id, err := it.it.Next() if err != nil { return err } var cr *CollectionRef if it.parent == nil { cr = newTopLevelCollRef(it.client, it.client.path(), id) } else { cr = newCollRefWithParent(it.client, it.parent, id) } it.items = append(it.items, cr) return nil }) } // GetAll returns all the collections remaining from the iterator. func (it *CollectionIterator) GetAll() ([]*CollectionRef, error) { var crs []*CollectionRef for { cr, err := it.Next() if err == iterator.Done { break } if err != nil { return nil, err } crs = append(crs, cr) } return crs, nil } // Common fetch code for iterators that are backed by vkit iterators. // TODO(jba): dedup with same function in logging/logadmin. func iterFetch(pageSize int, pageToken string, pi *iterator.PageInfo, next func() error) (string, error) { pi.MaxSize = pageSize pi.Token = pageToken // Get one item, which will fill the buffer. if err := next(); err != nil { return "", err } // Collect the rest of the buffer. for pi.Remaining() > 0 { if err := next(); err != nil { return "", err } } return pi.Token, nil } // Snapshots returns an iterator over snapshots of the document. Each time the document // changes or is added or deleted, a new snapshot will be generated. func (d *DocumentRef) Snapshots(ctx context.Context) *DocumentSnapshotIterator { return &DocumentSnapshotIterator{ docref: d, ws: newWatchStreamForDocument(ctx, d), } } // DocumentSnapshotIterator is an iterator over snapshots of a document. // Call Next on the iterator to get a snapshot of the document each time it changes. // Call Stop on the iterator when done. // // For an example, see DocumentRef.Snapshots. type DocumentSnapshotIterator struct { docref *DocumentRef ws *watchStream } // Next blocks until the document changes, then returns the DocumentSnapshot for // the current state of the document. If the document has been deleted, Next // returns a DocumentSnapshot whose Exists method returns false. // // Next never returns iterator.Done unless it is called after Stop. func (it *DocumentSnapshotIterator) Next() (*DocumentSnapshot, error) { btree, _, readTime, err := it.ws.nextSnapshot() if err != nil { if err == io.EOF { err = iterator.Done } // watchStream's error is sticky, so SnapshotIterator does not need to remember it. return nil, err } if btree.Len() == 0 { // document deleted return &DocumentSnapshot{Ref: it.docref, ReadTime: readTime}, nil } snap, _ := btree.At(0) return snap.(*DocumentSnapshot), nil } // Stop stops receiving snapshots. You should always call Stop when you are done with // a DocumentSnapshotIterator, to free up resources. It is not safe to call Stop // concurrently with Next. func (it *DocumentSnapshotIterator) Stop() { it.ws.stop() } google-cloud-go-0.49.0/firestore/docref_test.go000066400000000000000000000172561356504100700214350ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package firestore import ( "context" "reflect" "sort" "testing" "time" pb "google.golang.org/genproto/googleapis/firestore/v1" "google.golang.org/genproto/googleapis/type/latlng" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) var ( writeResultForSet = &WriteResult{UpdateTime: aTime} commitResponseForSet = &pb.CommitResponse{ WriteResults: []*pb.WriteResult{{UpdateTime: aTimestamp}}, } ) func TestDocGet(t *testing.T) { ctx := context.Background() c, srv, cleanup := newMock(t) defer cleanup() path := "projects/projectID/databases/(default)/documents/C/a" pdoc := &pb.Document{ Name: path, CreateTime: aTimestamp, UpdateTime: aTimestamp, Fields: map[string]*pb.Value{"f": intval(1)}, } srv.addRPC(&pb.BatchGetDocumentsRequest{ Database: c.path(), Documents: []string{path}, }, []interface{}{ &pb.BatchGetDocumentsResponse{ Result: &pb.BatchGetDocumentsResponse_Found{pdoc}, ReadTime: aTimestamp2, }, }) ref := c.Collection("C").Doc("a") gotDoc, err := ref.Get(ctx) if err != nil { t.Fatal(err) } wantDoc := &DocumentSnapshot{ Ref: ref, CreateTime: aTime, UpdateTime: aTime, ReadTime: aTime2, proto: pdoc, c: c, } if !testEqual(gotDoc, wantDoc) { t.Fatalf("\ngot %+v\nwant %+v", gotDoc, wantDoc) } path2 := "projects/projectID/databases/(default)/documents/C/b" srv.addRPC( &pb.BatchGetDocumentsRequest{ Database: c.path(), Documents: []string{path2}, }, []interface{}{ &pb.BatchGetDocumentsResponse{ Result: &pb.BatchGetDocumentsResponse_Missing{path2}, ReadTime: aTimestamp3, }, }) _, err = c.Collection("C").Doc("b").Get(ctx) if status.Code(err) != codes.NotFound { t.Errorf("got %v, want NotFound", err) } } func TestDocSet(t *testing.T) { // Most tests for Set are in the conformance tests. ctx := context.Background() c, srv, cleanup := newMock(t) defer cleanup() doc := c.Collection("C").Doc("d") // Merge with a struct and FieldPaths. srv.addRPC(&pb.CommitRequest{ Database: "projects/projectID/databases/(default)", Writes: []*pb.Write{ { Operation: &pb.Write_Update{ Update: &pb.Document{ Name: "projects/projectID/databases/(default)/documents/C/d", Fields: map[string]*pb.Value{ "*": mapval(map[string]*pb.Value{ "~": boolval(true), }), }, }, }, UpdateMask: &pb.DocumentMask{FieldPaths: []string{"`*`.`~`"}}, }, }, }, commitResponseForSet) data := struct { A map[string]bool `firestore:"*"` }{A: map[string]bool{"~": true}} wr, err := doc.Set(ctx, data, Merge([]string{"*", "~"})) if err != nil { t.Fatal(err) } if !testEqual(wr, writeResultForSet) { t.Errorf("got %v, want %v", wr, writeResultForSet) } // MergeAll cannot be used with structs. _, err = doc.Set(ctx, data, MergeAll) if err == nil { t.Errorf("got nil, want error") } } func TestDocCreate(t *testing.T) { // Verify creation with structs. In particular, make sure zero values // are handled well. // Other tests for Create are handled by the conformance tests. ctx := context.Background() c, srv, cleanup := newMock(t) defer cleanup() type create struct { Time time.Time Bytes []byte Geo *latlng.LatLng } srv.addRPC( &pb.CommitRequest{ Database: "projects/projectID/databases/(default)", Writes: []*pb.Write{ { Operation: &pb.Write_Update{ Update: &pb.Document{ Name: "projects/projectID/databases/(default)/documents/C/d", Fields: map[string]*pb.Value{ "Time": tsval(time.Time{}), "Bytes": bytesval(nil), "Geo": nullValue, }, }, }, CurrentDocument: &pb.Precondition{ ConditionType: &pb.Precondition_Exists{false}, }, }, }, }, commitResponseForSet, ) _, err := c.Collection("C").Doc("d").Create(ctx, &create{}) if err != nil { t.Fatal(err) } } func TestDocDelete(t *testing.T) { ctx := context.Background() c, srv, cleanup := newMock(t) defer cleanup() srv.addRPC( &pb.CommitRequest{ Database: "projects/projectID/databases/(default)", Writes: []*pb.Write{ {Operation: &pb.Write_Delete{"projects/projectID/databases/(default)/documents/C/d"}}, }, }, &pb.CommitResponse{ WriteResults: []*pb.WriteResult{{}}, }) wr, err := c.Collection("C").Doc("d").Delete(ctx) if err != nil { t.Fatal(err) } if !testEqual(wr, &WriteResult{}) { t.Errorf("got %+v, want %+v", wr, writeResultForSet) } } var ( testData = map[string]interface{}{"a": 1} testFields = map[string]*pb.Value{"a": intval(1)} ) // Update is tested by the conformance tests. func TestFPVsFromData(t *testing.T) { type S struct{ X int } for _, test := range []struct { in interface{} want []fpv }{ { in: nil, want: []fpv{{nil, nil}}, }, { in: map[string]interface{}{"a": nil}, want: []fpv{{[]string{"a"}, nil}}, }, { in: map[string]interface{}{"a": 1}, want: []fpv{{[]string{"a"}, 1}}, }, { in: map[string]interface{}{ "a": 1, "b": map[string]interface{}{"c": 2}, }, want: []fpv{{[]string{"a"}, 1}, {[]string{"b", "c"}, 2}}, }, { in: map[string]interface{}{"s": &S{X: 3}}, want: []fpv{{[]string{"s"}, &S{X: 3}}}, }, } { var got []fpv fpvsFromData(reflect.ValueOf(test.in), nil, &got) sort.Sort(byFieldPath(got)) if !testEqual(got, test.want) { t.Errorf("%+v: got %v, want %v", test.in, got, test.want) } } } type byFieldPath []fpv func (b byFieldPath) Len() int { return len(b) } func (b byFieldPath) Swap(i, j int) { b[i], b[j] = b[j], b[i] } func (b byFieldPath) Less(i, j int) bool { return b[i].fieldPath.less(b[j].fieldPath) } func commitRequestForSet() *pb.CommitRequest { return &pb.CommitRequest{ Database: "projects/projectID/databases/(default)", Writes: []*pb.Write{ { Operation: &pb.Write_Update{ Update: &pb.Document{ Name: "projects/projectID/databases/(default)/documents/C/d", Fields: testFields, }, }, }, }, } } func TestUpdateProcess(t *testing.T) { for _, test := range []struct { in Update want fpv wantErr bool }{ { in: Update{Path: "a", Value: 1}, want: fpv{fieldPath: []string{"a"}, value: 1}, }, { in: Update{Path: "c.d", Value: Delete}, want: fpv{fieldPath: []string{"c", "d"}, value: Delete}, }, { in: Update{FieldPath: []string{"*", "~"}, Value: ServerTimestamp}, want: fpv{fieldPath: []string{"*", "~"}, value: ServerTimestamp}, }, { in: Update{Path: "*"}, wantErr: true, // bad rune in path }, { in: Update{Path: "a", FieldPath: []string{"b"}}, wantErr: true, // both Path and FieldPath }, { in: Update{Value: 1}, wantErr: true, // neither Path nor FieldPath }, { in: Update{FieldPath: []string{"", "a"}}, wantErr: true, // empty FieldPath component }, } { got, err := test.in.process() if test.wantErr { if err == nil { t.Errorf("%+v: got nil, want error", test.in) } } else if err != nil { t.Errorf("%+v: got error %v, want nil", test.in, err) } else if !testEqual(got, test.want) { t.Errorf("%+v: got %+v, want %+v", test.in, got, test.want) } } } google-cloud-go-0.49.0/firestore/document.go000066400000000000000000000244721356504100700207500ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package firestore import ( "errors" "fmt" "reflect" "time" "github.com/golang/protobuf/ptypes" tspb "github.com/golang/protobuf/ptypes/timestamp" pb "google.golang.org/genproto/googleapis/firestore/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) // A DocumentSnapshot contains document data and metadata. type DocumentSnapshot struct { // The DocumentRef for this document. Ref *DocumentRef // Read-only. The time at which the document was created. // Increases monotonically when a document is deleted then // recreated. It can also be compared to values from other documents and // the read time of a query. CreateTime time.Time // Read-only. The time at which the document was last changed. This value // is initially set to CreateTime then increases monotonically with each // change to the document. It can also be compared to values from other // documents and the read time of a query. UpdateTime time.Time // Read-only. The time at which the document was read. ReadTime time.Time c *Client proto *pb.Document } // Exists reports whether the DocumentSnapshot represents an existing document. // Even if Exists returns false, the Ref and ReadTime fields of the DocumentSnapshot // are valid. func (d *DocumentSnapshot) Exists() bool { return d.proto != nil } // Data returns the DocumentSnapshot's fields as a map. // It is equivalent to // var m map[string]interface{} // d.DataTo(&m) // except that it returns nil if the document does not exist. func (d *DocumentSnapshot) Data() map[string]interface{} { if !d.Exists() { return nil } m, err := createMapFromValueMap(d.proto.Fields, d.c) // Any error here is a bug in the client. if err != nil { panic(fmt.Sprintf("firestore: %v", err)) } return m } // DataTo uses the document's fields to populate p, which can be a pointer to a // map[string]interface{} or a pointer to a struct. // // Firestore field values are converted to Go values as follows: // - Null converts to nil. // - Bool converts to bool. // - String converts to string. // - Integer converts int64. When setting a struct field, any signed or unsigned // integer type is permitted except uint, uint64 or uintptr. Overflow is detected // and results in an error. // - Double converts to float64. When setting a struct field, float32 is permitted. // Overflow is detected and results in an error. // - Bytes is converted to []byte. // - Timestamp converts to time.Time. // - GeoPoint converts to *latlng.LatLng, where latlng is the package // "google.golang.org/genproto/googleapis/type/latlng". // - Arrays convert to []interface{}. When setting a struct field, the field // may be a slice or array of any type and is populated recursively. // Slices are resized to the incoming value's size, while arrays that are too // long have excess elements filled with zero values. If the array is too short, // excess incoming values will be dropped. // - Maps convert to map[string]interface{}. When setting a struct field, // maps of key type string and any value type are permitted, and are populated // recursively. // - References are converted to *firestore.DocumentRefs. // // Field names given by struct field tags are observed, as described in // DocumentRef.Create. // // Only the fields actually present in the document are used to populate p. Other fields // of p are left unchanged. // // If the document does not exist, DataTo returns a NotFound error. func (d *DocumentSnapshot) DataTo(p interface{}) error { if !d.Exists() { return status.Errorf(codes.NotFound, "document %s does not exist", d.Ref.Path) } return setFromProtoValue(p, &pb.Value{ValueType: &pb.Value_MapValue{&pb.MapValue{Fields: d.proto.Fields}}}, d.c) } // DataAt returns the data value denoted by path. // // The path argument can be a single field or a dot-separated sequence of // fields, and must not contain any of the runes "Ëœ*/[]". Use DataAtPath instead for // such a path. // // See DocumentSnapshot.DataTo for how Firestore values are converted to Go values. // // If the document does not exist, DataAt returns a NotFound error. func (d *DocumentSnapshot) DataAt(path string) (interface{}, error) { if !d.Exists() { return nil, status.Errorf(codes.NotFound, "document %s does not exist", d.Ref.Path) } fp, err := parseDotSeparatedString(path) if err != nil { return nil, err } return d.DataAtPath(fp) } // DataAtPath returns the data value denoted by the FieldPath fp. // If the document does not exist, DataAtPath returns a NotFound error. func (d *DocumentSnapshot) DataAtPath(fp FieldPath) (interface{}, error) { if !d.Exists() { return nil, status.Errorf(codes.NotFound, "document %s does not exist", d.Ref.Path) } v, err := valueAtPath(fp, d.proto.Fields) if err != nil { return nil, err } return createFromProtoValue(v, d.c) } // valueAtPath returns the value of m referred to by fp. func valueAtPath(fp FieldPath, m map[string]*pb.Value) (*pb.Value, error) { for _, k := range fp[:len(fp)-1] { v := m[k] if v == nil { return nil, fmt.Errorf("firestore: no field %q", k) } mv := v.GetMapValue() if mv == nil { return nil, fmt.Errorf("firestore: value for field %q is not a map", k) } m = mv.Fields } k := fp[len(fp)-1] v := m[k] if v == nil { return nil, fmt.Errorf("firestore: no field %q", k) } return v, nil } // toProtoDocument converts a Go value to a Document proto. // Valid values are: map[string]T, struct, or pointer to a valid value. // It also returns a list DocumentTransforms. func toProtoDocument(x interface{}) (*pb.Document, []*pb.DocumentTransform_FieldTransform, error) { if x == nil { return nil, nil, errors.New("firestore: nil document contents") } v := reflect.ValueOf(x) pv, _, err := toProtoValue(v) if err != nil { return nil, nil, err } var transforms []*pb.DocumentTransform_FieldTransform transforms, err = extractTransforms(v, nil) if err != nil { return nil, nil, err } var fields map[string]*pb.Value if pv != nil { m := pv.GetMapValue() if m == nil { return nil, nil, fmt.Errorf("firestore: cannot convert value of type %T into a map", x) } fields = m.Fields } return &pb.Document{Fields: fields}, transforms, nil } func extractTransforms(v reflect.Value, prefix FieldPath) ([]*pb.DocumentTransform_FieldTransform, error) { switch v.Kind() { case reflect.Map: return extractTransformsFromMap(v, prefix) case reflect.Struct: return extractTransformsFromStruct(v, prefix) case reflect.Ptr: if v.IsNil() { return nil, nil } return extractTransforms(v.Elem(), prefix) case reflect.Interface: if v.NumMethod() == 0 { // empty interface: recurse on its contents return extractTransforms(v.Elem(), prefix) } return nil, nil default: return nil, nil } } func extractTransformsFromMap(v reflect.Value, prefix FieldPath) ([]*pb.DocumentTransform_FieldTransform, error) { var transforms []*pb.DocumentTransform_FieldTransform for _, k := range v.MapKeys() { sk := k.Interface().(string) // assume keys are strings; checked in toProtoValue path := prefix.with(sk) mi := v.MapIndex(k) if mi.Interface() == ServerTimestamp { transforms = append(transforms, serverTimestamp(path.toServiceFieldPath())) } else if au, ok := mi.Interface().(arrayUnion); ok { t, err := arrayUnionTransform(au, path) if err != nil { return nil, err } transforms = append(transforms, t) } else if ar, ok := mi.Interface().(arrayRemove); ok { t, err := arrayRemoveTransform(ar, path) if err != nil { return nil, err } transforms = append(transforms, t) } else if ar, ok := mi.Interface().(increment); ok { t, err := incrementTransform(ar, path) if err != nil { return nil, err } transforms = append(transforms, t) } else { ps, err := extractTransforms(mi, path) if err != nil { return nil, err } transforms = append(transforms, ps...) } } return transforms, nil } func extractTransformsFromStruct(v reflect.Value, prefix FieldPath) ([]*pb.DocumentTransform_FieldTransform, error) { var transforms []*pb.DocumentTransform_FieldTransform fields, err := fieldCache.Fields(v.Type()) if err != nil { return nil, err } for _, f := range fields { fv := v.FieldByIndex(f.Index) path := prefix.with(f.Name) opts := f.ParsedTag.(tagOptions) if opts.serverTimestamp { var isZero bool switch f.Type { case typeOfGoTime: isZero = fv.Interface().(time.Time).IsZero() case reflect.PtrTo(typeOfGoTime): isZero = fv.IsNil() || fv.Elem().Interface().(time.Time).IsZero() default: return nil, fmt.Errorf("firestore: field %s of struct %s with serverTimestamp tag must be of type time.Time or *time.Time", f.Name, v.Type()) } if isZero { transforms = append(transforms, serverTimestamp(path.toServiceFieldPath())) } } else { ps, err := extractTransforms(fv, path) if err != nil { return nil, err } transforms = append(transforms, ps...) } } return transforms, nil } func newDocumentSnapshot(ref *DocumentRef, proto *pb.Document, c *Client, readTime *tspb.Timestamp) (*DocumentSnapshot, error) { d := &DocumentSnapshot{ Ref: ref, c: c, proto: proto, } if proto != nil { ts, err := ptypes.Timestamp(proto.CreateTime) if err != nil { return nil, err } d.CreateTime = ts ts, err = ptypes.Timestamp(proto.UpdateTime) if err != nil { return nil, err } d.UpdateTime = ts } if readTime != nil { ts, err := ptypes.Timestamp(readTime) if err != nil { return nil, err } d.ReadTime = ts } return d, nil } func serverTimestamp(path string) *pb.DocumentTransform_FieldTransform { return &pb.DocumentTransform_FieldTransform{ FieldPath: path, TransformType: &pb.DocumentTransform_FieldTransform_SetToServerValue{ SetToServerValue: pb.DocumentTransform_FieldTransform_REQUEST_TIME, }, } } google-cloud-go-0.49.0/firestore/document_test.go000066400000000000000000000177001356504100700220030ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package firestore import ( "reflect" "sort" "strings" "testing" "time" tspb "github.com/golang/protobuf/ptypes/timestamp" pb "google.golang.org/genproto/googleapis/firestore/v1" ) func TestToProtoDocument(t *testing.T) { type s struct{ I int } for _, test := range []struct { in interface{} want *pb.Document wantErr bool }{ {nil, nil, true}, {[]int{1}, nil, true}, {map[string]int{"a": 1}, &pb.Document{Fields: map[string]*pb.Value{"a": intval(1)}}, false}, {s{2}, &pb.Document{Fields: map[string]*pb.Value{"I": intval(2)}}, false}, {&s{3}, &pb.Document{Fields: map[string]*pb.Value{"I": intval(3)}}, false}, } { got, _, gotErr := toProtoDocument(test.in) if (gotErr != nil) != test.wantErr { t.Errorf("%v: got error %v, want %t", test.in, gotErr, test.wantErr) } if gotErr != nil { continue } if !testEqual(got, test.want) { t.Errorf("%v: got %v, want %v", test.in, got, test.want) } } } func TestNewDocumentSnapshot(t *testing.T) { c := &Client{ projectID: "projID", databaseID: "(database)", } docRef := c.Doc("C/a") in := &pb.Document{ CreateTime: &tspb.Timestamp{Seconds: 10}, UpdateTime: &tspb.Timestamp{Seconds: 20}, Fields: map[string]*pb.Value{"a": intval(1)}, } want := &DocumentSnapshot{ Ref: docRef, CreateTime: time.Unix(10, 0).UTC(), UpdateTime: time.Unix(20, 0).UTC(), ReadTime: aTime, proto: in, c: c, } got, err := newDocumentSnapshot(docRef, in, c, aTimestamp) if err != nil { t.Fatal(err) } if !testEqual(got, want) { t.Errorf("got %+v\nwant %+v", got, want) } } func TestData(t *testing.T) { doc := &DocumentSnapshot{ proto: &pb.Document{ Fields: map[string]*pb.Value{"a": intval(1), "b": strval("x")}, }, } got := doc.Data() want := map[string]interface{}{"a": int64(1), "b": "x"} if !testEqual(got, want) { t.Errorf("got %#v\nwant %#v", got, want) } var got2 map[string]interface{} if err := doc.DataTo(&got2); err != nil { t.Fatal(err) } if !testEqual(got2, want) { t.Errorf("got %#v\nwant %#v", got2, want) } type s struct { A int B string } var got3 s if err := doc.DataTo(&got3); err != nil { t.Fatal(err) } want2 := s{A: 1, B: "x"} if !testEqual(got3, want2) { t.Errorf("got %#v\nwant %#v", got3, want2) } } var testDoc = &DocumentSnapshot{ proto: &pb.Document{ Fields: map[string]*pb.Value{ "a": intval(1), "b": mapval(map[string]*pb.Value{ "`": intval(2), "~": mapval(map[string]*pb.Value{ "x": intval(3), }), }), }, }, } func TestDataAt(t *testing.T) { for _, test := range []struct { fieldPath string want interface{} }{ {"a", int64(1)}, {"b.`", int64(2)}, } { got, err := testDoc.DataAt(test.fieldPath) if err != nil { t.Errorf("%q: %v", test.fieldPath, err) continue } if !testEqual(got, test.want) { t.Errorf("%q: got %v, want %v", test.fieldPath, got, test.want) } } for _, bad := range []string{ "c.~.x", // bad field path "a.b", // "a" isn't a map "z.b", // bad non-final key "b.z", // bad final key } { _, err := testDoc.DataAt(bad) if err == nil { t.Errorf("%q: got nil, want error", bad) } } } func TestDataAtPath(t *testing.T) { for _, test := range []struct { fieldPath FieldPath want interface{} }{ {[]string{"a"}, int64(1)}, {[]string{"b", "`"}, int64(2)}, {[]string{"b", "~"}, map[string]interface{}{"x": int64(3)}}, {[]string{"b", "~", "x"}, int64(3)}, } { got, err := testDoc.DataAtPath(test.fieldPath) if err != nil { t.Errorf("%v: %v", test.fieldPath, err) continue } if !testEqual(got, test.want) { t.Errorf("%v: got %v, want %v", test.fieldPath, got, test.want) } } for _, bad := range []FieldPath{ []string{"c", "", "x"}, // bad field path []string{"a", "b"}, // "a" isn't a map []string{"z", "~"}, // bad non-final key []string{"b", "z"}, // bad final key } { _, err := testDoc.DataAtPath(bad) if err == nil { t.Errorf("%v: got nil, want error", bad) } } } func TestExtractTransforms(t *testing.T) { type S struct { A time.Time `firestore:",serverTimestamp"` B time.Time `firestore:",serverTimestamp"` C *time.Time `firestore:",serverTimestamp"` D *time.Time `firestore:"d.d,serverTimestamp"` E *time.Time `firestore:",serverTimestamp"` F time.Time G int } m := map[string]interface{}{ "ar": map[string]interface{}{"k2": ArrayRemove("e", "f", "g")}, "au": map[string]interface{}{"k1": ArrayUnion("a", "b", "c")}, "inc": map[string]interface{}{"k3": Increment(7)}, "x": 1, "y": &S{ // A is a zero time: included B: aTime, // not a zero time: excluded //C is nil: included D: &time.Time{}, // pointer to a zero time: included E: &aTime, // pointer to a non-zero time: excluded //F is a zero time, but does not have the right tag: excluded G: 15, // not a time.Time }, "z": map[string]interface{}{"w": ServerTimestamp}, } got, err := extractTransforms(reflect.ValueOf(m), nil) if err != nil { t.Fatal(err) } want := []*pb.DocumentTransform_FieldTransform{ { FieldPath: "ar.k2", TransformType: &pb.DocumentTransform_FieldTransform_RemoveAllFromArray{ RemoveAllFromArray: &pb.ArrayValue{Values: []*pb.Value{ {ValueType: &pb.Value_StringValue{"e"}}, {ValueType: &pb.Value_StringValue{"f"}}, {ValueType: &pb.Value_StringValue{"g"}}, }}, }, }, { FieldPath: "au.k1", TransformType: &pb.DocumentTransform_FieldTransform_AppendMissingElements{ AppendMissingElements: &pb.ArrayValue{Values: []*pb.Value{ {ValueType: &pb.Value_StringValue{"a"}}, {ValueType: &pb.Value_StringValue{"b"}}, {ValueType: &pb.Value_StringValue{"c"}}, }}, }, }, { FieldPath: "inc.k3", TransformType: &pb.DocumentTransform_FieldTransform_Increment{ Increment: &pb.Value{ValueType: &pb.Value_IntegerValue{7}}, }, }, { FieldPath: "y.A", TransformType: &pb.DocumentTransform_FieldTransform_SetToServerValue{ SetToServerValue: pb.DocumentTransform_FieldTransform_REQUEST_TIME, }, }, { FieldPath: "y.C", TransformType: &pb.DocumentTransform_FieldTransform_SetToServerValue{ SetToServerValue: pb.DocumentTransform_FieldTransform_REQUEST_TIME, }, }, { FieldPath: "y.`d.d`", TransformType: &pb.DocumentTransform_FieldTransform_SetToServerValue{ SetToServerValue: pb.DocumentTransform_FieldTransform_REQUEST_TIME, }, }, { FieldPath: "z.w", TransformType: &pb.DocumentTransform_FieldTransform_SetToServerValue{ SetToServerValue: pb.DocumentTransform_FieldTransform_REQUEST_TIME, }, }, } if len(got) != len(want) { t.Fatalf("Expected output array of size %d, got %d: %v", len(want), len(got), got) } sort.Sort(byDocumentTransformFieldPath(got)) for i, vw := range want { vg := got[i] if !testEqual(vw, vg) { t.Fatalf("index %d: got %#v, want %#v", i, vg, vw) } } } type byDocumentTransformFieldPath []*pb.DocumentTransform_FieldTransform func (b byDocumentTransformFieldPath) Len() int { return len(b) } func (b byDocumentTransformFieldPath) Swap(i, j int) { b[i], b[j] = b[j], b[i] } func (b byDocumentTransformFieldPath) Less(i, j int) bool { return strings.Compare(b[i].FieldPath, b[j].FieldPath) < 1 } func TestExtractTransformPathsErrors(t *testing.T) { type S struct { A int `firestore:",serverTimestamp"` } _, err := extractTransforms(reflect.ValueOf(S{}), nil) if err == nil { t.Error("got nil, want error") } } google-cloud-go-0.49.0/firestore/examples_test.go000066400000000000000000000374341356504100700220110ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // TODO(jba): add Output comments to examples when feasible. package firestore_test import ( "context" "fmt" "cloud.google.com/go/firestore" "google.golang.org/api/iterator" ) func ExampleNewClient() { ctx := context.Background() client, err := firestore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } defer client.Close() // Close client when done. _ = client // TODO: Use client. } func ExampleClient_Collection() { ctx := context.Background() client, err := firestore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } defer client.Close() coll1 := client.Collection("States") coll2 := client.Collection("States/NewYork/Cities") fmt.Println(coll1, coll2) } func ExampleClient_Doc() { ctx := context.Background() client, err := firestore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } defer client.Close() doc1 := client.Doc("States/NewYork") doc2 := client.Doc("States/NewYork/Cities/Albany") fmt.Println(doc1, doc2) } func ExampleClient_GetAll() { ctx := context.Background() client, err := firestore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } defer client.Close() docs, err := client.GetAll(ctx, []*firestore.DocumentRef{ client.Doc("States/NorthCarolina"), client.Doc("States/SouthCarolina"), client.Doc("States/WestCarolina"), client.Doc("States/EastCarolina"), }) if err != nil { // TODO: Handle error. } // docs is a slice with four DocumentSnapshots, but the last two are // nil because there is no West or East Carolina. fmt.Println(docs) } func ExampleClient_Batch() { ctx := context.Background() client, err := firestore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } defer client.Close() b := client.Batch() _ = b // TODO: Use batch. } func ExampleWriteBatch_Commit() { ctx := context.Background() client, err := firestore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } defer client.Close() type State struct { Capital string `firestore:"capital"` Population float64 `firestore:"pop"` // in millions } ny := client.Doc("States/NewYork") ca := client.Doc("States/California") writeResults, err := client.Batch(). Create(ny, State{Capital: "Albany", Population: 19.8}). Set(ca, State{Capital: "Sacramento", Population: 39.14}). Delete(client.Doc("States/WestDakota")). Commit(ctx) if err != nil { // TODO: Handle error. } fmt.Println(writeResults) } func ExampleCollectionRef_Add() { ctx := context.Background() client, err := firestore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } defer client.Close() doc, wr, err := client.Collection("Users").Add(ctx, map[string]interface{}{ "name": "Alice", "email": "aj@example.com", }) if err != nil { // TODO: Handle error. } fmt.Println(doc, wr) } func ExampleCollectionRef_Doc() { ctx := context.Background() client, err := firestore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } defer client.Close() fl := client.Collection("States").Doc("Florida") ta := client.Collection("States").Doc("Florida/Cities/Tampa") fmt.Println(fl, ta) } func ExampleCollectionRef_NewDoc() { ctx := context.Background() client, err := firestore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } defer client.Close() doc := client.Collection("Users").NewDoc() fmt.Println(doc) } func ExampleDocumentRef_Collection() { ctx := context.Background() client, err := firestore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } defer client.Close() mi := client.Collection("States").Doc("Michigan") cities := mi.Collection("Cities") fmt.Println(cities) } func ExampleDocumentRef_Create_map() { ctx := context.Background() client, err := firestore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } defer client.Close() wr, err := client.Doc("States/Colorado").Create(ctx, map[string]interface{}{ "capital": "Denver", "pop": 5.5, }) if err != nil { // TODO: Handle error. } fmt.Println(wr.UpdateTime) } func ExampleDocumentRef_Create_struct() { ctx := context.Background() client, err := firestore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } defer client.Close() type State struct { Capital string `firestore:"capital"` Population float64 `firestore:"pop"` // in millions } wr, err := client.Doc("States/Colorado").Create(ctx, State{ Capital: "Denver", Population: 5.5, }) if err != nil { // TODO: Handle error. } fmt.Println(wr.UpdateTime) } func ExampleDocumentRef_Set() { ctx := context.Background() client, err := firestore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } defer client.Close() // Overwrite the document with the given data. Any other fields currently // in the document will be removed. wr, err := client.Doc("States/Alabama").Set(ctx, map[string]interface{}{ "capital": "Montgomery", "pop": 4.9, }) if err != nil { // TODO: Handle error. } fmt.Println(wr.UpdateTime) } func ExampleDocumentRef_Set_merge() { ctx := context.Background() client, err := firestore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } defer client.Close() // Overwrite only the fields in the map; preserve all others. _, err = client.Doc("States/Alabama").Set(ctx, map[string]interface{}{ "pop": 5.2, }, firestore.MergeAll) if err != nil { // TODO: Handle error. } type State struct { Capital string `firestore:"capital"` Population float64 `firestore:"pop"` // in millions } // To do a merging Set with struct data, specify the exact fields to overwrite. // MergeAll is disallowed here, because it would probably be a mistake: the "capital" // field would be overwritten with the empty string. _, err = client.Doc("States/Alabama").Set(ctx, State{Population: 5.2}, firestore.Merge([]string{"pop"})) if err != nil { // TODO: Handle error. } } func ExampleDocumentRef_Update() { ctx := context.Background() client, err := firestore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } defer client.Close() tenn := client.Doc("States/Tennessee") wr, err := tenn.Update(ctx, []firestore.Update{ {Path: "pop", Value: 6.6}, {FieldPath: []string{".", "*", "/"}, Value: "odd"}, }) if err != nil { // TODO: Handle error. } fmt.Println(wr.UpdateTime) } func ExampleDocumentRef_Delete() { ctx := context.Background() client, err := firestore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } defer client.Close() // Oops, Ontario is a Canadian province... if _, err = client.Doc("States/Ontario").Delete(ctx); err != nil { // TODO: Handle error. } } func ExampleDocumentRef_Get() { ctx := context.Background() client, err := firestore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } defer client.Close() docsnap, err := client.Doc("States/Ohio").Get(ctx) if err != nil { // TODO: Handle error. } _ = docsnap // TODO: Use DocumentSnapshot. } func ExampleDocumentRef_Snapshots() { ctx := context.Background() client, err := firestore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } defer client.Close() iter := client.Doc("States/Idaho").Snapshots(ctx) defer iter.Stop() for { docsnap, err := iter.Next() if err != nil { // TODO: Handle error. } _ = docsnap // TODO: Use DocumentSnapshot. } } func ExampleDocumentSnapshot_Data() { ctx := context.Background() client, err := firestore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } defer client.Close() docsnap, err := client.Doc("States/Ohio").Get(ctx) if err != nil { // TODO: Handle error. } ohioMap := docsnap.Data() fmt.Println(ohioMap["capital"]) } func ExampleDocumentSnapshot_DataAt() { ctx := context.Background() client, err := firestore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } defer client.Close() docsnap, err := client.Doc("States/Ohio").Get(ctx) if err != nil { // TODO: Handle error. } cap, err := docsnap.DataAt("capital") if err != nil { // TODO: Handle error. } fmt.Println(cap) } func ExampleDocumentSnapshot_DataAtPath() { ctx := context.Background() client, err := firestore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } defer client.Close() docsnap, err := client.Doc("States/Ohio").Get(ctx) if err != nil { // TODO: Handle error. } pop, err := docsnap.DataAtPath([]string{"capital", "population"}) if err != nil { // TODO: Handle error. } fmt.Println(pop) } func ExampleDocumentSnapshot_DataTo() { ctx := context.Background() client, err := firestore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } defer client.Close() docsnap, err := client.Doc("States/Ohio").Get(ctx) if err != nil { // TODO: Handle error. } type State struct { Capital string `firestore:"capital"` Population float64 `firestore:"pop"` // in millions } var s State if err := docsnap.DataTo(&s); err != nil { // TODO: Handle error. } fmt.Println(s) } func ExampleQuery_Documents() { ctx := context.Background() client, err := firestore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } defer client.Close() q := client.Collection("States").Select("pop"). Where("pop", ">", 10). OrderBy("pop", firestore.Desc). Limit(10) iter1 := q.Documents(ctx) _ = iter1 // TODO: Use iter1. // You can call Documents directly on a CollectionRef as well. iter2 := client.Collection("States").Documents(ctx) _ = iter2 // TODO: Use iter2. } // This example is just like the one above, but illustrates // how to use the XXXPath methods of Query for field paths // that can't be expressed as a dot-separated string. func ExampleQuery_Documents_path_methods() { ctx := context.Background() client, err := firestore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } defer client.Close() q := client.Collection("Unusual").SelectPaths([]string{"*"}, []string{"[~]"}). WherePath([]string{"/"}, ">", 10). OrderByPath([]string{"/"}, firestore.Desc). Limit(10) iter1 := q.Documents(ctx) _ = iter1 // TODO: Use iter1. // You can call Documents directly on a CollectionRef as well. iter2 := client.Collection("States").Documents(ctx) _ = iter2 // TODO: Use iter2. } func ExampleQuery_Snapshots() { ctx := context.Background() client, err := firestore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } defer client.Close() q := client.Collection("States"). Where("pop", ">", 10). OrderBy("pop", firestore.Desc). Limit(10) qsnapIter := q.Snapshots(ctx) // Listen forever for changes to the query's results. for { qsnap, err := qsnapIter.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } fmt.Printf("At %s there were %d results.\n", qsnap.ReadTime, qsnap.Size) _ = qsnap.Documents // TODO: Iterate over the results if desired. _ = qsnap.Changes // TODO: Use the list of incremental changes if desired. } } func ExampleDocumentIterator_Next() { ctx := context.Background() client, err := firestore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } defer client.Close() q := client.Collection("States"). Where("pop", ">", 10). OrderBy("pop", firestore.Desc) iter := q.Documents(ctx) defer iter.Stop() for { doc, err := iter.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } fmt.Println(doc.Data()) } } func ExampleDocumentIterator_GetAll() { ctx := context.Background() client, err := firestore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } defer client.Close() q := client.Collection("States"). Where("pop", ">", 10). OrderBy("pop", firestore.Desc). Limit(10) // a good idea with GetAll, to avoid filling memory docs, err := q.Documents(ctx).GetAll() if err != nil { // TODO: Handle error. } for _, doc := range docs { fmt.Println(doc.Data()) } } func ExampleClient_RunTransaction() { ctx := context.Background() client, err := firestore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } defer client.Close() nm := client.Doc("States/NewMexico") err = client.RunTransaction(ctx, func(ctx context.Context, tx *firestore.Transaction) error { doc, err := tx.Get(nm) // tx.Get, NOT nm.Get! if err != nil { return err } pop, err := doc.DataAt("pop") if err != nil { return err } return tx.Update(nm, []firestore.Update{{Path: "pop", Value: pop.(float64) + 0.2}}) }) if err != nil { // TODO: Handle error. } } func ExampleArrayUnion_create() { ctx := context.Background() client, err := firestore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } defer client.Close() wr, err := client.Doc("States/Colorado").Create(ctx, map[string]interface{}{ "cities": firestore.ArrayUnion("Denver", "Golden", "Boulder"), "pop": 5.5, }) if err != nil { // TODO: Handle error. } fmt.Println(wr.UpdateTime) } func ExampleArrayUnion_update() { ctx := context.Background() client, err := firestore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } defer client.Close() co := client.Doc("States/Colorado") wr, err := co.Update(ctx, []firestore.Update{ {Path: "cities", Value: firestore.ArrayUnion("Broomfield")}, }) if err != nil { // TODO: Handle error. } fmt.Println(wr.UpdateTime) } func ExampleArrayRemove_update() { ctx := context.Background() client, err := firestore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } defer client.Close() co := client.Doc("States/Colorado") wr, err := co.Update(ctx, []firestore.Update{ {Path: "cities", Value: firestore.ArrayRemove("Denver")}, }) if err != nil { // TODO: Handle error. } fmt.Println(wr.UpdateTime) } func ExampleIncrement_create() { ctx := context.Background() client, err := firestore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } defer client.Close() wr, err := client.Doc("States/Colorado").Create(ctx, map[string]interface{}{ "cities": []string{"Denver", "Golden", "Boulder"}, "pop": firestore.Increment(7), // "pop" will be set to 7. }) if err != nil { // TODO: Handle error. } fmt.Println(wr.UpdateTime) } func ExampleIncrement_update() { ctx := context.Background() client, err := firestore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } defer client.Close() co := client.Doc("States/Colorado") wr, err := co.Update(ctx, []firestore.Update{ {Path: "pop", Value: firestore.Increment(7)}, // "pop" will incremented by 7. }) if err != nil { // TODO: Handle error. } fmt.Println(wr.UpdateTime) } func ExampleClient_CollectionGroup() { // Given: // France/Cities/Paris = {population: 100} // Canada/Cities/Montreal = {population: 95} ctx := context.Background() client, err := firestore.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } defer client.Close() // Query for ANY city with >95 pop, regardless of country. docs, err := client.CollectionGroup("Cities"). Where("pop", ">", 95). OrderBy("pop", firestore.Desc). Limit(10). Documents(ctx). GetAll() if err != nil { // TODO: Handle error. } _ = docs // TODO: Use docs. } google-cloud-go-0.49.0/firestore/fieldpath.go000066400000000000000000000156641356504100700210750ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package firestore import ( "bytes" "errors" "fmt" "reflect" "regexp" "sort" "strings" "sync" "cloud.google.com/go/internal/fields" pb "google.golang.org/genproto/googleapis/firestore/v1" ) // A FieldPath is a non-empty sequence of non-empty fields that reference a value. // // A FieldPath value should only be necessary if one of the field names contains // one of the runes ".Ëœ*/[]". Most methods accept a simpler form of field path // as a string in which the individual fields are separated by dots. // For example, // []string{"a", "b"} // is equivalent to the string form // "a.b" // but // []string{"*"} // has no equivalent string form. type FieldPath []string // parseDotSeparatedString constructs a FieldPath from a string that separates // path components with dots. Other than splitting at dots and checking for invalid // characters, it ignores everything else about the string, // including attempts to quote field path compontents. So "a.`b.c`.d" is parsed into // four parts, "a", "`b", "c`" and "d". func parseDotSeparatedString(s string) (FieldPath, error) { const invalidRunes = "~*/[]" if strings.ContainsAny(s, invalidRunes) { return nil, fmt.Errorf("firestore: %q contains an invalid rune (one of %s)", s, invalidRunes) } fp := FieldPath(strings.Split(s, ".")) if err := fp.validate(); err != nil { return nil, err } return fp, nil } func (fp1 FieldPath) equal(fp2 FieldPath) bool { if len(fp1) != len(fp2) { return false } for i, c1 := range fp1 { if c1 != fp2[i] { return false } } return true } func (fp1 FieldPath) prefixOf(fp2 FieldPath) bool { return len(fp1) <= len(fp2) && fp1.equal(fp2[:len(fp1)]) } // Lexicographic ordering. func (fp1 FieldPath) less(fp2 FieldPath) bool { for i := range fp1 { switch { case i >= len(fp2): return false case fp1[i] < fp2[i]: return true case fp1[i] > fp2[i]: return false } } // fp1 and fp2 are equal up to len(fp1). return len(fp1) < len(fp2) } // validate checks the validity of fp and returns an error if it is invalid. func (fp FieldPath) validate() error { if len(fp) == 0 { return errors.New("firestore: empty field path") } for _, c := range fp { if len(c) == 0 { return errors.New("firestore: empty component in field path") } } return nil } // with creates a new FieldPath consisting of fp followed by k. func (fp FieldPath) with(k string) FieldPath { r := make(FieldPath, len(fp), len(fp)+1) copy(r, fp) return append(r, k) } // checkNoDupOrPrefix checks whether any FieldPath is a prefix of (or equal to) // another. // It modifies the order of FieldPaths in its argument (via sorting). func checkNoDupOrPrefix(fps []FieldPath) error { // Sort fps lexicographically. sort.Sort(byPath(fps)) // Check adjacent pairs for prefix. for i := 1; i < len(fps); i++ { if fps[i-1].prefixOf(fps[i]) { return fmt.Errorf("field path %v cannot be used in the same update as %v", fps[i-1], fps[i]) } } return nil } type byPath []FieldPath func (b byPath) Len() int { return len(b) } func (b byPath) Swap(i, j int) { b[i], b[j] = b[j], b[i] } func (b byPath) Less(i, j int) bool { return b[i].less(b[j]) } // setAtPath sets val at the location in m specified by fp, creating sub-maps as // needed. m must not be nil. fp is assumed to be valid. func setAtPath(m map[string]*pb.Value, fp FieldPath, val *pb.Value) { if val == nil { return } if len(fp) == 1 { m[fp[0]] = val } else { v, ok := m[fp[0]] if !ok { v = &pb.Value{ValueType: &pb.Value_MapValue{&pb.MapValue{Fields: map[string]*pb.Value{}}}} m[fp[0]] = v } // The type assertion below cannot fail, because setAtPath is only called // with either an empty map or one filled by setAtPath itself, and the // set of FieldPaths it is called with has been checked to make sure that // no path is the prefix of any other. setAtPath(v.GetMapValue().Fields, fp[1:], val) } } // getAtPath gets the value in data referred to by fp. The data argument can // be a map or a struct. // Compare with valueAtPath, which does the same thing for a document. func getAtPath(v reflect.Value, fp FieldPath) (interface{}, error) { var err error for _, k := range fp { v, err = getAtField(v, k) if err != nil { return nil, err } } return v.Interface(), nil } // getAtField returns the equivalent of v[k], if v is a map, or v.k if v is a struct. func getAtField(v reflect.Value, k string) (reflect.Value, error) { switch v.Kind() { case reflect.Map: if r := v.MapIndex(reflect.ValueOf(k)); r.IsValid() { return r, nil } case reflect.Struct: fm, err := fieldMap(v.Type()) if err != nil { return reflect.Value{}, err } if f, ok := fm[k]; ok { return v.FieldByIndex(f.Index), nil } case reflect.Interface: return getAtField(v.Elem(), k) case reflect.Ptr: return getAtField(v.Elem(), k) } return reflect.Value{}, fmt.Errorf("firestore: no field %q for value %#v", k, v) } // fieldMapCache holds maps from from Firestore field name to struct field, // keyed by struct type. var fieldMapCache sync.Map func fieldMap(t reflect.Type) (map[string]fields.Field, error) { x, ok := fieldMapCache.Load(t) if !ok { fieldList, err := fieldCache.Fields(t) if err != nil { x = err } else { m := map[string]fields.Field{} for _, f := range fieldList { m[f.Name] = f } x = m } fieldMapCache.Store(t, x) } if err, ok := x.(error); ok { return nil, err } return x.(map[string]fields.Field), nil } // toServiceFieldPath converts fp the form required by the Firestore service. // It assumes fp has been validated. func (fp FieldPath) toServiceFieldPath() string { cs := make([]string, len(fp)) for i, c := range fp { cs[i] = toServiceFieldPathComponent(c) } return strings.Join(cs, ".") } func toServiceFieldPaths(fps []FieldPath) []string { var sfps []string for _, fp := range fps { sfps = append(sfps, fp.toServiceFieldPath()) } return sfps } // Google SQL syntax for an unquoted field. var unquotedFieldRegexp = regexp.MustCompile("^[A-Za-z_][A-Za-z_0-9]*$") // toServiceFieldPathComponent returns a string that represents key and is a valid // field path component. func toServiceFieldPathComponent(key string) string { if unquotedFieldRegexp.MatchString(key) { return key } var buf bytes.Buffer buf.WriteRune('`') for _, r := range key { if r == '`' || r == '\\' { buf.WriteRune('\\') } buf.WriteRune(r) } buf.WriteRune('`') return buf.String() } google-cloud-go-0.49.0/firestore/fieldpath_test.go000066400000000000000000000117521356504100700221260ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package firestore import ( "reflect" "strings" "testing" "cloud.google.com/go/internal/testutil" ) func TestFieldPathValidate(t *testing.T) { for _, in := range [][]string{nil, {}, {"a", "", "b"}} { if err := FieldPath(in).validate(); err == nil { t.Errorf("%v: want error, got nil", in) } } } func TestFieldPathLess(t *testing.T) { for _, test := range []struct { in1, in2 string want bool }{ {"a b", "a b", false}, {"a", "b", true}, {"b", "a", false}, {"a", "a b", true}, {"a b", "a", false}, {"a b c", "a b d", true}, {"a b d", "a b c", false}, } { fp1 := FieldPath(strings.Fields(test.in1)) fp2 := FieldPath(strings.Fields(test.in2)) got := fp1.less(fp2) if got != test.want { t.Errorf("%q.less(%q): got %t, want %t", test.in1, test.in2, got, test.want) } } } func TestCheckForPrefix(t *testing.T) { for _, test := range []struct { in []string // field paths as space-separated strings wantErr bool }{ {in: []string{"a", "b", "c"}, wantErr: false}, {in: []string{"a b", "b", "c d"}, wantErr: false}, {in: []string{"a b", "a c", "a d"}, wantErr: false}, {in: []string{"a b", "b", "b d"}, wantErr: true}, {in: []string{"a b", "b", "b d"}, wantErr: true}, {in: []string{"b c d", "c d", "b c"}, wantErr: true}, } { var fps []FieldPath for _, s := range test.in { fps = append(fps, strings.Fields(s)) } err := checkNoDupOrPrefix(fps) if got, want := (err != nil), test.wantErr; got != want { t.Errorf("%#v: got '%v', want %t", test.in, err, want) } } } func TestGetAtPath(t *testing.T) { type S struct { X int Y int `firestore:"y"` M map[string]interface{} Next *S } const fail = "ERROR" // value for expected error for _, test := range []struct { val interface{} fp FieldPath want interface{} }{ { val: map[string]int(nil), fp: nil, want: map[string]int(nil), }, { val: 1, fp: nil, want: 1, }, { val: 1, fp: []string{"a"}, want: fail, }, { val: map[string]int{"a": 2}, fp: []string{"a"}, want: 2, }, { val: map[string]int{"a": 2}, fp: []string{"b"}, want: fail, }, { val: map[string]interface{}{"a": map[string]int{"b": 3}}, fp: []string{"a", "b"}, want: 3, }, { val: map[string]interface{}{"a": map[string]int{"b": 3}}, fp: []string{"a", "b", "c"}, want: fail, }, { val: S{X: 1, Y: 2}, fp: nil, want: S{X: 1, Y: 2}, }, { val: S{X: 1, Y: 2}, fp: []string{"X"}, want: 1, }, { val: S{X: 1, Y: 2}, fp: []string{"Y"}, want: fail, // because Y is tagged with name "y" }, { val: S{X: 1, Y: 2}, fp: []string{"y"}, want: 2, }, { val: &S{X: 1}, fp: []string{"X"}, want: 1, }, { val: &S{X: 1, Next: nil}, fp: []string{"Next"}, want: (*S)(nil), }, { val: &S{X: 1, Next: nil}, fp: []string{"Next", "Next"}, want: fail, }, { val: map[string]S{"a": {X: 1, Y: 2}}, fp: []string{"a", "y"}, want: 2, }, { val: map[string]S{"a": {X: 1, Y: 2}}, fp: []string{"a", "z"}, want: fail, }, { val: map[string]*S{ "a": { M: map[string]interface{}{ "b": S{ Next: &S{ X: 17, }, }, }, }, }, fp: []string{"a", "M", "b", "Next", "X"}, want: 17, }, } { got, err := getAtPath(reflect.ValueOf(test.val), test.fp) if err != nil && test.want != fail { t.Errorf("%+v: got error <%v>, want nil", test, err) } if err == nil && !testutil.Equal(got, test.want) { t.Errorf("%+v: got %v, want %v, want nil", test, got, test.want) } } } func TestToServiceFieldPath(t *testing.T) { for _, test := range []struct { in FieldPath want string }{ {[]string{"a"}, "a"}, {[]string{"a", "b"}, "a.b"}, {[]string{"a.", "[b*", "c2"}, "`a.`.`[b*`.c2"}, {[]string{"`a", `b\`}, "`\\`a`.`b\\\\`"}, } { got := test.in.toServiceFieldPath() if got != test.want { t.Errorf("%v: got %s, want %s", test.in, got, test.want) } } } func TestToServiceFieldPathComponent(t *testing.T) { for _, test := range []struct { in, want string }{ {"", "``"}, {"clam_chowder23", "clam_chowder23"}, {"23skidoo", "`23skidoo`"}, {"bak`tik", "`bak\\`tik`"}, {"a\\b", "`a\\\\b`"}, {"dots.are.confusing", "`dots.are.confusing`"}, } { got := toServiceFieldPathComponent(test.in) if got != test.want { t.Errorf("%q: got %q, want %q", test.in, got, test.want) } } } google-cloud-go-0.49.0/firestore/from_value.go000066400000000000000000000254411356504100700212660ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package firestore import ( "errors" "fmt" "reflect" "strings" "github.com/golang/protobuf/ptypes" pb "google.golang.org/genproto/googleapis/firestore/v1" ) func setFromProtoValue(x interface{}, vproto *pb.Value, c *Client) error { v := reflect.ValueOf(x) if v.Kind() != reflect.Ptr || v.IsNil() { return errors.New("firestore: nil or not a pointer") } return setReflectFromProtoValue(v.Elem(), vproto, c) } // setReflectFromProtoValue sets v from a Firestore Value. // v must be a settable value. func setReflectFromProtoValue(v reflect.Value, vproto *pb.Value, c *Client) error { typeErr := func() error { return fmt.Errorf("firestore: cannot set type %s to %s", v.Type(), typeString(vproto)) } val := vproto.ValueType // A Null value sets anything nullable to nil, and has no effect // on anything else. if _, ok := val.(*pb.Value_NullValue); ok { switch v.Kind() { case reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice: v.Set(reflect.Zero(v.Type())) } return nil } // Handle special types first. switch v.Type() { case typeOfByteSlice: x, ok := val.(*pb.Value_BytesValue) if !ok { return typeErr() } v.SetBytes(x.BytesValue) return nil case typeOfGoTime: x, ok := val.(*pb.Value_TimestampValue) if !ok { return typeErr() } t, err := ptypes.Timestamp(x.TimestampValue) if err != nil { return err } v.Set(reflect.ValueOf(t)) return nil case typeOfProtoTimestamp: x, ok := val.(*pb.Value_TimestampValue) if !ok { return typeErr() } v.Set(reflect.ValueOf(x.TimestampValue)) return nil case typeOfLatLng: x, ok := val.(*pb.Value_GeoPointValue) if !ok { return typeErr() } v.Set(reflect.ValueOf(x.GeoPointValue)) return nil case typeOfDocumentRef: x, ok := val.(*pb.Value_ReferenceValue) if !ok { return typeErr() } dr, err := pathToDoc(x.ReferenceValue, c) if err != nil { return err } v.Set(reflect.ValueOf(dr)) return nil } switch v.Kind() { case reflect.Bool: x, ok := val.(*pb.Value_BooleanValue) if !ok { return typeErr() } v.SetBool(x.BooleanValue) case reflect.String: x, ok := val.(*pb.Value_StringValue) if !ok { return typeErr() } v.SetString(x.StringValue) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: var i int64 switch x := val.(type) { case *pb.Value_IntegerValue: i = x.IntegerValue case *pb.Value_DoubleValue: f := x.DoubleValue i = int64(f) if float64(i) != f { return fmt.Errorf("firestore: float %f does not fit into %s", f, v.Type()) } default: return typeErr() } if v.OverflowInt(i) { return overflowErr(v, i) } v.SetInt(i) case reflect.Uint8, reflect.Uint16, reflect.Uint32: var u uint64 switch x := val.(type) { case *pb.Value_IntegerValue: u = uint64(x.IntegerValue) case *pb.Value_DoubleValue: f := x.DoubleValue u = uint64(f) if float64(u) != f { return fmt.Errorf("firestore: float %f does not fit into %s", f, v.Type()) } default: return typeErr() } if v.OverflowUint(u) { return overflowErr(v, u) } v.SetUint(u) case reflect.Float32, reflect.Float64: var f float64 switch x := val.(type) { case *pb.Value_DoubleValue: f = x.DoubleValue case *pb.Value_IntegerValue: f = float64(x.IntegerValue) if int64(f) != x.IntegerValue { return overflowErr(v, x.IntegerValue) } default: return typeErr() } if v.OverflowFloat(f) { return overflowErr(v, f) } v.SetFloat(f) case reflect.Slice: x, ok := val.(*pb.Value_ArrayValue) if !ok { return typeErr() } vals := x.ArrayValue.Values vlen := v.Len() xlen := len(vals) // Make a slice of the right size, avoiding allocation if possible. switch { case vlen < xlen: v.Set(reflect.MakeSlice(v.Type(), xlen, xlen)) case vlen > xlen: v.SetLen(xlen) } return populateRepeated(v, vals, xlen, c) case reflect.Array: x, ok := val.(*pb.Value_ArrayValue) if !ok { return typeErr() } vals := x.ArrayValue.Values xlen := len(vals) vlen := v.Len() minlen := vlen // Set extra elements to their zero value. if vlen > xlen { z := reflect.Zero(v.Type().Elem()) for i := xlen; i < vlen; i++ { v.Index(i).Set(z) } minlen = xlen } return populateRepeated(v, vals, minlen, c) case reflect.Map: x, ok := val.(*pb.Value_MapValue) if !ok { return typeErr() } return populateMap(v, x.MapValue.Fields, c) case reflect.Ptr: // If the pointer is nil, set it to a zero value. if v.IsNil() { v.Set(reflect.New(v.Type().Elem())) } return setReflectFromProtoValue(v.Elem(), vproto, c) case reflect.Struct: x, ok := val.(*pb.Value_MapValue) if !ok { return typeErr() } return populateStruct(v, x.MapValue.Fields, c) case reflect.Interface: if v.NumMethod() == 0 { // empty interface // If v holds a pointer, set the pointer. if !v.IsNil() && v.Elem().Kind() == reflect.Ptr { return setReflectFromProtoValue(v.Elem(), vproto, c) } // Otherwise, create a fresh value. x, err := createFromProtoValue(vproto, c) if err != nil { return err } v.Set(reflect.ValueOf(x)) return nil } // Any other kind of interface is an error. fallthrough default: return fmt.Errorf("firestore: cannot set type %s", v.Type()) } return nil } // populateRepeated sets the first n elements of vr, which must be a slice or // array, to the corresponding elements of vals. func populateRepeated(vr reflect.Value, vals []*pb.Value, n int, c *Client) error { for i := 0; i < n; i++ { if err := setReflectFromProtoValue(vr.Index(i), vals[i], c); err != nil { return err } } return nil } // populateMap sets the elements of vm, which must be a map, from the // corresponding elements of pm. // // Since a map value is not settable, this function always creates a new // element for each corresponding map key. Existing values of vm are // overwritten. This happens even if the map value is something like a pointer // to a struct, where we could in theory populate the existing struct value // instead of discarding it. This behavior matches encoding/json. func populateMap(vm reflect.Value, pm map[string]*pb.Value, c *Client) error { t := vm.Type() if t.Key().Kind() != reflect.String { return errors.New("firestore: map key type is not string") } if vm.IsNil() { vm.Set(reflect.MakeMap(t)) } et := t.Elem() for k, vproto := range pm { el := reflect.New(et).Elem() if err := setReflectFromProtoValue(el, vproto, c); err != nil { return err } vm.SetMapIndex(reflect.ValueOf(k), el) } return nil } // createMapFromValueMap creates a fresh map and populates it with pm. func createMapFromValueMap(pm map[string]*pb.Value, c *Client) (map[string]interface{}, error) { m := map[string]interface{}{} for k, pv := range pm { v, err := createFromProtoValue(pv, c) if err != nil { return nil, err } m[k] = v } return m, nil } // populateStruct sets the fields of vs, which must be a struct, from // the matching elements of pm. func populateStruct(vs reflect.Value, pm map[string]*pb.Value, c *Client) error { fields, err := fieldCache.Fields(vs.Type()) if err != nil { return err } for k, vproto := range pm { f := fields.Match(k) if f == nil { continue } if err := setReflectFromProtoValue(vs.FieldByIndex(f.Index), vproto, c); err != nil { return fmt.Errorf("%s.%s: %v", vs.Type(), f.Name, err) } } return nil } func createFromProtoValue(vproto *pb.Value, c *Client) (interface{}, error) { switch v := vproto.ValueType.(type) { case *pb.Value_NullValue: return nil, nil case *pb.Value_BooleanValue: return v.BooleanValue, nil case *pb.Value_IntegerValue: return v.IntegerValue, nil case *pb.Value_DoubleValue: return v.DoubleValue, nil case *pb.Value_TimestampValue: return ptypes.Timestamp(v.TimestampValue) case *pb.Value_StringValue: return v.StringValue, nil case *pb.Value_BytesValue: return v.BytesValue, nil case *pb.Value_ReferenceValue: return pathToDoc(v.ReferenceValue, c) case *pb.Value_GeoPointValue: return v.GeoPointValue, nil case *pb.Value_ArrayValue: vals := v.ArrayValue.Values ret := make([]interface{}, len(vals)) for i, v := range vals { r, err := createFromProtoValue(v, c) if err != nil { return nil, err } ret[i] = r } return ret, nil case *pb.Value_MapValue: fields := v.MapValue.Fields ret := make(map[string]interface{}, len(fields)) for k, v := range fields { r, err := createFromProtoValue(v, c) if err != nil { return nil, err } ret[k] = r } return ret, nil default: return nil, fmt.Errorf("firestore: unknown value type %T", v) } } // Convert a document path to a DocumentRef. func pathToDoc(docPath string, c *Client) (*DocumentRef, error) { projID, dbID, docIDs, err := parseDocumentPath(docPath) if err != nil { return nil, err } parentResourceName := fmt.Sprintf("projects/%s/databases/%s", projID, dbID) _, doc := c.idsToRef(docIDs, parentResourceName) return doc, nil } // A document path should be of the form "projects/P/databases/D/documents/coll1/doc1/coll2/doc2/...". func parseDocumentPath(path string) (projectID, databaseID string, docPath []string, err error) { parts := strings.Split(path, "/") if len(parts) < 6 || parts[0] != "projects" || parts[2] != "databases" || parts[4] != "documents" { return "", "", nil, fmt.Errorf("firestore: malformed document path %q", path) } docp := parts[5:] if len(docp)%2 != 0 { return "", "", nil, fmt.Errorf("firestore: path %q refers to collection, not document", path) } return parts[1], parts[3], docp, nil } func typeString(vproto *pb.Value) string { switch vproto.ValueType.(type) { case *pb.Value_NullValue: return "null" case *pb.Value_BooleanValue: return "bool" case *pb.Value_IntegerValue: return "int" case *pb.Value_DoubleValue: return "float" case *pb.Value_TimestampValue: return "timestamp" case *pb.Value_StringValue: return "string" case *pb.Value_BytesValue: return "bytes" case *pb.Value_ReferenceValue: return "reference" case *pb.Value_GeoPointValue: return "GeoPoint" case *pb.Value_MapValue: return "map" case *pb.Value_ArrayValue: return "array" default: return "" } } func overflowErr(v reflect.Value, x interface{}) error { return fmt.Errorf("firestore: value %v overflows type %s", x, v.Type()) } google-cloud-go-0.49.0/firestore/from_value_test.go000066400000000000000000000402351356504100700223230ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package firestore import ( "encoding/json" "fmt" "io" "math" "reflect" "strings" "testing" "time" ts "github.com/golang/protobuf/ptypes/timestamp" pb "google.golang.org/genproto/googleapis/firestore/v1" "google.golang.org/genproto/googleapis/type/latlng" ) var ( tm = time.Date(2016, 12, 25, 0, 0, 0, 123456789, time.UTC) ll = &latlng.LatLng{Latitude: 20, Longitude: 30} ptm = &ts.Timestamp{Seconds: 12345, Nanos: 67890} ) func TestCreateFromProtoValue(t *testing.T) { for _, test := range []struct { in *pb.Value want interface{} }{ {in: nullValue, want: nil}, {in: boolval(true), want: true}, {in: intval(3), want: int64(3)}, {in: floatval(1.5), want: 1.5}, {in: strval("str"), want: "str"}, {in: tsval(tm), want: tm}, { in: bytesval([]byte{1, 2}), want: []byte{1, 2}, }, { in: &pb.Value{ValueType: &pb.Value_GeoPointValue{ll}}, want: ll, }, { in: arrayval(intval(1), intval(2)), want: []interface{}{int64(1), int64(2)}, }, { in: arrayval(), want: []interface{}{}, }, { in: mapval(map[string]*pb.Value{"a": intval(1), "b": intval(2)}), want: map[string]interface{}{"a": int64(1), "b": int64(2)}, }, { in: mapval(map[string]*pb.Value{}), want: map[string]interface{}{}, }, { in: refval("projects/P/databases/D/documents/c/d"), want: &DocumentRef{ ID: "d", Path: "projects/P/databases/D/documents/c/d", shortPath: "c/d", Parent: &CollectionRef{ ID: "c", parentPath: "projects/P/databases/D/documents", selfPath: "c", Path: "projects/P/databases/D/documents/c", Query: Query{ collectionID: "c", parentPath: "projects/P/databases/D/documents", path: "projects/P/databases/D/documents/c", }, }, }, }, } { got, err := createFromProtoValue(test.in, nil) if err != nil { t.Errorf("%+v: %+v", test.in, err) continue } if !testEqual(got, test.want) { t.Errorf("%+v:\ngot\n%#v\nwant\n%#v", test.in, got, test.want) } } } func TestSetFromProtoValue(t *testing.T) { testSetFromProtoValue(t, "json", jsonTester{}) testSetFromProtoValue(t, "firestore", protoTester{}) } func testSetFromProtoValue(t *testing.T, prefix string, r tester) { pi := newfloat(7) s := []float64{7, 8} ar1 := [1]float64{7} ar2 := [2]float64{7, 8} ar3 := [3]float64{7, 8, 9} mf := map[string]float64{"a": 7} type T struct { I **float64 J float64 } one := newfloat(1) six := newfloat(6) st := []*T{{I: &six}, nil, {I: &six, J: 7}} vs := interface{}(T{J: 1}) vm := interface{}(map[string]float64{"i": 1}) var ( i int i8 int8 i16 int16 i32 int32 i64 int64 u8 uint8 u16 uint16 u32 uint32 b bool ll *latlng.LatLng mi map[string]interface{} ms map[string]T ) for i, test := range []struct { in interface{} val interface{} want interface{} }{ {&pi, r.Null(), (*float64)(nil)}, {pi, r.Float(1), 1.0}, {&s, r.Null(), ([]float64)(nil)}, {&s, r.Array(r.Float(1), r.Float(2)), []float64{1, 2}}, {&ar1, r.Array(r.Float(1), r.Float(2)), [1]float64{1}}, {&ar2, r.Array(r.Float(1), r.Float(2)), [2]float64{1, 2}}, {&ar3, r.Array(r.Float(1), r.Float(2)), [3]float64{1, 2, 0}}, {&mf, r.Null(), (map[string]float64)(nil)}, {&mf, r.Map("a", r.Float(1), "b", r.Float(2)), map[string]float64{"a": 1, "b": 2}}, {&st, r.Array( r.Null(), // overwrites st[0] with nil r.Map("i", r.Float(1)), // sets st[1] to a new struct r.Map("i", r.Float(2)), // modifies st[2] ), []*T{nil, {I: &one}, {I: &six, J: 7}}}, {&mi, r.Map("a", r.Float(1), "b", r.Float(2)), map[string]interface{}{"a": 1.0, "b": 2.0}}, {&ms, r.Map("a", r.Map("j", r.Float(1))), map[string]T{"a": {J: 1}}}, {&vs, r.Map("i", r.Float(2)), map[string]interface{}{"i": 2.0}}, {&vm, r.Map("i", r.Float(2)), map[string]interface{}{"i": 2.0}}, {&ll, r.Null(), (*latlng.LatLng)(nil)}, {&i, r.Int(1), int(1)}, {&i8, r.Int(1), int8(1)}, {&i16, r.Int(1), int16(1)}, {&i32, r.Int(1), int32(1)}, {&i64, r.Int(1), int64(1)}, {&u8, r.Int(1), uint8(1)}, {&u16, r.Int(1), uint16(1)}, {&u32, r.Int(1), uint32(1)}, {&b, r.Bool(true), true}, {&i, r.Float(1), int(1)}, // can put a float with no fractional part into an int {pi, r.Int(1), float64(1)}, // can put an int into a float } { if err := r.Set(test.in, test.val); err != nil { t.Errorf("%s: #%d: got error %v", prefix, i, err) continue } got := reflect.ValueOf(test.in).Elem().Interface() if !testEqual(got, test.want) { t.Errorf("%s: #%d, %v:\ngot\n%+v (%T)\nwant\n%+v (%T)", prefix, i, test.val, got, got, test.want, test.want) } } } func TestSetFromProtoValueNoJSON(t *testing.T) { // Test code paths that we cannot compare to JSON. var ( bs []byte tmi time.Time lli *latlng.LatLng tmp *ts.Timestamp ) bytes := []byte{1, 2, 3} for i, test := range []struct { in interface{} val *pb.Value want interface{} }{ {&bs, bytesval(bytes), bytes}, {&tmi, tsval(tm), tm}, {&tmp, &pb.Value{ValueType: &pb.Value_TimestampValue{ptm}}, ptm}, {&lli, geoval(ll), ll}, } { if err := setFromProtoValue(test.in, test.val, &Client{}); err != nil { t.Errorf("#%d: got error %v", i, err) continue } got := reflect.ValueOf(test.in).Elem().Interface() if !testEqual(got, test.want) { t.Errorf("#%d, %v:\ngot\n%+v (%T)\nwant\n%+v (%T)", i, test.val, got, got, test.want, test.want) } } } func TestSetFromProtoValueErrors(t *testing.T) { c := &Client{} ival := intval(3) for i, test := range []struct { in interface{} val *pb.Value }{ {3, ival}, // not a pointer {new(int8), intval(128)}, // int overflow {new(uint8), intval(256)}, // uint overflow {new(float32), floatval(2 * math.MaxFloat32)}, // float overflow {new(uint), ival}, // cannot set type {new(uint64), ival}, // cannot set type {new(io.Reader), ival}, // cannot set type {new(map[int]int), mapval(map[string]*pb.Value{"x": ival})}, // map key type is not string // the rest are all type mismatches {new(bool), ival}, {new(*latlng.LatLng), ival}, {new(time.Time), ival}, {new(string), ival}, {new([]byte), ival}, {new([]int), ival}, {new([1]int), ival}, {new(map[string]int), ival}, {new(*bool), ival}, {new(struct{}), ival}, {new(int), floatval(2.5)}, // float must be integral {new(uint16), intval(-1)}, // uint cannot be negative {new(int16), floatval(math.MaxFloat32)}, // doesn't fit {new(uint16), floatval(math.MaxFloat32)}, // doesn't fit {new(float32), &pb.Value{ValueType: &pb.Value_IntegerValue{math.MaxInt64}}}, // overflow } { err := setFromProtoValue(test.in, test.val, c) if err == nil { t.Errorf("#%d: %v, %v: got nil, want error", i, test.in, test.val) } } } func TestSetFromProtoValuePointers(t *testing.T) { // Verify that pointers are set, instead of being replaced. // Confirm that the behavior matches encoding/json. testSetPointer(t, "json", jsonTester{}) testSetPointer(t, "firestore", protoTester{&Client{}}) } func testSetPointer(t *testing.T, prefix string, r tester) { // If an interface{} holds a pointer, the pointer is set. set := func(x, val interface{}) { if err := r.Set(x, val); err != nil { t.Fatalf("%s: set(%v, %v): %v", prefix, x, val, err) } } p := new(float64) var st struct { I interface{} } // A pointer in a slice of interface{} is set. s := []interface{}{p} set(&s, r.Array(r.Float(1))) if s[0] != p { t.Errorf("%s: pointers not identical", prefix) } if *p != 1 { t.Errorf("%s: got %f, want 1", prefix, *p) } // Setting a null will set the pointer to nil. set(&s, r.Array(r.Null())) if got := s[0]; got != nil { t.Errorf("%s: got %v, want null", prefix, got) } // It doesn't matter how deep the pointers nest. p = new(float64) p2 := &p p3 := &p2 s = []interface{}{p3} set(&s, r.Array(r.Float(1))) if s[0] != p3 { t.Errorf("%s: pointers not identical", prefix) } if *p != 1 { t.Errorf("%s: got %f, want 1", prefix, *p) } // A pointer in an interface{} field is set. p = new(float64) st.I = p set(&st, r.Map("i", r.Float(1))) if st.I != p { t.Errorf("%s: pointers not identical", prefix) } if *p != 1 { t.Errorf("%s: got %f, want 1", prefix, *p) } // Setting a null will set the pointer to nil. set(&st, r.Map("i", r.Null())) if got := st.I; got != nil { t.Errorf("%s: got %v, want null", prefix, got) } // A pointer to a slice (instead of to float64) is set. psi := &[]float64{7, 8, 9} st.I = psi set(&st, r.Map("i", r.Array(r.Float(1)))) if st.I != psi { t.Errorf("%s: pointers not identical", prefix) } // The slice itself should be truncated and filled, not replaced. if got, want := cap(*psi), 3; got != want { t.Errorf("cap: got %d, want %d", got, want) } if want := &[]float64{1}; !testEqual(st.I, want) { t.Errorf("got %+v, want %+v", st.I, want) } // A pointer to a map is set. pmf := &map[string]float64{"a": 7, "b": 8} st.I = pmf set(&st, r.Map("i", r.Map("a", r.Float(1)))) if st.I != pmf { t.Errorf("%s: pointers not identical", prefix) } if want := map[string]float64{"a": 1, "b": 8}; !testEqual(*pmf, want) { t.Errorf("%s: got %+v, want %+v", prefix, *pmf, want) } // Maps are different: since the map values aren't addressable, they // are always discarded, even if the map element type is not interface{}. // A map's values are discarded if the value type is a pointer type. p = new(float64) m := map[string]*float64{"i": p} set(&m, r.Map("i", r.Float(1))) if m["i"] == p { t.Errorf("%s: pointers are identical", prefix) } if got, want := *m["i"], 1.0; got != want { t.Errorf("%s: got %v, want %v", prefix, got, want) } // A map's values are discarded if the value type is interface{}. p = new(float64) m2 := map[string]interface{}{"i": p} set(&m2, r.Map("i", r.Float(1))) if m2["i"] == p { t.Errorf("%s: pointers are identical", prefix) } if got, want := m2["i"].(float64), 1.0; got != want { t.Errorf("%s: got %f, want %f", prefix, got, want) } } // An interface for setting and building values, to facilitate comparing firestore deserialization // with encoding/json. type tester interface { Set(x, val interface{}) error Null() interface{} Int(int) interface{} Float(float64) interface{} Bool(bool) interface{} Array(...interface{}) interface{} Map(keysvals ...interface{}) interface{} } type protoTester struct { c *Client } func (p protoTester) Set(x, val interface{}) error { return setFromProtoValue(x, val.(*pb.Value), p.c) } func (protoTester) Null() interface{} { return nullValue } func (protoTester) Int(i int) interface{} { return intval(i) } func (protoTester) Float(f float64) interface{} { return floatval(f) } func (protoTester) Bool(b bool) interface{} { return boolval(b) } func (protoTester) Array(els ...interface{}) interface{} { var s []*pb.Value for _, el := range els { s = append(s, el.(*pb.Value)) } return arrayval(s...) } func (protoTester) Map(keysvals ...interface{}) interface{} { m := map[string]*pb.Value{} for i := 0; i < len(keysvals); i += 2 { m[keysvals[i].(string)] = keysvals[i+1].(*pb.Value) } return mapval(m) } type jsonTester struct{} func (jsonTester) Set(x, val interface{}) error { return json.Unmarshal([]byte(val.(string)), x) } func (jsonTester) Null() interface{} { return "null" } func (jsonTester) Int(i int) interface{} { return fmt.Sprint(i) } func (jsonTester) Float(f float64) interface{} { return fmt.Sprint(f) } func (jsonTester) Bool(b bool) interface{} { if b { return "true" } return "false" } func (jsonTester) Array(els ...interface{}) interface{} { var s []string for _, el := range els { s = append(s, el.(string)) } return "[" + strings.Join(s, ", ") + "]" } func (jsonTester) Map(keysvals ...interface{}) interface{} { var s []string for i := 0; i < len(keysvals); i += 2 { s = append(s, fmt.Sprintf("%q: %v", keysvals[i], keysvals[i+1])) } return "{" + strings.Join(s, ", ") + "}" } func newfloat(f float64) *float64 { p := new(float64) *p = f return p } func TestParseDocumentPath(t *testing.T) { for _, test := range []struct { in string pid, dbid string dpath []string }{ {"projects/foo-bar/databases/db2/documents/c1/d1", "foo-bar", "db2", []string{"c1", "d1"}}, {"projects/P/databases/D/documents/c1/d1/c2/d2", "P", "D", []string{"c1", "d1", "c2", "d2"}}, } { gotPid, gotDbid, gotDpath, err := parseDocumentPath(test.in) if err != nil { t.Fatal(err) } if got, want := gotPid, test.pid; got != want { t.Errorf("project ID: got %q, want %q", got, want) } if got, want := gotDbid, test.dbid; got != want { t.Errorf("db ID: got %q, want %q", got, want) } if got, want := gotDpath, test.dpath; !testEqual(got, want) { t.Errorf("doc path: got %q, want %q", got, want) } } } func TestParseDocumentPathErrors(t *testing.T) { for _, badPath := range []string{ "projects/P/databases/D/documents/c", // collection path "/projects/P/databases/D/documents/c/d", // initial slash "projects/P/databases/D/c/d", // missing "documents" "project/P/database/D/document/c/d", } { // Every prefix of a bad path is also bad. for i := 0; i <= len(badPath); i++ { in := badPath[:i] _, _, _, err := parseDocumentPath(in) if err == nil { t.Errorf("%q: got nil, want error", in) } } } } func TestPathToDoc(t *testing.T) { c := &Client{} path := "projects/P/databases/D/documents/c1/d1/c2/d2" got, err := pathToDoc(path, c) if err != nil { t.Fatal(err) } want := &DocumentRef{ ID: "d2", Path: "projects/P/databases/D/documents/c1/d1/c2/d2", shortPath: "c1/d1/c2/d2", Parent: &CollectionRef{ ID: "c2", parentPath: "projects/P/databases/D/documents/c1/d1", Path: "projects/P/databases/D/documents/c1/d1/c2", selfPath: "c1/d1/c2", c: c, Query: Query{ c: c, collectionID: "c2", parentPath: "projects/P/databases/D/documents/c1/d1", path: "projects/P/databases/D/documents/c1/d1/c2", }, Parent: &DocumentRef{ ID: "d1", Path: "projects/P/databases/D/documents/c1/d1", shortPath: "c1/d1", Parent: &CollectionRef{ ID: "c1", c: c, parentPath: "projects/P/databases/D/documents", Path: "projects/P/databases/D/documents/c1", selfPath: "c1", Parent: nil, Query: Query{ c: c, collectionID: "c1", parentPath: "projects/P/databases/D/documents", path: "projects/P/databases/D/documents/c1", }, }, }, }, } if !testEqual(got, want) { t.Errorf("\ngot %+v\nwant %+v", got, want) t.Logf("\ngot.Parent %+v\nwant.Parent %+v", got.Parent, want.Parent) t.Logf("\ngot.Parent.Query %+v\nwant.Parent.Query %+v", got.Parent.Query, want.Parent.Query) t.Logf("\ngot.Parent.Parent %+v\nwant.Parent.Parent %+v", got.Parent.Parent, want.Parent.Parent) t.Logf("\ngot.Parent.Parent.Parent %+v\nwant.Parent.Parent.Parent %+v", got.Parent.Parent.Parent, want.Parent.Parent.Parent) t.Logf("\ngot.Parent.Parent.Parent.Query %+v\nwant.Parent.Parent.Parent.Query %+v", got.Parent.Parent.Parent.Query, want.Parent.Parent.Parent.Query) } } func TestTypeString(t *testing.T) { for _, test := range []struct { in *pb.Value want string }{ {nullValue, "null"}, {intval(1), "int"}, {floatval(1), "float"}, {boolval(true), "bool"}, {strval(""), "string"}, {tsval(tm), "timestamp"}, {geoval(ll), "GeoPoint"}, {bytesval(nil), "bytes"}, {refval(""), "reference"}, {arrayval(nil), "array"}, {mapval(nil), "map"}, } { got := typeString(test.in) if got != test.want { t.Errorf("%+v: got %q, want %q", test.in, got, test.want) } } } google-cloud-go-0.49.0/firestore/go.mod000066400000000000000000000010701356504100700176760ustar00rootroot00000000000000module cloud.google.com/go/firestore go 1.11 require ( cloud.google.com/go v0.46.3 cloud.google.com/go/storage v1.0.0 // indirect github.com/golang/protobuf v1.3.2 github.com/google/go-cmp v0.3.0 github.com/googleapis/gax-go/v2 v2.0.5 golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136 // indirect golang.org/x/lint v0.0.0-20190930215403-16217165b5de // indirect golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2 // indirect google.golang.org/api v0.14.0 google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9 google.golang.org/grpc v1.21.1 ) google-cloud-go-0.49.0/firestore/go.sum000066400000000000000000000421021356504100700177240ustar00rootroot00000000000000cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3 h1:AVXDdKsrtX33oR9fbCMu/+c1o8Ofjq6Ku/MInaLVg5Y= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go/bigquery v1.0.1 h1:hL+ycaJpVE9M7nLoiXb/Pn10ENE2u+oddxbD8uu0ZVU= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/datastore v1.0.0 h1:Kt+gOPPp2LEPWp8CSfxhsM8ik9CcyE/gYu+0r+RnZvM= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/pubsub v1.0.1 h1:W9tAK3E57P75u0XLLR82LZyw8VpAnhmyTOxW9qzmyj8= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/storage v1.0.0 h1:VV2nUM3wwLLGh9lSABFgZMjInyUbJeaRSE64WuAIQ+4= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024 h1:rBMNdlhTLzJjJSDIjNEXX1Pz3Hmwmz91v+zycvx9PJc= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522 h1:OeRHuibLsmZkFj773W4LcfAGsSxJgfPONhr8cmO+eLA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979 h1:Agxu5KLo8o7Bb634SVDnhIfpTvxmzUwhbYAzBvXt6h4= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136 h1:A1gGSx58LAGVHUUsOf7IiR0u8Xb6W51gRwfDBhkdcaw= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422 h1:QzoH/1pFpZguR8NrRHLcO6jKqfv2zpuSqZLgdm7ZmjI= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac h1:8R1esu+8QioDxo4E4mX6bFztO+dMTM49DNAaWfO5OeY= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0 h1:HyfiK1WMnHj5FXFXatD+Qs1A/xC2Run6RzeW1SyHxpc= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0 h1:Dh6fw+p6FyRl5x/FvNswO1ji0lIGzm3KP8Y9VkS9PTE= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff h1:On1qIo75ByTwFJ4/W2bIqHcwJ9XAqtSWUs8GwRrIhtc= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2 h1:EtTFh6h4SAKemS+CURDMTDIANuduG5zKEXShyy18bGA= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0 h1:jbyannxz0XFD3zdjgrSUsaJbgpH4eTrkdhRChkHPfO8= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.14.0 h1:uMf5uLi4eQMRrMKhCplNik4U4H8Z6C1br3zOtAa/aDE= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51 h1:Ex1mq5jaJof+kRnYi3SlYJ8KKa9Ao3NHyIT5XJ1gF6U= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9 h1:6XzpBoANz1NqMNfDXzc2QmHmbb1vyMsvRfoP5rM+K1I= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1 h1:j6XxA85m/6txkUCHvzlV5f+HBNl/1r5cZ2A/3IEFOO8= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a h1:LJwr7TCTghdatWv40WobzlKXc9c4s8oGa7QKJUtHhWA= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= google-cloud-go-0.49.0/firestore/go_mod_tidy_hack.go000066400000000000000000000016301356504100700224040ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // This file, and the cloud.google.com/go import, won't actually become part of // the resultant binary. // +build modhack package firestore // Necessary for safely adding multi-module repo. See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository import _ "cloud.google.com/go" google-cloud-go-0.49.0/firestore/integration_test.go000066400000000000000000001213621356504100700225100ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package firestore import ( "context" "errors" "flag" "fmt" "log" "math" "os" "path/filepath" "reflect" "runtime" "sort" "testing" "time" "cloud.google.com/go/internal/pretty" "cloud.google.com/go/internal/testutil" "cloud.google.com/go/internal/uid" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "google.golang.org/api/option" "google.golang.org/genproto/googleapis/type/latlng" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) func TestMain(m *testing.M) { initIntegrationTest() status := m.Run() cleanupIntegrationTest() os.Exit(status) } const ( envProjID = "GCLOUD_TESTS_GOLANG_FIRESTORE_PROJECT_ID" envPrivateKey = "GCLOUD_TESTS_GOLANG_FIRESTORE_KEY" ) var ( iClient *Client iColl *CollectionRef collectionIDs = uid.NewSpace("go-integration-test", nil) ) func initIntegrationTest() { flag.Parse() // needed for testing.Short() if testing.Short() { return } ctx := context.Background() testProjectID := os.Getenv(envProjID) if testProjectID == "" { log.Println("Integration tests skipped. See CONTRIBUTING.md for details") return } ts := testutil.TokenSourceEnv(ctx, envPrivateKey, "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/datastore") if ts == nil { log.Fatal("The project key must be set. See CONTRIBUTING.md for details") } wantDBPath := "projects/" + testProjectID + "/databases/(default)" ti := &testutil.HeadersEnforcer{ Checkers: []*testutil.HeaderChecker{ testutil.XGoogClientHeaderChecker, { Key: "google-cloud-resource-prefix", ValuesValidator: func(values ...string) error { if len(values) == 0 { return errors.New("expected non-blank header") } if values[0] != wantDBPath { return fmt.Errorf("resource prefix mismatch; got %q want %q", values[0], wantDBPath) } return nil }, }, }, } copts := append(ti.CallOptions(), option.WithTokenSource(ts)) c, err := NewClient(ctx, testProjectID, copts...) if err != nil { log.Fatalf("NewClient: %v", err) } iClient = c iColl = c.Collection(collectionIDs.New()) refDoc := iColl.NewDoc() integrationTestMap["ref"] = refDoc wantIntegrationTestMap["ref"] = refDoc integrationTestStruct.Ref = refDoc } func cleanupIntegrationTest() { if iClient == nil { return } // TODO(jba): delete everything in integrationColl. iClient.Close() } // integrationClient should be called by integration tests to get a valid client. It will never // return nil. If integrationClient returns, an integration test can proceed without // further checks. func integrationClient(t *testing.T) *Client { if testing.Short() { t.Skip("Integration tests skipped in short mode") } if iClient == nil { t.SkipNow() // log message printed in initIntegrationTest } return iClient } func integrationColl(t *testing.T) *CollectionRef { _ = integrationClient(t) return iColl } type integrationTestStructType struct { Int int Str string Bool bool Float float32 Null interface{} Bytes []byte Time time.Time Geo, NilGeo *latlng.LatLng Ref *DocumentRef } var ( integrationTime = time.Date(2017, 3, 20, 1, 2, 3, 456789, time.UTC) // Firestore times are accurate only to microseconds. wantIntegrationTime = time.Date(2017, 3, 20, 1, 2, 3, 456000, time.UTC) integrationGeo = &latlng.LatLng{Latitude: 30, Longitude: 70} // Use this when writing a doc. integrationTestMap = map[string]interface{}{ "int": 1, "int8": int8(2), "int16": int16(3), "int32": int32(4), "int64": int64(5), "uint8": uint8(6), "uint16": uint16(7), "uint32": uint32(8), "str": "two", "bool": true, "float": 3.14, "null": nil, "bytes": []byte("bytes"), "*": map[string]interface{}{"`": 4}, "time": integrationTime, "geo": integrationGeo, "ref": nil, // populated by initIntegrationTest } // The returned data is slightly different. wantIntegrationTestMap = map[string]interface{}{ "int": int64(1), "int8": int64(2), "int16": int64(3), "int32": int64(4), "int64": int64(5), "uint8": int64(6), "uint16": int64(7), "uint32": int64(8), "str": "two", "bool": true, "float": 3.14, "null": nil, "bytes": []byte("bytes"), "*": map[string]interface{}{"`": int64(4)}, "time": wantIntegrationTime, "geo": integrationGeo, "ref": nil, // populated by initIntegrationTest } integrationTestStruct = integrationTestStructType{ Int: 1, Str: "two", Bool: true, Float: 3.14, Null: nil, Bytes: []byte("bytes"), Time: integrationTime, Geo: integrationGeo, NilGeo: nil, Ref: nil, // populated by initIntegrationTest } ) func TestIntegration_Create(t *testing.T) { ctx := context.Background() doc := integrationColl(t).NewDoc() start := time.Now() h := testHelper{t} wr := h.mustCreate(doc, integrationTestMap) end := time.Now() checkTimeBetween(t, wr.UpdateTime, start, end) _, err := doc.Create(ctx, integrationTestMap) codeEq(t, "Create on a present doc", codes.AlreadyExists, err) // OK to create an empty document. _, err = integrationColl(t).NewDoc().Create(ctx, map[string]interface{}{}) codeEq(t, "Create empty doc", codes.OK, err) } func TestIntegration_Get(t *testing.T) { ctx := context.Background() doc := integrationColl(t).NewDoc() h := testHelper{t} h.mustCreate(doc, integrationTestMap) ds := h.mustGet(doc) if ds.CreateTime != ds.UpdateTime { t.Errorf("create time %s != update time %s", ds.CreateTime, ds.UpdateTime) } got := ds.Data() if want := wantIntegrationTestMap; !testEqual(got, want) { t.Errorf("got\n%v\nwant\n%v", pretty.Value(got), pretty.Value(want)) } doc = integrationColl(t).NewDoc() empty := map[string]interface{}{} h.mustCreate(doc, empty) ds = h.mustGet(doc) if ds.CreateTime != ds.UpdateTime { t.Errorf("create time %s != update time %s", ds.CreateTime, ds.UpdateTime) } if got, want := ds.Data(), empty; !testEqual(got, want) { t.Errorf("got\n%v\nwant\n%v", pretty.Value(got), pretty.Value(want)) } ds, err := integrationColl(t).NewDoc().Get(ctx) codeEq(t, "Get on a missing doc", codes.NotFound, err) if ds == nil || ds.Exists() { t.Error("got nil or existing doc snapshot, want !ds.Exists") } if ds.ReadTime.IsZero() { t.Error("got zero read time") } } func TestIntegration_GetAll(t *testing.T) { type getAll struct{ N int } h := testHelper{t} coll := integrationColl(t) ctx := context.Background() var docRefs []*DocumentRef for i := 0; i < 5; i++ { doc := coll.NewDoc() docRefs = append(docRefs, doc) if i != 3 { h.mustCreate(doc, getAll{N: i}) } } docSnapshots, err := iClient.GetAll(ctx, docRefs) if err != nil { t.Fatal(err) } if got, want := len(docSnapshots), len(docRefs); got != want { t.Fatalf("got %d snapshots, want %d", got, want) } for i, ds := range docSnapshots { if i == 3 { if ds == nil || ds.Exists() { t.Fatal("got nil or existing doc snapshot, want !ds.Exists") } err := ds.DataTo(nil) codeEq(t, "DataTo on a missing doc", codes.NotFound, err) } else { var got getAll if err := ds.DataTo(&got); err != nil { t.Fatal(err) } want := getAll{N: i} if got != want { t.Errorf("%d: got %+v, want %+v", i, got, want) } } if ds.ReadTime.IsZero() { t.Errorf("%d: got zero read time", i) } } } func TestIntegration_Add(t *testing.T) { start := time.Now() _, wr, err := integrationColl(t).Add(context.Background(), integrationTestMap) if err != nil { t.Fatal(err) } end := time.Now() checkTimeBetween(t, wr.UpdateTime, start, end) } func TestIntegration_Set(t *testing.T) { coll := integrationColl(t) h := testHelper{t} ctx := context.Background() // Set Should be able to create a new doc. doc := coll.NewDoc() wr1 := h.mustSet(doc, integrationTestMap) // Calling Set on the doc completely replaces the contents. // The update time should increase. newData := map[string]interface{}{ "str": "change", "x": "1", } wr2 := h.mustSet(doc, newData) if !wr1.UpdateTime.Before(wr2.UpdateTime) { t.Errorf("update time did not increase: old=%s, new=%s", wr1.UpdateTime, wr2.UpdateTime) } ds := h.mustGet(doc) if got := ds.Data(); !testEqual(got, newData) { t.Errorf("got %v, want %v", got, newData) } newData = map[string]interface{}{ "str": "1", "x": "2", "y": "3", } // SetOptions: // Only fields mentioned in the Merge option will be changed. // In this case, "str" will not be changed to "1". wr3, err := doc.Set(ctx, newData, Merge([]string{"x"}, []string{"y"})) if err != nil { t.Fatal(err) } ds = h.mustGet(doc) want := map[string]interface{}{ "str": "change", "x": "2", "y": "3", } if got := ds.Data(); !testEqual(got, want) { t.Errorf("got %v, want %v", got, want) } if !wr2.UpdateTime.Before(wr3.UpdateTime) { t.Errorf("update time did not increase: old=%s, new=%s", wr2.UpdateTime, wr3.UpdateTime) } // Another way to change only x and y is to pass a map with only // those keys, and use MergeAll. wr4, err := doc.Set(ctx, map[string]interface{}{"x": "4", "y": "5"}, MergeAll) if err != nil { t.Fatal(err) } ds = h.mustGet(doc) want = map[string]interface{}{ "str": "change", "x": "4", "y": "5", } if got := ds.Data(); !testEqual(got, want) { t.Errorf("got %v, want %v", got, want) } if !wr3.UpdateTime.Before(wr4.UpdateTime) { t.Errorf("update time did not increase: old=%s, new=%s", wr3.UpdateTime, wr4.UpdateTime) } // use firestore.Delete to delete a field. // TODO(deklerk): We should be able to use mustSet, but then we get a test error. We should investigate this. _, err = doc.Set(ctx, map[string]interface{}{"str": Delete}, MergeAll) if err != nil { t.Fatal(err) } ds = h.mustGet(doc) want = map[string]interface{}{ "x": "4", "y": "5", } if got := ds.Data(); !testEqual(got, want) { t.Errorf("got %v, want %v", got, want) } // Writing an empty doc with MergeAll should create the doc. doc2 := coll.NewDoc() want = map[string]interface{}{} h.mustSet(doc2, want, MergeAll) ds = h.mustGet(doc2) if got := ds.Data(); !testEqual(got, want) { t.Errorf("got %v, want %v", got, want) } } func TestIntegration_Delete(t *testing.T) { ctx := context.Background() doc := integrationColl(t).NewDoc() h := testHelper{t} h.mustCreate(doc, integrationTestMap) h.mustDelete(doc) // Confirm that doc doesn't exist. if _, err := doc.Get(ctx); status.Code(err) != codes.NotFound { t.Fatalf("got error <%v>, want NotFound", err) } er := func(_ *WriteResult, err error) error { return err } codeEq(t, "Delete on a missing doc", codes.OK, er(doc.Delete(ctx))) // TODO(jba): confirm that the server should return InvalidArgument instead of // FailedPrecondition. wr := h.mustCreate(doc, integrationTestMap) codeEq(t, "Delete with wrong LastUpdateTime", codes.FailedPrecondition, er(doc.Delete(ctx, LastUpdateTime(wr.UpdateTime.Add(-time.Millisecond))))) codeEq(t, "Delete with right LastUpdateTime", codes.OK, er(doc.Delete(ctx, LastUpdateTime(wr.UpdateTime)))) } func TestIntegration_Update(t *testing.T) { ctx := context.Background() doc := integrationColl(t).NewDoc() h := testHelper{t} h.mustCreate(doc, integrationTestMap) fpus := []Update{ {Path: "bool", Value: false}, {Path: "time", Value: 17}, {FieldPath: []string{"*", "`"}, Value: 18}, {Path: "null", Value: Delete}, {Path: "noSuchField", Value: Delete}, // deleting a non-existent field is a no-op } wr := h.mustUpdate(doc, fpus) ds := h.mustGet(doc) got := ds.Data() want := copyMap(wantIntegrationTestMap) want["bool"] = false want["time"] = int64(17) want["*"] = map[string]interface{}{"`": int64(18)} delete(want, "null") if !testEqual(got, want) { t.Errorf("got\n%#v\nwant\n%#v", got, want) } er := func(_ *WriteResult, err error) error { return err } codeEq(t, "Update on missing doc", codes.NotFound, er(integrationColl(t).NewDoc().Update(ctx, fpus))) codeEq(t, "Update with wrong LastUpdateTime", codes.FailedPrecondition, er(doc.Update(ctx, fpus, LastUpdateTime(wr.UpdateTime.Add(-time.Millisecond))))) codeEq(t, "Update with right LastUpdateTime", codes.OK, er(doc.Update(ctx, fpus, LastUpdateTime(wr.UpdateTime)))) } func TestIntegration_Collections(t *testing.T) { ctx := context.Background() c := integrationClient(t) h := testHelper{t} got, err := c.Collections(ctx).GetAll() if err != nil { t.Fatal(err) } // There should be at least one collection. if len(got) == 0 { t.Error("got 0 top-level collections, want at least one") } doc := integrationColl(t).NewDoc() got, err = doc.Collections(ctx).GetAll() if err != nil { t.Fatal(err) } if len(got) != 0 { t.Errorf("got %d collections, want 0", len(got)) } var want []*CollectionRef for i := 0; i < 3; i++ { id := collectionIDs.New() cr := doc.Collection(id) want = append(want, cr) h.mustCreate(cr.NewDoc(), integrationTestMap) } got, err = doc.Collections(ctx).GetAll() if err != nil { t.Fatal(err) } if !testEqual(got, want) { t.Errorf("got\n%#v\nwant\n%#v", got, want) } } func TestIntegration_ServerTimestamp(t *testing.T) { type S struct { A int B time.Time C time.Time `firestore:"C.C,serverTimestamp"` D map[string]interface{} E time.Time `firestore:",omitempty,serverTimestamp"` } data := S{ A: 1, B: aTime, // C is unset, so will get the server timestamp. D: map[string]interface{}{"x": ServerTimestamp}, // E is unset, so will get the server timestamp. } h := testHelper{t} doc := integrationColl(t).NewDoc() // Bound times of the RPC, with some slack for clock skew. start := time.Now() h.mustCreate(doc, data) end := time.Now() ds := h.mustGet(doc) var got S if err := ds.DataTo(&got); err != nil { t.Fatal(err) } if !testEqual(got.B, aTime) { t.Errorf("B: got %s, want %s", got.B, aTime) } checkTimeBetween(t, got.C, start, end) if g, w := got.D["x"], got.C; !testEqual(g, w) { t.Errorf(`D["x"] = %s, want equal to C (%s)`, g, w) } if g, w := got.E, got.C; !testEqual(g, w) { t.Errorf(`E = %s, want equal to C (%s)`, g, w) } } func TestIntegration_MergeServerTimestamp(t *testing.T) { doc := integrationColl(t).NewDoc() h := testHelper{t} // Create a doc with an ordinary field "a" and a ServerTimestamp field "b". h.mustSet(doc, map[string]interface{}{"a": 1, "b": ServerTimestamp}) docSnap := h.mustGet(doc) data1 := docSnap.Data() // Merge with a document with a different value of "a". However, // specify only "b" in the list of merge fields. h.mustSet(doc, map[string]interface{}{"a": 2, "b": ServerTimestamp}, Merge([]string{"b"})) // The result should leave "a" unchanged, while "b" is updated. docSnap = h.mustGet(doc) data2 := docSnap.Data() if got, want := data2["a"], data1["a"]; got != want { t.Errorf("got %v, want %v", got, want) } t1 := data1["b"].(time.Time) t2 := data2["b"].(time.Time) if !t1.Before(t2) { t.Errorf("got t1=%s, t2=%s; want t1 before t2", t1, t2) } } func TestIntegration_MergeNestedServerTimestamp(t *testing.T) { doc := integrationColl(t).NewDoc() h := testHelper{t} // Create a doc with an ordinary field "a" a ServerTimestamp field "b", // and a second ServerTimestamp field "c.d". h.mustSet(doc, map[string]interface{}{ "a": 1, "b": ServerTimestamp, "c": map[string]interface{}{"d": ServerTimestamp}, }) data1 := h.mustGet(doc).Data() // Merge with a document with a different value of "a". However, // specify only "c.d" in the list of merge fields. h.mustSet(doc, map[string]interface{}{ "a": 2, "b": ServerTimestamp, "c": map[string]interface{}{"d": ServerTimestamp}, }, Merge([]string{"c", "d"})) // The result should leave "a" and "b" unchanged, while "c.d" is updated. data2 := h.mustGet(doc).Data() if got, want := data2["a"], data1["a"]; got != want { t.Errorf("a: got %v, want %v", got, want) } want := data1["b"].(time.Time) got := data2["b"].(time.Time) if !got.Equal(want) { t.Errorf("b: got %s, want %s", got, want) } t1 := data1["c"].(map[string]interface{})["d"].(time.Time) t2 := data2["c"].(map[string]interface{})["d"].(time.Time) if !t1.Before(t2) { t.Errorf("got t1=%s, t2=%s; want t1 before t2", t1, t2) } } func TestIntegration_WriteBatch(t *testing.T) { ctx := context.Background() b := integrationClient(t).Batch() h := testHelper{t} doc1 := iColl.NewDoc() doc2 := iColl.NewDoc() b.Create(doc1, integrationTestMap) b.Set(doc2, integrationTestMap) b.Update(doc1, []Update{{Path: "bool", Value: false}}) b.Update(doc1, []Update{{Path: "str", Value: Delete}}) wrs, err := b.Commit(ctx) if err != nil { t.Fatal(err) } if got, want := len(wrs), 4; got != want { t.Fatalf("got %d WriteResults, want %d", got, want) } got1 := h.mustGet(doc1).Data() want := copyMap(wantIntegrationTestMap) want["bool"] = false delete(want, "str") if !testEqual(got1, want) { t.Errorf("got\n%#v\nwant\n%#v", got1, want) } got2 := h.mustGet(doc2).Data() if !testEqual(got2, wantIntegrationTestMap) { t.Errorf("got\n%#v\nwant\n%#v", got2, wantIntegrationTestMap) } // TODO(jba): test two updates to the same document when it is supported. // TODO(jba): test verify when it is supported. } func TestIntegration_Query(t *testing.T) { ctx := context.Background() coll := integrationColl(t) h := testHelper{t} var wants []map[string]interface{} for i := 0; i < 3; i++ { doc := coll.NewDoc() // To support running this test in parallel with the others, use a field name // that we don't use anywhere else. h.mustCreate(doc, map[string]interface{}{"q": i, "x": 1}) wants = append(wants, map[string]interface{}{"q": int64(i)}) } q := coll.Select("q").OrderBy("q", Asc) for i, test := range []struct { q Query want []map[string]interface{} }{ {q, wants}, {q.Where("q", ">", 1), wants[2:]}, {q.WherePath([]string{"q"}, ">", 1), wants[2:]}, {q.Offset(1).Limit(1), wants[1:2]}, {q.StartAt(1), wants[1:]}, {q.StartAfter(1), wants[2:]}, {q.EndAt(1), wants[:2]}, {q.EndBefore(1), wants[:1]}, } { gotDocs, err := test.q.Documents(ctx).GetAll() if err != nil { t.Errorf("#%d: %+v: %v", i, test.q, err) continue } if len(gotDocs) != len(test.want) { t.Errorf("#%d: %+v: got %d docs, want %d", i, test.q, len(gotDocs), len(test.want)) continue } for j, g := range gotDocs { if got, want := g.Data(), test.want[j]; !testEqual(got, want) { t.Errorf("#%d: %+v, #%d: got\n%+v\nwant\n%+v", i, test.q, j, got, want) } } } _, err := coll.Select("q").Where("x", "==", 1).OrderBy("q", Asc).Documents(ctx).GetAll() codeEq(t, "Where and OrderBy on different fields without an index", codes.FailedPrecondition, err) // Using the collection itself as the query should return the full documents. allDocs, err := coll.Documents(ctx).GetAll() if err != nil { t.Fatal(err) } seen := map[int64]bool{} // "q" values we see for _, d := range allDocs { data := d.Data() q, ok := data["q"] if !ok { // A document from another test. continue } if seen[q.(int64)] { t.Errorf("%v: duplicate doc", data) } seen[q.(int64)] = true if data["x"] != int64(1) { t.Errorf("%v: wrong or missing 'x'", data) } if len(data) != 2 { t.Errorf("%v: want two keys", data) } } if got, want := len(seen), len(wants); got != want { t.Errorf("got %d docs with 'q', want %d", len(seen), len(wants)) } } // Test unary filters. func TestIntegration_QueryUnary(t *testing.T) { ctx := context.Background() coll := integrationColl(t) h := testHelper{t} h.mustCreate(coll.NewDoc(), map[string]interface{}{"x": 2, "q": "a"}) h.mustCreate(coll.NewDoc(), map[string]interface{}{"x": 2, "q": nil}) h.mustCreate(coll.NewDoc(), map[string]interface{}{"x": 2, "q": math.NaN()}) wantNull := map[string]interface{}{"q": nil} wantNaN := map[string]interface{}{"q": math.NaN()} base := coll.Select("q").Where("x", "==", 2) for _, test := range []struct { q Query want map[string]interface{} }{ {base.Where("q", "==", nil), wantNull}, {base.Where("q", "==", math.NaN()), wantNaN}, } { got, err := test.q.Documents(ctx).GetAll() if err != nil { t.Fatal(err) } if len(got) != 1 { t.Errorf("got %d responses, want 1", len(got)) continue } if g, w := got[0].Data(), test.want; !testEqual(g, w) { t.Errorf("%v: got %v, want %v", test.q, g, w) } } } // Test the special DocumentID field in queries. func TestIntegration_QueryName(t *testing.T) { ctx := context.Background() h := testHelper{t} checkIDs := func(q Query, wantIDs []string) { gots, err := q.Documents(ctx).GetAll() if err != nil { t.Fatal(err) } if len(gots) != len(wantIDs) { t.Fatalf("got %d, want %d", len(gots), len(wantIDs)) } for i, g := range gots { if got, want := g.Ref.ID, wantIDs[i]; got != want { t.Errorf("#%d: got %s, want %s", i, got, want) } } } coll := integrationColl(t) var wantIDs []string for i := 0; i < 3; i++ { doc := coll.NewDoc() h.mustCreate(doc, map[string]interface{}{"nm": 1}) wantIDs = append(wantIDs, doc.ID) } sort.Strings(wantIDs) q := coll.Where("nm", "==", 1).OrderBy(DocumentID, Asc) checkIDs(q, wantIDs) // Empty Select. q = coll.Select().Where("nm", "==", 1).OrderBy(DocumentID, Asc) checkIDs(q, wantIDs) // Test cursors with __name__. checkIDs(q.StartAt(wantIDs[1]), wantIDs[1:]) checkIDs(q.EndAt(wantIDs[1]), wantIDs[:2]) } func TestIntegration_QueryNested(t *testing.T) { ctx := context.Background() h := testHelper{t} coll1 := integrationColl(t) doc1 := coll1.NewDoc() coll2 := doc1.Collection(collectionIDs.New()) doc2 := coll2.NewDoc() wantData := map[string]interface{}{"x": int64(1)} h.mustCreate(doc2, wantData) q := coll2.Select("x") got, err := q.Documents(ctx).GetAll() if err != nil { t.Fatal(err) } if len(got) != 1 { t.Fatalf("got %d docs, want 1", len(got)) } if gotData := got[0].Data(); !testEqual(gotData, wantData) { t.Errorf("got\n%+v\nwant\n%+v", gotData, wantData) } } func TestIntegration_RunTransaction(t *testing.T) { ctx := context.Background() h := testHelper{t} type Player struct { Name string Score int Star bool `firestore:"*"` } pat := Player{Name: "Pat", Score: 3, Star: false} client := integrationClient(t) patDoc := iColl.Doc("pat") var anError error incPat := func(_ context.Context, tx *Transaction) error { doc, err := tx.Get(patDoc) if err != nil { return err } score, err := doc.DataAt("Score") if err != nil { return err } // Since the Star field is called "*", we must use DataAtPath to get it. star, err := doc.DataAtPath([]string{"*"}) if err != nil { return err } err = tx.Update(patDoc, []Update{{Path: "Score", Value: int(score.(int64) + 7)}}) if err != nil { return err } // Since the Star field is called "*", we must use Update to change it. err = tx.Update(patDoc, []Update{{FieldPath: []string{"*"}, Value: !star.(bool)}}) if err != nil { return err } return anError } h.mustCreate(patDoc, pat) err := client.RunTransaction(ctx, incPat) if err != nil { t.Fatal(err) } ds := h.mustGet(patDoc) var got Player if err := ds.DataTo(&got); err != nil { t.Fatal(err) } want := Player{Name: "Pat", Score: 10, Star: true} if got != want { t.Errorf("got %+v, want %+v", got, want) } // Function returns error, so transaction is rolled back and no writes happen. anError = errors.New("bad") err = client.RunTransaction(ctx, incPat) if err != anError { t.Fatalf("got %v, want %v", err, anError) } if err := ds.DataTo(&got); err != nil { t.Fatal(err) } // want is same as before. if got != want { t.Errorf("got %+v, want %+v", got, want) } } func TestIntegration_TransactionGetAll(t *testing.T) { ctx := context.Background() h := testHelper{t} type Player struct { Name string Score int } lee := Player{Name: "Lee", Score: 3} sam := Player{Name: "Sam", Score: 1} client := integrationClient(t) leeDoc := iColl.Doc("lee") samDoc := iColl.Doc("sam") h.mustCreate(leeDoc, lee) h.mustCreate(samDoc, sam) err := client.RunTransaction(ctx, func(_ context.Context, tx *Transaction) error { docs, err := tx.GetAll([]*DocumentRef{samDoc, leeDoc}) if err != nil { return err } for i, want := range []Player{sam, lee} { var got Player if err := docs[i].DataTo(&got); err != nil { return err } if !testutil.Equal(got, want) { return fmt.Errorf("got %+v, want %+v", got, want) } } return nil }) if err != nil { t.Fatal(err) } } func TestIntegration_WatchDocument(t *testing.T) { coll := integrationColl(t) ctx := context.Background() h := testHelper{t} doc := coll.NewDoc() it := doc.Snapshots(ctx) defer it.Stop() next := func() *DocumentSnapshot { snap, err := it.Next() if err != nil { t.Fatal(err) } return snap } snap := next() if snap.Exists() { t.Fatal("snapshot exists; it should not") } want := map[string]interface{}{"a": int64(1), "b": "two"} h.mustCreate(doc, want) snap = next() if got := snap.Data(); !testutil.Equal(got, want) { t.Fatalf("got %v, want %v", got, want) } h.mustUpdate(doc, []Update{{Path: "a", Value: int64(2)}}) want["a"] = int64(2) snap = next() if got := snap.Data(); !testutil.Equal(got, want) { t.Fatalf("got %v, want %v", got, want) } h.mustDelete(doc) snap = next() if snap.Exists() { t.Fatal("snapshot exists; it should not") } h.mustCreate(doc, want) snap = next() if got := snap.Data(); !testutil.Equal(got, want) { t.Fatalf("got %v, want %v", got, want) } } func TestIntegration_ArrayUnion_Create(t *testing.T) { path := "somePath" data := map[string]interface{}{ path: ArrayUnion("a", "b"), } doc := integrationColl(t).NewDoc() h := testHelper{t} h.mustCreate(doc, data) ds := h.mustGet(doc) var gotMap map[string][]string if err := ds.DataTo(&gotMap); err != nil { t.Fatal(err) } if _, ok := gotMap[path]; !ok { t.Fatalf("expected a %v key in data, got %v", path, gotMap) } want := []string{"a", "b"} for i, v := range gotMap[path] { if v != want[i] { t.Fatalf("got\n%#v\nwant\n%#v", gotMap[path], want) } } } func TestIntegration_ArrayUnion_Update(t *testing.T) { doc := integrationColl(t).NewDoc() h := testHelper{t} path := "somePath" h.mustCreate(doc, map[string]interface{}{ path: []string{"a", "b"}, }) fpus := []Update{ { Path: path, Value: ArrayUnion("this should be added"), }, } h.mustUpdate(doc, fpus) ds := h.mustGet(doc) var gotMap map[string][]string if err := ds.DataTo(&gotMap); err != nil { t.Fatal(err) } if _, ok := gotMap[path]; !ok { t.Fatalf("expected a %v key in data, got %v", path, gotMap) } want := []string{"a", "b", "this should be added"} for i, v := range gotMap[path] { if v != want[i] { t.Fatalf("got\n%#v\nwant\n%#v", gotMap[path], want) } } } func TestIntegration_ArrayUnion_Set(t *testing.T) { coll := integrationColl(t) h := testHelper{t} path := "somePath" doc := coll.NewDoc() newData := map[string]interface{}{ path: ArrayUnion("a", "b"), } h.mustSet(doc, newData) ds := h.mustGet(doc) var gotMap map[string][]string if err := ds.DataTo(&gotMap); err != nil { t.Fatal(err) } if _, ok := gotMap[path]; !ok { t.Fatalf("expected a %v key in data, got %v", path, gotMap) } want := []string{"a", "b"} for i, v := range gotMap[path] { if v != want[i] { t.Fatalf("got\n%#v\nwant\n%#v", gotMap[path], want) } } } func TestIntegration_ArrayRemove_Create(t *testing.T) { doc := integrationColl(t).NewDoc() h := testHelper{t} path := "somePath" h.mustCreate(doc, map[string]interface{}{ path: ArrayRemove("a", "b"), }) ds := h.mustGet(doc) var gotMap map[string][]string if err := ds.DataTo(&gotMap); err != nil { t.Fatal(err) } if _, ok := gotMap[path]; !ok { t.Fatalf("expected a %v key in data, got %v", path, gotMap) } // A create with arrayRemove results in an empty array. want := []string(nil) if !testEqual(gotMap[path], want) { t.Fatalf("got\n%#v\nwant\n%#v", gotMap[path], want) } } func TestIntegration_ArrayRemove_Update(t *testing.T) { doc := integrationColl(t).NewDoc() h := testHelper{t} path := "somePath" h.mustCreate(doc, map[string]interface{}{ path: []string{"a", "this should be removed", "c"}, }) fpus := []Update{ { Path: path, Value: ArrayRemove("this should be removed"), }, } h.mustUpdate(doc, fpus) ds := h.mustGet(doc) var gotMap map[string][]string if err := ds.DataTo(&gotMap); err != nil { t.Fatal(err) } if _, ok := gotMap[path]; !ok { t.Fatalf("expected a %v key in data, got %v", path, gotMap) } want := []string{"a", "c"} for i, v := range gotMap[path] { if v != want[i] { t.Fatalf("got\n%#v\nwant\n%#v", gotMap[path], want) } } } func TestIntegration_ArrayRemove_Set(t *testing.T) { coll := integrationColl(t) h := testHelper{t} path := "somePath" doc := coll.NewDoc() newData := map[string]interface{}{ path: ArrayRemove("a", "b"), } h.mustSet(doc, newData) ds := h.mustGet(doc) var gotMap map[string][]string if err := ds.DataTo(&gotMap); err != nil { t.Fatal(err) } if _, ok := gotMap[path]; !ok { t.Fatalf("expected a %v key in data, got %v", path, gotMap) } want := []string(nil) if !testEqual(gotMap[path], want) { t.Fatalf("got\n%#v\nwant\n%#v", gotMap[path], want) } } func TestIntegration_Increment_Create(t *testing.T) { doc := integrationColl(t).NewDoc() h := testHelper{t} path := "somePath" want := 7 h.mustCreate(doc, map[string]interface{}{ path: Increment(want), }) ds := h.mustGet(doc) var gotMap map[string]int if err := ds.DataTo(&gotMap); err != nil { t.Fatal(err) } if _, ok := gotMap[path]; !ok { t.Fatalf("expected a %v key in data, got %v", path, gotMap) } if gotMap[path] != want { t.Fatalf("want %d, got %d", want, gotMap[path]) } } // Also checks that all appropriate types are supported. func TestIntegration_Increment_Update(t *testing.T) { type MyInt = int // Test a custom type. for _, tc := range []struct { // All three should be same type. start interface{} inc interface{} want interface{} wantErr bool }{ {start: int(7), inc: int(4), want: int(11)}, {start: int8(7), inc: int8(4), want: int8(11)}, {start: int16(7), inc: int16(4), want: int16(11)}, {start: int32(7), inc: int32(4), want: int32(11)}, {start: int64(7), inc: int64(4), want: int64(11)}, {start: uint8(7), inc: uint8(4), want: uint8(11)}, {start: uint16(7), inc: uint16(4), want: uint16(11)}, {start: uint32(7), inc: uint32(4), want: uint32(11)}, {start: float32(7.7), inc: float32(4.1), want: float32(11.8)}, {start: float64(7.7), inc: float64(4.1), want: float64(11.8)}, {start: MyInt(7), inc: MyInt(4), want: MyInt(11)}, {start: 7, inc: "strings are not allowed", wantErr: true}, {start: 7, inc: uint(3), wantErr: true}, {start: 7, inc: uint64(3), wantErr: true}, } { typeStr := reflect.TypeOf(tc.inc).String() t.Run(typeStr, func(t *testing.T) { doc := integrationColl(t).NewDoc() h := testHelper{t} path := "somePath" h.mustCreate(doc, map[string]interface{}{ path: tc.start, }) fpus := []Update{ { Path: path, Value: Increment(tc.inc), }, } _, err := doc.Update(context.Background(), fpus) if err != nil { if tc.wantErr { return } h.t.Fatalf("%s: updating: %v", loc(), err) } ds := h.mustGet(doc) var gotMap map[string]interface{} if err := ds.DataTo(&gotMap); err != nil { t.Fatal(err) } switch tc.want.(type) { case int, int8, int16, int32, int64: if _, ok := gotMap[path]; !ok { t.Fatalf("expected a %v key in data, got %v", path, gotMap) } if got, want := reflect.ValueOf(gotMap[path]).Int(), reflect.ValueOf(tc.want).Int(); got != want { t.Fatalf("want %v, got %v", want, got) } case uint8, uint16, uint32: if _, ok := gotMap[path]; !ok { t.Fatalf("expected a %v key in data, got %v", path, gotMap) } if got, want := uint64(reflect.ValueOf(gotMap[path]).Int()), reflect.ValueOf(tc.want).Uint(); got != want { t.Fatalf("want %v, got %v", want, got) } case float32, float64: if _, ok := gotMap[path]; !ok { t.Fatalf("expected a %v key in data, got %v", path, gotMap) } const precision = 1e-6 // Floats are never precisely comparable. if got, want := reflect.ValueOf(gotMap[path]).Float(), reflect.ValueOf(tc.want).Float(); math.Abs(got-want) > precision { t.Fatalf("want %v, got %v", want, got) } default: // Either some unsupported type was added without specifying // wantErr, or a supported type needs to be added to this // switch statement. t.Fatalf("unsupported type %T", tc.want) } }) } } func TestIntegration_Increment_Set(t *testing.T) { coll := integrationColl(t) h := testHelper{t} path := "somePath" want := 9 doc := coll.NewDoc() newData := map[string]interface{}{ path: Increment(want), } h.mustSet(doc, newData) ds := h.mustGet(doc) var gotMap map[string]int if err := ds.DataTo(&gotMap); err != nil { t.Fatal(err) } if _, ok := gotMap[path]; !ok { t.Fatalf("expected a %v key in data, got %v", path, gotMap) } if gotMap[path] != want { t.Fatalf("want %d, got %d", want, gotMap[path]) } } type imap map[string]interface{} func TestIntegration_WatchQuery(t *testing.T) { ctx := context.Background() coll := integrationColl(t) h := testHelper{t} q := coll.Where("e", ">", 1).OrderBy("e", Asc) it := q.Snapshots(ctx) defer it.Stop() next := func() ([]*DocumentSnapshot, []DocumentChange) { qsnap, err := it.Next() if err != nil { t.Fatal(err) } if qsnap.ReadTime.IsZero() { t.Fatal("zero time") } ds, err := qsnap.Documents.GetAll() if err != nil { t.Fatal(err) } if qsnap.Size != len(ds) { t.Fatalf("Size=%d but we have %d docs", qsnap.Size, len(ds)) } return ds, qsnap.Changes } copts := append([]cmp.Option{cmpopts.IgnoreFields(DocumentSnapshot{}, "ReadTime")}, cmpOpts...) check := func(msg string, wantd []*DocumentSnapshot, wantc []DocumentChange) { gotd, gotc := next() if diff := testutil.Diff(gotd, wantd, copts...); diff != "" { t.Errorf("%s: %s", msg, diff) } if diff := testutil.Diff(gotc, wantc, copts...); diff != "" { t.Errorf("%s: %s", msg, diff) } } check("initial", nil, nil) doc1 := coll.NewDoc() h.mustCreate(doc1, imap{"e": int64(2), "b": "two"}) wds := h.mustGet(doc1) check("one", []*DocumentSnapshot{wds}, []DocumentChange{{Kind: DocumentAdded, Doc: wds, OldIndex: -1, NewIndex: 0}}) // Add a doc that does not match. We won't see a snapshot for this. doc2 := coll.NewDoc() h.mustCreate(doc2, imap{"e": int64(1)}) // Update the first doc. We should see the change. We won't see doc2. h.mustUpdate(doc1, []Update{{Path: "e", Value: int64(3)}}) wds = h.mustGet(doc1) check("update", []*DocumentSnapshot{wds}, []DocumentChange{{Kind: DocumentModified, Doc: wds, OldIndex: 0, NewIndex: 0}}) // Now update doc so that it is not in the query. We should see a snapshot with no docs. h.mustUpdate(doc1, []Update{{Path: "e", Value: int64(0)}}) check("update2", nil, []DocumentChange{{Kind: DocumentRemoved, Doc: wds, OldIndex: 0, NewIndex: -1}}) // Add two docs out of order. We should see them in order. doc3 := coll.NewDoc() doc4 := coll.NewDoc() want3 := imap{"e": int64(5)} want4 := imap{"e": int64(4)} h.mustCreate(doc3, want3) h.mustCreate(doc4, want4) wds4 := h.mustGet(doc4) wds3 := h.mustGet(doc3) check("two#1", []*DocumentSnapshot{wds3}, []DocumentChange{{Kind: DocumentAdded, Doc: wds3, OldIndex: -1, NewIndex: 0}}) check("two#2", []*DocumentSnapshot{wds4, wds3}, []DocumentChange{{Kind: DocumentAdded, Doc: wds4, OldIndex: -1, NewIndex: 0}}) // Delete a doc. h.mustDelete(doc4) check("after del", []*DocumentSnapshot{wds3}, []DocumentChange{{Kind: DocumentRemoved, Doc: wds4, OldIndex: 0, NewIndex: -1}}) } func TestIntegration_WatchQueryCancel(t *testing.T) { ctx := context.Background() coll := integrationColl(t) q := coll.Where("e", ">", 1).OrderBy("e", Asc) ctx, cancel := context.WithCancel(ctx) it := q.Snapshots(ctx) defer it.Stop() // First call opens the stream. _, err := it.Next() if err != nil { t.Fatal(err) } cancel() _, err = it.Next() codeEq(t, "after cancel", codes.Canceled, err) } func TestIntegration_MissingDocs(t *testing.T) { ctx := context.Background() h := testHelper{t} client := integrationClient(t) coll := client.Collection(collectionIDs.New()) dr1 := coll.NewDoc() dr2 := coll.NewDoc() dr3 := dr2.Collection("sub").NewDoc() h.mustCreate(dr1, integrationTestMap) defer h.mustDelete(dr1) h.mustCreate(dr3, integrationTestMap) defer h.mustDelete(dr3) // dr1 is a document in coll. dr2 was never created, but there are documents in // its sub-collections. It is "missing". // The Collection.DocumentRefs method includes missing document refs. want := []string{dr1.Path, dr2.Path} drs, err := coll.DocumentRefs(ctx).GetAll() if err != nil { t.Fatal(err) } var got []string for _, dr := range drs { got = append(got, dr.Path) } sort.Strings(want) sort.Strings(got) if !testutil.Equal(got, want) { t.Errorf("got %v, want %v", got, want) } } func TestIntegration_CollectionGroupQueries(t *testing.T) { shouldBeFoundID := collectionIDs.New() shouldNotBeFoundID := collectionIDs.New() ctx := context.Background() h := testHelper{t} client := integrationClient(t) cr1 := client.Collection(shouldBeFoundID) dr1 := cr1.Doc("should-be-found-1") h.mustCreate(dr1, map[string]string{"some-key": "should-be-found"}) defer h.mustDelete(dr1) dr1.Collection(shouldBeFoundID) dr2 := cr1.Doc("should-be-found-2") h.mustCreate(dr2, map[string]string{"some-key": "should-be-found"}) defer h.mustDelete(dr2) cr3 := client.Collection(shouldNotBeFoundID) dr3 := cr3.Doc("should-not-be-found") h.mustCreate(dr3, map[string]string{"some-key": "should-NOT-be-found"}) defer h.mustDelete(dr3) cg := client.CollectionGroup(shouldBeFoundID) snaps, err := cg.Documents(ctx).GetAll() if err != nil { t.Fatal(err) } if len(snaps) != 2 { t.Fatalf("expected 2 snapshots but got %d", len(snaps)) } if snaps[0].Ref.ID != "should-be-found-1" { t.Fatalf("expected ID 'should-be-found-1', got %s", snaps[0].Ref.ID) } if snaps[1].Ref.ID != "should-be-found-2" { t.Fatalf("expected ID 'should-be-found-2', got %s", snaps[1].Ref.ID) } } func codeEq(t *testing.T, msg string, code codes.Code, err error) { if status.Code(err) != code { t.Fatalf("%s:\ngot <%v>\nwant code %s", msg, err, code) } } func loc() string { _, file, line, ok := runtime.Caller(2) if !ok { return "???" } return fmt.Sprintf("%s:%d", filepath.Base(file), line) } func copyMap(m map[string]interface{}) map[string]interface{} { c := map[string]interface{}{} for k, v := range m { c[k] = v } return c } func checkTimeBetween(t *testing.T, got, low, high time.Time) { // Allow slack for clock skew. const slack = 4 * time.Second low = low.Add(-slack) high = high.Add(slack) if got.Before(low) || got.After(high) { t.Fatalf("got %s, not in [%s, %s]", got, low, high) } } type testHelper struct { t *testing.T } func (h testHelper) mustCreate(doc *DocumentRef, data interface{}) *WriteResult { wr, err := doc.Create(context.Background(), data) if err != nil { h.t.Fatalf("%s: creating: %v", loc(), err) } return wr } func (h testHelper) mustUpdate(doc *DocumentRef, updates []Update) *WriteResult { wr, err := doc.Update(context.Background(), updates) if err != nil { h.t.Fatalf("%s: updating: %v", loc(), err) } return wr } func (h testHelper) mustGet(doc *DocumentRef) *DocumentSnapshot { d, err := doc.Get(context.Background()) if err != nil { h.t.Fatalf("%s: getting: %v", loc(), err) } return d } func (h testHelper) mustDelete(doc *DocumentRef) *WriteResult { wr, err := doc.Delete(context.Background()) if err != nil { h.t.Fatalf("%s: updating: %v", loc(), err) } return wr } func (h testHelper) mustSet(doc *DocumentRef, data interface{}, opts ...SetOption) *WriteResult { wr, err := doc.Set(context.Background(), data, opts...) if err != nil { h.t.Fatalf("%s: updating: %v", loc(), err) } return wr } func TestDetectProjectID(t *testing.T) { if testing.Short() { t.Skip("Integration tests skipped in short mode") } ctx := context.Background() creds := testutil.Credentials(ctx) if creds == nil { t.Skip("Integration tests skipped. See CONTRIBUTING.md for details") } // Use creds with project ID. if _, err := NewClient(ctx, DetectProjectID, option.WithCredentials(creds)); err != nil { t.Errorf("NewClient: %v", err) } ts := testutil.ErroringTokenSource{} // Try to use creds without project ID. _, err := NewClient(ctx, DetectProjectID, option.WithTokenSource(ts)) if err == nil || err.Error() != "firestore: see the docs on DetectProjectID" { t.Errorf("expected an error while using TokenSource that does not have a project ID") } } google-cloud-go-0.49.0/firestore/internal/000077500000000000000000000000001356504100700204065ustar00rootroot00000000000000google-cloud-go-0.49.0/firestore/internal/Makefile000066400000000000000000000004771356504100700220560ustar00rootroot00000000000000# Build doc.go from template and snippets. SHELL=/bin/bash ../doc.go: build doc-snippets.go doc.template snipdoc.awk @tmp=$$(mktemp) && \ awk -f snipdoc.awk doc-snippets.go doc.template > $$tmp && \ chmod +w $@ && \ mv $$tmp $@ && \ chmod -w $@ @echo "wrote $@" .PHONY: build build: go build doc-snippets.go google-cloud-go-0.49.0/firestore/internal/conformance/000077500000000000000000000000001356504100700227005ustar00rootroot00000000000000google-cloud-go-0.49.0/firestore/internal/conformance/README.md000066400000000000000000000004571356504100700241650ustar00rootroot00000000000000# Generating tests.pb.go ``` # Note: Change /usr/local/google/home/deklerk/workspace/googleapis to wherever # you've installed https://github.com/googleapis/googleapis. # Note: Run whilst cd-ed in this directory. protoc --go_out=. -I /usr/local/google/home/deklerk/workspace/googleapis -I . *.proto ```google-cloud-go-0.49.0/firestore/internal/conformance/testdata/000077500000000000000000000000001356504100700245115ustar00rootroot00000000000000google-cloud-go-0.49.0/firestore/internal/conformance/testdata/create-all-transforms.json000066400000000000000000000043121356504100700316110ustar00rootroot00000000000000{ "tests": [ { "description": "create: all transforms in a single call", "comment": "A document can be created with any amount of transforms.", "create": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1, \"b\": \"ServerTimestamp\", \"c\": [\"ArrayUnion\", 1, 2, 3], \"d\": [\"ArrayRemove\", 4, 5, 6]}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "currentDocument": { "exists": false } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b", "setToServerValue": "REQUEST_TIME" }, { "fieldPath": "c", "appendMissingElements": { "values": [ { "integerValue": "1" }, { "integerValue": "2" }, { "integerValue": "3" } ] } }, { "fieldPath": "d", "removeAllFromArray": { "values": [ { "integerValue": "4" }, { "integerValue": "5" }, { "integerValue": "6" } ] } } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/create-arrayremove-multi.json000066400000000000000000000041771356504100700323420ustar00rootroot00000000000000{ "tests": [ { "description": "create: multiple ArrayRemove fields", "comment": "A document can have more than one ArrayRemove field.\nSince all the ArrayRemove fields are removed, the only field in the update is \"a\".", "create": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1, \"b\": [\"ArrayRemove\", 1, 2, 3], \"c\": {\"d\": [\"ArrayRemove\", 4, 5, 6]}}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "currentDocument": { "exists": false } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b", "removeAllFromArray": { "values": [ { "integerValue": "1" }, { "integerValue": "2" }, { "integerValue": "3" } ] } }, { "fieldPath": "c.d", "removeAllFromArray": { "values": [ { "integerValue": "4" }, { "integerValue": "5" }, { "integerValue": "6" } ] } } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/create-arrayremove-nested.json000066400000000000000000000032551356504100700324660ustar00rootroot00000000000000{ "tests": [ { "description": "create: nested ArrayRemove field", "comment": "An ArrayRemove value can occur at any depth. In this case,\nthe transform applies to the field path \"b.c\". Since \"c\" is removed from the update,\n\"b\" becomes empty, so it is also removed from the update.", "create": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1, \"b\": {\"c\": [\"ArrayRemove\", 1, 2, 3]}}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "currentDocument": { "exists": false } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b.c", "removeAllFromArray": { "values": [ { "integerValue": "1" }, { "integerValue": "2" }, { "integerValue": "3" } ] } } ] } } ] } } } ] } create-arrayremove-noarray-nested.json000066400000000000000000000007461356504100700340620ustar00rootroot00000000000000google-cloud-go-0.49.0/firestore/internal/conformance/testdata{ "tests": [ { "description": "create: ArrayRemove cannot be anywhere inside an array value", "comment": "There cannot be an array value anywhere on the path from the document\nroot to the ArrayRemove. Firestore transforms don't support array indexing.", "create": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": [1, {\"b\": [\"ArrayRemove\", 1, 2, 3]}]}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/create-arrayremove-noarray.json000066400000000000000000000006361356504100700326570ustar00rootroot00000000000000{ "tests": [ { "description": "create: ArrayRemove cannot be in an array value", "comment": "ArrayRemove must be the value of a field. Firestore\ntransforms don't support array indexing.", "create": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": [1, 2, [\"ArrayRemove\", 1, 2, 3]]}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/create-arrayremove-with-st.json000066400000000000000000000006721356504100700326030ustar00rootroot00000000000000{ "tests": [ { "description": "create: The ServerTimestamp sentinel cannot be in an ArrayUnion", "comment": "The ServerTimestamp sentinel must be the value of a field. It may\nnot appear in an ArrayUnion.", "create": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": [\"ArrayRemove\", 1, \"ServerTimestamp\", 3]}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/create-arrayremove.json000066400000000000000000000031161356504100700312020ustar00rootroot00000000000000{ "tests": [ { "description": "create: ArrayRemove with data", "comment": "A key with ArrayRemove is removed from the data in the update \noperation. Instead it appears in a separate Transform operation.", "create": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1, \"b\": [\"ArrayRemove\", 1, 2, 3]}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "currentDocument": { "exists": false } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b", "removeAllFromArray": { "values": [ { "integerValue": "1" }, { "integerValue": "2" }, { "integerValue": "3" } ] } } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/create-arrayunion-multi.json000066400000000000000000000042001356504100700321600ustar00rootroot00000000000000{ "tests": [ { "description": "create: multiple ArrayUnion fields", "comment": "A document can have more than one ArrayUnion field.\nSince all the ArrayUnion fields are removed, the only field in the update is \"a\".", "create": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1, \"b\": [\"ArrayUnion\", 1, 2, 3], \"c\": {\"d\": [\"ArrayUnion\", 4, 5, 6]}}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "currentDocument": { "exists": false } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b", "appendMissingElements": { "values": [ { "integerValue": "1" }, { "integerValue": "2" }, { "integerValue": "3" } ] } }, { "fieldPath": "c.d", "appendMissingElements": { "values": [ { "integerValue": "4" }, { "integerValue": "5" }, { "integerValue": "6" } ] } } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/create-arrayunion-nested.json000066400000000000000000000032551356504100700323210ustar00rootroot00000000000000{ "tests": [ { "description": "create: nested ArrayUnion field", "comment": "An ArrayUnion value can occur at any depth. In this case,\nthe transform applies to the field path \"b.c\". Since \"c\" is removed from the update,\n\"b\" becomes empty, so it is also removed from the update.", "create": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1, \"b\": {\"c\": [\"ArrayUnion\", 1, 2, 3]}}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "currentDocument": { "exists": false } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b.c", "appendMissingElements": { "values": [ { "integerValue": "1" }, { "integerValue": "2" }, { "integerValue": "3" } ] } } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/create-arrayunion-noarray-nested.json000066400000000000000000000007431356504100700337710ustar00rootroot00000000000000{ "tests": [ { "description": "create: ArrayUnion cannot be anywhere inside an array value", "comment": "There cannot be an array value anywhere on the path from the document\nroot to the ArrayUnion. Firestore transforms don't support array indexing.", "create": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": [1, {\"b\": [\"ArrayUnion\", 1, 2, 3]}]}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/create-arrayunion-noarray.json000066400000000000000000000006341356504100700325100ustar00rootroot00000000000000{ "tests": [ { "description": "create: ArrayUnion cannot be in an array value", "comment": "ArrayUnion must be the value of a field. Firestore\ntransforms don't support array indexing.", "create": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": [1, 2, [\"ArrayRemove\", 1, 2, 3]]}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/create-arrayunion-with-st.json000066400000000000000000000006711356504100700324350ustar00rootroot00000000000000{ "tests": [ { "description": "create: The ServerTimestamp sentinel cannot be in an ArrayUnion", "comment": "The ServerTimestamp sentinel must be the value of a field. It may\nnot appear in an ArrayUnion.", "create": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": [\"ArrayUnion\", 1, \"ServerTimestamp\", 3]}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/create-arrayunion.json000066400000000000000000000031161356504100700310350ustar00rootroot00000000000000{ "tests": [ { "description": "create: ArrayUnion with data", "comment": "A key with ArrayUnion is removed from the data in the update \noperation. Instead it appears in a separate Transform operation.", "create": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1, \"b\": [\"ArrayUnion\", 1, 2, 3]}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "currentDocument": { "exists": false } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b", "appendMissingElements": { "values": [ { "integerValue": "1" }, { "integerValue": "2" }, { "integerValue": "3" } ] } } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/create-basic.json000066400000000000000000000014121356504100700277240ustar00rootroot00000000000000{ "tests": [ { "description": "create: basic", "comment": "A simple call, resulting in a single update operation.", "create": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "currentDocument": { "exists": false } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/create-complex.json000066400000000000000000000036311356504100700303170ustar00rootroot00000000000000{ "tests": [ { "description": "create: complex", "comment": "A call to a write method with complicated input data.", "create": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": [1, 2.5], \"b\": {\"c\": [\"three\", {\"d\": true}]}}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "arrayValue": { "values": [ { "integerValue": "1" }, { "doubleValue": 2.5 } ] } }, "b": { "mapValue": { "fields": { "c": { "arrayValue": { "values": [ { "stringValue": "three" }, { "mapValue": { "fields": { "d": { "booleanValue": true } } } } ] } } } } } } }, "currentDocument": { "exists": false } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/create-del-noarray-nested.json000066400000000000000000000007651356504100700323520ustar00rootroot00000000000000{ "tests": [ { "description": "create: Delete cannot be anywhere inside an array value", "comment": "The Delete sentinel must be the value of a field. Deletes are implemented\nby turning the path to the Delete sentinel into a FieldPath, and FieldPaths do not support\narray indexing.", "create": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": [1, {\"b\": \"Delete\"}]}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/create-del-noarray.json000066400000000000000000000007421356504100700310650ustar00rootroot00000000000000{ "tests": [ { "description": "create: Delete cannot be in an array value", "comment": "The Delete sentinel must be the value of a field. Deletes are\nimplemented by turning the path to the Delete sentinel into a FieldPath, and FieldPaths\ndo not support array indexing.", "create": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": [1, 2, \"Delete\"]}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/create-empty.json000066400000000000000000000011541356504100700300040ustar00rootroot00000000000000{ "tests": [ { "description": "create: creating or setting an empty map", "create": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": {} }, "currentDocument": { "exists": false } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/create-nodel.json000066400000000000000000000005671356504100700277560ustar00rootroot00000000000000{ "tests": [ { "description": "create: Delete cannot appear in data", "comment": "The Delete sentinel cannot be used in Create, or in Set without a Merge option.", "create": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1, \"b\": \"Delete\"}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/create-nosplit.json000066400000000000000000000021231356504100700303330ustar00rootroot00000000000000{ "tests": [ { "description": "create: don’t split on dots", "comment": "Create and Set treat their map keys literally. They do not split on dots.", "create": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{ \"a.b\": { \"c.d\": 1 }, \"e\": 2 }", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a.b": { "mapValue": { "fields": { "c.d": { "integerValue": "1" } } } }, "e": { "integerValue": "2" } } }, "currentDocument": { "exists": false } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/create-special-chars.json000066400000000000000000000021421356504100700313620ustar00rootroot00000000000000{ "tests": [ { "description": "create: non-alpha characters in map keys", "comment": "Create and Set treat their map keys literally. They do not escape special characters.", "create": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{ \"*\": { \".\": 1 }, \"~\": 2 }", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "*": { "mapValue": { "fields": { ".": { "integerValue": "1" } } } }, "~": { "integerValue": "2" } } }, "currentDocument": { "exists": false } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/create-st-alone.json000066400000000000000000000016311356504100700303700ustar00rootroot00000000000000{ "tests": [ { "description": "create: ServerTimestamp alone", "comment": "If the only values in the input are ServerTimestamps, then no\nupdate operation should be produced.", "create": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": \"ServerTimestamp\"}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "a", "setToServerValue": "REQUEST_TIME" } ] }, "currentDocument": { "exists": false } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/create-st-multi.json000066400000000000000000000026431356504100700304300ustar00rootroot00000000000000{ "tests": [ { "description": "create: multiple ServerTimestamp fields", "comment": "A document can have more than one ServerTimestamp field.\nSince all the ServerTimestamp fields are removed, the only field in the update is \"a\".", "create": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1, \"b\": \"ServerTimestamp\", \"c\": {\"d\": \"ServerTimestamp\"}}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "currentDocument": { "exists": false } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b", "setToServerValue": "REQUEST_TIME" }, { "fieldPath": "c.d", "setToServerValue": "REQUEST_TIME" } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/create-st-nested.json000066400000000000000000000025001356504100700305500ustar00rootroot00000000000000{ "tests": [ { "description": "create: nested ServerTimestamp field", "comment": "A ServerTimestamp value can occur at any depth. In this case,\nthe transform applies to the field path \"b.c\". Since \"c\" is removed from the update,\n\"b\" becomes empty, so it is also removed from the update.", "create": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1, \"b\": {\"c\": \"ServerTimestamp\"}}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "currentDocument": { "exists": false } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b.c", "setToServerValue": "REQUEST_TIME" } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/create-st-noarray-nested.json000066400000000000000000000007601356504100700322270ustar00rootroot00000000000000{ "tests": [ { "description": "create: ServerTimestamp cannot be anywhere inside an array value", "comment": "There cannot be an array value anywhere on the path from the document\nroot to the ServerTimestamp sentinel. Firestore transforms don't support array indexing.", "create": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": [1, {\"b\": \"ServerTimestamp\"}]}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/create-st-noarray.json000066400000000000000000000006541356504100700307510ustar00rootroot00000000000000{ "tests": [ { "description": "create: ServerTimestamp cannot be in an array value", "comment": "The ServerTimestamp sentinel must be the value of a field. Firestore\ntransforms don't support array indexing.", "create": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": [1, 2, \"ServerTimestamp\"]}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/create-st-with-empty-map.json000066400000000000000000000027531356504100700321620ustar00rootroot00000000000000{ "tests": [ { "description": "create: ServerTimestamp beside an empty map", "comment": "When a ServerTimestamp and a map both reside inside a map, the\nServerTimestamp should be stripped out but the empty map should remain.", "create": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": {\"b\": {}, \"c\": \"ServerTimestamp\"}}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "mapValue": { "fields": { "b": { "mapValue": { "fields": {} } } } } } } }, "currentDocument": { "exists": false } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "a.c", "setToServerValue": "REQUEST_TIME" } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/create-st.json000066400000000000000000000025541356504100700273010ustar00rootroot00000000000000{ "tests": [ { "description": "create: ServerTimestamp with data", "comment": "A key with the special ServerTimestamp sentinel is removed from\nthe data in the update operation. Instead it appears in a separate Transform operation.\nNote that in these tests, the string \"ServerTimestamp\" should be replaced with the\nspecial ServerTimestamp value.", "create": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1, \"b\": \"ServerTimestamp\"}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "currentDocument": { "exists": false } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b", "setToServerValue": "REQUEST_TIME" } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/delete-exists-precond.json000066400000000000000000000012021356504100700316060ustar00rootroot00000000000000{ "tests": [ { "description": "delete: delete with exists precondition", "comment": "Delete supports an exists precondition.", "delete": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "precondition": { "exists": true }, "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "delete": "projects/projectID/databases/(default)/documents/C/d", "currentDocument": { "exists": true } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/delete-no-precond.json000066400000000000000000000007361356504100700307160ustar00rootroot00000000000000{ "tests": [ { "description": "delete: delete without precondition", "comment": "An ordinary Delete call.", "delete": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "delete": "projects/projectID/databases/(default)/documents/C/d" } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/delete-time-precond.json000066400000000000000000000013011356504100700312250ustar00rootroot00000000000000{ "tests": [ { "description": "delete: delete with last-update-time precondition", "comment": "Delete supports a last-update-time precondition.", "delete": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "precondition": { "updateTime": "1970-01-01T00:00:42Z" }, "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "delete": "projects/projectID/databases/(default)/documents/C/d", "currentDocument": { "updateTime": "1970-01-01T00:00:42Z" } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/get-basic.json000066400000000000000000000005101356504100700272360ustar00rootroot00000000000000{ "tests": [ { "description": "get: get a document", "comment": "A call to DocumentRef.Get", "get": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "request": { "name": "projects/projectID/databases/(default)/documents/C/d" } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/listen-add-mod-del-add.json000066400000000000000000000135501356504100700315010ustar00rootroot00000000000000{ "tests": [ { "description": "listen: add a doc, modify it, delete it, then add it again", "comment": "Various changes to a single document.", "listen": { "responses": [ { "documentChange": { "document": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "targetIds": [ 1 ] } }, { "targetChange": { "targetChangeType": "CURRENT" } }, { "targetChange": { "readTime": "1970-01-01T00:00:01Z" } }, { "documentChange": { "document": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "2" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:02Z" }, "targetIds": [ 1 ] } }, { "targetChange": { "readTime": "1970-01-01T00:00:02Z" } }, { "documentDelete": { "document": "projects/projectID/databases/(default)/documents/C/d1" } }, { "targetChange": { "readTime": "1970-01-01T00:00:03Z" } }, { "documentChange": { "document": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:03Z" }, "targetIds": [ 1 ] } }, { "targetChange": { "readTime": "1970-01-01T00:00:04Z" } } ], "snapshots": [ { "docs": [ { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" } ], "changes": [ { "kind": "ADDED", "doc": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "oldIndex": -1 } ], "readTime": "1970-01-01T00:00:01Z" }, { "docs": [ { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "2" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:02Z" } ], "changes": [ { "kind": "MODIFIED", "doc": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "2" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:02Z" } } ], "readTime": "1970-01-01T00:00:02Z" }, { "changes": [ { "kind": "REMOVED", "doc": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "2" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:02Z" }, "newIndex": -1 } ], "readTime": "1970-01-01T00:00:03Z" }, { "docs": [ { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:03Z" } ], "changes": [ { "kind": "ADDED", "doc": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:03Z" }, "oldIndex": -1 } ], "readTime": "1970-01-01T00:00:04Z" } ] } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/listen-add-one.json000066400000000000000000000036061356504100700302140ustar00rootroot00000000000000{ "tests": [ { "description": "listen: add a doc", "comment": "Snapshot with a single document.", "listen": { "responses": [ { "documentChange": { "document": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "targetIds": [ 1 ] } }, { "targetChange": { "targetChangeType": "CURRENT" } }, { "targetChange": { "readTime": "1970-01-01T00:00:02Z" } } ], "snapshots": [ { "docs": [ { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" } ], "changes": [ { "kind": "ADDED", "doc": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "oldIndex": -1 } ], "readTime": "1970-01-01T00:00:02Z" } ] } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/listen-add-three.json000066400000000000000000000112361356504100700305400ustar00rootroot00000000000000{ "tests": [ { "description": "listen: add three documents", "comment": "A snapshot with three documents. The documents are sorted\nfirst by the \"a\" field, then by their path. The changes are ordered the same way.", "listen": { "responses": [ { "documentChange": { "document": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "targetIds": [ 1 ] } }, { "documentChange": { "document": { "name": "projects/projectID/databases/(default)/documents/C/d3", "fields": { "a": { "integerValue": "1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "targetIds": [ 1 ] } }, { "documentChange": { "document": { "name": "projects/projectID/databases/(default)/documents/C/d2", "fields": { "a": { "integerValue": "1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "targetIds": [ 1 ] } }, { "targetChange": { "targetChangeType": "CURRENT" } }, { "targetChange": { "readTime": "1970-01-01T00:00:02Z" } } ], "snapshots": [ { "docs": [ { "name": "projects/projectID/databases/(default)/documents/C/d2", "fields": { "a": { "integerValue": "1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, { "name": "projects/projectID/databases/(default)/documents/C/d3", "fields": { "a": { "integerValue": "1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" } ], "changes": [ { "kind": "ADDED", "doc": { "name": "projects/projectID/databases/(default)/documents/C/d2", "fields": { "a": { "integerValue": "1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "oldIndex": -1 }, { "kind": "ADDED", "doc": { "name": "projects/projectID/databases/(default)/documents/C/d3", "fields": { "a": { "integerValue": "1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "oldIndex": -1, "newIndex": 1 }, { "kind": "ADDED", "doc": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "oldIndex": -1, "newIndex": 2 } ], "readTime": "1970-01-01T00:00:02Z" } ] } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/listen-doc-remove.json000066400000000000000000000054441356504100700307470ustar00rootroot00000000000000{ "tests": [ { "description": "listen: DocumentRemove behaves like DocumentDelete", "comment": "The DocumentRemove response behaves exactly like DocumentDelete.", "listen": { "responses": [ { "documentChange": { "document": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "targetIds": [ 1 ] } }, { "targetChange": { "targetChangeType": "CURRENT" } }, { "targetChange": { "readTime": "1970-01-01T00:00:01Z" } }, { "documentRemove": { "document": "projects/projectID/databases/(default)/documents/C/d1" } }, { "targetChange": { "readTime": "1970-01-01T00:00:02Z" } } ], "snapshots": [ { "docs": [ { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" } ], "changes": [ { "kind": "ADDED", "doc": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "oldIndex": -1 } ], "readTime": "1970-01-01T00:00:01Z" }, { "changes": [ { "kind": "REMOVED", "doc": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "newIndex": -1 } ], "readTime": "1970-01-01T00:00:02Z" } ] } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/listen-empty.json000066400000000000000000000010611356504100700300340ustar00rootroot00000000000000{ "tests": [ { "description": "listen: no changes; empty snapshot", "comment": "There are no changes, so the snapshot should be empty.", "listen": { "responses": [ { "targetChange": { "targetChangeType": "CURRENT" } }, { "targetChange": { "readTime": "1970-01-01T00:00:01Z" } } ], "snapshots": [ { "readTime": "1970-01-01T00:00:01Z" } ] } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/listen-filter-nop.json000066400000000000000000000140031356504100700307550ustar00rootroot00000000000000{ "tests": [ { "description": "listen: Filter response with same size is a no-op", "comment": "A Filter response whose count matches the size of the current\nstate (docs in last snapshot + docs added - docs deleted) is a no-op.", "listen": { "responses": [ { "documentChange": { "document": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "targetIds": [ 1 ] } }, { "documentChange": { "document": { "name": "projects/projectID/databases/(default)/documents/C/d2", "fields": { "a": { "integerValue": "1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "targetIds": [ 1 ] } }, { "targetChange": { "targetChangeType": "CURRENT" } }, { "targetChange": { "readTime": "1970-01-01T00:00:01Z" } }, { "documentChange": { "document": { "name": "projects/projectID/databases/(default)/documents/C/d3", "fields": { "a": { "integerValue": "1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "targetIds": [ 1 ] } }, { "documentDelete": { "document": "projects/projectID/databases/(default)/documents/C/d1" } }, { "filter": { "count": 2 } }, { "targetChange": { "readTime": "1970-01-01T00:00:02Z" } } ], "snapshots": [ { "docs": [ { "name": "projects/projectID/databases/(default)/documents/C/d2", "fields": { "a": { "integerValue": "1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" } ], "changes": [ { "kind": "ADDED", "doc": { "name": "projects/projectID/databases/(default)/documents/C/d2", "fields": { "a": { "integerValue": "1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "oldIndex": -1 }, { "kind": "ADDED", "doc": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "oldIndex": -1, "newIndex": 1 } ], "readTime": "1970-01-01T00:00:01Z" }, { "docs": [ { "name": "projects/projectID/databases/(default)/documents/C/d2", "fields": { "a": { "integerValue": "1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, { "name": "projects/projectID/databases/(default)/documents/C/d3", "fields": { "a": { "integerValue": "1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" } ], "changes": [ { "kind": "REMOVED", "doc": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "oldIndex": 1, "newIndex": -1 }, { "kind": "ADDED", "doc": { "name": "projects/projectID/databases/(default)/documents/C/d3", "fields": { "a": { "integerValue": "1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "oldIndex": -1, "newIndex": 1 } ], "readTime": "1970-01-01T00:00:02Z" } ] } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/listen-multi-docs.json000066400000000000000000000314561356504100700307710ustar00rootroot00000000000000{ "tests": [ { "description": "listen: multiple documents, added, deleted and updated", "comment": "Changes should be ordered with deletes first, then additions, then mods,\neach in query order.\nOld indices refer to the immediately previous state, not the previous snapshot", "listen": { "responses": [ { "documentChange": { "document": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "targetIds": [ 1 ] } }, { "documentChange": { "document": { "name": "projects/projectID/databases/(default)/documents/C/d3", "fields": { "a": { "integerValue": "1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "targetIds": [ 1 ] } }, { "documentChange": { "document": { "name": "projects/projectID/databases/(default)/documents/C/d2", "fields": { "a": { "integerValue": "1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "targetIds": [ 1 ] } }, { "documentChange": { "document": { "name": "projects/projectID/databases/(default)/documents/C/d4", "fields": { "a": { "integerValue": "2" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "targetIds": [ 1 ] } }, { "targetChange": { "targetChangeType": "CURRENT" } }, { "targetChange": { "readTime": "1970-01-01T00:00:02Z" } }, { "documentChange": { "document": { "name": "projects/projectID/databases/(default)/documents/C/d5", "fields": { "a": { "integerValue": "4" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "targetIds": [ 1 ] } }, { "documentDelete": { "document": "projects/projectID/databases/(default)/documents/C/d3" } }, { "documentChange": { "document": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "-1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:03Z" }, "targetIds": [ 1 ] } }, { "documentChange": { "document": { "name": "projects/projectID/databases/(default)/documents/C/d6", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "targetIds": [ 1 ] } }, { "documentDelete": { "document": "projects/projectID/databases/(default)/documents/C/d2" } }, { "documentChange": { "document": { "name": "projects/projectID/databases/(default)/documents/C/d4", "fields": { "a": { "integerValue": "-2" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:03Z" }, "targetIds": [ 1 ] } }, { "targetChange": { "readTime": "1970-01-01T00:00:04Z" } } ], "snapshots": [ { "docs": [ { "name": "projects/projectID/databases/(default)/documents/C/d2", "fields": { "a": { "integerValue": "1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, { "name": "projects/projectID/databases/(default)/documents/C/d3", "fields": { "a": { "integerValue": "1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, { "name": "projects/projectID/databases/(default)/documents/C/d4", "fields": { "a": { "integerValue": "2" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" } ], "changes": [ { "kind": "ADDED", "doc": { "name": "projects/projectID/databases/(default)/documents/C/d2", "fields": { "a": { "integerValue": "1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "oldIndex": -1 }, { "kind": "ADDED", "doc": { "name": "projects/projectID/databases/(default)/documents/C/d3", "fields": { "a": { "integerValue": "1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "oldIndex": -1, "newIndex": 1 }, { "kind": "ADDED", "doc": { "name": "projects/projectID/databases/(default)/documents/C/d4", "fields": { "a": { "integerValue": "2" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "oldIndex": -1, "newIndex": 2 }, { "kind": "ADDED", "doc": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "oldIndex": -1, "newIndex": 3 } ], "readTime": "1970-01-01T00:00:02Z" }, { "docs": [ { "name": "projects/projectID/databases/(default)/documents/C/d4", "fields": { "a": { "integerValue": "-2" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:03Z" }, { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "-1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:03Z" }, { "name": "projects/projectID/databases/(default)/documents/C/d6", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, { "name": "projects/projectID/databases/(default)/documents/C/d5", "fields": { "a": { "integerValue": "4" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" } ], "changes": [ { "kind": "REMOVED", "doc": { "name": "projects/projectID/databases/(default)/documents/C/d2", "fields": { "a": { "integerValue": "1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "newIndex": -1 }, { "kind": "REMOVED", "doc": { "name": "projects/projectID/databases/(default)/documents/C/d3", "fields": { "a": { "integerValue": "1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "newIndex": -1 }, { "kind": "ADDED", "doc": { "name": "projects/projectID/databases/(default)/documents/C/d6", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "oldIndex": -1, "newIndex": 2 }, { "kind": "ADDED", "doc": { "name": "projects/projectID/databases/(default)/documents/C/d5", "fields": { "a": { "integerValue": "4" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "oldIndex": -1, "newIndex": 3 }, { "kind": "MODIFIED", "doc": { "name": "projects/projectID/databases/(default)/documents/C/d4", "fields": { "a": { "integerValue": "-2" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:03Z" } }, { "kind": "MODIFIED", "doc": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "-1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:03Z" }, "oldIndex": 1, "newIndex": 1 } ], "readTime": "1970-01-01T00:00:04Z" } ] } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/listen-nocurrent.json000066400000000000000000000066061356504100700307270ustar00rootroot00000000000000{ "tests": [ { "description": "listen: no snapshot if we don't see CURRENT", "comment": "If the watch state is not marked CURRENT, no snapshot is issued.", "listen": { "responses": [ { "documentChange": { "document": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "targetIds": [ 1 ] } }, { "targetChange": { "readTime": "1970-01-01T00:00:01Z" } }, { "documentChange": { "document": { "name": "projects/projectID/databases/(default)/documents/C/d2", "fields": { "a": { "integerValue": "2" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:02Z" }, "targetIds": [ 1 ] } }, { "targetChange": { "targetChangeType": "CURRENT" } }, { "targetChange": { "readTime": "1970-01-01T00:00:02Z" } } ], "snapshots": [ { "docs": [ { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, { "name": "projects/projectID/databases/(default)/documents/C/d2", "fields": { "a": { "integerValue": "2" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:02Z" } ], "changes": [ { "kind": "ADDED", "doc": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "oldIndex": -1 }, { "kind": "ADDED", "doc": { "name": "projects/projectID/databases/(default)/documents/C/d2", "fields": { "a": { "integerValue": "2" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:02Z" }, "oldIndex": -1, "newIndex": 1 } ], "readTime": "1970-01-01T00:00:02Z" } ] } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/listen-nomod.json000066400000000000000000000067661356504100700300330ustar00rootroot00000000000000{ "tests": [ { "description": "listen: add a doc, then change it but without changing its update time", "comment": "Document updates are recognized by a change in the update time, not the data.\nThis shouldn't actually happen. It is just a test of the update logic.", "listen": { "responses": [ { "documentChange": { "document": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "targetIds": [ 1 ] } }, { "targetChange": { "targetChangeType": "CURRENT" } }, { "targetChange": { "readTime": "1970-01-01T00:00:01Z" } }, { "documentChange": { "document": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "2" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "targetIds": [ 1 ] } }, { "targetChange": { "readTime": "1970-01-01T00:00:02Z" } }, { "documentDelete": { "document": "projects/projectID/databases/(default)/documents/C/d1" } }, { "targetChange": { "readTime": "1970-01-01T00:00:03Z" } } ], "snapshots": [ { "docs": [ { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" } ], "changes": [ { "kind": "ADDED", "doc": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "oldIndex": -1 } ], "readTime": "1970-01-01T00:00:01Z" }, { "changes": [ { "kind": "REMOVED", "doc": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "newIndex": -1 } ], "readTime": "1970-01-01T00:00:03Z" } ] } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/listen-removed-target-ids.json000066400000000000000000000063001356504100700324010ustar00rootroot00000000000000{ "tests": [ { "description": "listen: DocumentChange with removed_target_id is like a delete.", "comment": "A DocumentChange with the watch target ID in the removed_target_ids field is the\nsame as deleting a document.", "listen": { "responses": [ { "documentChange": { "document": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "targetIds": [ 1 ] } }, { "targetChange": { "targetChangeType": "CURRENT" } }, { "targetChange": { "readTime": "1970-01-01T00:00:01Z" } }, { "documentChange": { "document": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "removedTargetIds": [ 1 ] } }, { "targetChange": { "readTime": "1970-01-01T00:00:02Z" } } ], "snapshots": [ { "docs": [ { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" } ], "changes": [ { "kind": "ADDED", "doc": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "oldIndex": -1 } ], "readTime": "1970-01-01T00:00:01Z" }, { "changes": [ { "kind": "REMOVED", "doc": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "newIndex": -1 } ], "readTime": "1970-01-01T00:00:02Z" } ] } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/listen-reset.json000066400000000000000000000223721356504100700300300ustar00rootroot00000000000000{ "tests": [ { "description": "listen: RESET turns off CURRENT", "comment": "A RESET message turns off the CURRENT state, and marks all documents as deleted.\n\nIf a document appeared on the stream but was never part of a snapshot (\"d3\" in this test), a reset\nwill make it disappear completely.\n\nFor a snapshot to happen at a NO_CHANGE reponse, we need to have both seen a CURRENT response, and\nhave a change from the previous snapshot. Here, after the reset, we see the same version of d2\nagain. That doesn't result in a snapshot.\n", "listen": { "responses": [ { "documentChange": { "document": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "2" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "targetIds": [ 1 ] } }, { "documentChange": { "document": { "name": "projects/projectID/databases/(default)/documents/C/d2", "fields": { "a": { "integerValue": "1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:02Z" }, "targetIds": [ 1 ] } }, { "targetChange": { "targetChangeType": "CURRENT" } }, { "targetChange": { "readTime": "1970-01-01T00:00:01Z" } }, { "documentChange": { "document": { "name": "projects/projectID/databases/(default)/documents/C/d3", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:02Z" }, "targetIds": [ 1 ] } }, { "targetChange": { "targetChangeType": "RESET" } }, { "targetChange": { "readTime": "1970-01-01T00:00:02Z" } }, { "targetChange": { "targetChangeType": "CURRENT" } }, { "documentChange": { "document": { "name": "projects/projectID/databases/(default)/documents/C/d2", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:03Z" }, "targetIds": [ 1 ] } }, { "targetChange": { "readTime": "1970-01-01T00:00:03Z" } }, { "targetChange": { "targetChangeType": "RESET" } }, { "documentChange": { "document": { "name": "projects/projectID/databases/(default)/documents/C/d2", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:03Z" }, "targetIds": [ 1 ] } }, { "targetChange": { "targetChangeType": "CURRENT" } }, { "targetChange": { "readTime": "1970-01-01T00:00:04Z" } }, { "documentChange": { "document": { "name": "projects/projectID/databases/(default)/documents/C/d3", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:02Z" }, "targetIds": [ 1 ] } }, { "targetChange": { "readTime": "1970-01-01T00:00:05Z" } } ], "snapshots": [ { "docs": [ { "name": "projects/projectID/databases/(default)/documents/C/d2", "fields": { "a": { "integerValue": "1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:02Z" }, { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "2" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" } ], "changes": [ { "kind": "ADDED", "doc": { "name": "projects/projectID/databases/(default)/documents/C/d2", "fields": { "a": { "integerValue": "1" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:02Z" }, "oldIndex": -1 }, { "kind": "ADDED", "doc": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "2" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "oldIndex": -1, "newIndex": 1 } ], "readTime": "1970-01-01T00:00:01Z" }, { "docs": [ { "name": "projects/projectID/databases/(default)/documents/C/d2", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:03Z" } ], "changes": [ { "kind": "REMOVED", "doc": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "2" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "oldIndex": 1, "newIndex": -1 }, { "kind": "MODIFIED", "doc": { "name": "projects/projectID/databases/(default)/documents/C/d2", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:03Z" } } ], "readTime": "1970-01-01T00:00:03Z" }, { "docs": [ { "name": "projects/projectID/databases/(default)/documents/C/d2", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:03Z" }, { "name": "projects/projectID/databases/(default)/documents/C/d3", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:02Z" } ], "changes": [ { "kind": "ADDED", "doc": { "name": "projects/projectID/databases/(default)/documents/C/d3", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:02Z" }, "oldIndex": -1, "newIndex": 1 } ], "readTime": "1970-01-01T00:00:05Z" } ] } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/listen-target-add-nop.json000066400000000000000000000042631356504100700315130ustar00rootroot00000000000000{ "tests": [ { "description": "listen: TargetChange_ADD is a no-op if it has the same target ID", "comment": "A TargetChange_ADD response must have the same watch target ID.", "listen": { "responses": [ { "documentChange": { "document": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "targetIds": [ 1 ] } }, { "targetChange": { "targetChangeType": "CURRENT" } }, { "targetChange": { "targetChangeType": "ADD", "targetIds": [ 1 ], "readTime": "1970-01-01T00:00:02Z" } }, { "targetChange": { "readTime": "1970-01-01T00:00:01Z" } } ], "snapshots": [ { "docs": [ { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" } ], "changes": [ { "kind": "ADDED", "doc": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "oldIndex": -1 } ], "readTime": "1970-01-01T00:00:01Z" } ] } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/listen-target-add-wrong-id.json000066400000000000000000000023361356504100700324440ustar00rootroot00000000000000{ "tests": [ { "description": "listen: TargetChange_ADD is an error if it has a different target ID", "comment": "A TargetChange_ADD response must have the same watch target ID.", "listen": { "responses": [ { "documentChange": { "document": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "targetIds": [ 1 ] } }, { "targetChange": { "targetChangeType": "CURRENT" } }, { "targetChange": { "targetChangeType": "ADD", "targetIds": [ 2 ], "readTime": "1970-01-01T00:00:02Z" } }, { "targetChange": { "readTime": "1970-01-01T00:00:01Z" } } ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/listen-target-remove.json000066400000000000000000000021151356504100700314600ustar00rootroot00000000000000{ "tests": [ { "description": "listen: TargetChange_REMOVE should not appear", "comment": "A TargetChange_REMOVE response should never be sent.", "listen": { "responses": [ { "documentChange": { "document": { "name": "projects/projectID/databases/(default)/documents/C/d1", "fields": { "a": { "integerValue": "3" } }, "createTime": "1970-01-01T00:00:01Z", "updateTime": "1970-01-01T00:00:01Z" }, "targetIds": [ 1 ] } }, { "targetChange": { "targetChangeType": "CURRENT" } }, { "targetChange": { "targetChangeType": "REMOVE" } }, { "targetChange": { "readTime": "1970-01-01T00:00:01Z" } } ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-arrayremove-cursor.json000066400000000000000000000012361356504100700324200ustar00rootroot00000000000000{ "tests": [ { "description": "query: ArrayRemove in cursor method", "comment": "ArrayRemove is not permitted in queries.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "orderBy": { "path": { "field": [ "a" ] }, "direction": "asc" } }, { "endBefore": { "jsonValues": [ "[\"ArrayRemove\", 1, 2, 3]" ] } } ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-arrayremove-where.json000066400000000000000000000010501356504100700322070ustar00rootroot00000000000000{ "tests": [ { "description": "query: ArrayRemove in Where", "comment": "ArrayRemove is not permitted in queries.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "where": { "path": { "field": [ "a" ] }, "op": "==", "jsonValue": "[\"ArrayRemove\", 1, 2, 3]" } } ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-arrayunion-cursor.json000066400000000000000000000012331356504100700322500ustar00rootroot00000000000000{ "tests": [ { "description": "query: ArrayUnion in cursor method", "comment": "ArrayUnion is not permitted in queries.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "orderBy": { "path": { "field": [ "a" ] }, "direction": "asc" } }, { "endBefore": { "jsonValues": [ "[\"ArrayUnion\", 1, 2, 3]" ] } } ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-arrayunion-where.json000066400000000000000000000010451356504100700320460ustar00rootroot00000000000000{ "tests": [ { "description": "query: ArrayUnion in Where", "comment": "ArrayUnion is not permitted in queries.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "where": { "path": { "field": [ "a" ] }, "op": "==", "jsonValue": "[\"ArrayUnion\", 1, 2, 3]" } } ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-bad-NaN.json000066400000000000000000000010571356504100700277520ustar00rootroot00000000000000{ "tests": [ { "description": "query: where clause with non-== comparison with NaN", "comment": "You can only compare NaN for equality.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "where": { "path": { "field": [ "a" ] }, "op": "\u003c", "jsonValue": "\"NaN\"" } } ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-bad-null.json000066400000000000000000000010561356504100700302470ustar00rootroot00000000000000{ "tests": [ { "description": "query: where clause with non-== comparison with Null", "comment": "You can only compare Null for equality.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "where": { "path": { "field": [ "a" ] }, "op": "\u003e", "jsonValue": "null" } } ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-cursor-docsnap-order.json000066400000000000000000000037021356504100700326240ustar00rootroot00000000000000{ "tests": [ { "description": "query: cursor methods with a document snapshot, existing orderBy", "comment": "When a document snapshot is used, the client appends a __name__ order-by clause\nwith the direction of the last order-by clause.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "orderBy": { "path": { "field": [ "a" ] }, "direction": "asc" } }, { "orderBy": { "path": { "field": [ "b" ] }, "direction": "desc" } }, { "startAfter": { "docSnapshot": { "path": "projects/projectID/databases/(default)/documents/C/D", "jsonData": "{\"a\": 7, \"b\": 8}" } } } ], "query": { "from": [ { "collectionId": "C" } ], "orderBy": [ { "field": { "fieldPath": "a" }, "direction": "ASCENDING" }, { "field": { "fieldPath": "b" }, "direction": "DESCENDING" }, { "field": { "fieldPath": "__name__" }, "direction": "DESCENDING" } ], "startAt": { "values": [ { "integerValue": "7" }, { "integerValue": "8" }, { "referenceValue": "projects/projectID/databases/(default)/documents/C/D" } ] } } } } ] } query-cursor-docsnap-orderby-name.json000066400000000000000000000043501356504100700340160ustar00rootroot00000000000000google-cloud-go-0.49.0/firestore/internal/conformance/testdata{ "tests": [ { "description": "query: cursor method, doc snapshot, existing orderBy __name__", "comment": "If there is an existing orderBy clause on __name__,\nno changes are made to the list of orderBy clauses.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "orderBy": { "path": { "field": [ "a" ] }, "direction": "desc" } }, { "orderBy": { "path": { "field": [ "__name__" ] }, "direction": "asc" } }, { "startAt": { "docSnapshot": { "path": "projects/projectID/databases/(default)/documents/C/D", "jsonData": "{\"a\": 7, \"b\": 8}" } } }, { "endAt": { "docSnapshot": { "path": "projects/projectID/databases/(default)/documents/C/D", "jsonData": "{\"a\": 7, \"b\": 8}" } } } ], "query": { "from": [ { "collectionId": "C" } ], "orderBy": [ { "field": { "fieldPath": "a" }, "direction": "DESCENDING" }, { "field": { "fieldPath": "__name__" }, "direction": "ASCENDING" } ], "startAt": { "values": [ { "integerValue": "7" }, { "referenceValue": "projects/projectID/databases/(default)/documents/C/D" } ], "before": true }, "endAt": { "values": [ { "integerValue": "7" }, { "referenceValue": "projects/projectID/databases/(default)/documents/C/D" } ] } } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-cursor-docsnap-where-eq.json000066400000000000000000000030601356504100700332230ustar00rootroot00000000000000{ "tests": [ { "description": "query: cursor methods with a document snapshot and an equality where clause", "comment": "A Where clause using equality doesn't change the implicit orderBy clauses.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "where": { "path": { "field": [ "a" ] }, "op": "==", "jsonValue": "3" } }, { "endAt": { "docSnapshot": { "path": "projects/projectID/databases/(default)/documents/C/D", "jsonData": "{\"a\": 7, \"b\": 8}" } } } ], "query": { "from": [ { "collectionId": "C" } ], "where": { "fieldFilter": { "field": { "fieldPath": "a" }, "op": "EQUAL", "value": { "integerValue": "3" } } }, "orderBy": [ { "field": { "fieldPath": "__name__" }, "direction": "ASCENDING" } ], "endAt": { "values": [ { "referenceValue": "projects/projectID/databases/(default)/documents/C/D" } ] } } } } ] } query-cursor-docsnap-where-neq-orderby.json000066400000000000000000000041121356504100700347650ustar00rootroot00000000000000google-cloud-go-0.49.0/firestore/internal/conformance/testdata{ "tests": [ { "description": "query: cursor method, doc snapshot, inequality where clause, and existing orderBy clause", "comment": "If there is an OrderBy clause, the inequality Where clause does\nnot result in a new OrderBy clause. We still add a __name__ OrderBy clause", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "orderBy": { "path": { "field": [ "a" ] }, "direction": "desc" } }, { "where": { "path": { "field": [ "a" ] }, "op": "\u003c", "jsonValue": "4" } }, { "startAt": { "docSnapshot": { "path": "projects/projectID/databases/(default)/documents/C/D", "jsonData": "{\"a\": 7, \"b\": 8}" } } } ], "query": { "from": [ { "collectionId": "C" } ], "where": { "fieldFilter": { "field": { "fieldPath": "a" }, "op": "LESS_THAN", "value": { "integerValue": "4" } } }, "orderBy": [ { "field": { "fieldPath": "a" }, "direction": "DESCENDING" }, { "field": { "fieldPath": "__name__" }, "direction": "DESCENDING" } ], "startAt": { "values": [ { "integerValue": "7" }, { "referenceValue": "projects/projectID/databases/(default)/documents/C/D" } ], "before": true } } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-cursor-docsnap-where-neq.json000066400000000000000000000035521356504100700334070ustar00rootroot00000000000000{ "tests": [ { "description": "query: cursor method with a document snapshot and an inequality where clause", "comment": "A Where clause with an inequality results in an OrderBy clause\non that clause's path, if there are no other OrderBy clauses.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "where": { "path": { "field": [ "a" ] }, "op": "\u003c=", "jsonValue": "3" } }, { "endBefore": { "docSnapshot": { "path": "projects/projectID/databases/(default)/documents/C/D", "jsonData": "{\"a\": 7, \"b\": 8}" } } } ], "query": { "from": [ { "collectionId": "C" } ], "where": { "fieldFilter": { "field": { "fieldPath": "a" }, "op": "LESS_THAN_OR_EQUAL", "value": { "integerValue": "3" } } }, "orderBy": [ { "field": { "fieldPath": "a" }, "direction": "ASCENDING" }, { "field": { "fieldPath": "__name__" }, "direction": "ASCENDING" } ], "endAt": { "values": [ { "integerValue": "7" }, { "referenceValue": "projects/projectID/databases/(default)/documents/C/D" } ], "before": true } } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-cursor-docsnap.json000066400000000000000000000021241356504100700315100ustar00rootroot00000000000000{ "tests": [ { "description": "query: cursor methods with a document snapshot", "comment": "When a document snapshot is used, the client appends a __name__ order-by clause.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "startAt": { "docSnapshot": { "path": "projects/projectID/databases/(default)/documents/C/D", "jsonData": "{\"a\": 7, \"b\": 8}" } } } ], "query": { "from": [ { "collectionId": "C" } ], "orderBy": [ { "field": { "fieldPath": "__name__" }, "direction": "ASCENDING" } ], "startAt": { "values": [ { "referenceValue": "projects/projectID/databases/(default)/documents/C/D" } ], "before": true } } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-cursor-endbefore-empty-map.json000066400000000000000000000022661356504100700337300ustar00rootroot00000000000000{ "tests": [ { "description": "query: EndBefore with explicit empty map", "comment": "Cursor methods are allowed to use empty maps with EndBefore. It should result in an empty map in the query.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "orderBy": { "path": { "field": [ "a" ] }, "direction": "asc" } }, { "endBefore": { "jsonValues": [ "{}" ] } } ], "query": { "from": [ { "collectionId": "C" } ], "orderBy": [ { "field": { "fieldPath": "a" }, "direction": "ASCENDING" } ], "endAt": { "values": [ { "mapValue": { "fields": {} } } ], "before": true } } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-cursor-endbefore-empty.json000066400000000000000000000011551356504100700331510ustar00rootroot00000000000000{ "tests": [ { "description": "query: EndBefore with empty values", "comment": "Cursor methods are not allowed to use empty values with EndBefore. It should result in an error.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "orderBy": { "path": { "field": [ "a" ] }, "direction": "asc" } }, { "endBefore": {} } ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-cursor-no-order.json000066400000000000000000000010101356504100700315770ustar00rootroot00000000000000{ "tests": [ { "description": "query: cursor method without orderBy", "comment": "If a cursor method with a list of values is provided, there must be at least as many\nexplicit orderBy clauses as values.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "startAt": { "jsonValues": [ "2" ] } } ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-cursor-startat-empty-map.json000066400000000000000000000022621356504100700334550ustar00rootroot00000000000000{ "tests": [ { "description": "query: StartAt with explicit empty map", "comment": "Cursor methods are allowed to use empty maps with StartAt. It should result in an empty map in the query.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "orderBy": { "path": { "field": [ "a" ] }, "direction": "asc" } }, { "startAt": { "jsonValues": [ "{}" ] } } ], "query": { "from": [ { "collectionId": "C" } ], "orderBy": [ { "field": { "fieldPath": "a" }, "direction": "ASCENDING" } ], "startAt": { "values": [ { "mapValue": { "fields": {} } } ], "before": true } } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-cursor-startat-empty.json000066400000000000000000000011471356504100700327030ustar00rootroot00000000000000{ "tests": [ { "description": "query: StartAt with empty values", "comment": "Cursor methods are not allowed to use empty values with StartAt. It should result in an error.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "orderBy": { "path": { "field": [ "a" ] }, "direction": "asc" } }, { "startAt": {} } ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-cursor-vals-1a.json000066400000000000000000000026221356504100700313300ustar00rootroot00000000000000{ "tests": [ { "description": "query: StartAt/EndBefore with values", "comment": "Cursor methods take the same number of values as there are OrderBy clauses.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "orderBy": { "path": { "field": [ "a" ] }, "direction": "asc" } }, { "startAt": { "jsonValues": [ "7" ] } }, { "endBefore": { "jsonValues": [ "9" ] } } ], "query": { "from": [ { "collectionId": "C" } ], "orderBy": [ { "field": { "fieldPath": "a" }, "direction": "ASCENDING" } ], "startAt": { "values": [ { "integerValue": "7" } ], "before": true }, "endAt": { "values": [ { "integerValue": "9" } ], "before": true } } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-cursor-vals-1b.json000066400000000000000000000025301356504100700313270ustar00rootroot00000000000000{ "tests": [ { "description": "query: StartAfter/EndAt with values", "comment": "Cursor methods take the same number of values as there are OrderBy clauses.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "orderBy": { "path": { "field": [ "a" ] }, "direction": "asc" } }, { "startAfter": { "jsonValues": [ "7" ] } }, { "endAt": { "jsonValues": [ "9" ] } } ], "query": { "from": [ { "collectionId": "C" } ], "orderBy": [ { "field": { "fieldPath": "a" }, "direction": "ASCENDING" } ], "startAt": { "values": [ { "integerValue": "7" } ] }, "endAt": { "values": [ { "integerValue": "9" } ] } } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-cursor-vals-2.json000066400000000000000000000036021356504100700311670ustar00rootroot00000000000000{ "tests": [ { "description": "query: Start/End with two values", "comment": "Cursor methods take the same number of values as there are OrderBy clauses.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "orderBy": { "path": { "field": [ "a" ] }, "direction": "asc" } }, { "orderBy": { "path": { "field": [ "b" ] }, "direction": "desc" } }, { "startAt": { "jsonValues": [ "7", "8" ] } }, { "endAt": { "jsonValues": [ "9", "10" ] } } ], "query": { "from": [ { "collectionId": "C" } ], "orderBy": [ { "field": { "fieldPath": "a" }, "direction": "ASCENDING" }, { "field": { "fieldPath": "b" }, "direction": "DESCENDING" } ], "startAt": { "values": [ { "integerValue": "7" }, { "integerValue": "8" } ], "before": true }, "endAt": { "values": [ { "integerValue": "9" }, { "integerValue": "10" } ] } } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-cursor-vals-docid.json000066400000000000000000000030341356504100700321070ustar00rootroot00000000000000{ "tests": [ { "description": "query: cursor methods with __name__", "comment": "Cursor values corresponding to a __name__ field take the document path relative to the\nquery's collection.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "orderBy": { "path": { "field": [ "__name__" ] }, "direction": "asc" } }, { "startAfter": { "jsonValues": [ "\"D1\"" ] } }, { "endBefore": { "jsonValues": [ "\"D2\"" ] } } ], "query": { "from": [ { "collectionId": "C" } ], "orderBy": [ { "field": { "fieldPath": "__name__" }, "direction": "ASCENDING" } ], "startAt": { "values": [ { "referenceValue": "projects/projectID/databases/(default)/documents/C/D1" } ] }, "endAt": { "values": [ { "referenceValue": "projects/projectID/databases/(default)/documents/C/D2" } ], "before": true } } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-cursor-vals-last-wins.json000066400000000000000000000032321356504100700327460ustar00rootroot00000000000000{ "tests": [ { "description": "query: cursor methods, last one wins", "comment": "When multiple Start* or End* calls occur, the values of the last one are used.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "orderBy": { "path": { "field": [ "a" ] }, "direction": "asc" } }, { "startAfter": { "jsonValues": [ "1" ] } }, { "startAt": { "jsonValues": [ "2" ] } }, { "endAt": { "jsonValues": [ "3" ] } }, { "endBefore": { "jsonValues": [ "4" ] } } ], "query": { "from": [ { "collectionId": "C" } ], "orderBy": [ { "field": { "fieldPath": "a" }, "direction": "ASCENDING" } ], "startAt": { "values": [ { "integerValue": "2" } ], "before": true }, "endAt": { "values": [ { "integerValue": "4" } ], "before": true } } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-del-cursor.json000066400000000000000000000012161356504100700306260ustar00rootroot00000000000000{ "tests": [ { "description": "query: Delete in cursor method", "comment": "Sentinel values are not permitted in queries.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "orderBy": { "path": { "field": [ "a" ] }, "direction": "asc" } }, { "endBefore": { "jsonValues": [ "\"Delete\"" ] } } ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-del-where.json000066400000000000000000000010301356504100700304150ustar00rootroot00000000000000{ "tests": [ { "description": "query: Delete in Where", "comment": "Sentinel values are not permitted in queries.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "where": { "path": { "field": [ "a" ] }, "op": "==", "jsonValue": "\"Delete\"" } } ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-invalid-operator.json000066400000000000000000000010251356504100700320240ustar00rootroot00000000000000{ "tests": [ { "description": "query: invalid operator in Where clause", "comment": "The != operator is not supported.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "where": { "path": { "field": [ "a" ] }, "op": "!=", "jsonValue": "4" } } ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-invalid-path-order.json000066400000000000000000000010211356504100700322320ustar00rootroot00000000000000{ "tests": [ { "description": "query: invalid path in OrderBy clause", "comment": "The path has an empty component.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "orderBy": { "path": { "field": [ "*", "" ] }, "direction": "asc" } } ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-invalid-path-select.json000066400000000000000000000010321356504100700324000ustar00rootroot00000000000000{ "tests": [ { "description": "query: invalid path in Where clause", "comment": "The path has an empty component.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "select": { "fields": [ { "field": [ "*", "" ] } ] } } ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-invalid-path-where.json000066400000000000000000000010451356504100700322370ustar00rootroot00000000000000{ "tests": [ { "description": "query: invalid path in Where clause", "comment": "The path has an empty component.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "where": { "path": { "field": [ "*", "" ] }, "op": "==", "jsonValue": "4" } } ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-offset-limit-last-wins.json000066400000000000000000000012341356504100700330700ustar00rootroot00000000000000{ "tests": [ { "description": "query: multiple Offset and Limit clauses", "comment": "With multiple Offset or Limit clauses, the last one wins.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "offset": 2 }, { "limit": 3 }, { "limit": 4 }, { "offset": 5 } ], "query": { "from": [ { "collectionId": "C" } ], "offset": 5, "limit": 4 } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-offset-limit.json000066400000000000000000000010221356504100700311440ustar00rootroot00000000000000{ "tests": [ { "description": "query: Offset and Limit clauses", "comment": "Offset and Limit clauses.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "offset": 2 }, { "limit": 3 } ], "query": { "from": [ { "collectionId": "C" } ], "offset": 2, "limit": 3 } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-order.json000066400000000000000000000021461356504100700276650ustar00rootroot00000000000000{ "tests": [ { "description": "query: basic OrderBy clauses", "comment": "Multiple OrderBy clauses combine.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "orderBy": { "path": { "field": [ "b" ] }, "direction": "asc" } }, { "orderBy": { "path": { "field": [ "a" ] }, "direction": "desc" } } ], "query": { "from": [ { "collectionId": "C" } ], "orderBy": [ { "field": { "fieldPath": "b" }, "direction": "ASCENDING" }, { "field": { "fieldPath": "a" }, "direction": "DESCENDING" } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-select-empty.json000066400000000000000000000012051356504100700311600ustar00rootroot00000000000000{ "tests": [ { "description": "query: empty Select clause", "comment": "An empty Select clause selects just the document ID.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "select": { "fields": [] } } ], "query": { "select": { "fields": [ { "fieldPath": "__name__" } ] }, "from": [ { "collectionId": "C" } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-select-last-wins.json000066400000000000000000000020651356504100700317500ustar00rootroot00000000000000{ "tests": [ { "description": "query: two Select clauses", "comment": "The last Select clause is the only one used.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "select": { "fields": [ { "field": [ "a" ] }, { "field": [ "b" ] } ] } }, { "select": { "fields": [ { "field": [ "c" ] } ] } } ], "query": { "select": { "fields": [ { "fieldPath": "c" } ] }, "from": [ { "collectionId": "C" } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-select.json000066400000000000000000000016331356504100700300310ustar00rootroot00000000000000{ "tests": [ { "description": "query: Select clause with some fields", "comment": "An ordinary Select clause.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "select": { "fields": [ { "field": [ "a" ] }, { "field": [ "b" ] } ] } } ], "query": { "select": { "fields": [ { "fieldPath": "a" }, { "fieldPath": "b" } ] }, "from": [ { "collectionId": "C" } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-st-cursor.json000066400000000000000000000012401356504100700305050ustar00rootroot00000000000000{ "tests": [ { "description": "query: ServerTimestamp in cursor method", "comment": "Sentinel values are not permitted in queries.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "orderBy": { "path": { "field": [ "a" ] }, "direction": "asc" } }, { "endBefore": { "jsonValues": [ "\"ServerTimestamp\"" ] } } ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-st-where.json000066400000000000000000000010521356504100700303030ustar00rootroot00000000000000{ "tests": [ { "description": "query: ServerTimestamp in Where", "comment": "Sentinel values are not permitted in queries.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "where": { "path": { "field": [ "a" ] }, "op": "==", "jsonValue": "\"ServerTimestamp\"" } } ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-where-2.json000066400000000000000000000032261356504100700300230ustar00rootroot00000000000000{ "tests": [ { "description": "query: two Where clauses", "comment": "Multiple Where clauses are combined into a composite filter.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "where": { "path": { "field": [ "a" ] }, "op": "\u003e=", "jsonValue": "5" } }, { "where": { "path": { "field": [ "b" ] }, "op": "\u003c", "jsonValue": "\"foo\"" } } ], "query": { "from": [ { "collectionId": "C" } ], "where": { "compositeFilter": { "op": "AND", "filters": [ { "fieldFilter": { "field": { "fieldPath": "a" }, "op": "GREATER_THAN_OR_EQUAL", "value": { "integerValue": "5" } } }, { "fieldFilter": { "field": { "fieldPath": "b" }, "op": "LESS_THAN", "value": { "stringValue": "foo" } } } ] } } } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-where-NaN.json000066400000000000000000000015321356504100700303340ustar00rootroot00000000000000{ "tests": [ { "description": "query: a Where clause comparing to NaN", "comment": "A Where clause that tests for equality with NaN results in a unary filter.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "where": { "path": { "field": [ "a" ] }, "op": "==", "jsonValue": "\"NaN\"" } } ], "query": { "from": [ { "collectionId": "C" } ], "where": { "unaryFilter": { "op": "IS_NAN", "field": { "fieldPath": "a" } } } } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-where-null.json000066400000000000000000000015321356504100700306320ustar00rootroot00000000000000{ "tests": [ { "description": "query: a Where clause comparing to null", "comment": "A Where clause that tests for equality with null results in a unary filter.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "where": { "path": { "field": [ "a" ] }, "op": "==", "jsonValue": "null" } } ], "query": { "from": [ { "collectionId": "C" } ], "where": { "unaryFilter": { "op": "IS_NULL", "field": { "fieldPath": "a" } } } } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-where.json000066400000000000000000000015451356504100700276660ustar00rootroot00000000000000{ "tests": [ { "description": "query: Where clause", "comment": "A simple Where clause.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "where": { "path": { "field": [ "a" ] }, "op": "\u003e", "jsonValue": "5" } } ], "query": { "from": [ { "collectionId": "C" } ], "where": { "fieldFilter": { "field": { "fieldPath": "a" }, "op": "GREATER_THAN", "value": { "integerValue": "5" } } } } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/query-wrong-collection.json000066400000000000000000000012021356504100700320270ustar00rootroot00000000000000{ "tests": [ { "description": "query: doc snapshot with wrong collection in cursor method", "comment": "If a document snapshot is passed to a Start*/End* method, it must be in the\nsame collection as the query.", "query": { "collPath": "projects/projectID/databases/(default)/documents/C", "clauses": [ { "endBefore": { "docSnapshot": { "path": "projects/projectID/databases/(default)/documents/C2/D", "jsonData": "{\"a\": 7, \"b\": 8}" } } } ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-all-transforms.json000066400000000000000000000041601356504100700311420ustar00rootroot00000000000000{ "tests": [ { "description": "set: all transforms in a single call", "comment": "A document can be created with any amount of transforms.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1, \"b\": \"ServerTimestamp\", \"c\": [\"ArrayUnion\", 1, 2, 3], \"d\": [\"ArrayRemove\", 4, 5, 6]}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b", "setToServerValue": "REQUEST_TIME" }, { "fieldPath": "c", "appendMissingElements": { "values": [ { "integerValue": "1" }, { "integerValue": "2" }, { "integerValue": "3" } ] } }, { "fieldPath": "d", "removeAllFromArray": { "values": [ { "integerValue": "4" }, { "integerValue": "5" }, { "integerValue": "6" } ] } } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-arrayremove-multi.json000066400000000000000000000040451356504100700316640ustar00rootroot00000000000000{ "tests": [ { "description": "set: multiple ArrayRemove fields", "comment": "A document can have more than one ArrayRemove field.\nSince all the ArrayRemove fields are removed, the only field in the update is \"a\".", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1, \"b\": [\"ArrayRemove\", 1, 2, 3], \"c\": {\"d\": [\"ArrayRemove\", 4, 5, 6]}}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b", "removeAllFromArray": { "values": [ { "integerValue": "1" }, { "integerValue": "2" }, { "integerValue": "3" } ] } }, { "fieldPath": "c.d", "removeAllFromArray": { "values": [ { "integerValue": "4" }, { "integerValue": "5" }, { "integerValue": "6" } ] } } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-arrayremove-nested.json000066400000000000000000000031231356504100700320100ustar00rootroot00000000000000{ "tests": [ { "description": "set: nested ArrayRemove field", "comment": "An ArrayRemove value can occur at any depth. In this case,\nthe transform applies to the field path \"b.c\". Since \"c\" is removed from the update,\n\"b\" becomes empty, so it is also removed from the update.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1, \"b\": {\"c\": [\"ArrayRemove\", 1, 2, 3]}}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b.c", "removeAllFromArray": { "values": [ { "integerValue": "1" }, { "integerValue": "2" }, { "integerValue": "3" } ] } } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-arrayremove-noarray-nested.json000066400000000000000000000007401356504100700334630ustar00rootroot00000000000000{ "tests": [ { "description": "set: ArrayRemove cannot be anywhere inside an array value", "comment": "There cannot be an array value anywhere on the path from the document\nroot to the ArrayRemove. Firestore transforms don't support array indexing.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": [1, {\"b\": [\"ArrayRemove\", 1, 2, 3]}]}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-arrayremove-noarray.json000066400000000000000000000006301356504100700322010ustar00rootroot00000000000000{ "tests": [ { "description": "set: ArrayRemove cannot be in an array value", "comment": "ArrayRemove must be the value of a field. Firestore\ntransforms don't support array indexing.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": [1, 2, [\"ArrayRemove\", 1, 2, 3]]}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-arrayremove-with-st.json000066400000000000000000000006641356504100700321340ustar00rootroot00000000000000{ "tests": [ { "description": "set: The ServerTimestamp sentinel cannot be in an ArrayUnion", "comment": "The ServerTimestamp sentinel must be the value of a field. It may\nnot appear in an ArrayUnion.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": [\"ArrayRemove\", 1, \"ServerTimestamp\", 3]}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-arrayremove.json000066400000000000000000000027641356504100700305420ustar00rootroot00000000000000{ "tests": [ { "description": "set: ArrayRemove with data", "comment": "A key with ArrayRemove is removed from the data in the update \noperation. Instead it appears in a separate Transform operation.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1, \"b\": [\"ArrayRemove\", 1, 2, 3]}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b", "removeAllFromArray": { "values": [ { "integerValue": "1" }, { "integerValue": "2" }, { "integerValue": "3" } ] } } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-arrayunion-multi.json000066400000000000000000000040461356504100700315200ustar00rootroot00000000000000{ "tests": [ { "description": "set: multiple ArrayUnion fields", "comment": "A document can have more than one ArrayUnion field.\nSince all the ArrayUnion fields are removed, the only field in the update is \"a\".", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1, \"b\": [\"ArrayUnion\", 1, 2, 3], \"c\": {\"d\": [\"ArrayUnion\", 4, 5, 6]}}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b", "appendMissingElements": { "values": [ { "integerValue": "1" }, { "integerValue": "2" }, { "integerValue": "3" } ] } }, { "fieldPath": "c.d", "appendMissingElements": { "values": [ { "integerValue": "4" }, { "integerValue": "5" }, { "integerValue": "6" } ] } } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-arrayunion-nested.json000066400000000000000000000031231356504100700316430ustar00rootroot00000000000000{ "tests": [ { "description": "set: nested ArrayUnion field", "comment": "An ArrayUnion value can occur at any depth. In this case,\nthe transform applies to the field path \"b.c\". Since \"c\" is removed from the update,\n\"b\" becomes empty, so it is also removed from the update.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1, \"b\": {\"c\": [\"ArrayUnion\", 1, 2, 3]}}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b.c", "appendMissingElements": { "values": [ { "integerValue": "1" }, { "integerValue": "2" }, { "integerValue": "3" } ] } } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-arrayunion-noarray-nested.json000066400000000000000000000007351356504100700333220ustar00rootroot00000000000000{ "tests": [ { "description": "set: ArrayUnion cannot be anywhere inside an array value", "comment": "There cannot be an array value anywhere on the path from the document\nroot to the ArrayUnion. Firestore transforms don't support array indexing.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": [1, {\"b\": [\"ArrayUnion\", 1, 2, 3]}]}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-arrayunion-noarray.json000066400000000000000000000006261356504100700320410ustar00rootroot00000000000000{ "tests": [ { "description": "set: ArrayUnion cannot be in an array value", "comment": "ArrayUnion must be the value of a field. Firestore\ntransforms don't support array indexing.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": [1, 2, [\"ArrayRemove\", 1, 2, 3]]}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-arrayunion-with-st.json000066400000000000000000000006631356504100700317660ustar00rootroot00000000000000{ "tests": [ { "description": "set: The ServerTimestamp sentinel cannot be in an ArrayUnion", "comment": "The ServerTimestamp sentinel must be the value of a field. It may\nnot appear in an ArrayUnion.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": [\"ArrayUnion\", 1, \"ServerTimestamp\", 3]}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-arrayunion.json000066400000000000000000000027641356504100700303750ustar00rootroot00000000000000{ "tests": [ { "description": "set: ArrayUnion with data", "comment": "A key with ArrayUnion is removed from the data in the update \noperation. Instead it appears in a separate Transform operation.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1, \"b\": [\"ArrayUnion\", 1, 2, 3]}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b", "appendMissingElements": { "values": [ { "integerValue": "1" }, { "integerValue": "2" }, { "integerValue": "3" } ] } } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-basic.json000066400000000000000000000012601356504100700272550ustar00rootroot00000000000000{ "tests": [ { "description": "set: basic", "comment": "A simple call, resulting in a single update operation.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-complex.json000066400000000000000000000034771356504100700276570ustar00rootroot00000000000000{ "tests": [ { "description": "set: complex", "comment": "A call to a write method with complicated input data.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": [1, 2.5], \"b\": {\"c\": [\"three\", {\"d\": true}]}}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "arrayValue": { "values": [ { "integerValue": "1" }, { "doubleValue": 2.5 } ] } }, "b": { "mapValue": { "fields": { "c": { "arrayValue": { "values": [ { "stringValue": "three" }, { "mapValue": { "fields": { "d": { "booleanValue": true } } } } ] } } } } } } } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-del-merge-alone.json000066400000000000000000000017411356504100700311350ustar00rootroot00000000000000{ "tests": [ { "description": "set-merge: Delete with merge", "comment": "A Delete sentinel can appear with a merge option. If the delete\npaths are the only ones to be merged, then no document is sent, just an update mask.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "option": { "fields": [ { "field": [ "b", "c" ] } ] }, "jsonData": "{\"a\": 1, \"b\": {\"c\": \"Delete\"}}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d" }, "updateMask": { "fieldPaths": [ "b.c" ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-del-merge.json000066400000000000000000000021621356504100700300370ustar00rootroot00000000000000{ "tests": [ { "description": "set-merge: Delete with merge", "comment": "A Delete sentinel can appear with a merge option.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "option": { "fields": [ { "field": [ "a" ] }, { "field": [ "b", "c" ] } ] }, "jsonData": "{\"a\": 1, \"b\": {\"c\": \"Delete\"}}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "updateMask": { "fieldPaths": [ "a", "b.c" ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-del-mergeall.json000066400000000000000000000016361356504100700305350ustar00rootroot00000000000000{ "tests": [ { "description": "set: Delete with MergeAll", "comment": "A Delete sentinel can appear with a mergeAll option.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "option": { "all": true }, "jsonData": "{\"a\": 1, \"b\": {\"c\": \"Delete\"}}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "updateMask": { "fieldPaths": [ "a", "b.c" ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-del-noarray-nested.json000066400000000000000000000007571356504100700317030ustar00rootroot00000000000000{ "tests": [ { "description": "set: Delete cannot be anywhere inside an array value", "comment": "The Delete sentinel must be the value of a field. Deletes are implemented\nby turning the path to the Delete sentinel into a FieldPath, and FieldPaths do not support\narray indexing.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": [1, {\"b\": \"Delete\"}]}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-del-noarray.json000066400000000000000000000007341356504100700304160ustar00rootroot00000000000000{ "tests": [ { "description": "set: Delete cannot be in an array value", "comment": "The Delete sentinel must be the value of a field. Deletes are\nimplemented by turning the path to the Delete sentinel into a FieldPath, and FieldPaths\ndo not support array indexing.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": [1, 2, \"Delete\"]}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-del-nomerge.json000066400000000000000000000011541356504100700303740ustar00rootroot00000000000000{ "tests": [ { "description": "set-merge: Delete cannot appear in an unmerged field", "comment": "The client signals an error if the Delete sentinel is in the\ninput data, but not selected by a merge option, because this is most likely a programming\nbug.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "option": { "fields": [ { "field": [ "a" ] } ] }, "jsonData": "{\"a\": 1, \"b\": \"Delete\"}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-del-nonleaf.json000066400000000000000000000013371356504100700303650ustar00rootroot00000000000000{ "tests": [ { "description": "set-merge: Delete cannot appear as part of a merge path", "comment": "If a Delete is part of the value at a merge path, then the user is\nconfused: their merge path says \"replace this entire value\" but their Delete says\n\"delete this part of the value\". This should be an error, just as if they specified Delete\nin a Set with no merge.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "option": { "fields": [ { "field": [ "h" ] } ] }, "jsonData": "{\"h\": {\"g\": \"Delete\"}}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-del-wo-merge.json000066400000000000000000000006771356504100700304730ustar00rootroot00000000000000{ "tests": [ { "description": "set: Delete cannot appear unless a merge option is specified", "comment": "Without a merge option, Set replaces the document with the input\ndata. A Delete sentinel in the data makes no sense in this case.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1, \"b\": \"Delete\"}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-empty.json000066400000000000000000000010221356504100700273260ustar00rootroot00000000000000{ "tests": [ { "description": "set: creating or setting an empty map", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": {} } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-merge-fp.json000066400000000000000000000022521356504100700277000ustar00rootroot00000000000000{ "tests": [ { "description": "set-merge: Merge with FieldPaths", "comment": "A merge with fields that use special characters.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "option": { "fields": [ { "field": [ "*", "~" ] } ] }, "jsonData": "{\"*\": {\"~\": true}}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "*": { "mapValue": { "fields": { "~": { "booleanValue": true } } } } } }, "updateMask": { "fieldPaths": [ "`*`.`~`" ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-merge-nested.json000066400000000000000000000023751356504100700305630ustar00rootroot00000000000000{ "tests": [ { "description": "set-merge: Merge with a nested field", "comment": "A merge option where the field is not at top level.\nOnly fields mentioned in the option are present in the update operation.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "option": { "fields": [ { "field": [ "h", "g" ] } ] }, "jsonData": "{\"h\": {\"g\": 4, \"f\": 5}}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "h": { "mapValue": { "fields": { "g": { "integerValue": "4" } } } } } }, "updateMask": { "fieldPaths": [ "h.g" ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-merge-nonleaf.json000066400000000000000000000025361356504100700307220ustar00rootroot00000000000000{ "tests": [ { "description": "set-merge: Merge field is not a leaf", "comment": "If a field path is in a merge option, the value at that path\nreplaces the stored value. That is true even if the value is complex.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "option": { "fields": [ { "field": [ "h" ] } ] }, "jsonData": "{\"h\": {\"f\": 5, \"g\": 6}, \"e\": 7}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "h": { "mapValue": { "fields": { "f": { "integerValue": "5" }, "g": { "integerValue": "6" } } } } } }, "updateMask": { "fieldPaths": [ "h" ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-merge-prefix.json000066400000000000000000000012241356504100700305660ustar00rootroot00000000000000{ "tests": [ { "description": "set-merge: One merge path cannot be the prefix of another", "comment": "The prefix would make the other path meaningless, so this is\nprobably a programming error.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "option": { "fields": [ { "field": [ "a" ] }, { "field": [ "a", "b" ] } ] }, "jsonData": "{\"a\": {\"b\": 1}}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-merge-present.json000066400000000000000000000011621356504100700307520ustar00rootroot00000000000000{ "tests": [ { "description": "set-merge: Merge fields must all be present in data", "comment": "The client signals an error if a merge option mentions a path\nthat is not in the input data.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "option": { "fields": [ { "field": [ "b" ] }, { "field": [ "a" ] } ] }, "jsonData": "{\"a\": 1}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-merge.json000066400000000000000000000017461356504100700273040ustar00rootroot00000000000000{ "tests": [ { "description": "set-merge: Merge with a field", "comment": "Fields in the input data but not in a merge option are pruned.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "option": { "fields": [ { "field": [ "a" ] } ] }, "jsonData": "{\"a\": 1, \"b\": 2}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "updateMask": { "fieldPaths": [ "a" ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-mergeall-empty.json000066400000000000000000000013701356504100700311220ustar00rootroot00000000000000{ "tests": [ { "description": "set: MergeAll can be specified with empty data.", "comment": "This is a valid call that can be used to ensure a document exists.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "option": { "all": true }, "jsonData": "{}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": {} }, "updateMask": { "fieldPaths": [] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-mergeall-nested.json000066400000000000000000000023521356504100700312470ustar00rootroot00000000000000{ "tests": [ { "description": "set: MergeAll with nested fields", "comment": "MergeAll with nested fields results in an update mask that\nincludes entries for all the leaf fields.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "option": { "all": true }, "jsonData": "{\"h\": { \"g\": 3, \"f\": 4 }}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "h": { "mapValue": { "fields": { "f": { "integerValue": "4" }, "g": { "integerValue": "3" } } } } } }, "updateMask": { "fieldPaths": [ "h.f", "h.g" ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-mergeall.json000066400000000000000000000017201356504100700277650ustar00rootroot00000000000000{ "tests": [ { "description": "set: MergeAll", "comment": "The MergeAll option with a simple piece of data.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "option": { "all": true }, "jsonData": "{\"a\": 1, \"b\": 2}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" }, "b": { "integerValue": "2" } } }, "updateMask": { "fieldPaths": [ "a", "b" ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-nodel.json000066400000000000000000000005611356504100700273000ustar00rootroot00000000000000{ "tests": [ { "description": "set: Delete cannot appear in data", "comment": "The Delete sentinel cannot be used in Create, or in Set without a Merge option.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1, \"b\": \"Delete\"}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-nosplit.json000066400000000000000000000017711356504100700276730ustar00rootroot00000000000000{ "tests": [ { "description": "set: don’t split on dots", "comment": "Create and Set treat their map keys literally. They do not split on dots.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{ \"a.b\": { \"c.d\": 1 }, \"e\": 2 }", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a.b": { "mapValue": { "fields": { "c.d": { "integerValue": "1" } } } }, "e": { "integerValue": "2" } } } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-special-chars.json000066400000000000000000000020101356504100700307040ustar00rootroot00000000000000{ "tests": [ { "description": "set: non-alpha characters in map keys", "comment": "Create and Set treat their map keys literally. They do not escape special characters.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{ \"*\": { \".\": 1 }, \"~\": 2 }", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "*": { "mapValue": { "fields": { ".": { "integerValue": "1" } } } }, "~": { "integerValue": "2" } } } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-st-alone-mergeall.json000066400000000000000000000016021356504100700315040ustar00rootroot00000000000000{ "tests": [ { "description": "set: ServerTimestamp alone with MergeAll", "comment": "If the only values in the input are ServerTimestamps, then no\nupdate operation should be produced.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "option": { "all": true }, "jsonData": "{\"a\": \"ServerTimestamp\"}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "a", "setToServerValue": "REQUEST_TIME" } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-st-alone.json000066400000000000000000000020051356504100700277140ustar00rootroot00000000000000{ "tests": [ { "description": "set: ServerTimestamp alone", "comment": "If the only values in the input are ServerTimestamps, then\nan update operation with an empty map should be produced.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": \"ServerTimestamp\"}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": {} } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "a", "setToServerValue": "REQUEST_TIME" } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-st-merge-both.json000066400000000000000000000030321356504100700306500ustar00rootroot00000000000000{ "tests": [ { "description": "set-merge: ServerTimestamp with Merge of both fields", "comment": "Just as when no merge option is specified, ServerTimestamp\nsentinel values are removed from the data in the update operation and become\ntransforms.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "option": { "fields": [ { "field": [ "a" ] }, { "field": [ "b" ] } ] }, "jsonData": "{\"a\": 1, \"b\": \"ServerTimestamp\"}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "updateMask": { "fieldPaths": [ "a" ] } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b", "setToServerValue": "REQUEST_TIME" } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-st-merge-nonleaf-alone.json000066400000000000000000000026271356504100700324430ustar00rootroot00000000000000{ "tests": [ { "description": "set-merge: non-leaf merge field with ServerTimestamp alone", "comment": "If a field path is in a merge option, the value at that path\nreplaces the stored value. If the value has only ServerTimestamps, they become transforms\nand we clear the value by including the field path in the update mask.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "option": { "fields": [ { "field": [ "h" ] } ] }, "jsonData": "{\"h\": {\"g\": \"ServerTimestamp\"}, \"e\": 7}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d" }, "updateMask": { "fieldPaths": [ "h" ] } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "h.g", "setToServerValue": "REQUEST_TIME" } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-st-merge-nonleaf.json000066400000000000000000000032151356504100700313410ustar00rootroot00000000000000{ "tests": [ { "description": "set-merge: non-leaf merge field with ServerTimestamp", "comment": "If a field path is in a merge option, the value at that path\nreplaces the stored value, and ServerTimestamps inside that value become transforms\nas usual.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "option": { "fields": [ { "field": [ "h" ] } ] }, "jsonData": "{\"h\": {\"f\": 5, \"g\": \"ServerTimestamp\"}, \"e\": 7}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "h": { "mapValue": { "fields": { "f": { "integerValue": "5" } } } } } }, "updateMask": { "fieldPaths": [ "h" ] } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "h.g", "setToServerValue": "REQUEST_TIME" } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-st-merge-nowrite.json000066400000000000000000000020241356504100700314030ustar00rootroot00000000000000{ "tests": [ { "description": "set-merge: If no ordinary values in Merge, no write", "comment": "If all the fields in the merge option have ServerTimestamp\nvalues, then no update operation is produced, only a transform.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "option": { "fields": [ { "field": [ "b" ] } ] }, "jsonData": "{\"a\": 1, \"b\": \"ServerTimestamp\"}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b", "setToServerValue": "REQUEST_TIME" } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-st-mergeall.json000066400000000000000000000025111356504100700304100ustar00rootroot00000000000000{ "tests": [ { "description": "set: ServerTimestamp with MergeAll", "comment": "Just as when no merge option is specified, ServerTimestamp\nsentinel values are removed from the data in the update operation and become\ntransforms.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "option": { "all": true }, "jsonData": "{\"a\": 1, \"b\": \"ServerTimestamp\"}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "updateMask": { "fieldPaths": [ "a" ] } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b", "setToServerValue": "REQUEST_TIME" } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-st-multi.json000066400000000000000000000025111356504100700277520ustar00rootroot00000000000000{ "tests": [ { "description": "set: multiple ServerTimestamp fields", "comment": "A document can have more than one ServerTimestamp field.\nSince all the ServerTimestamp fields are removed, the only field in the update is \"a\".", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1, \"b\": \"ServerTimestamp\", \"c\": {\"d\": \"ServerTimestamp\"}}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b", "setToServerValue": "REQUEST_TIME" }, { "fieldPath": "c.d", "setToServerValue": "REQUEST_TIME" } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-st-nested.json000066400000000000000000000023461356504100700301100ustar00rootroot00000000000000{ "tests": [ { "description": "set: nested ServerTimestamp field", "comment": "A ServerTimestamp value can occur at any depth. In this case,\nthe transform applies to the field path \"b.c\". Since \"c\" is removed from the update,\n\"b\" becomes empty, so it is also removed from the update.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1, \"b\": {\"c\": \"ServerTimestamp\"}}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b.c", "setToServerValue": "REQUEST_TIME" } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-st-noarray-nested.json000066400000000000000000000007521356504100700315600ustar00rootroot00000000000000{ "tests": [ { "description": "set: ServerTimestamp cannot be anywhere inside an array value", "comment": "There cannot be an array value anywhere on the path from the document\nroot to the ServerTimestamp sentinel. Firestore transforms don't support array indexing.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": [1, {\"b\": \"ServerTimestamp\"}]}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-st-noarray.json000066400000000000000000000006461356504100700303020ustar00rootroot00000000000000{ "tests": [ { "description": "set: ServerTimestamp cannot be in an array value", "comment": "The ServerTimestamp sentinel must be the value of a field. Firestore\ntransforms don't support array indexing.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": [1, 2, \"ServerTimestamp\"]}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-st-nomerge.json000066400000000000000000000021351356504100700302560ustar00rootroot00000000000000{ "tests": [ { "description": "set-merge: If is ServerTimestamp not in Merge, no transform", "comment": "If the ServerTimestamp value is not mentioned in a merge option,\nthen it is pruned from the data but does not result in a transform.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "option": { "fields": [ { "field": [ "a" ] } ] }, "jsonData": "{\"a\": 1, \"b\": \"ServerTimestamp\"}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "updateMask": { "fieldPaths": [ "a" ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-st-with-empty-map.json000066400000000000000000000026211356504100700315040ustar00rootroot00000000000000{ "tests": [ { "description": "set: ServerTimestamp beside an empty map", "comment": "When a ServerTimestamp and a map both reside inside a map, the\nServerTimestamp should be stripped out but the empty map should remain.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": {\"b\": {}, \"c\": \"ServerTimestamp\"}}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "mapValue": { "fields": { "b": { "mapValue": { "fields": {} } } } } } } } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "a.c", "setToServerValue": "REQUEST_TIME" } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/set-st.json000066400000000000000000000024221356504100700266230ustar00rootroot00000000000000{ "tests": [ { "description": "set: ServerTimestamp with data", "comment": "A key with the special ServerTimestamp sentinel is removed from\nthe data in the update operation. Instead it appears in a separate Transform operation.\nNote that in these tests, the string \"ServerTimestamp\" should be replaced with the\nspecial ServerTimestamp value.", "set": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1, \"b\": \"ServerTimestamp\"}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b", "setToServerValue": "REQUEST_TIME" } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-all-transforms.json000066400000000000000000000045001356504100700316270ustar00rootroot00000000000000{ "tests": [ { "description": "update: all transforms in a single call", "comment": "A document can be created with any amount of transforms.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1, \"b\": \"ServerTimestamp\", \"c\": [\"ArrayUnion\", 1, 2, 3], \"d\": [\"ArrayRemove\", 4, 5, 6]}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "updateMask": { "fieldPaths": [ "a" ] }, "currentDocument": { "exists": true } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b", "setToServerValue": "REQUEST_TIME" }, { "fieldPath": "c", "appendMissingElements": { "values": [ { "integerValue": "1" }, { "integerValue": "2" }, { "integerValue": "3" } ] } }, { "fieldPath": "d", "removeAllFromArray": { "values": [ { "integerValue": "4" }, { "integerValue": "5" }, { "integerValue": "6" } ] } } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-arrayremove-alone.json000066400000000000000000000024031356504100700323130ustar00rootroot00000000000000{ "tests": [ { "description": "update: ArrayRemove alone", "comment": "If the only values in the input are ArrayRemove, then no\nupdate operation should be produced.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": [\"ArrayRemove\", 1, 2, 3]}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "a", "removeAllFromArray": { "values": [ { "integerValue": "1" }, { "integerValue": "2" }, { "integerValue": "3" } ] } } ] }, "currentDocument": { "exists": true } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-arrayremove-multi.json000066400000000000000000000044141356504100700323530ustar00rootroot00000000000000{ "tests": [ { "description": "update: multiple ArrayRemove fields", "comment": "A document can have more than one ArrayRemove field.\nSince all the ArrayRemove fields are removed, the only field in the update is \"a\".", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1, \"b\": [\"ArrayRemove\", 1, 2, 3], \"c\": {\"d\": [\"ArrayRemove\", 4, 5, 6]}}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "updateMask": { "fieldPaths": [ "a", "c" ] }, "currentDocument": { "exists": true } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b", "removeAllFromArray": { "values": [ { "integerValue": "1" }, { "integerValue": "2" }, { "integerValue": "3" } ] } }, { "fieldPath": "c.d", "removeAllFromArray": { "values": [ { "integerValue": "4" }, { "integerValue": "5" }, { "integerValue": "6" } ] } } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-arrayremove-nested.json000066400000000000000000000034721356504100700325060ustar00rootroot00000000000000{ "tests": [ { "description": "update: nested ArrayRemove field", "comment": "An ArrayRemove value can occur at any depth. In this case,\nthe transform applies to the field path \"b.c\". Since \"c\" is removed from the update,\n\"b\" becomes empty, so it is also removed from the update.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1, \"b\": {\"c\": [\"ArrayRemove\", 1, 2, 3]}}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "updateMask": { "fieldPaths": [ "a", "b" ] }, "currentDocument": { "exists": true } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b.c", "removeAllFromArray": { "values": [ { "integerValue": "1" }, { "integerValue": "2" }, { "integerValue": "3" } ] } } ] } } ] } } } ] } update-arrayremove-noarray-nested.json000066400000000000000000000007461356504100700341010ustar00rootroot00000000000000google-cloud-go-0.49.0/firestore/internal/conformance/testdata{ "tests": [ { "description": "update: ArrayRemove cannot be anywhere inside an array value", "comment": "There cannot be an array value anywhere on the path from the document\nroot to the ArrayRemove. Firestore transforms don't support array indexing.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": [1, {\"b\": [\"ArrayRemove\", 1, 2, 3]}]}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-arrayremove-noarray.json000066400000000000000000000006361356504100700326760ustar00rootroot00000000000000{ "tests": [ { "description": "update: ArrayRemove cannot be in an array value", "comment": "ArrayRemove must be the value of a field. Firestore\ntransforms don't support array indexing.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": [1, 2, [\"ArrayRemove\", 1, 2, 3]]}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-arrayremove-with-st.json000066400000000000000000000006721356504100700326220ustar00rootroot00000000000000{ "tests": [ { "description": "update: The ServerTimestamp sentinel cannot be in an ArrayUnion", "comment": "The ServerTimestamp sentinel must be the value of a field. It may\nnot appear in an ArrayUnion.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": [\"ArrayRemove\", 1, \"ServerTimestamp\", 3]}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-arrayremove.json000066400000000000000000000033041356504100700312200ustar00rootroot00000000000000{ "tests": [ { "description": "update: ArrayRemove with data", "comment": "A key with ArrayRemove is removed from the data in the update \noperation. Instead it appears in a separate Transform operation.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1, \"b\": [\"ArrayRemove\", 1, 2, 3]}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "updateMask": { "fieldPaths": [ "a" ] }, "currentDocument": { "exists": true } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b", "removeAllFromArray": { "values": [ { "integerValue": "1" }, { "integerValue": "2" }, { "integerValue": "3" } ] } } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-arrayunion-alone.json000066400000000000000000000024031356504100700321460ustar00rootroot00000000000000{ "tests": [ { "description": "update: ArrayUnion alone", "comment": "If the only values in the input are ArrayUnion, then no\nupdate operation should be produced.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": [\"ArrayUnion\", 1, 2, 3]}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "a", "appendMissingElements": { "values": [ { "integerValue": "1" }, { "integerValue": "2" }, { "integerValue": "3" } ] } } ] }, "currentDocument": { "exists": true } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-arrayunion-multi.json000066400000000000000000000044151356504100700322070ustar00rootroot00000000000000{ "tests": [ { "description": "update: multiple ArrayUnion fields", "comment": "A document can have more than one ArrayUnion field.\nSince all the ArrayUnion fields are removed, the only field in the update is \"a\".", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1, \"b\": [\"ArrayUnion\", 1, 2, 3], \"c\": {\"d\": [\"ArrayUnion\", 4, 5, 6]}}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "updateMask": { "fieldPaths": [ "a", "c" ] }, "currentDocument": { "exists": true } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b", "appendMissingElements": { "values": [ { "integerValue": "1" }, { "integerValue": "2" }, { "integerValue": "3" } ] } }, { "fieldPath": "c.d", "appendMissingElements": { "values": [ { "integerValue": "4" }, { "integerValue": "5" }, { "integerValue": "6" } ] } } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-arrayunion-nested.json000066400000000000000000000034721356504100700323410ustar00rootroot00000000000000{ "tests": [ { "description": "update: nested ArrayUnion field", "comment": "An ArrayUnion value can occur at any depth. In this case,\nthe transform applies to the field path \"b.c\". Since \"c\" is removed from the update,\n\"b\" becomes empty, so it is also removed from the update.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1, \"b\": {\"c\": [\"ArrayUnion\", 1, 2, 3]}}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "updateMask": { "fieldPaths": [ "a", "b" ] }, "currentDocument": { "exists": true } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b.c", "appendMissingElements": { "values": [ { "integerValue": "1" }, { "integerValue": "2" }, { "integerValue": "3" } ] } } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-arrayunion-noarray-nested.json000066400000000000000000000007431356504100700340100ustar00rootroot00000000000000{ "tests": [ { "description": "update: ArrayUnion cannot be anywhere inside an array value", "comment": "There cannot be an array value anywhere on the path from the document\nroot to the ArrayUnion. Firestore transforms don't support array indexing.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": [1, {\"b\": [\"ArrayUnion\", 1, 2, 3]}]}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-arrayunion-noarray.json000066400000000000000000000006341356504100700325270ustar00rootroot00000000000000{ "tests": [ { "description": "update: ArrayUnion cannot be in an array value", "comment": "ArrayUnion must be the value of a field. Firestore\ntransforms don't support array indexing.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": [1, 2, [\"ArrayRemove\", 1, 2, 3]]}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-arrayunion-with-st.json000066400000000000000000000006711356504100700324540ustar00rootroot00000000000000{ "tests": [ { "description": "update: The ServerTimestamp sentinel cannot be in an ArrayUnion", "comment": "The ServerTimestamp sentinel must be the value of a field. It may\nnot appear in an ArrayUnion.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": [\"ArrayUnion\", 1, \"ServerTimestamp\", 3]}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-arrayunion.json000066400000000000000000000033041356504100700310530ustar00rootroot00000000000000{ "tests": [ { "description": "update: ArrayUnion with data", "comment": "A key with ArrayUnion is removed from the data in the update \noperation. Instead it appears in a separate Transform operation.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1, \"b\": [\"ArrayUnion\", 1, 2, 3]}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "updateMask": { "fieldPaths": [ "a" ] }, "currentDocument": { "exists": true } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b", "appendMissingElements": { "values": [ { "integerValue": "1" }, { "integerValue": "2" }, { "integerValue": "3" } ] } } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-badchar.json000066400000000000000000000006111356504100700302460ustar00rootroot00000000000000{ "tests": [ { "description": "update: invalid character", "comment": "The keys of the data given to Update are interpreted, unlike those of Create and Set. They cannot contain special characters.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a~b\": 1}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-basic.json000066400000000000000000000016001356504100700277420ustar00rootroot00000000000000{ "tests": [ { "description": "update: basic", "comment": "A simple call, resulting in a single update operation.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "updateMask": { "fieldPaths": [ "a" ] }, "currentDocument": { "exists": true } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-complex.json000066400000000000000000000040461356504100700303370ustar00rootroot00000000000000{ "tests": [ { "description": "update: complex", "comment": "A call to a write method with complicated input data.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": [1, 2.5], \"b\": {\"c\": [\"three\", {\"d\": true}]}}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "arrayValue": { "values": [ { "integerValue": "1" }, { "doubleValue": 2.5 } ] } }, "b": { "mapValue": { "fields": { "c": { "arrayValue": { "values": [ { "stringValue": "three" }, { "mapValue": { "fields": { "d": { "booleanValue": true } } } } ] } } } } } } }, "updateMask": { "fieldPaths": [ "a", "b" ] }, "currentDocument": { "exists": true } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-del-alone.json000066400000000000000000000014771356504100700305350ustar00rootroot00000000000000{ "tests": [ { "description": "update: Delete alone", "comment": "If the input data consists solely of Deletes, then the update\noperation has no map, just an update mask.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": \"Delete\"}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d" }, "updateMask": { "fieldPaths": [ "a" ] }, "currentDocument": { "exists": true } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-del-dot.json000066400000000000000000000024741356504100700302230ustar00rootroot00000000000000{ "tests": [ { "description": "update: Delete with a dotted field", "comment": "After expanding top-level dotted fields, fields with Delete\nvalues are pruned from the output data, but appear in the update mask.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1, \"b.c\": \"Delete\", \"b.d\": 2}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" }, "b": { "mapValue": { "fields": { "d": { "integerValue": "2" } } } } } }, "updateMask": { "fieldPaths": [ "a", "b.c", "b.d" ] }, "currentDocument": { "exists": true } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-del-nested.json000066400000000000000000000005331356504100700307110ustar00rootroot00000000000000{ "tests": [ { "description": "update: Delete cannot be nested", "comment": "The Delete sentinel must be the value of a top-level key.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": {\"b\": \"Delete\"}}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-del-noarray-nested.json000066400000000000000000000007651356504100700323710ustar00rootroot00000000000000{ "tests": [ { "description": "update: Delete cannot be anywhere inside an array value", "comment": "The Delete sentinel must be the value of a field. Deletes are implemented\nby turning the path to the Delete sentinel into a FieldPath, and FieldPaths do not support\narray indexing.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": [1, {\"b\": \"Delete\"}]}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-del-noarray.json000066400000000000000000000007421356504100700311040ustar00rootroot00000000000000{ "tests": [ { "description": "update: Delete cannot be in an array value", "comment": "The Delete sentinel must be the value of a field. Deletes are\nimplemented by turning the path to the Delete sentinel into a FieldPath, and FieldPaths\ndo not support array indexing.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": [1, 2, \"Delete\"]}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-del.json000066400000000000000000000017411356504100700274330ustar00rootroot00000000000000{ "tests": [ { "description": "update: Delete", "comment": "If a field's value is the Delete sentinel, then it doesn't appear\nin the update data, but does in the mask.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1, \"b\": \"Delete\"}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "updateMask": { "fieldPaths": [ "a", "b" ] }, "currentDocument": { "exists": true } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-exists-precond.json000066400000000000000000000006301356504100700316320ustar00rootroot00000000000000{ "tests": [ { "description": "update: Exists precondition is invalid", "comment": "The Update method does not support an explicit exists precondition.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "precondition": { "exists": true }, "jsonData": "{\"a\": 1}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-fp-empty-component.json000066400000000000000000000004631356504100700324300ustar00rootroot00000000000000{ "tests": [ { "description": "update: empty field path component", "comment": "Empty fields are not allowed.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a..b\": 1}", "isError": true } } ] } update-nested-transform-and-nested-value.json000066400000000000000000000045461356504100700352430ustar00rootroot00000000000000google-cloud-go-0.49.0/firestore/internal/conformance/testdata{ "tests": [ { "description": "update: Nested transforms should not affect the field mask, even\nwhen there are other values that do. Transforms should only affect the\nDocumentTransform_FieldTransform list.", "comment": "For updates, top-level paths in json-like map inputs\nare split on the dot. That is, an input {\"a.b.c\": 7} results in an update to\nfield c of object b of object a with value 7. In order to specify this behavior,\nthe update must use a fieldmask \"a.b.c\". However, fieldmasks are only used for\nconcrete values - transforms are separately encoded in a\nDocumentTransform_FieldTransform array.\n\nThis test exercises a bug found in python (https://github.com/googleapis/google-cloud-python/issues/7215)\nin which nested transforms ({\"a.c\": \"ServerTimestamp\"}) next to nested values\n({\"a.b\": 7}) incorrectly caused the fieldmask \"a\" to be set, which has the\neffect of wiping out all data in \"a\" other than what was specified in the\njson-like input.\n\nInstead, as this test specifies, transforms should not affect the fieldmask.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a.b\": 7, \"a.c\": \"ServerTimestamp\"}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "mapValue": { "fields": { "b": { "integerValue": "7" } } } } } }, "updateMask": { "fieldPaths": [ "a.b" ] }, "currentDocument": { "exists": true } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "a.c", "setToServerValue": "REQUEST_TIME" } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-no-paths.json000066400000000000000000000004621356504100700304170ustar00rootroot00000000000000{ "tests": [ { "description": "update: no paths", "comment": "It is a client-side error to call Update with empty data.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-all-transforms.json000066400000000000000000000053131356504100700327470ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: all transforms in a single call", "comment": "A document can be created with any amount of transforms.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "a" ] }, { "field": [ "b" ] }, { "field": [ "c" ] }, { "field": [ "d" ] } ], "jsonValues": [ "1", "\"ServerTimestamp\"", "[\"ArrayUnion\", 1, 2, 3]", "[\"ArrayRemove\", 4, 5, 6]" ], "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "updateMask": { "fieldPaths": [ "a" ] }, "currentDocument": { "exists": true } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b", "setToServerValue": "REQUEST_TIME" }, { "fieldPath": "c", "appendMissingElements": { "values": [ { "integerValue": "1" }, { "integerValue": "2" }, { "integerValue": "3" } ] } }, { "fieldPath": "d", "removeAllFromArray": { "values": [ { "integerValue": "4" }, { "integerValue": "5" }, { "integerValue": "6" } ] } } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-arrayremove-alone.json000066400000000000000000000026171356504100700334370ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: ArrayRemove alone", "comment": "If the only values in the input are ArrayRemove, then no\nupdate operation should be produced.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "a" ] } ], "jsonValues": [ "[\"ArrayRemove\", 1, 2, 3]" ], "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "a", "removeAllFromArray": { "values": [ { "integerValue": "1" }, { "integerValue": "2" }, { "integerValue": "3" } ] } } ] }, "currentDocument": { "exists": true } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-arrayremove-multi.json000066400000000000000000000051021356504100700334630ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: multiple ArrayRemove fields", "comment": "A document can have more than one ArrayRemove field.\nSince all the ArrayRemove fields are removed, the only field in the update is \"a\".", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "a" ] }, { "field": [ "b" ] }, { "field": [ "c" ] } ], "jsonValues": [ "1", "[\"ArrayRemove\", 1, 2, 3]", "{\"d\": [\"ArrayRemove\", 4, 5, 6]}" ], "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "updateMask": { "fieldPaths": [ "a", "c" ] }, "currentDocument": { "exists": true } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b", "removeAllFromArray": { "values": [ { "integerValue": "1" }, { "integerValue": "2" }, { "integerValue": "3" } ] } }, { "fieldPath": "c.d", "removeAllFromArray": { "values": [ { "integerValue": "4" }, { "integerValue": "5" }, { "integerValue": "6" } ] } } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-arrayremove-nested.json000066400000000000000000000040331356504100700336150ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: nested ArrayRemove field", "comment": "An ArrayRemove value can occur at any depth. In this case,\nthe transform applies to the field path \"b.c\". Since \"c\" is removed from the update,\n\"b\" becomes empty, so it is also removed from the update.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "a" ] }, { "field": [ "b" ] } ], "jsonValues": [ "1", "{\"c\": [\"ArrayRemove\", 1, 2, 3]}" ], "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "updateMask": { "fieldPaths": [ "a", "b" ] }, "currentDocument": { "exists": true } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b.c", "removeAllFromArray": { "values": [ { "integerValue": "1" }, { "integerValue": "2" }, { "integerValue": "3" } ] } } ] } } ] } } } ] } update-paths-arrayremove-noarray-nested.json000066400000000000000000000011621356504100700352070ustar00rootroot00000000000000google-cloud-go-0.49.0/firestore/internal/conformance/testdata{ "tests": [ { "description": "update-paths: ArrayRemove cannot be anywhere inside an array value", "comment": "There cannot be an array value anywhere on the path from the document\nroot to the ArrayRemove. Firestore transforms don't support array indexing.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "a" ] } ], "jsonValues": [ "[1, {\"b\": [\"ArrayRemove\", 1, 2, 3]}]" ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-arrayremove-noarray.json000066400000000000000000000010521356504100700340040ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: ArrayRemove cannot be in an array value", "comment": "ArrayRemove must be the value of a field. Firestore\ntransforms don't support array indexing.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "a" ] } ], "jsonValues": [ "[1, 2, [\"ArrayRemove\", 1, 2, 3]]" ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-arrayremove-with-st.json000066400000000000000000000011061356504100700337300ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: The ServerTimestamp sentinel cannot be in an ArrayUnion", "comment": "The ServerTimestamp sentinel must be the value of a field. It may\nnot appear in an ArrayUnion.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "a" ] } ], "jsonValues": [ "[\"ArrayRemove\", 1, \"ServerTimestamp\", 3]" ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-arrayremove.json000066400000000000000000000036451356504100700323450ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: ArrayRemove with data", "comment": "A key with ArrayRemove is removed from the data in the update \noperation. Instead it appears in a separate Transform operation.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "a" ] }, { "field": [ "b" ] } ], "jsonValues": [ "1", "[\"ArrayRemove\", 1, 2, 3]" ], "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "updateMask": { "fieldPaths": [ "a" ] }, "currentDocument": { "exists": true } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b", "removeAllFromArray": { "values": [ { "integerValue": "1" }, { "integerValue": "2" }, { "integerValue": "3" } ] } } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-arrayunion-alone.json000066400000000000000000000026171356504100700332720ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: ArrayUnion alone", "comment": "If the only values in the input are ArrayUnion, then no\nupdate operation should be produced.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "a" ] } ], "jsonValues": [ "[\"ArrayUnion\", 1, 2, 3]" ], "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "a", "appendMissingElements": { "values": [ { "integerValue": "1" }, { "integerValue": "2" }, { "integerValue": "3" } ] } } ] }, "currentDocument": { "exists": true } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-arrayunion-multi.json000066400000000000000000000051031356504100700333170ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: multiple ArrayUnion fields", "comment": "A document can have more than one ArrayUnion field.\nSince all the ArrayUnion fields are removed, the only field in the update is \"a\".", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "a" ] }, { "field": [ "b" ] }, { "field": [ "c" ] } ], "jsonValues": [ "1", "[\"ArrayUnion\", 1, 2, 3]", "{\"d\": [\"ArrayUnion\", 4, 5, 6]}" ], "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "updateMask": { "fieldPaths": [ "a", "c" ] }, "currentDocument": { "exists": true } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b", "appendMissingElements": { "values": [ { "integerValue": "1" }, { "integerValue": "2" }, { "integerValue": "3" } ] } }, { "fieldPath": "c.d", "appendMissingElements": { "values": [ { "integerValue": "4" }, { "integerValue": "5" }, { "integerValue": "6" } ] } } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-arrayunion-nested.json000066400000000000000000000040331356504100700334500ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: nested ArrayUnion field", "comment": "An ArrayUnion value can occur at any depth. In this case,\nthe transform applies to the field path \"b.c\". Since \"c\" is removed from the update,\n\"b\" becomes empty, so it is also removed from the update.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "a" ] }, { "field": [ "b" ] } ], "jsonValues": [ "1", "{\"c\": [\"ArrayUnion\", 1, 2, 3]}" ], "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "updateMask": { "fieldPaths": [ "a", "b" ] }, "currentDocument": { "exists": true } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b.c", "appendMissingElements": { "values": [ { "integerValue": "1" }, { "integerValue": "2" }, { "integerValue": "3" } ] } } ] } } ] } } } ] } update-paths-arrayunion-noarray-nested.json000066400000000000000000000011571356504100700350460ustar00rootroot00000000000000google-cloud-go-0.49.0/firestore/internal/conformance/testdata{ "tests": [ { "description": "update-paths: ArrayUnion cannot be anywhere inside an array value", "comment": "There cannot be an array value anywhere on the path from the document\nroot to the ArrayUnion. Firestore transforms don't support array indexing.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "a" ] } ], "jsonValues": [ "[1, {\"b\": [\"ArrayUnion\", 1, 2, 3]}]" ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-arrayunion-noarray.json000066400000000000000000000010501356504100700336350ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: ArrayUnion cannot be in an array value", "comment": "ArrayUnion must be the value of a field. Firestore\ntransforms don't support array indexing.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "a" ] } ], "jsonValues": [ "[1, 2, [\"ArrayRemove\", 1, 2, 3]]" ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-arrayunion-with-st.json000066400000000000000000000011051356504100700335620ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: The ServerTimestamp sentinel cannot be in an ArrayUnion", "comment": "The ServerTimestamp sentinel must be the value of a field. It may\nnot appear in an ArrayUnion.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "a" ] } ], "jsonValues": [ "[\"ArrayUnion\", 1, \"ServerTimestamp\", 3]" ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-arrayunion.json000066400000000000000000000036451356504100700322000ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: ArrayUnion with data", "comment": "A key with ArrayUnion is removed from the data in the update \noperation. Instead it appears in a separate Transform operation.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "a" ] }, { "field": [ "b" ] } ], "jsonValues": [ "1", "[\"ArrayUnion\", 1, 2, 3]" ], "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "updateMask": { "fieldPaths": [ "a" ] }, "currentDocument": { "exists": true } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b", "appendMissingElements": { "values": [ { "integerValue": "1" }, { "integerValue": "2" }, { "integerValue": "3" } ] } } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-basic.json000066400000000000000000000020141356504100700310570ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: basic", "comment": "A simple call, resulting in a single update operation.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "a" ] } ], "jsonValues": [ "1" ], "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "updateMask": { "fieldPaths": [ "a" ] }, "currentDocument": { "exists": true } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-complex.json000066400000000000000000000044071356504100700314550ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: complex", "comment": "A call to a write method with complicated input data.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "a" ] }, { "field": [ "b" ] } ], "jsonValues": [ "[1, 2.5]", "{\"c\": [\"three\", {\"d\": true}]}" ], "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "arrayValue": { "values": [ { "integerValue": "1" }, { "doubleValue": 2.5 } ] } }, "b": { "mapValue": { "fields": { "c": { "arrayValue": { "values": [ { "stringValue": "three" }, { "mapValue": { "fields": { "d": { "booleanValue": true } } } } ] } } } } } } }, "updateMask": { "fieldPaths": [ "a", "b" ] }, "currentDocument": { "exists": true } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-del-alone.json000066400000000000000000000017131356504100700316430ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: Delete alone", "comment": "If the input data consists solely of Deletes, then the update\noperation has no map, just an update mask.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "a" ] } ], "jsonValues": [ "\"Delete\"" ], "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d" }, "updateMask": { "fieldPaths": [ "a" ] }, "currentDocument": { "exists": true } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-del-nested.json000066400000000000000000000007471356504100700320350ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: Delete cannot be nested", "comment": "The Delete sentinel must be the value of a top-level key.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "a" ] } ], "jsonValues": [ "{\"b\": \"Delete\"}" ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-del-noarray-nested.json000066400000000000000000000012011356504100700334700ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: Delete cannot be anywhere inside an array value", "comment": "The Delete sentinel must be the value of a field. Deletes are implemented\nby turning the path to the Delete sentinel into a FieldPath, and FieldPaths do not support\narray indexing.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "a" ] } ], "jsonValues": [ "[1, {\"b\": \"Delete\"}]" ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-del-noarray.json000066400000000000000000000011561356504100700322210ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: Delete cannot be in an array value", "comment": "The Delete sentinel must be the value of a field. Deletes are\nimplemented by turning the path to the Delete sentinel into a FieldPath, and FieldPaths\ndo not support array indexing.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "a" ] } ], "jsonValues": [ "[1, 2, \"Delete\"]" ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-del.json000066400000000000000000000023021356504100700305420ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: Delete", "comment": "If a field's value is the Delete sentinel, then it doesn't appear\nin the update data, but does in the mask.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "a" ] }, { "field": [ "b" ] } ], "jsonValues": [ "1", "\"Delete\"" ], "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "updateMask": { "fieldPaths": [ "a", "b" ] }, "currentDocument": { "exists": true } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-exists-precond.json000066400000000000000000000010441356504100700327470ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: Exists precondition is invalid", "comment": "The Update method does not support an explicit exists precondition.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "precondition": { "exists": true }, "fieldPaths": [ { "field": [ "a" ] } ], "jsonValues": [ "1" ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-fp-del.json000066400000000000000000000026431356504100700311550ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: field paths with delete", "comment": "If one nested field is deleted, and another isn't, preserve the second.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "foo", "bar" ] }, { "field": [ "foo", "delete" ] } ], "jsonValues": [ "1", "\"Delete\"" ], "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "foo": { "mapValue": { "fields": { "bar": { "integerValue": "1" } } } } } }, "updateMask": { "fieldPaths": [ "foo.bar", "foo.delete" ] }, "currentDocument": { "exists": true } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-fp-dup-transforms.json000066400000000000000000000014041356504100700333670ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: duplicate field path with only transforms", "comment": "The same field cannot occur more than once, even if all the operations are transforms.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "a" ] }, { "field": [ "b" ] }, { "field": [ "a" ] } ], "jsonValues": [ "[\"ArrayUnion\", 1, 2, 3]", "\"ServerTimestamp\"", "[\"ArrayUnion\", 4, 5, 6]" ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-fp-dup.json000066400000000000000000000012021356504100700311670ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: duplicate field path", "comment": "The same field cannot occur more than once.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "a" ] }, { "field": [ "b" ] }, { "field": [ "a" ] } ], "jsonValues": [ "1", "2", "3" ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-fp-empty-component.json000066400000000000000000000007161356504100700335460ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: empty field path component", "comment": "Empty fields are not allowed.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "*", "" ] } ], "jsonValues": [ "1" ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-fp-empty.json000066400000000000000000000006341356504100700315450ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: empty field path", "comment": "A FieldPath of length zero is invalid.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [] } ], "jsonValues": [ "1" ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-fp-multi.json000066400000000000000000000024621356504100700315420ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: multiple-element field path", "comment": "The UpdatePaths or equivalent method takes a list of FieldPaths.\nEach FieldPath is a sequence of uninterpreted path components.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "a", "b" ] } ], "jsonValues": [ "1" ], "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "mapValue": { "fields": { "b": { "integerValue": "1" } } } } } }, "updateMask": { "fieldPaths": [ "a.b" ] }, "currentDocument": { "exists": true } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-fp-nosplit.json000066400000000000000000000027341356504100700321020ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: FieldPath elements are not split on dots", "comment": "FieldPath components are not split on dots.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "a.b", "f.g" ] } ], "jsonValues": [ "{\"n.o\": 7}" ], "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a.b": { "mapValue": { "fields": { "f.g": { "mapValue": { "fields": { "n.o": { "integerValue": "7" } } } } } } } } }, "updateMask": { "fieldPaths": [ "`a.b`.`f.g`" ] }, "currentDocument": { "exists": true } } ] } } } ] } update-paths-nested-transform-and-nested-value.json000066400000000000000000000051511356504100700363510ustar00rootroot00000000000000google-cloud-go-0.49.0/firestore/internal/conformance/testdata{ "tests": [ { "description": "update-paths: Nested transforms should not affect the field mask, even\nwhen there are other values that do. Transforms should only affect the\nDocumentTransform_FieldTransform list.", "comment": "For updates, top-level paths in json-like map inputs\nare split on the dot. That is, an input {\"a.b.c\": 7} results in an update to\nfield c of object b of object a with value 7. In order to specify this behavior,\nthe update must use a fieldmask \"a.b.c\". However, fieldmasks are only used for\nconcrete values - transforms are separately encoded in a\nDocumentTransform_FieldTransform array.\n\nThis test exercises a bug found in python (https://github.com/googleapis/google-cloud-python/issues/7215)\nin which nested transforms ({\"a.c\": \"ServerTimestamp\"}) next to nested values\n({\"a.b\": 7}) incorrectly caused the fieldmask \"a\" to be set, which has the\neffect of wiping out all data in \"a\" other than what was specified in the\njson-like input.\n\nInstead, as this test specifies, transforms should not affect the fieldmask.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "a", "b" ] }, { "field": [ "a", "c" ] } ], "jsonValues": [ "7", "\"ServerTimestamp\"" ], "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "mapValue": { "fields": { "b": { "integerValue": "7" } } } } } }, "updateMask": { "fieldPaths": [ "a.b" ] }, "currentDocument": { "exists": true } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "a.c", "setToServerValue": "REQUEST_TIME" } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-no-paths.json000066400000000000000000000004431356504100700315330ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: no paths", "comment": "It is a client-side error to call Update with empty data.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-prefix-1.json000066400000000000000000000010731356504100700314350ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: prefix #1", "comment": "In the input data, one field cannot be a prefix of another.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "a", "b" ] }, { "field": [ "a" ] } ], "jsonValues": [ "1", "2" ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-prefix-2.json000066400000000000000000000010731356504100700314360ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: prefix #2", "comment": "In the input data, one field cannot be a prefix of another.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "a" ] }, { "field": [ "a", "b" ] } ], "jsonValues": [ "1", "2" ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-prefix-3.json000066400000000000000000000011671356504100700314430ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: prefix #3", "comment": "In the input data, one field cannot be a prefix of another, even if the values could in principle be combined.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "a" ] }, { "field": [ "a", "d" ] } ], "jsonValues": [ "{\"b\": 1}", "2" ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-special-chars.json000066400000000000000000000027201356504100700325200ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: special characters", "comment": "FieldPaths can contain special characters.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "*", "~" ] }, { "field": [ "*", "`" ] } ], "jsonValues": [ "1", "2" ], "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "*": { "mapValue": { "fields": { "`": { "integerValue": "2" }, "~": { "integerValue": "1" } } } } } }, "updateMask": { "fieldPaths": [ "`*`.`\\``", "`*`.`~`" ] }, "currentDocument": { "exists": true } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-st-alone.json000066400000000000000000000020441356504100700315230ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: ServerTimestamp alone", "comment": "If the only values in the input are ServerTimestamps, then no\nupdate operation should be produced.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "a" ] } ], "jsonValues": [ "\"ServerTimestamp\"" ], "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "a", "setToServerValue": "REQUEST_TIME" } ] }, "currentDocument": { "exists": true } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-st-multi.json000066400000000000000000000035461356504100700315670ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: multiple ServerTimestamp fields", "comment": "A document can have more than one ServerTimestamp field.\nSince all the ServerTimestamp fields are removed, the only field in the update is \"a\".", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "a" ] }, { "field": [ "b" ] }, { "field": [ "c" ] } ], "jsonValues": [ "1", "\"ServerTimestamp\"", "{\"d\": \"ServerTimestamp\"}" ], "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "updateMask": { "fieldPaths": [ "a", "c" ] }, "currentDocument": { "exists": true } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b", "setToServerValue": "REQUEST_TIME" }, { "fieldPath": "c.d", "setToServerValue": "REQUEST_TIME" } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-st-nested.json000066400000000000000000000032561356504100700317150ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: nested ServerTimestamp field", "comment": "A ServerTimestamp value can occur at any depth. In this case,\nthe transform applies to the field path \"b.c\". Since \"c\" is removed from the update,\n\"b\" becomes empty, so it is also removed from the update.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "a" ] }, { "field": [ "b" ] } ], "jsonValues": [ "1", "{\"c\": \"ServerTimestamp\"}" ], "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "updateMask": { "fieldPaths": [ "a", "b" ] }, "currentDocument": { "exists": true } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b.c", "setToServerValue": "REQUEST_TIME" } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-st-noarray-nested.json000066400000000000000000000011741356504100700333630ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: ServerTimestamp cannot be anywhere inside an array value", "comment": "There cannot be an array value anywhere on the path from the document\nroot to the ServerTimestamp sentinel. Firestore transforms don't support array indexing.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "a" ] } ], "jsonValues": [ "[1, {\"b\": \"ServerTimestamp\"}]" ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-st-noarray.json000066400000000000000000000010701356504100700320760ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: ServerTimestamp cannot be in an array value", "comment": "The ServerTimestamp sentinel must be the value of a field. Firestore\ntransforms don't support array indexing.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "a" ] } ], "jsonValues": [ "[1, 2, \"ServerTimestamp\"]" ], "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-st-with-empty-map.json000066400000000000000000000033551356504100700333150ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: ServerTimestamp beside an empty map", "comment": "When a ServerTimestamp and a map both reside inside a map, the\nServerTimestamp should be stripped out but the empty map should remain.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "a" ] } ], "jsonValues": [ "{\"b\": {}, \"c\": \"ServerTimestamp\"}" ], "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "mapValue": { "fields": { "b": { "mapValue": { "fields": {} } } } } } } }, "updateMask": { "fieldPaths": [ "a" ] }, "currentDocument": { "exists": true } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "a.c", "setToServerValue": "REQUEST_TIME" } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-st.json000066400000000000000000000033031356504100700304260ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: ServerTimestamp with data", "comment": "A key with the special ServerTimestamp sentinel is removed from\nthe data in the update operation. Instead it appears in a separate Transform operation.\nNote that in these tests, the string \"ServerTimestamp\" should be replaced with the\nspecial ServerTimestamp value.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "fieldPaths": [ { "field": [ "a" ] }, { "field": [ "b" ] } ], "jsonValues": [ "1", "\"ServerTimestamp\"" ], "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "updateMask": { "fieldPaths": [ "a" ] }, "currentDocument": { "exists": true } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b", "setToServerValue": "REQUEST_TIME" } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-paths-uptime.json000066400000000000000000000022211356504100700313010ustar00rootroot00000000000000{ "tests": [ { "description": "update-paths: last-update-time precondition", "comment": "The Update call supports a last-update-time precondition.", "updatePaths": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "precondition": { "updateTime": "1970-01-01T00:00:42Z" }, "fieldPaths": [ { "field": [ "a" ] } ], "jsonValues": [ "1" ], "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "updateMask": { "fieldPaths": [ "a" ] }, "currentDocument": { "updateTime": "1970-01-01T00:00:42Z" } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-prefix-1.json000066400000000000000000000005111356504100700303140ustar00rootroot00000000000000{ "tests": [ { "description": "update: prefix #1", "comment": "In the input data, one field cannot be a prefix of another.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a.b\": 1, \"a\": 2}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-prefix-2.json000066400000000000000000000005111356504100700303150ustar00rootroot00000000000000{ "tests": [ { "description": "update: prefix #2", "comment": "In the input data, one field cannot be a prefix of another.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1, \"a.b\": 2}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-prefix-3.json000066400000000000000000000006051356504100700303220ustar00rootroot00000000000000{ "tests": [ { "description": "update: prefix #3", "comment": "In the input data, one field cannot be a prefix of another, even if the values could in principle be combined.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": {\"b\": 1}, \"a.d\": 2}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-quoting.json000066400000000000000000000025471356504100700303620ustar00rootroot00000000000000{ "tests": [ { "description": "update: non-letter starting chars are quoted, except underscore", "comment": "In a field path, any component beginning with a non-letter or underscore is quoted.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"_0.1.+2\": 1}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "_0": { "mapValue": { "fields": { "1": { "mapValue": { "fields": { "+2": { "integerValue": "1" } } } } } } } } }, "updateMask": { "fieldPaths": [ "_0.`1`.`+2`" ] }, "currentDocument": { "exists": true } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-split-top-level.json000066400000000000000000000025411356504100700317260ustar00rootroot00000000000000{ "tests": [ { "description": "update: Split on dots for top-level keys only", "comment": "The Update method splits only top-level keys at dots. Keys at\nother levels are taken literally.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"h.g\": {\"j.k\": 6}}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "h": { "mapValue": { "fields": { "g": { "mapValue": { "fields": { "j.k": { "integerValue": "6" } } } } } } } } }, "updateMask": { "fieldPaths": [ "h.g" ] }, "currentDocument": { "exists": true } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-split.json000066400000000000000000000024201356504100700300150ustar00rootroot00000000000000{ "tests": [ { "description": "update: split on dots", "comment": "The Update method splits top-level keys at dots.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a.b.c\": 1}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "mapValue": { "fields": { "b": { "mapValue": { "fields": { "c": { "integerValue": "1" } } } } } } } } }, "updateMask": { "fieldPaths": [ "a.b.c" ] }, "currentDocument": { "exists": true } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-st-alone.json000066400000000000000000000016301356504100700304060ustar00rootroot00000000000000{ "tests": [ { "description": "update: ServerTimestamp alone", "comment": "If the only values in the input are ServerTimestamps, then no\nupdate operation should be produced.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": \"ServerTimestamp\"}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "a", "setToServerValue": "REQUEST_TIME" } ] }, "currentDocument": { "exists": true } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-st-dot.json000066400000000000000000000020371356504100700301000ustar00rootroot00000000000000{ "tests": [ { "description": "update: ServerTimestamp with dotted field", "comment": "Like other uses of ServerTimestamp, the data is pruned and the\nfield does not appear in the update mask, because it is in the transform. In this case\nAn update operation is produced just to hold the precondition.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a.b.c\": \"ServerTimestamp\"}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "a.b.c", "setToServerValue": "REQUEST_TIME" } ] }, "currentDocument": { "exists": true } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-st-multi.json000066400000000000000000000030601356504100700304410ustar00rootroot00000000000000{ "tests": [ { "description": "update: multiple ServerTimestamp fields", "comment": "A document can have more than one ServerTimestamp field.\nSince all the ServerTimestamp fields are removed, the only field in the update is \"a\".", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1, \"b\": \"ServerTimestamp\", \"c\": {\"d\": \"ServerTimestamp\"}}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "updateMask": { "fieldPaths": [ "a", "c" ] }, "currentDocument": { "exists": true } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b", "setToServerValue": "REQUEST_TIME" }, { "fieldPath": "c.d", "setToServerValue": "REQUEST_TIME" } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-st-nested.json000066400000000000000000000027151356504100700305770ustar00rootroot00000000000000{ "tests": [ { "description": "update: nested ServerTimestamp field", "comment": "A ServerTimestamp value can occur at any depth. In this case,\nthe transform applies to the field path \"b.c\". Since \"c\" is removed from the update,\n\"b\" becomes empty, so it is also removed from the update.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1, \"b\": {\"c\": \"ServerTimestamp\"}}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "updateMask": { "fieldPaths": [ "a", "b" ] }, "currentDocument": { "exists": true } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b.c", "setToServerValue": "REQUEST_TIME" } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-st-noarray-nested.json000066400000000000000000000007601356504100700322460ustar00rootroot00000000000000{ "tests": [ { "description": "update: ServerTimestamp cannot be anywhere inside an array value", "comment": "There cannot be an array value anywhere on the path from the document\nroot to the ServerTimestamp sentinel. Firestore transforms don't support array indexing.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": [1, {\"b\": \"ServerTimestamp\"}]}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-st-noarray.json000066400000000000000000000006541356504100700307700ustar00rootroot00000000000000{ "tests": [ { "description": "update: ServerTimestamp cannot be in an array value", "comment": "The ServerTimestamp sentinel must be the value of a field. Firestore\ntransforms don't support array indexing.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": [1, 2, \"ServerTimestamp\"]}", "isError": true } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-st-with-empty-map.json000066400000000000000000000031411356504100700321710ustar00rootroot00000000000000{ "tests": [ { "description": "update: ServerTimestamp beside an empty map", "comment": "When a ServerTimestamp and a map both reside inside a map, the\nServerTimestamp should be stripped out but the empty map should remain.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": {\"b\": {}, \"c\": \"ServerTimestamp\"}}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "mapValue": { "fields": { "b": { "mapValue": { "fields": {} } } } } } } }, "updateMask": { "fieldPaths": [ "a" ] }, "currentDocument": { "exists": true } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "a.c", "setToServerValue": "REQUEST_TIME" } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-st.json000066400000000000000000000027421356504100700273170ustar00rootroot00000000000000{ "tests": [ { "description": "update: ServerTimestamp with data", "comment": "A key with the special ServerTimestamp sentinel is removed from\nthe data in the update operation. Instead it appears in a separate Transform operation.\nNote that in these tests, the string \"ServerTimestamp\" should be replaced with the\nspecial ServerTimestamp value.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "jsonData": "{\"a\": 1, \"b\": \"ServerTimestamp\"}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "updateMask": { "fieldPaths": [ "a" ] }, "currentDocument": { "exists": true } }, { "transform": { "document": "projects/projectID/databases/(default)/documents/C/d", "fieldTransforms": [ { "fieldPath": "b", "setToServerValue": "REQUEST_TIME" } ] } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/testdata/update-uptime.json000066400000000000000000000020051356504100700301640ustar00rootroot00000000000000{ "tests": [ { "description": "update: last-update-time precondition", "comment": "The Update call supports a last-update-time precondition.", "update": { "docRefPath": "projects/projectID/databases/(default)/documents/C/d", "precondition": { "updateTime": "1970-01-01T00:00:42Z" }, "jsonData": "{\"a\": 1}", "request": { "database": "projects/projectID/databases/(default)", "writes": [ { "update": { "name": "projects/projectID/databases/(default)/documents/C/d", "fields": { "a": { "integerValue": "1" } } }, "updateMask": { "fieldPaths": [ "a" ] }, "currentDocument": { "updateTime": "1970-01-01T00:00:42Z" } } ] } } } ] } google-cloud-go-0.49.0/firestore/internal/conformance/tests.pb.go000066400000000000000000001447131356504100700250030ustar00rootroot00000000000000// Code generated by protoc-gen-go. DO NOT EDIT. // source: tests.proto package google_cloud_conformance_firestore_v1 import ( fmt "fmt" math "math" proto "github.com/golang/protobuf/proto" timestamp "github.com/golang/protobuf/ptypes/timestamp" v1 "google.golang.org/genproto/googleapis/firestore/v1" ) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal var _ = fmt.Errorf var _ = math.Inf // This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package type DocChange_Kind int32 const ( DocChange_KIND_UNSPECIFIED DocChange_Kind = 0 DocChange_ADDED DocChange_Kind = 1 DocChange_REMOVED DocChange_Kind = 2 DocChange_MODIFIED DocChange_Kind = 3 ) var DocChange_Kind_name = map[int32]string{ 0: "KIND_UNSPECIFIED", 1: "ADDED", 2: "REMOVED", 3: "MODIFIED", } var DocChange_Kind_value = map[string]int32{ "KIND_UNSPECIFIED": 0, "ADDED": 1, "REMOVED": 2, "MODIFIED": 3, } func (x DocChange_Kind) String() string { return proto.EnumName(DocChange_Kind_name, int32(x)) } func (DocChange_Kind) EnumDescriptor() ([]byte, []int) { return fileDescriptor_e49b496f4919bda1, []int{19, 0} } // A collection of tests. type TestFile struct { Tests []*Test `protobuf:"bytes,1,rep,name=tests,proto3" json:"tests,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *TestFile) Reset() { *m = TestFile{} } func (m *TestFile) String() string { return proto.CompactTextString(m) } func (*TestFile) ProtoMessage() {} func (*TestFile) Descriptor() ([]byte, []int) { return fileDescriptor_e49b496f4919bda1, []int{0} } func (m *TestFile) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_TestFile.Unmarshal(m, b) } func (m *TestFile) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_TestFile.Marshal(b, m, deterministic) } func (m *TestFile) XXX_Merge(src proto.Message) { xxx_messageInfo_TestFile.Merge(m, src) } func (m *TestFile) XXX_Size() int { return xxx_messageInfo_TestFile.Size(m) } func (m *TestFile) XXX_DiscardUnknown() { xxx_messageInfo_TestFile.DiscardUnknown(m) } var xxx_messageInfo_TestFile proto.InternalMessageInfo func (m *TestFile) GetTests() []*Test { if m != nil { return m.Tests } return nil } // A Test describes a single client method call and its expected result. type Test struct { Description string `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"` Comment string `protobuf:"bytes,10,opt,name=comment,proto3" json:"comment,omitempty"` // Types that are valid to be assigned to Test: // *Test_Get // *Test_Create // *Test_Set // *Test_Update // *Test_UpdatePaths // *Test_Delete // *Test_Query // *Test_Listen Test isTest_Test `protobuf_oneof:"test"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *Test) Reset() { *m = Test{} } func (m *Test) String() string { return proto.CompactTextString(m) } func (*Test) ProtoMessage() {} func (*Test) Descriptor() ([]byte, []int) { return fileDescriptor_e49b496f4919bda1, []int{1} } func (m *Test) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Test.Unmarshal(m, b) } func (m *Test) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Test.Marshal(b, m, deterministic) } func (m *Test) XXX_Merge(src proto.Message) { xxx_messageInfo_Test.Merge(m, src) } func (m *Test) XXX_Size() int { return xxx_messageInfo_Test.Size(m) } func (m *Test) XXX_DiscardUnknown() { xxx_messageInfo_Test.DiscardUnknown(m) } var xxx_messageInfo_Test proto.InternalMessageInfo func (m *Test) GetDescription() string { if m != nil { return m.Description } return "" } func (m *Test) GetComment() string { if m != nil { return m.Comment } return "" } type isTest_Test interface { isTest_Test() } type Test_Get struct { Get *GetTest `protobuf:"bytes,2,opt,name=get,proto3,oneof"` } type Test_Create struct { Create *CreateTest `protobuf:"bytes,3,opt,name=create,proto3,oneof"` } type Test_Set struct { Set *SetTest `protobuf:"bytes,4,opt,name=set,proto3,oneof"` } type Test_Update struct { Update *UpdateTest `protobuf:"bytes,5,opt,name=update,proto3,oneof"` } type Test_UpdatePaths struct { UpdatePaths *UpdatePathsTest `protobuf:"bytes,6,opt,name=update_paths,json=updatePaths,proto3,oneof"` } type Test_Delete struct { Delete *DeleteTest `protobuf:"bytes,7,opt,name=delete,proto3,oneof"` } type Test_Query struct { Query *QueryTest `protobuf:"bytes,8,opt,name=query,proto3,oneof"` } type Test_Listen struct { Listen *ListenTest `protobuf:"bytes,9,opt,name=listen,proto3,oneof"` } func (*Test_Get) isTest_Test() {} func (*Test_Create) isTest_Test() {} func (*Test_Set) isTest_Test() {} func (*Test_Update) isTest_Test() {} func (*Test_UpdatePaths) isTest_Test() {} func (*Test_Delete) isTest_Test() {} func (*Test_Query) isTest_Test() {} func (*Test_Listen) isTest_Test() {} func (m *Test) GetTest() isTest_Test { if m != nil { return m.Test } return nil } func (m *Test) GetGet() *GetTest { if x, ok := m.GetTest().(*Test_Get); ok { return x.Get } return nil } func (m *Test) GetCreate() *CreateTest { if x, ok := m.GetTest().(*Test_Create); ok { return x.Create } return nil } func (m *Test) GetSet() *SetTest { if x, ok := m.GetTest().(*Test_Set); ok { return x.Set } return nil } func (m *Test) GetUpdate() *UpdateTest { if x, ok := m.GetTest().(*Test_Update); ok { return x.Update } return nil } func (m *Test) GetUpdatePaths() *UpdatePathsTest { if x, ok := m.GetTest().(*Test_UpdatePaths); ok { return x.UpdatePaths } return nil } func (m *Test) GetDelete() *DeleteTest { if x, ok := m.GetTest().(*Test_Delete); ok { return x.Delete } return nil } func (m *Test) GetQuery() *QueryTest { if x, ok := m.GetTest().(*Test_Query); ok { return x.Query } return nil } func (m *Test) GetListen() *ListenTest { if x, ok := m.GetTest().(*Test_Listen); ok { return x.Listen } return nil } // XXX_OneofWrappers is for the internal use of the proto package. func (*Test) XXX_OneofWrappers() []interface{} { return []interface{}{ (*Test_Get)(nil), (*Test_Create)(nil), (*Test_Set)(nil), (*Test_Update)(nil), (*Test_UpdatePaths)(nil), (*Test_Delete)(nil), (*Test_Query)(nil), (*Test_Listen)(nil), } } // Call to the DocumentRef.Get method. type GetTest struct { // The path of the doc, e.g. "projects/projectID/databases/(default)/documents/C/d" DocRefPath string `protobuf:"bytes,1,opt,name=doc_ref_path,json=docRefPath,proto3" json:"doc_ref_path,omitempty"` // The request that the call should send to the Firestore service. Request *v1.GetDocumentRequest `protobuf:"bytes,2,opt,name=request,proto3" json:"request,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *GetTest) Reset() { *m = GetTest{} } func (m *GetTest) String() string { return proto.CompactTextString(m) } func (*GetTest) ProtoMessage() {} func (*GetTest) Descriptor() ([]byte, []int) { return fileDescriptor_e49b496f4919bda1, []int{2} } func (m *GetTest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetTest.Unmarshal(m, b) } func (m *GetTest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_GetTest.Marshal(b, m, deterministic) } func (m *GetTest) XXX_Merge(src proto.Message) { xxx_messageInfo_GetTest.Merge(m, src) } func (m *GetTest) XXX_Size() int { return xxx_messageInfo_GetTest.Size(m) } func (m *GetTest) XXX_DiscardUnknown() { xxx_messageInfo_GetTest.DiscardUnknown(m) } var xxx_messageInfo_GetTest proto.InternalMessageInfo func (m *GetTest) GetDocRefPath() string { if m != nil { return m.DocRefPath } return "" } func (m *GetTest) GetRequest() *v1.GetDocumentRequest { if m != nil { return m.Request } return nil } // Call to DocumentRef.Create. type CreateTest struct { // The path of the doc, e.g. "projects/projectID/databases/(default)/documents/C/d" DocRefPath string `protobuf:"bytes,1,opt,name=doc_ref_path,json=docRefPath,proto3" json:"doc_ref_path,omitempty"` // The data passed to Create, as JSON. The strings "Delete" and "ServerTimestamp" // denote the two special sentinel values. Values that could be interpreted as integers // (i.e. digit strings) should be treated as integers. JsonData string `protobuf:"bytes,2,opt,name=json_data,json=jsonData,proto3" json:"json_data,omitempty"` // The request that the call should generate. Request *v1.CommitRequest `protobuf:"bytes,3,opt,name=request,proto3" json:"request,omitempty"` // If true, the call should result in an error without generating a request. // If this is true, request should not be set. IsError bool `protobuf:"varint,4,opt,name=is_error,json=isError,proto3" json:"is_error,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *CreateTest) Reset() { *m = CreateTest{} } func (m *CreateTest) String() string { return proto.CompactTextString(m) } func (*CreateTest) ProtoMessage() {} func (*CreateTest) Descriptor() ([]byte, []int) { return fileDescriptor_e49b496f4919bda1, []int{3} } func (m *CreateTest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CreateTest.Unmarshal(m, b) } func (m *CreateTest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_CreateTest.Marshal(b, m, deterministic) } func (m *CreateTest) XXX_Merge(src proto.Message) { xxx_messageInfo_CreateTest.Merge(m, src) } func (m *CreateTest) XXX_Size() int { return xxx_messageInfo_CreateTest.Size(m) } func (m *CreateTest) XXX_DiscardUnknown() { xxx_messageInfo_CreateTest.DiscardUnknown(m) } var xxx_messageInfo_CreateTest proto.InternalMessageInfo func (m *CreateTest) GetDocRefPath() string { if m != nil { return m.DocRefPath } return "" } func (m *CreateTest) GetJsonData() string { if m != nil { return m.JsonData } return "" } func (m *CreateTest) GetRequest() *v1.CommitRequest { if m != nil { return m.Request } return nil } func (m *CreateTest) GetIsError() bool { if m != nil { return m.IsError } return false } // A call to DocumentRef.Set. type SetTest struct { DocRefPath string `protobuf:"bytes,1,opt,name=doc_ref_path,json=docRefPath,proto3" json:"doc_ref_path,omitempty"` Option *SetOption `protobuf:"bytes,2,opt,name=option,proto3" json:"option,omitempty"` JsonData string `protobuf:"bytes,3,opt,name=json_data,json=jsonData,proto3" json:"json_data,omitempty"` Request *v1.CommitRequest `protobuf:"bytes,4,opt,name=request,proto3" json:"request,omitempty"` IsError bool `protobuf:"varint,5,opt,name=is_error,json=isError,proto3" json:"is_error,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *SetTest) Reset() { *m = SetTest{} } func (m *SetTest) String() string { return proto.CompactTextString(m) } func (*SetTest) ProtoMessage() {} func (*SetTest) Descriptor() ([]byte, []int) { return fileDescriptor_e49b496f4919bda1, []int{4} } func (m *SetTest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetTest.Unmarshal(m, b) } func (m *SetTest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SetTest.Marshal(b, m, deterministic) } func (m *SetTest) XXX_Merge(src proto.Message) { xxx_messageInfo_SetTest.Merge(m, src) } func (m *SetTest) XXX_Size() int { return xxx_messageInfo_SetTest.Size(m) } func (m *SetTest) XXX_DiscardUnknown() { xxx_messageInfo_SetTest.DiscardUnknown(m) } var xxx_messageInfo_SetTest proto.InternalMessageInfo func (m *SetTest) GetDocRefPath() string { if m != nil { return m.DocRefPath } return "" } func (m *SetTest) GetOption() *SetOption { if m != nil { return m.Option } return nil } func (m *SetTest) GetJsonData() string { if m != nil { return m.JsonData } return "" } func (m *SetTest) GetRequest() *v1.CommitRequest { if m != nil { return m.Request } return nil } func (m *SetTest) GetIsError() bool { if m != nil { return m.IsError } return false } // A call to the form of DocumentRef.Update that represents the data as a map // or dictionary. type UpdateTest struct { DocRefPath string `protobuf:"bytes,1,opt,name=doc_ref_path,json=docRefPath,proto3" json:"doc_ref_path,omitempty"` Precondition *v1.Precondition `protobuf:"bytes,2,opt,name=precondition,proto3" json:"precondition,omitempty"` JsonData string `protobuf:"bytes,3,opt,name=json_data,json=jsonData,proto3" json:"json_data,omitempty"` Request *v1.CommitRequest `protobuf:"bytes,4,opt,name=request,proto3" json:"request,omitempty"` IsError bool `protobuf:"varint,5,opt,name=is_error,json=isError,proto3" json:"is_error,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *UpdateTest) Reset() { *m = UpdateTest{} } func (m *UpdateTest) String() string { return proto.CompactTextString(m) } func (*UpdateTest) ProtoMessage() {} func (*UpdateTest) Descriptor() ([]byte, []int) { return fileDescriptor_e49b496f4919bda1, []int{5} } func (m *UpdateTest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_UpdateTest.Unmarshal(m, b) } func (m *UpdateTest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_UpdateTest.Marshal(b, m, deterministic) } func (m *UpdateTest) XXX_Merge(src proto.Message) { xxx_messageInfo_UpdateTest.Merge(m, src) } func (m *UpdateTest) XXX_Size() int { return xxx_messageInfo_UpdateTest.Size(m) } func (m *UpdateTest) XXX_DiscardUnknown() { xxx_messageInfo_UpdateTest.DiscardUnknown(m) } var xxx_messageInfo_UpdateTest proto.InternalMessageInfo func (m *UpdateTest) GetDocRefPath() string { if m != nil { return m.DocRefPath } return "" } func (m *UpdateTest) GetPrecondition() *v1.Precondition { if m != nil { return m.Precondition } return nil } func (m *UpdateTest) GetJsonData() string { if m != nil { return m.JsonData } return "" } func (m *UpdateTest) GetRequest() *v1.CommitRequest { if m != nil { return m.Request } return nil } func (m *UpdateTest) GetIsError() bool { if m != nil { return m.IsError } return false } // A call to the form of DocumentRef.Update that represents the data as a list // of field paths and their values. type UpdatePathsTest struct { DocRefPath string `protobuf:"bytes,1,opt,name=doc_ref_path,json=docRefPath,proto3" json:"doc_ref_path,omitempty"` Precondition *v1.Precondition `protobuf:"bytes,2,opt,name=precondition,proto3" json:"precondition,omitempty"` // parallel sequences: field_paths[i] corresponds to json_values[i] FieldPaths []*FieldPath `protobuf:"bytes,3,rep,name=field_paths,json=fieldPaths,proto3" json:"field_paths,omitempty"` JsonValues []string `protobuf:"bytes,4,rep,name=json_values,json=jsonValues,proto3" json:"json_values,omitempty"` Request *v1.CommitRequest `protobuf:"bytes,5,opt,name=request,proto3" json:"request,omitempty"` IsError bool `protobuf:"varint,6,opt,name=is_error,json=isError,proto3" json:"is_error,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *UpdatePathsTest) Reset() { *m = UpdatePathsTest{} } func (m *UpdatePathsTest) String() string { return proto.CompactTextString(m) } func (*UpdatePathsTest) ProtoMessage() {} func (*UpdatePathsTest) Descriptor() ([]byte, []int) { return fileDescriptor_e49b496f4919bda1, []int{6} } func (m *UpdatePathsTest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_UpdatePathsTest.Unmarshal(m, b) } func (m *UpdatePathsTest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_UpdatePathsTest.Marshal(b, m, deterministic) } func (m *UpdatePathsTest) XXX_Merge(src proto.Message) { xxx_messageInfo_UpdatePathsTest.Merge(m, src) } func (m *UpdatePathsTest) XXX_Size() int { return xxx_messageInfo_UpdatePathsTest.Size(m) } func (m *UpdatePathsTest) XXX_DiscardUnknown() { xxx_messageInfo_UpdatePathsTest.DiscardUnknown(m) } var xxx_messageInfo_UpdatePathsTest proto.InternalMessageInfo func (m *UpdatePathsTest) GetDocRefPath() string { if m != nil { return m.DocRefPath } return "" } func (m *UpdatePathsTest) GetPrecondition() *v1.Precondition { if m != nil { return m.Precondition } return nil } func (m *UpdatePathsTest) GetFieldPaths() []*FieldPath { if m != nil { return m.FieldPaths } return nil } func (m *UpdatePathsTest) GetJsonValues() []string { if m != nil { return m.JsonValues } return nil } func (m *UpdatePathsTest) GetRequest() *v1.CommitRequest { if m != nil { return m.Request } return nil } func (m *UpdatePathsTest) GetIsError() bool { if m != nil { return m.IsError } return false } // A call to DocmentRef.Delete type DeleteTest struct { DocRefPath string `protobuf:"bytes,1,opt,name=doc_ref_path,json=docRefPath,proto3" json:"doc_ref_path,omitempty"` Precondition *v1.Precondition `protobuf:"bytes,2,opt,name=precondition,proto3" json:"precondition,omitempty"` Request *v1.CommitRequest `protobuf:"bytes,3,opt,name=request,proto3" json:"request,omitempty"` IsError bool `protobuf:"varint,4,opt,name=is_error,json=isError,proto3" json:"is_error,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *DeleteTest) Reset() { *m = DeleteTest{} } func (m *DeleteTest) String() string { return proto.CompactTextString(m) } func (*DeleteTest) ProtoMessage() {} func (*DeleteTest) Descriptor() ([]byte, []int) { return fileDescriptor_e49b496f4919bda1, []int{7} } func (m *DeleteTest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_DeleteTest.Unmarshal(m, b) } func (m *DeleteTest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_DeleteTest.Marshal(b, m, deterministic) } func (m *DeleteTest) XXX_Merge(src proto.Message) { xxx_messageInfo_DeleteTest.Merge(m, src) } func (m *DeleteTest) XXX_Size() int { return xxx_messageInfo_DeleteTest.Size(m) } func (m *DeleteTest) XXX_DiscardUnknown() { xxx_messageInfo_DeleteTest.DiscardUnknown(m) } var xxx_messageInfo_DeleteTest proto.InternalMessageInfo func (m *DeleteTest) GetDocRefPath() string { if m != nil { return m.DocRefPath } return "" } func (m *DeleteTest) GetPrecondition() *v1.Precondition { if m != nil { return m.Precondition } return nil } func (m *DeleteTest) GetRequest() *v1.CommitRequest { if m != nil { return m.Request } return nil } func (m *DeleteTest) GetIsError() bool { if m != nil { return m.IsError } return false } // An option to the DocumentRef.Set call. type SetOption struct { All bool `protobuf:"varint,1,opt,name=all,proto3" json:"all,omitempty"` Fields []*FieldPath `protobuf:"bytes,2,rep,name=fields,proto3" json:"fields,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *SetOption) Reset() { *m = SetOption{} } func (m *SetOption) String() string { return proto.CompactTextString(m) } func (*SetOption) ProtoMessage() {} func (*SetOption) Descriptor() ([]byte, []int) { return fileDescriptor_e49b496f4919bda1, []int{8} } func (m *SetOption) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetOption.Unmarshal(m, b) } func (m *SetOption) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SetOption.Marshal(b, m, deterministic) } func (m *SetOption) XXX_Merge(src proto.Message) { xxx_messageInfo_SetOption.Merge(m, src) } func (m *SetOption) XXX_Size() int { return xxx_messageInfo_SetOption.Size(m) } func (m *SetOption) XXX_DiscardUnknown() { xxx_messageInfo_SetOption.DiscardUnknown(m) } var xxx_messageInfo_SetOption proto.InternalMessageInfo func (m *SetOption) GetAll() bool { if m != nil { return m.All } return false } func (m *SetOption) GetFields() []*FieldPath { if m != nil { return m.Fields } return nil } type QueryTest struct { CollPath string `protobuf:"bytes,1,opt,name=coll_path,json=collPath,proto3" json:"coll_path,omitempty"` Clauses []*Clause `protobuf:"bytes,2,rep,name=clauses,proto3" json:"clauses,omitempty"` Query *v1.StructuredQuery `protobuf:"bytes,3,opt,name=query,proto3" json:"query,omitempty"` IsError bool `protobuf:"varint,4,opt,name=is_error,json=isError,proto3" json:"is_error,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *QueryTest) Reset() { *m = QueryTest{} } func (m *QueryTest) String() string { return proto.CompactTextString(m) } func (*QueryTest) ProtoMessage() {} func (*QueryTest) Descriptor() ([]byte, []int) { return fileDescriptor_e49b496f4919bda1, []int{9} } func (m *QueryTest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_QueryTest.Unmarshal(m, b) } func (m *QueryTest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_QueryTest.Marshal(b, m, deterministic) } func (m *QueryTest) XXX_Merge(src proto.Message) { xxx_messageInfo_QueryTest.Merge(m, src) } func (m *QueryTest) XXX_Size() int { return xxx_messageInfo_QueryTest.Size(m) } func (m *QueryTest) XXX_DiscardUnknown() { xxx_messageInfo_QueryTest.DiscardUnknown(m) } var xxx_messageInfo_QueryTest proto.InternalMessageInfo func (m *QueryTest) GetCollPath() string { if m != nil { return m.CollPath } return "" } func (m *QueryTest) GetClauses() []*Clause { if m != nil { return m.Clauses } return nil } func (m *QueryTest) GetQuery() *v1.StructuredQuery { if m != nil { return m.Query } return nil } func (m *QueryTest) GetIsError() bool { if m != nil { return m.IsError } return false } type Clause struct { // Types that are valid to be assigned to Clause: // *Clause_Select // *Clause_Where // *Clause_OrderBy // *Clause_Offset // *Clause_Limit // *Clause_StartAt // *Clause_StartAfter // *Clause_EndAt // *Clause_EndBefore Clause isClause_Clause `protobuf_oneof:"clause"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *Clause) Reset() { *m = Clause{} } func (m *Clause) String() string { return proto.CompactTextString(m) } func (*Clause) ProtoMessage() {} func (*Clause) Descriptor() ([]byte, []int) { return fileDescriptor_e49b496f4919bda1, []int{10} } func (m *Clause) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Clause.Unmarshal(m, b) } func (m *Clause) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Clause.Marshal(b, m, deterministic) } func (m *Clause) XXX_Merge(src proto.Message) { xxx_messageInfo_Clause.Merge(m, src) } func (m *Clause) XXX_Size() int { return xxx_messageInfo_Clause.Size(m) } func (m *Clause) XXX_DiscardUnknown() { xxx_messageInfo_Clause.DiscardUnknown(m) } var xxx_messageInfo_Clause proto.InternalMessageInfo type isClause_Clause interface { isClause_Clause() } type Clause_Select struct { Select *Select `protobuf:"bytes,1,opt,name=select,proto3,oneof"` } type Clause_Where struct { Where *Where `protobuf:"bytes,2,opt,name=where,proto3,oneof"` } type Clause_OrderBy struct { OrderBy *OrderBy `protobuf:"bytes,3,opt,name=order_by,json=orderBy,proto3,oneof"` } type Clause_Offset struct { Offset int32 `protobuf:"varint,4,opt,name=offset,proto3,oneof"` } type Clause_Limit struct { Limit int32 `protobuf:"varint,5,opt,name=limit,proto3,oneof"` } type Clause_StartAt struct { StartAt *Cursor `protobuf:"bytes,6,opt,name=start_at,json=startAt,proto3,oneof"` } type Clause_StartAfter struct { StartAfter *Cursor `protobuf:"bytes,7,opt,name=start_after,json=startAfter,proto3,oneof"` } type Clause_EndAt struct { EndAt *Cursor `protobuf:"bytes,8,opt,name=end_at,json=endAt,proto3,oneof"` } type Clause_EndBefore struct { EndBefore *Cursor `protobuf:"bytes,9,opt,name=end_before,json=endBefore,proto3,oneof"` } func (*Clause_Select) isClause_Clause() {} func (*Clause_Where) isClause_Clause() {} func (*Clause_OrderBy) isClause_Clause() {} func (*Clause_Offset) isClause_Clause() {} func (*Clause_Limit) isClause_Clause() {} func (*Clause_StartAt) isClause_Clause() {} func (*Clause_StartAfter) isClause_Clause() {} func (*Clause_EndAt) isClause_Clause() {} func (*Clause_EndBefore) isClause_Clause() {} func (m *Clause) GetClause() isClause_Clause { if m != nil { return m.Clause } return nil } func (m *Clause) GetSelect() *Select { if x, ok := m.GetClause().(*Clause_Select); ok { return x.Select } return nil } func (m *Clause) GetWhere() *Where { if x, ok := m.GetClause().(*Clause_Where); ok { return x.Where } return nil } func (m *Clause) GetOrderBy() *OrderBy { if x, ok := m.GetClause().(*Clause_OrderBy); ok { return x.OrderBy } return nil } func (m *Clause) GetOffset() int32 { if x, ok := m.GetClause().(*Clause_Offset); ok { return x.Offset } return 0 } func (m *Clause) GetLimit() int32 { if x, ok := m.GetClause().(*Clause_Limit); ok { return x.Limit } return 0 } func (m *Clause) GetStartAt() *Cursor { if x, ok := m.GetClause().(*Clause_StartAt); ok { return x.StartAt } return nil } func (m *Clause) GetStartAfter() *Cursor { if x, ok := m.GetClause().(*Clause_StartAfter); ok { return x.StartAfter } return nil } func (m *Clause) GetEndAt() *Cursor { if x, ok := m.GetClause().(*Clause_EndAt); ok { return x.EndAt } return nil } func (m *Clause) GetEndBefore() *Cursor { if x, ok := m.GetClause().(*Clause_EndBefore); ok { return x.EndBefore } return nil } // XXX_OneofWrappers is for the internal use of the proto package. func (*Clause) XXX_OneofWrappers() []interface{} { return []interface{}{ (*Clause_Select)(nil), (*Clause_Where)(nil), (*Clause_OrderBy)(nil), (*Clause_Offset)(nil), (*Clause_Limit)(nil), (*Clause_StartAt)(nil), (*Clause_StartAfter)(nil), (*Clause_EndAt)(nil), (*Clause_EndBefore)(nil), } } type Select struct { Fields []*FieldPath `protobuf:"bytes,1,rep,name=fields,proto3" json:"fields,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *Select) Reset() { *m = Select{} } func (m *Select) String() string { return proto.CompactTextString(m) } func (*Select) ProtoMessage() {} func (*Select) Descriptor() ([]byte, []int) { return fileDescriptor_e49b496f4919bda1, []int{11} } func (m *Select) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Select.Unmarshal(m, b) } func (m *Select) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Select.Marshal(b, m, deterministic) } func (m *Select) XXX_Merge(src proto.Message) { xxx_messageInfo_Select.Merge(m, src) } func (m *Select) XXX_Size() int { return xxx_messageInfo_Select.Size(m) } func (m *Select) XXX_DiscardUnknown() { xxx_messageInfo_Select.DiscardUnknown(m) } var xxx_messageInfo_Select proto.InternalMessageInfo func (m *Select) GetFields() []*FieldPath { if m != nil { return m.Fields } return nil } type Where struct { Path *FieldPath `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` Op string `protobuf:"bytes,2,opt,name=op,proto3" json:"op,omitempty"` JsonValue string `protobuf:"bytes,3,opt,name=json_value,json=jsonValue,proto3" json:"json_value,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *Where) Reset() { *m = Where{} } func (m *Where) String() string { return proto.CompactTextString(m) } func (*Where) ProtoMessage() {} func (*Where) Descriptor() ([]byte, []int) { return fileDescriptor_e49b496f4919bda1, []int{12} } func (m *Where) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Where.Unmarshal(m, b) } func (m *Where) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Where.Marshal(b, m, deterministic) } func (m *Where) XXX_Merge(src proto.Message) { xxx_messageInfo_Where.Merge(m, src) } func (m *Where) XXX_Size() int { return xxx_messageInfo_Where.Size(m) } func (m *Where) XXX_DiscardUnknown() { xxx_messageInfo_Where.DiscardUnknown(m) } var xxx_messageInfo_Where proto.InternalMessageInfo func (m *Where) GetPath() *FieldPath { if m != nil { return m.Path } return nil } func (m *Where) GetOp() string { if m != nil { return m.Op } return "" } func (m *Where) GetJsonValue() string { if m != nil { return m.JsonValue } return "" } type OrderBy struct { Path *FieldPath `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` Direction string `protobuf:"bytes,2,opt,name=direction,proto3" json:"direction,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *OrderBy) Reset() { *m = OrderBy{} } func (m *OrderBy) String() string { return proto.CompactTextString(m) } func (*OrderBy) ProtoMessage() {} func (*OrderBy) Descriptor() ([]byte, []int) { return fileDescriptor_e49b496f4919bda1, []int{13} } func (m *OrderBy) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_OrderBy.Unmarshal(m, b) } func (m *OrderBy) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_OrderBy.Marshal(b, m, deterministic) } func (m *OrderBy) XXX_Merge(src proto.Message) { xxx_messageInfo_OrderBy.Merge(m, src) } func (m *OrderBy) XXX_Size() int { return xxx_messageInfo_OrderBy.Size(m) } func (m *OrderBy) XXX_DiscardUnknown() { xxx_messageInfo_OrderBy.DiscardUnknown(m) } var xxx_messageInfo_OrderBy proto.InternalMessageInfo func (m *OrderBy) GetPath() *FieldPath { if m != nil { return m.Path } return nil } func (m *OrderBy) GetDirection() string { if m != nil { return m.Direction } return "" } type Cursor struct { // one of: DocSnapshot *DocSnapshot `protobuf:"bytes,1,opt,name=doc_snapshot,json=docSnapshot,proto3" json:"doc_snapshot,omitempty"` JsonValues []string `protobuf:"bytes,2,rep,name=json_values,json=jsonValues,proto3" json:"json_values,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *Cursor) Reset() { *m = Cursor{} } func (m *Cursor) String() string { return proto.CompactTextString(m) } func (*Cursor) ProtoMessage() {} func (*Cursor) Descriptor() ([]byte, []int) { return fileDescriptor_e49b496f4919bda1, []int{14} } func (m *Cursor) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Cursor.Unmarshal(m, b) } func (m *Cursor) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Cursor.Marshal(b, m, deterministic) } func (m *Cursor) XXX_Merge(src proto.Message) { xxx_messageInfo_Cursor.Merge(m, src) } func (m *Cursor) XXX_Size() int { return xxx_messageInfo_Cursor.Size(m) } func (m *Cursor) XXX_DiscardUnknown() { xxx_messageInfo_Cursor.DiscardUnknown(m) } var xxx_messageInfo_Cursor proto.InternalMessageInfo func (m *Cursor) GetDocSnapshot() *DocSnapshot { if m != nil { return m.DocSnapshot } return nil } func (m *Cursor) GetJsonValues() []string { if m != nil { return m.JsonValues } return nil } type DocSnapshot struct { Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` JsonData string `protobuf:"bytes,2,opt,name=json_data,json=jsonData,proto3" json:"json_data,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *DocSnapshot) Reset() { *m = DocSnapshot{} } func (m *DocSnapshot) String() string { return proto.CompactTextString(m) } func (*DocSnapshot) ProtoMessage() {} func (*DocSnapshot) Descriptor() ([]byte, []int) { return fileDescriptor_e49b496f4919bda1, []int{15} } func (m *DocSnapshot) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_DocSnapshot.Unmarshal(m, b) } func (m *DocSnapshot) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_DocSnapshot.Marshal(b, m, deterministic) } func (m *DocSnapshot) XXX_Merge(src proto.Message) { xxx_messageInfo_DocSnapshot.Merge(m, src) } func (m *DocSnapshot) XXX_Size() int { return xxx_messageInfo_DocSnapshot.Size(m) } func (m *DocSnapshot) XXX_DiscardUnknown() { xxx_messageInfo_DocSnapshot.DiscardUnknown(m) } var xxx_messageInfo_DocSnapshot proto.InternalMessageInfo func (m *DocSnapshot) GetPath() string { if m != nil { return m.Path } return "" } func (m *DocSnapshot) GetJsonData() string { if m != nil { return m.JsonData } return "" } type FieldPath struct { Field []string `protobuf:"bytes,1,rep,name=field,proto3" json:"field,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *FieldPath) Reset() { *m = FieldPath{} } func (m *FieldPath) String() string { return proto.CompactTextString(m) } func (*FieldPath) ProtoMessage() {} func (*FieldPath) Descriptor() ([]byte, []int) { return fileDescriptor_e49b496f4919bda1, []int{16} } func (m *FieldPath) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_FieldPath.Unmarshal(m, b) } func (m *FieldPath) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_FieldPath.Marshal(b, m, deterministic) } func (m *FieldPath) XXX_Merge(src proto.Message) { xxx_messageInfo_FieldPath.Merge(m, src) } func (m *FieldPath) XXX_Size() int { return xxx_messageInfo_FieldPath.Size(m) } func (m *FieldPath) XXX_DiscardUnknown() { xxx_messageInfo_FieldPath.DiscardUnknown(m) } var xxx_messageInfo_FieldPath proto.InternalMessageInfo func (m *FieldPath) GetField() []string { if m != nil { return m.Field } return nil } // A test of the Listen streaming RPC (a.k.a. FireStore watch). // If the sequence of responses is provided to the implementation, // it should produce the sequence of snapshots. // If is_error is true, an error should occur after the snapshots. // // The tests assume that the query is // Collection("projects/projectID/databases/(default)/documents/C").OrderBy("a", Ascending) // // The watch target ID used in these tests is 1. Test interpreters // should either change their client's ID for testing, // or change the ID in the tests before running them. type ListenTest struct { Responses []*v1.ListenResponse `protobuf:"bytes,1,rep,name=responses,proto3" json:"responses,omitempty"` Snapshots []*Snapshot `protobuf:"bytes,2,rep,name=snapshots,proto3" json:"snapshots,omitempty"` IsError bool `protobuf:"varint,3,opt,name=is_error,json=isError,proto3" json:"is_error,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *ListenTest) Reset() { *m = ListenTest{} } func (m *ListenTest) String() string { return proto.CompactTextString(m) } func (*ListenTest) ProtoMessage() {} func (*ListenTest) Descriptor() ([]byte, []int) { return fileDescriptor_e49b496f4919bda1, []int{17} } func (m *ListenTest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ListenTest.Unmarshal(m, b) } func (m *ListenTest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ListenTest.Marshal(b, m, deterministic) } func (m *ListenTest) XXX_Merge(src proto.Message) { xxx_messageInfo_ListenTest.Merge(m, src) } func (m *ListenTest) XXX_Size() int { return xxx_messageInfo_ListenTest.Size(m) } func (m *ListenTest) XXX_DiscardUnknown() { xxx_messageInfo_ListenTest.DiscardUnknown(m) } var xxx_messageInfo_ListenTest proto.InternalMessageInfo func (m *ListenTest) GetResponses() []*v1.ListenResponse { if m != nil { return m.Responses } return nil } func (m *ListenTest) GetSnapshots() []*Snapshot { if m != nil { return m.Snapshots } return nil } func (m *ListenTest) GetIsError() bool { if m != nil { return m.IsError } return false } type Snapshot struct { Docs []*v1.Document `protobuf:"bytes,1,rep,name=docs,proto3" json:"docs,omitempty"` Changes []*DocChange `protobuf:"bytes,2,rep,name=changes,proto3" json:"changes,omitempty"` ReadTime *timestamp.Timestamp `protobuf:"bytes,3,opt,name=read_time,json=readTime,proto3" json:"read_time,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *Snapshot) Reset() { *m = Snapshot{} } func (m *Snapshot) String() string { return proto.CompactTextString(m) } func (*Snapshot) ProtoMessage() {} func (*Snapshot) Descriptor() ([]byte, []int) { return fileDescriptor_e49b496f4919bda1, []int{18} } func (m *Snapshot) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Snapshot.Unmarshal(m, b) } func (m *Snapshot) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Snapshot.Marshal(b, m, deterministic) } func (m *Snapshot) XXX_Merge(src proto.Message) { xxx_messageInfo_Snapshot.Merge(m, src) } func (m *Snapshot) XXX_Size() int { return xxx_messageInfo_Snapshot.Size(m) } func (m *Snapshot) XXX_DiscardUnknown() { xxx_messageInfo_Snapshot.DiscardUnknown(m) } var xxx_messageInfo_Snapshot proto.InternalMessageInfo func (m *Snapshot) GetDocs() []*v1.Document { if m != nil { return m.Docs } return nil } func (m *Snapshot) GetChanges() []*DocChange { if m != nil { return m.Changes } return nil } func (m *Snapshot) GetReadTime() *timestamp.Timestamp { if m != nil { return m.ReadTime } return nil } type DocChange struct { Kind DocChange_Kind `protobuf:"varint,1,opt,name=kind,proto3,enum=google.cloud.conformance.firestore.v1.DocChange_Kind" json:"kind,omitempty"` Doc *v1.Document `protobuf:"bytes,2,opt,name=doc,proto3" json:"doc,omitempty"` OldIndex int32 `protobuf:"varint,3,opt,name=old_index,json=oldIndex,proto3" json:"old_index,omitempty"` NewIndex int32 `protobuf:"varint,4,opt,name=new_index,json=newIndex,proto3" json:"new_index,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *DocChange) Reset() { *m = DocChange{} } func (m *DocChange) String() string { return proto.CompactTextString(m) } func (*DocChange) ProtoMessage() {} func (*DocChange) Descriptor() ([]byte, []int) { return fileDescriptor_e49b496f4919bda1, []int{19} } func (m *DocChange) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_DocChange.Unmarshal(m, b) } func (m *DocChange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_DocChange.Marshal(b, m, deterministic) } func (m *DocChange) XXX_Merge(src proto.Message) { xxx_messageInfo_DocChange.Merge(m, src) } func (m *DocChange) XXX_Size() int { return xxx_messageInfo_DocChange.Size(m) } func (m *DocChange) XXX_DiscardUnknown() { xxx_messageInfo_DocChange.DiscardUnknown(m) } var xxx_messageInfo_DocChange proto.InternalMessageInfo func (m *DocChange) GetKind() DocChange_Kind { if m != nil { return m.Kind } return DocChange_KIND_UNSPECIFIED } func (m *DocChange) GetDoc() *v1.Document { if m != nil { return m.Doc } return nil } func (m *DocChange) GetOldIndex() int32 { if m != nil { return m.OldIndex } return 0 } func (m *DocChange) GetNewIndex() int32 { if m != nil { return m.NewIndex } return 0 } func init() { proto.RegisterEnum("google.cloud.conformance.firestore.v1.DocChange_Kind", DocChange_Kind_name, DocChange_Kind_value) proto.RegisterType((*TestFile)(nil), "google.cloud.conformance.firestore.v1.TestFile") proto.RegisterType((*Test)(nil), "google.cloud.conformance.firestore.v1.Test") proto.RegisterType((*GetTest)(nil), "google.cloud.conformance.firestore.v1.GetTest") proto.RegisterType((*CreateTest)(nil), "google.cloud.conformance.firestore.v1.CreateTest") proto.RegisterType((*SetTest)(nil), "google.cloud.conformance.firestore.v1.SetTest") proto.RegisterType((*UpdateTest)(nil), "google.cloud.conformance.firestore.v1.UpdateTest") proto.RegisterType((*UpdatePathsTest)(nil), "google.cloud.conformance.firestore.v1.UpdatePathsTest") proto.RegisterType((*DeleteTest)(nil), "google.cloud.conformance.firestore.v1.DeleteTest") proto.RegisterType((*SetOption)(nil), "google.cloud.conformance.firestore.v1.SetOption") proto.RegisterType((*QueryTest)(nil), "google.cloud.conformance.firestore.v1.QueryTest") proto.RegisterType((*Clause)(nil), "google.cloud.conformance.firestore.v1.Clause") proto.RegisterType((*Select)(nil), "google.cloud.conformance.firestore.v1.Select") proto.RegisterType((*Where)(nil), "google.cloud.conformance.firestore.v1.Where") proto.RegisterType((*OrderBy)(nil), "google.cloud.conformance.firestore.v1.OrderBy") proto.RegisterType((*Cursor)(nil), "google.cloud.conformance.firestore.v1.Cursor") proto.RegisterType((*DocSnapshot)(nil), "google.cloud.conformance.firestore.v1.DocSnapshot") proto.RegisterType((*FieldPath)(nil), "google.cloud.conformance.firestore.v1.FieldPath") proto.RegisterType((*ListenTest)(nil), "google.cloud.conformance.firestore.v1.ListenTest") proto.RegisterType((*Snapshot)(nil), "google.cloud.conformance.firestore.v1.Snapshot") proto.RegisterType((*DocChange)(nil), "google.cloud.conformance.firestore.v1.DocChange") } func init() { proto.RegisterFile("tests.proto", fileDescriptor_e49b496f4919bda1) } var fileDescriptor_e49b496f4919bda1 = []byte{ // 1340 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x58, 0xdf, 0x8e, 0xdb, 0xc4, 0x17, 0xae, 0x93, 0xd8, 0xb1, 0x4f, 0x56, 0xfd, 0xad, 0x46, 0xd5, 0x4f, 0xa6, 0x50, 0x35, 0x75, 0x41, 0x2c, 0x02, 0xb2, 0xec, 0x22, 0x40, 0x42, 0x08, 0x69, 0x13, 0x67, 0xff, 0x74, 0xd9, 0xee, 0xd6, 0x69, 0xcb, 0x05, 0x2b, 0x45, 0x5e, 0xfb, 0x64, 0xd7, 0xe0, 0x78, 0xd2, 0xf1, 0xa4, 0xa5, 0x12, 0x17, 0xdc, 0x70, 0xc5, 0x6b, 0x70, 0x85, 0xc4, 0x03, 0x70, 0xcb, 0x0d, 0x88, 0x0b, 0x2e, 0x79, 0x09, 0x5e, 0x02, 0xcd, 0x1f, 0xc7, 0xd9, 0x6d, 0x28, 0x4e, 0x0b, 0xe5, 0xce, 0x33, 0x73, 0xbe, 0x6f, 0xbe, 0x73, 0xe6, 0x9c, 0x33, 0x93, 0x40, 0x8b, 0x63, 0xce, 0xf3, 0xce, 0x84, 0x51, 0x4e, 0xc9, 0x6b, 0xa7, 0x94, 0x9e, 0xa6, 0xd8, 0x89, 0x52, 0x3a, 0x8d, 0x3b, 0x11, 0xcd, 0x46, 0x94, 0x8d, 0xc3, 0x2c, 0xc2, 0xce, 0x28, 0x61, 0x98, 0x73, 0xca, 0xb0, 0xf3, 0x70, 0xe3, 0x6a, 0x5b, 0x99, 0xad, 0xcf, 0x26, 0xd7, 0x1f, 0x6e, 0xac, 0x47, 0x74, 0x3c, 0xa6, 0x99, 0x22, 0xba, 0xea, 0x2d, 0xb2, 0x88, 0x69, 0x34, 0x1d, 0x63, 0xc6, 0xb5, 0xcd, 0xcd, 0x45, 0x36, 0xe5, 0x3e, 0xca, 0xe8, 0xfa, 0x22, 0xa3, 0x07, 0x53, 0x64, 0x8f, 0x2f, 0x18, 0xc8, 0xd1, 0xc9, 0x74, 0xb4, 0xce, 0x93, 0x31, 0xe6, 0x3c, 0x1c, 0x4f, 0x94, 0x81, 0x77, 0x00, 0xf6, 0x5d, 0xcc, 0xf9, 0x76, 0x92, 0x22, 0xd9, 0x02, 0x53, 0xba, 0xeb, 0x1a, 0xed, 0xfa, 0x5a, 0x6b, 0xf3, 0xcd, 0x4e, 0x25, 0x7f, 0x3b, 0x02, 0x1f, 0x28, 0xa4, 0xf7, 0x83, 0x09, 0x0d, 0x31, 0x26, 0x6d, 0x68, 0xc5, 0x98, 0x47, 0x2c, 0x99, 0xf0, 0x84, 0x66, 0xae, 0xd1, 0x36, 0xd6, 0x9c, 0x60, 0x7e, 0x8a, 0xb8, 0xd0, 0x14, 0x41, 0xc1, 0x8c, 0xbb, 0x20, 0x57, 0x8b, 0x21, 0xe9, 0x42, 0xfd, 0x14, 0xb9, 0x5b, 0x6b, 0x1b, 0x6b, 0xad, 0xcd, 0x4e, 0x45, 0x15, 0x3b, 0xc8, 0xc5, 0xc6, 0xbb, 0x97, 0x02, 0x01, 0x26, 0xfb, 0x60, 0x45, 0x0c, 0x43, 0x8e, 0x6e, 0x5d, 0xd2, 0x6c, 0x54, 0xa4, 0xe9, 0x49, 0x90, 0x66, 0xd2, 0x14, 0x42, 0x50, 0x8e, 0xdc, 0x6d, 0x2c, 0x25, 0x68, 0x50, 0x0a, 0xca, 0x95, 0xa0, 0xe9, 0x24, 0x16, 0x82, 0xcc, 0xa5, 0x04, 0xdd, 0x93, 0xa0, 0x42, 0x90, 0xa2, 0x20, 0x9f, 0xc1, 0x8a, 0xfa, 0x1a, 0x4e, 0x42, 0x7e, 0x96, 0xbb, 0x96, 0xa4, 0x7c, 0x7f, 0x29, 0xca, 0x23, 0x81, 0xd4, 0xbc, 0xad, 0x69, 0x39, 0x25, 0x94, 0xc6, 0x98, 0x22, 0x47, 0xb7, 0xb9, 0x94, 0x52, 0x5f, 0x82, 0x0a, 0xa5, 0x8a, 0x82, 0xec, 0x82, 0x29, 0xf3, 0xd1, 0xb5, 0x25, 0xd7, 0x3b, 0x15, 0xb9, 0xee, 0x08, 0x8c, 0xa6, 0x52, 0x04, 0x42, 0x56, 0x9a, 0xe4, 0x1c, 0x33, 0xd7, 0x59, 0x4a, 0xd6, 0x27, 0x12, 0x54, 0xc8, 0x52, 0x14, 0x5d, 0x0b, 0x1a, 0x22, 0x61, 0xbd, 0x0c, 0x9a, 0x3a, 0x71, 0x48, 0x1b, 0x56, 0x62, 0x1a, 0x0d, 0x19, 0x8e, 0x64, 0x50, 0x75, 0xca, 0x42, 0x4c, 0xa3, 0x00, 0x47, 0x22, 0x32, 0x64, 0x0b, 0x9a, 0x0c, 0x1f, 0x4c, 0x31, 0x2f, 0x72, 0xf3, 0xf5, 0x42, 0xc2, 0xc5, 0x4c, 0xf4, 0x75, 0x2d, 0x07, 0xca, 0x3c, 0x28, 0x70, 0xde, 0x77, 0x06, 0x40, 0x99, 0x62, 0x15, 0xf6, 0x7c, 0x19, 0x9c, 0xcf, 0x73, 0x9a, 0x0d, 0xe3, 0x90, 0x87, 0x72, 0x57, 0x27, 0xb0, 0xc5, 0x84, 0x1f, 0xf2, 0x90, 0x7c, 0x54, 0x0a, 0x52, 0x59, 0xee, 0x2d, 0x14, 0xd4, 0xa3, 0xe3, 0x71, 0xf2, 0x84, 0x16, 0xf2, 0x12, 0xd8, 0x49, 0x3e, 0x44, 0xc6, 0x28, 0x93, 0xa9, 0x6d, 0x07, 0xcd, 0x24, 0xef, 0x8b, 0xa1, 0xf7, 0x87, 0x01, 0xcd, 0x41, 0xe5, 0xb8, 0xec, 0x82, 0x45, 0x55, 0x99, 0xd7, 0x96, 0x3a, 0xe4, 0x01, 0xf2, 0x43, 0x89, 0x0b, 0x34, 0xfe, 0xbc, 0xb7, 0xf5, 0xbf, 0xf6, 0xb6, 0xf1, 0x7c, 0xde, 0x9a, 0x4f, 0x78, 0x0b, 0x65, 0x99, 0x55, 0x70, 0xb8, 0x0f, 0x2b, 0x13, 0x86, 0x11, 0xcd, 0xe2, 0x64, 0xce, 0xed, 0x1b, 0x0b, 0xe5, 0x1c, 0xcd, 0x19, 0x06, 0xe7, 0x60, 0xff, 0x91, 0xb7, 0x3f, 0xd7, 0xe0, 0x7f, 0x17, 0x3a, 0xc0, 0x8b, 0x73, 0xf9, 0x0e, 0xb4, 0x46, 0x09, 0xa6, 0xb1, 0xee, 0x5b, 0x75, 0x79, 0xd1, 0x54, 0xcd, 0x97, 0x6d, 0x81, 0x14, 0x6a, 0x02, 0x18, 0x15, 0x9f, 0x39, 0xb9, 0x0e, 0x2d, 0x19, 0xc5, 0x87, 0x61, 0x3a, 0xc5, 0xdc, 0x6d, 0xb4, 0xeb, 0x42, 0xba, 0x98, 0xba, 0x2f, 0x67, 0xe6, 0x23, 0x69, 0x3e, 0x5f, 0x24, 0xad, 0xf3, 0x91, 0xfc, 0xcd, 0x00, 0x28, 0x9b, 0xde, 0x8b, 0x0b, 0xe2, 0xbf, 0x56, 0xf6, 0xa7, 0xe0, 0xcc, 0x6a, 0x92, 0xac, 0x42, 0x3d, 0x4c, 0x53, 0xe9, 0x85, 0x1d, 0x88, 0x4f, 0x51, 0xe7, 0x32, 0xee, 0xb9, 0x5b, 0x7b, 0xc6, 0x73, 0xd3, 0x78, 0xef, 0x17, 0x03, 0x9c, 0x59, 0x8b, 0x17, 0x75, 0x10, 0xd1, 0x34, 0x9d, 0x8f, 0x9a, 0x2d, 0x26, 0x64, 0xcc, 0x76, 0xa0, 0x19, 0xa5, 0xe1, 0x34, 0xc7, 0x62, 0xd7, 0xb7, 0xab, 0xde, 0xe4, 0x12, 0x15, 0x14, 0x68, 0xf2, 0x61, 0x71, 0x13, 0xa9, 0x98, 0xbd, 0xba, 0x30, 0x66, 0x03, 0xce, 0xa6, 0x11, 0x9f, 0x32, 0x8c, 0xa5, 0xbc, 0xe2, 0xee, 0x79, 0x4a, 0xcc, 0x7e, 0x6f, 0x80, 0xa5, 0xb6, 0x22, 0x3b, 0x60, 0xe5, 0x98, 0x62, 0xc4, 0xa5, 0x13, 0xd5, 0x95, 0x0e, 0x24, 0x48, 0xdc, 0x4e, 0x0a, 0x4e, 0x7c, 0x30, 0x1f, 0x9d, 0x21, 0x43, 0x9d, 0x20, 0x6f, 0x55, 0xe4, 0xf9, 0x54, 0x60, 0xc4, 0x85, 0x29, 0xc1, 0x64, 0x1f, 0x6c, 0xca, 0x62, 0x64, 0xc3, 0x93, 0xc2, 0xe7, 0xaa, 0x4f, 0x97, 0x43, 0x01, 0xeb, 0x3e, 0xde, 0xbd, 0x14, 0x34, 0xa9, 0xfa, 0x24, 0x2e, 0x58, 0x74, 0x34, 0x2a, 0x5e, 0x41, 0xa6, 0x10, 0xab, 0xc6, 0xe4, 0xff, 0x60, 0xa6, 0xc9, 0x38, 0x51, 0xc5, 0x25, 0x16, 0xd4, 0x90, 0xdc, 0x02, 0x3b, 0xe7, 0x21, 0xe3, 0xc3, 0x90, 0xeb, 0xf7, 0x49, 0xe5, 0x93, 0x9b, 0xb2, 0x9c, 0x32, 0xb1, 0xbb, 0x24, 0xd8, 0xe2, 0xe4, 0x08, 0x5a, 0x9a, 0x6b, 0xc4, 0x91, 0xe9, 0x77, 0xc9, 0xd2, 0x74, 0xa0, 0xe8, 0x04, 0x05, 0xd9, 0x06, 0x0b, 0xb3, 0x58, 0x68, 0xb3, 0x9f, 0x8d, 0xcc, 0xc4, 0x2c, 0xde, 0xe2, 0xe4, 0x36, 0x80, 0xe0, 0x39, 0xc1, 0x11, 0x65, 0xa8, 0x5f, 0x26, 0x4b, 0x73, 0x39, 0x98, 0xc5, 0x5d, 0xc9, 0xd0, 0xb5, 0xc1, 0x52, 0x09, 0xeb, 0x05, 0x60, 0xa9, 0xc4, 0x98, 0xab, 0x3b, 0xe3, 0x39, 0xeb, 0xee, 0x2b, 0x30, 0x65, 0x92, 0x10, 0x1f, 0x1a, 0xb3, 0x6a, 0x7b, 0x16, 0x42, 0x89, 0x26, 0x97, 0xa1, 0x46, 0x27, 0xfa, 0x55, 0x52, 0xa3, 0x13, 0x72, 0x0d, 0xa0, 0x6c, 0xc5, 0xfa, 0x46, 0x73, 0x66, 0x9d, 0xd8, 0x1b, 0x43, 0x53, 0x67, 0xd6, 0x3f, 0xb4, 0xff, 0x2b, 0xe0, 0xc4, 0x09, 0xc3, 0x68, 0xd6, 0x4c, 0x9d, 0xa0, 0x9c, 0xf0, 0xbe, 0x36, 0xc0, 0x52, 0x21, 0x26, 0xf7, 0x54, 0x6b, 0xce, 0xb3, 0x70, 0x92, 0x9f, 0xd1, 0xa2, 0x3e, 0x37, 0xab, 0x3e, 0x6c, 0x69, 0x34, 0xd0, 0xc8, 0xa0, 0x15, 0x97, 0x83, 0x8b, 0x57, 0x4f, 0xed, 0xe2, 0xd5, 0xe3, 0x7d, 0x0c, 0xad, 0x39, 0x30, 0x21, 0x73, 0x5e, 0x3b, 0xda, 0x87, 0xa7, 0x3d, 0xf0, 0xbc, 0x1b, 0xe0, 0xcc, 0x7c, 0x26, 0x57, 0xc0, 0x94, 0xc7, 0x28, 0xb3, 0xc0, 0x09, 0xd4, 0xc0, 0xfb, 0xd1, 0x00, 0x28, 0x9f, 0xb8, 0x64, 0x0b, 0x1c, 0x86, 0xf9, 0x84, 0x66, 0xa2, 0x61, 0xaa, 0x74, 0xb9, 0xb9, 0xb0, 0xd3, 0x29, 0x4c, 0xa0, 0x6d, 0x83, 0x12, 0x45, 0x0e, 0xc0, 0x29, 0x02, 0x55, 0xf4, 0xdc, 0xf5, 0xaa, 0x9d, 0xac, 0x08, 0x53, 0xc9, 0x70, 0xae, 0x77, 0xd6, 0xcf, 0xf7, 0xce, 0x9f, 0x0c, 0xb0, 0x67, 0xc1, 0xd9, 0x80, 0x46, 0x4c, 0xa3, 0x42, 0xf4, 0xb5, 0x85, 0xa2, 0x67, 0xef, 0x6a, 0x69, 0x4a, 0x6e, 0x41, 0x33, 0x3a, 0x0b, 0xb3, 0x53, 0x5c, 0xf6, 0x46, 0xf2, 0x69, 0xd4, 0x93, 0xc0, 0xa0, 0x20, 0x20, 0x1f, 0x88, 0xc0, 0x85, 0xf1, 0x50, 0xfc, 0x40, 0xd6, 0xed, 0xf2, 0x6a, 0xc1, 0x56, 0xfc, 0x7a, 0xee, 0xdc, 0x2d, 0x7e, 0x3d, 0x07, 0xb6, 0x30, 0x16, 0x43, 0xef, 0x9b, 0x1a, 0x38, 0x33, 0x3e, 0xb2, 0x07, 0x8d, 0x2f, 0x92, 0x2c, 0x96, 0x47, 0x7c, 0x79, 0xf3, 0xbd, 0x65, 0xf5, 0x74, 0xf6, 0x93, 0x2c, 0x0e, 0x24, 0x05, 0x59, 0x87, 0x7a, 0x4c, 0x23, 0x7d, 0x07, 0xfc, 0x4d, 0x3c, 0x84, 0xa5, 0x48, 0x25, 0x9a, 0xc6, 0xc3, 0x24, 0x8b, 0xf1, 0x4b, 0xe9, 0x82, 0x19, 0xd8, 0x34, 0x8d, 0xf7, 0xc4, 0x58, 0x2c, 0x66, 0xf8, 0x48, 0x2f, 0x36, 0xd4, 0x62, 0x86, 0x8f, 0xe4, 0xa2, 0xd7, 0x85, 0x86, 0xd8, 0x98, 0x5c, 0x81, 0xd5, 0xfd, 0xbd, 0xdb, 0xfe, 0xf0, 0xde, 0xed, 0xc1, 0x51, 0xbf, 0xb7, 0xb7, 0xbd, 0xd7, 0xf7, 0x57, 0x2f, 0x11, 0x07, 0xcc, 0x2d, 0xdf, 0xef, 0xfb, 0xab, 0x06, 0x69, 0x41, 0x33, 0xe8, 0x1f, 0x1c, 0xde, 0xef, 0xfb, 0xab, 0x35, 0xb2, 0x02, 0xf6, 0xc1, 0xa1, 0xaf, 0xac, 0xea, 0xdd, 0x6f, 0x0d, 0x78, 0x23, 0xa2, 0xe3, 0x6a, 0x1e, 0x77, 0x2f, 0x8b, 0x6c, 0xf5, 0x71, 0x94, 0x64, 0xf2, 0x4d, 0xf3, 0x7d, 0xcd, 0xdb, 0x51, 0xb8, 0x9e, 0xc4, 0x6d, 0xcf, 0x6c, 0xef, 0xca, 0x3f, 0x60, 0x8e, 0xc4, 0x09, 0xfc, 0x5a, 0x5b, 0x53, 0x46, 0xc7, 0xd2, 0xe8, 0x78, 0x66, 0x74, 0x2c, 0x8d, 0x8e, 0x7b, 0xe5, 0x66, 0x27, 0x96, 0x3c, 0xb3, 0x77, 0xff, 0x0c, 0x00, 0x00, 0xff, 0xff, 0xe0, 0x87, 0x8a, 0x65, 0xc1, 0x11, 0x00, 0x00, } google-cloud-go-0.49.0/firestore/internal/conformance/tests.proto000066400000000000000000000146621356504100700251400ustar00rootroot00000000000000// Copyright 2019 Google LLC. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // Tests for firestore clients. syntax = "proto3"; package google.cloud.conformance.firestore.v1; option php_namespace = "Google\\Cloud\\Firestore\\Tests\\Conformance"; option csharp_namespace = "Google.Cloud.Firestore.Tests.Proto"; option java_outer_classname = "TestDefinition"; option java_package = "com.google.cloud.conformance.firestore.v1"; import "google/firestore/v1/common.proto"; import "google/firestore/v1/document.proto"; import "google/firestore/v1/firestore.proto"; import "google/firestore/v1/query.proto"; import "google/protobuf/timestamp.proto"; // A collection of tests. message TestFile { repeated Test tests = 1; } // A Test describes a single client method call and its expected result. message Test { string description = 1; // short description of the test string comment = 10; // a comment describing the behavior being tested oneof test { GetTest get = 2; CreateTest create = 3; SetTest set = 4; UpdateTest update = 5; UpdatePathsTest update_paths = 6; DeleteTest delete = 7; QueryTest query = 8; ListenTest listen = 9; } } // Call to the DocumentRef.Get method. message GetTest { // The path of the doc, e.g. "projects/projectID/databases/(default)/documents/C/d" string doc_ref_path = 1; // The request that the call should send to the Firestore service. google.firestore.v1.GetDocumentRequest request = 2; } // Call to DocumentRef.Create. message CreateTest { // The path of the doc, e.g. "projects/projectID/databases/(default)/documents/C/d" string doc_ref_path = 1; // The data passed to Create, as JSON. The strings "Delete" and "ServerTimestamp" // denote the two special sentinel values. Values that could be interpreted as integers // (i.e. digit strings) should be treated as integers. string json_data = 2; // The request that the call should generate. google.firestore.v1.CommitRequest request = 3; // If true, the call should result in an error without generating a request. // If this is true, request should not be set. bool is_error = 4; } // A call to DocumentRef.Set. message SetTest { string doc_ref_path = 1; // path of doc SetOption option = 2; // option to the Set call, if any string json_data = 3; // data (see CreateTest.json_data) google.firestore.v1.CommitRequest request = 4; // expected request bool is_error = 5; // call signals an error } // A call to the form of DocumentRef.Update that represents the data as a map // or dictionary. message UpdateTest { string doc_ref_path = 1; // path of doc google.firestore.v1.Precondition precondition = 2; // precondition in call, if any string json_data = 3; // data (see CreateTest.json_data) google.firestore.v1.CommitRequest request = 4; // expected request bool is_error = 5; // call signals an error } // A call to the form of DocumentRef.Update that represents the data as a list // of field paths and their values. message UpdatePathsTest { string doc_ref_path = 1; // path of doc google.firestore.v1.Precondition precondition = 2; // precondition in call, if any // parallel sequences: field_paths[i] corresponds to json_values[i] repeated FieldPath field_paths = 3; // the argument field paths repeated string json_values = 4; // the argument values, as JSON google.firestore.v1.CommitRequest request = 5; // expected rquest bool is_error = 6; // call signals an error } // A call to DocmentRef.Delete message DeleteTest { string doc_ref_path = 1; // path of doc google.firestore.v1.Precondition precondition = 2; google.firestore.v1.CommitRequest request = 3; // expected rquest bool is_error = 4; // call signals an error } // An option to the DocumentRef.Set call. message SetOption { bool all = 1; // if true, merge all fields ("fields" is ignored). repeated FieldPath fields = 2; // field paths for a Merge option } message QueryTest { string coll_path = 1; // path of collection, e.g. "projects/projectID/databases/(default)/documents/C" repeated Clause clauses = 2; google.firestore.v1.StructuredQuery query = 3; bool is_error = 4; } message Clause { oneof clause { Select select = 1; Where where = 2; OrderBy order_by = 3; int32 offset = 4; int32 limit = 5; Cursor start_at = 6; Cursor start_after = 7; Cursor end_at = 8; Cursor end_before = 9; } } message Select { repeated FieldPath fields = 1; } message Where { FieldPath path = 1; string op = 2; string json_value = 3; } message OrderBy { FieldPath path = 1; string direction = 2; // "asc" or "desc" } message Cursor { // one of: DocSnapshot doc_snapshot = 1; repeated string json_values = 2; } message DocSnapshot { string path = 1; string json_data = 2; } message FieldPath { repeated string field = 1; } // A test of the Listen streaming RPC (a.k.a. FireStore watch). // If the sequence of responses is provided to the implementation, // it should produce the sequence of snapshots. // If is_error is true, an error should occur after the snapshots. // // The tests assume that the query is // Collection("projects/projectID/databases/(default)/documents/C").OrderBy("a", Ascending) // // The watch target ID used in these tests is 1. Test interpreters // should either change their client's ID for testing, // or change the ID in the tests before running them. message ListenTest { repeated google.firestore.v1.ListenResponse responses = 1; repeated Snapshot snapshots = 2; bool is_error = 3; } message Snapshot { repeated google.firestore.v1.Document docs = 1; repeated DocChange changes = 2; google.protobuf.Timestamp read_time = 3; } message DocChange { enum Kind { KIND_UNSPECIFIED = 0; ADDED = 1; REMOVED = 2; MODIFIED = 3; } Kind kind = 1; google.firestore.v1.Document doc = 2; int32 old_index = 3; int32 new_index = 4; } google-cloud-go-0.49.0/firestore/internal/doc-snippets.go000066400000000000000000000070051356504100700233470ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package internal // TODO(deklerk): can this file and directory be deleted, or is it being used for documentation somewhere? import ( "context" "fmt" firestore "cloud.google.com/go/firestore" "google.golang.org/api/iterator" ) // State represents a state. //[ structDef type State struct { Capital string `firestore:"capital"` Population float64 `firestore:"pop"` // in millions } //] func f1() { //[ NewClient ctx := context.Background() client, err := firestore.NewClient(ctx, "projectID") if err != nil { // TODO: Handle error. } //] //[ refs states := client.Collection("States") ny := states.Doc("NewYork") // Or, in a single call: ny = client.Doc("States/NewYork") //] //[ docref.Get docsnap, err := ny.Get(ctx) if err != nil { // TODO: Handle error. } dataMap := docsnap.Data() fmt.Println(dataMap) //] //[ DataTo var nyData State if err := docsnap.DataTo(&nyData); err != nil { // TODO: Handle error. } //] //[ GetAll docsnaps, err := client.GetAll(ctx, []*firestore.DocumentRef{ states.Doc("Wisconsin"), states.Doc("Ohio"), }) if err != nil { // TODO: Handle error. } for _, ds := range docsnaps { _ = ds // TODO: Use ds. } //[ docref.Create wr, err := ny.Create(ctx, State{ Capital: "Albany", Population: 19.8, }) if err != nil { // TODO: Handle error. } fmt.Println(wr) //] //[ docref.Set ca := states.Doc("California") _, err = ca.Set(ctx, State{ Capital: "Sacramento", Population: 39.14, }) //] //[ docref.Update _, err = ca.Update(ctx, []firestore.Update{{Path: "capital", Value: "Sacramento"}}) //] //[ docref.Delete _, err = ny.Delete(ctx) //] //[ LUT-precond docsnap, err = ca.Get(ctx) if err != nil { // TODO: Handle error. } _, err = ca.Update(ctx, []firestore.Update{{Path: "capital", Value: "Sacramento"}}, firestore.LastUpdateTime(docsnap.UpdateTime)) //] //[ WriteBatch writeResults, err := client.Batch(). Create(ny, State{Capital: "Albany"}). Update(ca, []firestore.Update{{Path: "capital", Value: "Sacramento"}}). Delete(client.Doc("States/WestDakota")). Commit(ctx) //] _ = writeResults //[ Query q := states.Where("pop", ">", 10).OrderBy("pop", firestore.Desc) //] //[ Documents iter := q.Documents(ctx) for { doc, err := iter.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } fmt.Println(doc.Data()) } //] //[ CollQuery iter = client.Collection("States").Documents(ctx) //] } func txn() { var ctx context.Context var client *firestore.Client //[ Transaction ny := client.Doc("States/NewYork") err := client.RunTransaction(ctx, func(ctx context.Context, tx *firestore.Transaction) error { doc, err := tx.Get(ny) // tx.Get, NOT ny.Get! if err != nil { return err } pop, err := doc.DataAt("pop") if err != nil { return err } return tx.Update(ny, []firestore.Update{{Path: "pop", Value: pop.(float64) + 0.2}}) }) if err != nil { // TODO: Handle error. } //] } google-cloud-go-0.49.0/firestore/internal/doc.template000066400000000000000000000102571356504100700227150ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // DO NOT EDIT doc.go. Modify internal/doc.template, then run make -C internal. /* Package firestore provides a client for reading and writing to a Cloud Firestore database. See https://cloud.google.com/firestore/docs for an introduction to Cloud Firestore and additional help on using the Firestore API. Note: you can't use both Cloud Firestore and Cloud Datastore in the same project. Creating a Client To start working with this package, create a client with a project ID: [NewClient] CollectionRefs and DocumentRefs In Firestore, documents are sets of key-value pairs, and collections are groups of documents. A Firestore database consists of a hierarchy of alternating collections and documents, referred to by slash-separated paths like "States/California/Cities/SanFrancisco". This client is built around references to collections and documents. CollectionRefs and DocumentRefs are lightweight values that refer to the corresponding database entities. Creating a ref does not involve any network traffic. [refs] Reading Use DocumentRef.Get to read a document. The result is a DocumentSnapshot. Call its Data method to obtain the entire document contents as a map. [docref.Get] You can also obtain a single field with DataAt, or extract the data into a struct with DataTo. With the type definition [structDef] we can extract the document's data into a value of type State: [DataTo] Note that this client supports struct tags beginning with "firestore:" that work like the tags of the encoding/json package, letting you rename fields, ignore them, or omit their values when empty. To retrieve multiple documents from their references in a single call, use Client.GetAll. [GetAll] Writing For writing individual documents, use the methods on DocumentReference. Create creates a new document. [docref.Create] The first return value is a WriteResult, which contains the time at which the document was updated. Create fails if the document exists. Another method, Set, either replaces an existing document or creates a new one. [docref.Set] To update some fields of an existing document, use Update. It takes a list of paths to update and their corresponding values. [docref.Update] Use DocumentRef.Delete to delete a document. [docref.Delete] Preconditions You can condition Deletes or Updates on when a document was last changed. Specify these preconditions as an option to a Delete or Update method. The check and the write happen atomically with a single RPC. [LUT-precond] Here we update a doc only if it hasn't changed since we read it. You could also do this with a transaction. To perform multiple writes at once, use a WriteBatch. Its methods chain for convenience. WriteBatch.Commit sends the collected writes to the server, where they happen atomically. [WriteBatch] Queries You can use SQL to select documents from a collection. Begin with the collection, and build up a query using Select, Where and other methods of Query. [Query] Call the Query's Documents method to get an iterator, and use it like the other Google Cloud Client iterators. [Documents] To get all the documents in a collection, you can use the collection itself as a query. [CollQuery] Transactions Use a transaction to execute reads and writes atomically. All reads must happen before any writes. Transaction creation, commit, rollback and retry are handled for you by the Client.RunTransaction method; just provide a function and use the read and write methods of the Transaction passed to it. [Transaction] Authentication See examples of authorization and authentication at https://godoc.org/cloud.google.com/go#pkg-examples. */ package firestore google-cloud-go-0.49.0/firestore/internal/snipdoc.awk000066400000000000000000000050711356504100700225540ustar00rootroot00000000000000# Copyright 2017 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # snipdoc merges code snippets from Go source files into a template to # produce another go file (typically doc.go). # # Call with one or more .go files and a template file. # # awk -f snipmd.awk foo.go bar.go doc.template # # In the Go files, start a snippet with # //[ NAME # and end it with # //] # # In the template, write # [NAME] # on a line by itself to insert the snippet NAME on that line. # # The following transformations are made to the Go code: # - Trailing blank lines are removed. # - `ELLIPSIS` and `_ = ELLIPSIS` are replaced by `...` /^[ \t]*\/\/\[/ { # start snippet in Go file if (inGo()) { if ($2 == "") { die("missing snippet name") } curSnip = $2 next } } /^[ \t]*\/\/]/ { # end snippet in Go file if (inGo()) { if (curSnip != "") { # Remove all trailing newlines. gsub(/[\t\n]+$/, "", snips[curSnip]) curSnip = "" next } else { die("//] without corresponding //[") } } } ENDFILE { if (curSnip != "") { die("unclosed snippet: " curSnip) } } /^\[.*\]$/ { # Snippet marker in template file. if (inTemplate()) { name = substr($1, 2, length($1)-2) if (snips[name] == "") { die("no snippet named " name) } printf("%s\n", snips[name]) afterSnip = 1 next } } # Matches every line. { if (curSnip != "") { # If the first line in the snip has no indent, add the indent. if (snips[curSnip] == "") { if (index($0, "\t") == 1) { extraIndent = "" } else { extraIndent = "\t" } } line = $0 # Replace ELLIPSIS. gsub(/_ = ELLIPSIS/, "...", line) gsub(/ELLIPSIS/, "...", line) snips[curSnip] = snips[curSnip] extraIndent line "\n" } else if (inTemplate()) { afterSnip = 0 # Copy to output. print } } function inTemplate() { return match(FILENAME, /\.template$/) } function inGo() { return match(FILENAME, /\.go$/) } function die(msg) { printf("%s:%d: %s\n", FILENAME, FNR, msg) > "/dev/stderr" exit 1 } google-cloud-go-0.49.0/firestore/list_documents.go000066400000000000000000000056471356504100700221710ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package firestore import ( "context" vkit "cloud.google.com/go/firestore/apiv1" "google.golang.org/api/iterator" pb "google.golang.org/genproto/googleapis/firestore/v1" ) // DocumentRefIterator is an interator over DocumentRefs. type DocumentRefIterator struct { client *Client it *vkit.DocumentIterator pageInfo *iterator.PageInfo nextFunc func() error items []*DocumentRef err error } func newDocumentRefIterator(ctx context.Context, cr *CollectionRef, tid []byte) *DocumentRefIterator { client := cr.c req := &pb.ListDocumentsRequest{ Parent: cr.parentPath, CollectionId: cr.ID, ShowMissing: true, Mask: &pb.DocumentMask{}, // empty mask: we want only the ref } if tid != nil { req.ConsistencySelector = &pb.ListDocumentsRequest_Transaction{tid} } it := &DocumentRefIterator{ client: client, it: client.c.ListDocuments(withResourceHeader(ctx, client.path()), req), } it.pageInfo, it.nextFunc = iterator.NewPageInfo( it.fetch, func() int { return len(it.items) }, func() interface{} { b := it.items; it.items = nil; return b }) return it } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *DocumentRefIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there // are no more results. Once Next returns Done, all subsequent calls will return // Done. func (it *DocumentRefIterator) Next() (*DocumentRef, error) { if err := it.nextFunc(); err != nil { return nil, err } item := it.items[0] it.items = it.items[1:] return item, nil } func (it *DocumentRefIterator) fetch(pageSize int, pageToken string) (string, error) { if it.err != nil { return "", it.err } return iterFetch(pageSize, pageToken, it.it.PageInfo(), func() error { docProto, err := it.it.Next() if err != nil { return err } docRef, err := pathToDoc(docProto.Name, it.client) if err != nil { return err } it.items = append(it.items, docRef) return nil }) } // GetAll returns all the DocumentRefs remaining from the iterator. func (it *DocumentRefIterator) GetAll() ([]*DocumentRef, error) { var drs []*DocumentRef for { dr, err := it.Next() if err == iterator.Done { break } if err != nil { return nil, err } drs = append(drs, dr) } return drs, nil } google-cloud-go-0.49.0/firestore/mock_test.go000066400000000000000000000141751356504100700211210ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package firestore // A simple mock server. import ( "context" "fmt" "reflect" "sort" "strings" "cloud.google.com/go/internal/testutil" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes/empty" pb "google.golang.org/genproto/googleapis/firestore/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) type mockServer struct { pb.FirestoreServer Addr string reqItems []reqItem resps []interface{} } type reqItem struct { wantReq proto.Message adjust func(gotReq proto.Message) } func newMockServer() (_ *mockServer, cleanup func(), _ error) { srv, err := testutil.NewServer() if err != nil { return nil, func() {}, err } mock := &mockServer{Addr: srv.Addr} pb.RegisterFirestoreServer(srv.Gsrv, mock) srv.Start() return mock, func() { srv.Close() }, nil } // addRPC adds a (request, response) pair to the server's list of expected // interactions. The server will compare the incoming request with wantReq // using proto.Equal. The response can be a message or an error. // // For the Listen RPC, resp should be a []interface{}, where each element // is either ListenResponse or an error. // // Passing nil for wantReq disables the request check. func (s *mockServer) addRPC(wantReq proto.Message, resp interface{}) { s.addRPCAdjust(wantReq, resp, nil) } // addRPCAdjust is like addRPC, but accepts a function that can be used // to tweak the requests before comparison, for example to adjust for // randomness. func (s *mockServer) addRPCAdjust(wantReq proto.Message, resp interface{}, adjust func(proto.Message)) { s.reqItems = append(s.reqItems, reqItem{wantReq, adjust}) s.resps = append(s.resps, resp) } // popRPC compares the request with the next expected (request, response) pair. // It returns the response, or an error if the request doesn't match what // was expected or there are no expected rpcs. func (s *mockServer) popRPC(gotReq proto.Message) (interface{}, error) { if len(s.reqItems) == 0 { panic(fmt.Sprintf("out of RPCs, saw %v", reflect.TypeOf(gotReq))) } ri := s.reqItems[0] s.reqItems = s.reqItems[1:] if ri.wantReq != nil { if ri.adjust != nil { ri.adjust(gotReq) } // Sort FieldTransforms by FieldPath, since slice order is undefined and proto.Equal // is strict about order. switch gotReqTyped := gotReq.(type) { case *pb.CommitRequest: for _, w := range gotReqTyped.Writes { switch opTyped := w.Operation.(type) { case *pb.Write_Transform: sort.Sort(ByFieldPath(opTyped.Transform.FieldTransforms)) } } } if !proto.Equal(gotReq, ri.wantReq) { return nil, fmt.Errorf("mockServer: bad request\ngot:\n%T\n%s\nwant:\n%T\n%s", gotReq, proto.MarshalTextString(gotReq), ri.wantReq, proto.MarshalTextString(ri.wantReq)) } } resp := s.resps[0] s.resps = s.resps[1:] if err, ok := resp.(error); ok { return nil, err } return resp, nil } func (a ByFieldPath) Len() int { return len(a) } func (a ByFieldPath) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a ByFieldPath) Less(i, j int) bool { return a[i].FieldPath < a[j].FieldPath } type ByFieldPath []*pb.DocumentTransform_FieldTransform func (s *mockServer) reset() { s.reqItems = nil s.resps = nil } func (s *mockServer) GetDocument(_ context.Context, req *pb.GetDocumentRequest) (*pb.Document, error) { res, err := s.popRPC(req) if err != nil { return nil, err } return res.(*pb.Document), nil } func (s *mockServer) Commit(_ context.Context, req *pb.CommitRequest) (*pb.CommitResponse, error) { res, err := s.popRPC(req) if err != nil { return nil, err } return res.(*pb.CommitResponse), nil } func (s *mockServer) BatchGetDocuments(req *pb.BatchGetDocumentsRequest, bs pb.Firestore_BatchGetDocumentsServer) error { res, err := s.popRPC(req) if err != nil { return err } responses := res.([]interface{}) for _, res := range responses { switch res := res.(type) { case *pb.BatchGetDocumentsResponse: if err := bs.Send(res); err != nil { return err } case error: return res default: panic(fmt.Sprintf("bad response type in BatchGetDocuments: %+v", res)) } } return nil } func (s *mockServer) RunQuery(req *pb.RunQueryRequest, qs pb.Firestore_RunQueryServer) error { res, err := s.popRPC(req) if err != nil { return err } responses := res.([]interface{}) for _, res := range responses { switch res := res.(type) { case *pb.RunQueryResponse: if err := qs.Send(res); err != nil { return err } case error: return res default: panic(fmt.Sprintf("bad response type in RunQuery: %+v", res)) } } return nil } func (s *mockServer) BeginTransaction(_ context.Context, req *pb.BeginTransactionRequest) (*pb.BeginTransactionResponse, error) { res, err := s.popRPC(req) if err != nil { return nil, err } return res.(*pb.BeginTransactionResponse), nil } func (s *mockServer) Rollback(_ context.Context, req *pb.RollbackRequest) (*empty.Empty, error) { res, err := s.popRPC(req) if err != nil { return nil, err } return res.(*empty.Empty), nil } func (s *mockServer) Listen(stream pb.Firestore_ListenServer) error { req, err := stream.Recv() if err != nil { return err } responses, err := s.popRPC(req) if err != nil { if status.Code(err) == codes.Unknown && strings.Contains(err.Error(), "mockServer") { // The stream will retry on Unknown, but we don't want that to happen if // the error comes from us. panic(err) } return err } for _, res := range responses.([]interface{}) { if err, ok := res.(error); ok { return err } if err := stream.Send(res.(*pb.ListenResponse)); err != nil { return err } } return nil } google-cloud-go-0.49.0/firestore/options.go000066400000000000000000000113031356504100700206120ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package firestore import ( "errors" "fmt" "time" "github.com/golang/protobuf/ptypes" pb "google.golang.org/genproto/googleapis/firestore/v1" ) // A Precondition modifies a Firestore update or delete operation. type Precondition interface { // Returns the corresponding Precondition proto. preconditionProto() (*pb.Precondition, error) } // Exists is a Precondition that checks for the existence of a resource before // writing to it. If the check fails, the write does not occur. var Exists Precondition func init() { // Initialize here so godoc doesn't show the internal value. Exists = exists(true) } type exists bool func (e exists) preconditionProto() (*pb.Precondition, error) { return &pb.Precondition{ ConditionType: &pb.Precondition_Exists{bool(e)}, }, nil } func (e exists) String() string { if e { return "Exists" } return "DoesNotExist" } // LastUpdateTime returns a Precondition that checks that a resource must exist and // must have last been updated at the given time. If the check fails, the write // does not occur. func LastUpdateTime(t time.Time) Precondition { return lastUpdateTime(t) } type lastUpdateTime time.Time func (u lastUpdateTime) preconditionProto() (*pb.Precondition, error) { ts, err := ptypes.TimestampProto(time.Time(u)) if err != nil { return nil, err } return &pb.Precondition{ ConditionType: &pb.Precondition_UpdateTime{ts}, }, nil } func (u lastUpdateTime) String() string { return fmt.Sprintf("LastUpdateTime(%s)", time.Time(u)) } func processPreconditionsForDelete(preconds []Precondition) (*pb.Precondition, error) { // At most one option permitted. switch len(preconds) { case 0: return nil, nil case 1: return preconds[0].preconditionProto() default: return nil, fmt.Errorf("firestore: conflicting preconditions: %+v", preconds) } } func processPreconditionsForUpdate(preconds []Precondition) (*pb.Precondition, error) { // At most one option permitted, and it cannot be Exists. switch len(preconds) { case 0: // If the user doesn't provide any options, default to Exists(true). return exists(true).preconditionProto() case 1: if _, ok := preconds[0].(exists); ok { return nil, errors.New("cannot use Exists with Update") } return preconds[0].preconditionProto() default: return nil, fmt.Errorf("firestore: conflicting preconditions: %+v", preconds) } } func processPreconditionsForVerify(preconds []Precondition) (*pb.Precondition, error) { // At most one option permitted. switch len(preconds) { case 0: return nil, nil case 1: return preconds[0].preconditionProto() default: return nil, fmt.Errorf("firestore: conflicting preconditions: %+v", preconds) } } // A SetOption modifies a Firestore set operation. type SetOption interface { fieldPaths() (fps []FieldPath, all bool, err error) } // MergeAll is a SetOption that causes all the field paths given in the data argument // to Set to be overwritten. It is not supported for struct data. var MergeAll SetOption = merge{all: true} // Merge returns a SetOption that causes only the given field paths to be // overwritten. Other fields on the existing document will be untouched. It is an // error if a provided field path does not refer to a value in the data passed to // Set. func Merge(fps ...FieldPath) SetOption { for _, fp := range fps { if err := fp.validate(); err != nil { return merge{err: err} } } return merge{paths: fps} } type merge struct { all bool paths []FieldPath err error } func (m merge) String() string { if m.err != nil { return fmt.Sprintf("", m.err) } if m.all { return "MergeAll" } return fmt.Sprintf("Merge(%+v)", m.paths) } func (m merge) fieldPaths() (fps []FieldPath, all bool, err error) { if m.err != nil { return nil, false, m.err } if err := checkNoDupOrPrefix(m.paths); err != nil { return nil, false, err } if m.all { return nil, true, nil } return m.paths, false, nil } func processSetOptions(opts []SetOption) (fps []FieldPath, all bool, err error) { switch len(opts) { case 0: return nil, false, nil case 1: return opts[0].fieldPaths() default: return nil, false, fmt.Errorf("conflicting options: %+v", opts) } } google-cloud-go-0.49.0/firestore/options_test.go000066400000000000000000000074431356504100700216630ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package firestore import ( "testing" pb "google.golang.org/genproto/googleapis/firestore/v1" ) func TestProcessPreconditionsForVerify(t *testing.T) { for _, test := range []struct { in []Precondition want *pb.Precondition wantErr bool }{ { in: nil, want: nil, }, { in: []Precondition{}, want: nil, }, { in: []Precondition{Exists}, want: &pb.Precondition{ConditionType: &pb.Precondition_Exists{true}}, }, { in: []Precondition{LastUpdateTime(aTime)}, want: &pb.Precondition{ConditionType: &pb.Precondition_UpdateTime{aTimestamp}}, }, { in: []Precondition{Exists, LastUpdateTime(aTime)}, wantErr: true, }, { in: []Precondition{Exists, Exists}, wantErr: true, }, } { got, err := processPreconditionsForVerify(test.in) switch { case test.wantErr && err == nil: t.Errorf("%v: got nil, want error", test.in) case !test.wantErr && err != nil: t.Errorf("%v: got <%v>, want no error", test.in, err) case !test.wantErr && err == nil && !testEqual(got, test.want): t.Errorf("%v: got %+v, want %v", test.in, got, test.want) } } } func TestProcessPreconditionsForDelete(t *testing.T) { for _, test := range []struct { in []Precondition want *pb.Precondition wantErr bool }{ { in: nil, want: nil, }, { in: []Precondition{}, want: nil, }, { in: []Precondition{Exists}, want: &pb.Precondition{ConditionType: &pb.Precondition_Exists{true}}, }, { in: []Precondition{LastUpdateTime(aTime)}, want: &pb.Precondition{ConditionType: &pb.Precondition_UpdateTime{aTimestamp}}, }, { in: []Precondition{Exists, LastUpdateTime(aTime)}, wantErr: true, }, { in: []Precondition{Exists, Exists}, wantErr: true, }, } { got, err := processPreconditionsForDelete(test.in) switch { case test.wantErr && err == nil: t.Errorf("%v: got nil, want error", test.in) case !test.wantErr && err != nil: t.Errorf("%v: got <%v>, want no error", test.in, err) case !test.wantErr && err == nil && !testEqual(got, test.want): t.Errorf("%v: got %+v, want %v", test.in, got, test.want) } } } func TestProcessPreconditionsForUpdate(t *testing.T) { for _, test := range []struct { in []Precondition want *pb.Precondition wantErr bool }{ { in: nil, want: &pb.Precondition{ConditionType: &pb.Precondition_Exists{true}}, }, { in: []Precondition{}, want: &pb.Precondition{ConditionType: &pb.Precondition_Exists{true}}, }, { in: []Precondition{Exists}, wantErr: true, }, { in: []Precondition{LastUpdateTime(aTime)}, want: &pb.Precondition{ConditionType: &pb.Precondition_UpdateTime{aTimestamp}}, }, { in: []Precondition{Exists, LastUpdateTime(aTime)}, wantErr: true, }, { in: []Precondition{Exists, Exists}, wantErr: true, }, } { got, err := processPreconditionsForUpdate(test.in) switch { case test.wantErr && err == nil: t.Errorf("%v: got nil, want error", test.in) case !test.wantErr && err != nil: t.Errorf("%v: got <%v>, want no error", test.in, err) case !test.wantErr && err == nil && !testEqual(got, test.want): t.Errorf("%v: got %+v, want %v", test.in, got, test.want) } } } google-cloud-go-0.49.0/firestore/order.go000066400000000000000000000116641356504100700202440ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package firestore import ( "bytes" "fmt" "math" "sort" "strings" tspb "github.com/golang/protobuf/ptypes/timestamp" pb "google.golang.org/genproto/googleapis/firestore/v1" ) // Returns a negative number, zero, or a positive number depending on whether a is // less than, equal to, or greater than b according to Firestore's ordering of // values. func compareValues(a, b *pb.Value) int { ta := typeOrder(a) tb := typeOrder(b) if ta != tb { return compareInt64s(int64(ta), int64(tb)) } switch a := a.ValueType.(type) { case *pb.Value_NullValue: return 0 // nulls are equal case *pb.Value_BooleanValue: av := a.BooleanValue bv := b.GetBooleanValue() switch { case av && !bv: return 1 case bv && !av: return -1 default: return 0 } case *pb.Value_IntegerValue: return compareNumbers(float64(a.IntegerValue), toFloat(b)) case *pb.Value_DoubleValue: return compareNumbers(a.DoubleValue, toFloat(b)) case *pb.Value_TimestampValue: return compareTimestamps(a.TimestampValue, b.GetTimestampValue()) case *pb.Value_StringValue: return strings.Compare(a.StringValue, b.GetStringValue()) case *pb.Value_BytesValue: return bytes.Compare(a.BytesValue, b.GetBytesValue()) case *pb.Value_ReferenceValue: return compareReferences(a.ReferenceValue, b.GetReferenceValue()) case *pb.Value_GeoPointValue: ag := a.GeoPointValue bg := b.GetGeoPointValue() if ag.Latitude != bg.Latitude { return compareFloat64s(ag.Latitude, bg.Latitude) } return compareFloat64s(ag.Longitude, bg.Longitude) case *pb.Value_ArrayValue: return compareArrays(a.ArrayValue.Values, b.GetArrayValue().Values) case *pb.Value_MapValue: return compareMaps(a.MapValue.Fields, b.GetMapValue().Fields) default: panic(fmt.Sprintf("bad value type: %v", a)) } } // Treats NaN as less than any non-NaN. func compareNumbers(a, b float64) int { switch { case math.IsNaN(a): if math.IsNaN(b) { return 0 } return -1 case math.IsNaN(b): return 1 default: return compareFloat64s(a, b) } } // Return v as a float64, assuming it's an Integer or Double. func toFloat(v *pb.Value) float64 { if x, ok := v.ValueType.(*pb.Value_IntegerValue); ok { return float64(x.IntegerValue) } return v.GetDoubleValue() } func compareTimestamps(a, b *tspb.Timestamp) int { if c := compareInt64s(a.Seconds, b.Seconds); c != 0 { return c } return compareInt64s(int64(a.Nanos), int64(b.Nanos)) } func compareReferences(a, b string) int { // Compare path components lexicographically. pa := strings.Split(a, "/") pb := strings.Split(b, "/") return compareSequences(len(pa), len(pb), func(i int) int { return strings.Compare(pa[i], pb[i]) }) } func compareArrays(a, b []*pb.Value) int { return compareSequences(len(a), len(b), func(i int) int { return compareValues(a[i], b[i]) }) } func compareMaps(a, b map[string]*pb.Value) int { sortedKeys := func(m map[string]*pb.Value) []string { var ks []string for k := range m { ks = append(ks, k) } sort.Strings(ks) return ks } aks := sortedKeys(a) bks := sortedKeys(b) return compareSequences(len(aks), len(bks), func(i int) int { if c := strings.Compare(aks[i], bks[i]); c != 0 { return c } k := aks[i] return compareValues(a[k], b[k]) }) } func compareSequences(len1, len2 int, compare func(int) int) int { for i := 0; i < len1 && i < len2; i++ { if c := compare(i); c != 0 { return c } } return compareInt64s(int64(len1), int64(len2)) } func compareFloat64s(a, b float64) int { switch { case a < b: return -1 case a > b: return 1 default: return 0 } } func compareInt64s(a, b int64) int { switch { case a < b: return -1 case a > b: return 1 default: return 0 } } // Return an integer corresponding to the type of value stored in v, such that // comparing the resulting integers gives the Firestore ordering for types. func typeOrder(v *pb.Value) int { switch v.ValueType.(type) { case *pb.Value_NullValue: return 0 case *pb.Value_BooleanValue: return 1 case *pb.Value_IntegerValue: return 2 case *pb.Value_DoubleValue: return 2 case *pb.Value_TimestampValue: return 3 case *pb.Value_StringValue: return 4 case *pb.Value_BytesValue: return 5 case *pb.Value_ReferenceValue: return 6 case *pb.Value_GeoPointValue: return 7 case *pb.Value_ArrayValue: return 8 case *pb.Value_MapValue: return 9 default: panic(fmt.Sprintf("bad value type: %v", v)) } } google-cloud-go-0.49.0/firestore/order_test.go000066400000000000000000000067201356504100700213000ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package firestore import ( "math" "testing" "time" pb "google.golang.org/genproto/googleapis/firestore/v1" "google.golang.org/genproto/googleapis/type/latlng" ) func TestCompareValues(t *testing.T) { // Ordered list of values. vals := []*pb.Value{ nullValue, boolval(false), boolval(true), floatval(math.NaN()), floatval(math.Inf(-1)), floatval(-math.MaxFloat64), int64val(math.MinInt64), floatval(-1.1), intval(-1), intval(0), floatval(math.SmallestNonzeroFloat64), intval(1), floatval(1.1), intval(2), int64val(math.MaxInt64), floatval(math.MaxFloat64), floatval(math.Inf(1)), tsval(time.Date(2016, 5, 20, 10, 20, 0, 0, time.UTC)), tsval(time.Date(2016, 10, 21, 15, 32, 0, 0, time.UTC)), strval(""), strval("\u0000\ud7ff\ue000\uffff"), strval("(╯°□°)╯︵ â”»â”â”»"), strval("a"), strval("abc def"), strval("e\u0301b"), strval("æ"), strval("\u00e9a"), bytesval([]byte{}), bytesval([]byte{0}), bytesval([]byte{0, 1, 2, 3, 4}), bytesval([]byte{0, 1, 2, 4, 3}), bytesval([]byte{255}), refval("projects/p1/databases/d1/documents/c1/doc1"), refval("projects/p1/databases/d1/documents/c1/doc2"), refval("projects/p1/databases/d1/documents/c1/doc2/c2/doc1"), refval("projects/p1/databases/d1/documents/c1/doc2/c2/doc2"), refval("projects/p1/databases/d1/documents/c10/doc1"), refval("projects/p1/databases/dkkkkklkjnjkkk1/documents/c2/doc1"), refval("projects/p2/databases/d2/documents/c1/doc1"), refval("projects/p2/databases/d2/documents/c1-/doc1"), geopoint(-90, -180), geopoint(-90, 0), geopoint(-90, 180), geopoint(0, -180), geopoint(0, 0), geopoint(0, 180), geopoint(1, -180), geopoint(1, 0), geopoint(1, 180), geopoint(90, -180), geopoint(90, 0), geopoint(90, 180), arrayval(), arrayval(strval("bar")), arrayval(strval("foo")), arrayval(strval("foo"), intval(1)), arrayval(strval("foo"), intval(2)), arrayval(strval("foo"), strval("0")), mapval(map[string]*pb.Value{"bar": intval(0)}), mapval(map[string]*pb.Value{"bar": intval(0), "foo": intval(1)}), mapval(map[string]*pb.Value{"foo": intval(1)}), mapval(map[string]*pb.Value{"foo": intval(2)}), mapval(map[string]*pb.Value{"foo": strval("0")}), } for i, v1 := range vals { if got := compareValues(v1, v1); got != 0 { t.Errorf("compare(%v, %v) == %d, want 0", v1, v1, got) } for _, v2 := range vals[i+1:] { if got := compareValues(v1, v2); got != -1 { t.Errorf("compare(%v, %v) == %d, want -1", v1, v2, got) } if got := compareValues(v2, v1); got != 1 { t.Errorf("compare(%v, %v) == %d, want 1", v1, v2, got) } } } // Integers and Doubles order the same. n1 := intval(17) n2 := floatval(17) if got := compareValues(n1, n2); got != 0 { t.Errorf("compare(%v, %v) == %d, want 0", n1, n2, got) } } func geopoint(lat, lng float64) *pb.Value { return geoval(&latlng.LatLng{Latitude: lat, Longitude: lng}) } google-cloud-go-0.49.0/firestore/query.go000066400000000000000000000561311356504100700202740ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package firestore import ( "context" "errors" "fmt" "io" "math" "reflect" "time" "cloud.google.com/go/internal/btree" "github.com/golang/protobuf/ptypes/wrappers" "google.golang.org/api/iterator" pb "google.golang.org/genproto/googleapis/firestore/v1" ) // Query represents a Firestore query. // // Query values are immutable. Each Query method creates // a new Query; it does not modify the old. type Query struct { c *Client path string // path to query (collection) parentPath string // path of the collection's parent (document) collectionID string selection []FieldPath filters []filter orders []order offset int32 limit *wrappers.Int32Value startVals, endVals []interface{} startDoc, endDoc *DocumentSnapshot startBefore, endBefore bool err error // allDescendants indicates whether this query is for all collections // that match the ID under the specified parentPath. allDescendants bool } // DocumentID is the special field name representing the ID of a document // in queries. const DocumentID = "__name__" // Select returns a new Query that specifies the paths // to return from the result documents. // Each path argument can be a single field or a dot-separated sequence of // fields, and must not contain any of the runes "Ëœ*/[]". // // An empty Select call will produce a query that returns only document IDs. func (q Query) Select(paths ...string) Query { var fps []FieldPath for _, s := range paths { fp, err := parseDotSeparatedString(s) if err != nil { q.err = err return q } fps = append(fps, fp) } return q.SelectPaths(fps...) } // SelectPaths returns a new Query that specifies the field paths // to return from the result documents. // // An empty SelectPaths call will produce a query that returns only document IDs. func (q Query) SelectPaths(fieldPaths ...FieldPath) Query { if len(fieldPaths) == 0 { q.selection = []FieldPath{{DocumentID}} } else { q.selection = fieldPaths } return q } // Where returns a new Query that filters the set of results. // A Query can have multiple filters. // The path argument can be a single field or a dot-separated sequence of // fields, and must not contain any of the runes "Ëœ*/[]". // The op argument must be one of "==", "<", "<=", ">" or ">=". func (q Query) Where(path, op string, value interface{}) Query { fp, err := parseDotSeparatedString(path) if err != nil { q.err = err return q } q.filters = append(append([]filter(nil), q.filters...), filter{fp, op, value}) return q } // WherePath returns a new Query that filters the set of results. // A Query can have multiple filters. // The op argument must be one of "==", "<", "<=", ">" or ">=". func (q Query) WherePath(fp FieldPath, op string, value interface{}) Query { q.filters = append(append([]filter(nil), q.filters...), filter{fp, op, value}) return q } // Direction is the sort direction for result ordering. type Direction int32 const ( // Asc sorts results from smallest to largest. Asc Direction = Direction(pb.StructuredQuery_ASCENDING) // Desc sorts results from largest to smallest. Desc Direction = Direction(pb.StructuredQuery_DESCENDING) ) // OrderBy returns a new Query that specifies the order in which results are // returned. A Query can have multiple OrderBy/OrderByPath specifications. // OrderBy appends the specification to the list of existing ones. // // The path argument can be a single field or a dot-separated sequence of // fields, and must not contain any of the runes "Ëœ*/[]". // // To order by document name, use the special field path DocumentID. func (q Query) OrderBy(path string, dir Direction) Query { fp, err := parseDotSeparatedString(path) if err != nil { q.err = err return q } q.orders = append(q.copyOrders(), order{fp, dir}) return q } // OrderByPath returns a new Query that specifies the order in which results are // returned. A Query can have multiple OrderBy/OrderByPath specifications. // OrderByPath appends the specification to the list of existing ones. func (q Query) OrderByPath(fp FieldPath, dir Direction) Query { q.orders = append(q.copyOrders(), order{fp, dir}) return q } func (q *Query) copyOrders() []order { return append([]order(nil), q.orders...) } // Offset returns a new Query that specifies the number of initial results to skip. // It must not be negative. func (q Query) Offset(n int) Query { q.offset = trunc32(n) return q } // Limit returns a new Query that specifies the maximum number of results to return. // It must not be negative. func (q Query) Limit(n int) Query { q.limit = &wrappers.Int32Value{Value: trunc32(n)} return q } // StartAt returns a new Query that specifies that results should start at // the document with the given field values. // // StartAt may be called with a single DocumentSnapshot, representing an // existing document within the query. The document must be a direct child of // the location being queried (not a parent document, or document in a // different collection, or a grandchild document, for example). // // Otherwise, StartAt should be called with one field value for each OrderBy clause, // in the order that they appear. For example, in // q.OrderBy("X", Asc).OrderBy("Y", Desc).StartAt(1, 2) // results will begin at the first document where X = 1 and Y = 2. // // If an OrderBy call uses the special DocumentID field path, the corresponding value // should be the document ID relative to the query's collection. For example, to // start at the document "NewYork" in the "States" collection, write // // client.Collection("States").OrderBy(DocumentID, firestore.Asc).StartAt("NewYork") // // Calling StartAt overrides a previous call to StartAt or StartAfter. func (q Query) StartAt(docSnapshotOrFieldValues ...interface{}) Query { q.startBefore = true q.startVals, q.startDoc, q.err = q.processCursorArg("StartAt", docSnapshotOrFieldValues) return q } // StartAfter returns a new Query that specifies that results should start just after // the document with the given field values. See Query.StartAt for more information. // // Calling StartAfter overrides a previous call to StartAt or StartAfter. func (q Query) StartAfter(docSnapshotOrFieldValues ...interface{}) Query { q.startBefore = false q.startVals, q.startDoc, q.err = q.processCursorArg("StartAfter", docSnapshotOrFieldValues) return q } // EndAt returns a new Query that specifies that results should end at the // document with the given field values. See Query.StartAt for more information. // // Calling EndAt overrides a previous call to EndAt or EndBefore. func (q Query) EndAt(docSnapshotOrFieldValues ...interface{}) Query { q.endBefore = false q.endVals, q.endDoc, q.err = q.processCursorArg("EndAt", docSnapshotOrFieldValues) return q } // EndBefore returns a new Query that specifies that results should end just before // the document with the given field values. See Query.StartAt for more information. // // Calling EndBefore overrides a previous call to EndAt or EndBefore. func (q Query) EndBefore(docSnapshotOrFieldValues ...interface{}) Query { q.endBefore = true q.endVals, q.endDoc, q.err = q.processCursorArg("EndBefore", docSnapshotOrFieldValues) return q } func (q *Query) processCursorArg(name string, docSnapshotOrFieldValues []interface{}) ([]interface{}, *DocumentSnapshot, error) { for _, e := range docSnapshotOrFieldValues { if ds, ok := e.(*DocumentSnapshot); ok { if len(docSnapshotOrFieldValues) == 1 { return nil, ds, nil } return nil, nil, fmt.Errorf("firestore: a document snapshot must be the only argument to %s", name) } } return docSnapshotOrFieldValues, nil, nil } func (q Query) query() *Query { return &q } func (q Query) toProto() (*pb.StructuredQuery, error) { if q.err != nil { return nil, q.err } if q.collectionID == "" { return nil, errors.New("firestore: query created without CollectionRef") } if q.startBefore { if len(q.startVals) == 0 && q.startDoc == nil { return nil, errors.New("firestore: StartAt/StartAfter must be called with at least one value") } } if q.endBefore { if len(q.endVals) == 0 && q.endDoc == nil { return nil, errors.New("firestore: EndAt/EndBefore must be called with at least one value") } } p := &pb.StructuredQuery{ From: []*pb.StructuredQuery_CollectionSelector{{ CollectionId: q.collectionID, AllDescendants: q.allDescendants, }}, Offset: q.offset, Limit: q.limit, } if len(q.selection) > 0 { p.Select = &pb.StructuredQuery_Projection{} for _, fp := range q.selection { if err := fp.validate(); err != nil { return nil, err } p.Select.Fields = append(p.Select.Fields, fref(fp)) } } // If there is only filter, use it directly. Otherwise, construct // a CompositeFilter. if len(q.filters) == 1 { pf, err := q.filters[0].toProto() if err != nil { return nil, err } p.Where = pf } else if len(q.filters) > 1 { cf := &pb.StructuredQuery_CompositeFilter{ Op: pb.StructuredQuery_CompositeFilter_AND, } p.Where = &pb.StructuredQuery_Filter{ FilterType: &pb.StructuredQuery_Filter_CompositeFilter{cf}, } for _, f := range q.filters { pf, err := f.toProto() if err != nil { return nil, err } cf.Filters = append(cf.Filters, pf) } } orders := q.orders if q.startDoc != nil || q.endDoc != nil { orders = q.adjustOrders() } for _, ord := range orders { po, err := ord.toProto() if err != nil { return nil, err } p.OrderBy = append(p.OrderBy, po) } cursor, err := q.toCursor(q.startVals, q.startDoc, q.startBefore, orders) if err != nil { return nil, err } p.StartAt = cursor cursor, err = q.toCursor(q.endVals, q.endDoc, q.endBefore, orders) if err != nil { return nil, err } p.EndAt = cursor return p, nil } // If there is a start/end that uses a Document Snapshot, we may need to adjust the OrderBy // clauses that the user provided: we add OrderBy(__name__) if it isn't already present, and // we make sure we don't invalidate the original query by adding an OrderBy for inequality filters. func (q *Query) adjustOrders() []order { // If the user is already ordering by document ID, don't change anything. for _, ord := range q.orders { if ord.isDocumentID() { return q.orders } } // If there are OrderBy clauses, append an OrderBy(DocumentID), using the direction of the last OrderBy clause. if len(q.orders) > 0 { return append(q.copyOrders(), order{ fieldPath: FieldPath{DocumentID}, dir: q.orders[len(q.orders)-1].dir, }) } // If there are no OrderBy clauses but there is an inequality, add an OrderBy clause // for the field of the first inequality. var orders []order for _, f := range q.filters { if f.op != "==" { orders = []order{{fieldPath: f.fieldPath, dir: Asc}} break } } // Add an ascending OrderBy(DocumentID). return append(orders, order{fieldPath: FieldPath{DocumentID}, dir: Asc}) } func (q *Query) toCursor(fieldValues []interface{}, ds *DocumentSnapshot, before bool, orders []order) (*pb.Cursor, error) { var vals []*pb.Value var err error if ds != nil { vals, err = q.docSnapshotToCursorValues(ds, orders) } else if len(fieldValues) != 0 { vals, err = q.fieldValuesToCursorValues(fieldValues) } else { return nil, nil } if err != nil { return nil, err } return &pb.Cursor{Values: vals, Before: before}, nil } // toPositionValues converts the field values to protos. func (q *Query) fieldValuesToCursorValues(fieldValues []interface{}) ([]*pb.Value, error) { if len(fieldValues) != len(q.orders) { return nil, errors.New("firestore: number of field values in StartAt/StartAfter/EndAt/EndBefore does not match number of OrderBy fields") } vals := make([]*pb.Value, len(fieldValues)) var err error for i, ord := range q.orders { fval := fieldValues[i] if ord.isDocumentID() { // TODO(jba): support DocumentRefs as well as strings. // TODO(jba): error if document ref does not belong to the right collection. docID, ok := fval.(string) if !ok { return nil, fmt.Errorf("firestore: expected doc ID for DocumentID field, got %T", fval) } vals[i] = &pb.Value{ValueType: &pb.Value_ReferenceValue{q.path + "/" + docID}} } else { var sawTransform bool vals[i], sawTransform, err = toProtoValue(reflect.ValueOf(fval)) if err != nil { return nil, err } if sawTransform { return nil, errors.New("firestore: transforms disallowed in query value") } } } return vals, nil } func (q *Query) docSnapshotToCursorValues(ds *DocumentSnapshot, orders []order) ([]*pb.Value, error) { // TODO(jba): error if doc snap does not belong to the right collection. vals := make([]*pb.Value, len(orders)) for i, ord := range orders { if ord.isDocumentID() { dp, qp := ds.Ref.Parent.Path, q.path if dp != qp { return nil, fmt.Errorf("firestore: document snapshot for %s passed to query on %s", dp, qp) } vals[i] = &pb.Value{ValueType: &pb.Value_ReferenceValue{ds.Ref.Path}} } else { val, err := valueAtPath(ord.fieldPath, ds.proto.Fields) if err != nil { return nil, err } vals[i] = val } } return vals, nil } // Returns a function that compares DocumentSnapshots according to q's ordering. func (q Query) compareFunc() func(d1, d2 *DocumentSnapshot) (int, error) { // Add implicit sorting by name, using the last specified direction. lastDir := Asc if len(q.orders) > 0 { lastDir = q.orders[len(q.orders)-1].dir } orders := append(q.copyOrders(), order{[]string{DocumentID}, lastDir}) return func(d1, d2 *DocumentSnapshot) (int, error) { for _, ord := range orders { var cmp int if len(ord.fieldPath) == 1 && ord.fieldPath[0] == DocumentID { cmp = compareReferences(d1.Ref.Path, d2.Ref.Path) } else { v1, err := valueAtPath(ord.fieldPath, d1.proto.Fields) if err != nil { return 0, err } v2, err := valueAtPath(ord.fieldPath, d2.proto.Fields) if err != nil { return 0, err } cmp = compareValues(v1, v2) } if cmp != 0 { if ord.dir == Desc { cmp = -cmp } return cmp, nil } } return 0, nil } } type filter struct { fieldPath FieldPath op string value interface{} } func (f filter) toProto() (*pb.StructuredQuery_Filter, error) { if err := f.fieldPath.validate(); err != nil { return nil, err } if uop, ok := unaryOpFor(f.value); ok { if f.op != "==" { return nil, fmt.Errorf("firestore: must use '==' when comparing %v", f.value) } return &pb.StructuredQuery_Filter{ FilterType: &pb.StructuredQuery_Filter_UnaryFilter{ UnaryFilter: &pb.StructuredQuery_UnaryFilter{ OperandType: &pb.StructuredQuery_UnaryFilter_Field{ Field: fref(f.fieldPath), }, Op: uop, }, }, }, nil } var op pb.StructuredQuery_FieldFilter_Operator switch f.op { case "<": op = pb.StructuredQuery_FieldFilter_LESS_THAN case "<=": op = pb.StructuredQuery_FieldFilter_LESS_THAN_OR_EQUAL case ">": op = pb.StructuredQuery_FieldFilter_GREATER_THAN case ">=": op = pb.StructuredQuery_FieldFilter_GREATER_THAN_OR_EQUAL case "==": op = pb.StructuredQuery_FieldFilter_EQUAL case "in": op = pb.StructuredQuery_FieldFilter_IN case "array-contains": op = pb.StructuredQuery_FieldFilter_ARRAY_CONTAINS case "array-contains-any": op = pb.StructuredQuery_FieldFilter_ARRAY_CONTAINS_ANY default: return nil, fmt.Errorf("firestore: invalid operator %q", f.op) } val, sawTransform, err := toProtoValue(reflect.ValueOf(f.value)) if err != nil { return nil, err } if sawTransform { return nil, errors.New("firestore: transforms disallowed in query value") } return &pb.StructuredQuery_Filter{ FilterType: &pb.StructuredQuery_Filter_FieldFilter{ FieldFilter: &pb.StructuredQuery_FieldFilter{ Field: fref(f.fieldPath), Op: op, Value: val, }, }, }, nil } func unaryOpFor(value interface{}) (pb.StructuredQuery_UnaryFilter_Operator, bool) { switch { case value == nil: return pb.StructuredQuery_UnaryFilter_IS_NULL, true case isNaN(value): return pb.StructuredQuery_UnaryFilter_IS_NAN, true default: return pb.StructuredQuery_UnaryFilter_OPERATOR_UNSPECIFIED, false } } func isNaN(x interface{}) bool { switch x := x.(type) { case float32: return math.IsNaN(float64(x)) case float64: return math.IsNaN(x) default: return false } } type order struct { fieldPath FieldPath dir Direction } func (r order) isDocumentID() bool { return len(r.fieldPath) == 1 && r.fieldPath[0] == DocumentID } func (r order) toProto() (*pb.StructuredQuery_Order, error) { if err := r.fieldPath.validate(); err != nil { return nil, err } return &pb.StructuredQuery_Order{ Field: fref(r.fieldPath), Direction: pb.StructuredQuery_Direction(r.dir), }, nil } func fref(fp FieldPath) *pb.StructuredQuery_FieldReference { return &pb.StructuredQuery_FieldReference{FieldPath: fp.toServiceFieldPath()} } func trunc32(i int) int32 { if i > math.MaxInt32 { i = math.MaxInt32 } return int32(i) } // Documents returns an iterator over the query's resulting documents. func (q Query) Documents(ctx context.Context) *DocumentIterator { return &DocumentIterator{ iter: newQueryDocumentIterator(withResourceHeader(ctx, q.c.path()), &q, nil), } } // DocumentIterator is an iterator over documents returned by a query. type DocumentIterator struct { iter docIterator err error } // Unexported interface so we can have two different kinds of DocumentIterator: one // for straight queries, and one for query snapshots. We do it this way instead of // making DocumentIterator an interface because in the client libraries, iterators are // always concrete types, and the fact that this one has two different implementations // is an internal detail. type docIterator interface { next() (*DocumentSnapshot, error) stop() } // Next returns the next result. Its second return value is iterator.Done if there // are no more results. Once Next returns Done, all subsequent calls will return // Done. func (it *DocumentIterator) Next() (*DocumentSnapshot, error) { if it.err != nil { return nil, it.err } ds, err := it.iter.next() if err != nil { it.err = err } return ds, err } // Stop stops the iterator, freeing its resources. // Always call Stop when you are done with a DocumentIterator. // It is not safe to call Stop concurrently with Next. func (it *DocumentIterator) Stop() { if it.iter != nil { // possible in error cases it.iter.stop() } if it.err == nil { it.err = iterator.Done } } // GetAll returns all the documents remaining from the iterator. // It is not necessary to call Stop on the iterator after calling GetAll. func (it *DocumentIterator) GetAll() ([]*DocumentSnapshot, error) { defer it.Stop() var docs []*DocumentSnapshot for { doc, err := it.Next() if err == iterator.Done { break } if err != nil { return nil, err } docs = append(docs, doc) } return docs, nil } type queryDocumentIterator struct { ctx context.Context cancel func() q *Query tid []byte // transaction ID, if any streamClient pb.Firestore_RunQueryClient } func newQueryDocumentIterator(ctx context.Context, q *Query, tid []byte) *queryDocumentIterator { ctx, cancel := context.WithCancel(ctx) return &queryDocumentIterator{ ctx: ctx, cancel: cancel, q: q, tid: tid, } } func (it *queryDocumentIterator) next() (*DocumentSnapshot, error) { client := it.q.c if it.streamClient == nil { sq, err := it.q.toProto() if err != nil { return nil, err } req := &pb.RunQueryRequest{ Parent: it.q.parentPath, QueryType: &pb.RunQueryRequest_StructuredQuery{sq}, } if it.tid != nil { req.ConsistencySelector = &pb.RunQueryRequest_Transaction{it.tid} } it.streamClient, err = client.c.RunQuery(it.ctx, req) if err != nil { return nil, err } } var res *pb.RunQueryResponse var err error for { res, err = it.streamClient.Recv() if err == io.EOF { return nil, iterator.Done } if err != nil { return nil, err } if res.Document != nil { break } // No document => partial progress; keep receiving. } docRef, err := pathToDoc(res.Document.Name, client) if err != nil { return nil, err } doc, err := newDocumentSnapshot(docRef, res.Document, client, res.ReadTime) if err != nil { return nil, err } return doc, nil } func (it *queryDocumentIterator) stop() { it.cancel() } // Snapshots returns an iterator over snapshots of the query. Each time the query // results change, a new snapshot will be generated. func (q Query) Snapshots(ctx context.Context) *QuerySnapshotIterator { ws, err := newWatchStreamForQuery(ctx, q) if err != nil { return &QuerySnapshotIterator{err: err} } return &QuerySnapshotIterator{ Query: q, ws: ws, } } // QuerySnapshotIterator is an iterator over snapshots of a query. // Call Next on the iterator to get a snapshot of the query's results each time they change. // Call Stop on the iterator when done. // // For an example, see Query.Snapshots. type QuerySnapshotIterator struct { // The Query used to construct this iterator. Query Query ws *watchStream err error } // Next blocks until the query's results change, then returns a QuerySnapshot for // the current results. // // Next never returns iterator.Done unless it is called after Stop. func (it *QuerySnapshotIterator) Next() (*QuerySnapshot, error) { if it.err != nil { return nil, it.err } btree, changes, readTime, err := it.ws.nextSnapshot() if err != nil { if err == io.EOF { err = iterator.Done } it.err = err return nil, it.err } return &QuerySnapshot{ Documents: &DocumentIterator{ iter: (*btreeDocumentIterator)(btree.BeforeIndex(0)), }, Size: btree.Len(), Changes: changes, ReadTime: readTime, }, nil } // Stop stops receiving snapshots. You should always call Stop when you are done with // a QuerySnapshotIterator, to free up resources. It is not safe to call Stop // concurrently with Next. func (it *QuerySnapshotIterator) Stop() { if it.ws != nil { it.ws.stop() } } // A QuerySnapshot is a snapshot of query results. It is returned by // QuerySnapshotIterator.Next whenever the results of a query change. type QuerySnapshot struct { // An iterator over the query results. // It is not necessary to call Stop on this iterator. Documents *DocumentIterator // The number of results in this snapshot. Size int // The changes since the previous snapshot. Changes []DocumentChange // The time at which this snapshot was obtained from Firestore. ReadTime time.Time } type btreeDocumentIterator btree.Iterator func (it *btreeDocumentIterator) next() (*DocumentSnapshot, error) { if !(*btree.Iterator)(it).Next() { return nil, iterator.Done } return it.Key.(*DocumentSnapshot), nil } func (*btreeDocumentIterator) stop() {} google-cloud-go-0.49.0/firestore/query_test.go000066400000000000000000000613451356504100700213360ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package firestore import ( "context" "math" "sort" "testing" "cloud.google.com/go/internal/pretty" tspb "github.com/golang/protobuf/ptypes/timestamp" "github.com/golang/protobuf/ptypes/wrappers" pb "google.golang.org/genproto/googleapis/firestore/v1" ) func TestFilterToProto(t *testing.T) { for _, test := range []struct { in filter want *pb.StructuredQuery_Filter }{ { filter{[]string{"a"}, ">", 1}, &pb.StructuredQuery_Filter{FilterType: &pb.StructuredQuery_Filter_FieldFilter{ FieldFilter: &pb.StructuredQuery_FieldFilter{ Field: &pb.StructuredQuery_FieldReference{FieldPath: "a"}, Op: pb.StructuredQuery_FieldFilter_GREATER_THAN, Value: intval(1), }, }}, }, { filter{[]string{"a"}, "==", nil}, &pb.StructuredQuery_Filter{FilterType: &pb.StructuredQuery_Filter_UnaryFilter{ UnaryFilter: &pb.StructuredQuery_UnaryFilter{ OperandType: &pb.StructuredQuery_UnaryFilter_Field{ Field: &pb.StructuredQuery_FieldReference{FieldPath: "a"}, }, Op: pb.StructuredQuery_UnaryFilter_IS_NULL, }, }}, }, { filter{[]string{"a"}, "==", math.NaN()}, &pb.StructuredQuery_Filter{FilterType: &pb.StructuredQuery_Filter_UnaryFilter{ UnaryFilter: &pb.StructuredQuery_UnaryFilter{ OperandType: &pb.StructuredQuery_UnaryFilter_Field{ Field: &pb.StructuredQuery_FieldReference{FieldPath: "a"}, }, Op: pb.StructuredQuery_UnaryFilter_IS_NAN, }, }}, }, } { got, err := test.in.toProto() if err != nil { t.Fatal(err) } if !testEqual(got, test.want) { t.Errorf("%+v:\ngot\n%v\nwant\n%v", test.in, pretty.Value(got), pretty.Value(test.want)) } } } func TestQueryToProto(t *testing.T) { filtr := func(path []string, op string, val interface{}) *pb.StructuredQuery_Filter { f, err := filter{path, op, val}.toProto() if err != nil { t.Fatal(err) } return f } c := &Client{projectID: "P", databaseID: "DB"} coll := c.Collection("C") q := coll.Query docsnap := &DocumentSnapshot{ Ref: coll.Doc("D"), proto: &pb.Document{ Fields: map[string]*pb.Value{"a": intval(7), "b": intval(8), "c": arrayval(intval(1), intval(2))}, }, } for _, test := range []struct { desc string in Query want *pb.StructuredQuery }{ { desc: "q.Select()", in: q.Select(), want: &pb.StructuredQuery{ Select: &pb.StructuredQuery_Projection{ Fields: []*pb.StructuredQuery_FieldReference{fref1("__name__")}, }, }, }, { desc: `q.Select("a", "b")`, in: q.Select("a", "b"), want: &pb.StructuredQuery{ Select: &pb.StructuredQuery_Projection{ Fields: []*pb.StructuredQuery_FieldReference{fref1("a"), fref1("b")}, }, }, }, { desc: `q.Select("a", "b").Select("c")`, in: q.Select("a", "b").Select("c"), // last wins want: &pb.StructuredQuery{ Select: &pb.StructuredQuery_Projection{ Fields: []*pb.StructuredQuery_FieldReference{fref1("c")}, }, }, }, { desc: `q.SelectPaths([]string{"*"}, []string{"/"})`, in: q.SelectPaths([]string{"*"}, []string{"/"}), want: &pb.StructuredQuery{ Select: &pb.StructuredQuery_Projection{ Fields: []*pb.StructuredQuery_FieldReference{fref1("*"), fref1("/")}, }, }, }, { desc: `q.Where("a", ">", 5)`, in: q.Where("a", ">", 5), want: &pb.StructuredQuery{Where: filtr([]string{"a"}, ">", 5)}, }, { desc: `q.Where("a", "==", NaN)`, in: q.Where("a", "==", float32(math.NaN())), want: &pb.StructuredQuery{Where: filtr([]string{"a"}, "==", math.NaN())}, }, { desc: `q.Where("a", "in", []int{7, 8})`, in: q.Where("a", "in", []int{7, 8}), want: &pb.StructuredQuery{Where: filtr([]string{"a"}, "in", []int{7, 8})}, }, { desc: `q.Where("c", "array-contains", 1)`, in: q.Where("c", "array-contains", 1), want: &pb.StructuredQuery{Where: filtr([]string{"c"}, "array-contains", 1)}, }, { desc: `q.Where("c", "array-contains-any", []int{1, 2})`, in: q.Where("c", "array-contains-any", []int{1, 2}), want: &pb.StructuredQuery{Where: filtr([]string{"c"}, "array-contains-any", []int{1, 2})}, }, { desc: `q.Where("a", ">", 5).Where("b", "<", "foo")`, in: q.Where("a", ">", 5).Where("b", "<", "foo"), want: &pb.StructuredQuery{ Where: &pb.StructuredQuery_Filter{ FilterType: &pb.StructuredQuery_Filter_CompositeFilter{ &pb.StructuredQuery_CompositeFilter{ Op: pb.StructuredQuery_CompositeFilter_AND, Filters: []*pb.StructuredQuery_Filter{ filtr([]string{"a"}, ">", 5), filtr([]string{"b"}, "<", "foo"), }, }, }, }, }, }, { desc: ` q.WherePath([]string{"/", "*"}, ">", 5)`, in: q.WherePath([]string{"/", "*"}, ">", 5), want: &pb.StructuredQuery{Where: filtr([]string{"/", "*"}, ">", 5)}, }, { desc: `q.OrderBy("b", Asc).OrderBy("a", Desc).OrderByPath([]string{"~"}, Asc)`, in: q.OrderBy("b", Asc).OrderBy("a", Desc).OrderByPath([]string{"~"}, Asc), want: &pb.StructuredQuery{ OrderBy: []*pb.StructuredQuery_Order{ {Field: fref1("b"), Direction: pb.StructuredQuery_ASCENDING}, {Field: fref1("a"), Direction: pb.StructuredQuery_DESCENDING}, {Field: fref1("~"), Direction: pb.StructuredQuery_ASCENDING}, }, }, }, { desc: `q.Offset(2).Limit(3)`, in: q.Offset(2).Limit(3), want: &pb.StructuredQuery{ Offset: 2, Limit: &wrappers.Int32Value{Value: 3}, }, }, { desc: `q.Offset(2).Limit(3).Limit(4).Offset(5)`, in: q.Offset(2).Limit(3).Limit(4).Offset(5), // last wins want: &pb.StructuredQuery{ Offset: 5, Limit: &wrappers.Int32Value{Value: 4}, }, }, { desc: `q.OrderBy("a", Asc).StartAt(7).EndBefore(9)`, in: q.OrderBy("a", Asc).StartAt(7).EndBefore(9), want: &pb.StructuredQuery{ OrderBy: []*pb.StructuredQuery_Order{ {Field: fref1("a"), Direction: pb.StructuredQuery_ASCENDING}, }, StartAt: &pb.Cursor{ Values: []*pb.Value{intval(7)}, Before: true, }, EndAt: &pb.Cursor{ Values: []*pb.Value{intval(9)}, Before: true, }, }, }, { desc: `q.OrderBy("a", Asc).StartAt(7).EndAt(9)`, in: q.OrderBy("a", Asc).StartAt(7).EndAt(9), want: &pb.StructuredQuery{ OrderBy: []*pb.StructuredQuery_Order{ {Field: fref1("a"), Direction: pb.StructuredQuery_ASCENDING}, }, StartAt: &pb.Cursor{ Values: []*pb.Value{intval(7)}, Before: true, }, EndAt: &pb.Cursor{ Values: []*pb.Value{intval(9)}, Before: false, }, }, }, { desc: `q.OrderBy("a", Asc).StartAfter(7).EndAt(9)`, in: q.OrderBy("a", Asc).StartAfter(7).EndAt(9), want: &pb.StructuredQuery{ OrderBy: []*pb.StructuredQuery_Order{ {Field: fref1("a"), Direction: pb.StructuredQuery_ASCENDING}, }, StartAt: &pb.Cursor{ Values: []*pb.Value{intval(7)}, Before: false, }, EndAt: &pb.Cursor{ Values: []*pb.Value{intval(9)}, Before: false, }, }, }, { desc: `q.OrderBy(DocumentID, Asc).StartAfter("foo").EndBefore("bar")`, in: q.OrderBy(DocumentID, Asc).StartAfter("foo").EndBefore("bar"), want: &pb.StructuredQuery{ OrderBy: []*pb.StructuredQuery_Order{ {Field: fref1("__name__"), Direction: pb.StructuredQuery_ASCENDING}, }, StartAt: &pb.Cursor{ Values: []*pb.Value{refval(coll.parentPath + "/C/foo")}, Before: false, }, EndAt: &pb.Cursor{ Values: []*pb.Value{refval(coll.parentPath + "/C/bar")}, Before: true, }, }, }, { desc: `q.OrderBy("a", Asc).OrderBy("b", Desc).StartAfter(7, 8).EndAt(9, 10)`, in: q.OrderBy("a", Asc).OrderBy("b", Desc).StartAfter(7, 8).EndAt(9, 10), want: &pb.StructuredQuery{ OrderBy: []*pb.StructuredQuery_Order{ {Field: fref1("a"), Direction: pb.StructuredQuery_ASCENDING}, {Field: fref1("b"), Direction: pb.StructuredQuery_DESCENDING}, }, StartAt: &pb.Cursor{ Values: []*pb.Value{intval(7), intval(8)}, Before: false, }, EndAt: &pb.Cursor{ Values: []*pb.Value{intval(9), intval(10)}, Before: false, }, }, }, { // last of StartAt/After wins, same for End desc: `q.OrderBy("a", Asc).StartAfter(1).StartAt(2).EndAt(3).EndBefore(4)`, in: q.OrderBy("a", Asc). StartAfter(1).StartAt(2). EndAt(3).EndBefore(4), want: &pb.StructuredQuery{ OrderBy: []*pb.StructuredQuery_Order{ {Field: fref1("a"), Direction: pb.StructuredQuery_ASCENDING}, }, StartAt: &pb.Cursor{ Values: []*pb.Value{intval(2)}, Before: true, }, EndAt: &pb.Cursor{ Values: []*pb.Value{intval(4)}, Before: true, }, }, }, // Start/End with DocumentSnapshot // These tests are from the "Document Snapshot Cursors" doc. { desc: `q.StartAt(docsnap)`, in: q.StartAt(docsnap), want: &pb.StructuredQuery{ OrderBy: []*pb.StructuredQuery_Order{ {Field: fref1("__name__"), Direction: pb.StructuredQuery_ASCENDING}, }, StartAt: &pb.Cursor{ Values: []*pb.Value{refval(coll.parentPath + "/C/D")}, Before: true, }, }, }, { desc: `q.OrderBy("a", Asc).StartAt(docsnap)`, in: q.OrderBy("a", Asc).StartAt(docsnap), want: &pb.StructuredQuery{ OrderBy: []*pb.StructuredQuery_Order{ {Field: fref1("a"), Direction: pb.StructuredQuery_ASCENDING}, {Field: fref1("__name__"), Direction: pb.StructuredQuery_ASCENDING}, }, StartAt: &pb.Cursor{ Values: []*pb.Value{intval(7), refval(coll.parentPath + "/C/D")}, Before: true, }, }, }, { desc: `q.OrderBy("a", Desc).StartAt(docsnap)`, in: q.OrderBy("a", Desc).StartAt(docsnap), want: &pb.StructuredQuery{ OrderBy: []*pb.StructuredQuery_Order{ {Field: fref1("a"), Direction: pb.StructuredQuery_DESCENDING}, {Field: fref1("__name__"), Direction: pb.StructuredQuery_DESCENDING}, }, StartAt: &pb.Cursor{ Values: []*pb.Value{intval(7), refval(coll.parentPath + "/C/D")}, Before: true, }, }, }, { desc: `q.OrderBy("a", Desc).OrderBy("b", Asc).StartAt(docsnap)`, in: q.OrderBy("a", Desc).OrderBy("b", Asc).StartAt(docsnap), want: &pb.StructuredQuery{ OrderBy: []*pb.StructuredQuery_Order{ {Field: fref1("a"), Direction: pb.StructuredQuery_DESCENDING}, {Field: fref1("b"), Direction: pb.StructuredQuery_ASCENDING}, {Field: fref1("__name__"), Direction: pb.StructuredQuery_ASCENDING}, }, StartAt: &pb.Cursor{ Values: []*pb.Value{intval(7), intval(8), refval(coll.parentPath + "/C/D")}, Before: true, }, }, }, { desc: `q.Where("a", "==", 3).StartAt(docsnap)`, in: q.Where("a", "==", 3).StartAt(docsnap), want: &pb.StructuredQuery{ Where: filtr([]string{"a"}, "==", 3), OrderBy: []*pb.StructuredQuery_Order{ {Field: fref1("__name__"), Direction: pb.StructuredQuery_ASCENDING}, }, StartAt: &pb.Cursor{ Values: []*pb.Value{refval(coll.parentPath + "/C/D")}, Before: true, }, }, }, { desc: `q.Where("a", "<", 3).StartAt(docsnap)`, in: q.Where("a", "<", 3).StartAt(docsnap), want: &pb.StructuredQuery{ Where: filtr([]string{"a"}, "<", 3), OrderBy: []*pb.StructuredQuery_Order{ {Field: fref1("a"), Direction: pb.StructuredQuery_ASCENDING}, {Field: fref1("__name__"), Direction: pb.StructuredQuery_ASCENDING}, }, StartAt: &pb.Cursor{ Values: []*pb.Value{intval(7), refval(coll.parentPath + "/C/D")}, Before: true, }, }, }, { desc: `q.Where("b", "==", 1).Where("a", "<", 3).StartAt(docsnap)`, in: q.Where("b", "==", 1).Where("a", "<", 3).StartAt(docsnap), want: &pb.StructuredQuery{ Where: &pb.StructuredQuery_Filter{ FilterType: &pb.StructuredQuery_Filter_CompositeFilter{ &pb.StructuredQuery_CompositeFilter{ Op: pb.StructuredQuery_CompositeFilter_AND, Filters: []*pb.StructuredQuery_Filter{ filtr([]string{"b"}, "==", 1), filtr([]string{"a"}, "<", 3), }, }, }, }, OrderBy: []*pb.StructuredQuery_Order{ {Field: fref1("a"), Direction: pb.StructuredQuery_ASCENDING}, {Field: fref1("__name__"), Direction: pb.StructuredQuery_ASCENDING}, }, StartAt: &pb.Cursor{ Values: []*pb.Value{intval(7), refval(coll.parentPath + "/C/D")}, Before: true, }, }, }, } { got, err := test.in.toProto() if err != nil { t.Fatalf("%s: %v", test.desc, err) continue } test.want.From = []*pb.StructuredQuery_CollectionSelector{{CollectionId: "C"}} if !testEqual(got, test.want) { t.Fatalf("%s:\ngot\n%v\nwant\n%v", test.desc, pretty.Value(got), pretty.Value(test.want)) } } } func fref1(s string) *pb.StructuredQuery_FieldReference { return fref([]string{s}) } func TestQueryToProtoErrors(t *testing.T) { st := map[string]interface{}{"a": ServerTimestamp} del := map[string]interface{}{"a": Delete} c := &Client{projectID: "P", databaseID: "DB"} coll := c.Collection("C") docsnap := &DocumentSnapshot{ Ref: coll.Doc("D"), proto: &pb.Document{ Fields: map[string]*pb.Value{"a": intval(7)}, }, } q := coll.Query for i, query := range []Query{ {}, // no collection ID q.Where("x", "!=", 1), // invalid operator q.Where("~", ">", 1), // invalid path q.WherePath([]string{"*", ""}, ">", 1), // invalid path q.StartAt(1), // no OrderBy q.StartAt(2).OrderBy("x", Asc).OrderBy("y", Desc), // wrong # OrderBy q.Select("*"), // invalid path q.SelectPaths([]string{"/", "", "~"}), // invalid path q.OrderBy("[", Asc), // invalid path q.OrderByPath([]string{""}, Desc), // invalid path q.Where("x", "==", st), // ServerTimestamp in filter q.OrderBy("a", Asc).StartAt(st), // ServerTimestamp in Start q.OrderBy("a", Asc).EndAt(st), // ServerTimestamp in End q.Where("x", "==", del), // Delete in filter q.OrderBy("a", Asc).StartAt(del), // Delete in Start q.OrderBy("a", Asc).EndAt(del), // Delete in End q.OrderBy(DocumentID, Asc).StartAt(7), // wrong type for __name__ q.OrderBy(DocumentID, Asc).EndAt(7), // wrong type for __name__ q.OrderBy("b", Asc).StartAt(docsnap), // doc snapshot does not have order-by field q.StartAt(docsnap).EndAt("x"), // mixed doc snapshot and fields q.StartAfter("x").EndBefore(docsnap), // mixed doc snapshot and fields } { _, err := query.toProto() if err == nil { t.Errorf("query %d \"%+v\": got nil, want error", i, query) } } } func TestQueryMethodsDoNotModifyReceiver(t *testing.T) { var empty Query q := Query{} _ = q.Select("a", "b") if !testEqual(q, empty) { t.Errorf("got %+v, want empty", q) } q = Query{} q1 := q.Where("a", ">", 3) if !testEqual(q, empty) { t.Errorf("got %+v, want empty", q) } // Extra check because Where appends to a slice. q1before := q.Where("a", ">", 3) // same as q1 _ = q1.Where("b", "<", "foo") if !testEqual(q1, q1before) { t.Errorf("got %+v, want %+v", q1, q1before) } q = Query{} q1 = q.OrderBy("a", Asc) if !testEqual(q, empty) { t.Errorf("got %+v, want empty", q) } // Extra check because Where appends to a slice. q1before = q.OrderBy("a", Asc) // same as q1 _ = q1.OrderBy("b", Desc) if !testEqual(q1, q1before) { t.Errorf("got %+v, want %+v", q1, q1before) } q = Query{} _ = q.Offset(5) if !testEqual(q, empty) { t.Errorf("got %+v, want empty", q) } q = Query{} _ = q.Limit(5) if !testEqual(q, empty) { t.Errorf("got %+v, want empty", q) } q = Query{} _ = q.StartAt(5) if !testEqual(q, empty) { t.Errorf("got %+v, want empty", q) } q = Query{} _ = q.StartAfter(5) if !testEqual(q, empty) { t.Errorf("got %+v, want empty", q) } q = Query{} _ = q.EndAt(5) if !testEqual(q, empty) { t.Errorf("got %+v, want empty", q) } q = Query{} _ = q.EndBefore(5) if !testEqual(q, empty) { t.Errorf("got %+v, want empty", q) } } func TestQueryFromCollectionRef(t *testing.T) { c := &Client{projectID: "P", databaseID: "D"} coll := c.Collection("C") got := coll.Select("x").Offset(8) want := Query{ c: c, parentPath: c.path() + "/documents", path: "projects/P/databases/D/documents/C", collectionID: "C", selection: []FieldPath{{"x"}}, offset: 8, } if !testEqual(got, want) { t.Fatalf("\ngot %+v, \nwant %+v", got, want) } } func TestQueryGetAll(t *testing.T) { // This implicitly tests DocumentIterator as well. const dbPath = "projects/projectID/databases/(default)" ctx := context.Background() c, srv, cleanup := newMock(t) defer cleanup() docNames := []string{"C/a", "C/b"} wantPBDocs := []*pb.Document{ { Name: dbPath + "/documents/" + docNames[0], CreateTime: aTimestamp, UpdateTime: aTimestamp, Fields: map[string]*pb.Value{"f": intval(2)}, }, { Name: dbPath + "/documents/" + docNames[1], CreateTime: aTimestamp2, UpdateTime: aTimestamp3, Fields: map[string]*pb.Value{"f": intval(1)}, }, } wantReadTimes := []*tspb.Timestamp{aTimestamp, aTimestamp2} srv.addRPC(nil, []interface{}{ &pb.RunQueryResponse{Document: wantPBDocs[0], ReadTime: aTimestamp}, &pb.RunQueryResponse{Document: wantPBDocs[1], ReadTime: aTimestamp2}, }) gotDocs, err := c.Collection("C").Documents(ctx).GetAll() if err != nil { t.Fatal(err) } if got, want := len(gotDocs), len(wantPBDocs); got != want { t.Errorf("got %d docs, wanted %d", got, want) } for i, got := range gotDocs { want, err := newDocumentSnapshot(c.Doc(docNames[i]), wantPBDocs[i], c, wantReadTimes[i]) if err != nil { t.Fatal(err) } if !testEqual(got, want) { // avoid writing a cycle got.c = nil want.c = nil t.Errorf("#%d: got %+v, want %+v", i, pretty.Value(got), pretty.Value(want)) } } } func TestQueryCompareFunc(t *testing.T) { mv := func(fields ...interface{}) map[string]*pb.Value { m := map[string]*pb.Value{} for i := 0; i < len(fields); i += 2 { m[fields[i].(string)] = fields[i+1].(*pb.Value) } return m } snap := func(ref *DocumentRef, fields map[string]*pb.Value) *DocumentSnapshot { return &DocumentSnapshot{Ref: ref, proto: &pb.Document{Fields: fields}} } c := &Client{} coll := c.Collection("C") doc1 := coll.Doc("doc1") doc2 := coll.Doc("doc2") doc3 := coll.Doc("doc3") doc4 := coll.Doc("doc4") for _, test := range []struct { q Query in []*DocumentSnapshot want []*DocumentSnapshot }{ { q: coll.OrderBy("foo", Asc), in: []*DocumentSnapshot{ snap(doc3, mv("foo", intval(2))), snap(doc4, mv("foo", intval(1))), snap(doc2, mv("foo", intval(2))), }, want: []*DocumentSnapshot{ snap(doc4, mv("foo", intval(1))), snap(doc2, mv("foo", intval(2))), snap(doc3, mv("foo", intval(2))), }, }, { q: coll.OrderBy("foo", Desc), in: []*DocumentSnapshot{ snap(doc3, mv("foo", intval(2))), snap(doc4, mv("foo", intval(1))), snap(doc2, mv("foo", intval(2))), }, want: []*DocumentSnapshot{ snap(doc3, mv("foo", intval(2))), snap(doc2, mv("foo", intval(2))), snap(doc4, mv("foo", intval(1))), }, }, { q: coll.OrderBy("foo.bar", Asc), in: []*DocumentSnapshot{ snap(doc1, mv("foo", mapval(mv("bar", intval(1))))), snap(doc2, mv("foo", mapval(mv("bar", intval(2))))), snap(doc3, mv("foo", mapval(mv("bar", intval(2))))), }, want: []*DocumentSnapshot{ snap(doc1, mv("foo", mapval(mv("bar", intval(1))))), snap(doc2, mv("foo", mapval(mv("bar", intval(2))))), snap(doc3, mv("foo", mapval(mv("bar", intval(2))))), }, }, { q: coll.OrderBy("foo.bar", Desc), in: []*DocumentSnapshot{ snap(doc1, mv("foo", mapval(mv("bar", intval(1))))), snap(doc2, mv("foo", mapval(mv("bar", intval(2))))), snap(doc3, mv("foo", mapval(mv("bar", intval(2))))), }, want: []*DocumentSnapshot{ snap(doc3, mv("foo", mapval(mv("bar", intval(2))))), snap(doc2, mv("foo", mapval(mv("bar", intval(2))))), snap(doc1, mv("foo", mapval(mv("bar", intval(1))))), }, }, } { got := append([]*DocumentSnapshot(nil), test.in...) sort.Sort(byQuery{test.q.compareFunc(), got}) if diff := testDiff(got, test.want); diff != "" { t.Errorf("%+v: %s", test.q, diff) } } // Want error on missing field. q := coll.OrderBy("bar", Asc) if q.err != nil { t.Fatalf("bad query: %v", q.err) } cf := q.compareFunc() s := snap(doc1, mv("foo", intval(1))) if _, err := cf(s, s); err == nil { t.Error("got nil, want error") } } func TestQuerySubCollections(t *testing.T) { c := &Client{projectID: "P", databaseID: "DB"} /* parent-collection +---------+ +---------+ | | | | parent-doc some-other-parent-doc | | sub-collection | | sub-doc | | sub-sub-collection | | sub-sub-doc */ parentColl := c.Collection("parent-collection") parentDoc := parentColl.Doc("parent-doc") someOtherParentDoc := parentColl.Doc("some-other-parent-doc") subColl := parentDoc.Collection("sub-collection") subDoc := subColl.Doc("sub-doc") subSubColl := subDoc.Collection("sub-sub-collection") subSubDoc := subSubColl.Doc("sub-sub-doc") testCases := []struct { queryColl *CollectionRef queryFilterDoc *DocumentRef // startAt or endBefore wantColl string wantRef string wantErr bool }{ // Queries are allowed at depth 0. {parentColl, parentDoc, "parent-collection", "projects/P/databases/DB/documents/parent-collection/parent-doc", false}, // Queries are allowed at any depth. {subColl, subDoc, "sub-collection", "projects/P/databases/DB/documents/parent-collection/parent-doc/sub-collection/sub-doc", false}, // Queries must be on immediate children (not allowed on grandchildren). {subColl, someOtherParentDoc, "", "", true}, // Queries must be on immediate children (not allowed on siblings). {subColl, subSubDoc, "", "", true}, } // startAt for _, testCase := range testCases { // Query a child within the document. q := testCase.queryColl.StartAt(&DocumentSnapshot{ Ref: testCase.queryFilterDoc, proto: &pb.Document{ Fields: map[string]*pb.Value{"a": intval(7)}, }, }).OrderBy("a", Asc) got, err := q.toProto() if testCase.wantErr { if err == nil { t.Fatal("expected err, got nil") } continue } if err != nil { t.Fatal(err) } want := &pb.StructuredQuery{ From: []*pb.StructuredQuery_CollectionSelector{ {CollectionId: testCase.wantColl}, }, OrderBy: []*pb.StructuredQuery_Order{ {Field: fref1("a"), Direction: pb.StructuredQuery_ASCENDING}, {Field: fref1("__name__"), Direction: pb.StructuredQuery_ASCENDING}, }, StartAt: &pb.Cursor{ Values: []*pb.Value{ intval(7), // This is the only part of the assertion we really care about. refval(testCase.wantRef), }, Before: true, }, } if !testEqual(got, want) { t.Fatalf("got\n%v\nwant\n%v", pretty.Value(got), pretty.Value(want)) } } // endBefore for _, testCase := range testCases { // Query a child within the document. q := testCase.queryColl.EndBefore(&DocumentSnapshot{ Ref: testCase.queryFilterDoc, proto: &pb.Document{ Fields: map[string]*pb.Value{"a": intval(7)}, }, }).OrderBy("a", Asc) got, err := q.toProto() if testCase.wantErr { if err == nil { t.Fatal("expected err, got nil") } continue } if err != nil { t.Fatal(err) } want := &pb.StructuredQuery{ From: []*pb.StructuredQuery_CollectionSelector{ {CollectionId: testCase.wantColl}, }, OrderBy: []*pb.StructuredQuery_Order{ {Field: fref1("a"), Direction: pb.StructuredQuery_ASCENDING}, {Field: fref1("__name__"), Direction: pb.StructuredQuery_ASCENDING}, }, EndAt: &pb.Cursor{ Values: []*pb.Value{ intval(7), // This is the only part of the assertion we really care about. refval(testCase.wantRef), }, Before: true, }, } if !testEqual(got, want) { t.Fatalf("got\n%v\nwant\n%v", pretty.Value(got), pretty.Value(want)) } } } // Stop should be callable on an uninitialized QuerySnapshotIterator. func TestStop_Uninitialized(t *testing.T) { i := &QuerySnapshotIterator{} i.Stop() } type byQuery struct { compare func(d1, d2 *DocumentSnapshot) (int, error) docs []*DocumentSnapshot } func (b byQuery) Len() int { return len(b.docs) } func (b byQuery) Swap(i, j int) { b.docs[i], b.docs[j] = b.docs[j], b.docs[i] } func (b byQuery) Less(i, j int) bool { c, err := b.compare(b.docs[i], b.docs[j]) if err != nil { panic(err) } return c < 0 } google-cloud-go-0.49.0/firestore/to_value.go000066400000000000000000000234601356504100700207440ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package firestore import ( "errors" "fmt" "reflect" "time" "cloud.google.com/go/internal/fields" "github.com/golang/protobuf/ptypes" ts "github.com/golang/protobuf/ptypes/timestamp" pb "google.golang.org/genproto/googleapis/firestore/v1" "google.golang.org/genproto/googleapis/type/latlng" ) var nullValue = &pb.Value{ValueType: &pb.Value_NullValue{}} var ( typeOfByteSlice = reflect.TypeOf([]byte{}) typeOfGoTime = reflect.TypeOf(time.Time{}) typeOfLatLng = reflect.TypeOf((*latlng.LatLng)(nil)) typeOfDocumentRef = reflect.TypeOf((*DocumentRef)(nil)) typeOfProtoTimestamp = reflect.TypeOf((*ts.Timestamp)(nil)) ) // toProtoValue converts a Go value to a Firestore Value protobuf. // Some corner cases: // - All nils (nil interface, nil slice, nil map, nil pointer) are converted to // a NullValue (not a nil *pb.Value). toProtoValue never returns (nil, false, nil). // It returns (nil, true, nil) if everything in the value is ServerTimestamp. // - An error is returned for uintptr, uint, and uint64, because Firestore uses // an int64 to represent integral values, and those types can't be properly // represented in an int64. // - An error is returned for the special Delete value. // // toProtoValue also reports whether it recursively encountered a transform. func toProtoValue(v reflect.Value) (pbv *pb.Value, sawTransform bool, err error) { if !v.IsValid() { return nullValue, false, nil } vi := v.Interface() if vi == Delete { return nil, false, errors.New("firestore: cannot use Delete in value") } if vi == ServerTimestamp { return nil, false, errors.New("firestore: must use ServerTimestamp as a map value") } switch x := vi.(type) { case []byte: return &pb.Value{ValueType: &pb.Value_BytesValue{x}}, false, nil case time.Time: ts, err := ptypes.TimestampProto(x) if err != nil { return nil, false, err } return &pb.Value{ValueType: &pb.Value_TimestampValue{ts}}, false, nil case *ts.Timestamp: if x == nil { // gRPC doesn't like nil oneofs. Use NullValue. return nullValue, false, nil } return &pb.Value{ValueType: &pb.Value_TimestampValue{x}}, false, nil case *latlng.LatLng: if x == nil { // gRPC doesn't like nil oneofs. Use NullValue. return nullValue, false, nil } return &pb.Value{ValueType: &pb.Value_GeoPointValue{x}}, false, nil case *DocumentRef: if x == nil { // gRPC doesn't like nil oneofs. Use NullValue. return nullValue, false, nil } return &pb.Value{ValueType: &pb.Value_ReferenceValue{x.Path}}, false, nil // Do not add bool, string, int, etc. to this switch; leave them in the // reflect-based switch below. Moving them here would drop support for // types whose underlying types are those primitives. // E.g. Given "type mybool bool", an ordinary type switch on bool will // not catch a mybool, but the reflect.Kind of a mybool is reflect.Bool. } switch v.Kind() { case reflect.Bool: return &pb.Value{ValueType: &pb.Value_BooleanValue{v.Bool()}}, false, nil case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return &pb.Value{ValueType: &pb.Value_IntegerValue{v.Int()}}, false, nil case reflect.Uint8, reflect.Uint16, reflect.Uint32: return &pb.Value{ValueType: &pb.Value_IntegerValue{int64(v.Uint())}}, false, nil case reflect.Float32, reflect.Float64: return &pb.Value{ValueType: &pb.Value_DoubleValue{v.Float()}}, false, nil case reflect.String: return &pb.Value{ValueType: &pb.Value_StringValue{v.String()}}, false, nil case reflect.Array: return arrayToProtoValue(v) case reflect.Slice: return sliceToProtoValue(v) case reflect.Map: return mapToProtoValue(v) case reflect.Struct: return structToProtoValue(v) case reflect.Ptr: if v.IsNil() { return nullValue, false, nil } return toProtoValue(v.Elem()) case reflect.Interface: if v.NumMethod() == 0 { // empty interface: recurse on its contents return toProtoValue(v.Elem()) } fallthrough // any other interface value is an error default: return nil, false, fmt.Errorf("firestore: cannot convert type %s to value", v.Type()) } } // arrayToProtoValue converts a array to a Firestore Value protobuf and reports // whether a transform was encountered. func arrayToProtoValue(v reflect.Value) (*pb.Value, bool, error) { vals := make([]*pb.Value, v.Len()) for i := 0; i < v.Len(); i++ { val, sawTransform, err := toProtoValue(v.Index(i)) if err != nil { return nil, false, err } if sawTransform { return nil, false, fmt.Errorf("firestore: transforms cannot occur in an array, but saw some in %v", v.Index(i)) } vals[i] = val } return &pb.Value{ValueType: &pb.Value_ArrayValue{&pb.ArrayValue{Values: vals}}}, false, nil } // sliceToProtoValue converts a slice to a Firestore Value protobuf and reports // whether a transform was encountered. func sliceToProtoValue(v reflect.Value) (*pb.Value, bool, error) { // A nil slice is converted to a null value. if v.IsNil() { return nullValue, false, nil } return arrayToProtoValue(v) } // mapToProtoValue converts a map to a Firestore Value protobuf and reports whether // a transform was encountered. func mapToProtoValue(v reflect.Value) (*pb.Value, bool, error) { if v.Type().Key().Kind() != reflect.String { return nil, false, errors.New("firestore: map key type must be string") } // A nil map is converted to a null value. if v.IsNil() { return nullValue, false, nil } m := map[string]*pb.Value{} sawTransform := false for _, k := range v.MapKeys() { mi := v.MapIndex(k) if mi.Interface() == ServerTimestamp { sawTransform = true continue } else if _, ok := mi.Interface().(arrayUnion); ok { sawTransform = true continue } else if _, ok := mi.Interface().(arrayRemove); ok { sawTransform = true continue } val, sst, err := toProtoValue(mi) if err != nil { return nil, false, err } if sst { sawTransform = true } if val == nil { // value was a map with all ServerTimestamp values continue } m[k.String()] = val } var pv *pb.Value if len(m) == 0 && sawTransform { // The entire map consisted of transform values. pv = nil } else { pv = &pb.Value{ValueType: &pb.Value_MapValue{&pb.MapValue{Fields: m}}} } return pv, sawTransform, nil } // structToProtoValue converts a struct to a Firestore Value protobuf and reports // whether a transform was encountered. func structToProtoValue(v reflect.Value) (*pb.Value, bool, error) { m := map[string]*pb.Value{} fields, err := fieldCache.Fields(v.Type()) if err != nil { return nil, false, err } sawTransform := false if _, ok := v.Interface().(arrayUnion); ok { return nil, false, errors.New("firestore: ArrayUnion may not be used in structs") } if _, ok := v.Interface().(arrayRemove); ok { return nil, false, errors.New("firestore: ArrayRemove may not be used in structs") } for _, f := range fields { fv := v.FieldByIndex(f.Index) opts := f.ParsedTag.(tagOptions) if opts.serverTimestamp { // TODO(jba): should we return a non-zero time? sawTransform = true continue } if opts.omitEmpty && isEmptyValue(fv) { continue } val, sst, err := toProtoValue(fv) if err != nil { return nil, false, err } if sst { sawTransform = true } if val == nil { // value was a map with all ServerTimestamp values continue } m[f.Name] = val } var pv *pb.Value if len(m) == 0 && sawTransform { // The entire struct consisted of ServerTimestamp or omitempty values. pv = nil } else { pv = &pb.Value{ValueType: &pb.Value_MapValue{&pb.MapValue{Fields: m}}} } return pv, sawTransform, nil } type tagOptions struct { omitEmpty bool // do not marshal value if empty serverTimestamp bool // set time.Time to server timestamp on write } // parseTag interprets firestore struct field tags. func parseTag(t reflect.StructTag) (name string, keep bool, other interface{}, err error) { name, keep, opts, err := fields.ParseStandardTag("firestore", t) if err != nil { return "", false, nil, fmt.Errorf("firestore: %v", err) } tagOpts := tagOptions{} for _, opt := range opts { switch opt { case "omitempty": tagOpts.omitEmpty = true case "serverTimestamp": tagOpts.serverTimestamp = true default: return "", false, nil, fmt.Errorf("firestore: unknown tag option: %q", opt) } } return name, keep, tagOpts, nil } // isLeafType determines whether or not a type is a 'leaf type' // and should not be recursed into, but considered one field. func isLeafType(t reflect.Type) bool { return t == typeOfGoTime || t == typeOfLatLng || t == typeOfProtoTimestamp } var fieldCache = fields.NewCache(parseTag, nil, isLeafType) // isEmptyValue is taken from the encoding/json package in the // standard library. // TODO(jba): move to the fields package func isEmptyValue(v reflect.Value) bool { switch v.Kind() { case reflect.Array, reflect.Map, reflect.Slice, reflect.String: return v.Len() == 0 case reflect.Bool: return !v.Bool() case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return v.Int() == 0 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: return v.Uint() == 0 case reflect.Float32, reflect.Float64: return v.Float() == 0 case reflect.Interface, reflect.Ptr: return v.IsNil() } if v.Type() == typeOfGoTime { return v.Interface().(time.Time).IsZero() } return false } google-cloud-go-0.49.0/firestore/to_value_test.go000066400000000000000000000241751356504100700220070ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package firestore import ( "fmt" "reflect" "testing" "time" ts "github.com/golang/protobuf/ptypes/timestamp" pb "google.golang.org/genproto/googleapis/firestore/v1" "google.golang.org/genproto/googleapis/type/latlng" ) type testStruct1 struct { B bool I int U uint32 F float64 S string Y []byte T time.Time Ts *ts.Timestamp G *latlng.LatLng L []int M map[string]int P *int } var ( p = new(int) testVal1 = testStruct1{ B: true, I: 1, U: 2, F: 3.0, S: "four", Y: []byte{5}, T: tm, Ts: ptm, G: ll, L: []int{6}, M: map[string]int{"a": 7}, P: p, } mapVal1 = mapval(map[string]*pb.Value{ "B": boolval(true), "I": intval(1), "U": intval(2), "F": floatval(3), "S": {ValueType: &pb.Value_StringValue{"four"}}, "Y": bytesval([]byte{5}), "T": tsval(tm), "Ts": {ValueType: &pb.Value_TimestampValue{ptm}}, "G": geoval(ll), "L": arrayval(intval(6)), "M": mapval(map[string]*pb.Value{"a": intval(7)}), "P": intval(8), }) ) // TODO descriptions // TODO cause the array failure func TestToProtoValue_Conversions(t *testing.T) { *p = 8 for _, test := range []struct { desc string in interface{} want *pb.Value }{ { desc: "nil", in: nil, want: nullValue, }, { desc: "nil slice", in: []int(nil), want: nullValue, }, { desc: "nil map", in: map[string]int(nil), want: nullValue, }, { desc: "nil struct", in: (*testStruct1)(nil), want: nullValue, }, { desc: "nil timestamp", in: (*ts.Timestamp)(nil), want: nullValue, }, { desc: "nil latlng", in: (*latlng.LatLng)(nil), want: nullValue, }, { desc: "nil docref", in: (*DocumentRef)(nil), want: nullValue, }, { desc: "bool", in: true, want: boolval(true), }, { desc: "int", in: 3, want: intval(3), }, { desc: "uint32", in: uint32(3), want: intval(3), }, { desc: "float", in: 1.5, want: floatval(1.5), }, { desc: "string", in: "str", want: strval("str"), }, { desc: "byte slice", in: []byte{1, 2}, want: bytesval([]byte{1, 2}), }, { desc: "date time", in: tm, want: tsval(tm), }, { desc: "pointer to timestamp", in: ptm, want: &pb.Value{ValueType: &pb.Value_TimestampValue{ptm}}, }, { desc: "pointer to latlng", in: ll, want: geoval(ll), }, { desc: "populated slice", in: []int{1, 2}, want: arrayval(intval(1), intval(2)), }, { desc: "pointer to populated slice", in: &[]int{1, 2}, want: arrayval(intval(1), intval(2)), }, { desc: "empty slice", in: []int{}, want: arrayval(), }, { desc: "populated map", in: map[string]int{"a": 1, "b": 2}, want: mapval(map[string]*pb.Value{"a": intval(1), "b": intval(2)}), }, { desc: "empty map", in: map[string]int{}, want: mapval(map[string]*pb.Value{}), }, { desc: "int", in: p, want: intval(8), }, { desc: "pointer to int", in: &p, want: intval(8), }, { desc: "populated map", in: map[string]interface{}{"a": 1, "p": p, "s": "str"}, want: mapval(map[string]*pb.Value{"a": intval(1), "p": intval(8), "s": strval("str")}), }, { desc: "map with timestamp", in: map[string]fmt.Stringer{"a": tm}, want: mapval(map[string]*pb.Value{"a": tsval(tm)}), }, { desc: "struct", in: testVal1, want: mapVal1, }, { desc: "array", in: [1]int{7}, want: arrayval(intval(7)), }, { desc: "pointer to docref", in: &DocumentRef{ ID: "d", Path: "projects/P/databases/D/documents/c/d", Parent: &CollectionRef{ ID: "c", parentPath: "projects/P/databases/D", Path: "projects/P/databases/D/documents/c", Query: Query{collectionID: "c", parentPath: "projects/P/databases/D"}, }, }, want: refval("projects/P/databases/D/documents/c/d"), }, { desc: "Transforms are removed, which can lead to leaving nil", in: map[string]interface{}{"a": ServerTimestamp}, want: nil, }, { desc: "Transform nested in map is ignored", in: map[string]interface{}{ "a": map[string]interface{}{ "b": map[string]interface{}{ "c": ServerTimestamp, }, }, }, want: nil, }, { desc: "Transforms nested in map are ignored", in: map[string]interface{}{ "a": map[string]interface{}{ "b": map[string]interface{}{ "c": ServerTimestamp, "d": ServerTimestamp, }, }, }, want: nil, }, { desc: "int nested in map is kept whilst Transforms are ignored", in: map[string]interface{}{ "a": map[string]interface{}{ "b": map[string]interface{}{ "c": ServerTimestamp, "d": ServerTimestamp, "e": 1, }, }, }, want: mapval(map[string]*pb.Value{ "a": mapval(map[string]*pb.Value{ "b": mapval(map[string]*pb.Value{"e": intval(1)}), }), }), }, // Transforms are allowed in maps, but won't show up in the returned proto. Instead, we rely // on seeing sawTransforms=true and a call to extractTransforms. { desc: "Transforms in map are ignored, other values are kept (ServerTimestamp)", in: map[string]interface{}{"a": ServerTimestamp, "b": 5}, want: mapval(map[string]*pb.Value{"b": intval(5)}), }, { desc: "Transforms in map are ignored, other values are kept (ArrayUnion)", in: map[string]interface{}{"a": ArrayUnion(1, 2, 3), "b": 5}, want: mapval(map[string]*pb.Value{"b": intval(5)}), }, { desc: "Transforms in map are ignored, other values are kept (ArrayRemove)", in: map[string]interface{}{"a": ArrayRemove(1, 2, 3), "b": 5}, want: mapval(map[string]*pb.Value{"b": intval(5)}), }, } { t.Run(test.desc, func(t *testing.T) { got, _, err := toProtoValue(reflect.ValueOf(test.in)) if err != nil { t.Fatalf("%v (%T): %v", test.in, test.in, err) } if !testEqual(got, test.want) { t.Fatalf("%+v (%T):\ngot\n%+v\nwant\n%+v", test.in, test.in, got, test.want) } }) } } type stringy struct{} func (stringy) String() string { return "stringy" } func TestToProtoValue_Errors(t *testing.T) { for _, in := range []interface{}{ uint64(0), // a bad fit for int64 map[int]bool{}, // map key type is not string make(chan int), // can't handle type map[string]fmt.Stringer{"a": stringy{}}, // only empty interfaces ServerTimestamp, // ServerTimestamp can only be a field value struct{ A interface{} }{A: ServerTimestamp}, map[string]interface{}{"a": []interface{}{ServerTimestamp}}, map[string]interface{}{"a": []interface{}{ map[string]interface{}{"b": ServerTimestamp}, }}, Delete, // Delete should never appear []interface{}{Delete}, map[string]interface{}{"a": Delete}, map[string]interface{}{"a": []interface{}{Delete}}, // Transforms are not allowed to occur in an array. []interface{}{ServerTimestamp}, []interface{}{ArrayUnion(1, 2, 3)}, []interface{}{ArrayRemove(1, 2, 3)}, // Transforms are not allowed to occur in a struct. struct{ A interface{} }{A: ServerTimestamp}, struct{ A interface{} }{A: ArrayUnion()}, struct{ A interface{} }{A: ArrayRemove()}, } { _, _, err := toProtoValue(reflect.ValueOf(in)) if err == nil { t.Errorf("%v: got nil, want error", in) } } } func TestToProtoValue_SawTransform(t *testing.T) { for i, in := range []interface{}{ map[string]interface{}{"a": ServerTimestamp}, map[string]interface{}{"a": ArrayUnion()}, map[string]interface{}{"a": ArrayRemove()}, } { _, sawTransform, err := toProtoValue(reflect.ValueOf(in)) if err != nil { t.Fatalf("%d %v: got err %v\nexpected nil", i, in, err) } if !sawTransform { t.Errorf("%d %v: got sawTransform=false, expected sawTransform=true", i, in) } } } type testStruct2 struct { Ignore int `firestore:"-"` Rename int `firestore:"a"` OmitEmpty int `firestore:",omitempty"` OmitEmptyTime time.Time `firestore:",omitempty"` } func TestToProtoValue_Tags(t *testing.T) { in := &testStruct2{ Ignore: 1, Rename: 2, OmitEmpty: 3, OmitEmptyTime: aTime, } got, _, err := toProtoValue(reflect.ValueOf(in)) if err != nil { t.Fatal(err) } want := mapval(map[string]*pb.Value{ "a": intval(2), "OmitEmpty": intval(3), "OmitEmptyTime": tsval(aTime), }) if !testEqual(got, want) { t.Errorf("got %+v, want %+v", got, want) } got, _, err = toProtoValue(reflect.ValueOf(testStruct2{})) if err != nil { t.Fatal(err) } want = mapval(map[string]*pb.Value{"a": intval(0)}) if !testEqual(got, want) { t.Errorf("got\n%+v\nwant\n%+v", got, want) } } func TestToProtoValue_Embedded(t *testing.T) { // Embedded time.Time, LatLng, or Timestamp should behave like non-embedded. type embed struct { time.Time *latlng.LatLng *ts.Timestamp } got, _, err := toProtoValue(reflect.ValueOf(embed{tm, ll, ptm})) if err != nil { t.Fatal(err) } want := mapval(map[string]*pb.Value{ "Time": tsval(tm), "LatLng": geoval(ll), "Timestamp": {ValueType: &pb.Value_TimestampValue{ptm}}, }) if !testEqual(got, want) { t.Errorf("got %+v, want %+v", got, want) } } func TestIsEmpty(t *testing.T) { for _, e := range []interface{}{int(0), float32(0), false, "", []int{}, []int(nil), (*int)(nil)} { if !isEmptyValue(reflect.ValueOf(e)) { t.Errorf("%v (%T): want true, got false", e, e) } } i := 3 for _, n := range []interface{}{int(1), float32(1), true, "x", []int{1}, &i} { if isEmptyValue(reflect.ValueOf(n)) { t.Errorf("%v (%T): want false, got true", n, n) } } } google-cloud-go-0.49.0/firestore/transaction.go000066400000000000000000000224611356504100700214530ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package firestore import ( "context" "errors" "cloud.google.com/go/internal/trace" gax "github.com/googleapis/gax-go/v2" pb "google.golang.org/genproto/googleapis/firestore/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) // Transaction represents a Firestore transaction. type Transaction struct { c *Client ctx context.Context id []byte writes []*pb.Write maxAttempts int readOnly bool readAfterWrite bool } // A TransactionOption is an option passed to Client.Transaction. type TransactionOption interface { config(t *Transaction) } // MaxAttempts is a TransactionOption that configures the maximum number of times to // try a transaction. In defaults to DefaultTransactionMaxAttempts. func MaxAttempts(n int) maxAttempts { return maxAttempts(n) } type maxAttempts int func (m maxAttempts) config(t *Transaction) { t.maxAttempts = int(m) } // DefaultTransactionMaxAttempts is the default number of times to attempt a transaction. const DefaultTransactionMaxAttempts = 5 // ReadOnly is a TransactionOption that makes the transaction read-only. Read-only // transactions cannot issue write operations, but are more efficient. var ReadOnly = ro{} type ro struct{} func (ro) config(t *Transaction) { t.readOnly = true } var ( // Defined here for testing. errReadAfterWrite = errors.New("firestore: read after write in transaction") errWriteReadOnly = errors.New("firestore: write in read-only transaction") errNestedTransaction = errors.New("firestore: nested transaction") ) type transactionInProgressKey struct{} // RunTransaction runs f in a transaction. f should use the transaction it is given // for all Firestore operations. For any operation requiring a context, f should use // the context it is passed, not the first argument to RunTransaction. // // f must not call Commit or Rollback on the provided Transaction. // // If f returns nil, RunTransaction commits the transaction. If the commit fails due // to a conflicting transaction, RunTransaction retries f. It gives up and returns an // error after a number of attempts that can be configured with the MaxAttempts // option. If the commit succeeds, RunTransaction returns a nil error. // // If f returns non-nil, then the transaction will be rolled back and // this method will return the same error. The function f is not retried. // // Note that when f returns, the transaction is not committed. Calling code // must not assume that any of f's changes have been committed until // RunTransaction returns nil. // // Since f may be called more than once, f should usually be idempotent – that is, it // should have the same result when called multiple times. func (c *Client) RunTransaction(ctx context.Context, f func(context.Context, *Transaction) error, opts ...TransactionOption) (err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/firestore.Client.RunTransaction") defer func() { trace.EndSpan(ctx, err) }() if ctx.Value(transactionInProgressKey{}) != nil { return errNestedTransaction } db := c.path() t := &Transaction{ c: c, ctx: withResourceHeader(ctx, db), maxAttempts: DefaultTransactionMaxAttempts, } for _, opt := range opts { opt.config(t) } var txOpts *pb.TransactionOptions if t.readOnly { txOpts = &pb.TransactionOptions{ Mode: &pb.TransactionOptions_ReadOnly_{&pb.TransactionOptions_ReadOnly{}}, } } var backoff gax.Backoff // TODO(jba): use other than the standard backoff parameters? // TODO(jba): get backoff time from gRPC trailer metadata? See // extractRetryDelay in https://code.googlesource.com/gocloud/+/master/spanner/retry.go. for i := 0; i < t.maxAttempts; i++ { var res *pb.BeginTransactionResponse res, err = t.c.c.BeginTransaction(t.ctx, &pb.BeginTransactionRequest{ Database: db, Options: txOpts, }) if err != nil { return err } t.id = res.Transaction err = f(context.WithValue(ctx, transactionInProgressKey{}, 1), t) // Read after write can only be checked client-side, so we make sure to check // even if the user does not. if err == nil && t.readAfterWrite { err = errReadAfterWrite } if err != nil { t.rollback() // Prefer f's returned error to rollback error. return err } _, err = t.c.c.Commit(t.ctx, &pb.CommitRequest{ Database: t.c.path(), Writes: t.writes, Transaction: t.id, }) // If a read-write transaction returns Aborted, retry. // On success or other failures, return here. if t.readOnly || status.Code(err) != codes.Aborted { // According to the Firestore team, we should not roll back here // if err != nil. But spanner does. // See https://code.googlesource.com/gocloud/+/master/spanner/transaction.go#740. return err } if txOpts == nil { // txOpts can only be nil if is the first retry of a read-write transaction. // (It is only set here and in the body of "if t.readOnly" above.) // Mention the transaction ID in BeginTransaction so the service // knows it is a retry. txOpts = &pb.TransactionOptions{ Mode: &pb.TransactionOptions_ReadWrite_{ &pb.TransactionOptions_ReadWrite{RetryTransaction: t.id}, }, } } // Use exponential backoff to avoid contention with other running // transactions. if cerr := sleep(ctx, backoff.Pause()); cerr != nil { err = cerr break } // Reset state for the next attempt. t.writes = nil } // If we run out of retries, return the last error we saw (which should // be the Aborted from Commit, or a context error). if err != nil { t.rollback() } return err } func (t *Transaction) rollback() { _ = t.c.c.Rollback(t.ctx, &pb.RollbackRequest{ Database: t.c.path(), Transaction: t.id, }) // Ignore the rollback error. // TODO(jba): Log it? // Note: Rollback is idempotent so it will be retried by the gapic layer. } // Get gets the document in the context of the transaction. The transaction holds a // pessimistic lock on the returned document. func (t *Transaction) Get(dr *DocumentRef) (*DocumentSnapshot, error) { docsnaps, err := t.GetAll([]*DocumentRef{dr}) if err != nil { return nil, err } ds := docsnaps[0] if !ds.Exists() { return ds, status.Errorf(codes.NotFound, "%q not found", dr.Path) } return ds, nil } // GetAll retrieves multiple documents with a single call. The DocumentSnapshots are // returned in the order of the given DocumentRefs. If a document is not present, the // corresponding DocumentSnapshot's Exists method will return false. The transaction // holds a pessimistic lock on all of the returned documents. func (t *Transaction) GetAll(drs []*DocumentRef) ([]*DocumentSnapshot, error) { if len(t.writes) > 0 { t.readAfterWrite = true return nil, errReadAfterWrite } return t.c.getAll(t.ctx, drs, t.id) } // A Queryer is a Query or a CollectionRef. CollectionRefs act as queries whose // results are all the documents in the collection. type Queryer interface { query() *Query } // Documents returns a DocumentIterator based on given Query or CollectionRef. The // results will be in the context of the transaction. func (t *Transaction) Documents(q Queryer) *DocumentIterator { if len(t.writes) > 0 { t.readAfterWrite = true return &DocumentIterator{err: errReadAfterWrite} } return &DocumentIterator{ iter: newQueryDocumentIterator(t.ctx, q.query(), t.id), } } // DocumentRefs returns references to all the documents in the collection, including // missing documents. A missing document is a document that does not exist but has // sub-documents. func (t *Transaction) DocumentRefs(cr *CollectionRef) *DocumentRefIterator { if len(t.writes) > 0 { t.readAfterWrite = true return &DocumentRefIterator{err: errReadAfterWrite} } return newDocumentRefIterator(t.ctx, cr, t.id) } // Create adds a Create operation to the Transaction. // See DocumentRef.Create for details. func (t *Transaction) Create(dr *DocumentRef, data interface{}) error { return t.addWrites(dr.newCreateWrites(data)) } // Set adds a Set operation to the Transaction. // See DocumentRef.Set for details. func (t *Transaction) Set(dr *DocumentRef, data interface{}, opts ...SetOption) error { return t.addWrites(dr.newSetWrites(data, opts)) } // Delete adds a Delete operation to the Transaction. // See DocumentRef.Delete for details. func (t *Transaction) Delete(dr *DocumentRef, opts ...Precondition) error { return t.addWrites(dr.newDeleteWrites(opts)) } // Update adds a new Update operation to the Transaction. // See DocumentRef.Update for details. func (t *Transaction) Update(dr *DocumentRef, data []Update, opts ...Precondition) error { return t.addWrites(dr.newUpdatePathWrites(data, opts)) } func (t *Transaction) addWrites(ws []*pb.Write, err error) error { if t.readOnly { return errWriteReadOnly } if err != nil { return err } t.writes = append(t.writes, ws...) return nil } google-cloud-go-0.49.0/firestore/transaction_test.go000066400000000000000000000324061356504100700225120ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package firestore import ( "context" "testing" "github.com/golang/protobuf/ptypes/empty" "google.golang.org/api/iterator" pb "google.golang.org/genproto/googleapis/firestore/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) func TestRunTransaction(t *testing.T) { ctx := context.Background() c, srv, cleanup := newMock(t) defer cleanup() const db = "projects/projectID/databases/(default)" tid := []byte{1} beginReq := &pb.BeginTransactionRequest{Database: db} beginRes := &pb.BeginTransactionResponse{Transaction: tid} commitReq := &pb.CommitRequest{Database: db, Transaction: tid} // Empty transaction. srv.addRPC(beginReq, beginRes) srv.addRPC(commitReq, &pb.CommitResponse{CommitTime: aTimestamp}) err := c.RunTransaction(ctx, func(context.Context, *Transaction) error { return nil }) if err != nil { t.Fatal(err) } // Transaction with read and write. srv.reset() srv.addRPC(beginReq, beginRes) aDoc := &pb.Document{ Name: db + "/documents/C/a", CreateTime: aTimestamp, UpdateTime: aTimestamp2, Fields: map[string]*pb.Value{"count": intval(1)}, } srv.addRPC( &pb.BatchGetDocumentsRequest{ Database: c.path(), Documents: []string{db + "/documents/C/a"}, ConsistencySelector: &pb.BatchGetDocumentsRequest_Transaction{tid}, }, []interface{}{ &pb.BatchGetDocumentsResponse{ Result: &pb.BatchGetDocumentsResponse_Found{aDoc}, ReadTime: aTimestamp2, }, }) aDoc2 := &pb.Document{ Name: aDoc.Name, Fields: map[string]*pb.Value{"count": intval(2)}, } srv.addRPC( &pb.CommitRequest{ Database: db, Transaction: tid, Writes: []*pb.Write{{ Operation: &pb.Write_Update{aDoc2}, UpdateMask: &pb.DocumentMask{FieldPaths: []string{"count"}}, CurrentDocument: &pb.Precondition{ ConditionType: &pb.Precondition_Exists{true}, }, }}, }, &pb.CommitResponse{CommitTime: aTimestamp3}, ) err = c.RunTransaction(ctx, func(_ context.Context, tx *Transaction) error { docref := c.Collection("C").Doc("a") doc, err := tx.Get(docref) if err != nil { return err } count, err := doc.DataAt("count") if err != nil { return err } return tx.Update(docref, []Update{{Path: "count", Value: count.(int64) + 1}}) }) if err != nil { t.Fatal(err) } // Query srv.reset() srv.addRPC(beginReq, beginRes) srv.addRPC( &pb.RunQueryRequest{ Parent: db + "/documents", QueryType: &pb.RunQueryRequest_StructuredQuery{ &pb.StructuredQuery{ From: []*pb.StructuredQuery_CollectionSelector{{CollectionId: "C"}}, }, }, ConsistencySelector: &pb.RunQueryRequest_Transaction{tid}, }, []interface{}{}, ) srv.addRPC(commitReq, &pb.CommitResponse{CommitTime: aTimestamp3}) err = c.RunTransaction(ctx, func(_ context.Context, tx *Transaction) error { it := tx.Documents(c.Collection("C")) defer it.Stop() _, err := it.Next() if err != iterator.Done { return err } return nil }) if err != nil { t.Fatal(err) } // Retry entire transaction. srv.reset() srv.addRPC(beginReq, beginRes) srv.addRPC(commitReq, status.Errorf(codes.Aborted, "")) srv.addRPC( &pb.BeginTransactionRequest{ Database: db, Options: &pb.TransactionOptions{ Mode: &pb.TransactionOptions_ReadWrite_{ &pb.TransactionOptions_ReadWrite{RetryTransaction: tid}, }, }, }, beginRes, ) srv.addRPC(commitReq, &pb.CommitResponse{CommitTime: aTimestamp}) err = c.RunTransaction(ctx, func(_ context.Context, tx *Transaction) error { return nil }) if err != nil { t.Fatal(err) } } func TestTransactionErrors(t *testing.T) { ctx := context.Background() const db = "projects/projectID/databases/(default)" c, srv, cleanup := newMock(t) defer cleanup() var ( tid = []byte{1} internalErr = status.Errorf(codes.Internal, "so sad") beginReq = &pb.BeginTransactionRequest{ Database: db, } beginRes = &pb.BeginTransactionResponse{Transaction: tid} getReq = &pb.BatchGetDocumentsRequest{ Database: c.path(), Documents: []string{db + "/documents/C/a"}, ConsistencySelector: &pb.BatchGetDocumentsRequest_Transaction{tid}, } rollbackReq = &pb.RollbackRequest{Database: db, Transaction: tid} commitReq = &pb.CommitRequest{Database: db, Transaction: tid} ) // BeginTransaction has a permanent error. srv.addRPC(beginReq, internalErr) err := c.RunTransaction(ctx, func(context.Context, *Transaction) error { return nil }) if status.Code(err) != codes.Internal { t.Errorf("got <%v>, want Internal", err) } // Get has a permanent error. get := func(_ context.Context, tx *Transaction) error { _, err := tx.Get(c.Doc("C/a")) return err } srv.reset() srv.addRPC(beginReq, beginRes) srv.addRPC(getReq, internalErr) srv.addRPC(rollbackReq, &empty.Empty{}) err = c.RunTransaction(ctx, get) if status.Code(err) != codes.Internal { t.Errorf("got <%v>, want Internal", err) } // Get has a permanent error, but the rollback fails. We still // return Get's error. srv.reset() srv.addRPC(beginReq, beginRes) srv.addRPC(getReq, internalErr) srv.addRPC(rollbackReq, status.Errorf(codes.FailedPrecondition, "")) err = c.RunTransaction(ctx, get) if status.Code(err) != codes.Internal { t.Errorf("got <%v>, want Internal", err) } // Commit has a permanent error. srv.reset() srv.addRPC(beginReq, beginRes) srv.addRPC(getReq, []interface{}{ &pb.BatchGetDocumentsResponse{ Result: &pb.BatchGetDocumentsResponse_Found{&pb.Document{ Name: "projects/projectID/databases/(default)/documents/C/a", CreateTime: aTimestamp, UpdateTime: aTimestamp2, }}, ReadTime: aTimestamp2, }, }) srv.addRPC(commitReq, internalErr) err = c.RunTransaction(ctx, get) if status.Code(err) != codes.Internal { t.Errorf("got <%v>, want Internal", err) } // Read after write. srv.reset() srv.addRPC(beginReq, beginRes) srv.addRPC(rollbackReq, &empty.Empty{}) err = c.RunTransaction(ctx, func(_ context.Context, tx *Transaction) error { if err := tx.Delete(c.Doc("C/a")); err != nil { return err } if _, err := tx.Get(c.Doc("C/a")); err != nil { return err } return nil }) if err != errReadAfterWrite { t.Errorf("got <%v>, want <%v>", err, errReadAfterWrite) } // Read after write, with query. srv.reset() srv.addRPC(beginReq, beginRes) srv.addRPC(rollbackReq, &empty.Empty{}) err = c.RunTransaction(ctx, func(_ context.Context, tx *Transaction) error { if err := tx.Delete(c.Doc("C/a")); err != nil { return err } it := tx.Documents(c.Collection("C").Select("x")) defer it.Stop() if _, err := it.Next(); err != iterator.Done { return err } return nil }) if err != errReadAfterWrite { t.Errorf("got <%v>, want <%v>", err, errReadAfterWrite) } // Read after write fails even if the user ignores the read's error. srv.reset() srv.addRPC(beginReq, beginRes) srv.addRPC(rollbackReq, &empty.Empty{}) err = c.RunTransaction(ctx, func(_ context.Context, tx *Transaction) error { if err := tx.Delete(c.Doc("C/a")); err != nil { return err } if _, err := tx.Get(c.Doc("C/a")); err != nil { return err } return nil }) if err != errReadAfterWrite { t.Errorf("got <%v>, want <%v>", err, errReadAfterWrite) } // Write in read-only transaction. srv.reset() srv.addRPC( &pb.BeginTransactionRequest{ Database: db, Options: &pb.TransactionOptions{ Mode: &pb.TransactionOptions_ReadOnly_{&pb.TransactionOptions_ReadOnly{}}, }, }, beginRes, ) srv.addRPC(rollbackReq, &empty.Empty{}) err = c.RunTransaction(ctx, func(_ context.Context, tx *Transaction) error { return tx.Delete(c.Doc("C/a")) }, ReadOnly) if err != errWriteReadOnly { t.Errorf("got <%v>, want <%v>", err, errWriteReadOnly) } // Too many retries. srv.reset() srv.addRPC(beginReq, beginRes) srv.addRPC(commitReq, status.Errorf(codes.Aborted, "")) srv.addRPC( &pb.BeginTransactionRequest{ Database: db, Options: &pb.TransactionOptions{ Mode: &pb.TransactionOptions_ReadWrite_{ &pb.TransactionOptions_ReadWrite{RetryTransaction: tid}, }, }, }, beginRes, ) srv.addRPC(commitReq, status.Errorf(codes.Aborted, "")) srv.addRPC(rollbackReq, &empty.Empty{}) err = c.RunTransaction(ctx, func(context.Context, *Transaction) error { return nil }, MaxAttempts(2)) if status.Code(err) != codes.Aborted { t.Errorf("got <%v>, want Aborted", err) } // Nested transaction. srv.reset() srv.addRPC(beginReq, beginRes) srv.addRPC(rollbackReq, &empty.Empty{}) err = c.RunTransaction(ctx, func(ctx context.Context, tx *Transaction) error { return c.RunTransaction(ctx, func(context.Context, *Transaction) error { return nil }) }) if got, want := err, errNestedTransaction; got != want { t.Errorf("got <%v>, want <%v>", got, want) } } func TestTransactionGetAll(t *testing.T) { c, srv, cleanup := newMock(t) defer cleanup() const dbPath = "projects/projectID/databases/(default)" tid := []byte{1} beginReq := &pb.BeginTransactionRequest{Database: dbPath} beginRes := &pb.BeginTransactionResponse{Transaction: tid} srv.addRPC(beginReq, beginRes) req := &pb.BatchGetDocumentsRequest{ Database: dbPath, Documents: []string{ dbPath + "/documents/C/a", dbPath + "/documents/C/b", dbPath + "/documents/C/c", }, ConsistencySelector: &pb.BatchGetDocumentsRequest_Transaction{tid}, } err := c.RunTransaction(context.Background(), func(_ context.Context, tx *Transaction) error { testGetAll(t, c, srv, dbPath, func(drs []*DocumentRef) ([]*DocumentSnapshot, error) { return tx.GetAll(drs) }, req) commitReq := &pb.CommitRequest{Database: dbPath, Transaction: tid} srv.addRPC(commitReq, &pb.CommitResponse{CommitTime: aTimestamp}) return nil }) if err != nil { t.Fatal(err) } } // Each retry attempt has the same amount of commit writes. func TestRunTransaction_Retries(t *testing.T) { ctx := context.Background() c, srv, cleanup := newMock(t) defer cleanup() const db = "projects/projectID/databases/(default)" tid := []byte{1} srv.addRPC( &pb.BeginTransactionRequest{Database: db}, &pb.BeginTransactionResponse{Transaction: tid}, ) aDoc := &pb.Document{ Name: db + "/documents/C/a", CreateTime: aTimestamp, UpdateTime: aTimestamp2, Fields: map[string]*pb.Value{"count": intval(1)}, } aDoc2 := &pb.Document{ Name: aDoc.Name, Fields: map[string]*pb.Value{"count": intval(7)}, } srv.addRPC( &pb.CommitRequest{ Database: db, Transaction: tid, Writes: []*pb.Write{{ Operation: &pb.Write_Update{aDoc2}, UpdateMask: &pb.DocumentMask{FieldPaths: []string{"count"}}, CurrentDocument: &pb.Precondition{ ConditionType: &pb.Precondition_Exists{true}, }, }}, }, status.Errorf(codes.Aborted, "something failed! please retry me!"), ) srv.addRPC( &pb.BeginTransactionRequest{ Database: db, Options: &pb.TransactionOptions{ Mode: &pb.TransactionOptions_ReadWrite_{ &pb.TransactionOptions_ReadWrite{RetryTransaction: tid}, }, }, }, &pb.BeginTransactionResponse{Transaction: tid}, ) srv.addRPC( &pb.CommitRequest{ Database: db, Transaction: tid, Writes: []*pb.Write{{ Operation: &pb.Write_Update{aDoc2}, UpdateMask: &pb.DocumentMask{FieldPaths: []string{"count"}}, CurrentDocument: &pb.Precondition{ ConditionType: &pb.Precondition_Exists{true}, }, }}, }, &pb.CommitResponse{CommitTime: aTimestamp3}, ) err := c.RunTransaction(ctx, func(_ context.Context, tx *Transaction) error { docref := c.Collection("C").Doc("a") return tx.Update(docref, []Update{{Path: "count", Value: 7}}) }) if err != nil { t.Fatal(err) } } // Non-transactional operations are allowed in transactions (although // discouraged). func TestRunTransaction_NonTransactionalOp(t *testing.T) { ctx := context.Background() c, srv, cleanup := newMock(t) defer cleanup() const db = "projects/projectID/databases/(default)" tid := []byte{1} beginReq := &pb.BeginTransactionRequest{Database: db} beginRes := &pb.BeginTransactionResponse{Transaction: tid} srv.reset() srv.addRPC(beginReq, beginRes) aDoc := &pb.Document{ Name: db + "/documents/C/a", CreateTime: aTimestamp, UpdateTime: aTimestamp2, Fields: map[string]*pb.Value{"count": intval(1)}, } srv.addRPC( &pb.BatchGetDocumentsRequest{ Database: c.path(), Documents: []string{db + "/documents/C/a"}, }, []interface{}{ &pb.BatchGetDocumentsResponse{ Result: &pb.BatchGetDocumentsResponse_Found{aDoc}, ReadTime: aTimestamp2, }, }) srv.addRPC( &pb.CommitRequest{ Database: db, Transaction: tid, }, &pb.CommitResponse{CommitTime: aTimestamp3}, ) if err := c.RunTransaction(ctx, func(ctx2 context.Context, tx *Transaction) error { docref := c.Collection("C").Doc("a") if _, err := c.GetAll(ctx2, []*DocumentRef{docref}); err != nil { t.Fatal(err) } return nil }); err != nil { t.Fatal(err) } } google-cloud-go-0.49.0/firestore/util_test.go000066400000000000000000000075451356504100700211500ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package firestore import ( "context" "fmt" "testing" "time" "cloud.google.com/go/internal/testutil" "github.com/golang/protobuf/ptypes" tspb "github.com/golang/protobuf/ptypes/timestamp" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "google.golang.org/api/option" pb "google.golang.org/genproto/googleapis/firestore/v1" "google.golang.org/genproto/googleapis/type/latlng" "google.golang.org/grpc" ) var ( aTime = time.Date(2017, 1, 26, 0, 0, 0, 0, time.UTC) aTime2 = time.Date(2017, 2, 5, 0, 0, 0, 0, time.UTC) aTime3 = time.Date(2017, 3, 20, 0, 0, 0, 0, time.UTC) aTimestamp = mustTimestampProto(aTime) aTimestamp2 = mustTimestampProto(aTime2) aTimestamp3 = mustTimestampProto(aTime3) ) func mustTimestampProto(t time.Time) *tspb.Timestamp { ts, err := ptypes.TimestampProto(t) if err != nil { panic(err) } return ts } var cmpOpts = []cmp.Option{ cmp.AllowUnexported(DocumentRef{}, CollectionRef{}, DocumentSnapshot{}, Query{}, filter{}, order{}, fpv{}), cmpopts.IgnoreTypes(Client{}, &Client{}), } // testEqual implements equality for Firestore tests. func testEqual(a, b interface{}) bool { return testutil.Equal(a, b, cmpOpts...) } func testDiff(a, b interface{}) string { return testutil.Diff(a, b, cmpOpts...) } func TestTestEqual(t *testing.T) { for _, test := range []struct { a, b interface{} want bool }{ {nil, nil, true}, {([]int)(nil), nil, false}, {nil, ([]int)(nil), false}, {([]int)(nil), ([]int)(nil), true}, } { if got := testEqual(test.a, test.b); got != test.want { t.Errorf("testEqual(%#v, %#v) == %t, want %t", test.a, test.b, got, test.want) } } } func newMock(t *testing.T) (_ *Client, _ *mockServer, _ func()) { srv, cleanup, err := newMockServer() if err != nil { t.Fatal(err) } conn, err := grpc.Dial(srv.Addr, grpc.WithInsecure(), grpc.WithBlock()) if err != nil { t.Fatal(err) } client, err := NewClient(context.Background(), "projectID", option.WithGRPCConn(conn)) if err != nil { t.Fatal(err) } return client, srv, func() { client.Close() conn.Close() cleanup() } } func intval(i int) *pb.Value { return int64val(int64(i)) } func int64val(i int64) *pb.Value { return &pb.Value{ValueType: &pb.Value_IntegerValue{i}} } func boolval(b bool) *pb.Value { return &pb.Value{ValueType: &pb.Value_BooleanValue{b}} } func floatval(f float64) *pb.Value { return &pb.Value{ValueType: &pb.Value_DoubleValue{f}} } func strval(s string) *pb.Value { return &pb.Value{ValueType: &pb.Value_StringValue{s}} } func bytesval(b []byte) *pb.Value { return &pb.Value{ValueType: &pb.Value_BytesValue{b}} } func tsval(t time.Time) *pb.Value { ts, err := ptypes.TimestampProto(t) if err != nil { panic(fmt.Sprintf("bad time %s in test: %v", t, err)) } return &pb.Value{ValueType: &pb.Value_TimestampValue{ts}} } func geoval(ll *latlng.LatLng) *pb.Value { return &pb.Value{ValueType: &pb.Value_GeoPointValue{ll}} } func arrayval(s ...*pb.Value) *pb.Value { if s == nil { s = []*pb.Value{} } return &pb.Value{ValueType: &pb.Value_ArrayValue{&pb.ArrayValue{Values: s}}} } func mapval(m map[string]*pb.Value) *pb.Value { return &pb.Value{ValueType: &pb.Value_MapValue{&pb.MapValue{Fields: m}}} } func refval(path string) *pb.Value { return &pb.Value{ValueType: &pb.Value_ReferenceValue{path}} } google-cloud-go-0.49.0/firestore/watch.go000066400000000000000000000366241356504100700202420ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package firestore import ( "context" "errors" "fmt" "io" "log" "sort" "time" "cloud.google.com/go/internal/btree" "github.com/golang/protobuf/ptypes" gax "github.com/googleapis/gax-go/v2" pb "google.golang.org/genproto/googleapis/firestore/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) // LogWatchStreams controls whether watch stream status changes are logged. // This feature is EXPERIMENTAL and may disappear at any time. var LogWatchStreams = false // DocumentChangeKind describes the kind of change to a document between // query snapshots. type DocumentChangeKind int const ( // DocumentAdded indicates that the document was added for the first time. DocumentAdded DocumentChangeKind = iota // DocumentRemoved indicates that the document was removed. DocumentRemoved // DocumentModified indicates that the document was modified. DocumentModified ) // A DocumentChange describes the change to a document from one query snapshot to the next. type DocumentChange struct { Kind DocumentChangeKind Doc *DocumentSnapshot // The zero-based index of the document in the sequence of query results prior to this change, // or -1 if the document was not present. OldIndex int // The zero-based index of the document in the sequence of query results after this change, // or -1 if the document is no longer present. NewIndex int } // Implementation of realtime updates (a.k.a. watch). // This code is closely based on the Node.js implementation, // https://github.com/googleapis/nodejs-firestore/blob/master/src/watch.js. // The sole target ID for all streams from this client. // Variable for testing. var watchTargetID int32 = 'g' + 'o' var defaultBackoff = gax.Backoff{ // Values from https://github.com/googleapis/nodejs-firestore/blob/master/src/backoff.js. Initial: 1 * time.Second, Max: 60 * time.Second, Multiplier: 1.5, } // not goroutine-safe type watchStream struct { ctx context.Context c *Client lc pb.Firestore_ListenClient // the gRPC stream target *pb.Target // document or query being watched backoff gax.Backoff // for stream retries err error // sticky permanent error readTime time.Time // time of most recent snapshot current bool // saw CURRENT, but not RESET; precondition for a snapshot hasReturned bool // have we returned a snapshot yet? compare func(a, b *DocumentSnapshot) (int, error) // compare documents according to query // An ordered tree where DocumentSnapshots are the keys. docTree *btree.BTree // Map of document name to DocumentSnapshot for the last returned snapshot. docMap map[string]*DocumentSnapshot // Map of document name to DocumentSnapshot for accumulated changes for the current snapshot. // A nil value means the document was removed. changeMap map[string]*DocumentSnapshot } func newWatchStreamForDocument(ctx context.Context, dr *DocumentRef) *watchStream { // A single document is always equal to itself. compare := func(_, _ *DocumentSnapshot) (int, error) { return 0, nil } return newWatchStream(ctx, dr.Parent.c, compare, &pb.Target{ TargetType: &pb.Target_Documents{ Documents: &pb.Target_DocumentsTarget{Documents: []string{dr.Path}}, }, TargetId: watchTargetID, }) } func newWatchStreamForQuery(ctx context.Context, q Query) (*watchStream, error) { qp, err := q.toProto() if err != nil { return nil, err } target := &pb.Target{ TargetType: &pb.Target_Query{ Query: &pb.Target_QueryTarget{ Parent: q.parentPath, QueryType: &pb.Target_QueryTarget_StructuredQuery{qp}, }, }, TargetId: watchTargetID, } return newWatchStream(ctx, q.c, q.compareFunc(), target), nil } const btreeDegree = 4 func newWatchStream(ctx context.Context, c *Client, compare func(_, _ *DocumentSnapshot) (int, error), target *pb.Target) *watchStream { w := &watchStream{ ctx: ctx, c: c, compare: compare, target: target, backoff: defaultBackoff, docMap: map[string]*DocumentSnapshot{}, changeMap: map[string]*DocumentSnapshot{}, } w.docTree = btree.New(btreeDegree, func(a, b interface{}) bool { return w.less(a.(*DocumentSnapshot), b.(*DocumentSnapshot)) }) return w } func (s *watchStream) less(a, b *DocumentSnapshot) bool { c, err := s.compare(a, b) if err != nil { s.err = err return false } return c < 0 } // Once nextSnapshot returns an error, it will always return the same error. func (s *watchStream) nextSnapshot() (*btree.BTree, []DocumentChange, time.Time, error) { if s.err != nil { return nil, nil, time.Time{}, s.err } var changes []DocumentChange for { // Process messages until we are in a consistent state. for !s.handleNextMessage() { } if s.err != nil { _ = s.close() // ignore error return nil, nil, time.Time{}, s.err } var newDocTree *btree.BTree newDocTree, changes = s.computeSnapshot(s.docTree, s.docMap, s.changeMap, s.readTime) if s.err != nil { return nil, nil, time.Time{}, s.err } // Only return a snapshot if something has changed, or this is the first snapshot. if !s.hasReturned || newDocTree != s.docTree { s.docTree = newDocTree break } } s.changeMap = map[string]*DocumentSnapshot{} s.hasReturned = true return s.docTree, changes, s.readTime, nil } // Read a message from the stream and handle it. Return true when // we're in a consistent state, or there is a permanent error. func (s *watchStream) handleNextMessage() bool { res, err := s.recv() if err != nil { s.err = err // Errors returned by recv are permanent. return true } switch r := res.ResponseType.(type) { case *pb.ListenResponse_TargetChange: return s.handleTargetChange(r.TargetChange) case *pb.ListenResponse_DocumentChange: name := r.DocumentChange.Document.Name s.logf("DocumentChange %q", name) if hasWatchTargetID(r.DocumentChange.TargetIds) { // document changed ref, err := pathToDoc(name, s.c) if err == nil { s.changeMap[name], err = newDocumentSnapshot(ref, r.DocumentChange.Document, s.c, nil) } if err != nil { s.err = err return true } } else if hasWatchTargetID(r.DocumentChange.RemovedTargetIds) { // document removed s.changeMap[name] = nil } case *pb.ListenResponse_DocumentDelete: s.logf("Delete %q", r.DocumentDelete.Document) s.changeMap[r.DocumentDelete.Document] = nil case *pb.ListenResponse_DocumentRemove: s.logf("Remove %q", r.DocumentRemove.Document) s.changeMap[r.DocumentRemove.Document] = nil case *pb.ListenResponse_Filter: s.logf("Filter %d", r.Filter.Count) if int(r.Filter.Count) != s.currentSize() { s.resetDocs() // Remove all the current results. // The filter didn't match; close the stream so it will be re-opened on the next // call to nextSnapshot. _ = s.close() // ignore error s.lc = nil } default: s.err = fmt.Errorf("unknown response type %T", r) return true } return false } // Return true iff in a consistent state, or there is a permanent error. func (s *watchStream) handleTargetChange(tc *pb.TargetChange) bool { switch tc.TargetChangeType { case pb.TargetChange_NO_CHANGE: s.logf("TargetNoChange %d %v", len(tc.TargetIds), tc.ReadTime) if len(tc.TargetIds) == 0 && tc.ReadTime != nil && s.current { // Everything is up-to-date, so we are ready to return a snapshot. rt, err := ptypes.Timestamp(tc.ReadTime) if err != nil { s.err = err return true } s.readTime = rt s.target.ResumeType = &pb.Target_ResumeToken{tc.ResumeToken} return true } case pb.TargetChange_ADD: s.logf("TargetAdd") if tc.TargetIds[0] != watchTargetID { s.err = errors.New("unexpected target ID sent by server") return true } case pb.TargetChange_REMOVE: s.logf("TargetRemove") // We should never see a remove. if tc.Cause != nil { s.err = status.Error(codes.Code(tc.Cause.Code), tc.Cause.Message) } else { s.err = status.Error(codes.Internal, "firestore: client saw REMOVE") } return true // The targets reflect all changes committed before the targets were added // to the stream. case pb.TargetChange_CURRENT: s.logf("TargetCurrent") s.current = true // The targets have been reset, and a new initial state for the targets will be // returned in subsequent changes. Whatever changes have happened so far no // longer matter. case pb.TargetChange_RESET: s.logf("TargetReset") s.resetDocs() default: s.err = fmt.Errorf("firestore: unknown TargetChange type %s", tc.TargetChangeType) return true } // If we see a resume token and our watch ID is affected, we assume the stream // is now healthy, so we reset our backoff time to the minimum. if tc.ResumeToken != nil && (len(tc.TargetIds) == 0 || hasWatchTargetID(tc.TargetIds)) { s.backoff = defaultBackoff } return false // not in a consistent state, keep receiving } func (s *watchStream) resetDocs() { s.target.ResumeType = nil // clear resume token s.current = false s.changeMap = map[string]*DocumentSnapshot{} // Mark each document as deleted. If documents are not deleted, they // will be send again by the server. it := s.docTree.BeforeIndex(0) for it.Next() { s.changeMap[it.Key.(*DocumentSnapshot).Ref.Path] = nil } } func (s *watchStream) currentSize() int { _, adds, deletes := extractChanges(s.docMap, s.changeMap) return len(s.docMap) + len(adds) - len(deletes) } // Return the changes that have occurred since the last snapshot. func extractChanges(docMap, changeMap map[string]*DocumentSnapshot) (updates, adds []*DocumentSnapshot, deletes []string) { for name, doc := range changeMap { switch { case doc == nil: if _, ok := docMap[name]; ok { deletes = append(deletes, name) } case docMap[name] != nil: updates = append(updates, doc) default: adds = append(adds, doc) } } return updates, adds, deletes } // For development only. // TODO(jba): remove. func assert(b bool) { if !b { panic("assertion failed") } } // Applies the mutations in changeMap to both the document tree and the // document lookup map. Modifies docMap in place and returns a new docTree. // If there were no changes, returns docTree unmodified. func (s *watchStream) computeSnapshot(docTree *btree.BTree, docMap, changeMap map[string]*DocumentSnapshot, readTime time.Time) (*btree.BTree, []DocumentChange) { var changes []DocumentChange updatedTree := docTree assert(docTree.Len() == len(docMap)) updates, adds, deletes := extractChanges(docMap, changeMap) if len(adds) > 0 || len(deletes) > 0 { updatedTree = docTree.Clone() } // Process the sorted changes in the order that is expected by our clients // (removals, additions, and then modifications). We also need to sort the // individual changes to assure that oldIndex/newIndex keep incrementing. deldocs := make([]*DocumentSnapshot, len(deletes)) for i, d := range deletes { deldocs[i] = docMap[d] } sort.Sort(byLess{deldocs, s.less}) for _, oldDoc := range deldocs { assert(oldDoc != nil) delete(docMap, oldDoc.Ref.Path) _, oldi := updatedTree.GetWithIndex(oldDoc) // TODO(jba): have btree.Delete return old index _, found := updatedTree.Delete(oldDoc) assert(found) changes = append(changes, DocumentChange{ Kind: DocumentRemoved, Doc: oldDoc, OldIndex: oldi, NewIndex: -1, }) } sort.Sort(byLess{adds, s.less}) for _, newDoc := range adds { name := newDoc.Ref.Path assert(docMap[name] == nil) newDoc.ReadTime = readTime docMap[name] = newDoc updatedTree.Set(newDoc, nil) // TODO(jba): change btree so Set returns index as second value. _, newi := updatedTree.GetWithIndex(newDoc) changes = append(changes, DocumentChange{ Kind: DocumentAdded, Doc: newDoc, OldIndex: -1, NewIndex: newi, }) } sort.Sort(byLess{updates, s.less}) for _, newDoc := range updates { name := newDoc.Ref.Path oldDoc := docMap[name] assert(oldDoc != nil) if newDoc.UpdateTime.Equal(oldDoc.UpdateTime) { continue } if updatedTree == docTree { updatedTree = docTree.Clone() } newDoc.ReadTime = readTime docMap[name] = newDoc _, oldi := updatedTree.GetWithIndex(oldDoc) updatedTree.Delete(oldDoc) updatedTree.Set(newDoc, nil) _, newi := updatedTree.GetWithIndex(newDoc) changes = append(changes, DocumentChange{ Kind: DocumentModified, Doc: newDoc, OldIndex: oldi, NewIndex: newi, }) } assert(updatedTree.Len() == len(docMap)) return updatedTree, changes } type byLess struct { s []*DocumentSnapshot less func(a, b *DocumentSnapshot) bool } func (b byLess) Len() int { return len(b.s) } func (b byLess) Swap(i, j int) { b.s[i], b.s[j] = b.s[j], b.s[i] } func (b byLess) Less(i, j int) bool { return b.less(b.s[i], b.s[j]) } func hasWatchTargetID(ids []int32) bool { for _, id := range ids { if id == watchTargetID { return true } } return false } func (s *watchStream) logf(format string, args ...interface{}) { if LogWatchStreams { log.Printf(format, args...) } } // Close the stream. From this point on, calls to nextSnapshot will return // io.EOF, or the error from CloseSend. func (s *watchStream) stop() { err := s.close() if s.err != nil { // don't change existing error return } if err != nil { s.err = err } s.err = io.EOF // normal shutdown } func (s *watchStream) close() error { if s.lc == nil { return nil } return s.lc.CloseSend() } // recv receives the next message from the stream. It also handles opening the stream // initially, and reopening it on non-permanent errors. // recv doesn't have to be goroutine-safe. func (s *watchStream) recv() (*pb.ListenResponse, error) { var err error for { if s.lc == nil { s.lc, err = s.open() if err != nil { // Do not retry if open fails. return nil, err } } res, err := s.lc.Recv() if err == nil || isPermanentWatchError(err) { return res, err } // Non-permanent error. Sleep and retry. s.changeMap = map[string]*DocumentSnapshot{} // clear changeMap dur := s.backoff.Pause() // If we're out of quota, wait a long time before retrying. if status.Code(err) == codes.ResourceExhausted { dur = s.backoff.Max } if err := sleep(s.ctx, dur); err != nil { return nil, err } s.lc = nil } } func (s *watchStream) open() (pb.Firestore_ListenClient, error) { dbPath := s.c.path() lc, err := s.c.c.Listen(withResourceHeader(s.ctx, dbPath)) if err == nil { err = lc.Send(&pb.ListenRequest{ Database: dbPath, TargetChange: &pb.ListenRequest_AddTarget{AddTarget: s.target}, }) } if err != nil { return nil, err } return lc, nil } func isPermanentWatchError(err error) bool { if err == io.EOF { // Retry on normal end-of-stream. return false } switch status.Code(err) { case codes.Unknown, codes.DeadlineExceeded, codes.ResourceExhausted, codes.Internal, codes.Unavailable, codes.Unauthenticated: return false default: return true } } google-cloud-go-0.49.0/firestore/watch_test.go000066400000000000000000000166331356504100700212770ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package firestore import ( "context" "sort" "testing" "time" "cloud.google.com/go/internal/btree" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" pb "google.golang.org/genproto/googleapis/firestore/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) func TestWatchRecv(t *testing.T) { ctx := context.Background() c, srv, cleanup := newMock(t) defer cleanup() db := defaultBackoff defaultBackoff = gax.Backoff{Initial: 1, Max: 1, Multiplier: 1} defer func() { defaultBackoff = db }() ws := newWatchStream(ctx, c, nil, &pb.Target{}) request := &pb.ListenRequest{ Database: "projects/projectID/databases/(default)", TargetChange: &pb.ListenRequest_AddTarget{&pb.Target{}}, } response := &pb.ListenResponse{ResponseType: &pb.ListenResponse_DocumentChange{&pb.DocumentChange{}}} // Stream should retry on non-permanent errors, returning only the responses. srv.addRPC(request, []interface{}{response, status.Error(codes.Unknown, "")}) srv.addRPC(request, []interface{}{response}) // stream will return io.EOF srv.addRPC(request, []interface{}{response, status.Error(codes.DeadlineExceeded, "")}) srv.addRPC(request, []interface{}{status.Error(codes.ResourceExhausted, "")}) srv.addRPC(request, []interface{}{status.Error(codes.Internal, "")}) srv.addRPC(request, []interface{}{status.Error(codes.Unavailable, "")}) srv.addRPC(request, []interface{}{status.Error(codes.Unauthenticated, "")}) srv.addRPC(request, []interface{}{response}) for i := 0; i < 4; i++ { res, err := ws.recv() if err != nil { t.Fatal(err) } if !proto.Equal(res, response) { t.Fatalf("got %v, want %v", res, response) } } // Stream should not retry on a permanent error. srv.addRPC(request, []interface{}{status.Error(codes.AlreadyExists, "")}) _, err := ws.recv() if got, want := status.Code(err), codes.AlreadyExists; got != want { t.Fatalf("got %s, want %s", got, want) } } func TestComputeSnapshot(t *testing.T) { c := &Client{ projectID: "projID", databaseID: "(database)", } ws := newWatchStream(context.Background(), c, nil, &pb.Target{}) tm := time.Now() i := 0 doc := func(path, value string) *DocumentSnapshot { i++ return &DocumentSnapshot{ Ref: c.Doc(path), proto: &pb.Document{Fields: map[string]*pb.Value{"foo": strval(value)}}, UpdateTime: tm.Add(time.Duration(i) * time.Second), // need unique time for updates } } val := func(d *DocumentSnapshot) string { return d.proto.Fields["foo"].GetStringValue() } less := func(a, b *DocumentSnapshot) bool { return val(a) < val(b) } type dmap map[string]*DocumentSnapshot ds1 := doc("C/d1", "a") ds2 := doc("C/d2", "b") ds2c := doc("C/d2", "c") docTree := btree.New(4, func(a, b interface{}) bool { return less(a.(*DocumentSnapshot), b.(*DocumentSnapshot)) }) var gotChanges []DocumentChange docMap := dmap{} // The following test cases are not independent; each builds on the output of the previous. for _, test := range []struct { desc string changeMap dmap wantDocs []*DocumentSnapshot wantChanges []DocumentChange }{ { "no changes", nil, nil, nil, }, { "add a doc", dmap{ds1.Ref.Path: ds1}, []*DocumentSnapshot{ds1}, []DocumentChange{{Kind: DocumentAdded, Doc: ds1, OldIndex: -1, NewIndex: 0}}, }, { "add, remove", dmap{ds1.Ref.Path: nil, ds2.Ref.Path: ds2}, []*DocumentSnapshot{ds2}, []DocumentChange{ {Kind: DocumentRemoved, Doc: ds1, OldIndex: 0, NewIndex: -1}, {Kind: DocumentAdded, Doc: ds2, OldIndex: -1, NewIndex: 0}, }, }, { "add back, modify", dmap{ds1.Ref.Path: ds1, ds2c.Ref.Path: ds2c}, []*DocumentSnapshot{ds1, ds2c}, []DocumentChange{ {Kind: DocumentAdded, Doc: ds1, OldIndex: -1, NewIndex: 0}, {Kind: DocumentModified, Doc: ds2c, OldIndex: 1, NewIndex: 1}, }, }, } { docTree, gotChanges = ws.computeSnapshot(docTree, docMap, test.changeMap, time.Time{}) gotDocs := treeDocs(docTree) if diff := testDiff(gotDocs, test.wantDocs); diff != "" { t.Fatalf("%s: %s", test.desc, diff) } mgot := mapDocs(docMap, less) if diff := testDiff(gotDocs, mgot); diff != "" { t.Fatalf("%s: docTree and docMap disagree: %s", test.desc, diff) } if diff := testDiff(gotChanges, test.wantChanges); diff != "" { t.Fatalf("%s: %s", test.desc, diff) } } // Verify that if there are no changes, the returned docTree is identical to the first arg. // docTree already has ds2c. got, _ := ws.computeSnapshot(docTree, docMap, dmap{ds2c.Ref.Path: ds2c}, time.Time{}) if got != docTree { t.Error("returned docTree != arg docTree") } } func treeDocs(bt *btree.BTree) []*DocumentSnapshot { var ds []*DocumentSnapshot it := bt.BeforeIndex(0) for it.Next() { ds = append(ds, it.Key.(*DocumentSnapshot)) } return ds } func mapDocs(m map[string]*DocumentSnapshot, less func(a, b *DocumentSnapshot) bool) []*DocumentSnapshot { var ds []*DocumentSnapshot for _, d := range m { ds = append(ds, d) } sort.Sort(byLess{ds, less}) return ds } func TestWatchCancel(t *testing.T) { // Canceling the context of a watch should result in a codes.Canceled error from the next // call to the iterator's Next method. ctx := context.Background() c, srv, cleanup := newMock(t) defer cleanup() q := Query{c: c, collectionID: "x"} // Cancel before open. ctx2, cancel := context.WithCancel(ctx) ws, err := newWatchStreamForQuery(ctx2, q) if err != nil { t.Fatal(err) } cancel() _, _, _, err = ws.nextSnapshot() codeEq(t, "cancel before open", codes.Canceled, err) request := &pb.ListenRequest{ Database: "projects/projectID/databases/(default)", TargetChange: &pb.ListenRequest_AddTarget{ws.target}, } current := &pb.ListenResponse{ResponseType: &pb.ListenResponse_TargetChange{&pb.TargetChange{ TargetChangeType: pb.TargetChange_CURRENT, }}} noChange := &pb.ListenResponse{ResponseType: &pb.ListenResponse_TargetChange{&pb.TargetChange{ TargetChangeType: pb.TargetChange_NO_CHANGE, ReadTime: aTimestamp, }}} // Cancel from gax.Sleep. We should still see a gRPC error with codes.Canceled, not a // context.Canceled error. ctx2, cancel = context.WithCancel(ctx) ws, err = newWatchStreamForQuery(ctx2, q) if err != nil { t.Fatal(err) } srv.addRPC(request, []interface{}{current, noChange}) _, _, _, _ = ws.nextSnapshot() cancel() // Because of how the mock works, the following results in an EOF on the stream, which // is a non-permanent error that causes a retry. That retry ends up in gax.Sleep, which // finds that the context is done and returns ctx.Err(), which is context.Canceled. // Verify that we transform that context.Canceled into a gRPC Status with code Canceled. _, _, _, err = ws.nextSnapshot() codeEq(t, "cancel from gax.Sleep", codes.Canceled, err) // TODO(jba): Test that we get codes.Canceled when canceling an RPC. // We had a test for this in a21236af, but it was flaky for unclear reasons. } google-cloud-go-0.49.0/firestore/writebatch.go000066400000000000000000000053351356504100700212630ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package firestore import ( "context" "errors" "cloud.google.com/go/internal/trace" pb "google.golang.org/genproto/googleapis/firestore/v1" ) // A WriteBatch holds multiple database updates. Build a batch with the Create, Set, // Update and Delete methods, then run it with the Commit method. Errors in Create, // Set, Update or Delete are recorded instead of being returned immediately. The // first such error is returned by Commit. type WriteBatch struct { c *Client err error writes []*pb.Write } func (b *WriteBatch) add(ws []*pb.Write, err error) *WriteBatch { if b.err != nil { return b } if err != nil { b.err = err return b } b.writes = append(b.writes, ws...) return b } // Create adds a Create operation to the batch. // See DocumentRef.Create for details. func (b *WriteBatch) Create(dr *DocumentRef, data interface{}) *WriteBatch { return b.add(dr.newCreateWrites(data)) } // Set adds a Set operation to the batch. // See DocumentRef.Set for details. func (b *WriteBatch) Set(dr *DocumentRef, data interface{}, opts ...SetOption) *WriteBatch { return b.add(dr.newSetWrites(data, opts)) } // Delete adds a Delete operation to the batch. // See DocumentRef.Delete for details. func (b *WriteBatch) Delete(dr *DocumentRef, opts ...Precondition) *WriteBatch { return b.add(dr.newDeleteWrites(opts)) } // Update adds an Update operation to the batch. // See DocumentRef.Update for details. func (b *WriteBatch) Update(dr *DocumentRef, data []Update, opts ...Precondition) *WriteBatch { return b.add(dr.newUpdatePathWrites(data, opts)) } // Commit applies all the writes in the batch to the database atomically. Commit // returns an error if there are no writes in the batch, if any errors occurred in // constructing the writes, or if the Commmit operation fails. func (b *WriteBatch) Commit(ctx context.Context) (_ []*WriteResult, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/firestore.WriteBatch.Commit") defer func() { trace.EndSpan(ctx, err) }() if b.err != nil { return nil, b.err } if len(b.writes) == 0 { return nil, errors.New("firestore: cannot commit empty WriteBatch") } return b.c.commit(ctx, b.writes) } google-cloud-go-0.49.0/firestore/writebatch_test.go000066400000000000000000000054641356504100700223250ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package firestore import ( "context" "testing" pb "google.golang.org/genproto/googleapis/firestore/v1" ) func TestWriteBatch(t *testing.T) { c, srv, cleanup := newMock(t) defer cleanup() docPrefix := c.Collection("C").Path + "/" srv.addRPC( &pb.CommitRequest{ Database: c.path(), Writes: []*pb.Write{ { // Create Operation: &pb.Write_Update{ Update: &pb.Document{ Name: docPrefix + "a", Fields: testFields, }, }, CurrentDocument: &pb.Precondition{ ConditionType: &pb.Precondition_Exists{false}, }, }, { // Set Operation: &pb.Write_Update{ Update: &pb.Document{ Name: docPrefix + "b", Fields: testFields, }, }, }, { // Delete Operation: &pb.Write_Delete{ Delete: docPrefix + "c", }, }, { // Update Operation: &pb.Write_Update{ Update: &pb.Document{ Name: docPrefix + "f", Fields: map[string]*pb.Value{"*": intval(3)}, }, }, UpdateMask: &pb.DocumentMask{FieldPaths: []string{"`*`"}}, CurrentDocument: &pb.Precondition{ ConditionType: &pb.Precondition_Exists{true}, }, }, }, }, &pb.CommitResponse{ WriteResults: []*pb.WriteResult{ {UpdateTime: aTimestamp}, {UpdateTime: aTimestamp2}, {UpdateTime: aTimestamp3}, }, }, ) gotWRs, err := c.Batch(). Create(c.Doc("C/a"), testData). Set(c.Doc("C/b"), testData). Delete(c.Doc("C/c")). Update(c.Doc("C/f"), []Update{{FieldPath: []string{"*"}, Value: 3}}). Commit(context.Background()) if err != nil { t.Fatal(err) } wantWRs := []*WriteResult{{aTime}, {aTime2}, {aTime3}} if !testEqual(gotWRs, wantWRs) { t.Errorf("got %+v\nwant %+v", gotWRs, wantWRs) } } func TestWriteBatchErrors(t *testing.T) { ctx := context.Background() c, _, cleanup := newMock(t) defer cleanup() for _, test := range []struct { desc string batch *WriteBatch }{ { "empty batch", c.Batch(), }, { "bad doc reference", c.Batch().Create(c.Doc("a"), testData), }, { "bad data", c.Batch().Create(c.Doc("a/b"), 3), }, } { t.Run(test.desc, func(t *testing.T) { if _, err := test.batch.Commit(ctx); err == nil { t.Fatal("got nil, want error") } }) } } google-cloud-go-0.49.0/functions/000077500000000000000000000000001356504100700166005ustar00rootroot00000000000000google-cloud-go-0.49.0/functions/metadata/000077500000000000000000000000001356504100700203605ustar00rootroot00000000000000google-cloud-go-0.49.0/functions/metadata/.repo-metadata.json000066400000000000000000000006521356504100700240570ustar00rootroot00000000000000{ "name": "metadata", "name_pretty": "Cloud Functions", "product_documentation": "http://cloud.google.com/functions", "client_documentation": "https://godoc.org/cloud.google.com/go/functions/metadata", "release_level": "alpha", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go/functions/metadata", "api_id": "functions:metadata", "requires_billing": true } google-cloud-go-0.49.0/functions/metadata/doc.go000066400000000000000000000015431356504100700214570ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package metadata provides methods for creating and accessing context.Context // objects with Google Cloud Functions metadata. // // NOTE: This package is in alpha. It is not stable, and is likely to change. package metadata // import "cloud.google.com/go/functions/metadata" google-cloud-go-0.49.0/functions/metadata/metadata.go000066400000000000000000000106741356504100700224770ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package metadata import ( "context" "encoding/json" "errors" "fmt" "time" ) // Metadata holds Google Cloud Functions metadata. type Metadata struct { // EventID is a unique ID for the event. For example: "70172329041928". EventID string `json:"eventId"` // Timestamp is the date/time this event was created. Timestamp time.Time `json:"timestamp"` // EventType is the type of the event. For example: "google.pubsub.topic.publish". EventType string `json:"eventType"` // Resource is the resource that triggered the event. Resource *Resource `json:"resource"` } // Resource holds Google Cloud Functions resource metadata. // Resource values are dependent on the event type they're from. type Resource struct { // Service is the service that triggered the event. Service string `json:"service"` // Name is the name associated with the event. Name string `json:"name"` // Type is the type of event. Type string `json:"type"` // Path is the path to the resource type (deprecated). // This is the case for some deprecated GCS // notifications, which populate the resource field as a string containing the topic // rather than as the expected dictionary. // See the Attributes section of https://cloud.google.com/storage/docs/pubsub-notifications // for more details. RawPath string `json:"-"` } // UnmarshalJSON specializes the Resource unmarshalling to handle the case where the // value is a string instead of a map. See the comment above on RawPath for why this // needs to be handled. func (r *Resource) UnmarshalJSON(data []byte) error { // Try to unmarshal the resource into a string. var path string if err := json.Unmarshal(data, &path); err == nil { r.RawPath = path return nil } // Otherwise, accept whatever the result of the normal unmarshal would be. // Need to define a new type, otherwise it infinitely recurses and panics. type resource Resource var res resource if err := json.Unmarshal(data, &res); err != nil { return err } r.Service = res.Service r.Name = res.Name r.Type = res.Type return nil } type contextKey string // GCFContextKey satisfies an interface to be able to use contextKey to read // metadata from a Cloud Functions context.Context. // // Be careful making changes to this function. See FromContext. func (k contextKey) GCFContextKey() string { return string(k) } const metadataContextKey = contextKey("metadata") // FromContext extracts the Metadata from the Context, if present. func FromContext(ctx context.Context) (*Metadata, error) { if ctx == nil { return nil, errors.New("nil ctx") } // The original JSON is inserted by the Cloud Functions worker. So, the // format must not change, or the message may fail to unmarshal. We use // JSON as a common format between the worker and this package to ensure // this package can be updated independently from the worker. The contextKey // type and the metadataContextKey value use an interface to avoid using // a built-in type as a context key (which is easy to have collisions with). // If we need another value to be stored in the context, we can use a new // key or interface and avoid needing to change this one. Similarly, if we // need to change the format of the message, we should add an additional key // to keep backward compatibility. b, ok := ctx.Value(metadataContextKey).(json.RawMessage) if !ok { return nil, errors.New("unable to find metadata") } meta := &Metadata{} if err := json.Unmarshal(b, meta); err != nil { return nil, fmt.Errorf("json.Unmarshal: %v", err) } return meta, nil } // NewContext returns a new Context carrying m. If m is nil, NewContext returns // ctx. NewContext is only used for writing tests which rely on Metadata. func NewContext(ctx context.Context, m *Metadata) context.Context { if m == nil { return ctx } b, err := json.Marshal(m) if err != nil { return ctx } return context.WithValue(ctx, metadataContextKey, json.RawMessage(b)) } google-cloud-go-0.49.0/functions/metadata/metadata_test.go000066400000000000000000000063351356504100700235350ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package metadata import ( "context" "encoding/json" "reflect" "testing" "time" "github.com/google/go-cmp/cmp" ) func TestMetadata(t *testing.T) { md := &Metadata{EventID: "test event ID"} ctx := NewContext(context.Background(), md) got, err := FromContext(ctx) if err != nil { t.Fatalf("FromContext error: %v", err) } if !reflect.DeepEqual(got, md) { t.Fatalf("FromContext\nGot %v\nWant %v", got, md) } } func TestMetadataError(t *testing.T) { if _, err := FromContext(nil); err == nil { t.Errorf("FromContext got no error, wanted an error") } if _, err := FromContext(context.Background()); err == nil { t.Errorf("FromContext got no error, wanted an error") } if _, err := FromContext(NewContext(context.Background(), nil)); err == nil { t.Errorf("FromContext got no error, wanted an error") } } func TestUnmarshalJSON(t *testing.T) { ts, err := time.Parse("2006-01-02T15:04:05Z07:00", "2019-11-04T23:01:10.112Z") if err != nil { t.Fatalf("Error parsing time: %v.", err) } var tests = []struct { name string data []byte want Metadata }{ { name: "MetadataWithResource", data: []byte(`{ "eventId": "1234567", "timestamp": "2019-11-04T23:01:10.112Z", "eventType": "google.pubsub.topic.publish", "resource": { "service": "pubsub.googleapis.com", "name": "mytopic", "type": "type.googleapis.com/google.pubsub.v1.PubsubMessage" }, "data": { "@type": "type.googleapis.com/google.pubsub.v1.PubsubMessage", "attributes": null, "data": "test data" } }`), want: Metadata{ EventID: "1234567", Timestamp: ts, EventType: "google.pubsub.topic.publish", Resource: &Resource{ Service: "pubsub.googleapis.com", Name: "mytopic", Type: "type.googleapis.com/google.pubsub.v1.PubsubMessage", }, }, }, { name: "MetadataWithString", data: []byte(`{ "eventId": "1234567", "timestamp": "2019-11-04T23:01:10.112Z", "eventType": "google.pubsub.topic.publish", "resource": "projects/myproject/mytopic", "data": { "@type": "type.googleapis.com/google.pubsub.v1.PubsubMessage", "attributes": null, "data": "test data" } }`), want: Metadata{ EventID: "1234567", Timestamp: ts, EventType: "google.pubsub.topic.publish", Resource: &Resource{ RawPath: "projects/myproject/mytopic", }, }, }, } for _, tc := range tests { var m Metadata if err := json.Unmarshal(tc.data, &m); err != nil { t.Errorf("UnmarshalJSON(%s) error: %v", tc.name, err) } if !cmp.Equal(m, tc.want) { t.Errorf("UnmarshalJSON(%s) error: got %v, want %v", tc.name, m, tc.want) } } } google-cloud-go-0.49.0/gapics.txt000066400000000000000000000045351356504100700166060ustar00rootroot00000000000000google/api/expr/artman_cel.yaml google/cloud/asset/artman_cloudasset_v1beta1.yaml google/cloud/asset/artman_cloudasset_v1p2beta1.yaml google/iam/credentials/artman_iamcredentials_v1.yaml google/cloud/automl/artman_automl_v1.yaml google/cloud/automl/artman_automl_v1beta1.yaml google/cloud/bigquery/datatransfer/artman_bigquerydatatransfer.yaml google/cloud/bigquery/storage/artman_bigquerystorage_v1beta1.yaml google/cloud/dataproc/artman_dataproc_v1.yaml google/cloud/dataproc/artman_dataproc_v1beta2.yaml google/cloud/dialogflow/v2/artman_dialogflow_v2.yaml google/cloud/iot/artman_cloudiot.yaml google/cloud/irm/artman_irm_v1alpha2.yaml google/cloud/kms/artman_cloudkms.yaml google/cloud/language/artman_language_v1beta2.yaml google/cloud/oslogin/artman_oslogin_v1.yaml google/cloud/oslogin/artman_oslogin_v1beta.yaml google/cloud/recaptchaenterprise/artman_recaptchaenterprise_v1beta1.yaml google/cloud/recommender/artman_recommender_v1beta1.yaml google/cloud/redis/artman_redis_v1beta1.yaml google/cloud/redis/artman_redis_v1.yaml google/cloud/securitycenter/artman_securitycenter_v1beta1.yaml google/cloud/securitycenter/artman_securitycenter_v1.yaml google/cloud/talent/artman_talent_v4beta1.yaml google/cloud/tasks/artman_cloudtasks_v2beta2.yaml google/cloud/tasks/artman_cloudtasks_v2beta3.yaml google/cloud/tasks/artman_cloudtasks_v2.yaml google/cloud/videointelligence/artman_videointelligence_v1.yaml google/cloud/videointelligence/artman_videointelligence_v1beta2.yaml google/cloud/vision/artman_vision_v1.yaml google/cloud/vision/artman_vision_v1p1beta1.yaml google/cloud/webrisk/artman_webrisk_v1beta1.yaml google/devtools/artman_clouddebugger.yaml google/devtools/cloudbuild/artman_cloudbuild.yaml google/devtools/clouderrorreporting/artman_errorreporting.yaml google/devtools/cloudtrace/artman_cloudtrace_v1.yaml google/devtools/cloudtrace/artman_cloudtrace_v2.yaml google/devtools/containeranalysis/artman_containeranalysis_v1beta1.yaml google/firestore/artman_firestore.yaml google/firestore/admin/artman_firestore_v1.yaml google/logging/artman_logging.yaml google/longrunning/artman_longrunning.yaml google/monitoring/artman_monitoring.yaml google/privacy/dlp/artman_dlp_v2.yaml google/pubsub/artman_pubsub.yaml google/spanner/admin/database/artman_spanner_admin_database.yaml google/spanner/admin/instance/artman_spanner_admin_instance.yaml google/spanner/artman_spanner.yaml google-cloud-go-0.49.0/go.mod000066400000000000000000000017461356504100700157060ustar00rootroot00000000000000module cloud.google.com/go go 1.11 require ( cloud.google.com/go/bigquery v1.0.1 cloud.google.com/go/datastore v1.0.0 cloud.google.com/go/pubsub v1.0.1 cloud.google.com/go/storage v1.0.0 github.com/golang/mock v1.3.1 github.com/golang/protobuf v1.3.2 github.com/google/go-cmp v0.3.0 github.com/google/martian v2.1.0+incompatible github.com/google/pprof v0.0.0-20190515194954-54271f7e092f github.com/googleapis/gax-go/v2 v2.0.5 github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024 go.opencensus.io v0.22.0 golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136 golang.org/x/lint v0.0.0-20190930215403-16217165b5de golang.org/x/net v0.0.0-20190620200207-3b0461eec859 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 golang.org/x/text v0.3.2 golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2 google.golang.org/api v0.14.0 google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9 google.golang.org/grpc v1.21.1 honnef.co/go/tools v0.0.1-2019.2.3 ) google-cloud-go-0.49.0/go.sum000066400000000000000000000501511356504100700157250ustar00rootroot00000000000000cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go/bigquery v1.0.1 h1:hL+ycaJpVE9M7nLoiXb/Pn10ENE2u+oddxbD8uu0ZVU= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/datastore v1.0.0 h1:Kt+gOPPp2LEPWp8CSfxhsM8ik9CcyE/gYu+0r+RnZvM= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/pubsub v1.0.1 h1:W9tAK3E57P75u0XLLR82LZyw8VpAnhmyTOxW9qzmyj8= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/storage v1.0.0 h1:VV2nUM3wwLLGh9lSABFgZMjInyUbJeaRSE64WuAIQ+4= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCydnIczKteheJEzHRToSGK3Bnlw= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57 h1:eqyIo2HjKhKe/mJzTG8n4VqvLXIOEG+SLdDqX7xGtkY= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f h1:Jnx61latede7zDD3DiiP4gmNz33uK0U5HDUaF0a/HVQ= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/googleapis/gax-go/v2 v2.0.4 h1:hU4mGcQI4DaAYW+IbTun+2qEZVFxK0ySjQLTbS0VQKc= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024 h1:rBMNdlhTLzJjJSDIjNEXX1Pz3Hmwmz91v+zycvx9PJc= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= go.opencensus.io v0.21.0 h1:mU6zScU4U1YAFPHEHYk+3JC4SY7JxgkqS10ZOSyksNg= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4 h1:c2HOrn5iMezYjSlGPncknSEr/8x5LELb/ilJbXi9DEA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522 h1:OeRHuibLsmZkFj773W4LcfAGsSxJgfPONhr8cmO+eLA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979 h1:Agxu5KLo8o7Bb634SVDnhIfpTvxmzUwhbYAzBvXt6h4= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136 h1:A1gGSx58LAGVHUUsOf7IiR0u8Xb6W51gRwfDBhkdcaw= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f h1:hX65Cu3JDlGH3uEdK7I99Ii+9kjD6mvnnpfLdEAH0x4= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422 h1:QzoH/1pFpZguR8NrRHLcO6jKqfv2zpuSqZLgdm7ZmjI= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac h1:8R1esu+8QioDxo4E4mX6bFztO+dMTM49DNAaWfO5OeY= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c h1:uOCk1iQW6Vc18bnC13MfzScl+wdKBmM9Y9kU7Z83/lw= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421 h1:Wo7BWFiOk0QRFMLYMqJGFMd9CgUAcGx7V+qEg/h5IBI= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 h1:bjcUS9ztw9kFmmIxJInhon/0Is3p+EHBKNgquIzo1OI= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b h1:ag/x1USPSsqHud38I9BAC88qdNLDHHtQ4mlgQIZPPNA= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0 h1:HyfiK1WMnHj5FXFXatD+Qs1A/xC2Run6RzeW1SyHxpc= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2 h1:z99zHgr7hKfrUcX/KsoJk5FJfjTceCKIp96+biqP4To= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c h1:fqgJT0MGcGpPgpWU7VRdRjuArfcOvC4AoJmILihzhDg= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138 h1:H3uGjxCR/6Ds0Mjgyp7LMK81+LvmbvWWEnJhzk1Pi9E= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c h1:97SnQk1GYRXJgvwZ8fadnxDOWfKvkNQHH3CtZntPSrM= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0 h1:Dh6fw+p6FyRl5x/FvNswO1ji0lIGzm3KP8Y9VkS9PTE= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff h1:On1qIo75ByTwFJ4/W2bIqHcwJ9XAqtSWUs8GwRrIhtc= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2 h1:EtTFh6h4SAKemS+CURDMTDIANuduG5zKEXShyy18bGA= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0 h1:VGGbLNyPF7dvYHhcUGYBBGCRDDK0RRJAI6KCvo0CL+E= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0 h1:jbyannxz0XFD3zdjgrSUsaJbgpH4eTrkdhRChkHPfO8= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.14.0 h1:uMf5uLi4eQMRrMKhCplNik4U4H8Z6C1br3zOtAa/aDE= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19 h1:Lj2SnHtxkRGJDqnGaSjo+CCdIieEnwVazbOXILwQemk= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873 h1:nfPFGzJkUDX6uBmpN/pSw7MbOAWegH5QDQuoXFHedLg= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64 h1:iKtrH9Y8mcbADOP0YFaEMth7OfuHY9xHOwNj4znpM1A= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51 h1:Ex1mq5jaJof+kRnYi3SlYJ8KKa9Ao3NHyIT5XJ1gF6U= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9 h1:6XzpBoANz1NqMNfDXzc2QmHmbb1vyMsvRfoP5rM+K1I= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/grpc v1.19.0 h1:cfg4PD8YEdSFnm7qLV4++93WcmhH2nIUhMjhdCvl3j8= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1 h1:Hz2g2wirWK7H0qIIhGIqRGTuMwTE8HEKFnDZZ7lm9NU= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1 h1:j6XxA85m/6txkUCHvzlV5f+HBNl/1r5cZ2A/3IEFOO8= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a h1:/8zB6iBfHCl1qAnEAWwGPNrUvapuy6CPla1VM0k8hQw= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a h1:LJwr7TCTghdatWv40WobzlKXc9c4s8oGa7QKJUtHhWA= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= google-cloud-go-0.49.0/grafeas/000077500000000000000000000000001356504100700162005ustar00rootroot00000000000000google-cloud-go-0.49.0/grafeas/apiv1/000077500000000000000000000000001356504100700172205ustar00rootroot00000000000000google-cloud-go-0.49.0/grafeas/apiv1/.repo-metadata.json000066400000000000000000000006571356504100700227240ustar00rootroot00000000000000{ "name": "grafeas", "name_pretty": "Container Analysis API", "product_documentation": "https://cloud.google.com/container-registry/docs/container-analysis", "client_documentation": "https://godoc.org/cloud.google.com/go/grafeas/apiv1", "release_level": "alpha", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "grafeas", "requires_billing": true } google-cloud-go-0.49.0/grafeas/apiv1/doc.go000066400000000000000000000051421356504100700203160ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package grafeas is an auto-generated package for the // Container Analysis API. // // NOTE: This package is in alpha. It is not stable, and is likely to change. // // An implementation of the Grafeas API, which stores, and enables querying // and // retrieval of critical metadata about all of your software artifacts. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package grafeas // import "cloud.google.com/go/grafeas/apiv1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20190910" google-cloud-go-0.49.0/grafeas/apiv1/grafeas_client.go000066400000000000000000000512371356504100700225250ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package grafeas import ( "context" "fmt" "math" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" grafeaspb "google.golang.org/genproto/googleapis/grafeas/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // CallOptions contains the retry settings for each method of Client. type CallOptions struct { GetOccurrence []gax.CallOption ListOccurrences []gax.CallOption DeleteOccurrence []gax.CallOption CreateOccurrence []gax.CallOption BatchCreateOccurrences []gax.CallOption UpdateOccurrence []gax.CallOption GetOccurrenceNote []gax.CallOption GetNote []gax.CallOption ListNotes []gax.CallOption DeleteNote []gax.CallOption CreateNote []gax.CallOption BatchCreateNotes []gax.CallOption UpdateNote []gax.CallOption ListNoteOccurrences []gax.CallOption } func defaultCallOptions() *CallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &CallOptions{ GetOccurrence: retry[[2]string{"default", "idempotent"}], ListOccurrences: retry[[2]string{"default", "idempotent"}], DeleteOccurrence: retry[[2]string{"default", "idempotent"}], CreateOccurrence: retry[[2]string{"default", "non_idempotent"}], BatchCreateOccurrences: retry[[2]string{"default", "non_idempotent"}], UpdateOccurrence: retry[[2]string{"default", "non_idempotent"}], GetOccurrenceNote: retry[[2]string{"default", "idempotent"}], GetNote: retry[[2]string{"default", "idempotent"}], ListNotes: retry[[2]string{"default", "idempotent"}], DeleteNote: retry[[2]string{"default", "idempotent"}], CreateNote: retry[[2]string{"default", "non_idempotent"}], BatchCreateNotes: retry[[2]string{"default", "non_idempotent"}], UpdateNote: retry[[2]string{"default", "non_idempotent"}], ListNoteOccurrences: retry[[2]string{"default", "idempotent"}], } } // Client is a client for interacting with Container Analysis API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. client grafeaspb.GrafeasClient // The call options for this service. CallOptions *CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewClient creates a new grafeas client. // // Grafeas (at grafeas.io) API. // // Retrieves analysis results of Cloud components such as Docker container // images. // // Analysis results are stored as a series of occurrences. An Occurrence // contains information about a specific analysis instance on a resource. An // occurrence refers to a Note. A note contains details describing the // analysis and is generally stored in a separate project, called a Provider. // Multiple occurrences can refer to the same note. // // For example, an SSL vulnerability could affect multiple images. In this case, // there would be one note for the vulnerability and an occurrence for each // image with the vulnerability referring to that note. func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { conn, err := transport.DialGRPC(ctx, opts...) if err != nil { return nil, err } c := &Client{ conn: conn, CallOptions: defaultCallOptions(), client: grafeaspb.NewGrafeasClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *Client) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *Client) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // GetOccurrence gets the specified occurrence. func (c *Client) GetOccurrence(ctx context.Context, req *grafeaspb.GetOccurrenceRequest, opts ...gax.CallOption) (*grafeaspb.Occurrence, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", req.GetName())) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetOccurrence[0:len(c.CallOptions.GetOccurrence):len(c.CallOptions.GetOccurrence)], opts...) var resp *grafeaspb.Occurrence err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetOccurrence(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListOccurrences lists occurrences for the specified project. func (c *Client) ListOccurrences(ctx context.Context, req *grafeaspb.ListOccurrencesRequest, opts ...gax.CallOption) *OccurrenceIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", req.GetParent())) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListOccurrences[0:len(c.CallOptions.ListOccurrences):len(c.CallOptions.ListOccurrences)], opts...) it := &OccurrenceIterator{} req = proto.Clone(req).(*grafeaspb.ListOccurrencesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*grafeaspb.Occurrence, string, error) { var resp *grafeaspb.ListOccurrencesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListOccurrences(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Occurrences, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // DeleteOccurrence deletes the specified occurrence. For example, use this method to delete an // occurrence when the occurrence is no longer applicable for the given // resource. func (c *Client) DeleteOccurrence(ctx context.Context, req *grafeaspb.DeleteOccurrenceRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", req.GetName())) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteOccurrence[0:len(c.CallOptions.DeleteOccurrence):len(c.CallOptions.DeleteOccurrence)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.client.DeleteOccurrence(ctx, req, settings.GRPC...) return err }, opts...) return err } // CreateOccurrence creates a new occurrence. func (c *Client) CreateOccurrence(ctx context.Context, req *grafeaspb.CreateOccurrenceRequest, opts ...gax.CallOption) (*grafeaspb.Occurrence, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", req.GetParent())) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateOccurrence[0:len(c.CallOptions.CreateOccurrence):len(c.CallOptions.CreateOccurrence)], opts...) var resp *grafeaspb.Occurrence err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CreateOccurrence(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // BatchCreateOccurrences creates new occurrences in batch. func (c *Client) BatchCreateOccurrences(ctx context.Context, req *grafeaspb.BatchCreateOccurrencesRequest, opts ...gax.CallOption) (*grafeaspb.BatchCreateOccurrencesResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", req.GetParent())) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.BatchCreateOccurrences[0:len(c.CallOptions.BatchCreateOccurrences):len(c.CallOptions.BatchCreateOccurrences)], opts...) var resp *grafeaspb.BatchCreateOccurrencesResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.BatchCreateOccurrences(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateOccurrence updates the specified occurrence. func (c *Client) UpdateOccurrence(ctx context.Context, req *grafeaspb.UpdateOccurrenceRequest, opts ...gax.CallOption) (*grafeaspb.Occurrence, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", req.GetName())) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateOccurrence[0:len(c.CallOptions.UpdateOccurrence):len(c.CallOptions.UpdateOccurrence)], opts...) var resp *grafeaspb.Occurrence err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.UpdateOccurrence(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetOccurrenceNote gets the note attached to the specified occurrence. Consumer projects can // use this method to get a note that belongs to a provider project. func (c *Client) GetOccurrenceNote(ctx context.Context, req *grafeaspb.GetOccurrenceNoteRequest, opts ...gax.CallOption) (*grafeaspb.Note, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", req.GetName())) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetOccurrenceNote[0:len(c.CallOptions.GetOccurrenceNote):len(c.CallOptions.GetOccurrenceNote)], opts...) var resp *grafeaspb.Note err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetOccurrenceNote(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetNote gets the specified note. func (c *Client) GetNote(ctx context.Context, req *grafeaspb.GetNoteRequest, opts ...gax.CallOption) (*grafeaspb.Note, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", req.GetName())) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetNote[0:len(c.CallOptions.GetNote):len(c.CallOptions.GetNote)], opts...) var resp *grafeaspb.Note err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetNote(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListNotes lists notes for the specified project. func (c *Client) ListNotes(ctx context.Context, req *grafeaspb.ListNotesRequest, opts ...gax.CallOption) *NoteIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", req.GetParent())) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListNotes[0:len(c.CallOptions.ListNotes):len(c.CallOptions.ListNotes)], opts...) it := &NoteIterator{} req = proto.Clone(req).(*grafeaspb.ListNotesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*grafeaspb.Note, string, error) { var resp *grafeaspb.ListNotesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListNotes(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Notes, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // DeleteNote deletes the specified note. func (c *Client) DeleteNote(ctx context.Context, req *grafeaspb.DeleteNoteRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", req.GetName())) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteNote[0:len(c.CallOptions.DeleteNote):len(c.CallOptions.DeleteNote)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.client.DeleteNote(ctx, req, settings.GRPC...) return err }, opts...) return err } // CreateNote creates a new note. func (c *Client) CreateNote(ctx context.Context, req *grafeaspb.CreateNoteRequest, opts ...gax.CallOption) (*grafeaspb.Note, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", req.GetParent())) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateNote[0:len(c.CallOptions.CreateNote):len(c.CallOptions.CreateNote)], opts...) var resp *grafeaspb.Note err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CreateNote(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // BatchCreateNotes creates new notes in batch. func (c *Client) BatchCreateNotes(ctx context.Context, req *grafeaspb.BatchCreateNotesRequest, opts ...gax.CallOption) (*grafeaspb.BatchCreateNotesResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", req.GetParent())) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.BatchCreateNotes[0:len(c.CallOptions.BatchCreateNotes):len(c.CallOptions.BatchCreateNotes)], opts...) var resp *grafeaspb.BatchCreateNotesResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.BatchCreateNotes(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateNote updates the specified note. func (c *Client) UpdateNote(ctx context.Context, req *grafeaspb.UpdateNoteRequest, opts ...gax.CallOption) (*grafeaspb.Note, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", req.GetName())) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateNote[0:len(c.CallOptions.UpdateNote):len(c.CallOptions.UpdateNote)], opts...) var resp *grafeaspb.Note err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.UpdateNote(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListNoteOccurrences lists occurrences referencing the specified note. Provider projects can use // this method to get all occurrences across consumer projects referencing the // specified note. func (c *Client) ListNoteOccurrences(ctx context.Context, req *grafeaspb.ListNoteOccurrencesRequest, opts ...gax.CallOption) *OccurrenceIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", req.GetName())) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListNoteOccurrences[0:len(c.CallOptions.ListNoteOccurrences):len(c.CallOptions.ListNoteOccurrences)], opts...) it := &OccurrenceIterator{} req = proto.Clone(req).(*grafeaspb.ListNoteOccurrencesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*grafeaspb.Occurrence, string, error) { var resp *grafeaspb.ListNoteOccurrencesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListNoteOccurrences(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Occurrences, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // NoteIterator manages a stream of *grafeaspb.Note. type NoteIterator struct { items []*grafeaspb.Note pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*grafeaspb.Note, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *NoteIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *NoteIterator) Next() (*grafeaspb.Note, error) { var item *grafeaspb.Note if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *NoteIterator) bufLen() int { return len(it.items) } func (it *NoteIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // OccurrenceIterator manages a stream of *grafeaspb.Occurrence. type OccurrenceIterator struct { items []*grafeaspb.Occurrence pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*grafeaspb.Occurrence, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *OccurrenceIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *OccurrenceIterator) Next() (*grafeaspb.Occurrence, error) { var item *grafeaspb.Occurrence if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *OccurrenceIterator) bufLen() int { return len(it.items) } func (it *OccurrenceIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/grafeas/apiv1/grafeas_client_example_test.go000066400000000000000000000136311356504100700252730ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package grafeas_test import ( "context" grafeas "cloud.google.com/go/grafeas/apiv1" "google.golang.org/api/iterator" grafeaspb "google.golang.org/genproto/googleapis/grafeas/v1" ) func ExampleNewClient() { ctx := context.Background() c, err := grafeas.NewClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleClient_GetOccurrence() { ctx := context.Background() c, err := grafeas.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &grafeaspb.GetOccurrenceRequest{ // TODO: Fill request struct fields. } resp, err := c.GetOccurrence(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ListOccurrences() { ctx := context.Background() c, err := grafeas.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &grafeaspb.ListOccurrencesRequest{ // TODO: Fill request struct fields. } it := c.ListOccurrences(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_DeleteOccurrence() { ctx := context.Background() c, err := grafeas.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &grafeaspb.DeleteOccurrenceRequest{ // TODO: Fill request struct fields. } err = c.DeleteOccurrence(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleClient_CreateOccurrence() { ctx := context.Background() c, err := grafeas.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &grafeaspb.CreateOccurrenceRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateOccurrence(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_BatchCreateOccurrences() { ctx := context.Background() c, err := grafeas.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &grafeaspb.BatchCreateOccurrencesRequest{ // TODO: Fill request struct fields. } resp, err := c.BatchCreateOccurrences(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_UpdateOccurrence() { ctx := context.Background() c, err := grafeas.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &grafeaspb.UpdateOccurrenceRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateOccurrence(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_GetOccurrenceNote() { ctx := context.Background() c, err := grafeas.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &grafeaspb.GetOccurrenceNoteRequest{ // TODO: Fill request struct fields. } resp, err := c.GetOccurrenceNote(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_GetNote() { ctx := context.Background() c, err := grafeas.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &grafeaspb.GetNoteRequest{ // TODO: Fill request struct fields. } resp, err := c.GetNote(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ListNotes() { ctx := context.Background() c, err := grafeas.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &grafeaspb.ListNotesRequest{ // TODO: Fill request struct fields. } it := c.ListNotes(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_DeleteNote() { ctx := context.Background() c, err := grafeas.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &grafeaspb.DeleteNoteRequest{ // TODO: Fill request struct fields. } err = c.DeleteNote(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleClient_CreateNote() { ctx := context.Background() c, err := grafeas.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &grafeaspb.CreateNoteRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateNote(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_BatchCreateNotes() { ctx := context.Background() c, err := grafeas.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &grafeaspb.BatchCreateNotesRequest{ // TODO: Fill request struct fields. } resp, err := c.BatchCreateNotes(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_UpdateNote() { ctx := context.Background() c, err := grafeas.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &grafeaspb.UpdateNoteRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateNote(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ListNoteOccurrences() { ctx := context.Background() c, err := grafeas.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &grafeaspb.ListNoteOccurrencesRequest{ // TODO: Fill request struct fields. } it := c.ListNoteOccurrences(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } google-cloud-go-0.49.0/grafeas/apiv1/integration_test.go000066400000000000000000000027761356504100700231450ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package grafeas_test import ( "context" "fmt" "testing" grafeas "cloud.google.com/go/grafeas/apiv1" "cloud.google.com/go/internal/testutil" "google.golang.org/api/iterator" "google.golang.org/api/option" grafeaspb "google.golang.org/genproto/googleapis/grafeas/v1" ) const containerAnalysisEndpoint = "containeranalysis.googleapis.com:443" func TestIntegration(t *testing.T) { if testing.Short() { t.Skip("integration tests skipped in short mode") } ctx := context.Background() c, err := grafeas.NewClient(ctx, option.WithEndpoint(containerAnalysisEndpoint), option.WithScopes("https://www.googleapis.com/auth/cloud-platform")) if err != nil { t.Fatal(err) } defer c.Close() projID := testutil.ProjID() ni := c.ListNotes(ctx, &grafeaspb.ListNotesRequest{ Parent: fmt.Sprintf("projects/%s", projID), }) for _, err := ni.Next(); err != iterator.Done; _, err = ni.Next() { if err != nil { t.Fatal(err) } } } google-cloud-go-0.49.0/grafeas/apiv1/mock_test.go000066400000000000000000001012451356504100700215420ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package grafeas import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" "google.golang.org/api/option" grafeaspb "google.golang.org/genproto/googleapis/grafeas/v1" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockGrafeasServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. grafeaspb.GrafeasServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockGrafeasServer) GetOccurrence(ctx context.Context, req *grafeaspb.GetOccurrenceRequest) (*grafeaspb.Occurrence, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*grafeaspb.Occurrence), nil } func (s *mockGrafeasServer) ListOccurrences(ctx context.Context, req *grafeaspb.ListOccurrencesRequest) (*grafeaspb.ListOccurrencesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*grafeaspb.ListOccurrencesResponse), nil } func (s *mockGrafeasServer) DeleteOccurrence(ctx context.Context, req *grafeaspb.DeleteOccurrenceRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockGrafeasServer) CreateOccurrence(ctx context.Context, req *grafeaspb.CreateOccurrenceRequest) (*grafeaspb.Occurrence, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*grafeaspb.Occurrence), nil } func (s *mockGrafeasServer) BatchCreateOccurrences(ctx context.Context, req *grafeaspb.BatchCreateOccurrencesRequest) (*grafeaspb.BatchCreateOccurrencesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*grafeaspb.BatchCreateOccurrencesResponse), nil } func (s *mockGrafeasServer) UpdateOccurrence(ctx context.Context, req *grafeaspb.UpdateOccurrenceRequest) (*grafeaspb.Occurrence, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*grafeaspb.Occurrence), nil } func (s *mockGrafeasServer) GetOccurrenceNote(ctx context.Context, req *grafeaspb.GetOccurrenceNoteRequest) (*grafeaspb.Note, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*grafeaspb.Note), nil } func (s *mockGrafeasServer) GetNote(ctx context.Context, req *grafeaspb.GetNoteRequest) (*grafeaspb.Note, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*grafeaspb.Note), nil } func (s *mockGrafeasServer) ListNotes(ctx context.Context, req *grafeaspb.ListNotesRequest) (*grafeaspb.ListNotesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*grafeaspb.ListNotesResponse), nil } func (s *mockGrafeasServer) DeleteNote(ctx context.Context, req *grafeaspb.DeleteNoteRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockGrafeasServer) CreateNote(ctx context.Context, req *grafeaspb.CreateNoteRequest) (*grafeaspb.Note, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*grafeaspb.Note), nil } func (s *mockGrafeasServer) BatchCreateNotes(ctx context.Context, req *grafeaspb.BatchCreateNotesRequest) (*grafeaspb.BatchCreateNotesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*grafeaspb.BatchCreateNotesResponse), nil } func (s *mockGrafeasServer) UpdateNote(ctx context.Context, req *grafeaspb.UpdateNoteRequest) (*grafeaspb.Note, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*grafeaspb.Note), nil } func (s *mockGrafeasServer) ListNoteOccurrences(ctx context.Context, req *grafeaspb.ListNoteOccurrencesRequest) (*grafeaspb.ListNoteOccurrencesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*grafeaspb.ListNoteOccurrencesResponse), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockGrafeas mockGrafeasServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() grafeaspb.RegisterGrafeasServer(serv, &mockGrafeas) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestGrafeasGetOccurrence(t *testing.T) { var name2 string = "name2-1052831874" var resourceUri string = "resourceUri-384040517" var noteName string = "noteName1780787896" var remediation string = "remediation779381797" var expectedResponse = &grafeaspb.Occurrence{ Name: name2, ResourceUri: resourceUri, NoteName: noteName, Remediation: remediation, } mockGrafeas.err = nil mockGrafeas.reqs = nil mockGrafeas.resps = append(mockGrafeas.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/occurrences/%s", "[PROJECT]", "[OCCURRENCE]") var request = &grafeaspb.GetOccurrenceRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetOccurrence(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockGrafeas.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestGrafeasGetOccurrenceError(t *testing.T) { errCode := codes.PermissionDenied mockGrafeas.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/occurrences/%s", "[PROJECT]", "[OCCURRENCE]") var request = &grafeaspb.GetOccurrenceRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetOccurrence(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestGrafeasListOccurrences(t *testing.T) { var nextPageToken string = "" var occurrencesElement *grafeaspb.Occurrence = &grafeaspb.Occurrence{} var occurrences = []*grafeaspb.Occurrence{occurrencesElement} var expectedResponse = &grafeaspb.ListOccurrencesResponse{ NextPageToken: nextPageToken, Occurrences: occurrences, } mockGrafeas.err = nil mockGrafeas.reqs = nil mockGrafeas.resps = append(mockGrafeas.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &grafeaspb.ListOccurrencesRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListOccurrences(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockGrafeas.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Occurrences[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestGrafeasListOccurrencesError(t *testing.T) { errCode := codes.PermissionDenied mockGrafeas.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &grafeaspb.ListOccurrencesRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListOccurrences(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestGrafeasDeleteOccurrence(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockGrafeas.err = nil mockGrafeas.reqs = nil mockGrafeas.resps = append(mockGrafeas.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/occurrences/%s", "[PROJECT]", "[OCCURRENCE]") var request = &grafeaspb.DeleteOccurrenceRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteOccurrence(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockGrafeas.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestGrafeasDeleteOccurrenceError(t *testing.T) { errCode := codes.PermissionDenied mockGrafeas.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/occurrences/%s", "[PROJECT]", "[OCCURRENCE]") var request = &grafeaspb.DeleteOccurrenceRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteOccurrence(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestGrafeasCreateOccurrence(t *testing.T) { var name string = "name3373707" var resourceUri string = "resourceUri-384040517" var noteName string = "noteName1780787896" var remediation string = "remediation779381797" var expectedResponse = &grafeaspb.Occurrence{ Name: name, ResourceUri: resourceUri, NoteName: noteName, Remediation: remediation, } mockGrafeas.err = nil mockGrafeas.reqs = nil mockGrafeas.resps = append(mockGrafeas.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var occurrence *grafeaspb.Occurrence = &grafeaspb.Occurrence{} var request = &grafeaspb.CreateOccurrenceRequest{ Parent: formattedParent, Occurrence: occurrence, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateOccurrence(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockGrafeas.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestGrafeasCreateOccurrenceError(t *testing.T) { errCode := codes.PermissionDenied mockGrafeas.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var occurrence *grafeaspb.Occurrence = &grafeaspb.Occurrence{} var request = &grafeaspb.CreateOccurrenceRequest{ Parent: formattedParent, Occurrence: occurrence, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateOccurrence(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestGrafeasBatchCreateOccurrences(t *testing.T) { var expectedResponse *grafeaspb.BatchCreateOccurrencesResponse = &grafeaspb.BatchCreateOccurrencesResponse{} mockGrafeas.err = nil mockGrafeas.reqs = nil mockGrafeas.resps = append(mockGrafeas.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var occurrences []*grafeaspb.Occurrence = nil var request = &grafeaspb.BatchCreateOccurrencesRequest{ Parent: formattedParent, Occurrences: occurrences, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.BatchCreateOccurrences(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockGrafeas.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestGrafeasBatchCreateOccurrencesError(t *testing.T) { errCode := codes.PermissionDenied mockGrafeas.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var occurrences []*grafeaspb.Occurrence = nil var request = &grafeaspb.BatchCreateOccurrencesRequest{ Parent: formattedParent, Occurrences: occurrences, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.BatchCreateOccurrences(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestGrafeasUpdateOccurrence(t *testing.T) { var name2 string = "name2-1052831874" var resourceUri string = "resourceUri-384040517" var noteName string = "noteName1780787896" var remediation string = "remediation779381797" var expectedResponse = &grafeaspb.Occurrence{ Name: name2, ResourceUri: resourceUri, NoteName: noteName, Remediation: remediation, } mockGrafeas.err = nil mockGrafeas.reqs = nil mockGrafeas.resps = append(mockGrafeas.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/occurrences/%s", "[PROJECT]", "[OCCURRENCE]") var occurrence *grafeaspb.Occurrence = &grafeaspb.Occurrence{} var request = &grafeaspb.UpdateOccurrenceRequest{ Name: formattedName, Occurrence: occurrence, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateOccurrence(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockGrafeas.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestGrafeasUpdateOccurrenceError(t *testing.T) { errCode := codes.PermissionDenied mockGrafeas.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/occurrences/%s", "[PROJECT]", "[OCCURRENCE]") var occurrence *grafeaspb.Occurrence = &grafeaspb.Occurrence{} var request = &grafeaspb.UpdateOccurrenceRequest{ Name: formattedName, Occurrence: occurrence, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateOccurrence(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestGrafeasGetOccurrenceNote(t *testing.T) { var name2 string = "name2-1052831874" var shortDescription string = "shortDescription-235369287" var longDescription string = "longDescription-1747792199" var expectedResponse = &grafeaspb.Note{ Name: name2, ShortDescription: shortDescription, LongDescription: longDescription, } mockGrafeas.err = nil mockGrafeas.reqs = nil mockGrafeas.resps = append(mockGrafeas.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/occurrences/%s", "[PROJECT]", "[OCCURRENCE]") var request = &grafeaspb.GetOccurrenceNoteRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetOccurrenceNote(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockGrafeas.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestGrafeasGetOccurrenceNoteError(t *testing.T) { errCode := codes.PermissionDenied mockGrafeas.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/occurrences/%s", "[PROJECT]", "[OCCURRENCE]") var request = &grafeaspb.GetOccurrenceNoteRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetOccurrenceNote(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestGrafeasGetNote(t *testing.T) { var name2 string = "name2-1052831874" var shortDescription string = "shortDescription-235369287" var longDescription string = "longDescription-1747792199" var expectedResponse = &grafeaspb.Note{ Name: name2, ShortDescription: shortDescription, LongDescription: longDescription, } mockGrafeas.err = nil mockGrafeas.reqs = nil mockGrafeas.resps = append(mockGrafeas.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]") var request = &grafeaspb.GetNoteRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetNote(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockGrafeas.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestGrafeasGetNoteError(t *testing.T) { errCode := codes.PermissionDenied mockGrafeas.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]") var request = &grafeaspb.GetNoteRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetNote(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestGrafeasListNotes(t *testing.T) { var nextPageToken string = "" var notesElement *grafeaspb.Note = &grafeaspb.Note{} var notes = []*grafeaspb.Note{notesElement} var expectedResponse = &grafeaspb.ListNotesResponse{ NextPageToken: nextPageToken, Notes: notes, } mockGrafeas.err = nil mockGrafeas.reqs = nil mockGrafeas.resps = append(mockGrafeas.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &grafeaspb.ListNotesRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListNotes(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockGrafeas.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Notes[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestGrafeasListNotesError(t *testing.T) { errCode := codes.PermissionDenied mockGrafeas.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &grafeaspb.ListNotesRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListNotes(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestGrafeasDeleteNote(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockGrafeas.err = nil mockGrafeas.reqs = nil mockGrafeas.resps = append(mockGrafeas.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]") var request = &grafeaspb.DeleteNoteRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteNote(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockGrafeas.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestGrafeasDeleteNoteError(t *testing.T) { errCode := codes.PermissionDenied mockGrafeas.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]") var request = &grafeaspb.DeleteNoteRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteNote(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestGrafeasCreateNote(t *testing.T) { var name string = "name3373707" var shortDescription string = "shortDescription-235369287" var longDescription string = "longDescription-1747792199" var expectedResponse = &grafeaspb.Note{ Name: name, ShortDescription: shortDescription, LongDescription: longDescription, } mockGrafeas.err = nil mockGrafeas.reqs = nil mockGrafeas.resps = append(mockGrafeas.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var noteId string = "noteId2129224840" var note *grafeaspb.Note = &grafeaspb.Note{} var request = &grafeaspb.CreateNoteRequest{ Parent: formattedParent, NoteId: noteId, Note: note, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateNote(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockGrafeas.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestGrafeasCreateNoteError(t *testing.T) { errCode := codes.PermissionDenied mockGrafeas.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var noteId string = "noteId2129224840" var note *grafeaspb.Note = &grafeaspb.Note{} var request = &grafeaspb.CreateNoteRequest{ Parent: formattedParent, NoteId: noteId, Note: note, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateNote(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestGrafeasBatchCreateNotes(t *testing.T) { var expectedResponse *grafeaspb.BatchCreateNotesResponse = &grafeaspb.BatchCreateNotesResponse{} mockGrafeas.err = nil mockGrafeas.reqs = nil mockGrafeas.resps = append(mockGrafeas.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var notes map[string]*grafeaspb.Note = nil var request = &grafeaspb.BatchCreateNotesRequest{ Parent: formattedParent, Notes: notes, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.BatchCreateNotes(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockGrafeas.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestGrafeasBatchCreateNotesError(t *testing.T) { errCode := codes.PermissionDenied mockGrafeas.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var notes map[string]*grafeaspb.Note = nil var request = &grafeaspb.BatchCreateNotesRequest{ Parent: formattedParent, Notes: notes, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.BatchCreateNotes(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestGrafeasUpdateNote(t *testing.T) { var name2 string = "name2-1052831874" var shortDescription string = "shortDescription-235369287" var longDescription string = "longDescription-1747792199" var expectedResponse = &grafeaspb.Note{ Name: name2, ShortDescription: shortDescription, LongDescription: longDescription, } mockGrafeas.err = nil mockGrafeas.reqs = nil mockGrafeas.resps = append(mockGrafeas.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]") var note *grafeaspb.Note = &grafeaspb.Note{} var request = &grafeaspb.UpdateNoteRequest{ Name: formattedName, Note: note, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateNote(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockGrafeas.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestGrafeasUpdateNoteError(t *testing.T) { errCode := codes.PermissionDenied mockGrafeas.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]") var note *grafeaspb.Note = &grafeaspb.Note{} var request = &grafeaspb.UpdateNoteRequest{ Name: formattedName, Note: note, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateNote(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestGrafeasListNoteOccurrences(t *testing.T) { var nextPageToken string = "" var occurrencesElement *grafeaspb.Occurrence = &grafeaspb.Occurrence{} var occurrences = []*grafeaspb.Occurrence{occurrencesElement} var expectedResponse = &grafeaspb.ListNoteOccurrencesResponse{ NextPageToken: nextPageToken, Occurrences: occurrences, } mockGrafeas.err = nil mockGrafeas.reqs = nil mockGrafeas.resps = append(mockGrafeas.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]") var request = &grafeaspb.ListNoteOccurrencesRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListNoteOccurrences(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockGrafeas.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Occurrences[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestGrafeasListNoteOccurrencesError(t *testing.T) { errCode := codes.PermissionDenied mockGrafeas.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]") var request = &grafeaspb.ListNoteOccurrencesRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListNoteOccurrences(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/httpreplay/000077500000000000000000000000001356504100700167645ustar00rootroot00000000000000google-cloud-go-0.49.0/httpreplay/cmd/000077500000000000000000000000001356504100700175275ustar00rootroot00000000000000google-cloud-go-0.49.0/httpreplay/cmd/httpr/000077500000000000000000000000001356504100700206705ustar00rootroot00000000000000google-cloud-go-0.49.0/httpreplay/cmd/httpr/README.md000066400000000000000000000056521356504100700221570ustar00rootroot00000000000000# httpr, a Record/Replay Proxy httpr is an HTTP proxy that records and replays traffic. It is designed specifically for Google APIs that use HTTP exclusively. These include the Google Cloud Storage and BigQuery clients, as well as the clients in the `github.com/google/google-api-*-client` repos. If you are writing Go code, you should use the `cloud.google.com/go/httpreplay` package, which is a simpler way to use the proxy. ## Using a Record/Replay Proxy A record/replay proxy lets you run an "integration" test that accesses a backend like a Google service and record the interaction. Subsequent runs of the test can replay the server's responses without actually contacting the server, turning the integration test into a fast and inexpensive unit test. ## Usage First, obtain the `httpr` binary. If you have the Go toolchain, you can run `go get -u cloud.google.com/go/httpreplay/cmd/httpr`. Otherwise, precompiled binaries for various architectures and operating systems are available from [the releases page](https://github.com/googleapis/google-cloud-go/releases). ### Recording 1. Start `httpr` in record mode by passing it the `-record` flag with a filename: ``` httpr -record myclient.replay ``` By default, `httpr` will run on port 8080, and open a control port on 8181. You can change these with the `-port` and `-control-port` flags. You will want to run `httpr` in the background or in another window. 1. In order for `httpr` to record HTTPS traffic, your client must trust it. It does so by installing a CA certificate created by `httpr` during the recording session. To obtain the certificate in PEM form, GET the URL `http://localhost:8181/authority.cer`. (If you changed the control port, use it in place of 8181.) Consult your language to determine how to install the certificate. Note that the certificate is different for each run of `httpr`. 1. Arrange for your test program to use `httpr` as a proxy. This may be as simple as setting the `HTTPS_PROXY` environment variable. 1. Run your test program, using whatever authentication for your Google API clients that you wish. 1. Send `httpr` a SIGINT signal (`kill -2`). `httpr` will write the replay file, then exit. ### Replaying 1. Start `httpr` in replay mode, in the background or another window: ``` httpr -replay myclient.replay ``` 1. Install the CA certificate as described above. 1. Have your test program treat `httpr` as a proxy, as described above. 1. Run your test program. Your Google API clients should use no authentication. ## Tips You must remove all randomness from your interaction while recording, so that the replay is fully deterministic. Note that BigQuery clients choose random values for job IDs and insert ID if you do not supply them. Either supply your own, or seed the client's random number generator if possible. ## Examples Examples of running `httpr` can be found in `examples` under this file's directory. google-cloud-go-0.49.0/httpreplay/cmd/httpr/examples/000077500000000000000000000000001356504100700225065ustar00rootroot00000000000000google-cloud-go-0.49.0/httpreplay/cmd/httpr/examples/python/000077500000000000000000000000001356504100700240275ustar00rootroot00000000000000google-cloud-go-0.49.0/httpreplay/cmd/httpr/examples/python/httpr-demo.py000066400000000000000000000013161356504100700264650ustar00rootroot00000000000000from __future__ import print_function import sys from google.auth.credentials import AnonymousCredentials from google.cloud import storage if len(sys.argv)-1 != 3: print('args: PROJECT BUCKET record|replay') sys.exit(1) project = sys.argv[1] bucket_name = sys.argv[2] mode = sys.argv[3] if mode == 'record': creds = None # use default creds for demo purposes; not recommended client = storage.Client(project=project) elif mode == 'replay': creds = AnonymousCredentials() else: print('want record or replay') sys.exit(1) client = storage.Client(project=project, credentials=creds) bucket = client.get_bucket(bucket_name) print('bucket %s created %s' %(bucket.id, bucket.time_created)) google-cloud-go-0.49.0/httpreplay/cmd/httpr/examples/python/httpr-demo.sh000077500000000000000000000037471356504100700264640ustar00rootroot00000000000000#!/bin/sh -e # Copyright 2019 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # This script and the accompanying program, httpr-demo.py, demonstrate how to use # httpr with Python. # # Prerequisites: # - httpr is on your path. # - The google-cloud and google-auth Python packages have been installed: # pip install --upgrade google-cloud # pip install --upgrade google-auth # Execution: # 1. Pick a project and a GCS bucket. # 2. Invoke this script to record an interaction: # http-demo.sh PROJECT BUCKET record # 3. Invoke the script again to replay: # http-demo.sh PROJECT BUCKET replay project=$1 bucket=$2 mode=$3 if [[ $mode != "record" && $mode != "replay" ]]; then echo >&2 "usage: $0 PROJECT BUCKET record|replay" exit 1 fi if [[ $(which httpr) == "" ]]; then echo >&2 "httpr is not on PATH" exit 1 fi # Start the proxy and wait for it to come up. httpr -$mode /tmp/demo.replay & proxy_pid=$! # Stop the proxy on exit. # When the proxy is recording, this will cause it to write the replay file. trap "kill -2 $proxy_pid" EXIT sleep 1 # Download the CA certificate from the proxy's control port # and inform Python of the cert via an environment variable. cert_file=/tmp/httpr.cer curl -s localhost:8181/authority.cer > $cert_file export REQUESTS_CA_BUNDLE=$cert_file # Tell Python to use the proxy. # If you passed the -port argument to httpr, use that port here. export HTTPS_PROXY=localhost:8080 # Run the program. python httpr-demo.py $project $bucket $mode google-cloud-go-0.49.0/httpreplay/cmd/httpr/httpr.go000066400000000000000000000060501356504100700223610ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // httpr is a proxy that can record or replay HTTP requests. // Start httpr with either the -record or -replay flags, providing a filename. // Terminate the process with an interrupt (kill -2) to write the log file when recording. // To get the CA certificate of the proxy, issue a GET to http://localhost:CP/authority.cer, where // CP is the control port. package main import ( "flag" "fmt" "io/ioutil" "log" "net" "net/http" "os" "os/signal" "cloud.google.com/go/httpreplay/internal/proxy" "github.com/google/martian/martianhttp" ) var ( port = flag.Int("port", 8080, "port of the proxy") controlPort = flag.Int("control-port", 8181, "port for controlling the proxy") record = flag.String("record", "", "record traffic and save to filename") replay = flag.String("replay", "", "read filename and replay traffic") debugHeaders = flag.Bool("debug-headers", false, "log header mismatches") ) func main() { flag.Parse() if *record == "" && *replay == "" { log.Fatal("provide either -record or -replay") } if *record != "" && *replay != "" { log.Fatal("provide only one of -record and -replay") } log.Printf("httpr: starting proxy on port %d and control on port %d", *port, *controlPort) var pr *proxy.Proxy var err error if *record != "" { pr, err = proxy.ForRecording(*record, *port) } else { pr, err = proxy.ForReplaying(*replay, *port) } if err != nil { log.Fatal(err) } proxy.DebugHeaders = *debugHeaders // Expose handlers on the control port. mux := http.NewServeMux() mux.Handle("/authority.cer", martianhttp.NewAuthorityHandler(pr.CACert)) mux.HandleFunc("/initial", handleInitial(pr)) lControl, err := net.Listen("tcp", fmt.Sprintf(":%d", *controlPort)) if err != nil { log.Fatal(err) } go http.Serve(lControl, mux) sigc := make(chan os.Signal, 1) signal.Notify(sigc, os.Interrupt) <-sigc log.Println("httpr: shutting down") if err := pr.Close(); err != nil { log.Fatal(err) } } func handleInitial(pr *proxy.Proxy) http.HandlerFunc { return func(w http.ResponseWriter, req *http.Request) { switch req.Method { case "GET": if pr.Initial != nil { w.Write(pr.Initial) } case "POST": bytes, err := ioutil.ReadAll(req.Body) req.Body.Close() if err != nil { w.WriteHeader(http.StatusInternalServerError) fmt.Fprintf(w, "reading body: %v", err) } pr.Initial = bytes default: w.WriteHeader(http.StatusBadRequest) fmt.Fprint(w, "use GET to retrieve initial or POST to set it") } } } google-cloud-go-0.49.0/httpreplay/cmd/httpr/integration_test.go000066400000000000000000000127061356504100700246070ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package main_test import ( "context" "crypto/tls" "crypto/x509" "errors" "fmt" "io/ioutil" "net" "net/http" "net/url" "os" "os/exec" "strings" "testing" "time" "cloud.google.com/go/internal/testutil" "cloud.google.com/go/storage" "golang.org/x/oauth2" "google.golang.org/api/option" ) const initial = "initial state" func TestIntegration_HTTPR(t *testing.T) { if testing.Short() { t.Skip("Integration tests skipped in short mode") } if testutil.ProjID() == "" { t.Fatal("set GCLOUD_TESTS_GOLANG_PROJECT_ID and GCLOUD_TESTS_GOLANG_KEY") } // Get a unique temporary filename. f, err := ioutil.TempFile("", "httpreplay") if err != nil { t.Fatal(err) } replayFilename := f.Name() if err := f.Close(); err != nil { t.Fatal(err) } defer os.Remove(replayFilename) if err := exec.Command("go", "build").Run(); err != nil { t.Fatalf("running 'go build': %v", err) } defer os.Remove("./httpr") want := runRecord(t, replayFilename) got := runReplay(t, replayFilename) if got != want { t.Fatalf("got %q, want %q", got, want) } } func runRecord(t *testing.T, filename string) string { cmd, tr, cport, err := start("-record", filename) if err != nil { t.Fatal(err) } defer stop(t, cmd) ctx := context.Background() hc := &http.Client{ Transport: &oauth2.Transport{ Base: tr, Source: testutil.TokenSource(ctx, storage.ScopeFullControl), }, } res, err := http.Post( fmt.Sprintf("http://localhost:%s/initial", cport), "text/plain", strings.NewReader(initial)) if err != nil { t.Fatal(err) } if res.StatusCode != 200 { t.Fatalf("from POST: %s", res.Status) } info, err := getBucketInfo(ctx, hc) if err != nil { t.Fatal(err) } return info } func runReplay(t *testing.T, filename string) string { cmd, tr, cport, err := start("-replay", filename) if err != nil { t.Fatal(err) } defer stop(t, cmd) hc := &http.Client{Transport: tr} res, err := http.Get(fmt.Sprintf("http://localhost:%s/initial", cport)) if err != nil { t.Fatal(err) } if res.StatusCode != 200 { t.Fatalf("from GET: %s", res.Status) } bytes, err := ioutil.ReadAll(res.Body) res.Body.Close() if err != nil { t.Fatal(err) } if got, want := string(bytes), initial; got != want { t.Errorf("initial: got %q, want %q", got, want) } info, err := getBucketInfo(context.Background(), hc) if err != nil { t.Fatal(err) } return info } // Start the proxy binary and wait for it to come up. // Return a transport that talks to the proxy, as well as the control port. // modeFlag must be either "-record" or "-replay". func start(modeFlag, filename string) (*exec.Cmd, *http.Transport, string, error) { pport, err := pickPort() if err != nil { return nil, nil, "", err } cport, err := pickPort() if err != nil { return nil, nil, "", err } cmd := exec.Command("./httpr", "-port", pport, "-control-port", cport, modeFlag, filename, "-debug-headers") if err := cmd.Start(); err != nil { return nil, nil, "", err } // Wait for the server to come up. serverUp := false for i := 0; i < 10; i++ { if conn, err := net.Dial("tcp", "localhost:"+cport); err == nil { conn.Close() serverUp = true break } time.Sleep(time.Second) } if !serverUp { return nil, nil, "", errors.New("server never came up") } tr, err := proxyTransport(pport, cport) if err != nil { return nil, nil, "", err } return cmd, tr, cport, nil } func stop(t *testing.T, cmd *exec.Cmd) { if err := cmd.Process.Signal(os.Interrupt); err != nil { t.Fatal(err) } } // pickPort picks an unused port. func pickPort() (string, error) { l, err := net.Listen("tcp", ":0") if err != nil { return "", err } addr := l.Addr().String() _, port, err := net.SplitHostPort(addr) if err != nil { return "", err } l.Close() return port, nil } func proxyTransport(pport, cport string) (*http.Transport, error) { caCert, err := getBody(fmt.Sprintf("http://localhost:%s/authority.cer", cport)) if err != nil { return nil, err } caCertPool := x509.NewCertPool() if !caCertPool.AppendCertsFromPEM([]byte(caCert)) { return nil, errors.New("bad CA Cert") } return &http.Transport{ Proxy: http.ProxyURL(&url.URL{Host: "localhost:" + pport}), TLSClientConfig: &tls.Config{RootCAs: caCertPool}, }, nil } func getBucketInfo(ctx context.Context, hc *http.Client) (string, error) { client, err := storage.NewClient(ctx, option.WithHTTPClient(hc)) if err != nil { return "", err } defer client.Close() b := client.Bucket(testutil.ProjID()) attrs, err := b.Attrs(ctx) if err != nil { return "", err } return fmt.Sprintf("name:%s reqpays:%v location:%s sclass:%s", attrs.Name, attrs.RequesterPays, attrs.Location, attrs.StorageClass), nil } func getBody(url string) ([]byte, error) { res, err := http.Get(url) if err != nil { return nil, err } if res.StatusCode != 200 { return nil, fmt.Errorf("response: %s", res.Status) } defer res.Body.Close() return ioutil.ReadAll(res.Body) } google-cloud-go-0.49.0/httpreplay/httpreplay.go000066400000000000000000000133631356504100700215150ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package httpreplay provides an API for recording and replaying traffic // from HTTP-based Google API clients. // // To record: // 1. Call NewRecorder to get a Recorder. // 2. Use its Client method to obtain an HTTP client to use when making API calls. // 3. Close the Recorder when you're done. That will save the log of interactions // to the file you provided to NewRecorder. // // To replay: // 1. Call NewReplayer with the same filename you used to record to get a Replayer. // 2. Call its Client method and use the client to make the same API calls. // You will get back the recorded responses. // 3. Close the Replayer when you're done. // // This package is EXPERIMENTAL and is subject to change or removal without notice. // It requires Go version 1.8 or higher. package httpreplay // TODO(jba): add examples. import ( "context" "net/http" "cloud.google.com/go/httpreplay/internal/proxy" "google.golang.org/api/option" htransport "google.golang.org/api/transport/http" ) // A Recorder records HTTP interactions. type Recorder struct { proxy *proxy.Proxy } // NewRecorder creates a recorder that writes to filename. The file will // also store initial state that can be retrieved to configure replay. // // You must call Close on the Recorder to ensure that all data is written. func NewRecorder(filename string, initial []byte) (*Recorder, error) { p, err := proxy.ForRecording(filename, 0) if err != nil { return nil, err } p.Initial = initial return &Recorder{proxy: p}, nil } // RemoveRequestHeaders will remove request headers matching patterns from the log, // and skip matching them during replay. // // Pattern is taken literally except for *, which matches any sequence of characters. func (r *Recorder) RemoveRequestHeaders(patterns ...string) { r.proxy.RemoveRequestHeaders(patterns) } // ClearHeaders will replace the value of request and response headers that match // any of the patterns with CLEARED, on both recording and replay. // Use ClearHeaders when the header information is secret or may change from run to // run, but you still want to verify that the headers are being sent and received. // // Pattern is taken literally except for *, which matches any sequence of characters. func (r *Recorder) ClearHeaders(patterns ...string) { r.proxy.ClearHeaders(patterns) } // RemoveQueryParams will remove URL query parameters matching patterns from the log, // and skip matching them during replay. // // Pattern is taken literally except for *, which matches any sequence of characters. func (r *Recorder) RemoveQueryParams(patterns ...string) { r.proxy.RemoveQueryParams(patterns) } // ClearQueryParams will replace the value of URL query parametrs that match any of // the patterns with CLEARED, on both recording and replay. // Use ClearQueryParams when the parameter information is secret or may change from // run to run, but you still want to verify that it are being sent. // // Pattern is taken literally except for *, which matches any sequence of characters. func (r *Recorder) ClearQueryParams(patterns ...string) { r.proxy.ClearQueryParams(patterns) } // Client returns an http.Client to be used for recording. Provide authentication options // like option.WithTokenSource as you normally would, or omit them to use Application Default // Credentials. func (r *Recorder) Client(ctx context.Context, opts ...option.ClientOption) (*http.Client, error) { return proxyClient(ctx, r.proxy, opts...) } func proxyClient(ctx context.Context, p *proxy.Proxy, opts ...option.ClientOption) (*http.Client, error) { trans, err := htransport.NewTransport(ctx, p.Transport(), opts...) if err != nil { return nil, err } return &http.Client{Transport: trans}, nil } // Close closes the Recorder and saves the log file. func (r *Recorder) Close() error { return r.proxy.Close() } // A Replayer replays previously recorded HTTP interactions. type Replayer struct { proxy *proxy.Proxy } // NewReplayer creates a replayer that reads from filename. func NewReplayer(filename string) (*Replayer, error) { p, err := proxy.ForReplaying(filename, 0) if err != nil { return nil, err } return &Replayer{proxy: p}, nil } // Client returns an HTTP client for replaying. The client does not need to be // configured with credentials for authenticating to a server, since it never // contacts a real backend. func (r *Replayer) Client(ctx context.Context) (*http.Client, error) { return proxyClient(ctx, r.proxy, option.WithoutAuthentication()) } // Initial returns the initial state saved by the Recorder. func (r *Replayer) Initial() []byte { return r.proxy.Initial } // IgnoreHeader will not use h when matching requests. func (r *Replayer) IgnoreHeader(h string) { r.proxy.IgnoreHeader(h) } // Close closes the replayer. func (r *Replayer) Close() error { return r.proxy.Close() } // DebugHeaders helps to determine whether a header should be ignored. // When true, if requests have the same method, URL and body but differ // in a header, the first mismatched header is logged. func DebugHeaders() { proxy.DebugHeaders = true } // Supported reports whether httpreplay is supported in the current version of Go. // For Go 1.8 and above, the answer is true. func Supported() bool { return true } google-cloud-go-0.49.0/httpreplay/httpreplay_test.go000066400000000000000000000232541356504100700225540ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package httpreplay_test import ( "bytes" "context" "encoding/json" "fmt" "io/ioutil" "log" "net/http" "net/http/httptest" "os" "testing" "time" "cloud.google.com/go/httpreplay" "cloud.google.com/go/internal/testutil" "cloud.google.com/go/storage" "google.golang.org/api/option" ) func TestIntegration_RecordAndReplay(t *testing.T) { httpreplay.DebugHeaders() if testing.Short() { t.Skip("Integration tests skipped in short mode") } replayFilename := tempFilename(t, "RecordAndReplay*.replay") defer os.Remove(replayFilename) projectID := testutil.ProjID() if projectID == "" { t.Skip("Need project ID. See CONTRIBUTING.md for details.") } ctx := context.Background() // Record. initial := time.Now() ibytes, err := json.Marshal(initial) if err != nil { t.Fatal(err) } rec, err := httpreplay.NewRecorder(replayFilename, ibytes) if err != nil { t.Fatal(err) } hc, err := rec.Client(ctx, option.WithTokenSource( testutil.TokenSource(ctx, storage.ScopeFullControl))) if err != nil { t.Fatal(err) } wanta, wantc := run(t, hc) testReadCRC(t, hc, "recording") if err := rec.Close(); err != nil { t.Fatalf("rec.Close: %v", err) } // Replay. rep, err := httpreplay.NewReplayer(replayFilename) if err != nil { t.Fatal(err) } defer rep.Close() hc, err = rep.Client(ctx) if err != nil { t.Fatal(err) } gota, gotc := run(t, hc) testReadCRC(t, hc, "replaying") if diff := testutil.Diff(gota, wanta); diff != "" { t.Error(diff) } if !bytes.Equal(gotc, wantc) { t.Errorf("got %q, want %q", gotc, wantc) } var gotInitial time.Time if err := json.Unmarshal(rep.Initial(), &gotInitial); err != nil { t.Fatal(err) } if !gotInitial.Equal(initial) { t.Errorf("initial: got %v, want %v", gotInitial, initial) } } // TODO(jba): test errors func run(t *testing.T, hc *http.Client) (*storage.BucketAttrs, []byte) { ctx := context.Background() client, err := storage.NewClient(ctx, option.WithHTTPClient(hc)) if err != nil { t.Fatal(err) } defer client.Close() b := client.Bucket(testutil.ProjID()) attrs, err := b.Attrs(ctx) if err != nil { t.Fatal(err) } obj := b.Object("replay-test") w := obj.NewWriter(ctx) data := []byte{150, 151, 152} if _, err := w.Write(data); err != nil { t.Fatal(err) } if err := w.Close(); err != nil { t.Fatal(err) } r, err := obj.NewReader(ctx) if err != nil { t.Fatal(err) } defer r.Close() contents, err := ioutil.ReadAll(r) if err != nil { t.Fatal(err) } return attrs, contents } func testReadCRC(t *testing.T, hc *http.Client, mode string) { const ( // This is an uncompressed file. // See https://cloud.google.com/storage/docs/public-datasets/landsat uncompressedBucket = "gcp-public-data-landsat" uncompressedObject = "LC08/PRE/044/034/LC80440342016259LGN00/LC80440342016259LGN00_MTL.txt" gzippedBucket = "storage-library-test-bucket" gzippedObject = "gzipped-text.txt" ) ctx := context.Background() client, err := storage.NewClient(ctx, option.WithHTTPClient(hc)) if err != nil { t.Fatalf("%s: %v", mode, err) } defer client.Close() uncompressedObj := client.Bucket(uncompressedBucket).Object(uncompressedObject) gzippedObj := client.Bucket(gzippedBucket).Object(gzippedObject) for _, test := range []struct { desc string obj *storage.ObjectHandle offset, length int64 readCompressed bool // don't decompress a gzipped file wantErr bool wantLen int // length of contents }{ { desc: "uncompressed, entire file", obj: uncompressedObj, offset: 0, length: -1, readCompressed: false, wantLen: 7903, }, { desc: "uncompressed, entire file, don't decompress", obj: uncompressedObj, offset: 0, length: -1, readCompressed: true, wantLen: 7903, }, { desc: "uncompressed, suffix", obj: uncompressedObj, offset: 3, length: -1, readCompressed: false, wantLen: 7900, }, { desc: "uncompressed, prefix", obj: uncompressedObj, offset: 0, length: 18, readCompressed: false, wantLen: 18, }, { // When a gzipped file is unzipped by GCS, we can't verify the checksum // because it was computed against the zipped contents. There is no // header that indicates that a gzipped file is being served unzipped. // But our CRC check only happens if there is a Content-Length header, // and that header is absent for this read. desc: "compressed, entire file, server unzips", obj: gzippedObj, offset: 0, length: -1, readCompressed: false, wantLen: 11, }, { // When we read a gzipped file uncompressed, it's like reading a regular file: // the served content and the CRC match. desc: "compressed, entire file, read compressed", obj: gzippedObj, offset: 0, length: -1, readCompressed: true, wantLen: 31, }, { desc: "compressed, partial, read compressed", obj: gzippedObj, offset: 1, length: 8, readCompressed: true, wantLen: 8, }, { desc: "uncompressed, HEAD", obj: uncompressedObj, offset: 0, length: 0, wantLen: 0, }, { desc: "compressed, HEAD", obj: gzippedObj, offset: 0, length: 0, wantLen: 0, }, } { obj := test.obj.ReadCompressed(test.readCompressed) r, err := obj.NewRangeReader(ctx, test.offset, test.length) if err != nil { if test.wantErr { continue } t.Errorf("%s: %s: %v", mode, test.desc, err) continue } data, err := ioutil.ReadAll(r) _ = r.Close() if err != nil { t.Errorf("%s: %s: %v", mode, test.desc, err) continue } if got, want := len(data), test.wantLen; got != want { t.Errorf("%s: %s: len: got %d, want %d", mode, test.desc, got, want) } } } func TestRemoveAndClear(t *testing.T) { // Disable logging for this test, since it generates a lot. log.SetOutput(ioutil.Discard) srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { fmt.Fprintln(w, "LGTM") })) defer srv.Close() replayFilename := tempFilename(t, "TestRemoveAndClear*.replay") defer os.Remove(replayFilename) ctx := context.Background() // Record rec, err := httpreplay.NewRecorder(replayFilename, nil) if err != nil { t.Fatal(err) } rec.ClearHeaders("Clear") rec.RemoveRequestHeaders("Rem*") rec.ClearQueryParams("c") rec.RemoveQueryParams("r") hc, err := rec.Client(ctx, option.WithoutAuthentication()) if err != nil { t.Fatal(err) } query := "k=1&r=2&c=3" req, err := http.NewRequest("GET", srv.URL+"?"+query, nil) if err != nil { t.Fatal(err) } headers := map[string]string{"Keep": "ok", "Clear": "secret", "Remove": "bye"} for k, v := range headers { req.Header.Set(k, v) } if _, err := hc.Do(req); err != nil { t.Fatal(err) } if err := rec.Close(); err != nil { t.Fatal(err) } // Replay // For both headers and query param: // - k or Keep must be present and identical // - c or Clear must be present, but can be different // - r or Remove can be anything for _, test := range []struct { query string headers map[string]string wantSuccess bool }{ {query, headers, true}, // same query string and headers {query, map[string]string{"Keep": "oops", "Clear": "secret", "Remove": "bye"}, false, // different Keep }, {query, map[string]string{}, false}, // missing Keep and Clear {query, map[string]string{"Keep": "ok"}, false}, // missing Clear {query, map[string]string{"Keep": "ok", "Clear": "secret"}, true}, // missing Remove is OK { query, map[string]string{"Keep": "ok", "Clear": "secret", "Remove": "whatev"}, true, }, // different Remove is OK {query, map[string]string{"Keep": "ok", "Clear": "diff"}, true}, // different Clear is OK {"", headers, false}, // no query string {"k=x&r=2&c=3", headers, false}, // different k {"r=2", headers, false}, // missing k and c {"k=1&r=2", headers, false}, // missing c {"k=1&c=3", headers, true}, // missing r is OK {"k=1&r=x&c=3", headers, true}, // different r is OK, {"k=1&r=2&c=x", headers, true}, // different clear is OK } { rep, err := httpreplay.NewReplayer(replayFilename) if err != nil { t.Fatal(err) } hc, err = rep.Client(ctx) if err != nil { t.Fatal(err) } url := srv.URL if test.query != "" { url += "?" + test.query } req, err = http.NewRequest("GET", url, nil) if err != nil { t.Fatal(err) } for k, v := range test.headers { req.Header.Set(k, v) } resp, err := hc.Do(req) if err != nil { t.Fatal(err) } rep.Close() if (resp.StatusCode == 200) != test.wantSuccess { t.Errorf("%q, %v: got %d, wanted success=%t", test.query, test.headers, resp.StatusCode, test.wantSuccess) } } } func tempFilename(t *testing.T, pattern string) string { f, err := ioutil.TempFile("", pattern) if err != nil { t.Fatal(err) } filename := f.Name() if err := f.Close(); err != nil { t.Fatal(err) } return filename } google-cloud-go-0.49.0/httpreplay/internal/000077500000000000000000000000001356504100700206005ustar00rootroot00000000000000google-cloud-go-0.49.0/httpreplay/internal/proxy/000077500000000000000000000000001356504100700217615ustar00rootroot00000000000000google-cloud-go-0.49.0/httpreplay/internal/proxy/converter.go000066400000000000000000000172621356504100700243270ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package proxy import ( "bytes" "io" "io/ioutil" "mime" "mime/multipart" "net/http" "net/url" "regexp" "strings" ) // A Converter converts HTTP requests and responses to the Request and Response types // of this package, while removing or redacting information. type Converter struct { // These all apply to both headers and trailers. ClearHeaders []tRegexp // replace matching headers with "CLEARED" RemoveRequestHeaders []tRegexp // remove matching headers in requests RemoveResponseHeaders []tRegexp // remove matching headers in responses ClearParams []tRegexp // replace matching query params with "CLEARED" RemoveParams []tRegexp // remove matching query params } // A regexp that can be marshaled to and from text. type tRegexp struct { *regexp.Regexp } func (r tRegexp) MarshalText() ([]byte, error) { return []byte(r.String()), nil } func (r *tRegexp) UnmarshalText(b []byte) error { var err error r.Regexp, err = regexp.Compile(string(b)) return err } func (c *Converter) registerRemoveRequestHeaders(pat string) { c.RemoveRequestHeaders = append(c.RemoveRequestHeaders, pattern(pat)) } func (c *Converter) registerClearHeaders(pat string) { c.ClearHeaders = append(c.ClearHeaders, pattern(pat)) } func (c *Converter) registerRemoveParams(pat string) { c.RemoveParams = append(c.RemoveParams, pattern(pat)) } func (c *Converter) registerClearParams(pat string) { c.ClearParams = append(c.ClearParams, pattern(pat)) } var ( defaultRemoveRequestHeaders = []string{ "Authorization", // not only is it secret, but it is probably missing on replay "Proxy-Authorization", "Connection", "Content-Type", // because it may contain a random multipart boundary "Date", "Host", "Transfer-Encoding", "Via", "X-Forwarded-*", // Google-specific "X-Cloud-Trace-Context", // OpenCensus traces have a random ID "X-Goog-Api-Client", // can differ for, e.g., different Go versions } defaultRemoveBothHeaders = []string{ // Google-specific // GFEs scrub X-Google- and X-GFE- headers from requests and responses. // Drop them from recordings made by users inside Google. // http://g3doc/gfe/g3doc/gfe3/design/http_filters/google_header_filter // (internal Google documentation). "X-Google-*", "X-Gfe-*", } defaultClearHeaders = []string{ // Google-specific // Used by Cloud Storage for customer-supplied encryption. "X-Goog-*Encryption-Key", } ) func defaultConverter() *Converter { c := &Converter{} for _, h := range defaultClearHeaders { c.registerClearHeaders(h) } for _, h := range defaultRemoveRequestHeaders { c.registerRemoveRequestHeaders(h) } for _, h := range defaultRemoveBothHeaders { c.registerRemoveRequestHeaders(h) c.RemoveResponseHeaders = append(c.RemoveResponseHeaders, pattern(h)) } return c } // Convert a pattern into a regexp. // A pattern is like a literal regexp anchored on both ends, with only one // non-literal character: "*", which matches zero or more characters. func pattern(p string) tRegexp { q := regexp.QuoteMeta(p) q = "^" + strings.Replace(q, `\*`, `.*`, -1) + "$" // q must be a legal regexp. return tRegexp{regexp.MustCompile(q)} } func (c *Converter) convertRequest(req *http.Request) (*Request, error) { body, err := snapshotBody(&req.Body) if err != nil { return nil, err } // If the body is empty, set it to nil to make sure the proxy sends a // Content-Length header. if len(body) == 0 { req.Body = nil } mediaType, parts, err := parseRequestBody(req.Header.Get("Content-Type"), body) if err != nil { return nil, err } url2 := *req.URL url2.RawQuery = scrubQuery(url2.RawQuery, c.ClearParams, c.RemoveParams) return &Request{ Method: req.Method, URL: url2.String(), Header: scrubHeaders(req.Header, c.ClearHeaders, c.RemoveRequestHeaders), MediaType: mediaType, BodyParts: parts, Trailer: scrubHeaders(req.Trailer, c.ClearHeaders, c.RemoveRequestHeaders), }, nil } // parseRequestBody parses the Content-Type header, reads the body, and splits it into // parts if necessary. It returns the media type and the body parts. func parseRequestBody(contentType string, body []byte) (string, [][]byte, error) { if contentType == "" { // No content-type header. Treat the body as a single part. return "", [][]byte{body}, nil } mediaType, params, err := mime.ParseMediaType(contentType) if err != nil { return "", nil, err } var parts [][]byte if strings.HasPrefix(mediaType, "multipart/") { mr := multipart.NewReader(bytes.NewReader(body), params["boundary"]) for { p, err := mr.NextPart() if err == io.EOF { break } if err != nil { return "", nil, err } part, err := ioutil.ReadAll(p) if err != nil { return "", nil, err } // TODO(jba): care about part headers? parts = append(parts, part) } } else { parts = [][]byte{body} } return mediaType, parts, nil } func (c *Converter) convertResponse(res *http.Response) (*Response, error) { data, err := snapshotBody(&res.Body) if err != nil { return nil, err } return &Response{ StatusCode: res.StatusCode, Proto: res.Proto, ProtoMajor: res.ProtoMajor, ProtoMinor: res.ProtoMinor, Header: scrubHeaders(res.Header, c.ClearHeaders, c.RemoveResponseHeaders), Body: data, Trailer: scrubHeaders(res.Trailer, c.ClearHeaders, c.RemoveResponseHeaders), }, nil } func snapshotBody(body *io.ReadCloser) ([]byte, error) { data, err := ioutil.ReadAll(*body) if err != nil { return nil, err } (*body).Close() *body = ioutil.NopCloser(bytes.NewReader(data)) return data, nil } // Copy headers, clearing some and removing others. func scrubHeaders(hs http.Header, clear, remove []tRegexp) http.Header { rh := http.Header{} for k, v := range hs { switch { case match(k, clear): rh.Set(k, "CLEARED") case match(k, remove): // skip default: rh[k] = v } } return rh } // Copy the query string, clearing some query params and removing others. // Preserve the order of the string. func scrubQuery(query string, clear, remove []tRegexp) string { // We can't use url.ParseQuery because it doesn't preserve order. var buf bytes.Buffer for { if i := strings.IndexAny(query, "&;"); i >= 0 { scrubParam(&buf, query[:i], query[i], clear, remove) query = query[i+1:] } else { scrubParam(&buf, query, 0, clear, remove) break } } s := buf.String() if strings.HasSuffix(s, "&") { return s[:len(s)-1] } return s } func scrubParam(buf *bytes.Buffer, param string, sep byte, clear, remove []tRegexp) { if param == "" { return } key := param value := "" if i := strings.Index(param, "="); i >= 0 { key, value = key[:i], key[i+1:] } ukey, err := url.QueryUnescape(key) // If the key is bad, just pass it and the value through. if err != nil { buf.WriteString(param) if sep != 0 { buf.WriteByte(sep) } return } if match(ukey, remove) { return } if match(ukey, clear) && value != "" { value = "CLEARED" } buf.WriteString(key) buf.WriteByte('=') buf.WriteString(value) if sep != 0 { buf.WriteByte(sep) } } func match(s string, res []tRegexp) bool { for _, re := range res { if re.MatchString(s) { return true } } return false } google-cloud-go-0.49.0/httpreplay/internal/proxy/converter_test.go000066400000000000000000000056411356504100700253640ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package proxy import ( "bytes" "io/ioutil" "net/http" "net/url" "testing" "cloud.google.com/go/internal/testutil" "github.com/google/go-cmp/cmp" ) func TestConvertRequest(t *testing.T) { clone := func(h http.Header) http.Header { h2 := http.Header{} for k, v := range h { h2[k] = v } return h2 } body := []byte("hello") conv := defaultConverter() conv.registerClearParams("secret") conv.registerRemoveParams("rm*") url, err := url.Parse("https://www.example.com?a=1&rmx=x&secret=2&c=3&rmy=4") if err != nil { t.Fatal(err) } in := &http.Request{ Method: "GET", URL: url, Body: ioutil.NopCloser(bytes.NewReader(body)), Header: http.Header{ "Content-Type": {"text/plain"}, "Authorization": {"oauth2-token"}, "X-Goog-Encryption-Key": {"a-secret-key"}, "X-Goog-Copy-Source-Encryption-Key": {"another-secret-key"}, }, } origHeader := clone(in.Header) got, err := conv.convertRequest(in) if err != nil { t.Fatal(err) } want := &Request{ Method: "GET", URL: "https://www.example.com?a=1&secret=CLEARED&c=3", MediaType: "text/plain", BodyParts: [][]byte{body}, Header: http.Header{ "X-Goog-Encryption-Key": {"CLEARED"}, "X-Goog-Copy-Source-Encryption-Key": {"CLEARED"}, }, Trailer: http.Header{}, } if diff := cmp.Diff(got, want); diff != "" { t.Error(diff) } // The original headers should be the same. if got, want := in.Header, origHeader; !testutil.Equal(got, want) { t.Errorf("got %+v\nwant %+v", got, want) } } func TestPattern(t *testing.T) { for _, test := range []struct { in, want string }{ {"", "^$"}, {"abc", "^abc$"}, {"*ab*", "^.*ab.*$"}, {`a\*b`, `^a\\.*b$`}, {"***", "^.*.*.*$"}, } { got := pattern(test.in).String() if got != test.want { t.Errorf("%q: got %s, want %s", test.in, got, test.want) } } } func TestScrubQuery(t *testing.T) { clear := []tRegexp{pattern("c*")} remove := []tRegexp{pattern("r*")} for _, test := range []struct { in, want string }{ {"", ""}, {"a=1", "a=1"}, {"a=1&b=2;g=3", "a=1&b=2;g=3"}, {"a=1&r=2;c=3", "a=1&c=CLEARED"}, {"ra=1&rb=2&rc=3", ""}, {"a=1&%Z=2&r=3&c=4", "a=1&%Z=2&c=CLEARED"}, } { got := scrubQuery(test.in, clear, remove) if got != test.want { t.Errorf("%s: got %q, want %q", test.in, got, test.want) } } } google-cloud-go-0.49.0/httpreplay/internal/proxy/debug.go000066400000000000000000000026171356504100700234040ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package proxy import ( "log" "net/http" ) // Useful things for when we need to figure out what's actually going on under the hood. type debugTransport struct { prefix string t *http.Transport } func (d debugTransport) RoundTrip(req *http.Request) (*http.Response, error) { log.Printf("proxy %s: %s %s", d.prefix, req.Method, req.URL) logHeaders(req.Header) res, err := d.t.RoundTrip(req) if err != nil { log.Printf("proxy %s: error %v", d.prefix, err) } else { log.Printf("proxy %s: %s", d.prefix, res.Status) log.Printf("Uncompressed = %v", res.Uncompressed) log.Printf("ContentLength = %d", res.ContentLength) logHeaders(res.Header) log.Printf("Trailers:") logHeaders(res.Trailer) } return res, err } func logHeaders(hs http.Header) { for k, v := range hs { log.Printf(" %s: %s", k, v) } } google-cloud-go-0.49.0/httpreplay/internal/proxy/log.go000066400000000000000000000115041356504100700230720ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package proxy import ( "bytes" "fmt" "io/ioutil" "net/http" "strconv" "sync" "github.com/google/martian" ) // Replacement for the HAR logging that comes with martian. HAR is not designed for // replay. In particular, response bodies are interpreted (e.g. decompressed), and we // just want them to be stored literally. This isn't something we can fix in martian: it // is required in the HAR spec (http://www.softwareishard.com/blog/har-12-spec/#content). // LogVersion is the current version of the log format. It can be used to // support changes to the format over time, so newer code can read older files. const LogVersion = "0.2" // A Log is a record of HTTP interactions, suitable for replay. It can be serialized to JSON. type Log struct { Initial []byte // initial data for replay Version string // version of this log format Converter *Converter Entries []*Entry } // An Entry single request-response pair. type Entry struct { ID string // unique ID Request *Request Response *Response } // A Request represents an http.Request in the log. type Request struct { Method string // http.Request.Method URL string // http.Request.URL, as a string Header http.Header // http.Request.Header // We need to understand multipart bodies because the boundaries are // generated randomly, so we can't just compare the entire bodies for equality. MediaType string // the media type part of the Content-Type header BodyParts [][]byte // http.Request.Body, read to completion and split for multipart Trailer http.Header `json:",omitempty"` // http.Request.Trailer } // A Response represents an http.Response in the log. type Response struct { StatusCode int // http.Response.StatusCode Proto string // http.Response.Proto ProtoMajor int // http.Response.ProtoMajor ProtoMinor int // http.Response.ProtoMinor Header http.Header // http.Response.Header Body []byte // http.Response.Body, read to completion Trailer http.Header `json:",omitempty"` // http.Response.Trailer } // A Logger maintains a request-response log. type Logger struct { mu sync.Mutex entries map[string]*Entry // from ID log *Log } // newLogger creates a new logger. func newLogger() *Logger { return &Logger{ log: &Log{ Version: LogVersion, Converter: defaultConverter(), }, entries: map[string]*Entry{}, } } // ModifyRequest logs requests. func (l *Logger) ModifyRequest(req *http.Request) error { if req.Method == "CONNECT" { return nil } ctx := martian.NewContext(req) if ctx.SkippingLogging() { return nil } lreq, err := l.log.Converter.convertRequest(req) if err != nil { return err } id := ctx.ID() entry := &Entry{ID: id, Request: lreq} l.mu.Lock() defer l.mu.Unlock() if _, ok := l.entries[id]; ok { panic(fmt.Sprintf("proxy: duplicate request ID: %s", id)) } l.entries[id] = entry l.log.Entries = append(l.log.Entries, entry) return nil } // ModifyResponse logs responses. func (l *Logger) ModifyResponse(res *http.Response) error { ctx := martian.NewContext(res.Request) if ctx.SkippingLogging() { return nil } id := ctx.ID() lres, err := l.log.Converter.convertResponse(res) if err != nil { return err } l.mu.Lock() defer l.mu.Unlock() if e, ok := l.entries[id]; ok { e.Response = lres } // Ignore the response if we haven't seen the request. return nil } // Extract returns the Log and removes it. The Logger is not usable // after this call. func (l *Logger) Extract() *Log { l.mu.Lock() defer l.mu.Unlock() r := l.log l.log = nil l.entries = nil return r } func toHTTPResponse(lr *Response, req *http.Request) *http.Response { res := &http.Response{ StatusCode: lr.StatusCode, Proto: lr.Proto, ProtoMajor: lr.ProtoMajor, ProtoMinor: lr.ProtoMinor, Header: lr.Header, Body: ioutil.NopCloser(bytes.NewReader(lr.Body)), ContentLength: int64(len(lr.Body)), } res.Request = req // For HEAD, set ContentLength to the value of the Content-Length header, or -1 // if there isn't one. if req.Method == "HEAD" { res.ContentLength = -1 if c := res.Header["Content-Length"]; len(c) == 1 { if c64, err := strconv.ParseInt(c[0], 10, 64); err == nil { res.ContentLength = c64 } } } return res } google-cloud-go-0.49.0/httpreplay/internal/proxy/log_test.go000066400000000000000000000106451356504100700241360ustar00rootroot00000000000000// Copyright 2018 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package proxy import ( "io/ioutil" "net/http" "net/url" "strings" "testing" "cloud.google.com/go/internal/testutil" "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/martian" ) func TestLogger(t *testing.T) { req := &http.Request{ Method: "POST", URL: &url.URL{ Scheme: "https", Host: "example.com", Path: "a/b/c", }, Header: http.Header{"H1": {"v1", "v2"}, "Content-Type": {"text/plain"}}, Body: ioutil.NopCloser(strings.NewReader("hello")), Trailer: http.Header{"T1": {"v3", "v4"}}, } res := &http.Response{ Request: req, StatusCode: 204, Body: ioutil.NopCloser(strings.NewReader("goodbye")), Header: http.Header{"H2": {"v5"}}, Trailer: http.Header{"T2": {"v6", "v7"}}, } l := newLogger() _, remove, err := martian.TestContext(req, nil, nil) if err != nil { t.Fatal(err) } defer remove() if err := l.ModifyRequest(req); err != nil { t.Fatal(err) } if err := l.ModifyResponse(res); err != nil { t.Fatal(err) } lg := l.Extract() want := []*Entry{ { ID: lg.Entries[0].ID, Request: &Request{ Method: "POST", URL: "https://example.com/a/b/c", Header: http.Header{"H1": {"v1", "v2"}}, MediaType: "text/plain", BodyParts: [][]byte{[]byte("hello")}, Trailer: http.Header{"T1": {"v3", "v4"}}, }, Response: &Response{ StatusCode: 204, Body: []byte("goodbye"), Header: http.Header{"H2": {"v5"}}, Trailer: http.Header{"T2": {"v6", "v7"}}, }, }, } if diff := testutil.Diff(lg.Entries, want); diff != "" { t.Error(diff) } } func TestToHTTPResponse(t *testing.T) { for _, test := range []struct { desc string lr *Response req *http.Request want *http.Response }{ { desc: "GET request", lr: &Response{ StatusCode: 201, Proto: "1.1", Header: http.Header{"h": {"v"}}, Body: []byte("text"), }, req: &http.Request{Method: "GET"}, want: &http.Response{ Request: &http.Request{Method: "GET"}, StatusCode: 201, Proto: "1.1", Header: http.Header{"h": {"v"}}, ContentLength: 4, }, }, { desc: "HEAD request with no Content-Length header", lr: &Response{ StatusCode: 201, Proto: "1.1", Header: http.Header{"h": {"v"}}, Body: []byte("text"), }, req: &http.Request{Method: "HEAD"}, want: &http.Response{ Request: &http.Request{Method: "HEAD"}, StatusCode: 201, Proto: "1.1", Header: http.Header{"h": {"v"}}, ContentLength: -1, }, }, { desc: "HEAD request with Content-Length header", lr: &Response{ StatusCode: 201, Proto: "1.1", Header: http.Header{"h": {"v"}, "Content-Length": {"17"}}, Body: []byte("text"), }, req: &http.Request{Method: "HEAD"}, want: &http.Response{ Request: &http.Request{Method: "HEAD"}, StatusCode: 201, Proto: "1.1", Header: http.Header{"h": {"v"}, "Content-Length": {"17"}}, ContentLength: 17, }, }, } { got := toHTTPResponse(test.lr, test.req) got.Body = nil if diff := testutil.Diff(got, test.want, cmpopts.IgnoreUnexported(http.Request{})); diff != "" { t.Errorf("%s: %s", test.desc, diff) } } } func TestEmptyBody(t *testing.T) { // Verify that a zero-length body is nil after logging. // That will ensure that net/http sends a "Content-Length: 0" header. req := &http.Request{ Method: "POST", URL: &url.URL{ Scheme: "https", Host: "example.com", Path: "a/b/c", }, Body: ioutil.NopCloser(strings.NewReader("")), } l := newLogger() _, remove, err := martian.TestContext(req, nil, nil) if err != nil { t.Fatal(err) } defer remove() if err := l.ModifyRequest(req); err != nil { t.Fatal(err) } if req.Body != nil { t.Error("got non-nil req.Body, want nil") } } google-cloud-go-0.49.0/httpreplay/internal/proxy/record.go000066400000000000000000000153171356504100700235750ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package proxy provides a record/replay HTTP proxy. It is designed to support // both an in-memory API (cloud.google.com/go/httpreplay) and a standalone server // (cloud.google.com/go/httpreplay/cmd/httpr). package proxy // See github.com/google/martian/cmd/proxy/main.go for the origin of much of this. import ( "crypto/tls" "crypto/x509" "encoding/json" "fmt" "io/ioutil" "net" "net/http" "net/url" "strings" "sync" "time" "github.com/google/martian" "github.com/google/martian/fifo" "github.com/google/martian/httpspec" "github.com/google/martian/martianlog" "github.com/google/martian/mitm" ) // A Proxy is an HTTP proxy that supports recording or replaying requests. type Proxy struct { // The certificate that the proxy uses to participate in TLS. CACert *x509.Certificate // The URL of the proxy. URL *url.URL // Initial state of the client. Initial []byte mproxy *martian.Proxy filename string // for log logger *Logger // for recording only ignoreHeaders map[string]bool // headers the user has asked to ignore } // ForRecording returns a Proxy configured to record. func ForRecording(filename string, port int) (*Proxy, error) { p, err := newProxy(filename) if err != nil { return nil, err } // Construct a group that performs the standard proxy stack of request/response // modifications. stack, _ := httpspec.NewStack("httpr") // second arg is an internal group that we don't need p.mproxy.SetRequestModifier(stack) p.mproxy.SetResponseModifier(stack) // Make a group for logging requests and responses. logGroup := fifo.NewGroup() skipAuth := skipLoggingByHost("accounts.google.com") logGroup.AddRequestModifier(skipAuth) logGroup.AddResponseModifier(skipAuth) p.logger = newLogger() logGroup.AddRequestModifier(p.logger) logGroup.AddResponseModifier(p.logger) stack.AddRequestModifier(logGroup) stack.AddResponseModifier(logGroup) // Ordinary debug logging. logger := martianlog.NewLogger() logger.SetDecode(true) stack.AddRequestModifier(logger) stack.AddResponseModifier(logger) if err := p.start(port); err != nil { return nil, err } return p, nil } var ( configOnce sync.Once cert *x509.Certificate config *mitm.Config configErr error ) func newProxy(filename string) (*Proxy, error) { configOnce.Do(func() { // Set up a man-in-the-middle configuration with a CA certificate so the proxy can // participate in TLS. x509c, priv, err := mitm.NewAuthority("cloud.google.com/go/httpreplay", "HTTPReplay Authority", 100*time.Hour) if err != nil { configErr = err return } cert = x509c config, configErr = mitm.NewConfig(x509c, priv) if config != nil { config.SetValidity(100 * time.Hour) config.SetOrganization("cloud.google.com/go/httpreplay") config.SkipTLSVerify(false) } }) if configErr != nil { return nil, configErr } mproxy := martian.NewProxy() mproxy.SetMITM(config) return &Proxy{ mproxy: mproxy, CACert: cert, filename: filename, ignoreHeaders: map[string]bool{}, }, nil } func (p *Proxy) start(port int) error { l, err := net.Listen("tcp", fmt.Sprintf(":%d", port)) if err != nil { return err } p.URL = &url.URL{Scheme: "http", Host: l.Addr().String()} go p.mproxy.Serve(l) return nil } // Transport returns an http.Transport for clients who want to talk to the proxy. func (p *Proxy) Transport() *http.Transport { caCertPool := x509.NewCertPool() caCertPool.AddCert(p.CACert) return &http.Transport{ TLSClientConfig: &tls.Config{RootCAs: caCertPool}, Proxy: func(*http.Request) (*url.URL, error) { return p.URL, nil }, } } // RemoveRequestHeaders will remove request headers matching patterns from the log, // and skip matching them. Pattern is taken literally except for *, which matches any // sequence of characters. // // This only needs to be called during recording; the patterns will be saved to the // log for replay. func (p *Proxy) RemoveRequestHeaders(patterns []string) { for _, pat := range patterns { p.logger.log.Converter.registerRemoveRequestHeaders(pat) } } // ClearHeaders will replace matching headers with CLEARED. // // This only needs to be called during recording; the patterns will be saved to the // log for replay. func (p *Proxy) ClearHeaders(patterns []string) { for _, pat := range patterns { p.logger.log.Converter.registerClearHeaders(pat) } } // RemoveQueryParams will remove query parameters matching patterns from the request // URL before logging, and skip matching them. Pattern is taken literally except for // *, which matches any sequence of characters. // // This only needs to be called during recording; the patterns will be saved to the // log for replay. func (p *Proxy) RemoveQueryParams(patterns []string) { for _, pat := range patterns { p.logger.log.Converter.registerRemoveParams(pat) } } // ClearQueryParams will replace matching query params in the request URL with CLEARED. // // This only needs to be called during recording; the patterns will be saved to the // log for replay. func (p *Proxy) ClearQueryParams(patterns []string) { for _, pat := range patterns { p.logger.log.Converter.registerClearParams(pat) } } // IgnoreHeader will cause h to be ignored during matching on replay. // Deprecated: use RemoveRequestHeaders instead. func (p *Proxy) IgnoreHeader(h string) { p.ignoreHeaders[http.CanonicalHeaderKey(h)] = true } // Close closes the proxy. If the proxy is recording, it also writes the log. func (p *Proxy) Close() error { p.mproxy.Close() if p.logger != nil { return p.writeLog() } return nil } func (p *Proxy) writeLog() error { lg := p.logger.Extract() lg.Initial = p.Initial bytes, err := json.MarshalIndent(lg, "", " ") if err != nil { return err } return ioutil.WriteFile(p.filename, bytes, 0600) // only accessible by owner } // skipLoggingByHost disables logging for traffic to a particular host. type skipLoggingByHost string func (s skipLoggingByHost) ModifyRequest(req *http.Request) error { if strings.HasPrefix(req.Host, string(s)) { martian.NewContext(req).SkipLogging() } return nil } func (s skipLoggingByHost) ModifyResponse(res *http.Response) error { return s.ModifyRequest(res.Request) } google-cloud-go-0.49.0/httpreplay/internal/proxy/replay.go000066400000000000000000000122001356504100700235770ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package proxy import ( "bytes" "encoding/json" "errors" "fmt" "io/ioutil" "log" "net/http" "reflect" "sync" "github.com/google/martian/martianlog" ) // ForReplaying returns a Proxy configured to replay. func ForReplaying(filename string, port int) (*Proxy, error) { p, err := newProxy(filename) if err != nil { return nil, err } lg, err := readLog(filename) if err != nil { return nil, err } calls, err := constructCalls(lg) if err != nil { return nil, err } p.Initial = lg.Initial p.mproxy.SetRoundTripper(&replayRoundTripper{ calls: calls, ignoreHeaders: p.ignoreHeaders, conv: lg.Converter, }) // Debug logging. // TODO(jba): factor out from here and ForRecording. logger := martianlog.NewLogger() logger.SetDecode(true) p.mproxy.SetRequestModifier(logger) p.mproxy.SetResponseModifier(logger) if err := p.start(port); err != nil { return nil, err } return p, nil } func readLog(filename string) (*Log, error) { bytes, err := ioutil.ReadFile(filename) if err != nil { return nil, err } var lg Log if err := json.Unmarshal(bytes, &lg); err != nil { return nil, fmt.Errorf("%s: %v", filename, err) } if lg.Version != LogVersion { return nil, fmt.Errorf( "httpreplay: read log version %s but current version is %s; re-record the log", lg.Version, LogVersion) } return &lg, nil } // A call is an HTTP request and its matching response. type call struct { req *Request res *Response } func constructCalls(lg *Log) ([]*call, error) { ignoreIDs := map[string]bool{} // IDs of requests to ignore callsByID := map[string]*call{} var calls []*call for _, e := range lg.Entries { if ignoreIDs[e.ID] { continue } c, ok := callsByID[e.ID] switch { case !ok: if e.Request == nil { return nil, fmt.Errorf("first entry for ID %s does not have a request", e.ID) } if e.Request.Method == "CONNECT" { // Ignore CONNECT methods. ignoreIDs[e.ID] = true } else { c := &call{e.Request, e.Response} calls = append(calls, c) callsByID[e.ID] = c } case e.Request != nil: if e.Response != nil { return nil, errors.New("entry has both request and response") } c.req = e.Request case e.Response != nil: c.res = e.Response default: return nil, errors.New("entry has neither request nor response") } } for _, c := range calls { if c.req == nil || c.res == nil { return nil, fmt.Errorf("missing request or response: %+v", c) } } return calls, nil } type replayRoundTripper struct { mu sync.Mutex calls []*call ignoreHeaders map[string]bool conv *Converter } func (r *replayRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { if req.Body != nil { defer req.Body.Close() } creq, err := r.conv.convertRequest(req) if err != nil { return nil, err } r.mu.Lock() defer r.mu.Unlock() for i, call := range r.calls { if call == nil { continue } if requestsMatch(creq, call.req, r.ignoreHeaders) { r.calls[i] = nil // nil out this call so we don't reuse it return toHTTPResponse(call.res, req), nil } } return nil, fmt.Errorf("no matching request for %+v", req) } // Report whether the incoming request in matches the candidate request cand. func requestsMatch(in, cand *Request, ignoreHeaders map[string]bool) bool { if in.Method != cand.Method { return false } if in.URL != cand.URL { return false } if in.MediaType != cand.MediaType { return false } if len(in.BodyParts) != len(cand.BodyParts) { return false } for i, p1 := range in.BodyParts { if !bytes.Equal(p1, cand.BodyParts[i]) { return false } } // Check headers last. See DebugHeaders. return headersMatch(in.Header, cand.Header, ignoreHeaders) } // DebugHeaders helps to determine whether a header should be ignored. // When true, if requests have the same method, URL and body but differ // in a header, the first mismatched header is logged. var DebugHeaders = false func headersMatch(in, cand http.Header, ignores map[string]bool) bool { for k1, v1 := range in { if ignores[k1] { continue } v2 := cand[k1] if v2 == nil { if DebugHeaders { log.Printf("header %s: present in incoming request but not candidate", k1) } return false } if !reflect.DeepEqual(v1, v2) { if DebugHeaders { log.Printf("header %s: incoming %v, candidate %v", k1, v1, v2) } return false } } for k2 := range cand { if ignores[k2] { continue } if in[k2] == nil { if DebugHeaders { log.Printf("header %s: not in incoming request but present in candidate", k2) } return false } } return true } google-cloud-go-0.49.0/httpreplay/internal/proxy/replay_test.go000066400000000000000000000050671356504100700246530ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package proxy import ( "net/http" "testing" "cloud.google.com/go/internal/testutil" ) func TestParseRequestBody(t *testing.T) { wantMediaType := "multipart/mixed" wantParts := [][]byte{ []byte("A section"), []byte("And another"), } for i, test := range []struct { contentType, body string }{ { wantMediaType + "; boundary=foo", "--foo\r\nFoo: one\r\n\r\nA section\r\n" + "--foo\r\nFoo: two\r\n\r\nAnd another\r\n" + "--foo--\r\n", }, // Same contents, different boundary. { wantMediaType + "; boundary=bar", "--bar\r\nFoo: one\r\n\r\nA section\r\n" + "--bar\r\nFoo: two\r\n\r\nAnd another\r\n" + "--bar--\r\n", }, } { gotMediaType, gotParts, err := parseRequestBody(test.contentType, []byte(test.body)) if err != nil { t.Fatalf("#%d: %v", i, err) } if gotMediaType != wantMediaType { t.Errorf("#%d: got %q, want %q", i, gotMediaType, wantMediaType) } if diff := testutil.Diff(gotParts, wantParts); diff != "" { t.Errorf("#%d: %s", i, diff) } } } func TestHeadersMatch(t *testing.T) { for _, test := range []struct { h1, h2 http.Header want bool }{ { http.Header{"A": {"x"}, "B": {"y", "z"}}, http.Header{"A": {"x"}, "B": {"y", "z"}}, true, }, { http.Header{"A": {"x"}, "B": {"y", "z"}}, http.Header{"A": {"x"}, "B": {"w"}}, false, }, { http.Header{"A": {"x"}, "B": {"y", "z"}, "I": {"foo"}}, http.Header{"A": {"x"}, "B": {"y", "z"}, "I": {"bar"}}, true, }, { http.Header{"A": {"x"}, "B": {"y", "z"}}, http.Header{"A": {"x"}, "B": {"y", "z"}, "I": {"bar"}}, true, }, { http.Header{"A": {"x"}, "B": {"y", "z"}, "I": {"foo"}}, http.Header{"A": {"x"}, "I": {"bar"}}, false, }, { http.Header{"A": {"x"}, "I": {"foo"}}, http.Header{"A": {"x"}, "B": {"y", "z"}, "I": {"bar"}}, false, }, } { got := headersMatch(test.h1, test.h2, map[string]bool{"I": true}) if got != test.want { t.Errorf("%v, %v: got %t, want %t", test.h1, test.h2, got, test.want) } } } google-cloud-go-0.49.0/iam/000077500000000000000000000000001356504100700153365ustar00rootroot00000000000000google-cloud-go-0.49.0/iam/.repo-metadata.json000066400000000000000000000006301356504100700210310ustar00rootroot00000000000000{ "name": "iam", "name_pretty": "Cloud Identify and Access Management API", "product_documentation": "https://cloud.google.com/iam", "client_documentation": "https://godoc.org/cloud.google.com/go/iam", "release_level": "ga", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go/iam", "api_id": "iam.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/iam/admin/000077500000000000000000000000001356504100700164265ustar00rootroot00000000000000google-cloud-go-0.49.0/iam/admin/apiv1/000077500000000000000000000000001356504100700174465ustar00rootroot00000000000000google-cloud-go-0.49.0/iam/admin/apiv1/.repo-metadata.json000066400000000000000000000006431356504100700231450ustar00rootroot00000000000000{ "name": "iam", "name_pretty": "Cloud Identify and Access Management API", "product_documentation": "https://cloud.google.com/iam", "client_documentation": "https://godoc.org/cloud.google.com/go/iam/admin/apiv1", "release_level": "alpha", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "iam.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/iam/admin/apiv1/doc.go000066400000000000000000000056241356504100700205510ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package admin is an auto-generated package for the // Google Identity and Access Management (IAM) API. // // NOTE: This package is in alpha. It is not stable, and is likely to change. // // Manages identity and access control for Google Cloud Platform resources, // including the creation of service accounts, which you can use to // authenticate to Google and make API calls. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package admin // import "cloud.google.com/go/iam/admin/apiv1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/iam", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "UNKNOWN" google-cloud-go-0.49.0/iam/admin/apiv1/iam_client.go000066400000000000000000000654311356504100700221120ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package admin import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" adminpb "google.golang.org/genproto/googleapis/iam/admin/v1" iampb "google.golang.org/genproto/googleapis/iam/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // IamCallOptions contains the retry settings for each method of IamClient. type IamCallOptions struct { ListServiceAccounts []gax.CallOption GetServiceAccount []gax.CallOption CreateServiceAccount []gax.CallOption UpdateServiceAccount []gax.CallOption DeleteServiceAccount []gax.CallOption ListServiceAccountKeys []gax.CallOption GetServiceAccountKey []gax.CallOption CreateServiceAccountKey []gax.CallOption DeleteServiceAccountKey []gax.CallOption SignBlob []gax.CallOption GetIamPolicy []gax.CallOption SetIamPolicy []gax.CallOption TestIamPermissions []gax.CallOption QueryGrantableRoles []gax.CallOption SignJwt []gax.CallOption ListRoles []gax.CallOption GetRole []gax.CallOption CreateRole []gax.CallOption UpdateRole []gax.CallOption DeleteRole []gax.CallOption UndeleteRole []gax.CallOption QueryTestablePermissions []gax.CallOption } func defaultIamClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("iam.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultIamCallOptions() *IamCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &IamCallOptions{ ListServiceAccounts: retry[[2]string{"default", "idempotent"}], GetServiceAccount: retry[[2]string{"default", "idempotent"}], CreateServiceAccount: retry[[2]string{"default", "non_idempotent"}], UpdateServiceAccount: retry[[2]string{"default", "idempotent"}], DeleteServiceAccount: retry[[2]string{"default", "idempotent"}], ListServiceAccountKeys: retry[[2]string{"default", "idempotent"}], GetServiceAccountKey: retry[[2]string{"default", "idempotent"}], CreateServiceAccountKey: retry[[2]string{"default", "non_idempotent"}], DeleteServiceAccountKey: retry[[2]string{"default", "idempotent"}], SignBlob: retry[[2]string{"default", "non_idempotent"}], GetIamPolicy: retry[[2]string{"default", "non_idempotent"}], SetIamPolicy: retry[[2]string{"default", "non_idempotent"}], TestIamPermissions: retry[[2]string{"default", "non_idempotent"}], QueryGrantableRoles: retry[[2]string{"default", "non_idempotent"}], SignJwt: retry[[2]string{"default", "non_idempotent"}], ListRoles: retry[[2]string{"default", "idempotent"}], GetRole: retry[[2]string{"default", "idempotent"}], CreateRole: retry[[2]string{"default", "non_idempotent"}], UpdateRole: retry[[2]string{"default", "non_idempotent"}], DeleteRole: retry[[2]string{"default", "non_idempotent"}], UndeleteRole: retry[[2]string{"default", "non_idempotent"}], QueryTestablePermissions: retry[[2]string{"default", "non_idempotent"}], } } // IamClient is a client for interacting with Google Identity and Access Management (IAM) API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type IamClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. iamClient adminpb.IAMClient // The call options for this service. CallOptions *IamCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewIamClient creates a new iam client. // // Creates and manages service account objects. // // Service account is an account that belongs to your project instead // of to an individual end user. It is used to authenticate calls // to a Google API. // // To create a service account, specify the project_id and account_id // for the account. The account_id is unique within the project, and used // to generate the service account email address and a stable // unique_id. // // All other methods can identify accounts using the format // projects/{PROJECT_ID}/serviceAccounts/{SERVICE_ACCOUNT_EMAIL}. // Using - as a wildcard for the project will infer the project from // the account. The account value can be the email address or the // unique_id of the service account. func NewIamClient(ctx context.Context, opts ...option.ClientOption) (*IamClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultIamClientOptions(), opts...)...) if err != nil { return nil, err } c := &IamClient{ conn: conn, CallOptions: defaultIamCallOptions(), iamClient: adminpb.NewIAMClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *IamClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *IamClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *IamClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // ListServiceAccounts lists [ServiceAccounts][google.iam.admin.v1.ServiceAccount] for a project. func (c *IamClient) ListServiceAccounts(ctx context.Context, req *adminpb.ListServiceAccountsRequest, opts ...gax.CallOption) *ServiceAccountIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListServiceAccounts[0:len(c.CallOptions.ListServiceAccounts):len(c.CallOptions.ListServiceAccounts)], opts...) it := &ServiceAccountIterator{} req = proto.Clone(req).(*adminpb.ListServiceAccountsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*adminpb.ServiceAccount, string, error) { var resp *adminpb.ListServiceAccountsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.iamClient.ListServiceAccounts(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Accounts, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetServiceAccount gets a [ServiceAccount][google.iam.admin.v1.ServiceAccount]. func (c *IamClient) GetServiceAccount(ctx context.Context, req *adminpb.GetServiceAccountRequest, opts ...gax.CallOption) (*adminpb.ServiceAccount, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetServiceAccount[0:len(c.CallOptions.GetServiceAccount):len(c.CallOptions.GetServiceAccount)], opts...) var resp *adminpb.ServiceAccount err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.iamClient.GetServiceAccount(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateServiceAccount creates a [ServiceAccount][google.iam.admin.v1.ServiceAccount] // and returns it. func (c *IamClient) CreateServiceAccount(ctx context.Context, req *adminpb.CreateServiceAccountRequest, opts ...gax.CallOption) (*adminpb.ServiceAccount, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateServiceAccount[0:len(c.CallOptions.CreateServiceAccount):len(c.CallOptions.CreateServiceAccount)], opts...) var resp *adminpb.ServiceAccount err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.iamClient.CreateServiceAccount(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateServiceAccount updates a [ServiceAccount][google.iam.admin.v1.ServiceAccount]. // // Currently, only the following fields are updatable: // display_name . // The etag is mandatory. func (c *IamClient) UpdateServiceAccount(ctx context.Context, req *adminpb.ServiceAccount, opts ...gax.CallOption) (*adminpb.ServiceAccount, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateServiceAccount[0:len(c.CallOptions.UpdateServiceAccount):len(c.CallOptions.UpdateServiceAccount)], opts...) var resp *adminpb.ServiceAccount err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.iamClient.UpdateServiceAccount(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteServiceAccount deletes a [ServiceAccount][google.iam.admin.v1.ServiceAccount]. func (c *IamClient) DeleteServiceAccount(ctx context.Context, req *adminpb.DeleteServiceAccountRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteServiceAccount[0:len(c.CallOptions.DeleteServiceAccount):len(c.CallOptions.DeleteServiceAccount)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.iamClient.DeleteServiceAccount(ctx, req, settings.GRPC...) return err }, opts...) return err } // ListServiceAccountKeys lists [ServiceAccountKeys][google.iam.admin.v1.ServiceAccountKey]. func (c *IamClient) ListServiceAccountKeys(ctx context.Context, req *adminpb.ListServiceAccountKeysRequest, opts ...gax.CallOption) (*adminpb.ListServiceAccountKeysResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListServiceAccountKeys[0:len(c.CallOptions.ListServiceAccountKeys):len(c.CallOptions.ListServiceAccountKeys)], opts...) var resp *adminpb.ListServiceAccountKeysResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.iamClient.ListServiceAccountKeys(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetServiceAccountKey gets the [ServiceAccountKey][google.iam.admin.v1.ServiceAccountKey] // by key id. func (c *IamClient) GetServiceAccountKey(ctx context.Context, req *adminpb.GetServiceAccountKeyRequest, opts ...gax.CallOption) (*adminpb.ServiceAccountKey, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetServiceAccountKey[0:len(c.CallOptions.GetServiceAccountKey):len(c.CallOptions.GetServiceAccountKey)], opts...) var resp *adminpb.ServiceAccountKey err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.iamClient.GetServiceAccountKey(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateServiceAccountKey creates a [ServiceAccountKey][google.iam.admin.v1.ServiceAccountKey] // and returns it. func (c *IamClient) CreateServiceAccountKey(ctx context.Context, req *adminpb.CreateServiceAccountKeyRequest, opts ...gax.CallOption) (*adminpb.ServiceAccountKey, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateServiceAccountKey[0:len(c.CallOptions.CreateServiceAccountKey):len(c.CallOptions.CreateServiceAccountKey)], opts...) var resp *adminpb.ServiceAccountKey err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.iamClient.CreateServiceAccountKey(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteServiceAccountKey deletes a [ServiceAccountKey][google.iam.admin.v1.ServiceAccountKey]. func (c *IamClient) DeleteServiceAccountKey(ctx context.Context, req *adminpb.DeleteServiceAccountKeyRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteServiceAccountKey[0:len(c.CallOptions.DeleteServiceAccountKey):len(c.CallOptions.DeleteServiceAccountKey)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.iamClient.DeleteServiceAccountKey(ctx, req, settings.GRPC...) return err }, opts...) return err } // SignBlob signs a blob using a service account's system-managed private key. func (c *IamClient) SignBlob(ctx context.Context, req *adminpb.SignBlobRequest, opts ...gax.CallOption) (*adminpb.SignBlobResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.SignBlob[0:len(c.CallOptions.SignBlob):len(c.CallOptions.SignBlob)], opts...) var resp *adminpb.SignBlobResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.iamClient.SignBlob(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // getIamPolicy returns the IAM access control policy for a // [ServiceAccount][google.iam.admin.v1.ServiceAccount]. func (c *IamClient) getIamPolicy(ctx context.Context, req *iampb.GetIamPolicyRequest, opts ...gax.CallOption) (*iampb.Policy, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetIamPolicy[0:len(c.CallOptions.GetIamPolicy):len(c.CallOptions.GetIamPolicy)], opts...) var resp *iampb.Policy err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.iamClient.GetIamPolicy(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // setIamPolicy sets the IAM access control policy for a // [ServiceAccount][google.iam.admin.v1.ServiceAccount]. func (c *IamClient) setIamPolicy(ctx context.Context, req *iampb.SetIamPolicyRequest, opts ...gax.CallOption) (*iampb.Policy, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.SetIamPolicy[0:len(c.CallOptions.SetIamPolicy):len(c.CallOptions.SetIamPolicy)], opts...) var resp *iampb.Policy err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.iamClient.SetIamPolicy(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // TestIamPermissions tests the specified permissions against the IAM access control policy // for a [ServiceAccount][google.iam.admin.v1.ServiceAccount]. func (c *IamClient) TestIamPermissions(ctx context.Context, req *iampb.TestIamPermissionsRequest, opts ...gax.CallOption) (*iampb.TestIamPermissionsResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.TestIamPermissions[0:len(c.CallOptions.TestIamPermissions):len(c.CallOptions.TestIamPermissions)], opts...) var resp *iampb.TestIamPermissionsResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.iamClient.TestIamPermissions(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // QueryGrantableRoles queries roles that can be granted on a particular resource. // A role is grantable if it can be used as the role in a binding for a policy // for that resource. func (c *IamClient) QueryGrantableRoles(ctx context.Context, req *adminpb.QueryGrantableRolesRequest, opts ...gax.CallOption) (*adminpb.QueryGrantableRolesResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.QueryGrantableRoles[0:len(c.CallOptions.QueryGrantableRoles):len(c.CallOptions.QueryGrantableRoles)], opts...) var resp *adminpb.QueryGrantableRolesResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.iamClient.QueryGrantableRoles(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // SignJwt signs a JWT using a service account's system-managed private key. // // If no expiry time (exp) is provided in the SignJwtRequest, IAM sets an // an expiry time of one hour by default. If you request an expiry time of // more than one hour, the request will fail. func (c *IamClient) SignJwt(ctx context.Context, req *adminpb.SignJwtRequest, opts ...gax.CallOption) (*adminpb.SignJwtResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.SignJwt[0:len(c.CallOptions.SignJwt):len(c.CallOptions.SignJwt)], opts...) var resp *adminpb.SignJwtResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.iamClient.SignJwt(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListRoles lists the Roles defined on a resource. func (c *IamClient) ListRoles(ctx context.Context, req *adminpb.ListRolesRequest, opts ...gax.CallOption) (*adminpb.ListRolesResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.ListRoles[0:len(c.CallOptions.ListRoles):len(c.CallOptions.ListRoles)], opts...) var resp *adminpb.ListRolesResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.iamClient.ListRoles(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetRole gets a Role definition. func (c *IamClient) GetRole(ctx context.Context, req *adminpb.GetRoleRequest, opts ...gax.CallOption) (*adminpb.Role, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetRole[0:len(c.CallOptions.GetRole):len(c.CallOptions.GetRole)], opts...) var resp *adminpb.Role err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.iamClient.GetRole(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateRole creates a new Role. func (c *IamClient) CreateRole(ctx context.Context, req *adminpb.CreateRoleRequest, opts ...gax.CallOption) (*adminpb.Role, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateRole[0:len(c.CallOptions.CreateRole):len(c.CallOptions.CreateRole)], opts...) var resp *adminpb.Role err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.iamClient.CreateRole(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateRole updates a Role definition. func (c *IamClient) UpdateRole(ctx context.Context, req *adminpb.UpdateRoleRequest, opts ...gax.CallOption) (*adminpb.Role, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateRole[0:len(c.CallOptions.UpdateRole):len(c.CallOptions.UpdateRole)], opts...) var resp *adminpb.Role err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.iamClient.UpdateRole(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteRole soft deletes a role. The role is suspended and cannot be used to create new // IAM Policy Bindings. // The Role will not be included in ListRoles() unless show_deleted is set // in the ListRolesRequest. The Role contains the deleted boolean set. // Existing Bindings remains, but are inactive. The Role can be undeleted // within 7 days. After 7 days the Role is deleted and all Bindings associated // with the role are removed. func (c *IamClient) DeleteRole(ctx context.Context, req *adminpb.DeleteRoleRequest, opts ...gax.CallOption) (*adminpb.Role, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteRole[0:len(c.CallOptions.DeleteRole):len(c.CallOptions.DeleteRole)], opts...) var resp *adminpb.Role err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.iamClient.DeleteRole(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UndeleteRole undelete a Role, bringing it back in its previous state. func (c *IamClient) UndeleteRole(ctx context.Context, req *adminpb.UndeleteRoleRequest, opts ...gax.CallOption) (*adminpb.Role, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UndeleteRole[0:len(c.CallOptions.UndeleteRole):len(c.CallOptions.UndeleteRole)], opts...) var resp *adminpb.Role err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.iamClient.UndeleteRole(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // QueryTestablePermissions lists the permissions testable on a resource. // A permission is testable if it can be tested for an identity on a resource. func (c *IamClient) QueryTestablePermissions(ctx context.Context, req *adminpb.QueryTestablePermissionsRequest, opts ...gax.CallOption) (*adminpb.QueryTestablePermissionsResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.QueryTestablePermissions[0:len(c.CallOptions.QueryTestablePermissions):len(c.CallOptions.QueryTestablePermissions)], opts...) var resp *adminpb.QueryTestablePermissionsResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.iamClient.QueryTestablePermissions(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ServiceAccountIterator manages a stream of *adminpb.ServiceAccount. type ServiceAccountIterator struct { items []*adminpb.ServiceAccount pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*adminpb.ServiceAccount, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *ServiceAccountIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *ServiceAccountIterator) Next() (*adminpb.ServiceAccount, error) { var item *adminpb.ServiceAccount if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *ServiceAccountIterator) bufLen() int { return len(it.items) } func (it *ServiceAccountIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/iam/admin/apiv1/iam_client_example_test.go000066400000000000000000000177741356504100700246730ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package admin_test import ( "context" admin "cloud.google.com/go/iam/admin/apiv1" "google.golang.org/api/iterator" adminpb "google.golang.org/genproto/googleapis/iam/admin/v1" iampb "google.golang.org/genproto/googleapis/iam/v1" ) func ExampleNewIamClient() { ctx := context.Background() c, err := admin.NewIamClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleIamClient_ListServiceAccounts() { ctx := context.Background() c, err := admin.NewIamClient(ctx) if err != nil { // TODO: Handle error. } req := &adminpb.ListServiceAccountsRequest{ // TODO: Fill request struct fields. } it := c.ListServiceAccounts(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleIamClient_GetServiceAccount() { ctx := context.Background() c, err := admin.NewIamClient(ctx) if err != nil { // TODO: Handle error. } req := &adminpb.GetServiceAccountRequest{ // TODO: Fill request struct fields. } resp, err := c.GetServiceAccount(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIamClient_CreateServiceAccount() { ctx := context.Background() c, err := admin.NewIamClient(ctx) if err != nil { // TODO: Handle error. } req := &adminpb.CreateServiceAccountRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateServiceAccount(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIamClient_UpdateServiceAccount() { ctx := context.Background() c, err := admin.NewIamClient(ctx) if err != nil { // TODO: Handle error. } req := &adminpb.ServiceAccount{ // TODO: Fill request struct fields. } resp, err := c.UpdateServiceAccount(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIamClient_DeleteServiceAccount() { ctx := context.Background() c, err := admin.NewIamClient(ctx) if err != nil { // TODO: Handle error. } req := &adminpb.DeleteServiceAccountRequest{ // TODO: Fill request struct fields. } err = c.DeleteServiceAccount(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleIamClient_ListServiceAccountKeys() { ctx := context.Background() c, err := admin.NewIamClient(ctx) if err != nil { // TODO: Handle error. } req := &adminpb.ListServiceAccountKeysRequest{ // TODO: Fill request struct fields. } resp, err := c.ListServiceAccountKeys(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIamClient_GetServiceAccountKey() { ctx := context.Background() c, err := admin.NewIamClient(ctx) if err != nil { // TODO: Handle error. } req := &adminpb.GetServiceAccountKeyRequest{ // TODO: Fill request struct fields. } resp, err := c.GetServiceAccountKey(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIamClient_CreateServiceAccountKey() { ctx := context.Background() c, err := admin.NewIamClient(ctx) if err != nil { // TODO: Handle error. } req := &adminpb.CreateServiceAccountKeyRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateServiceAccountKey(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIamClient_DeleteServiceAccountKey() { ctx := context.Background() c, err := admin.NewIamClient(ctx) if err != nil { // TODO: Handle error. } req := &adminpb.DeleteServiceAccountKeyRequest{ // TODO: Fill request struct fields. } err = c.DeleteServiceAccountKey(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleIamClient_SignBlob() { ctx := context.Background() c, err := admin.NewIamClient(ctx) if err != nil { // TODO: Handle error. } req := &adminpb.SignBlobRequest{ // TODO: Fill request struct fields. } resp, err := c.SignBlob(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIamClient_TestIamPermissions() { ctx := context.Background() c, err := admin.NewIamClient(ctx) if err != nil { // TODO: Handle error. } req := &iampb.TestIamPermissionsRequest{ // TODO: Fill request struct fields. } resp, err := c.TestIamPermissions(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIamClient_QueryGrantableRoles() { ctx := context.Background() c, err := admin.NewIamClient(ctx) if err != nil { // TODO: Handle error. } req := &adminpb.QueryGrantableRolesRequest{ // TODO: Fill request struct fields. } resp, err := c.QueryGrantableRoles(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIamClient_SignJwt() { ctx := context.Background() c, err := admin.NewIamClient(ctx) if err != nil { // TODO: Handle error. } req := &adminpb.SignJwtRequest{ // TODO: Fill request struct fields. } resp, err := c.SignJwt(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIamClient_ListRoles() { ctx := context.Background() c, err := admin.NewIamClient(ctx) if err != nil { // TODO: Handle error. } req := &adminpb.ListRolesRequest{ // TODO: Fill request struct fields. } resp, err := c.ListRoles(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIamClient_GetRole() { ctx := context.Background() c, err := admin.NewIamClient(ctx) if err != nil { // TODO: Handle error. } req := &adminpb.GetRoleRequest{ // TODO: Fill request struct fields. } resp, err := c.GetRole(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIamClient_CreateRole() { ctx := context.Background() c, err := admin.NewIamClient(ctx) if err != nil { // TODO: Handle error. } req := &adminpb.CreateRoleRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateRole(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIamClient_UpdateRole() { ctx := context.Background() c, err := admin.NewIamClient(ctx) if err != nil { // TODO: Handle error. } req := &adminpb.UpdateRoleRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateRole(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIamClient_DeleteRole() { ctx := context.Background() c, err := admin.NewIamClient(ctx) if err != nil { // TODO: Handle error. } req := &adminpb.DeleteRoleRequest{ // TODO: Fill request struct fields. } resp, err := c.DeleteRole(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIamClient_UndeleteRole() { ctx := context.Background() c, err := admin.NewIamClient(ctx) if err != nil { // TODO: Handle error. } req := &adminpb.UndeleteRoleRequest{ // TODO: Fill request struct fields. } resp, err := c.UndeleteRole(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIamClient_QueryTestablePermissions() { ctx := context.Background() c, err := admin.NewIamClient(ctx) if err != nil { // TODO: Handle error. } req := &adminpb.QueryTestablePermissionsRequest{ // TODO: Fill request struct fields. } resp, err := c.QueryTestablePermissions(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/iam/admin/apiv1/mock_test.go000066400000000000000000001371771356504100700220050ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package admin import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" "google.golang.org/api/option" adminpb "google.golang.org/genproto/googleapis/iam/admin/v1" iampb "google.golang.org/genproto/googleapis/iam/v1" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockIamServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. adminpb.IAMServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockIamServer) ListServiceAccounts(ctx context.Context, req *adminpb.ListServiceAccountsRequest) (*adminpb.ListServiceAccountsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*adminpb.ListServiceAccountsResponse), nil } func (s *mockIamServer) GetServiceAccount(ctx context.Context, req *adminpb.GetServiceAccountRequest) (*adminpb.ServiceAccount, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*adminpb.ServiceAccount), nil } func (s *mockIamServer) CreateServiceAccount(ctx context.Context, req *adminpb.CreateServiceAccountRequest) (*adminpb.ServiceAccount, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*adminpb.ServiceAccount), nil } func (s *mockIamServer) UpdateServiceAccount(ctx context.Context, req *adminpb.ServiceAccount) (*adminpb.ServiceAccount, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*adminpb.ServiceAccount), nil } func (s *mockIamServer) DeleteServiceAccount(ctx context.Context, req *adminpb.DeleteServiceAccountRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockIamServer) ListServiceAccountKeys(ctx context.Context, req *adminpb.ListServiceAccountKeysRequest) (*adminpb.ListServiceAccountKeysResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*adminpb.ListServiceAccountKeysResponse), nil } func (s *mockIamServer) GetServiceAccountKey(ctx context.Context, req *adminpb.GetServiceAccountKeyRequest) (*adminpb.ServiceAccountKey, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*adminpb.ServiceAccountKey), nil } func (s *mockIamServer) CreateServiceAccountKey(ctx context.Context, req *adminpb.CreateServiceAccountKeyRequest) (*adminpb.ServiceAccountKey, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*adminpb.ServiceAccountKey), nil } func (s *mockIamServer) DeleteServiceAccountKey(ctx context.Context, req *adminpb.DeleteServiceAccountKeyRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockIamServer) SignBlob(ctx context.Context, req *adminpb.SignBlobRequest) (*adminpb.SignBlobResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*adminpb.SignBlobResponse), nil } func (s *mockIamServer) SignJwt(ctx context.Context, req *adminpb.SignJwtRequest) (*adminpb.SignJwtResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*adminpb.SignJwtResponse), nil } func (s *mockIamServer) GetIamPolicy(ctx context.Context, req *iampb.GetIamPolicyRequest) (*iampb.Policy, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iampb.Policy), nil } func (s *mockIamServer) SetIamPolicy(ctx context.Context, req *iampb.SetIamPolicyRequest) (*iampb.Policy, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iampb.Policy), nil } func (s *mockIamServer) TestIamPermissions(ctx context.Context, req *iampb.TestIamPermissionsRequest) (*iampb.TestIamPermissionsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iampb.TestIamPermissionsResponse), nil } func (s *mockIamServer) QueryGrantableRoles(ctx context.Context, req *adminpb.QueryGrantableRolesRequest) (*adminpb.QueryGrantableRolesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*adminpb.QueryGrantableRolesResponse), nil } func (s *mockIamServer) ListRoles(ctx context.Context, req *adminpb.ListRolesRequest) (*adminpb.ListRolesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*adminpb.ListRolesResponse), nil } func (s *mockIamServer) GetRole(ctx context.Context, req *adminpb.GetRoleRequest) (*adminpb.Role, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*adminpb.Role), nil } func (s *mockIamServer) CreateRole(ctx context.Context, req *adminpb.CreateRoleRequest) (*adminpb.Role, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*adminpb.Role), nil } func (s *mockIamServer) UpdateRole(ctx context.Context, req *adminpb.UpdateRoleRequest) (*adminpb.Role, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*adminpb.Role), nil } func (s *mockIamServer) DeleteRole(ctx context.Context, req *adminpb.DeleteRoleRequest) (*adminpb.Role, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*adminpb.Role), nil } func (s *mockIamServer) UndeleteRole(ctx context.Context, req *adminpb.UndeleteRoleRequest) (*adminpb.Role, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*adminpb.Role), nil } func (s *mockIamServer) QueryTestablePermissions(ctx context.Context, req *adminpb.QueryTestablePermissionsRequest) (*adminpb.QueryTestablePermissionsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*adminpb.QueryTestablePermissionsResponse), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockIam mockIamServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() adminpb.RegisterIAMServer(serv, &mockIam) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestIamListServiceAccounts(t *testing.T) { var nextPageToken string = "" var accountsElement *adminpb.ServiceAccount = &adminpb.ServiceAccount{} var accounts = []*adminpb.ServiceAccount{accountsElement} var expectedResponse = &adminpb.ListServiceAccountsResponse{ NextPageToken: nextPageToken, Accounts: accounts, } mockIam.err = nil mockIam.reqs = nil mockIam.resps = append(mockIam.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &adminpb.ListServiceAccountsRequest{ Name: formattedName, } c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListServiceAccounts(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockIam.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Accounts[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIamListServiceAccountsError(t *testing.T) { errCode := codes.PermissionDenied mockIam.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &adminpb.ListServiceAccountsRequest{ Name: formattedName, } c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListServiceAccounts(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIamGetServiceAccount(t *testing.T) { var name2 string = "name2-1052831874" var projectId string = "projectId-1969970175" var uniqueId string = "uniqueId-538310583" var email string = "email96619420" var displayName string = "displayName1615086568" var etag []byte = []byte("21") var oauth2ClientId string = "oauth2ClientId-1833466037" var expectedResponse = &adminpb.ServiceAccount{ Name: name2, ProjectId: projectId, UniqueId: uniqueId, Email: email, DisplayName: displayName, Etag: etag, Oauth2ClientId: oauth2ClientId, } mockIam.err = nil mockIam.reqs = nil mockIam.resps = append(mockIam.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/serviceAccounts/%s", "[PROJECT]", "[SERVICE_ACCOUNT]") var request = &adminpb.GetServiceAccountRequest{ Name: formattedName, } c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetServiceAccount(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIam.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIamGetServiceAccountError(t *testing.T) { errCode := codes.PermissionDenied mockIam.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/serviceAccounts/%s", "[PROJECT]", "[SERVICE_ACCOUNT]") var request = &adminpb.GetServiceAccountRequest{ Name: formattedName, } c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetServiceAccount(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIamCreateServiceAccount(t *testing.T) { var name2 string = "name2-1052831874" var projectId string = "projectId-1969970175" var uniqueId string = "uniqueId-538310583" var email string = "email96619420" var displayName string = "displayName1615086568" var etag []byte = []byte("21") var oauth2ClientId string = "oauth2ClientId-1833466037" var expectedResponse = &adminpb.ServiceAccount{ Name: name2, ProjectId: projectId, UniqueId: uniqueId, Email: email, DisplayName: displayName, Etag: etag, Oauth2ClientId: oauth2ClientId, } mockIam.err = nil mockIam.reqs = nil mockIam.resps = append(mockIam.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s", "[PROJECT]") var accountId string = "accountId-803333011" var request = &adminpb.CreateServiceAccountRequest{ Name: formattedName, AccountId: accountId, } c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateServiceAccount(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIam.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIamCreateServiceAccountError(t *testing.T) { errCode := codes.PermissionDenied mockIam.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s", "[PROJECT]") var accountId string = "accountId-803333011" var request = &adminpb.CreateServiceAccountRequest{ Name: formattedName, AccountId: accountId, } c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateServiceAccount(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIamUpdateServiceAccount(t *testing.T) { var name string = "name3373707" var projectId string = "projectId-1969970175" var uniqueId string = "uniqueId-538310583" var email string = "email96619420" var displayName string = "displayName1615086568" var etag2 []byte = []byte("-120") var oauth2ClientId string = "oauth2ClientId-1833466037" var expectedResponse = &adminpb.ServiceAccount{ Name: name, ProjectId: projectId, UniqueId: uniqueId, Email: email, DisplayName: displayName, Etag: etag2, Oauth2ClientId: oauth2ClientId, } mockIam.err = nil mockIam.reqs = nil mockIam.resps = append(mockIam.resps[:0], expectedResponse) var etag []byte = []byte("21") var request = &adminpb.ServiceAccount{ Etag: etag, } c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateServiceAccount(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIam.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIamUpdateServiceAccountError(t *testing.T) { errCode := codes.PermissionDenied mockIam.err = gstatus.Error(errCode, "test error") var etag []byte = []byte("21") var request = &adminpb.ServiceAccount{ Etag: etag, } c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateServiceAccount(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIamDeleteServiceAccount(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockIam.err = nil mockIam.reqs = nil mockIam.resps = append(mockIam.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/serviceAccounts/%s", "[PROJECT]", "[SERVICE_ACCOUNT]") var request = &adminpb.DeleteServiceAccountRequest{ Name: formattedName, } c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteServiceAccount(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIam.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestIamDeleteServiceAccountError(t *testing.T) { errCode := codes.PermissionDenied mockIam.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/serviceAccounts/%s", "[PROJECT]", "[SERVICE_ACCOUNT]") var request = &adminpb.DeleteServiceAccountRequest{ Name: formattedName, } c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteServiceAccount(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestIamListServiceAccountKeys(t *testing.T) { var expectedResponse *adminpb.ListServiceAccountKeysResponse = &adminpb.ListServiceAccountKeysResponse{} mockIam.err = nil mockIam.reqs = nil mockIam.resps = append(mockIam.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/serviceAccounts/%s", "[PROJECT]", "[SERVICE_ACCOUNT]") var request = &adminpb.ListServiceAccountKeysRequest{ Name: formattedName, } c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListServiceAccountKeys(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIam.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIamListServiceAccountKeysError(t *testing.T) { errCode := codes.PermissionDenied mockIam.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/serviceAccounts/%s", "[PROJECT]", "[SERVICE_ACCOUNT]") var request = &adminpb.ListServiceAccountKeysRequest{ Name: formattedName, } c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListServiceAccountKeys(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIamGetServiceAccountKey(t *testing.T) { var name2 string = "name2-1052831874" var privateKeyData []byte = []byte("-58") var publicKeyData []byte = []byte("-96") var expectedResponse = &adminpb.ServiceAccountKey{ Name: name2, PrivateKeyData: privateKeyData, PublicKeyData: publicKeyData, } mockIam.err = nil mockIam.reqs = nil mockIam.resps = append(mockIam.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/serviceAccounts/%s/keys/%s", "[PROJECT]", "[SERVICE_ACCOUNT]", "[KEY]") var request = &adminpb.GetServiceAccountKeyRequest{ Name: formattedName, } c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetServiceAccountKey(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIam.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIamGetServiceAccountKeyError(t *testing.T) { errCode := codes.PermissionDenied mockIam.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/serviceAccounts/%s/keys/%s", "[PROJECT]", "[SERVICE_ACCOUNT]", "[KEY]") var request = &adminpb.GetServiceAccountKeyRequest{ Name: formattedName, } c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetServiceAccountKey(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIamCreateServiceAccountKey(t *testing.T) { var name2 string = "name2-1052831874" var privateKeyData []byte = []byte("-58") var publicKeyData []byte = []byte("-96") var expectedResponse = &adminpb.ServiceAccountKey{ Name: name2, PrivateKeyData: privateKeyData, PublicKeyData: publicKeyData, } mockIam.err = nil mockIam.reqs = nil mockIam.resps = append(mockIam.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/serviceAccounts/%s", "[PROJECT]", "[SERVICE_ACCOUNT]") var request = &adminpb.CreateServiceAccountKeyRequest{ Name: formattedName, } c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateServiceAccountKey(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIam.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIamCreateServiceAccountKeyError(t *testing.T) { errCode := codes.PermissionDenied mockIam.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/serviceAccounts/%s", "[PROJECT]", "[SERVICE_ACCOUNT]") var request = &adminpb.CreateServiceAccountKeyRequest{ Name: formattedName, } c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateServiceAccountKey(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIamDeleteServiceAccountKey(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockIam.err = nil mockIam.reqs = nil mockIam.resps = append(mockIam.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/serviceAccounts/%s/keys/%s", "[PROJECT]", "[SERVICE_ACCOUNT]", "[KEY]") var request = &adminpb.DeleteServiceAccountKeyRequest{ Name: formattedName, } c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteServiceAccountKey(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIam.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestIamDeleteServiceAccountKeyError(t *testing.T) { errCode := codes.PermissionDenied mockIam.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/serviceAccounts/%s/keys/%s", "[PROJECT]", "[SERVICE_ACCOUNT]", "[KEY]") var request = &adminpb.DeleteServiceAccountKeyRequest{ Name: formattedName, } c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteServiceAccountKey(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestIamSignBlob(t *testing.T) { var keyId string = "keyId-1134673157" var signature []byte = []byte("-72") var expectedResponse = &adminpb.SignBlobResponse{ KeyId: keyId, Signature: signature, } mockIam.err = nil mockIam.reqs = nil mockIam.resps = append(mockIam.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/serviceAccounts/%s", "[PROJECT]", "[SERVICE_ACCOUNT]") var bytesToSign []byte = []byte("45") var request = &adminpb.SignBlobRequest{ Name: formattedName, BytesToSign: bytesToSign, } c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SignBlob(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIam.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIamSignBlobError(t *testing.T) { errCode := codes.PermissionDenied mockIam.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/serviceAccounts/%s", "[PROJECT]", "[SERVICE_ACCOUNT]") var bytesToSign []byte = []byte("45") var request = &adminpb.SignBlobRequest{ Name: formattedName, BytesToSign: bytesToSign, } c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SignBlob(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIamGetIamPolicy(t *testing.T) { var version int32 = 351608024 var etag []byte = []byte("21") var expectedResponse = &iampb.Policy{ Version: version, Etag: etag, } mockIam.err = nil mockIam.reqs = nil mockIam.resps = append(mockIam.resps[:0], expectedResponse) var formattedResource string = fmt.Sprintf("projects/%s/serviceAccounts/%s", "[PROJECT]", "[SERVICE_ACCOUNT]") var request = &iampb.GetIamPolicyRequest{ Resource: formattedResource, } c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.getIamPolicy(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIam.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIamGetIamPolicyError(t *testing.T) { errCode := codes.PermissionDenied mockIam.err = gstatus.Error(errCode, "test error") var formattedResource string = fmt.Sprintf("projects/%s/serviceAccounts/%s", "[PROJECT]", "[SERVICE_ACCOUNT]") var request = &iampb.GetIamPolicyRequest{ Resource: formattedResource, } c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.getIamPolicy(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIamSetIamPolicy(t *testing.T) { var version int32 = 351608024 var etag []byte = []byte("21") var expectedResponse = &iampb.Policy{ Version: version, Etag: etag, } mockIam.err = nil mockIam.reqs = nil mockIam.resps = append(mockIam.resps[:0], expectedResponse) var formattedResource string = fmt.Sprintf("projects/%s/serviceAccounts/%s", "[PROJECT]", "[SERVICE_ACCOUNT]") var policy *iampb.Policy = &iampb.Policy{} var request = &iampb.SetIamPolicyRequest{ Resource: formattedResource, Policy: policy, } c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.setIamPolicy(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIam.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIamSetIamPolicyError(t *testing.T) { errCode := codes.PermissionDenied mockIam.err = gstatus.Error(errCode, "test error") var formattedResource string = fmt.Sprintf("projects/%s/serviceAccounts/%s", "[PROJECT]", "[SERVICE_ACCOUNT]") var policy *iampb.Policy = &iampb.Policy{} var request = &iampb.SetIamPolicyRequest{ Resource: formattedResource, Policy: policy, } c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.setIamPolicy(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIamTestIamPermissions(t *testing.T) { var expectedResponse *iampb.TestIamPermissionsResponse = &iampb.TestIamPermissionsResponse{} mockIam.err = nil mockIam.reqs = nil mockIam.resps = append(mockIam.resps[:0], expectedResponse) var formattedResource string = fmt.Sprintf("projects/%s/serviceAccounts/%s", "[PROJECT]", "[SERVICE_ACCOUNT]") var permissions []string = nil var request = &iampb.TestIamPermissionsRequest{ Resource: formattedResource, Permissions: permissions, } c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.TestIamPermissions(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIam.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIamTestIamPermissionsError(t *testing.T) { errCode := codes.PermissionDenied mockIam.err = gstatus.Error(errCode, "test error") var formattedResource string = fmt.Sprintf("projects/%s/serviceAccounts/%s", "[PROJECT]", "[SERVICE_ACCOUNT]") var permissions []string = nil var request = &iampb.TestIamPermissionsRequest{ Resource: formattedResource, Permissions: permissions, } c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.TestIamPermissions(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIamQueryGrantableRoles(t *testing.T) { var nextPageToken string = "nextPageToken-1530815211" var expectedResponse = &adminpb.QueryGrantableRolesResponse{ NextPageToken: nextPageToken, } mockIam.err = nil mockIam.reqs = nil mockIam.resps = append(mockIam.resps[:0], expectedResponse) var fullResourceName string = "fullResourceName1300993644" var request = &adminpb.QueryGrantableRolesRequest{ FullResourceName: fullResourceName, } c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.QueryGrantableRoles(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIam.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIamQueryGrantableRolesError(t *testing.T) { errCode := codes.PermissionDenied mockIam.err = gstatus.Error(errCode, "test error") var fullResourceName string = "fullResourceName1300993644" var request = &adminpb.QueryGrantableRolesRequest{ FullResourceName: fullResourceName, } c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.QueryGrantableRoles(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIamSignJwt(t *testing.T) { var keyId string = "keyId-1134673157" var signedJwt string = "signedJwt-979546844" var expectedResponse = &adminpb.SignJwtResponse{ KeyId: keyId, SignedJwt: signedJwt, } mockIam.err = nil mockIam.reqs = nil mockIam.resps = append(mockIam.resps[:0], expectedResponse) var name string = "name3373707" var payload string = "payload-786701938" var request = &adminpb.SignJwtRequest{ Name: name, Payload: payload, } c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SignJwt(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIam.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIamSignJwtError(t *testing.T) { errCode := codes.PermissionDenied mockIam.err = gstatus.Error(errCode, "test error") var name string = "name3373707" var payload string = "payload-786701938" var request = &adminpb.SignJwtRequest{ Name: name, Payload: payload, } c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SignJwt(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIamListRoles(t *testing.T) { var nextPageToken string = "nextPageToken-1530815211" var expectedResponse = &adminpb.ListRolesResponse{ NextPageToken: nextPageToken, } mockIam.err = nil mockIam.reqs = nil mockIam.resps = append(mockIam.resps[:0], expectedResponse) var request *adminpb.ListRolesRequest = &adminpb.ListRolesRequest{} c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListRoles(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIam.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIamListRolesError(t *testing.T) { errCode := codes.PermissionDenied mockIam.err = gstatus.Error(errCode, "test error") var request *adminpb.ListRolesRequest = &adminpb.ListRolesRequest{} c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListRoles(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIamGetRole(t *testing.T) { var name string = "name3373707" var title string = "title110371416" var description string = "description-1724546052" var etag []byte = []byte("21") var deleted bool = false var expectedResponse = &adminpb.Role{ Name: name, Title: title, Description: description, Etag: etag, Deleted: deleted, } mockIam.err = nil mockIam.reqs = nil mockIam.resps = append(mockIam.resps[:0], expectedResponse) var request *adminpb.GetRoleRequest = &adminpb.GetRoleRequest{} c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetRole(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIam.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIamGetRoleError(t *testing.T) { errCode := codes.PermissionDenied mockIam.err = gstatus.Error(errCode, "test error") var request *adminpb.GetRoleRequest = &adminpb.GetRoleRequest{} c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetRole(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIamCreateRole(t *testing.T) { var name string = "name3373707" var title string = "title110371416" var description string = "description-1724546052" var etag []byte = []byte("21") var deleted bool = false var expectedResponse = &adminpb.Role{ Name: name, Title: title, Description: description, Etag: etag, Deleted: deleted, } mockIam.err = nil mockIam.reqs = nil mockIam.resps = append(mockIam.resps[:0], expectedResponse) var request *adminpb.CreateRoleRequest = &adminpb.CreateRoleRequest{} c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateRole(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIam.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIamCreateRoleError(t *testing.T) { errCode := codes.PermissionDenied mockIam.err = gstatus.Error(errCode, "test error") var request *adminpb.CreateRoleRequest = &adminpb.CreateRoleRequest{} c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateRole(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIamUpdateRole(t *testing.T) { var name string = "name3373707" var title string = "title110371416" var description string = "description-1724546052" var etag []byte = []byte("21") var deleted bool = false var expectedResponse = &adminpb.Role{ Name: name, Title: title, Description: description, Etag: etag, Deleted: deleted, } mockIam.err = nil mockIam.reqs = nil mockIam.resps = append(mockIam.resps[:0], expectedResponse) var request *adminpb.UpdateRoleRequest = &adminpb.UpdateRoleRequest{} c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateRole(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIam.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIamUpdateRoleError(t *testing.T) { errCode := codes.PermissionDenied mockIam.err = gstatus.Error(errCode, "test error") var request *adminpb.UpdateRoleRequest = &adminpb.UpdateRoleRequest{} c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateRole(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIamDeleteRole(t *testing.T) { var name string = "name3373707" var title string = "title110371416" var description string = "description-1724546052" var etag []byte = []byte("21") var deleted bool = false var expectedResponse = &adminpb.Role{ Name: name, Title: title, Description: description, Etag: etag, Deleted: deleted, } mockIam.err = nil mockIam.reqs = nil mockIam.resps = append(mockIam.resps[:0], expectedResponse) var request *adminpb.DeleteRoleRequest = &adminpb.DeleteRoleRequest{} c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.DeleteRole(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIam.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIamDeleteRoleError(t *testing.T) { errCode := codes.PermissionDenied mockIam.err = gstatus.Error(errCode, "test error") var request *adminpb.DeleteRoleRequest = &adminpb.DeleteRoleRequest{} c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.DeleteRole(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIamUndeleteRole(t *testing.T) { var name string = "name3373707" var title string = "title110371416" var description string = "description-1724546052" var etag []byte = []byte("21") var deleted bool = false var expectedResponse = &adminpb.Role{ Name: name, Title: title, Description: description, Etag: etag, Deleted: deleted, } mockIam.err = nil mockIam.reqs = nil mockIam.resps = append(mockIam.resps[:0], expectedResponse) var request *adminpb.UndeleteRoleRequest = &adminpb.UndeleteRoleRequest{} c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UndeleteRole(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIam.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIamUndeleteRoleError(t *testing.T) { errCode := codes.PermissionDenied mockIam.err = gstatus.Error(errCode, "test error") var request *adminpb.UndeleteRoleRequest = &adminpb.UndeleteRoleRequest{} c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UndeleteRole(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIamQueryTestablePermissions(t *testing.T) { var nextPageToken string = "nextPageToken-1530815211" var expectedResponse = &adminpb.QueryTestablePermissionsResponse{ NextPageToken: nextPageToken, } mockIam.err = nil mockIam.reqs = nil mockIam.resps = append(mockIam.resps[:0], expectedResponse) var request *adminpb.QueryTestablePermissionsRequest = &adminpb.QueryTestablePermissionsRequest{} c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.QueryTestablePermissions(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIam.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIamQueryTestablePermissionsError(t *testing.T) { errCode := codes.PermissionDenied mockIam.err = gstatus.Error(errCode, "test error") var request *adminpb.QueryTestablePermissionsRequest = &adminpb.QueryTestablePermissionsRequest{} c, err := NewIamClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.QueryTestablePermissions(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/iam/admin/apiv1/path_funcs.go000066400000000000000000000023061356504100700221300ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package admin // IamProjectPath returns the path for the project resource. func IamProjectPath(project string) string { return "" + "projects/" + project + "" } // IamServiceAccountPath returns the path for the service account resource. func IamServiceAccountPath(project, serviceAccount string) string { return "" + "projects/" + project + "/serviceAccounts/" + serviceAccount + "" } // IamKeyPath returns the path for the key resource. func IamKeyPath(project, serviceAccount, key string) string { return "" + "projects/" + project + "/serviceAccounts/" + serviceAccount + "/keys/" + key + "" } google-cloud-go-0.49.0/iam/admin/apiv1/policy_methods.go000066400000000000000000000032321356504100700230170ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // This is handwritten code. These methods are implemented by hand so they can use // the iam.Policy type. package admin import ( "context" "cloud.google.com/go/iam" iampb "google.golang.org/genproto/googleapis/iam/v1" ) // GetIamPolicy returns the IAM access control policy for a ServiceAccount. func (c *IamClient) GetIamPolicy(ctx context.Context, req *iampb.GetIamPolicyRequest) (*iam.Policy, error) { policy, err := c.getIamPolicy(ctx, req) if err != nil { return nil, err } return &iam.Policy{InternalProto: policy}, nil } // SetIamPolicyRequest is the request type for the SetIamPolicy method. type SetIamPolicyRequest struct { Resource string Policy *iam.Policy } // SetIamPolicy sets the IAM access control policy for a ServiceAccount. func (c *IamClient) SetIamPolicy(ctx context.Context, req *SetIamPolicyRequest) (*iam.Policy, error) { preq := &iampb.SetIamPolicyRequest{ Resource: req.Resource, Policy: req.Policy.InternalProto, } policy, err := c.setIamPolicy(ctx, preq) if err != nil { return nil, err } return &iam.Policy{InternalProto: policy}, nil } google-cloud-go-0.49.0/iam/credentials/000077500000000000000000000000001356504100700176335ustar00rootroot00000000000000google-cloud-go-0.49.0/iam/credentials/apiv1/000077500000000000000000000000001356504100700206535ustar00rootroot00000000000000google-cloud-go-0.49.0/iam/credentials/apiv1/.repo-metadata.json000066400000000000000000000006771356504100700243610ustar00rootroot00000000000000{ "name": "iamcredentials", "name_pretty": "Cloud Identify and Access Management API", "product_documentation": "https://cloud.google.com/iam", "client_documentation": "https://godoc.org/cloud.google.com/go/iam/credentials/apiv1", "release_level": "alpha", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "iamcredentials.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/iam/credentials/apiv1/doc.go000066400000000000000000000053331356504100700217530ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package credentials is an auto-generated package for the // IAM Service Account Credentials API. // // NOTE: This package is in alpha. It is not stable, and is likely to change. // // IAM Service Account Credentials API // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package credentials // import "cloud.google.com/go/iam/credentials/apiv1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191115" google-cloud-go-0.49.0/iam/credentials/apiv1/iam_credentials_client.go000066400000000000000000000177011356504100700256710ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package credentials import ( "context" "fmt" "math" "net/url" "time" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" "google.golang.org/api/transport" credentialspb "google.golang.org/genproto/googleapis/iam/credentials/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // IamCredentialsCallOptions contains the retry settings for each method of IamCredentialsClient. type IamCredentialsCallOptions struct { GenerateAccessToken []gax.CallOption GenerateIdToken []gax.CallOption SignBlob []gax.CallOption SignJwt []gax.CallOption } func defaultIamCredentialsClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("iamcredentials.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultIamCredentialsCallOptions() *IamCredentialsCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &IamCredentialsCallOptions{ GenerateAccessToken: retry[[2]string{"default", "idempotent"}], GenerateIdToken: retry[[2]string{"default", "idempotent"}], SignBlob: retry[[2]string{"default", "idempotent"}], SignJwt: retry[[2]string{"default", "idempotent"}], } } // IamCredentialsClient is a client for interacting with IAM Service Account Credentials API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type IamCredentialsClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. iamCredentialsClient credentialspb.IAMCredentialsClient // The call options for this service. CallOptions *IamCredentialsCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewIamCredentialsClient creates a new iam credentials client. // // A service account is a special type of Google account that belongs to your // application or a virtual machine (VM), instead of to an individual end user. // Your application assumes the identity of the service account to call Google // APIs, so that the users aren't directly involved. // // Service account credentials are used to temporarily assume the identity // of the service account. Supported credential types include OAuth 2.0 access // tokens, OpenID Connect ID tokens, self-signed JSON Web Tokens (JWTs), and // more. func NewIamCredentialsClient(ctx context.Context, opts ...option.ClientOption) (*IamCredentialsClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultIamCredentialsClientOptions(), opts...)...) if err != nil { return nil, err } c := &IamCredentialsClient{ conn: conn, CallOptions: defaultIamCredentialsCallOptions(), iamCredentialsClient: credentialspb.NewIAMCredentialsClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *IamCredentialsClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *IamCredentialsClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *IamCredentialsClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // GenerateAccessToken generates an OAuth 2.0 access token for a service account. func (c *IamCredentialsClient) GenerateAccessToken(ctx context.Context, req *credentialspb.GenerateAccessTokenRequest, opts ...gax.CallOption) (*credentialspb.GenerateAccessTokenResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GenerateAccessToken[0:len(c.CallOptions.GenerateAccessToken):len(c.CallOptions.GenerateAccessToken)], opts...) var resp *credentialspb.GenerateAccessTokenResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.iamCredentialsClient.GenerateAccessToken(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GenerateIdToken generates an OpenID Connect ID token for a service account. func (c *IamCredentialsClient) GenerateIdToken(ctx context.Context, req *credentialspb.GenerateIdTokenRequest, opts ...gax.CallOption) (*credentialspb.GenerateIdTokenResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GenerateIdToken[0:len(c.CallOptions.GenerateIdToken):len(c.CallOptions.GenerateIdToken)], opts...) var resp *credentialspb.GenerateIdTokenResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.iamCredentialsClient.GenerateIdToken(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // SignBlob signs a blob using a service account's system-managed private key. func (c *IamCredentialsClient) SignBlob(ctx context.Context, req *credentialspb.SignBlobRequest, opts ...gax.CallOption) (*credentialspb.SignBlobResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.SignBlob[0:len(c.CallOptions.SignBlob):len(c.CallOptions.SignBlob)], opts...) var resp *credentialspb.SignBlobResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.iamCredentialsClient.SignBlob(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // SignJwt signs a JWT using a service account's system-managed private key. func (c *IamCredentialsClient) SignJwt(ctx context.Context, req *credentialspb.SignJwtRequest, opts ...gax.CallOption) (*credentialspb.SignJwtResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.SignJwt[0:len(c.CallOptions.SignJwt):len(c.CallOptions.SignJwt)], opts...) var resp *credentialspb.SignJwtResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.iamCredentialsClient.SignJwt(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } google-cloud-go-0.49.0/iam/credentials/apiv1/iam_credentials_client_example_test.go000066400000000000000000000047561356504100700304510ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package credentials_test import ( "context" credentials "cloud.google.com/go/iam/credentials/apiv1" credentialspb "google.golang.org/genproto/googleapis/iam/credentials/v1" ) func ExampleNewIamCredentialsClient() { ctx := context.Background() c, err := credentials.NewIamCredentialsClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleIamCredentialsClient_GenerateAccessToken() { ctx := context.Background() c, err := credentials.NewIamCredentialsClient(ctx) if err != nil { // TODO: Handle error. } req := &credentialspb.GenerateAccessTokenRequest{ // TODO: Fill request struct fields. } resp, err := c.GenerateAccessToken(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIamCredentialsClient_GenerateIdToken() { ctx := context.Background() c, err := credentials.NewIamCredentialsClient(ctx) if err != nil { // TODO: Handle error. } req := &credentialspb.GenerateIdTokenRequest{ // TODO: Fill request struct fields. } resp, err := c.GenerateIdToken(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIamCredentialsClient_SignBlob() { ctx := context.Background() c, err := credentials.NewIamCredentialsClient(ctx) if err != nil { // TODO: Handle error. } req := &credentialspb.SignBlobRequest{ // TODO: Fill request struct fields. } resp, err := c.SignBlob(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIamCredentialsClient_SignJwt() { ctx := context.Background() c, err := credentials.NewIamCredentialsClient(ctx) if err != nil { // TODO: Handle error. } req := &credentialspb.SignJwtRequest{ // TODO: Fill request struct fields. } resp, err := c.SignJwt(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/iam/credentials/apiv1/mock_test.go000066400000000000000000000263251356504100700232020ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package credentials import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" "google.golang.org/api/option" credentialspb "google.golang.org/genproto/googleapis/iam/credentials/v1" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockIamCredentialsServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. credentialspb.IAMCredentialsServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockIamCredentialsServer) GenerateAccessToken(ctx context.Context, req *credentialspb.GenerateAccessTokenRequest) (*credentialspb.GenerateAccessTokenResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*credentialspb.GenerateAccessTokenResponse), nil } func (s *mockIamCredentialsServer) GenerateIdToken(ctx context.Context, req *credentialspb.GenerateIdTokenRequest) (*credentialspb.GenerateIdTokenResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*credentialspb.GenerateIdTokenResponse), nil } func (s *mockIamCredentialsServer) SignBlob(ctx context.Context, req *credentialspb.SignBlobRequest) (*credentialspb.SignBlobResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*credentialspb.SignBlobResponse), nil } func (s *mockIamCredentialsServer) SignJwt(ctx context.Context, req *credentialspb.SignJwtRequest) (*credentialspb.SignJwtResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*credentialspb.SignJwtResponse), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockIamCredentials mockIamCredentialsServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() credentialspb.RegisterIAMCredentialsServer(serv, &mockIamCredentials) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestIamCredentialsGenerateAccessToken(t *testing.T) { var accessToken string = "accessToken-1938933922" var expectedResponse = &credentialspb.GenerateAccessTokenResponse{ AccessToken: accessToken, } mockIamCredentials.err = nil mockIamCredentials.reqs = nil mockIamCredentials.resps = append(mockIamCredentials.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/serviceAccounts/%s", "[PROJECT]", "[SERVICE_ACCOUNT]") var scope []string = nil var request = &credentialspb.GenerateAccessTokenRequest{ Name: formattedName, Scope: scope, } c, err := NewIamCredentialsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GenerateAccessToken(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIamCredentials.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIamCredentialsGenerateAccessTokenError(t *testing.T) { errCode := codes.PermissionDenied mockIamCredentials.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/serviceAccounts/%s", "[PROJECT]", "[SERVICE_ACCOUNT]") var scope []string = nil var request = &credentialspb.GenerateAccessTokenRequest{ Name: formattedName, Scope: scope, } c, err := NewIamCredentialsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GenerateAccessToken(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIamCredentialsGenerateIdToken(t *testing.T) { var token string = "token110541305" var expectedResponse = &credentialspb.GenerateIdTokenResponse{ Token: token, } mockIamCredentials.err = nil mockIamCredentials.reqs = nil mockIamCredentials.resps = append(mockIamCredentials.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/serviceAccounts/%s", "[PROJECT]", "[SERVICE_ACCOUNT]") var audience string = "audience975628804" var request = &credentialspb.GenerateIdTokenRequest{ Name: formattedName, Audience: audience, } c, err := NewIamCredentialsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GenerateIdToken(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIamCredentials.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIamCredentialsGenerateIdTokenError(t *testing.T) { errCode := codes.PermissionDenied mockIamCredentials.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/serviceAccounts/%s", "[PROJECT]", "[SERVICE_ACCOUNT]") var audience string = "audience975628804" var request = &credentialspb.GenerateIdTokenRequest{ Name: formattedName, Audience: audience, } c, err := NewIamCredentialsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GenerateIdToken(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIamCredentialsSignBlob(t *testing.T) { var keyId string = "keyId-1134673157" var signedBlob []byte = []byte("-32") var expectedResponse = &credentialspb.SignBlobResponse{ KeyId: keyId, SignedBlob: signedBlob, } mockIamCredentials.err = nil mockIamCredentials.reqs = nil mockIamCredentials.resps = append(mockIamCredentials.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/serviceAccounts/%s", "[PROJECT]", "[SERVICE_ACCOUNT]") var payload []byte = []byte("-114") var request = &credentialspb.SignBlobRequest{ Name: formattedName, Payload: payload, } c, err := NewIamCredentialsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SignBlob(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIamCredentials.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIamCredentialsSignBlobError(t *testing.T) { errCode := codes.PermissionDenied mockIamCredentials.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/serviceAccounts/%s", "[PROJECT]", "[SERVICE_ACCOUNT]") var payload []byte = []byte("-114") var request = &credentialspb.SignBlobRequest{ Name: formattedName, Payload: payload, } c, err := NewIamCredentialsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SignBlob(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIamCredentialsSignJwt(t *testing.T) { var keyId string = "keyId-1134673157" var signedJwt string = "signedJwt-979546844" var expectedResponse = &credentialspb.SignJwtResponse{ KeyId: keyId, SignedJwt: signedJwt, } mockIamCredentials.err = nil mockIamCredentials.reqs = nil mockIamCredentials.resps = append(mockIamCredentials.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/serviceAccounts/%s", "[PROJECT]", "[SERVICE_ACCOUNT]") var payload string = "-114" var request = &credentialspb.SignJwtRequest{ Name: formattedName, Payload: payload, } c, err := NewIamCredentialsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SignJwt(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIamCredentials.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIamCredentialsSignJwtError(t *testing.T) { errCode := codes.PermissionDenied mockIamCredentials.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/serviceAccounts/%s", "[PROJECT]", "[SERVICE_ACCOUNT]") var payload string = "-114" var request = &credentialspb.SignJwtRequest{ Name: formattedName, Payload: payload, } c, err := NewIamCredentialsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SignJwt(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/iam/iam.go000066400000000000000000000220701356504100700164340ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package iam supports the resource-specific operations of Google Cloud // IAM (Identity and Access Management) for the Google Cloud Libraries. // See https://cloud.google.com/iam for more about IAM. // // Users of the Google Cloud Libraries will typically not use this package // directly. Instead they will begin with some resource that supports IAM, like // a pubsub topic, and call its IAM method to get a Handle for that resource. package iam import ( "context" "fmt" "time" gax "github.com/googleapis/gax-go/v2" pb "google.golang.org/genproto/googleapis/iam/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // client abstracts the IAMPolicy API to allow multiple implementations. type client interface { Get(ctx context.Context, resource string) (*pb.Policy, error) Set(ctx context.Context, resource string, p *pb.Policy) error Test(ctx context.Context, resource string, perms []string) ([]string, error) } // grpcClient implements client for the standard gRPC-based IAMPolicy service. type grpcClient struct { c pb.IAMPolicyClient } var withRetry = gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60 * time.Second, Multiplier: 1.3, }) }) func (g *grpcClient) Get(ctx context.Context, resource string) (*pb.Policy, error) { var proto *pb.Policy md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", resource)) ctx = insertMetadata(ctx, md) err := gax.Invoke(ctx, func(ctx context.Context, _ gax.CallSettings) error { var err error proto, err = g.c.GetIamPolicy(ctx, &pb.GetIamPolicyRequest{Resource: resource}) return err }, withRetry) if err != nil { return nil, err } return proto, nil } func (g *grpcClient) Set(ctx context.Context, resource string, p *pb.Policy) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", resource)) ctx = insertMetadata(ctx, md) return gax.Invoke(ctx, func(ctx context.Context, _ gax.CallSettings) error { _, err := g.c.SetIamPolicy(ctx, &pb.SetIamPolicyRequest{ Resource: resource, Policy: p, }) return err }, withRetry) } func (g *grpcClient) Test(ctx context.Context, resource string, perms []string) ([]string, error) { var res *pb.TestIamPermissionsResponse md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", resource)) ctx = insertMetadata(ctx, md) err := gax.Invoke(ctx, func(ctx context.Context, _ gax.CallSettings) error { var err error res, err = g.c.TestIamPermissions(ctx, &pb.TestIamPermissionsRequest{ Resource: resource, Permissions: perms, }) return err }, withRetry) if err != nil { return nil, err } return res.Permissions, nil } // A Handle provides IAM operations for a resource. type Handle struct { c client resource string } // InternalNewHandle is for use by the Google Cloud Libraries only. // // InternalNewHandle returns a Handle for resource. // The conn parameter refers to a server that must support the IAMPolicy service. func InternalNewHandle(conn *grpc.ClientConn, resource string) *Handle { return InternalNewHandleGRPCClient(pb.NewIAMPolicyClient(conn), resource) } // InternalNewHandleGRPCClient is for use by the Google Cloud Libraries only. // // InternalNewHandleClient returns a Handle for resource using the given // grpc service that implements IAM as a mixin func InternalNewHandleGRPCClient(c pb.IAMPolicyClient, resource string) *Handle { return InternalNewHandleClient(&grpcClient{c: c}, resource) } // InternalNewHandleClient is for use by the Google Cloud Libraries only. // // InternalNewHandleClient returns a Handle for resource using the given // client implementation. func InternalNewHandleClient(c client, resource string) *Handle { return &Handle{ c: c, resource: resource, } } // Policy retrieves the IAM policy for the resource. func (h *Handle) Policy(ctx context.Context) (*Policy, error) { proto, err := h.c.Get(ctx, h.resource) if err != nil { return nil, err } return &Policy{InternalProto: proto}, nil } // SetPolicy replaces the resource's current policy with the supplied Policy. // // If policy was created from a prior call to Get, then the modification will // only succeed if the policy has not changed since the Get. func (h *Handle) SetPolicy(ctx context.Context, policy *Policy) error { return h.c.Set(ctx, h.resource, policy.InternalProto) } // TestPermissions returns the subset of permissions that the caller has on the resource. func (h *Handle) TestPermissions(ctx context.Context, permissions []string) ([]string, error) { return h.c.Test(ctx, h.resource, permissions) } // A RoleName is a name representing a collection of permissions. type RoleName string // Common role names. const ( Owner RoleName = "roles/owner" Editor RoleName = "roles/editor" Viewer RoleName = "roles/viewer" ) const ( // AllUsers is a special member that denotes all users, even unauthenticated ones. AllUsers = "allUsers" // AllAuthenticatedUsers is a special member that denotes all authenticated users. AllAuthenticatedUsers = "allAuthenticatedUsers" ) // A Policy is a list of Bindings representing roles // granted to members. // // The zero Policy is a valid policy with no bindings. type Policy struct { // TODO(jba): when type aliases are available, put Policy into an internal package // and provide an exported alias here. // This field is exported for use by the Google Cloud Libraries only. // It may become unexported in a future release. InternalProto *pb.Policy } // Members returns the list of members with the supplied role. // The return value should not be modified. Use Add and Remove // to modify the members of a role. func (p *Policy) Members(r RoleName) []string { b := p.binding(r) if b == nil { return nil } return b.Members } // HasRole reports whether member has role r. func (p *Policy) HasRole(member string, r RoleName) bool { return memberIndex(member, p.binding(r)) >= 0 } // Add adds member member to role r if it is not already present. // A new binding is created if there is no binding for the role. func (p *Policy) Add(member string, r RoleName) { b := p.binding(r) if b == nil { if p.InternalProto == nil { p.InternalProto = &pb.Policy{} } p.InternalProto.Bindings = append(p.InternalProto.Bindings, &pb.Binding{ Role: string(r), Members: []string{member}, }) return } if memberIndex(member, b) < 0 { b.Members = append(b.Members, member) return } } // Remove removes member from role r if it is present. func (p *Policy) Remove(member string, r RoleName) { bi := p.bindingIndex(r) if bi < 0 { return } bindings := p.InternalProto.Bindings b := bindings[bi] mi := memberIndex(member, b) if mi < 0 { return } // Order doesn't matter for bindings or members, so to remove, move the last item // into the removed spot and shrink the slice. if len(b.Members) == 1 { // Remove binding. last := len(bindings) - 1 bindings[bi] = bindings[last] bindings[last] = nil p.InternalProto.Bindings = bindings[:last] return } // Remove member. // TODO(jba): worry about multiple copies of m? last := len(b.Members) - 1 b.Members[mi] = b.Members[last] b.Members[last] = "" b.Members = b.Members[:last] } // Roles returns the names of all the roles that appear in the Policy. func (p *Policy) Roles() []RoleName { if p.InternalProto == nil { return nil } var rns []RoleName for _, b := range p.InternalProto.Bindings { rns = append(rns, RoleName(b.Role)) } return rns } // binding returns the Binding for the suppied role, or nil if there isn't one. func (p *Policy) binding(r RoleName) *pb.Binding { i := p.bindingIndex(r) if i < 0 { return nil } return p.InternalProto.Bindings[i] } func (p *Policy) bindingIndex(r RoleName) int { if p.InternalProto == nil { return -1 } for i, b := range p.InternalProto.Bindings { if b.Role == string(r) { return i } } return -1 } // memberIndex returns the index of m in b's Members, or -1 if not found. func memberIndex(m string, b *pb.Binding) int { if b == nil { return -1 } for i, mm := range b.Members { if mm == m { return i } } return -1 } // insertMetadata inserts metadata into the given context func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } google-cloud-go-0.49.0/iam/iam_test.go000066400000000000000000000044701356504100700174770ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package iam import ( "fmt" "sort" "testing" "cloud.google.com/go/internal/testutil" ) func TestPolicy(t *testing.T) { p := &Policy{} add := func(member string, role RoleName) { p.Add(member, role) } remove := func(member string, role RoleName) { p.Remove(member, role) } if msg, ok := checkMembers(p, Owner, nil); !ok { t.Fatal(msg) } add("m1", Owner) if msg, ok := checkMembers(p, Owner, []string{"m1"}); !ok { t.Fatal(msg) } add("m2", Owner) if msg, ok := checkMembers(p, Owner, []string{"m1", "m2"}); !ok { t.Fatal(msg) } add("m1", Owner) // duplicate adds ignored if msg, ok := checkMembers(p, Owner, []string{"m1", "m2"}); !ok { t.Fatal(msg) } // No other roles populated yet. if msg, ok := checkMembers(p, Viewer, nil); !ok { t.Fatal(msg) } remove("m1", Owner) if msg, ok := checkMembers(p, Owner, []string{"m2"}); !ok { t.Fatal(msg) } if msg, ok := checkMembers(p, Viewer, nil); !ok { t.Fatal(msg) } remove("m3", Owner) // OK to remove non-existent member. if msg, ok := checkMembers(p, Owner, []string{"m2"}); !ok { t.Fatal(msg) } remove("m2", Owner) if msg, ok := checkMembers(p, Owner, nil); !ok { t.Fatal(msg) } if got, want := p.Roles(), []RoleName(nil); !testutil.Equal(got, want) { t.Fatalf("roles: got %v, want %v", got, want) } } func checkMembers(p *Policy, role RoleName, wantMembers []string) (string, bool) { gotMembers := p.Members(role) sort.Strings(gotMembers) sort.Strings(wantMembers) if !testutil.Equal(gotMembers, wantMembers) { return fmt.Sprintf("got %v, want %v", gotMembers, wantMembers), false } for _, m := range wantMembers { if !p.HasRole(m, role) { return fmt.Sprintf("member %q should have role %s but does not", m, role), false } } return "", true } google-cloud-go-0.49.0/internal/000077500000000000000000000000001356504100700164045ustar00rootroot00000000000000google-cloud-go-0.49.0/internal/annotate.go000066400000000000000000000031741356504100700205510ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package internal import ( "fmt" "google.golang.org/api/googleapi" "google.golang.org/grpc/status" ) // Annotate prepends msg to the error message in err, attempting // to preserve other information in err, like an error code. // // Annotate panics if err is nil. // // Annotate knows about these error types: // - "google.golang.org/grpc/status".Status // - "google.golang.org/api/googleapi".Error // If the error is not one of these types, Annotate behaves // like // fmt.Errorf("%s: %v", msg, err) func Annotate(err error, msg string) error { if err == nil { panic("Annotate called with nil") } if s, ok := status.FromError(err); ok { p := s.Proto() p.Message = msg + ": " + p.Message return status.ErrorProto(p) } if g, ok := err.(*googleapi.Error); ok { g.Message = msg + ": " + g.Message return g } return fmt.Errorf("%s: %v", msg, err) } // Annotatef uses format and args to format a string, then calls Annotate. func Annotatef(err error, format string, args ...interface{}) error { return Annotate(err, fmt.Sprintf(format, args...)) } google-cloud-go-0.49.0/internal/annotate_test.go000066400000000000000000000034311356504100700216040ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package internal import ( "errors" "testing" "google.golang.org/api/googleapi" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) const wantMessage = "prefix: msg" func TestAnnotateGRPC(t *testing.T) { // grpc Status error err := status.Error(codes.NotFound, "msg") err = Annotate(err, "prefix") got, ok := status.FromError(err) if !ok { t.Fatalf("got %T, wanted a status", got) } if g, w := got.Code(), codes.NotFound; g != w { t.Errorf("got code %v, want %v", g, w) } if g, w := got.Message(), wantMessage; g != w { t.Errorf("got message %q, want %q", g, w) } } func TestAnnotateGoogleapi(t *testing.T) { // googleapi error var err error = &googleapi.Error{Code: 403, Message: "msg"} err = Annotate(err, "prefix") got2, ok := err.(*googleapi.Error) if !ok { t.Fatalf("got %T, wanted a googleapi.Error", got2) } if g, w := got2.Code, 403; g != w { t.Errorf("got code %d, want %d", g, w) } if g, w := got2.Message, wantMessage; g != w { t.Errorf("got message %q, want %q", g, w) } } func TestAnnotateUnknownError(t *testing.T) { err := Annotate(errors.New("msg"), "prefix") if g, w := err.Error(), wantMessage; g != w { t.Errorf("got message %q, want %q", g, w) } } google-cloud-go-0.49.0/internal/btree/000077500000000000000000000000001356504100700175055ustar00rootroot00000000000000google-cloud-go-0.49.0/internal/btree/README.md000066400000000000000000000006331356504100700207660ustar00rootroot00000000000000This package is a fork of github.com/jba/btree at commit d4edd57f39b8425fc2c631047ff4dc6024d82a4f, which itself was a fork of github.com/google/btree at 316fb6d3f031ae8f4d457c6c5186b9e3ded70435. This directory makes the following modifications: - Updated copyright notice. - removed LICENSE (it is the same as the repo-wide license, Apache 2.0) - Removed examples_test.go and .travis.yml. - Added this file. google-cloud-go-0.49.0/internal/btree/benchmarks_test.go000066400000000000000000000122771356504100700232210ustar00rootroot00000000000000// Copyright 2014 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package btree import ( "fmt" "sort" "testing" ) const benchmarkTreeSize = 10000 var degrees = []int{2, 8, 32, 64} func BenchmarkInsert(b *testing.B) { insertP := perm(benchmarkTreeSize) for _, d := range degrees { b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) { i := 0 for i < b.N { tr := New(d, less) for _, m := range insertP { tr.Set(m.Key, m.Value) i++ if i >= b.N { return } } } }) } } func BenchmarkDeleteInsert(b *testing.B) { insertP := perm(benchmarkTreeSize) for _, d := range degrees { b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) { tr := New(d, less) for _, m := range insertP { tr.Set(m.Key, m.Value) } b.ResetTimer() for i := 0; i < b.N; i++ { m := insertP[i%benchmarkTreeSize] tr.Delete(m.Key) tr.Set(m.Key, m.Value) } }) } } func BenchmarkDeleteInsertCloneOnce(b *testing.B) { insertP := perm(benchmarkTreeSize) for _, d := range degrees { b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) { tr := New(d, less) for _, m := range insertP { tr.Set(m.Key, m.Value) } tr = tr.Clone() b.ResetTimer() for i := 0; i < b.N; i++ { m := insertP[i%benchmarkTreeSize] tr.Delete(m.Key) tr.Set(m.Key, m.Value) } }) } } func BenchmarkDeleteInsertCloneEachTime(b *testing.B) { insertP := perm(benchmarkTreeSize) for _, d := range degrees { b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) { tr := New(d, less) for _, m := range insertP { tr.Set(m.Key, m.Value) } b.ResetTimer() for i := 0; i < b.N; i++ { tr = tr.Clone() m := insertP[i%benchmarkTreeSize] tr.Delete(m.Key) tr.Set(m.Key, m.Value) } }) } } func BenchmarkDelete(b *testing.B) { insertP := perm(benchmarkTreeSize) removeP := perm(benchmarkTreeSize) for _, d := range degrees { b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) { i := 0 for i < b.N { b.StopTimer() tr := New(d, less) for _, v := range insertP { tr.Set(v.Key, v.Value) } b.StartTimer() for _, m := range removeP { tr.Delete(m.Key) i++ if i >= b.N { return } } if tr.Len() > 0 { panic(tr.Len()) } } }) } } func BenchmarkGet(b *testing.B) { insertP := perm(benchmarkTreeSize) getP := perm(benchmarkTreeSize) for _, d := range degrees { b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) { i := 0 for i < b.N { b.StopTimer() tr := New(d, less) for _, v := range insertP { tr.Set(v.Key, v.Value) } b.StartTimer() for _, m := range getP { tr.Get(m.Key) i++ if i >= b.N { return } } } }) } } func BenchmarkGetWithIndex(b *testing.B) { insertP := perm(benchmarkTreeSize) getP := perm(benchmarkTreeSize) for _, d := range degrees { b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) { i := 0 for i < b.N { b.StopTimer() tr := New(d, less) for _, v := range insertP { tr.Set(v.Key, v.Value) } b.StartTimer() for _, m := range getP { tr.GetWithIndex(m.Key) i++ if i >= b.N { return } } } }) } } func BenchmarkGetCloneEachTime(b *testing.B) { insertP := perm(benchmarkTreeSize) getP := perm(benchmarkTreeSize) for _, d := range degrees { b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) { i := 0 for i < b.N { b.StopTimer() tr := New(d, less) for _, m := range insertP { tr.Set(m.Key, m.Value) } b.StartTimer() for _, m := range getP { tr = tr.Clone() tr.Get(m.Key) i++ if i >= b.N { return } } } }) } } func BenchmarkFind(b *testing.B) { for _, d := range degrees { var items []item for i := 0; i < 2*d; i++ { items = append(items, item{i, i}) } b.Run(fmt.Sprintf("size=%d", len(items)), func(b *testing.B) { for _, alg := range []struct { name string fun func(Key, []item) (int, bool) }{ {"binary", findBinary}, {"linear", findLinear}, } { b.Run(alg.name, func(b *testing.B) { for i := 0; i < b.N; i++ { for j := 0; j < len(items); j++ { alg.fun(items[j].key, items) } } }) } }) } } func findBinary(k Key, s []item) (int, bool) { i := sort.Search(len(s), func(i int) bool { return less(k, s[i].key) }) // i is the smallest index of s for which key.Less(s[i].Key), or len(s). if i > 0 && !less(s[i-1], k) { return i - 1, true } return i, false } func findLinear(k Key, s []item) (int, bool) { var i int for i = 0; i < len(s); i++ { if less(k, s[i].key) { break } } if i > 0 && !less(s[i-1].key, k) { return i - 1, true } return i, false } google-cloud-go-0.49.0/internal/btree/btree.go000066400000000000000000000745721356504100700211540ustar00rootroot00000000000000// Copyright 2014 Google LLC // Modified 2018 by Jonathan Amsterdam (jbamsterdam@gmail.com) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package btree implements in-memory B-Trees of arbitrary degree. // // This implementation is based on google/btree (http://github.com/google/btree), and // much of the code is taken from there. But the API has been changed significantly, // particularly around iteration, and support for indexing by position has been // added. // // btree implements an in-memory B-Tree for use as an ordered data structure. // It is not meant for persistent storage solutions. // // It has a flatter structure than an equivalent red-black or other binary tree, // which in some cases yields better memory usage and/or performance. // See some discussion on the matter here: // http://google-opensource.blogspot.com/2013/01/c-containers-that-save-memory-and-time.html // Note, though, that this project is in no way related to the C++ B-Tree // implementation written about there. // // Within this tree, each node contains a slice of items and a (possibly nil) // slice of children. For basic numeric values or raw structs, this can cause // efficiency differences when compared to equivalent C++ template code that // stores values in arrays within the node: // * Due to the overhead of storing values as interfaces (each // value needs to be stored as the value itself, then 2 words for the // interface pointing to that value and its type), resulting in higher // memory use. // * Since interfaces can point to values anywhere in memory, values are // most likely not stored in contiguous blocks, resulting in a higher // number of cache misses. // These issues don't tend to matter, though, when working with strings or other // heap-allocated structures, since C++-equivalent structures also must store // pointers and also distribute their values across the heap. package btree import ( "sort" "sync" ) // Key represents a key into the tree. type Key interface{} // Value represents a value in the tree. type Value interface{} // item is a key-value pair. type item struct { key Key value Value } type lessFunc func(interface{}, interface{}) bool // New creates a new B-Tree with the given degree and comparison function. // // New(2, less), for example, will create a 2-3-4 tree (each node contains 1-3 items // and 2-4 children). // // The less function tests whether the current item is less than the given argument. // It must provide a strict weak ordering. // If !less(a, b) && !less(b, a), we treat this to mean a == b (i.e. the tree // can hold only one of a or b). func New(degree int, less func(interface{}, interface{}) bool) *BTree { if degree <= 1 { panic("bad degree") } return &BTree{ degree: degree, less: less, cow: ©OnWriteContext{}, } } // items stores items in a node. type items []item // insertAt inserts a value into the given index, pushing all subsequent values // forward. func (s *items) insertAt(index int, m item) { *s = append(*s, item{}) if index < len(*s) { copy((*s)[index+1:], (*s)[index:]) } (*s)[index] = m } // removeAt removes a value at a given index, pulling all subsequent values // back. func (s *items) removeAt(index int) item { m := (*s)[index] copy((*s)[index:], (*s)[index+1:]) (*s)[len(*s)-1] = item{} *s = (*s)[:len(*s)-1] return m } // pop removes and returns the last element in the list. func (s *items) pop() item { index := len(*s) - 1 out := (*s)[index] (*s)[index] = item{} *s = (*s)[:index] return out } var nilItems = make(items, 16) // truncate truncates this instance at index so that it contains only the // first index items. index must be less than or equal to length. func (s *items) truncate(index int) { var toClear items *s, toClear = (*s)[:index], (*s)[index:] for len(toClear) > 0 { toClear = toClear[copy(toClear, nilItems):] } } // find returns the index where an item with key should be inserted into this // list. 'found' is true if the item already exists in the list at the given // index. func (s items) find(k Key, less lessFunc) (index int, found bool) { i := sort.Search(len(s), func(i int) bool { return less(k, s[i].key) }) // i is the smallest index of s for which k.Less(s[i].Key), or len(s). if i > 0 && !less(s[i-1].key, k) { return i - 1, true } return i, false } // children stores child nodes in a node. type children []*node // insertAt inserts a value into the given index, pushing all subsequent values // forward. func (s *children) insertAt(index int, n *node) { *s = append(*s, nil) if index < len(*s) { copy((*s)[index+1:], (*s)[index:]) } (*s)[index] = n } // removeAt removes a value at a given index, pulling all subsequent values // back. func (s *children) removeAt(index int) *node { n := (*s)[index] copy((*s)[index:], (*s)[index+1:]) (*s)[len(*s)-1] = nil *s = (*s)[:len(*s)-1] return n } // pop removes and returns the last element in the list. func (s *children) pop() (out *node) { index := len(*s) - 1 out = (*s)[index] (*s)[index] = nil *s = (*s)[:index] return } var nilChildren = make(children, 16) // truncate truncates this instance at index so that it contains only the // first index children. index must be less than or equal to length. func (s *children) truncate(index int) { var toClear children *s, toClear = (*s)[:index], (*s)[index:] for len(toClear) > 0 { toClear = toClear[copy(toClear, nilChildren):] } } // node is an internal node in a tree. // // It must at all times maintain the invariant that either // * len(children) == 0, len(items) unconstrained // * len(children) == len(items) + 1 type node struct { items items children children size int // number of items in the subtree: len(items) + sum over i of children[i].size cow *copyOnWriteContext } func (n *node) computeSize() int { sz := len(n.items) for _, c := range n.children { sz += c.size } return sz } func (n *node) mutableFor(cow *copyOnWriteContext) *node { if n.cow == cow { return n } out := cow.newNode() if cap(out.items) >= len(n.items) { out.items = out.items[:len(n.items)] } else { out.items = make(items, len(n.items), cap(n.items)) } copy(out.items, n.items) // Copy children if cap(out.children) >= len(n.children) { out.children = out.children[:len(n.children)] } else { out.children = make(children, len(n.children), cap(n.children)) } copy(out.children, n.children) out.size = n.size return out } func (n *node) mutableChild(i int) *node { c := n.children[i].mutableFor(n.cow) n.children[i] = c return c } // split splits the given node at the given index. The current node shrinks, // and this function returns the item that existed at that index and a new node // containing all items/children after it. func (n *node) split(i int) (item, *node) { item := n.items[i] next := n.cow.newNode() next.items = append(next.items, n.items[i+1:]...) n.items.truncate(i) if len(n.children) > 0 { next.children = append(next.children, n.children[i+1:]...) n.children.truncate(i + 1) } n.size = n.computeSize() next.size = next.computeSize() return item, next } // maybeSplitChild checks if a child should be split, and if so splits it. // Returns whether or not a split occurred. func (n *node) maybeSplitChild(i, maxItems int) bool { if len(n.children[i].items) < maxItems { return false } first := n.mutableChild(i) item, second := first.split(maxItems / 2) n.items.insertAt(i, item) n.children.insertAt(i+1, second) // The size of n doesn't change. return true } // insert inserts an item into the subtree rooted at this node, making sure // no nodes in the subtree exceed maxItems items. Should an equivalent item be // be found/replaced by insert, its value will be returned. // // If computeIndex is true, the third return value is the index of the value with respect to n. func (n *node) insert(m item, maxItems int, less lessFunc, computeIndex bool) (old Value, present bool, idx int) { i, found := n.items.find(m.key, less) if found { out := n.items[i] n.items[i] = m if computeIndex { idx = n.itemIndex(i) } return out.value, true, idx } if len(n.children) == 0 { n.items.insertAt(i, m) n.size++ return old, false, i } if n.maybeSplitChild(i, maxItems) { inTree := n.items[i] switch { case less(m.key, inTree.key): // no change, we want first split node case less(inTree.key, m.key): i++ // we want second split node default: out := n.items[i] n.items[i] = m if computeIndex { idx = n.itemIndex(i) } return out.value, true, idx } } old, present, idx = n.mutableChild(i).insert(m, maxItems, less, computeIndex) if !present { n.size++ } if computeIndex { idx += n.partialSize(i) } return old, present, idx } // get finds the given key in the subtree and returns the corresponding item, along with a boolean reporting // whether it was found. // If computeIndex is true, it also returns the index of the key relative to the node's subtree. func (n *node) get(k Key, computeIndex bool, less lessFunc) (item, bool, int) { i, found := n.items.find(k, less) if found { return n.items[i], true, n.itemIndex(i) } if len(n.children) > 0 { m, found, idx := n.children[i].get(k, computeIndex, less) if computeIndex && found { idx += n.partialSize(i) } return m, found, idx } return item{}, false, -1 } // itemIndex returns the index w.r.t. n of the ith item in n. func (n *node) itemIndex(i int) int { if len(n.children) == 0 { return i } // Get the size of the node up to but not including the child to the right of // item i. Subtract 1 because the index is 0-based. return n.partialSize(i+1) - 1 } // Returns the size of the non-leaf node up to but not including child i. func (n *node) partialSize(i int) int { var sz int for j, c := range n.children { if j == i { break } sz += c.size + 1 } return sz } // cursorStackForKey returns a stack of cursors for the key, along with whether the key was found and the index. func (n *node) cursorStackForKey(k Key, cs cursorStack, less lessFunc) (cursorStack, bool, int) { i, found := n.items.find(k, less) cs.push(cursor{n, i}) idx := i if found { if len(n.children) > 0 { idx = n.partialSize(i+1) - 1 } return cs, true, idx } if len(n.children) > 0 { cs, found, idx := n.children[i].cursorStackForKey(k, cs, less) return cs, found, idx + n.partialSize(i) } return cs, false, idx } // at returns the item at the i'th position in the subtree rooted at n. // It assumes i is in range. func (n *node) at(i int) item { if len(n.children) == 0 { return n.items[i] } for j, c := range n.children { if i < c.size { return c.at(i) } i -= c.size if i == 0 { return n.items[j] } i-- } panic("impossible") } // cursorStackForIndex returns a stack of cursors for the index. // It assumes i is in range. func (n *node) cursorStackForIndex(i int, cs cursorStack) cursorStack { if len(n.children) == 0 { return cs.push(cursor{n, i}) } for j, c := range n.children { if i < c.size { return c.cursorStackForIndex(i, cs.push(cursor{n, j})) } i -= c.size if i == 0 { return cs.push(cursor{n, j}) } i-- } panic("impossible") } // toRemove details what item to remove in a node.remove call. type toRemove int const ( removeItem toRemove = iota // removes the given item removeMin // removes smallest item in the subtree removeMax // removes largest item in the subtree ) // remove removes an item from the subtree rooted at this node. func (n *node) remove(key Key, minItems int, typ toRemove, less lessFunc) (item, bool) { var i int var found bool switch typ { case removeMax: if len(n.children) == 0 { n.size-- return n.items.pop(), true } i = len(n.items) case removeMin: if len(n.children) == 0 { n.size-- return n.items.removeAt(0), true } i = 0 case removeItem: i, found = n.items.find(key, less) if len(n.children) == 0 { if found { n.size-- return n.items.removeAt(i), true } return item{}, false } default: panic("invalid type") } // If we get to here, we have children. if len(n.children[i].items) <= minItems { return n.growChildAndRemove(i, key, minItems, typ, less) } child := n.mutableChild(i) // Either we had enough items to begin with, or we've done some // merging/stealing, because we've got enough now and we're ready to return // stuff. if found { // The item exists at index 'i', and the child we've selected can give us a // predecessor, since if we've gotten here it's got > minItems items in it. out := n.items[i] // We use our special-case 'remove' call with typ=maxItem to pull the // predecessor of item i (the rightmost leaf of our immediate left child) // and set it into where we pulled the item from. n.items[i], _ = child.remove(nil, minItems, removeMax, less) n.size-- return out, true } // Final recursive call. Once we're here, we know that the item isn't in this // node and that the child is big enough to remove from. m, removed := child.remove(key, minItems, typ, less) if removed { n.size-- } return m, removed } // growChildAndRemove grows child 'i' to make sure it's possible to remove an // item from it while keeping it at minItems, then calls remove to actually // remove it. // // Most documentation says we have to do two sets of special casing: // 1) item is in this node // 2) item is in child // In both cases, we need to handle the two subcases: // A) node has enough values that it can spare one // B) node doesn't have enough values // For the latter, we have to check: // a) left sibling has node to spare // b) right sibling has node to spare // c) we must merge // To simplify our code here, we handle cases #1 and #2 the same: // If a node doesn't have enough items, we make sure it does (using a,b,c). // We then simply redo our remove call, and the second time (regardless of // whether we're in case 1 or 2), we'll have enough items and can guarantee // that we hit case A. func (n *node) growChildAndRemove(i int, key Key, minItems int, typ toRemove, less lessFunc) (item, bool) { if i > 0 && len(n.children[i-1].items) > minItems { // Steal from left child child := n.mutableChild(i) stealFrom := n.mutableChild(i - 1) stolenItem := stealFrom.items.pop() stealFrom.size-- child.items.insertAt(0, n.items[i-1]) child.size++ n.items[i-1] = stolenItem if len(stealFrom.children) > 0 { c := stealFrom.children.pop() stealFrom.size -= c.size child.children.insertAt(0, c) child.size += c.size } } else if i < len(n.items) && len(n.children[i+1].items) > minItems { // steal from right child child := n.mutableChild(i) stealFrom := n.mutableChild(i + 1) stolenItem := stealFrom.items.removeAt(0) stealFrom.size-- child.items = append(child.items, n.items[i]) child.size++ n.items[i] = stolenItem if len(stealFrom.children) > 0 { c := stealFrom.children.removeAt(0) stealFrom.size -= c.size child.children = append(child.children, c) child.size += c.size } } else { if i >= len(n.items) { i-- } child := n.mutableChild(i) // merge with right child mergeItem := n.items.removeAt(i) mergeChild := n.children.removeAt(i + 1) child.items = append(child.items, mergeItem) child.items = append(child.items, mergeChild.items...) child.children = append(child.children, mergeChild.children...) child.size = child.computeSize() n.cow.freeNode(mergeChild) } return n.remove(key, minItems, typ, less) } // BTree is an implementation of a B-Tree. // // BTree stores item instances in an ordered structure, allowing easy insertion, // removal, and iteration. // // Write operations are not safe for concurrent mutation by multiple // goroutines, but Read operations are. type BTree struct { degree int less lessFunc root *node cow *copyOnWriteContext } // copyOnWriteContext pointers determine node ownership. A tree with a cow // context equivalent to a node's cow context is allowed to modify that node. // A tree whose write context does not match a node's is not allowed to modify // it, and must create a new, writable copy (IE: it's a Clone). // // When doing any write operation, we maintain the invariant that the current // node's context is equal to the context of the tree that requested the write. // We do this by, before we descend into any node, creating a copy with the // correct context if the contexts don't match. // // Since the node we're currently visiting on any write has the requesting // tree's context, that node is modifiable in place. Children of that node may // not share context, but before we descend into them, we'll make a mutable // copy. type copyOnWriteContext struct{ byte } // non-empty, because empty structs may have same addr // Clone clones the btree, lazily. Clone should not be called concurrently, // but the original tree (t) and the new tree (t2) can be used concurrently // once the Clone call completes. // // The internal tree structure of b is marked read-only and shared between t and // t2. Writes to both t and t2 use copy-on-write logic, creating new nodes // whenever one of b's original nodes would have been modified. Read operations // should have no performance degredation. Write operations for both t and t2 // will initially experience minor slow-downs caused by additional allocs and // copies due to the aforementioned copy-on-write logic, but should converge to // the original performance characteristics of the original tree. func (t *BTree) Clone() *BTree { // Create two entirely new copy-on-write contexts. // This operation effectively creates three trees: // the original, shared nodes (old b.cow) // the new b.cow nodes // the new out.cow nodes cow1, cow2 := *t.cow, *t.cow out := *t t.cow = &cow1 out.cow = &cow2 return &out } // maxItems returns the max number of items to allow per node. func (t *BTree) maxItems() int { return t.degree*2 - 1 } // minItems returns the min number of items to allow per node (ignored for the // root node). func (t *BTree) minItems() int { return t.degree - 1 } var nodePool = sync.Pool{New: func() interface{} { return new(node) }} func (c *copyOnWriteContext) newNode() *node { n := nodePool.Get().(*node) n.cow = c return n } func (c *copyOnWriteContext) freeNode(n *node) { if n.cow == c { // clear to allow GC n.items.truncate(0) n.children.truncate(0) n.cow = nil nodePool.Put(n) } } // Set sets the given key to the given value in the tree. If the key is present in // the tree, its value is changed and the old value is returned along with a second // return value of true. If the key is not in the tree, it is added, and the second // return value is false. func (t *BTree) Set(k Key, v Value) (old Value, present bool) { old, present, _ = t.set(k, v, false) return old, present } // SetWithIndex sets the given key to the given value in the tree, and returns the // index at which it was inserted. func (t *BTree) SetWithIndex(k Key, v Value) (old Value, present bool, index int) { return t.set(k, v, true) } func (t *BTree) set(k Key, v Value, computeIndex bool) (old Value, present bool, idx int) { if t.root == nil { t.root = t.cow.newNode() t.root.items = append(t.root.items, item{k, v}) t.root.size = 1 return old, false, 0 } t.root = t.root.mutableFor(t.cow) if len(t.root.items) >= t.maxItems() { sz := t.root.size item2, second := t.root.split(t.maxItems() / 2) oldroot := t.root t.root = t.cow.newNode() t.root.items = append(t.root.items, item2) t.root.children = append(t.root.children, oldroot, second) t.root.size = sz } return t.root.insert(item{k, v}, t.maxItems(), t.less, computeIndex) } // Delete removes the item with the given key, returning its value. The second return value // reports whether the key was found. func (t *BTree) Delete(k Key) (Value, bool) { m, removed := t.deleteItem(k, removeItem) return m.value, removed } // DeleteMin removes the smallest item in the tree and returns its key and value. // If the tree is empty, it returns zero values. func (t *BTree) DeleteMin() (Key, Value) { item, _ := t.deleteItem(nil, removeMin) return item.key, item.value } // DeleteMax removes the largest item in the tree and returns its key and value. // If the tree is empty, it returns zero values. func (t *BTree) DeleteMax() (Key, Value) { item, _ := t.deleteItem(nil, removeMax) return item.key, item.value } func (t *BTree) deleteItem(key Key, typ toRemove) (item, bool) { if t.root == nil || len(t.root.items) == 0 { return item{}, false } t.root = t.root.mutableFor(t.cow) out, removed := t.root.remove(key, t.minItems(), typ, t.less) if len(t.root.items) == 0 && len(t.root.children) > 0 { oldroot := t.root t.root = t.root.children[0] t.cow.freeNode(oldroot) } return out, removed } // Get returns the value for the given key in the tree, or the zero value if the // key is not in the tree. // // To distinguish a zero value from a key that is not present, use GetWithIndex. func (t *BTree) Get(k Key) Value { var z Value if t.root == nil { return z } item, ok, _ := t.root.get(k, false, t.less) if !ok { return z } return item.value } // GetWithIndex returns the value and index for the given key in the tree, or the // zero value and -1 if the key is not in the tree. func (t *BTree) GetWithIndex(k Key) (Value, int) { var z Value if t.root == nil { return z, -1 } item, _, index := t.root.get(k, true, t.less) return item.value, index } // At returns the key and value at index i. The minimum item has index 0. // If i is outside the range [0, t.Len()), At panics. func (t *BTree) At(i int) (Key, Value) { if i < 0 || i >= t.Len() { panic("btree: index out of range") } item := t.root.at(i) return item.key, item.value } // Has reports whether the given key is in the tree. func (t *BTree) Has(k Key) bool { if t.root == nil { return false } _, ok, _ := t.root.get(k, false, t.less) return ok } // Min returns the smallest key in the tree and its value. If the tree is empty, it // returns zero values. func (t *BTree) Min() (Key, Value) { var k Key var v Value if t.root == nil { return k, v } n := t.root for len(n.children) > 0 { n = n.children[0] } if len(n.items) == 0 { return k, v } return n.items[0].key, n.items[0].value } // Max returns the largest key in the tree and its value. If the tree is empty, both // return values are zero values. func (t *BTree) Max() (Key, Value) { var k Key var v Value if t.root == nil { return k, v } n := t.root for len(n.children) > 0 { n = n.children[len(n.children)-1] } if len(n.items) == 0 { return k, v } m := n.items[len(n.items)-1] return m.key, m.value } // Len returns the number of items currently in the tree. func (t *BTree) Len() int { if t.root == nil { return 0 } return t.root.size } // Before returns an iterator positioned just before k. After the first call to Next, // the Iterator will be at k, or at the key just greater than k if k is not in the tree. // Subsequent calls to Next will traverse the tree's items in ascending order. func (t *BTree) Before(k Key) *Iterator { if t.root == nil { return &Iterator{} } var cs cursorStack cs, found, idx := t.root.cursorStackForKey(k, cs, t.less) // If we found the key, the cursor stack is pointing to it. Since that is // the first element we want, don't advance the iterator on the initial call to Next. // If we haven't found the key, then the top of the cursor stack is either pointing at the // item just after k, in which case we do not want to move the iterator; or the index // is past the end of the items slice, in which case we do. var stay bool top := cs[len(cs)-1] if found { stay = true } else if top.index < len(top.node.items) { stay = true } else { idx-- } return &Iterator{ cursors: cs, stay: stay, descending: false, Index: idx, } } // After returns an iterator positioned just after k. After the first call to Next, // the Iterator will be at k, or at the key just less than k if k is not in the tree. // Subsequent calls to Next will traverse the tree's items in descending order. func (t *BTree) After(k Key) *Iterator { if t.root == nil { return &Iterator{} } var cs cursorStack cs, found, idx := t.root.cursorStackForKey(k, cs, t.less) // If we found the key, the cursor stack is pointing to it. Since that is // the first element we want, don't advance the iterator on the initial call to Next. // If we haven't found the key, the cursor stack is pointing just after the first item, // so we do want to advance. return &Iterator{ cursors: cs, stay: found, descending: true, Index: idx, } } // BeforeIndex returns an iterator positioned just before the item with the given index. // The iterator will traverse the tree's items in ascending order. // If i is not in the range [0, tr.Len()], BeforeIndex panics. // Note that it is not an error to provide an index of tr.Len(). func (t *BTree) BeforeIndex(i int) *Iterator { return t.indexIterator(i, false) } // AfterIndex returns an iterator positioned just after the item with the given index. // The iterator will traverse the tree's items in descending order. // If i is not in the range [0, tr.Len()], AfterIndex panics. // Note that it is not an error to provide an index of tr.Len(). func (t *BTree) AfterIndex(i int) *Iterator { return t.indexIterator(i, true) } func (t *BTree) indexIterator(i int, descending bool) *Iterator { if i < 0 || i > t.Len() { panic("btree: index out of range") } if i == t.Len() { return &Iterator{} } var cs cursorStack return &Iterator{ cursors: t.root.cursorStackForIndex(i, cs), stay: true, descending: descending, Index: i, } } // An Iterator supports traversing the items in the tree. type Iterator struct { Key Key Value Value // Index is the position of the item in the tree viewed as a sequence. // The minimum item has index zero. Index int cursors cursorStack // stack of nodes with indices; last element is the top stay bool // don't do anything on the first call to Next. descending bool // traverse the items in descending order } // Next advances the Iterator to the next item in the tree. If Next returns true, // the Iterator's Key, Value and Index fields refer to the next item. If Next returns // false, there are no more items and the values of Key, Value and Index are undefined. // // If the tree is modified during iteration, the behavior is undefined. func (it *Iterator) Next() bool { var more bool switch { case len(it.cursors) == 0: more = false case it.stay: it.stay = false more = true case it.descending: more = it.dec() default: more = it.inc() } if !more { return false } top := it.cursors[len(it.cursors)-1] item := top.node.items[top.index] it.Key = item.key it.Value = item.value return true } // When inc returns true, the top cursor on the stack refers to the new current item. func (it *Iterator) inc() bool { // Useful invariants for understanding this function: // - Leaf nodes have zero children, and zero or more items. // - Nonleaf nodes have one more child than item, and children[i] < items[i] < children[i+1]. // - The current item in the iterator is top.node.items[top.index]. it.Index++ // If we are at a non-leaf node, the current item is items[i], so // now we want to continue with children[i+1], which must exist // by the node invariant. We want the minimum item in that child's subtree. top := it.cursors.incTop(1) for len(top.node.children) > 0 { top = cursor{top.node.children[top.index], 0} it.cursors.push(top) } // Here, we are at a leaf node. top.index points to // the new current item, if it's within the items slice. for top.index >= len(top.node.items) { // We've gone through everything in this node. Pop it off the stack. it.cursors.pop() // If the stack is now empty,we're past the last item in the tree. if it.cursors.empty() { return false } top = it.cursors.top() // The new top's index points to a child, which we've just finished // exploring. The next item is the one at the same index in the items slice. } // Here, the top cursor on the stack points to the new current item. return true } func (it *Iterator) dec() bool { // See the invariants for inc, above. it.Index-- top := it.cursors.top() // If we are at a non-leaf node, the current item is items[i], so // now we want to continue with children[i]. We want the maximum item in that child's subtree. for len(top.node.children) > 0 { c := top.node.children[top.index] top = cursor{c, len(c.items)} it.cursors.push(top) } top = it.cursors.incTop(-1) // Here, we are at a leaf node. top.index points to // the new current item, if it's within the items slice. for top.index < 0 { // We've gone through everything in this node. Pop it off the stack. it.cursors.pop() // If the stack is now empty,we're past the last item in the tree. if it.cursors.empty() { return false } // The new top's index points to a child, which we've just finished // exploring. That child is to the right of the item we want to advance to, // so decrement the index. top = it.cursors.incTop(-1) } return true } // A cursor is effectively a pointer into a node. A stack of cursors identifies an item in the tree, // and makes it possible to move to the next or previous item efficiently. // // If the cursor is on the top of the stack, its index points into the node's items slice, selecting // the current item. Otherwise, the index points into the children slice and identifies the child // that is next in the stack. type cursor struct { node *node index int } // A cursorStack is a stack of cursors, representing a path of nodes from the root of the tree. type cursorStack []cursor func (s *cursorStack) push(c cursor) cursorStack { *s = append(*s, c) return *s } func (s *cursorStack) pop() cursor { last := len(*s) - 1 t := (*s)[last] *s = (*s)[:last] return t } func (s *cursorStack) top() cursor { return (*s)[len(*s)-1] } func (s *cursorStack) empty() bool { return len(*s) == 0 } // incTop increments top's index by n and returns it. func (s *cursorStack) incTop(n int) cursor { (*s)[len(*s)-1].index += n // Don't call top: modify the original, not a copy. return s.top() } google-cloud-go-0.49.0/internal/btree/btree_test.go000066400000000000000000000222121356504100700221730ustar00rootroot00000000000000// Copyright 2014 Google LLC // Modified 2018 by Jonathan Amsterdam (jbamsterdam@gmail.com) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package btree import ( "flag" "math/rand" "os" "sort" "sync" "testing" "time" "github.com/google/go-cmp/cmp" ) func init() { seed := time.Now().Unix() rand.Seed(seed) } type itemWithIndex struct { Key Key Value Value Index int } // perm returns a random permutation of n Int items in the range [0, n). func perm(n int) []itemWithIndex { var out []itemWithIndex for _, v := range rand.Perm(n) { out = append(out, itemWithIndex{v, v, v}) } return out } // rang returns an ordered list of Int items in the range [0, n). func rang(n int) []itemWithIndex { var out []itemWithIndex for i := 0; i < n; i++ { out = append(out, itemWithIndex{i, i, i}) } return out } // all extracts all items from an iterator. func all(it *Iterator) []itemWithIndex { var out []itemWithIndex for it.Next() { out = append(out, itemWithIndex{it.Key, it.Value, it.Index}) } return out } func reverse(s []itemWithIndex) { for i := 0; i < len(s)/2; i++ { s[i], s[len(s)-i-1] = s[len(s)-i-1], s[i] } } var btreeDegree = flag.Int("degree", 32, "B-Tree degree") func TestBTree(t *testing.T) { tr := New(*btreeDegree, less) const treeSize = 10000 for i := 0; i < 10; i++ { if min, _ := tr.Min(); min != nil { t.Fatalf("empty min, got %+v", min) } if max, _ := tr.Max(); max != nil { t.Fatalf("empty max, got %+v", max) } for _, m := range perm(treeSize) { if _, ok := tr.Set(m.Key, m.Value); ok { t.Fatal("set found item", m) } } for _, m := range perm(treeSize) { _, ok, idx := tr.SetWithIndex(m.Key, m.Value) if !ok { t.Fatal("set didn't find item", m) } if idx != m.Index { t.Fatalf("got index %d, want %d", idx, m.Index) } } mink, minv := tr.Min() if want := 0; mink != want || minv != want { t.Fatalf("min: want %+v, got %+v, %+v", want, mink, minv) } maxk, maxv := tr.Max() if want := treeSize - 1; maxk != want || maxv != want { t.Fatalf("max: want %+v, got %+v, %+v", want, maxk, maxv) } got := all(tr.BeforeIndex(0)) want := rang(treeSize) if !cmp.Equal(got, want) { t.Fatalf("mismatch:\n got: %v\nwant: %v", got, want) } for _, m := range perm(treeSize) { if _, removed := tr.Delete(m.Key); !removed { t.Fatalf("didn't find %v", m) } } if got = all(tr.BeforeIndex(0)); len(got) > 0 { t.Fatalf("some left!: %v", got) } } } func TestAt(t *testing.T) { tr := New(*btreeDegree, less) for _, m := range perm(100) { tr.Set(m.Key, m.Value) } for i := 0; i < tr.Len(); i++ { gotk, gotv := tr.At(i) if want := i; gotk != want || gotv != want { t.Fatalf("At(%d) = (%v, %v), want (%v, %v)", i, gotk, gotv, want, want) } } } func TestGetWithIndex(t *testing.T) { tr := New(*btreeDegree, less) for _, m := range perm(100) { tr.Set(m.Key, m.Value) } for i := 0; i < tr.Len(); i++ { gotv, goti := tr.GetWithIndex(i) wantv, wanti := i, i if gotv != wantv || goti != wanti { t.Errorf("GetWithIndex(%d) = (%v, %v), want (%v, %v)", i, gotv, goti, wantv, wanti) } } _, got := tr.GetWithIndex(100) if want := -1; got != want { t.Errorf("got %d, want %d", got, want) } } func TestSetWithIndex(t *testing.T) { tr := New(4, less) // use a small degree to cover more cases var contents []int for _, m := range perm(100) { _, _, idx := tr.SetWithIndex(m.Key, m.Value) contents = append(contents, m.Index) sort.Ints(contents) want := -1 for i, c := range contents { if c == m.Index { want = i break } } if idx != want { t.Fatalf("got %d, want %d", idx, want) } } } func TestDeleteMin(t *testing.T) { tr := New(3, less) for _, m := range perm(100) { tr.Set(m.Key, m.Value) } var got []itemWithIndex for i := 0; tr.Len() > 0; i++ { k, v := tr.DeleteMin() got = append(got, itemWithIndex{k, v, i}) } if want := rang(100); !cmp.Equal(got, want) { t.Fatalf("got: %v\nwant: %v", got, want) } } func TestDeleteMax(t *testing.T) { tr := New(3, less) for _, m := range perm(100) { tr.Set(m.Key, m.Value) } var got []itemWithIndex for tr.Len() > 0 { k, v := tr.DeleteMax() got = append(got, itemWithIndex{k, v, tr.Len()}) } reverse(got) if want := rang(100); !cmp.Equal(got, want) { t.Fatalf("got: %v\nwant: %v", got, want) } } func TestIterator(t *testing.T) { const size = 10 tr := New(2, less) // Empty tree. for i, it := range []*Iterator{ tr.BeforeIndex(0), tr.Before(3), tr.After(3), } { if got, want := it.Next(), false; got != want { t.Errorf("empty, #%d: got %t, want %t", i, got, want) } } // Root with zero children. tr.Set(1, nil) tr.Delete(1) if !(tr.root != nil && len(tr.root.children) == 0 && len(tr.root.items) == 0) { t.Fatal("wrong shape tree") } for i, it := range []*Iterator{ tr.BeforeIndex(0), tr.Before(3), tr.After(3), } { if got, want := it.Next(), false; got != want { t.Errorf("zero root, #%d: got %t, want %t", i, got, want) } } // Tree with size elements. p := perm(size) for _, v := range p { tr.Set(v.Key, v.Value) } it := tr.BeforeIndex(0) got := all(it) want := rang(size) if !cmp.Equal(got, want) { t.Fatalf("got %+v\nwant %+v\n", got, want) } for i, w := range want { it := tr.Before(w.Key) got = all(it) wn := want[w.Key.(int):] if !cmp.Equal(got, wn) { t.Fatalf("got %+v\nwant %+v\n", got, wn) } it = tr.BeforeIndex(i) got = all(it) if !cmp.Equal(got, wn) { t.Fatalf("got %+v\nwant %+v\n", got, wn) } it = tr.After(w.Key) got = all(it) wn = append([]itemWithIndex(nil), want[:w.Key.(int)+1]...) reverse(wn) if !cmp.Equal(got, wn) { t.Fatalf("got %+v\nwant %+v\n", got, wn) } it = tr.AfterIndex(i) got = all(it) if !cmp.Equal(got, wn) { t.Fatalf("got %+v\nwant %+v\n", got, wn) } } // Non-existent keys. tr = New(2, less) for _, v := range p { tr.Set(v.Key.(int)*2, v.Value) } // tr has only even keys: 0, 2, 4, ... Iterate from odd keys. for i := -1; i <= size+1; i += 2 { it := tr.Before(i) got := all(it) var want []itemWithIndex for j := (i + 1) / 2; j < size; j++ { want = append(want, itemWithIndex{j * 2, j, j}) } if !cmp.Equal(got, want) { tr.print(os.Stdout) t.Fatalf("%d: got %+v\nwant %+v\n", i, got, want) } it = tr.After(i) got = all(it) want = nil for j := (i - 1) / 2; j >= 0; j-- { want = append(want, itemWithIndex{j * 2, j, j}) } if !cmp.Equal(got, want) { t.Fatalf("%d: got %+v\nwant %+v\n", i, got, want) } } } func TestMixed(t *testing.T) { // Test random, mixed insertions and deletions. const maxSize = 1000 tr := New(3, less) has := map[int]bool{} for i := 0; i < 10000; i++ { r := rand.Intn(maxSize) if r >= tr.Len() { old, ok := tr.Set(r, r) if has[r] != ok { t.Fatalf("%d: has=%t, ok=%t", r, has[r], ok) } if ok && old.(int) != r { t.Fatalf("%d: bad old", r) } has[r] = true if got, want := tr.Get(r), r; got != want { t.Fatalf("Get(%d) = %d, want %d", r, got, want) } } else { // Expoit random map iteration order. var d int for d = range has { break } old, removed := tr.Delete(d) if !removed { t.Fatalf("%d not found", d) } if old.(int) != d { t.Fatalf("%d: bad old", d) } delete(has, d) } } } const cloneTestSize = 10000 func cloneTest(t *testing.T, b *BTree, start int, p []itemWithIndex, wg *sync.WaitGroup, treec chan<- *BTree) { treec <- b for i := start; i < cloneTestSize; i++ { b.Set(p[i].Key, p[i].Value) if i%(cloneTestSize/5) == 0 { wg.Add(1) go cloneTest(t, b.Clone(), i+1, p, wg, treec) } } wg.Done() } func TestCloneConcurrentOperations(t *testing.T) { b := New(*btreeDegree, less) treec := make(chan *BTree) p := perm(cloneTestSize) var wg sync.WaitGroup wg.Add(1) go cloneTest(t, b, 0, p, &wg, treec) var trees []*BTree donec := make(chan struct{}) go func() { for t := range treec { trees = append(trees, t) } close(donec) }() wg.Wait() close(treec) <-donec want := rang(cloneTestSize) for i, tree := range trees { if !cmp.Equal(want, all(tree.BeforeIndex(0))) { t.Errorf("tree %v mismatch", i) } } toRemove := rang(cloneTestSize)[cloneTestSize/2:] for i := 0; i < len(trees)/2; i++ { tree := trees[i] wg.Add(1) go func() { for _, m := range toRemove { tree.Delete(m.Key) } wg.Done() }() } wg.Wait() for i, tree := range trees { var wantpart []itemWithIndex if i < len(trees)/2 { wantpart = want[:cloneTestSize/2] } else { wantpart = want } if got := all(tree.BeforeIndex(0)); !cmp.Equal(wantpart, got) { t.Errorf("tree %v mismatch, want %v got %v", i, len(want), len(got)) } } } func less(a, b interface{}) bool { return a.(int) < b.(int) } google-cloud-go-0.49.0/internal/btree/debug.go000066400000000000000000000016711356504100700211270ustar00rootroot00000000000000// Copyright 2014 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package btree import ( "fmt" "io" "strings" ) func (t *BTree) print(w io.Writer) { t.root.print(w, 0) } func (n *node) print(w io.Writer, level int) { indent := strings.Repeat(" ", level) if n == nil { fmt.Fprintf(w, "%s\n", indent) return } fmt.Fprintf(w, "%s%v\n", indent, n.items) for _, c := range n.children { c.print(w, level+1) } } google-cloud-go-0.49.0/internal/fields/000077500000000000000000000000001356504100700176525ustar00rootroot00000000000000google-cloud-go-0.49.0/internal/fields/fields.go000066400000000000000000000367051356504100700214620ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package fields provides a view of the fields of a struct that follows the Go // rules, amended to consider tags and case insensitivity. // // Usage // // First define a function that interprets tags: // // func parseTag(st reflect.StructTag) (name string, keep bool, other interface{}, err error) { ... } // // The function's return values describe whether to ignore the field // completely or provide an alternate name, as well as other data from the // parse that is stored to avoid re-parsing. // // Then define a function to validate the type: // // func validate(t reflect.Type) error { ... } // // Then, if necessary, define a function to specify leaf types - types // which should be considered one field and not be recursed into: // // func isLeafType(t reflect.Type) bool { ... } // // eg: // // func isLeafType(t reflect.Type) bool { // return t == reflect.TypeOf(time.Time{}) // } // // Next, construct a Cache, passing your functions. As its name suggests, a // Cache remembers validation and field information for a type, so subsequent // calls with the same type are very fast. // // cache := fields.NewCache(parseTag, validate, isLeafType) // // To get the fields of a struct type as determined by the above rules, call // the Fields method: // // fields, err := cache.Fields(reflect.TypeOf(MyStruct{})) // // The return value can be treated as a slice of Fields. // // Given a string, such as a key or column name obtained during unmarshalling, // call Match on the list of fields to find a field whose name is the best // match: // // field := fields.Match(name) // // Match looks for an exact match first, then falls back to a case-insensitive // comparison. package fields import ( "bytes" "errors" "reflect" "sort" "strings" "sync" ) // A Field records information about a struct field. type Field struct { Name string // effective field name NameFromTag bool // did Name come from a tag? Type reflect.Type // field type Index []int // index sequence, for reflect.Value.FieldByIndex ParsedTag interface{} // third return value of the parseTag function nameBytes []byte equalFold func(s, t []byte) bool } // ParseTagFunc is a function that accepts a struct tag and returns four values: an alternative name for the field // extracted from the tag, a boolean saying whether to keep the field or ignore it, additional data that is stored // with the field information to avoid having to parse the tag again, and an error. type ParseTagFunc func(reflect.StructTag) (name string, keep bool, other interface{}, err error) // ValidateFunc is a function that accepts a reflect.Type and returns an error if the struct type is invalid in any // way. type ValidateFunc func(reflect.Type) error // LeafTypesFunc is a function that accepts a reflect.Type and returns true if the struct type a leaf, or false if not. // TODO(deklerk): is this description accurate? type LeafTypesFunc func(reflect.Type) bool // A Cache records information about the fields of struct types. // // A Cache is safe for use by multiple goroutines. type Cache struct { parseTag ParseTagFunc validate ValidateFunc leafTypes LeafTypesFunc cache sync.Map // from reflect.Type to cacheValue } // NewCache constructs a Cache. // // Its first argument should be a function that accepts // a struct tag and returns four values: an alternative name for the field // extracted from the tag, a boolean saying whether to keep the field or ignore // it, additional data that is stored with the field information to avoid // having to parse the tag again, and an error. // // Its second argument should be a function that accepts a reflect.Type and // returns an error if the struct type is invalid in any way. For example, it // may check that all of the struct field tags are valid, or that all fields // are of an appropriate type. func NewCache(parseTag ParseTagFunc, validate ValidateFunc, leafTypes LeafTypesFunc) *Cache { if parseTag == nil { parseTag = func(reflect.StructTag) (string, bool, interface{}, error) { return "", true, nil, nil } } if validate == nil { validate = func(reflect.Type) error { return nil } } if leafTypes == nil { leafTypes = func(reflect.Type) bool { return false } } return &Cache{ parseTag: parseTag, validate: validate, leafTypes: leafTypes, } } // A fieldScan represents an item on the fieldByNameFunc scan work list. type fieldScan struct { typ reflect.Type index []int } // Fields returns all the exported fields of t, which must be a struct type. It // follows the standard Go rules for embedded fields, modified by the presence // of tags. The result is sorted lexicographically by index. // // These rules apply in the absence of tags: // Anonymous struct fields are treated as if their inner exported fields were // fields in the outer struct (embedding). The result includes all fields that // aren't shadowed by fields at higher level of embedding. If more than one // field with the same name exists at the same level of embedding, it is // excluded. An anonymous field that is not of struct type is treated as having // its type as its name. // // Tags modify these rules as follows: // A field's tag is used as its name. // An anonymous struct field with a name given in its tag is treated as // a field having that name, rather than an embedded struct (the struct's // fields will not be returned). // If more than one field with the same name exists at the same level of embedding, // but exactly one of them is tagged, then the tagged field is reported and the others // are ignored. func (c *Cache) Fields(t reflect.Type) (List, error) { if t.Kind() != reflect.Struct { panic("fields: Fields of non-struct type") } return c.cachedTypeFields(t) } // A List is a list of Fields. type List []Field // Match returns the field in the list whose name best matches the supplied // name, nor nil if no field does. If there is a field with the exact name, it // is returned. Otherwise the first field (sorted by index) whose name matches // case-insensitively is returned. func (l List) Match(name string) *Field { return l.MatchBytes([]byte(name)) } // MatchBytes is identical to Match, except that the argument is a byte slice. func (l List) MatchBytes(name []byte) *Field { var f *Field for i := range l { ff := &l[i] if bytes.Equal(ff.nameBytes, name) { return ff } if f == nil && ff.equalFold(ff.nameBytes, name) { f = ff } } return f } type cacheValue struct { fields List err error } // cachedTypeFields is like typeFields but uses a cache to avoid repeated work. // This code has been copied and modified from // https://go.googlesource.com/go/+/go1.7.3/src/encoding/json/encode.go. func (c *Cache) cachedTypeFields(t reflect.Type) (List, error) { var cv cacheValue x, ok := c.cache.Load(t) if ok { cv = x.(cacheValue) } else { if err := c.validate(t); err != nil { cv = cacheValue{nil, err} } else { f, err := c.typeFields(t) cv = cacheValue{List(f), err} } c.cache.Store(t, cv) } return cv.fields, cv.err } func (c *Cache) typeFields(t reflect.Type) ([]Field, error) { fields, err := c.listFields(t) if err != nil { return nil, err } sort.Sort(byName(fields)) // Delete all fields that are hidden by the Go rules for embedded fields. // The fields are sorted in primary order of name, secondary order of field // index length. So the first field with a given name is the dominant one. var out []Field for advance, i := 0, 0; i < len(fields); i += advance { // One iteration per name. // Find the sequence of fields with the name of this first field. fi := fields[i] name := fi.Name for advance = 1; i+advance < len(fields); advance++ { fj := fields[i+advance] if fj.Name != name { break } } // Find the dominant field, if any, out of all fields that have the same name. dominant, ok := dominantField(fields[i : i+advance]) if ok { out = append(out, dominant) } } sort.Sort(byIndex(out)) return out, nil } func (c *Cache) listFields(t reflect.Type) ([]Field, error) { // This uses the same condition that the Go language does: there must be a unique instance // of the match at a given depth level. If there are multiple instances of a match at the // same depth, they annihilate each other and inhibit any possible match at a lower level. // The algorithm is breadth first search, one depth level at a time. // The current and next slices are work queues: // current lists the fields to visit on this depth level, // and next lists the fields on the next lower level. current := []fieldScan{} next := []fieldScan{{typ: t}} // nextCount records the number of times an embedded type has been // encountered and considered for queueing in the 'next' slice. // We only queue the first one, but we increment the count on each. // If a struct type T can be reached more than once at a given depth level, // then it annihilates itself and need not be considered at all when we // process that next depth level. var nextCount map[reflect.Type]int // visited records the structs that have been considered already. // Embedded pointer fields can create cycles in the graph of // reachable embedded types; visited avoids following those cycles. // It also avoids duplicated effort: if we didn't find the field in an // embedded type T at level 2, we won't find it in one at level 4 either. visited := map[reflect.Type]bool{} var fields []Field // Fields found. for len(next) > 0 { current, next = next, current[:0] count := nextCount nextCount = nil // Process all the fields at this depth, now listed in 'current'. // The loop queues embedded fields found in 'next', for processing during the next // iteration. The multiplicity of the 'current' field counts is recorded // in 'count'; the multiplicity of the 'next' field counts is recorded in 'nextCount'. for _, scan := range current { t := scan.typ if visited[t] { // We've looked through this type before, at a higher level. // That higher level would shadow the lower level we're now at, // so this one can't be useful to us. Ignore it. continue } visited[t] = true for i := 0; i < t.NumField(); i++ { f := t.Field(i) exported := (f.PkgPath == "") // If a named field is unexported, ignore it. An anonymous // unexported field is processed, because it may contain // exported fields, which are visible. if !exported && !f.Anonymous { continue } // Examine the tag. tagName, keep, other, err := c.parseTag(f.Tag) if err != nil { return nil, err } if !keep { continue } if c.leafTypes(f.Type) { fields = append(fields, newField(f, tagName, other, scan.index, i)) continue } var ntyp reflect.Type if f.Anonymous { // Anonymous field of type T or *T. ntyp = f.Type if ntyp.Kind() == reflect.Ptr { ntyp = ntyp.Elem() } } // Record fields with a tag name, non-anonymous fields, or // anonymous non-struct fields. if tagName != "" || ntyp == nil || ntyp.Kind() != reflect.Struct { if !exported { continue } fields = append(fields, newField(f, tagName, other, scan.index, i)) if count[t] > 1 { // If there were multiple instances, add a second, // so that the annihilation code will see a duplicate. fields = append(fields, fields[len(fields)-1]) } continue } // Queue embedded struct fields for processing with next level, // but only if the embedded types haven't already been queued. if nextCount[ntyp] > 0 { nextCount[ntyp] = 2 // exact multiple doesn't matter continue } if nextCount == nil { nextCount = map[reflect.Type]int{} } nextCount[ntyp] = 1 if count[t] > 1 { nextCount[ntyp] = 2 // exact multiple doesn't matter } var index []int index = append(index, scan.index...) index = append(index, i) next = append(next, fieldScan{ntyp, index}) } } } return fields, nil } func newField(f reflect.StructField, tagName string, other interface{}, index []int, i int) Field { name := tagName if name == "" { name = f.Name } sf := Field{ Name: name, NameFromTag: tagName != "", Type: f.Type, ParsedTag: other, nameBytes: []byte(name), } sf.equalFold = foldFunc(sf.nameBytes) sf.Index = append(sf.Index, index...) sf.Index = append(sf.Index, i) return sf } // byName sorts fields using the following criteria, in order: // 1. name // 2. embedding depth // 3. tag presence (preferring a tagged field) // 4. index sequence. type byName []Field func (x byName) Len() int { return len(x) } func (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] } func (x byName) Less(i, j int) bool { if x[i].Name != x[j].Name { return x[i].Name < x[j].Name } if len(x[i].Index) != len(x[j].Index) { return len(x[i].Index) < len(x[j].Index) } if x[i].NameFromTag != x[j].NameFromTag { return x[i].NameFromTag } return byIndex(x).Less(i, j) } // byIndex sorts field by index sequence. type byIndex []Field func (x byIndex) Len() int { return len(x) } func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] } func (x byIndex) Less(i, j int) bool { xi := x[i].Index xj := x[j].Index ln := len(xi) if l := len(xj); l < ln { ln = l } for k := 0; k < ln; k++ { if xi[k] != xj[k] { return xi[k] < xj[k] } } return len(xi) < len(xj) } // dominantField looks through the fields, all of which are known to have the // same name, to find the single field that dominates the others using Go's // embedding rules, modified by the presence of tags. If there are multiple // top-level fields, the boolean will be false: This condition is an error in // Go and we skip all the fields. func dominantField(fs []Field) (Field, bool) { // The fields are sorted in increasing index-length order, then by presence of tag. // That means that the first field is the dominant one. We need only check // for error cases: two fields at top level, either both tagged or neither tagged. if len(fs) > 1 && len(fs[0].Index) == len(fs[1].Index) && fs[0].NameFromTag == fs[1].NameFromTag { return Field{}, false } return fs[0], true } // ParseStandardTag extracts the sub-tag named by key, then parses it using the // de facto standard format introduced in encoding/json: // "-" means "ignore this tag". It must occur by itself. (parseStandardTag returns an error // in this case, whereas encoding/json accepts the "-" even if it is not alone.) // "" provides an alternative name for the field // ",opt1,opt2,..." specifies options after the name. // The options are returned as a []string. func ParseStandardTag(key string, t reflect.StructTag) (name string, keep bool, options []string, err error) { s := t.Get(key) parts := strings.Split(s, ",") if parts[0] == "-" { if len(parts) > 1 { return "", false, nil, errors.New(`"-" field tag with options`) } return "", false, nil, nil } if len(parts) > 1 { options = parts[1:] } return parts[0], true, options, nil } google-cloud-go-0.49.0/internal/fields/fields_test.go000066400000000000000000000315371356504100700225170ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package fields import ( "encoding/json" "errors" "fmt" "reflect" "testing" "time" "cloud.google.com/go/internal/testutil" "github.com/google/go-cmp/cmp" ) type embed1 struct { Em1 int Dup int // annihilates with embed2.Dup Shadow int embed3 } type embed2 struct { Dup int embed3 embed4 } type embed3 struct { Em3 int // annihilated because embed3 is in both embed1 and embed2 embed5 } type embed4 struct { Em4 int Dup int // annihilation of Dup in embed1, embed2 hides this Dup *embed1 // ignored because it occurs at a higher level } type embed5 struct { x int } type Anonymous int type S1 struct { Exported int unexported int Shadow int // shadows S1.Shadow embed1 *embed2 Anonymous } type Time struct { time.Time } var intType = reflect.TypeOf(int(0)) func field(name string, tval interface{}, index ...int) *Field { return &Field{ Name: name, Type: reflect.TypeOf(tval), Index: index, ParsedTag: []string(nil), } } func tfield(name string, tval interface{}, index ...int) *Field { return &Field{ Name: name, Type: reflect.TypeOf(tval), Index: index, NameFromTag: true, ParsedTag: []string(nil), } } func TestFieldsNoTags(t *testing.T) { c := NewCache(nil, nil, nil) got, err := c.Fields(reflect.TypeOf(S1{})) if err != nil { t.Fatal(err) } want := []*Field{ field("Exported", int(0), 0), field("Shadow", int(0), 2), field("Em1", int(0), 3, 0), field("Em4", int(0), 4, 2, 0), field("Anonymous", Anonymous(0), 5), } for _, f := range want { f.ParsedTag = nil } if msg, ok := compareFields(got, want); !ok { t.Error(msg) } } func TestAgainstJSONEncodingNoTags(t *testing.T) { // Demonstrates that this package produces the same set of fields as encoding/json. s1 := S1{ Exported: 1, unexported: 2, Shadow: 3, embed1: embed1{ Em1: 4, Dup: 5, Shadow: 6, embed3: embed3{ Em3: 7, embed5: embed5{x: 8}, }, }, embed2: &embed2{ Dup: 9, embed3: embed3{ Em3: 10, embed5: embed5{x: 11}, }, embed4: embed4{ Em4: 12, Dup: 13, embed1: &embed1{Em1: 14}, }, }, Anonymous: Anonymous(15), } var want S1 want.embed2 = &embed2{} // need this because reflection won't create it jsonRoundTrip(t, s1, &want) var got S1 got.embed2 = &embed2{} fields, err := NewCache(nil, nil, nil).Fields(reflect.TypeOf(got)) if err != nil { t.Fatal(err) } setFields(fields, &got, s1) if !testutil.Equal(got, want, cmp.AllowUnexported(S1{}, embed1{}, embed2{}, embed3{}, embed4{}, embed5{})) { t.Errorf("got\n%+v\nwant\n%+v", got, want) } } // Tests use of LeafTypes parameter to NewCache func TestAgainstJSONEncodingEmbeddedTime(t *testing.T) { timeLeafFn := func(t reflect.Type) bool { return t == reflect.TypeOf(time.Time{}) } // Demonstrates that this package can produce the same set of // fields as encoding/json for a struct with an embedded time.Time. now := time.Now().UTC() myt := Time{ now, } var want Time jsonRoundTrip(t, myt, &want) var got Time fields, err := NewCache(nil, nil, timeLeafFn).Fields(reflect.TypeOf(got)) if err != nil { t.Fatal(err) } setFields(fields, &got, myt) if !testutil.Equal(got, want) { t.Errorf("got\n%+v\nwant\n%+v", got, want) } } type S2 struct { NoTag int XXX int `json:"tag"` // tag name takes precedence Anonymous `json:"anon"` // anonymous non-structs also get their name from the tag Embed `json:"em"` // embedded structs with tags become fields Tag int YYY int `json:"Tag"` // tag takes precedence over untagged field of the same name Empty int `json:""` // empty tag is noop tEmbed1 tEmbed2 } type Embed struct { Em int } type tEmbed1 struct { Dup int X int `json:"Dup2"` } type tEmbed2 struct { Y int `json:"Dup"` // takes precedence over tEmbed1.Dup because it is tagged Z int `json:"Dup2"` // same name as tEmbed1.X and both tagged, so ignored } func jsonTagParser(t reflect.StructTag) (name string, keep bool, other interface{}, err error) { return ParseStandardTag("json", t) } func validateFunc(t reflect.Type) (err error) { if t.Kind() != reflect.Struct { return errors.New("non-struct type used") } for i := 0; i < t.NumField(); i++ { if t.Field(i).Type.Kind() == reflect.Slice { return fmt.Errorf("slice field found at field %s on struct %s", t.Field(i).Name, t.Name()) } } return nil } func TestFieldsWithTags(t *testing.T) { got, err := NewCache(jsonTagParser, nil, nil).Fields(reflect.TypeOf(S2{})) if err != nil { t.Fatal(err) } want := []*Field{ field("NoTag", int(0), 0), tfield("tag", int(0), 1), tfield("anon", Anonymous(0), 2), tfield("em", Embed{}, 4), tfield("Tag", int(0), 6), field("Empty", int(0), 7), tfield("Dup", int(0), 8, 0), } if msg, ok := compareFields(got, want); !ok { t.Error(msg) } } func TestAgainstJSONEncodingWithTags(t *testing.T) { // Demonstrates that this package produces the same set of fields as encoding/json. s2 := S2{ NoTag: 1, XXX: 2, Anonymous: 3, Embed: Embed{ Em: 4, }, tEmbed1: tEmbed1{ Dup: 5, X: 6, }, tEmbed2: tEmbed2{ Y: 7, Z: 8, }, } var want S2 jsonRoundTrip(t, s2, &want) var got S2 fields, err := NewCache(jsonTagParser, nil, nil).Fields(reflect.TypeOf(got)) if err != nil { t.Fatal(err) } setFields(fields, &got, s2) if !testutil.Equal(got, want, cmp.AllowUnexported(S2{})) { t.Errorf("got\n%+v\nwant\n%+v", got, want) } } func TestUnexportedAnonymousNonStruct(t *testing.T) { // An unexported anonymous non-struct field should not be recorded. // This is currently a bug in encoding/json. // https://github.com/golang/go/issues/18009 type S struct{} got, err := NewCache(jsonTagParser, nil, nil).Fields(reflect.TypeOf(S{})) if err != nil { t.Fatal(err) } if len(got) != 0 { t.Errorf("got %d fields, want 0", len(got)) } } func TestUnexportedAnonymousStruct(t *testing.T) { // An unexported anonymous struct with a tag is ignored. // This is currently a bug in encoding/json. // https://github.com/golang/go/issues/18009 type ( s1 struct{ X int } S2 struct { s1 `json:"Y"` } ) got, err := NewCache(jsonTagParser, nil, nil).Fields(reflect.TypeOf(S2{})) if err != nil { t.Fatal(err) } if len(got) != 0 { t.Errorf("got %d fields, want 0", len(got)) } } func TestDominantField(t *testing.T) { // With fields sorted by index length and then by tag presence, // the dominant field is always the first. Make sure all error // cases are caught. for _, test := range []struct { fields []Field wantOK bool }{ // A single field is OK. {[]Field{{Index: []int{0}}}, true}, {[]Field{{Index: []int{0}, NameFromTag: true}}, true}, // A single field at top level is OK. {[]Field{{Index: []int{0}}, {Index: []int{1, 0}}}, true}, {[]Field{{Index: []int{0}}, {Index: []int{1, 0}, NameFromTag: true}}, true}, {[]Field{{Index: []int{0}, NameFromTag: true}, {Index: []int{1, 0}, NameFromTag: true}}, true}, // A single tagged field is OK. {[]Field{{Index: []int{0}, NameFromTag: true}, {Index: []int{1}}}, true}, // Two untagged fields at the same level is an error. {[]Field{{Index: []int{0}}, {Index: []int{1}}}, false}, // Two tagged fields at the same level is an error. {[]Field{{Index: []int{0}, NameFromTag: true}, {Index: []int{1}, NameFromTag: true}}, false}, } { _, gotOK := dominantField(test.fields) if gotOK != test.wantOK { t.Errorf("%v: got %t, want %t", test.fields, gotOK, test.wantOK) } } } func TestIgnore(t *testing.T) { type S struct { X int `json:"-"` } got, err := NewCache(jsonTagParser, nil, nil).Fields(reflect.TypeOf(S{})) if err != nil { t.Fatal(err) } if len(got) != 0 { t.Errorf("got %d fields, want 0", len(got)) } } func TestParsedTag(t *testing.T) { type S struct { X int `json:"name,omitempty"` } got, err := NewCache(jsonTagParser, nil, nil).Fields(reflect.TypeOf(S{})) if err != nil { t.Fatal(err) } want := []*Field{ {Name: "name", NameFromTag: true, Type: intType, Index: []int{0}, ParsedTag: []string{"omitempty"}}, } if msg, ok := compareFields(got, want); !ok { t.Error(msg) } } func TestValidateFunc(t *testing.T) { type MyInvalidStruct struct { A string B []int } _, err := NewCache(nil, validateFunc, nil).Fields(reflect.TypeOf(MyInvalidStruct{})) if err == nil { t.Fatal("expected error, got nil") } type MyValidStruct struct { A string B int } _, err = NewCache(nil, validateFunc, nil).Fields(reflect.TypeOf(MyValidStruct{})) if err != nil { t.Fatalf("expected nil, got error: %s\n", err) } } func compareFields(got []Field, want []*Field) (msg string, ok bool) { if len(got) != len(want) { return fmt.Sprintf("got %d fields, want %d", len(got), len(want)), false } for i, g := range got { w := *want[i] if !fieldsEqual(&g, &w) { return fmt.Sprintf("got\n%+v\nwant\n%+v", g, w), false } } return "", true } // Need this because Field contains a function, which cannot be compared even // by testutil.Equal. func fieldsEqual(f1, f2 *Field) bool { if f1 == nil || f2 == nil { return f1 == f2 } return f1.Name == f2.Name && f1.NameFromTag == f2.NameFromTag && f1.Type == f2.Type && testutil.Equal(f1.ParsedTag, f2.ParsedTag) } // Set the fields of dst from those of src. // dst must be a pointer to a struct value. // src must be a struct value. func setFields(fields []Field, dst, src interface{}) { vsrc := reflect.ValueOf(src) vdst := reflect.ValueOf(dst).Elem() for _, f := range fields { fdst := vdst.FieldByIndex(f.Index) fsrc := vsrc.FieldByIndex(f.Index) fdst.Set(fsrc) } } func jsonRoundTrip(t *testing.T, in, out interface{}) { bytes, err := json.Marshal(in) if err != nil { t.Fatal(err) } if err := json.Unmarshal(bytes, out); err != nil { t.Fatal(err) } } type S3 struct { S4 Abc int AbC int Tag int X int `json:"Tag"` unexported int } type S4 struct { ABc int Y int `json:"Abc"` // ignored because of top-level Abc } func TestMatchingField(t *testing.T) { fields, err := NewCache(jsonTagParser, nil, nil).Fields(reflect.TypeOf(S3{})) if err != nil { t.Fatal(err) } for _, test := range []struct { name string want *Field }{ // Exact match wins. {"Abc", field("Abc", int(0), 1)}, {"AbC", field("AbC", int(0), 2)}, {"ABc", field("ABc", int(0), 0, 0)}, // If there are multiple matches but no exact match or tag, // the first field wins, lexicographically by index. // Here, "ABc" is at a deeper embedding level, but since S4 appears // first in S3, its index precedes the other fields of S3. {"abc", field("ABc", int(0), 0, 0)}, // Tag name takes precedence over untagged field of the same name. {"Tag", tfield("Tag", int(0), 4)}, // Unexported fields disappear. {"unexported", nil}, // Untagged embedded structs disappear. {"S4", nil}, } { if got := fields.Match(test.name); !fieldsEqual(got, test.want) { t.Errorf("match %q:\ngot %+v\nwant %+v", test.name, got, test.want) } } } func TestAgainstJSONMatchingField(t *testing.T) { s3 := S3{ S4: S4{ABc: 1, Y: 2}, Abc: 3, AbC: 4, Tag: 5, X: 6, unexported: 7, } var want S3 jsonRoundTrip(t, s3, &want) v := reflect.ValueOf(want) fields, err := NewCache(jsonTagParser, nil, nil).Fields(reflect.TypeOf(S3{})) if err != nil { t.Fatal(err) } for _, test := range []struct { name string got int }{ {"Abc", 3}, {"AbC", 4}, {"ABc", 1}, {"abc", 1}, {"Tag", 6}, } { f := fields.Match(test.name) if f == nil { t.Fatalf("%s: no match", test.name) } w := v.FieldByIndex(f.Index).Interface() if test.got != w { t.Errorf("%s: got %d, want %d", test.name, test.got, w) } } } func TestTagErrors(t *testing.T) { called := false c := NewCache(func(t reflect.StructTag) (string, bool, interface{}, error) { called = true s := t.Get("f") if s == "bad" { return "", false, nil, errors.New("error") } return s, true, nil, nil }, nil, nil) type T struct { X int `f:"ok"` Y int `f:"bad"` } _, err := c.Fields(reflect.TypeOf(T{})) if !called { t.Fatal("tag parser not called") } if err == nil { t.Error("want error, got nil") } // Second time, we should cache the error. called = false _, err = c.Fields(reflect.TypeOf(T{})) if called { t.Fatal("tag parser called on second time") } if err == nil { t.Error("want error, got nil") } } google-cloud-go-0.49.0/internal/fields/fold.go000066400000000000000000000077161356504100700211400ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package fields // This file was copied from https://go.googlesource.com/go/+/go1.7.3/src/encoding/json/fold.go. // Only the license and package were changed. import ( "bytes" "unicode/utf8" ) const ( caseMask = ^byte(0x20) // Mask to ignore case in ASCII. kelvin = '\u212a' smallLongEss = '\u017f' ) // foldFunc returns one of four different case folding equivalence // functions, from most general (and slow) to fastest: // // 1) bytes.EqualFold, if the key s contains any non-ASCII UTF-8 // 2) equalFoldRight, if s contains special folding ASCII ('k', 'K', 's', 'S') // 3) asciiEqualFold, no special, but includes non-letters (including _) // 4) simpleLetterEqualFold, no specials, no non-letters. // // The letters S and K are special because they map to 3 runes, not just 2: // * S maps to s and to U+017F 'Å¿' Latin small letter long s // * k maps to K and to U+212A 'K' Kelvin sign // See https://play.golang.org/p/tTxjOc0OGo // // The returned function is specialized for matching against s and // should only be given s. It's not curried for performance reasons. func foldFunc(s []byte) func(s, t []byte) bool { nonLetter := false special := false // special letter for _, b := range s { if b >= utf8.RuneSelf { return bytes.EqualFold } upper := b & caseMask if upper < 'A' || upper > 'Z' { nonLetter = true } else if upper == 'K' || upper == 'S' { // See above for why these letters are special. special = true } } if special { return equalFoldRight } if nonLetter { return asciiEqualFold } return simpleLetterEqualFold } // equalFoldRight is a specialization of bytes.EqualFold when s is // known to be all ASCII (including punctuation), but contains an 's', // 'S', 'k', or 'K', requiring a Unicode fold on the bytes in t. // See comments on foldFunc. func equalFoldRight(s, t []byte) bool { for _, sb := range s { if len(t) == 0 { return false } tb := t[0] if tb < utf8.RuneSelf { if sb != tb { sbUpper := sb & caseMask if 'A' <= sbUpper && sbUpper <= 'Z' { if sbUpper != tb&caseMask { return false } } else { return false } } t = t[1:] continue } // sb is ASCII and t is not. t must be either kelvin // sign or long s; sb must be s, S, k, or K. tr, size := utf8.DecodeRune(t) switch sb { case 's', 'S': if tr != smallLongEss { return false } case 'k', 'K': if tr != kelvin { return false } default: return false } t = t[size:] } if len(t) > 0 { return false } return true } // asciiEqualFold is a specialization of bytes.EqualFold for use when // s is all ASCII (but may contain non-letters) and contains no // special-folding letters. // See comments on foldFunc. func asciiEqualFold(s, t []byte) bool { if len(s) != len(t) { return false } for i, sb := range s { tb := t[i] if sb == tb { continue } if ('a' <= sb && sb <= 'z') || ('A' <= sb && sb <= 'Z') { if sb&caseMask != tb&caseMask { return false } } else { return false } } return true } // simpleLetterEqualFold is a specialization of bytes.EqualFold for // use when s is all ASCII letters (no underscores, etc) and also // doesn't contain 'k', 'K', 's', or 'S'. // See comments on foldFunc. func simpleLetterEqualFold(s, t []byte) bool { if len(s) != len(t) { return false } for i, b := range s { if b&caseMask != t[i]&caseMask { return false } } return true } google-cloud-go-0.49.0/internal/fields/fold_test.go000066400000000000000000000067241356504100700221750ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package fields // This file was copied from https://go.googlesource.com/go/+/go1.7.3/src/encoding/json/fold_test.go. // Only the license and package were changed. import ( "bytes" "strings" "testing" "unicode/utf8" ) var foldTests = []struct { fn func(s, t []byte) bool s, t string want bool }{ {equalFoldRight, "", "", true}, {equalFoldRight, "a", "a", true}, {equalFoldRight, "", "a", false}, {equalFoldRight, "a", "", false}, {equalFoldRight, "a", "A", true}, {equalFoldRight, "AB", "ab", true}, {equalFoldRight, "AB", "ac", false}, {equalFoldRight, "sbkKc", "Å¿bKKc", true}, {equalFoldRight, "SbKkc", "Å¿bKKc", true}, {equalFoldRight, "SbKkc", "Å¿bKK", false}, {equalFoldRight, "e", "é", false}, {equalFoldRight, "s", "S", true}, {simpleLetterEqualFold, "", "", true}, {simpleLetterEqualFold, "abc", "abc", true}, {simpleLetterEqualFold, "abc", "ABC", true}, {simpleLetterEqualFold, "abc", "ABCD", false}, {simpleLetterEqualFold, "abc", "xxx", false}, {asciiEqualFold, "a_B", "A_b", true}, {asciiEqualFold, "aa@", "aa`", false}, // verify 0x40 and 0x60 aren't case-equivalent } func TestFold(t *testing.T) { for i, tt := range foldTests { if got := tt.fn([]byte(tt.s), []byte(tt.t)); got != tt.want { t.Errorf("%d. %q, %q = %v; want %v", i, tt.s, tt.t, got, tt.want) } truth := strings.EqualFold(tt.s, tt.t) if truth != tt.want { t.Errorf("strings.EqualFold doesn't agree with case %d", i) } } } func TestFoldAgainstUnicode(t *testing.T) { const bufSize = 5 buf1 := make([]byte, 0, bufSize) buf2 := make([]byte, 0, bufSize) var runes []rune for i := 0x20; i <= 0x7f; i++ { runes = append(runes, rune(i)) } runes = append(runes, kelvin, smallLongEss) funcs := []struct { name string fold func(s, t []byte) bool letter bool // must be ASCII letter simple bool // must be simple ASCII letter (not 'S' or 'K') }{ { name: "equalFoldRight", fold: equalFoldRight, }, { name: "asciiEqualFold", fold: asciiEqualFold, simple: true, }, { name: "simpleLetterEqualFold", fold: simpleLetterEqualFold, simple: true, letter: true, }, } for _, ff := range funcs { for _, r := range runes { if r >= utf8.RuneSelf { continue } if ff.letter && !isASCIILetter(byte(r)) { continue } if ff.simple && (r == 's' || r == 'S' || r == 'k' || r == 'K') { continue } for _, r2 := range runes { buf1 := append(buf1[:0], 'x') buf2 := append(buf2[:0], 'x') buf1 = buf1[:1+utf8.EncodeRune(buf1[1:bufSize], r)] buf2 = buf2[:1+utf8.EncodeRune(buf2[1:bufSize], r2)] buf1 = append(buf1, 'x') buf2 = append(buf2, 'x') want := bytes.EqualFold(buf1, buf2) if got := ff.fold(buf1, buf2); got != want { t.Errorf("%s(%q, %q) = %v; want %v", ff.name, buf1, buf2, got, want) } } } } } func isASCIILetter(b byte) bool { return ('A' <= b && b <= 'Z') || ('a' <= b && b <= 'z') } google-cloud-go-0.49.0/internal/kokoro/000077500000000000000000000000001356504100700177105ustar00rootroot00000000000000google-cloud-go-0.49.0/internal/kokoro/check_incompat_changes.sh000077500000000000000000000040121356504100700247030ustar00rootroot00000000000000#!/usr/bin/env bash # Copyright 2019 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Skipped until https://github.com/golang/go/issues/34849 is resolved. exit 0 # Display commands being run set -x # Only run apidiff checks on go1.12 (we only need it once). if [[ `go version` != *"go1.12"* ]]; then exit 0 fi if git log -1 | grep BREAKING_CHANGE_ACCEPTABLE; then exit 0 fi go install golang.org/x/exp/cmd/apidiff # We compare against master@HEAD. This is unfortunate in some cases: if you're # working on an out-of-date branch, and master gets some new feature (that has # nothing to do with your work on your branch), you'll get an error message. # Thankfully the fix is quite simple: rebase your branch. git clone https://code.googlesource.com/gocloud /tmp/gocloud MANUALS="bigquery bigtable datastore firestore pubsub spanner storage logging" STABLE_GAPICS="container/apiv1 dataproc/apiv1 iam iam/admin/apiv1 iam/credentials/apiv1 kms/apiv1 language/apiv1 logging/apiv2 logging/logadmin pubsub/apiv1 spanner/apiv1 translate/apiv1 vision/apiv1" for dir in $MANUALS $STABLE_GAPICS; do pkg="cloud.google.com/go/$dir" echo "Testing $pkg" cd /tmp/gocloud apidiff -w /tmp/pkg.master $pkg cd - > /dev/null # TODO(deklerk): there's probably a nicer way to do this that doesn't require # two invocations if ! apidiff -incompatible /tmp/pkg.master $pkg | (! read); then echo "Detected incompatible API changes between master@HEAD and current state:" apidiff -incompatible /tmp/pkg.master $pkg exit 1 fi done google-cloud-go-0.49.0/internal/kokoro/continuous.sh000077500000000000000000000052421356504100700224600ustar00rootroot00000000000000#!/bin/bash # Copyright 2019 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. export GOOGLE_APPLICATION_CREDENTIALS=$KOKORO_KEYSTORE_DIR/72523_go_integration_service_account # Removing the GCLOUD_TESTS_GOLANG_PROJECT_ID setting may make some integration # tests (like profiler's) silently skipped, so make sure you know what you are # doing when changing / removing the next line. export GCLOUD_TESTS_GOLANG_PROJECT_ID=dulcet-port-762 export GCLOUD_TESTS_GOLANG_KEY=$GOOGLE_APPLICATION_CREDENTIALS export GCLOUD_TESTS_GOLANG_FIRESTORE_PROJECT_ID=gcloud-golang-firestore-tests export GCLOUD_TESTS_GOLANG_FIRESTORE_KEY=$KOKORO_KEYSTORE_DIR/72523_go_firestore_integration_service_account export GCLOUD_TESTS_API_KEY=`cat $KOKORO_KEYSTORE_DIR/72523_go_gcloud_tests_api_key` export GCLOUD_TESTS_GOLANG_KEYRING=projects/dulcet-port-762/locations/global/keyRings/go-integration-test export GCLOUD_TESTS_GOLANG_PROFILER_ZONE="us-west1-b" # Fail on any error set -eo pipefail # Display commands being run set -x # cd to project dir on Kokoro instance cd git/gocloud go version # Set $GOPATH export GOPATH="$HOME/go" export GOCLOUD_HOME=$GOPATH/src/cloud.google.com/go/ export PATH="$GOPATH/bin:$PATH" export GO111MODULE=on # Move code into $GOPATH and get dependencies mkdir -p $GOCLOUD_HOME git clone . $GOCLOUD_HOME cd $GOCLOUD_HOME try3() { eval "$*" || eval "$*" || eval "$*"; } # All packages, including +build tools, are fetched. try3 go mod download go install github.com/jstemmer/go-junit-report ./internal/kokoro/vet.sh mkdir $KOKORO_ARTIFACTS_DIR/tests # Takes the kokoro output log (raw stdout) and creates a machine-parseable xml # file (xUnit). Then it exits with whatever exit code the last command had. create_junit_xml() { last_status_code=$? cat $KOKORO_ARTIFACTS_DIR/$KOKORO_GERRIT_CHANGE_NUMBER.txt \ | go-junit-report > $KOKORO_ARTIFACTS_DIR/tests/sponge_log.xml exit $last_status_code } trap create_junit_xml EXIT ERR # Run tests and tee output to log file, to be pushed to GCS as artifact. for i in `find . -name go.mod`; do pushd `dirname $i`; go test -race -v -timeout 30m ./... 2>&1 \ | tee $KOKORO_ARTIFACTS_DIR/$KOKORO_GERRIT_CHANGE_NUMBER.txt popd; done google-cloud-go-0.49.0/internal/kokoro/presubmit.sh000077500000000000000000000037161356504100700222700ustar00rootroot00000000000000#!/bin/bash # Copyright 2019 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License.. # TODO(deklerk): Add integration tests when it's secure to do so. b/64723143 # Fail on any error set -eo pipefail # Display commands being run set -x # cd to project dir on Kokoro instance cd git/gocloud go version # Set $GOPATH export GOPATH="$HOME/go" export GOCLOUD_HOME=$GOPATH/src/cloud.google.com/go/ export PATH="$GOPATH/bin:$PATH" export GO111MODULE=on # Move code into $GOPATH and get dependencies mkdir -p $GOCLOUD_HOME git clone . $GOCLOUD_HOME cd $GOCLOUD_HOME try3() { eval "$*" || eval "$*" || eval "$*"; } # All packages, including +build tools, are fetched. try3 go mod download go install github.com/jstemmer/go-junit-report ./internal/kokoro/vet.sh ./internal/kokoro/check_incompat_changes.sh mkdir $KOKORO_ARTIFACTS_DIR/tests # Takes the kokoro output log (raw stdout) and creates a machine-parseable xml # file (xUnit). Then it exits with whatever exit code the last command had. create_junit_xml() { last_status_code=$? cat $KOKORO_ARTIFACTS_DIR/$KOKORO_GERRIT_CHANGE_NUMBER.txt \ | go-junit-report > $KOKORO_ARTIFACTS_DIR/tests/sponge_log.xml exit $last_status_code } trap create_junit_xml EXIT ERR # Run tests and tee output to log file, to be pushed to GCS as artifact. for i in `find . -name go.mod`; do pushd `dirname $i`; go test -race -v -timeout 15m -short ./... 2>&1 \ | tee $KOKORO_ARTIFACTS_DIR/$KOKORO_GERRIT_CHANGE_NUMBER.txt popd; done google-cloud-go-0.49.0/internal/kokoro/trampoline.sh000066400000000000000000000016131356504100700224170ustar00rootroot00000000000000#!/bin/bash # Copyright 2019 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -eo pipefail # Always run the cleanup script, regardless of the success of bouncing into # the container. function cleanup() { chmod +x ${KOKORO_GFILE_DIR}/trampoline_cleanup.sh ${KOKORO_GFILE_DIR}/trampoline_cleanup.sh echo "cleanup"; } trap cleanup EXIT python3 "${KOKORO_GFILE_DIR}/trampoline_v1.py" google-cloud-go-0.49.0/internal/kokoro/vet.sh000077500000000000000000000101461356504100700210470ustar00rootroot00000000000000#!/bin/bash # Copyright 2019 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Fail on any error set -e # Display commands being run set -x # Only run the linter on go1.13, because: # - It needs type aliases (so we can't use anything less than 1.9). # - It only has to run once per CI (so we just have to pick 1 version). # - It runs out of memory in go 1.12 https://github.com/dominikh/go-tools/issues/419. if [[ `go version` != *"go1.13"* ]]; then exit 0 fi go install \ github.com/golang/protobuf/protoc-gen-go \ golang.org/x/lint/golint \ golang.org/x/tools/cmd/goimports \ honnef.co/go/tools/cmd/staticcheck # Fail if a dependency was added without the necessary go.mod/go.sum change # being part of the commit. go mod tidy for i in `find . -name go.mod`; do pushd `dirname $i`; go mod tidy; popd; done git diff go.mod | tee /dev/stderr | (! read) git diff go.sum | tee /dev/stderr | (! read) gofmt -s -d -l . 2>&1 | tee /dev/stderr | (! read) goimports -l . 2>&1 | tee /dev/stderr | (! read) # Runs the linter. Regrettably the linter is very simple and does not provide the ability to exclude rules or files, # so we rely on inverse grepping to do this for us. # # Piping a bunch of greps may be slower than `grep -vE (thing|otherthing|anotherthing|etc)`, but since we have a good # amount of things we're excluding, it seems better to optimize for readability. # # Note: since we added the linter after-the-fact, some of the ignored errors here are because we can't change an # existing interface. (as opposed to us not caring about the error) golint ./... 2>&1 | ( \ grep -vE "gen\.go" | \ grep -vE "receiver name [a-zA-Z]+[0-9]* should be consistent with previous receiver name" | \ grep -vE "exported const AllUsers|AllAuthenticatedUsers|RoleOwner|SSD|HDD|PRODUCTION|DEVELOPMENT should have comment" | \ grep -v "exported func Value returns unexported type pretty.val, which can be annoying to use" | \ grep -v "exported func Increment returns unexported type firestore.increment, which can be annoying to use" | \ grep -v "ExecuteStreamingSql" | \ grep -v "MethodExecuteSql should be MethodExecuteSQL" | \ grep -vE "pubsub\/pstest\/fake\.go.+should have comment or be unexported" | \ grep -v "ClusterId" | \ grep -v "InstanceId" | \ grep -v "firestore.arrayUnion" | \ grep -v "firestore.arrayRemove" | \ grep -v "maxAttempts" | \ grep -v "UptimeCheckIpIterator" | \ grep -vE "apiv[0-9]+" | \ grep -v "ALL_CAPS" | \ grep -v "go-cloud-debug-agent" | \ grep -v "mock_test" | \ grep -v "internal/testutil/funcmock.go" | \ grep -v "internal/backoff" | \ grep -v "internal/trace" | \ grep -v "a blank import should be only in a main or test package" | \ grep -v "method ExecuteSql should be ExecuteSQL" | \ grep -vE "spanner/spansql/(sql|types).go:.*should have comment" | \ grep -vE "\.pb\.go:") | \ tee /dev/stderr | (! read) staticcheck -go 1.11 ./... 2>&1 | ( \ grep -v S1007 | \ grep -v SA1019 | \ grep -v firestore/internal/doc-snippets.go | \ grep -v functions/metadata/metadata_test.go | \ grep -v storage/bucket.go | \ grep -v spanner/value.go | \ grep -v go-cloud-debug-agent | \ grep -v pubsub/integration_test.go | \ grep -v internal/fields/fold.go | \ grep -v httpreplay/internal/proxy/debug.go | \ grep -v bigtable/internal/cbtconfig/cbtconfig.go | \ grep -v bigtable/cmd/cbt/cbt.go | \ grep -v asset/v1beta1/doc.go | \ grep -v asset/v1beta1/mock_test.go | \ grep -v spanner/value_test.go | \ grep -v bigtable/reader.go | \ grep -v internal/btree/btree.go | \ grep -v container/apiv1/mock_test.go) | \ tee /dev/stderr | (! read) echo "Done vetting!" google-cloud-go-0.49.0/internal/leakcheck/000077500000000000000000000000001356504100700203165ustar00rootroot00000000000000google-cloud-go-0.49.0/internal/leakcheck/leakcheck.go000066400000000000000000000062011356504100700225560ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package leakcheck contains functions to check leaked goroutines. // // Call "defer leakcheck.Check(t)" at the beginning of tests. // // This is very closely based on grpc-go's leakcheck. package leakcheck import ( "runtime" "sort" "strings" "time" ) var goroutinesToIgnore = []string{ "net/http/transport.go", "net/http/h2_bundle.go", "src/go.opencensus.io/stats/view/worker.go", "testing.Main(", "testing.tRunner(", "testing.(*M).", "runtime.goexit", "created by runtime.gc", "created by runtime/trace.Start", "interestingGoroutines", "runtime.MHeap_Scavenger", "signal.signal_recv", "sigterm.handler", "runtime_mcall", "(*loggingT).flushDaemon", "goroutine in C code", } // RegisterIgnoreGoroutine appends s into the ignore goroutine list. The // goroutines whose stack trace contains s will not be identified as leaked // goroutines. Not thread-safe, only call this function in init(). func RegisterIgnoreGoroutine(s string) { goroutinesToIgnore = append(goroutinesToIgnore, s) } func ignore(g string) bool { sl := strings.SplitN(g, "\n", 2) if len(sl) != 2 { return true } stack := strings.TrimSpace(sl[1]) if strings.HasPrefix(stack, "testing.RunTests") { return true } if stack == "" { return true } for _, s := range goroutinesToIgnore { if strings.Contains(stack, s) { return true } } return false } // interestingGoroutines returns all goroutines we care about for the purpose of // leak checking. It excludes testing or runtime ones. func interestingGoroutines() (gs []string) { buf := make([]byte, 2<<20) buf = buf[:runtime.Stack(buf, true)] for _, g := range strings.Split(string(buf), "\n\n") { if !ignore(g) { gs = append(gs, g) } } sort.Strings(gs) return } // Errorfer is the interface that wraps the Errorf method. It's a subset of // testing.TB to make it easy to use Check. type Errorfer interface { Errorf(format string, args ...interface{}) } func check(efer Errorfer, timeout time.Duration) { // Loop, waiting for goroutines to shut down. // Wait up to timeout, but finish as quickly as possible. deadline := time.Now().Add(timeout) var leaked []string for time.Now().Before(deadline) { if leaked = interestingGoroutines(); len(leaked) == 0 { return } time.Sleep(50 * time.Millisecond) } for _, g := range leaked { efer.Errorf("Leaked goroutine: %v", g) } } // Check looks at the currently-running goroutines and checks if there are any // interestring (created by gRPC) goroutines leaked. It waits up to 10 seconds // in the error cases. func Check(efer Errorfer) { check(efer, 10*time.Second) } google-cloud-go-0.49.0/internal/leakcheck/leakcheck_test.go000066400000000000000000000036401356504100700236210ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package leakcheck import ( "fmt" "strings" "testing" "time" ) type testErrorfer struct { errorCount int errors []string } func (e *testErrorfer) Errorf(format string, args ...interface{}) { e.errors = append(e.errors, fmt.Sprintf(format, args...)) e.errorCount++ } func TestCheck(t *testing.T) { const leakCount = 3 for i := 0; i < leakCount; i++ { go func() { time.Sleep(2 * time.Second) }() } if ig := interestingGoroutines(); len(ig) == 0 { t.Error("blah") } e := &testErrorfer{} check(e, time.Second) if e.errorCount != leakCount { t.Errorf("check found %v leaks, want %v leaks", e.errorCount, leakCount) t.Logf("leaked goroutines:\n%v", strings.Join(e.errors, "\n")) } check(t, 3*time.Second) } func ignoredTestingLeak(d time.Duration) { time.Sleep(d) } func TestCheckRegisterIgnore(t *testing.T) { RegisterIgnoreGoroutine("ignoredTestingLeak") const leakCount = 3 for i := 0; i < leakCount; i++ { go func() { time.Sleep(2 * time.Second) }() } go func() { ignoredTestingLeak(3 * time.Second) }() if ig := interestingGoroutines(); len(ig) == 0 { t.Error("blah") } e := &testErrorfer{} check(e, time.Second) if e.errorCount != leakCount { t.Errorf("check found %v leaks, want %v leaks", e.errorCount, leakCount) t.Logf("leaked goroutines:\n%v", strings.Join(e.errors, "\n")) } check(t, 3*time.Second) } google-cloud-go-0.49.0/internal/optional/000077500000000000000000000000001356504100700202315ustar00rootroot00000000000000google-cloud-go-0.49.0/internal/optional/optional.go000066400000000000000000000047101356504100700224070ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package optional provides versions of primitive types that can // be nil. These are useful in methods that update some of an API object's // fields. package optional import ( "fmt" "strings" "time" ) type ( // Bool is either a bool or nil. Bool interface{} // String is either a string or nil. String interface{} // Int is either an int or nil. Int interface{} // Uint is either a uint or nil. Uint interface{} // Float64 is either a float64 or nil. Float64 interface{} // Duration is either a time.Duration or nil. Duration interface{} ) // ToBool returns its argument as a bool. // It panics if its argument is nil or not a bool. func ToBool(v Bool) bool { x, ok := v.(bool) if !ok { doPanic("Bool", v) } return x } // ToString returns its argument as a string. // It panics if its argument is nil or not a string. func ToString(v String) string { x, ok := v.(string) if !ok { doPanic("String", v) } return x } // ToInt returns its argument as an int. // It panics if its argument is nil or not an int. func ToInt(v Int) int { x, ok := v.(int) if !ok { doPanic("Int", v) } return x } // ToUint returns its argument as a uint. // It panics if its argument is nil or not a uint. func ToUint(v Uint) uint { x, ok := v.(uint) if !ok { doPanic("Uint", v) } return x } // ToFloat64 returns its argument as a float64. // It panics if its argument is nil or not a float64. func ToFloat64(v Float64) float64 { x, ok := v.(float64) if !ok { doPanic("Float64", v) } return x } // ToDuration returns its argument as a time.Duration. // It panics if its argument is nil or not a time.Duration. func ToDuration(v Duration) time.Duration { x, ok := v.(time.Duration) if !ok { doPanic("Duration", v) } return x } func doPanic(capType string, v interface{}) { panic(fmt.Sprintf("optional.%s value should be %s, got %T", capType, strings.ToLower(capType), v)) } google-cloud-go-0.49.0/internal/optional/optional_test.go000066400000000000000000000031741356504100700234510ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package optional import "testing" func TestConvertSuccess(t *testing.T) { if got, want := ToBool(false), false; got != want { t.Errorf("got %v, want %v", got, want) } if got, want := ToString(""), ""; got != want { t.Errorf("got %v, want %v", got, want) } if got, want := ToInt(0), 0; got != want { t.Errorf("got %v, want %v", got, want) } if got, want := ToUint(uint(0)), uint(0); got != want { t.Errorf("got %v, want %v", got, want) } if got, want := ToFloat64(0.0), 0.0; got != want { t.Errorf("got %v, want %v", got, want) } } func TestConvertFailure(t *testing.T) { for _, f := range []func(){ func() { ToBool(nil) }, func() { ToBool(3) }, func() { ToString(nil) }, func() { ToString(3) }, func() { ToInt(nil) }, func() { ToInt("") }, func() { ToUint(nil) }, func() { ToUint("") }, func() { ToFloat64(nil) }, func() { ToFloat64("") }, } { if !panics(f) { t.Error("got no panic, want panic") } } } func panics(f func()) (b bool) { defer func() { if recover() != nil { b = true } }() f() return false } google-cloud-go-0.49.0/internal/pretty/000077500000000000000000000000001356504100700177335ustar00rootroot00000000000000google-cloud-go-0.49.0/internal/pretty/diff.go000066400000000000000000000040551356504100700211760ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package pretty import ( "fmt" "io/ioutil" "os" "os/exec" "syscall" ) // Diff compares the pretty-printed representation of two values. The second // return value reports whether the two values' representations are identical. // If it is false, the first return value contains the diffs. // // The output labels the first value "want" and the second "got". // // Diff works by invoking the "diff" command. It will only succeed in // environments where "diff" is on the shell path. func Diff(want, got interface{}) (string, bool, error) { fname1, err := writeToTemp(want) if err != nil { return "", false, err } defer os.Remove(fname1) fname2, err := writeToTemp(got) if err != nil { return "", false, err } defer os.Remove(fname2) cmd := exec.Command("diff", "-u", "--label=want", "--label=got", fname1, fname2) out, err := cmd.Output() if err == nil { return string(out), true, nil } eerr, ok := err.(*exec.ExitError) if !ok { return "", false, err } ws, ok := eerr.Sys().(syscall.WaitStatus) if !ok { return "", false, err } if ws.ExitStatus() != 1 { return "", false, err } // Exit status of 1 means no error, but diffs were found. return string(out), false, nil } func writeToTemp(v interface{}) (string, error) { f, err := ioutil.TempFile("", "prettyDiff") if err != nil { return "", err } if _, err := fmt.Fprintf(f, "%+v\n", Value(v)); err != nil { return "", err } if err := f.Close(); err != nil { return "", err } return f.Name(), nil } google-cloud-go-0.49.0/internal/pretty/diff_test.go000066400000000000000000000023471356504100700222370ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package pretty import "testing" func TestDiff(t *testing.T) { for _, test := range []struct { v1, v2 interface{} ok bool want string }{ {5, 5, true, ""}, {"foo", "foo", true, ""}, {[]int{1, 2, 3}, []int{1, 0, 3}, false, `--- want +++ got @@ -1,5 +1,5 @@ []int{ 1, - 2, + 0, 3, } `}, } { got, ok, err := Diff(test.v1, test.v2) if err != nil { t.Errorf("%v vs. %v: %v", test.v1, test.v2, err) continue } if ok != test.ok { t.Errorf("%v vs. %v: got %t, want %t", test.v1, test.v2, ok, test.ok) } if got != test.want { t.Errorf("%v vs. %v: got:\n%q\nwant:\n%q", test.v1, test.v2, got, test.want) } } } google-cloud-go-0.49.0/internal/pretty/pretty.go000066400000000000000000000150461356504100700216170ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package pretty implements a simple pretty-printer. It is intended for // debugging the output of tests. // // It follows pointers and produces multi-line output for complex values like // slices, maps and structs. package pretty import ( "fmt" "io" "reflect" "sort" "strings" "time" ) // Indent is the string output at each level of indentation. var Indent = " " // Value returns a value that will print prettily when used as an // argument for the %v or %s format specifiers. // With no flags, struct fields and map keys with default values are omitted. // With the '+' or '#' flags, all values are displayed. // // This package does not detect cycles. Attempting to print a Value that // contains cycles will result in unbounded recursion. func Value(v interface{}) val { return val{v: v} } // val is a value. type val struct{ v interface{} } // Format implements the fmt.Formatter interface. func (v val) Format(s fmt.State, c rune) { if c == 'v' || c == 's' { fprint(s, reflect.ValueOf(v.v), state{ defaults: s.Flag('+') || s.Flag('#'), }) } else { fmt.Fprintf(s, "%%!%c(pretty.val)", c) } } type state struct { level int prefix, suffix string defaults bool } const maxLevel = 100 var typeOfTime = reflect.TypeOf(time.Time{}) func fprint(w io.Writer, v reflect.Value, s state) { if s.level > maxLevel { fmt.Fprintln(w, "pretty: max nested depth exceeded") return } indent := strings.Repeat(Indent, s.level) fmt.Fprintf(w, "%s%s", indent, s.prefix) if isNil(v) { fmt.Fprintf(w, "nil%s", s.suffix) return } if v.Type().Kind() == reflect.Interface { v = v.Elem() } if v.Type() == typeOfTime { fmt.Fprintf(w, "%s%s", v.Interface(), s.suffix) return } for v.Type().Kind() == reflect.Ptr { fmt.Fprintf(w, "&") v = v.Elem() } switch v.Type().Kind() { default: fmt.Fprintf(w, "%s%s", short(v), s.suffix) case reflect.Array: fmt.Fprintf(w, "%s{\n", v.Type()) for i := 0; i < v.Len(); i++ { fprint(w, v.Index(i), state{ level: s.level + 1, prefix: "", suffix: ",", defaults: s.defaults, }) fmt.Fprintln(w) } fmt.Fprintf(w, "%s}", indent) case reflect.Slice: fmt.Fprintf(w, "%s{", v.Type()) if v.Len() > 0 { fmt.Fprintln(w) for i := 0; i < v.Len(); i++ { fprint(w, v.Index(i), state{ level: s.level + 1, prefix: "", suffix: ",", defaults: s.defaults, }) fmt.Fprintln(w) } } fmt.Fprintf(w, "%s}%s", indent, s.suffix) case reflect.Map: fmt.Fprintf(w, "%s{", v.Type()) if v.Len() > 0 { fmt.Fprintln(w) keys := v.MapKeys() maybeSort(keys, v.Type().Key()) for _, key := range keys { val := v.MapIndex(key) if s.defaults || !isDefault(val) { fprint(w, val, state{ level: s.level + 1, prefix: short(key) + ": ", suffix: ",", defaults: s.defaults, }) fmt.Fprintln(w) } } } fmt.Fprintf(w, "%s}%s", indent, s.suffix) case reflect.Struct: t := v.Type() fmt.Fprintf(w, "%s{\n", t) for i := 0; i < t.NumField(); i++ { f := v.Field(i) if s.defaults || !isDefault(f) { fprint(w, f, state{ level: s.level + 1, prefix: t.Field(i).Name + ": ", suffix: ",", defaults: s.defaults, }) fmt.Fprintln(w) } } fmt.Fprintf(w, "%s}%s", indent, s.suffix) } } func isNil(v reflect.Value) bool { if !v.IsValid() { return true } switch v.Type().Kind() { case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: return v.IsNil() default: return false } } func isDefault(v reflect.Value) bool { if !v.IsValid() { return true } t := v.Type() switch t.Kind() { case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: return v.IsNil() default: if !v.CanInterface() { return false } return t.Comparable() && v.Interface() == reflect.Zero(t).Interface() } } // short returns a short, one-line string for v. func short(v reflect.Value) string { if !v.IsValid() { return "nil" } if v.Type().Kind() == reflect.String { return fmt.Sprintf("%q", v) } return fmt.Sprintf("%v", v) } func maybeSort(vs []reflect.Value, t reflect.Type) { if less := lessFunc(t); less != nil { sort.Sort(&sorter{vs, less}) } } // lessFunc returns a function that implements the "<" operator // for the given type, or nil if the type doesn't support "<" . func lessFunc(t reflect.Type) func(v1, v2 interface{}) bool { switch t.Kind() { case reflect.String: return func(v1, v2 interface{}) bool { return v1.(string) < v2.(string) } case reflect.Int: return func(v1, v2 interface{}) bool { return v1.(int) < v2.(int) } case reflect.Int8: return func(v1, v2 interface{}) bool { return v1.(int8) < v2.(int8) } case reflect.Int16: return func(v1, v2 interface{}) bool { return v1.(int16) < v2.(int16) } case reflect.Int32: return func(v1, v2 interface{}) bool { return v1.(int32) < v2.(int32) } case reflect.Int64: return func(v1, v2 interface{}) bool { return v1.(int64) < v2.(int64) } case reflect.Uint: return func(v1, v2 interface{}) bool { return v1.(uint) < v2.(uint) } case reflect.Uint8: return func(v1, v2 interface{}) bool { return v1.(uint8) < v2.(uint8) } case reflect.Uint16: return func(v1, v2 interface{}) bool { return v1.(uint16) < v2.(uint16) } case reflect.Uint32: return func(v1, v2 interface{}) bool { return v1.(uint32) < v2.(uint32) } case reflect.Uint64: return func(v1, v2 interface{}) bool { return v1.(uint64) < v2.(uint64) } case reflect.Float32: return func(v1, v2 interface{}) bool { return v1.(float32) < v2.(float32) } case reflect.Float64: return func(v1, v2 interface{}) bool { return v1.(float64) < v2.(float64) } default: return nil } } type sorter struct { vs []reflect.Value less func(v1, v2 interface{}) bool } func (s *sorter) Len() int { return len(s.vs) } func (s *sorter) Swap(i, j int) { s.vs[i], s.vs[j] = s.vs[j], s.vs[i] } func (s *sorter) Less(i, j int) bool { return s.less(s.vs[i].Interface(), s.vs[j].Interface()) } google-cloud-go-0.49.0/internal/pretty/pretty_test.go000066400000000000000000000045711356504100700226570ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package pretty import ( "fmt" "strings" "testing" ) type S struct { X int Y bool z *string } func TestSprint(t *testing.T) { Indent = "~" i := 17 for _, test := range []struct { value interface{} want string }{ // primitives and pointer {nil, "nil"}, {3, "3"}, {9.8, "9.8"}, {true, "true"}, {"foo", `"foo"`}, {&i, "&17"}, // array and slice {[3]int{1, 2, 3}, "[3]int{\n~1,\n~2,\n~3,\n}"}, {[]int{1, 2, 3}, "[]int{\n~1,\n~2,\n~3,\n}"}, {[]int{}, "[]int{}"}, {[]string{"foo"}, "[]string{\n~\"foo\",\n}"}, // map {map[int]bool{}, "map[int]bool{}"}, {map[int]bool{1: true, 2: false, 3: true}, "map[int]bool{\n~1: true,\n~3: true,\n}"}, // struct {S{}, "pretty.S{\n}"}, {S{3, true, ptr("foo")}, "pretty.S{\n~X: 3,\n~Y: true,\n~z: &\"foo\",\n}"}, // interface {[]interface{}{&i}, "[]interface {}{\n~&17,\n}"}, // nesting {[]S{{1, false, ptr("a")}, {2, true, ptr("b")}}, `[]pretty.S{ ~pretty.S{ ~~X: 1, ~~z: &"a", ~}, ~pretty.S{ ~~X: 2, ~~Y: true, ~~z: &"b", ~}, }`}, } { got := fmt.Sprintf("%v", Value(test.value)) if got != test.want { t.Errorf("%v: got:\n%q\nwant:\n%q", test.value, got, test.want) } } } func TestWithDefaults(t *testing.T) { Indent = "~" for _, test := range []struct { value interface{} want string }{ {map[int]bool{1: true, 2: false, 3: true}, "map[int]bool{\n~1: true,\n~2: false,\n~3: true,\n}"}, {S{}, "pretty.S{\n~X: 0,\n~Y: false,\n~z: nil,\n}"}, } { got := fmt.Sprintf("%+v", Value(test.value)) if got != test.want { t.Errorf("%v: got:\n%q\nwant:\n%q", test.value, got, test.want) } } } func TestBadVerb(t *testing.T) { got := fmt.Sprintf("%d", Value(8)) want := "%!d(" if !strings.HasPrefix(got, want) { t.Errorf("got %q, want prefix %q", got, want) } } func ptr(s string) *string { return &s } google-cloud-go-0.49.0/internal/protostruct/000077500000000000000000000000001356504100700210145ustar00rootroot00000000000000google-cloud-go-0.49.0/internal/protostruct/protostruct.go000066400000000000000000000030671356504100700237610ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package protostruct supports operations on the protocol buffer Struct message. package protostruct import ( pb "github.com/golang/protobuf/ptypes/struct" ) // DecodeToMap converts a pb.Struct to a map from strings to Go types. // DecodeToMap panics if s is invalid. func DecodeToMap(s *pb.Struct) map[string]interface{} { if s == nil { return nil } m := map[string]interface{}{} for k, v := range s.Fields { m[k] = decodeValue(v) } return m } func decodeValue(v *pb.Value) interface{} { switch k := v.Kind.(type) { case *pb.Value_NullValue: return nil case *pb.Value_NumberValue: return k.NumberValue case *pb.Value_StringValue: return k.StringValue case *pb.Value_BoolValue: return k.BoolValue case *pb.Value_StructValue: return DecodeToMap(k.StructValue) case *pb.Value_ListValue: s := make([]interface{}, len(k.ListValue.Values)) for i, e := range k.ListValue.Values { s[i] = decodeValue(e) } return s default: panic("protostruct: unknown kind") } } google-cloud-go-0.49.0/internal/protostruct/protostruct_test.go000066400000000000000000000034211356504100700250120ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package protostruct supports operations on the protocol buffer Struct message. package protostruct import ( "testing" "cloud.google.com/go/internal/testutil" pb "github.com/golang/protobuf/ptypes/struct" ) func TestDecodeToMap(t *testing.T) { if got := DecodeToMap(nil); !testutil.Equal(got, map[string]interface{}(nil)) { t.Errorf("DecodeToMap(nil) = %v, want nil", got) } nullv := &pb.Value{Kind: &pb.Value_NullValue{}} stringv := &pb.Value{Kind: &pb.Value_StringValue{"x"}} boolv := &pb.Value{Kind: &pb.Value_BoolValue{true}} numberv := &pb.Value{Kind: &pb.Value_NumberValue{2.7}} in := &pb.Struct{Fields: map[string]*pb.Value{ "n": nullv, "s": stringv, "b": boolv, "f": numberv, "l": {Kind: &pb.Value_ListValue{&pb.ListValue{ Values: []*pb.Value{nullv, stringv, boolv, numberv}, }}}, "S": {Kind: &pb.Value_StructValue{&pb.Struct{Fields: map[string]*pb.Value{ "n1": nullv, "b1": boolv, }}}}, }} want := map[string]interface{}{ "n": nil, "s": "x", "b": true, "f": 2.7, "l": []interface{}{nil, "x", true, 2.7}, "S": map[string]interface{}{"n1": nil, "b1": true}, } got := DecodeToMap(in) if diff := testutil.Diff(got, want); diff != "" { t.Error(diff) } } google-cloud-go-0.49.0/internal/retry.go000066400000000000000000000033001356504100700200740ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package internal import ( "context" "time" gax "github.com/googleapis/gax-go/v2" ) // Retry calls the supplied function f repeatedly according to the provided // backoff parameters. It returns when one of the following occurs: // When f's first return value is true, Retry immediately returns with f's second // return value. // When the provided context is done, Retry returns with an error that // includes both ctx.Error() and the last error returned by f. func Retry(ctx context.Context, bo gax.Backoff, f func() (stop bool, err error)) error { return retry(ctx, bo, f, gax.Sleep) } func retry(ctx context.Context, bo gax.Backoff, f func() (stop bool, err error), sleep func(context.Context, time.Duration) error) error { var lastErr error for { stop, err := f() if stop { return err } // Remember the last "real" error from f. if err != nil && err != context.Canceled && err != context.DeadlineExceeded { lastErr = err } p := bo.Pause() if cerr := sleep(ctx, p); cerr != nil { if lastErr != nil { return Annotatef(lastErr, "retry failed with %v; last error", cerr) } return cerr } } } google-cloud-go-0.49.0/internal/retry_test.go000066400000000000000000000046161356504100700211460ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package internal import ( "context" "errors" "fmt" "testing" "time" gax "github.com/googleapis/gax-go/v2" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) func TestRetry(t *testing.T) { ctx := context.Background() // Without a context deadline, retry will run until the function // says not to retry any more. n := 0 endRetry := errors.New("end retry") err := retry(ctx, gax.Backoff{}, func() (bool, error) { n++ if n < 10 { return false, nil } return true, endRetry }, func(context.Context, time.Duration) error { return nil }) if got, want := err, endRetry; got != want { t.Errorf("got %v, want %v", err, endRetry) } if n != 10 { t.Errorf("n: got %d, want %d", n, 10) } // If the context has a deadline, sleep will return an error // and end the function. n = 0 err = retry(ctx, gax.Backoff{}, func() (bool, error) { return false, nil }, func(context.Context, time.Duration) error { n++ if n < 10 { return nil } return context.DeadlineExceeded }) if err == nil { t.Error("got nil, want error") } } func TestRetryPreserveError(t *testing.T) { // Retry tries to preserve the type and other information from // the last error returned by the function. err := retry(context.Background(), gax.Backoff{}, func() (bool, error) { return false, status.Error(codes.NotFound, "not found") }, func(context.Context, time.Duration) error { return context.DeadlineExceeded }) got, ok := status.FromError(err) if !ok { t.Fatalf("got %T, wanted a status", got) } if g, w := got.Code(), codes.NotFound; g != w { t.Errorf("got code %v, want %v", g, w) } wantMessage := fmt.Sprintf("retry failed with %v; last error: not found", context.DeadlineExceeded) if g, w := got.Message(), wantMessage; g != w { t.Errorf("got message %q, want %q", g, w) } } google-cloud-go-0.49.0/internal/testutil/000077500000000000000000000000001356504100700202615ustar00rootroot00000000000000google-cloud-go-0.49.0/internal/testutil/cmp.go000066400000000000000000000035051356504100700213720ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package testutil import ( "math" "math/big" "github.com/golang/protobuf/proto" "github.com/google/go-cmp/cmp" ) var ( alwaysEqual = cmp.Comparer(func(_, _ interface{}) bool { return true }) defaultCmpOptions = []cmp.Option{ // Use proto.Equal for protobufs cmp.Comparer(proto.Equal), // Use big.Rat.Cmp for big.Rats cmp.Comparer(func(x, y *big.Rat) bool { if x == nil || y == nil { return x == y } return x.Cmp(y) == 0 }), // NaNs compare equal cmp.FilterValues(func(x, y float64) bool { return math.IsNaN(x) && math.IsNaN(y) }, alwaysEqual), cmp.FilterValues(func(x, y float32) bool { return math.IsNaN(float64(x)) && math.IsNaN(float64(y)) }, alwaysEqual), } ) // Equal tests two values for equality. func Equal(x, y interface{}, opts ...cmp.Option) bool { // Put default options at the end. Order doesn't matter. opts = append(opts[:len(opts):len(opts)], defaultCmpOptions...) return cmp.Equal(x, y, opts...) } // Diff reports the differences between two values. // Diff(x, y) == "" iff Equal(x, y). func Diff(x, y interface{}, opts ...cmp.Option) string { // Put default options at the end. Order doesn't matter. opts = append(opts[:len(opts):len(opts)], defaultCmpOptions...) return cmp.Diff(x, y, opts...) } google-cloud-go-0.49.0/internal/testutil/context.go000066400000000000000000000121101356504100700222670ustar00rootroot00000000000000// Copyright 2014 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package testutil contains helper functions for writing tests. package testutil import ( "context" "errors" "fmt" "io/ioutil" "log" "os" "golang.org/x/oauth2" "golang.org/x/oauth2/google" "golang.org/x/oauth2/jwt" ) const ( envProjID = "GCLOUD_TESTS_GOLANG_PROJECT_ID" envPrivateKey = "GCLOUD_TESTS_GOLANG_KEY" ) // ProjID returns the project ID to use in integration tests, or the empty // string if none is configured. func ProjID() string { return os.Getenv(envProjID) } // Credentials returns the credentials to use in integration tests, or nil if // none is configured. It uses the standard environment variable for tests in // this repo. func Credentials(ctx context.Context, scopes ...string) *google.Credentials { return CredentialsEnv(ctx, envPrivateKey, scopes...) } // CredentialsEnv returns the credentials to use in integration tests, or nil // if none is configured. If the environment variable is unset, CredentialsEnv // will try to find 'Application Default Credentials'. Else, CredentialsEnv // will return nil. CredentialsEnv will log.Fatal if the token source is // specified but missing or invalid. func CredentialsEnv(ctx context.Context, envVar string, scopes ...string) *google.Credentials { key := os.Getenv(envVar) if key == "" { // Try for application default credentials. creds, err := google.FindDefaultCredentials(ctx, scopes...) if err != nil { log.Println("No 'Application Default Credentials' found.") return nil } return creds } data, err := ioutil.ReadFile(key) if err != nil { log.Fatal(err) } creds, err := google.CredentialsFromJSON(ctx, data, scopes...) if err != nil { log.Fatal(err) } return creds } // TokenSource returns the OAuth2 token source to use in integration tests, // or nil if none is configured. It uses the standard environment variable // for tests in this repo. func TokenSource(ctx context.Context, scopes ...string) oauth2.TokenSource { return TokenSourceEnv(ctx, envPrivateKey, scopes...) } // TokenSourceEnv returns the OAuth2 token source to use in integration tests. or nil // if none is configured. It tries to get credentials from the filename in the // environment variable envVar. If the environment variable is unset, TokenSourceEnv // will try to find 'Application Default Credentials'. Else, TokenSourceEnv will // return nil. TokenSourceEnv will log.Fatal if the token source is specified but // missing or invalid. func TokenSourceEnv(ctx context.Context, envVar string, scopes ...string) oauth2.TokenSource { key := os.Getenv(envVar) if key == "" { // Try for application default credentials. ts, err := google.DefaultTokenSource(ctx, scopes...) if err != nil { log.Println("No 'Application Default Credentials' found.") return nil } return ts } conf, err := jwtConfigFromFile(key, scopes) if err != nil { log.Fatal(err) } return conf.TokenSource(ctx) } // JWTConfig reads the JSON private key file whose name is in the default // environment variable, and returns the jwt.Config it contains. It ignores // scopes. // If the environment variable is empty, it returns (nil, nil). func JWTConfig() (*jwt.Config, error) { return jwtConfigFromFile(os.Getenv(envPrivateKey), nil) } // jwtConfigFromFile reads the given JSON private key file, and returns the // jwt.Config it contains. // If the filename is empty, it returns (nil, nil). func jwtConfigFromFile(filename string, scopes []string) (*jwt.Config, error) { if filename == "" { return nil, nil } jsonKey, err := ioutil.ReadFile(filename) if err != nil { return nil, fmt.Errorf("cannot read the JSON key file, err: %v", err) } conf, err := google.JWTConfigFromJSON(jsonKey, scopes...) if err != nil { return nil, fmt.Errorf("google.JWTConfigFromJSON: %v", err) } return conf, nil } // CanReplay reports whether an integration test can be run in replay mode. // The replay file must exist, and the GCLOUD_TESTS_GOLANG_ENABLE_REPLAY // environment variable must be non-empty. func CanReplay(replayFilename string) bool { if os.Getenv("GCLOUD_TESTS_GOLANG_ENABLE_REPLAY") == "" { return false } _, err := os.Stat(replayFilename) return err == nil } // ErroringTokenSource is a token source for testing purposes, // to always return a non-nil error to its caller. It is useful // when testing error responses with bad oauth2 credentials. type ErroringTokenSource struct{} // Token implements oauth2.TokenSource, returning a nil oauth2.Token and a non-nil error. func (fts ErroringTokenSource) Token() (*oauth2.Token, error) { return nil, errors.New("intentional error") } google-cloud-go-0.49.0/internal/testutil/headers_enforcer.go000066400000000000000000000146751356504100700241230ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package testutil import ( "bytes" "context" "errors" "fmt" "log" "os" "strings" "google.golang.org/api/option" "google.golang.org/grpc" "google.golang.org/grpc/metadata" ) // HeaderChecker defines header checking and validation rules for any outgoing metadata. type HeaderChecker struct { // Key is the header name to be checked against e.g. "x-goog-api-client". Key string // ValuesValidator validates the header values retrieved from mapping against // Key in the Headers. ValuesValidator func(values ...string) error } // HeadersEnforcer asserts that outgoing RPC headers // are present and match expectations. If the expected headers // are not present or don't match expectations, it'll invoke OnFailure // with the validation error, or instead log.Fatal if OnFailure is nil. // // It expects that every declared key will be present in the outgoing // RPC header and each value will be validated by the validation function. type HeadersEnforcer struct { // Checkers maps header keys that are expected to be sent in the metadata // of outgoing gRPC requests, against the values passed into the custom // validation functions. // // If Checkers is nil or empty, only the default header "x-goog-api-client" // will be checked for. // Otherwise, if you supply Matchers, those keys and their respective // validation functions will be checked. Checkers []*HeaderChecker // OnFailure is the function that will be invoked after all validation // failures have been composed. If OnFailure is nil, log.Fatal will be // invoked instead. OnFailure func(fmt_ string, args ...interface{}) } // StreamInterceptors returns a list of StreamClientInterceptor functions which // enforce the presence and validity of expected headers during streaming RPCs. // // For client implementations which provide their own StreamClientInterceptor(s) // these interceptors should be specified as the final elements to // WithChainStreamInterceptor. // // Alternatively, users may apply gPRC options produced from DialOptions to // apply all applicable gRPC interceptors. func (h *HeadersEnforcer) StreamInterceptors() []grpc.StreamClientInterceptor { return []grpc.StreamClientInterceptor{h.interceptStream} } // UnaryInterceptors returns a list of UnaryClientInterceptor functions which // enforce the presence and validity of expected headers during unary RPCs. // // For client implementations which provide their own UnaryClientInterceptor(s) // these interceptors should be specified as the final elements to // WithChainUnaryInterceptor. // // Alternatively, users may apply gPRC options produced from DialOptions to // apply all applicable gRPC interceptors. func (h *HeadersEnforcer) UnaryInterceptors() []grpc.UnaryClientInterceptor { return []grpc.UnaryClientInterceptor{h.interceptUnary} } // DialOptions returns gRPC DialOptions consisting of unary and stream interceptors // to enforce the presence and validity of expected headers. func (h *HeadersEnforcer) DialOptions() []grpc.DialOption { return []grpc.DialOption{ grpc.WithStreamInterceptor(h.interceptStream), grpc.WithUnaryInterceptor(h.interceptUnary), } } // CallOptions returns ClientOptions consisting of unary and stream interceptors // to enforce the presence and validity of expected headers. func (h *HeadersEnforcer) CallOptions() (copts []option.ClientOption) { dopts := h.DialOptions() for _, dopt := range dopts { copts = append(copts, option.WithGRPCDialOption(dopt)) } return } func (h *HeadersEnforcer) interceptUnary(ctx context.Context, method string, req, res interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { h.checkMetadata(ctx, method) return invoker(ctx, method, req, res, cc, opts...) } func (h *HeadersEnforcer) interceptStream(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) { h.checkMetadata(ctx, method) return streamer(ctx, desc, cc, method, opts...) } // XGoogClientHeaderChecker is a HeaderChecker that ensures that the "x-goog-api-client" // header is present on outgoing metadata. var XGoogClientHeaderChecker = &HeaderChecker{ Key: "x-goog-api-client", ValuesValidator: func(values ...string) error { if len(values) == 0 { return errors.New("expecting values") } for _, value := range values { switch { case strings.Contains(value, "gl-go/"): // TODO: check for exact version strings. return nil default: // Add others here. } } return errors.New("unmatched values") }, } // DefaultHeadersEnforcer returns a HeadersEnforcer that at bare minimum checks that // the "x-goog-api-client" key is present in the outgoing metadata headers. On any // validation failure, it will invoke log.Fatalf with the error message. func DefaultHeadersEnforcer() *HeadersEnforcer { return &HeadersEnforcer{ Checkers: []*HeaderChecker{XGoogClientHeaderChecker}, } } func (h *HeadersEnforcer) checkMetadata(ctx context.Context, method string) { onFailure := h.OnFailure if onFailure == nil { lgr := log.New(os.Stderr, "", 0) // Do not log the time prefix, it is noisy in test failure logs. onFailure = func(fmt_ string, args ...interface{}) { lgr.Fatalf(fmt_, args...) } } md, ok := metadata.FromOutgoingContext(ctx) if !ok { onFailure("Missing metadata for method %q", method) return } checkers := h.Checkers if len(checkers) == 0 { // Instead use the default HeaderChecker. checkers = append(checkers, XGoogClientHeaderChecker) } errBuf := new(bytes.Buffer) for _, checker := range checkers { hdrKey := checker.Key outHdrValues, ok := md[hdrKey] if !ok { fmt.Fprintf(errBuf, "missing header %q\n", hdrKey) continue } if err := checker.ValuesValidator(outHdrValues...); err != nil { fmt.Fprintf(errBuf, "header %q: %v\n", hdrKey, err) } } if errBuf.Len() != 0 { onFailure("For method %q, errors:\n%s", method, errBuf) return } } google-cloud-go-0.49.0/internal/testutil/rand.go000066400000000000000000000022501356504100700215330ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package testutil import ( "math/rand" "sync" "time" ) // NewRand creates a new *rand.Rand seeded with t. The return value is safe for use // with multiple goroutines. func NewRand(t time.Time) *rand.Rand { s := &lockedSource{src: rand.NewSource(t.UnixNano())} return rand.New(s) } // lockedSource makes a rand.Source safe for use by multiple goroutines. type lockedSource struct { mu sync.Mutex src rand.Source } func (ls *lockedSource) Int63() int64 { ls.mu.Lock() defer ls.mu.Unlock() return ls.src.Int63() } func (ls *lockedSource) Seed(int64) { panic("shouldn't be calling Seed") } google-cloud-go-0.49.0/internal/testutil/server.go000066400000000000000000000074361356504100700221300ustar00rootroot00000000000000/* Copyright 2016 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package testutil import ( "fmt" "log" "net" "regexp" "strconv" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) // A Server is an in-process gRPC server, listening on a system-chosen port on // the local loopback interface. Servers are for testing only and are not // intended to be used in production code. // // To create a server, make a new Server, register your handlers, then call // Start: // // srv, err := NewServer() // ... // mypb.RegisterMyServiceServer(srv.Gsrv, &myHandler) // .... // srv.Start() // // Clients should connect to the server with no security: // // conn, err := grpc.Dial(srv.Addr, grpc.WithInsecure()) // ... type Server struct { Addr string Port int l net.Listener Gsrv *grpc.Server } // NewServer creates a new Server. The Server will be listening for gRPC connections // at the address named by the Addr field, without TLS. func NewServer(opts ...grpc.ServerOption) (*Server, error) { return NewServerWithPort(0, opts...) } // NewServerWithPort creates a new Server at a specific port. The Server will be listening // for gRPC connections at the address named by the Addr field, without TLS. func NewServerWithPort(port int, opts ...grpc.ServerOption) (*Server, error) { l, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", port)) if err != nil { return nil, err } s := &Server{ Addr: l.Addr().String(), Port: parsePort(l.Addr().String()), l: l, Gsrv: grpc.NewServer(opts...), } return s, nil } // Start causes the server to start accepting incoming connections. // Call Start after registering handlers. func (s *Server) Start() { go func() { if err := s.Gsrv.Serve(s.l); err != nil { log.Printf("testutil.Server.Start: %v", err) } }() } // Close shuts down the server. func (s *Server) Close() { s.Gsrv.Stop() s.l.Close() } // PageBounds converts an incoming page size and token from an RPC request into // slice bounds and the outgoing next-page token. // // PageBounds assumes that the complete, unpaginated list of items exists as a // single slice. In addition to the page size and token, PageBounds needs the // length of that slice. // // PageBounds's first two return values should be used to construct a sub-slice of // the complete, unpaginated slice. E.g. if the complete slice is s, then // s[from:to] is the desired page. Its third return value should be set as the // NextPageToken field of the RPC response. func PageBounds(pageSize int, pageToken string, length int) (from, to int, nextPageToken string, err error) { from, to = 0, length if pageToken != "" { from, err = strconv.Atoi(pageToken) if err != nil { return 0, 0, "", status.Errorf(codes.InvalidArgument, "bad page token: %v", err) } if from >= length { return length, length, "", nil } } if pageSize > 0 && from+pageSize < length { to = from + pageSize nextPageToken = strconv.Itoa(to) } return from, to, nextPageToken, nil } var portParser = regexp.MustCompile(`:[0-9]+`) func parsePort(addr string) int { res := portParser.FindAllString(addr, -1) if len(res) == 0 { panic(fmt.Errorf("parsePort: found no numbers in %s", addr)) } stringPort := res[0][1:] // strip the : p, err := strconv.ParseInt(stringPort, 10, 32) if err != nil { panic(err) } return int(p) } google-cloud-go-0.49.0/internal/testutil/server_test.go000066400000000000000000000035621356504100700231630ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package testutil import ( "testing" grpc "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) func TestNewServer(t *testing.T) { srv, err := NewServer() if err != nil { t.Fatal(err) } defer srv.Close() srv.Start() conn, err := grpc.Dial(srv.Addr, grpc.WithInsecure()) if err != nil { t.Fatal(err) } defer conn.Close() } func TestPageBounds(t *testing.T) { const length = 10 for _, test := range []struct { size int tok string wantFrom int wantTo int wantTok string }{ {5, "", 0, 5, "5"}, {11, "", 0, 10, ""}, {5, "2", 2, 7, "7"}, {5, "8", 8, 10, ""}, {11, "8", 8, 10, ""}, {1, "11", 10, 10, ""}, } { gotFrom, gotTo, gotTok, err := PageBounds(test.size, test.tok, length) if err != nil { t.Fatal(err) } if got, want := gotFrom, test.wantFrom; got != want { t.Errorf("%+v: from: got %d, want %d", test, got, want) } if got, want := gotTo, test.wantTo; got != want { t.Errorf("%+v: to: got %d, want %d", test, got, want) } if got, want := gotTok, test.wantTok; got != want { t.Errorf("%+v: got %q, want %q", test, got, want) } } _, _, _, err := PageBounds(4, "xyz", 5) if status.Code(err) != codes.InvalidArgument { t.Errorf("want invalid argument, got <%v>", err) } } google-cloud-go-0.49.0/internal/testutil/trace.go000066400000000000000000000034361356504100700217140ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package testutil import ( "log" "time" "go.opencensus.io/plugin/ocgrpc" "go.opencensus.io/stats/view" "go.opencensus.io/trace" ) // TestExporter is a test utility exporter. It should be created with NewtestExporter. type TestExporter struct { Spans []*trace.SpanData Stats chan *view.Data } // NewTestExporter creates a TestExporter and registers it with OpenCensus. func NewTestExporter() *TestExporter { te := &TestExporter{Stats: make(chan *view.Data)} view.RegisterExporter(te) view.SetReportingPeriod(time.Millisecond) if err := view.Register(ocgrpc.DefaultClientViews...); err != nil { log.Fatal(err) } trace.RegisterExporter(te) trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()}) return te } // ExportSpan exports a span. func (te *TestExporter) ExportSpan(s *trace.SpanData) { te.Spans = append(te.Spans, s) } // ExportView exports a view. func (te *TestExporter) ExportView(vd *view.Data) { if len(vd.Rows) > 0 { select { case te.Stats <- vd: default: } } } // Unregister unregisters the exporter from OpenCensus. func (te *TestExporter) Unregister() { view.UnregisterExporter(te) trace.UnregisterExporter(te) view.SetReportingPeriod(0) // reset to default value } google-cloud-go-0.49.0/internal/trace/000077500000000000000000000000001356504100700175025ustar00rootroot00000000000000google-cloud-go-0.49.0/internal/trace/trace.go000066400000000000000000000065541356504100700211410ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package trace import ( "context" "fmt" "go.opencensus.io/trace" "google.golang.org/api/googleapi" "google.golang.org/genproto/googleapis/rpc/code" "google.golang.org/grpc/status" ) // StartSpan adds a span to the trace with the given name. func StartSpan(ctx context.Context, name string) context.Context { ctx, _ = trace.StartSpan(ctx, name) return ctx } // EndSpan ends a span with the given error. func EndSpan(ctx context.Context, err error) { span := trace.FromContext(ctx) if err != nil { span.SetStatus(toStatus(err)) } span.End() } // toStatus interrogates an error and converts it to an appropriate // OpenCensus status. func toStatus(err error) trace.Status { if err2, ok := err.(*googleapi.Error); ok { return trace.Status{Code: httpStatusCodeToOCCode(err2.Code), Message: err2.Message} } else if s, ok := status.FromError(err); ok { return trace.Status{Code: int32(s.Code()), Message: s.Message()} } else { return trace.Status{Code: int32(code.Code_UNKNOWN), Message: err.Error()} } } // TODO(deklerk): switch to using OpenCensus function when it becomes available. // Reference: https://github.com/googleapis/googleapis/blob/26b634d2724ac5dd30ae0b0cbfb01f07f2e4050e/google/rpc/code.proto func httpStatusCodeToOCCode(httpStatusCode int) int32 { switch httpStatusCode { case 200: return int32(code.Code_OK) case 499: return int32(code.Code_CANCELLED) case 500: return int32(code.Code_UNKNOWN) // Could also be Code_INTERNAL, Code_DATA_LOSS case 400: return int32(code.Code_INVALID_ARGUMENT) // Could also be Code_OUT_OF_RANGE case 504: return int32(code.Code_DEADLINE_EXCEEDED) case 404: return int32(code.Code_NOT_FOUND) case 409: return int32(code.Code_ALREADY_EXISTS) // Could also be Code_ABORTED case 403: return int32(code.Code_PERMISSION_DENIED) case 401: return int32(code.Code_UNAUTHENTICATED) case 429: return int32(code.Code_RESOURCE_EXHAUSTED) case 501: return int32(code.Code_UNIMPLEMENTED) case 503: return int32(code.Code_UNAVAILABLE) default: return int32(code.Code_UNKNOWN) } } // TODO: (odeke-em): perhaps just pass around spans due to the cost // incurred from using trace.FromContext(ctx) yet we could avoid // throwing away the work done by ctx, span := trace.StartSpan. func TracePrintf(ctx context.Context, attrMap map[string]interface{}, format string, args ...interface{}) { var attrs []trace.Attribute for k, v := range attrMap { var a trace.Attribute switch v := v.(type) { case string: a = trace.StringAttribute(k, v) case bool: a = trace.BoolAttribute(k, v) case int: a = trace.Int64Attribute(k, int64(v)) case int64: a = trace.Int64Attribute(k, v) default: a = trace.StringAttribute(k, fmt.Sprintf("%#v", v)) } attrs = append(attrs, a) } trace.FromContext(ctx).Annotatef(attrs, format, args...) } google-cloud-go-0.49.0/internal/trace/trace_test.go000066400000000000000000000031261356504100700221700ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package trace import ( "errors" "net/http" "testing" "cloud.google.com/go/internal/testutil" octrace "go.opencensus.io/trace" "google.golang.org/api/googleapi" "google.golang.org/genproto/googleapis/rpc/code" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) func TestToStatus(t *testing.T) { for _, testcase := range []struct { input error want octrace.Status }{ { errors.New("some random error"), octrace.Status{Code: int32(code.Code_UNKNOWN), Message: "some random error"}, }, { &googleapi.Error{Code: http.StatusConflict, Message: "some specific googleapi http error"}, octrace.Status{Code: int32(code.Code_ALREADY_EXISTS), Message: "some specific googleapi http error"}, }, { status.Error(codes.DataLoss, "some specific grpc error"), octrace.Status{Code: int32(code.Code_DATA_LOSS), Message: "some specific grpc error"}, }, } { got := toStatus(testcase.input) if r := testutil.Diff(got, testcase.want); r != "" { t.Errorf("got -, want +:\n%s", r) } } } google-cloud-go-0.49.0/internal/tracecontext/000077500000000000000000000000001356504100700211075ustar00rootroot00000000000000google-cloud-go-0.49.0/internal/tracecontext/tracecontext.go000066400000000000000000000045531356504100700241500ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package tracecontext provides encoders and decoders for Stackdriver Trace contexts. package tracecontext import "encoding/binary" const ( versionID = 0 traceIDField = 0 spanIDField = 1 optsField = 2 traceIDLen = 16 spanIDLen = 8 optsLen = 1 // Len represents the length of trace context. Len = 1 + 1 + traceIDLen + 1 + spanIDLen + 1 + optsLen ) // Encode encodes trace ID, span ID and options into dst. The number of bytes // written will be returned. If len(dst) isn't big enough to fit the trace context, // a negative number is returned. func Encode(dst []byte, traceID []byte, spanID uint64, opts byte) (n int) { if len(dst) < Len { return -1 } var offset = 0 putByte := func(b byte) { dst[offset] = b; offset++ } putUint64 := func(u uint64) { binary.LittleEndian.PutUint64(dst[offset:], u); offset += 8 } putByte(versionID) putByte(traceIDField) for _, b := range traceID { putByte(b) } putByte(spanIDField) putUint64(spanID) putByte(optsField) putByte(opts) return offset } // Decode decodes the src into a trace ID, span ID and options. If src doesn't // contain a valid trace context, ok = false is returned. func Decode(src []byte) (traceID []byte, spanID uint64, opts byte, ok bool) { if len(src) < Len { return traceID, spanID, 0, false } var offset = 0 readByte := func() byte { b := src[offset]; offset++; return b } readUint64 := func() uint64 { v := binary.LittleEndian.Uint64(src[offset:]); offset += 8; return v } if readByte() != versionID { return traceID, spanID, 0, false } for offset < len(src) { switch readByte() { case traceIDField: traceID = src[offset : offset+traceIDLen] offset += traceIDLen case spanIDField: spanID = readUint64() case optsField: opts = readByte() } } return traceID, spanID, opts, true } google-cloud-go-0.49.0/internal/tracecontext/tracecontext_test.go000066400000000000000000000072121356504100700252020ustar00rootroot00000000000000// Copyright 2014 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package tracecontext import ( "testing" "cloud.google.com/go/internal/testutil" ) var validData = []byte{0, 0, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 1, 97, 98, 99, 100, 101, 102, 103, 104, 2, 1} func TestDecode(t *testing.T) { tests := []struct { name string data []byte wantTraceID []byte wantSpanID uint64 wantOpts byte wantOk bool }{ { name: "nil data", data: nil, wantTraceID: nil, wantSpanID: 0, wantOpts: 0, wantOk: false, }, { name: "short data", data: []byte{0, 0, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77}, wantTraceID: nil, wantSpanID: 0, wantOpts: 0, wantOk: false, }, { name: "wrong field number", data: []byte{0, 1, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77}, wantTraceID: nil, wantSpanID: 0, wantOpts: 0, wantOk: false, }, { name: "valid data", data: validData, wantTraceID: []byte{64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79}, wantSpanID: 0x6867666564636261, wantOpts: 1, wantOk: true, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { gotTraceID, gotSpanID, gotOpts, gotOk := Decode(test.data) if !testutil.Equal(gotTraceID, test.wantTraceID) { t.Errorf("%s: Decode() gotTraceID = %v, want %v", test.name, gotTraceID, test.wantTraceID) } if gotSpanID != test.wantSpanID { t.Errorf("%s: Decode() gotSpanID = %v, want %v", test.name, gotSpanID, test.wantSpanID) } if gotOpts != test.wantOpts { t.Errorf("%s: Decode() gotOpts = %v, want %v", test.name, gotOpts, test.wantOpts) } if gotOk != test.wantOk { t.Errorf("%s: Decode() gotOk = %v, want %v", test.name, gotOk, test.wantOk) } }) } } func TestEncode(t *testing.T) { tests := []struct { name string dst []byte traceID []byte spanID uint64 opts byte wantN int wantData []byte }{ { name: "short data", dst: make([]byte, 0), traceID: []byte("00112233445566"), spanID: 0x6867666564636261, opts: 1, wantN: -1, wantData: make([]byte, 0), }, { name: "valid data", dst: make([]byte, Len), traceID: []byte{64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79}, spanID: 0x6867666564636261, opts: 1, wantN: Len, wantData: validData, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { gotN := Encode(test.dst, test.traceID, test.spanID, test.opts) if gotN != test.wantN { t.Errorf("%s: n = %v, want %v", test.name, gotN, test.wantN) } if gotData := test.dst; !testutil.Equal(gotData, test.wantData) { t.Errorf("%s: dst = %v, want %v", test.name, gotData, test.wantData) } }) } } func BenchmarkDecode(b *testing.B) { for i := 0; i < b.N; i++ { Decode(validData) } } func BenchmarkEncode(b *testing.B) { for i := 0; i < b.N; i++ { traceID := make([]byte, 16) var opts byte Encode(validData, traceID, 0, opts) } } google-cloud-go-0.49.0/internal/uid/000077500000000000000000000000001356504100700171655ustar00rootroot00000000000000google-cloud-go-0.49.0/internal/uid/uid.go000066400000000000000000000111011356504100700202670ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package uid supports generating unique IDs. Its chief purpose is to prevent // multiple test executions from interfering with each other, and to facilitate // cleanup of old entities that may remain if tests exit early. package uid import ( "fmt" "regexp" "strconv" "sync/atomic" "time" ) // A Space manages a set of unique IDs distinguished by a prefix. type Space struct { Prefix string // Prefix of UIDs. Read-only. Sep rune // Separates UID parts. Read-only. Time time.Time // Timestamp for UIDs. Read-only. re *regexp.Regexp count int32 // atomic short bool } // Options are optional values for a Space. type Options struct { Sep rune // Separates parts of the UID. Defaults to '-'. Time time.Time // Timestamp for all UIDs made with this space. Defaults to current time. // Short, if true, makes the result of space.New shorter by 6 characters. // This can be useful for character restricted IDs. It will use a shorter // but less readable time representation, and will only use two characters // for the count suffix instead of four. // // e.x. normal: gotest-20181030-59751273685000-0001 // e.x. short: gotest-1540917351273685000-01 Short bool } // NewSpace creates a new UID space. A UID Space is used to generate unique IDs. func NewSpace(prefix string, opts *Options) *Space { var short bool sep := '-' tm := time.Now().UTC() if opts != nil { short = opts.Short if opts.Sep != 0 { sep = opts.Sep } if !opts.Time.IsZero() { tm = opts.Time } } var re string if short { re = fmt.Sprintf(`^%s%[2]c(\d+)%[2]c\d+$`, regexp.QuoteMeta(prefix), sep) } else { re = fmt.Sprintf(`^%s%[2]c(\d{4})(\d{2})(\d{2})%[2]c(\d+)%[2]c\d+$`, regexp.QuoteMeta(prefix), sep) } return &Space{ Prefix: prefix, Sep: sep, Time: tm, re: regexp.MustCompile(re), short: short, } } // New generates a new unique ID. The ID consists of the Space's prefix, a // timestamp, and a counter value. All unique IDs generated in the same test // execution will have the same timestamp. // // Aside from the characters in the prefix, IDs contain only letters, numbers // and sep. func (s *Space) New() string { c := atomic.AddInt32(&s.count, 1) if s.short && c > 99 { // Short spaces only have space for 99 IDs. (two characters) panic("Short space called New more than 99 times. Ran out of IDs.") } else if c > 9999 { // Spaces only have space for 9999 IDs. (four characters) panic("New called more than 9999 times. Ran out of IDs.") } if s.short { return fmt.Sprintf("%s%c%d%c%02d", s.Prefix, s.Sep, s.Time.UnixNano(), s.Sep, c) } // Write the time as a date followed by nanoseconds from midnight of that date. // That makes it easier to see the approximate time of the ID when it is displayed. y, m, d := s.Time.Date() ns := s.Time.Sub(time.Date(y, m, d, 0, 0, 0, 0, time.UTC)) // Zero-pad the counter for lexical sort order for IDs with the same timestamp. return fmt.Sprintf("%s%c%04d%02d%02d%c%d%c%04d", s.Prefix, s.Sep, y, m, d, s.Sep, ns, s.Sep, c) } // Timestamp extracts the timestamp of uid, which must have been generated by // s. The second return value is true on success, false if there was a problem. func (s *Space) Timestamp(uid string) (time.Time, bool) { subs := s.re.FindStringSubmatch(uid) if subs == nil { return time.Time{}, false } if s.short { ns, err := strconv.ParseInt(subs[1], 10, 64) if err != nil { return time.Time{}, false } return time.Unix(ns/1e9, ns%1e9), true } y, err1 := strconv.Atoi(subs[1]) m, err2 := strconv.Atoi(subs[2]) d, err3 := strconv.Atoi(subs[3]) ns, err4 := strconv.Atoi(subs[4]) if err1 != nil || err2 != nil || err3 != nil || err4 != nil { return time.Time{}, false } return time.Date(y, time.Month(m), d, 0, 0, 0, ns, time.UTC), true } // Older reports whether uid was created by m and has a timestamp older than // the current time by at least d. func (s *Space) Older(uid string, d time.Duration) bool { ts, ok := s.Timestamp(uid) if !ok { return false } return time.Since(ts) > d } google-cloud-go-0.49.0/internal/uid/uid_test.go000066400000000000000000000045411356504100700213400ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package uid import ( "fmt" "testing" "time" ) func TestNew(t *testing.T) { tm := time.Date(2017, 1, 6, 0, 0, 0, 21, time.UTC) s := NewSpace("prefix", &Options{Time: tm}) got := s.New() want := "prefix-20170106-21-0001" if got != want { t.Errorf("got %q, want %q", got, want) } s2 := NewSpace("prefix2", &Options{Sep: '_', Time: tm}) got = s2.New() want = "prefix2_20170106_21_0001" if got != want { t.Errorf("got %q, want %q", got, want) } } func TestTimestamp(t *testing.T) { s := NewSpace("unique-ID", nil) startTime := s.Time uid := s.New() got, ok := s.Timestamp(uid) if !ok { t.Fatal("got ok = false, want true") } if !startTime.Equal(got) { t.Errorf("got %s, want %s", got, startTime) } got, ok = s.Timestamp("unique-ID-20160308-123-8") if !ok { t.Fatal("got false, want true") } if want := time.Date(2016, 3, 8, 0, 0, 0, 123, time.UTC); !want.Equal(got) { t.Errorf("got %s, want %s", got, want) } if _, ok = s.Timestamp("invalid-time-1234"); ok { t.Error("got true, want false") } } func TestOlder(t *testing.T) { s := NewSpace("uid", nil) // A non-matching ID returns false. id2 := NewSpace("different-prefix", nil).New() if got, want := s.Older(id2, time.Second), false; got != want { t.Errorf("got %t, want %t", got, want) } } func TestShorter(t *testing.T) { now := time.Now() shortSpace := NewSpace("uid", &Options{Short: true, Time: now}) shortUID := shortSpace.New() want := fmt.Sprintf("uid-%d-01", now.UnixNano()) if shortUID != want { t.Fatalf("expected %s, got %s", want, shortUID) } if got, ok := shortSpace.Timestamp(shortUID); !ok { t.Fatal("expected to be able to parse timestamp from short space, but was unable to") } else if got.UnixNano() != now.UnixNano() { t.Fatalf("expected to get %v, got %v", now, got) } } google-cloud-go-0.49.0/internal/version/000077500000000000000000000000001356504100700200715ustar00rootroot00000000000000google-cloud-go-0.49.0/internal/version/update_version.sh000077500000000000000000000012601356504100700234560ustar00rootroot00000000000000#!/bin/bash # Copyright 2019 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. today=$(date +%Y%m%d) sed -i -r -e 's/const Repo = "([0-9]{8})"/const Repo = "'$today'"/' $GOFILE google-cloud-go-0.49.0/internal/version/version.go000066400000000000000000000033351356504100700221110ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:generate ./update_version.sh // Package version contains version information for Google Cloud Client // Libraries for Go, as reported in request headers. package version import ( "runtime" "strings" "unicode" ) // Repo is the current version of the client libraries in this // repo. It should be a date in YYYYMMDD format. const Repo = "20191119" // Go returns the Go runtime version. The returned string // has no whitespace. func Go() string { return goVersion } var goVersion = goVer(runtime.Version()) const develPrefix = "devel +" func goVer(s string) string { if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "" } func notSemverRune(r rune) bool { return !strings.ContainsRune("0123456789.", r) } google-cloud-go-0.49.0/internal/version/version_test.go000066400000000000000000000020701356504100700231430ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package version import "testing" func TestGoVer(t *testing.T) { for _, tst := range []struct { in, want string }{ {"go1.8", "1.8.0"}, {"go1.7.3", "1.7.3"}, {"go1.8.typealias", "1.8.0-typealias"}, {"go1.8beta1", "1.8.0-beta1"}, {"go1.8rc2", "1.8.0-rc2"}, {"devel +824f981dd4b7 Tue Apr 29 21:41:54 2014 -0400", "824f981dd4b7"}, {"foo bar zipzap", ""}, } { if got := goVer(tst.in); got != tst.want { t.Errorf("goVer(%q) = %q, want %q", tst.in, got, tst.want) } } } google-cloud-go-0.49.0/iot/000077500000000000000000000000001356504100700153635ustar00rootroot00000000000000google-cloud-go-0.49.0/iot/apiv1/000077500000000000000000000000001356504100700164035ustar00rootroot00000000000000google-cloud-go-0.49.0/iot/apiv1/.repo-metadata.json000066400000000000000000000006161356504100700221020ustar00rootroot00000000000000{ "name": "iot", "name_pretty": "Google Cloud IoT API", "product_documentation": "https://cloud.google.com/iot", "client_documentation": "https://godoc.org/cloud.google.com/go/iot/apiv1", "release_level": "alpha", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "cloudiot.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/iot/apiv1/ListDeviceRegistries_smoke_test.go000066400000000000000000000032701356504100700252650ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package iot import ( "context" "fmt" "strconv" "testing" "time" "cloud.google.com/go/internal/testutil" "google.golang.org/api/iterator" "google.golang.org/api/option" iotpb "google.golang.org/genproto/googleapis/cloud/iot/v1" ) var _ = fmt.Sprintf var _ = iterator.Done var _ = strconv.FormatUint var _ = time.Now func TestDeviceManagerSmoke(t *testing.T) { if testing.Short() { t.Skip("skipping smoke test in short mode") } ctx := context.Background() ts := testutil.TokenSource(ctx, DefaultAuthScopes()...) if ts == nil { t.Skip("Integration tests skipped. See CONTRIBUTING.md for details") } projectId := testutil.ProjID() _ = projectId c, err := NewDeviceManagerClient(ctx, option.WithTokenSource(ts)) if err != nil { t.Fatal(err) } var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", projectId, "us-central1") var request = &iotpb.ListDeviceRegistriesRequest{ Parent: formattedParent, } iter := c.ListDeviceRegistries(ctx, request) if _, err := iter.Next(); err != nil && err != iterator.Done { t.Error(err) } } google-cloud-go-0.49.0/iot/apiv1/device_manager_client.go000066400000000000000000000651551356504100700232350ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package iot import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" iotpb "google.golang.org/genproto/googleapis/cloud/iot/v1" iampb "google.golang.org/genproto/googleapis/iam/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // DeviceManagerCallOptions contains the retry settings for each method of DeviceManagerClient. type DeviceManagerCallOptions struct { CreateDeviceRegistry []gax.CallOption GetDeviceRegistry []gax.CallOption UpdateDeviceRegistry []gax.CallOption DeleteDeviceRegistry []gax.CallOption ListDeviceRegistries []gax.CallOption CreateDevice []gax.CallOption GetDevice []gax.CallOption UpdateDevice []gax.CallOption DeleteDevice []gax.CallOption ListDevices []gax.CallOption ModifyCloudToDeviceConfig []gax.CallOption ListDeviceConfigVersions []gax.CallOption ListDeviceStates []gax.CallOption SetIamPolicy []gax.CallOption GetIamPolicy []gax.CallOption TestIamPermissions []gax.CallOption SendCommandToDevice []gax.CallOption BindDeviceToGateway []gax.CallOption UnbindDeviceFromGateway []gax.CallOption } func defaultDeviceManagerClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("cloudiot.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultDeviceManagerCallOptions() *DeviceManagerCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &DeviceManagerCallOptions{ CreateDeviceRegistry: retry[[2]string{"default", "non_idempotent"}], GetDeviceRegistry: retry[[2]string{"default", "idempotent"}], UpdateDeviceRegistry: retry[[2]string{"default", "non_idempotent"}], DeleteDeviceRegistry: retry[[2]string{"default", "non_idempotent"}], ListDeviceRegistries: retry[[2]string{"default", "idempotent"}], CreateDevice: retry[[2]string{"default", "non_idempotent"}], GetDevice: retry[[2]string{"default", "idempotent"}], UpdateDevice: retry[[2]string{"default", "non_idempotent"}], DeleteDevice: retry[[2]string{"default", "non_idempotent"}], ListDevices: retry[[2]string{"default", "idempotent"}], ModifyCloudToDeviceConfig: retry[[2]string{"default", "non_idempotent"}], ListDeviceConfigVersions: retry[[2]string{"default", "idempotent"}], ListDeviceStates: retry[[2]string{"default", "idempotent"}], SetIamPolicy: retry[[2]string{"default", "non_idempotent"}], GetIamPolicy: retry[[2]string{"default", "non_idempotent"}], TestIamPermissions: retry[[2]string{"default", "non_idempotent"}], SendCommandToDevice: retry[[2]string{"default", "non_idempotent"}], BindDeviceToGateway: retry[[2]string{"default", "non_idempotent"}], UnbindDeviceFromGateway: retry[[2]string{"default", "non_idempotent"}], } } // DeviceManagerClient is a client for interacting with Cloud IoT API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type DeviceManagerClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. deviceManagerClient iotpb.DeviceManagerClient // The call options for this service. CallOptions *DeviceManagerCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewDeviceManagerClient creates a new device manager client. // // Internet of Things (IoT) service. Securely connect and manage IoT devices. func NewDeviceManagerClient(ctx context.Context, opts ...option.ClientOption) (*DeviceManagerClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultDeviceManagerClientOptions(), opts...)...) if err != nil { return nil, err } c := &DeviceManagerClient{ conn: conn, CallOptions: defaultDeviceManagerCallOptions(), deviceManagerClient: iotpb.NewDeviceManagerClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *DeviceManagerClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *DeviceManagerClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *DeviceManagerClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // CreateDeviceRegistry creates a device registry that contains devices. func (c *DeviceManagerClient) CreateDeviceRegistry(ctx context.Context, req *iotpb.CreateDeviceRegistryRequest, opts ...gax.CallOption) (*iotpb.DeviceRegistry, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateDeviceRegistry[0:len(c.CallOptions.CreateDeviceRegistry):len(c.CallOptions.CreateDeviceRegistry)], opts...) var resp *iotpb.DeviceRegistry err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.deviceManagerClient.CreateDeviceRegistry(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetDeviceRegistry gets a device registry configuration. func (c *DeviceManagerClient) GetDeviceRegistry(ctx context.Context, req *iotpb.GetDeviceRegistryRequest, opts ...gax.CallOption) (*iotpb.DeviceRegistry, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetDeviceRegistry[0:len(c.CallOptions.GetDeviceRegistry):len(c.CallOptions.GetDeviceRegistry)], opts...) var resp *iotpb.DeviceRegistry err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.deviceManagerClient.GetDeviceRegistry(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateDeviceRegistry updates a device registry configuration. func (c *DeviceManagerClient) UpdateDeviceRegistry(ctx context.Context, req *iotpb.UpdateDeviceRegistryRequest, opts ...gax.CallOption) (*iotpb.DeviceRegistry, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "device_registry.name", url.QueryEscape(req.GetDeviceRegistry().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateDeviceRegistry[0:len(c.CallOptions.UpdateDeviceRegistry):len(c.CallOptions.UpdateDeviceRegistry)], opts...) var resp *iotpb.DeviceRegistry err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.deviceManagerClient.UpdateDeviceRegistry(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteDeviceRegistry deletes a device registry configuration. func (c *DeviceManagerClient) DeleteDeviceRegistry(ctx context.Context, req *iotpb.DeleteDeviceRegistryRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteDeviceRegistry[0:len(c.CallOptions.DeleteDeviceRegistry):len(c.CallOptions.DeleteDeviceRegistry)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.deviceManagerClient.DeleteDeviceRegistry(ctx, req, settings.GRPC...) return err }, opts...) return err } // ListDeviceRegistries lists device registries. func (c *DeviceManagerClient) ListDeviceRegistries(ctx context.Context, req *iotpb.ListDeviceRegistriesRequest, opts ...gax.CallOption) *DeviceRegistryIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListDeviceRegistries[0:len(c.CallOptions.ListDeviceRegistries):len(c.CallOptions.ListDeviceRegistries)], opts...) it := &DeviceRegistryIterator{} req = proto.Clone(req).(*iotpb.ListDeviceRegistriesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*iotpb.DeviceRegistry, string, error) { var resp *iotpb.ListDeviceRegistriesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.deviceManagerClient.ListDeviceRegistries(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.DeviceRegistries, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // CreateDevice creates a device in a device registry. func (c *DeviceManagerClient) CreateDevice(ctx context.Context, req *iotpb.CreateDeviceRequest, opts ...gax.CallOption) (*iotpb.Device, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateDevice[0:len(c.CallOptions.CreateDevice):len(c.CallOptions.CreateDevice)], opts...) var resp *iotpb.Device err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.deviceManagerClient.CreateDevice(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetDevice gets details about a device. func (c *DeviceManagerClient) GetDevice(ctx context.Context, req *iotpb.GetDeviceRequest, opts ...gax.CallOption) (*iotpb.Device, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetDevice[0:len(c.CallOptions.GetDevice):len(c.CallOptions.GetDevice)], opts...) var resp *iotpb.Device err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.deviceManagerClient.GetDevice(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateDevice updates a device. func (c *DeviceManagerClient) UpdateDevice(ctx context.Context, req *iotpb.UpdateDeviceRequest, opts ...gax.CallOption) (*iotpb.Device, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "device.name", url.QueryEscape(req.GetDevice().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateDevice[0:len(c.CallOptions.UpdateDevice):len(c.CallOptions.UpdateDevice)], opts...) var resp *iotpb.Device err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.deviceManagerClient.UpdateDevice(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteDevice deletes a device. func (c *DeviceManagerClient) DeleteDevice(ctx context.Context, req *iotpb.DeleteDeviceRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteDevice[0:len(c.CallOptions.DeleteDevice):len(c.CallOptions.DeleteDevice)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.deviceManagerClient.DeleteDevice(ctx, req, settings.GRPC...) return err }, opts...) return err } // ListDevices list devices in a device registry. func (c *DeviceManagerClient) ListDevices(ctx context.Context, req *iotpb.ListDevicesRequest, opts ...gax.CallOption) *DeviceIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListDevices[0:len(c.CallOptions.ListDevices):len(c.CallOptions.ListDevices)], opts...) it := &DeviceIterator{} req = proto.Clone(req).(*iotpb.ListDevicesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*iotpb.Device, string, error) { var resp *iotpb.ListDevicesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.deviceManagerClient.ListDevices(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Devices, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // ModifyCloudToDeviceConfig modifies the configuration for the device, which is eventually sent from // the Cloud IoT Core servers. Returns the modified configuration version and // its metadata. func (c *DeviceManagerClient) ModifyCloudToDeviceConfig(ctx context.Context, req *iotpb.ModifyCloudToDeviceConfigRequest, opts ...gax.CallOption) (*iotpb.DeviceConfig, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ModifyCloudToDeviceConfig[0:len(c.CallOptions.ModifyCloudToDeviceConfig):len(c.CallOptions.ModifyCloudToDeviceConfig)], opts...) var resp *iotpb.DeviceConfig err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.deviceManagerClient.ModifyCloudToDeviceConfig(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListDeviceConfigVersions lists the last few versions of the device configuration in descending // order (i.e.: newest first). func (c *DeviceManagerClient) ListDeviceConfigVersions(ctx context.Context, req *iotpb.ListDeviceConfigVersionsRequest, opts ...gax.CallOption) (*iotpb.ListDeviceConfigVersionsResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListDeviceConfigVersions[0:len(c.CallOptions.ListDeviceConfigVersions):len(c.CallOptions.ListDeviceConfigVersions)], opts...) var resp *iotpb.ListDeviceConfigVersionsResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.deviceManagerClient.ListDeviceConfigVersions(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListDeviceStates lists the last few versions of the device state in descending order (i.e.: // newest first). func (c *DeviceManagerClient) ListDeviceStates(ctx context.Context, req *iotpb.ListDeviceStatesRequest, opts ...gax.CallOption) (*iotpb.ListDeviceStatesResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListDeviceStates[0:len(c.CallOptions.ListDeviceStates):len(c.CallOptions.ListDeviceStates)], opts...) var resp *iotpb.ListDeviceStatesResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.deviceManagerClient.ListDeviceStates(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // SetIamPolicy sets the access control policy on the specified resource. Replaces any // existing policy. func (c *DeviceManagerClient) SetIamPolicy(ctx context.Context, req *iampb.SetIamPolicyRequest, opts ...gax.CallOption) (*iampb.Policy, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.SetIamPolicy[0:len(c.CallOptions.SetIamPolicy):len(c.CallOptions.SetIamPolicy)], opts...) var resp *iampb.Policy err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.deviceManagerClient.SetIamPolicy(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetIamPolicy gets the access control policy for a resource. // Returns an empty policy if the resource exists and does not have a policy // set. func (c *DeviceManagerClient) GetIamPolicy(ctx context.Context, req *iampb.GetIamPolicyRequest, opts ...gax.CallOption) (*iampb.Policy, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetIamPolicy[0:len(c.CallOptions.GetIamPolicy):len(c.CallOptions.GetIamPolicy)], opts...) var resp *iampb.Policy err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.deviceManagerClient.GetIamPolicy(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // TestIamPermissions returns permissions that a caller has on the specified resource. // If the resource does not exist, this will return an empty set of // permissions, not a NOT_FOUND error. func (c *DeviceManagerClient) TestIamPermissions(ctx context.Context, req *iampb.TestIamPermissionsRequest, opts ...gax.CallOption) (*iampb.TestIamPermissionsResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.TestIamPermissions[0:len(c.CallOptions.TestIamPermissions):len(c.CallOptions.TestIamPermissions)], opts...) var resp *iampb.TestIamPermissionsResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.deviceManagerClient.TestIamPermissions(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // SendCommandToDevice sends a command to the specified device. In order for a device to be able // to receive commands, it must: // 1) be connected to Cloud IoT Core using the MQTT protocol, and // 2) be subscribed to the group of MQTT topics specified by // /devices/{device-id}/commands/#. This subscription will receive commands // at the top-level topic /devices/{device-id}/commands as well as commands // for subfolders, like /devices/{device-id}/commands/subfolder. // Note that subscribing to specific subfolders is not supported. // If the command could not be delivered to the device, this method will // return an error; in particular, if the device is not subscribed, this // method will return FAILED_PRECONDITION. Otherwise, this method will // return OK. If the subscription is QoS 1, at least once delivery will be // guaranteed; for QoS 0, no acknowledgment will be expected from the device. func (c *DeviceManagerClient) SendCommandToDevice(ctx context.Context, req *iotpb.SendCommandToDeviceRequest, opts ...gax.CallOption) (*iotpb.SendCommandToDeviceResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.SendCommandToDevice[0:len(c.CallOptions.SendCommandToDevice):len(c.CallOptions.SendCommandToDevice)], opts...) var resp *iotpb.SendCommandToDeviceResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.deviceManagerClient.SendCommandToDevice(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // BindDeviceToGateway associates the device with the gateway. func (c *DeviceManagerClient) BindDeviceToGateway(ctx context.Context, req *iotpb.BindDeviceToGatewayRequest, opts ...gax.CallOption) (*iotpb.BindDeviceToGatewayResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.BindDeviceToGateway[0:len(c.CallOptions.BindDeviceToGateway):len(c.CallOptions.BindDeviceToGateway)], opts...) var resp *iotpb.BindDeviceToGatewayResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.deviceManagerClient.BindDeviceToGateway(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UnbindDeviceFromGateway deletes the association between the device and the gateway. func (c *DeviceManagerClient) UnbindDeviceFromGateway(ctx context.Context, req *iotpb.UnbindDeviceFromGatewayRequest, opts ...gax.CallOption) (*iotpb.UnbindDeviceFromGatewayResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UnbindDeviceFromGateway[0:len(c.CallOptions.UnbindDeviceFromGateway):len(c.CallOptions.UnbindDeviceFromGateway)], opts...) var resp *iotpb.UnbindDeviceFromGatewayResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.deviceManagerClient.UnbindDeviceFromGateway(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeviceIterator manages a stream of *iotpb.Device. type DeviceIterator struct { items []*iotpb.Device pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*iotpb.Device, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *DeviceIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *DeviceIterator) Next() (*iotpb.Device, error) { var item *iotpb.Device if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *DeviceIterator) bufLen() int { return len(it.items) } func (it *DeviceIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // DeviceRegistryIterator manages a stream of *iotpb.DeviceRegistry. type DeviceRegistryIterator struct { items []*iotpb.DeviceRegistry pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*iotpb.DeviceRegistry, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *DeviceRegistryIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *DeviceRegistryIterator) Next() (*iotpb.DeviceRegistry, error) { var item *iotpb.DeviceRegistry if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *DeviceRegistryIterator) bufLen() int { return len(it.items) } func (it *DeviceRegistryIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/iot/apiv1/device_manager_client_example_test.go000066400000000000000000000201361356504100700257750ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package iot_test import ( "context" iot "cloud.google.com/go/iot/apiv1" "google.golang.org/api/iterator" iotpb "google.golang.org/genproto/googleapis/cloud/iot/v1" iampb "google.golang.org/genproto/googleapis/iam/v1" ) func ExampleNewDeviceManagerClient() { ctx := context.Background() c, err := iot.NewDeviceManagerClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleDeviceManagerClient_CreateDeviceRegistry() { ctx := context.Background() c, err := iot.NewDeviceManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &iotpb.CreateDeviceRegistryRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateDeviceRegistry(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleDeviceManagerClient_GetDeviceRegistry() { ctx := context.Background() c, err := iot.NewDeviceManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &iotpb.GetDeviceRegistryRequest{ // TODO: Fill request struct fields. } resp, err := c.GetDeviceRegistry(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleDeviceManagerClient_UpdateDeviceRegistry() { ctx := context.Background() c, err := iot.NewDeviceManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &iotpb.UpdateDeviceRegistryRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateDeviceRegistry(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleDeviceManagerClient_DeleteDeviceRegistry() { ctx := context.Background() c, err := iot.NewDeviceManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &iotpb.DeleteDeviceRegistryRequest{ // TODO: Fill request struct fields. } err = c.DeleteDeviceRegistry(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleDeviceManagerClient_ListDeviceRegistries() { ctx := context.Background() c, err := iot.NewDeviceManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &iotpb.ListDeviceRegistriesRequest{ // TODO: Fill request struct fields. } it := c.ListDeviceRegistries(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleDeviceManagerClient_CreateDevice() { ctx := context.Background() c, err := iot.NewDeviceManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &iotpb.CreateDeviceRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateDevice(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleDeviceManagerClient_GetDevice() { ctx := context.Background() c, err := iot.NewDeviceManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &iotpb.GetDeviceRequest{ // TODO: Fill request struct fields. } resp, err := c.GetDevice(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleDeviceManagerClient_UpdateDevice() { ctx := context.Background() c, err := iot.NewDeviceManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &iotpb.UpdateDeviceRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateDevice(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleDeviceManagerClient_DeleteDevice() { ctx := context.Background() c, err := iot.NewDeviceManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &iotpb.DeleteDeviceRequest{ // TODO: Fill request struct fields. } err = c.DeleteDevice(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleDeviceManagerClient_ListDevices() { ctx := context.Background() c, err := iot.NewDeviceManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &iotpb.ListDevicesRequest{ // TODO: Fill request struct fields. } it := c.ListDevices(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleDeviceManagerClient_ModifyCloudToDeviceConfig() { ctx := context.Background() c, err := iot.NewDeviceManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &iotpb.ModifyCloudToDeviceConfigRequest{ // TODO: Fill request struct fields. } resp, err := c.ModifyCloudToDeviceConfig(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleDeviceManagerClient_ListDeviceConfigVersions() { ctx := context.Background() c, err := iot.NewDeviceManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &iotpb.ListDeviceConfigVersionsRequest{ // TODO: Fill request struct fields. } resp, err := c.ListDeviceConfigVersions(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleDeviceManagerClient_ListDeviceStates() { ctx := context.Background() c, err := iot.NewDeviceManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &iotpb.ListDeviceStatesRequest{ // TODO: Fill request struct fields. } resp, err := c.ListDeviceStates(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleDeviceManagerClient_SetIamPolicy() { ctx := context.Background() c, err := iot.NewDeviceManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &iampb.SetIamPolicyRequest{ // TODO: Fill request struct fields. } resp, err := c.SetIamPolicy(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleDeviceManagerClient_GetIamPolicy() { ctx := context.Background() c, err := iot.NewDeviceManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &iampb.GetIamPolicyRequest{ // TODO: Fill request struct fields. } resp, err := c.GetIamPolicy(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleDeviceManagerClient_TestIamPermissions() { ctx := context.Background() c, err := iot.NewDeviceManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &iampb.TestIamPermissionsRequest{ // TODO: Fill request struct fields. } resp, err := c.TestIamPermissions(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleDeviceManagerClient_SendCommandToDevice() { ctx := context.Background() c, err := iot.NewDeviceManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &iotpb.SendCommandToDeviceRequest{ // TODO: Fill request struct fields. } resp, err := c.SendCommandToDevice(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleDeviceManagerClient_BindDeviceToGateway() { ctx := context.Background() c, err := iot.NewDeviceManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &iotpb.BindDeviceToGatewayRequest{ // TODO: Fill request struct fields. } resp, err := c.BindDeviceToGateway(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleDeviceManagerClient_UnbindDeviceFromGateway() { ctx := context.Background() c, err := iot.NewDeviceManagerClient(ctx) if err != nil { // TODO: Handle error. } req := &iotpb.UnbindDeviceFromGatewayRequest{ // TODO: Fill request struct fields. } resp, err := c.UnbindDeviceFromGateway(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/iot/apiv1/doc.go000066400000000000000000000054301356504100700175010ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package iot is an auto-generated package for the // Cloud IoT API. // // NOTE: This package is in alpha. It is not stable, and is likely to change. // // Registers and manages IoT (Internet of Things) devices that connect to the // Google Cloud Platform. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package iot // import "cloud.google.com/go/iot/apiv1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/cloudiot", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191115" google-cloud-go-0.49.0/iot/apiv1/mock_test.go000066400000000000000000001314661356504100700207350ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package iot import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" "google.golang.org/api/option" iotpb "google.golang.org/genproto/googleapis/cloud/iot/v1" iampb "google.golang.org/genproto/googleapis/iam/v1" field_maskpb "google.golang.org/genproto/protobuf/field_mask" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockDeviceManagerServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. iotpb.DeviceManagerServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockDeviceManagerServer) CreateDeviceRegistry(ctx context.Context, req *iotpb.CreateDeviceRegistryRequest) (*iotpb.DeviceRegistry, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iotpb.DeviceRegistry), nil } func (s *mockDeviceManagerServer) GetDeviceRegistry(ctx context.Context, req *iotpb.GetDeviceRegistryRequest) (*iotpb.DeviceRegistry, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iotpb.DeviceRegistry), nil } func (s *mockDeviceManagerServer) UpdateDeviceRegistry(ctx context.Context, req *iotpb.UpdateDeviceRegistryRequest) (*iotpb.DeviceRegistry, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iotpb.DeviceRegistry), nil } func (s *mockDeviceManagerServer) DeleteDeviceRegistry(ctx context.Context, req *iotpb.DeleteDeviceRegistryRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockDeviceManagerServer) ListDeviceRegistries(ctx context.Context, req *iotpb.ListDeviceRegistriesRequest) (*iotpb.ListDeviceRegistriesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iotpb.ListDeviceRegistriesResponse), nil } func (s *mockDeviceManagerServer) CreateDevice(ctx context.Context, req *iotpb.CreateDeviceRequest) (*iotpb.Device, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iotpb.Device), nil } func (s *mockDeviceManagerServer) GetDevice(ctx context.Context, req *iotpb.GetDeviceRequest) (*iotpb.Device, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iotpb.Device), nil } func (s *mockDeviceManagerServer) UpdateDevice(ctx context.Context, req *iotpb.UpdateDeviceRequest) (*iotpb.Device, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iotpb.Device), nil } func (s *mockDeviceManagerServer) DeleteDevice(ctx context.Context, req *iotpb.DeleteDeviceRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockDeviceManagerServer) ListDevices(ctx context.Context, req *iotpb.ListDevicesRequest) (*iotpb.ListDevicesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iotpb.ListDevicesResponse), nil } func (s *mockDeviceManagerServer) ModifyCloudToDeviceConfig(ctx context.Context, req *iotpb.ModifyCloudToDeviceConfigRequest) (*iotpb.DeviceConfig, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iotpb.DeviceConfig), nil } func (s *mockDeviceManagerServer) ListDeviceConfigVersions(ctx context.Context, req *iotpb.ListDeviceConfigVersionsRequest) (*iotpb.ListDeviceConfigVersionsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iotpb.ListDeviceConfigVersionsResponse), nil } func (s *mockDeviceManagerServer) ListDeviceStates(ctx context.Context, req *iotpb.ListDeviceStatesRequest) (*iotpb.ListDeviceStatesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iotpb.ListDeviceStatesResponse), nil } func (s *mockDeviceManagerServer) SetIamPolicy(ctx context.Context, req *iampb.SetIamPolicyRequest) (*iampb.Policy, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iampb.Policy), nil } func (s *mockDeviceManagerServer) GetIamPolicy(ctx context.Context, req *iampb.GetIamPolicyRequest) (*iampb.Policy, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iampb.Policy), nil } func (s *mockDeviceManagerServer) TestIamPermissions(ctx context.Context, req *iampb.TestIamPermissionsRequest) (*iampb.TestIamPermissionsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iampb.TestIamPermissionsResponse), nil } func (s *mockDeviceManagerServer) SendCommandToDevice(ctx context.Context, req *iotpb.SendCommandToDeviceRequest) (*iotpb.SendCommandToDeviceResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iotpb.SendCommandToDeviceResponse), nil } func (s *mockDeviceManagerServer) BindDeviceToGateway(ctx context.Context, req *iotpb.BindDeviceToGatewayRequest) (*iotpb.BindDeviceToGatewayResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iotpb.BindDeviceToGatewayResponse), nil } func (s *mockDeviceManagerServer) UnbindDeviceFromGateway(ctx context.Context, req *iotpb.UnbindDeviceFromGatewayRequest) (*iotpb.UnbindDeviceFromGatewayResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iotpb.UnbindDeviceFromGatewayResponse), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockDeviceManager mockDeviceManagerServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() iotpb.RegisterDeviceManagerServer(serv, &mockDeviceManager) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestDeviceManagerCreateDeviceRegistry(t *testing.T) { var id string = "id3355" var name string = "name3373707" var expectedResponse = &iotpb.DeviceRegistry{ Id: id, Name: name, } mockDeviceManager.err = nil mockDeviceManager.reqs = nil mockDeviceManager.resps = append(mockDeviceManager.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var deviceRegistry *iotpb.DeviceRegistry = &iotpb.DeviceRegistry{} var request = &iotpb.CreateDeviceRegistryRequest{ Parent: formattedParent, DeviceRegistry: deviceRegistry, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateDeviceRegistry(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDeviceManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDeviceManagerCreateDeviceRegistryError(t *testing.T) { errCode := codes.PermissionDenied mockDeviceManager.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var deviceRegistry *iotpb.DeviceRegistry = &iotpb.DeviceRegistry{} var request = &iotpb.CreateDeviceRegistryRequest{ Parent: formattedParent, DeviceRegistry: deviceRegistry, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateDeviceRegistry(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDeviceManagerGetDeviceRegistry(t *testing.T) { var id string = "id3355" var name2 string = "name2-1052831874" var expectedResponse = &iotpb.DeviceRegistry{ Id: id, Name: name2, } mockDeviceManager.err = nil mockDeviceManager.reqs = nil mockDeviceManager.resps = append(mockDeviceManager.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/registries/%s", "[PROJECT]", "[LOCATION]", "[REGISTRY]") var request = &iotpb.GetDeviceRegistryRequest{ Name: formattedName, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetDeviceRegistry(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDeviceManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDeviceManagerGetDeviceRegistryError(t *testing.T) { errCode := codes.PermissionDenied mockDeviceManager.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/registries/%s", "[PROJECT]", "[LOCATION]", "[REGISTRY]") var request = &iotpb.GetDeviceRegistryRequest{ Name: formattedName, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetDeviceRegistry(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDeviceManagerUpdateDeviceRegistry(t *testing.T) { var id string = "id3355" var name string = "name3373707" var expectedResponse = &iotpb.DeviceRegistry{ Id: id, Name: name, } mockDeviceManager.err = nil mockDeviceManager.reqs = nil mockDeviceManager.resps = append(mockDeviceManager.resps[:0], expectedResponse) var deviceRegistry *iotpb.DeviceRegistry = &iotpb.DeviceRegistry{} var updateMask *field_maskpb.FieldMask = &field_maskpb.FieldMask{} var request = &iotpb.UpdateDeviceRegistryRequest{ DeviceRegistry: deviceRegistry, UpdateMask: updateMask, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateDeviceRegistry(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDeviceManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDeviceManagerUpdateDeviceRegistryError(t *testing.T) { errCode := codes.PermissionDenied mockDeviceManager.err = gstatus.Error(errCode, "test error") var deviceRegistry *iotpb.DeviceRegistry = &iotpb.DeviceRegistry{} var updateMask *field_maskpb.FieldMask = &field_maskpb.FieldMask{} var request = &iotpb.UpdateDeviceRegistryRequest{ DeviceRegistry: deviceRegistry, UpdateMask: updateMask, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateDeviceRegistry(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDeviceManagerDeleteDeviceRegistry(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockDeviceManager.err = nil mockDeviceManager.reqs = nil mockDeviceManager.resps = append(mockDeviceManager.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/registries/%s", "[PROJECT]", "[LOCATION]", "[REGISTRY]") var request = &iotpb.DeleteDeviceRegistryRequest{ Name: formattedName, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteDeviceRegistry(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDeviceManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestDeviceManagerDeleteDeviceRegistryError(t *testing.T) { errCode := codes.PermissionDenied mockDeviceManager.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/registries/%s", "[PROJECT]", "[LOCATION]", "[REGISTRY]") var request = &iotpb.DeleteDeviceRegistryRequest{ Name: formattedName, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteDeviceRegistry(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestDeviceManagerListDeviceRegistries(t *testing.T) { var nextPageToken string = "" var deviceRegistriesElement *iotpb.DeviceRegistry = &iotpb.DeviceRegistry{} var deviceRegistries = []*iotpb.DeviceRegistry{deviceRegistriesElement} var expectedResponse = &iotpb.ListDeviceRegistriesResponse{ NextPageToken: nextPageToken, DeviceRegistries: deviceRegistries, } mockDeviceManager.err = nil mockDeviceManager.reqs = nil mockDeviceManager.resps = append(mockDeviceManager.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &iotpb.ListDeviceRegistriesRequest{ Parent: formattedParent, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListDeviceRegistries(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockDeviceManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.DeviceRegistries[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDeviceManagerListDeviceRegistriesError(t *testing.T) { errCode := codes.PermissionDenied mockDeviceManager.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &iotpb.ListDeviceRegistriesRequest{ Parent: formattedParent, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListDeviceRegistries(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDeviceManagerCreateDevice(t *testing.T) { var id string = "id3355" var name string = "name3373707" var numId uint64 = 1034366860 var blocked bool = true var expectedResponse = &iotpb.Device{ Id: id, Name: name, NumId: numId, Blocked: blocked, } mockDeviceManager.err = nil mockDeviceManager.reqs = nil mockDeviceManager.resps = append(mockDeviceManager.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/registries/%s", "[PROJECT]", "[LOCATION]", "[REGISTRY]") var device *iotpb.Device = &iotpb.Device{} var request = &iotpb.CreateDeviceRequest{ Parent: formattedParent, Device: device, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateDevice(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDeviceManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDeviceManagerCreateDeviceError(t *testing.T) { errCode := codes.PermissionDenied mockDeviceManager.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/registries/%s", "[PROJECT]", "[LOCATION]", "[REGISTRY]") var device *iotpb.Device = &iotpb.Device{} var request = &iotpb.CreateDeviceRequest{ Parent: formattedParent, Device: device, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateDevice(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDeviceManagerGetDevice(t *testing.T) { var id string = "id3355" var name2 string = "name2-1052831874" var numId uint64 = 1034366860 var blocked bool = true var expectedResponse = &iotpb.Device{ Id: id, Name: name2, NumId: numId, Blocked: blocked, } mockDeviceManager.err = nil mockDeviceManager.reqs = nil mockDeviceManager.resps = append(mockDeviceManager.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/registries/%s/devices/%s", "[PROJECT]", "[LOCATION]", "[REGISTRY]", "[DEVICE]") var request = &iotpb.GetDeviceRequest{ Name: formattedName, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetDevice(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDeviceManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDeviceManagerGetDeviceError(t *testing.T) { errCode := codes.PermissionDenied mockDeviceManager.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/registries/%s/devices/%s", "[PROJECT]", "[LOCATION]", "[REGISTRY]", "[DEVICE]") var request = &iotpb.GetDeviceRequest{ Name: formattedName, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetDevice(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDeviceManagerUpdateDevice(t *testing.T) { var id string = "id3355" var name string = "name3373707" var numId uint64 = 1034366860 var blocked bool = true var expectedResponse = &iotpb.Device{ Id: id, Name: name, NumId: numId, Blocked: blocked, } mockDeviceManager.err = nil mockDeviceManager.reqs = nil mockDeviceManager.resps = append(mockDeviceManager.resps[:0], expectedResponse) var device *iotpb.Device = &iotpb.Device{} var updateMask *field_maskpb.FieldMask = &field_maskpb.FieldMask{} var request = &iotpb.UpdateDeviceRequest{ Device: device, UpdateMask: updateMask, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateDevice(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDeviceManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDeviceManagerUpdateDeviceError(t *testing.T) { errCode := codes.PermissionDenied mockDeviceManager.err = gstatus.Error(errCode, "test error") var device *iotpb.Device = &iotpb.Device{} var updateMask *field_maskpb.FieldMask = &field_maskpb.FieldMask{} var request = &iotpb.UpdateDeviceRequest{ Device: device, UpdateMask: updateMask, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateDevice(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDeviceManagerDeleteDevice(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockDeviceManager.err = nil mockDeviceManager.reqs = nil mockDeviceManager.resps = append(mockDeviceManager.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/registries/%s/devices/%s", "[PROJECT]", "[LOCATION]", "[REGISTRY]", "[DEVICE]") var request = &iotpb.DeleteDeviceRequest{ Name: formattedName, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteDevice(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDeviceManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestDeviceManagerDeleteDeviceError(t *testing.T) { errCode := codes.PermissionDenied mockDeviceManager.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/registries/%s/devices/%s", "[PROJECT]", "[LOCATION]", "[REGISTRY]", "[DEVICE]") var request = &iotpb.DeleteDeviceRequest{ Name: formattedName, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteDevice(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestDeviceManagerListDevices(t *testing.T) { var nextPageToken string = "" var devicesElement *iotpb.Device = &iotpb.Device{} var devices = []*iotpb.Device{devicesElement} var expectedResponse = &iotpb.ListDevicesResponse{ NextPageToken: nextPageToken, Devices: devices, } mockDeviceManager.err = nil mockDeviceManager.reqs = nil mockDeviceManager.resps = append(mockDeviceManager.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/registries/%s", "[PROJECT]", "[LOCATION]", "[REGISTRY]") var request = &iotpb.ListDevicesRequest{ Parent: formattedParent, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListDevices(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockDeviceManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Devices[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDeviceManagerListDevicesError(t *testing.T) { errCode := codes.PermissionDenied mockDeviceManager.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/registries/%s", "[PROJECT]", "[LOCATION]", "[REGISTRY]") var request = &iotpb.ListDevicesRequest{ Parent: formattedParent, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListDevices(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDeviceManagerModifyCloudToDeviceConfig(t *testing.T) { var version int64 = 351608024 var binaryData2 []byte = []byte("-37") var expectedResponse = &iotpb.DeviceConfig{ Version: version, BinaryData: binaryData2, } mockDeviceManager.err = nil mockDeviceManager.reqs = nil mockDeviceManager.resps = append(mockDeviceManager.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/registries/%s/devices/%s", "[PROJECT]", "[LOCATION]", "[REGISTRY]", "[DEVICE]") var binaryData []byte = []byte("40") var request = &iotpb.ModifyCloudToDeviceConfigRequest{ Name: formattedName, BinaryData: binaryData, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ModifyCloudToDeviceConfig(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDeviceManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDeviceManagerModifyCloudToDeviceConfigError(t *testing.T) { errCode := codes.PermissionDenied mockDeviceManager.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/registries/%s/devices/%s", "[PROJECT]", "[LOCATION]", "[REGISTRY]", "[DEVICE]") var binaryData []byte = []byte("40") var request = &iotpb.ModifyCloudToDeviceConfigRequest{ Name: formattedName, BinaryData: binaryData, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ModifyCloudToDeviceConfig(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDeviceManagerListDeviceConfigVersions(t *testing.T) { var expectedResponse *iotpb.ListDeviceConfigVersionsResponse = &iotpb.ListDeviceConfigVersionsResponse{} mockDeviceManager.err = nil mockDeviceManager.reqs = nil mockDeviceManager.resps = append(mockDeviceManager.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/registries/%s/devices/%s", "[PROJECT]", "[LOCATION]", "[REGISTRY]", "[DEVICE]") var request = &iotpb.ListDeviceConfigVersionsRequest{ Name: formattedName, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListDeviceConfigVersions(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDeviceManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDeviceManagerListDeviceConfigVersionsError(t *testing.T) { errCode := codes.PermissionDenied mockDeviceManager.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/registries/%s/devices/%s", "[PROJECT]", "[LOCATION]", "[REGISTRY]", "[DEVICE]") var request = &iotpb.ListDeviceConfigVersionsRequest{ Name: formattedName, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListDeviceConfigVersions(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDeviceManagerListDeviceStates(t *testing.T) { var expectedResponse *iotpb.ListDeviceStatesResponse = &iotpb.ListDeviceStatesResponse{} mockDeviceManager.err = nil mockDeviceManager.reqs = nil mockDeviceManager.resps = append(mockDeviceManager.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/registries/%s/devices/%s", "[PROJECT]", "[LOCATION]", "[REGISTRY]", "[DEVICE]") var request = &iotpb.ListDeviceStatesRequest{ Name: formattedName, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListDeviceStates(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDeviceManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDeviceManagerListDeviceStatesError(t *testing.T) { errCode := codes.PermissionDenied mockDeviceManager.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/registries/%s/devices/%s", "[PROJECT]", "[LOCATION]", "[REGISTRY]", "[DEVICE]") var request = &iotpb.ListDeviceStatesRequest{ Name: formattedName, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListDeviceStates(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDeviceManagerSetIamPolicy(t *testing.T) { var version int32 = 351608024 var etag []byte = []byte("21") var expectedResponse = &iampb.Policy{ Version: version, Etag: etag, } mockDeviceManager.err = nil mockDeviceManager.reqs = nil mockDeviceManager.resps = append(mockDeviceManager.resps[:0], expectedResponse) var resource string = "resource-341064690" var policy *iampb.Policy = &iampb.Policy{} var request = &iampb.SetIamPolicyRequest{ Resource: resource, Policy: policy, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetIamPolicy(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDeviceManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDeviceManagerSetIamPolicyError(t *testing.T) { errCode := codes.PermissionDenied mockDeviceManager.err = gstatus.Error(errCode, "test error") var resource string = "resource-341064690" var policy *iampb.Policy = &iampb.Policy{} var request = &iampb.SetIamPolicyRequest{ Resource: resource, Policy: policy, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetIamPolicy(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDeviceManagerGetIamPolicy(t *testing.T) { var version int32 = 351608024 var etag []byte = []byte("21") var expectedResponse = &iampb.Policy{ Version: version, Etag: etag, } mockDeviceManager.err = nil mockDeviceManager.reqs = nil mockDeviceManager.resps = append(mockDeviceManager.resps[:0], expectedResponse) var resource string = "resource-341064690" var request = &iampb.GetIamPolicyRequest{ Resource: resource, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetIamPolicy(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDeviceManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDeviceManagerGetIamPolicyError(t *testing.T) { errCode := codes.PermissionDenied mockDeviceManager.err = gstatus.Error(errCode, "test error") var resource string = "resource-341064690" var request = &iampb.GetIamPolicyRequest{ Resource: resource, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetIamPolicy(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDeviceManagerTestIamPermissions(t *testing.T) { var expectedResponse *iampb.TestIamPermissionsResponse = &iampb.TestIamPermissionsResponse{} mockDeviceManager.err = nil mockDeviceManager.reqs = nil mockDeviceManager.resps = append(mockDeviceManager.resps[:0], expectedResponse) var resource string = "resource-341064690" var permissions []string = nil var request = &iampb.TestIamPermissionsRequest{ Resource: resource, Permissions: permissions, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.TestIamPermissions(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDeviceManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDeviceManagerTestIamPermissionsError(t *testing.T) { errCode := codes.PermissionDenied mockDeviceManager.err = gstatus.Error(errCode, "test error") var resource string = "resource-341064690" var permissions []string = nil var request = &iampb.TestIamPermissionsRequest{ Resource: resource, Permissions: permissions, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.TestIamPermissions(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDeviceManagerSendCommandToDevice(t *testing.T) { var expectedResponse *iotpb.SendCommandToDeviceResponse = &iotpb.SendCommandToDeviceResponse{} mockDeviceManager.err = nil mockDeviceManager.reqs = nil mockDeviceManager.resps = append(mockDeviceManager.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/registries/%s/devices/%s", "[PROJECT]", "[LOCATION]", "[REGISTRY]", "[DEVICE]") var binaryData []byte = []byte("40") var request = &iotpb.SendCommandToDeviceRequest{ Name: formattedName, BinaryData: binaryData, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SendCommandToDevice(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDeviceManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDeviceManagerSendCommandToDeviceError(t *testing.T) { errCode := codes.PermissionDenied mockDeviceManager.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/registries/%s/devices/%s", "[PROJECT]", "[LOCATION]", "[REGISTRY]", "[DEVICE]") var binaryData []byte = []byte("40") var request = &iotpb.SendCommandToDeviceRequest{ Name: formattedName, BinaryData: binaryData, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SendCommandToDevice(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDeviceManagerBindDeviceToGateway(t *testing.T) { var expectedResponse *iotpb.BindDeviceToGatewayResponse = &iotpb.BindDeviceToGatewayResponse{} mockDeviceManager.err = nil mockDeviceManager.reqs = nil mockDeviceManager.resps = append(mockDeviceManager.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/registries/%s", "[PROJECT]", "[LOCATION]", "[REGISTRY]") var gatewayId string = "gatewayId955798774" var deviceId string = "deviceId25209764" var request = &iotpb.BindDeviceToGatewayRequest{ Parent: formattedParent, GatewayId: gatewayId, DeviceId: deviceId, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.BindDeviceToGateway(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDeviceManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDeviceManagerBindDeviceToGatewayError(t *testing.T) { errCode := codes.PermissionDenied mockDeviceManager.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/registries/%s", "[PROJECT]", "[LOCATION]", "[REGISTRY]") var gatewayId string = "gatewayId955798774" var deviceId string = "deviceId25209764" var request = &iotpb.BindDeviceToGatewayRequest{ Parent: formattedParent, GatewayId: gatewayId, DeviceId: deviceId, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.BindDeviceToGateway(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDeviceManagerUnbindDeviceFromGateway(t *testing.T) { var expectedResponse *iotpb.UnbindDeviceFromGatewayResponse = &iotpb.UnbindDeviceFromGatewayResponse{} mockDeviceManager.err = nil mockDeviceManager.reqs = nil mockDeviceManager.resps = append(mockDeviceManager.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/registries/%s", "[PROJECT]", "[LOCATION]", "[REGISTRY]") var gatewayId string = "gatewayId955798774" var deviceId string = "deviceId25209764" var request = &iotpb.UnbindDeviceFromGatewayRequest{ Parent: formattedParent, GatewayId: gatewayId, DeviceId: deviceId, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UnbindDeviceFromGateway(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDeviceManager.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDeviceManagerUnbindDeviceFromGatewayError(t *testing.T) { errCode := codes.PermissionDenied mockDeviceManager.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/registries/%s", "[PROJECT]", "[LOCATION]", "[REGISTRY]") var gatewayId string = "gatewayId955798774" var deviceId string = "deviceId25209764" var request = &iotpb.UnbindDeviceFromGatewayRequest{ Parent: formattedParent, GatewayId: gatewayId, DeviceId: deviceId, } c, err := NewDeviceManagerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UnbindDeviceFromGateway(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/irm/000077500000000000000000000000001356504100700153575ustar00rootroot00000000000000google-cloud-go-0.49.0/irm/apiv1alpha2/000077500000000000000000000000001356504100700174675ustar00rootroot00000000000000google-cloud-go-0.49.0/irm/apiv1alpha2/.repo-metadata.json000066400000000000000000000006721356504100700231700ustar00rootroot00000000000000{ "name": "irm", "name_pretty": "Stackdriver Incident Response and Management API", "product_documentation": "https://cloud.google.com/incident-response/", "client_documentation": "https://godoc.org/cloud.google.com/go/irm/apiv1alpha2", "release_level": "alpha", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "irm.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/irm/apiv1alpha2/doc.go000066400000000000000000000052511356504100700205660ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package irm is an auto-generated package for the // Stackdriver Incident Response & Management API. // // NOTE: This package is in alpha. It is not stable, and is likely to change. // // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package irm // import "cloud.google.com/go/irm/apiv1alpha2" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191115" google-cloud-go-0.49.0/irm/apiv1alpha2/incident_client.go000066400000000000000000001456131356504100700231630ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package irm import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" irmpb "google.golang.org/genproto/googleapis/cloud/irm/v1alpha2" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // IncidentCallOptions contains the retry settings for each method of IncidentClient. type IncidentCallOptions struct { CreateIncident []gax.CallOption GetIncident []gax.CallOption SearchIncidents []gax.CallOption UpdateIncident []gax.CallOption SearchSimilarIncidents []gax.CallOption CreateAnnotation []gax.CallOption ListAnnotations []gax.CallOption CreateTag []gax.CallOption DeleteTag []gax.CallOption ListTags []gax.CallOption CreateSignal []gax.CallOption SearchSignals []gax.CallOption GetSignal []gax.CallOption LookupSignal []gax.CallOption UpdateSignal []gax.CallOption EscalateIncident []gax.CallOption CreateArtifact []gax.CallOption ListArtifacts []gax.CallOption UpdateArtifact []gax.CallOption DeleteArtifact []gax.CallOption SendShiftHandoff []gax.CallOption CreateSubscription []gax.CallOption UpdateSubscription []gax.CallOption ListSubscriptions []gax.CallOption DeleteSubscription []gax.CallOption CreateIncidentRoleAssignment []gax.CallOption DeleteIncidentRoleAssignment []gax.CallOption ListIncidentRoleAssignments []gax.CallOption RequestIncidentRoleHandover []gax.CallOption ConfirmIncidentRoleHandover []gax.CallOption ForceIncidentRoleHandover []gax.CallOption CancelIncidentRoleHandover []gax.CallOption } func defaultIncidentClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("irm.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultIncidentCallOptions() *IncidentCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &IncidentCallOptions{ CreateIncident: retry[[2]string{"default", "non_idempotent"}], GetIncident: retry[[2]string{"default", "idempotent"}], SearchIncidents: retry[[2]string{"default", "idempotent"}], UpdateIncident: retry[[2]string{"default", "non_idempotent"}], SearchSimilarIncidents: retry[[2]string{"default", "idempotent"}], CreateAnnotation: retry[[2]string{"default", "non_idempotent"}], ListAnnotations: retry[[2]string{"default", "idempotent"}], CreateTag: retry[[2]string{"default", "non_idempotent"}], DeleteTag: retry[[2]string{"default", "idempotent"}], ListTags: retry[[2]string{"default", "idempotent"}], CreateSignal: retry[[2]string{"default", "non_idempotent"}], SearchSignals: retry[[2]string{"default", "idempotent"}], GetSignal: retry[[2]string{"default", "idempotent"}], LookupSignal: retry[[2]string{"default", "idempotent"}], UpdateSignal: retry[[2]string{"default", "non_idempotent"}], EscalateIncident: retry[[2]string{"default", "non_idempotent"}], CreateArtifact: retry[[2]string{"default", "non_idempotent"}], ListArtifacts: retry[[2]string{"default", "idempotent"}], UpdateArtifact: retry[[2]string{"default", "non_idempotent"}], DeleteArtifact: retry[[2]string{"default", "idempotent"}], SendShiftHandoff: retry[[2]string{"default", "non_idempotent"}], CreateSubscription: retry[[2]string{"default", "non_idempotent"}], UpdateSubscription: retry[[2]string{"default", "non_idempotent"}], ListSubscriptions: retry[[2]string{"default", "idempotent"}], DeleteSubscription: retry[[2]string{"default", "idempotent"}], CreateIncidentRoleAssignment: retry[[2]string{"default", "non_idempotent"}], DeleteIncidentRoleAssignment: retry[[2]string{"default", "idempotent"}], ListIncidentRoleAssignments: retry[[2]string{"default", "idempotent"}], RequestIncidentRoleHandover: retry[[2]string{"default", "non_idempotent"}], ConfirmIncidentRoleHandover: retry[[2]string{"default", "non_idempotent"}], ForceIncidentRoleHandover: retry[[2]string{"default", "non_idempotent"}], CancelIncidentRoleHandover: retry[[2]string{"default", "non_idempotent"}], } } // IncidentClient is a client for interacting with Stackdriver Incident Response & Management API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type IncidentClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. incidentClient irmpb.IncidentServiceClient // The call options for this service. CallOptions *IncidentCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewIncidentClient creates a new incident service client. // // The Incident API for Incident Response & Management. func NewIncidentClient(ctx context.Context, opts ...option.ClientOption) (*IncidentClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultIncidentClientOptions(), opts...)...) if err != nil { return nil, err } c := &IncidentClient{ conn: conn, CallOptions: defaultIncidentCallOptions(), incidentClient: irmpb.NewIncidentServiceClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *IncidentClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *IncidentClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *IncidentClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // CreateIncident creates a new incident. func (c *IncidentClient) CreateIncident(ctx context.Context, req *irmpb.CreateIncidentRequest, opts ...gax.CallOption) (*irmpb.Incident, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateIncident[0:len(c.CallOptions.CreateIncident):len(c.CallOptions.CreateIncident)], opts...) var resp *irmpb.Incident err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.incidentClient.CreateIncident(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetIncident returns an incident by name. func (c *IncidentClient) GetIncident(ctx context.Context, req *irmpb.GetIncidentRequest, opts ...gax.CallOption) (*irmpb.Incident, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetIncident[0:len(c.CallOptions.GetIncident):len(c.CallOptions.GetIncident)], opts...) var resp *irmpb.Incident err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.incidentClient.GetIncident(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // SearchIncidents returns a list of incidents. // Incidents are ordered by start time, with the most recent incidents first. func (c *IncidentClient) SearchIncidents(ctx context.Context, req *irmpb.SearchIncidentsRequest, opts ...gax.CallOption) *IncidentIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.SearchIncidents[0:len(c.CallOptions.SearchIncidents):len(c.CallOptions.SearchIncidents)], opts...) it := &IncidentIterator{} req = proto.Clone(req).(*irmpb.SearchIncidentsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*irmpb.Incident, string, error) { var resp *irmpb.SearchIncidentsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.incidentClient.SearchIncidents(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Incidents, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // UpdateIncident updates an existing incident. func (c *IncidentClient) UpdateIncident(ctx context.Context, req *irmpb.UpdateIncidentRequest, opts ...gax.CallOption) (*irmpb.Incident, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "incident.name", url.QueryEscape(req.GetIncident().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateIncident[0:len(c.CallOptions.UpdateIncident):len(c.CallOptions.UpdateIncident)], opts...) var resp *irmpb.Incident err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.incidentClient.UpdateIncident(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // SearchSimilarIncidents returns a list of incidents that are "similar" to the specified incident // or signal. This functionality is provided on a best-effort basis and the // definition of "similar" is subject to change. func (c *IncidentClient) SearchSimilarIncidents(ctx context.Context, req *irmpb.SearchSimilarIncidentsRequest, opts ...gax.CallOption) *SearchSimilarIncidentsResponse_ResultIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.SearchSimilarIncidents[0:len(c.CallOptions.SearchSimilarIncidents):len(c.CallOptions.SearchSimilarIncidents)], opts...) it := &SearchSimilarIncidentsResponse_ResultIterator{} req = proto.Clone(req).(*irmpb.SearchSimilarIncidentsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*irmpb.SearchSimilarIncidentsResponse_Result, string, error) { var resp *irmpb.SearchSimilarIncidentsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.incidentClient.SearchSimilarIncidents(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Results, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // CreateAnnotation creates an annotation on an existing incident. Only 'text/plain' and // 'text/markdown' annotations can be created via this method. func (c *IncidentClient) CreateAnnotation(ctx context.Context, req *irmpb.CreateAnnotationRequest, opts ...gax.CallOption) (*irmpb.Annotation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateAnnotation[0:len(c.CallOptions.CreateAnnotation):len(c.CallOptions.CreateAnnotation)], opts...) var resp *irmpb.Annotation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.incidentClient.CreateAnnotation(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListAnnotations lists annotations that are part of an incident. No assumptions should be // made on the content-type of the annotation returned. func (c *IncidentClient) ListAnnotations(ctx context.Context, req *irmpb.ListAnnotationsRequest, opts ...gax.CallOption) *AnnotationIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListAnnotations[0:len(c.CallOptions.ListAnnotations):len(c.CallOptions.ListAnnotations)], opts...) it := &AnnotationIterator{} req = proto.Clone(req).(*irmpb.ListAnnotationsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*irmpb.Annotation, string, error) { var resp *irmpb.ListAnnotationsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.incidentClient.ListAnnotations(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Annotations, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // CreateTag creates a tag on an existing incident. func (c *IncidentClient) CreateTag(ctx context.Context, req *irmpb.CreateTagRequest, opts ...gax.CallOption) (*irmpb.Tag, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateTag[0:len(c.CallOptions.CreateTag):len(c.CallOptions.CreateTag)], opts...) var resp *irmpb.Tag err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.incidentClient.CreateTag(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteTag deletes an existing tag. func (c *IncidentClient) DeleteTag(ctx context.Context, req *irmpb.DeleteTagRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteTag[0:len(c.CallOptions.DeleteTag):len(c.CallOptions.DeleteTag)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.incidentClient.DeleteTag(ctx, req, settings.GRPC...) return err }, opts...) return err } // ListTags lists tags that are part of an incident. func (c *IncidentClient) ListTags(ctx context.Context, req *irmpb.ListTagsRequest, opts ...gax.CallOption) *TagIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListTags[0:len(c.CallOptions.ListTags):len(c.CallOptions.ListTags)], opts...) it := &TagIterator{} req = proto.Clone(req).(*irmpb.ListTagsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*irmpb.Tag, string, error) { var resp *irmpb.ListTagsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.incidentClient.ListTags(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Tags, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // CreateSignal creates a new signal. func (c *IncidentClient) CreateSignal(ctx context.Context, req *irmpb.CreateSignalRequest, opts ...gax.CallOption) (*irmpb.Signal, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateSignal[0:len(c.CallOptions.CreateSignal):len(c.CallOptions.CreateSignal)], opts...) var resp *irmpb.Signal err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.incidentClient.CreateSignal(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // SearchSignals lists signals that are part of an incident. // Signals are returned in reverse chronological order. func (c *IncidentClient) SearchSignals(ctx context.Context, req *irmpb.SearchSignalsRequest, opts ...gax.CallOption) *SignalIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.SearchSignals[0:len(c.CallOptions.SearchSignals):len(c.CallOptions.SearchSignals)], opts...) it := &SignalIterator{} req = proto.Clone(req).(*irmpb.SearchSignalsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*irmpb.Signal, string, error) { var resp *irmpb.SearchSignalsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.incidentClient.SearchSignals(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Signals, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetSignal returns a signal by name. func (c *IncidentClient) GetSignal(ctx context.Context, req *irmpb.GetSignalRequest, opts ...gax.CallOption) (*irmpb.Signal, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetSignal[0:len(c.CallOptions.GetSignal):len(c.CallOptions.GetSignal)], opts...) var resp *irmpb.Signal err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.incidentClient.GetSignal(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // LookupSignal finds a signal by other unique IDs. func (c *IncidentClient) LookupSignal(ctx context.Context, req *irmpb.LookupSignalRequest, opts ...gax.CallOption) (*irmpb.Signal, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.LookupSignal[0:len(c.CallOptions.LookupSignal):len(c.CallOptions.LookupSignal)], opts...) var resp *irmpb.Signal err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.incidentClient.LookupSignal(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateSignal updates an existing signal (for example, to assign/unassign it to an // incident). func (c *IncidentClient) UpdateSignal(ctx context.Context, req *irmpb.UpdateSignalRequest, opts ...gax.CallOption) (*irmpb.Signal, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "signal.name", url.QueryEscape(req.GetSignal().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateSignal[0:len(c.CallOptions.UpdateSignal):len(c.CallOptions.UpdateSignal)], opts...) var resp *irmpb.Signal err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.incidentClient.UpdateSignal(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // EscalateIncident escalates an incident. func (c *IncidentClient) EscalateIncident(ctx context.Context, req *irmpb.EscalateIncidentRequest, opts ...gax.CallOption) (*irmpb.EscalateIncidentResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "incident.name", url.QueryEscape(req.GetIncident().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.EscalateIncident[0:len(c.CallOptions.EscalateIncident):len(c.CallOptions.EscalateIncident)], opts...) var resp *irmpb.EscalateIncidentResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.incidentClient.EscalateIncident(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateArtifact creates a new artifact. func (c *IncidentClient) CreateArtifact(ctx context.Context, req *irmpb.CreateArtifactRequest, opts ...gax.CallOption) (*irmpb.Artifact, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateArtifact[0:len(c.CallOptions.CreateArtifact):len(c.CallOptions.CreateArtifact)], opts...) var resp *irmpb.Artifact err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.incidentClient.CreateArtifact(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListArtifacts returns a list of artifacts for an incident. func (c *IncidentClient) ListArtifacts(ctx context.Context, req *irmpb.ListArtifactsRequest, opts ...gax.CallOption) *ArtifactIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListArtifacts[0:len(c.CallOptions.ListArtifacts):len(c.CallOptions.ListArtifacts)], opts...) it := &ArtifactIterator{} req = proto.Clone(req).(*irmpb.ListArtifactsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*irmpb.Artifact, string, error) { var resp *irmpb.ListArtifactsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.incidentClient.ListArtifacts(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Artifacts, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // UpdateArtifact updates an existing artifact. func (c *IncidentClient) UpdateArtifact(ctx context.Context, req *irmpb.UpdateArtifactRequest, opts ...gax.CallOption) (*irmpb.Artifact, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "artifact.name", url.QueryEscape(req.GetArtifact().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateArtifact[0:len(c.CallOptions.UpdateArtifact):len(c.CallOptions.UpdateArtifact)], opts...) var resp *irmpb.Artifact err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.incidentClient.UpdateArtifact(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteArtifact deletes an existing artifact. func (c *IncidentClient) DeleteArtifact(ctx context.Context, req *irmpb.DeleteArtifactRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteArtifact[0:len(c.CallOptions.DeleteArtifact):len(c.CallOptions.DeleteArtifact)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.incidentClient.DeleteArtifact(ctx, req, settings.GRPC...) return err }, opts...) return err } // SendShiftHandoff sends a summary of the shift for oncall handoff. func (c *IncidentClient) SendShiftHandoff(ctx context.Context, req *irmpb.SendShiftHandoffRequest, opts ...gax.CallOption) (*irmpb.SendShiftHandoffResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.SendShiftHandoff[0:len(c.CallOptions.SendShiftHandoff):len(c.CallOptions.SendShiftHandoff)], opts...) var resp *irmpb.SendShiftHandoffResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.incidentClient.SendShiftHandoff(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateSubscription creates a new subscription. // This will fail if: // a. there are too many (50) subscriptions in the incident already // b. a subscription using the given channel already exists func (c *IncidentClient) CreateSubscription(ctx context.Context, req *irmpb.CreateSubscriptionRequest, opts ...gax.CallOption) (*irmpb.Subscription, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateSubscription[0:len(c.CallOptions.CreateSubscription):len(c.CallOptions.CreateSubscription)], opts...) var resp *irmpb.Subscription err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.incidentClient.CreateSubscription(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateSubscription updates a subscription. func (c *IncidentClient) UpdateSubscription(ctx context.Context, req *irmpb.UpdateSubscriptionRequest, opts ...gax.CallOption) (*irmpb.Subscription, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "subscription.name", url.QueryEscape(req.GetSubscription().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateSubscription[0:len(c.CallOptions.UpdateSubscription):len(c.CallOptions.UpdateSubscription)], opts...) var resp *irmpb.Subscription err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.incidentClient.UpdateSubscription(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListSubscriptions returns a list of subscriptions for an incident. func (c *IncidentClient) ListSubscriptions(ctx context.Context, req *irmpb.ListSubscriptionsRequest, opts ...gax.CallOption) *SubscriptionIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListSubscriptions[0:len(c.CallOptions.ListSubscriptions):len(c.CallOptions.ListSubscriptions)], opts...) it := &SubscriptionIterator{} req = proto.Clone(req).(*irmpb.ListSubscriptionsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*irmpb.Subscription, string, error) { var resp *irmpb.ListSubscriptionsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.incidentClient.ListSubscriptions(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Subscriptions, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // DeleteSubscription deletes an existing subscription. func (c *IncidentClient) DeleteSubscription(ctx context.Context, req *irmpb.DeleteSubscriptionRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteSubscription[0:len(c.CallOptions.DeleteSubscription):len(c.CallOptions.DeleteSubscription)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.incidentClient.DeleteSubscription(ctx, req, settings.GRPC...) return err }, opts...) return err } // CreateIncidentRoleAssignment creates a role assignment on an existing incident. Normally, the user field // will be set when assigning a role to oneself, and the next field will be // set when proposing another user as the assignee. Setting the next field // directly to a user other than oneself is equivalent to proposing and // force-assigning the role to the user. func (c *IncidentClient) CreateIncidentRoleAssignment(ctx context.Context, req *irmpb.CreateIncidentRoleAssignmentRequest, opts ...gax.CallOption) (*irmpb.IncidentRoleAssignment, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateIncidentRoleAssignment[0:len(c.CallOptions.CreateIncidentRoleAssignment):len(c.CallOptions.CreateIncidentRoleAssignment)], opts...) var resp *irmpb.IncidentRoleAssignment err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.incidentClient.CreateIncidentRoleAssignment(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteIncidentRoleAssignment deletes an existing role assignment. func (c *IncidentClient) DeleteIncidentRoleAssignment(ctx context.Context, req *irmpb.DeleteIncidentRoleAssignmentRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteIncidentRoleAssignment[0:len(c.CallOptions.DeleteIncidentRoleAssignment):len(c.CallOptions.DeleteIncidentRoleAssignment)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.incidentClient.DeleteIncidentRoleAssignment(ctx, req, settings.GRPC...) return err }, opts...) return err } // ListIncidentRoleAssignments lists role assignments that are part of an incident. func (c *IncidentClient) ListIncidentRoleAssignments(ctx context.Context, req *irmpb.ListIncidentRoleAssignmentsRequest, opts ...gax.CallOption) *IncidentRoleAssignmentIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListIncidentRoleAssignments[0:len(c.CallOptions.ListIncidentRoleAssignments):len(c.CallOptions.ListIncidentRoleAssignments)], opts...) it := &IncidentRoleAssignmentIterator{} req = proto.Clone(req).(*irmpb.ListIncidentRoleAssignmentsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*irmpb.IncidentRoleAssignment, string, error) { var resp *irmpb.ListIncidentRoleAssignmentsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.incidentClient.ListIncidentRoleAssignments(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.IncidentRoleAssignments, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // RequestIncidentRoleHandover starts a role handover. The proposed assignee will receive an email // notifying them of the assignment. This will fail if a role handover is // already pending. func (c *IncidentClient) RequestIncidentRoleHandover(ctx context.Context, req *irmpb.RequestIncidentRoleHandoverRequest, opts ...gax.CallOption) (*irmpb.IncidentRoleAssignment, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.RequestIncidentRoleHandover[0:len(c.CallOptions.RequestIncidentRoleHandover):len(c.CallOptions.RequestIncidentRoleHandover)], opts...) var resp *irmpb.IncidentRoleAssignment err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.incidentClient.RequestIncidentRoleHandover(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ConfirmIncidentRoleHandover confirms a role handover. This will fail if the 'proposed_assignee' field // of the IncidentRoleAssignment is not equal to the 'new_assignee' field of // the request. If the caller is not the new_assignee, // ForceIncidentRoleHandover should be used instead. func (c *IncidentClient) ConfirmIncidentRoleHandover(ctx context.Context, req *irmpb.ConfirmIncidentRoleHandoverRequest, opts ...gax.CallOption) (*irmpb.IncidentRoleAssignment, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ConfirmIncidentRoleHandover[0:len(c.CallOptions.ConfirmIncidentRoleHandover):len(c.CallOptions.ConfirmIncidentRoleHandover)], opts...) var resp *irmpb.IncidentRoleAssignment err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.incidentClient.ConfirmIncidentRoleHandover(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ForceIncidentRoleHandover forces a role handover. This will fail if the 'proposed_assignee' field of // the IncidentRoleAssignment is not equal to the 'new_assignee' field of the // request. If the caller is the new_assignee, ConfirmIncidentRoleHandover // should be used instead. func (c *IncidentClient) ForceIncidentRoleHandover(ctx context.Context, req *irmpb.ForceIncidentRoleHandoverRequest, opts ...gax.CallOption) (*irmpb.IncidentRoleAssignment, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ForceIncidentRoleHandover[0:len(c.CallOptions.ForceIncidentRoleHandover):len(c.CallOptions.ForceIncidentRoleHandover)], opts...) var resp *irmpb.IncidentRoleAssignment err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.incidentClient.ForceIncidentRoleHandover(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CancelIncidentRoleHandover cancels a role handover. This will fail if the 'proposed_assignee' field of // the IncidentRoleAssignment is not equal to the 'new_assignee' field of the // request. func (c *IncidentClient) CancelIncidentRoleHandover(ctx context.Context, req *irmpb.CancelIncidentRoleHandoverRequest, opts ...gax.CallOption) (*irmpb.IncidentRoleAssignment, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CancelIncidentRoleHandover[0:len(c.CallOptions.CancelIncidentRoleHandover):len(c.CallOptions.CancelIncidentRoleHandover)], opts...) var resp *irmpb.IncidentRoleAssignment err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.incidentClient.CancelIncidentRoleHandover(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // AnnotationIterator manages a stream of *irmpb.Annotation. type AnnotationIterator struct { items []*irmpb.Annotation pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*irmpb.Annotation, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *AnnotationIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *AnnotationIterator) Next() (*irmpb.Annotation, error) { var item *irmpb.Annotation if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *AnnotationIterator) bufLen() int { return len(it.items) } func (it *AnnotationIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // ArtifactIterator manages a stream of *irmpb.Artifact. type ArtifactIterator struct { items []*irmpb.Artifact pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*irmpb.Artifact, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *ArtifactIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *ArtifactIterator) Next() (*irmpb.Artifact, error) { var item *irmpb.Artifact if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *ArtifactIterator) bufLen() int { return len(it.items) } func (it *ArtifactIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // IncidentIterator manages a stream of *irmpb.Incident. type IncidentIterator struct { items []*irmpb.Incident pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*irmpb.Incident, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *IncidentIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *IncidentIterator) Next() (*irmpb.Incident, error) { var item *irmpb.Incident if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *IncidentIterator) bufLen() int { return len(it.items) } func (it *IncidentIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // IncidentRoleAssignmentIterator manages a stream of *irmpb.IncidentRoleAssignment. type IncidentRoleAssignmentIterator struct { items []*irmpb.IncidentRoleAssignment pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*irmpb.IncidentRoleAssignment, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *IncidentRoleAssignmentIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *IncidentRoleAssignmentIterator) Next() (*irmpb.IncidentRoleAssignment, error) { var item *irmpb.IncidentRoleAssignment if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *IncidentRoleAssignmentIterator) bufLen() int { return len(it.items) } func (it *IncidentRoleAssignmentIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // SearchSimilarIncidentsResponse_ResultIterator manages a stream of *irmpb.SearchSimilarIncidentsResponse_Result. type SearchSimilarIncidentsResponse_ResultIterator struct { items []*irmpb.SearchSimilarIncidentsResponse_Result pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*irmpb.SearchSimilarIncidentsResponse_Result, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *SearchSimilarIncidentsResponse_ResultIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *SearchSimilarIncidentsResponse_ResultIterator) Next() (*irmpb.SearchSimilarIncidentsResponse_Result, error) { var item *irmpb.SearchSimilarIncidentsResponse_Result if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *SearchSimilarIncidentsResponse_ResultIterator) bufLen() int { return len(it.items) } func (it *SearchSimilarIncidentsResponse_ResultIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // SignalIterator manages a stream of *irmpb.Signal. type SignalIterator struct { items []*irmpb.Signal pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*irmpb.Signal, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *SignalIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *SignalIterator) Next() (*irmpb.Signal, error) { var item *irmpb.Signal if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *SignalIterator) bufLen() int { return len(it.items) } func (it *SignalIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // SubscriptionIterator manages a stream of *irmpb.Subscription. type SubscriptionIterator struct { items []*irmpb.Subscription pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*irmpb.Subscription, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *SubscriptionIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *SubscriptionIterator) Next() (*irmpb.Subscription, error) { var item *irmpb.Subscription if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *SubscriptionIterator) bufLen() int { return len(it.items) } func (it *SubscriptionIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // TagIterator manages a stream of *irmpb.Tag. type TagIterator struct { items []*irmpb.Tag pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*irmpb.Tag, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *TagIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *TagIterator) Next() (*irmpb.Tag, error) { var item *irmpb.Tag if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *TagIterator) bufLen() int { return len(it.items) } func (it *TagIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/irm/apiv1alpha2/incident_client_example_test.go000066400000000000000000000315621356504100700257320ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package irm_test import ( "context" irm "cloud.google.com/go/irm/apiv1alpha2" "google.golang.org/api/iterator" irmpb "google.golang.org/genproto/googleapis/cloud/irm/v1alpha2" ) func ExampleNewIncidentClient() { ctx := context.Background() c, err := irm.NewIncidentClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleIncidentClient_CreateIncident() { ctx := context.Background() c, err := irm.NewIncidentClient(ctx) if err != nil { // TODO: Handle error. } req := &irmpb.CreateIncidentRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateIncident(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIncidentClient_GetIncident() { ctx := context.Background() c, err := irm.NewIncidentClient(ctx) if err != nil { // TODO: Handle error. } req := &irmpb.GetIncidentRequest{ // TODO: Fill request struct fields. } resp, err := c.GetIncident(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIncidentClient_SearchIncidents() { ctx := context.Background() c, err := irm.NewIncidentClient(ctx) if err != nil { // TODO: Handle error. } req := &irmpb.SearchIncidentsRequest{ // TODO: Fill request struct fields. } it := c.SearchIncidents(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleIncidentClient_UpdateIncident() { ctx := context.Background() c, err := irm.NewIncidentClient(ctx) if err != nil { // TODO: Handle error. } req := &irmpb.UpdateIncidentRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateIncident(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIncidentClient_SearchSimilarIncidents() { ctx := context.Background() c, err := irm.NewIncidentClient(ctx) if err != nil { // TODO: Handle error. } req := &irmpb.SearchSimilarIncidentsRequest{ // TODO: Fill request struct fields. } it := c.SearchSimilarIncidents(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleIncidentClient_CreateAnnotation() { ctx := context.Background() c, err := irm.NewIncidentClient(ctx) if err != nil { // TODO: Handle error. } req := &irmpb.CreateAnnotationRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateAnnotation(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIncidentClient_ListAnnotations() { ctx := context.Background() c, err := irm.NewIncidentClient(ctx) if err != nil { // TODO: Handle error. } req := &irmpb.ListAnnotationsRequest{ // TODO: Fill request struct fields. } it := c.ListAnnotations(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleIncidentClient_CreateTag() { ctx := context.Background() c, err := irm.NewIncidentClient(ctx) if err != nil { // TODO: Handle error. } req := &irmpb.CreateTagRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateTag(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIncidentClient_DeleteTag() { ctx := context.Background() c, err := irm.NewIncidentClient(ctx) if err != nil { // TODO: Handle error. } req := &irmpb.DeleteTagRequest{ // TODO: Fill request struct fields. } err = c.DeleteTag(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleIncidentClient_ListTags() { ctx := context.Background() c, err := irm.NewIncidentClient(ctx) if err != nil { // TODO: Handle error. } req := &irmpb.ListTagsRequest{ // TODO: Fill request struct fields. } it := c.ListTags(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleIncidentClient_CreateSignal() { ctx := context.Background() c, err := irm.NewIncidentClient(ctx) if err != nil { // TODO: Handle error. } req := &irmpb.CreateSignalRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateSignal(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIncidentClient_SearchSignals() { ctx := context.Background() c, err := irm.NewIncidentClient(ctx) if err != nil { // TODO: Handle error. } req := &irmpb.SearchSignalsRequest{ // TODO: Fill request struct fields. } it := c.SearchSignals(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleIncidentClient_GetSignal() { ctx := context.Background() c, err := irm.NewIncidentClient(ctx) if err != nil { // TODO: Handle error. } req := &irmpb.GetSignalRequest{ // TODO: Fill request struct fields. } resp, err := c.GetSignal(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIncidentClient_LookupSignal() { ctx := context.Background() c, err := irm.NewIncidentClient(ctx) if err != nil { // TODO: Handle error. } req := &irmpb.LookupSignalRequest{ // TODO: Fill request struct fields. } resp, err := c.LookupSignal(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIncidentClient_UpdateSignal() { ctx := context.Background() c, err := irm.NewIncidentClient(ctx) if err != nil { // TODO: Handle error. } req := &irmpb.UpdateSignalRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateSignal(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIncidentClient_EscalateIncident() { ctx := context.Background() c, err := irm.NewIncidentClient(ctx) if err != nil { // TODO: Handle error. } req := &irmpb.EscalateIncidentRequest{ // TODO: Fill request struct fields. } resp, err := c.EscalateIncident(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIncidentClient_CreateArtifact() { ctx := context.Background() c, err := irm.NewIncidentClient(ctx) if err != nil { // TODO: Handle error. } req := &irmpb.CreateArtifactRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateArtifact(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIncidentClient_ListArtifacts() { ctx := context.Background() c, err := irm.NewIncidentClient(ctx) if err != nil { // TODO: Handle error. } req := &irmpb.ListArtifactsRequest{ // TODO: Fill request struct fields. } it := c.ListArtifacts(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleIncidentClient_UpdateArtifact() { ctx := context.Background() c, err := irm.NewIncidentClient(ctx) if err != nil { // TODO: Handle error. } req := &irmpb.UpdateArtifactRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateArtifact(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIncidentClient_DeleteArtifact() { ctx := context.Background() c, err := irm.NewIncidentClient(ctx) if err != nil { // TODO: Handle error. } req := &irmpb.DeleteArtifactRequest{ // TODO: Fill request struct fields. } err = c.DeleteArtifact(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleIncidentClient_SendShiftHandoff() { ctx := context.Background() c, err := irm.NewIncidentClient(ctx) if err != nil { // TODO: Handle error. } req := &irmpb.SendShiftHandoffRequest{ // TODO: Fill request struct fields. } resp, err := c.SendShiftHandoff(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIncidentClient_CreateSubscription() { ctx := context.Background() c, err := irm.NewIncidentClient(ctx) if err != nil { // TODO: Handle error. } req := &irmpb.CreateSubscriptionRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateSubscription(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIncidentClient_UpdateSubscription() { ctx := context.Background() c, err := irm.NewIncidentClient(ctx) if err != nil { // TODO: Handle error. } req := &irmpb.UpdateSubscriptionRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateSubscription(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIncidentClient_ListSubscriptions() { ctx := context.Background() c, err := irm.NewIncidentClient(ctx) if err != nil { // TODO: Handle error. } req := &irmpb.ListSubscriptionsRequest{ // TODO: Fill request struct fields. } it := c.ListSubscriptions(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleIncidentClient_DeleteSubscription() { ctx := context.Background() c, err := irm.NewIncidentClient(ctx) if err != nil { // TODO: Handle error. } req := &irmpb.DeleteSubscriptionRequest{ // TODO: Fill request struct fields. } err = c.DeleteSubscription(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleIncidentClient_CreateIncidentRoleAssignment() { ctx := context.Background() c, err := irm.NewIncidentClient(ctx) if err != nil { // TODO: Handle error. } req := &irmpb.CreateIncidentRoleAssignmentRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateIncidentRoleAssignment(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIncidentClient_DeleteIncidentRoleAssignment() { ctx := context.Background() c, err := irm.NewIncidentClient(ctx) if err != nil { // TODO: Handle error. } req := &irmpb.DeleteIncidentRoleAssignmentRequest{ // TODO: Fill request struct fields. } err = c.DeleteIncidentRoleAssignment(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleIncidentClient_ListIncidentRoleAssignments() { ctx := context.Background() c, err := irm.NewIncidentClient(ctx) if err != nil { // TODO: Handle error. } req := &irmpb.ListIncidentRoleAssignmentsRequest{ // TODO: Fill request struct fields. } it := c.ListIncidentRoleAssignments(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleIncidentClient_RequestIncidentRoleHandover() { ctx := context.Background() c, err := irm.NewIncidentClient(ctx) if err != nil { // TODO: Handle error. } req := &irmpb.RequestIncidentRoleHandoverRequest{ // TODO: Fill request struct fields. } resp, err := c.RequestIncidentRoleHandover(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIncidentClient_ConfirmIncidentRoleHandover() { ctx := context.Background() c, err := irm.NewIncidentClient(ctx) if err != nil { // TODO: Handle error. } req := &irmpb.ConfirmIncidentRoleHandoverRequest{ // TODO: Fill request struct fields. } resp, err := c.ConfirmIncidentRoleHandover(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIncidentClient_ForceIncidentRoleHandover() { ctx := context.Background() c, err := irm.NewIncidentClient(ctx) if err != nil { // TODO: Handle error. } req := &irmpb.ForceIncidentRoleHandoverRequest{ // TODO: Fill request struct fields. } resp, err := c.ForceIncidentRoleHandover(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleIncidentClient_CancelIncidentRoleHandover() { ctx := context.Background() c, err := irm.NewIncidentClient(ctx) if err != nil { // TODO: Handle error. } req := &irmpb.CancelIncidentRoleHandoverRequest{ // TODO: Fill request struct fields. } resp, err := c.CancelIncidentRoleHandover(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/irm/apiv1alpha2/mock_test.go000066400000000000000000002236021356504100700220130ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package irm import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" "google.golang.org/api/option" irmpb "google.golang.org/genproto/googleapis/cloud/irm/v1alpha2" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockIncidentServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. irmpb.IncidentServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockIncidentServer) CreateIncident(ctx context.Context, req *irmpb.CreateIncidentRequest) (*irmpb.Incident, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*irmpb.Incident), nil } func (s *mockIncidentServer) GetIncident(ctx context.Context, req *irmpb.GetIncidentRequest) (*irmpb.Incident, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*irmpb.Incident), nil } func (s *mockIncidentServer) SearchIncidents(ctx context.Context, req *irmpb.SearchIncidentsRequest) (*irmpb.SearchIncidentsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*irmpb.SearchIncidentsResponse), nil } func (s *mockIncidentServer) UpdateIncident(ctx context.Context, req *irmpb.UpdateIncidentRequest) (*irmpb.Incident, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*irmpb.Incident), nil } func (s *mockIncidentServer) SearchSimilarIncidents(ctx context.Context, req *irmpb.SearchSimilarIncidentsRequest) (*irmpb.SearchSimilarIncidentsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*irmpb.SearchSimilarIncidentsResponse), nil } func (s *mockIncidentServer) CreateAnnotation(ctx context.Context, req *irmpb.CreateAnnotationRequest) (*irmpb.Annotation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*irmpb.Annotation), nil } func (s *mockIncidentServer) ListAnnotations(ctx context.Context, req *irmpb.ListAnnotationsRequest) (*irmpb.ListAnnotationsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*irmpb.ListAnnotationsResponse), nil } func (s *mockIncidentServer) CreateTag(ctx context.Context, req *irmpb.CreateTagRequest) (*irmpb.Tag, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*irmpb.Tag), nil } func (s *mockIncidentServer) DeleteTag(ctx context.Context, req *irmpb.DeleteTagRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockIncidentServer) ListTags(ctx context.Context, req *irmpb.ListTagsRequest) (*irmpb.ListTagsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*irmpb.ListTagsResponse), nil } func (s *mockIncidentServer) CreateSignal(ctx context.Context, req *irmpb.CreateSignalRequest) (*irmpb.Signal, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*irmpb.Signal), nil } func (s *mockIncidentServer) SearchSignals(ctx context.Context, req *irmpb.SearchSignalsRequest) (*irmpb.SearchSignalsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*irmpb.SearchSignalsResponse), nil } func (s *mockIncidentServer) LookupSignal(ctx context.Context, req *irmpb.LookupSignalRequest) (*irmpb.Signal, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*irmpb.Signal), nil } func (s *mockIncidentServer) GetSignal(ctx context.Context, req *irmpb.GetSignalRequest) (*irmpb.Signal, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*irmpb.Signal), nil } func (s *mockIncidentServer) UpdateSignal(ctx context.Context, req *irmpb.UpdateSignalRequest) (*irmpb.Signal, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*irmpb.Signal), nil } func (s *mockIncidentServer) EscalateIncident(ctx context.Context, req *irmpb.EscalateIncidentRequest) (*irmpb.EscalateIncidentResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*irmpb.EscalateIncidentResponse), nil } func (s *mockIncidentServer) CreateArtifact(ctx context.Context, req *irmpb.CreateArtifactRequest) (*irmpb.Artifact, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*irmpb.Artifact), nil } func (s *mockIncidentServer) ListArtifacts(ctx context.Context, req *irmpb.ListArtifactsRequest) (*irmpb.ListArtifactsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*irmpb.ListArtifactsResponse), nil } func (s *mockIncidentServer) UpdateArtifact(ctx context.Context, req *irmpb.UpdateArtifactRequest) (*irmpb.Artifact, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*irmpb.Artifact), nil } func (s *mockIncidentServer) DeleteArtifact(ctx context.Context, req *irmpb.DeleteArtifactRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockIncidentServer) SendShiftHandoff(ctx context.Context, req *irmpb.SendShiftHandoffRequest) (*irmpb.SendShiftHandoffResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*irmpb.SendShiftHandoffResponse), nil } func (s *mockIncidentServer) CreateSubscription(ctx context.Context, req *irmpb.CreateSubscriptionRequest) (*irmpb.Subscription, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*irmpb.Subscription), nil } func (s *mockIncidentServer) UpdateSubscription(ctx context.Context, req *irmpb.UpdateSubscriptionRequest) (*irmpb.Subscription, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*irmpb.Subscription), nil } func (s *mockIncidentServer) ListSubscriptions(ctx context.Context, req *irmpb.ListSubscriptionsRequest) (*irmpb.ListSubscriptionsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*irmpb.ListSubscriptionsResponse), nil } func (s *mockIncidentServer) DeleteSubscription(ctx context.Context, req *irmpb.DeleteSubscriptionRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockIncidentServer) CreateIncidentRoleAssignment(ctx context.Context, req *irmpb.CreateIncidentRoleAssignmentRequest) (*irmpb.IncidentRoleAssignment, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*irmpb.IncidentRoleAssignment), nil } func (s *mockIncidentServer) DeleteIncidentRoleAssignment(ctx context.Context, req *irmpb.DeleteIncidentRoleAssignmentRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockIncidentServer) ListIncidentRoleAssignments(ctx context.Context, req *irmpb.ListIncidentRoleAssignmentsRequest) (*irmpb.ListIncidentRoleAssignmentsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*irmpb.ListIncidentRoleAssignmentsResponse), nil } func (s *mockIncidentServer) RequestIncidentRoleHandover(ctx context.Context, req *irmpb.RequestIncidentRoleHandoverRequest) (*irmpb.IncidentRoleAssignment, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*irmpb.IncidentRoleAssignment), nil } func (s *mockIncidentServer) ConfirmIncidentRoleHandover(ctx context.Context, req *irmpb.ConfirmIncidentRoleHandoverRequest) (*irmpb.IncidentRoleAssignment, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*irmpb.IncidentRoleAssignment), nil } func (s *mockIncidentServer) ForceIncidentRoleHandover(ctx context.Context, req *irmpb.ForceIncidentRoleHandoverRequest) (*irmpb.IncidentRoleAssignment, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*irmpb.IncidentRoleAssignment), nil } func (s *mockIncidentServer) CancelIncidentRoleHandover(ctx context.Context, req *irmpb.CancelIncidentRoleHandoverRequest) (*irmpb.IncidentRoleAssignment, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*irmpb.IncidentRoleAssignment), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockIncident mockIncidentServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() irmpb.RegisterIncidentServiceServer(serv, &mockIncident) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestIncidentServiceCreateIncident(t *testing.T) { var name string = "name3373707" var title string = "title110371416" var etag string = "etag3123477" var duplicateIncident string = "duplicateIncident-316496506" var expectedResponse = &irmpb.Incident{ Name: name, Title: title, Etag: etag, DuplicateIncident: duplicateIncident, } mockIncident.err = nil mockIncident.reqs = nil mockIncident.resps = append(mockIncident.resps[:0], expectedResponse) var incident *irmpb.Incident = &irmpb.Incident{} var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &irmpb.CreateIncidentRequest{ Incident: incident, Parent: formattedParent, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateIncident(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIncident.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIncidentServiceCreateIncidentError(t *testing.T) { errCode := codes.PermissionDenied mockIncident.err = gstatus.Error(errCode, "test error") var incident *irmpb.Incident = &irmpb.Incident{} var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &irmpb.CreateIncidentRequest{ Incident: incident, Parent: formattedParent, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateIncident(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIncidentServiceGetIncident(t *testing.T) { var name2 string = "name2-1052831874" var title string = "title110371416" var etag string = "etag3123477" var duplicateIncident string = "duplicateIncident-316496506" var expectedResponse = &irmpb.Incident{ Name: name2, Title: title, Etag: etag, DuplicateIncident: duplicateIncident, } mockIncident.err = nil mockIncident.reqs = nil mockIncident.resps = append(mockIncident.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]") var request = &irmpb.GetIncidentRequest{ Name: formattedName, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetIncident(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIncident.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIncidentServiceGetIncidentError(t *testing.T) { errCode := codes.PermissionDenied mockIncident.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]") var request = &irmpb.GetIncidentRequest{ Name: formattedName, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetIncident(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIncidentServiceSearchIncidents(t *testing.T) { var nextPageToken string = "" var incidentsElement *irmpb.Incident = &irmpb.Incident{} var incidents = []*irmpb.Incident{incidentsElement} var expectedResponse = &irmpb.SearchIncidentsResponse{ NextPageToken: nextPageToken, Incidents: incidents, } mockIncident.err = nil mockIncident.reqs = nil mockIncident.resps = append(mockIncident.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &irmpb.SearchIncidentsRequest{ Parent: formattedParent, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SearchIncidents(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockIncident.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Incidents[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIncidentServiceSearchIncidentsError(t *testing.T) { errCode := codes.PermissionDenied mockIncident.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &irmpb.SearchIncidentsRequest{ Parent: formattedParent, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SearchIncidents(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIncidentServiceUpdateIncident(t *testing.T) { var name string = "name3373707" var title string = "title110371416" var etag string = "etag3123477" var duplicateIncident string = "duplicateIncident-316496506" var expectedResponse = &irmpb.Incident{ Name: name, Title: title, Etag: etag, DuplicateIncident: duplicateIncident, } mockIncident.err = nil mockIncident.reqs = nil mockIncident.resps = append(mockIncident.resps[:0], expectedResponse) var incident *irmpb.Incident = &irmpb.Incident{} var request = &irmpb.UpdateIncidentRequest{ Incident: incident, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateIncident(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIncident.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIncidentServiceUpdateIncidentError(t *testing.T) { errCode := codes.PermissionDenied mockIncident.err = gstatus.Error(errCode, "test error") var incident *irmpb.Incident = &irmpb.Incident{} var request = &irmpb.UpdateIncidentRequest{ Incident: incident, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateIncident(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIncidentServiceSearchSimilarIncidents(t *testing.T) { var nextPageToken string = "" var resultsElement *irmpb.SearchSimilarIncidentsResponse_Result = &irmpb.SearchSimilarIncidentsResponse_Result{} var results = []*irmpb.SearchSimilarIncidentsResponse_Result{resultsElement} var expectedResponse = &irmpb.SearchSimilarIncidentsResponse{ NextPageToken: nextPageToken, Results: results, } mockIncident.err = nil mockIncident.reqs = nil mockIncident.resps = append(mockIncident.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]") var request = &irmpb.SearchSimilarIncidentsRequest{ Name: formattedName, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SearchSimilarIncidents(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockIncident.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Results[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIncidentServiceSearchSimilarIncidentsError(t *testing.T) { errCode := codes.PermissionDenied mockIncident.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]") var request = &irmpb.SearchSimilarIncidentsRequest{ Name: formattedName, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SearchSimilarIncidents(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIncidentServiceCreateAnnotation(t *testing.T) { var name string = "name3373707" var content string = "content951530617" var contentType string = "contentType831846208" var expectedResponse = &irmpb.Annotation{ Name: name, Content: content, ContentType: contentType, } mockIncident.err = nil mockIncident.reqs = nil mockIncident.resps = append(mockIncident.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]") var annotation *irmpb.Annotation = &irmpb.Annotation{} var request = &irmpb.CreateAnnotationRequest{ Parent: formattedParent, Annotation: annotation, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateAnnotation(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIncident.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIncidentServiceCreateAnnotationError(t *testing.T) { errCode := codes.PermissionDenied mockIncident.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]") var annotation *irmpb.Annotation = &irmpb.Annotation{} var request = &irmpb.CreateAnnotationRequest{ Parent: formattedParent, Annotation: annotation, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateAnnotation(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIncidentServiceListAnnotations(t *testing.T) { var nextPageToken string = "" var annotationsElement *irmpb.Annotation = &irmpb.Annotation{} var annotations = []*irmpb.Annotation{annotationsElement} var expectedResponse = &irmpb.ListAnnotationsResponse{ NextPageToken: nextPageToken, Annotations: annotations, } mockIncident.err = nil mockIncident.reqs = nil mockIncident.resps = append(mockIncident.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]") var request = &irmpb.ListAnnotationsRequest{ Parent: formattedParent, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListAnnotations(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockIncident.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Annotations[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIncidentServiceListAnnotationsError(t *testing.T) { errCode := codes.PermissionDenied mockIncident.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]") var request = &irmpb.ListAnnotationsRequest{ Parent: formattedParent, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListAnnotations(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIncidentServiceCreateTag(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var expectedResponse = &irmpb.Tag{ Name: name, DisplayName: displayName, } mockIncident.err = nil mockIncident.reqs = nil mockIncident.resps = append(mockIncident.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]") var tag *irmpb.Tag = &irmpb.Tag{} var request = &irmpb.CreateTagRequest{ Parent: formattedParent, Tag: tag, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateTag(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIncident.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIncidentServiceCreateTagError(t *testing.T) { errCode := codes.PermissionDenied mockIncident.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]") var tag *irmpb.Tag = &irmpb.Tag{} var request = &irmpb.CreateTagRequest{ Parent: formattedParent, Tag: tag, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateTag(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIncidentServiceDeleteTag(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockIncident.err = nil mockIncident.reqs = nil mockIncident.resps = append(mockIncident.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/incidents/%s/tags/%s", "[PROJECT]", "[INCIDENT]", "[TAG]") var request = &irmpb.DeleteTagRequest{ Name: formattedName, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteTag(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIncident.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestIncidentServiceDeleteTagError(t *testing.T) { errCode := codes.PermissionDenied mockIncident.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/incidents/%s/tags/%s", "[PROJECT]", "[INCIDENT]", "[TAG]") var request = &irmpb.DeleteTagRequest{ Name: formattedName, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteTag(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestIncidentServiceListTags(t *testing.T) { var nextPageToken string = "" var tagsElement *irmpb.Tag = &irmpb.Tag{} var tags = []*irmpb.Tag{tagsElement} var expectedResponse = &irmpb.ListTagsResponse{ NextPageToken: nextPageToken, Tags: tags, } mockIncident.err = nil mockIncident.reqs = nil mockIncident.resps = append(mockIncident.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]") var request = &irmpb.ListTagsRequest{ Parent: formattedParent, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListTags(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockIncident.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Tags[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIncidentServiceListTagsError(t *testing.T) { errCode := codes.PermissionDenied mockIncident.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]") var request = &irmpb.ListTagsRequest{ Parent: formattedParent, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListTags(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIncidentServiceCreateSignal(t *testing.T) { var name string = "name3373707" var etag string = "etag3123477" var incident string = "incident86983890" var title string = "title110371416" var contentType string = "contentType831846208" var content string = "content951530617" var expectedResponse = &irmpb.Signal{ Name: name, Etag: etag, Incident: incident, Title: title, ContentType: contentType, Content: content, } mockIncident.err = nil mockIncident.reqs = nil mockIncident.resps = append(mockIncident.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var signal *irmpb.Signal = &irmpb.Signal{} var request = &irmpb.CreateSignalRequest{ Parent: formattedParent, Signal: signal, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateSignal(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIncident.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIncidentServiceCreateSignalError(t *testing.T) { errCode := codes.PermissionDenied mockIncident.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var signal *irmpb.Signal = &irmpb.Signal{} var request = &irmpb.CreateSignalRequest{ Parent: formattedParent, Signal: signal, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateSignal(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIncidentServiceSearchSignals(t *testing.T) { var nextPageToken string = "" var signalsElement *irmpb.Signal = &irmpb.Signal{} var signals = []*irmpb.Signal{signalsElement} var expectedResponse = &irmpb.SearchSignalsResponse{ NextPageToken: nextPageToken, Signals: signals, } mockIncident.err = nil mockIncident.reqs = nil mockIncident.resps = append(mockIncident.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &irmpb.SearchSignalsRequest{ Parent: formattedParent, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SearchSignals(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockIncident.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Signals[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIncidentServiceSearchSignalsError(t *testing.T) { errCode := codes.PermissionDenied mockIncident.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &irmpb.SearchSignalsRequest{ Parent: formattedParent, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SearchSignals(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIncidentServiceGetSignal(t *testing.T) { var name2 string = "name2-1052831874" var etag string = "etag3123477" var incident string = "incident86983890" var title string = "title110371416" var contentType string = "contentType831846208" var content string = "content951530617" var expectedResponse = &irmpb.Signal{ Name: name2, Etag: etag, Incident: incident, Title: title, ContentType: contentType, Content: content, } mockIncident.err = nil mockIncident.reqs = nil mockIncident.resps = append(mockIncident.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/signals/%s", "[PROJECT]", "[SIGNAL]") var request = &irmpb.GetSignalRequest{ Name: formattedName, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetSignal(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIncident.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIncidentServiceGetSignalError(t *testing.T) { errCode := codes.PermissionDenied mockIncident.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/signals/%s", "[PROJECT]", "[SIGNAL]") var request = &irmpb.GetSignalRequest{ Name: formattedName, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetSignal(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIncidentServiceLookupSignal(t *testing.T) { var name string = "name3373707" var etag string = "etag3123477" var incident string = "incident86983890" var title string = "title110371416" var contentType string = "contentType831846208" var content string = "content951530617" var expectedResponse = &irmpb.Signal{ Name: name, Etag: etag, Incident: incident, Title: title, ContentType: contentType, Content: content, } mockIncident.err = nil mockIncident.reqs = nil mockIncident.resps = append(mockIncident.resps[:0], expectedResponse) var request *irmpb.LookupSignalRequest = &irmpb.LookupSignalRequest{} c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.LookupSignal(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIncident.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIncidentServiceLookupSignalError(t *testing.T) { errCode := codes.PermissionDenied mockIncident.err = gstatus.Error(errCode, "test error") var request *irmpb.LookupSignalRequest = &irmpb.LookupSignalRequest{} c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.LookupSignal(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIncidentServiceUpdateSignal(t *testing.T) { var name string = "name3373707" var etag string = "etag3123477" var incident string = "incident86983890" var title string = "title110371416" var contentType string = "contentType831846208" var content string = "content951530617" var expectedResponse = &irmpb.Signal{ Name: name, Etag: etag, Incident: incident, Title: title, ContentType: contentType, Content: content, } mockIncident.err = nil mockIncident.reqs = nil mockIncident.resps = append(mockIncident.resps[:0], expectedResponse) var signal *irmpb.Signal = &irmpb.Signal{} var request = &irmpb.UpdateSignalRequest{ Signal: signal, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateSignal(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIncident.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIncidentServiceUpdateSignalError(t *testing.T) { errCode := codes.PermissionDenied mockIncident.err = gstatus.Error(errCode, "test error") var signal *irmpb.Signal = &irmpb.Signal{} var request = &irmpb.UpdateSignalRequest{ Signal: signal, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateSignal(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIncidentServiceEscalateIncident(t *testing.T) { var expectedResponse *irmpb.EscalateIncidentResponse = &irmpb.EscalateIncidentResponse{} mockIncident.err = nil mockIncident.reqs = nil mockIncident.resps = append(mockIncident.resps[:0], expectedResponse) var incident *irmpb.Incident = &irmpb.Incident{} var request = &irmpb.EscalateIncidentRequest{ Incident: incident, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.EscalateIncident(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIncident.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIncidentServiceEscalateIncidentError(t *testing.T) { errCode := codes.PermissionDenied mockIncident.err = gstatus.Error(errCode, "test error") var incident *irmpb.Incident = &irmpb.Incident{} var request = &irmpb.EscalateIncidentRequest{ Incident: incident, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.EscalateIncident(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIncidentServiceCreateArtifact(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var etag string = "etag3123477" var url string = "url116079" var expectedResponse = &irmpb.Artifact{ Name: name, DisplayName: displayName, Etag: etag, Url: url, } mockIncident.err = nil mockIncident.reqs = nil mockIncident.resps = append(mockIncident.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]") var artifact *irmpb.Artifact = &irmpb.Artifact{} var request = &irmpb.CreateArtifactRequest{ Parent: formattedParent, Artifact: artifact, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateArtifact(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIncident.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIncidentServiceCreateArtifactError(t *testing.T) { errCode := codes.PermissionDenied mockIncident.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]") var artifact *irmpb.Artifact = &irmpb.Artifact{} var request = &irmpb.CreateArtifactRequest{ Parent: formattedParent, Artifact: artifact, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateArtifact(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIncidentServiceListArtifacts(t *testing.T) { var nextPageToken string = "" var artifactsElement *irmpb.Artifact = &irmpb.Artifact{} var artifacts = []*irmpb.Artifact{artifactsElement} var expectedResponse = &irmpb.ListArtifactsResponse{ NextPageToken: nextPageToken, Artifacts: artifacts, } mockIncident.err = nil mockIncident.reqs = nil mockIncident.resps = append(mockIncident.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]") var request = &irmpb.ListArtifactsRequest{ Parent: formattedParent, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListArtifacts(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockIncident.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Artifacts[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIncidentServiceListArtifactsError(t *testing.T) { errCode := codes.PermissionDenied mockIncident.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]") var request = &irmpb.ListArtifactsRequest{ Parent: formattedParent, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListArtifacts(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIncidentServiceUpdateArtifact(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var etag string = "etag3123477" var url string = "url116079" var expectedResponse = &irmpb.Artifact{ Name: name, DisplayName: displayName, Etag: etag, Url: url, } mockIncident.err = nil mockIncident.reqs = nil mockIncident.resps = append(mockIncident.resps[:0], expectedResponse) var artifact *irmpb.Artifact = &irmpb.Artifact{} var request = &irmpb.UpdateArtifactRequest{ Artifact: artifact, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateArtifact(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIncident.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIncidentServiceUpdateArtifactError(t *testing.T) { errCode := codes.PermissionDenied mockIncident.err = gstatus.Error(errCode, "test error") var artifact *irmpb.Artifact = &irmpb.Artifact{} var request = &irmpb.UpdateArtifactRequest{ Artifact: artifact, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateArtifact(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIncidentServiceDeleteArtifact(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockIncident.err = nil mockIncident.reqs = nil mockIncident.resps = append(mockIncident.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/incidents/%s/artifacts/%s", "[PROJECT]", "[INCIDENT]", "[ARTIFACT]") var request = &irmpb.DeleteArtifactRequest{ Name: formattedName, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteArtifact(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIncident.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestIncidentServiceDeleteArtifactError(t *testing.T) { errCode := codes.PermissionDenied mockIncident.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/incidents/%s/artifacts/%s", "[PROJECT]", "[INCIDENT]", "[ARTIFACT]") var request = &irmpb.DeleteArtifactRequest{ Name: formattedName, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteArtifact(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestIncidentServiceSendShiftHandoff(t *testing.T) { var contentType string = "contentType831846208" var content string = "content951530617" var expectedResponse = &irmpb.SendShiftHandoffResponse{ ContentType: contentType, Content: content, } mockIncident.err = nil mockIncident.reqs = nil mockIncident.resps = append(mockIncident.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var recipients []string = nil var subject string = "subject-1867885268" var request = &irmpb.SendShiftHandoffRequest{ Parent: formattedParent, Recipients: recipients, Subject: subject, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SendShiftHandoff(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIncident.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIncidentServiceSendShiftHandoffError(t *testing.T) { errCode := codes.PermissionDenied mockIncident.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var recipients []string = nil var subject string = "subject-1867885268" var request = &irmpb.SendShiftHandoffRequest{ Parent: formattedParent, Recipients: recipients, Subject: subject, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SendShiftHandoff(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIncidentServiceCreateSubscription(t *testing.T) { var name string = "name3373707" var etag string = "etag3123477" var expectedResponse = &irmpb.Subscription{ Name: name, Etag: etag, } mockIncident.err = nil mockIncident.reqs = nil mockIncident.resps = append(mockIncident.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]") var subscription *irmpb.Subscription = &irmpb.Subscription{} var request = &irmpb.CreateSubscriptionRequest{ Parent: formattedParent, Subscription: subscription, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateSubscription(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIncident.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIncidentServiceCreateSubscriptionError(t *testing.T) { errCode := codes.PermissionDenied mockIncident.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]") var subscription *irmpb.Subscription = &irmpb.Subscription{} var request = &irmpb.CreateSubscriptionRequest{ Parent: formattedParent, Subscription: subscription, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateSubscription(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIncidentServiceUpdateSubscription(t *testing.T) { var name string = "name3373707" var etag string = "etag3123477" var expectedResponse = &irmpb.Subscription{ Name: name, Etag: etag, } mockIncident.err = nil mockIncident.reqs = nil mockIncident.resps = append(mockIncident.resps[:0], expectedResponse) var subscription *irmpb.Subscription = &irmpb.Subscription{} var request = &irmpb.UpdateSubscriptionRequest{ Subscription: subscription, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateSubscription(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIncident.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIncidentServiceUpdateSubscriptionError(t *testing.T) { errCode := codes.PermissionDenied mockIncident.err = gstatus.Error(errCode, "test error") var subscription *irmpb.Subscription = &irmpb.Subscription{} var request = &irmpb.UpdateSubscriptionRequest{ Subscription: subscription, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateSubscription(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIncidentServiceListSubscriptions(t *testing.T) { var nextPageToken string = "" var subscriptionsElement *irmpb.Subscription = &irmpb.Subscription{} var subscriptions = []*irmpb.Subscription{subscriptionsElement} var expectedResponse = &irmpb.ListSubscriptionsResponse{ NextPageToken: nextPageToken, Subscriptions: subscriptions, } mockIncident.err = nil mockIncident.reqs = nil mockIncident.resps = append(mockIncident.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]") var request = &irmpb.ListSubscriptionsRequest{ Parent: formattedParent, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListSubscriptions(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockIncident.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Subscriptions[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIncidentServiceListSubscriptionsError(t *testing.T) { errCode := codes.PermissionDenied mockIncident.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]") var request = &irmpb.ListSubscriptionsRequest{ Parent: formattedParent, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListSubscriptions(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIncidentServiceDeleteSubscription(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockIncident.err = nil mockIncident.reqs = nil mockIncident.resps = append(mockIncident.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/incidents/%s/subscriptions/%s", "[PROJECT]", "[INCIDENT]", "[SUBSCRIPTION]") var request = &irmpb.DeleteSubscriptionRequest{ Name: formattedName, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteSubscription(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIncident.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestIncidentServiceDeleteSubscriptionError(t *testing.T) { errCode := codes.PermissionDenied mockIncident.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/incidents/%s/subscriptions/%s", "[PROJECT]", "[INCIDENT]", "[SUBSCRIPTION]") var request = &irmpb.DeleteSubscriptionRequest{ Name: formattedName, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteSubscription(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestIncidentServiceCreateIncidentRoleAssignment(t *testing.T) { var name string = "name3373707" var etag string = "etag3123477" var expectedResponse = &irmpb.IncidentRoleAssignment{ Name: name, Etag: etag, } mockIncident.err = nil mockIncident.reqs = nil mockIncident.resps = append(mockIncident.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]") var incidentRoleAssignment *irmpb.IncidentRoleAssignment = &irmpb.IncidentRoleAssignment{} var request = &irmpb.CreateIncidentRoleAssignmentRequest{ Parent: formattedParent, IncidentRoleAssignment: incidentRoleAssignment, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateIncidentRoleAssignment(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIncident.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIncidentServiceCreateIncidentRoleAssignmentError(t *testing.T) { errCode := codes.PermissionDenied mockIncident.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]") var incidentRoleAssignment *irmpb.IncidentRoleAssignment = &irmpb.IncidentRoleAssignment{} var request = &irmpb.CreateIncidentRoleAssignmentRequest{ Parent: formattedParent, IncidentRoleAssignment: incidentRoleAssignment, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateIncidentRoleAssignment(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIncidentServiceDeleteIncidentRoleAssignment(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockIncident.err = nil mockIncident.reqs = nil mockIncident.resps = append(mockIncident.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/incidents/%s/roleAssignments/%s", "[PROJECT]", "[INCIDENT]", "[ROLE_ASSIGNMENT]") var request = &irmpb.DeleteIncidentRoleAssignmentRequest{ Name: formattedName, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteIncidentRoleAssignment(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIncident.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestIncidentServiceDeleteIncidentRoleAssignmentError(t *testing.T) { errCode := codes.PermissionDenied mockIncident.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/incidents/%s/roleAssignments/%s", "[PROJECT]", "[INCIDENT]", "[ROLE_ASSIGNMENT]") var request = &irmpb.DeleteIncidentRoleAssignmentRequest{ Name: formattedName, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteIncidentRoleAssignment(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestIncidentServiceListIncidentRoleAssignments(t *testing.T) { var nextPageToken string = "" var incidentRoleAssignmentsElement *irmpb.IncidentRoleAssignment = &irmpb.IncidentRoleAssignment{} var incidentRoleAssignments = []*irmpb.IncidentRoleAssignment{incidentRoleAssignmentsElement} var expectedResponse = &irmpb.ListIncidentRoleAssignmentsResponse{ NextPageToken: nextPageToken, IncidentRoleAssignments: incidentRoleAssignments, } mockIncident.err = nil mockIncident.reqs = nil mockIncident.resps = append(mockIncident.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]") var request = &irmpb.ListIncidentRoleAssignmentsRequest{ Parent: formattedParent, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListIncidentRoleAssignments(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockIncident.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.IncidentRoleAssignments[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIncidentServiceListIncidentRoleAssignmentsError(t *testing.T) { errCode := codes.PermissionDenied mockIncident.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]") var request = &irmpb.ListIncidentRoleAssignmentsRequest{ Parent: formattedParent, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListIncidentRoleAssignments(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIncidentServiceRequestIncidentRoleHandover(t *testing.T) { var name2 string = "name2-1052831874" var etag string = "etag3123477" var expectedResponse = &irmpb.IncidentRoleAssignment{ Name: name2, Etag: etag, } mockIncident.err = nil mockIncident.reqs = nil mockIncident.resps = append(mockIncident.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/incidents/%s/roleAssignments/%s", "[PROJECT]", "[INCIDENT]", "[ROLE_ASSIGNMENT]") var newAssignee *irmpb.User = &irmpb.User{} var request = &irmpb.RequestIncidentRoleHandoverRequest{ Name: formattedName, NewAssignee: newAssignee, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.RequestIncidentRoleHandover(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIncident.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIncidentServiceRequestIncidentRoleHandoverError(t *testing.T) { errCode := codes.PermissionDenied mockIncident.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/incidents/%s/roleAssignments/%s", "[PROJECT]", "[INCIDENT]", "[ROLE_ASSIGNMENT]") var newAssignee *irmpb.User = &irmpb.User{} var request = &irmpb.RequestIncidentRoleHandoverRequest{ Name: formattedName, NewAssignee: newAssignee, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.RequestIncidentRoleHandover(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIncidentServiceConfirmIncidentRoleHandover(t *testing.T) { var name2 string = "name2-1052831874" var etag string = "etag3123477" var expectedResponse = &irmpb.IncidentRoleAssignment{ Name: name2, Etag: etag, } mockIncident.err = nil mockIncident.reqs = nil mockIncident.resps = append(mockIncident.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/incidents/%s/roleAssignments/%s", "[PROJECT]", "[INCIDENT]", "[ROLE_ASSIGNMENT]") var newAssignee *irmpb.User = &irmpb.User{} var request = &irmpb.ConfirmIncidentRoleHandoverRequest{ Name: formattedName, NewAssignee: newAssignee, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ConfirmIncidentRoleHandover(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIncident.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIncidentServiceConfirmIncidentRoleHandoverError(t *testing.T) { errCode := codes.PermissionDenied mockIncident.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/incidents/%s/roleAssignments/%s", "[PROJECT]", "[INCIDENT]", "[ROLE_ASSIGNMENT]") var newAssignee *irmpb.User = &irmpb.User{} var request = &irmpb.ConfirmIncidentRoleHandoverRequest{ Name: formattedName, NewAssignee: newAssignee, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ConfirmIncidentRoleHandover(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIncidentServiceForceIncidentRoleHandover(t *testing.T) { var name2 string = "name2-1052831874" var etag string = "etag3123477" var expectedResponse = &irmpb.IncidentRoleAssignment{ Name: name2, Etag: etag, } mockIncident.err = nil mockIncident.reqs = nil mockIncident.resps = append(mockIncident.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/incidents/%s/roleAssignments/%s", "[PROJECT]", "[INCIDENT]", "[ROLE_ASSIGNMENT]") var newAssignee *irmpb.User = &irmpb.User{} var request = &irmpb.ForceIncidentRoleHandoverRequest{ Name: formattedName, NewAssignee: newAssignee, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ForceIncidentRoleHandover(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIncident.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIncidentServiceForceIncidentRoleHandoverError(t *testing.T) { errCode := codes.PermissionDenied mockIncident.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/incidents/%s/roleAssignments/%s", "[PROJECT]", "[INCIDENT]", "[ROLE_ASSIGNMENT]") var newAssignee *irmpb.User = &irmpb.User{} var request = &irmpb.ForceIncidentRoleHandoverRequest{ Name: formattedName, NewAssignee: newAssignee, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ForceIncidentRoleHandover(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestIncidentServiceCancelIncidentRoleHandover(t *testing.T) { var name2 string = "name2-1052831874" var etag string = "etag3123477" var expectedResponse = &irmpb.IncidentRoleAssignment{ Name: name2, Etag: etag, } mockIncident.err = nil mockIncident.reqs = nil mockIncident.resps = append(mockIncident.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/incidents/%s/roleAssignments/%s", "[PROJECT]", "[INCIDENT]", "[ROLE_ASSIGNMENT]") var newAssignee *irmpb.User = &irmpb.User{} var request = &irmpb.CancelIncidentRoleHandoverRequest{ Name: formattedName, NewAssignee: newAssignee, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CancelIncidentRoleHandover(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockIncident.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestIncidentServiceCancelIncidentRoleHandoverError(t *testing.T) { errCode := codes.PermissionDenied mockIncident.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/incidents/%s/roleAssignments/%s", "[PROJECT]", "[INCIDENT]", "[ROLE_ASSIGNMENT]") var newAssignee *irmpb.User = &irmpb.User{} var request = &irmpb.CancelIncidentRoleHandoverRequest{ Name: formattedName, NewAssignee: newAssignee, } c, err := NewIncidentClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CancelIncidentRoleHandover(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/issue_template.md000066400000000000000000000003451356504100700201370ustar00rootroot00000000000000(delete this for feature requests) ## Client e.g. PubSub ## Describe Your Environment e.g. Alpine Docker on GKE ## Expected Behavior e.g. Messages arrive really fast. ## Actual Behavior e.g. Messages arrive really slowly.google-cloud-go-0.49.0/kms/000077500000000000000000000000001356504100700153625ustar00rootroot00000000000000google-cloud-go-0.49.0/kms/apiv1/000077500000000000000000000000001356504100700164025ustar00rootroot00000000000000google-cloud-go-0.49.0/kms/apiv1/.repo-metadata.json000066400000000000000000000006411356504100700220770ustar00rootroot00000000000000{ "name": "kms", "name_pretty": "Cloud Key Management Service API", "product_documentation": "https://cloud.google.com/kms", "client_documentation": "https://godoc.org/cloud.google.com/go/kms/apiv1", "release_level": "ga", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go/kms/apiv1", "api_id": "cloudkms.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/kms/apiv1/doc.go000066400000000000000000000054061356504100700175030ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package kms is an auto-generated package for the // Cloud Key Management Service (KMS) API. // // Manages keys and performs cryptographic operations in a central cloud // service, for direct use by other cloud resources and applications. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package kms // import "cloud.google.com/go/kms/apiv1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/cloudkms", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191115" google-cloud-go-0.49.0/kms/apiv1/iam.go000066400000000000000000000030531356504100700175000ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package kms import ( "cloud.google.com/go/iam" kmspb "google.golang.org/genproto/googleapis/cloud/kms/v1" ) // KeyRingIAM returns a handle to inspect and change permissions of a KeyRing. // // Deprecated: Please use ResourceIAM and provide the KeyRing.Name as input. func (c *KeyManagementClient) KeyRingIAM(keyRing *kmspb.KeyRing) *iam.Handle { return iam.InternalNewHandle(c.Connection(), keyRing.Name) } // CryptoKeyIAM returns a handle to inspect and change permissions of a CryptoKey. // // Deprecated: Please use ResourceIAM and provide the CryptoKey.Name as input. func (c *KeyManagementClient) CryptoKeyIAM(cryptoKey *kmspb.CryptoKey) *iam.Handle { return iam.InternalNewHandle(c.Connection(), cryptoKey.Name) } // ResourceIAM returns a handle to inspect and change permissions of the resource // indicated by the given resource path. func (c *KeyManagementClient) ResourceIAM(resourcePath string) *iam.Handle { return iam.InternalNewHandle(c.Connection(), resourcePath) } google-cloud-go-0.49.0/kms/apiv1/iam_example_test.go000066400000000000000000000021171356504100700222520ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package kms_test import ( "context" kms "cloud.google.com/go/kms/apiv1" ) func ExampleKeyManagementClient_ResourceIAM() { ctx := context.Background() c, err := kms.NewKeyManagementClient(ctx) if err != nil { // TODO: Handle error. } // TODO: fill in key ring resource path keyRing := "projects/[PROJECT_ID]/locations/[LOCATION]/keyRings/[KEY_RING]" handle := c.ResourceIAM(keyRing) policy, err := handle.Policy(ctx) if err != nil { // TODO: Handle error. } // TODO: Use policy. _ = policy } google-cloud-go-0.49.0/kms/apiv1/integration_test.go000066400000000000000000000024521356504100700223160ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package kms_test import ( "context" "fmt" "log" "testing" "cloud.google.com/go/internal/testutil" kms "cloud.google.com/go/kms/apiv1" "google.golang.org/api/iterator" kmspb "google.golang.org/genproto/googleapis/cloud/kms/v1" ) func TestIntegration(t *testing.T) { if testing.Short() { t.Skip("skipping integration test in short mode") } ctx := context.Background() projectID := testutil.ProjID() c, err := kms.NewKeyManagementClient(ctx) if err != nil { panic(err) } it := c.ListKeyRings(ctx, &kmspb.ListKeyRingsRequest{ Parent: fmt.Sprintf("projects/%s/locations/global", projectID), }) for { _, err := it.Next() if err == iterator.Done { break } if err != nil { log.Fatal(err) } } } google-cloud-go-0.49.0/kms/apiv1/key_management_client.go000066400000000000000000001141631356504100700232610ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package kms import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" kmspb "google.golang.org/genproto/googleapis/cloud/kms/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // KeyManagementCallOptions contains the retry settings for each method of KeyManagementClient. type KeyManagementCallOptions struct { ListKeyRings []gax.CallOption ListImportJobs []gax.CallOption ListCryptoKeys []gax.CallOption ListCryptoKeyVersions []gax.CallOption GetKeyRing []gax.CallOption GetImportJob []gax.CallOption GetCryptoKey []gax.CallOption GetCryptoKeyVersion []gax.CallOption CreateKeyRing []gax.CallOption CreateImportJob []gax.CallOption CreateCryptoKey []gax.CallOption CreateCryptoKeyVersion []gax.CallOption ImportCryptoKeyVersion []gax.CallOption UpdateCryptoKey []gax.CallOption UpdateCryptoKeyVersion []gax.CallOption Encrypt []gax.CallOption Decrypt []gax.CallOption UpdateCryptoKeyPrimaryVersion []gax.CallOption DestroyCryptoKeyVersion []gax.CallOption RestoreCryptoKeyVersion []gax.CallOption GetPublicKey []gax.CallOption AsymmetricDecrypt []gax.CallOption AsymmetricSign []gax.CallOption } func defaultKeyManagementClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("cloudkms.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultKeyManagementCallOptions() *KeyManagementCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "retryable"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Internal, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &KeyManagementCallOptions{ ListKeyRings: retry[[2]string{"default", "retryable"}], ListImportJobs: retry[[2]string{"default", "retryable"}], ListCryptoKeys: retry[[2]string{"default", "retryable"}], ListCryptoKeyVersions: retry[[2]string{"default", "retryable"}], GetKeyRing: retry[[2]string{"default", "retryable"}], GetImportJob: retry[[2]string{"default", "retryable"}], GetCryptoKey: retry[[2]string{"default", "retryable"}], GetCryptoKeyVersion: retry[[2]string{"default", "retryable"}], CreateKeyRing: retry[[2]string{"default", "retryable"}], CreateImportJob: retry[[2]string{"default", "retryable"}], CreateCryptoKey: retry[[2]string{"default", "retryable"}], CreateCryptoKeyVersion: retry[[2]string{"default", "non_retryable"}], ImportCryptoKeyVersion: retry[[2]string{"default", "non_retryable"}], UpdateCryptoKey: retry[[2]string{"default", "retryable"}], UpdateCryptoKeyVersion: retry[[2]string{"default", "retryable"}], Encrypt: retry[[2]string{"default", "retryable"}], Decrypt: retry[[2]string{"default", "retryable"}], UpdateCryptoKeyPrimaryVersion: retry[[2]string{"default", "retryable"}], DestroyCryptoKeyVersion: retry[[2]string{"default", "retryable"}], RestoreCryptoKeyVersion: retry[[2]string{"default", "retryable"}], GetPublicKey: retry[[2]string{"default", "retryable"}], AsymmetricDecrypt: retry[[2]string{"default", "retryable"}], AsymmetricSign: retry[[2]string{"default", "retryable"}], } } // KeyManagementClient is a client for interacting with Cloud Key Management Service (KMS) API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type KeyManagementClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. keyManagementClient kmspb.KeyManagementServiceClient // The call options for this service. CallOptions *KeyManagementCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewKeyManagementClient creates a new key management service client. // // Google Cloud Key Management Service // // Manages cryptographic keys and operations using those keys. Implements a REST // model with the following objects: // // [KeyRing][google.cloud.kms.v1.KeyRing] // // [CryptoKey][google.cloud.kms.v1.CryptoKey] // // [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion] // // If you are using manual gRPC libraries, see // Using gRPC with Cloud KMS (at https://cloud.google.com/kms/docs/grpc). func NewKeyManagementClient(ctx context.Context, opts ...option.ClientOption) (*KeyManagementClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultKeyManagementClientOptions(), opts...)...) if err != nil { return nil, err } c := &KeyManagementClient{ conn: conn, CallOptions: defaultKeyManagementCallOptions(), keyManagementClient: kmspb.NewKeyManagementServiceClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *KeyManagementClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *KeyManagementClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *KeyManagementClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // ListKeyRings lists [KeyRings][google.cloud.kms.v1.KeyRing]. func (c *KeyManagementClient) ListKeyRings(ctx context.Context, req *kmspb.ListKeyRingsRequest, opts ...gax.CallOption) *KeyRingIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListKeyRings[0:len(c.CallOptions.ListKeyRings):len(c.CallOptions.ListKeyRings)], opts...) it := &KeyRingIterator{} req = proto.Clone(req).(*kmspb.ListKeyRingsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*kmspb.KeyRing, string, error) { var resp *kmspb.ListKeyRingsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.keyManagementClient.ListKeyRings(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.KeyRings, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // ListImportJobs lists [ImportJobs][google.cloud.kms.v1.ImportJob]. func (c *KeyManagementClient) ListImportJobs(ctx context.Context, req *kmspb.ListImportJobsRequest, opts ...gax.CallOption) *ImportJobIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListImportJobs[0:len(c.CallOptions.ListImportJobs):len(c.CallOptions.ListImportJobs)], opts...) it := &ImportJobIterator{} req = proto.Clone(req).(*kmspb.ListImportJobsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*kmspb.ImportJob, string, error) { var resp *kmspb.ListImportJobsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.keyManagementClient.ListImportJobs(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.ImportJobs, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // ListCryptoKeys lists [CryptoKeys][google.cloud.kms.v1.CryptoKey]. func (c *KeyManagementClient) ListCryptoKeys(ctx context.Context, req *kmspb.ListCryptoKeysRequest, opts ...gax.CallOption) *CryptoKeyIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListCryptoKeys[0:len(c.CallOptions.ListCryptoKeys):len(c.CallOptions.ListCryptoKeys)], opts...) it := &CryptoKeyIterator{} req = proto.Clone(req).(*kmspb.ListCryptoKeysRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*kmspb.CryptoKey, string, error) { var resp *kmspb.ListCryptoKeysResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.keyManagementClient.ListCryptoKeys(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.CryptoKeys, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // ListCryptoKeyVersions lists [CryptoKeyVersions][google.cloud.kms.v1.CryptoKeyVersion]. func (c *KeyManagementClient) ListCryptoKeyVersions(ctx context.Context, req *kmspb.ListCryptoKeyVersionsRequest, opts ...gax.CallOption) *CryptoKeyVersionIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListCryptoKeyVersions[0:len(c.CallOptions.ListCryptoKeyVersions):len(c.CallOptions.ListCryptoKeyVersions)], opts...) it := &CryptoKeyVersionIterator{} req = proto.Clone(req).(*kmspb.ListCryptoKeyVersionsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*kmspb.CryptoKeyVersion, string, error) { var resp *kmspb.ListCryptoKeyVersionsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.keyManagementClient.ListCryptoKeyVersions(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.CryptoKeyVersions, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetKeyRing returns metadata for a given [KeyRing][google.cloud.kms.v1.KeyRing]. func (c *KeyManagementClient) GetKeyRing(ctx context.Context, req *kmspb.GetKeyRingRequest, opts ...gax.CallOption) (*kmspb.KeyRing, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetKeyRing[0:len(c.CallOptions.GetKeyRing):len(c.CallOptions.GetKeyRing)], opts...) var resp *kmspb.KeyRing err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.keyManagementClient.GetKeyRing(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetImportJob returns metadata for a given [ImportJob][google.cloud.kms.v1.ImportJob]. func (c *KeyManagementClient) GetImportJob(ctx context.Context, req *kmspb.GetImportJobRequest, opts ...gax.CallOption) (*kmspb.ImportJob, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetImportJob[0:len(c.CallOptions.GetImportJob):len(c.CallOptions.GetImportJob)], opts...) var resp *kmspb.ImportJob err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.keyManagementClient.GetImportJob(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetCryptoKey returns metadata for a given [CryptoKey][google.cloud.kms.v1.CryptoKey], as well as its // [primary][google.cloud.kms.v1.CryptoKey.primary] [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion]. func (c *KeyManagementClient) GetCryptoKey(ctx context.Context, req *kmspb.GetCryptoKeyRequest, opts ...gax.CallOption) (*kmspb.CryptoKey, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetCryptoKey[0:len(c.CallOptions.GetCryptoKey):len(c.CallOptions.GetCryptoKey)], opts...) var resp *kmspb.CryptoKey err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.keyManagementClient.GetCryptoKey(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetCryptoKeyVersion returns metadata for a given [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion]. func (c *KeyManagementClient) GetCryptoKeyVersion(ctx context.Context, req *kmspb.GetCryptoKeyVersionRequest, opts ...gax.CallOption) (*kmspb.CryptoKeyVersion, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetCryptoKeyVersion[0:len(c.CallOptions.GetCryptoKeyVersion):len(c.CallOptions.GetCryptoKeyVersion)], opts...) var resp *kmspb.CryptoKeyVersion err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.keyManagementClient.GetCryptoKeyVersion(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateKeyRing create a new [KeyRing][google.cloud.kms.v1.KeyRing] in a given Project and Location. func (c *KeyManagementClient) CreateKeyRing(ctx context.Context, req *kmspb.CreateKeyRingRequest, opts ...gax.CallOption) (*kmspb.KeyRing, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateKeyRing[0:len(c.CallOptions.CreateKeyRing):len(c.CallOptions.CreateKeyRing)], opts...) var resp *kmspb.KeyRing err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.keyManagementClient.CreateKeyRing(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateImportJob create a new [ImportJob][google.cloud.kms.v1.ImportJob] within a [KeyRing][google.cloud.kms.v1.KeyRing]. // // [ImportJob.import_method][google.cloud.kms.v1.ImportJob.import_method] is required. func (c *KeyManagementClient) CreateImportJob(ctx context.Context, req *kmspb.CreateImportJobRequest, opts ...gax.CallOption) (*kmspb.ImportJob, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateImportJob[0:len(c.CallOptions.CreateImportJob):len(c.CallOptions.CreateImportJob)], opts...) var resp *kmspb.ImportJob err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.keyManagementClient.CreateImportJob(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateCryptoKey create a new [CryptoKey][google.cloud.kms.v1.CryptoKey] within a [KeyRing][google.cloud.kms.v1.KeyRing]. // // [CryptoKey.purpose][google.cloud.kms.v1.CryptoKey.purpose] and // [CryptoKey.version_template.algorithm][google.cloud.kms.v1.CryptoKeyVersionTemplate.algorithm] // are required. func (c *KeyManagementClient) CreateCryptoKey(ctx context.Context, req *kmspb.CreateCryptoKeyRequest, opts ...gax.CallOption) (*kmspb.CryptoKey, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateCryptoKey[0:len(c.CallOptions.CreateCryptoKey):len(c.CallOptions.CreateCryptoKey)], opts...) var resp *kmspb.CryptoKey err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.keyManagementClient.CreateCryptoKey(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateCryptoKeyVersion create a new [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion] in a [CryptoKey][google.cloud.kms.v1.CryptoKey]. // // The server will assign the next sequential id. If unset, // [state][google.cloud.kms.v1.CryptoKeyVersion.state] will be set to // [ENABLED][google.cloud.kms.v1.CryptoKeyVersion.CryptoKeyVersionState.ENABLED]. func (c *KeyManagementClient) CreateCryptoKeyVersion(ctx context.Context, req *kmspb.CreateCryptoKeyVersionRequest, opts ...gax.CallOption) (*kmspb.CryptoKeyVersion, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateCryptoKeyVersion[0:len(c.CallOptions.CreateCryptoKeyVersion):len(c.CallOptions.CreateCryptoKeyVersion)], opts...) var resp *kmspb.CryptoKeyVersion err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.keyManagementClient.CreateCryptoKeyVersion(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ImportCryptoKeyVersion imports a new [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion] into an existing [CryptoKey][google.cloud.kms.v1.CryptoKey] using the // wrapped key material provided in the request. // // The version ID will be assigned the next sequential id within the // [CryptoKey][google.cloud.kms.v1.CryptoKey]. func (c *KeyManagementClient) ImportCryptoKeyVersion(ctx context.Context, req *kmspb.ImportCryptoKeyVersionRequest, opts ...gax.CallOption) (*kmspb.CryptoKeyVersion, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ImportCryptoKeyVersion[0:len(c.CallOptions.ImportCryptoKeyVersion):len(c.CallOptions.ImportCryptoKeyVersion)], opts...) var resp *kmspb.CryptoKeyVersion err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.keyManagementClient.ImportCryptoKeyVersion(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateCryptoKey update a [CryptoKey][google.cloud.kms.v1.CryptoKey]. func (c *KeyManagementClient) UpdateCryptoKey(ctx context.Context, req *kmspb.UpdateCryptoKeyRequest, opts ...gax.CallOption) (*kmspb.CryptoKey, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "crypto_key.name", url.QueryEscape(req.GetCryptoKey().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateCryptoKey[0:len(c.CallOptions.UpdateCryptoKey):len(c.CallOptions.UpdateCryptoKey)], opts...) var resp *kmspb.CryptoKey err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.keyManagementClient.UpdateCryptoKey(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateCryptoKeyVersion update a [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion]'s metadata. // // [state][google.cloud.kms.v1.CryptoKeyVersion.state] may be changed between // [ENABLED][google.cloud.kms.v1.CryptoKeyVersion.CryptoKeyVersionState.ENABLED] and // [DISABLED][google.cloud.kms.v1.CryptoKeyVersion.CryptoKeyVersionState.DISABLED] using this // method. See [DestroyCryptoKeyVersion][google.cloud.kms.v1.KeyManagementService.DestroyCryptoKeyVersion] and [RestoreCryptoKeyVersion][google.cloud.kms.v1.KeyManagementService.RestoreCryptoKeyVersion] to // move between other states. func (c *KeyManagementClient) UpdateCryptoKeyVersion(ctx context.Context, req *kmspb.UpdateCryptoKeyVersionRequest, opts ...gax.CallOption) (*kmspb.CryptoKeyVersion, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "crypto_key_version.name", url.QueryEscape(req.GetCryptoKeyVersion().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateCryptoKeyVersion[0:len(c.CallOptions.UpdateCryptoKeyVersion):len(c.CallOptions.UpdateCryptoKeyVersion)], opts...) var resp *kmspb.CryptoKeyVersion err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.keyManagementClient.UpdateCryptoKeyVersion(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // Encrypt encrypts data, so that it can only be recovered by a call to [Decrypt][google.cloud.kms.v1.KeyManagementService.Decrypt]. // The [CryptoKey.purpose][google.cloud.kms.v1.CryptoKey.purpose] must be // [ENCRYPT_DECRYPT][google.cloud.kms.v1.CryptoKey.CryptoKeyPurpose.ENCRYPT_DECRYPT]. func (c *KeyManagementClient) Encrypt(ctx context.Context, req *kmspb.EncryptRequest, opts ...gax.CallOption) (*kmspb.EncryptResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.Encrypt[0:len(c.CallOptions.Encrypt):len(c.CallOptions.Encrypt)], opts...) var resp *kmspb.EncryptResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.keyManagementClient.Encrypt(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // Decrypt decrypts data that was protected by [Encrypt][google.cloud.kms.v1.KeyManagementService.Encrypt]. The [CryptoKey.purpose][google.cloud.kms.v1.CryptoKey.purpose] // must be [ENCRYPT_DECRYPT][google.cloud.kms.v1.CryptoKey.CryptoKeyPurpose.ENCRYPT_DECRYPT]. func (c *KeyManagementClient) Decrypt(ctx context.Context, req *kmspb.DecryptRequest, opts ...gax.CallOption) (*kmspb.DecryptResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.Decrypt[0:len(c.CallOptions.Decrypt):len(c.CallOptions.Decrypt)], opts...) var resp *kmspb.DecryptResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.keyManagementClient.Decrypt(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateCryptoKeyPrimaryVersion update the version of a [CryptoKey][google.cloud.kms.v1.CryptoKey] that will be used in [Encrypt][google.cloud.kms.v1.KeyManagementService.Encrypt]. // // Returns an error if called on an asymmetric key. func (c *KeyManagementClient) UpdateCryptoKeyPrimaryVersion(ctx context.Context, req *kmspb.UpdateCryptoKeyPrimaryVersionRequest, opts ...gax.CallOption) (*kmspb.CryptoKey, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateCryptoKeyPrimaryVersion[0:len(c.CallOptions.UpdateCryptoKeyPrimaryVersion):len(c.CallOptions.UpdateCryptoKeyPrimaryVersion)], opts...) var resp *kmspb.CryptoKey err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.keyManagementClient.UpdateCryptoKeyPrimaryVersion(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DestroyCryptoKeyVersion schedule a [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion] for destruction. // // Upon calling this method, [CryptoKeyVersion.state][google.cloud.kms.v1.CryptoKeyVersion.state] will be set to // [DESTROY_SCHEDULED][google.cloud.kms.v1.CryptoKeyVersion.CryptoKeyVersionState.DESTROY_SCHEDULED] // and [destroy_time][google.cloud.kms.v1.CryptoKeyVersion.destroy_time] will be set to a time 24 // hours in the future, at which point the [state][google.cloud.kms.v1.CryptoKeyVersion.state] // will be changed to // [DESTROYED][google.cloud.kms.v1.CryptoKeyVersion.CryptoKeyVersionState.DESTROYED], and the key // material will be irrevocably destroyed. // // Before the [destroy_time][google.cloud.kms.v1.CryptoKeyVersion.destroy_time] is reached, // [RestoreCryptoKeyVersion][google.cloud.kms.v1.KeyManagementService.RestoreCryptoKeyVersion] may be called to reverse the process. func (c *KeyManagementClient) DestroyCryptoKeyVersion(ctx context.Context, req *kmspb.DestroyCryptoKeyVersionRequest, opts ...gax.CallOption) (*kmspb.CryptoKeyVersion, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DestroyCryptoKeyVersion[0:len(c.CallOptions.DestroyCryptoKeyVersion):len(c.CallOptions.DestroyCryptoKeyVersion)], opts...) var resp *kmspb.CryptoKeyVersion err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.keyManagementClient.DestroyCryptoKeyVersion(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // RestoreCryptoKeyVersion restore a [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion] in the // [DESTROY_SCHEDULED][google.cloud.kms.v1.CryptoKeyVersion.CryptoKeyVersionState.DESTROY_SCHEDULED] // state. // // Upon restoration of the CryptoKeyVersion, [state][google.cloud.kms.v1.CryptoKeyVersion.state] // will be set to [DISABLED][google.cloud.kms.v1.CryptoKeyVersion.CryptoKeyVersionState.DISABLED], // and [destroy_time][google.cloud.kms.v1.CryptoKeyVersion.destroy_time] will be cleared. func (c *KeyManagementClient) RestoreCryptoKeyVersion(ctx context.Context, req *kmspb.RestoreCryptoKeyVersionRequest, opts ...gax.CallOption) (*kmspb.CryptoKeyVersion, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.RestoreCryptoKeyVersion[0:len(c.CallOptions.RestoreCryptoKeyVersion):len(c.CallOptions.RestoreCryptoKeyVersion)], opts...) var resp *kmspb.CryptoKeyVersion err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.keyManagementClient.RestoreCryptoKeyVersion(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetPublicKey returns the public key for the given [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion]. The // [CryptoKey.purpose][google.cloud.kms.v1.CryptoKey.purpose] must be // [ASYMMETRIC_SIGN][google.cloud.kms.v1.CryptoKey.CryptoKeyPurpose.ASYMMETRIC_SIGN] or // [ASYMMETRIC_DECRYPT][google.cloud.kms.v1.CryptoKey.CryptoKeyPurpose.ASYMMETRIC_DECRYPT]. func (c *KeyManagementClient) GetPublicKey(ctx context.Context, req *kmspb.GetPublicKeyRequest, opts ...gax.CallOption) (*kmspb.PublicKey, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetPublicKey[0:len(c.CallOptions.GetPublicKey):len(c.CallOptions.GetPublicKey)], opts...) var resp *kmspb.PublicKey err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.keyManagementClient.GetPublicKey(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // AsymmetricDecrypt decrypts data that was encrypted with a public key retrieved from // [GetPublicKey][google.cloud.kms.v1.KeyManagementService.GetPublicKey] corresponding to a [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion] with // [CryptoKey.purpose][google.cloud.kms.v1.CryptoKey.purpose] ASYMMETRIC_DECRYPT. func (c *KeyManagementClient) AsymmetricDecrypt(ctx context.Context, req *kmspb.AsymmetricDecryptRequest, opts ...gax.CallOption) (*kmspb.AsymmetricDecryptResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.AsymmetricDecrypt[0:len(c.CallOptions.AsymmetricDecrypt):len(c.CallOptions.AsymmetricDecrypt)], opts...) var resp *kmspb.AsymmetricDecryptResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.keyManagementClient.AsymmetricDecrypt(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // AsymmetricSign signs data using a [CryptoKeyVersion][google.cloud.kms.v1.CryptoKeyVersion] with [CryptoKey.purpose][google.cloud.kms.v1.CryptoKey.purpose] // ASYMMETRIC_SIGN, producing a signature that can be verified with the public // key retrieved from [GetPublicKey][google.cloud.kms.v1.KeyManagementService.GetPublicKey]. func (c *KeyManagementClient) AsymmetricSign(ctx context.Context, req *kmspb.AsymmetricSignRequest, opts ...gax.CallOption) (*kmspb.AsymmetricSignResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.AsymmetricSign[0:len(c.CallOptions.AsymmetricSign):len(c.CallOptions.AsymmetricSign)], opts...) var resp *kmspb.AsymmetricSignResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.keyManagementClient.AsymmetricSign(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CryptoKeyIterator manages a stream of *kmspb.CryptoKey. type CryptoKeyIterator struct { items []*kmspb.CryptoKey pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*kmspb.CryptoKey, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *CryptoKeyIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *CryptoKeyIterator) Next() (*kmspb.CryptoKey, error) { var item *kmspb.CryptoKey if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *CryptoKeyIterator) bufLen() int { return len(it.items) } func (it *CryptoKeyIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // CryptoKeyVersionIterator manages a stream of *kmspb.CryptoKeyVersion. type CryptoKeyVersionIterator struct { items []*kmspb.CryptoKeyVersion pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*kmspb.CryptoKeyVersion, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *CryptoKeyVersionIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *CryptoKeyVersionIterator) Next() (*kmspb.CryptoKeyVersion, error) { var item *kmspb.CryptoKeyVersion if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *CryptoKeyVersionIterator) bufLen() int { return len(it.items) } func (it *CryptoKeyVersionIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // ImportJobIterator manages a stream of *kmspb.ImportJob. type ImportJobIterator struct { items []*kmspb.ImportJob pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*kmspb.ImportJob, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *ImportJobIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *ImportJobIterator) Next() (*kmspb.ImportJob, error) { var item *kmspb.ImportJob if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *ImportJobIterator) bufLen() int { return len(it.items) } func (it *ImportJobIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // KeyRingIterator manages a stream of *kmspb.KeyRing. type KeyRingIterator struct { items []*kmspb.KeyRing pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*kmspb.KeyRing, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *KeyRingIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *KeyRingIterator) Next() (*kmspb.KeyRing, error) { var item *kmspb.KeyRing if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *KeyRingIterator) bufLen() int { return len(it.items) } func (it *KeyRingIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/kms/apiv1/key_management_client_example_test.go000066400000000000000000000232611356504100700260310ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package kms_test import ( "context" kms "cloud.google.com/go/kms/apiv1" "google.golang.org/api/iterator" kmspb "google.golang.org/genproto/googleapis/cloud/kms/v1" ) func ExampleNewKeyManagementClient() { ctx := context.Background() c, err := kms.NewKeyManagementClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleKeyManagementClient_ListKeyRings() { ctx := context.Background() c, err := kms.NewKeyManagementClient(ctx) if err != nil { // TODO: Handle error. } req := &kmspb.ListKeyRingsRequest{ // TODO: Fill request struct fields. } it := c.ListKeyRings(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleKeyManagementClient_ListImportJobs() { ctx := context.Background() c, err := kms.NewKeyManagementClient(ctx) if err != nil { // TODO: Handle error. } req := &kmspb.ListImportJobsRequest{ // TODO: Fill request struct fields. } it := c.ListImportJobs(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleKeyManagementClient_ListCryptoKeys() { ctx := context.Background() c, err := kms.NewKeyManagementClient(ctx) if err != nil { // TODO: Handle error. } req := &kmspb.ListCryptoKeysRequest{ // TODO: Fill request struct fields. } it := c.ListCryptoKeys(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleKeyManagementClient_ListCryptoKeyVersions() { ctx := context.Background() c, err := kms.NewKeyManagementClient(ctx) if err != nil { // TODO: Handle error. } req := &kmspb.ListCryptoKeyVersionsRequest{ // TODO: Fill request struct fields. } it := c.ListCryptoKeyVersions(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleKeyManagementClient_GetKeyRing() { ctx := context.Background() c, err := kms.NewKeyManagementClient(ctx) if err != nil { // TODO: Handle error. } req := &kmspb.GetKeyRingRequest{ // TODO: Fill request struct fields. } resp, err := c.GetKeyRing(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleKeyManagementClient_GetImportJob() { ctx := context.Background() c, err := kms.NewKeyManagementClient(ctx) if err != nil { // TODO: Handle error. } req := &kmspb.GetImportJobRequest{ // TODO: Fill request struct fields. } resp, err := c.GetImportJob(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleKeyManagementClient_GetCryptoKey() { ctx := context.Background() c, err := kms.NewKeyManagementClient(ctx) if err != nil { // TODO: Handle error. } req := &kmspb.GetCryptoKeyRequest{ // TODO: Fill request struct fields. } resp, err := c.GetCryptoKey(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleKeyManagementClient_GetCryptoKeyVersion() { ctx := context.Background() c, err := kms.NewKeyManagementClient(ctx) if err != nil { // TODO: Handle error. } req := &kmspb.GetCryptoKeyVersionRequest{ // TODO: Fill request struct fields. } resp, err := c.GetCryptoKeyVersion(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleKeyManagementClient_CreateKeyRing() { ctx := context.Background() c, err := kms.NewKeyManagementClient(ctx) if err != nil { // TODO: Handle error. } req := &kmspb.CreateKeyRingRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateKeyRing(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleKeyManagementClient_CreateImportJob() { ctx := context.Background() c, err := kms.NewKeyManagementClient(ctx) if err != nil { // TODO: Handle error. } req := &kmspb.CreateImportJobRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateImportJob(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleKeyManagementClient_CreateCryptoKey() { ctx := context.Background() c, err := kms.NewKeyManagementClient(ctx) if err != nil { // TODO: Handle error. } req := &kmspb.CreateCryptoKeyRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateCryptoKey(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleKeyManagementClient_CreateCryptoKeyVersion() { ctx := context.Background() c, err := kms.NewKeyManagementClient(ctx) if err != nil { // TODO: Handle error. } req := &kmspb.CreateCryptoKeyVersionRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateCryptoKeyVersion(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleKeyManagementClient_ImportCryptoKeyVersion() { ctx := context.Background() c, err := kms.NewKeyManagementClient(ctx) if err != nil { // TODO: Handle error. } req := &kmspb.ImportCryptoKeyVersionRequest{ // TODO: Fill request struct fields. } resp, err := c.ImportCryptoKeyVersion(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleKeyManagementClient_UpdateCryptoKey() { ctx := context.Background() c, err := kms.NewKeyManagementClient(ctx) if err != nil { // TODO: Handle error. } req := &kmspb.UpdateCryptoKeyRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateCryptoKey(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleKeyManagementClient_UpdateCryptoKeyVersion() { ctx := context.Background() c, err := kms.NewKeyManagementClient(ctx) if err != nil { // TODO: Handle error. } req := &kmspb.UpdateCryptoKeyVersionRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateCryptoKeyVersion(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleKeyManagementClient_Encrypt() { ctx := context.Background() c, err := kms.NewKeyManagementClient(ctx) if err != nil { // TODO: Handle error. } req := &kmspb.EncryptRequest{ // TODO: Fill request struct fields. } resp, err := c.Encrypt(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleKeyManagementClient_Decrypt() { ctx := context.Background() c, err := kms.NewKeyManagementClient(ctx) if err != nil { // TODO: Handle error. } req := &kmspb.DecryptRequest{ // TODO: Fill request struct fields. } resp, err := c.Decrypt(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleKeyManagementClient_UpdateCryptoKeyPrimaryVersion() { ctx := context.Background() c, err := kms.NewKeyManagementClient(ctx) if err != nil { // TODO: Handle error. } req := &kmspb.UpdateCryptoKeyPrimaryVersionRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateCryptoKeyPrimaryVersion(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleKeyManagementClient_DestroyCryptoKeyVersion() { ctx := context.Background() c, err := kms.NewKeyManagementClient(ctx) if err != nil { // TODO: Handle error. } req := &kmspb.DestroyCryptoKeyVersionRequest{ // TODO: Fill request struct fields. } resp, err := c.DestroyCryptoKeyVersion(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleKeyManagementClient_RestoreCryptoKeyVersion() { ctx := context.Background() c, err := kms.NewKeyManagementClient(ctx) if err != nil { // TODO: Handle error. } req := &kmspb.RestoreCryptoKeyVersionRequest{ // TODO: Fill request struct fields. } resp, err := c.RestoreCryptoKeyVersion(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleKeyManagementClient_GetPublicKey() { ctx := context.Background() c, err := kms.NewKeyManagementClient(ctx) if err != nil { // TODO: Handle error. } req := &kmspb.GetPublicKeyRequest{ // TODO: Fill request struct fields. } resp, err := c.GetPublicKey(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleKeyManagementClient_AsymmetricDecrypt() { ctx := context.Background() c, err := kms.NewKeyManagementClient(ctx) if err != nil { // TODO: Handle error. } req := &kmspb.AsymmetricDecryptRequest{ // TODO: Fill request struct fields. } resp, err := c.AsymmetricDecrypt(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleKeyManagementClient_AsymmetricSign() { ctx := context.Background() c, err := kms.NewKeyManagementClient(ctx) if err != nil { // TODO: Handle error. } req := &kmspb.AsymmetricSignRequest{ // TODO: Fill request struct fields. } resp, err := c.AsymmetricSign(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/kms/apiv1/mock_test.go000066400000000000000000001662531356504100700207360ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package kms import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" durationpb "github.com/golang/protobuf/ptypes/duration" timestamppb "github.com/golang/protobuf/ptypes/timestamp" "google.golang.org/api/option" kmspb "google.golang.org/genproto/googleapis/cloud/kms/v1" field_maskpb "google.golang.org/genproto/protobuf/field_mask" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockKeyManagementServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. kmspb.KeyManagementServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockKeyManagementServer) ListKeyRings(ctx context.Context, req *kmspb.ListKeyRingsRequest) (*kmspb.ListKeyRingsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*kmspb.ListKeyRingsResponse), nil } func (s *mockKeyManagementServer) ListCryptoKeys(ctx context.Context, req *kmspb.ListCryptoKeysRequest) (*kmspb.ListCryptoKeysResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*kmspb.ListCryptoKeysResponse), nil } func (s *mockKeyManagementServer) ListCryptoKeyVersions(ctx context.Context, req *kmspb.ListCryptoKeyVersionsRequest) (*kmspb.ListCryptoKeyVersionsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*kmspb.ListCryptoKeyVersionsResponse), nil } func (s *mockKeyManagementServer) ListImportJobs(ctx context.Context, req *kmspb.ListImportJobsRequest) (*kmspb.ListImportJobsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*kmspb.ListImportJobsResponse), nil } func (s *mockKeyManagementServer) GetKeyRing(ctx context.Context, req *kmspb.GetKeyRingRequest) (*kmspb.KeyRing, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*kmspb.KeyRing), nil } func (s *mockKeyManagementServer) GetCryptoKey(ctx context.Context, req *kmspb.GetCryptoKeyRequest) (*kmspb.CryptoKey, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*kmspb.CryptoKey), nil } func (s *mockKeyManagementServer) GetCryptoKeyVersion(ctx context.Context, req *kmspb.GetCryptoKeyVersionRequest) (*kmspb.CryptoKeyVersion, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*kmspb.CryptoKeyVersion), nil } func (s *mockKeyManagementServer) GetPublicKey(ctx context.Context, req *kmspb.GetPublicKeyRequest) (*kmspb.PublicKey, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*kmspb.PublicKey), nil } func (s *mockKeyManagementServer) GetImportJob(ctx context.Context, req *kmspb.GetImportJobRequest) (*kmspb.ImportJob, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*kmspb.ImportJob), nil } func (s *mockKeyManagementServer) CreateKeyRing(ctx context.Context, req *kmspb.CreateKeyRingRequest) (*kmspb.KeyRing, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*kmspb.KeyRing), nil } func (s *mockKeyManagementServer) CreateCryptoKey(ctx context.Context, req *kmspb.CreateCryptoKeyRequest) (*kmspb.CryptoKey, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*kmspb.CryptoKey), nil } func (s *mockKeyManagementServer) CreateCryptoKeyVersion(ctx context.Context, req *kmspb.CreateCryptoKeyVersionRequest) (*kmspb.CryptoKeyVersion, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*kmspb.CryptoKeyVersion), nil } func (s *mockKeyManagementServer) ImportCryptoKeyVersion(ctx context.Context, req *kmspb.ImportCryptoKeyVersionRequest) (*kmspb.CryptoKeyVersion, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*kmspb.CryptoKeyVersion), nil } func (s *mockKeyManagementServer) CreateImportJob(ctx context.Context, req *kmspb.CreateImportJobRequest) (*kmspb.ImportJob, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*kmspb.ImportJob), nil } func (s *mockKeyManagementServer) UpdateCryptoKey(ctx context.Context, req *kmspb.UpdateCryptoKeyRequest) (*kmspb.CryptoKey, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*kmspb.CryptoKey), nil } func (s *mockKeyManagementServer) UpdateCryptoKeyVersion(ctx context.Context, req *kmspb.UpdateCryptoKeyVersionRequest) (*kmspb.CryptoKeyVersion, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*kmspb.CryptoKeyVersion), nil } func (s *mockKeyManagementServer) Encrypt(ctx context.Context, req *kmspb.EncryptRequest) (*kmspb.EncryptResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*kmspb.EncryptResponse), nil } func (s *mockKeyManagementServer) Decrypt(ctx context.Context, req *kmspb.DecryptRequest) (*kmspb.DecryptResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*kmspb.DecryptResponse), nil } func (s *mockKeyManagementServer) AsymmetricSign(ctx context.Context, req *kmspb.AsymmetricSignRequest) (*kmspb.AsymmetricSignResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*kmspb.AsymmetricSignResponse), nil } func (s *mockKeyManagementServer) AsymmetricDecrypt(ctx context.Context, req *kmspb.AsymmetricDecryptRequest) (*kmspb.AsymmetricDecryptResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*kmspb.AsymmetricDecryptResponse), nil } func (s *mockKeyManagementServer) UpdateCryptoKeyPrimaryVersion(ctx context.Context, req *kmspb.UpdateCryptoKeyPrimaryVersionRequest) (*kmspb.CryptoKey, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*kmspb.CryptoKey), nil } func (s *mockKeyManagementServer) DestroyCryptoKeyVersion(ctx context.Context, req *kmspb.DestroyCryptoKeyVersionRequest) (*kmspb.CryptoKeyVersion, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*kmspb.CryptoKeyVersion), nil } func (s *mockKeyManagementServer) RestoreCryptoKeyVersion(ctx context.Context, req *kmspb.RestoreCryptoKeyVersionRequest) (*kmspb.CryptoKeyVersion, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*kmspb.CryptoKeyVersion), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockKeyManagement mockKeyManagementServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() kmspb.RegisterKeyManagementServiceServer(serv, &mockKeyManagement) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestKeyManagementServiceListKeyRings(t *testing.T) { var nextPageToken string = "" var totalSize int32 = 705419236 var keyRingsElement *kmspb.KeyRing = &kmspb.KeyRing{} var keyRings = []*kmspb.KeyRing{keyRingsElement} var expectedResponse = &kmspb.ListKeyRingsResponse{ NextPageToken: nextPageToken, TotalSize: totalSize, KeyRings: keyRings, } mockKeyManagement.err = nil mockKeyManagement.reqs = nil mockKeyManagement.resps = append(mockKeyManagement.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &kmspb.ListKeyRingsRequest{ Parent: formattedParent, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListKeyRings(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockKeyManagement.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.KeyRings[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestKeyManagementServiceListKeyRingsError(t *testing.T) { errCode := codes.PermissionDenied mockKeyManagement.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &kmspb.ListKeyRingsRequest{ Parent: formattedParent, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListKeyRings(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestKeyManagementServiceListImportJobs(t *testing.T) { var nextPageToken string = "" var totalSize int32 = 705419236 var importJobsElement *kmspb.ImportJob = &kmspb.ImportJob{} var importJobs = []*kmspb.ImportJob{importJobsElement} var expectedResponse = &kmspb.ListImportJobsResponse{ NextPageToken: nextPageToken, TotalSize: totalSize, ImportJobs: importJobs, } mockKeyManagement.err = nil mockKeyManagement.reqs = nil mockKeyManagement.resps = append(mockKeyManagement.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]") var request = &kmspb.ListImportJobsRequest{ Parent: formattedParent, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListImportJobs(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockKeyManagement.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.ImportJobs[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestKeyManagementServiceListImportJobsError(t *testing.T) { errCode := codes.PermissionDenied mockKeyManagement.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]") var request = &kmspb.ListImportJobsRequest{ Parent: formattedParent, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListImportJobs(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestKeyManagementServiceListCryptoKeys(t *testing.T) { var nextPageToken string = "" var totalSize int32 = 705419236 var cryptoKeysElement *kmspb.CryptoKey = &kmspb.CryptoKey{} var cryptoKeys = []*kmspb.CryptoKey{cryptoKeysElement} var expectedResponse = &kmspb.ListCryptoKeysResponse{ NextPageToken: nextPageToken, TotalSize: totalSize, CryptoKeys: cryptoKeys, } mockKeyManagement.err = nil mockKeyManagement.reqs = nil mockKeyManagement.resps = append(mockKeyManagement.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]") var request = &kmspb.ListCryptoKeysRequest{ Parent: formattedParent, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListCryptoKeys(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockKeyManagement.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.CryptoKeys[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestKeyManagementServiceListCryptoKeysError(t *testing.T) { errCode := codes.PermissionDenied mockKeyManagement.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]") var request = &kmspb.ListCryptoKeysRequest{ Parent: formattedParent, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListCryptoKeys(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestKeyManagementServiceListCryptoKeyVersions(t *testing.T) { var nextPageToken string = "" var totalSize int32 = 705419236 var cryptoKeyVersionsElement *kmspb.CryptoKeyVersion = &kmspb.CryptoKeyVersion{} var cryptoKeyVersions = []*kmspb.CryptoKeyVersion{cryptoKeyVersionsElement} var expectedResponse = &kmspb.ListCryptoKeyVersionsResponse{ NextPageToken: nextPageToken, TotalSize: totalSize, CryptoKeyVersions: cryptoKeyVersions, } mockKeyManagement.err = nil mockKeyManagement.reqs = nil mockKeyManagement.resps = append(mockKeyManagement.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]", "[CRYPTO_KEY]") var request = &kmspb.ListCryptoKeyVersionsRequest{ Parent: formattedParent, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListCryptoKeyVersions(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockKeyManagement.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.CryptoKeyVersions[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestKeyManagementServiceListCryptoKeyVersionsError(t *testing.T) { errCode := codes.PermissionDenied mockKeyManagement.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]", "[CRYPTO_KEY]") var request = &kmspb.ListCryptoKeyVersionsRequest{ Parent: formattedParent, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListCryptoKeyVersions(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestKeyManagementServiceGetKeyRing(t *testing.T) { var name2 string = "name2-1052831874" var expectedResponse = &kmspb.KeyRing{ Name: name2, } mockKeyManagement.err = nil mockKeyManagement.reqs = nil mockKeyManagement.resps = append(mockKeyManagement.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]") var request = &kmspb.GetKeyRingRequest{ Name: formattedName, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetKeyRing(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockKeyManagement.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestKeyManagementServiceGetKeyRingError(t *testing.T) { errCode := codes.PermissionDenied mockKeyManagement.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]") var request = &kmspb.GetKeyRingRequest{ Name: formattedName, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetKeyRing(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestKeyManagementServiceGetImportJob(t *testing.T) { var name2 string = "name2-1052831874" var expectedResponse = &kmspb.ImportJob{ Name: name2, } mockKeyManagement.err = nil mockKeyManagement.reqs = nil mockKeyManagement.resps = append(mockKeyManagement.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/importJobs/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]", "[IMPORT_JOB]") var request = &kmspb.GetImportJobRequest{ Name: formattedName, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetImportJob(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockKeyManagement.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestKeyManagementServiceGetImportJobError(t *testing.T) { errCode := codes.PermissionDenied mockKeyManagement.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/importJobs/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]", "[IMPORT_JOB]") var request = &kmspb.GetImportJobRequest{ Name: formattedName, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetImportJob(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestKeyManagementServiceGetCryptoKey(t *testing.T) { var name2 string = "name2-1052831874" var expectedResponse = &kmspb.CryptoKey{ Name: name2, } mockKeyManagement.err = nil mockKeyManagement.reqs = nil mockKeyManagement.resps = append(mockKeyManagement.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]", "[CRYPTO_KEY]") var request = &kmspb.GetCryptoKeyRequest{ Name: formattedName, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetCryptoKey(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockKeyManagement.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestKeyManagementServiceGetCryptoKeyError(t *testing.T) { errCode := codes.PermissionDenied mockKeyManagement.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]", "[CRYPTO_KEY]") var request = &kmspb.GetCryptoKeyRequest{ Name: formattedName, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetCryptoKey(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestKeyManagementServiceGetCryptoKeyVersion(t *testing.T) { var name2 string = "name2-1052831874" var importJob string = "importJob2125587491" var importFailureReason string = "importFailureReason-494073229" var expectedResponse = &kmspb.CryptoKeyVersion{ Name: name2, ImportJob: importJob, ImportFailureReason: importFailureReason, } mockKeyManagement.err = nil mockKeyManagement.reqs = nil mockKeyManagement.resps = append(mockKeyManagement.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s/cryptoKeyVersions/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]", "[CRYPTO_KEY]", "[CRYPTO_KEY_VERSION]") var request = &kmspb.GetCryptoKeyVersionRequest{ Name: formattedName, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetCryptoKeyVersion(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockKeyManagement.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestKeyManagementServiceGetCryptoKeyVersionError(t *testing.T) { errCode := codes.PermissionDenied mockKeyManagement.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s/cryptoKeyVersions/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]", "[CRYPTO_KEY]", "[CRYPTO_KEY_VERSION]") var request = &kmspb.GetCryptoKeyVersionRequest{ Name: formattedName, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetCryptoKeyVersion(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestKeyManagementServiceCreateKeyRing(t *testing.T) { var name string = "name3373707" var expectedResponse = &kmspb.KeyRing{ Name: name, } mockKeyManagement.err = nil mockKeyManagement.reqs = nil mockKeyManagement.resps = append(mockKeyManagement.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var keyRingId string = "keyRingId-2056646742" var keyRing *kmspb.KeyRing = &kmspb.KeyRing{} var request = &kmspb.CreateKeyRingRequest{ Parent: formattedParent, KeyRingId: keyRingId, KeyRing: keyRing, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateKeyRing(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockKeyManagement.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestKeyManagementServiceCreateKeyRingError(t *testing.T) { errCode := codes.PermissionDenied mockKeyManagement.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var keyRingId string = "keyRingId-2056646742" var keyRing *kmspb.KeyRing = &kmspb.KeyRing{} var request = &kmspb.CreateKeyRingRequest{ Parent: formattedParent, KeyRingId: keyRingId, KeyRing: keyRing, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateKeyRing(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestKeyManagementServiceCreateImportJob(t *testing.T) { var name string = "name3373707" var expectedResponse = &kmspb.ImportJob{ Name: name, } mockKeyManagement.err = nil mockKeyManagement.reqs = nil mockKeyManagement.resps = append(mockKeyManagement.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]") var importJobId string = "my-import-job" var importMethod kmspb.ImportJob_ImportMethod = kmspb.ImportJob_RSA_OAEP_3072_SHA1_AES_256 var protectionLevel kmspb.ProtectionLevel = kmspb.ProtectionLevel_HSM var importJob = &kmspb.ImportJob{ ImportMethod: importMethod, ProtectionLevel: protectionLevel, } var request = &kmspb.CreateImportJobRequest{ Parent: formattedParent, ImportJobId: importJobId, ImportJob: importJob, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateImportJob(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockKeyManagement.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestKeyManagementServiceCreateImportJobError(t *testing.T) { errCode := codes.PermissionDenied mockKeyManagement.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]") var importJobId string = "my-import-job" var importMethod kmspb.ImportJob_ImportMethod = kmspb.ImportJob_RSA_OAEP_3072_SHA1_AES_256 var protectionLevel kmspb.ProtectionLevel = kmspb.ProtectionLevel_HSM var importJob = &kmspb.ImportJob{ ImportMethod: importMethod, ProtectionLevel: protectionLevel, } var request = &kmspb.CreateImportJobRequest{ Parent: formattedParent, ImportJobId: importJobId, ImportJob: importJob, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateImportJob(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestKeyManagementServiceCreateCryptoKey(t *testing.T) { var name string = "name3373707" var expectedResponse = &kmspb.CryptoKey{ Name: name, } mockKeyManagement.err = nil mockKeyManagement.reqs = nil mockKeyManagement.resps = append(mockKeyManagement.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]") var cryptoKeyId string = "my-app-key" var purpose kmspb.CryptoKey_CryptoKeyPurpose = kmspb.CryptoKey_ENCRYPT_DECRYPT var seconds int64 = 2147483647 var nextRotationTime = ×tamppb.Timestamp{ Seconds: seconds, } var seconds2 int64 = 604800 var rotationPeriod = &durationpb.Duration{ Seconds: seconds2, } var cryptoKey = &kmspb.CryptoKey{ Purpose: purpose, NextRotationTime: nextRotationTime, RotationSchedule: &kmspb.CryptoKey_RotationPeriod{ RotationPeriod: rotationPeriod, }, } var request = &kmspb.CreateCryptoKeyRequest{ Parent: formattedParent, CryptoKeyId: cryptoKeyId, CryptoKey: cryptoKey, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateCryptoKey(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockKeyManagement.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestKeyManagementServiceCreateCryptoKeyError(t *testing.T) { errCode := codes.PermissionDenied mockKeyManagement.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]") var cryptoKeyId string = "my-app-key" var purpose kmspb.CryptoKey_CryptoKeyPurpose = kmspb.CryptoKey_ENCRYPT_DECRYPT var seconds int64 = 2147483647 var nextRotationTime = ×tamppb.Timestamp{ Seconds: seconds, } var seconds2 int64 = 604800 var rotationPeriod = &durationpb.Duration{ Seconds: seconds2, } var cryptoKey = &kmspb.CryptoKey{ Purpose: purpose, NextRotationTime: nextRotationTime, RotationSchedule: &kmspb.CryptoKey_RotationPeriod{ RotationPeriod: rotationPeriod, }, } var request = &kmspb.CreateCryptoKeyRequest{ Parent: formattedParent, CryptoKeyId: cryptoKeyId, CryptoKey: cryptoKey, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateCryptoKey(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestKeyManagementServiceCreateCryptoKeyVersion(t *testing.T) { var name string = "name3373707" var importJob string = "importJob2125587491" var importFailureReason string = "importFailureReason-494073229" var expectedResponse = &kmspb.CryptoKeyVersion{ Name: name, ImportJob: importJob, ImportFailureReason: importFailureReason, } mockKeyManagement.err = nil mockKeyManagement.reqs = nil mockKeyManagement.resps = append(mockKeyManagement.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]", "[CRYPTO_KEY]") var cryptoKeyVersion *kmspb.CryptoKeyVersion = &kmspb.CryptoKeyVersion{} var request = &kmspb.CreateCryptoKeyVersionRequest{ Parent: formattedParent, CryptoKeyVersion: cryptoKeyVersion, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateCryptoKeyVersion(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockKeyManagement.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestKeyManagementServiceCreateCryptoKeyVersionError(t *testing.T) { errCode := codes.PermissionDenied mockKeyManagement.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]", "[CRYPTO_KEY]") var cryptoKeyVersion *kmspb.CryptoKeyVersion = &kmspb.CryptoKeyVersion{} var request = &kmspb.CreateCryptoKeyVersionRequest{ Parent: formattedParent, CryptoKeyVersion: cryptoKeyVersion, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateCryptoKeyVersion(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestKeyManagementServiceImportCryptoKeyVersion(t *testing.T) { var name string = "name3373707" var importJob2 string = "importJob2-1714851050" var importFailureReason string = "importFailureReason-494073229" var expectedResponse = &kmspb.CryptoKeyVersion{ Name: name, ImportJob: importJob2, ImportFailureReason: importFailureReason, } mockKeyManagement.err = nil mockKeyManagement.reqs = nil mockKeyManagement.resps = append(mockKeyManagement.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]", "[CRYPTO_KEY]") var algorithm kmspb.CryptoKeyVersion_CryptoKeyVersionAlgorithm = kmspb.CryptoKeyVersion_CRYPTO_KEY_VERSION_ALGORITHM_UNSPECIFIED var importJob string = "importJob2125587491" var request = &kmspb.ImportCryptoKeyVersionRequest{ Parent: formattedParent, Algorithm: algorithm, ImportJob: importJob, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ImportCryptoKeyVersion(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockKeyManagement.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestKeyManagementServiceImportCryptoKeyVersionError(t *testing.T) { errCode := codes.PermissionDenied mockKeyManagement.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]", "[CRYPTO_KEY]") var algorithm kmspb.CryptoKeyVersion_CryptoKeyVersionAlgorithm = kmspb.CryptoKeyVersion_CRYPTO_KEY_VERSION_ALGORITHM_UNSPECIFIED var importJob string = "importJob2125587491" var request = &kmspb.ImportCryptoKeyVersionRequest{ Parent: formattedParent, Algorithm: algorithm, ImportJob: importJob, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ImportCryptoKeyVersion(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestKeyManagementServiceUpdateCryptoKey(t *testing.T) { var name string = "name3373707" var expectedResponse = &kmspb.CryptoKey{ Name: name, } mockKeyManagement.err = nil mockKeyManagement.reqs = nil mockKeyManagement.resps = append(mockKeyManagement.resps[:0], expectedResponse) var cryptoKey *kmspb.CryptoKey = &kmspb.CryptoKey{} var updateMask *field_maskpb.FieldMask = &field_maskpb.FieldMask{} var request = &kmspb.UpdateCryptoKeyRequest{ CryptoKey: cryptoKey, UpdateMask: updateMask, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateCryptoKey(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockKeyManagement.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestKeyManagementServiceUpdateCryptoKeyError(t *testing.T) { errCode := codes.PermissionDenied mockKeyManagement.err = gstatus.Error(errCode, "test error") var cryptoKey *kmspb.CryptoKey = &kmspb.CryptoKey{} var updateMask *field_maskpb.FieldMask = &field_maskpb.FieldMask{} var request = &kmspb.UpdateCryptoKeyRequest{ CryptoKey: cryptoKey, UpdateMask: updateMask, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateCryptoKey(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestKeyManagementServiceUpdateCryptoKeyVersion(t *testing.T) { var name string = "name3373707" var importJob string = "importJob2125587491" var importFailureReason string = "importFailureReason-494073229" var expectedResponse = &kmspb.CryptoKeyVersion{ Name: name, ImportJob: importJob, ImportFailureReason: importFailureReason, } mockKeyManagement.err = nil mockKeyManagement.reqs = nil mockKeyManagement.resps = append(mockKeyManagement.resps[:0], expectedResponse) var cryptoKeyVersion *kmspb.CryptoKeyVersion = &kmspb.CryptoKeyVersion{} var updateMask *field_maskpb.FieldMask = &field_maskpb.FieldMask{} var request = &kmspb.UpdateCryptoKeyVersionRequest{ CryptoKeyVersion: cryptoKeyVersion, UpdateMask: updateMask, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateCryptoKeyVersion(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockKeyManagement.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestKeyManagementServiceUpdateCryptoKeyVersionError(t *testing.T) { errCode := codes.PermissionDenied mockKeyManagement.err = gstatus.Error(errCode, "test error") var cryptoKeyVersion *kmspb.CryptoKeyVersion = &kmspb.CryptoKeyVersion{} var updateMask *field_maskpb.FieldMask = &field_maskpb.FieldMask{} var request = &kmspb.UpdateCryptoKeyVersionRequest{ CryptoKeyVersion: cryptoKeyVersion, UpdateMask: updateMask, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateCryptoKeyVersion(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestKeyManagementServiceEncrypt(t *testing.T) { var name2 string = "name2-1052831874" var ciphertext []byte = []byte("-72") var expectedResponse = &kmspb.EncryptResponse{ Name: name2, Ciphertext: ciphertext, } mockKeyManagement.err = nil mockKeyManagement.reqs = nil mockKeyManagement.resps = append(mockKeyManagement.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]", "[CRYPTO_KEY_PATH]") var plaintext []byte = []byte("-9") var request = &kmspb.EncryptRequest{ Name: formattedName, Plaintext: plaintext, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Encrypt(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockKeyManagement.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestKeyManagementServiceEncryptError(t *testing.T) { errCode := codes.PermissionDenied mockKeyManagement.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]", "[CRYPTO_KEY_PATH]") var plaintext []byte = []byte("-9") var request = &kmspb.EncryptRequest{ Name: formattedName, Plaintext: plaintext, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Encrypt(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestKeyManagementServiceDecrypt(t *testing.T) { var plaintext []byte = []byte("-9") var expectedResponse = &kmspb.DecryptResponse{ Plaintext: plaintext, } mockKeyManagement.err = nil mockKeyManagement.reqs = nil mockKeyManagement.resps = append(mockKeyManagement.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]", "[CRYPTO_KEY]") var ciphertext []byte = []byte("-72") var request = &kmspb.DecryptRequest{ Name: formattedName, Ciphertext: ciphertext, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Decrypt(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockKeyManagement.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestKeyManagementServiceDecryptError(t *testing.T) { errCode := codes.PermissionDenied mockKeyManagement.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]", "[CRYPTO_KEY]") var ciphertext []byte = []byte("-72") var request = &kmspb.DecryptRequest{ Name: formattedName, Ciphertext: ciphertext, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Decrypt(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestKeyManagementServiceUpdateCryptoKeyPrimaryVersion(t *testing.T) { var name2 string = "name2-1052831874" var expectedResponse = &kmspb.CryptoKey{ Name: name2, } mockKeyManagement.err = nil mockKeyManagement.reqs = nil mockKeyManagement.resps = append(mockKeyManagement.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]", "[CRYPTO_KEY]") var cryptoKeyVersionId string = "cryptoKeyVersionId729489152" var request = &kmspb.UpdateCryptoKeyPrimaryVersionRequest{ Name: formattedName, CryptoKeyVersionId: cryptoKeyVersionId, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateCryptoKeyPrimaryVersion(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockKeyManagement.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestKeyManagementServiceUpdateCryptoKeyPrimaryVersionError(t *testing.T) { errCode := codes.PermissionDenied mockKeyManagement.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]", "[CRYPTO_KEY]") var cryptoKeyVersionId string = "cryptoKeyVersionId729489152" var request = &kmspb.UpdateCryptoKeyPrimaryVersionRequest{ Name: formattedName, CryptoKeyVersionId: cryptoKeyVersionId, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateCryptoKeyPrimaryVersion(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestKeyManagementServiceDestroyCryptoKeyVersion(t *testing.T) { var name2 string = "name2-1052831874" var importJob string = "importJob2125587491" var importFailureReason string = "importFailureReason-494073229" var expectedResponse = &kmspb.CryptoKeyVersion{ Name: name2, ImportJob: importJob, ImportFailureReason: importFailureReason, } mockKeyManagement.err = nil mockKeyManagement.reqs = nil mockKeyManagement.resps = append(mockKeyManagement.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s/cryptoKeyVersions/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]", "[CRYPTO_KEY]", "[CRYPTO_KEY_VERSION]") var request = &kmspb.DestroyCryptoKeyVersionRequest{ Name: formattedName, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.DestroyCryptoKeyVersion(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockKeyManagement.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestKeyManagementServiceDestroyCryptoKeyVersionError(t *testing.T) { errCode := codes.PermissionDenied mockKeyManagement.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s/cryptoKeyVersions/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]", "[CRYPTO_KEY]", "[CRYPTO_KEY_VERSION]") var request = &kmspb.DestroyCryptoKeyVersionRequest{ Name: formattedName, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.DestroyCryptoKeyVersion(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestKeyManagementServiceRestoreCryptoKeyVersion(t *testing.T) { var name2 string = "name2-1052831874" var importJob string = "importJob2125587491" var importFailureReason string = "importFailureReason-494073229" var expectedResponse = &kmspb.CryptoKeyVersion{ Name: name2, ImportJob: importJob, ImportFailureReason: importFailureReason, } mockKeyManagement.err = nil mockKeyManagement.reqs = nil mockKeyManagement.resps = append(mockKeyManagement.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s/cryptoKeyVersions/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]", "[CRYPTO_KEY]", "[CRYPTO_KEY_VERSION]") var request = &kmspb.RestoreCryptoKeyVersionRequest{ Name: formattedName, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.RestoreCryptoKeyVersion(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockKeyManagement.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestKeyManagementServiceRestoreCryptoKeyVersionError(t *testing.T) { errCode := codes.PermissionDenied mockKeyManagement.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s/cryptoKeyVersions/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]", "[CRYPTO_KEY]", "[CRYPTO_KEY_VERSION]") var request = &kmspb.RestoreCryptoKeyVersionRequest{ Name: formattedName, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.RestoreCryptoKeyVersion(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestKeyManagementServiceGetPublicKey(t *testing.T) { var pem string = "pem110872" var expectedResponse = &kmspb.PublicKey{ Pem: pem, } mockKeyManagement.err = nil mockKeyManagement.reqs = nil mockKeyManagement.resps = append(mockKeyManagement.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s/cryptoKeyVersions/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]", "[CRYPTO_KEY]", "[CRYPTO_KEY_VERSION]") var request = &kmspb.GetPublicKeyRequest{ Name: formattedName, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetPublicKey(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockKeyManagement.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestKeyManagementServiceGetPublicKeyError(t *testing.T) { errCode := codes.PermissionDenied mockKeyManagement.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s/cryptoKeyVersions/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]", "[CRYPTO_KEY]", "[CRYPTO_KEY_VERSION]") var request = &kmspb.GetPublicKeyRequest{ Name: formattedName, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetPublicKey(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestKeyManagementServiceAsymmetricDecrypt(t *testing.T) { var plaintext []byte = []byte("-9") var expectedResponse = &kmspb.AsymmetricDecryptResponse{ Plaintext: plaintext, } mockKeyManagement.err = nil mockKeyManagement.reqs = nil mockKeyManagement.resps = append(mockKeyManagement.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s/cryptoKeyVersions/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]", "[CRYPTO_KEY]", "[CRYPTO_KEY_VERSION]") var ciphertext []byte = []byte("-72") var request = &kmspb.AsymmetricDecryptRequest{ Name: formattedName, Ciphertext: ciphertext, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.AsymmetricDecrypt(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockKeyManagement.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestKeyManagementServiceAsymmetricDecryptError(t *testing.T) { errCode := codes.PermissionDenied mockKeyManagement.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s/cryptoKeyVersions/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]", "[CRYPTO_KEY]", "[CRYPTO_KEY_VERSION]") var ciphertext []byte = []byte("-72") var request = &kmspb.AsymmetricDecryptRequest{ Name: formattedName, Ciphertext: ciphertext, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.AsymmetricDecrypt(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestKeyManagementServiceAsymmetricSign(t *testing.T) { var signature []byte = []byte("106") var expectedResponse = &kmspb.AsymmetricSignResponse{ Signature: signature, } mockKeyManagement.err = nil mockKeyManagement.reqs = nil mockKeyManagement.resps = append(mockKeyManagement.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s/cryptoKeyVersions/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]", "[CRYPTO_KEY]", "[CRYPTO_KEY_VERSION]") var digest *kmspb.Digest = &kmspb.Digest{} var request = &kmspb.AsymmetricSignRequest{ Name: formattedName, Digest: digest, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.AsymmetricSign(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockKeyManagement.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestKeyManagementServiceAsymmetricSignError(t *testing.T) { errCode := codes.PermissionDenied mockKeyManagement.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s/cryptoKeyVersions/%s", "[PROJECT]", "[LOCATION]", "[KEY_RING]", "[CRYPTO_KEY]", "[CRYPTO_KEY_VERSION]") var digest *kmspb.Digest = &kmspb.Digest{} var request = &kmspb.AsymmetricSignRequest{ Name: formattedName, Digest: digest, } c, err := NewKeyManagementClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.AsymmetricSign(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/language/000077500000000000000000000000001356504100700163535ustar00rootroot00000000000000google-cloud-go-0.49.0/language/apiv1/000077500000000000000000000000001356504100700173735ustar00rootroot00000000000000google-cloud-go-0.49.0/language/apiv1/.repo-metadata.json000066400000000000000000000006451356504100700230740ustar00rootroot00000000000000{ "name": "language", "name_pretty": "Natural Language API", "product_documentation": "https://cloud.google.com/natural-language", "client_documentation": "https://godoc.org/cloud.google.com/go/language/apiv1", "release_level": "alpha", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "language.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/language/apiv1/AnalyzeSentiment_smoke_test.go000066400000000000000000000034141356504100700254530ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package language import ( "context" "fmt" "strconv" "testing" "time" "cloud.google.com/go/internal/testutil" "google.golang.org/api/iterator" "google.golang.org/api/option" languagepb "google.golang.org/genproto/googleapis/cloud/language/v1" ) var _ = fmt.Sprintf var _ = iterator.Done var _ = strconv.FormatUint var _ = time.Now func TestLanguageServiceSmoke(t *testing.T) { if testing.Short() { t.Skip("skipping smoke test in short mode") } ctx := context.Background() ts := testutil.TokenSource(ctx, DefaultAuthScopes()...) if ts == nil { t.Skip("Integration tests skipped. See CONTRIBUTING.md for details") } projectId := testutil.ProjID() _ = projectId c, err := NewClient(ctx, option.WithTokenSource(ts)) if err != nil { t.Fatal(err) } var content string = "Hello, world!" var type_ languagepb.Document_Type = languagepb.Document_PLAIN_TEXT var document = &languagepb.Document{ Source: &languagepb.Document_Content{ Content: content, }, Type: type_, } var request = &languagepb.AnalyzeSentimentRequest{ Document: document, } if _, err := c.AnalyzeSentiment(ctx, request); err != nil { t.Error(err) } } google-cloud-go-0.49.0/language/apiv1/doc.go000066400000000000000000000056141356504100700204750ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go_gapic. DO NOT EDIT. // Package language is an auto-generated package for the // Cloud Natural Language API. // // Provides natural language understanding technologies, such as sentiment // analysis, entity recognition, entity sentiment analysis, and other text // annotations, to developers. // // NOTE: This package is in alpha. It is not stable, and is likely to change. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package language // import "cloud.google.com/go/language/apiv1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) const versionClient = "20191115" func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-language", "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return !strings.ContainsRune("0123456789.", r) } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } google-cloud-go-0.49.0/language/apiv1/language_client.go000066400000000000000000000235021356504100700230450ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go_gapic. DO NOT EDIT. package language import ( "context" "math" "time" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" "google.golang.org/api/transport" languagepb "google.golang.org/genproto/googleapis/cloud/language/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // CallOptions contains the retry settings for each method of Client. type CallOptions struct { AnalyzeSentiment []gax.CallOption AnalyzeEntities []gax.CallOption AnalyzeEntitySentiment []gax.CallOption AnalyzeSyntax []gax.CallOption ClassifyText []gax.CallOption AnnotateText []gax.CallOption } func defaultClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("language.googleapis.com:443"), option.WithGRPCDialOption(grpc.WithDisableServiceConfig()), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultCallOptions() *CallOptions { return &CallOptions{ AnalyzeSentiment: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, AnalyzeEntities: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, AnalyzeEntitySentiment: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, AnalyzeSyntax: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, ClassifyText: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, AnnotateText: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, } } // Client is a client for interacting with Cloud Natural Language API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. client languagepb.LanguageServiceClient // The call options for this service. CallOptions *CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewClient creates a new language service client. // // Provides text analysis operations such as sentiment analysis and entity // recognition. func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultClientOptions(), opts...)...) if err != nil { return nil, err } c := &Client{ conn: conn, CallOptions: defaultCallOptions(), client: languagepb.NewLanguageServiceClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *Client) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *Client) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // AnalyzeSentiment analyzes the sentiment of the provided text. func (c *Client) AnalyzeSentiment(ctx context.Context, req *languagepb.AnalyzeSentimentRequest, opts ...gax.CallOption) (*languagepb.AnalyzeSentimentResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.AnalyzeSentiment[0:len(c.CallOptions.AnalyzeSentiment):len(c.CallOptions.AnalyzeSentiment)], opts...) var resp *languagepb.AnalyzeSentimentResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.AnalyzeSentiment(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // AnalyzeEntities finds named entities (currently proper names and common nouns) in the text // along with entity types, salience, mentions for each entity, and // other properties. func (c *Client) AnalyzeEntities(ctx context.Context, req *languagepb.AnalyzeEntitiesRequest, opts ...gax.CallOption) (*languagepb.AnalyzeEntitiesResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.AnalyzeEntities[0:len(c.CallOptions.AnalyzeEntities):len(c.CallOptions.AnalyzeEntities)], opts...) var resp *languagepb.AnalyzeEntitiesResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.AnalyzeEntities(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // AnalyzeEntitySentiment finds entities, similar to [AnalyzeEntities][google.cloud.language.v1.LanguageService.AnalyzeEntities] in the text and analyzes // sentiment associated with each entity and its mentions. func (c *Client) AnalyzeEntitySentiment(ctx context.Context, req *languagepb.AnalyzeEntitySentimentRequest, opts ...gax.CallOption) (*languagepb.AnalyzeEntitySentimentResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.AnalyzeEntitySentiment[0:len(c.CallOptions.AnalyzeEntitySentiment):len(c.CallOptions.AnalyzeEntitySentiment)], opts...) var resp *languagepb.AnalyzeEntitySentimentResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.AnalyzeEntitySentiment(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // AnalyzeSyntax analyzes the syntax of the text and provides sentence boundaries and // tokenization along with part of speech tags, dependency trees, and other // properties. func (c *Client) AnalyzeSyntax(ctx context.Context, req *languagepb.AnalyzeSyntaxRequest, opts ...gax.CallOption) (*languagepb.AnalyzeSyntaxResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.AnalyzeSyntax[0:len(c.CallOptions.AnalyzeSyntax):len(c.CallOptions.AnalyzeSyntax)], opts...) var resp *languagepb.AnalyzeSyntaxResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.AnalyzeSyntax(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ClassifyText classifies a document into categories. func (c *Client) ClassifyText(ctx context.Context, req *languagepb.ClassifyTextRequest, opts ...gax.CallOption) (*languagepb.ClassifyTextResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.ClassifyText[0:len(c.CallOptions.ClassifyText):len(c.CallOptions.ClassifyText)], opts...) var resp *languagepb.ClassifyTextResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ClassifyText(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // AnnotateText a convenience method that provides all the features that analyzeSentiment, // analyzeEntities, and analyzeSyntax provide in one call. func (c *Client) AnnotateText(ctx context.Context, req *languagepb.AnnotateTextRequest, opts ...gax.CallOption) (*languagepb.AnnotateTextResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.AnnotateText[0:len(c.CallOptions.AnnotateText):len(c.CallOptions.AnnotateText)], opts...) var resp *languagepb.AnnotateTextResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.AnnotateText(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } google-cloud-go-0.49.0/language/apiv1/language_client_example_test.go000066400000000000000000000070071356504100700256210ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go_gapic. DO NOT EDIT. package language_test import ( "context" language "cloud.google.com/go/language/apiv1" languagepb "google.golang.org/genproto/googleapis/cloud/language/v1" ) func ExampleNewClient() { ctx := context.Background() c, err := language.NewClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleClient_AnalyzeSentiment() { // import languagepb "google.golang.org/genproto/googleapis/cloud/language/v1" ctx := context.Background() c, err := language.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &languagepb.AnalyzeSentimentRequest{ // TODO: Fill request struct fields. } resp, err := c.AnalyzeSentiment(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_AnalyzeEntities() { // import languagepb "google.golang.org/genproto/googleapis/cloud/language/v1" ctx := context.Background() c, err := language.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &languagepb.AnalyzeEntitiesRequest{ // TODO: Fill request struct fields. } resp, err := c.AnalyzeEntities(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_AnalyzeEntitySentiment() { // import languagepb "google.golang.org/genproto/googleapis/cloud/language/v1" ctx := context.Background() c, err := language.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &languagepb.AnalyzeEntitySentimentRequest{ // TODO: Fill request struct fields. } resp, err := c.AnalyzeEntitySentiment(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_AnalyzeSyntax() { // import languagepb "google.golang.org/genproto/googleapis/cloud/language/v1" ctx := context.Background() c, err := language.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &languagepb.AnalyzeSyntaxRequest{ // TODO: Fill request struct fields. } resp, err := c.AnalyzeSyntax(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ClassifyText() { // import languagepb "google.golang.org/genproto/googleapis/cloud/language/v1" ctx := context.Background() c, err := language.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &languagepb.ClassifyTextRequest{ // TODO: Fill request struct fields. } resp, err := c.ClassifyText(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_AnnotateText() { // import languagepb "google.golang.org/genproto/googleapis/cloud/language/v1" ctx := context.Background() c, err := language.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &languagepb.AnnotateTextRequest{ // TODO: Fill request struct fields. } resp, err := c.AnnotateText(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/language/apiv1/mock_test.go000066400000000000000000000343351356504100700217220ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package language import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" "google.golang.org/api/option" languagepb "google.golang.org/genproto/googleapis/cloud/language/v1" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockLanguageServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. languagepb.LanguageServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockLanguageServer) AnalyzeSentiment(ctx context.Context, req *languagepb.AnalyzeSentimentRequest) (*languagepb.AnalyzeSentimentResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*languagepb.AnalyzeSentimentResponse), nil } func (s *mockLanguageServer) AnalyzeEntities(ctx context.Context, req *languagepb.AnalyzeEntitiesRequest) (*languagepb.AnalyzeEntitiesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*languagepb.AnalyzeEntitiesResponse), nil } func (s *mockLanguageServer) AnalyzeEntitySentiment(ctx context.Context, req *languagepb.AnalyzeEntitySentimentRequest) (*languagepb.AnalyzeEntitySentimentResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*languagepb.AnalyzeEntitySentimentResponse), nil } func (s *mockLanguageServer) AnalyzeSyntax(ctx context.Context, req *languagepb.AnalyzeSyntaxRequest) (*languagepb.AnalyzeSyntaxResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*languagepb.AnalyzeSyntaxResponse), nil } func (s *mockLanguageServer) ClassifyText(ctx context.Context, req *languagepb.ClassifyTextRequest) (*languagepb.ClassifyTextResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*languagepb.ClassifyTextResponse), nil } func (s *mockLanguageServer) AnnotateText(ctx context.Context, req *languagepb.AnnotateTextRequest) (*languagepb.AnnotateTextResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*languagepb.AnnotateTextResponse), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockLanguage mockLanguageServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() languagepb.RegisterLanguageServiceServer(serv, &mockLanguage) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestLanguageServiceAnalyzeSentiment(t *testing.T) { var language string = "language-1613589672" var expectedResponse = &languagepb.AnalyzeSentimentResponse{ Language: language, } mockLanguage.err = nil mockLanguage.reqs = nil mockLanguage.resps = append(mockLanguage.resps[:0], expectedResponse) var document *languagepb.Document = &languagepb.Document{} var request = &languagepb.AnalyzeSentimentRequest{ Document: document, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.AnalyzeSentiment(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockLanguage.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestLanguageServiceAnalyzeSentimentError(t *testing.T) { errCode := codes.PermissionDenied mockLanguage.err = gstatus.Error(errCode, "test error") var document *languagepb.Document = &languagepb.Document{} var request = &languagepb.AnalyzeSentimentRequest{ Document: document, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.AnalyzeSentiment(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestLanguageServiceAnalyzeEntities(t *testing.T) { var language string = "language-1613589672" var expectedResponse = &languagepb.AnalyzeEntitiesResponse{ Language: language, } mockLanguage.err = nil mockLanguage.reqs = nil mockLanguage.resps = append(mockLanguage.resps[:0], expectedResponse) var document *languagepb.Document = &languagepb.Document{} var request = &languagepb.AnalyzeEntitiesRequest{ Document: document, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.AnalyzeEntities(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockLanguage.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestLanguageServiceAnalyzeEntitiesError(t *testing.T) { errCode := codes.PermissionDenied mockLanguage.err = gstatus.Error(errCode, "test error") var document *languagepb.Document = &languagepb.Document{} var request = &languagepb.AnalyzeEntitiesRequest{ Document: document, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.AnalyzeEntities(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestLanguageServiceAnalyzeEntitySentiment(t *testing.T) { var language string = "language-1613589672" var expectedResponse = &languagepb.AnalyzeEntitySentimentResponse{ Language: language, } mockLanguage.err = nil mockLanguage.reqs = nil mockLanguage.resps = append(mockLanguage.resps[:0], expectedResponse) var document *languagepb.Document = &languagepb.Document{} var request = &languagepb.AnalyzeEntitySentimentRequest{ Document: document, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.AnalyzeEntitySentiment(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockLanguage.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestLanguageServiceAnalyzeEntitySentimentError(t *testing.T) { errCode := codes.PermissionDenied mockLanguage.err = gstatus.Error(errCode, "test error") var document *languagepb.Document = &languagepb.Document{} var request = &languagepb.AnalyzeEntitySentimentRequest{ Document: document, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.AnalyzeEntitySentiment(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestLanguageServiceAnalyzeSyntax(t *testing.T) { var language string = "language-1613589672" var expectedResponse = &languagepb.AnalyzeSyntaxResponse{ Language: language, } mockLanguage.err = nil mockLanguage.reqs = nil mockLanguage.resps = append(mockLanguage.resps[:0], expectedResponse) var document *languagepb.Document = &languagepb.Document{} var request = &languagepb.AnalyzeSyntaxRequest{ Document: document, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.AnalyzeSyntax(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockLanguage.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestLanguageServiceAnalyzeSyntaxError(t *testing.T) { errCode := codes.PermissionDenied mockLanguage.err = gstatus.Error(errCode, "test error") var document *languagepb.Document = &languagepb.Document{} var request = &languagepb.AnalyzeSyntaxRequest{ Document: document, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.AnalyzeSyntax(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestLanguageServiceClassifyText(t *testing.T) { var expectedResponse *languagepb.ClassifyTextResponse = &languagepb.ClassifyTextResponse{} mockLanguage.err = nil mockLanguage.reqs = nil mockLanguage.resps = append(mockLanguage.resps[:0], expectedResponse) var document *languagepb.Document = &languagepb.Document{} var request = &languagepb.ClassifyTextRequest{ Document: document, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ClassifyText(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockLanguage.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestLanguageServiceClassifyTextError(t *testing.T) { errCode := codes.PermissionDenied mockLanguage.err = gstatus.Error(errCode, "test error") var document *languagepb.Document = &languagepb.Document{} var request = &languagepb.ClassifyTextRequest{ Document: document, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ClassifyText(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestLanguageServiceAnnotateText(t *testing.T) { var language string = "language-1613589672" var expectedResponse = &languagepb.AnnotateTextResponse{ Language: language, } mockLanguage.err = nil mockLanguage.reqs = nil mockLanguage.resps = append(mockLanguage.resps[:0], expectedResponse) var document *languagepb.Document = &languagepb.Document{} var features *languagepb.AnnotateTextRequest_Features = &languagepb.AnnotateTextRequest_Features{} var request = &languagepb.AnnotateTextRequest{ Document: document, Features: features, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.AnnotateText(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockLanguage.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestLanguageServiceAnnotateTextError(t *testing.T) { errCode := codes.PermissionDenied mockLanguage.err = gstatus.Error(errCode, "test error") var document *languagepb.Document = &languagepb.Document{} var features *languagepb.AnnotateTextRequest_Features = &languagepb.AnnotateTextRequest_Features{} var request = &languagepb.AnnotateTextRequest{ Document: document, Features: features, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.AnnotateText(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/language/apiv1beta2/000077500000000000000000000000001356504100700203115ustar00rootroot00000000000000google-cloud-go-0.49.0/language/apiv1beta2/.repo-metadata.json000066400000000000000000000006511356504100700240070ustar00rootroot00000000000000{ "name": "language", "name_pretty": "Natural Language API", "product_documentation": "https://cloud.google.com/natural-language", "client_documentation": "https://godoc.org/cloud.google.com/go/language/apiv1beta2", "release_level": "beta", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "language.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/language/apiv1beta2/AnalyzeSentiment_smoke_test.go000066400000000000000000000034211356504100700263670ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package language import ( "context" "fmt" "strconv" "testing" "time" "cloud.google.com/go/internal/testutil" "google.golang.org/api/iterator" "google.golang.org/api/option" languagepb "google.golang.org/genproto/googleapis/cloud/language/v1beta2" ) var _ = fmt.Sprintf var _ = iterator.Done var _ = strconv.FormatUint var _ = time.Now func TestLanguageServiceSmoke(t *testing.T) { if testing.Short() { t.Skip("skipping smoke test in short mode") } ctx := context.Background() ts := testutil.TokenSource(ctx, DefaultAuthScopes()...) if ts == nil { t.Skip("Integration tests skipped. See CONTRIBUTING.md for details") } projectId := testutil.ProjID() _ = projectId c, err := NewClient(ctx, option.WithTokenSource(ts)) if err != nil { t.Fatal(err) } var content string = "Hello, world!" var type_ languagepb.Document_Type = languagepb.Document_PLAIN_TEXT var document = &languagepb.Document{ Source: &languagepb.Document_Content{ Content: content, }, Type: type_, } var request = &languagepb.AnalyzeSentimentRequest{ Document: document, } if _, err := c.AnalyzeSentiment(ctx, request); err != nil { t.Error(err) } } google-cloud-go-0.49.0/language/apiv1beta2/doc.go000066400000000000000000000055551356504100700214170ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package language is an auto-generated package for the // Google Cloud Natural Language API. // // NOTE: This package is in beta. It is not stable, and may be subject to changes. // // Google Cloud Natural Language API provides natural language understanding // technologies to developers. Examples include sentiment analysis, entity // recognition, and text annotations. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package language // import "cloud.google.com/go/language/apiv1beta2" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191115" google-cloud-go-0.49.0/language/apiv1beta2/language_client.go000066400000000000000000000212511356504100700237620ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package language import ( "context" "math" "time" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" "google.golang.org/api/transport" languagepb "google.golang.org/genproto/googleapis/cloud/language/v1beta2" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // CallOptions contains the retry settings for each method of Client. type CallOptions struct { AnalyzeSentiment []gax.CallOption AnalyzeEntities []gax.CallOption AnalyzeEntitySentiment []gax.CallOption AnalyzeSyntax []gax.CallOption ClassifyText []gax.CallOption AnnotateText []gax.CallOption } func defaultClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("language.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultCallOptions() *CallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &CallOptions{ AnalyzeSentiment: retry[[2]string{"default", "idempotent"}], AnalyzeEntities: retry[[2]string{"default", "idempotent"}], AnalyzeEntitySentiment: retry[[2]string{"default", "idempotent"}], AnalyzeSyntax: retry[[2]string{"default", "idempotent"}], ClassifyText: retry[[2]string{"default", "idempotent"}], AnnotateText: retry[[2]string{"default", "idempotent"}], } } // Client is a client for interacting with Google Cloud Natural Language API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. client languagepb.LanguageServiceClient // The call options for this service. CallOptions *CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewClient creates a new language service client. // // Provides text analysis operations such as sentiment analysis and entity // recognition. func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultClientOptions(), opts...)...) if err != nil { return nil, err } c := &Client{ conn: conn, CallOptions: defaultCallOptions(), client: languagepb.NewLanguageServiceClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *Client) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *Client) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // AnalyzeSentiment analyzes the sentiment of the provided text. func (c *Client) AnalyzeSentiment(ctx context.Context, req *languagepb.AnalyzeSentimentRequest, opts ...gax.CallOption) (*languagepb.AnalyzeSentimentResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.AnalyzeSentiment[0:len(c.CallOptions.AnalyzeSentiment):len(c.CallOptions.AnalyzeSentiment)], opts...) var resp *languagepb.AnalyzeSentimentResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.AnalyzeSentiment(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // AnalyzeEntities finds named entities (currently proper names and common nouns) in the text // along with entity types, salience, mentions for each entity, and // other properties. func (c *Client) AnalyzeEntities(ctx context.Context, req *languagepb.AnalyzeEntitiesRequest, opts ...gax.CallOption) (*languagepb.AnalyzeEntitiesResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.AnalyzeEntities[0:len(c.CallOptions.AnalyzeEntities):len(c.CallOptions.AnalyzeEntities)], opts...) var resp *languagepb.AnalyzeEntitiesResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.AnalyzeEntities(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // AnalyzeEntitySentiment finds entities, similar to [AnalyzeEntities][google.cloud.language.v1beta2.LanguageService.AnalyzeEntities] in the text and analyzes // sentiment associated with each entity and its mentions. func (c *Client) AnalyzeEntitySentiment(ctx context.Context, req *languagepb.AnalyzeEntitySentimentRequest, opts ...gax.CallOption) (*languagepb.AnalyzeEntitySentimentResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.AnalyzeEntitySentiment[0:len(c.CallOptions.AnalyzeEntitySentiment):len(c.CallOptions.AnalyzeEntitySentiment)], opts...) var resp *languagepb.AnalyzeEntitySentimentResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.AnalyzeEntitySentiment(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // AnalyzeSyntax analyzes the syntax of the text and provides sentence boundaries and // tokenization along with part of speech tags, dependency trees, and other // properties. func (c *Client) AnalyzeSyntax(ctx context.Context, req *languagepb.AnalyzeSyntaxRequest, opts ...gax.CallOption) (*languagepb.AnalyzeSyntaxResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.AnalyzeSyntax[0:len(c.CallOptions.AnalyzeSyntax):len(c.CallOptions.AnalyzeSyntax)], opts...) var resp *languagepb.AnalyzeSyntaxResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.AnalyzeSyntax(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ClassifyText classifies a document into categories. func (c *Client) ClassifyText(ctx context.Context, req *languagepb.ClassifyTextRequest, opts ...gax.CallOption) (*languagepb.ClassifyTextResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.ClassifyText[0:len(c.CallOptions.ClassifyText):len(c.CallOptions.ClassifyText)], opts...) var resp *languagepb.ClassifyTextResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ClassifyText(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // AnnotateText a convenience method that provides all syntax, sentiment, entity, and // classification features in one call. func (c *Client) AnnotateText(ctx context.Context, req *languagepb.AnnotateTextRequest, opts ...gax.CallOption) (*languagepb.AnnotateTextResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.AnnotateText[0:len(c.CallOptions.AnnotateText):len(c.CallOptions.AnnotateText)], opts...) var resp *languagepb.AnnotateTextResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.AnnotateText(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } google-cloud-go-0.49.0/language/apiv1beta2/language_client_example_test.go000066400000000000000000000060471356504100700265420ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package language_test import ( "context" language "cloud.google.com/go/language/apiv1beta2" languagepb "google.golang.org/genproto/googleapis/cloud/language/v1beta2" ) func ExampleNewClient() { ctx := context.Background() c, err := language.NewClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleClient_AnalyzeSentiment() { ctx := context.Background() c, err := language.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &languagepb.AnalyzeSentimentRequest{ // TODO: Fill request struct fields. } resp, err := c.AnalyzeSentiment(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_AnalyzeEntities() { ctx := context.Background() c, err := language.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &languagepb.AnalyzeEntitiesRequest{ // TODO: Fill request struct fields. } resp, err := c.AnalyzeEntities(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_AnalyzeEntitySentiment() { ctx := context.Background() c, err := language.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &languagepb.AnalyzeEntitySentimentRequest{ // TODO: Fill request struct fields. } resp, err := c.AnalyzeEntitySentiment(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_AnalyzeSyntax() { ctx := context.Background() c, err := language.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &languagepb.AnalyzeSyntaxRequest{ // TODO: Fill request struct fields. } resp, err := c.AnalyzeSyntax(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ClassifyText() { ctx := context.Background() c, err := language.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &languagepb.ClassifyTextRequest{ // TODO: Fill request struct fields. } resp, err := c.ClassifyText(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_AnnotateText() { ctx := context.Background() c, err := language.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &languagepb.AnnotateTextRequest{ // TODO: Fill request struct fields. } resp, err := c.AnnotateText(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/language/apiv1beta2/mock_test.go000066400000000000000000000343421356504100700226360ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package language import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" "google.golang.org/api/option" languagepb "google.golang.org/genproto/googleapis/cloud/language/v1beta2" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockLanguageServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. languagepb.LanguageServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockLanguageServer) AnalyzeSentiment(ctx context.Context, req *languagepb.AnalyzeSentimentRequest) (*languagepb.AnalyzeSentimentResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*languagepb.AnalyzeSentimentResponse), nil } func (s *mockLanguageServer) AnalyzeEntities(ctx context.Context, req *languagepb.AnalyzeEntitiesRequest) (*languagepb.AnalyzeEntitiesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*languagepb.AnalyzeEntitiesResponse), nil } func (s *mockLanguageServer) AnalyzeEntitySentiment(ctx context.Context, req *languagepb.AnalyzeEntitySentimentRequest) (*languagepb.AnalyzeEntitySentimentResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*languagepb.AnalyzeEntitySentimentResponse), nil } func (s *mockLanguageServer) AnalyzeSyntax(ctx context.Context, req *languagepb.AnalyzeSyntaxRequest) (*languagepb.AnalyzeSyntaxResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*languagepb.AnalyzeSyntaxResponse), nil } func (s *mockLanguageServer) ClassifyText(ctx context.Context, req *languagepb.ClassifyTextRequest) (*languagepb.ClassifyTextResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*languagepb.ClassifyTextResponse), nil } func (s *mockLanguageServer) AnnotateText(ctx context.Context, req *languagepb.AnnotateTextRequest) (*languagepb.AnnotateTextResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*languagepb.AnnotateTextResponse), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockLanguage mockLanguageServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() languagepb.RegisterLanguageServiceServer(serv, &mockLanguage) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestLanguageServiceAnalyzeSentiment(t *testing.T) { var language string = "language-1613589672" var expectedResponse = &languagepb.AnalyzeSentimentResponse{ Language: language, } mockLanguage.err = nil mockLanguage.reqs = nil mockLanguage.resps = append(mockLanguage.resps[:0], expectedResponse) var document *languagepb.Document = &languagepb.Document{} var request = &languagepb.AnalyzeSentimentRequest{ Document: document, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.AnalyzeSentiment(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockLanguage.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestLanguageServiceAnalyzeSentimentError(t *testing.T) { errCode := codes.PermissionDenied mockLanguage.err = gstatus.Error(errCode, "test error") var document *languagepb.Document = &languagepb.Document{} var request = &languagepb.AnalyzeSentimentRequest{ Document: document, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.AnalyzeSentiment(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestLanguageServiceAnalyzeEntities(t *testing.T) { var language string = "language-1613589672" var expectedResponse = &languagepb.AnalyzeEntitiesResponse{ Language: language, } mockLanguage.err = nil mockLanguage.reqs = nil mockLanguage.resps = append(mockLanguage.resps[:0], expectedResponse) var document *languagepb.Document = &languagepb.Document{} var request = &languagepb.AnalyzeEntitiesRequest{ Document: document, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.AnalyzeEntities(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockLanguage.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestLanguageServiceAnalyzeEntitiesError(t *testing.T) { errCode := codes.PermissionDenied mockLanguage.err = gstatus.Error(errCode, "test error") var document *languagepb.Document = &languagepb.Document{} var request = &languagepb.AnalyzeEntitiesRequest{ Document: document, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.AnalyzeEntities(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestLanguageServiceAnalyzeEntitySentiment(t *testing.T) { var language string = "language-1613589672" var expectedResponse = &languagepb.AnalyzeEntitySentimentResponse{ Language: language, } mockLanguage.err = nil mockLanguage.reqs = nil mockLanguage.resps = append(mockLanguage.resps[:0], expectedResponse) var document *languagepb.Document = &languagepb.Document{} var request = &languagepb.AnalyzeEntitySentimentRequest{ Document: document, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.AnalyzeEntitySentiment(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockLanguage.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestLanguageServiceAnalyzeEntitySentimentError(t *testing.T) { errCode := codes.PermissionDenied mockLanguage.err = gstatus.Error(errCode, "test error") var document *languagepb.Document = &languagepb.Document{} var request = &languagepb.AnalyzeEntitySentimentRequest{ Document: document, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.AnalyzeEntitySentiment(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestLanguageServiceAnalyzeSyntax(t *testing.T) { var language string = "language-1613589672" var expectedResponse = &languagepb.AnalyzeSyntaxResponse{ Language: language, } mockLanguage.err = nil mockLanguage.reqs = nil mockLanguage.resps = append(mockLanguage.resps[:0], expectedResponse) var document *languagepb.Document = &languagepb.Document{} var request = &languagepb.AnalyzeSyntaxRequest{ Document: document, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.AnalyzeSyntax(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockLanguage.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestLanguageServiceAnalyzeSyntaxError(t *testing.T) { errCode := codes.PermissionDenied mockLanguage.err = gstatus.Error(errCode, "test error") var document *languagepb.Document = &languagepb.Document{} var request = &languagepb.AnalyzeSyntaxRequest{ Document: document, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.AnalyzeSyntax(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestLanguageServiceClassifyText(t *testing.T) { var expectedResponse *languagepb.ClassifyTextResponse = &languagepb.ClassifyTextResponse{} mockLanguage.err = nil mockLanguage.reqs = nil mockLanguage.resps = append(mockLanguage.resps[:0], expectedResponse) var document *languagepb.Document = &languagepb.Document{} var request = &languagepb.ClassifyTextRequest{ Document: document, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ClassifyText(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockLanguage.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestLanguageServiceClassifyTextError(t *testing.T) { errCode := codes.PermissionDenied mockLanguage.err = gstatus.Error(errCode, "test error") var document *languagepb.Document = &languagepb.Document{} var request = &languagepb.ClassifyTextRequest{ Document: document, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ClassifyText(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestLanguageServiceAnnotateText(t *testing.T) { var language string = "language-1613589672" var expectedResponse = &languagepb.AnnotateTextResponse{ Language: language, } mockLanguage.err = nil mockLanguage.reqs = nil mockLanguage.resps = append(mockLanguage.resps[:0], expectedResponse) var document *languagepb.Document = &languagepb.Document{} var features *languagepb.AnnotateTextRequest_Features = &languagepb.AnnotateTextRequest_Features{} var request = &languagepb.AnnotateTextRequest{ Document: document, Features: features, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.AnnotateText(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockLanguage.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestLanguageServiceAnnotateTextError(t *testing.T) { errCode := codes.PermissionDenied mockLanguage.err = gstatus.Error(errCode, "test error") var document *languagepb.Document = &languagepb.Document{} var features *languagepb.AnnotateTextRequest_Features = &languagepb.AnnotateTextRequest_Features{} var request = &languagepb.AnnotateTextRequest{ Document: document, Features: features, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.AnnotateText(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/license_test.go000066400000000000000000000035141356504100700176030ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package cloud import ( "bytes" "io/ioutil" "os" "path/filepath" "strings" "testing" ) var sentinels = []string{ "Copyright", "Google", `Licensed under the Apache License, Version 2.0 (the "License");`, } func TestLicense(t *testing.T) { t.Parallel() err := filepath.Walk(".", func(path string, fi os.FileInfo, err error) error { if err != nil { return err } if ext := filepath.Ext(path); ext != ".go" && ext != ".proto" { return nil } if strings.HasSuffix(path, ".pb.go") { // .pb.go files are generated from the proto files. // .proto files must have license headers. return nil } if path == "bigtable/cmd/cbt/cbtdoc.go" { // Automatically generated. return nil } if path == "cmd/go-cloud-debug-agent/internal/debug/elf/elf.go" { // BSD license, which is compatible, is embedded in the file. return nil } src, err := ioutil.ReadFile(path) if err != nil { return nil } src = src[:300] // Ensure all of the sentinel values are at the top of the file. // Find license for _, sentinel := range sentinels { if !bytes.Contains(src, []byte(sentinel)) { t.Errorf("%v: license header not present. want %q", path, sentinel) return nil } } return nil }) if err != nil { t.Fatal(err) } } google-cloud-go-0.49.0/logging/000077500000000000000000000000001356504100700162165ustar00rootroot00000000000000google-cloud-go-0.49.0/logging/.repo-metadata.json000066400000000000000000000006271356504100700217170ustar00rootroot00000000000000{ "name": "logging", "name_pretty": "Stackdriver Logging", "product_documentation": "https://cloud.google.com/logging", "client_documentation": "https://godoc.org/cloud.google.com/go/logging", "release_level": "ga", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go/logging", "api_id": "logging.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/logging/CHANGES.md000066400000000000000000000002771356504100700176160ustar00rootroot00000000000000# Changes ## v1.0.0 This is the first tag to carve out logging as its own module. See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository.google-cloud-go-0.49.0/logging/README.md000066400000000000000000000021561356504100700175010ustar00rootroot00000000000000## Stackdriver Logging [![GoDoc](https://godoc.org/cloud.google.com/go/logging?status.svg)](https://godoc.org/cloud.google.com/go/logging) - [About Stackdriver Logging](https://cloud.google.com/logging/) - [API documentation](https://cloud.google.com/logging/docs) - [Go client documentation](https://godoc.org/cloud.google.com/go/logging) - [Complete sample programs](https://github.com/GoogleCloudPlatform/golang-samples/tree/master/logging) ### Example Usage First create a `logging.Client` to use throughout your application: [snip]:# (logging-1) ```go ctx := context.Background() client, err := logging.NewClient(ctx, "my-project") if err != nil { // TODO: Handle error. } ``` Usually, you'll want to add log entries to a buffer to be periodically flushed (automatically and asynchronously) to the Stackdriver Logging service. [snip]:# (logging-2) ```go logger := client.Logger("my-log") logger.Log(logging.Entry{Payload: "something happened!"}) ``` Close your client before your program exits, to flush any buffered log entries. [snip]:# (logging-3) ```go err = client.Close() if err != nil { // TODO: Handle error. } ```google-cloud-go-0.49.0/logging/apiv2/000077500000000000000000000000001356504100700172375ustar00rootroot00000000000000google-cloud-go-0.49.0/logging/apiv2/.repo-metadata.json000066400000000000000000000006301356504100700227320ustar00rootroot00000000000000{ "name": "logging", "name_pretty": "Stackdriver Logging", "product_documentation": "https://cloud.google.com/logging", "client_documentation": "https://godoc.org/cloud.google.com/go/logging/apiv2", "release_level": "alpha", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "logging.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/logging/apiv2/README.md000066400000000000000000000004741356504100700205230ustar00rootroot00000000000000Auto-generated logging v2 clients ================================= This package includes auto-generated clients for the logging v2 API. Use the handwritten logging client (in the parent directory, cloud.google.com/go/logging) in preference to this. This code is EXPERIMENTAL and subject to CHANGE AT ANY TIME. google-cloud-go-0.49.0/logging/apiv2/WriteLogEntries_smoke_test.go000066400000000000000000000033301356504100700251100ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // AUTO-GENERATED CODE. DO NOT EDIT. package logging import ( "context" "fmt" "strconv" "testing" "time" "cloud.google.com/go/internal/testutil" "google.golang.org/api/iterator" "google.golang.org/api/option" loggingpb "google.golang.org/genproto/googleapis/logging/v2" ) var _ = fmt.Sprintf var _ = iterator.Done var _ = strconv.FormatUint var _ = time.Now func TestLoggingServiceV2Smoke(t *testing.T) { if testing.Short() { t.Skip("skipping smoke test in short mode") } ctx := context.Background() ts := testutil.TokenSource(ctx, DefaultAuthScopes()...) if ts == nil { t.Skip("Integration tests skipped. See CONTRIBUTING.md for details") } projectId := testutil.ProjID() _ = projectId c, err := NewClient(ctx, option.WithTokenSource(ts)) if err != nil { t.Fatal(err) } var entries []*loggingpb.LogEntry = nil var formattedLogName string = fmt.Sprintf("projects/%s/logs/%s", projectId, "test-"+strconv.FormatInt(time.Now().UnixNano(), 10)+"") var request = &loggingpb.WriteLogEntriesRequest{ Entries: entries, LogName: formattedLogName, } if _, err := c.WriteLogEntries(ctx, request); err != nil { t.Error(err) } } google-cloud-go-0.49.0/logging/apiv2/config_client.go000066400000000000000000000413701356504100700223760ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package logging import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" loggingpb "google.golang.org/genproto/googleapis/logging/v2" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // ConfigCallOptions contains the retry settings for each method of ConfigClient. type ConfigCallOptions struct { ListSinks []gax.CallOption GetSink []gax.CallOption CreateSink []gax.CallOption UpdateSink []gax.CallOption DeleteSink []gax.CallOption ListExclusions []gax.CallOption GetExclusion []gax.CallOption CreateExclusion []gax.CallOption UpdateExclusion []gax.CallOption DeleteExclusion []gax.CallOption } func defaultConfigClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("logging.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultConfigCallOptions() *ConfigCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Internal, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &ConfigCallOptions{ ListSinks: retry[[2]string{"default", "idempotent"}], GetSink: retry[[2]string{"default", "idempotent"}], CreateSink: retry[[2]string{"default", "non_idempotent"}], UpdateSink: retry[[2]string{"default", "idempotent"}], DeleteSink: retry[[2]string{"default", "idempotent"}], ListExclusions: retry[[2]string{"default", "idempotent"}], GetExclusion: retry[[2]string{"default", "idempotent"}], CreateExclusion: retry[[2]string{"default", "non_idempotent"}], UpdateExclusion: retry[[2]string{"default", "non_idempotent"}], DeleteExclusion: retry[[2]string{"default", "idempotent"}], } } // ConfigClient is a client for interacting with Stackdriver Logging API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type ConfigClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. configClient loggingpb.ConfigServiceV2Client // The call options for this service. CallOptions *ConfigCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewConfigClient creates a new config service v2 client. // // Service for configuring sinks used to route log entries. func NewConfigClient(ctx context.Context, opts ...option.ClientOption) (*ConfigClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultConfigClientOptions(), opts...)...) if err != nil { return nil, err } c := &ConfigClient{ conn: conn, CallOptions: defaultConfigCallOptions(), configClient: loggingpb.NewConfigServiceV2Client(conn), } c.SetGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *ConfigClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *ConfigClient) Close() error { return c.conn.Close() } // SetGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *ConfigClient) SetGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // ListSinks lists sinks. func (c *ConfigClient) ListSinks(ctx context.Context, req *loggingpb.ListSinksRequest, opts ...gax.CallOption) *LogSinkIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListSinks[0:len(c.CallOptions.ListSinks):len(c.CallOptions.ListSinks)], opts...) it := &LogSinkIterator{} req = proto.Clone(req).(*loggingpb.ListSinksRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*loggingpb.LogSink, string, error) { var resp *loggingpb.ListSinksResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.configClient.ListSinks(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Sinks, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetSink gets a sink. func (c *ConfigClient) GetSink(ctx context.Context, req *loggingpb.GetSinkRequest, opts ...gax.CallOption) (*loggingpb.LogSink, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "sink_name", url.QueryEscape(req.GetSinkName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetSink[0:len(c.CallOptions.GetSink):len(c.CallOptions.GetSink)], opts...) var resp *loggingpb.LogSink err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.configClient.GetSink(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateSink creates a sink that exports specified log entries to a destination. The // export of newly-ingested log entries begins immediately, unless the sink's // writer_identity is not permitted to write to the destination. A sink can // export log entries only from the resource owning the sink. func (c *ConfigClient) CreateSink(ctx context.Context, req *loggingpb.CreateSinkRequest, opts ...gax.CallOption) (*loggingpb.LogSink, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateSink[0:len(c.CallOptions.CreateSink):len(c.CallOptions.CreateSink)], opts...) var resp *loggingpb.LogSink err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.configClient.CreateSink(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateSink updates a sink. This method replaces the following fields in the existing // sink with values from the new sink: destination, and filter. // // The updated sink might also have a new writer_identity; see the // unique_writer_identity field. func (c *ConfigClient) UpdateSink(ctx context.Context, req *loggingpb.UpdateSinkRequest, opts ...gax.CallOption) (*loggingpb.LogSink, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "sink_name", url.QueryEscape(req.GetSinkName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateSink[0:len(c.CallOptions.UpdateSink):len(c.CallOptions.UpdateSink)], opts...) var resp *loggingpb.LogSink err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.configClient.UpdateSink(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteSink deletes a sink. If the sink has a unique writer_identity, then that // service account is also deleted. func (c *ConfigClient) DeleteSink(ctx context.Context, req *loggingpb.DeleteSinkRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "sink_name", url.QueryEscape(req.GetSinkName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteSink[0:len(c.CallOptions.DeleteSink):len(c.CallOptions.DeleteSink)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.configClient.DeleteSink(ctx, req, settings.GRPC...) return err }, opts...) return err } // ListExclusions lists all the exclusions in a parent resource. func (c *ConfigClient) ListExclusions(ctx context.Context, req *loggingpb.ListExclusionsRequest, opts ...gax.CallOption) *LogExclusionIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListExclusions[0:len(c.CallOptions.ListExclusions):len(c.CallOptions.ListExclusions)], opts...) it := &LogExclusionIterator{} req = proto.Clone(req).(*loggingpb.ListExclusionsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*loggingpb.LogExclusion, string, error) { var resp *loggingpb.ListExclusionsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.configClient.ListExclusions(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Exclusions, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetExclusion gets the description of an exclusion. func (c *ConfigClient) GetExclusion(ctx context.Context, req *loggingpb.GetExclusionRequest, opts ...gax.CallOption) (*loggingpb.LogExclusion, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetExclusion[0:len(c.CallOptions.GetExclusion):len(c.CallOptions.GetExclusion)], opts...) var resp *loggingpb.LogExclusion err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.configClient.GetExclusion(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateExclusion creates a new exclusion in a specified parent resource. // Only log entries belonging to that resource can be excluded. // You can have up to 10 exclusions in a resource. func (c *ConfigClient) CreateExclusion(ctx context.Context, req *loggingpb.CreateExclusionRequest, opts ...gax.CallOption) (*loggingpb.LogExclusion, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateExclusion[0:len(c.CallOptions.CreateExclusion):len(c.CallOptions.CreateExclusion)], opts...) var resp *loggingpb.LogExclusion err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.configClient.CreateExclusion(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateExclusion changes one or more properties of an existing exclusion. func (c *ConfigClient) UpdateExclusion(ctx context.Context, req *loggingpb.UpdateExclusionRequest, opts ...gax.CallOption) (*loggingpb.LogExclusion, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateExclusion[0:len(c.CallOptions.UpdateExclusion):len(c.CallOptions.UpdateExclusion)], opts...) var resp *loggingpb.LogExclusion err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.configClient.UpdateExclusion(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteExclusion deletes an exclusion. func (c *ConfigClient) DeleteExclusion(ctx context.Context, req *loggingpb.DeleteExclusionRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteExclusion[0:len(c.CallOptions.DeleteExclusion):len(c.CallOptions.DeleteExclusion)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.configClient.DeleteExclusion(ctx, req, settings.GRPC...) return err }, opts...) return err } // LogExclusionIterator manages a stream of *loggingpb.LogExclusion. type LogExclusionIterator struct { items []*loggingpb.LogExclusion pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*loggingpb.LogExclusion, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *LogExclusionIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *LogExclusionIterator) Next() (*loggingpb.LogExclusion, error) { var item *loggingpb.LogExclusion if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *LogExclusionIterator) bufLen() int { return len(it.items) } func (it *LogExclusionIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // LogSinkIterator manages a stream of *loggingpb.LogSink. type LogSinkIterator struct { items []*loggingpb.LogSink pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*loggingpb.LogSink, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *LogSinkIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *LogSinkIterator) Next() (*loggingpb.LogSink, error) { var item *loggingpb.LogSink if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *LogSinkIterator) bufLen() int { return len(it.items) } func (it *LogSinkIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/logging/apiv2/config_client_example_test.go000066400000000000000000000110261356504100700251430ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package logging_test import ( "context" logging "cloud.google.com/go/logging/apiv2" "google.golang.org/api/iterator" loggingpb "google.golang.org/genproto/googleapis/logging/v2" ) func ExampleNewConfigClient() { ctx := context.Background() c, err := logging.NewConfigClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleConfigClient_ListSinks() { ctx := context.Background() c, err := logging.NewConfigClient(ctx) if err != nil { // TODO: Handle error. } req := &loggingpb.ListSinksRequest{ // TODO: Fill request struct fields. } it := c.ListSinks(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleConfigClient_GetSink() { ctx := context.Background() c, err := logging.NewConfigClient(ctx) if err != nil { // TODO: Handle error. } req := &loggingpb.GetSinkRequest{ // TODO: Fill request struct fields. } resp, err := c.GetSink(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleConfigClient_CreateSink() { ctx := context.Background() c, err := logging.NewConfigClient(ctx) if err != nil { // TODO: Handle error. } req := &loggingpb.CreateSinkRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateSink(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleConfigClient_UpdateSink() { ctx := context.Background() c, err := logging.NewConfigClient(ctx) if err != nil { // TODO: Handle error. } req := &loggingpb.UpdateSinkRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateSink(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleConfigClient_DeleteSink() { ctx := context.Background() c, err := logging.NewConfigClient(ctx) if err != nil { // TODO: Handle error. } req := &loggingpb.DeleteSinkRequest{ // TODO: Fill request struct fields. } err = c.DeleteSink(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleConfigClient_ListExclusions() { ctx := context.Background() c, err := logging.NewConfigClient(ctx) if err != nil { // TODO: Handle error. } req := &loggingpb.ListExclusionsRequest{ // TODO: Fill request struct fields. } it := c.ListExclusions(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleConfigClient_GetExclusion() { ctx := context.Background() c, err := logging.NewConfigClient(ctx) if err != nil { // TODO: Handle error. } req := &loggingpb.GetExclusionRequest{ // TODO: Fill request struct fields. } resp, err := c.GetExclusion(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleConfigClient_CreateExclusion() { ctx := context.Background() c, err := logging.NewConfigClient(ctx) if err != nil { // TODO: Handle error. } req := &loggingpb.CreateExclusionRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateExclusion(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleConfigClient_UpdateExclusion() { ctx := context.Background() c, err := logging.NewConfigClient(ctx) if err != nil { // TODO: Handle error. } req := &loggingpb.UpdateExclusionRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateExclusion(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleConfigClient_DeleteExclusion() { ctx := context.Background() c, err := logging.NewConfigClient(ctx) if err != nil { // TODO: Handle error. } req := &loggingpb.DeleteExclusionRequest{ // TODO: Fill request struct fields. } err = c.DeleteExclusion(ctx, req) if err != nil { // TODO: Handle error. } } google-cloud-go-0.49.0/logging/apiv2/doc.go000066400000000000000000000063371356504100700203440ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package logging is an auto-generated package for the // Stackdriver Logging API. // // NOTE: This package is in alpha. It is not stable, and is likely to change. // // Writes log entries and manages your Stackdriver Logging configuration. The // table entries below are presented in alphabetical order, not in order of // common use. For explanations of the concepts found in the table entries, // read the [Stackdriver Logging documentation](/logging/docs). // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. // // Use the client at cloud.google.com/go/logging in preference to this. package logging // import "cloud.google.com/go/logging/apiv2" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/cloud-platform.read-only", "https://www.googleapis.com/auth/logging.admin", "https://www.googleapis.com/auth/logging.read", "https://www.googleapis.com/auth/logging.write", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191115" google-cloud-go-0.49.0/logging/apiv2/logging_client.go000066400000000000000000000356351356504100700225660ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package logging import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" monitoredrespb "google.golang.org/genproto/googleapis/api/monitoredres" loggingpb "google.golang.org/genproto/googleapis/logging/v2" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // CallOptions contains the retry settings for each method of Client. type CallOptions struct { DeleteLog []gax.CallOption WriteLogEntries []gax.CallOption ListLogEntries []gax.CallOption ListMonitoredResourceDescriptors []gax.CallOption ListLogs []gax.CallOption } func defaultClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("logging.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultCallOptions() *CallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Internal, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &CallOptions{ DeleteLog: retry[[2]string{"default", "idempotent"}], WriteLogEntries: retry[[2]string{"default", "idempotent"}], ListLogEntries: retry[[2]string{"default", "idempotent"}], ListMonitoredResourceDescriptors: retry[[2]string{"default", "idempotent"}], ListLogs: retry[[2]string{"default", "idempotent"}], } } // Client is a client for interacting with Stackdriver Logging API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. client loggingpb.LoggingServiceV2Client // The call options for this service. CallOptions *CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewClient creates a new logging service v2 client. // // Service for ingesting and querying logs. func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultClientOptions(), opts...)...) if err != nil { return nil, err } c := &Client{ conn: conn, CallOptions: defaultCallOptions(), client: loggingpb.NewLoggingServiceV2Client(conn), } c.SetGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *Client) Close() error { return c.conn.Close() } // SetGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *Client) SetGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // DeleteLog deletes all the log entries in a log. // The log reappears if it receives new entries. // Log entries written shortly before the delete operation might not be // deleted. func (c *Client) DeleteLog(ctx context.Context, req *loggingpb.DeleteLogRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "log_name", url.QueryEscape(req.GetLogName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteLog[0:len(c.CallOptions.DeleteLog):len(c.CallOptions.DeleteLog)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.client.DeleteLog(ctx, req, settings.GRPC...) return err }, opts...) return err } // WriteLogEntries writes log entries to Logging. This API method is the // only way to send log entries to Logging. This method // is used, directly or indirectly, by the Logging agent // (fluentd) and all logging libraries configured to use Logging. // A single request may contain log entries for a maximum of 1000 // different resources (projects, organizations, billing accounts or // folders) func (c *Client) WriteLogEntries(ctx context.Context, req *loggingpb.WriteLogEntriesRequest, opts ...gax.CallOption) (*loggingpb.WriteLogEntriesResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.WriteLogEntries[0:len(c.CallOptions.WriteLogEntries):len(c.CallOptions.WriteLogEntries)], opts...) var resp *loggingpb.WriteLogEntriesResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.WriteLogEntries(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListLogEntries lists log entries. Use this method to retrieve log entries that originated // from a project/folder/organization/billing account. For ways to export log // entries, see Exporting Logs (at /logging/docs/export). func (c *Client) ListLogEntries(ctx context.Context, req *loggingpb.ListLogEntriesRequest, opts ...gax.CallOption) *LogEntryIterator { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.ListLogEntries[0:len(c.CallOptions.ListLogEntries):len(c.CallOptions.ListLogEntries)], opts...) it := &LogEntryIterator{} req = proto.Clone(req).(*loggingpb.ListLogEntriesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*loggingpb.LogEntry, string, error) { var resp *loggingpb.ListLogEntriesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListLogEntries(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Entries, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // ListMonitoredResourceDescriptors lists the descriptors for monitored resource types used by Logging. func (c *Client) ListMonitoredResourceDescriptors(ctx context.Context, req *loggingpb.ListMonitoredResourceDescriptorsRequest, opts ...gax.CallOption) *MonitoredResourceDescriptorIterator { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.ListMonitoredResourceDescriptors[0:len(c.CallOptions.ListMonitoredResourceDescriptors):len(c.CallOptions.ListMonitoredResourceDescriptors)], opts...) it := &MonitoredResourceDescriptorIterator{} req = proto.Clone(req).(*loggingpb.ListMonitoredResourceDescriptorsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*monitoredrespb.MonitoredResourceDescriptor, string, error) { var resp *loggingpb.ListMonitoredResourceDescriptorsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListMonitoredResourceDescriptors(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.ResourceDescriptors, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // ListLogs lists the logs in projects, organizations, folders, or billing accounts. // Only logs that have entries are listed. func (c *Client) ListLogs(ctx context.Context, req *loggingpb.ListLogsRequest, opts ...gax.CallOption) *StringIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListLogs[0:len(c.CallOptions.ListLogs):len(c.CallOptions.ListLogs)], opts...) it := &StringIterator{} req = proto.Clone(req).(*loggingpb.ListLogsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]string, string, error) { var resp *loggingpb.ListLogsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListLogs(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.LogNames, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // LogEntryIterator manages a stream of *loggingpb.LogEntry. type LogEntryIterator struct { items []*loggingpb.LogEntry pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*loggingpb.LogEntry, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *LogEntryIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *LogEntryIterator) Next() (*loggingpb.LogEntry, error) { var item *loggingpb.LogEntry if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *LogEntryIterator) bufLen() int { return len(it.items) } func (it *LogEntryIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // MonitoredResourceDescriptorIterator manages a stream of *monitoredrespb.MonitoredResourceDescriptor. type MonitoredResourceDescriptorIterator struct { items []*monitoredrespb.MonitoredResourceDescriptor pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*monitoredrespb.MonitoredResourceDescriptor, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *MonitoredResourceDescriptorIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *MonitoredResourceDescriptorIterator) Next() (*monitoredrespb.MonitoredResourceDescriptor, error) { var item *monitoredrespb.MonitoredResourceDescriptor if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *MonitoredResourceDescriptorIterator) bufLen() int { return len(it.items) } func (it *MonitoredResourceDescriptorIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // StringIterator manages a stream of string. type StringIterator struct { items []string pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []string, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *StringIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *StringIterator) Next() (string, error) { var item string if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *StringIterator) bufLen() int { return len(it.items) } func (it *StringIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/logging/apiv2/logging_client_example_test.go000066400000000000000000000056101356504100700253260ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package logging_test import ( "context" logging "cloud.google.com/go/logging/apiv2" "google.golang.org/api/iterator" loggingpb "google.golang.org/genproto/googleapis/logging/v2" ) func ExampleNewClient() { ctx := context.Background() c, err := logging.NewClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleClient_DeleteLog() { ctx := context.Background() c, err := logging.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &loggingpb.DeleteLogRequest{ // TODO: Fill request struct fields. } err = c.DeleteLog(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleClient_WriteLogEntries() { ctx := context.Background() c, err := logging.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &loggingpb.WriteLogEntriesRequest{ // TODO: Fill request struct fields. } resp, err := c.WriteLogEntries(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ListLogEntries() { ctx := context.Background() c, err := logging.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &loggingpb.ListLogEntriesRequest{ // TODO: Fill request struct fields. } it := c.ListLogEntries(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_ListMonitoredResourceDescriptors() { ctx := context.Background() c, err := logging.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &loggingpb.ListMonitoredResourceDescriptorsRequest{ // TODO: Fill request struct fields. } it := c.ListMonitoredResourceDescriptors(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_ListLogs() { ctx := context.Background() c, err := logging.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &loggingpb.ListLogsRequest{ // TODO: Fill request struct fields. } it := c.ListLogs(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } google-cloud-go-0.49.0/logging/apiv2/metrics_client.go000066400000000000000000000237631356504100700226050ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package logging import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" loggingpb "google.golang.org/genproto/googleapis/logging/v2" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // MetricsCallOptions contains the retry settings for each method of MetricsClient. type MetricsCallOptions struct { ListLogMetrics []gax.CallOption GetLogMetric []gax.CallOption CreateLogMetric []gax.CallOption UpdateLogMetric []gax.CallOption DeleteLogMetric []gax.CallOption } func defaultMetricsClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("logging.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultMetricsCallOptions() *MetricsCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Internal, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &MetricsCallOptions{ ListLogMetrics: retry[[2]string{"default", "idempotent"}], GetLogMetric: retry[[2]string{"default", "idempotent"}], CreateLogMetric: retry[[2]string{"default", "non_idempotent"}], UpdateLogMetric: retry[[2]string{"default", "idempotent"}], DeleteLogMetric: retry[[2]string{"default", "idempotent"}], } } // MetricsClient is a client for interacting with Stackdriver Logging API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type MetricsClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. metricsClient loggingpb.MetricsServiceV2Client // The call options for this service. CallOptions *MetricsCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewMetricsClient creates a new metrics service v2 client. // // Service for configuring logs-based metrics. func NewMetricsClient(ctx context.Context, opts ...option.ClientOption) (*MetricsClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultMetricsClientOptions(), opts...)...) if err != nil { return nil, err } c := &MetricsClient{ conn: conn, CallOptions: defaultMetricsCallOptions(), metricsClient: loggingpb.NewMetricsServiceV2Client(conn), } c.SetGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *MetricsClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *MetricsClient) Close() error { return c.conn.Close() } // SetGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *MetricsClient) SetGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // ListLogMetrics lists logs-based metrics. func (c *MetricsClient) ListLogMetrics(ctx context.Context, req *loggingpb.ListLogMetricsRequest, opts ...gax.CallOption) *LogMetricIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListLogMetrics[0:len(c.CallOptions.ListLogMetrics):len(c.CallOptions.ListLogMetrics)], opts...) it := &LogMetricIterator{} req = proto.Clone(req).(*loggingpb.ListLogMetricsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*loggingpb.LogMetric, string, error) { var resp *loggingpb.ListLogMetricsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.metricsClient.ListLogMetrics(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Metrics, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetLogMetric gets a logs-based metric. func (c *MetricsClient) GetLogMetric(ctx context.Context, req *loggingpb.GetLogMetricRequest, opts ...gax.CallOption) (*loggingpb.LogMetric, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "metric_name", url.QueryEscape(req.GetMetricName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetLogMetric[0:len(c.CallOptions.GetLogMetric):len(c.CallOptions.GetLogMetric)], opts...) var resp *loggingpb.LogMetric err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.metricsClient.GetLogMetric(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateLogMetric creates a logs-based metric. func (c *MetricsClient) CreateLogMetric(ctx context.Context, req *loggingpb.CreateLogMetricRequest, opts ...gax.CallOption) (*loggingpb.LogMetric, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateLogMetric[0:len(c.CallOptions.CreateLogMetric):len(c.CallOptions.CreateLogMetric)], opts...) var resp *loggingpb.LogMetric err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.metricsClient.CreateLogMetric(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateLogMetric creates or updates a logs-based metric. func (c *MetricsClient) UpdateLogMetric(ctx context.Context, req *loggingpb.UpdateLogMetricRequest, opts ...gax.CallOption) (*loggingpb.LogMetric, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "metric_name", url.QueryEscape(req.GetMetricName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateLogMetric[0:len(c.CallOptions.UpdateLogMetric):len(c.CallOptions.UpdateLogMetric)], opts...) var resp *loggingpb.LogMetric err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.metricsClient.UpdateLogMetric(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteLogMetric deletes a logs-based metric. func (c *MetricsClient) DeleteLogMetric(ctx context.Context, req *loggingpb.DeleteLogMetricRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "metric_name", url.QueryEscape(req.GetMetricName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteLogMetric[0:len(c.CallOptions.DeleteLogMetric):len(c.CallOptions.DeleteLogMetric)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.metricsClient.DeleteLogMetric(ctx, req, settings.GRPC...) return err }, opts...) return err } // LogMetricIterator manages a stream of *loggingpb.LogMetric. type LogMetricIterator struct { items []*loggingpb.LogMetric pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*loggingpb.LogMetric, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *LogMetricIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *LogMetricIterator) Next() (*loggingpb.LogMetric, error) { var item *loggingpb.LogMetric if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *LogMetricIterator) bufLen() int { return len(it.items) } func (it *LogMetricIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/logging/apiv2/metrics_client_example_test.go000066400000000000000000000054631356504100700253540ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package logging_test import ( "context" logging "cloud.google.com/go/logging/apiv2" "google.golang.org/api/iterator" loggingpb "google.golang.org/genproto/googleapis/logging/v2" ) func ExampleNewMetricsClient() { ctx := context.Background() c, err := logging.NewMetricsClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleMetricsClient_ListLogMetrics() { ctx := context.Background() c, err := logging.NewMetricsClient(ctx) if err != nil { // TODO: Handle error. } req := &loggingpb.ListLogMetricsRequest{ // TODO: Fill request struct fields. } it := c.ListLogMetrics(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleMetricsClient_GetLogMetric() { ctx := context.Background() c, err := logging.NewMetricsClient(ctx) if err != nil { // TODO: Handle error. } req := &loggingpb.GetLogMetricRequest{ // TODO: Fill request struct fields. } resp, err := c.GetLogMetric(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleMetricsClient_CreateLogMetric() { ctx := context.Background() c, err := logging.NewMetricsClient(ctx) if err != nil { // TODO: Handle error. } req := &loggingpb.CreateLogMetricRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateLogMetric(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleMetricsClient_UpdateLogMetric() { ctx := context.Background() c, err := logging.NewMetricsClient(ctx) if err != nil { // TODO: Handle error. } req := &loggingpb.UpdateLogMetricRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateLogMetric(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleMetricsClient_DeleteLogMetric() { ctx := context.Background() c, err := logging.NewMetricsClient(ctx) if err != nil { // TODO: Handle error. } req := &loggingpb.DeleteLogMetricRequest{ // TODO: Fill request struct fields. } err = c.DeleteLogMetric(ctx, req) if err != nil { // TODO: Handle error. } } google-cloud-go-0.49.0/logging/apiv2/mock_test.go000066400000000000000000001364721356504100700215730ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package logging import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" "google.golang.org/api/option" monitoredrespb "google.golang.org/genproto/googleapis/api/monitoredres" loggingpb "google.golang.org/genproto/googleapis/logging/v2" field_maskpb "google.golang.org/genproto/protobuf/field_mask" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockConfigServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. loggingpb.ConfigServiceV2Server reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockConfigServer) ListSinks(ctx context.Context, req *loggingpb.ListSinksRequest) (*loggingpb.ListSinksResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*loggingpb.ListSinksResponse), nil } func (s *mockConfigServer) GetSink(ctx context.Context, req *loggingpb.GetSinkRequest) (*loggingpb.LogSink, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*loggingpb.LogSink), nil } func (s *mockConfigServer) CreateSink(ctx context.Context, req *loggingpb.CreateSinkRequest) (*loggingpb.LogSink, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*loggingpb.LogSink), nil } func (s *mockConfigServer) UpdateSink(ctx context.Context, req *loggingpb.UpdateSinkRequest) (*loggingpb.LogSink, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*loggingpb.LogSink), nil } func (s *mockConfigServer) DeleteSink(ctx context.Context, req *loggingpb.DeleteSinkRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockConfigServer) ListExclusions(ctx context.Context, req *loggingpb.ListExclusionsRequest) (*loggingpb.ListExclusionsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*loggingpb.ListExclusionsResponse), nil } func (s *mockConfigServer) GetExclusion(ctx context.Context, req *loggingpb.GetExclusionRequest) (*loggingpb.LogExclusion, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*loggingpb.LogExclusion), nil } func (s *mockConfigServer) CreateExclusion(ctx context.Context, req *loggingpb.CreateExclusionRequest) (*loggingpb.LogExclusion, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*loggingpb.LogExclusion), nil } func (s *mockConfigServer) UpdateExclusion(ctx context.Context, req *loggingpb.UpdateExclusionRequest) (*loggingpb.LogExclusion, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*loggingpb.LogExclusion), nil } func (s *mockConfigServer) DeleteExclusion(ctx context.Context, req *loggingpb.DeleteExclusionRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } type mockLoggingServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. loggingpb.LoggingServiceV2Server reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockLoggingServer) DeleteLog(ctx context.Context, req *loggingpb.DeleteLogRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockLoggingServer) WriteLogEntries(ctx context.Context, req *loggingpb.WriteLogEntriesRequest) (*loggingpb.WriteLogEntriesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*loggingpb.WriteLogEntriesResponse), nil } func (s *mockLoggingServer) ListLogEntries(ctx context.Context, req *loggingpb.ListLogEntriesRequest) (*loggingpb.ListLogEntriesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*loggingpb.ListLogEntriesResponse), nil } func (s *mockLoggingServer) ListMonitoredResourceDescriptors(ctx context.Context, req *loggingpb.ListMonitoredResourceDescriptorsRequest) (*loggingpb.ListMonitoredResourceDescriptorsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*loggingpb.ListMonitoredResourceDescriptorsResponse), nil } func (s *mockLoggingServer) ListLogs(ctx context.Context, req *loggingpb.ListLogsRequest) (*loggingpb.ListLogsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*loggingpb.ListLogsResponse), nil } type mockMetricsServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. loggingpb.MetricsServiceV2Server reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockMetricsServer) ListLogMetrics(ctx context.Context, req *loggingpb.ListLogMetricsRequest) (*loggingpb.ListLogMetricsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*loggingpb.ListLogMetricsResponse), nil } func (s *mockMetricsServer) GetLogMetric(ctx context.Context, req *loggingpb.GetLogMetricRequest) (*loggingpb.LogMetric, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*loggingpb.LogMetric), nil } func (s *mockMetricsServer) CreateLogMetric(ctx context.Context, req *loggingpb.CreateLogMetricRequest) (*loggingpb.LogMetric, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*loggingpb.LogMetric), nil } func (s *mockMetricsServer) UpdateLogMetric(ctx context.Context, req *loggingpb.UpdateLogMetricRequest) (*loggingpb.LogMetric, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*loggingpb.LogMetric), nil } func (s *mockMetricsServer) DeleteLogMetric(ctx context.Context, req *loggingpb.DeleteLogMetricRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockConfig mockConfigServer mockLogging mockLoggingServer mockMetrics mockMetricsServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() loggingpb.RegisterConfigServiceV2Server(serv, &mockConfig) loggingpb.RegisterLoggingServiceV2Server(serv, &mockLogging) loggingpb.RegisterMetricsServiceV2Server(serv, &mockMetrics) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestConfigServiceV2ListSinks(t *testing.T) { var nextPageToken string = "" var sinksElement *loggingpb.LogSink = &loggingpb.LogSink{} var sinks = []*loggingpb.LogSink{sinksElement} var expectedResponse = &loggingpb.ListSinksResponse{ NextPageToken: nextPageToken, Sinks: sinks, } mockConfig.err = nil mockConfig.reqs = nil mockConfig.resps = append(mockConfig.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &loggingpb.ListSinksRequest{ Parent: formattedParent, } c, err := NewConfigClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListSinks(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockConfig.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Sinks[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestConfigServiceV2ListSinksError(t *testing.T) { errCode := codes.PermissionDenied mockConfig.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &loggingpb.ListSinksRequest{ Parent: formattedParent, } c, err := NewConfigClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListSinks(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestConfigServiceV2GetSink(t *testing.T) { var name string = "name3373707" var destination string = "destination-1429847026" var filter string = "filter-1274492040" var writerIdentity string = "writerIdentity775638794" var includeChildren bool = true var expectedResponse = &loggingpb.LogSink{ Name: name, Destination: destination, Filter: filter, WriterIdentity: writerIdentity, IncludeChildren: includeChildren, } mockConfig.err = nil mockConfig.reqs = nil mockConfig.resps = append(mockConfig.resps[:0], expectedResponse) var formattedSinkName string = fmt.Sprintf("projects/%s/sinks/%s", "[PROJECT]", "[SINK]") var request = &loggingpb.GetSinkRequest{ SinkName: formattedSinkName, } c, err := NewConfigClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetSink(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockConfig.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestConfigServiceV2GetSinkError(t *testing.T) { errCode := codes.PermissionDenied mockConfig.err = gstatus.Error(errCode, "test error") var formattedSinkName string = fmt.Sprintf("projects/%s/sinks/%s", "[PROJECT]", "[SINK]") var request = &loggingpb.GetSinkRequest{ SinkName: formattedSinkName, } c, err := NewConfigClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetSink(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestConfigServiceV2CreateSink(t *testing.T) { var name string = "name3373707" var destination string = "destination-1429847026" var filter string = "filter-1274492040" var writerIdentity string = "writerIdentity775638794" var includeChildren bool = true var expectedResponse = &loggingpb.LogSink{ Name: name, Destination: destination, Filter: filter, WriterIdentity: writerIdentity, IncludeChildren: includeChildren, } mockConfig.err = nil mockConfig.reqs = nil mockConfig.resps = append(mockConfig.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var sink *loggingpb.LogSink = &loggingpb.LogSink{} var request = &loggingpb.CreateSinkRequest{ Parent: formattedParent, Sink: sink, } c, err := NewConfigClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateSink(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockConfig.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestConfigServiceV2CreateSinkError(t *testing.T) { errCode := codes.PermissionDenied mockConfig.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var sink *loggingpb.LogSink = &loggingpb.LogSink{} var request = &loggingpb.CreateSinkRequest{ Parent: formattedParent, Sink: sink, } c, err := NewConfigClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateSink(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestConfigServiceV2UpdateSink(t *testing.T) { var name string = "name3373707" var destination string = "destination-1429847026" var filter string = "filter-1274492040" var writerIdentity string = "writerIdentity775638794" var includeChildren bool = true var expectedResponse = &loggingpb.LogSink{ Name: name, Destination: destination, Filter: filter, WriterIdentity: writerIdentity, IncludeChildren: includeChildren, } mockConfig.err = nil mockConfig.reqs = nil mockConfig.resps = append(mockConfig.resps[:0], expectedResponse) var formattedSinkName string = fmt.Sprintf("projects/%s/sinks/%s", "[PROJECT]", "[SINK]") var sink *loggingpb.LogSink = &loggingpb.LogSink{} var request = &loggingpb.UpdateSinkRequest{ SinkName: formattedSinkName, Sink: sink, } c, err := NewConfigClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateSink(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockConfig.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestConfigServiceV2UpdateSinkError(t *testing.T) { errCode := codes.PermissionDenied mockConfig.err = gstatus.Error(errCode, "test error") var formattedSinkName string = fmt.Sprintf("projects/%s/sinks/%s", "[PROJECT]", "[SINK]") var sink *loggingpb.LogSink = &loggingpb.LogSink{} var request = &loggingpb.UpdateSinkRequest{ SinkName: formattedSinkName, Sink: sink, } c, err := NewConfigClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateSink(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestConfigServiceV2DeleteSink(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockConfig.err = nil mockConfig.reqs = nil mockConfig.resps = append(mockConfig.resps[:0], expectedResponse) var formattedSinkName string = fmt.Sprintf("projects/%s/sinks/%s", "[PROJECT]", "[SINK]") var request = &loggingpb.DeleteSinkRequest{ SinkName: formattedSinkName, } c, err := NewConfigClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteSink(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockConfig.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestConfigServiceV2DeleteSinkError(t *testing.T) { errCode := codes.PermissionDenied mockConfig.err = gstatus.Error(errCode, "test error") var formattedSinkName string = fmt.Sprintf("projects/%s/sinks/%s", "[PROJECT]", "[SINK]") var request = &loggingpb.DeleteSinkRequest{ SinkName: formattedSinkName, } c, err := NewConfigClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteSink(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestConfigServiceV2ListExclusions(t *testing.T) { var nextPageToken string = "" var exclusionsElement *loggingpb.LogExclusion = &loggingpb.LogExclusion{} var exclusions = []*loggingpb.LogExclusion{exclusionsElement} var expectedResponse = &loggingpb.ListExclusionsResponse{ NextPageToken: nextPageToken, Exclusions: exclusions, } mockConfig.err = nil mockConfig.reqs = nil mockConfig.resps = append(mockConfig.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &loggingpb.ListExclusionsRequest{ Parent: formattedParent, } c, err := NewConfigClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListExclusions(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockConfig.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Exclusions[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestConfigServiceV2ListExclusionsError(t *testing.T) { errCode := codes.PermissionDenied mockConfig.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &loggingpb.ListExclusionsRequest{ Parent: formattedParent, } c, err := NewConfigClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListExclusions(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestConfigServiceV2GetExclusion(t *testing.T) { var name2 string = "name2-1052831874" var description string = "description-1724546052" var filter string = "filter-1274492040" var disabled bool = true var expectedResponse = &loggingpb.LogExclusion{ Name: name2, Description: description, Filter: filter, Disabled: disabled, } mockConfig.err = nil mockConfig.reqs = nil mockConfig.resps = append(mockConfig.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/exclusions/%s", "[PROJECT]", "[EXCLUSION]") var request = &loggingpb.GetExclusionRequest{ Name: formattedName, } c, err := NewConfigClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetExclusion(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockConfig.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestConfigServiceV2GetExclusionError(t *testing.T) { errCode := codes.PermissionDenied mockConfig.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/exclusions/%s", "[PROJECT]", "[EXCLUSION]") var request = &loggingpb.GetExclusionRequest{ Name: formattedName, } c, err := NewConfigClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetExclusion(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestConfigServiceV2CreateExclusion(t *testing.T) { var name string = "name3373707" var description string = "description-1724546052" var filter string = "filter-1274492040" var disabled bool = true var expectedResponse = &loggingpb.LogExclusion{ Name: name, Description: description, Filter: filter, Disabled: disabled, } mockConfig.err = nil mockConfig.reqs = nil mockConfig.resps = append(mockConfig.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var exclusion *loggingpb.LogExclusion = &loggingpb.LogExclusion{} var request = &loggingpb.CreateExclusionRequest{ Parent: formattedParent, Exclusion: exclusion, } c, err := NewConfigClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateExclusion(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockConfig.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestConfigServiceV2CreateExclusionError(t *testing.T) { errCode := codes.PermissionDenied mockConfig.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var exclusion *loggingpb.LogExclusion = &loggingpb.LogExclusion{} var request = &loggingpb.CreateExclusionRequest{ Parent: formattedParent, Exclusion: exclusion, } c, err := NewConfigClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateExclusion(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestConfigServiceV2UpdateExclusion(t *testing.T) { var name2 string = "name2-1052831874" var description string = "description-1724546052" var filter string = "filter-1274492040" var disabled bool = true var expectedResponse = &loggingpb.LogExclusion{ Name: name2, Description: description, Filter: filter, Disabled: disabled, } mockConfig.err = nil mockConfig.reqs = nil mockConfig.resps = append(mockConfig.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/exclusions/%s", "[PROJECT]", "[EXCLUSION]") var exclusion *loggingpb.LogExclusion = &loggingpb.LogExclusion{} var updateMask *field_maskpb.FieldMask = &field_maskpb.FieldMask{} var request = &loggingpb.UpdateExclusionRequest{ Name: formattedName, Exclusion: exclusion, UpdateMask: updateMask, } c, err := NewConfigClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateExclusion(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockConfig.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestConfigServiceV2UpdateExclusionError(t *testing.T) { errCode := codes.PermissionDenied mockConfig.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/exclusions/%s", "[PROJECT]", "[EXCLUSION]") var exclusion *loggingpb.LogExclusion = &loggingpb.LogExclusion{} var updateMask *field_maskpb.FieldMask = &field_maskpb.FieldMask{} var request = &loggingpb.UpdateExclusionRequest{ Name: formattedName, Exclusion: exclusion, UpdateMask: updateMask, } c, err := NewConfigClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateExclusion(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestConfigServiceV2DeleteExclusion(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockConfig.err = nil mockConfig.reqs = nil mockConfig.resps = append(mockConfig.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/exclusions/%s", "[PROJECT]", "[EXCLUSION]") var request = &loggingpb.DeleteExclusionRequest{ Name: formattedName, } c, err := NewConfigClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteExclusion(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockConfig.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestConfigServiceV2DeleteExclusionError(t *testing.T) { errCode := codes.PermissionDenied mockConfig.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/exclusions/%s", "[PROJECT]", "[EXCLUSION]") var request = &loggingpb.DeleteExclusionRequest{ Name: formattedName, } c, err := NewConfigClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteExclusion(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestLoggingServiceV2DeleteLog(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockLogging.err = nil mockLogging.reqs = nil mockLogging.resps = append(mockLogging.resps[:0], expectedResponse) var formattedLogName string = fmt.Sprintf("projects/%s/logs/%s", "[PROJECT]", "[LOG]") var request = &loggingpb.DeleteLogRequest{ LogName: formattedLogName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteLog(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockLogging.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestLoggingServiceV2DeleteLogError(t *testing.T) { errCode := codes.PermissionDenied mockLogging.err = gstatus.Error(errCode, "test error") var formattedLogName string = fmt.Sprintf("projects/%s/logs/%s", "[PROJECT]", "[LOG]") var request = &loggingpb.DeleteLogRequest{ LogName: formattedLogName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteLog(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestLoggingServiceV2WriteLogEntries(t *testing.T) { var expectedResponse *loggingpb.WriteLogEntriesResponse = &loggingpb.WriteLogEntriesResponse{} mockLogging.err = nil mockLogging.reqs = nil mockLogging.resps = append(mockLogging.resps[:0], expectedResponse) var entries []*loggingpb.LogEntry = nil var request = &loggingpb.WriteLogEntriesRequest{ Entries: entries, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.WriteLogEntries(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockLogging.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestLoggingServiceV2WriteLogEntriesError(t *testing.T) { errCode := codes.PermissionDenied mockLogging.err = gstatus.Error(errCode, "test error") var entries []*loggingpb.LogEntry = nil var request = &loggingpb.WriteLogEntriesRequest{ Entries: entries, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.WriteLogEntries(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestLoggingServiceV2ListLogEntries(t *testing.T) { var nextPageToken string = "" var entriesElement *loggingpb.LogEntry = &loggingpb.LogEntry{} var entries = []*loggingpb.LogEntry{entriesElement} var expectedResponse = &loggingpb.ListLogEntriesResponse{ NextPageToken: nextPageToken, Entries: entries, } mockLogging.err = nil mockLogging.reqs = nil mockLogging.resps = append(mockLogging.resps[:0], expectedResponse) var formattedResourceNames []string = nil var request = &loggingpb.ListLogEntriesRequest{ ResourceNames: formattedResourceNames, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListLogEntries(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockLogging.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Entries[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestLoggingServiceV2ListLogEntriesError(t *testing.T) { errCode := codes.PermissionDenied mockLogging.err = gstatus.Error(errCode, "test error") var formattedResourceNames []string = nil var request = &loggingpb.ListLogEntriesRequest{ ResourceNames: formattedResourceNames, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListLogEntries(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestLoggingServiceV2ListMonitoredResourceDescriptors(t *testing.T) { var nextPageToken string = "" var resourceDescriptorsElement *monitoredrespb.MonitoredResourceDescriptor = &monitoredrespb.MonitoredResourceDescriptor{} var resourceDescriptors = []*monitoredrespb.MonitoredResourceDescriptor{resourceDescriptorsElement} var expectedResponse = &loggingpb.ListMonitoredResourceDescriptorsResponse{ NextPageToken: nextPageToken, ResourceDescriptors: resourceDescriptors, } mockLogging.err = nil mockLogging.reqs = nil mockLogging.resps = append(mockLogging.resps[:0], expectedResponse) var request *loggingpb.ListMonitoredResourceDescriptorsRequest = &loggingpb.ListMonitoredResourceDescriptorsRequest{} c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListMonitoredResourceDescriptors(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockLogging.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.ResourceDescriptors[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestLoggingServiceV2ListMonitoredResourceDescriptorsError(t *testing.T) { errCode := codes.PermissionDenied mockLogging.err = gstatus.Error(errCode, "test error") var request *loggingpb.ListMonitoredResourceDescriptorsRequest = &loggingpb.ListMonitoredResourceDescriptorsRequest{} c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListMonitoredResourceDescriptors(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestLoggingServiceV2ListLogs(t *testing.T) { var nextPageToken string = "" var logNamesElement string = "logNamesElement-1079688374" var logNames = []string{logNamesElement} var expectedResponse = &loggingpb.ListLogsResponse{ NextPageToken: nextPageToken, LogNames: logNames, } mockLogging.err = nil mockLogging.reqs = nil mockLogging.resps = append(mockLogging.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &loggingpb.ListLogsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListLogs(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockLogging.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.LogNames[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestLoggingServiceV2ListLogsError(t *testing.T) { errCode := codes.PermissionDenied mockLogging.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &loggingpb.ListLogsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListLogs(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestMetricsServiceV2ListLogMetrics(t *testing.T) { var nextPageToken string = "" var metricsElement *loggingpb.LogMetric = &loggingpb.LogMetric{} var metrics = []*loggingpb.LogMetric{metricsElement} var expectedResponse = &loggingpb.ListLogMetricsResponse{ NextPageToken: nextPageToken, Metrics: metrics, } mockMetrics.err = nil mockMetrics.reqs = nil mockMetrics.resps = append(mockMetrics.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &loggingpb.ListLogMetricsRequest{ Parent: formattedParent, } c, err := NewMetricsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListLogMetrics(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockMetrics.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Metrics[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestMetricsServiceV2ListLogMetricsError(t *testing.T) { errCode := codes.PermissionDenied mockMetrics.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &loggingpb.ListLogMetricsRequest{ Parent: formattedParent, } c, err := NewMetricsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListLogMetrics(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestMetricsServiceV2GetLogMetric(t *testing.T) { var name string = "name3373707" var description string = "description-1724546052" var filter string = "filter-1274492040" var valueExtractor string = "valueExtractor2047672534" var expectedResponse = &loggingpb.LogMetric{ Name: name, Description: description, Filter: filter, ValueExtractor: valueExtractor, } mockMetrics.err = nil mockMetrics.reqs = nil mockMetrics.resps = append(mockMetrics.resps[:0], expectedResponse) var formattedMetricName string = fmt.Sprintf("projects/%s/metrics/%s", "[PROJECT]", "[METRIC]") var request = &loggingpb.GetLogMetricRequest{ MetricName: formattedMetricName, } c, err := NewMetricsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetLogMetric(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockMetrics.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestMetricsServiceV2GetLogMetricError(t *testing.T) { errCode := codes.PermissionDenied mockMetrics.err = gstatus.Error(errCode, "test error") var formattedMetricName string = fmt.Sprintf("projects/%s/metrics/%s", "[PROJECT]", "[METRIC]") var request = &loggingpb.GetLogMetricRequest{ MetricName: formattedMetricName, } c, err := NewMetricsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetLogMetric(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestMetricsServiceV2CreateLogMetric(t *testing.T) { var name string = "name3373707" var description string = "description-1724546052" var filter string = "filter-1274492040" var valueExtractor string = "valueExtractor2047672534" var expectedResponse = &loggingpb.LogMetric{ Name: name, Description: description, Filter: filter, ValueExtractor: valueExtractor, } mockMetrics.err = nil mockMetrics.reqs = nil mockMetrics.resps = append(mockMetrics.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var metric *loggingpb.LogMetric = &loggingpb.LogMetric{} var request = &loggingpb.CreateLogMetricRequest{ Parent: formattedParent, Metric: metric, } c, err := NewMetricsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateLogMetric(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockMetrics.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestMetricsServiceV2CreateLogMetricError(t *testing.T) { errCode := codes.PermissionDenied mockMetrics.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var metric *loggingpb.LogMetric = &loggingpb.LogMetric{} var request = &loggingpb.CreateLogMetricRequest{ Parent: formattedParent, Metric: metric, } c, err := NewMetricsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateLogMetric(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestMetricsServiceV2UpdateLogMetric(t *testing.T) { var name string = "name3373707" var description string = "description-1724546052" var filter string = "filter-1274492040" var valueExtractor string = "valueExtractor2047672534" var expectedResponse = &loggingpb.LogMetric{ Name: name, Description: description, Filter: filter, ValueExtractor: valueExtractor, } mockMetrics.err = nil mockMetrics.reqs = nil mockMetrics.resps = append(mockMetrics.resps[:0], expectedResponse) var formattedMetricName string = fmt.Sprintf("projects/%s/metrics/%s", "[PROJECT]", "[METRIC]") var metric *loggingpb.LogMetric = &loggingpb.LogMetric{} var request = &loggingpb.UpdateLogMetricRequest{ MetricName: formattedMetricName, Metric: metric, } c, err := NewMetricsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateLogMetric(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockMetrics.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestMetricsServiceV2UpdateLogMetricError(t *testing.T) { errCode := codes.PermissionDenied mockMetrics.err = gstatus.Error(errCode, "test error") var formattedMetricName string = fmt.Sprintf("projects/%s/metrics/%s", "[PROJECT]", "[METRIC]") var metric *loggingpb.LogMetric = &loggingpb.LogMetric{} var request = &loggingpb.UpdateLogMetricRequest{ MetricName: formattedMetricName, Metric: metric, } c, err := NewMetricsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateLogMetric(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestMetricsServiceV2DeleteLogMetric(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockMetrics.err = nil mockMetrics.reqs = nil mockMetrics.resps = append(mockMetrics.resps[:0], expectedResponse) var formattedMetricName string = fmt.Sprintf("projects/%s/metrics/%s", "[PROJECT]", "[METRIC]") var request = &loggingpb.DeleteLogMetricRequest{ MetricName: formattedMetricName, } c, err := NewMetricsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteLogMetric(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockMetrics.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestMetricsServiceV2DeleteLogMetricError(t *testing.T) { errCode := codes.PermissionDenied mockMetrics.err = gstatus.Error(errCode, "test error") var formattedMetricName string = fmt.Sprintf("projects/%s/metrics/%s", "[PROJECT]", "[METRIC]") var request = &loggingpb.DeleteLogMetricRequest{ MetricName: formattedMetricName, } c, err := NewMetricsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteLogMetric(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } google-cloud-go-0.49.0/logging/apiv2/path_funcs.go000066400000000000000000000045711356504100700217270ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package logging // ConfigProjectPath returns the path for the project resource. // // Deprecated: Use // fmt.Sprintf("projects/%s", project) // instead. func ConfigProjectPath(project string) string { return "" + "projects/" + project + "" } // ConfigSinkPath returns the path for the sink resource. // // Deprecated: Use // fmt.Sprintf("projects/%s/sinks/%s", project, sink) // instead. func ConfigSinkPath(project, sink string) string { return "" + "projects/" + project + "/sinks/" + sink + "" } // ConfigExclusionPath returns the path for the exclusion resource. // // Deprecated: Use // fmt.Sprintf("projects/%s/exclusions/%s", project, exclusion) // instead. func ConfigExclusionPath(project, exclusion string) string { return "" + "projects/" + project + "/exclusions/" + exclusion + "" } // ProjectPath returns the path for the project resource. // // Deprecated: Use // fmt.Sprintf("projects/%s", project) // instead. func ProjectPath(project string) string { return "" + "projects/" + project + "" } // LogPath returns the path for the log resource. // // Deprecated: Use // fmt.Sprintf("projects/%s/logs/%s", project, log) // instead. func LogPath(project, log string) string { return "" + "projects/" + project + "/logs/" + log + "" } // MetricsProjectPath returns the path for the project resource. // // Deprecated: Use // fmt.Sprintf("projects/%s", project) // instead. func MetricsProjectPath(project string) string { return "" + "projects/" + project + "" } // MetricsMetricPath returns the path for the metric resource. // // Deprecated: Use // fmt.Sprintf("projects/%s/metrics/%s", project, metric) // instead. func MetricsMetricPath(project, metric string) string { return "" + "projects/" + project + "/metrics/" + metric + "" } google-cloud-go-0.49.0/logging/doc.go000066400000000000000000000101671356504100700173170ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. /* Package logging contains a Stackdriver Logging client suitable for writing logs. For reading logs, and working with sinks, metrics and monitored resources, see package cloud.google.com/go/logging/logadmin. This client uses Logging API v2. See https://cloud.google.com/logging/docs/api/v2/ for an introduction to the API. Creating a Client Use a Client to interact with the Stackdriver Logging API. // Create a Client ctx := context.Background() client, err := logging.NewClient(ctx, "my-project") if err != nil { // TODO: Handle error. } Basic Usage For most use cases, you'll want to add log entries to a buffer to be periodically flushed (automatically and asynchronously) to the Stackdriver Logging service. // Initialize a logger lg := client.Logger("my-log") // Add entry to log buffer lg.Log(logging.Entry{Payload: "something happened!"}) Closing your Client You should call Client.Close before your program exits to flush any buffered log entries to the Stackdriver Logging service. // Close the client when finished. err = client.Close() if err != nil { // TODO: Handle error. } Synchronous Logging For critical errors, you may want to send your log entries immediately. LogSync is slow and will block until the log entry has been sent, so it is not recommended for normal use. err = lg.LogSync(ctx, logging.Entry{Payload: "ALERT! Something critical happened!"}) if err != nil { // TODO: Handle error. } Payloads An entry payload can be a string, as in the examples above. It can also be any value that can be marshaled to a JSON object, like a map[string]interface{} or a struct: type MyEntry struct { Name string Count int } lg.Log(logging.Entry{Payload: MyEntry{Name: "Bob", Count: 3}}) If you have a []byte of JSON, wrap it in json.RawMessage: j := []byte(`{"Name": "Bob", "Count": 3}`) lg.Log(logging.Entry{Payload: json.RawMessage(j)}) The Standard Logger You may want use a standard log.Logger in your program. // stdlg is an instance of *log.Logger. stdlg := lg.StandardLogger(logging.Info) stdlg.Println("some info") Log Levels An Entry may have one of a number of severity levels associated with it. logging.Entry{ Payload: "something terrible happened!", Severity: logging.Critical, } Viewing Logs You can view Stackdriver logs for projects at https://console.cloud.google.com/logs/viewer. Use the dropdown at the top left. When running from a Google Cloud Platform VM, select "GCE VM Instance". Otherwise, select "Google Project" and then the project ID. Logs for organizations, folders and billing accounts can be viewed on the command line with the "gcloud logging read" command. Grouping Logs by Request To group all the log entries written during a single HTTP request, create two Loggers, a "parent" and a "child," with different log IDs. Both should be in the same project, and have the same MonitoredResource type and labels. - Parent entries must have HTTPRequest.Request populated. (Strictly speaking, only the URL is necessary.) - A child entry's timestamp must be within the time interval covered by the parent request. (i.e., before the parent.Timestamp and after the parent.Timestamp - parent.HTTPRequest.Latency. This assumes the parent.Timestamp marks the end of the request.) - The trace field must be populated in all of the entries and match exactly. You should observe the child log entries grouped under the parent on the console. The parent entry will not inherit the severity of its children; you must update the parent severity yourself. */ package logging // import "cloud.google.com/go/logging" google-cloud-go-0.49.0/logging/examples_test.go000066400000000000000000000117461356504100700214330ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package logging_test import ( "context" "encoding/json" "fmt" "os" "cloud.google.com/go/logging" "go.opencensus.io/trace" ) func ExampleNewClient() { ctx := context.Background() client, err := logging.NewClient(ctx, "my-project") if err != nil { // TODO: Handle error. } // Use client to manage logs, metrics and sinks. // Close the client when finished. if err := client.Close(); err != nil { // TODO: Handle error. } } func ExampleClient_Ping() { ctx := context.Background() client, err := logging.NewClient(ctx, "my-project") if err != nil { // TODO: Handle error. } if err := client.Ping(ctx); err != nil { // TODO: Handle error. } } // Although Logger.Flush and Client.Close both return errors, they don't tell you // whether the errors were frequent or significant. For most programs, it doesn't // matter if there were a few errors while writing logs, although if those few errors // indicated a bug in your program, you might want to know about them. The best way // to handle errors is by setting the OnError function. If it runs quickly, it will // see every error generated during logging. func ExampleNewClient_errorFunc() { ctx := context.Background() client, err := logging.NewClient(ctx, "my-project") if err != nil { // TODO: Handle error. } // Print all errors to stdout, and count them. Multiple calls to the OnError // function never happen concurrently, so there is no need for locking nErrs, // provided you don't read it until after the logging client is closed. var nErrs int client.OnError = func(e error) { fmt.Fprintf(os.Stdout, "logging: %v", e) nErrs++ } // Use client to manage logs, metrics and sinks. // Close the client when finished. if err := client.Close(); err != nil { // TODO: Handle error. } fmt.Printf("saw %d errors\n", nErrs) } func ExampleClient_Logger() { ctx := context.Background() client, err := logging.NewClient(ctx, "my-project") if err != nil { // TODO: Handle error. } lg := client.Logger("my-log") _ = lg // TODO: use the Logger. } func ExampleLogger_LogSync() { ctx := context.Background() client, err := logging.NewClient(ctx, "my-project") if err != nil { // TODO: Handle error. } lg := client.Logger("my-log") err = lg.LogSync(ctx, logging.Entry{Payload: "red alert"}) if err != nil { // TODO: Handle error. } } func ExampleLogger_Log() { ctx := context.Background() client, err := logging.NewClient(ctx, "my-project") if err != nil { // TODO: Handle error. } lg := client.Logger("my-log") lg.Log(logging.Entry{Payload: "something happened"}) } // An Entry payload can be anything that marshals to a // JSON object, like a struct. func ExampleLogger_Log_struct() { type MyEntry struct { Name string Count int } ctx := context.Background() client, err := logging.NewClient(ctx, "my-project") if err != nil { // TODO: Handle error. } lg := client.Logger("my-log") lg.Log(logging.Entry{Payload: MyEntry{Name: "Bob", Count: 3}}) } // To log a JSON value, wrap it in json.RawMessage. func ExampleLogger_Log_json() { ctx := context.Background() client, err := logging.NewClient(ctx, "my-project") if err != nil { // TODO: Handle error. } lg := client.Logger("my-log") j := []byte(`{"Name": "Bob", "Count": 3}`) lg.Log(logging.Entry{Payload: json.RawMessage(j)}) } func ExampleLogger_Flush() { ctx := context.Background() client, err := logging.NewClient(ctx, "my-project") if err != nil { // TODO: Handle error. } lg := client.Logger("my-log") lg.Log(logging.Entry{Payload: "something happened"}) lg.Flush() } func ExampleLogger_StandardLogger() { ctx := context.Background() client, err := logging.NewClient(ctx, "my-project") if err != nil { // TODO: Handle error. } lg := client.Logger("my-log") slg := lg.StandardLogger(logging.Info) slg.Println("an informative message") } func ExampleParseSeverity() { sev := logging.ParseSeverity("ALERT") fmt.Println(sev) // Output: Alert } // This example shows how to create a Logger that disables OpenCensus tracing of the // WriteLogEntries RPC. func ExampleContextFunc() { ctx := context.Background() client, err := logging.NewClient(ctx, "my-project") if err != nil { // TODO: Handle error. } lg := client.Logger("logID", logging.ContextFunc(func() (context.Context, func()) { ctx, span := trace.StartSpan(context.Background(), "this span will not be exported", trace.WithSampler(trace.NeverSample())) return ctx, span.End })) _ = lg // TODO: Use lg } google-cloud-go-0.49.0/logging/go.mod000066400000000000000000000011741356504100700173270ustar00rootroot00000000000000module cloud.google.com/go/logging go 1.11 require ( cloud.google.com/go v0.46.3 cloud.google.com/go/storage v1.0.0 github.com/golang/protobuf v1.3.2 github.com/google/go-cmp v0.3.0 github.com/googleapis/gax-go/v2 v2.0.5 go.opencensus.io v0.22.0 golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136 // indirect golang.org/x/lint v0.0.0-20190930215403-16217165b5de // indirect golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2 // indirect google.golang.org/api v0.14.0 google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9 google.golang.org/grpc v1.21.1 ) google-cloud-go-0.49.0/logging/go.sum000066400000000000000000000421631356504100700173570ustar00rootroot00000000000000cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3 h1:AVXDdKsrtX33oR9fbCMu/+c1o8Ofjq6Ku/MInaLVg5Y= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go/bigquery v1.0.1 h1:hL+ycaJpVE9M7nLoiXb/Pn10ENE2u+oddxbD8uu0ZVU= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/datastore v1.0.0 h1:Kt+gOPPp2LEPWp8CSfxhsM8ik9CcyE/gYu+0r+RnZvM= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/pubsub v1.0.1 h1:W9tAK3E57P75u0XLLR82LZyw8VpAnhmyTOxW9qzmyj8= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/storage v1.0.0 h1:VV2nUM3wwLLGh9lSABFgZMjInyUbJeaRSE64WuAIQ+4= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024 h1:rBMNdlhTLzJjJSDIjNEXX1Pz3Hmwmz91v+zycvx9PJc= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522 h1:OeRHuibLsmZkFj773W4LcfAGsSxJgfPONhr8cmO+eLA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979 h1:Agxu5KLo8o7Bb634SVDnhIfpTvxmzUwhbYAzBvXt6h4= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136 h1:A1gGSx58LAGVHUUsOf7IiR0u8Xb6W51gRwfDBhkdcaw= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422 h1:QzoH/1pFpZguR8NrRHLcO6jKqfv2zpuSqZLgdm7ZmjI= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac h1:8R1esu+8QioDxo4E4mX6bFztO+dMTM49DNAaWfO5OeY= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0 h1:HyfiK1WMnHj5FXFXatD+Qs1A/xC2Run6RzeW1SyHxpc= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0 h1:Dh6fw+p6FyRl5x/FvNswO1ji0lIGzm3KP8Y9VkS9PTE= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff h1:On1qIo75ByTwFJ4/W2bIqHcwJ9XAqtSWUs8GwRrIhtc= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2 h1:EtTFh6h4SAKemS+CURDMTDIANuduG5zKEXShyy18bGA= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0 h1:9sdfJOzWlkqPltHAuzT2Cp+yrBeY1KRVYgms8soxMwM= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0 h1:jbyannxz0XFD3zdjgrSUsaJbgpH4eTrkdhRChkHPfO8= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.14.0 h1:uMf5uLi4eQMRrMKhCplNik4U4H8Z6C1br3zOtAa/aDE= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51 h1:Ex1mq5jaJof+kRnYi3SlYJ8KKa9Ao3NHyIT5XJ1gF6U= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9 h1:6XzpBoANz1NqMNfDXzc2QmHmbb1vyMsvRfoP5rM+K1I= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1 h1:j6XxA85m/6txkUCHvzlV5f+HBNl/1r5cZ2A/3IEFOO8= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a h1:LJwr7TCTghdatWv40WobzlKXc9c4s8oGa7QKJUtHhWA= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= google-cloud-go-0.49.0/logging/go_mod_tidy_hack.go000066400000000000000000000016261356504100700220350ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // This file, and the cloud.google.com/go import, won't actually become part of // the resultant binary. // +build modhack package logging // Necessary for safely adding multi-module repo. See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository import _ "cloud.google.com/go" google-cloud-go-0.49.0/logging/internal/000077500000000000000000000000001356504100700200325ustar00rootroot00000000000000google-cloud-go-0.49.0/logging/internal/common.go000066400000000000000000000022521356504100700216520ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package internal import ( "fmt" "strings" ) const ( // ProdAddr is the production address. ProdAddr = "logging.googleapis.com:443" ) // LogPath creates a formatted path from a parent and a logID. func LogPath(parent, logID string) string { logID = strings.Replace(logID, "/", "%2F", -1) return fmt.Sprintf("%s/logs/%s", parent, logID) } // LogIDFromPath parses and returns the ID from a log path. func LogIDFromPath(parent, path string) string { start := len(parent) + len("/logs/") if len(path) < start { return "" } logID := path[start:] return strings.Replace(logID, "%2F", "/", -1) } google-cloud-go-0.49.0/logging/internal/testing/000077500000000000000000000000001356504100700215075ustar00rootroot00000000000000google-cloud-go-0.49.0/logging/internal/testing/equal.go000066400000000000000000000020431356504100700231440ustar00rootroot00000000000000/* Copyright 2017 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package testing import ( "fmt" "github.com/golang/protobuf/proto" ) // PayloadEqual compares two payloads, assuming they are both proto.Messages or both strings. func PayloadEqual(a, b interface{}) bool { if a == nil && b == nil { return true } if a == nil || b == nil { return false } switch a := a.(type) { case proto.Message: return proto.Equal(a, b.(proto.Message)) case string: return a == b.(string) default: panic(fmt.Sprintf("payloadEqual: unexpected type %T", a)) } } google-cloud-go-0.49.0/logging/internal/testing/fake.go000066400000000000000000000321401356504100700227440ustar00rootroot00000000000000/* Copyright 2016 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // Package testing provides support for testing the logging client. package testing import ( "context" "errors" "fmt" "regexp" "sort" "strings" "sync" "time" "cloud.google.com/go/internal/testutil" emptypb "github.com/golang/protobuf/ptypes/empty" tspb "github.com/golang/protobuf/ptypes/timestamp" lpb "google.golang.org/genproto/googleapis/api/label" mrpb "google.golang.org/genproto/googleapis/api/monitoredres" logpb "google.golang.org/genproto/googleapis/logging/v2" ) type loggingHandler struct { logpb.LoggingServiceV2Server mu sync.Mutex logs map[string][]*logpb.LogEntry // indexed by log name } type configHandler struct { logpb.ConfigServiceV2Server mu sync.Mutex sinks map[string]*logpb.LogSink // indexed by (full) sink name } type metricHandler struct { logpb.MetricsServiceV2Server mu sync.Mutex metrics map[string]*logpb.LogMetric // indexed by (full) metric name } // NewServer creates a new in-memory fake server implementing the logging service. // It returns the address of the server. func NewServer() (string, error) { srv, err := testutil.NewServer() if err != nil { return "", err } logpb.RegisterLoggingServiceV2Server(srv.Gsrv, &loggingHandler{ logs: make(map[string][]*logpb.LogEntry), }) logpb.RegisterConfigServiceV2Server(srv.Gsrv, &configHandler{ sinks: make(map[string]*logpb.LogSink), }) logpb.RegisterMetricsServiceV2Server(srv.Gsrv, &metricHandler{ metrics: make(map[string]*logpb.LogMetric), }) srv.Start() return srv.Addr, nil } // DeleteLog deletes a log and all its log entries. The log will reappear if it // receives new entries. func (h *loggingHandler) DeleteLog(_ context.Context, req *logpb.DeleteLogRequest) (*emptypb.Empty, error) { // TODO(jba): return NotFound if log isn't there? h.mu.Lock() defer h.mu.Unlock() delete(h.logs, req.LogName) return &emptypb.Empty{}, nil } // The only IDs that WriteLogEntries will accept. // Important for testing Ping. const ( ValidProjectID = "PROJECT_ID" ValidOrgID = "433637338589" SharedServiceAccount = "serviceAccount:cloud-logs@system.gserviceaccount.com" ) // WriteLogEntries writes log entries to Stackdriver Logging. All log entries in // Stackdriver Logging are written by this method. func (h *loggingHandler) WriteLogEntries(_ context.Context, req *logpb.WriteLogEntriesRequest) (*logpb.WriteLogEntriesResponse, error) { if !strings.HasPrefix(req.LogName, "projects/"+ValidProjectID+"/") && !strings.HasPrefix(req.LogName, "organizations/"+ValidOrgID+"/") { return nil, fmt.Errorf("bad LogName: %q", req.LogName) } // TODO(jba): support insertId? h.mu.Lock() defer h.mu.Unlock() for _, e := range req.Entries { // Assign timestamp if missing. if e.Timestamp == nil { e.Timestamp = &tspb.Timestamp{Seconds: time.Now().Unix(), Nanos: 0} } // Fill from common fields in request. if e.LogName == "" { e.LogName = req.LogName } if e.Resource == nil { // TODO(jba): use a global one if nil? e.Resource = req.Resource } for k, v := range req.Labels { if _, ok := e.Labels[k]; !ok { e.Labels[k] = v } } // Store by log name. h.logs[e.LogName] = append(h.logs[e.LogName], e) } return &logpb.WriteLogEntriesResponse{}, nil } // ListLogEntries lists log entries. Use this method to retrieve log entries // from Stackdriver Logging. // // This fake implementation ignores project IDs. It does not support full filtering, only // expressions of the form "logName = NAME". func (h *loggingHandler) ListLogEntries(_ context.Context, req *logpb.ListLogEntriesRequest) (*logpb.ListLogEntriesResponse, error) { h.mu.Lock() defer h.mu.Unlock() entries, err := h.filterEntries(req.Filter) if err != nil { return nil, err } if err = sortEntries(entries, req.OrderBy); err != nil { return nil, err } from, to, nextPageToken, err := testutil.PageBounds(int(req.PageSize), req.PageToken, len(entries)) if err != nil { return nil, err } return &logpb.ListLogEntriesResponse{ Entries: entries[from:to], NextPageToken: nextPageToken, }, nil } func (h *loggingHandler) filterEntries(filter string) ([]*logpb.LogEntry, error) { logName, err := parseFilter(filter) if err != nil { return nil, err } if logName != "" { return h.logs[logName], nil } var entries []*logpb.LogEntry for _, es := range h.logs { entries = append(entries, es...) } return entries, nil } var filterRegexp = regexp.MustCompile(`^logName\s*=\s*"?([-_/.%\w]+)"?`) // returns the log name, or "" for the empty filter func parseFilter(filter string) (string, error) { if filter == "" { return "", nil } subs := filterRegexp.FindStringSubmatch(filter) if subs == nil { return "", invalidArgument(fmt.Sprintf("fake.go: failed to parse filter %s", filter)) } return subs[1], nil // cannot panic by construction of regexp } func sortEntries(entries []*logpb.LogEntry, orderBy string) error { switch orderBy { case "", "timestamp asc": sort.Sort(byTimestamp(entries)) return nil case "timestamp desc": sort.Sort(sort.Reverse(byTimestamp(entries))) return nil default: return invalidArgument("bad order_by") } } type byTimestamp []*logpb.LogEntry func (s byTimestamp) Len() int { return len(s) } func (s byTimestamp) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (s byTimestamp) Less(i, j int) bool { c := compareTimestamps(s[i].Timestamp, s[j].Timestamp) switch { case c < 0: return true case c > 0: return false default: return s[i].InsertId < s[j].InsertId } } func compareTimestamps(ts1, ts2 *tspb.Timestamp) int64 { if ts1.Seconds != ts2.Seconds { return ts1.Seconds - ts2.Seconds } return int64(ts1.Nanos - ts2.Nanos) } // Lists monitored resource descriptors that are used by Stackdriver Logging. func (h *loggingHandler) ListMonitoredResourceDescriptors(context.Context, *logpb.ListMonitoredResourceDescriptorsRequest) (*logpb.ListMonitoredResourceDescriptorsResponse, error) { return &logpb.ListMonitoredResourceDescriptorsResponse{ ResourceDescriptors: []*mrpb.MonitoredResourceDescriptor{ { Type: "global", DisplayName: "Global", Description: "... a log is not associated with any specific resource.", Labels: []*lpb.LabelDescriptor{ {Key: "project_id", Description: "The identifier of the GCP project..."}, }, }, }, }, nil } // Lists logs. func (h *loggingHandler) ListLogs(_ context.Context, req *logpb.ListLogsRequest) (*logpb.ListLogsResponse, error) { // Return fixed, fake response. logNames := []string{"a", "b", "c"} from, to, npt, err := testutil.PageBounds(int(req.PageSize), req.PageToken, len(logNames)) if err != nil { return nil, err } var lns []string for _, ln := range logNames[from:to] { lns = append(lns, req.Parent+"/logs/"+ln) } return &logpb.ListLogsResponse{ LogNames: lns, NextPageToken: npt, }, nil } // Gets a sink. func (h *configHandler) GetSink(_ context.Context, req *logpb.GetSinkRequest) (*logpb.LogSink, error) { h.mu.Lock() defer h.mu.Unlock() if s, ok := h.sinks[req.SinkName]; ok { return s, nil } // TODO(jba): use error codes return nil, fmt.Errorf("sink %q not found", req.SinkName) } // Creates a sink. func (h *configHandler) CreateSink(_ context.Context, req *logpb.CreateSinkRequest) (*logpb.LogSink, error) { h.mu.Lock() defer h.mu.Unlock() fullName := fmt.Sprintf("%s/sinks/%s", req.Parent, req.Sink.Name) if _, ok := h.sinks[fullName]; ok { return nil, fmt.Errorf("sink with name %q already exists", fullName) } h.setSink(fullName, req.Sink, req.UniqueWriterIdentity) return req.Sink, nil } func (h *configHandler) setSink(name string, s *logpb.LogSink, uniqueWriterIdentity bool) { if uniqueWriterIdentity { s.WriterIdentity = "serviceAccount:" + name + "@gmail.com" } else { s.WriterIdentity = SharedServiceAccount } h.sinks[name] = s } // Creates or updates a sink. func (h *configHandler) UpdateSink(_ context.Context, req *logpb.UpdateSinkRequest) (*logpb.LogSink, error) { h.mu.Lock() defer h.mu.Unlock() sink := h.sinks[req.SinkName] // Update of a non-existent sink will create it. if sink == nil { h.setSink(req.SinkName, req.Sink, req.UniqueWriterIdentity) sink = req.Sink } else { // sink is the existing sink named req.SinkName. // Update all and only the fields of sink that are specified in the update mask. paths := req.UpdateMask.GetPaths() if len(paths) == 0 { // An empty update mask is considered to have these fields by default. paths = []string{"destination", "filter", "include_children"} } for _, p := range paths { switch p { case "destination": sink.Destination = req.Sink.Destination case "filter": sink.Filter = req.Sink.Filter case "include_children": sink.IncludeChildren = req.Sink.IncludeChildren case "output_version_format": // noop default: return nil, fmt.Errorf("unknown path in mask: %q", p) } } if req.UniqueWriterIdentity { if sink.WriterIdentity != SharedServiceAccount { return nil, invalidArgument("cannot change unique writer identity") } sink.WriterIdentity = "serviceAccount:" + req.SinkName + "@gmail.com" } } return sink, nil } // Deletes a sink. func (h *configHandler) DeleteSink(_ context.Context, req *logpb.DeleteSinkRequest) (*emptypb.Empty, error) { h.mu.Lock() defer h.mu.Unlock() delete(h.sinks, req.SinkName) return &emptypb.Empty{}, nil } // Lists sinks. This fake implementation ignores the Parent field of // ListSinksRequest. All sinks are listed, regardless of their project. func (h *configHandler) ListSinks(_ context.Context, req *logpb.ListSinksRequest) (*logpb.ListSinksResponse, error) { h.mu.Lock() var sinks []*logpb.LogSink for _, s := range h.sinks { sinks = append(sinks, s) } h.mu.Unlock() // safe because no *logpb.LogSink is ever modified // Since map iteration varies, sort the sinks. sort.Sort(sinksByName(sinks)) from, to, nextPageToken, err := testutil.PageBounds(int(req.PageSize), req.PageToken, len(sinks)) if err != nil { return nil, err } return &logpb.ListSinksResponse{ Sinks: sinks[from:to], NextPageToken: nextPageToken, }, nil } type sinksByName []*logpb.LogSink func (s sinksByName) Len() int { return len(s) } func (s sinksByName) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (s sinksByName) Less(i, j int) bool { return s[i].Name < s[j].Name } // Gets a metric. func (h *metricHandler) GetLogMetric(_ context.Context, req *logpb.GetLogMetricRequest) (*logpb.LogMetric, error) { h.mu.Lock() defer h.mu.Unlock() if s, ok := h.metrics[req.MetricName]; ok { return s, nil } // TODO(jba): use error codes return nil, fmt.Errorf("metric %q not found", req.MetricName) } // Creates a metric. func (h *metricHandler) CreateLogMetric(_ context.Context, req *logpb.CreateLogMetricRequest) (*logpb.LogMetric, error) { h.mu.Lock() defer h.mu.Unlock() fullName := fmt.Sprintf("%s/metrics/%s", req.Parent, req.Metric.Name) if _, ok := h.metrics[fullName]; ok { return nil, fmt.Errorf("metric with name %q already exists", fullName) } h.metrics[fullName] = req.Metric return req.Metric, nil } // Creates or updates a metric. func (h *metricHandler) UpdateLogMetric(_ context.Context, req *logpb.UpdateLogMetricRequest) (*logpb.LogMetric, error) { h.mu.Lock() defer h.mu.Unlock() // Update of a non-existent metric will create it. h.metrics[req.MetricName] = req.Metric return req.Metric, nil } // Deletes a metric. func (h *metricHandler) DeleteLogMetric(_ context.Context, req *logpb.DeleteLogMetricRequest) (*emptypb.Empty, error) { h.mu.Lock() defer h.mu.Unlock() delete(h.metrics, req.MetricName) return &emptypb.Empty{}, nil } // Lists metrics. This fake implementation ignores the Parent field of // ListMetricsRequest. All metrics are listed, regardless of their project. func (h *metricHandler) ListLogMetrics(_ context.Context, req *logpb.ListLogMetricsRequest) (*logpb.ListLogMetricsResponse, error) { h.mu.Lock() var metrics []*logpb.LogMetric for _, s := range h.metrics { metrics = append(metrics, s) } h.mu.Unlock() // safe because no *logpb.LogMetric is ever modified // Since map iteration varies, sort the metrics. sort.Sort(metricsByName(metrics)) from, to, nextPageToken, err := testutil.PageBounds(int(req.PageSize), req.PageToken, len(metrics)) if err != nil { return nil, err } return &logpb.ListLogMetricsResponse{ Metrics: metrics[from:to], NextPageToken: nextPageToken, }, nil } type metricsByName []*logpb.LogMetric func (s metricsByName) Len() int { return len(s) } func (s metricsByName) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (s metricsByName) Less(i, j int) bool { return s[i].Name < s[j].Name } func invalidArgument(msg string) error { // TODO(jba): status codes return errors.New(msg) } google-cloud-go-0.49.0/logging/internal/testing/fake_test.go000066400000000000000000000061511356504100700240060ustar00rootroot00000000000000/* Copyright 2016 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // This file contains only basic checks. The fake is effectively tested by the // logging client unit tests. package testing import ( "testing" "time" "github.com/golang/protobuf/proto" tspb "github.com/golang/protobuf/ptypes/timestamp" logpb "google.golang.org/genproto/googleapis/logging/v2" grpc "google.golang.org/grpc" ) func TestNewServer(t *testing.T) { // Confirm that we can create and use a working gRPC server. addr, err := NewServer() if err != nil { t.Fatal(err) } conn, err := grpc.Dial(addr, grpc.WithInsecure()) if err != nil { t.Fatal(err) } // Avoid "connection is closing; please retry" message from gRPC. time.Sleep(300 * time.Millisecond) conn.Close() } func TestParseFilter(t *testing.T) { for _, test := range []struct { filter string want string wantErr bool }{ {"", "", false}, {"logName = syslog", "syslog", false}, {"logname = syslog", "", true}, {"logName = 'syslog'", "", true}, {"logName == syslog", "", true}, } { got, err := parseFilter(test.filter) if err != nil { if !test.wantErr { t.Errorf("%q: got %v, want no error", test.filter, err) } continue } if test.wantErr { t.Errorf("%q: got no error, want one", test.filter) continue } if got != test.want { t.Errorf("%q: got %q, want %q", test.filter, got, test.want) } } } func TestSortEntries(t *testing.T) { entries := []*logpb.LogEntry{ /* 0 */ {Timestamp: &tspb.Timestamp{Seconds: 30}}, /* 1 */ {Timestamp: &tspb.Timestamp{Seconds: 10}}, /* 2 */ {Timestamp: &tspb.Timestamp{Seconds: 20}, InsertId: "b"}, /* 3 */ {Timestamp: &tspb.Timestamp{Seconds: 20}, InsertId: "a"}, /* 4 */ {Timestamp: &tspb.Timestamp{Seconds: 20}, InsertId: "c"}, } for _, test := range []struct { orderBy string want []int // slice of index into entries; nil == error }{ {"", []int{1, 3, 2, 4, 0}}, {"timestamp asc", []int{1, 3, 2, 4, 0}}, {"timestamp desc", []int{0, 4, 2, 3, 1}}, {"something else", nil}, } { got := make([]*logpb.LogEntry, len(entries)) copy(got, entries) err := sortEntries(got, test.orderBy) if err != nil { if test.want != nil { t.Errorf("%q: got %v, want nil error", test.orderBy, err) } continue } want := make([]*logpb.LogEntry, len(entries)) for i, j := range test.want { want[i] = entries[j] } if !logEntriesEqual(got, want) { t.Errorf("%q: got %v, want %v", test.orderBy, got, want) } } } func logEntriesEqual(a, b []*logpb.LogEntry) bool { if len(a) != len(b) { return false } for i, aa := range a { if !proto.Equal(aa, b[i]) { return false } } return true } google-cloud-go-0.49.0/logging/logadmin/000077500000000000000000000000001356504100700200105ustar00rootroot00000000000000google-cloud-go-0.49.0/logging/logadmin/example_entry_iterator_test.go000066400000000000000000000035311356504100700261650ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package logadmin_test import ( "context" "fmt" "time" "cloud.google.com/go/logging/logadmin" "google.golang.org/api/iterator" ) func ExampleClient_Entries() { ctx := context.Background() client, err := logadmin.NewClient(ctx, "my-project") if err != nil { // TODO: Handle error. } it := client.Entries(ctx, logadmin.Filter(`logName = "projects/my-project/logs/my-log"`)) _ = it // TODO: iterate using Next or iterator.Pager. } func ExampleFilter_timestamp() { // This example demonstrates how to list the last 24 hours of log entries. ctx := context.Background() client, err := logadmin.NewClient(ctx, "my-project") if err != nil { // TODO: Handle error. } oneDayAgo := time.Now().Add(-24 * time.Hour) t := oneDayAgo.Format(time.RFC3339) // Logging API wants timestamps in RFC 3339 format. it := client.Entries(ctx, logadmin.Filter(fmt.Sprintf(`timestamp > "%s"`, t))) _ = it // TODO: iterate using Next or iterator.Pager. } func ExampleEntryIterator_Next() { ctx := context.Background() client, err := logadmin.NewClient(ctx, "my-project") if err != nil { // TODO: Handle error. } it := client.Entries(ctx) for { entry, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } fmt.Println(entry) } } google-cloud-go-0.49.0/logging/logadmin/example_metric_iterator_test.go000066400000000000000000000024261356504100700263110ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package logadmin_test import ( "context" "fmt" "cloud.google.com/go/logging/logadmin" "google.golang.org/api/iterator" ) func ExampleClient_Metrics() { ctx := context.Background() client, err := logadmin.NewClient(ctx, "my-project") if err != nil { // TODO: Handle error. } it := client.Metrics(ctx) _ = it // TODO: iterate using Next or iterator.Pager. } func ExampleMetricIterator_Next() { ctx := context.Background() client, err := logadmin.NewClient(ctx, "my-project") if err != nil { // TODO: Handle error. } it := client.Metrics(ctx) for { metric, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } fmt.Println(metric) } } google-cloud-go-0.49.0/logging/logadmin/example_paging_test.go000066400000000000000000000051641356504100700243640ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package logadmin_test import ( "bytes" "context" "flag" "fmt" "html/template" "log" "net/http" "cloud.google.com/go/logging" "cloud.google.com/go/logging/logadmin" "google.golang.org/api/iterator" ) var ( client *logadmin.Client projectID = flag.String("project-id", "", "ID of the project to use") ) func ExampleClient_Entries_pagination() { // This example demonstrates how to iterate through items a page at a time // even if each successive page is fetched by a different process. It is a // complete web server that displays pages of log entries. To run it as a // standalone program, rename both the package and this function to "main". ctx := context.Background() flag.Parse() if *projectID == "" { log.Fatal("-project-id missing") } var err error client, err = logadmin.NewClient(ctx, *projectID) if err != nil { log.Fatalf("creating logging client: %v", err) } http.HandleFunc("/entries", handleEntries) log.Print("listening on 8080") log.Fatal(http.ListenAndServe(":8080", nil)) } var pageTemplate = template.Must(template.New("").Parse(`
{{range .Entries}} {{end}}
{{.}}
{{if .Next}} Next Page {{end}} `)) func handleEntries(w http.ResponseWriter, r *http.Request) { ctx := context.Background() filter := fmt.Sprintf(`logName = "projects/%s/logs/testlog"`, *projectID) it := client.Entries(ctx, logadmin.Filter(filter)) var entries []*logging.Entry nextTok, err := iterator.NewPager(it, 5, r.URL.Query().Get("pageToken")).NextPage(&entries) if err != nil { http.Error(w, fmt.Sprintf("problem getting the next page: %v", err), http.StatusInternalServerError) return } data := struct { Entries []*logging.Entry Next string }{ entries, nextTok, } var buf bytes.Buffer if err := pageTemplate.Execute(&buf, data); err != nil { http.Error(w, fmt.Sprintf("problem executing page template: %v", err), http.StatusInternalServerError) } if _, err := buf.WriteTo(w); err != nil { log.Printf("writing response: %v", err) } } google-cloud-go-0.49.0/logging/logadmin/example_resource_iterator_test.go000066400000000000000000000025041356504100700266520ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package logadmin_test import ( "context" "fmt" "cloud.google.com/go/logging/logadmin" "google.golang.org/api/iterator" ) func ExampleClient_ResourceDescriptors() { ctx := context.Background() client, err := logadmin.NewClient(ctx, "my-project") if err != nil { // TODO: Handle error. } it := client.ResourceDescriptors(ctx) _ = it // TODO: iterate using Next or iterator.Pager. } func ExampleResourceDescriptorIterator_Next() { ctx := context.Background() client, err := logadmin.NewClient(ctx, "my-project") if err != nil { // TODO: Handle error. } it := client.ResourceDescriptors(ctx) for { rdesc, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } fmt.Println(rdesc) } } google-cloud-go-0.49.0/logging/logadmin/example_sink_iterator_test.go000066400000000000000000000024121356504100700257650ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package logadmin_test import ( "context" "fmt" "cloud.google.com/go/logging/logadmin" "google.golang.org/api/iterator" ) func ExampleClient_Sinks() { ctx := context.Background() client, err := logadmin.NewClient(ctx, "my-project") if err != nil { // TODO: Handle error. } it := client.Sinks(ctx) _ = it // TODO: iterate using Next or iterator.Pager. } func ExampleSinkIterator_Next() { ctx := context.Background() client, err := logadmin.NewClient(ctx, "my-project") if err != nil { // TODO: Handle error. } it := client.Sinks(ctx) for { sink, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } fmt.Println(sink) } } google-cloud-go-0.49.0/logging/logadmin/examples_test.go000066400000000000000000000075031356504100700232210ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package logadmin_test import ( "context" "fmt" "cloud.google.com/go/logging/logadmin" ) func ExampleNewClient() { ctx := context.Background() client, err := logadmin.NewClient(ctx, "my-project") if err != nil { // TODO: Handle error. } // Use client to manage logs, metrics and sinks. // Close the client when finished. if err := client.Close(); err != nil { // TODO: Handle error. } } func ExampleClient_DeleteLog() { ctx := context.Background() client, err := logadmin.NewClient(ctx, "my-project") if err != nil { // TODO: Handle error. } err = client.DeleteLog(ctx, "my-log") if err != nil { // TODO: Handle error. } } func ExampleClient_CreateMetric() { ctx := context.Background() client, err := logadmin.NewClient(ctx, "my-project") if err != nil { // TODO: Handle error. } err = client.CreateMetric(ctx, &logadmin.Metric{ ID: "severe-errors", Description: "entries at ERROR or higher severities", Filter: "severity >= ERROR", }) if err != nil { // TODO: Handle error. } } func ExampleClient_DeleteMetric() { ctx := context.Background() client, err := logadmin.NewClient(ctx, "my-project") if err != nil { // TODO: Handle error. } if err := client.DeleteMetric(ctx, "severe-errors"); err != nil { // TODO: Handle error. } } func ExampleClient_Metric() { ctx := context.Background() client, err := logadmin.NewClient(ctx, "my-project") if err != nil { // TODO: Handle error. } m, err := client.Metric(ctx, "severe-errors") if err != nil { // TODO: Handle error. } fmt.Println(m) } func ExampleClient_UpdateMetric() { ctx := context.Background() client, err := logadmin.NewClient(ctx, "my-project") if err != nil { // TODO: Handle error. } err = client.UpdateMetric(ctx, &logadmin.Metric{ ID: "severe-errors", Description: "entries at high severities", Filter: "severity > ERROR", }) if err != nil { // TODO: Handle error. } } func ExampleClient_CreateSink() { ctx := context.Background() client, err := logadmin.NewClient(ctx, "my-project") if err != nil { // TODO: Handle error. } sink, err := client.CreateSink(ctx, &logadmin.Sink{ ID: "severe-errors-to-gcs", Destination: "storage.googleapis.com/my-bucket", Filter: "severity >= ERROR", }) if err != nil { // TODO: Handle error. } fmt.Println(sink) } func ExampleClient_DeleteSink() { ctx := context.Background() client, err := logadmin.NewClient(ctx, "my-project") if err != nil { // TODO: Handle error. } if err := client.DeleteSink(ctx, "severe-errors-to-gcs"); err != nil { // TODO: Handle error. } } func ExampleClient_Sink() { ctx := context.Background() client, err := logadmin.NewClient(ctx, "my-project") if err != nil { // TODO: Handle error. } s, err := client.Sink(ctx, "severe-errors-to-gcs") if err != nil { // TODO: Handle error. } fmt.Println(s) } func ExampleClient_UpdateSink() { ctx := context.Background() client, err := logadmin.NewClient(ctx, "my-project") if err != nil { // TODO: Handle error. } sink, err := client.UpdateSink(ctx, &logadmin.Sink{ ID: "severe-errors-to-gcs", Destination: "storage.googleapis.com/my-other-bucket", Filter: "severity >= ERROR", }) if err != nil { // TODO: Handle error. } fmt.Println(sink) } google-cloud-go-0.49.0/logging/logadmin/logadmin.go000066400000000000000000000313001356504100700221260ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // These features are missing now, but will likely be added: // - There is no way to specify CallOptions. // Package logadmin contains a Stackdriver Logging client that can be used // for reading logs and working with sinks, metrics and monitored resources. // For a client that can write logs, see package cloud.google.com/go/logging. // // The client uses Logging API v2. // See https://cloud.google.com/logging/docs/api/v2/ for an introduction to the API. // // Note: This package is in beta. Some backwards-incompatible changes may occur. package logadmin // import "cloud.google.com/go/logging/logadmin" import ( "context" "fmt" "net/http" "net/url" "strings" "time" "cloud.google.com/go/internal/version" "cloud.google.com/go/logging" vkit "cloud.google.com/go/logging/apiv2" "cloud.google.com/go/logging/internal" "github.com/golang/protobuf/ptypes" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" _ "google.golang.org/genproto/googleapis/appengine/logging/v1" // Import the following so EntryIterator can unmarshal log protos. _ "google.golang.org/genproto/googleapis/cloud/audit" logtypepb "google.golang.org/genproto/googleapis/logging/type" logpb "google.golang.org/genproto/googleapis/logging/v2" "google.golang.org/grpc/codes" ) // Client is a Logging client. A Client is associated with a single Cloud project. type Client struct { lClient *vkit.Client // logging client sClient *vkit.ConfigClient // sink client mClient *vkit.MetricsClient // metric client parent string closed bool } // NewClient returns a new logging client associated with the provided project ID. // // By default NewClient uses AdminScope. To use a different scope, call // NewClient using a WithScopes option (see https://godoc.org/google.golang.org/api/option#WithScopes). func NewClient(ctx context.Context, parent string, opts ...option.ClientOption) (*Client, error) { if !strings.ContainsRune(parent, '/') { parent = "projects/" + parent } opts = append([]option.ClientOption{ option.WithEndpoint(internal.ProdAddr), option.WithScopes(logging.AdminScope), }, opts...) lc, err := vkit.NewClient(ctx, opts...) if err != nil { return nil, err } // TODO(jba): pass along any client options that should be provided to all clients. sc, err := vkit.NewConfigClient(ctx, option.WithGRPCConn(lc.Connection())) if err != nil { return nil, err } mc, err := vkit.NewMetricsClient(ctx, option.WithGRPCConn(lc.Connection())) if err != nil { return nil, err } // Retry some non-idempotent methods on INTERNAL, because it happens sometimes // and in all observed cases the operation did not complete. retryerOnInternal := func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Internal, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 1000 * time.Millisecond, Multiplier: 1.2, }) } mc.CallOptions.CreateLogMetric = []gax.CallOption{gax.WithRetry(retryerOnInternal)} mc.CallOptions.UpdateLogMetric = []gax.CallOption{gax.WithRetry(retryerOnInternal)} lc.SetGoogleClientInfo("gccl", version.Repo) sc.SetGoogleClientInfo("gccl", version.Repo) mc.SetGoogleClientInfo("gccl", version.Repo) client := &Client{ lClient: lc, sClient: sc, mClient: mc, parent: parent, } return client, nil } // Close closes the client. func (c *Client) Close() error { if c.closed { return nil } // Return only the first error. Since all clients share an underlying connection, // Closes after the first always report a "connection is closing" error. err := c.lClient.Close() _ = c.sClient.Close() _ = c.mClient.Close() c.closed = true return err } // DeleteLog deletes a log and all its log entries. The log will reappear if it receives new entries. // logID identifies the log within the project. An example log ID is "syslog". Requires AdminScope. func (c *Client) DeleteLog(ctx context.Context, logID string) error { return c.lClient.DeleteLog(ctx, &logpb.DeleteLogRequest{ LogName: internal.LogPath(c.parent, logID), }) } func toHTTPRequest(p *logtypepb.HttpRequest) (*logging.HTTPRequest, error) { if p == nil { return nil, nil } u, err := url.Parse(p.RequestUrl) if err != nil { return nil, err } var dur time.Duration if p.Latency != nil { dur, err = ptypes.Duration(p.Latency) if err != nil { return nil, err } } hr := &http.Request{ Method: p.RequestMethod, URL: u, Header: map[string][]string{}, } if p.UserAgent != "" { hr.Header.Set("User-Agent", p.UserAgent) } if p.Referer != "" { hr.Header.Set("Referer", p.Referer) } return &logging.HTTPRequest{ Request: hr, RequestSize: p.RequestSize, Status: int(p.Status), ResponseSize: p.ResponseSize, Latency: dur, RemoteIP: p.RemoteIp, CacheHit: p.CacheHit, CacheValidatedWithOriginServer: p.CacheValidatedWithOriginServer, }, nil } // An EntriesOption is an option for listing log entries. type EntriesOption interface { set(*logpb.ListLogEntriesRequest) } // ProjectIDs sets the project IDs or project numbers from which to retrieve // log entries. Examples of a project ID: "my-project-1A", "1234567890". func ProjectIDs(pids []string) EntriesOption { return projectIDs(pids) } type projectIDs []string func (p projectIDs) set(r *logpb.ListLogEntriesRequest) { r.ResourceNames = make([]string, len(p)) for i, v := range p { r.ResourceNames[i] = fmt.Sprintf("projects/%s", v) } } // ResourceNames sets the resource names from which to retrieve // log entries. Examples: "projects/my-project-1A", "organizations/my-org". func ResourceNames(rns []string) EntriesOption { return resourceNames(rns) } type resourceNames []string func (rn resourceNames) set(r *logpb.ListLogEntriesRequest) { r.ResourceNames = append([]string(nil), rn...) } // Filter sets an advanced logs filter for listing log entries (see // https://cloud.google.com/logging/docs/view/advanced_filters). The filter is // compared against all log entries in the projects specified by ProjectIDs. // Only entries that match the filter are retrieved. An empty filter (the // default) matches all log entries. // // In the filter string, log names must be written in their full form, as // "projects/PROJECT-ID/logs/LOG-ID". Forward slashes in LOG-ID must be // replaced by %2F before calling Filter. // // Timestamps in the filter string must be written in RFC 3339 format. See the // timestamp example. func Filter(f string) EntriesOption { return filter(f) } type filter string func (f filter) set(r *logpb.ListLogEntriesRequest) { r.Filter = string(f) } // NewestFirst causes log entries to be listed from most recent (newest) to // least recent (oldest). By default, they are listed from oldest to newest. func NewestFirst() EntriesOption { return newestFirst{} } type newestFirst struct{} func (newestFirst) set(r *logpb.ListLogEntriesRequest) { r.OrderBy = "timestamp desc" } // Entries returns an EntryIterator for iterating over log entries. By default, // the log entries will be restricted to those from the project passed to // NewClient. This may be overridden by passing a ProjectIDs option. Requires ReadScope or AdminScope. func (c *Client) Entries(ctx context.Context, opts ...EntriesOption) *EntryIterator { it := &EntryIterator{ it: c.lClient.ListLogEntries(ctx, listLogEntriesRequest(c.parent, opts)), } it.pageInfo, it.nextFunc = iterator.NewPageInfo( it.fetch, func() int { return len(it.items) }, func() interface{} { b := it.items; it.items = nil; return b }) return it } func listLogEntriesRequest(parent string, opts []EntriesOption) *logpb.ListLogEntriesRequest { req := &logpb.ListLogEntriesRequest{ ResourceNames: []string{parent}, } for _, opt := range opts { opt.set(req) } return req } // An EntryIterator iterates over log entries. type EntryIterator struct { it *vkit.LogEntryIterator pageInfo *iterator.PageInfo nextFunc func() error items []*logging.Entry } // PageInfo supports pagination. See https://godoc.org/google.golang.org/api/iterator package for details. func (it *EntryIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done // (https://godoc.org/google.golang.org/api/iterator) if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *EntryIterator) Next() (*logging.Entry, error) { if err := it.nextFunc(); err != nil { return nil, err } item := it.items[0] it.items = it.items[1:] return item, nil } func (it *EntryIterator) fetch(pageSize int, pageToken string) (string, error) { return iterFetch(pageSize, pageToken, it.it.PageInfo(), func() error { item, err := it.it.Next() if err != nil { return err } e, err := fromLogEntry(item) if err != nil { return err } it.items = append(it.items, e) return nil }) } var slashUnescaper = strings.NewReplacer("%2F", "/", "%2f", "/") func fromLogEntry(le *logpb.LogEntry) (*logging.Entry, error) { time, err := ptypes.Timestamp(le.Timestamp) if err != nil { return nil, err } var payload interface{} switch x := le.Payload.(type) { case *logpb.LogEntry_TextPayload: payload = x.TextPayload case *logpb.LogEntry_ProtoPayload: var d ptypes.DynamicAny if err := ptypes.UnmarshalAny(x.ProtoPayload, &d); err != nil { return nil, fmt.Errorf("logging: unmarshalling proto payload: %v", err) } payload = d.Message case *logpb.LogEntry_JsonPayload: // Leave this as a Struct. // TODO(jba): convert to map[string]interface{}? payload = x.JsonPayload case nil: payload = nil default: return nil, fmt.Errorf("logging: unknown payload type: %T", le.Payload) } hr, err := toHTTPRequest(le.HttpRequest) if err != nil { return nil, err } return &logging.Entry{ Timestamp: time, Severity: logging.Severity(le.Severity), Payload: payload, Labels: le.Labels, InsertID: le.InsertId, HTTPRequest: hr, Operation: le.Operation, LogName: slashUnescaper.Replace(le.LogName), Resource: le.Resource, Trace: le.Trace, SourceLocation: le.SourceLocation, }, nil } // Logs lists the logs owned by the parent resource of the client. func (c *Client) Logs(ctx context.Context) *LogIterator { it := &LogIterator{ parentResource: c.parent, it: c.lClient.ListLogs(ctx, &logpb.ListLogsRequest{Parent: c.parent}), } it.pageInfo, it.nextFunc = iterator.NewPageInfo( it.fetch, func() int { return len(it.items) }, func() interface{} { b := it.items; it.items = nil; return b }) return it } // A LogIterator iterates over logs. type LogIterator struct { parentResource string it *vkit.StringIterator pageInfo *iterator.PageInfo nextFunc func() error items []string } // PageInfo supports pagination. See https://godoc.org/google.golang.org/api/iterator package for details. func (it *LogIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done // (https://godoc.org/google.golang.org/api/iterator) if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *LogIterator) Next() (string, error) { if err := it.nextFunc(); err != nil { return "", err } item := it.items[0] it.items = it.items[1:] return item, nil } func (it *LogIterator) fetch(pageSize int, pageToken string) (string, error) { return iterFetch(pageSize, pageToken, it.it.PageInfo(), func() error { logPath, err := it.it.Next() if err != nil { return err } logID := internal.LogIDFromPath(it.parentResource, logPath) it.items = append(it.items, logID) return nil }) } // Common fetch code for iterators that are backed by vkit iterators. func iterFetch(pageSize int, pageToken string, pi *iterator.PageInfo, next func() error) (string, error) { pi.MaxSize = pageSize pi.Token = pageToken // Get one item, which will fill the buffer. if err := next(); err != nil { return "", err } // Collect the rest of the buffer. for pi.Remaining() > 0 { if err := next(); err != nil { return "", err } } return pi.Token, nil } google-cloud-go-0.49.0/logging/logadmin/logadmin_test.go000066400000000000000000000206471356504100700232010ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // TODO(jba): test that OnError is getting called appropriately. package logadmin import ( "context" "flag" "log" "net/http" "net/url" "os" "testing" "time" "cloud.google.com/go/internal/testutil" "cloud.google.com/go/logging" ltesting "cloud.google.com/go/logging/internal/testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" durpb "github.com/golang/protobuf/ptypes/duration" structpb "github.com/golang/protobuf/ptypes/struct" "github.com/google/go-cmp/cmp/cmpopts" "google.golang.org/api/option" mrpb "google.golang.org/genproto/googleapis/api/monitoredres" audit "google.golang.org/genproto/googleapis/cloud/audit" logtypepb "google.golang.org/genproto/googleapis/logging/type" logpb "google.golang.org/genproto/googleapis/logging/v2" "google.golang.org/grpc" ) var ( client *Client testProjectID string ) var ( // If true, this test is using the production service, not a fake. integrationTest bool newClient func(ctx context.Context, projectID string) *Client ) func TestMain(m *testing.M) { flag.Parse() // needed for testing.Short() ctx := context.Background() testProjectID = testutil.ProjID() if testProjectID == "" || testing.Short() { integrationTest = false if testProjectID != "" { log.Print("Integration tests skipped in short mode (using fake instead)") } testProjectID = "PROJECT_ID" addr, err := ltesting.NewServer() if err != nil { log.Fatalf("creating fake server: %v", err) } newClient = func(ctx context.Context, projectID string) *Client { conn, err := grpc.Dial(addr, grpc.WithInsecure(), grpc.WithBlock()) if err != nil { log.Fatalf("dialing %q: %v", addr, err) } c, err := NewClient(ctx, projectID, option.WithGRPCConn(conn)) if err != nil { log.Fatalf("creating client for fake at %q: %v", addr, err) } return c } } else { // TODO(enocom): Delete this once we can get these tests to reliably pass. return integrationTest = true ts := testutil.TokenSource(ctx, logging.AdminScope) if ts == nil { log.Fatal("The project key must be set. See CONTRIBUTING.md for details") } log.Printf("running integration tests with project %s", testProjectID) newClient = func(ctx context.Context, projectID string) *Client { c, err := NewClient(ctx, projectID, option.WithTokenSource(ts), option.WithGRPCDialOption(grpc.WithBlock())) if err != nil { log.Fatalf("creating prod client: %v", err) } return c } } client = newClient(ctx, testProjectID) initMetrics(ctx) cleanup := initSinks(ctx) exit := m.Run() cleanup() client.Close() os.Exit(exit) } // EntryIterator and DeleteLog are tested in the logging package. func TestClientClose(t *testing.T) { c := newClient(context.Background(), testProjectID) if err := c.Close(); err != nil { t.Errorf("want got %v, want nil", err) } } func TestFromLogEntry(t *testing.T) { now := time.Now() res := &mrpb.MonitoredResource{Type: "global"} ts, err := ptypes.TimestampProto(now) if err != nil { t.Fatal(err) } logEntry := logpb.LogEntry{ LogName: "projects/PROJECT_ID/logs/LOG_ID", Resource: res, Payload: &logpb.LogEntry_TextPayload{TextPayload: "hello"}, Timestamp: ts, Severity: logtypepb.LogSeverity_INFO, InsertId: "123", HttpRequest: &logtypepb.HttpRequest{ RequestMethod: "GET", RequestUrl: "http:://example.com/path?q=1", RequestSize: 100, Status: 200, ResponseSize: 25, Latency: &durpb.Duration{Seconds: 100}, UserAgent: "user-agent", RemoteIp: "127.0.0.1", Referer: "referer", CacheHit: true, CacheValidatedWithOriginServer: true, }, Labels: map[string]string{ "a": "1", "b": "two", "c": "true", }, SourceLocation: &logpb.LogEntrySourceLocation{ File: "some_file.go", Line: 1, Function: "someFunction", }, } u, err := url.Parse("http:://example.com/path?q=1") if err != nil { t.Fatal(err) } want := &logging.Entry{ LogName: "projects/PROJECT_ID/logs/LOG_ID", Resource: res, Timestamp: now.In(time.UTC), Severity: logging.Info, Payload: "hello", Labels: map[string]string{ "a": "1", "b": "two", "c": "true", }, InsertID: "123", HTTPRequest: &logging.HTTPRequest{ Request: &http.Request{ Method: "GET", URL: u, Header: map[string][]string{ "User-Agent": {"user-agent"}, "Referer": {"referer"}, }, }, RequestSize: 100, Status: 200, ResponseSize: 25, Latency: 100 * time.Second, RemoteIP: "127.0.0.1", CacheHit: true, CacheValidatedWithOriginServer: true, }, SourceLocation: &logpb.LogEntrySourceLocation{ File: "some_file.go", Line: 1, Function: "someFunction", }, } got, err := fromLogEntry(&logEntry) if err != nil { t.Fatal(err) } if diff := testutil.Diff(got, want, cmpopts.IgnoreUnexported(http.Request{})); diff != "" { t.Errorf("FullEntry:\n%s", diff) } // Proto payload. alog := &audit.AuditLog{ ServiceName: "svc", MethodName: "method", ResourceName: "shelves/S/books/B", } any, err := ptypes.MarshalAny(alog) if err != nil { t.Fatal(err) } logEntry = logpb.LogEntry{ LogName: "projects/PROJECT_ID/logs/LOG_ID", Resource: res, Timestamp: ts, Payload: &logpb.LogEntry_ProtoPayload{ProtoPayload: any}, } got, err = fromLogEntry(&logEntry) if err != nil { t.Fatal(err) } if !ltesting.PayloadEqual(got.Payload, alog) { t.Errorf("got %+v, want %+v", got.Payload, alog) } // JSON payload. jstruct := &structpb.Struct{Fields: map[string]*structpb.Value{ "f": {Kind: &structpb.Value_NumberValue{NumberValue: 3.1}}, }} logEntry = logpb.LogEntry{ LogName: "projects/PROJECT_ID/logs/LOG_ID", Resource: res, Timestamp: ts, Payload: &logpb.LogEntry_JsonPayload{JsonPayload: jstruct}, } got, err = fromLogEntry(&logEntry) if err != nil { t.Fatal(err) } if !ltesting.PayloadEqual(got.Payload, jstruct) { t.Errorf("got %+v, want %+v", got.Payload, jstruct) } // No payload. logEntry = logpb.LogEntry{ LogName: "projects/PROJECT_ID/logs/LOG_ID", Resource: res, Timestamp: ts, } got, err = fromLogEntry(&logEntry) if err != nil { t.Fatal(err) } if !ltesting.PayloadEqual(got.Payload, nil) { t.Errorf("got %+v, want %+v", got.Payload, nil) } } func TestListLogEntriesRequest(t *testing.T) { for _, test := range []struct { opts []EntriesOption resourceNames []string filter string orderBy string }{ // Default is client's project ID, empty filter and orderBy. {nil, []string{"projects/PROJECT_ID"}, "", ""}, {[]EntriesOption{NewestFirst(), Filter("f")}, []string{"projects/PROJECT_ID"}, "f", "timestamp desc"}, {[]EntriesOption{ProjectIDs([]string{"foo"})}, []string{"projects/foo"}, "", ""}, {[]EntriesOption{ResourceNames([]string{"folders/F", "organizations/O"})}, []string{"folders/F", "organizations/O"}, "", ""}, {[]EntriesOption{NewestFirst(), Filter("f"), ProjectIDs([]string{"foo"})}, []string{"projects/foo"}, "f", "timestamp desc"}, {[]EntriesOption{NewestFirst(), Filter("f"), ProjectIDs([]string{"foo"})}, []string{"projects/foo"}, "f", "timestamp desc"}, // If there are repeats, last one wins. {[]EntriesOption{NewestFirst(), Filter("no"), ProjectIDs([]string{"foo"}), Filter("f")}, []string{"projects/foo"}, "f", "timestamp desc"}, } { got := listLogEntriesRequest("projects/PROJECT_ID", test.opts) want := &logpb.ListLogEntriesRequest{ ResourceNames: test.resourceNames, Filter: test.filter, OrderBy: test.orderBy, } if !proto.Equal(got, want) { t.Errorf("%v:\ngot %v\nwant %v", test.opts, got, want) } } } google-cloud-go-0.49.0/logging/logadmin/metrics.go000066400000000000000000000114461356504100700220130ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package logadmin import ( "context" "fmt" vkit "cloud.google.com/go/logging/apiv2" "google.golang.org/api/iterator" logpb "google.golang.org/genproto/googleapis/logging/v2" ) // Metric describes a logs-based metric. The value of the metric is the // number of log entries that match a logs filter. // // Metrics are a feature of Stackdriver Monitoring. // See https://cloud.google.com/monitoring/api/v3/metrics for more about them. type Metric struct { // ID is a client-assigned metric identifier. Example: // "severe_errors". Metric identifiers are limited to 1000 // characters and can include only the following characters: A-Z, // a-z, 0-9, and the special characters _-.,+!*',()%/\. The // forward-slash character (/) denotes a hierarchy of name pieces, // and it cannot be the first character of the name. ID string // Description describes this metric. It is used in documentation. Description string // Filter is an advanced logs filter (see // https://cloud.google.com/logging/docs/view/advanced_filters). // Example: "logName:syslog AND severity>=ERROR". Filter string } // CreateMetric creates a logs-based metric. func (c *Client) CreateMetric(ctx context.Context, m *Metric) error { _, err := c.mClient.CreateLogMetric(ctx, &logpb.CreateLogMetricRequest{ Parent: c.parent, Metric: toLogMetric(m), }) return err } // DeleteMetric deletes a log-based metric. // The provided metric ID is the metric identifier. For example, "severe_errors". func (c *Client) DeleteMetric(ctx context.Context, metricID string) error { return c.mClient.DeleteLogMetric(ctx, &logpb.DeleteLogMetricRequest{ MetricName: c.metricPath(metricID), }) } // Metric gets a logs-based metric. // The provided metric ID is the metric identifier. For example, "severe_errors". // Requires ReadScope or AdminScope. func (c *Client) Metric(ctx context.Context, metricID string) (*Metric, error) { lm, err := c.mClient.GetLogMetric(ctx, &logpb.GetLogMetricRequest{ MetricName: c.metricPath(metricID), }) if err != nil { return nil, err } return fromLogMetric(lm), nil } // UpdateMetric creates a logs-based metric if it does not exist, or updates an // existing one. func (c *Client) UpdateMetric(ctx context.Context, m *Metric) error { _, err := c.mClient.UpdateLogMetric(ctx, &logpb.UpdateLogMetricRequest{ MetricName: c.metricPath(m.ID), Metric: toLogMetric(m), }) return err } func (c *Client) metricPath(metricID string) string { return fmt.Sprintf("%s/metrics/%s", c.parent, metricID) } // Metrics returns a MetricIterator for iterating over all Metrics in the Client's project. // Requires ReadScope or AdminScope. func (c *Client) Metrics(ctx context.Context) *MetricIterator { it := &MetricIterator{ it: c.mClient.ListLogMetrics(ctx, &logpb.ListLogMetricsRequest{Parent: c.parent}), } it.pageInfo, it.nextFunc = iterator.NewPageInfo( it.fetch, func() int { return len(it.items) }, func() interface{} { b := it.items; it.items = nil; return b }) return it } // A MetricIterator iterates over Metrics. type MetricIterator struct { it *vkit.LogMetricIterator pageInfo *iterator.PageInfo nextFunc func() error items []*Metric } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *MetricIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is Done if there are // no more results. Once Next returns Done, all subsequent calls will return // Done. func (it *MetricIterator) Next() (*Metric, error) { if err := it.nextFunc(); err != nil { return nil, err } item := it.items[0] it.items = it.items[1:] return item, nil } func (it *MetricIterator) fetch(pageSize int, pageToken string) (string, error) { return iterFetch(pageSize, pageToken, it.it.PageInfo(), func() error { item, err := it.it.Next() if err != nil { return err } it.items = append(it.items, fromLogMetric(item)) return nil }) } func toLogMetric(m *Metric) *logpb.LogMetric { return &logpb.LogMetric{ Name: m.ID, Description: m.Description, Filter: m.Filter, } } func fromLogMetric(lm *logpb.LogMetric) *Metric { return &Metric{ ID: lm.Name, Description: lm.Description, Filter: lm.Filter, } } google-cloud-go-0.49.0/logging/logadmin/metrics_test.go000066400000000000000000000070231356504100700230460ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package logadmin import ( "context" "log" "testing" "time" "cloud.google.com/go/internal/testutil" "cloud.google.com/go/internal/uid" "google.golang.org/api/iterator" ) var metricIDs = uid.NewSpace("GO-CLIENT-TEST-METRIC", nil) // Initializes the tests before they run. func initMetrics(ctx context.Context) { // Clean up from aborted tests. it := client.Metrics(ctx) loop: for { m, err := it.Next() switch err { case nil: if metricIDs.Older(m.ID, 24*time.Hour) { client.DeleteMetric(ctx, m.ID) } case iterator.Done: break loop default: log.Printf("cleanupMetrics: %v", err) return } } } func TestCreateDeleteMetric(t *testing.T) { ctx := context.Background() metric := &Metric{ ID: metricIDs.New(), Description: "DESC", Filter: "FILTER", } if err := client.CreateMetric(ctx, metric); err != nil { t.Fatal(err) } defer client.DeleteMetric(ctx, metric.ID) got, err := client.Metric(ctx, metric.ID) if err != nil { t.Fatal(err) } if want := metric; !testutil.Equal(got, want) { t.Errorf("got %+v, want %+v", got, want) } if err := client.DeleteMetric(ctx, metric.ID); err != nil { t.Fatal(err) } if _, err := client.Metric(ctx, metric.ID); err == nil { t.Fatal("got no error, expected one") } } func TestUpdateMetric(t *testing.T) { ctx := context.Background() metric := &Metric{ ID: metricIDs.New(), Description: "DESC", Filter: "FILTER", } // Updating a non-existent metric creates a new one. if err := client.UpdateMetric(ctx, metric); err != nil { t.Fatal(err) } defer client.DeleteMetric(ctx, metric.ID) got, err := client.Metric(ctx, metric.ID) if err != nil { t.Fatal(err) } if want := metric; !testutil.Equal(got, want) { t.Errorf("got %+v, want %+v", got, want) } // Updating an existing metric changes it. metric.Description = "CHANGED" if err := client.UpdateMetric(ctx, metric); err != nil { t.Fatal(err) } got, err = client.Metric(ctx, metric.ID) if err != nil { t.Fatal(err) } if want := metric; !testutil.Equal(got, want) { t.Errorf("got %+v, want %+v", got, want) } } func TestListMetrics(t *testing.T) { ctx := context.Background() var metrics []*Metric want := map[string]*Metric{} for i := 0; i < 10; i++ { m := &Metric{ ID: metricIDs.New(), Description: "DESC", Filter: "FILTER", } metrics = append(metrics, m) want[m.ID] = m } for _, m := range metrics { if err := client.CreateMetric(ctx, m); err != nil { t.Fatalf("Create(%q): %v", m.ID, err) } defer client.DeleteMetric(ctx, m.ID) } got := map[string]*Metric{} it := client.Metrics(ctx) for { m, err := it.Next() if err == iterator.Done { break } if err != nil { t.Fatal(err) } // If tests run simultaneously, we may have more metrics than we // created. So only check for our own. if _, ok := want[m.ID]; ok { got[m.ID] = m } } if !testutil.Equal(got, want) { t.Errorf("got %+v, want %+v", got, want) } } google-cloud-go-0.49.0/logging/logadmin/resources.go000066400000000000000000000052571356504100700223620ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package logadmin import ( "context" vkit "cloud.google.com/go/logging/apiv2" "google.golang.org/api/iterator" mrpb "google.golang.org/genproto/googleapis/api/monitoredres" logpb "google.golang.org/genproto/googleapis/logging/v2" ) // ResourceDescriptors returns a ResourceDescriptorIterator // for iterating over MonitoredResourceDescriptors. Requires ReadScope or AdminScope. // See https://cloud.google.com/logging/docs/api/v2/#monitored-resources for an explanation of // monitored resources. // See https://cloud.google.com/logging/docs/api/v2/resource-list for a list of monitored resources. func (c *Client) ResourceDescriptors(ctx context.Context) *ResourceDescriptorIterator { it := &ResourceDescriptorIterator{ it: c.lClient.ListMonitoredResourceDescriptors(ctx, &logpb.ListMonitoredResourceDescriptorsRequest{}), } it.pageInfo, it.nextFunc = iterator.NewPageInfo( it.fetch, func() int { return len(it.items) }, func() interface{} { b := it.items; it.items = nil; return b }) return it } // ResourceDescriptorIterator is an iterator over MonitoredResourceDescriptors. type ResourceDescriptorIterator struct { it *vkit.MonitoredResourceDescriptorIterator pageInfo *iterator.PageInfo nextFunc func() error items []*mrpb.MonitoredResourceDescriptor } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *ResourceDescriptorIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is Done if there are // no more results. Once Next returns Done, all subsequent calls will return // Done. func (it *ResourceDescriptorIterator) Next() (*mrpb.MonitoredResourceDescriptor, error) { if err := it.nextFunc(); err != nil { return nil, err } item := it.items[0] it.items = it.items[1:] return item, nil } func (it *ResourceDescriptorIterator) fetch(pageSize int, pageToken string) (string, error) { return iterFetch(pageSize, pageToken, it.it.PageInfo(), func() error { item, err := it.it.Next() if err != nil { return err } it.items = append(it.items, item) return nil }) } google-cloud-go-0.49.0/logging/logadmin/resources_test.go000066400000000000000000000023101356504100700234040ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package logadmin import ( "context" "testing" "google.golang.org/api/iterator" ) func TestMonitoredResourceDescriptors(t *testing.T) { // We can't create MonitoredResourceDescriptors, and there is no guarantee // about what the service will return. So we just check that the result is // non-empty. it := client.ResourceDescriptors(context.Background()) n := 0 loop: for { _, err := it.Next() switch err { case nil: n++ case iterator.Done: break loop default: t.Fatal(err) } } if n == 0 { t.Fatal("Next: got no MetricResourceDescriptors, expected at least one") } // TODO(jba) test pagination. } google-cloud-go-0.49.0/logging/logadmin/sinks.go000066400000000000000000000223611356504100700214720ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package logadmin import ( "context" "errors" "fmt" vkit "cloud.google.com/go/logging/apiv2" "google.golang.org/api/iterator" logpb "google.golang.org/genproto/googleapis/logging/v2" maskpb "google.golang.org/genproto/protobuf/field_mask" ) // Sink describes a sink used to export log entries outside Stackdriver // Logging. Incoming log entries matching a filter are exported to a // destination (a Cloud Storage bucket, BigQuery dataset or Cloud Pub/Sub // topic). // // For more information, see https://cloud.google.com/logging/docs/export/using_exported_logs. // (The Sinks in this package are what the documentation refers to as "project sinks".) type Sink struct { // ID is a client-assigned sink identifier. Example: // "my-severe-errors-to-pubsub". // Sink identifiers are limited to 1000 characters // and can include only the following characters: A-Z, a-z, // 0-9, and the special characters "_-.". ID string // Destination is the export destination. See // https://cloud.google.com/logging/docs/api/tasks/exporting-logs. // Examples: "storage.googleapis.com/a-bucket", // "bigquery.googleapis.com/projects/a-project-id/datasets/a-dataset". Destination string // Filter optionally specifies an advanced logs filter (see // https://cloud.google.com/logging/docs/view/advanced_filters) that // defines the log entries to be exported. Example: "logName:syslog AND // severity>=ERROR". If omitted, all entries are returned. Filter string // WriterIdentity must be a service account name. When exporting logs, Logging // adopts this identity for authorization. The export destination's owner must // give this service account permission to write to the export destination. WriterIdentity string // IncludeChildren, when set to true, allows the sink to export log entries from // the organization or folder, plus (recursively) from any contained folders, billing // accounts, or projects. IncludeChildren is false by default. You can use the sink's // filter to choose log entries from specific projects, specific resource types, or // specific named logs. // // Caution: If you enable this feature, your aggregated export sink might export // a very large number of log entries. To avoid exporting too many log entries, // design your aggregated export sink filter carefully, as described on // https://cloud.google.com/logging/docs/export/aggregated_exports. IncludeChildren bool } // CreateSink creates a Sink. It returns an error if the Sink already exists. // Requires AdminScope. func (c *Client) CreateSink(ctx context.Context, sink *Sink) (*Sink, error) { return c.CreateSinkOpt(ctx, sink, SinkOptions{}) } // CreateSinkOpt creates a Sink using the provided options. It returns an // error if the Sink already exists. Requires AdminScope. func (c *Client) CreateSinkOpt(ctx context.Context, sink *Sink, opts SinkOptions) (*Sink, error) { ls, err := c.sClient.CreateSink(ctx, &logpb.CreateSinkRequest{ Parent: c.parent, Sink: toLogSink(sink), UniqueWriterIdentity: opts.UniqueWriterIdentity, }) if err != nil { return nil, err } return fromLogSink(ls), nil } // SinkOptions define options to be used when creating or updating a sink. type SinkOptions struct { // Determines the kind of IAM identity returned as WriterIdentity in the new // sink. If this value is omitted or set to false, and if the sink's parent is a // project, then the value returned as WriterIdentity is the same group or // service account used by Stackdriver Logging before the addition of writer // identities to the API. The sink's destination must be in the same project as // the sink itself. // // If this field is set to true, or if the sink is owned by a non-project // resource such as an organization, then the value of WriterIdentity will // be a unique service account used only for exports from the new sink. UniqueWriterIdentity bool // These fields apply only to UpdateSinkOpt calls. The corresponding sink field // is updated if and only if the Update field is true. UpdateDestination bool UpdateFilter bool UpdateIncludeChildren bool } // DeleteSink deletes a sink. The provided sinkID is the sink's identifier, such as // "my-severe-errors-to-pubsub". // Requires AdminScope. func (c *Client) DeleteSink(ctx context.Context, sinkID string) error { return c.sClient.DeleteSink(ctx, &logpb.DeleteSinkRequest{ SinkName: c.sinkPath(sinkID), }) } // Sink gets a sink. The provided sinkID is the sink's identifier, such as // "my-severe-errors-to-pubsub". // Requires ReadScope or AdminScope. func (c *Client) Sink(ctx context.Context, sinkID string) (*Sink, error) { ls, err := c.sClient.GetSink(ctx, &logpb.GetSinkRequest{ SinkName: c.sinkPath(sinkID), }) if err != nil { return nil, err } return fromLogSink(ls), nil } // UpdateSink updates an existing Sink. Requires AdminScope. // // WARNING: UpdateSink will always update the Destination, Filter and IncludeChildren // fields of the sink, even if they have their zero values. Use UpdateSinkOpt // for more control over which fields to update. func (c *Client) UpdateSink(ctx context.Context, sink *Sink) (*Sink, error) { return c.UpdateSinkOpt(ctx, sink, SinkOptions{ UpdateDestination: true, UpdateFilter: true, UpdateIncludeChildren: true, }) } // UpdateSinkOpt updates an existing Sink, using the provided options. Requires AdminScope. // // To change a sink's writer identity to a service account unique to the sink, set // opts.UniqueWriterIdentity to true. It is not possible to change a sink's writer identity // from a unique service account to a non-unique writer identity. func (c *Client) UpdateSinkOpt(ctx context.Context, sink *Sink, opts SinkOptions) (*Sink, error) { mask := &maskpb.FieldMask{} if opts.UpdateDestination { mask.Paths = append(mask.Paths, "destination") } if opts.UpdateFilter { mask.Paths = append(mask.Paths, "filter") } if opts.UpdateIncludeChildren { mask.Paths = append(mask.Paths, "include_children") } if opts.UniqueWriterIdentity && len(mask.Paths) == 0 { // Hack: specify a deprecated, unchangeable field so that we have a non-empty // field mask. (An empty field mask would cause the destination, filter and include_children // fields to be changed.) mask.Paths = append(mask.Paths, "output_version_format") } if len(mask.Paths) == 0 { return nil, errors.New("logadmin: UpdateSinkOpt: nothing to update") } ls, err := c.sClient.UpdateSink(ctx, &logpb.UpdateSinkRequest{ SinkName: c.sinkPath(sink.ID), Sink: toLogSink(sink), UniqueWriterIdentity: opts.UniqueWriterIdentity, UpdateMask: mask, }) if err != nil { return nil, err } return fromLogSink(ls), err } func (c *Client) sinkPath(sinkID string) string { return fmt.Sprintf("%s/sinks/%s", c.parent, sinkID) } // Sinks returns a SinkIterator for iterating over all Sinks in the Client's project. // Requires ReadScope or AdminScope. func (c *Client) Sinks(ctx context.Context) *SinkIterator { it := &SinkIterator{ it: c.sClient.ListSinks(ctx, &logpb.ListSinksRequest{Parent: c.parent}), } it.pageInfo, it.nextFunc = iterator.NewPageInfo( it.fetch, func() int { return len(it.items) }, func() interface{} { b := it.items; it.items = nil; return b }) return it } // A SinkIterator iterates over Sinks. type SinkIterator struct { it *vkit.LogSinkIterator pageInfo *iterator.PageInfo nextFunc func() error items []*Sink } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *SinkIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is Done if there are // no more results. Once Next returns Done, all subsequent calls will return // Done. func (it *SinkIterator) Next() (*Sink, error) { if err := it.nextFunc(); err != nil { return nil, err } item := it.items[0] it.items = it.items[1:] return item, nil } func (it *SinkIterator) fetch(pageSize int, pageToken string) (string, error) { return iterFetch(pageSize, pageToken, it.it.PageInfo(), func() error { item, err := it.it.Next() if err != nil { return err } it.items = append(it.items, fromLogSink(item)) return nil }) } func toLogSink(s *Sink) *logpb.LogSink { return &logpb.LogSink{ Name: s.ID, Destination: s.Destination, Filter: s.Filter, IncludeChildren: s.IncludeChildren, OutputVersionFormat: logpb.LogSink_V2, // omit WriterIdentity because it is output-only. } } func fromLogSink(ls *logpb.LogSink) *Sink { return &Sink{ ID: ls.Name, Destination: ls.Destination, Filter: ls.Filter, WriterIdentity: ls.WriterIdentity, IncludeChildren: ls.IncludeChildren, } } google-cloud-go-0.49.0/logging/logadmin/sinks_test.go000066400000000000000000000170401356504100700225270ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // TODO(jba): document in CONTRIBUTING.md that service account must be given "Logs Configuration Writer" IAM role for sink tests to pass. // TODO(jba): [cont] (1) From top left menu, go to IAM & Admin. (2) In Roles dropdown for acct, select Logging > Logs Configuration Writer. (3) Save. // TODO(jba): Also, cloud-logs@google.com must have Owner permission on the GCS bucket named for the test project. package logadmin import ( "context" "log" "testing" "time" "cloud.google.com/go/internal/testutil" "cloud.google.com/go/internal/uid" ltest "cloud.google.com/go/logging/internal/testing" "cloud.google.com/go/storage" "google.golang.org/api/iterator" "google.golang.org/api/option" ) var sinkIDs = uid.NewSpace("GO-CLIENT-TEST-SINK", nil) const testFilter = "" var testSinkDestination string // Called just before TestMain calls m.Run. // Returns a cleanup function to be called after the tests finish. func initSinks(ctx context.Context) func() { // Create a unique GCS bucket so concurrent tests don't interfere with each other. bucketIDs := uid.NewSpace(testProjectID+"-log-sink", nil) testBucket := bucketIDs.New() testSinkDestination = "storage.googleapis.com/" + testBucket var storageClient *storage.Client if integrationTest { // Create a unique bucket as a sink destination, and give the cloud logging account // owner right. ts := testutil.TokenSource(ctx, storage.ScopeFullControl) var err error storageClient, err = storage.NewClient(ctx, option.WithTokenSource(ts)) if err != nil { log.Fatalf("new storage client: %v", err) } bucket := storageClient.Bucket(testBucket) if err := bucket.Create(ctx, testProjectID, nil); err != nil { log.Fatalf("creating storage bucket %q: %v", testBucket, err) } log.Printf("successfully created bucket %s", testBucket) if err := bucket.ACL().Set(ctx, "group-cloud-logs@google.com", storage.RoleOwner); err != nil { log.Fatalf("setting owner role: %v", err) } } // Clean up from aborted tests. it := client.Sinks(ctx) for { s, err := it.Next() if err == iterator.Done { break } if err != nil { log.Printf("listing sinks: %v", err) break } if sinkIDs.Older(s.ID, time.Hour) { client.DeleteSink(ctx, s.ID) // ignore error } } if integrationTest { for _, bn := range bucketNames(ctx, storageClient) { if bucketIDs.Older(bn, 24*time.Hour) { storageClient.Bucket(bn).Delete(ctx) // ignore error } } return func() { storageClient.Close() } } return func() {} } // Collect the name of all buckets for the test project. func bucketNames(ctx context.Context, client *storage.Client) []string { var names []string it := client.Buckets(ctx, testProjectID) loop: for { b, err := it.Next() switch err { case nil: names = append(names, b.Name) case iterator.Done: break loop default: log.Printf("listing buckets: %v", err) break loop } } return names } func TestCreateSink(t *testing.T) { ctx := context.Background() sink := &Sink{ ID: sinkIDs.New(), Destination: testSinkDestination, Filter: testFilter, IncludeChildren: true, } got, err := client.CreateSink(ctx, sink) if err != nil { t.Fatal(err) } sink.WriterIdentity = ltest.SharedServiceAccount if want := sink; !testutil.Equal(got, want) { t.Errorf("got %+v, want %+v", got, want) } got, err = client.Sink(ctx, sink.ID) if err != nil { t.Fatal(err) } if want := sink; !testutil.Equal(got, want) { t.Errorf("got %+v, want %+v", got, want) } // UniqueWriterIdentity sink.ID = sinkIDs.New() got, err = client.CreateSinkOpt(ctx, sink, SinkOptions{UniqueWriterIdentity: true}) if err != nil { t.Fatal(err) } // The WriterIdentity should be different. if got.WriterIdentity == sink.WriterIdentity { t.Errorf("got %s, want something different", got.WriterIdentity) } } func TestUpdateSink(t *testing.T) { ctx := context.Background() sink := &Sink{ ID: sinkIDs.New(), Destination: testSinkDestination, Filter: testFilter, IncludeChildren: true, WriterIdentity: ltest.SharedServiceAccount, } if _, err := client.CreateSink(ctx, sink); err != nil { t.Fatal(err) } got, err := client.UpdateSink(ctx, sink) if err != nil { t.Fatal(err) } if want := sink; !testutil.Equal(got, want) { t.Errorf("got\n%+v\nwant\n%+v", got, want) } got, err = client.Sink(ctx, sink.ID) if err != nil { t.Fatal(err) } if want := sink; !testutil.Equal(got, want) { t.Errorf("got\n%+v\nwant\n%+v", got, want) } // Updating an existing sink changes it. sink.Filter = "" sink.IncludeChildren = false if _, err := client.UpdateSink(ctx, sink); err != nil { t.Fatal(err) } got, err = client.Sink(ctx, sink.ID) if err != nil { t.Fatal(err) } if want := sink; !testutil.Equal(got, want) { t.Errorf("got\n%+v\nwant\n%+v", got, want) } } func TestUpdateSinkOpt(t *testing.T) { ctx := context.Background() id := sinkIDs.New() origSink := &Sink{ ID: id, Destination: testSinkDestination, Filter: testFilter, IncludeChildren: true, WriterIdentity: ltest.SharedServiceAccount, } if _, err := client.CreateSink(ctx, origSink); err != nil { t.Fatal(err) } // Updating with empty options is an error. _, err := client.UpdateSinkOpt(ctx, &Sink{ID: id, Destination: testSinkDestination}, SinkOptions{}) if err == nil { t.Errorf("got %v, want nil", err) } // Update selected fields. got, err := client.UpdateSinkOpt(ctx, &Sink{ID: id}, SinkOptions{ UpdateFilter: true, UpdateIncludeChildren: true, }) if err != nil { t.Fatal(err) } want := *origSink want.Filter = "" want.IncludeChildren = false if !testutil.Equal(got, &want) { t.Errorf("got\n%+v\nwant\n%+v", got, want) } // Update writer identity. got, err = client.UpdateSinkOpt(ctx, &Sink{ID: id, Filter: "foo"}, SinkOptions{UniqueWriterIdentity: true}) if err != nil { t.Fatal(err) } if got.WriterIdentity == want.WriterIdentity { t.Errorf("got %s, want something different", got.WriterIdentity) } want.WriterIdentity = got.WriterIdentity if !testutil.Equal(got, &want) { t.Errorf("got\n%+v\nwant\n%+v", got, want) } } func TestListSinks(t *testing.T) { ctx := context.Background() var sinks []*Sink want := map[string]*Sink{} for i := 0; i < 4; i++ { s := &Sink{ ID: sinkIDs.New(), Destination: testSinkDestination, Filter: testFilter, WriterIdentity: "serviceAccount:cloud-logs@system.gserviceaccount.com", } sinks = append(sinks, s) want[s.ID] = s } for _, s := range sinks { if _, err := client.CreateSink(ctx, s); err != nil { t.Fatalf("Create(%q): %v", s.ID, err) } } got := map[string]*Sink{} it := client.Sinks(ctx) for { s, err := it.Next() if err == iterator.Done { break } if err != nil { t.Fatal(err) } // If tests run simultaneously, we may have more sinks than we // created. So only check for our own. if _, ok := want[s.ID]; ok { got[s.ID] = s } } if !testutil.Equal(got, want) { t.Errorf("got %+v, want %+v", got, want) } } google-cloud-go-0.49.0/logging/logging.go000066400000000000000000000762521356504100700202070ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // API/gRPC features intentionally missing from this client: // - You cannot have the server pick the time of the entry. This client // always sends a time. // - There is no way to provide a protocol buffer payload. // - No support for the "partial success" feature when writing log entries. // TODO(jba): test whether forward-slash characters in the log ID must be URL-encoded. // These features are missing now, but will likely be added: // - There is no way to specify CallOptions. package logging import ( "bytes" "context" "encoding/json" "errors" "fmt" "log" "net/http" "os" "regexp" "strconv" "strings" "sync" "time" "unicode/utf8" "cloud.google.com/go/compute/metadata" "cloud.google.com/go/internal/version" vkit "cloud.google.com/go/logging/apiv2" "cloud.google.com/go/logging/internal" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" structpb "github.com/golang/protobuf/ptypes/struct" tspb "github.com/golang/protobuf/ptypes/timestamp" "google.golang.org/api/option" "google.golang.org/api/support/bundler" mrpb "google.golang.org/genproto/googleapis/api/monitoredres" logtypepb "google.golang.org/genproto/googleapis/logging/type" logpb "google.golang.org/genproto/googleapis/logging/v2" ) const ( // ReadScope is the scope for reading from the logging service. ReadScope = "https://www.googleapis.com/auth/logging.read" // WriteScope is the scope for writing to the logging service. WriteScope = "https://www.googleapis.com/auth/logging.write" // AdminScope is the scope for administrative actions on the logging service. AdminScope = "https://www.googleapis.com/auth/logging.admin" ) const ( // defaultErrorCapacity is the capacity of the channel used to deliver // errors to the OnError function. defaultErrorCapacity = 10 // DefaultDelayThreshold is the default value for the DelayThreshold LoggerOption. DefaultDelayThreshold = time.Second // DefaultEntryCountThreshold is the default value for the EntryCountThreshold LoggerOption. DefaultEntryCountThreshold = 1000 // DefaultEntryByteThreshold is the default value for the EntryByteThreshold LoggerOption. DefaultEntryByteThreshold = 1 << 20 // 1MiB // DefaultBufferedByteLimit is the default value for the BufferedByteLimit LoggerOption. DefaultBufferedByteLimit = 1 << 30 // 1GiB // defaultWriteTimeout is the timeout for the underlying write API calls. As // write API calls are not idempotent, they are not retried on timeout. This // timeout is to allow clients to degrade gracefully if underlying logging // service is temporarily impaired for some reason. defaultWriteTimeout = 10 * time.Minute ) // For testing: var now = time.Now // ErrOverflow signals that the number of buffered entries for a Logger // exceeds its BufferLimit. var ErrOverflow = bundler.ErrOverflow // ErrOversizedEntry signals that an entry's size exceeds the maximum number of // bytes that will be sent in a single call to the logging service. var ErrOversizedEntry = bundler.ErrOversizedItem // Client is a Logging client. A Client is associated with a single Cloud project. type Client struct { client *vkit.Client // client for the logging service parent string // e.g. "projects/proj-id" errc chan error // should be buffered to minimize dropped errors donec chan struct{} // closed on Client.Close to close Logger bundlers loggers sync.WaitGroup // so we can wait for loggers to close closed bool mu sync.Mutex nErrs int // number of errors we saw lastErr error // last error we saw // OnError is called when an error occurs in a call to Log or Flush. The // error may be due to an invalid Entry, an overflow because BufferLimit // was reached (in which case the error will be ErrOverflow) or an error // communicating with the logging service. OnError is called with errors // from all Loggers. It is never called concurrently. OnError is expected // to return quickly; if errors occur while OnError is running, some may // not be reported. The default behavior is to call log.Printf. // // This field should be set only once, before any method of Client is called. OnError func(err error) } // NewClient returns a new logging client associated with the provided parent. // A parent can take any of the following forms: // projects/PROJECT_ID // folders/FOLDER_ID // billingAccounts/ACCOUNT_ID // organizations/ORG_ID // for backwards compatibility, a string with no '/' is also allowed and is interpreted // as a project ID. // // By default NewClient uses WriteScope. To use a different scope, call // NewClient using a WithScopes option (see https://godoc.org/google.golang.org/api/option#WithScopes). func NewClient(ctx context.Context, parent string, opts ...option.ClientOption) (*Client, error) { if !strings.ContainsRune(parent, '/') { parent = "projects/" + parent } opts = append([]option.ClientOption{ option.WithEndpoint(internal.ProdAddr), option.WithScopes(WriteScope), }, opts...) c, err := vkit.NewClient(ctx, opts...) if err != nil { return nil, err } c.SetGoogleClientInfo("gccl", version.Repo) client := &Client{ client: c, parent: parent, errc: make(chan error, defaultErrorCapacity), // create a small buffer for errors donec: make(chan struct{}), OnError: func(e error) { log.Printf("logging client: %v", e) }, } // Call the user's function synchronously, to make life easier for them. go func() { for err := range client.errc { // This reference to OnError is memory-safe if the user sets OnError before // calling any client methods. The reference happens before the first read from // client.errc, which happens before the first write to client.errc, which // happens before any call, which happens before the user sets OnError. if fn := client.OnError; fn != nil { fn(err) } else { log.Printf("logging (parent %q): %v", parent, err) } } }() return client, nil } var unixZeroTimestamp *tspb.Timestamp func init() { var err error unixZeroTimestamp, err = ptypes.TimestampProto(time.Unix(0, 0)) if err != nil { panic(err) } } // Ping reports whether the client's connection to the logging service and the // authentication configuration are valid. To accomplish this, Ping writes a // log entry "ping" to a log named "ping". func (c *Client) Ping(ctx context.Context) error { ent := &logpb.LogEntry{ Payload: &logpb.LogEntry_TextPayload{TextPayload: "ping"}, Timestamp: unixZeroTimestamp, // Identical timestamps and insert IDs are both InsertId: "ping", // necessary for the service to dedup these entries. } _, err := c.client.WriteLogEntries(ctx, &logpb.WriteLogEntriesRequest{ LogName: internal.LogPath(c.parent, "ping"), Resource: monitoredResource(c.parent), Entries: []*logpb.LogEntry{ent}, }) return err } // error puts the error on the client's error channel // without blocking, and records summary error info. func (c *Client) error(err error) { select { case c.errc <- err: default: } c.mu.Lock() c.lastErr = err c.nErrs++ c.mu.Unlock() } func (c *Client) extractErrorInfo() error { var err error c.mu.Lock() if c.lastErr != nil { err = fmt.Errorf("saw %d errors; last: %v", c.nErrs, c.lastErr) c.nErrs = 0 c.lastErr = nil } c.mu.Unlock() return err } // A Logger is used to write log messages to a single log. It can be configured // with a log ID, common monitored resource, and a set of common labels. type Logger struct { client *Client logName string // "projects/{projectID}/logs/{logID}" stdLoggers map[Severity]*log.Logger bundler *bundler.Bundler // Options commonResource *mrpb.MonitoredResource commonLabels map[string]string ctxFunc func() (context.Context, func()) } // A LoggerOption is a configuration option for a Logger. type LoggerOption interface { set(*Logger) } // CommonResource sets the monitored resource associated with all log entries // written from a Logger. If not provided, the resource is automatically // detected based on the running environment (on GCE and GAE Standard only). // This value can be overridden per-entry by setting an Entry's Resource field. func CommonResource(r *mrpb.MonitoredResource) LoggerOption { return commonResource{r} } type commonResource struct{ *mrpb.MonitoredResource } func (r commonResource) set(l *Logger) { l.commonResource = r.MonitoredResource } var detectedResource struct { pb *mrpb.MonitoredResource once sync.Once } func detectGCEResource() *mrpb.MonitoredResource { projectID, err := metadata.ProjectID() if err != nil { return nil } id, err := metadata.InstanceID() if err != nil { return nil } zone, err := metadata.Zone() if err != nil { return nil } name, err := metadata.InstanceName() if err != nil { return nil } return &mrpb.MonitoredResource{ Type: "gce_instance", Labels: map[string]string{ "project_id": projectID, "instance_id": id, "instance_name": name, "zone": zone, }, } } func detectGAEResource() *mrpb.MonitoredResource { return &mrpb.MonitoredResource{ Type: "gae_app", Labels: map[string]string{ "project_id": os.Getenv("GOOGLE_CLOUD_PROJECT"), "module_id": os.Getenv("GAE_SERVICE"), "version_id": os.Getenv("GAE_VERSION"), "instance_id": os.Getenv("GAE_INSTANCE"), "runtime": os.Getenv("GAE_RUNTIME"), }, } } func detectResource() *mrpb.MonitoredResource { detectedResource.once.Do(func() { switch { // GAE needs to come first, as metadata.OnGCE() is actually true on GAE // Second Gen runtimes. case os.Getenv("GAE_ENV") == "standard": detectedResource.pb = detectGAEResource() case metadata.OnGCE(): detectedResource.pb = detectGCEResource() } }) return detectedResource.pb } var resourceInfo = map[string]struct{ rtype, label string }{ "organizations": {"organization", "organization_id"}, "folders": {"folder", "folder_id"}, "projects": {"project", "project_id"}, "billingAccounts": {"billing_account", "account_id"}, } func monitoredResource(parent string) *mrpb.MonitoredResource { parts := strings.SplitN(parent, "/", 2) if len(parts) != 2 { return globalResource(parent) } info, ok := resourceInfo[parts[0]] if !ok { return globalResource(parts[1]) } return &mrpb.MonitoredResource{ Type: info.rtype, Labels: map[string]string{info.label: parts[1]}, } } func globalResource(projectID string) *mrpb.MonitoredResource { return &mrpb.MonitoredResource{ Type: "global", Labels: map[string]string{ "project_id": projectID, }, } } // CommonLabels are labels that apply to all log entries written from a Logger, // so that you don't have to repeat them in each log entry's Labels field. If // any of the log entries contains a (key, value) with the same key that is in // CommonLabels, then the entry's (key, value) overrides the one in // CommonLabels. func CommonLabels(m map[string]string) LoggerOption { return commonLabels(m) } type commonLabels map[string]string func (c commonLabels) set(l *Logger) { l.commonLabels = c } // ConcurrentWriteLimit determines how many goroutines will send log entries to the // underlying service. The default is 1. Set ConcurrentWriteLimit to a higher value to // increase throughput. func ConcurrentWriteLimit(n int) LoggerOption { return concurrentWriteLimit(n) } type concurrentWriteLimit int func (c concurrentWriteLimit) set(l *Logger) { l.bundler.HandlerLimit = int(c) } // DelayThreshold is the maximum amount of time that an entry should remain // buffered in memory before a call to the logging service is triggered. Larger // values of DelayThreshold will generally result in fewer calls to the logging // service, while increasing the risk that log entries will be lost if the // process crashes. // The default is DefaultDelayThreshold. func DelayThreshold(d time.Duration) LoggerOption { return delayThreshold(d) } type delayThreshold time.Duration func (d delayThreshold) set(l *Logger) { l.bundler.DelayThreshold = time.Duration(d) } // EntryCountThreshold is the maximum number of entries that will be buffered // in memory before a call to the logging service is triggered. Larger values // will generally result in fewer calls to the logging service, while // increasing both memory consumption and the risk that log entries will be // lost if the process crashes. // The default is DefaultEntryCountThreshold. func EntryCountThreshold(n int) LoggerOption { return entryCountThreshold(n) } type entryCountThreshold int func (e entryCountThreshold) set(l *Logger) { l.bundler.BundleCountThreshold = int(e) } // EntryByteThreshold is the maximum number of bytes of entries that will be // buffered in memory before a call to the logging service is triggered. See // EntryCountThreshold for a discussion of the tradeoffs involved in setting // this option. // The default is DefaultEntryByteThreshold. func EntryByteThreshold(n int) LoggerOption { return entryByteThreshold(n) } type entryByteThreshold int func (e entryByteThreshold) set(l *Logger) { l.bundler.BundleByteThreshold = int(e) } // EntryByteLimit is the maximum number of bytes of entries that will be sent // in a single call to the logging service. ErrOversizedEntry is returned if an // entry exceeds EntryByteLimit. This option limits the size of a single RPC // payload, to account for network or service issues with large RPCs. If // EntryByteLimit is smaller than EntryByteThreshold, the latter has no effect. // The default is zero, meaning there is no limit. func EntryByteLimit(n int) LoggerOption { return entryByteLimit(n) } type entryByteLimit int func (e entryByteLimit) set(l *Logger) { l.bundler.BundleByteLimit = int(e) } // BufferedByteLimit is the maximum number of bytes that the Logger will keep // in memory before returning ErrOverflow. This option limits the total memory // consumption of the Logger (but note that each Logger has its own, separate // limit). It is possible to reach BufferedByteLimit even if it is larger than // EntryByteThreshold or EntryByteLimit, because calls triggered by the latter // two options may be enqueued (and hence occupying memory) while new log // entries are being added. // The default is DefaultBufferedByteLimit. func BufferedByteLimit(n int) LoggerOption { return bufferedByteLimit(n) } type bufferedByteLimit int func (b bufferedByteLimit) set(l *Logger) { l.bundler.BufferedByteLimit = int(b) } // ContextFunc is a function that will be called to obtain a context.Context for the // WriteLogEntries RPC executed in the background for calls to Logger.Log. The // default is a function that always returns context.Background. The second return // value of the function is a function to call after the RPC completes. // // The function is not used for calls to Logger.LogSync, since the caller can pass // in the context directly. // // This option is EXPERIMENTAL. It may be changed or removed. func ContextFunc(f func() (ctx context.Context, afterCall func())) LoggerOption { return contextFunc(f) } type contextFunc func() (ctx context.Context, afterCall func()) func (c contextFunc) set(l *Logger) { l.ctxFunc = c } // Logger returns a Logger that will write entries with the given log ID, such as // "syslog". A log ID must be less than 512 characters long and can only // include the following characters: upper and lower case alphanumeric // characters: [A-Za-z0-9]; and punctuation characters: forward-slash, // underscore, hyphen, and period. func (c *Client) Logger(logID string, opts ...LoggerOption) *Logger { r := detectResource() if r == nil { r = monitoredResource(c.parent) } l := &Logger{ client: c, logName: internal.LogPath(c.parent, logID), commonResource: r, ctxFunc: func() (context.Context, func()) { return context.Background(), nil }, } l.bundler = bundler.NewBundler(&logpb.LogEntry{}, func(entries interface{}) { l.writeLogEntries(entries.([]*logpb.LogEntry)) }) l.bundler.DelayThreshold = DefaultDelayThreshold l.bundler.BundleCountThreshold = DefaultEntryCountThreshold l.bundler.BundleByteThreshold = DefaultEntryByteThreshold l.bundler.BufferedByteLimit = DefaultBufferedByteLimit for _, opt := range opts { opt.set(l) } l.stdLoggers = map[Severity]*log.Logger{} for s := range severityName { l.stdLoggers[s] = log.New(severityWriter{l, s}, "", 0) } c.loggers.Add(1) // Start a goroutine that cleans up the bundler, its channel // and the writer goroutines when the client is closed. go func() { defer c.loggers.Done() <-c.donec l.bundler.Flush() }() return l } type severityWriter struct { l *Logger s Severity } func (w severityWriter) Write(p []byte) (n int, err error) { w.l.Log(Entry{ Severity: w.s, Payload: string(p), }) return len(p), nil } // Close waits for all opened loggers to be flushed and closes the client. func (c *Client) Close() error { if c.closed { return nil } close(c.donec) // close Logger bundlers c.loggers.Wait() // wait for all bundlers to flush and close // Now there can be no more errors. close(c.errc) // terminate error goroutine // Prefer errors arising from logging to the error returned from Close. err := c.extractErrorInfo() err2 := c.client.Close() if err == nil { err = err2 } c.closed = true return err } // Severity is the severity of the event described in a log entry. These // guideline severity levels are ordered, with numerically smaller levels // treated as less severe than numerically larger levels. type Severity int const ( // Default means the log entry has no assigned severity level. Default = Severity(logtypepb.LogSeverity_DEFAULT) // Debug means debug or trace information. Debug = Severity(logtypepb.LogSeverity_DEBUG) // Info means routine information, such as ongoing status or performance. Info = Severity(logtypepb.LogSeverity_INFO) // Notice means normal but significant events, such as start up, shut down, or configuration. Notice = Severity(logtypepb.LogSeverity_NOTICE) // Warning means events that might cause problems. Warning = Severity(logtypepb.LogSeverity_WARNING) // Error means events that are likely to cause problems. Error = Severity(logtypepb.LogSeverity_ERROR) // Critical means events that cause more severe problems or brief outages. Critical = Severity(logtypepb.LogSeverity_CRITICAL) // Alert means a person must take an action immediately. Alert = Severity(logtypepb.LogSeverity_ALERT) // Emergency means one or more systems are unusable. Emergency = Severity(logtypepb.LogSeverity_EMERGENCY) ) var severityName = map[Severity]string{ Default: "Default", Debug: "Debug", Info: "Info", Notice: "Notice", Warning: "Warning", Error: "Error", Critical: "Critical", Alert: "Alert", Emergency: "Emergency", } // String converts a severity level to a string. func (v Severity) String() string { // same as proto.EnumName s, ok := severityName[v] if ok { return s } return strconv.Itoa(int(v)) } // ParseSeverity returns the Severity whose name equals s, ignoring case. It // returns Default if no Severity matches. func ParseSeverity(s string) Severity { sl := strings.ToLower(s) for sev, name := range severityName { if strings.ToLower(name) == sl { return sev } } return Default } // Entry is a log entry. // See https://cloud.google.com/logging/docs/view/logs_index for more about entries. type Entry struct { // Timestamp is the time of the entry. If zero, the current time is used. Timestamp time.Time // Severity is the entry's severity level. // The zero value is Default. Severity Severity // Payload must be either a string, or something that marshals via the // encoding/json package to a JSON object (and not any other type of JSON value). Payload interface{} // Labels optionally specifies key/value labels for the log entry. // The Logger.Log method takes ownership of this map. See Logger.CommonLabels // for more about labels. Labels map[string]string // InsertID is a unique ID for the log entry. If you provide this field, // the logging service considers other log entries in the same log with the // same ID as duplicates which can be removed. If omitted, the logging // service will generate a unique ID for this log entry. Note that because // this client retries RPCs automatically, it is possible (though unlikely) // that an Entry without an InsertID will be written more than once. InsertID string // HTTPRequest optionally specifies metadata about the HTTP request // associated with this log entry, if applicable. It is optional. HTTPRequest *HTTPRequest // Operation optionally provides information about an operation associated // with the log entry, if applicable. Operation *logpb.LogEntryOperation // LogName is the full log name, in the form // "projects/{ProjectID}/logs/{LogID}". It is set by the client when // reading entries. It is an error to set it when writing entries. LogName string // Resource is the monitored resource associated with the entry. Resource *mrpb.MonitoredResource // Trace is the resource name of the trace associated with the log entry, // if any. If it contains a relative resource name, the name is assumed to // be relative to //tracing.googleapis.com. Trace string // ID of the span within the trace associated with the log entry. // The ID is a 16-character hexadecimal encoding of an 8-byte array. SpanID string // If set, symbolizes that this request was sampled. TraceSampled bool // Optional. Source code location information associated with the log entry, // if any. SourceLocation *logpb.LogEntrySourceLocation } // HTTPRequest contains an http.Request as well as additional // information about the request and its response. type HTTPRequest struct { // Request is the http.Request passed to the handler. Request *http.Request // RequestSize is the size of the HTTP request message in bytes, including // the request headers and the request body. RequestSize int64 // Status is the response code indicating the status of the response. // Examples: 200, 404. Status int // ResponseSize is the size of the HTTP response message sent back to the client, in bytes, // including the response headers and the response body. ResponseSize int64 // Latency is the request processing latency on the server, from the time the request was // received until the response was sent. Latency time.Duration // LocalIP is the IP address (IPv4 or IPv6) of the origin server that the request // was sent to. LocalIP string // RemoteIP is the IP address (IPv4 or IPv6) of the client that issued the // HTTP request. Examples: "192.168.1.1", "FE80::0202:B3FF:FE1E:8329". RemoteIP string // CacheHit reports whether an entity was served from cache (with or without // validation). CacheHit bool // CacheValidatedWithOriginServer reports whether the response was // validated with the origin server before being served from cache. This // field is only meaningful if CacheHit is true. CacheValidatedWithOriginServer bool } func fromHTTPRequest(r *HTTPRequest) *logtypepb.HttpRequest { if r == nil { return nil } if r.Request == nil { panic("HTTPRequest must have a non-nil Request") } u := *r.Request.URL u.Fragment = "" pb := &logtypepb.HttpRequest{ RequestMethod: r.Request.Method, RequestUrl: fixUTF8(u.String()), RequestSize: r.RequestSize, Status: int32(r.Status), ResponseSize: r.ResponseSize, UserAgent: r.Request.UserAgent(), ServerIp: r.LocalIP, RemoteIp: r.RemoteIP, // TODO(jba): attempt to parse http.Request.RemoteAddr? Referer: r.Request.Referer(), CacheHit: r.CacheHit, CacheValidatedWithOriginServer: r.CacheValidatedWithOriginServer, } if r.Latency != 0 { pb.Latency = ptypes.DurationProto(r.Latency) } return pb } // fixUTF8 is a helper that fixes an invalid UTF-8 string by replacing // invalid UTF-8 runes with the Unicode replacement character (U+FFFD). // See Issue https://github.com/googleapis/google-cloud-go/issues/1383. func fixUTF8(s string) string { if utf8.ValidString(s) { return s } // Otherwise time to build the sequence. buf := new(bytes.Buffer) buf.Grow(len(s)) for _, r := range s { if utf8.ValidRune(r) { buf.WriteRune(r) } else { buf.WriteRune('\uFFFD') } } return buf.String() } // toProtoStruct converts v, which must marshal into a JSON object, // into a Google Struct proto. func toProtoStruct(v interface{}) (*structpb.Struct, error) { // Fast path: if v is already a *structpb.Struct, nothing to do. if s, ok := v.(*structpb.Struct); ok { return s, nil } // v is a Go value that supports JSON marshalling. We want a Struct // protobuf. Some day we may have a more direct way to get there, but right // now the only way is to marshal the Go value to JSON, unmarshal into a // map, and then build the Struct proto from the map. var jb []byte var err error if raw, ok := v.(json.RawMessage); ok { // needed for Go 1.7 and below jb = []byte(raw) } else { jb, err = json.Marshal(v) if err != nil { return nil, fmt.Errorf("logging: json.Marshal: %v", err) } } var m map[string]interface{} err = json.Unmarshal(jb, &m) if err != nil { return nil, fmt.Errorf("logging: json.Unmarshal: %v", err) } return jsonMapToProtoStruct(m), nil } func jsonMapToProtoStruct(m map[string]interface{}) *structpb.Struct { fields := map[string]*structpb.Value{} for k, v := range m { fields[k] = jsonValueToStructValue(v) } return &structpb.Struct{Fields: fields} } func jsonValueToStructValue(v interface{}) *structpb.Value { switch x := v.(type) { case bool: return &structpb.Value{Kind: &structpb.Value_BoolValue{BoolValue: x}} case float64: return &structpb.Value{Kind: &structpb.Value_NumberValue{NumberValue: x}} case string: return &structpb.Value{Kind: &structpb.Value_StringValue{StringValue: x}} case nil: return &structpb.Value{Kind: &structpb.Value_NullValue{}} case map[string]interface{}: return &structpb.Value{Kind: &structpb.Value_StructValue{StructValue: jsonMapToProtoStruct(x)}} case []interface{}: var vals []*structpb.Value for _, e := range x { vals = append(vals, jsonValueToStructValue(e)) } return &structpb.Value{Kind: &structpb.Value_ListValue{ListValue: &structpb.ListValue{Values: vals}}} default: panic(fmt.Sprintf("bad type %T for JSON value", v)) } } // LogSync logs the Entry synchronously without any buffering. Because LogSync is slow // and will block, it is intended primarily for debugging or critical errors. // Prefer Log for most uses. func (l *Logger) LogSync(ctx context.Context, e Entry) error { ent, err := l.toLogEntry(e) if err != nil { return err } _, err = l.client.client.WriteLogEntries(ctx, &logpb.WriteLogEntriesRequest{ LogName: l.logName, Resource: l.commonResource, Labels: l.commonLabels, Entries: []*logpb.LogEntry{ent}, }) return err } // Log buffers the Entry for output to the logging service. It never blocks. func (l *Logger) Log(e Entry) { ent, err := l.toLogEntry(e) if err != nil { l.client.error(err) return } if err := l.bundler.Add(ent, proto.Size(ent)); err != nil { l.client.error(err) } } // Flush blocks until all currently buffered log entries are sent. // // If any errors occurred since the last call to Flush from any Logger, or the // creation of the client if this is the first call, then Flush returns a non-nil // error with summary information about the errors. This information is unlikely to // be actionable. For more accurate error reporting, set Client.OnError. func (l *Logger) Flush() error { l.bundler.Flush() return l.client.extractErrorInfo() } func (l *Logger) writeLogEntries(entries []*logpb.LogEntry) { req := &logpb.WriteLogEntriesRequest{ LogName: l.logName, Resource: l.commonResource, Labels: l.commonLabels, Entries: entries, } ctx, afterCall := l.ctxFunc() ctx, cancel := context.WithTimeout(ctx, defaultWriteTimeout) defer cancel() _, err := l.client.client.WriteLogEntries(ctx, req) if err != nil { l.client.error(err) } if afterCall != nil { afterCall() } } // StandardLogger returns a *log.Logger for the provided severity. // // This method is cheap. A single log.Logger is pre-allocated for each // severity level in each Logger. Callers may mutate the returned log.Logger // (for example by calling SetFlags or SetPrefix). func (l *Logger) StandardLogger(s Severity) *log.Logger { return l.stdLoggers[s] } var reCloudTraceContext = regexp.MustCompile(`([a-f\d]+)/([a-f\d]+);o=(\d)`) func deconstructXCloudTraceContext(s string) (traceID, spanID string, traceSampled bool) { // As per the format described at https://cloud.google.com/trace/docs/troubleshooting#force-trace // "X-Cloud-Trace-Context: TRACE_ID/SPAN_ID;o=TRACE_TRUE" // for example: // "X-Cloud-Trace-Context: 105445aa7843bc8bf206b120001000/0;o=1" // // We expect: // * traceID: "105445aa7843bc8bf206b120001000" // * spanID: "" // * traceSampled: true matches := reCloudTraceContext.FindAllStringSubmatch(s, -1) if len(matches) != 1 { return } sub := matches[0] if len(sub) != 4 { return } traceID, spanID = sub[1], sub[2] if spanID == "0" { spanID = "" } traceSampled = sub[3] == "1" return } func (l *Logger) toLogEntry(e Entry) (*logpb.LogEntry, error) { if e.LogName != "" { return nil, errors.New("logging: Entry.LogName should be not be set when writing") } t := e.Timestamp if t.IsZero() { t = now() } ts, err := ptypes.TimestampProto(t) if err != nil { return nil, err } if e.Trace == "" && e.HTTPRequest != nil && e.HTTPRequest.Request != nil { traceHeader := e.HTTPRequest.Request.Header.Get("X-Cloud-Trace-Context") if traceHeader != "" { // Set to a relative resource name, as described at // https://cloud.google.com/appengine/docs/flexible/go/writing-application-logs. traceID, spanID, traceSampled := deconstructXCloudTraceContext(traceHeader) if traceID != "" { e.Trace = fmt.Sprintf("%s/traces/%s", l.client.parent, traceID) } if e.SpanID == "" { e.SpanID = spanID } // If we previously hadn't set TraceSampled, let's retrieve it // from the HTTP request's header, as per: // https://cloud.google.com/trace/docs/troubleshooting#force-trace e.TraceSampled = e.TraceSampled || traceSampled } } ent := &logpb.LogEntry{ Timestamp: ts, Severity: logtypepb.LogSeverity(e.Severity), InsertId: e.InsertID, HttpRequest: fromHTTPRequest(e.HTTPRequest), Operation: e.Operation, Labels: e.Labels, Trace: e.Trace, SpanId: e.SpanID, Resource: e.Resource, SourceLocation: e.SourceLocation, TraceSampled: e.TraceSampled, } switch p := e.Payload.(type) { case string: ent.Payload = &logpb.LogEntry_TextPayload{TextPayload: p} default: s, err := toProtoStruct(p) if err != nil { return nil, err } ent.Payload = &logpb.LogEntry_JsonPayload{JsonPayload: s} } return ent, nil } google-cloud-go-0.49.0/logging/logging_test.go000066400000000000000000000416401356504100700212370ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // TODO(jba): test that OnError is getting called appropriately. package logging_test import ( "context" "flag" "fmt" "log" "math/rand" "os" "strings" "sync" "sync/atomic" "testing" "time" cinternal "cloud.google.com/go/internal" "cloud.google.com/go/internal/testutil" "cloud.google.com/go/internal/uid" "cloud.google.com/go/logging" ltesting "cloud.google.com/go/logging/internal/testing" "cloud.google.com/go/logging/logadmin" gax "github.com/googleapis/gax-go/v2" "golang.org/x/oauth2" "google.golang.org/api/iterator" "google.golang.org/api/option" mrpb "google.golang.org/genproto/googleapis/api/monitoredres" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) const testLogIDPrefix = "GO-LOGGING-CLIENT/TEST-LOG" var ( client *logging.Client aclient *logadmin.Client testProjectID string testLogID string testFilter string errorc chan error ctx context.Context // Adjust the fields of a FullEntry received from the production service // before comparing it with the expected result. We can't correctly // compare certain fields, like times or server-generated IDs. clean func(*logging.Entry) // Create a new client with the given project ID. newClients func(ctx context.Context, projectID string) (*logging.Client, *logadmin.Client) uids = uid.NewSpace(testLogIDPrefix, nil) // If true, this test is using the production service, not a fake. integrationTest bool ) func testNow() time.Time { return time.Unix(1000, 0) } func TestMain(m *testing.M) { flag.Parse() // needed for testing.Short() ctx = context.Background() testProjectID = testutil.ProjID() errorc = make(chan error, 100) if testProjectID == "" || testing.Short() { integrationTest = false if testProjectID != "" { log.Print("Integration tests skipped in short mode (using fake instead)") } testProjectID = ltesting.ValidProjectID clean = func(e *logging.Entry) { // Remove the insert ID for consistency with the integration test. e.InsertID = "" } addr, err := ltesting.NewServer() if err != nil { log.Fatalf("creating fake server: %v", err) } logging.SetNow(testNow) newClients = func(ctx context.Context, parent string) (*logging.Client, *logadmin.Client) { conn, err := grpc.Dial(addr, grpc.WithInsecure()) if err != nil { log.Fatalf("dialing %q: %v", addr, err) } c, err := logging.NewClient(ctx, parent, option.WithGRPCConn(conn)) if err != nil { log.Fatalf("creating client for fake at %q: %v", addr, err) } ac, err := logadmin.NewClient(ctx, parent, option.WithGRPCConn(conn)) if err != nil { log.Fatalf("creating client for fake at %q: %v", addr, err) } return c, ac } } else { integrationTest = true clean = func(e *logging.Entry) { // We cannot compare timestamps, so set them to the test time. // Also, remove the insert ID added by the service. e.Timestamp = testNow().UTC() e.InsertID = "" } ts := testutil.TokenSource(ctx, logging.AdminScope) if ts == nil { log.Fatal("The project key must be set. See CONTRIBUTING.md for details") } log.Printf("running integration tests with project %s", testProjectID) newClients = func(ctx context.Context, parent string) (*logging.Client, *logadmin.Client) { c, err := logging.NewClient(ctx, parent, option.WithTokenSource(ts)) if err != nil { log.Fatalf("creating prod client: %v", err) } ac, err := logadmin.NewClient(ctx, parent, option.WithTokenSource(ts)) if err != nil { log.Fatalf("creating prod client: %v", err) } return c, ac } } client, aclient = newClients(ctx, testProjectID) client.OnError = func(e error) { errorc <- e } exit := m.Run() os.Exit(exit) } func initLogs() { testLogID = uids.New() hourAgo := time.Now().Add(-1 * time.Hour).UTC() testFilter = fmt.Sprintf(`logName = "projects/%s/logs/%s" AND timestamp >= "%s"`, testProjectID, strings.Replace(testLogID, "/", "%2F", -1), hourAgo.Format(time.RFC3339)) } func TestLogSync(t *testing.T) { // TODO(deklerk): Un-flake and re-enable t.Skip("Inherently flaky") initLogs() // Generate new testLogID ctx := context.Background() lg := client.Logger(testLogID) err := lg.LogSync(ctx, logging.Entry{Payload: "hello"}) if err != nil { t.Fatal(err) } err = lg.LogSync(ctx, logging.Entry{Payload: "goodbye"}) if err != nil { t.Fatal(err) } // Allow overriding the MonitoredResource. err = lg.LogSync(ctx, logging.Entry{Payload: "mr", Resource: &mrpb.MonitoredResource{Type: "global"}}) if err != nil { t.Fatal(err) } want := []*logging.Entry{ entryForTesting("hello"), entryForTesting("goodbye"), entryForTesting("mr"), } var got []*logging.Entry ok := waitFor(func() bool { got, err = allTestLogEntries(ctx) if err != nil { t.Log("fetching log entries: ", err) return false } return len(got) == len(want) }) if !ok { t.Fatalf("timed out; got: %d, want: %d\n", len(got), len(want)) } if msg, ok := compareEntries(got, want); !ok { t.Error(msg) } } func TestLogAndEntries(t *testing.T) { // TODO(deklerk): Un-flake and re-enable t.Skip("Inherently flaky") initLogs() // Generate new testLogID ctx := context.Background() payloads := []string{"p1", "p2", "p3", "p4", "p5"} lg := client.Logger(testLogID) for _, p := range payloads { // Use the insert ID to guarantee iteration order. lg.Log(logging.Entry{Payload: p, InsertID: p}) } if err := lg.Flush(); err != nil { t.Fatal(err) } var want []*logging.Entry for _, p := range payloads { want = append(want, entryForTesting(p)) } var got []*logging.Entry ok := waitFor(func() bool { var err error got, err = allTestLogEntries(ctx) if err != nil { t.Log("fetching log entries: ", err) return false } return len(got) == len(want) }) if !ok { t.Fatalf("timed out; got: %d, want: %d\n", len(got), len(want)) } if msg, ok := compareEntries(got, want); !ok { t.Error(msg) } } func TestContextFunc(t *testing.T) { initLogs() var contextFuncCalls, cleanupCalls int32 //atomic lg := client.Logger(testLogID, logging.ContextFunc(func() (context.Context, func()) { atomic.AddInt32(&contextFuncCalls, 1) return context.Background(), func() { atomic.AddInt32(&cleanupCalls, 1) } })) lg.Log(logging.Entry{Payload: "p"}) if err := lg.Flush(); err != nil { t.Fatal(err) } got1 := atomic.LoadInt32(&contextFuncCalls) got2 := atomic.LoadInt32(&cleanupCalls) if got1 != 1 || got1 != got2 { t.Errorf("got %d calls to context func, %d calls to cleanup func; want 1, 1", got1, got2) } } // compareEntries compares most fields list of Entries against expected. compareEntries does not compare: // - HTTPRequest // - Operation // - Resource // - SourceLocation func compareEntries(got, want []*logging.Entry) (string, bool) { if len(got) != len(want) { return fmt.Sprintf("got %d entries, want %d", len(got), len(want)), false } for i := range got { if !compareEntry(got[i], want[i]) { return fmt.Sprintf("#%d:\ngot %+v\nwant %+v", i, got[i], want[i]), false } } return "", true } func compareEntry(got, want *logging.Entry) bool { if got.Timestamp.Unix() != want.Timestamp.Unix() { return false } if got.Severity != want.Severity { return false } if !ltesting.PayloadEqual(got.Payload, want.Payload) { return false } if !testutil.Equal(got.Labels, want.Labels) { return false } if got.InsertID != want.InsertID { return false } if got.LogName != want.LogName { return false } return true } func entryForTesting(payload interface{}) *logging.Entry { return &logging.Entry{ Timestamp: testNow().UTC(), Payload: payload, LogName: "projects/" + testProjectID + "/logs/" + testLogID, Resource: &mrpb.MonitoredResource{Type: "global", Labels: map[string]string{"project_id": testProjectID}}, } } func allTestLogEntries(ctx context.Context) ([]*logging.Entry, error) { return allEntries(ctx, aclient, testFilter) } func allEntries(ctx context.Context, aclient *logadmin.Client, filter string) ([]*logging.Entry, error) { var es []*logging.Entry it := aclient.Entries(ctx, logadmin.Filter(filter)) for { e, err := cleanNext(it) switch err { case nil: es = append(es, e) case iterator.Done: return es, nil default: return nil, err } } } func cleanNext(it *logadmin.EntryIterator) (*logging.Entry, error) { e, err := it.Next() if err != nil { return nil, err } clean(e) return e, nil } func TestStandardLogger(t *testing.T) { // TODO(deklerk): Un-flake and re-enable t.Skip("Inherently flaky") initLogs() // Generate new testLogID ctx := context.Background() lg := client.Logger(testLogID) slg := lg.StandardLogger(logging.Info) if slg != lg.StandardLogger(logging.Info) { t.Error("There should be only one standard logger at each severity.") } if slg == lg.StandardLogger(logging.Debug) { t.Error("There should be a different standard logger for each severity.") } slg.Print("info") if err := lg.Flush(); err != nil { t.Fatal(err) } var got []*logging.Entry ok := waitFor(func() bool { var err error got, err = allTestLogEntries(ctx) if err != nil { t.Log("fetching log entries: ", err) return false } return len(got) == 1 }) if !ok { t.Fatalf("timed out; got: %d, want: %d\n", len(got), 1) } if len(got) != 1 { t.Fatalf("expected non-nil request with one entry; got:\n%+v", got) } if got, want := got[0].Payload.(string), "info\n"; got != want { t.Errorf("payload: got %q, want %q", got, want) } if got, want := logging.Severity(got[0].Severity), logging.Info; got != want { t.Errorf("severity: got %s, want %s", got, want) } } func TestSeverity(t *testing.T) { if got, want := logging.Info.String(), "Info"; got != want { t.Errorf("got %q, want %q", got, want) } if got, want := logging.Severity(-99).String(), "-99"; got != want { t.Errorf("got %q, want %q", got, want) } } func TestParseSeverity(t *testing.T) { for _, test := range []struct { in string want logging.Severity }{ {"", logging.Default}, {"whatever", logging.Default}, {"Default", logging.Default}, {"ERROR", logging.Error}, {"Error", logging.Error}, {"error", logging.Error}, } { got := logging.ParseSeverity(test.in) if got != test.want { t.Errorf("%q: got %s, want %s\n", test.in, got, test.want) } } } func TestErrors(t *testing.T) { initLogs() // Generate new testLogID // Drain errors already seen. loop: for { select { case <-errorc: default: break loop } } // Try to log something that can't be JSON-marshalled. lg := client.Logger(testLogID) lg.Log(logging.Entry{Payload: func() {}}) // Expect an error from Flush. err := lg.Flush() if err == nil { t.Fatal("expected error, got nil") } } type badTokenSource struct{} func (badTokenSource) Token() (*oauth2.Token, error) { return &oauth2.Token{}, nil } func TestPing(t *testing.T) { // Ping twice, in case the service's InsertID logic messes with the error code. ctx := context.Background() // The global client should be valid. if err := client.Ping(ctx); err != nil { t.Errorf("project %s: got %v, expected nil", testProjectID, err) } if err := client.Ping(ctx); err != nil { t.Errorf("project %s, #2: got %v, expected nil", testProjectID, err) } // nonexistent project c, a := newClients(ctx, testProjectID+"-BAD") defer c.Close() defer a.Close() if err := c.Ping(ctx); err == nil { t.Errorf("nonexistent project: want error pinging logging api, got nil") } if err := c.Ping(ctx); err == nil { t.Errorf("nonexistent project, #2: want error pinging logging api, got nil") } // Bad creds. We cannot test this with the fake, since it doesn't do auth. if integrationTest { c, err := logging.NewClient(ctx, testProjectID, option.WithTokenSource(badTokenSource{})) if err != nil { t.Fatal(err) } if err := c.Ping(ctx); err == nil { t.Errorf("bad creds: want error pinging logging api, got nil") } if err := c.Ping(ctx); err == nil { t.Errorf("bad creds, #2: want error pinging logging api, got nil") } if err := c.Close(); err != nil { t.Fatalf("error closing client: %v", err) } } } func TestLogsAndDelete(t *testing.T) { t.Skip("https://github.com/googleapis/google-cloud-go/issues/1654") // This function tests both the Logs and DeleteLog methods. We only try to // delete those logs that we can observe and that were generated by this // test. This may not include the logs generated from the current test run, // because the logging service is only eventually consistent. It's // therefore possible that on some runs, this test will do nothing. ctx := context.Background() it := aclient.Logs(ctx) nDeleted := 0 for { logID, err := it.Next() if err == iterator.Done { break } if err != nil { t.Fatal(err) } if strings.HasPrefix(logID, testLogIDPrefix) { if err := aclient.DeleteLog(ctx, logID); err != nil { // Ignore NotFound. Sometimes, amazingly, DeleteLog cannot find // a log that is returned by Logs. if status.Code(err) != codes.NotFound { t.Fatalf("deleting %q: %v", logID, err) } } else { nDeleted++ } } } t.Logf("deleted %d logs", nDeleted) } func TestNonProjectParent(t *testing.T) { ctx := context.Background() initLogs() parent := "organizations/" + ltesting.ValidOrgID c, a := newClients(ctx, parent) defer c.Close() defer a.Close() lg := c.Logger(testLogID) err := lg.LogSync(ctx, logging.Entry{Payload: "hello"}) if integrationTest { // We don't have permission to log to the organization. if got, want := status.Code(err), codes.PermissionDenied; got != want { t.Errorf("got code %s, want %s", got, want) } return } // Continue test against fake. if err != nil { t.Fatal(err) } want := []*logging.Entry{{ Timestamp: testNow().UTC(), Payload: "hello", LogName: parent + "/logs/" + testLogID, Resource: &mrpb.MonitoredResource{ Type: "organization", Labels: map[string]string{"organization_id": ltesting.ValidOrgID}, }, }} var got []*logging.Entry ok := waitFor(func() bool { got, err = allEntries(ctx, a, fmt.Sprintf(`logName = "%s/logs/%s"`, parent, strings.Replace(testLogID, "/", "%2F", -1))) if err != nil { t.Log("fetching log entries: ", err) return false } return len(got) == len(want) }) if !ok { t.Fatalf("timed out; got: %d, want: %d\n", len(got), len(want)) } if msg, ok := compareEntries(got, want); !ok { t.Error(msg) } } // waitFor calls f repeatedly with exponential backoff, blocking until it returns true. // It returns false after a while (if it times out). func waitFor(f func() bool) bool { // TODO(shadams): Find a better way to deflake these tests. ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute) defer cancel() err := cinternal.Retry(ctx, gax.Backoff{Initial: time.Second, Multiplier: 2, Max: 30 * time.Second}, func() (bool, error) { return f(), nil }) return err == nil } // Interleave a lot of Log and Flush calls, to induce race conditions. // Run this test with: // go test -run LogFlushRace -race -count 100 func TestLogFlushRace(t *testing.T) { initLogs() // Generate new testLogID lg := client.Logger(testLogID, logging.ConcurrentWriteLimit(5), // up to 5 concurrent log writes logging.EntryCountThreshold(100)) // small bundle size to increase interleaving var wgf, wgl sync.WaitGroup donec := make(chan struct{}) for i := 0; i < 10; i++ { wgl.Add(1) go func() { defer wgl.Done() for j := 0; j < 1e4; j++ { lg.Log(logging.Entry{Payload: "the payload"}) } }() } for i := 0; i < 5; i++ { wgf.Add(1) go func() { defer wgf.Done() for { select { case <-donec: return case <-time.After(time.Duration(rand.Intn(5)) * time.Millisecond): if err := lg.Flush(); err != nil { t.Error(err) } } } }() } wgl.Wait() close(donec) wgf.Wait() } // Test the throughput of concurrent writers. func BenchmarkConcurrentWrites(b *testing.B) { if !integrationTest { b.Skip("only makes sense when running against production service") } for n := 1; n <= 32; n *= 2 { b.Run(fmt.Sprint(n), func(b *testing.B) { b.StopTimer() lg := client.Logger(testLogID, logging.ConcurrentWriteLimit(n), logging.EntryCountThreshold(1000)) const ( nEntries = 1e5 payload = "the quick brown fox jumps over the lazy dog" ) b.SetBytes(int64(nEntries * len(payload))) b.StartTimer() for i := 0; i < b.N; i++ { for j := 0; j < nEntries; j++ { lg.Log(logging.Entry{Payload: payload}) } if err := lg.Flush(); err != nil { b.Fatal(err) } } }) } } google-cloud-go-0.49.0/logging/logging_unexported_test.go000066400000000000000000000317361356504100700235210ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Tests that require access to unexported names of the logging package. package logging import ( "encoding/json" "net/http" "net/url" "testing" "time" "cloud.google.com/go/internal/testutil" "github.com/golang/protobuf/proto" durpb "github.com/golang/protobuf/ptypes/duration" structpb "github.com/golang/protobuf/ptypes/struct" "google.golang.org/api/logging/v2" "google.golang.org/api/support/bundler" mrpb "google.golang.org/genproto/googleapis/api/monitoredres" logtypepb "google.golang.org/genproto/googleapis/logging/type" ) func TestLoggerCreation(t *testing.T) { const logID = "testing" c := &Client{parent: "projects/PROJECT_ID"} customResource := &mrpb.MonitoredResource{ Type: "global", Labels: map[string]string{ "project_id": "ANOTHER_PROJECT", }, } defaultBundler := &bundler.Bundler{ DelayThreshold: DefaultDelayThreshold, BundleCountThreshold: DefaultEntryCountThreshold, BundleByteThreshold: DefaultEntryByteThreshold, BundleByteLimit: 0, BufferedByteLimit: DefaultBufferedByteLimit, } for _, test := range []struct { options []LoggerOption wantLogger *Logger defaultResource bool wantBundler *bundler.Bundler }{ { options: nil, wantLogger: &Logger{}, defaultResource: true, wantBundler: defaultBundler, }, { options: []LoggerOption{ CommonResource(nil), CommonLabels(map[string]string{"a": "1"}), }, wantLogger: &Logger{ commonResource: nil, commonLabels: map[string]string{"a": "1"}, }, wantBundler: defaultBundler, }, { options: []LoggerOption{CommonResource(customResource)}, wantLogger: &Logger{commonResource: customResource}, wantBundler: defaultBundler, }, { options: []LoggerOption{ DelayThreshold(time.Minute), EntryCountThreshold(99), EntryByteThreshold(17), EntryByteLimit(18), BufferedByteLimit(19), }, wantLogger: &Logger{}, defaultResource: true, wantBundler: &bundler.Bundler{ DelayThreshold: time.Minute, BundleCountThreshold: 99, BundleByteThreshold: 17, BundleByteLimit: 18, BufferedByteLimit: 19, }, }, } { gotLogger := c.Logger(logID, test.options...) if got, want := gotLogger.commonResource, test.wantLogger.commonResource; !test.defaultResource && !proto.Equal(got, want) { t.Errorf("%v: resource: got %v, want %v", test.options, got, want) } if got, want := gotLogger.commonLabels, test.wantLogger.commonLabels; !testutil.Equal(got, want) { t.Errorf("%v: commonLabels: got %v, want %v", test.options, got, want) } if got, want := gotLogger.bundler.DelayThreshold, test.wantBundler.DelayThreshold; got != want { t.Errorf("%v: DelayThreshold: got %v, want %v", test.options, got, want) } if got, want := gotLogger.bundler.BundleCountThreshold, test.wantBundler.BundleCountThreshold; got != want { t.Errorf("%v: BundleCountThreshold: got %v, want %v", test.options, got, want) } if got, want := gotLogger.bundler.BundleByteThreshold, test.wantBundler.BundleByteThreshold; got != want { t.Errorf("%v: BundleByteThreshold: got %v, want %v", test.options, got, want) } if got, want := gotLogger.bundler.BundleByteLimit, test.wantBundler.BundleByteLimit; got != want { t.Errorf("%v: BundleByteLimit: got %v, want %v", test.options, got, want) } if got, want := gotLogger.bundler.BufferedByteLimit, test.wantBundler.BufferedByteLimit; got != want { t.Errorf("%v: BufferedByteLimit: got %v, want %v", test.options, got, want) } } } func TestToProtoStruct(t *testing.T) { v := struct { Foo string `json:"foo"` Bar int `json:"bar,omitempty"` Baz []float64 `json:"baz"` Moo map[string]interface{} `json:"moo"` }{ Foo: "foovalue", Baz: []float64{1.1}, Moo: map[string]interface{}{ "a": 1, "b": "two", "c": true, }, } got, err := toProtoStruct(v) if err != nil { t.Fatal(err) } want := &structpb.Struct{ Fields: map[string]*structpb.Value{ "foo": {Kind: &structpb.Value_StringValue{StringValue: v.Foo}}, "baz": {Kind: &structpb.Value_ListValue{ListValue: &structpb.ListValue{Values: []*structpb.Value{ {Kind: &structpb.Value_NumberValue{NumberValue: 1.1}}, }}}}, "moo": {Kind: &structpb.Value_StructValue{ StructValue: &structpb.Struct{ Fields: map[string]*structpb.Value{ "a": {Kind: &structpb.Value_NumberValue{NumberValue: 1}}, "b": {Kind: &structpb.Value_StringValue{StringValue: "two"}}, "c": {Kind: &structpb.Value_BoolValue{BoolValue: true}}, }, }, }}, }, } if !proto.Equal(got, want) { t.Errorf("got %+v\nwant %+v", got, want) } // Non-structs should fail to convert. for v := range []interface{}{3, "foo", []int{1, 2, 3}} { _, err := toProtoStruct(v) if err == nil { t.Errorf("%v: got nil, want error", v) } } // Test fast path. got, err = toProtoStruct(want) if err != nil { t.Fatal(err) } if got != want { t.Error("got and want should be identical, but are not") } } func TestToLogEntryPayload(t *testing.T) { var logger Logger for _, test := range []struct { in interface{} wantText string wantStruct *structpb.Struct }{ { in: "string", wantText: "string", }, { in: map[string]interface{}{"a": 1, "b": true}, wantStruct: &structpb.Struct{ Fields: map[string]*structpb.Value{ "a": {Kind: &structpb.Value_NumberValue{NumberValue: 1}}, "b": {Kind: &structpb.Value_BoolValue{BoolValue: true}}, }, }, }, { in: json.RawMessage([]byte(`{"a": 1, "b": true}`)), wantStruct: &structpb.Struct{ Fields: map[string]*structpb.Value{ "a": {Kind: &structpb.Value_NumberValue{NumberValue: 1}}, "b": {Kind: &structpb.Value_BoolValue{BoolValue: true}}, }, }, }, } { e, err := logger.toLogEntry(Entry{Payload: test.in}) if err != nil { t.Fatalf("%+v: %v", test.in, err) } if test.wantStruct != nil { got := e.GetJsonPayload() if !proto.Equal(got, test.wantStruct) { t.Errorf("%+v: got %s, want %s", test.in, got, test.wantStruct) } } else { got := e.GetTextPayload() if got != test.wantText { t.Errorf("%+v: got %s, want %s", test.in, got, test.wantText) } } } } func TestToLogEntryTrace(t *testing.T) { logger := &Logger{client: &Client{parent: "projects/P"}} // Verify that we get the trace from the HTTP request if it isn't // provided by the caller. u := &url.URL{Scheme: "http"} tests := []struct { name string in Entry want logging.LogEntry }{ {"BlankLogEntry", Entry{}, logging.LogEntry{}}, {"Already set Trace", Entry{Trace: "t1"}, logging.LogEntry{Trace: "t1"}}, { "No X-Trace-Context header", Entry{ HTTPRequest: &HTTPRequest{ Request: &http.Request{URL: u, Header: http.Header{"foo": {"bar"}}}, }, }, logging.LogEntry{}, }, { "X-Trace-Context header with all fields", Entry{ TraceSampled: false, HTTPRequest: &HTTPRequest{ Request: &http.Request{ URL: u, Header: http.Header{"X-Cloud-Trace-Context": {"105445aa7843bc8bf206b120001000/000000000000004a;o=1"}}, }, }, }, logging.LogEntry{Trace: "projects/P/traces/105445aa7843bc8bf206b120001000", SpanId: "000000000000004a", TraceSampled: true}, }, { "X-Trace-Context header with all fields; TraceSampled explicitly set", Entry{ TraceSampled: true, HTTPRequest: &HTTPRequest{ Request: &http.Request{ URL: u, Header: http.Header{"X-Cloud-Trace-Context": {"105445aa7843bc8bf206b120001000/000000000000004a;o=0"}}, }, }, }, logging.LogEntry{Trace: "projects/P/traces/105445aa7843bc8bf206b120001000", SpanId: "000000000000004a", TraceSampled: true}, }, { "X-Trace-Context header with all fields; TraceSampled from Header", Entry{ HTTPRequest: &HTTPRequest{ Request: &http.Request{ URL: u, Header: http.Header{"X-Cloud-Trace-Context": {"105445aa7843bc8bf206b120001000/000000000000004a;o=1"}}, }, }, }, logging.LogEntry{Trace: "projects/P/traces/105445aa7843bc8bf206b120001000", SpanId: "000000000000004a", TraceSampled: true}, }, { "X-Trace-Context header with blank span", Entry{ HTTPRequest: &HTTPRequest{ Request: &http.Request{ URL: u, Header: http.Header{"X-Cloud-Trace-Context": {"105445aa7843bc8bf206b120001000/0;o=0"}}, }, }, }, logging.LogEntry{Trace: "projects/P/traces/105445aa7843bc8bf206b120001000"}, }, { "Invalid X-Trace-Context header but already set TraceID", Entry{ HTTPRequest: &HTTPRequest{ Request: &http.Request{ URL: u, Header: http.Header{"X-Cloud-Trace-Context": {"t3"}}, }, }, Trace: "t4", }, logging.LogEntry{Trace: "t4"}, }, { "Already set TraceID and SpanID", Entry{Trace: "t1", SpanID: "007"}, logging.LogEntry{Trace: "t1", SpanId: "007"}, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { e, err := logger.toLogEntry(test.in) if err != nil { t.Fatalf("Unexpected error:: %+v: %v", test.in, err) } if got := e.Trace; got != test.want.Trace { t.Errorf("TraceId: %+v: got %q, want %q", test.in, got, test.want.Trace) } if got := e.SpanId; got != test.want.SpanId { t.Errorf("SpanId: %+v: got %q, want %q", test.in, got, test.want.SpanId) } if got := e.TraceSampled; got != test.want.TraceSampled { t.Errorf("TraceSampled: %+v: got %t, want %t", test.in, got, test.want.TraceSampled) } }) } } func TestFromHTTPRequest(t *testing.T) { // The test URL has invalid UTF-8 runes. const testURL = "http://example.com/path?q=1&name=\xfe\xff" u, err := url.Parse(testURL) if err != nil { t.Fatal(err) } req := &HTTPRequest{ Request: &http.Request{ Method: "GET", URL: u, Header: map[string][]string{ "User-Agent": {"user-agent"}, "Referer": {"referer"}, }, }, RequestSize: 100, Status: 200, ResponseSize: 25, Latency: 100 * time.Second, LocalIP: "127.0.0.1", RemoteIP: "10.0.1.1", CacheHit: true, CacheValidatedWithOriginServer: true, } got := fromHTTPRequest(req) want := &logtypepb.HttpRequest{ RequestMethod: "GET", // RequestUrl should have its invalid utf-8 runes replaced by the Unicode replacement character U+FFFD. // See Issue https://github.com/googleapis/google-cloud-go/issues/1383 RequestUrl: "http://example.com/path?q=1&name=" + string('\ufffd') + string('\ufffd'), RequestSize: 100, Status: 200, ResponseSize: 25, Latency: &durpb.Duration{Seconds: 100}, UserAgent: "user-agent", ServerIp: "127.0.0.1", RemoteIp: "10.0.1.1", Referer: "referer", CacheHit: true, CacheValidatedWithOriginServer: true, } if !proto.Equal(got, want) { t.Errorf("got %+v\nwant %+v", got, want) } // And finally checks directly that the error that was // in https://github.com/googleapis/google-cloud-go/issues/1383 // doesn't not regress. if _, err := proto.Marshal(got); err != nil { t.Fatalf("Unexpected proto.Marshal error: %v", err) } } func TestMonitoredResource(t *testing.T) { for _, test := range []struct { parent string want *mrpb.MonitoredResource }{ { "projects/P", &mrpb.MonitoredResource{ Type: "project", Labels: map[string]string{"project_id": "P"}, }, }, { "folders/F", &mrpb.MonitoredResource{ Type: "folder", Labels: map[string]string{"folder_id": "F"}, }, }, { "billingAccounts/B", &mrpb.MonitoredResource{ Type: "billing_account", Labels: map[string]string{"account_id": "B"}, }, }, { "organizations/123", &mrpb.MonitoredResource{ Type: "organization", Labels: map[string]string{"organization_id": "123"}, }, }, { "unknown/X", &mrpb.MonitoredResource{ Type: "global", Labels: map[string]string{"project_id": "X"}, }, }, { "whatever", &mrpb.MonitoredResource{ Type: "global", Labels: map[string]string{"project_id": "whatever"}, }, }, } { got := monitoredResource(test.parent) if !testutil.Equal(got, test.want) { t.Errorf("%q: got %+v, want %+v", test.parent, got, test.want) } } } // Used by the tests in logging_test. func SetNow(f func() time.Time) { now = f } google-cloud-go-0.49.0/longrunning/000077500000000000000000000000001356504100700171305ustar00rootroot00000000000000google-cloud-go-0.49.0/longrunning/.repo-metadata.json000066400000000000000000000007711356504100700226310ustar00rootroot00000000000000{ "name": "longrunning", "name_pretty": "Longrunning operations API", "product_documentation": "https://cloud.google.com/service-infrastructure/docs/service-management/reference/rpc/google.longrunning", "client_documentation": "https://godoc.org/cloud.google.com/go/longrunning", "release_level": "alpha", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go/longrunning", "api_id": "longrunning.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/longrunning/autogen/000077500000000000000000000000001356504100700205725ustar00rootroot00000000000000google-cloud-go-0.49.0/longrunning/autogen/.repo-metadata.json000066400000000000000000000007651356504100700242760ustar00rootroot00000000000000{ "name": "longrunning", "name_pretty": "Longrunning operations API", "product_documentation": "https://cloud.google.com/service-infrastructure/docs/service-management/reference/rpc/google.longrunning", "client_documentation": "https://godoc.org/cloud.google.com/go/longrunning/autogen", "release_level": "alpha", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "longrunning.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/longrunning/autogen/doc.go000066400000000000000000000053031356504100700216670ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package longrunning is an auto-generated package for the // Long Running Operations API. // // NOTE: This package is in alpha. It is not stable, and is likely to change. // // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. // // Use the client at cloud.google.com/go/longrunning in preference to this. package longrunning // import "cloud.google.com/go/longrunning/autogen" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{} } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191115" google-cloud-go-0.49.0/longrunning/autogen/from_conn.go000066400000000000000000000021351356504100700231020ustar00rootroot00000000000000// Copyright 2017, Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package longrunning import ( longrunningpb "google.golang.org/genproto/googleapis/longrunning" "google.golang.org/grpc" ) // InternalFromConn is for use by the google Cloud Libraries only. // // InternalFromConn creates OperationsClient from available connection. func InternalFromConn(conn *grpc.ClientConn) *OperationsClient { c := &OperationsClient{ conn: conn, CallOptions: defaultOperationsCallOptions(), operationsClient: longrunningpb.NewOperationsClient(conn), } c.SetGoogleClientInfo() return c } google-cloud-go-0.49.0/longrunning/autogen/mock_test.go000066400000000000000000000235351356504100700231210ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package longrunning import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" "google.golang.org/api/option" longrunningpb "google.golang.org/genproto/googleapis/longrunning" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockOperationsServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. longrunningpb.OperationsServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockOperationsServer) ListOperations(ctx context.Context, req *longrunningpb.ListOperationsRequest) (*longrunningpb.ListOperationsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.ListOperationsResponse), nil } func (s *mockOperationsServer) GetOperation(ctx context.Context, req *longrunningpb.GetOperationRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockOperationsServer) DeleteOperation(ctx context.Context, req *longrunningpb.DeleteOperationRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockOperationsServer) CancelOperation(ctx context.Context, req *longrunningpb.CancelOperationRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockOperations mockOperationsServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() longrunningpb.RegisterOperationsServer(serv, &mockOperations) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestOperationsGetOperation(t *testing.T) { var name2 string = "name2-1052831874" var done bool = true var expectedResponse = &longrunningpb.Operation{ Name: name2, Done: done, } mockOperations.err = nil mockOperations.reqs = nil mockOperations.resps = append(mockOperations.resps[:0], expectedResponse) var name string = "name3373707" var request = &longrunningpb.GetOperationRequest{ Name: name, } c, err := NewOperationsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetOperation(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockOperations.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestOperationsGetOperationError(t *testing.T) { errCode := codes.PermissionDenied mockOperations.err = gstatus.Error(errCode, "test error") var name string = "name3373707" var request = &longrunningpb.GetOperationRequest{ Name: name, } c, err := NewOperationsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetOperation(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestOperationsListOperations(t *testing.T) { var nextPageToken string = "" var operationsElement *longrunningpb.Operation = &longrunningpb.Operation{} var operations = []*longrunningpb.Operation{operationsElement} var expectedResponse = &longrunningpb.ListOperationsResponse{ NextPageToken: nextPageToken, Operations: operations, } mockOperations.err = nil mockOperations.reqs = nil mockOperations.resps = append(mockOperations.resps[:0], expectedResponse) var name string = "name3373707" var filter string = "filter-1274492040" var request = &longrunningpb.ListOperationsRequest{ Name: name, Filter: filter, } c, err := NewOperationsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListOperations(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockOperations.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Operations[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestOperationsListOperationsError(t *testing.T) { errCode := codes.PermissionDenied mockOperations.err = gstatus.Error(errCode, "test error") var name string = "name3373707" var filter string = "filter-1274492040" var request = &longrunningpb.ListOperationsRequest{ Name: name, Filter: filter, } c, err := NewOperationsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListOperations(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestOperationsCancelOperation(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockOperations.err = nil mockOperations.reqs = nil mockOperations.resps = append(mockOperations.resps[:0], expectedResponse) var name string = "name3373707" var request = &longrunningpb.CancelOperationRequest{ Name: name, } c, err := NewOperationsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.CancelOperation(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockOperations.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestOperationsCancelOperationError(t *testing.T) { errCode := codes.PermissionDenied mockOperations.err = gstatus.Error(errCode, "test error") var name string = "name3373707" var request = &longrunningpb.CancelOperationRequest{ Name: name, } c, err := NewOperationsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.CancelOperation(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestOperationsDeleteOperation(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockOperations.err = nil mockOperations.reqs = nil mockOperations.resps = append(mockOperations.resps[:0], expectedResponse) var name string = "name3373707" var request = &longrunningpb.DeleteOperationRequest{ Name: name, } c, err := NewOperationsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteOperation(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockOperations.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestOperationsDeleteOperationError(t *testing.T) { errCode := codes.PermissionDenied mockOperations.err = gstatus.Error(errCode, "test error") var name string = "name3373707" var request = &longrunningpb.DeleteOperationRequest{ Name: name, } c, err := NewOperationsClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteOperation(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } google-cloud-go-0.49.0/longrunning/autogen/operations_client.go000066400000000000000000000263741356504100700246560ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package longrunning import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" longrunningpb "google.golang.org/genproto/googleapis/longrunning" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // OperationsCallOptions contains the retry settings for each method of OperationsClient. type OperationsCallOptions struct { GetOperation []gax.CallOption ListOperations []gax.CallOption CancelOperation []gax.CallOption DeleteOperation []gax.CallOption } func defaultOperationsClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("longrunning.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultOperationsCallOptions() *OperationsCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &OperationsCallOptions{ GetOperation: retry[[2]string{"default", "idempotent"}], ListOperations: retry[[2]string{"default", "idempotent"}], CancelOperation: retry[[2]string{"default", "idempotent"}], DeleteOperation: retry[[2]string{"default", "idempotent"}], } } // OperationsClient is a client for interacting with Long Running Operations API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type OperationsClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. operationsClient longrunningpb.OperationsClient // The call options for this service. CallOptions *OperationsCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewOperationsClient creates a new operations client. // // Manages long-running operations with an API service. // // When an API method normally takes long time to complete, it can be designed // to return [Operation][google.longrunning.Operation] to the client, and the client can use this // interface to receive the real response asynchronously by polling the // operation resource, or pass the operation resource to another API (such as // Google Cloud Pub/Sub API) to receive the response. Any API service that // returns long-running operations should implement the Operations interface // so developers can have a consistent client experience. func NewOperationsClient(ctx context.Context, opts ...option.ClientOption) (*OperationsClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultOperationsClientOptions(), opts...)...) if err != nil { return nil, err } c := &OperationsClient{ conn: conn, CallOptions: defaultOperationsCallOptions(), operationsClient: longrunningpb.NewOperationsClient(conn), } c.SetGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *OperationsClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *OperationsClient) Close() error { return c.conn.Close() } // SetGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *OperationsClient) SetGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // GetOperation gets the latest state of a long-running operation. Clients can use this // method to poll the operation result at intervals as recommended by the API // service. func (c *OperationsClient) GetOperation(ctx context.Context, req *longrunningpb.GetOperationRequest, opts ...gax.CallOption) (*longrunningpb.Operation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetOperation[0:len(c.CallOptions.GetOperation):len(c.CallOptions.GetOperation)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.operationsClient.GetOperation(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListOperations lists operations that match the specified filter in the request. If the // server doesn't support this method, it returns UNIMPLEMENTED. // // NOTE: the name binding allows API services to override the binding // to use different resource name schemes, such as users/*/operations. To // override the binding, API services can add a binding such as // "/v1/{name=users/*}/operations" to their service configuration. // For backwards compatibility, the default name includes the operations // collection id, however overriding users must ensure the name binding // is the parent resource, without the operations collection id. func (c *OperationsClient) ListOperations(ctx context.Context, req *longrunningpb.ListOperationsRequest, opts ...gax.CallOption) *OperationIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListOperations[0:len(c.CallOptions.ListOperations):len(c.CallOptions.ListOperations)], opts...) it := &OperationIterator{} req = proto.Clone(req).(*longrunningpb.ListOperationsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*longrunningpb.Operation, string, error) { var resp *longrunningpb.ListOperationsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.operationsClient.ListOperations(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Operations, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // CancelOperation starts asynchronous cancellation on a long-running operation. The server // makes a best effort to cancel the operation, but success is not // guaranteed. If the server doesn't support this method, it returns // google.rpc.Code.UNIMPLEMENTED. Clients can use // [Operations.GetOperation][google.longrunning.Operations.GetOperation] or // other methods to check whether the cancellation succeeded or whether the // operation completed despite cancellation. On successful cancellation, // the operation is not deleted; instead, it becomes an operation with // an [Operation.error][google.longrunning.Operation.error] value with a [google.rpc.Status.code][google.rpc.Status.code] of 1, // corresponding to Code.CANCELLED. func (c *OperationsClient) CancelOperation(ctx context.Context, req *longrunningpb.CancelOperationRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CancelOperation[0:len(c.CallOptions.CancelOperation):len(c.CallOptions.CancelOperation)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.operationsClient.CancelOperation(ctx, req, settings.GRPC...) return err }, opts...) return err } // DeleteOperation deletes a long-running operation. This method indicates that the client is // no longer interested in the operation result. It does not cancel the // operation. If the server doesn't support this method, it returns // google.rpc.Code.UNIMPLEMENTED. func (c *OperationsClient) DeleteOperation(ctx context.Context, req *longrunningpb.DeleteOperationRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteOperation[0:len(c.CallOptions.DeleteOperation):len(c.CallOptions.DeleteOperation)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.operationsClient.DeleteOperation(ctx, req, settings.GRPC...) return err }, opts...) return err } // OperationIterator manages a stream of *longrunningpb.Operation. type OperationIterator struct { items []*longrunningpb.Operation pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*longrunningpb.Operation, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *OperationIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *OperationIterator) Next() (*longrunningpb.Operation, error) { var item *longrunningpb.Operation if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *OperationIterator) bufLen() int { return len(it.items) } func (it *OperationIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/longrunning/autogen/operations_client_example_test.go000066400000000000000000000047641356504100700274270ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package longrunning_test import ( "context" longrunning "cloud.google.com/go/longrunning/autogen" "google.golang.org/api/iterator" longrunningpb "google.golang.org/genproto/googleapis/longrunning" ) func ExampleNewOperationsClient() { ctx := context.Background() c, err := longrunning.NewOperationsClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleOperationsClient_GetOperation() { ctx := context.Background() c, err := longrunning.NewOperationsClient(ctx) if err != nil { // TODO: Handle error. } req := &longrunningpb.GetOperationRequest{ // TODO: Fill request struct fields. } resp, err := c.GetOperation(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleOperationsClient_ListOperations() { ctx := context.Background() c, err := longrunning.NewOperationsClient(ctx) if err != nil { // TODO: Handle error. } req := &longrunningpb.ListOperationsRequest{ // TODO: Fill request struct fields. } it := c.ListOperations(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleOperationsClient_CancelOperation() { ctx := context.Background() c, err := longrunning.NewOperationsClient(ctx) if err != nil { // TODO: Handle error. } req := &longrunningpb.CancelOperationRequest{ // TODO: Fill request struct fields. } err = c.CancelOperation(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleOperationsClient_DeleteOperation() { ctx := context.Background() c, err := longrunning.NewOperationsClient(ctx) if err != nil { // TODO: Handle error. } req := &longrunningpb.DeleteOperationRequest{ // TODO: Fill request struct fields. } err = c.DeleteOperation(ctx, req) if err != nil { // TODO: Handle error. } } google-cloud-go-0.49.0/longrunning/example_test.go000066400000000000000000000055051356504100700221560ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package longrunning import ( "context" "fmt" "time" "github.com/golang/protobuf/ptypes" "github.com/golang/protobuf/ptypes/duration" "github.com/golang/protobuf/ptypes/timestamp" pb "google.golang.org/genproto/googleapis/longrunning" ) func bestMomentInHistory() (*Operation, error) { t, err := time.Parse("2006-01-02 15:04:05.999999999 -0700 MST", "2009-11-10 23:00:00 +0000 UTC") if err != nil { return nil, err } resp, err := ptypes.TimestampProto(t) if err != nil { return nil, err } respAny, err := ptypes.MarshalAny(resp) if err != nil { return nil, err } metaAny, err := ptypes.MarshalAny(ptypes.DurationProto(1 * time.Hour)) return &Operation{ proto: &pb.Operation{ Name: "best-moment", Done: true, Metadata: metaAny, Result: &pb.Operation_Response{ Response: respAny, }, }, }, err } func ExampleOperation_Wait() { // Complex computation, might take a long time. op, err := bestMomentInHistory() if err != nil { // TODO: Handle err. } var ts timestamp.Timestamp err = op.Wait(context.TODO(), &ts) if err != nil && !op.Done() { fmt.Println("failed to fetch operation status", err) } else if err != nil && op.Done() { fmt.Println("operation completed with error", err) } else { fmt.Println(ptypes.TimestampString(&ts)) } // Output: // 2009-11-10T23:00:00Z } func ExampleOperation_Metadata() { op, err := bestMomentInHistory() if err != nil { // TODO: Handle err. } // The operation might contain metadata. // In this example, the metadata contains the estimated length of time // the operation might take to complete. var meta duration.Duration if err := op.Metadata(&meta); err != nil { // TODO: Handle err. } d, err := ptypes.Duration(&meta) if err == ErrNoMetadata { fmt.Println("no metadata") } else if err != nil { // TODO: Handle err. } else { fmt.Println(d) } // Output: // 1h0m0s } func ExampleOperation_Cancel() { op, err := bestMomentInHistory() if err != nil { // TODO: Handle err. } if err := op.Cancel(context.Background()); err != nil { // TODO: Handle err. } } func ExampleOperation_Delete() { op, err := bestMomentInHistory() if err != nil { // TODO: Handle err. } if err := op.Delete(context.Background()); err != nil { // TODO: Handle err. } } google-cloud-go-0.49.0/longrunning/longrunning.go000066400000000000000000000150271356504100700220240ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package longrunning supports Long Running Operations for the Google Cloud Libraries. // See google.golang.org/genproto/googleapis/longrunning for its service definition. // // Users of the Google Cloud Libraries will typically not use this package directly. // Instead they will call functions returning Operations and call their methods. // // This package is still experimental and subject to change. package longrunning // import "cloud.google.com/go/longrunning" import ( "context" "errors" "fmt" "time" autogen "cloud.google.com/go/longrunning/autogen" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" gax "github.com/googleapis/gax-go/v2" pb "google.golang.org/genproto/googleapis/longrunning" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) // ErrNoMetadata is the error returned by Metadata if the operation contains no metadata. var ErrNoMetadata = errors.New("operation contains no metadata") // Operation represents the result of an API call that may not be ready yet. type Operation struct { c operationsClient proto *pb.Operation } type operationsClient interface { GetOperation(context.Context, *pb.GetOperationRequest, ...gax.CallOption) (*pb.Operation, error) CancelOperation(context.Context, *pb.CancelOperationRequest, ...gax.CallOption) error DeleteOperation(context.Context, *pb.DeleteOperationRequest, ...gax.CallOption) error } // InternalNewOperation is for use by the google Cloud Libraries only. // // InternalNewOperation returns an long-running operation, abstracting the raw pb.Operation. // The conn parameter refers to a server that proto was received from. func InternalNewOperation(inner *autogen.OperationsClient, proto *pb.Operation) *Operation { return &Operation{ c: inner, proto: proto, } } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service // from which the operation is created. func (op *Operation) Name() string { return op.proto.Name } // Done reports whether the long-running operation has completed. func (op *Operation) Done() bool { return op.proto.Done } // Metadata unmarshals op's metadata into meta. // If op does not contain any metadata, Metadata returns ErrNoMetadata and meta is unmodified. func (op *Operation) Metadata(meta proto.Message) error { if m := op.proto.Metadata; m != nil { return ptypes.UnmarshalAny(m, meta) } return ErrNoMetadata } // Poll fetches the latest state of a long-running operation. // // If Poll fails, the error is returned and op is unmodified. // If Poll succeeds and the operation has completed with failure, // the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true; if resp != nil, the response of the operation // is stored in resp. func (op *Operation) Poll(ctx context.Context, resp proto.Message, opts ...gax.CallOption) error { if !op.Done() { p, err := op.c.GetOperation(ctx, &pb.GetOperationRequest{Name: op.Name()}, opts...) if err != nil { return err } op.proto = p } if !op.Done() { return nil } switch r := op.proto.Result.(type) { case *pb.Operation_Error: // TODO(pongad): r.Details may contain further information return status.Errorf(codes.Code(r.Error.Code), "%s", r.Error.Message) case *pb.Operation_Response: if resp == nil { return nil } return ptypes.UnmarshalAny(r.Response, resp) default: return fmt.Errorf("unsupported result type %[1]T: %[1]v", r) } } // DefaultWaitInterval is the polling interval used by Operation.Wait. const DefaultWaitInterval = 60 * time.Second // Wait is equivalent to WaitWithInterval using DefaultWaitInterval. func (op *Operation) Wait(ctx context.Context, resp proto.Message, opts ...gax.CallOption) error { return op.WaitWithInterval(ctx, resp, DefaultWaitInterval, opts...) } // WaitWithInterval blocks until the operation is completed. // If resp != nil, Wait stores the response in resp. // WaitWithInterval polls every interval, except initially // when it polls using exponential backoff. // // See documentation of Poll for error-handling information. func (op *Operation) WaitWithInterval(ctx context.Context, resp proto.Message, interval time.Duration, opts ...gax.CallOption) error { bo := gax.Backoff{ Initial: 1 * time.Second, Max: interval, } if bo.Max < bo.Initial { bo.Max = bo.Initial } return op.wait(ctx, resp, &bo, gax.Sleep, opts...) } type sleeper func(context.Context, time.Duration) error // wait implements Wait, taking exponentialBackoff and sleeper arguments for testing. func (op *Operation) wait(ctx context.Context, resp proto.Message, bo *gax.Backoff, sl sleeper, opts ...gax.CallOption) error { for { if err := op.Poll(ctx, resp, opts...); err != nil { return err } if op.Done() { return nil } if err := sl(ctx, bo.Pause()); err != nil { return err } } } // Cancel starts asynchronous cancellation on a long-running operation. The server // makes a best effort to cancel the operation, but success is not // guaranteed. If the server doesn't support this method, it returns // status.Code(err) == codes.Unimplemented. Clients can use // Poll or other methods to check whether the cancellation succeeded or whether the // operation completed despite cancellation. On successful cancellation, // the operation is not deleted; instead, op.Poll returns an error // with code Canceled. func (op *Operation) Cancel(ctx context.Context, opts ...gax.CallOption) error { return op.c.CancelOperation(ctx, &pb.CancelOperationRequest{Name: op.Name()}, opts...) } // Delete deletes a long-running operation. This method indicates that the client is // no longer interested in the operation result. It does not cancel the // operation. If the server doesn't support this method, status.Code(err) == codes.Unimplemented. func (op *Operation) Delete(ctx context.Context, opts ...gax.CallOption) error { return op.c.DeleteOperation(ctx, &pb.DeleteOperationRequest{Name: op.Name()}, opts...) } google-cloud-go-0.49.0/longrunning/longrunning_test.go000066400000000000000000000122631356504100700230620ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package lro supports Long Running Operations for the Google Cloud Libraries. // // This package is still experimental and subject to change. package longrunning import ( "context" "errors" "testing" "time" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" "github.com/golang/protobuf/ptypes/duration" gax "github.com/googleapis/gax-go/v2" pb "google.golang.org/genproto/googleapis/longrunning" rpcstatus "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) type getterService struct { operationsClient // clock represents the fake current time of the service. // It is the running sum of the of the duration we have slept. clock time.Duration // getTimes records the times at which GetOperation is called. getTimes []time.Duration // results are the fake results that GetOperation should return. results []*pb.Operation } func (s *getterService) GetOperation(context.Context, *pb.GetOperationRequest, ...gax.CallOption) (*pb.Operation, error) { i := len(s.getTimes) s.getTimes = append(s.getTimes, s.clock) if i >= len(s.results) { return nil, errors.New("unexpected call") } return s.results[i], nil } func (s *getterService) sleeper() sleeper { return func(_ context.Context, d time.Duration) error { s.clock += d return nil } } func TestWait(t *testing.T) { responseDur := ptypes.DurationProto(42 * time.Second) responseAny, err := ptypes.MarshalAny(responseDur) if err != nil { t.Fatal(err) } s := &getterService{ results: []*pb.Operation{ {Name: "foo"}, {Name: "foo"}, {Name: "foo"}, {Name: "foo"}, {Name: "foo"}, { Name: "foo", Done: true, Result: &pb.Operation_Response{ Response: responseAny, }, }, }, } op := &Operation{ c: s, proto: &pb.Operation{Name: "foo"}, } if op.Done() { t.Fatal("operation should not have completed yet") } var resp duration.Duration bo := gax.Backoff{ Initial: 1 * time.Second, Max: 3 * time.Second, } if err := op.wait(context.Background(), &resp, &bo, s.sleeper()); err != nil { t.Fatal(err) } if !proto.Equal(&resp, responseDur) { t.Errorf("response, got %v, want %v", resp, responseDur) } if !op.Done() { t.Errorf("operation should have completed") } maxWait := []time.Duration{ 1 * time.Second, 2 * time.Second, 3 * time.Second, 3 * time.Second, 3 * time.Second, } for i := 0; i < len(s.getTimes)-1; i++ { w := s.getTimes[i+1] - s.getTimes[i] if mw := maxWait[i]; w > mw { t.Errorf("backoff, waited %s, max %s", w, mw) } } } func TestPollRequestError(t *testing.T) { const opName = "foo" // All calls error. s := &getterService{} op := &Operation{ c: s, proto: &pb.Operation{Name: opName}, } if err := op.Poll(context.Background(), nil); err == nil { t.Fatalf("Poll should error") } if n := op.Name(); n != opName { t.Errorf("operation name, got %q, want %q", n, opName) } if op.Done() { t.Errorf("operation should not have completed; we failed to fetch state") } } func TestPollErrorResult(t *testing.T) { const ( errCode = codes.NotFound errMsg = "my error" ) op := &Operation{ proto: &pb.Operation{ Name: "foo", Done: true, Result: &pb.Operation_Error{ Error: &rpcstatus.Status{ Code: int32(errCode), Message: errMsg, }, }, }, } err := op.Poll(context.Background(), nil) if got := status.Code(err); got != errCode { t.Errorf("error code, want %s, got %s", errCode, got) } if got := grpc.ErrorDesc(err); got != errMsg { t.Errorf("error code, want %s, got %s", errMsg, got) } if !op.Done() { t.Errorf("operation should have completed") } } type errService struct { operationsClient errCancel, errDelete error } func (s *errService) CancelOperation(context.Context, *pb.CancelOperationRequest, ...gax.CallOption) error { return s.errCancel } func (s *errService) DeleteOperation(context.Context, *pb.DeleteOperationRequest, ...gax.CallOption) error { return s.errDelete } func TestCancelReturnsError(t *testing.T) { s := &errService{ errCancel: errors.New("cancel error"), } op := &Operation{ c: s, proto: &pb.Operation{Name: "foo"}, } if got, want := op.Cancel(context.Background()), s.errCancel; got != want { t.Errorf("cancel, got error %s, want %s", got, want) } } func TestDeleteReturnsError(t *testing.T) { s := &errService{ errDelete: errors.New("delete error"), } op := &Operation{ c: s, proto: &pb.Operation{Name: "foo"}, } if got, want := op.Delete(context.Background()), s.errDelete; got != want { t.Errorf("cancel, got error %s, want %s", got, want) } } google-cloud-go-0.49.0/manuals.txt000066400000000000000000000002101356504100700167620ustar00rootroot00000000000000errorreporting/apiv1beta1 firestore/apiv1beta1 firestore/apiv1 logging/apiv2 longrunning/autogen pubsub/apiv1 spanner/apiv1 trace/apiv1 google-cloud-go-0.49.0/microgens.csv000066400000000000000000000050151356504100700172740ustar00rootroot00000000000000input directory path, go module;package flag, gRPC ServiceConfig path flag, API service config path flag, release level google/cloud/texttospeech/v1, --go-gapic-package cloud.google.com/go/texttospeech/apiv1;texttospeech, --grpc-service-config google/cloud/texttospeech/v1/texttospeech_grpc_service_config.json, --gapic-service-config google/cloud/texttospeech/v1/texttospeech_v1.yaml, --release-level alpha google/cloud/asset/v1, --go-gapic-package cloud.google.com/go/asset/apiv1;asset, --grpc-service-config google/cloud/asset/v1/cloudasset_grpc_service_config.json, --gapic-service-config google/cloud/asset/v1/cloudasset_v1.yaml, --release-level alpha google/cloud/language/v1, --go-gapic-package cloud.google.com/go/language/apiv1;language, --grpc-service-config google/cloud/language/v1/language_grpc_service_config.json, --gapic-service-config google/cloud/language/language_v1.yaml, --release-level alpha google/cloud/phishingprotection/v1beta1, --go-gapic-package cloud.google.com/go/phishingprotection/apiv1beta1;phishingprotection, --grpc-service-config google/cloud/phishingprotection/v1beta1/phishingprotection_grpc_service_config.json, --gapic-service-config google/cloud/phishingprotection/v1beta1/phishingprotection_v1beta1.yaml, --release-level beta google/cloud/translate/v3, --go-gapic-package cloud.google.com/go/translate/apiv3;translate, --grpc-service-config google/cloud/translate/v3/translate_grpc_service_config.json, --gapic-service-config google/cloud/translate/v3/translate_v3.yaml, google/cloud/scheduler/v1, --go-gapic-package cloud.google.com/go/scheduler/apiv1;scheduler, --grpc-service-config google/cloud/scheduler/v1/cloudscheduler_grpc_service_config.json, --gapic-service-config google/cloud/scheduler/v1/cloudscheduler_v1.yaml, google/cloud/scheduler/v1beta1, --go-gapic-package cloud.google.com/go/scheduler/apiv1beta1;scheduler, --grpc-service-config google/cloud/scheduler/v1beta1/cloudscheduler_grpc_service_config.json, --gapic-service-config google/cloud/scheduler/v1beta1/cloudscheduler_v1beta1.yaml, --release-level beta google/cloud/speech/v1, --go-gapic-package cloud.google.com/go/speech/apiv1;speech, --grpc-service-config google/cloud/speech/v1/speech_grpc_service_config.json, --gapic-service-config google/cloud/speech/v1/speech_v1.yaml, google/cloud/speech/v1p1beta1, --go-gapic-package cloud.google.com/go/speech/apiv1p1beta1;speech, --grpc-service-config google/cloud/speech/v1p1beta1/speech_grpc_service_config.json, --gapic-service-config google/cloud/speech/v1p1beta1/speech_v1p1beta1.yaml, --release-level beta google-cloud-go-0.49.0/monitoring/000077500000000000000000000000001356504100700167555ustar00rootroot00000000000000google-cloud-go-0.49.0/monitoring/apiv3/000077500000000000000000000000001356504100700177775ustar00rootroot00000000000000google-cloud-go-0.49.0/monitoring/apiv3/.repo-metadata.json000066400000000000000000000006531356504100700234770ustar00rootroot00000000000000{ "name": "monitoring", "name_pretty": "Stackdriver Monitoring API", "product_documentation": "https://cloud.google.com/monitoring", "client_documentation": "https://godoc.org/cloud.google.com/go/monitoring/apiv3", "release_level": "alpha", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "monitoring.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/monitoring/apiv3/ListMonitoredResourceDescriptors_smoke_test.go000066400000000000000000000032751356504100700313200ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package monitoring import ( "context" "fmt" "strconv" "testing" "time" "cloud.google.com/go/internal/testutil" "google.golang.org/api/iterator" "google.golang.org/api/option" monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3" ) var _ = fmt.Sprintf var _ = iterator.Done var _ = strconv.FormatUint var _ = time.Now func TestMetricServiceSmoke(t *testing.T) { if testing.Short() { t.Skip("skipping smoke test in short mode") } ctx := context.Background() ts := testutil.TokenSource(ctx, DefaultAuthScopes()...) if ts == nil { t.Skip("Integration tests skipped. See CONTRIBUTING.md for details") } projectId := testutil.ProjID() _ = projectId c, err := NewMetricClient(ctx, option.WithTokenSource(ts)) if err != nil { t.Fatal(err) } var formattedName string = fmt.Sprintf("projects/%s", projectId) var request = &monitoringpb.ListMonitoredResourceDescriptorsRequest{ Name: formattedName, } iter := c.ListMonitoredResourceDescriptors(ctx, request) if _, err := iter.Next(); err != nil && err != iterator.Done { t.Error(err) } } google-cloud-go-0.49.0/monitoring/apiv3/alert_policy_client.go000066400000000000000000000261001356504100700243510ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package monitoring import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // AlertPolicyCallOptions contains the retry settings for each method of AlertPolicyClient. type AlertPolicyCallOptions struct { ListAlertPolicies []gax.CallOption GetAlertPolicy []gax.CallOption CreateAlertPolicy []gax.CallOption DeleteAlertPolicy []gax.CallOption UpdateAlertPolicy []gax.CallOption } func defaultAlertPolicyClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("monitoring.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultAlertPolicyCallOptions() *AlertPolicyCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &AlertPolicyCallOptions{ ListAlertPolicies: retry[[2]string{"default", "idempotent"}], GetAlertPolicy: retry[[2]string{"default", "idempotent"}], CreateAlertPolicy: retry[[2]string{"default", "non_idempotent"}], DeleteAlertPolicy: retry[[2]string{"default", "idempotent"}], UpdateAlertPolicy: retry[[2]string{"default", "non_idempotent"}], } } // AlertPolicyClient is a client for interacting with Stackdriver Monitoring API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type AlertPolicyClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. alertPolicyClient monitoringpb.AlertPolicyServiceClient // The call options for this service. CallOptions *AlertPolicyCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewAlertPolicyClient creates a new alert policy service client. // // The AlertPolicyService API is used to manage (list, create, delete, // edit) alert policies in Stackdriver Monitoring. An alerting policy is // a description of the conditions under which some aspect of your // system is considered to be "unhealthy" and the ways to notify // people or services about this state. In addition to using this API, alert // policies can also be managed through // Stackdriver Monitoring (at https://cloud.google.com/monitoring/docs/), // which can be reached by clicking the "Monitoring" tab in // Cloud Console (at https://console.cloud.google.com/). func NewAlertPolicyClient(ctx context.Context, opts ...option.ClientOption) (*AlertPolicyClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultAlertPolicyClientOptions(), opts...)...) if err != nil { return nil, err } c := &AlertPolicyClient{ conn: conn, CallOptions: defaultAlertPolicyCallOptions(), alertPolicyClient: monitoringpb.NewAlertPolicyServiceClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *AlertPolicyClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *AlertPolicyClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *AlertPolicyClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // ListAlertPolicies lists the existing alerting policies for the project. func (c *AlertPolicyClient) ListAlertPolicies(ctx context.Context, req *monitoringpb.ListAlertPoliciesRequest, opts ...gax.CallOption) *AlertPolicyIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListAlertPolicies[0:len(c.CallOptions.ListAlertPolicies):len(c.CallOptions.ListAlertPolicies)], opts...) it := &AlertPolicyIterator{} req = proto.Clone(req).(*monitoringpb.ListAlertPoliciesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*monitoringpb.AlertPolicy, string, error) { var resp *monitoringpb.ListAlertPoliciesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.alertPolicyClient.ListAlertPolicies(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.AlertPolicies, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetAlertPolicy gets a single alerting policy. func (c *AlertPolicyClient) GetAlertPolicy(ctx context.Context, req *monitoringpb.GetAlertPolicyRequest, opts ...gax.CallOption) (*monitoringpb.AlertPolicy, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetAlertPolicy[0:len(c.CallOptions.GetAlertPolicy):len(c.CallOptions.GetAlertPolicy)], opts...) var resp *monitoringpb.AlertPolicy err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.alertPolicyClient.GetAlertPolicy(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateAlertPolicy creates a new alerting policy. func (c *AlertPolicyClient) CreateAlertPolicy(ctx context.Context, req *monitoringpb.CreateAlertPolicyRequest, opts ...gax.CallOption) (*monitoringpb.AlertPolicy, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateAlertPolicy[0:len(c.CallOptions.CreateAlertPolicy):len(c.CallOptions.CreateAlertPolicy)], opts...) var resp *monitoringpb.AlertPolicy err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.alertPolicyClient.CreateAlertPolicy(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteAlertPolicy deletes an alerting policy. func (c *AlertPolicyClient) DeleteAlertPolicy(ctx context.Context, req *monitoringpb.DeleteAlertPolicyRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteAlertPolicy[0:len(c.CallOptions.DeleteAlertPolicy):len(c.CallOptions.DeleteAlertPolicy)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.alertPolicyClient.DeleteAlertPolicy(ctx, req, settings.GRPC...) return err }, opts...) return err } // UpdateAlertPolicy updates an alerting policy. You can either replace the entire policy with // a new one or replace only certain fields in the current alerting policy by // specifying the fields to be updated via updateMask. Returns the // updated alerting policy. func (c *AlertPolicyClient) UpdateAlertPolicy(ctx context.Context, req *monitoringpb.UpdateAlertPolicyRequest, opts ...gax.CallOption) (*monitoringpb.AlertPolicy, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "alert_policy.name", url.QueryEscape(req.GetAlertPolicy().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateAlertPolicy[0:len(c.CallOptions.UpdateAlertPolicy):len(c.CallOptions.UpdateAlertPolicy)], opts...) var resp *monitoringpb.AlertPolicy err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.alertPolicyClient.UpdateAlertPolicy(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // AlertPolicyIterator manages a stream of *monitoringpb.AlertPolicy. type AlertPolicyIterator struct { items []*monitoringpb.AlertPolicy pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*monitoringpb.AlertPolicy, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *AlertPolicyIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *AlertPolicyIterator) Next() (*monitoringpb.AlertPolicy, error) { var item *monitoringpb.AlertPolicy if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *AlertPolicyIterator) bufLen() int { return len(it.items) } func (it *AlertPolicyIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/monitoring/apiv3/alert_policy_client_example_test.go000066400000000000000000000056641356504100700271370ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package monitoring_test import ( "context" monitoring "cloud.google.com/go/monitoring/apiv3" "google.golang.org/api/iterator" monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3" ) func ExampleNewAlertPolicyClient() { ctx := context.Background() c, err := monitoring.NewAlertPolicyClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleAlertPolicyClient_ListAlertPolicies() { ctx := context.Background() c, err := monitoring.NewAlertPolicyClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.ListAlertPoliciesRequest{ // TODO: Fill request struct fields. } it := c.ListAlertPolicies(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleAlertPolicyClient_GetAlertPolicy() { ctx := context.Background() c, err := monitoring.NewAlertPolicyClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.GetAlertPolicyRequest{ // TODO: Fill request struct fields. } resp, err := c.GetAlertPolicy(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleAlertPolicyClient_CreateAlertPolicy() { ctx := context.Background() c, err := monitoring.NewAlertPolicyClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.CreateAlertPolicyRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateAlertPolicy(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleAlertPolicyClient_DeleteAlertPolicy() { ctx := context.Background() c, err := monitoring.NewAlertPolicyClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.DeleteAlertPolicyRequest{ // TODO: Fill request struct fields. } err = c.DeleteAlertPolicy(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleAlertPolicyClient_UpdateAlertPolicy() { ctx := context.Background() c, err := monitoring.NewAlertPolicyClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.UpdateAlertPolicyRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateAlertPolicy(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/monitoring/apiv3/doc.go000066400000000000000000000063431356504100700211010ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package monitoring is an auto-generated package for the // Stackdriver Monitoring API. // // NOTE: This package is in alpha. It is not stable, and is likely to change. // // Manages your Stackdriver Monitoring data and configurations. Most projects // must be associated with a Stackdriver account, with a few exceptions as // noted on the individual method pages. The table entries below are // presented in alphabetical order, not in order of common use. For // explanations of the concepts found in the table entries, read the // [Stackdriver Monitoring documentation](/monitoring/docs). // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package monitoring // import "cloud.google.com/go/monitoring/apiv3" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/monitoring", "https://www.googleapis.com/auth/monitoring.read", "https://www.googleapis.com/auth/monitoring.write", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191115" google-cloud-go-0.49.0/monitoring/apiv3/group_client.go000066400000000000000000000331041356504100700230210ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package monitoring import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" monitoredrespb "google.golang.org/genproto/googleapis/api/monitoredres" monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // GroupCallOptions contains the retry settings for each method of GroupClient. type GroupCallOptions struct { ListGroups []gax.CallOption GetGroup []gax.CallOption CreateGroup []gax.CallOption UpdateGroup []gax.CallOption DeleteGroup []gax.CallOption ListGroupMembers []gax.CallOption } func defaultGroupClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("monitoring.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultGroupCallOptions() *GroupCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &GroupCallOptions{ ListGroups: retry[[2]string{"default", "idempotent"}], GetGroup: retry[[2]string{"default", "idempotent"}], CreateGroup: retry[[2]string{"default", "non_idempotent"}], UpdateGroup: retry[[2]string{"default", "idempotent"}], DeleteGroup: retry[[2]string{"default", "idempotent"}], ListGroupMembers: retry[[2]string{"default", "idempotent"}], } } // GroupClient is a client for interacting with Stackdriver Monitoring API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type GroupClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. groupClient monitoringpb.GroupServiceClient // The call options for this service. CallOptions *GroupCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewGroupClient creates a new group service client. // // The Group API lets you inspect and manage your // groups (at #google.monitoring.v3.Group). // // A group is a named filter that is used to identify // a collection of monitored resources. Groups are typically used to // mirror the physical and/or logical topology of the environment. // Because group membership is computed dynamically, monitored // resources that are started in the future are automatically placed // in matching groups. By using a group to name monitored resources in, // for example, an alert policy, the target of that alert policy is // updated automatically as monitored resources are added and removed // from the infrastructure. func NewGroupClient(ctx context.Context, opts ...option.ClientOption) (*GroupClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultGroupClientOptions(), opts...)...) if err != nil { return nil, err } c := &GroupClient{ conn: conn, CallOptions: defaultGroupCallOptions(), groupClient: monitoringpb.NewGroupServiceClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *GroupClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *GroupClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *GroupClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // ListGroups lists the existing groups. func (c *GroupClient) ListGroups(ctx context.Context, req *monitoringpb.ListGroupsRequest, opts ...gax.CallOption) *GroupIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListGroups[0:len(c.CallOptions.ListGroups):len(c.CallOptions.ListGroups)], opts...) it := &GroupIterator{} req = proto.Clone(req).(*monitoringpb.ListGroupsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*monitoringpb.Group, string, error) { var resp *monitoringpb.ListGroupsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.groupClient.ListGroups(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Group, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetGroup gets a single group. func (c *GroupClient) GetGroup(ctx context.Context, req *monitoringpb.GetGroupRequest, opts ...gax.CallOption) (*monitoringpb.Group, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetGroup[0:len(c.CallOptions.GetGroup):len(c.CallOptions.GetGroup)], opts...) var resp *monitoringpb.Group err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.groupClient.GetGroup(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateGroup creates a new group. func (c *GroupClient) CreateGroup(ctx context.Context, req *monitoringpb.CreateGroupRequest, opts ...gax.CallOption) (*monitoringpb.Group, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateGroup[0:len(c.CallOptions.CreateGroup):len(c.CallOptions.CreateGroup)], opts...) var resp *monitoringpb.Group err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.groupClient.CreateGroup(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateGroup updates an existing group. // You can change any group attributes except name. func (c *GroupClient) UpdateGroup(ctx context.Context, req *monitoringpb.UpdateGroupRequest, opts ...gax.CallOption) (*monitoringpb.Group, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "group.name", url.QueryEscape(req.GetGroup().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateGroup[0:len(c.CallOptions.UpdateGroup):len(c.CallOptions.UpdateGroup)], opts...) var resp *monitoringpb.Group err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.groupClient.UpdateGroup(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteGroup deletes an existing group. func (c *GroupClient) DeleteGroup(ctx context.Context, req *monitoringpb.DeleteGroupRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteGroup[0:len(c.CallOptions.DeleteGroup):len(c.CallOptions.DeleteGroup)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.groupClient.DeleteGroup(ctx, req, settings.GRPC...) return err }, opts...) return err } // ListGroupMembers lists the monitored resources that are members of a group. func (c *GroupClient) ListGroupMembers(ctx context.Context, req *monitoringpb.ListGroupMembersRequest, opts ...gax.CallOption) *MonitoredResourceIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListGroupMembers[0:len(c.CallOptions.ListGroupMembers):len(c.CallOptions.ListGroupMembers)], opts...) it := &MonitoredResourceIterator{} req = proto.Clone(req).(*monitoringpb.ListGroupMembersRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*monitoredrespb.MonitoredResource, string, error) { var resp *monitoringpb.ListGroupMembersResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.groupClient.ListGroupMembers(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Members, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GroupIterator manages a stream of *monitoringpb.Group. type GroupIterator struct { items []*monitoringpb.Group pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*monitoringpb.Group, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *GroupIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *GroupIterator) Next() (*monitoringpb.Group, error) { var item *monitoringpb.Group if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *GroupIterator) bufLen() int { return len(it.items) } func (it *GroupIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // MonitoredResourceIterator manages a stream of *monitoredrespb.MonitoredResource. type MonitoredResourceIterator struct { items []*monitoredrespb.MonitoredResource pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*monitoredrespb.MonitoredResource, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *MonitoredResourceIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *MonitoredResourceIterator) Next() (*monitoredrespb.MonitoredResource, error) { var item *monitoredrespb.MonitoredResource if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *MonitoredResourceIterator) bufLen() int { return len(it.items) } func (it *MonitoredResourceIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/monitoring/apiv3/group_client_example_test.go000066400000000000000000000063151356504100700255770ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package monitoring_test import ( "context" monitoring "cloud.google.com/go/monitoring/apiv3" "google.golang.org/api/iterator" monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3" ) func ExampleNewGroupClient() { ctx := context.Background() c, err := monitoring.NewGroupClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleGroupClient_ListGroups() { ctx := context.Background() c, err := monitoring.NewGroupClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.ListGroupsRequest{ // TODO: Fill request struct fields. } it := c.ListGroups(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleGroupClient_GetGroup() { ctx := context.Background() c, err := monitoring.NewGroupClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.GetGroupRequest{ // TODO: Fill request struct fields. } resp, err := c.GetGroup(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleGroupClient_CreateGroup() { ctx := context.Background() c, err := monitoring.NewGroupClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.CreateGroupRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateGroup(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleGroupClient_UpdateGroup() { ctx := context.Background() c, err := monitoring.NewGroupClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.UpdateGroupRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateGroup(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleGroupClient_DeleteGroup() { ctx := context.Background() c, err := monitoring.NewGroupClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.DeleteGroupRequest{ // TODO: Fill request struct fields. } err = c.DeleteGroup(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleGroupClient_ListGroupMembers() { ctx := context.Background() c, err := monitoring.NewGroupClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.ListGroupMembersRequest{ // TODO: Fill request struct fields. } it := c.ListGroupMembers(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } google-cloud-go-0.49.0/monitoring/apiv3/metric_client.go000066400000000000000000000453301356504100700231540ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package monitoring import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" metricpb "google.golang.org/genproto/googleapis/api/metric" monitoredrespb "google.golang.org/genproto/googleapis/api/monitoredres" monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // MetricCallOptions contains the retry settings for each method of MetricClient. type MetricCallOptions struct { ListMonitoredResourceDescriptors []gax.CallOption GetMonitoredResourceDescriptor []gax.CallOption ListMetricDescriptors []gax.CallOption GetMetricDescriptor []gax.CallOption CreateMetricDescriptor []gax.CallOption DeleteMetricDescriptor []gax.CallOption ListTimeSeries []gax.CallOption CreateTimeSeries []gax.CallOption } func defaultMetricClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("monitoring.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultMetricCallOptions() *MetricCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &MetricCallOptions{ ListMonitoredResourceDescriptors: retry[[2]string{"default", "idempotent"}], GetMonitoredResourceDescriptor: retry[[2]string{"default", "idempotent"}], ListMetricDescriptors: retry[[2]string{"default", "idempotent"}], GetMetricDescriptor: retry[[2]string{"default", "idempotent"}], CreateMetricDescriptor: retry[[2]string{"default", "non_idempotent"}], DeleteMetricDescriptor: retry[[2]string{"default", "idempotent"}], ListTimeSeries: retry[[2]string{"default", "idempotent"}], CreateTimeSeries: retry[[2]string{"default", "non_idempotent"}], } } // MetricClient is a client for interacting with Stackdriver Monitoring API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type MetricClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. metricClient monitoringpb.MetricServiceClient // The call options for this service. CallOptions *MetricCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewMetricClient creates a new metric service client. // // Manages metric descriptors, monitored resource descriptors, and // time series data. func NewMetricClient(ctx context.Context, opts ...option.ClientOption) (*MetricClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultMetricClientOptions(), opts...)...) if err != nil { return nil, err } c := &MetricClient{ conn: conn, CallOptions: defaultMetricCallOptions(), metricClient: monitoringpb.NewMetricServiceClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *MetricClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *MetricClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *MetricClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // ListMonitoredResourceDescriptors lists monitored resource descriptors that match a filter. This method does not require a Stackdriver account. func (c *MetricClient) ListMonitoredResourceDescriptors(ctx context.Context, req *monitoringpb.ListMonitoredResourceDescriptorsRequest, opts ...gax.CallOption) *MonitoredResourceDescriptorIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListMonitoredResourceDescriptors[0:len(c.CallOptions.ListMonitoredResourceDescriptors):len(c.CallOptions.ListMonitoredResourceDescriptors)], opts...) it := &MonitoredResourceDescriptorIterator{} req = proto.Clone(req).(*monitoringpb.ListMonitoredResourceDescriptorsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*monitoredrespb.MonitoredResourceDescriptor, string, error) { var resp *monitoringpb.ListMonitoredResourceDescriptorsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.metricClient.ListMonitoredResourceDescriptors(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.ResourceDescriptors, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetMonitoredResourceDescriptor gets a single monitored resource descriptor. This method does not require a Stackdriver account. func (c *MetricClient) GetMonitoredResourceDescriptor(ctx context.Context, req *monitoringpb.GetMonitoredResourceDescriptorRequest, opts ...gax.CallOption) (*monitoredrespb.MonitoredResourceDescriptor, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetMonitoredResourceDescriptor[0:len(c.CallOptions.GetMonitoredResourceDescriptor):len(c.CallOptions.GetMonitoredResourceDescriptor)], opts...) var resp *monitoredrespb.MonitoredResourceDescriptor err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.metricClient.GetMonitoredResourceDescriptor(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListMetricDescriptors lists metric descriptors that match a filter. This method does not require a Stackdriver account. func (c *MetricClient) ListMetricDescriptors(ctx context.Context, req *monitoringpb.ListMetricDescriptorsRequest, opts ...gax.CallOption) *MetricDescriptorIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListMetricDescriptors[0:len(c.CallOptions.ListMetricDescriptors):len(c.CallOptions.ListMetricDescriptors)], opts...) it := &MetricDescriptorIterator{} req = proto.Clone(req).(*monitoringpb.ListMetricDescriptorsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*metricpb.MetricDescriptor, string, error) { var resp *monitoringpb.ListMetricDescriptorsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.metricClient.ListMetricDescriptors(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.MetricDescriptors, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetMetricDescriptor gets a single metric descriptor. This method does not require a Stackdriver account. func (c *MetricClient) GetMetricDescriptor(ctx context.Context, req *monitoringpb.GetMetricDescriptorRequest, opts ...gax.CallOption) (*metricpb.MetricDescriptor, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetMetricDescriptor[0:len(c.CallOptions.GetMetricDescriptor):len(c.CallOptions.GetMetricDescriptor)], opts...) var resp *metricpb.MetricDescriptor err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.metricClient.GetMetricDescriptor(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateMetricDescriptor creates a new metric descriptor. // User-created metric descriptors define // custom metrics (at /monitoring/custom-metrics). func (c *MetricClient) CreateMetricDescriptor(ctx context.Context, req *monitoringpb.CreateMetricDescriptorRequest, opts ...gax.CallOption) (*metricpb.MetricDescriptor, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateMetricDescriptor[0:len(c.CallOptions.CreateMetricDescriptor):len(c.CallOptions.CreateMetricDescriptor)], opts...) var resp *metricpb.MetricDescriptor err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.metricClient.CreateMetricDescriptor(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteMetricDescriptor deletes a metric descriptor. Only user-created // custom metrics (at /monitoring/custom-metrics) can be deleted. func (c *MetricClient) DeleteMetricDescriptor(ctx context.Context, req *monitoringpb.DeleteMetricDescriptorRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteMetricDescriptor[0:len(c.CallOptions.DeleteMetricDescriptor):len(c.CallOptions.DeleteMetricDescriptor)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.metricClient.DeleteMetricDescriptor(ctx, req, settings.GRPC...) return err }, opts...) return err } // ListTimeSeries lists time series that match a filter. This method does not require a Stackdriver account. func (c *MetricClient) ListTimeSeries(ctx context.Context, req *monitoringpb.ListTimeSeriesRequest, opts ...gax.CallOption) *TimeSeriesIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListTimeSeries[0:len(c.CallOptions.ListTimeSeries):len(c.CallOptions.ListTimeSeries)], opts...) it := &TimeSeriesIterator{} req = proto.Clone(req).(*monitoringpb.ListTimeSeriesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*monitoringpb.TimeSeries, string, error) { var resp *monitoringpb.ListTimeSeriesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.metricClient.ListTimeSeries(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.TimeSeries, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // CreateTimeSeries creates or adds data to one or more time series. // The response is empty if all time series in the request were written. // If any time series could not be written, a corresponding failure message is // included in the error response. func (c *MetricClient) CreateTimeSeries(ctx context.Context, req *monitoringpb.CreateTimeSeriesRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateTimeSeries[0:len(c.CallOptions.CreateTimeSeries):len(c.CallOptions.CreateTimeSeries)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.metricClient.CreateTimeSeries(ctx, req, settings.GRPC...) return err }, opts...) return err } // MetricDescriptorIterator manages a stream of *metricpb.MetricDescriptor. type MetricDescriptorIterator struct { items []*metricpb.MetricDescriptor pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*metricpb.MetricDescriptor, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *MetricDescriptorIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *MetricDescriptorIterator) Next() (*metricpb.MetricDescriptor, error) { var item *metricpb.MetricDescriptor if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *MetricDescriptorIterator) bufLen() int { return len(it.items) } func (it *MetricDescriptorIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // MonitoredResourceDescriptorIterator manages a stream of *monitoredrespb.MonitoredResourceDescriptor. type MonitoredResourceDescriptorIterator struct { items []*monitoredrespb.MonitoredResourceDescriptor pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*monitoredrespb.MonitoredResourceDescriptor, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *MonitoredResourceDescriptorIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *MonitoredResourceDescriptorIterator) Next() (*monitoredrespb.MonitoredResourceDescriptor, error) { var item *monitoredrespb.MonitoredResourceDescriptor if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *MonitoredResourceDescriptorIterator) bufLen() int { return len(it.items) } func (it *MonitoredResourceDescriptorIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // TimeSeriesIterator manages a stream of *monitoringpb.TimeSeries. type TimeSeriesIterator struct { items []*monitoringpb.TimeSeries pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*monitoringpb.TimeSeries, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *TimeSeriesIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *TimeSeriesIterator) Next() (*monitoringpb.TimeSeries, error) { var item *monitoringpb.TimeSeries if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *TimeSeriesIterator) bufLen() int { return len(it.items) } func (it *TimeSeriesIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/monitoring/apiv3/metric_client_example_test.go000066400000000000000000000103231356504100700257200ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package monitoring_test import ( "context" monitoring "cloud.google.com/go/monitoring/apiv3" "google.golang.org/api/iterator" monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3" ) func ExampleNewMetricClient() { ctx := context.Background() c, err := monitoring.NewMetricClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleMetricClient_ListMonitoredResourceDescriptors() { ctx := context.Background() c, err := monitoring.NewMetricClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.ListMonitoredResourceDescriptorsRequest{ // TODO: Fill request struct fields. } it := c.ListMonitoredResourceDescriptors(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleMetricClient_GetMonitoredResourceDescriptor() { ctx := context.Background() c, err := monitoring.NewMetricClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.GetMonitoredResourceDescriptorRequest{ // TODO: Fill request struct fields. } resp, err := c.GetMonitoredResourceDescriptor(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleMetricClient_ListMetricDescriptors() { ctx := context.Background() c, err := monitoring.NewMetricClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.ListMetricDescriptorsRequest{ // TODO: Fill request struct fields. } it := c.ListMetricDescriptors(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleMetricClient_GetMetricDescriptor() { ctx := context.Background() c, err := monitoring.NewMetricClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.GetMetricDescriptorRequest{ // TODO: Fill request struct fields. } resp, err := c.GetMetricDescriptor(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleMetricClient_CreateMetricDescriptor() { ctx := context.Background() c, err := monitoring.NewMetricClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.CreateMetricDescriptorRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateMetricDescriptor(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleMetricClient_DeleteMetricDescriptor() { ctx := context.Background() c, err := monitoring.NewMetricClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.DeleteMetricDescriptorRequest{ // TODO: Fill request struct fields. } err = c.DeleteMetricDescriptor(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleMetricClient_ListTimeSeries() { ctx := context.Background() c, err := monitoring.NewMetricClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.ListTimeSeriesRequest{ // TODO: Fill request struct fields. } it := c.ListTimeSeries(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleMetricClient_CreateTimeSeries() { ctx := context.Background() c, err := monitoring.NewMetricClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.CreateTimeSeriesRequest{ // TODO: Fill request struct fields. } err = c.CreateTimeSeries(ctx, req) if err != nil { // TODO: Handle error. } } google-cloud-go-0.49.0/monitoring/apiv3/mock_test.go000066400000000000000000003352461356504100700223330ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package monitoring import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" "google.golang.org/api/option" metricpb "google.golang.org/genproto/googleapis/api/metric" monitoredrespb "google.golang.org/genproto/googleapis/api/monitoredres" monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockAlertPolicyServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. monitoringpb.AlertPolicyServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockAlertPolicyServer) ListAlertPolicies(ctx context.Context, req *monitoringpb.ListAlertPoliciesRequest) (*monitoringpb.ListAlertPoliciesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*monitoringpb.ListAlertPoliciesResponse), nil } func (s *mockAlertPolicyServer) GetAlertPolicy(ctx context.Context, req *monitoringpb.GetAlertPolicyRequest) (*monitoringpb.AlertPolicy, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*monitoringpb.AlertPolicy), nil } func (s *mockAlertPolicyServer) CreateAlertPolicy(ctx context.Context, req *monitoringpb.CreateAlertPolicyRequest) (*monitoringpb.AlertPolicy, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*monitoringpb.AlertPolicy), nil } func (s *mockAlertPolicyServer) DeleteAlertPolicy(ctx context.Context, req *monitoringpb.DeleteAlertPolicyRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockAlertPolicyServer) UpdateAlertPolicy(ctx context.Context, req *monitoringpb.UpdateAlertPolicyRequest) (*monitoringpb.AlertPolicy, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*monitoringpb.AlertPolicy), nil } type mockGroupServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. monitoringpb.GroupServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockGroupServer) ListGroups(ctx context.Context, req *monitoringpb.ListGroupsRequest) (*monitoringpb.ListGroupsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*monitoringpb.ListGroupsResponse), nil } func (s *mockGroupServer) GetGroup(ctx context.Context, req *monitoringpb.GetGroupRequest) (*monitoringpb.Group, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*monitoringpb.Group), nil } func (s *mockGroupServer) CreateGroup(ctx context.Context, req *monitoringpb.CreateGroupRequest) (*monitoringpb.Group, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*monitoringpb.Group), nil } func (s *mockGroupServer) UpdateGroup(ctx context.Context, req *monitoringpb.UpdateGroupRequest) (*monitoringpb.Group, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*monitoringpb.Group), nil } func (s *mockGroupServer) DeleteGroup(ctx context.Context, req *monitoringpb.DeleteGroupRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockGroupServer) ListGroupMembers(ctx context.Context, req *monitoringpb.ListGroupMembersRequest) (*monitoringpb.ListGroupMembersResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*monitoringpb.ListGroupMembersResponse), nil } type mockMetricServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. monitoringpb.MetricServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockMetricServer) ListMonitoredResourceDescriptors(ctx context.Context, req *monitoringpb.ListMonitoredResourceDescriptorsRequest) (*monitoringpb.ListMonitoredResourceDescriptorsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*monitoringpb.ListMonitoredResourceDescriptorsResponse), nil } func (s *mockMetricServer) GetMonitoredResourceDescriptor(ctx context.Context, req *monitoringpb.GetMonitoredResourceDescriptorRequest) (*monitoredrespb.MonitoredResourceDescriptor, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*monitoredrespb.MonitoredResourceDescriptor), nil } func (s *mockMetricServer) ListMetricDescriptors(ctx context.Context, req *monitoringpb.ListMetricDescriptorsRequest) (*monitoringpb.ListMetricDescriptorsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*monitoringpb.ListMetricDescriptorsResponse), nil } func (s *mockMetricServer) GetMetricDescriptor(ctx context.Context, req *monitoringpb.GetMetricDescriptorRequest) (*metricpb.MetricDescriptor, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*metricpb.MetricDescriptor), nil } func (s *mockMetricServer) CreateMetricDescriptor(ctx context.Context, req *monitoringpb.CreateMetricDescriptorRequest) (*metricpb.MetricDescriptor, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*metricpb.MetricDescriptor), nil } func (s *mockMetricServer) DeleteMetricDescriptor(ctx context.Context, req *monitoringpb.DeleteMetricDescriptorRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockMetricServer) ListTimeSeries(ctx context.Context, req *monitoringpb.ListTimeSeriesRequest) (*monitoringpb.ListTimeSeriesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*monitoringpb.ListTimeSeriesResponse), nil } func (s *mockMetricServer) CreateTimeSeries(ctx context.Context, req *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } type mockNotificationChannelServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. monitoringpb.NotificationChannelServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockNotificationChannelServer) ListNotificationChannelDescriptors(ctx context.Context, req *monitoringpb.ListNotificationChannelDescriptorsRequest) (*monitoringpb.ListNotificationChannelDescriptorsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*monitoringpb.ListNotificationChannelDescriptorsResponse), nil } func (s *mockNotificationChannelServer) GetNotificationChannelDescriptor(ctx context.Context, req *monitoringpb.GetNotificationChannelDescriptorRequest) (*monitoringpb.NotificationChannelDescriptor, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*monitoringpb.NotificationChannelDescriptor), nil } func (s *mockNotificationChannelServer) ListNotificationChannels(ctx context.Context, req *monitoringpb.ListNotificationChannelsRequest) (*monitoringpb.ListNotificationChannelsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*monitoringpb.ListNotificationChannelsResponse), nil } func (s *mockNotificationChannelServer) GetNotificationChannel(ctx context.Context, req *monitoringpb.GetNotificationChannelRequest) (*monitoringpb.NotificationChannel, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*monitoringpb.NotificationChannel), nil } func (s *mockNotificationChannelServer) CreateNotificationChannel(ctx context.Context, req *monitoringpb.CreateNotificationChannelRequest) (*monitoringpb.NotificationChannel, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*monitoringpb.NotificationChannel), nil } func (s *mockNotificationChannelServer) UpdateNotificationChannel(ctx context.Context, req *monitoringpb.UpdateNotificationChannelRequest) (*monitoringpb.NotificationChannel, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*monitoringpb.NotificationChannel), nil } func (s *mockNotificationChannelServer) DeleteNotificationChannel(ctx context.Context, req *monitoringpb.DeleteNotificationChannelRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockNotificationChannelServer) SendNotificationChannelVerificationCode(ctx context.Context, req *monitoringpb.SendNotificationChannelVerificationCodeRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockNotificationChannelServer) GetNotificationChannelVerificationCode(ctx context.Context, req *monitoringpb.GetNotificationChannelVerificationCodeRequest) (*monitoringpb.GetNotificationChannelVerificationCodeResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*monitoringpb.GetNotificationChannelVerificationCodeResponse), nil } func (s *mockNotificationChannelServer) VerifyNotificationChannel(ctx context.Context, req *monitoringpb.VerifyNotificationChannelRequest) (*monitoringpb.NotificationChannel, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*monitoringpb.NotificationChannel), nil } type mockServiceMonitoringServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. monitoringpb.ServiceMonitoringServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockServiceMonitoringServer) CreateService(ctx context.Context, req *monitoringpb.CreateServiceRequest) (*monitoringpb.Service, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*monitoringpb.Service), nil } func (s *mockServiceMonitoringServer) GetService(ctx context.Context, req *monitoringpb.GetServiceRequest) (*monitoringpb.Service, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*monitoringpb.Service), nil } func (s *mockServiceMonitoringServer) ListServices(ctx context.Context, req *monitoringpb.ListServicesRequest) (*monitoringpb.ListServicesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*monitoringpb.ListServicesResponse), nil } func (s *mockServiceMonitoringServer) UpdateService(ctx context.Context, req *monitoringpb.UpdateServiceRequest) (*monitoringpb.Service, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*monitoringpb.Service), nil } func (s *mockServiceMonitoringServer) DeleteService(ctx context.Context, req *monitoringpb.DeleteServiceRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockServiceMonitoringServer) CreateServiceLevelObjective(ctx context.Context, req *monitoringpb.CreateServiceLevelObjectiveRequest) (*monitoringpb.ServiceLevelObjective, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*monitoringpb.ServiceLevelObjective), nil } func (s *mockServiceMonitoringServer) GetServiceLevelObjective(ctx context.Context, req *monitoringpb.GetServiceLevelObjectiveRequest) (*monitoringpb.ServiceLevelObjective, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*monitoringpb.ServiceLevelObjective), nil } func (s *mockServiceMonitoringServer) ListServiceLevelObjectives(ctx context.Context, req *monitoringpb.ListServiceLevelObjectivesRequest) (*monitoringpb.ListServiceLevelObjectivesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*monitoringpb.ListServiceLevelObjectivesResponse), nil } func (s *mockServiceMonitoringServer) UpdateServiceLevelObjective(ctx context.Context, req *monitoringpb.UpdateServiceLevelObjectiveRequest) (*monitoringpb.ServiceLevelObjective, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*monitoringpb.ServiceLevelObjective), nil } func (s *mockServiceMonitoringServer) DeleteServiceLevelObjective(ctx context.Context, req *monitoringpb.DeleteServiceLevelObjectiveRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } type mockUptimeCheckServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. monitoringpb.UptimeCheckServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockUptimeCheckServer) ListUptimeCheckConfigs(ctx context.Context, req *monitoringpb.ListUptimeCheckConfigsRequest) (*monitoringpb.ListUptimeCheckConfigsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*monitoringpb.ListUptimeCheckConfigsResponse), nil } func (s *mockUptimeCheckServer) GetUptimeCheckConfig(ctx context.Context, req *monitoringpb.GetUptimeCheckConfigRequest) (*monitoringpb.UptimeCheckConfig, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*monitoringpb.UptimeCheckConfig), nil } func (s *mockUptimeCheckServer) CreateUptimeCheckConfig(ctx context.Context, req *monitoringpb.CreateUptimeCheckConfigRequest) (*monitoringpb.UptimeCheckConfig, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*monitoringpb.UptimeCheckConfig), nil } func (s *mockUptimeCheckServer) UpdateUptimeCheckConfig(ctx context.Context, req *monitoringpb.UpdateUptimeCheckConfigRequest) (*monitoringpb.UptimeCheckConfig, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*monitoringpb.UptimeCheckConfig), nil } func (s *mockUptimeCheckServer) DeleteUptimeCheckConfig(ctx context.Context, req *monitoringpb.DeleteUptimeCheckConfigRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockUptimeCheckServer) ListUptimeCheckIps(ctx context.Context, req *monitoringpb.ListUptimeCheckIpsRequest) (*monitoringpb.ListUptimeCheckIpsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*monitoringpb.ListUptimeCheckIpsResponse), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockAlertPolicy mockAlertPolicyServer mockGroup mockGroupServer mockMetric mockMetricServer mockNotificationChannel mockNotificationChannelServer mockServiceMonitoring mockServiceMonitoringServer mockUptimeCheck mockUptimeCheckServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() monitoringpb.RegisterAlertPolicyServiceServer(serv, &mockAlertPolicy) monitoringpb.RegisterGroupServiceServer(serv, &mockGroup) monitoringpb.RegisterMetricServiceServer(serv, &mockMetric) monitoringpb.RegisterNotificationChannelServiceServer(serv, &mockNotificationChannel) monitoringpb.RegisterServiceMonitoringServiceServer(serv, &mockServiceMonitoring) monitoringpb.RegisterUptimeCheckServiceServer(serv, &mockUptimeCheck) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestAlertPolicyServiceListAlertPolicies(t *testing.T) { var nextPageToken string = "" var alertPoliciesElement *monitoringpb.AlertPolicy = &monitoringpb.AlertPolicy{} var alertPolicies = []*monitoringpb.AlertPolicy{alertPoliciesElement} var expectedResponse = &monitoringpb.ListAlertPoliciesResponse{ NextPageToken: nextPageToken, AlertPolicies: alertPolicies, } mockAlertPolicy.err = nil mockAlertPolicy.reqs = nil mockAlertPolicy.resps = append(mockAlertPolicy.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &monitoringpb.ListAlertPoliciesRequest{ Name: formattedName, } c, err := NewAlertPolicyClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListAlertPolicies(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockAlertPolicy.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.AlertPolicies[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAlertPolicyServiceListAlertPoliciesError(t *testing.T) { errCode := codes.PermissionDenied mockAlertPolicy.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &monitoringpb.ListAlertPoliciesRequest{ Name: formattedName, } c, err := NewAlertPolicyClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListAlertPolicies(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAlertPolicyServiceGetAlertPolicy(t *testing.T) { var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var expectedResponse = &monitoringpb.AlertPolicy{ Name: name2, DisplayName: displayName, } mockAlertPolicy.err = nil mockAlertPolicy.reqs = nil mockAlertPolicy.resps = append(mockAlertPolicy.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/alertPolicies/%s", "[PROJECT]", "[ALERT_POLICY]") var request = &monitoringpb.GetAlertPolicyRequest{ Name: formattedName, } c, err := NewAlertPolicyClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetAlertPolicy(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockAlertPolicy.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAlertPolicyServiceGetAlertPolicyError(t *testing.T) { errCode := codes.PermissionDenied mockAlertPolicy.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/alertPolicies/%s", "[PROJECT]", "[ALERT_POLICY]") var request = &monitoringpb.GetAlertPolicyRequest{ Name: formattedName, } c, err := NewAlertPolicyClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetAlertPolicy(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAlertPolicyServiceCreateAlertPolicy(t *testing.T) { var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var expectedResponse = &monitoringpb.AlertPolicy{ Name: name2, DisplayName: displayName, } mockAlertPolicy.err = nil mockAlertPolicy.reqs = nil mockAlertPolicy.resps = append(mockAlertPolicy.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s", "[PROJECT]") var alertPolicy *monitoringpb.AlertPolicy = &monitoringpb.AlertPolicy{} var request = &monitoringpb.CreateAlertPolicyRequest{ Name: formattedName, AlertPolicy: alertPolicy, } c, err := NewAlertPolicyClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateAlertPolicy(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockAlertPolicy.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAlertPolicyServiceCreateAlertPolicyError(t *testing.T) { errCode := codes.PermissionDenied mockAlertPolicy.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s", "[PROJECT]") var alertPolicy *monitoringpb.AlertPolicy = &monitoringpb.AlertPolicy{} var request = &monitoringpb.CreateAlertPolicyRequest{ Name: formattedName, AlertPolicy: alertPolicy, } c, err := NewAlertPolicyClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateAlertPolicy(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestAlertPolicyServiceDeleteAlertPolicy(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockAlertPolicy.err = nil mockAlertPolicy.reqs = nil mockAlertPolicy.resps = append(mockAlertPolicy.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/alertPolicies/%s", "[PROJECT]", "[ALERT_POLICY]") var request = &monitoringpb.DeleteAlertPolicyRequest{ Name: formattedName, } c, err := NewAlertPolicyClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteAlertPolicy(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockAlertPolicy.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestAlertPolicyServiceDeleteAlertPolicyError(t *testing.T) { errCode := codes.PermissionDenied mockAlertPolicy.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/alertPolicies/%s", "[PROJECT]", "[ALERT_POLICY]") var request = &monitoringpb.DeleteAlertPolicyRequest{ Name: formattedName, } c, err := NewAlertPolicyClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteAlertPolicy(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestAlertPolicyServiceUpdateAlertPolicy(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var expectedResponse = &monitoringpb.AlertPolicy{ Name: name, DisplayName: displayName, } mockAlertPolicy.err = nil mockAlertPolicy.reqs = nil mockAlertPolicy.resps = append(mockAlertPolicy.resps[:0], expectedResponse) var alertPolicy *monitoringpb.AlertPolicy = &monitoringpb.AlertPolicy{} var request = &monitoringpb.UpdateAlertPolicyRequest{ AlertPolicy: alertPolicy, } c, err := NewAlertPolicyClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateAlertPolicy(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockAlertPolicy.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestAlertPolicyServiceUpdateAlertPolicyError(t *testing.T) { errCode := codes.PermissionDenied mockAlertPolicy.err = gstatus.Error(errCode, "test error") var alertPolicy *monitoringpb.AlertPolicy = &monitoringpb.AlertPolicy{} var request = &monitoringpb.UpdateAlertPolicyRequest{ AlertPolicy: alertPolicy, } c, err := NewAlertPolicyClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateAlertPolicy(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestGroupServiceListGroups(t *testing.T) { var nextPageToken string = "" var groupElement *monitoringpb.Group = &monitoringpb.Group{} var group = []*monitoringpb.Group{groupElement} var expectedResponse = &monitoringpb.ListGroupsResponse{ NextPageToken: nextPageToken, Group: group, } mockGroup.err = nil mockGroup.reqs = nil mockGroup.resps = append(mockGroup.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &monitoringpb.ListGroupsRequest{ Name: formattedName, } c, err := NewGroupClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListGroups(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockGroup.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Group[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestGroupServiceListGroupsError(t *testing.T) { errCode := codes.PermissionDenied mockGroup.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &monitoringpb.ListGroupsRequest{ Name: formattedName, } c, err := NewGroupClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListGroups(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestGroupServiceGetGroup(t *testing.T) { var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var parentName string = "parentName1015022848" var filter string = "filter-1274492040" var isCluster bool = false var expectedResponse = &monitoringpb.Group{ Name: name2, DisplayName: displayName, ParentName: parentName, Filter: filter, IsCluster: isCluster, } mockGroup.err = nil mockGroup.reqs = nil mockGroup.resps = append(mockGroup.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/groups/%s", "[PROJECT]", "[GROUP]") var request = &monitoringpb.GetGroupRequest{ Name: formattedName, } c, err := NewGroupClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetGroup(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockGroup.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestGroupServiceGetGroupError(t *testing.T) { errCode := codes.PermissionDenied mockGroup.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/groups/%s", "[PROJECT]", "[GROUP]") var request = &monitoringpb.GetGroupRequest{ Name: formattedName, } c, err := NewGroupClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetGroup(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestGroupServiceCreateGroup(t *testing.T) { var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var parentName string = "parentName1015022848" var filter string = "filter-1274492040" var isCluster bool = false var expectedResponse = &monitoringpb.Group{ Name: name2, DisplayName: displayName, ParentName: parentName, Filter: filter, IsCluster: isCluster, } mockGroup.err = nil mockGroup.reqs = nil mockGroup.resps = append(mockGroup.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s", "[PROJECT]") var group *monitoringpb.Group = &monitoringpb.Group{} var request = &monitoringpb.CreateGroupRequest{ Name: formattedName, Group: group, } c, err := NewGroupClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateGroup(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockGroup.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestGroupServiceCreateGroupError(t *testing.T) { errCode := codes.PermissionDenied mockGroup.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s", "[PROJECT]") var group *monitoringpb.Group = &monitoringpb.Group{} var request = &monitoringpb.CreateGroupRequest{ Name: formattedName, Group: group, } c, err := NewGroupClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateGroup(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestGroupServiceUpdateGroup(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var parentName string = "parentName1015022848" var filter string = "filter-1274492040" var isCluster bool = false var expectedResponse = &monitoringpb.Group{ Name: name, DisplayName: displayName, ParentName: parentName, Filter: filter, IsCluster: isCluster, } mockGroup.err = nil mockGroup.reqs = nil mockGroup.resps = append(mockGroup.resps[:0], expectedResponse) var group *monitoringpb.Group = &monitoringpb.Group{} var request = &monitoringpb.UpdateGroupRequest{ Group: group, } c, err := NewGroupClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateGroup(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockGroup.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestGroupServiceUpdateGroupError(t *testing.T) { errCode := codes.PermissionDenied mockGroup.err = gstatus.Error(errCode, "test error") var group *monitoringpb.Group = &monitoringpb.Group{} var request = &monitoringpb.UpdateGroupRequest{ Group: group, } c, err := NewGroupClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateGroup(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestGroupServiceDeleteGroup(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockGroup.err = nil mockGroup.reqs = nil mockGroup.resps = append(mockGroup.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/groups/%s", "[PROJECT]", "[GROUP]") var request = &monitoringpb.DeleteGroupRequest{ Name: formattedName, } c, err := NewGroupClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteGroup(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockGroup.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestGroupServiceDeleteGroupError(t *testing.T) { errCode := codes.PermissionDenied mockGroup.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/groups/%s", "[PROJECT]", "[GROUP]") var request = &monitoringpb.DeleteGroupRequest{ Name: formattedName, } c, err := NewGroupClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteGroup(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestGroupServiceListGroupMembers(t *testing.T) { var nextPageToken string = "" var totalSize int32 = 705419236 var membersElement *monitoredrespb.MonitoredResource = &monitoredrespb.MonitoredResource{} var members = []*monitoredrespb.MonitoredResource{membersElement} var expectedResponse = &monitoringpb.ListGroupMembersResponse{ NextPageToken: nextPageToken, TotalSize: totalSize, Members: members, } mockGroup.err = nil mockGroup.reqs = nil mockGroup.resps = append(mockGroup.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/groups/%s", "[PROJECT]", "[GROUP]") var request = &monitoringpb.ListGroupMembersRequest{ Name: formattedName, } c, err := NewGroupClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListGroupMembers(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockGroup.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Members[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestGroupServiceListGroupMembersError(t *testing.T) { errCode := codes.PermissionDenied mockGroup.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/groups/%s", "[PROJECT]", "[GROUP]") var request = &monitoringpb.ListGroupMembersRequest{ Name: formattedName, } c, err := NewGroupClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListGroupMembers(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestMetricServiceListMonitoredResourceDescriptors(t *testing.T) { var nextPageToken string = "" var resourceDescriptorsElement *monitoredrespb.MonitoredResourceDescriptor = &monitoredrespb.MonitoredResourceDescriptor{} var resourceDescriptors = []*monitoredrespb.MonitoredResourceDescriptor{resourceDescriptorsElement} var expectedResponse = &monitoringpb.ListMonitoredResourceDescriptorsResponse{ NextPageToken: nextPageToken, ResourceDescriptors: resourceDescriptors, } mockMetric.err = nil mockMetric.reqs = nil mockMetric.resps = append(mockMetric.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &monitoringpb.ListMonitoredResourceDescriptorsRequest{ Name: formattedName, } c, err := NewMetricClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListMonitoredResourceDescriptors(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockMetric.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.ResourceDescriptors[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestMetricServiceListMonitoredResourceDescriptorsError(t *testing.T) { errCode := codes.PermissionDenied mockMetric.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &monitoringpb.ListMonitoredResourceDescriptorsRequest{ Name: formattedName, } c, err := NewMetricClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListMonitoredResourceDescriptors(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestMetricServiceGetMonitoredResourceDescriptor(t *testing.T) { var name2 string = "name2-1052831874" var type_ string = "type3575610" var displayName string = "displayName1615086568" var description string = "description-1724546052" var expectedResponse = &monitoredrespb.MonitoredResourceDescriptor{ Name: name2, Type: type_, DisplayName: displayName, Description: description, } mockMetric.err = nil mockMetric.reqs = nil mockMetric.resps = append(mockMetric.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/monitoredResourceDescriptors/%s", "[PROJECT]", "[MONITORED_RESOURCE_DESCRIPTOR]") var request = &monitoringpb.GetMonitoredResourceDescriptorRequest{ Name: formattedName, } c, err := NewMetricClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetMonitoredResourceDescriptor(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockMetric.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestMetricServiceGetMonitoredResourceDescriptorError(t *testing.T) { errCode := codes.PermissionDenied mockMetric.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/monitoredResourceDescriptors/%s", "[PROJECT]", "[MONITORED_RESOURCE_DESCRIPTOR]") var request = &monitoringpb.GetMonitoredResourceDescriptorRequest{ Name: formattedName, } c, err := NewMetricClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetMonitoredResourceDescriptor(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestMetricServiceListMetricDescriptors(t *testing.T) { var nextPageToken string = "" var metricDescriptorsElement *metricpb.MetricDescriptor = &metricpb.MetricDescriptor{} var metricDescriptors = []*metricpb.MetricDescriptor{metricDescriptorsElement} var expectedResponse = &monitoringpb.ListMetricDescriptorsResponse{ NextPageToken: nextPageToken, MetricDescriptors: metricDescriptors, } mockMetric.err = nil mockMetric.reqs = nil mockMetric.resps = append(mockMetric.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &monitoringpb.ListMetricDescriptorsRequest{ Name: formattedName, } c, err := NewMetricClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListMetricDescriptors(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockMetric.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.MetricDescriptors[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestMetricServiceListMetricDescriptorsError(t *testing.T) { errCode := codes.PermissionDenied mockMetric.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &monitoringpb.ListMetricDescriptorsRequest{ Name: formattedName, } c, err := NewMetricClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListMetricDescriptors(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestMetricServiceGetMetricDescriptor(t *testing.T) { var name2 string = "name2-1052831874" var type_ string = "type3575610" var unit string = "unit3594628" var description string = "description-1724546052" var displayName string = "displayName1615086568" var expectedResponse = &metricpb.MetricDescriptor{ Name: name2, Type: type_, Unit: unit, Description: description, DisplayName: displayName, } mockMetric.err = nil mockMetric.reqs = nil mockMetric.resps = append(mockMetric.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/metricDescriptors/%s", "[PROJECT]", "[METRIC_DESCRIPTOR]") var request = &monitoringpb.GetMetricDescriptorRequest{ Name: formattedName, } c, err := NewMetricClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetMetricDescriptor(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockMetric.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestMetricServiceGetMetricDescriptorError(t *testing.T) { errCode := codes.PermissionDenied mockMetric.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/metricDescriptors/%s", "[PROJECT]", "[METRIC_DESCRIPTOR]") var request = &monitoringpb.GetMetricDescriptorRequest{ Name: formattedName, } c, err := NewMetricClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetMetricDescriptor(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestMetricServiceCreateMetricDescriptor(t *testing.T) { var name2 string = "name2-1052831874" var type_ string = "type3575610" var unit string = "unit3594628" var description string = "description-1724546052" var displayName string = "displayName1615086568" var expectedResponse = &metricpb.MetricDescriptor{ Name: name2, Type: type_, Unit: unit, Description: description, DisplayName: displayName, } mockMetric.err = nil mockMetric.reqs = nil mockMetric.resps = append(mockMetric.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s", "[PROJECT]") var metricDescriptor *metricpb.MetricDescriptor = &metricpb.MetricDescriptor{} var request = &monitoringpb.CreateMetricDescriptorRequest{ Name: formattedName, MetricDescriptor: metricDescriptor, } c, err := NewMetricClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateMetricDescriptor(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockMetric.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestMetricServiceCreateMetricDescriptorError(t *testing.T) { errCode := codes.PermissionDenied mockMetric.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s", "[PROJECT]") var metricDescriptor *metricpb.MetricDescriptor = &metricpb.MetricDescriptor{} var request = &monitoringpb.CreateMetricDescriptorRequest{ Name: formattedName, MetricDescriptor: metricDescriptor, } c, err := NewMetricClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateMetricDescriptor(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestMetricServiceDeleteMetricDescriptor(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockMetric.err = nil mockMetric.reqs = nil mockMetric.resps = append(mockMetric.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/metricDescriptors/%s", "[PROJECT]", "[METRIC_DESCRIPTOR]") var request = &monitoringpb.DeleteMetricDescriptorRequest{ Name: formattedName, } c, err := NewMetricClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteMetricDescriptor(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockMetric.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestMetricServiceDeleteMetricDescriptorError(t *testing.T) { errCode := codes.PermissionDenied mockMetric.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/metricDescriptors/%s", "[PROJECT]", "[METRIC_DESCRIPTOR]") var request = &monitoringpb.DeleteMetricDescriptorRequest{ Name: formattedName, } c, err := NewMetricClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteMetricDescriptor(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestMetricServiceListTimeSeries(t *testing.T) { var nextPageToken string = "" var timeSeriesElement *monitoringpb.TimeSeries = &monitoringpb.TimeSeries{} var timeSeries = []*monitoringpb.TimeSeries{timeSeriesElement} var expectedResponse = &monitoringpb.ListTimeSeriesResponse{ NextPageToken: nextPageToken, TimeSeries: timeSeries, } mockMetric.err = nil mockMetric.reqs = nil mockMetric.resps = append(mockMetric.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s", "[PROJECT]") var filter string = "filter-1274492040" var interval *monitoringpb.TimeInterval = &monitoringpb.TimeInterval{} var view monitoringpb.ListTimeSeriesRequest_TimeSeriesView = monitoringpb.ListTimeSeriesRequest_FULL var request = &monitoringpb.ListTimeSeriesRequest{ Name: formattedName, Filter: filter, Interval: interval, View: view, } c, err := NewMetricClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListTimeSeries(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockMetric.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.TimeSeries[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestMetricServiceListTimeSeriesError(t *testing.T) { errCode := codes.PermissionDenied mockMetric.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s", "[PROJECT]") var filter string = "filter-1274492040" var interval *monitoringpb.TimeInterval = &monitoringpb.TimeInterval{} var view monitoringpb.ListTimeSeriesRequest_TimeSeriesView = monitoringpb.ListTimeSeriesRequest_FULL var request = &monitoringpb.ListTimeSeriesRequest{ Name: formattedName, Filter: filter, Interval: interval, View: view, } c, err := NewMetricClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListTimeSeries(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestMetricServiceCreateTimeSeries(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockMetric.err = nil mockMetric.reqs = nil mockMetric.resps = append(mockMetric.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s", "[PROJECT]") var timeSeries []*monitoringpb.TimeSeries = nil var request = &monitoringpb.CreateTimeSeriesRequest{ Name: formattedName, TimeSeries: timeSeries, } c, err := NewMetricClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.CreateTimeSeries(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockMetric.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestMetricServiceCreateTimeSeriesError(t *testing.T) { errCode := codes.PermissionDenied mockMetric.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s", "[PROJECT]") var timeSeries []*monitoringpb.TimeSeries = nil var request = &monitoringpb.CreateTimeSeriesRequest{ Name: formattedName, TimeSeries: timeSeries, } c, err := NewMetricClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.CreateTimeSeries(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestNotificationChannelServiceListNotificationChannelDescriptors(t *testing.T) { var nextPageToken string = "" var channelDescriptorsElement *monitoringpb.NotificationChannelDescriptor = &monitoringpb.NotificationChannelDescriptor{} var channelDescriptors = []*monitoringpb.NotificationChannelDescriptor{channelDescriptorsElement} var expectedResponse = &monitoringpb.ListNotificationChannelDescriptorsResponse{ NextPageToken: nextPageToken, ChannelDescriptors: channelDescriptors, } mockNotificationChannel.err = nil mockNotificationChannel.reqs = nil mockNotificationChannel.resps = append(mockNotificationChannel.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &monitoringpb.ListNotificationChannelDescriptorsRequest{ Name: formattedName, } c, err := NewNotificationChannelClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListNotificationChannelDescriptors(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockNotificationChannel.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.ChannelDescriptors[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestNotificationChannelServiceListNotificationChannelDescriptorsError(t *testing.T) { errCode := codes.PermissionDenied mockNotificationChannel.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &monitoringpb.ListNotificationChannelDescriptorsRequest{ Name: formattedName, } c, err := NewNotificationChannelClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListNotificationChannelDescriptors(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestNotificationChannelServiceGetNotificationChannelDescriptor(t *testing.T) { var name2 string = "name2-1052831874" var type_ string = "type3575610" var displayName string = "displayName1615086568" var description string = "description-1724546052" var expectedResponse = &monitoringpb.NotificationChannelDescriptor{ Name: name2, Type: type_, DisplayName: displayName, Description: description, } mockNotificationChannel.err = nil mockNotificationChannel.reqs = nil mockNotificationChannel.resps = append(mockNotificationChannel.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/notificationChannelDescriptors/%s", "[PROJECT]", "[CHANNEL_DESCRIPTOR]") var request = &monitoringpb.GetNotificationChannelDescriptorRequest{ Name: formattedName, } c, err := NewNotificationChannelClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetNotificationChannelDescriptor(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockNotificationChannel.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestNotificationChannelServiceGetNotificationChannelDescriptorError(t *testing.T) { errCode := codes.PermissionDenied mockNotificationChannel.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/notificationChannelDescriptors/%s", "[PROJECT]", "[CHANNEL_DESCRIPTOR]") var request = &monitoringpb.GetNotificationChannelDescriptorRequest{ Name: formattedName, } c, err := NewNotificationChannelClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetNotificationChannelDescriptor(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestNotificationChannelServiceListNotificationChannels(t *testing.T) { var nextPageToken string = "" var notificationChannelsElement *monitoringpb.NotificationChannel = &monitoringpb.NotificationChannel{} var notificationChannels = []*monitoringpb.NotificationChannel{notificationChannelsElement} var expectedResponse = &monitoringpb.ListNotificationChannelsResponse{ NextPageToken: nextPageToken, NotificationChannels: notificationChannels, } mockNotificationChannel.err = nil mockNotificationChannel.reqs = nil mockNotificationChannel.resps = append(mockNotificationChannel.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &monitoringpb.ListNotificationChannelsRequest{ Name: formattedName, } c, err := NewNotificationChannelClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListNotificationChannels(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockNotificationChannel.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.NotificationChannels[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestNotificationChannelServiceListNotificationChannelsError(t *testing.T) { errCode := codes.PermissionDenied mockNotificationChannel.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &monitoringpb.ListNotificationChannelsRequest{ Name: formattedName, } c, err := NewNotificationChannelClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListNotificationChannels(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestNotificationChannelServiceGetNotificationChannel(t *testing.T) { var type_ string = "type3575610" var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var description string = "description-1724546052" var expectedResponse = &monitoringpb.NotificationChannel{ Type: type_, Name: name2, DisplayName: displayName, Description: description, } mockNotificationChannel.err = nil mockNotificationChannel.reqs = nil mockNotificationChannel.resps = append(mockNotificationChannel.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/notificationChannels/%s", "[PROJECT]", "[NOTIFICATION_CHANNEL]") var request = &monitoringpb.GetNotificationChannelRequest{ Name: formattedName, } c, err := NewNotificationChannelClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetNotificationChannel(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockNotificationChannel.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestNotificationChannelServiceGetNotificationChannelError(t *testing.T) { errCode := codes.PermissionDenied mockNotificationChannel.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/notificationChannels/%s", "[PROJECT]", "[NOTIFICATION_CHANNEL]") var request = &monitoringpb.GetNotificationChannelRequest{ Name: formattedName, } c, err := NewNotificationChannelClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetNotificationChannel(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestNotificationChannelServiceCreateNotificationChannel(t *testing.T) { var type_ string = "type3575610" var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var description string = "description-1724546052" var expectedResponse = &monitoringpb.NotificationChannel{ Type: type_, Name: name2, DisplayName: displayName, Description: description, } mockNotificationChannel.err = nil mockNotificationChannel.reqs = nil mockNotificationChannel.resps = append(mockNotificationChannel.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s", "[PROJECT]") var notificationChannel *monitoringpb.NotificationChannel = &monitoringpb.NotificationChannel{} var request = &monitoringpb.CreateNotificationChannelRequest{ Name: formattedName, NotificationChannel: notificationChannel, } c, err := NewNotificationChannelClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateNotificationChannel(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockNotificationChannel.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestNotificationChannelServiceCreateNotificationChannelError(t *testing.T) { errCode := codes.PermissionDenied mockNotificationChannel.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s", "[PROJECT]") var notificationChannel *monitoringpb.NotificationChannel = &monitoringpb.NotificationChannel{} var request = &monitoringpb.CreateNotificationChannelRequest{ Name: formattedName, NotificationChannel: notificationChannel, } c, err := NewNotificationChannelClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateNotificationChannel(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestNotificationChannelServiceUpdateNotificationChannel(t *testing.T) { var type_ string = "type3575610" var name string = "name3373707" var displayName string = "displayName1615086568" var description string = "description-1724546052" var expectedResponse = &monitoringpb.NotificationChannel{ Type: type_, Name: name, DisplayName: displayName, Description: description, } mockNotificationChannel.err = nil mockNotificationChannel.reqs = nil mockNotificationChannel.resps = append(mockNotificationChannel.resps[:0], expectedResponse) var notificationChannel *monitoringpb.NotificationChannel = &monitoringpb.NotificationChannel{} var request = &monitoringpb.UpdateNotificationChannelRequest{ NotificationChannel: notificationChannel, } c, err := NewNotificationChannelClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateNotificationChannel(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockNotificationChannel.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestNotificationChannelServiceUpdateNotificationChannelError(t *testing.T) { errCode := codes.PermissionDenied mockNotificationChannel.err = gstatus.Error(errCode, "test error") var notificationChannel *monitoringpb.NotificationChannel = &monitoringpb.NotificationChannel{} var request = &monitoringpb.UpdateNotificationChannelRequest{ NotificationChannel: notificationChannel, } c, err := NewNotificationChannelClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateNotificationChannel(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestNotificationChannelServiceDeleteNotificationChannel(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockNotificationChannel.err = nil mockNotificationChannel.reqs = nil mockNotificationChannel.resps = append(mockNotificationChannel.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/notificationChannels/%s", "[PROJECT]", "[NOTIFICATION_CHANNEL]") var request = &monitoringpb.DeleteNotificationChannelRequest{ Name: formattedName, } c, err := NewNotificationChannelClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteNotificationChannel(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockNotificationChannel.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestNotificationChannelServiceDeleteNotificationChannelError(t *testing.T) { errCode := codes.PermissionDenied mockNotificationChannel.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/notificationChannels/%s", "[PROJECT]", "[NOTIFICATION_CHANNEL]") var request = &monitoringpb.DeleteNotificationChannelRequest{ Name: formattedName, } c, err := NewNotificationChannelClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteNotificationChannel(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestNotificationChannelServiceSendNotificationChannelVerificationCode(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockNotificationChannel.err = nil mockNotificationChannel.reqs = nil mockNotificationChannel.resps = append(mockNotificationChannel.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/notificationChannels/%s", "[PROJECT]", "[NOTIFICATION_CHANNEL]") var request = &monitoringpb.SendNotificationChannelVerificationCodeRequest{ Name: formattedName, } c, err := NewNotificationChannelClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.SendNotificationChannelVerificationCode(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockNotificationChannel.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestNotificationChannelServiceSendNotificationChannelVerificationCodeError(t *testing.T) { errCode := codes.PermissionDenied mockNotificationChannel.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/notificationChannels/%s", "[PROJECT]", "[NOTIFICATION_CHANNEL]") var request = &monitoringpb.SendNotificationChannelVerificationCodeRequest{ Name: formattedName, } c, err := NewNotificationChannelClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.SendNotificationChannelVerificationCode(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestNotificationChannelServiceGetNotificationChannelVerificationCode(t *testing.T) { var code string = "code3059181" var expectedResponse = &monitoringpb.GetNotificationChannelVerificationCodeResponse{ Code: code, } mockNotificationChannel.err = nil mockNotificationChannel.reqs = nil mockNotificationChannel.resps = append(mockNotificationChannel.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/notificationChannels/%s", "[PROJECT]", "[NOTIFICATION_CHANNEL]") var request = &monitoringpb.GetNotificationChannelVerificationCodeRequest{ Name: formattedName, } c, err := NewNotificationChannelClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetNotificationChannelVerificationCode(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockNotificationChannel.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestNotificationChannelServiceGetNotificationChannelVerificationCodeError(t *testing.T) { errCode := codes.PermissionDenied mockNotificationChannel.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/notificationChannels/%s", "[PROJECT]", "[NOTIFICATION_CHANNEL]") var request = &monitoringpb.GetNotificationChannelVerificationCodeRequest{ Name: formattedName, } c, err := NewNotificationChannelClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetNotificationChannelVerificationCode(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestNotificationChannelServiceVerifyNotificationChannel(t *testing.T) { var type_ string = "type3575610" var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var description string = "description-1724546052" var expectedResponse = &monitoringpb.NotificationChannel{ Type: type_, Name: name2, DisplayName: displayName, Description: description, } mockNotificationChannel.err = nil mockNotificationChannel.reqs = nil mockNotificationChannel.resps = append(mockNotificationChannel.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/notificationChannels/%s", "[PROJECT]", "[NOTIFICATION_CHANNEL]") var code string = "code3059181" var request = &monitoringpb.VerifyNotificationChannelRequest{ Name: formattedName, Code: code, } c, err := NewNotificationChannelClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.VerifyNotificationChannel(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockNotificationChannel.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestNotificationChannelServiceVerifyNotificationChannelError(t *testing.T) { errCode := codes.PermissionDenied mockNotificationChannel.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/notificationChannels/%s", "[PROJECT]", "[NOTIFICATION_CHANNEL]") var code string = "code3059181" var request = &monitoringpb.VerifyNotificationChannelRequest{ Name: formattedName, Code: code, } c, err := NewNotificationChannelClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.VerifyNotificationChannel(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestServiceMonitoringServiceCreateService(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var expectedResponse = &monitoringpb.Service{ Name: name, DisplayName: displayName, } mockServiceMonitoring.err = nil mockServiceMonitoring.reqs = nil mockServiceMonitoring.resps = append(mockServiceMonitoring.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var service *monitoringpb.Service = &monitoringpb.Service{} var request = &monitoringpb.CreateServiceRequest{ Parent: formattedParent, Service: service, } c, err := NewServiceMonitoringClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateService(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockServiceMonitoring.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestServiceMonitoringServiceCreateServiceError(t *testing.T) { errCode := codes.PermissionDenied mockServiceMonitoring.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var service *monitoringpb.Service = &monitoringpb.Service{} var request = &monitoringpb.CreateServiceRequest{ Parent: formattedParent, Service: service, } c, err := NewServiceMonitoringClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateService(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestServiceMonitoringServiceGetService(t *testing.T) { var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var expectedResponse = &monitoringpb.Service{ Name: name2, DisplayName: displayName, } mockServiceMonitoring.err = nil mockServiceMonitoring.reqs = nil mockServiceMonitoring.resps = append(mockServiceMonitoring.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/services/%s", "[PROJECT]", "[SERVICE]") var request = &monitoringpb.GetServiceRequest{ Name: formattedName, } c, err := NewServiceMonitoringClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetService(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockServiceMonitoring.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestServiceMonitoringServiceGetServiceError(t *testing.T) { errCode := codes.PermissionDenied mockServiceMonitoring.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/services/%s", "[PROJECT]", "[SERVICE]") var request = &monitoringpb.GetServiceRequest{ Name: formattedName, } c, err := NewServiceMonitoringClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetService(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestServiceMonitoringServiceListServices(t *testing.T) { var nextPageToken string = "" var servicesElement *monitoringpb.Service = &monitoringpb.Service{} var services = []*monitoringpb.Service{servicesElement} var expectedResponse = &monitoringpb.ListServicesResponse{ NextPageToken: nextPageToken, Services: services, } mockServiceMonitoring.err = nil mockServiceMonitoring.reqs = nil mockServiceMonitoring.resps = append(mockServiceMonitoring.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &monitoringpb.ListServicesRequest{ Parent: formattedParent, } c, err := NewServiceMonitoringClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListServices(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockServiceMonitoring.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Services[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestServiceMonitoringServiceListServicesError(t *testing.T) { errCode := codes.PermissionDenied mockServiceMonitoring.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &monitoringpb.ListServicesRequest{ Parent: formattedParent, } c, err := NewServiceMonitoringClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListServices(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestServiceMonitoringServiceUpdateService(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var expectedResponse = &monitoringpb.Service{ Name: name, DisplayName: displayName, } mockServiceMonitoring.err = nil mockServiceMonitoring.reqs = nil mockServiceMonitoring.resps = append(mockServiceMonitoring.resps[:0], expectedResponse) var service *monitoringpb.Service = &monitoringpb.Service{} var request = &monitoringpb.UpdateServiceRequest{ Service: service, } c, err := NewServiceMonitoringClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateService(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockServiceMonitoring.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestServiceMonitoringServiceUpdateServiceError(t *testing.T) { errCode := codes.PermissionDenied mockServiceMonitoring.err = gstatus.Error(errCode, "test error") var service *monitoringpb.Service = &monitoringpb.Service{} var request = &monitoringpb.UpdateServiceRequest{ Service: service, } c, err := NewServiceMonitoringClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateService(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestServiceMonitoringServiceDeleteService(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockServiceMonitoring.err = nil mockServiceMonitoring.reqs = nil mockServiceMonitoring.resps = append(mockServiceMonitoring.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/services/%s", "[PROJECT]", "[SERVICE]") var request = &monitoringpb.DeleteServiceRequest{ Name: formattedName, } c, err := NewServiceMonitoringClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteService(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockServiceMonitoring.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestServiceMonitoringServiceDeleteServiceError(t *testing.T) { errCode := codes.PermissionDenied mockServiceMonitoring.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/services/%s", "[PROJECT]", "[SERVICE]") var request = &monitoringpb.DeleteServiceRequest{ Name: formattedName, } c, err := NewServiceMonitoringClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteService(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestServiceMonitoringServiceCreateServiceLevelObjective(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var goal float64 = 317825.0 var expectedResponse = &monitoringpb.ServiceLevelObjective{ Name: name, DisplayName: displayName, Goal: goal, } mockServiceMonitoring.err = nil mockServiceMonitoring.reqs = nil mockServiceMonitoring.resps = append(mockServiceMonitoring.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/services/%s", "[PROJECT]", "[SERVICE]") var serviceLevelObjective *monitoringpb.ServiceLevelObjective = &monitoringpb.ServiceLevelObjective{} var request = &monitoringpb.CreateServiceLevelObjectiveRequest{ Parent: formattedParent, ServiceLevelObjective: serviceLevelObjective, } c, err := NewServiceMonitoringClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateServiceLevelObjective(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockServiceMonitoring.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestServiceMonitoringServiceCreateServiceLevelObjectiveError(t *testing.T) { errCode := codes.PermissionDenied mockServiceMonitoring.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/services/%s", "[PROJECT]", "[SERVICE]") var serviceLevelObjective *monitoringpb.ServiceLevelObjective = &monitoringpb.ServiceLevelObjective{} var request = &monitoringpb.CreateServiceLevelObjectiveRequest{ Parent: formattedParent, ServiceLevelObjective: serviceLevelObjective, } c, err := NewServiceMonitoringClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateServiceLevelObjective(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestServiceMonitoringServiceGetServiceLevelObjective(t *testing.T) { var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var goal float64 = 317825.0 var expectedResponse = &monitoringpb.ServiceLevelObjective{ Name: name2, DisplayName: displayName, Goal: goal, } mockServiceMonitoring.err = nil mockServiceMonitoring.reqs = nil mockServiceMonitoring.resps = append(mockServiceMonitoring.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/services/%s/serviceLevelObjectives/%s", "[PROJECT]", "[SERVICE]", "[SERVICE_LEVEL_OBJECTIVE]") var request = &monitoringpb.GetServiceLevelObjectiveRequest{ Name: formattedName, } c, err := NewServiceMonitoringClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetServiceLevelObjective(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockServiceMonitoring.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestServiceMonitoringServiceGetServiceLevelObjectiveError(t *testing.T) { errCode := codes.PermissionDenied mockServiceMonitoring.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/services/%s/serviceLevelObjectives/%s", "[PROJECT]", "[SERVICE]", "[SERVICE_LEVEL_OBJECTIVE]") var request = &monitoringpb.GetServiceLevelObjectiveRequest{ Name: formattedName, } c, err := NewServiceMonitoringClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetServiceLevelObjective(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestServiceMonitoringServiceListServiceLevelObjectives(t *testing.T) { var nextPageToken string = "" var serviceLevelObjectivesElement *monitoringpb.ServiceLevelObjective = &monitoringpb.ServiceLevelObjective{} var serviceLevelObjectives = []*monitoringpb.ServiceLevelObjective{serviceLevelObjectivesElement} var expectedResponse = &monitoringpb.ListServiceLevelObjectivesResponse{ NextPageToken: nextPageToken, ServiceLevelObjectives: serviceLevelObjectives, } mockServiceMonitoring.err = nil mockServiceMonitoring.reqs = nil mockServiceMonitoring.resps = append(mockServiceMonitoring.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/services/%s", "[PROJECT]", "[SERVICE]") var request = &monitoringpb.ListServiceLevelObjectivesRequest{ Parent: formattedParent, } c, err := NewServiceMonitoringClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListServiceLevelObjectives(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockServiceMonitoring.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.ServiceLevelObjectives[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestServiceMonitoringServiceListServiceLevelObjectivesError(t *testing.T) { errCode := codes.PermissionDenied mockServiceMonitoring.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/services/%s", "[PROJECT]", "[SERVICE]") var request = &monitoringpb.ListServiceLevelObjectivesRequest{ Parent: formattedParent, } c, err := NewServiceMonitoringClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListServiceLevelObjectives(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestServiceMonitoringServiceUpdateServiceLevelObjective(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var goal float64 = 317825.0 var expectedResponse = &monitoringpb.ServiceLevelObjective{ Name: name, DisplayName: displayName, Goal: goal, } mockServiceMonitoring.err = nil mockServiceMonitoring.reqs = nil mockServiceMonitoring.resps = append(mockServiceMonitoring.resps[:0], expectedResponse) var serviceLevelObjective *monitoringpb.ServiceLevelObjective = &monitoringpb.ServiceLevelObjective{} var request = &monitoringpb.UpdateServiceLevelObjectiveRequest{ ServiceLevelObjective: serviceLevelObjective, } c, err := NewServiceMonitoringClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateServiceLevelObjective(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockServiceMonitoring.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestServiceMonitoringServiceUpdateServiceLevelObjectiveError(t *testing.T) { errCode := codes.PermissionDenied mockServiceMonitoring.err = gstatus.Error(errCode, "test error") var serviceLevelObjective *monitoringpb.ServiceLevelObjective = &monitoringpb.ServiceLevelObjective{} var request = &monitoringpb.UpdateServiceLevelObjectiveRequest{ ServiceLevelObjective: serviceLevelObjective, } c, err := NewServiceMonitoringClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateServiceLevelObjective(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestServiceMonitoringServiceDeleteServiceLevelObjective(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockServiceMonitoring.err = nil mockServiceMonitoring.reqs = nil mockServiceMonitoring.resps = append(mockServiceMonitoring.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/services/%s/serviceLevelObjectives/%s", "[PROJECT]", "[SERVICE]", "[SERVICE_LEVEL_OBJECTIVE]") var request = &monitoringpb.DeleteServiceLevelObjectiveRequest{ Name: formattedName, } c, err := NewServiceMonitoringClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteServiceLevelObjective(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockServiceMonitoring.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestServiceMonitoringServiceDeleteServiceLevelObjectiveError(t *testing.T) { errCode := codes.PermissionDenied mockServiceMonitoring.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/services/%s/serviceLevelObjectives/%s", "[PROJECT]", "[SERVICE]", "[SERVICE_LEVEL_OBJECTIVE]") var request = &monitoringpb.DeleteServiceLevelObjectiveRequest{ Name: formattedName, } c, err := NewServiceMonitoringClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteServiceLevelObjective(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestUptimeCheckServiceListUptimeCheckConfigs(t *testing.T) { var nextPageToken string = "" var totalSize int32 = 705419236 var uptimeCheckConfigsElement *monitoringpb.UptimeCheckConfig = &monitoringpb.UptimeCheckConfig{} var uptimeCheckConfigs = []*monitoringpb.UptimeCheckConfig{uptimeCheckConfigsElement} var expectedResponse = &monitoringpb.ListUptimeCheckConfigsResponse{ NextPageToken: nextPageToken, TotalSize: totalSize, UptimeCheckConfigs: uptimeCheckConfigs, } mockUptimeCheck.err = nil mockUptimeCheck.reqs = nil mockUptimeCheck.resps = append(mockUptimeCheck.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &monitoringpb.ListUptimeCheckConfigsRequest{ Parent: formattedParent, } c, err := NewUptimeCheckClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListUptimeCheckConfigs(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockUptimeCheck.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.UptimeCheckConfigs[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestUptimeCheckServiceListUptimeCheckConfigsError(t *testing.T) { errCode := codes.PermissionDenied mockUptimeCheck.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &monitoringpb.ListUptimeCheckConfigsRequest{ Parent: formattedParent, } c, err := NewUptimeCheckClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListUptimeCheckConfigs(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestUptimeCheckServiceGetUptimeCheckConfig(t *testing.T) { var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var isInternal bool = true var expectedResponse = &monitoringpb.UptimeCheckConfig{ Name: name2, DisplayName: displayName, IsInternal: isInternal, } mockUptimeCheck.err = nil mockUptimeCheck.reqs = nil mockUptimeCheck.resps = append(mockUptimeCheck.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/uptimeCheckConfigs/%s", "[PROJECT]", "[UPTIME_CHECK_CONFIG]") var request = &monitoringpb.GetUptimeCheckConfigRequest{ Name: formattedName, } c, err := NewUptimeCheckClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetUptimeCheckConfig(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockUptimeCheck.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestUptimeCheckServiceGetUptimeCheckConfigError(t *testing.T) { errCode := codes.PermissionDenied mockUptimeCheck.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/uptimeCheckConfigs/%s", "[PROJECT]", "[UPTIME_CHECK_CONFIG]") var request = &monitoringpb.GetUptimeCheckConfigRequest{ Name: formattedName, } c, err := NewUptimeCheckClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetUptimeCheckConfig(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestUptimeCheckServiceCreateUptimeCheckConfig(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var isInternal bool = true var expectedResponse = &monitoringpb.UptimeCheckConfig{ Name: name, DisplayName: displayName, IsInternal: isInternal, } mockUptimeCheck.err = nil mockUptimeCheck.reqs = nil mockUptimeCheck.resps = append(mockUptimeCheck.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var uptimeCheckConfig *monitoringpb.UptimeCheckConfig = &monitoringpb.UptimeCheckConfig{} var request = &monitoringpb.CreateUptimeCheckConfigRequest{ Parent: formattedParent, UptimeCheckConfig: uptimeCheckConfig, } c, err := NewUptimeCheckClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateUptimeCheckConfig(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockUptimeCheck.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestUptimeCheckServiceCreateUptimeCheckConfigError(t *testing.T) { errCode := codes.PermissionDenied mockUptimeCheck.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var uptimeCheckConfig *monitoringpb.UptimeCheckConfig = &monitoringpb.UptimeCheckConfig{} var request = &monitoringpb.CreateUptimeCheckConfigRequest{ Parent: formattedParent, UptimeCheckConfig: uptimeCheckConfig, } c, err := NewUptimeCheckClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateUptimeCheckConfig(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestUptimeCheckServiceUpdateUptimeCheckConfig(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var isInternal bool = true var expectedResponse = &monitoringpb.UptimeCheckConfig{ Name: name, DisplayName: displayName, IsInternal: isInternal, } mockUptimeCheck.err = nil mockUptimeCheck.reqs = nil mockUptimeCheck.resps = append(mockUptimeCheck.resps[:0], expectedResponse) var uptimeCheckConfig *monitoringpb.UptimeCheckConfig = &monitoringpb.UptimeCheckConfig{} var request = &monitoringpb.UpdateUptimeCheckConfigRequest{ UptimeCheckConfig: uptimeCheckConfig, } c, err := NewUptimeCheckClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateUptimeCheckConfig(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockUptimeCheck.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestUptimeCheckServiceUpdateUptimeCheckConfigError(t *testing.T) { errCode := codes.PermissionDenied mockUptimeCheck.err = gstatus.Error(errCode, "test error") var uptimeCheckConfig *monitoringpb.UptimeCheckConfig = &monitoringpb.UptimeCheckConfig{} var request = &monitoringpb.UpdateUptimeCheckConfigRequest{ UptimeCheckConfig: uptimeCheckConfig, } c, err := NewUptimeCheckClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateUptimeCheckConfig(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestUptimeCheckServiceDeleteUptimeCheckConfig(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockUptimeCheck.err = nil mockUptimeCheck.reqs = nil mockUptimeCheck.resps = append(mockUptimeCheck.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/uptimeCheckConfigs/%s", "[PROJECT]", "[UPTIME_CHECK_CONFIG]") var request = &monitoringpb.DeleteUptimeCheckConfigRequest{ Name: formattedName, } c, err := NewUptimeCheckClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteUptimeCheckConfig(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockUptimeCheck.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestUptimeCheckServiceDeleteUptimeCheckConfigError(t *testing.T) { errCode := codes.PermissionDenied mockUptimeCheck.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/uptimeCheckConfigs/%s", "[PROJECT]", "[UPTIME_CHECK_CONFIG]") var request = &monitoringpb.DeleteUptimeCheckConfigRequest{ Name: formattedName, } c, err := NewUptimeCheckClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteUptimeCheckConfig(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestUptimeCheckServiceListUptimeCheckIps(t *testing.T) { var nextPageToken string = "" var uptimeCheckIpsElement *monitoringpb.UptimeCheckIp = &monitoringpb.UptimeCheckIp{} var uptimeCheckIps = []*monitoringpb.UptimeCheckIp{uptimeCheckIpsElement} var expectedResponse = &monitoringpb.ListUptimeCheckIpsResponse{ NextPageToken: nextPageToken, UptimeCheckIps: uptimeCheckIps, } mockUptimeCheck.err = nil mockUptimeCheck.reqs = nil mockUptimeCheck.resps = append(mockUptimeCheck.resps[:0], expectedResponse) var request *monitoringpb.ListUptimeCheckIpsRequest = &monitoringpb.ListUptimeCheckIpsRequest{} c, err := NewUptimeCheckClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListUptimeCheckIps(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockUptimeCheck.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.UptimeCheckIps[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestUptimeCheckServiceListUptimeCheckIpsError(t *testing.T) { errCode := codes.PermissionDenied mockUptimeCheck.err = gstatus.Error(errCode, "test error") var request *monitoringpb.ListUptimeCheckIpsRequest = &monitoringpb.ListUptimeCheckIpsRequest{} c, err := NewUptimeCheckClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListUptimeCheckIps(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/monitoring/apiv3/notification_channel_client.go000066400000000000000000000526251356504100700260540ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package monitoring import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // NotificationChannelCallOptions contains the retry settings for each method of NotificationChannelClient. type NotificationChannelCallOptions struct { ListNotificationChannelDescriptors []gax.CallOption GetNotificationChannelDescriptor []gax.CallOption ListNotificationChannels []gax.CallOption GetNotificationChannel []gax.CallOption CreateNotificationChannel []gax.CallOption UpdateNotificationChannel []gax.CallOption DeleteNotificationChannel []gax.CallOption SendNotificationChannelVerificationCode []gax.CallOption GetNotificationChannelVerificationCode []gax.CallOption VerifyNotificationChannel []gax.CallOption } func defaultNotificationChannelClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("monitoring.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultNotificationChannelCallOptions() *NotificationChannelCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &NotificationChannelCallOptions{ ListNotificationChannelDescriptors: retry[[2]string{"default", "idempotent"}], GetNotificationChannelDescriptor: retry[[2]string{"default", "idempotent"}], ListNotificationChannels: retry[[2]string{"default", "idempotent"}], GetNotificationChannel: retry[[2]string{"default", "idempotent"}], CreateNotificationChannel: retry[[2]string{"default", "non_idempotent"}], UpdateNotificationChannel: retry[[2]string{"default", "non_idempotent"}], DeleteNotificationChannel: retry[[2]string{"default", "idempotent"}], SendNotificationChannelVerificationCode: retry[[2]string{"default", "non_idempotent"}], GetNotificationChannelVerificationCode: retry[[2]string{"default", "idempotent"}], VerifyNotificationChannel: retry[[2]string{"default", "idempotent"}], } } // NotificationChannelClient is a client for interacting with Stackdriver Monitoring API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type NotificationChannelClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. notificationChannelClient monitoringpb.NotificationChannelServiceClient // The call options for this service. CallOptions *NotificationChannelCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewNotificationChannelClient creates a new notification channel service client. // // The Notification Channel API provides access to configuration that // controls how messages related to incidents are sent. func NewNotificationChannelClient(ctx context.Context, opts ...option.ClientOption) (*NotificationChannelClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultNotificationChannelClientOptions(), opts...)...) if err != nil { return nil, err } c := &NotificationChannelClient{ conn: conn, CallOptions: defaultNotificationChannelCallOptions(), notificationChannelClient: monitoringpb.NewNotificationChannelServiceClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *NotificationChannelClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *NotificationChannelClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *NotificationChannelClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // ListNotificationChannelDescriptors lists the descriptors for supported channel types. The use of descriptors // makes it possible for new channel types to be dynamically added. func (c *NotificationChannelClient) ListNotificationChannelDescriptors(ctx context.Context, req *monitoringpb.ListNotificationChannelDescriptorsRequest, opts ...gax.CallOption) *NotificationChannelDescriptorIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListNotificationChannelDescriptors[0:len(c.CallOptions.ListNotificationChannelDescriptors):len(c.CallOptions.ListNotificationChannelDescriptors)], opts...) it := &NotificationChannelDescriptorIterator{} req = proto.Clone(req).(*monitoringpb.ListNotificationChannelDescriptorsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*monitoringpb.NotificationChannelDescriptor, string, error) { var resp *monitoringpb.ListNotificationChannelDescriptorsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.notificationChannelClient.ListNotificationChannelDescriptors(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.ChannelDescriptors, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetNotificationChannelDescriptor gets a single channel descriptor. The descriptor indicates which fields // are expected / permitted for a notification channel of the given type. func (c *NotificationChannelClient) GetNotificationChannelDescriptor(ctx context.Context, req *monitoringpb.GetNotificationChannelDescriptorRequest, opts ...gax.CallOption) (*monitoringpb.NotificationChannelDescriptor, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetNotificationChannelDescriptor[0:len(c.CallOptions.GetNotificationChannelDescriptor):len(c.CallOptions.GetNotificationChannelDescriptor)], opts...) var resp *monitoringpb.NotificationChannelDescriptor err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.notificationChannelClient.GetNotificationChannelDescriptor(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListNotificationChannels lists the notification channels that have been created for the project. func (c *NotificationChannelClient) ListNotificationChannels(ctx context.Context, req *monitoringpb.ListNotificationChannelsRequest, opts ...gax.CallOption) *NotificationChannelIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListNotificationChannels[0:len(c.CallOptions.ListNotificationChannels):len(c.CallOptions.ListNotificationChannels)], opts...) it := &NotificationChannelIterator{} req = proto.Clone(req).(*monitoringpb.ListNotificationChannelsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*monitoringpb.NotificationChannel, string, error) { var resp *monitoringpb.ListNotificationChannelsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.notificationChannelClient.ListNotificationChannels(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.NotificationChannels, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetNotificationChannel gets a single notification channel. The channel includes the relevant // configuration details with which the channel was created. However, the // response may truncate or omit passwords, API keys, or other private key // matter and thus the response may not be 100% identical to the information // that was supplied in the call to the create method. func (c *NotificationChannelClient) GetNotificationChannel(ctx context.Context, req *monitoringpb.GetNotificationChannelRequest, opts ...gax.CallOption) (*monitoringpb.NotificationChannel, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetNotificationChannel[0:len(c.CallOptions.GetNotificationChannel):len(c.CallOptions.GetNotificationChannel)], opts...) var resp *monitoringpb.NotificationChannel err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.notificationChannelClient.GetNotificationChannel(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateNotificationChannel creates a new notification channel, representing a single notification // endpoint such as an email address, SMS number, or PagerDuty service. func (c *NotificationChannelClient) CreateNotificationChannel(ctx context.Context, req *monitoringpb.CreateNotificationChannelRequest, opts ...gax.CallOption) (*monitoringpb.NotificationChannel, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateNotificationChannel[0:len(c.CallOptions.CreateNotificationChannel):len(c.CallOptions.CreateNotificationChannel)], opts...) var resp *monitoringpb.NotificationChannel err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.notificationChannelClient.CreateNotificationChannel(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateNotificationChannel updates a notification channel. Fields not specified in the field mask // remain unchanged. func (c *NotificationChannelClient) UpdateNotificationChannel(ctx context.Context, req *monitoringpb.UpdateNotificationChannelRequest, opts ...gax.CallOption) (*monitoringpb.NotificationChannel, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "notification_channel.name", url.QueryEscape(req.GetNotificationChannel().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateNotificationChannel[0:len(c.CallOptions.UpdateNotificationChannel):len(c.CallOptions.UpdateNotificationChannel)], opts...) var resp *monitoringpb.NotificationChannel err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.notificationChannelClient.UpdateNotificationChannel(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteNotificationChannel deletes a notification channel. func (c *NotificationChannelClient) DeleteNotificationChannel(ctx context.Context, req *monitoringpb.DeleteNotificationChannelRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteNotificationChannel[0:len(c.CallOptions.DeleteNotificationChannel):len(c.CallOptions.DeleteNotificationChannel)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.notificationChannelClient.DeleteNotificationChannel(ctx, req, settings.GRPC...) return err }, opts...) return err } // SendNotificationChannelVerificationCode causes a verification code to be delivered to the channel. The code // can then be supplied in VerifyNotificationChannel to verify the channel. func (c *NotificationChannelClient) SendNotificationChannelVerificationCode(ctx context.Context, req *monitoringpb.SendNotificationChannelVerificationCodeRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.SendNotificationChannelVerificationCode[0:len(c.CallOptions.SendNotificationChannelVerificationCode):len(c.CallOptions.SendNotificationChannelVerificationCode)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.notificationChannelClient.SendNotificationChannelVerificationCode(ctx, req, settings.GRPC...) return err }, opts...) return err } // GetNotificationChannelVerificationCode requests a verification code for an already verified channel that can then // be used in a call to VerifyNotificationChannel() on a different channel // with an equivalent identity in the same or in a different project. This // makes it possible to copy a channel between projects without requiring // manual reverification of the channel. If the channel is not in the // verified state, this method will fail (in other words, this may only be // used if the SendNotificationChannelVerificationCode and // VerifyNotificationChannel paths have already been used to put the given // channel into the verified state). // // There is no guarantee that the verification codes returned by this method // will be of a similar structure or form as the ones that are delivered // to the channel via SendNotificationChannelVerificationCode; while // VerifyNotificationChannel() will recognize both the codes delivered via // SendNotificationChannelVerificationCode() and returned from // GetNotificationChannelVerificationCode(), it is typically the case that // the verification codes delivered via // SendNotificationChannelVerificationCode() will be shorter and also // have a shorter expiration (e.g. codes such as "G-123456") whereas // GetVerificationCode() will typically return a much longer, websafe base // 64 encoded string that has a longer expiration time. func (c *NotificationChannelClient) GetNotificationChannelVerificationCode(ctx context.Context, req *monitoringpb.GetNotificationChannelVerificationCodeRequest, opts ...gax.CallOption) (*monitoringpb.GetNotificationChannelVerificationCodeResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetNotificationChannelVerificationCode[0:len(c.CallOptions.GetNotificationChannelVerificationCode):len(c.CallOptions.GetNotificationChannelVerificationCode)], opts...) var resp *monitoringpb.GetNotificationChannelVerificationCodeResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.notificationChannelClient.GetNotificationChannelVerificationCode(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // VerifyNotificationChannel verifies a NotificationChannel by proving receipt of the code // delivered to the channel as a result of calling // SendNotificationChannelVerificationCode. func (c *NotificationChannelClient) VerifyNotificationChannel(ctx context.Context, req *monitoringpb.VerifyNotificationChannelRequest, opts ...gax.CallOption) (*monitoringpb.NotificationChannel, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.VerifyNotificationChannel[0:len(c.CallOptions.VerifyNotificationChannel):len(c.CallOptions.VerifyNotificationChannel)], opts...) var resp *monitoringpb.NotificationChannel err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.notificationChannelClient.VerifyNotificationChannel(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // NotificationChannelDescriptorIterator manages a stream of *monitoringpb.NotificationChannelDescriptor. type NotificationChannelDescriptorIterator struct { items []*monitoringpb.NotificationChannelDescriptor pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*monitoringpb.NotificationChannelDescriptor, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *NotificationChannelDescriptorIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *NotificationChannelDescriptorIterator) Next() (*monitoringpb.NotificationChannelDescriptor, error) { var item *monitoringpb.NotificationChannelDescriptor if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *NotificationChannelDescriptorIterator) bufLen() int { return len(it.items) } func (it *NotificationChannelDescriptorIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // NotificationChannelIterator manages a stream of *monitoringpb.NotificationChannel. type NotificationChannelIterator struct { items []*monitoringpb.NotificationChannel pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*monitoringpb.NotificationChannel, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *NotificationChannelIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *NotificationChannelIterator) Next() (*monitoringpb.NotificationChannel, error) { var item *monitoringpb.NotificationChannel if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *NotificationChannelIterator) bufLen() int { return len(it.items) } func (it *NotificationChannelIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/monitoring/apiv3/notification_channel_client_example_test.go000066400000000000000000000126061356504100700306210ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package monitoring_test import ( "context" monitoring "cloud.google.com/go/monitoring/apiv3" "google.golang.org/api/iterator" monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3" ) func ExampleNewNotificationChannelClient() { ctx := context.Background() c, err := monitoring.NewNotificationChannelClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleNotificationChannelClient_ListNotificationChannelDescriptors() { ctx := context.Background() c, err := monitoring.NewNotificationChannelClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.ListNotificationChannelDescriptorsRequest{ // TODO: Fill request struct fields. } it := c.ListNotificationChannelDescriptors(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleNotificationChannelClient_GetNotificationChannelDescriptor() { ctx := context.Background() c, err := monitoring.NewNotificationChannelClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.GetNotificationChannelDescriptorRequest{ // TODO: Fill request struct fields. } resp, err := c.GetNotificationChannelDescriptor(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleNotificationChannelClient_ListNotificationChannels() { ctx := context.Background() c, err := monitoring.NewNotificationChannelClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.ListNotificationChannelsRequest{ // TODO: Fill request struct fields. } it := c.ListNotificationChannels(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleNotificationChannelClient_GetNotificationChannel() { ctx := context.Background() c, err := monitoring.NewNotificationChannelClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.GetNotificationChannelRequest{ // TODO: Fill request struct fields. } resp, err := c.GetNotificationChannel(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleNotificationChannelClient_CreateNotificationChannel() { ctx := context.Background() c, err := monitoring.NewNotificationChannelClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.CreateNotificationChannelRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateNotificationChannel(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleNotificationChannelClient_UpdateNotificationChannel() { ctx := context.Background() c, err := monitoring.NewNotificationChannelClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.UpdateNotificationChannelRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateNotificationChannel(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleNotificationChannelClient_DeleteNotificationChannel() { ctx := context.Background() c, err := monitoring.NewNotificationChannelClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.DeleteNotificationChannelRequest{ // TODO: Fill request struct fields. } err = c.DeleteNotificationChannel(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleNotificationChannelClient_SendNotificationChannelVerificationCode() { ctx := context.Background() c, err := monitoring.NewNotificationChannelClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.SendNotificationChannelVerificationCodeRequest{ // TODO: Fill request struct fields. } err = c.SendNotificationChannelVerificationCode(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleNotificationChannelClient_GetNotificationChannelVerificationCode() { ctx := context.Background() c, err := monitoring.NewNotificationChannelClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.GetNotificationChannelVerificationCodeRequest{ // TODO: Fill request struct fields. } resp, err := c.GetNotificationChannelVerificationCode(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleNotificationChannelClient_VerifyNotificationChannel() { ctx := context.Background() c, err := monitoring.NewNotificationChannelClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.VerifyNotificationChannelRequest{ // TODO: Fill request struct fields. } resp, err := c.VerifyNotificationChannel(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/monitoring/apiv3/path_funcs.go000066400000000000000000000053751356504100700224720ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package monitoring // GroupProjectPath returns the path for the project resource. // // Deprecated: Use // fmt.Sprintf("projects/%s", project) // instead. func GroupProjectPath(project string) string { return "" + "projects/" + project + "" } // GroupGroupPath returns the path for the group resource. // // Deprecated: Use // fmt.Sprintf("projects/%s/groups/%s", project, group) // instead. func GroupGroupPath(project, group string) string { return "" + "projects/" + project + "/groups/" + group + "" } // MetricProjectPath returns the path for the project resource. // // Deprecated: Use // fmt.Sprintf("projects/%s", project) // instead. func MetricProjectPath(project string) string { return "" + "projects/" + project + "" } // MetricMetricDescriptorPath returns the path for the metric descriptor resource. // // Deprecated: Use // fmt.Sprintf("projects/%s/metricDescriptors/%s", project, metricDescriptor) // instead. func MetricMetricDescriptorPath(project, metricDescriptor string) string { return "" + "projects/" + project + "/metricDescriptors/" + metricDescriptor + "" } // MetricMonitoredResourceDescriptorPath returns the path for the monitored resource descriptor resource. // // Deprecated: Use // fmt.Sprintf("projects/%s/monitoredResourceDescriptors/%s", project, monitoredResourceDescriptor) // instead. func MetricMonitoredResourceDescriptorPath(project, monitoredResourceDescriptor string) string { return "" + "projects/" + project + "/monitoredResourceDescriptors/" + monitoredResourceDescriptor + "" } // UptimeCheckProjectPath returns the path for the project resource. // // Deprecated: Use // fmt.Sprintf("projects/%s", project) // instead. func UptimeCheckProjectPath(project string) string { return "" + "projects/" + project + "" } // UptimeCheckUptimeCheckConfigPath returns the path for the uptime check config resource. // // Deprecated: Use // fmt.Sprintf("projects/%s/uptimeCheckConfigs/%s", project, uptimeCheckConfig) // instead. func UptimeCheckUptimeCheckConfigPath(project, uptimeCheckConfig string) string { return "" + "projects/" + project + "/uptimeCheckConfigs/" + uptimeCheckConfig + "" } google-cloud-go-0.49.0/monitoring/apiv3/service_monitoring_client.go000066400000000000000000000436441356504100700256040ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package monitoring import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // ServiceMonitoringCallOptions contains the retry settings for each method of ServiceMonitoringClient. type ServiceMonitoringCallOptions struct { CreateService []gax.CallOption GetService []gax.CallOption ListServices []gax.CallOption UpdateService []gax.CallOption DeleteService []gax.CallOption CreateServiceLevelObjective []gax.CallOption GetServiceLevelObjective []gax.CallOption ListServiceLevelObjectives []gax.CallOption UpdateServiceLevelObjective []gax.CallOption DeleteServiceLevelObjective []gax.CallOption } func defaultServiceMonitoringClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("monitoring.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultServiceMonitoringCallOptions() *ServiceMonitoringCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &ServiceMonitoringCallOptions{ CreateService: retry[[2]string{"default", "non_idempotent"}], GetService: retry[[2]string{"default", "idempotent"}], ListServices: retry[[2]string{"default", "idempotent"}], UpdateService: retry[[2]string{"default", "non_idempotent"}], DeleteService: retry[[2]string{"default", "idempotent"}], CreateServiceLevelObjective: retry[[2]string{"default", "non_idempotent"}], GetServiceLevelObjective: retry[[2]string{"default", "idempotent"}], ListServiceLevelObjectives: retry[[2]string{"default", "idempotent"}], UpdateServiceLevelObjective: retry[[2]string{"default", "non_idempotent"}], DeleteServiceLevelObjective: retry[[2]string{"default", "idempotent"}], } } // ServiceMonitoringClient is a client for interacting with Stackdriver Monitoring API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type ServiceMonitoringClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. serviceMonitoringClient monitoringpb.ServiceMonitoringServiceClient // The call options for this service. CallOptions *ServiceMonitoringCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewServiceMonitoringClient creates a new service monitoring service client. // // The Stackdriver Monitoring Service-Oriented Monitoring API has endpoints for // managing and querying aspects of a workspace's services. These include the // Service's monitored resources, its Service-Level Objectives, and a taxonomy // of categorized Health Metrics. func NewServiceMonitoringClient(ctx context.Context, opts ...option.ClientOption) (*ServiceMonitoringClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultServiceMonitoringClientOptions(), opts...)...) if err != nil { return nil, err } c := &ServiceMonitoringClient{ conn: conn, CallOptions: defaultServiceMonitoringCallOptions(), serviceMonitoringClient: monitoringpb.NewServiceMonitoringServiceClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *ServiceMonitoringClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *ServiceMonitoringClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *ServiceMonitoringClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // CreateService create a Service. func (c *ServiceMonitoringClient) CreateService(ctx context.Context, req *monitoringpb.CreateServiceRequest, opts ...gax.CallOption) (*monitoringpb.Service, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateService[0:len(c.CallOptions.CreateService):len(c.CallOptions.CreateService)], opts...) var resp *monitoringpb.Service err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.serviceMonitoringClient.CreateService(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetService get the named Service. func (c *ServiceMonitoringClient) GetService(ctx context.Context, req *monitoringpb.GetServiceRequest, opts ...gax.CallOption) (*monitoringpb.Service, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetService[0:len(c.CallOptions.GetService):len(c.CallOptions.GetService)], opts...) var resp *monitoringpb.Service err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.serviceMonitoringClient.GetService(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListServices list Services for this workspace. func (c *ServiceMonitoringClient) ListServices(ctx context.Context, req *monitoringpb.ListServicesRequest, opts ...gax.CallOption) *ServiceIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListServices[0:len(c.CallOptions.ListServices):len(c.CallOptions.ListServices)], opts...) it := &ServiceIterator{} req = proto.Clone(req).(*monitoringpb.ListServicesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*monitoringpb.Service, string, error) { var resp *monitoringpb.ListServicesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.serviceMonitoringClient.ListServices(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Services, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // UpdateService update this Service. func (c *ServiceMonitoringClient) UpdateService(ctx context.Context, req *monitoringpb.UpdateServiceRequest, opts ...gax.CallOption) (*monitoringpb.Service, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "service.name", url.QueryEscape(req.GetService().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateService[0:len(c.CallOptions.UpdateService):len(c.CallOptions.UpdateService)], opts...) var resp *monitoringpb.Service err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.serviceMonitoringClient.UpdateService(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteService soft delete this Service. func (c *ServiceMonitoringClient) DeleteService(ctx context.Context, req *monitoringpb.DeleteServiceRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteService[0:len(c.CallOptions.DeleteService):len(c.CallOptions.DeleteService)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.serviceMonitoringClient.DeleteService(ctx, req, settings.GRPC...) return err }, opts...) return err } // CreateServiceLevelObjective create a ServiceLevelObjective for the given Service. func (c *ServiceMonitoringClient) CreateServiceLevelObjective(ctx context.Context, req *monitoringpb.CreateServiceLevelObjectiveRequest, opts ...gax.CallOption) (*monitoringpb.ServiceLevelObjective, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateServiceLevelObjective[0:len(c.CallOptions.CreateServiceLevelObjective):len(c.CallOptions.CreateServiceLevelObjective)], opts...) var resp *monitoringpb.ServiceLevelObjective err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.serviceMonitoringClient.CreateServiceLevelObjective(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetServiceLevelObjective get a ServiceLevelObjective by name. func (c *ServiceMonitoringClient) GetServiceLevelObjective(ctx context.Context, req *monitoringpb.GetServiceLevelObjectiveRequest, opts ...gax.CallOption) (*monitoringpb.ServiceLevelObjective, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetServiceLevelObjective[0:len(c.CallOptions.GetServiceLevelObjective):len(c.CallOptions.GetServiceLevelObjective)], opts...) var resp *monitoringpb.ServiceLevelObjective err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.serviceMonitoringClient.GetServiceLevelObjective(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListServiceLevelObjectives list the ServiceLevelObjectives for the given Service. func (c *ServiceMonitoringClient) ListServiceLevelObjectives(ctx context.Context, req *monitoringpb.ListServiceLevelObjectivesRequest, opts ...gax.CallOption) *ServiceLevelObjectiveIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListServiceLevelObjectives[0:len(c.CallOptions.ListServiceLevelObjectives):len(c.CallOptions.ListServiceLevelObjectives)], opts...) it := &ServiceLevelObjectiveIterator{} req = proto.Clone(req).(*monitoringpb.ListServiceLevelObjectivesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*monitoringpb.ServiceLevelObjective, string, error) { var resp *monitoringpb.ListServiceLevelObjectivesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.serviceMonitoringClient.ListServiceLevelObjectives(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.ServiceLevelObjectives, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // UpdateServiceLevelObjective update the given ServiceLevelObjective. func (c *ServiceMonitoringClient) UpdateServiceLevelObjective(ctx context.Context, req *monitoringpb.UpdateServiceLevelObjectiveRequest, opts ...gax.CallOption) (*monitoringpb.ServiceLevelObjective, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "service_level_objective.name", url.QueryEscape(req.GetServiceLevelObjective().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateServiceLevelObjective[0:len(c.CallOptions.UpdateServiceLevelObjective):len(c.CallOptions.UpdateServiceLevelObjective)], opts...) var resp *monitoringpb.ServiceLevelObjective err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.serviceMonitoringClient.UpdateServiceLevelObjective(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteServiceLevelObjective delete the given ServiceLevelObjective. func (c *ServiceMonitoringClient) DeleteServiceLevelObjective(ctx context.Context, req *monitoringpb.DeleteServiceLevelObjectiveRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteServiceLevelObjective[0:len(c.CallOptions.DeleteServiceLevelObjective):len(c.CallOptions.DeleteServiceLevelObjective)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.serviceMonitoringClient.DeleteServiceLevelObjective(ctx, req, settings.GRPC...) return err }, opts...) return err } // ServiceIterator manages a stream of *monitoringpb.Service. type ServiceIterator struct { items []*monitoringpb.Service pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*monitoringpb.Service, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *ServiceIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *ServiceIterator) Next() (*monitoringpb.Service, error) { var item *monitoringpb.Service if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *ServiceIterator) bufLen() int { return len(it.items) } func (it *ServiceIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // ServiceLevelObjectiveIterator manages a stream of *monitoringpb.ServiceLevelObjective. type ServiceLevelObjectiveIterator struct { items []*monitoringpb.ServiceLevelObjective pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*monitoringpb.ServiceLevelObjective, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *ServiceLevelObjectiveIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *ServiceLevelObjectiveIterator) Next() (*monitoringpb.ServiceLevelObjective, error) { var item *monitoringpb.ServiceLevelObjective if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *ServiceLevelObjectiveIterator) bufLen() int { return len(it.items) } func (it *ServiceLevelObjectiveIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/monitoring/apiv3/service_monitoring_client_example_test.go000066400000000000000000000120671356504100700303510ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package monitoring_test import ( "context" monitoring "cloud.google.com/go/monitoring/apiv3" "google.golang.org/api/iterator" monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3" ) func ExampleNewServiceMonitoringClient() { ctx := context.Background() c, err := monitoring.NewServiceMonitoringClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleServiceMonitoringClient_CreateService() { ctx := context.Background() c, err := monitoring.NewServiceMonitoringClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.CreateServiceRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateService(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleServiceMonitoringClient_GetService() { ctx := context.Background() c, err := monitoring.NewServiceMonitoringClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.GetServiceRequest{ // TODO: Fill request struct fields. } resp, err := c.GetService(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleServiceMonitoringClient_ListServices() { ctx := context.Background() c, err := monitoring.NewServiceMonitoringClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.ListServicesRequest{ // TODO: Fill request struct fields. } it := c.ListServices(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleServiceMonitoringClient_UpdateService() { ctx := context.Background() c, err := monitoring.NewServiceMonitoringClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.UpdateServiceRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateService(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleServiceMonitoringClient_DeleteService() { ctx := context.Background() c, err := monitoring.NewServiceMonitoringClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.DeleteServiceRequest{ // TODO: Fill request struct fields. } err = c.DeleteService(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleServiceMonitoringClient_CreateServiceLevelObjective() { ctx := context.Background() c, err := monitoring.NewServiceMonitoringClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.CreateServiceLevelObjectiveRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateServiceLevelObjective(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleServiceMonitoringClient_GetServiceLevelObjective() { ctx := context.Background() c, err := monitoring.NewServiceMonitoringClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.GetServiceLevelObjectiveRequest{ // TODO: Fill request struct fields. } resp, err := c.GetServiceLevelObjective(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleServiceMonitoringClient_ListServiceLevelObjectives() { ctx := context.Background() c, err := monitoring.NewServiceMonitoringClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.ListServiceLevelObjectivesRequest{ // TODO: Fill request struct fields. } it := c.ListServiceLevelObjectives(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleServiceMonitoringClient_UpdateServiceLevelObjective() { ctx := context.Background() c, err := monitoring.NewServiceMonitoringClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.UpdateServiceLevelObjectiveRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateServiceLevelObjective(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleServiceMonitoringClient_DeleteServiceLevelObjective() { ctx := context.Background() c, err := monitoring.NewServiceMonitoringClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.DeleteServiceLevelObjectiveRequest{ // TODO: Fill request struct fields. } err = c.DeleteServiceLevelObjective(ctx, req) if err != nil { // TODO: Handle error. } } google-cloud-go-0.49.0/monitoring/apiv3/uptime_check_client.go000066400000000000000000000353701356504100700243340ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package monitoring import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // UptimeCheckCallOptions contains the retry settings for each method of UptimeCheckClient. type UptimeCheckCallOptions struct { ListUptimeCheckConfigs []gax.CallOption GetUptimeCheckConfig []gax.CallOption CreateUptimeCheckConfig []gax.CallOption UpdateUptimeCheckConfig []gax.CallOption DeleteUptimeCheckConfig []gax.CallOption ListUptimeCheckIps []gax.CallOption } func defaultUptimeCheckClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("monitoring.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultUptimeCheckCallOptions() *UptimeCheckCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &UptimeCheckCallOptions{ ListUptimeCheckConfigs: retry[[2]string{"default", "idempotent"}], GetUptimeCheckConfig: retry[[2]string{"default", "idempotent"}], CreateUptimeCheckConfig: retry[[2]string{"default", "non_idempotent"}], UpdateUptimeCheckConfig: retry[[2]string{"default", "non_idempotent"}], DeleteUptimeCheckConfig: retry[[2]string{"default", "idempotent"}], ListUptimeCheckIps: retry[[2]string{"default", "idempotent"}], } } // UptimeCheckClient is a client for interacting with Stackdriver Monitoring API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type UptimeCheckClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. uptimeCheckClient monitoringpb.UptimeCheckServiceClient // The call options for this service. CallOptions *UptimeCheckCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewUptimeCheckClient creates a new uptime check service client. // // The UptimeCheckService API is used to manage (list, create, delete, edit) // Uptime check configurations in the Stackdriver Monitoring product. An Uptime // check is a piece of configuration that determines which resources and // services to monitor for availability. These configurations can also be // configured interactively by navigating to the [Cloud Console] // (http://console.cloud.google.com), selecting the appropriate project, // clicking on "Monitoring" on the left-hand side to navigate to Stackdriver, // and then clicking on "Uptime". func NewUptimeCheckClient(ctx context.Context, opts ...option.ClientOption) (*UptimeCheckClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultUptimeCheckClientOptions(), opts...)...) if err != nil { return nil, err } c := &UptimeCheckClient{ conn: conn, CallOptions: defaultUptimeCheckCallOptions(), uptimeCheckClient: monitoringpb.NewUptimeCheckServiceClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *UptimeCheckClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *UptimeCheckClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *UptimeCheckClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // ListUptimeCheckConfigs lists the existing valid Uptime check configurations for the project // (leaving out any invalid configurations). func (c *UptimeCheckClient) ListUptimeCheckConfigs(ctx context.Context, req *monitoringpb.ListUptimeCheckConfigsRequest, opts ...gax.CallOption) *UptimeCheckConfigIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListUptimeCheckConfigs[0:len(c.CallOptions.ListUptimeCheckConfigs):len(c.CallOptions.ListUptimeCheckConfigs)], opts...) it := &UptimeCheckConfigIterator{} req = proto.Clone(req).(*monitoringpb.ListUptimeCheckConfigsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*monitoringpb.UptimeCheckConfig, string, error) { var resp *monitoringpb.ListUptimeCheckConfigsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.uptimeCheckClient.ListUptimeCheckConfigs(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.UptimeCheckConfigs, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetUptimeCheckConfig gets a single Uptime check configuration. func (c *UptimeCheckClient) GetUptimeCheckConfig(ctx context.Context, req *monitoringpb.GetUptimeCheckConfigRequest, opts ...gax.CallOption) (*monitoringpb.UptimeCheckConfig, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetUptimeCheckConfig[0:len(c.CallOptions.GetUptimeCheckConfig):len(c.CallOptions.GetUptimeCheckConfig)], opts...) var resp *monitoringpb.UptimeCheckConfig err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.uptimeCheckClient.GetUptimeCheckConfig(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateUptimeCheckConfig creates a new Uptime check configuration. func (c *UptimeCheckClient) CreateUptimeCheckConfig(ctx context.Context, req *monitoringpb.CreateUptimeCheckConfigRequest, opts ...gax.CallOption) (*monitoringpb.UptimeCheckConfig, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateUptimeCheckConfig[0:len(c.CallOptions.CreateUptimeCheckConfig):len(c.CallOptions.CreateUptimeCheckConfig)], opts...) var resp *monitoringpb.UptimeCheckConfig err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.uptimeCheckClient.CreateUptimeCheckConfig(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateUptimeCheckConfig updates an Uptime check configuration. You can either replace the entire // configuration with a new one or replace only certain fields in the current // configuration by specifying the fields to be updated via updateMask. // Returns the updated configuration. func (c *UptimeCheckClient) UpdateUptimeCheckConfig(ctx context.Context, req *monitoringpb.UpdateUptimeCheckConfigRequest, opts ...gax.CallOption) (*monitoringpb.UptimeCheckConfig, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "uptime_check_config.name", url.QueryEscape(req.GetUptimeCheckConfig().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateUptimeCheckConfig[0:len(c.CallOptions.UpdateUptimeCheckConfig):len(c.CallOptions.UpdateUptimeCheckConfig)], opts...) var resp *monitoringpb.UptimeCheckConfig err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.uptimeCheckClient.UpdateUptimeCheckConfig(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteUptimeCheckConfig deletes an Uptime check configuration. Note that this method will fail // if the Uptime check configuration is referenced by an alert policy or // other dependent configs that would be rendered invalid by the deletion. func (c *UptimeCheckClient) DeleteUptimeCheckConfig(ctx context.Context, req *monitoringpb.DeleteUptimeCheckConfigRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteUptimeCheckConfig[0:len(c.CallOptions.DeleteUptimeCheckConfig):len(c.CallOptions.DeleteUptimeCheckConfig)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.uptimeCheckClient.DeleteUptimeCheckConfig(ctx, req, settings.GRPC...) return err }, opts...) return err } // ListUptimeCheckIps returns the list of IP addresses that checkers run from func (c *UptimeCheckClient) ListUptimeCheckIps(ctx context.Context, req *monitoringpb.ListUptimeCheckIpsRequest, opts ...gax.CallOption) *UptimeCheckIpIterator { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.ListUptimeCheckIps[0:len(c.CallOptions.ListUptimeCheckIps):len(c.CallOptions.ListUptimeCheckIps)], opts...) it := &UptimeCheckIpIterator{} req = proto.Clone(req).(*monitoringpb.ListUptimeCheckIpsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*monitoringpb.UptimeCheckIp, string, error) { var resp *monitoringpb.ListUptimeCheckIpsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.uptimeCheckClient.ListUptimeCheckIps(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.UptimeCheckIps, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // UptimeCheckConfigIterator manages a stream of *monitoringpb.UptimeCheckConfig. type UptimeCheckConfigIterator struct { items []*monitoringpb.UptimeCheckConfig pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*monitoringpb.UptimeCheckConfig, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *UptimeCheckConfigIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *UptimeCheckConfigIterator) Next() (*monitoringpb.UptimeCheckConfig, error) { var item *monitoringpb.UptimeCheckConfig if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *UptimeCheckConfigIterator) bufLen() int { return len(it.items) } func (it *UptimeCheckConfigIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // UptimeCheckIpIterator manages a stream of *monitoringpb.UptimeCheckIp. type UptimeCheckIpIterator struct { items []*monitoringpb.UptimeCheckIp pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*monitoringpb.UptimeCheckIp, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *UptimeCheckIpIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *UptimeCheckIpIterator) Next() (*monitoringpb.UptimeCheckIp, error) { var item *monitoringpb.UptimeCheckIp if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *UptimeCheckIpIterator) bufLen() int { return len(it.items) } func (it *UptimeCheckIpIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/monitoring/apiv3/uptime_check_client_example_test.go000066400000000000000000000067331356504100700271070ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package monitoring_test import ( "context" monitoring "cloud.google.com/go/monitoring/apiv3" "google.golang.org/api/iterator" monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3" ) func ExampleNewUptimeCheckClient() { ctx := context.Background() c, err := monitoring.NewUptimeCheckClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleUptimeCheckClient_ListUptimeCheckConfigs() { ctx := context.Background() c, err := monitoring.NewUptimeCheckClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.ListUptimeCheckConfigsRequest{ // TODO: Fill request struct fields. } it := c.ListUptimeCheckConfigs(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleUptimeCheckClient_GetUptimeCheckConfig() { ctx := context.Background() c, err := monitoring.NewUptimeCheckClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.GetUptimeCheckConfigRequest{ // TODO: Fill request struct fields. } resp, err := c.GetUptimeCheckConfig(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleUptimeCheckClient_CreateUptimeCheckConfig() { ctx := context.Background() c, err := monitoring.NewUptimeCheckClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.CreateUptimeCheckConfigRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateUptimeCheckConfig(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleUptimeCheckClient_UpdateUptimeCheckConfig() { ctx := context.Background() c, err := monitoring.NewUptimeCheckClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.UpdateUptimeCheckConfigRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateUptimeCheckConfig(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleUptimeCheckClient_DeleteUptimeCheckConfig() { ctx := context.Background() c, err := monitoring.NewUptimeCheckClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.DeleteUptimeCheckConfigRequest{ // TODO: Fill request struct fields. } err = c.DeleteUptimeCheckConfig(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleUptimeCheckClient_ListUptimeCheckIps() { ctx := context.Background() c, err := monitoring.NewUptimeCheckClient(ctx) if err != nil { // TODO: Handle error. } req := &monitoringpb.ListUptimeCheckIpsRequest{ // TODO: Fill request struct fields. } it := c.ListUptimeCheckIps(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } google-cloud-go-0.49.0/oslogin/000077500000000000000000000000001356504100700162425ustar00rootroot00000000000000google-cloud-go-0.49.0/oslogin/apiv1/000077500000000000000000000000001356504100700172625ustar00rootroot00000000000000google-cloud-go-0.49.0/oslogin/apiv1/.repo-metadata.json000066400000000000000000000006441356504100700227620ustar00rootroot00000000000000{ "name": "oslogin", "name_pretty": "Cloud OS Login API", "product_documentation": "https://cloud.google.com/compute/docs/oslogin", "client_documentation": "https://godoc.org/cloud.google.com/go/oslogin/apiv1", "release_level": "alpha", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "oslogin.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/oslogin/apiv1/doc.go000066400000000000000000000055241356504100700203640ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package oslogin is an auto-generated package for the // Cloud OS Login API. // // NOTE: This package is in alpha. It is not stable, and is likely to change. // // You can use OS Login to manage access to your VM instances using IAM // roles. // For more information, read [OS Login](/compute/docs/oslogin/). // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package oslogin // import "cloud.google.com/go/oslogin/apiv1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/compute", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191108" google-cloud-go-0.49.0/oslogin/apiv1/mock_test.go000066400000000000000000000346701356504100700216130ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package oslogin import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" "google.golang.org/api/option" commonpb "google.golang.org/genproto/googleapis/cloud/oslogin/common" osloginpb "google.golang.org/genproto/googleapis/cloud/oslogin/v1" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockOsLoginServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. osloginpb.OsLoginServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockOsLoginServer) DeletePosixAccount(ctx context.Context, req *osloginpb.DeletePosixAccountRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockOsLoginServer) DeleteSshPublicKey(ctx context.Context, req *osloginpb.DeleteSshPublicKeyRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockOsLoginServer) GetLoginProfile(ctx context.Context, req *osloginpb.GetLoginProfileRequest) (*osloginpb.LoginProfile, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*osloginpb.LoginProfile), nil } func (s *mockOsLoginServer) GetSshPublicKey(ctx context.Context, req *osloginpb.GetSshPublicKeyRequest) (*commonpb.SshPublicKey, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*commonpb.SshPublicKey), nil } func (s *mockOsLoginServer) ImportSshPublicKey(ctx context.Context, req *osloginpb.ImportSshPublicKeyRequest) (*osloginpb.ImportSshPublicKeyResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*osloginpb.ImportSshPublicKeyResponse), nil } func (s *mockOsLoginServer) UpdateSshPublicKey(ctx context.Context, req *osloginpb.UpdateSshPublicKeyRequest) (*commonpb.SshPublicKey, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*commonpb.SshPublicKey), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockOsLogin mockOsLoginServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() osloginpb.RegisterOsLoginServiceServer(serv, &mockOsLogin) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestOsLoginServiceDeletePosixAccount(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockOsLogin.err = nil mockOsLogin.reqs = nil mockOsLogin.resps = append(mockOsLogin.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("users/%s/projects/%s", "[USER]", "[PROJECT]") var request = &osloginpb.DeletePosixAccountRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeletePosixAccount(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockOsLogin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestOsLoginServiceDeletePosixAccountError(t *testing.T) { errCode := codes.PermissionDenied mockOsLogin.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("users/%s/projects/%s", "[USER]", "[PROJECT]") var request = &osloginpb.DeletePosixAccountRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeletePosixAccount(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestOsLoginServiceDeleteSshPublicKey(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockOsLogin.err = nil mockOsLogin.reqs = nil mockOsLogin.resps = append(mockOsLogin.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("users/%s/sshPublicKeys/%s", "[USER]", "[FINGERPRINT]") var request = &osloginpb.DeleteSshPublicKeyRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteSshPublicKey(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockOsLogin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestOsLoginServiceDeleteSshPublicKeyError(t *testing.T) { errCode := codes.PermissionDenied mockOsLogin.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("users/%s/sshPublicKeys/%s", "[USER]", "[FINGERPRINT]") var request = &osloginpb.DeleteSshPublicKeyRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteSshPublicKey(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestOsLoginServiceGetLoginProfile(t *testing.T) { var name2 string = "name2-1052831874" var expectedResponse = &osloginpb.LoginProfile{ Name: name2, } mockOsLogin.err = nil mockOsLogin.reqs = nil mockOsLogin.resps = append(mockOsLogin.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("users/%s", "[USER]") var request = &osloginpb.GetLoginProfileRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetLoginProfile(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockOsLogin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestOsLoginServiceGetLoginProfileError(t *testing.T) { errCode := codes.PermissionDenied mockOsLogin.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("users/%s", "[USER]") var request = &osloginpb.GetLoginProfileRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetLoginProfile(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestOsLoginServiceGetSshPublicKey(t *testing.T) { var key string = "key106079" var expirationTimeUsec int64 = 2058878882 var fingerprint string = "fingerprint-1375934236" var name2 string = "name2-1052831874" var expectedResponse = &commonpb.SshPublicKey{ Key: key, ExpirationTimeUsec: expirationTimeUsec, Fingerprint: fingerprint, Name: name2, } mockOsLogin.err = nil mockOsLogin.reqs = nil mockOsLogin.resps = append(mockOsLogin.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("users/%s/sshPublicKeys/%s", "[USER]", "[FINGERPRINT]") var request = &osloginpb.GetSshPublicKeyRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetSshPublicKey(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockOsLogin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestOsLoginServiceGetSshPublicKeyError(t *testing.T) { errCode := codes.PermissionDenied mockOsLogin.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("users/%s/sshPublicKeys/%s", "[USER]", "[FINGERPRINT]") var request = &osloginpb.GetSshPublicKeyRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetSshPublicKey(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestOsLoginServiceImportSshPublicKey(t *testing.T) { var expectedResponse *osloginpb.ImportSshPublicKeyResponse = &osloginpb.ImportSshPublicKeyResponse{} mockOsLogin.err = nil mockOsLogin.reqs = nil mockOsLogin.resps = append(mockOsLogin.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("users/%s", "[USER]") var request = &osloginpb.ImportSshPublicKeyRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ImportSshPublicKey(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockOsLogin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestOsLoginServiceImportSshPublicKeyError(t *testing.T) { errCode := codes.PermissionDenied mockOsLogin.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("users/%s", "[USER]") var request = &osloginpb.ImportSshPublicKeyRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ImportSshPublicKey(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestOsLoginServiceUpdateSshPublicKey(t *testing.T) { var key string = "key106079" var expirationTimeUsec int64 = 2058878882 var fingerprint string = "fingerprint-1375934236" var name2 string = "name2-1052831874" var expectedResponse = &commonpb.SshPublicKey{ Key: key, ExpirationTimeUsec: expirationTimeUsec, Fingerprint: fingerprint, Name: name2, } mockOsLogin.err = nil mockOsLogin.reqs = nil mockOsLogin.resps = append(mockOsLogin.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("users/%s/sshPublicKeys/%s", "[USER]", "[FINGERPRINT]") var sshPublicKey *commonpb.SshPublicKey = &commonpb.SshPublicKey{} var request = &osloginpb.UpdateSshPublicKeyRequest{ Name: formattedName, SshPublicKey: sshPublicKey, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateSshPublicKey(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockOsLogin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestOsLoginServiceUpdateSshPublicKeyError(t *testing.T) { errCode := codes.PermissionDenied mockOsLogin.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("users/%s/sshPublicKeys/%s", "[USER]", "[FINGERPRINT]") var sshPublicKey *commonpb.SshPublicKey = &commonpb.SshPublicKey{} var request = &osloginpb.UpdateSshPublicKeyRequest{ Name: formattedName, SshPublicKey: sshPublicKey, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateSshPublicKey(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/oslogin/apiv1/os_login_client.go000066400000000000000000000217101356504100700227610ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package oslogin import ( "context" "fmt" "math" "net/url" "time" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" "google.golang.org/api/transport" commonpb "google.golang.org/genproto/googleapis/cloud/oslogin/common" osloginpb "google.golang.org/genproto/googleapis/cloud/oslogin/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // CallOptions contains the retry settings for each method of Client. type CallOptions struct { DeletePosixAccount []gax.CallOption DeleteSshPublicKey []gax.CallOption GetLoginProfile []gax.CallOption GetSshPublicKey []gax.CallOption ImportSshPublicKey []gax.CallOption UpdateSshPublicKey []gax.CallOption } func defaultClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("oslogin.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultCallOptions() *CallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &CallOptions{ DeletePosixAccount: retry[[2]string{"default", "non_idempotent"}], DeleteSshPublicKey: retry[[2]string{"default", "non_idempotent"}], GetLoginProfile: retry[[2]string{"default", "idempotent"}], GetSshPublicKey: retry[[2]string{"default", "idempotent"}], ImportSshPublicKey: retry[[2]string{"default", "non_idempotent"}], UpdateSshPublicKey: retry[[2]string{"default", "non_idempotent"}], } } // Client is a client for interacting with Cloud OS Login API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. client osloginpb.OsLoginServiceClient // The call options for this service. CallOptions *CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewClient creates a new os login service client. // // Cloud OS Login API // // The Cloud OS Login API allows you to manage users and their associated SSH // public keys for logging into virtual machines on Google Cloud Platform. func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultClientOptions(), opts...)...) if err != nil { return nil, err } c := &Client{ conn: conn, CallOptions: defaultCallOptions(), client: osloginpb.NewOsLoginServiceClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *Client) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *Client) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // DeletePosixAccount deletes a POSIX account. func (c *Client) DeletePosixAccount(ctx context.Context, req *osloginpb.DeletePosixAccountRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeletePosixAccount[0:len(c.CallOptions.DeletePosixAccount):len(c.CallOptions.DeletePosixAccount)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.client.DeletePosixAccount(ctx, req, settings.GRPC...) return err }, opts...) return err } // DeleteSshPublicKey deletes an SSH public key. func (c *Client) DeleteSshPublicKey(ctx context.Context, req *osloginpb.DeleteSshPublicKeyRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteSshPublicKey[0:len(c.CallOptions.DeleteSshPublicKey):len(c.CallOptions.DeleteSshPublicKey)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.client.DeleteSshPublicKey(ctx, req, settings.GRPC...) return err }, opts...) return err } // GetLoginProfile retrieves the profile information used for logging in to a virtual machine // on Google Compute Engine. func (c *Client) GetLoginProfile(ctx context.Context, req *osloginpb.GetLoginProfileRequest, opts ...gax.CallOption) (*osloginpb.LoginProfile, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetLoginProfile[0:len(c.CallOptions.GetLoginProfile):len(c.CallOptions.GetLoginProfile)], opts...) var resp *osloginpb.LoginProfile err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetLoginProfile(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetSshPublicKey retrieves an SSH public key. func (c *Client) GetSshPublicKey(ctx context.Context, req *osloginpb.GetSshPublicKeyRequest, opts ...gax.CallOption) (*commonpb.SshPublicKey, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetSshPublicKey[0:len(c.CallOptions.GetSshPublicKey):len(c.CallOptions.GetSshPublicKey)], opts...) var resp *commonpb.SshPublicKey err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetSshPublicKey(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ImportSshPublicKey adds an SSH public key and returns the profile information. Default POSIX // account information is set when no username and UID exist as part of the // login profile. func (c *Client) ImportSshPublicKey(ctx context.Context, req *osloginpb.ImportSshPublicKeyRequest, opts ...gax.CallOption) (*osloginpb.ImportSshPublicKeyResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ImportSshPublicKey[0:len(c.CallOptions.ImportSshPublicKey):len(c.CallOptions.ImportSshPublicKey)], opts...) var resp *osloginpb.ImportSshPublicKeyResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ImportSshPublicKey(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateSshPublicKey updates an SSH public key and returns the profile information. This method // supports patch semantics. func (c *Client) UpdateSshPublicKey(ctx context.Context, req *osloginpb.UpdateSshPublicKeyRequest, opts ...gax.CallOption) (*commonpb.SshPublicKey, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateSshPublicKey[0:len(c.CallOptions.UpdateSshPublicKey):len(c.CallOptions.UpdateSshPublicKey)], opts...) var resp *commonpb.SshPublicKey err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.UpdateSshPublicKey(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } google-cloud-go-0.49.0/oslogin/apiv1/os_login_client_example_test.go000066400000000000000000000057451356504100700255450ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package oslogin_test import ( "context" oslogin "cloud.google.com/go/oslogin/apiv1" osloginpb "google.golang.org/genproto/googleapis/cloud/oslogin/v1" ) func ExampleNewClient() { ctx := context.Background() c, err := oslogin.NewClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleClient_DeletePosixAccount() { ctx := context.Background() c, err := oslogin.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &osloginpb.DeletePosixAccountRequest{ // TODO: Fill request struct fields. } err = c.DeletePosixAccount(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleClient_DeleteSshPublicKey() { ctx := context.Background() c, err := oslogin.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &osloginpb.DeleteSshPublicKeyRequest{ // TODO: Fill request struct fields. } err = c.DeleteSshPublicKey(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleClient_GetLoginProfile() { ctx := context.Background() c, err := oslogin.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &osloginpb.GetLoginProfileRequest{ // TODO: Fill request struct fields. } resp, err := c.GetLoginProfile(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_GetSshPublicKey() { ctx := context.Background() c, err := oslogin.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &osloginpb.GetSshPublicKeyRequest{ // TODO: Fill request struct fields. } resp, err := c.GetSshPublicKey(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ImportSshPublicKey() { ctx := context.Background() c, err := oslogin.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &osloginpb.ImportSshPublicKeyRequest{ // TODO: Fill request struct fields. } resp, err := c.ImportSshPublicKey(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_UpdateSshPublicKey() { ctx := context.Background() c, err := oslogin.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &osloginpb.UpdateSshPublicKeyRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateSshPublicKey(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/oslogin/apiv1beta/000077500000000000000000000000001356504100700201165ustar00rootroot00000000000000google-cloud-go-0.49.0/oslogin/apiv1beta/.repo-metadata.json000066400000000000000000000006471356504100700236210ustar00rootroot00000000000000{ "name": "oslogin", "name_pretty": "Cloud OS Login API", "product_documentation": "https://cloud.google.com/compute/docs/oslogin", "client_documentation": "https://godoc.org/cloud.google.com/go/oslogin/apiv1beta", "release_level": "beta", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "oslogin.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/oslogin/apiv1beta/doc.go000066400000000000000000000056001356504100700212130ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package oslogin is an auto-generated package for the // Google Cloud OS Login API. // // NOTE: This package is in beta. It is not stable, and may be subject to changes. // // Manages OS login configuration for Google account users. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package oslogin // import "cloud.google.com/go/oslogin/apiv1beta" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/cloud-platform.read-only", "https://www.googleapis.com/auth/compute", "https://www.googleapis.com/auth/compute.readonly", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191115" google-cloud-go-0.49.0/oslogin/apiv1beta/mock_test.go000066400000000000000000000352141356504100700224420ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package oslogin import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" "google.golang.org/api/option" commonpb "google.golang.org/genproto/googleapis/cloud/oslogin/common" osloginpb "google.golang.org/genproto/googleapis/cloud/oslogin/v1beta" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockOsLoginServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. osloginpb.OsLoginServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockOsLoginServer) DeletePosixAccount(ctx context.Context, req *osloginpb.DeletePosixAccountRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockOsLoginServer) DeleteSshPublicKey(ctx context.Context, req *osloginpb.DeleteSshPublicKeyRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockOsLoginServer) GetLoginProfile(ctx context.Context, req *osloginpb.GetLoginProfileRequest) (*osloginpb.LoginProfile, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*osloginpb.LoginProfile), nil } func (s *mockOsLoginServer) GetSshPublicKey(ctx context.Context, req *osloginpb.GetSshPublicKeyRequest) (*commonpb.SshPublicKey, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*commonpb.SshPublicKey), nil } func (s *mockOsLoginServer) ImportSshPublicKey(ctx context.Context, req *osloginpb.ImportSshPublicKeyRequest) (*osloginpb.ImportSshPublicKeyResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*osloginpb.ImportSshPublicKeyResponse), nil } func (s *mockOsLoginServer) UpdateSshPublicKey(ctx context.Context, req *osloginpb.UpdateSshPublicKeyRequest) (*commonpb.SshPublicKey, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*commonpb.SshPublicKey), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockOsLogin mockOsLoginServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() osloginpb.RegisterOsLoginServiceServer(serv, &mockOsLogin) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestOsLoginServiceDeletePosixAccount(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockOsLogin.err = nil mockOsLogin.reqs = nil mockOsLogin.resps = append(mockOsLogin.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("users/%s/projects/%s", "[USER]", "[PROJECT]") var request = &osloginpb.DeletePosixAccountRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeletePosixAccount(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockOsLogin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestOsLoginServiceDeletePosixAccountError(t *testing.T) { errCode := codes.PermissionDenied mockOsLogin.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("users/%s/projects/%s", "[USER]", "[PROJECT]") var request = &osloginpb.DeletePosixAccountRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeletePosixAccount(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestOsLoginServiceDeleteSshPublicKey(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockOsLogin.err = nil mockOsLogin.reqs = nil mockOsLogin.resps = append(mockOsLogin.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("users/%s/sshPublicKeys/%s", "[USER]", "[FINGERPRINT]") var request = &osloginpb.DeleteSshPublicKeyRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteSshPublicKey(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockOsLogin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestOsLoginServiceDeleteSshPublicKeyError(t *testing.T) { errCode := codes.PermissionDenied mockOsLogin.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("users/%s/sshPublicKeys/%s", "[USER]", "[FINGERPRINT]") var request = &osloginpb.DeleteSshPublicKeyRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteSshPublicKey(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestOsLoginServiceGetLoginProfile(t *testing.T) { var name2 string = "name2-1052831874" var expectedResponse = &osloginpb.LoginProfile{ Name: name2, } mockOsLogin.err = nil mockOsLogin.reqs = nil mockOsLogin.resps = append(mockOsLogin.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("users/%s", "[USER]") var request = &osloginpb.GetLoginProfileRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetLoginProfile(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockOsLogin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestOsLoginServiceGetLoginProfileError(t *testing.T) { errCode := codes.PermissionDenied mockOsLogin.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("users/%s", "[USER]") var request = &osloginpb.GetLoginProfileRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetLoginProfile(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestOsLoginServiceGetSshPublicKey(t *testing.T) { var key string = "key106079" var expirationTimeUsec int64 = 2058878882 var fingerprint string = "fingerprint-1375934236" var name2 string = "name2-1052831874" var expectedResponse = &commonpb.SshPublicKey{ Key: key, ExpirationTimeUsec: expirationTimeUsec, Fingerprint: fingerprint, Name: name2, } mockOsLogin.err = nil mockOsLogin.reqs = nil mockOsLogin.resps = append(mockOsLogin.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("users/%s/sshPublicKeys/%s", "[USER]", "[FINGERPRINT]") var request = &osloginpb.GetSshPublicKeyRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetSshPublicKey(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockOsLogin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestOsLoginServiceGetSshPublicKeyError(t *testing.T) { errCode := codes.PermissionDenied mockOsLogin.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("users/%s/sshPublicKeys/%s", "[USER]", "[FINGERPRINT]") var request = &osloginpb.GetSshPublicKeyRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetSshPublicKey(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestOsLoginServiceImportSshPublicKey(t *testing.T) { var expectedResponse *osloginpb.ImportSshPublicKeyResponse = &osloginpb.ImportSshPublicKeyResponse{} mockOsLogin.err = nil mockOsLogin.reqs = nil mockOsLogin.resps = append(mockOsLogin.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("users/%s", "[USER]") var sshPublicKey *commonpb.SshPublicKey = &commonpb.SshPublicKey{} var request = &osloginpb.ImportSshPublicKeyRequest{ Parent: formattedParent, SshPublicKey: sshPublicKey, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ImportSshPublicKey(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockOsLogin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestOsLoginServiceImportSshPublicKeyError(t *testing.T) { errCode := codes.PermissionDenied mockOsLogin.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("users/%s", "[USER]") var sshPublicKey *commonpb.SshPublicKey = &commonpb.SshPublicKey{} var request = &osloginpb.ImportSshPublicKeyRequest{ Parent: formattedParent, SshPublicKey: sshPublicKey, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ImportSshPublicKey(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestOsLoginServiceUpdateSshPublicKey(t *testing.T) { var key string = "key106079" var expirationTimeUsec int64 = 2058878882 var fingerprint string = "fingerprint-1375934236" var name2 string = "name2-1052831874" var expectedResponse = &commonpb.SshPublicKey{ Key: key, ExpirationTimeUsec: expirationTimeUsec, Fingerprint: fingerprint, Name: name2, } mockOsLogin.err = nil mockOsLogin.reqs = nil mockOsLogin.resps = append(mockOsLogin.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("users/%s/sshPublicKeys/%s", "[USER]", "[FINGERPRINT]") var sshPublicKey *commonpb.SshPublicKey = &commonpb.SshPublicKey{} var request = &osloginpb.UpdateSshPublicKeyRequest{ Name: formattedName, SshPublicKey: sshPublicKey, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateSshPublicKey(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockOsLogin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestOsLoginServiceUpdateSshPublicKeyError(t *testing.T) { errCode := codes.PermissionDenied mockOsLogin.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("users/%s/sshPublicKeys/%s", "[USER]", "[FINGERPRINT]") var sshPublicKey *commonpb.SshPublicKey = &commonpb.SshPublicKey{} var request = &osloginpb.UpdateSshPublicKeyRequest{ Name: formattedName, SshPublicKey: sshPublicKey, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateSshPublicKey(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/oslogin/apiv1beta/os_login_client.go000066400000000000000000000217031356504100700236170ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package oslogin import ( "context" "fmt" "math" "net/url" "time" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" "google.golang.org/api/transport" commonpb "google.golang.org/genproto/googleapis/cloud/oslogin/common" osloginpb "google.golang.org/genproto/googleapis/cloud/oslogin/v1beta" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // CallOptions contains the retry settings for each method of Client. type CallOptions struct { DeletePosixAccount []gax.CallOption DeleteSshPublicKey []gax.CallOption GetLoginProfile []gax.CallOption GetSshPublicKey []gax.CallOption ImportSshPublicKey []gax.CallOption UpdateSshPublicKey []gax.CallOption } func defaultClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("oslogin.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultCallOptions() *CallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &CallOptions{ DeletePosixAccount: retry[[2]string{"default", "idempotent"}], DeleteSshPublicKey: retry[[2]string{"default", "idempotent"}], GetLoginProfile: retry[[2]string{"default", "idempotent"}], GetSshPublicKey: retry[[2]string{"default", "idempotent"}], ImportSshPublicKey: retry[[2]string{"default", "idempotent"}], UpdateSshPublicKey: retry[[2]string{"default", "idempotent"}], } } // Client is a client for interacting with Google Cloud OS Login API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. client osloginpb.OsLoginServiceClient // The call options for this service. CallOptions *CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewClient creates a new os login service client. // // Cloud OS Login API // // The Cloud OS Login API allows you to manage users and their associated SSH // public keys for logging into virtual machines on Google Cloud Platform. func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultClientOptions(), opts...)...) if err != nil { return nil, err } c := &Client{ conn: conn, CallOptions: defaultCallOptions(), client: osloginpb.NewOsLoginServiceClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *Client) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *Client) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // DeletePosixAccount deletes a POSIX account. func (c *Client) DeletePosixAccount(ctx context.Context, req *osloginpb.DeletePosixAccountRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeletePosixAccount[0:len(c.CallOptions.DeletePosixAccount):len(c.CallOptions.DeletePosixAccount)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.client.DeletePosixAccount(ctx, req, settings.GRPC...) return err }, opts...) return err } // DeleteSshPublicKey deletes an SSH public key. func (c *Client) DeleteSshPublicKey(ctx context.Context, req *osloginpb.DeleteSshPublicKeyRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteSshPublicKey[0:len(c.CallOptions.DeleteSshPublicKey):len(c.CallOptions.DeleteSshPublicKey)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.client.DeleteSshPublicKey(ctx, req, settings.GRPC...) return err }, opts...) return err } // GetLoginProfile retrieves the profile information used for logging in to a virtual machine // on Google Compute Engine. func (c *Client) GetLoginProfile(ctx context.Context, req *osloginpb.GetLoginProfileRequest, opts ...gax.CallOption) (*osloginpb.LoginProfile, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetLoginProfile[0:len(c.CallOptions.GetLoginProfile):len(c.CallOptions.GetLoginProfile)], opts...) var resp *osloginpb.LoginProfile err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetLoginProfile(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetSshPublicKey retrieves an SSH public key. func (c *Client) GetSshPublicKey(ctx context.Context, req *osloginpb.GetSshPublicKeyRequest, opts ...gax.CallOption) (*commonpb.SshPublicKey, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetSshPublicKey[0:len(c.CallOptions.GetSshPublicKey):len(c.CallOptions.GetSshPublicKey)], opts...) var resp *commonpb.SshPublicKey err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetSshPublicKey(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ImportSshPublicKey adds an SSH public key and returns the profile information. Default POSIX // account information is set when no username and UID exist as part of the // login profile. func (c *Client) ImportSshPublicKey(ctx context.Context, req *osloginpb.ImportSshPublicKeyRequest, opts ...gax.CallOption) (*osloginpb.ImportSshPublicKeyResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ImportSshPublicKey[0:len(c.CallOptions.ImportSshPublicKey):len(c.CallOptions.ImportSshPublicKey)], opts...) var resp *osloginpb.ImportSshPublicKeyResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ImportSshPublicKey(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateSshPublicKey updates an SSH public key and returns the profile information. This method // supports patch semantics. func (c *Client) UpdateSshPublicKey(ctx context.Context, req *osloginpb.UpdateSshPublicKeyRequest, opts ...gax.CallOption) (*commonpb.SshPublicKey, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateSshPublicKey[0:len(c.CallOptions.UpdateSshPublicKey):len(c.CallOptions.UpdateSshPublicKey)], opts...) var resp *commonpb.SshPublicKey err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.UpdateSshPublicKey(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } google-cloud-go-0.49.0/oslogin/apiv1beta/os_login_client_example_test.go000066400000000000000000000057551356504100700264020ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package oslogin_test import ( "context" oslogin "cloud.google.com/go/oslogin/apiv1beta" osloginpb "google.golang.org/genproto/googleapis/cloud/oslogin/v1beta" ) func ExampleNewClient() { ctx := context.Background() c, err := oslogin.NewClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleClient_DeletePosixAccount() { ctx := context.Background() c, err := oslogin.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &osloginpb.DeletePosixAccountRequest{ // TODO: Fill request struct fields. } err = c.DeletePosixAccount(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleClient_DeleteSshPublicKey() { ctx := context.Background() c, err := oslogin.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &osloginpb.DeleteSshPublicKeyRequest{ // TODO: Fill request struct fields. } err = c.DeleteSshPublicKey(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleClient_GetLoginProfile() { ctx := context.Background() c, err := oslogin.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &osloginpb.GetLoginProfileRequest{ // TODO: Fill request struct fields. } resp, err := c.GetLoginProfile(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_GetSshPublicKey() { ctx := context.Background() c, err := oslogin.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &osloginpb.GetSshPublicKeyRequest{ // TODO: Fill request struct fields. } resp, err := c.GetSshPublicKey(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ImportSshPublicKey() { ctx := context.Background() c, err := oslogin.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &osloginpb.ImportSshPublicKeyRequest{ // TODO: Fill request struct fields. } resp, err := c.ImportSshPublicKey(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_UpdateSshPublicKey() { ctx := context.Background() c, err := oslogin.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &osloginpb.UpdateSshPublicKeyRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateSshPublicKey(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/phishingprotection/000077500000000000000000000000001356504100700205105ustar00rootroot00000000000000google-cloud-go-0.49.0/phishingprotection/apiv1beta1/000077500000000000000000000000001356504100700224455ustar00rootroot00000000000000google-cloud-go-0.49.0/phishingprotection/apiv1beta1/.repo-metadata.json000066400000000000000000000007161356504100700261450ustar00rootroot00000000000000{ "name": "phishingprotection", "name_pretty": "Phishing Protection API", "product_documentation": "https://cloud.google.com/phishing-protection/", "client_documentation": "https://godoc.org/cloud.google.com/go/phishingprotection/apiv1beta1", "release_level": "beta", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "phishingprotection.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/phishingprotection/apiv1beta1/doc.go000066400000000000000000000053051356504100700235440ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go_gapic. DO NOT EDIT. // Package phishingprotection is an auto-generated package for the // Phishing Protection API. // // NOTE: This package is in beta. It is not stable, and may be subject to changes. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package phishingprotection // import "cloud.google.com/go/phishingprotection/apiv1beta1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) const versionClient = "20191115" func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return !strings.ContainsRune("0123456789.", r) } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } google-cloud-go-0.49.0/phishingprotection/apiv1beta1/mock_test.go000066400000000000000000000111651356504100700247700ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package phishingprotection import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" "google.golang.org/api/option" phishingprotectionpb "google.golang.org/genproto/googleapis/cloud/phishingprotection/v1beta1" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockPhishingProtectionServiceV1Beta1Server struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. phishingprotectionpb.PhishingProtectionServiceV1Beta1Server reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockPhishingProtectionServiceV1Beta1Server) ReportPhishing(ctx context.Context, req *phishingprotectionpb.ReportPhishingRequest) (*phishingprotectionpb.ReportPhishingResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*phishingprotectionpb.ReportPhishingResponse), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockPhishingProtectionServiceV1Beta1 mockPhishingProtectionServiceV1Beta1Server ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() phishingprotectionpb.RegisterPhishingProtectionServiceV1Beta1Server(serv, &mockPhishingProtectionServiceV1Beta1) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestPhishingProtectionServiceV1Beta1ReportPhishing(t *testing.T) { var expectedResponse *phishingprotectionpb.ReportPhishingResponse = &phishingprotectionpb.ReportPhishingResponse{} mockPhishingProtectionServiceV1Beta1.err = nil mockPhishingProtectionServiceV1Beta1.reqs = nil mockPhishingProtectionServiceV1Beta1.resps = append(mockPhishingProtectionServiceV1Beta1.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var uri string = "uri116076" var request = &phishingprotectionpb.ReportPhishingRequest{ Parent: formattedParent, Uri: uri, } c, err := NewPhishingProtectionServiceV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ReportPhishing(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockPhishingProtectionServiceV1Beta1.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestPhishingProtectionServiceV1Beta1ReportPhishingError(t *testing.T) { errCode := codes.PermissionDenied mockPhishingProtectionServiceV1Beta1.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var uri string = "uri116076" var request = &phishingprotectionpb.ReportPhishingRequest{ Parent: formattedParent, Uri: uri, } c, err := NewPhishingProtectionServiceV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ReportPhishing(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/phishingprotection/apiv1beta1/phishing_protection_service_v1_beta1_client.go000066400000000000000000000124541356504100700336210ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go_gapic. DO NOT EDIT. package phishingprotection import ( "context" "fmt" "math" "net/url" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" "google.golang.org/api/transport" phishingprotectionpb "google.golang.org/genproto/googleapis/cloud/phishingprotection/v1beta1" "google.golang.org/grpc" "google.golang.org/grpc/metadata" ) // PhishingProtectionServiceV1Beta1CallOptions contains the retry settings for each method of PhishingProtectionServiceV1Beta1Client. type PhishingProtectionServiceV1Beta1CallOptions struct { ReportPhishing []gax.CallOption } func defaultPhishingProtectionServiceV1Beta1ClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("phishingprotection.googleapis.com:443"), option.WithGRPCDialOption(grpc.WithDisableServiceConfig()), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultPhishingProtectionServiceV1Beta1CallOptions() *PhishingProtectionServiceV1Beta1CallOptions { return &PhishingProtectionServiceV1Beta1CallOptions{ ReportPhishing: []gax.CallOption{}, } } // PhishingProtectionServiceV1Beta1Client is a client for interacting with Phishing Protection API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type PhishingProtectionServiceV1Beta1Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. phishingProtectionServiceV1Beta1Client phishingprotectionpb.PhishingProtectionServiceV1Beta1Client // The call options for this service. CallOptions *PhishingProtectionServiceV1Beta1CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewPhishingProtectionServiceV1Beta1Client creates a new phishing protection service v1 beta1 client. // // Service to report phishing URIs. func NewPhishingProtectionServiceV1Beta1Client(ctx context.Context, opts ...option.ClientOption) (*PhishingProtectionServiceV1Beta1Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultPhishingProtectionServiceV1Beta1ClientOptions(), opts...)...) if err != nil { return nil, err } c := &PhishingProtectionServiceV1Beta1Client{ conn: conn, CallOptions: defaultPhishingProtectionServiceV1Beta1CallOptions(), phishingProtectionServiceV1Beta1Client: phishingprotectionpb.NewPhishingProtectionServiceV1Beta1Client(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *PhishingProtectionServiceV1Beta1Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *PhishingProtectionServiceV1Beta1Client) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *PhishingProtectionServiceV1Beta1Client) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // ReportPhishing reports a URI suspected of containing phishing content to be reviewed. Once // the report review is complete, its result can be found in the Cloud // Security Command Center findings dashboard for Phishing Protection. If the // result verifies the existence of malicious phishing content, the site will // be added the to Google’s Social Engineering // lists (at https://support.google.com/webmasters/answer/6350487/) in order to // protect users that could get exposed to this threat in the future. func (c *PhishingProtectionServiceV1Beta1Client) ReportPhishing(ctx context.Context, req *phishingprotectionpb.ReportPhishingRequest, opts ...gax.CallOption) (*phishingprotectionpb.ReportPhishingResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ReportPhishing[0:len(c.CallOptions.ReportPhishing):len(c.CallOptions.ReportPhishing)], opts...) var resp *phishingprotectionpb.ReportPhishingResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.phishingProtectionServiceV1Beta1Client.ReportPhishing(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } phishing_protection_service_v1_beta1_client_example_test.go000066400000000000000000000031631356504100700363110ustar00rootroot00000000000000google-cloud-go-0.49.0/phishingprotection/apiv1beta1// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go_gapic. DO NOT EDIT. package phishingprotection_test import ( "context" phishingprotection "cloud.google.com/go/phishingprotection/apiv1beta1" phishingprotectionpb "google.golang.org/genproto/googleapis/cloud/phishingprotection/v1beta1" ) func ExampleNewPhishingProtectionServiceV1Beta1Client() { ctx := context.Background() c, err := phishingprotection.NewPhishingProtectionServiceV1Beta1Client(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExamplePhishingProtectionServiceV1Beta1Client_ReportPhishing() { // import phishingprotectionpb "google.golang.org/genproto/googleapis/cloud/phishingprotection/v1beta1" ctx := context.Background() c, err := phishingprotection.NewPhishingProtectionServiceV1Beta1Client(ctx) if err != nil { // TODO: Handle error. } req := &phishingprotectionpb.ReportPhishingRequest{ // TODO: Fill request struct fields. } resp, err := c.ReportPhishing(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/profiler/000077500000000000000000000000001356504100700164125ustar00rootroot00000000000000google-cloud-go-0.49.0/profiler/.repo-metadata.json000066400000000000000000000006511356504100700221100ustar00rootroot00000000000000{ "name": "profiler", "name_pretty": "Stackdriver Profiler API", "product_documentation": "https://cloud.google.com/profiler", "client_documentation": "https://godoc.org/cloud.google.com/go/profiler", "release_level": "alpha", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go/profiler", "api_id": "cloudprofiler.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/profiler/busybench/000077500000000000000000000000001356504100700203745ustar00rootroot00000000000000google-cloud-go-0.49.0/profiler/busybench/Dockerfile000066400000000000000000000004751356504100700223740ustar00rootroot00000000000000FROM golang:alpine WORKDIR /go/src/busybench COPY *.go . EXPOSE 8080 RUN apk update \ && apk add --no-cache git \ && go get -d -v ./... \ && apk del git RUN go install -v ./... CMD ["busybench", "--service", "busybench", "--service_version", "1.0.2", "--duration", "0", "--mutex_profiling", "true"] google-cloud-go-0.49.0/profiler/busybench/busybench.go000066400000000000000000000057121356504100700227120ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Busybench is a tool that runs a benchmark with the profiler enabled. package main import ( "bytes" "compress/gzip" "flag" "log" "math/rand" "runtime" "sync" "time" "cloud.google.com/go/profiler" ) var ( service = flag.String("service", "", "service name") serviceVersion = flag.String("service_version", "1.0.0", "service version") mutexProfiling = flag.Bool("mutex_profiling", false, "enable mutex profiling") duration = flag.Int("duration", 200, "duration of the benchmark in seconds") apiAddr = flag.String("api_address", "", "API address of the profiler (e.g. 'cloudprofiler.googleapis.com:443')") projectID = flag.String("project_id", "", "cloud project ID") ) // busywork continuously generates 1MiB of random data and compresses it // throwing away the result. func busywork(mu *sync.Mutex) { start := time.Now() dur := time.Duration(*duration) * time.Second for time.Since(start) < dur || dur == 0 { busyworkOnce(mu) } } func busyworkOnce(mu *sync.Mutex) { data := make([]byte, 128*1024) rand.Read(data) // Grab the mutex after the allocation above is done so that // there are a number of outstanding allocations. This makes // the live heap profiles consistently non-empty. mu.Lock() defer mu.Unlock() var b bytes.Buffer gz := gzip.NewWriter(&b) if _, err := gz.Write(data); err != nil { log.Printf("Failed to write to gzip stream: %v", err) return } if err := gz.Flush(); err != nil { log.Printf("Failed to flush to gzip stream: %v", err) return } if err := gz.Close(); err != nil { log.Printf("Failed to close gzip stream: %v", err) } // Throw away the result. } func main() { flag.Parse() log.Printf("busybench using %s.", runtime.Version()) defer log.Printf("busybench finished profiling.") if *service == "" { log.Print("Service name must be configured using --service flag.") return } if err := profiler.Start(profiler.Config{Service: *service, MutexProfiling: *mutexProfiling, ServiceVersion: *serviceVersion, DebugLogging: true, APIAddr: *apiAddr, ProjectID: *projectID}); err != nil { log.Printf("Failed to start the profiler: %v", err) return } var mu sync.Mutex var wg sync.WaitGroup const numBusyworkers = 20 wg.Add(numBusyworkers) runtime.GOMAXPROCS(numBusyworkers) for i := 0; i < numBusyworkers; i++ { go func() { defer wg.Done() busywork(&mu) }() } wg.Wait() } google-cloud-go-0.49.0/profiler/heap.go000066400000000000000000000065721356504100700176700ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package profiler import ( "bytes" "context" "fmt" "runtime" "time" "github.com/google/pprof/profile" ) // heapProfile collects an in-use heap profile. The heap profiles returned by // the runtime also include the heap allocation metrics. We zero those out // since all allocations since program start are recorded, so these make the // profile large and there is a separate alloc profile type which shows // allocations from a set duration. func heapProfile(prof *bytes.Buffer) error { p, err := goHeapProfile() if err != nil { return err } for _, s := range p.Sample { s.Value[0] = 0 s.Value[1] = 0 } // Merge profile with itself to remove samples with only zero values and // reduce profile size. p, err = profile.Merge([]*profile.Profile{p}) if err != nil { return err } return p.Write(prof) } // deltaAllocProfile collects an allocation profile by gathering a heap profile, // sleeping for the specified duration, gathering another heap profile and // subtracting the initial one from that. It then drops the in-use metrics from // the profile. If requested, it forces the GC before taking each of the heap // profiles, which improves the profile accuracy (see docs in // https://golang.org/src/runtime/mprof.go on why). func deltaAllocProfile(ctx context.Context, duration time.Duration, forceGC bool, prof *bytes.Buffer) error { p1, err := allocProfile(forceGC) if err != nil { return err } sleep(ctx, duration) p2, err := allocProfile(forceGC) if err != nil { return err } p1.Scale(-1) p, err := profile.Merge([]*profile.Profile{p1, p2}) if err != nil { return err } p.DurationNanos = duration.Nanoseconds() return p.Write(prof) } // allocProfile collects a single heap profile, and removes all metrics but // allocation metrics. func allocProfile(forceGC bool) (*profile.Profile, error) { if forceGC { runtime.GC() } p, err := goHeapProfile() if err != nil { return nil, err } p.SampleType = p.SampleType[:2] for _, s := range p.Sample { s.Value = s.Value[:2] } return p, nil } // goHeapProfile collects a heap profile. It returns an error if the metrics // in the collected heap profile do not match the expected metrics. func goHeapProfile() (*profile.Profile, error) { var prof bytes.Buffer if err := writeHeapProfile(&prof); err != nil { return nil, fmt.Errorf("failed to write heap profile: %v", err) } p, err := profile.Parse(&prof) if err != nil { return nil, err } if got := len(p.SampleType); got != 4 { return nil, fmt.Errorf("invalid heap profile: got %d sample types, want 4", got) } for i, want := range []string{"alloc_objects", "alloc_space", "inuse_objects", "inuse_space"} { if got := p.SampleType[i].Type; got != want { return nil, fmt.Errorf("invalid heap profile: got %q sample type at index %d, want %q", got, i, want) } } return p, nil } google-cloud-go-0.49.0/profiler/heap_test.go000066400000000000000000000041261356504100700207200ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package profiler import ( "bytes" "io" "testing" "cloud.google.com/go/profiler/testdata" "github.com/google/pprof/profile" ) func TestGoHeapProfile(t *testing.T) { oldStartCPUProfile, oldStopCPUProfile, oldWriteHeapProfile, oldSleep := startCPUProfile, stopCPUProfile, writeHeapProfile, sleep defer func() { startCPUProfile, stopCPUProfile, writeHeapProfile, sleep = oldStartCPUProfile, oldStopCPUProfile, oldWriteHeapProfile, oldSleep }() tests := []struct { name string profile *profile.Profile wantErr bool }{ { name: "valid heap profile", profile: testdata.HeapProfileCollected1, }, { name: "profile with too few sample types", profile: testdata.AllocProfileUploaded, wantErr: true, }, { name: "profile with incorrect sample types", profile: &profile.Profile{ DurationNanos: 10e9, SampleType: []*profile.ValueType{ {Type: "objects", Unit: "count"}, {Type: "alloc_space", Unit: "bytes"}, {Type: "inuse_objects", Unit: "count"}, {Type: "inuse_space", Unit: "bytes"}, }, }, wantErr: true, }, } for _, tc := range tests { var profileBytes bytes.Buffer tc.profile.Write(&profileBytes) writeHeapProfile = func(w io.Writer) error { w.Write(profileBytes.Bytes()) return nil } _, err := goHeapProfile() if tc.wantErr { if err == nil { t.Errorf("%s: goHeapProfile() got no error, want error", tc.name) } continue } if err != nil { t.Errorf("%s: goHeapProfile() got %q, want no error", tc.name, err) } } } google-cloud-go-0.49.0/profiler/integration_test.go000066400000000000000000000171031356504100700223250ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package profiler import ( "bytes" "context" "fmt" "os" "os/exec" "runtime" "strings" "testing" "text/template" "time" "cloud.google.com/go/profiler/proftest" "golang.org/x/oauth2/google" compute "google.golang.org/api/compute/v1" ) const ( cloudScope = "https://www.googleapis.com/auth/cloud-platform" benchFinishString = "busybench finished profiling" errorString = "failed to set up or run the benchmark" ) const startupTemplate = ` {{- template "prologue" . }} # Install git retry apt-get update >/dev/null retry apt-get -y -q install git >/dev/null # $GOCACHE is required from Go 1.12. See https://golang.org/doc/go1.11#gocache # $GOCACHE is explicitly set becasue $HOME is not set when this code runs mkdir -p /tmp/gocache export GOCACHE=/tmp/gocache # Install gcc, needed to install go master if [ "{{.GoVersion}}" = "master" ] then retry apt-get -y -q install gcc >/dev/null fi # Install desired Go version mkdir -p /tmp/bin retry curl -sL -o /tmp/bin/gimme https://raw.githubusercontent.com/travis-ci/gimme/master/gimme chmod +x /tmp/bin/gimme export PATH=$PATH:/tmp/bin retry eval "$(gimme {{.GoVersion}})" # Set $GOPATH export GOPATH="$HOME/go" export GOCLOUD_HOME=$GOPATH/src/cloud.google.com/go mkdir -p $GOCLOUD_HOME # Install agent retry git clone https://code.googlesource.com/gocloud $GOCLOUD_HOME >/dev/null cd $GOCLOUD_HOME retry git fetch origin {{.Commit}} git reset --hard {{.Commit}} cd $GOCLOUD_HOME/profiler/busybench retry go get >/dev/null # Run benchmark with agent go run busybench.go --service="{{.Service}}" --mutex_profiling="{{.MutexProfiling}}" {{ template "epilogue" . -}} ` type goGCETestCase struct { proftest.InstanceConfig name string goVersion string mutexProfiling bool wantProfileTypes []string } func (tc *goGCETestCase) initializeStartupScript(template *template.Template, commit string) error { var buf bytes.Buffer err := template.Execute(&buf, struct { Service string GoVersion string Commit string ErrorString string MutexProfiling bool }{ Service: tc.InstanceConfig.Name, GoVersion: tc.goVersion, Commit: commit, ErrorString: errorString, MutexProfiling: tc.mutexProfiling, }) if err != nil { return fmt.Errorf("failed to render startup script for %s: %v", tc.name, err) } tc.StartupScript = buf.String() return nil } func TestAgentIntegration(t *testing.T) { // Testing against master requires building go code and may take up to 10 minutes. // Allow this test to run in parallel with other top level tests to avoid timeouts. t.Parallel() if testing.Short() { t.Skip("skipping profiler integration test in short mode") } projectID := os.Getenv("GCLOUD_TESTS_GOLANG_PROJECT_ID") if projectID == "" { t.Skip("skipping profiler integration test when GCLOUD_TESTS_GOLANG_PROJECT_ID variable is not set") } zone := os.Getenv("GCLOUD_TESTS_GOLANG_PROFILER_ZONE") if zone == "" { t.Fatalf("GCLOUD_TESTS_GOLANG_PROFILER_ZONE environment variable must be set when integration test is requested") } // Figure out the Git commit of the current directory. The source checkout in // the test VM will run in the same commit. Note that any local changes to // the profiler agent won't be tested in the integration test. This flow only // works with code that has been committed and pushed to the public repo // (either to master or to a branch). output, err := exec.Command("git", "rev-parse", "HEAD").CombinedOutput() if err != nil { t.Fatalf("failed to gather the Git revision of the current source: %v", err) } commit := strings.Trim(string(output), "\n") t.Logf("using Git commit %q for the profiler integration test", commit) pst, err := time.LoadLocation("America/Los_Angeles") if err != nil { t.Fatalf("failed to initiate PST location: %v", err) } runID := strings.Replace(time.Now().In(pst).Format("2006-01-02-15-04-05.000000-0700"), ".", "-", -1) ctx := context.Background() client, err := google.DefaultClient(ctx, cloudScope) if err != nil { t.Fatalf("failed to get default client: %v", err) } computeService, err := compute.New(client) if err != nil { t.Fatalf("failed to initialize compute service: %v", err) } template, err := proftest.BaseStartupTmpl.Parse(startupTemplate) if err != nil { t.Fatalf("failed to parse startup script template: %v", err) } tr := proftest.TestRunner{ Client: client, } gceTr := proftest.GCETestRunner{ TestRunner: tr, ComputeService: computeService, } // Determine go version used by current test run goVersion := strings.TrimPrefix(runtime.Version(), "go") goVersionName := strings.Replace(goVersion, ".", "", -1) testcases := []goGCETestCase{ { InstanceConfig: proftest.InstanceConfig{ ProjectID: projectID, Zone: zone, Name: fmt.Sprintf("profiler-test-gomaster-%s", runID), MachineType: "n1-standard-1", }, name: fmt.Sprintf("profiler-test-gomaster"), wantProfileTypes: []string{"CPU", "HEAP", "THREADS", "CONTENTION", "HEAP_ALLOC"}, goVersion: "master", mutexProfiling: true, }, { InstanceConfig: proftest.InstanceConfig{ ProjectID: projectID, Zone: zone, Name: fmt.Sprintf("profiler-test-go%s-%s", goVersionName, runID), MachineType: "n1-standard-1", }, name: fmt.Sprintf("profiler-test-go%s", goVersionName), wantProfileTypes: []string{"CPU", "HEAP", "THREADS", "CONTENTION", "HEAP_ALLOC"}, goVersion: goVersion, mutexProfiling: true, }, } // The number of tests run in parallel is the current value of GOMAXPROCS. runtime.GOMAXPROCS(len(testcases)) for _, tc := range testcases { tc := tc // capture range variable t.Run(tc.name, func(t *testing.T) { t.Parallel() if err := tc.initializeStartupScript(template, commit); err != nil { t.Fatalf("failed to initialize startup script") } if err := gceTr.StartInstance(ctx, &tc.InstanceConfig); err != nil { t.Fatal(err) } defer func() { if gceTr.DeleteInstance(ctx, &tc.InstanceConfig); err != nil { t.Fatal(err) } }() timeoutCtx, cancel := context.WithTimeout(ctx, time.Minute*25) defer cancel() if err := gceTr.PollForSerialOutput(timeoutCtx, &tc.InstanceConfig, benchFinishString, errorString); err != nil { t.Fatalf("PollForSerialOutput() got error: %v", err) } timeNow := time.Now() endTime := timeNow.Format(time.RFC3339) startTime := timeNow.Add(-1 * time.Hour).Format(time.RFC3339) for _, pType := range tc.wantProfileTypes { pr, err := tr.QueryProfilesWithZone(tc.ProjectID, tc.InstanceConfig.Name, startTime, endTime, pType, tc.Zone) if err != nil { t.Errorf("QueryProfilesWithZone(%s, %s, %s, %s, %s, %s) got error: %v", tc.ProjectID, tc.InstanceConfig.Name, startTime, endTime, pType, tc.Zone, err) continue } if err := pr.HasFunction("busywork"); err != nil { t.Errorf("HasFunction(%s, %s, %s, %s, %s) got error: %v", tc.ProjectID, tc.InstanceConfig.Name, startTime, endTime, pType, err) } } }) } } google-cloud-go-0.49.0/profiler/mocks/000077500000000000000000000000001356504100700175265ustar00rootroot00000000000000google-cloud-go-0.49.0/profiler/mocks/README.md000066400000000000000000000011031356504100700210000ustar00rootroot00000000000000This directory contains auto-generated mocks for the ProfilerService interface. To regenerate the mocks, install https://github.com/golang/mock tool and run the command below while in the `mocks` directory. ``` mockgen -package mocks google.golang.org/genproto/googleapis/devtools/cloudprofiler/v2 \ ProfilerServiceClient \ > mock_profiler_client.go ``` Then re-add the copyright header in the file. You also need to either run the commands above using Golang 1.6 or manually change the "context" import to "context" to ensure the compatibility with Go 1.6. google-cloud-go-0.49.0/profiler/mocks/mock_profiler_client.go000066400000000000000000000103311356504100700242440ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by MockGen. DO NOT EDIT. // Source: google.golang.org/genproto/googleapis/devtools/cloudprofiler/v2 (interfaces: ProfilerServiceClient) // Package mocks is a generated GoMock package. package mocks import ( "context" reflect "reflect" gomock "github.com/golang/mock/gomock" v2 "google.golang.org/genproto/googleapis/devtools/cloudprofiler/v2" grpc "google.golang.org/grpc" ) // MockProfilerServiceClient is a mock of ProfilerServiceClient interface type MockProfilerServiceClient struct { ctrl *gomock.Controller recorder *MockProfilerServiceClientMockRecorder } // MockProfilerServiceClientMockRecorder is the mock recorder for MockProfilerServiceClient type MockProfilerServiceClientMockRecorder struct { mock *MockProfilerServiceClient } // NewMockProfilerServiceClient creates a new mock instance func NewMockProfilerServiceClient(ctrl *gomock.Controller) *MockProfilerServiceClient { mock := &MockProfilerServiceClient{ctrl: ctrl} mock.recorder = &MockProfilerServiceClientMockRecorder{mock} return mock } // EXPECT returns an object that allows the caller to indicate expected use func (m *MockProfilerServiceClient) EXPECT() *MockProfilerServiceClientMockRecorder { return m.recorder } // CreateOfflineProfile mocks base method func (m *MockProfilerServiceClient) CreateOfflineProfile(arg0 context.Context, arg1 *v2.CreateOfflineProfileRequest, arg2 ...grpc.CallOption) (*v2.Profile, error) { varargs := []interface{}{arg0, arg1} for _, a := range arg2 { varargs = append(varargs, a) } ret := m.ctrl.Call(m, "CreateOfflineProfile", varargs...) ret0, _ := ret[0].(*v2.Profile) ret1, _ := ret[1].(error) return ret0, ret1 } // CreateOfflineProfile indicates an expected call of CreateOfflineProfile func (mr *MockProfilerServiceClientMockRecorder) CreateOfflineProfile(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { varargs := append([]interface{}{arg0, arg1}, arg2...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateOfflineProfile", reflect.TypeOf((*MockProfilerServiceClient)(nil).CreateOfflineProfile), varargs...) } // CreateProfile mocks base method func (m *MockProfilerServiceClient) CreateProfile(arg0 context.Context, arg1 *v2.CreateProfileRequest, arg2 ...grpc.CallOption) (*v2.Profile, error) { varargs := []interface{}{arg0, arg1} for _, a := range arg2 { varargs = append(varargs, a) } ret := m.ctrl.Call(m, "CreateProfile", varargs...) ret0, _ := ret[0].(*v2.Profile) ret1, _ := ret[1].(error) return ret0, ret1 } // CreateProfile indicates an expected call of CreateProfile func (mr *MockProfilerServiceClientMockRecorder) CreateProfile(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { varargs := append([]interface{}{arg0, arg1}, arg2...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateProfile", reflect.TypeOf((*MockProfilerServiceClient)(nil).CreateProfile), varargs...) } // UpdateProfile mocks base method func (m *MockProfilerServiceClient) UpdateProfile(arg0 context.Context, arg1 *v2.UpdateProfileRequest, arg2 ...grpc.CallOption) (*v2.Profile, error) { varargs := []interface{}{arg0, arg1} for _, a := range arg2 { varargs = append(varargs, a) } ret := m.ctrl.Call(m, "UpdateProfile", varargs...) ret0, _ := ret[0].(*v2.Profile) ret1, _ := ret[1].(error) return ret0, ret1 } // UpdateProfile indicates an expected call of UpdateProfile func (mr *MockProfilerServiceClientMockRecorder) UpdateProfile(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { varargs := append([]interface{}{arg0, arg1}, arg2...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateProfile", reflect.TypeOf((*MockProfilerServiceClient)(nil).UpdateProfile), varargs...) } google-cloud-go-0.49.0/profiler/mutex.go000066400000000000000000000014021356504100700201000ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package profiler import "runtime" func enableMutexProfiling() bool { // One percent of mutex contention events are profiled. runtime.SetMutexProfileFraction(100) return true } google-cloud-go-0.49.0/profiler/profiler.go000066400000000000000000000426361356504100700205760ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package profiler is a client for the Stackdriver Profiler service. // // This package is still experimental and subject to change. // // Usage example: // // import "cloud.google.com/go/profiler" // ... // if err := profiler.Start(profiler.Config{Service: "my-service"}); err != nil { // // TODO: Handle error. // } // // Calling Start will start a goroutine to collect profiles and upload to // the profiler server, at the rhythm specified by the server. // // The caller must provide the service string in the config, and may provide // other information as well. See Config for details. // // Profiler has CPU, heap and goroutine profiling enabled by default. Mutex // profiling can be enabled in the config. Note that goroutine and mutex // profiles are shown as "threads" and "contention" profiles in the profiler // UI. package profiler import ( "bytes" "context" "errors" "fmt" "log" "os" "regexp" "runtime" "runtime/pprof" "sync" "time" gcemd "cloud.google.com/go/compute/metadata" "cloud.google.com/go/internal/version" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" "github.com/google/pprof/profile" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" gtransport "google.golang.org/api/transport/grpc" pb "google.golang.org/genproto/googleapis/devtools/cloudprofiler/v2" edpb "google.golang.org/genproto/googleapis/rpc/errdetails" "google.golang.org/grpc" "google.golang.org/grpc/codes" grpcmd "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" ) var ( config Config startOnce allowUntilSuccess mutexEnabled bool // The functions below are stubbed to be overrideable for testing. getProjectID = gcemd.ProjectID getInstanceName = gcemd.InstanceName getZone = gcemd.Zone startCPUProfile = pprof.StartCPUProfile stopCPUProfile = pprof.StopCPUProfile writeHeapProfile = pprof.WriteHeapProfile sleep = gax.Sleep dialGRPC = gtransport.Dial onGCE = gcemd.OnGCE serviceRegexp = regexp.MustCompile(`^[a-z]([-a-z0-9_.]{0,253}[a-z0-9])?$`) ) const ( apiAddress = "cloudprofiler.googleapis.com:443" xGoogAPIMetadata = "x-goog-api-client" zoneNameLabel = "zone" versionLabel = "version" languageLabel = "language" instanceLabel = "instance" scope = "https://www.googleapis.com/auth/monitoring.write" initialBackoff = time.Minute // Ensure the agent will recover within 1 hour. maxBackoff = time.Hour backoffMultiplier = 1.3 // Backoff envelope increases by this factor on each retry. retryInfoMetadata = "google.rpc.retryinfo-bin" ) // Config is the profiler configuration. type Config struct { // Service must be provided to start the profiler. It specifies the name of // the service under which the profiled data will be recorded and exposed at // the Profiler UI for the project. You can specify an arbitrary string, but // see Deployment.target at // https://github.com/googleapis/googleapis/blob/master/google/devtools/cloudprofiler/v2/profiler.proto // for restrictions. If the parameter is not set, the agent will probe // GAE_SERVICE environment variable which is present in Google App Engine // environment. // NOTE: The string should be the same across different replicas of // your service so that the globally constant profiling rate is // maintained. Do not put things like PID or unique pod ID in the name. Service string // ServiceVersion is an optional field specifying the version of the // service. It can be an arbitrary string. Profiler profiles // once per minute for each version of each service in each zone. // ServiceVersion defaults to GAE_VERSION environment variable if that is // set, or to empty string otherwise. ServiceVersion string // DebugLogging enables detailed debug logging from profiler. It // defaults to false. DebugLogging bool // MutexProfiling enables mutex profiling. It defaults to false. // Note that mutex profiling is not supported by Go versions older // than Go 1.8. MutexProfiling bool // When true, collecting the allocation profiles is disabled. NoAllocProfiling bool // AllocForceGC forces garbage collection before the collection of each heap // profile collected to produce the allocation profile. This increases the // accuracy of allocation profiling. It defaults to false. AllocForceGC bool // When true, collecting the heap profiles is disabled. NoHeapProfiling bool // When true, collecting the goroutine profiles is disabled. NoGoroutineProfiling bool // ProjectID is the Cloud Console project ID to use instead of the one set by // GOOGLE_CLOUD_PROJECT environment variable or read from the VM metadata // server. // // Set this if you are running the agent in your local environment // or anywhere else outside of Google Cloud Platform. ProjectID string // APIAddr is the HTTP endpoint to use to connect to the profiler // agent API. Defaults to the production environment, overridable // for testing. APIAddr string // Instance is the name of Compute Engine instance the profiler agent runs // on. This is normally determined from the Compute Engine metadata server // and doesn't need to be initialized. It needs to be set in rare cases where // the metadata server is present but is flaky or otherwise misbehave. Instance string // Zone is the zone of Compute Engine instance the profiler agent runs // on. This is normally determined from the Compute Engine metadata server // and doesn't need to be initialized. It needs to be set in rare cases where // the metadata server is present but is flaky or otherwise misbehave. Zone string } // allowUntilSuccess is an object that will perform action till // it succeeds once. // This is a modified form of Go's sync.Once type allowUntilSuccess struct { m sync.Mutex done uint32 } // do calls function f only if it hasnt returned nil previously. // Once f returns nil, do will not call function f any more. // This is a modified form of Go's sync.Once.Do func (o *allowUntilSuccess) do(f func() error) (err error) { o.m.Lock() defer o.m.Unlock() if o.done == 0 { if err = f(); err == nil { o.done = 1 } } else { debugLog("profiler.Start() called again after it was previously called") err = nil } return err } // Start starts a goroutine to collect and upload profiles. The // caller must provide the service string in the config. See // Config for details. Start should only be called once. Any // additional calls will be ignored. func Start(cfg Config, options ...option.ClientOption) error { startError := startOnce.do(func() error { return start(cfg, options...) }) return startError } func start(cfg Config, options ...option.ClientOption) error { if err := initializeConfig(cfg); err != nil { debugLog("failed to initialize config: %v", err) return err } if config.MutexProfiling { if mutexEnabled = enableMutexProfiling(); !mutexEnabled { return fmt.Errorf("mutex profiling is not supported by %s, requires Go 1.8 or later", runtime.Version()) } } ctx := context.Background() opts := []option.ClientOption{ option.WithEndpoint(config.APIAddr), option.WithScopes(scope), option.WithUserAgent(fmt.Sprintf("gcloud-go-profiler/%s", version.Repo)), } opts = append(opts, options...) conn, err := dialGRPC(ctx, opts...) if err != nil { debugLog("failed to dial GRPC: %v", err) return err } a := initializeAgent(pb.NewProfilerServiceClient(conn)) go pollProfilerService(withXGoogHeader(ctx), a) return nil } func debugLog(format string, e ...interface{}) { if config.DebugLogging { log.Printf(format, e...) } } // agent polls the profiler server for instructions on behalf of a task, // and collects and uploads profiles as requested. type agent struct { client pb.ProfilerServiceClient deployment *pb.Deployment profileLabels map[string]string profileTypes []pb.ProfileType } // abortedBackoffDuration retrieves the retry duration from gRPC trailing // metadata, which is set by the profiler server. func abortedBackoffDuration(md grpcmd.MD) (time.Duration, error) { elem := md[retryInfoMetadata] if len(elem) <= 0 { return 0, errors.New("no retry info") } var retryInfo edpb.RetryInfo if err := proto.Unmarshal([]byte(elem[0]), &retryInfo); err != nil { return 0, err } else if time, err := ptypes.Duration(retryInfo.RetryDelay); err != nil { return 0, err } else { if time < 0 { return 0, errors.New("negative retry duration") } return time, nil } } type retryer struct { backoff gax.Backoff md grpcmd.MD } func (r *retryer) Retry(err error) (time.Duration, bool) { st, _ := status.FromError(err) if st != nil && st.Code() == codes.Aborted { dur, err := abortedBackoffDuration(r.md) if err == nil { return dur, true } debugLog("failed to get backoff duration: %v", err) } return r.backoff.Pause(), true } // createProfile talks to the profiler server to create profile. In // case of error, the goroutine will sleep and retry. Sleep duration may // be specified by the server. Otherwise it will be an exponentially // increasing value, bounded by maxBackoff. func (a *agent) createProfile(ctx context.Context) *pb.Profile { req := pb.CreateProfileRequest{ Parent: "projects/" + a.deployment.ProjectId, Deployment: a.deployment, ProfileType: a.profileTypes, } var p *pb.Profile md := grpcmd.New(map[string]string{}) gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error p, err = a.client.CreateProfile(ctx, &req, grpc.Trailer(&md)) if err != nil { debugLog("failed to create a profile, will retry: %v", err) } return err }, gax.WithRetry(func() gax.Retryer { return &retryer{ backoff: gax.Backoff{ Initial: initialBackoff, Max: maxBackoff, Multiplier: backoffMultiplier, }, md: md, } })) debugLog("successfully created profile %v", p.GetProfileType()) return p } func (a *agent) profileAndUpload(ctx context.Context, p *pb.Profile) { var prof bytes.Buffer pt := p.GetProfileType() switch pt { case pb.ProfileType_CPU: duration, err := ptypes.Duration(p.Duration) if err != nil { debugLog("failed to get profile duration for CPU profile: %v", err) return } if err := startCPUProfile(&prof); err != nil { debugLog("failed to start CPU profile: %v", err) return } sleep(ctx, duration) stopCPUProfile() case pb.ProfileType_HEAP: if err := heapProfile(&prof); err != nil { debugLog("failed to write heap profile: %v", err) return } case pb.ProfileType_HEAP_ALLOC: duration, err := ptypes.Duration(p.Duration) if err != nil { debugLog("failed to get profile duration for allocation profile: %v", err) return } if err := deltaAllocProfile(ctx, duration, config.AllocForceGC, &prof); err != nil { debugLog("failed to collect allocation profile: %v", err) return } case pb.ProfileType_THREADS: if err := pprof.Lookup("goroutine").WriteTo(&prof, 0); err != nil { debugLog("failed to collect goroutine profile: %v", err) return } case pb.ProfileType_CONTENTION: duration, err := ptypes.Duration(p.Duration) if err != nil { debugLog("failed to get profile duration: %v", err) return } if err := deltaMutexProfile(ctx, duration, &prof); err != nil { debugLog("failed to collect mutex profile: %v", err) return } default: debugLog("unexpected profile type: %v", pt) return } // Starting Go 1.9 the profiles are symbolized by runtime/pprof. // TODO(jianqiaoli): Remove the symbolization code when we decide to // stop supporting Go 1.8. if !shouldAssumeSymbolized && pt != pb.ProfileType_CONTENTION { if err := parseAndSymbolize(&prof); err != nil { debugLog("failed to symbolize profile: %v", err) } } p.ProfileBytes = prof.Bytes() p.Labels = a.profileLabels req := pb.UpdateProfileRequest{Profile: p} // Upload profile, discard profile in case of error. debugLog("start uploading profile") if _, err := a.client.UpdateProfile(ctx, &req); err != nil { debugLog("failed to upload profile: %v", err) } } // deltaMutexProfile writes mutex profile changes over a time period specified // with 'duration' to 'prof'. func deltaMutexProfile(ctx context.Context, duration time.Duration, prof *bytes.Buffer) error { if !mutexEnabled { return errors.New("mutex profiling is not enabled") } p0, err := mutexProfile() if err != nil { return err } sleep(ctx, duration) p, err := mutexProfile() if err != nil { return err } p0.Scale(-1) p, err = profile.Merge([]*profile.Profile{p0, p}) if err != nil { return err } // The mutex profile is not symbolized by runtime.pprof until // golang.org/issue/21474 is fixed in go1.10. symbolize(p) return p.Write(prof) } func mutexProfile() (*profile.Profile, error) { p := pprof.Lookup("mutex") if p == nil { return nil, errors.New("mutex profiling is not supported") } var buf bytes.Buffer if err := p.WriteTo(&buf, 0); err != nil { return nil, err } return profile.Parse(&buf) } // withXGoogHeader sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func withXGoogHeader(ctx context.Context, keyval ...string) context.Context { kv := append([]string{"gl-go", version.Go(), "gccl", version.Repo}, keyval...) kv = append(kv, "gax", gax.Version, "grpc", grpc.Version) md, _ := grpcmd.FromOutgoingContext(ctx) md = md.Copy() md[xGoogAPIMetadata] = []string{gax.XGoogHeader(kv...)} return grpcmd.NewOutgoingContext(ctx, md) } func initializeAgent(c pb.ProfilerServiceClient) *agent { labels := map[string]string{languageLabel: "go"} if config.Zone != "" { labels[zoneNameLabel] = config.Zone } if config.ServiceVersion != "" { labels[versionLabel] = config.ServiceVersion } d := &pb.Deployment{ ProjectId: config.ProjectID, Target: config.Service, Labels: labels, } profileLabels := map[string]string{} if config.Instance != "" { profileLabels[instanceLabel] = config.Instance } profileTypes := []pb.ProfileType{pb.ProfileType_CPU} if !config.NoHeapProfiling { profileTypes = append(profileTypes, pb.ProfileType_HEAP) } if !config.NoGoroutineProfiling { profileTypes = append(profileTypes, pb.ProfileType_THREADS) } if !config.NoAllocProfiling { profileTypes = append(profileTypes, pb.ProfileType_HEAP_ALLOC) } if mutexEnabled { profileTypes = append(profileTypes, pb.ProfileType_CONTENTION) } return &agent{ client: c, deployment: d, profileLabels: profileLabels, profileTypes: profileTypes, } } func initializeConfig(cfg Config) error { config = cfg if config.Service == "" { for _, ev := range []string{"GAE_SERVICE", "K_SERVICE"} { if val := os.Getenv(ev); val != "" { config.Service = val break } } } if config.Service == "" { return errors.New("service name must be configured") } if !serviceRegexp.MatchString(config.Service) { return fmt.Errorf("service name %q does not match regular expression %v", config.Service, serviceRegexp) } if config.ServiceVersion == "" { for _, ev := range []string{"GAE_VERSION", "K_REVISION"} { if val := os.Getenv(ev); val != "" { config.ServiceVersion = val break } } } if projectID := os.Getenv("GOOGLE_CLOUD_PROJECT"); config.ProjectID == "" && projectID != "" { // Cloud Shell and App Engine set this environment variable to the project // ID, so use it if present. In case of App Engine the project ID is also // available from the GCE metadata server, but by using the environment // variable saves one request to the metadata server. The environment // project ID is only used if no project ID is provided in the // configuration. config.ProjectID = projectID } if onGCE() { var err error if config.ProjectID == "" { if config.ProjectID, err = getProjectID(); err != nil { return fmt.Errorf("failed to get the project ID from Compute Engine metadata: %v", err) } } if config.Zone == "" { if config.Zone, err = getZone(); err != nil { return fmt.Errorf("failed to get zone from Compute Engine metadata: %v", err) } } if config.Instance == "" { if config.Instance, err = getInstanceName(); err != nil { if _, ok := err.(gcemd.NotDefinedError); !ok { return fmt.Errorf("failed to get instance name from Compute Engine metadata: %v", err) } debugLog("failed to get instance name from Compute Engine metadata, will use empty name: %v", err) } } } else { if config.ProjectID == "" { return fmt.Errorf("project ID must be specified in the configuration if running outside of GCP") } } if config.APIAddr == "" { config.APIAddr = apiAddress } return nil } // pollProfilerService starts an endless loop to poll the profiler // server for instructions, and collects and uploads profiles as // requested. func pollProfilerService(ctx context.Context, a *agent) { debugLog("Stackdriver Profiler Go Agent version: %s", version.Repo) debugLog("profiler has started") for { p := a.createProfile(ctx) a.profileAndUpload(ctx, p) } } google-cloud-go-0.49.0/profiler/profiler_example_test.go000066400000000000000000000014511356504100700233360ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package profiler_test import ( "cloud.google.com/go/profiler" ) func ExampleStart() { if err := profiler.Start(profiler.Config{Service: "my-service", ServiceVersion: "v1"}); err != nil { //TODO: Handle error. } } google-cloud-go-0.49.0/profiler/profiler_test.go000066400000000000000000000665711356504100700216410ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package profiler import ( "bytes" "compress/gzip" "context" "errors" "fmt" "io" "log" "math/rand" "os" "runtime" "strings" "sync" "testing" "time" gcemd "cloud.google.com/go/compute/metadata" "cloud.google.com/go/internal/testutil" "cloud.google.com/go/profiler/mocks" "cloud.google.com/go/profiler/testdata" "github.com/golang/mock/gomock" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" "github.com/google/pprof/profile" gax "github.com/googleapis/gax-go/v2" gtransport "google.golang.org/api/transport/grpc" pb "google.golang.org/genproto/googleapis/devtools/cloudprofiler/v2" edpb "google.golang.org/genproto/googleapis/rpc/errdetails" "google.golang.org/grpc/codes" grpcmd "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" ) const ( testProjectID = "test-project-ID" testInstance = "test-instance" testZone = "test-zone" testService = "test-service" testSvcVersion = "test-service-version" testProfileDuration = time.Second * 10 testServerTimeout = time.Second * 15 ) func createTestDeployment() *pb.Deployment { labels := map[string]string{ zoneNameLabel: testZone, versionLabel: testSvcVersion, } return &pb.Deployment{ ProjectId: testProjectID, Target: testService, Labels: labels, } } func createTestAgent(psc pb.ProfilerServiceClient) *agent { return &agent{ client: psc, deployment: createTestDeployment(), profileLabels: map[string]string{instanceLabel: testInstance}, profileTypes: []pb.ProfileType{pb.ProfileType_CPU, pb.ProfileType_HEAP, pb.ProfileType_THREADS}, } } func createTrailers(dur time.Duration) map[string]string { b, _ := proto.Marshal(&edpb.RetryInfo{ RetryDelay: ptypes.DurationProto(dur), }) return map[string]string{ retryInfoMetadata: string(b), } } func TestCreateProfile(t *testing.T) { ctx := context.Background() ctrl := gomock.NewController(t) defer ctrl.Finish() mpc := mocks.NewMockProfilerServiceClient(ctrl) a := createTestAgent(mpc) p := &pb.Profile{Name: "test_profile"} wantRequest := pb.CreateProfileRequest{ Parent: "projects/" + a.deployment.ProjectId, Deployment: a.deployment, ProfileType: a.profileTypes, } mpc.EXPECT().CreateProfile(ctx, gomock.Eq(&wantRequest), gomock.Any()).Times(1).Return(p, nil) gotP := a.createProfile(ctx) if !testutil.Equal(gotP, p) { t.Errorf("CreateProfile() got wrong profile, got %v, want %v", gotP, p) } } func TestProfileAndUpload(t *testing.T) { oldStartCPUProfile, oldStopCPUProfile, oldWriteHeapProfile, oldSleep := startCPUProfile, stopCPUProfile, writeHeapProfile, sleep defer func() { startCPUProfile, stopCPUProfile, writeHeapProfile, sleep = oldStartCPUProfile, oldStopCPUProfile, oldWriteHeapProfile, oldSleep }() ctx := context.Background() ctrl := gomock.NewController(t) defer ctrl.Finish() var heapCollected1, heapCollected2, heapUploaded, allocUploaded bytes.Buffer testdata.HeapProfileCollected1.Write(&heapCollected1) testdata.HeapProfileCollected2.Write(&heapCollected2) testdata.HeapProfileUploaded.Write(&heapUploaded) testdata.AllocProfileUploaded.Write(&allocUploaded) callCount := 0 writeTwoHeapFunc := func(w io.Writer) error { callCount++ if callCount%2 == 1 { w.Write(heapCollected1.Bytes()) return nil } w.Write(heapCollected2.Bytes()) return nil } errFunc := func(io.Writer) error { return errors.New("") } testDuration := time.Second * 5 tests := []struct { profileType pb.ProfileType duration *time.Duration startCPUProfileFunc func(io.Writer) error writeHeapProfileFunc func(io.Writer) error wantBytes []byte }{ { profileType: pb.ProfileType_CPU, duration: &testDuration, startCPUProfileFunc: func(w io.Writer) error { w.Write([]byte{1}) return nil }, writeHeapProfileFunc: errFunc, wantBytes: []byte{1}, }, { profileType: pb.ProfileType_CPU, startCPUProfileFunc: errFunc, writeHeapProfileFunc: errFunc, }, { profileType: pb.ProfileType_CPU, duration: &testDuration, startCPUProfileFunc: func(w io.Writer) error { w.Write([]byte{2}) return nil }, writeHeapProfileFunc: func(w io.Writer) error { w.Write([]byte{3}) return nil }, wantBytes: []byte{2}, }, { profileType: pb.ProfileType_HEAP, startCPUProfileFunc: errFunc, writeHeapProfileFunc: func(w io.Writer) error { w.Write(heapCollected1.Bytes()) return nil }, wantBytes: heapUploaded.Bytes(), }, { profileType: pb.ProfileType_HEAP_ALLOC, startCPUProfileFunc: errFunc, writeHeapProfileFunc: writeTwoHeapFunc, duration: &testDuration, wantBytes: allocUploaded.Bytes(), }, { profileType: pb.ProfileType_HEAP, startCPUProfileFunc: errFunc, writeHeapProfileFunc: errFunc, }, { profileType: pb.ProfileType_HEAP, startCPUProfileFunc: func(w io.Writer) error { w.Write([]byte{5}) return nil }, writeHeapProfileFunc: func(w io.Writer) error { w.Write(heapCollected1.Bytes()) return nil }, wantBytes: heapUploaded.Bytes(), }, { profileType: pb.ProfileType_PROFILE_TYPE_UNSPECIFIED, startCPUProfileFunc: func(w io.Writer) error { w.Write([]byte{7}) return nil }, writeHeapProfileFunc: func(w io.Writer) error { w.Write(heapCollected1.Bytes()) return nil }, }, } for _, tt := range tests { mpc := mocks.NewMockProfilerServiceClient(ctrl) a := createTestAgent(mpc) startCPUProfile = tt.startCPUProfileFunc stopCPUProfile = func() {} writeHeapProfile = tt.writeHeapProfileFunc var gotSleep *time.Duration sleep = func(ctx context.Context, d time.Duration) error { gotSleep = &d return nil } p := &pb.Profile{ProfileType: tt.profileType} if tt.duration != nil { p.Duration = ptypes.DurationProto(*tt.duration) } if tt.wantBytes != nil { wantProfile := &pb.Profile{ ProfileType: p.ProfileType, Duration: p.Duration, ProfileBytes: tt.wantBytes, Labels: a.profileLabels, } wantRequest := pb.UpdateProfileRequest{ Profile: wantProfile, } mpc.EXPECT().UpdateProfile(ctx, gomock.Eq(&wantRequest)).Times(1) } else { mpc.EXPECT().UpdateProfile(gomock.Any(), gomock.Any()).MaxTimes(0) } a.profileAndUpload(ctx, p) if tt.duration == nil { if gotSleep != nil { t.Errorf("profileAndUpload(%v) slept for: %v, want no sleep", p, gotSleep) } } else { if gotSleep == nil { t.Errorf("profileAndUpload(%v) didn't sleep, want sleep for: %v", p, tt.duration) } else if *gotSleep != *tt.duration { t.Errorf("profileAndUpload(%v) slept for wrong duration, got: %v, want: %v", p, gotSleep, tt.duration) } } } } func TestRetry(t *testing.T) { normalDuration := time.Second * 3 negativeDuration := time.Second * -3 tests := []struct { trailers map[string]string wantPause *time.Duration }{ { createTrailers(normalDuration), &normalDuration, }, { createTrailers(negativeDuration), nil, }, { map[string]string{retryInfoMetadata: "wrong format"}, nil, }, { map[string]string{}, nil, }, } for _, tt := range tests { md := grpcmd.New(tt.trailers) r := &retryer{ backoff: gax.Backoff{ Initial: initialBackoff, Max: maxBackoff, Multiplier: backoffMultiplier, }, md: md, } pause, shouldRetry := r.Retry(status.Error(codes.Aborted, "")) if !shouldRetry { t.Error("retryer.Retry() returned shouldRetry false, want true") } if tt.wantPause != nil { if pause != *tt.wantPause { t.Errorf("retryer.Retry() returned wrong pause, got: %v, want: %v", pause, tt.wantPause) } } else { if pause > initialBackoff { t.Errorf("retryer.Retry() returned wrong pause, got: %v, want: < %v", pause, initialBackoff) } } } md := grpcmd.New(map[string]string{}) r := &retryer{ backoff: gax.Backoff{ Initial: initialBackoff, Max: maxBackoff, Multiplier: backoffMultiplier, }, md: md, } for i := 0; i < 100; i++ { pause, shouldRetry := r.Retry(errors.New("")) if !shouldRetry { t.Errorf("retryer.Retry() called %v times, returned shouldRetry false, want true", i) } if pause > maxBackoff { t.Errorf("retryer.Retry() called %v times, returned wrong pause, got: %v, want: < %v", i, pause, maxBackoff) } } } func TestWithXGoogHeader(t *testing.T) { ctx := withXGoogHeader(context.Background()) md, _ := grpcmd.FromOutgoingContext(ctx) if xg := md[xGoogAPIMetadata]; len(xg) == 0 { t.Errorf("withXGoogHeader() sets empty xGoogHeader") } else { if !strings.Contains(xg[0], "gl-go/") { t.Errorf("withXGoogHeader() got: %v, want gl-go key", xg[0]) } if !strings.Contains(xg[0], "gccl/") { t.Errorf("withXGoogHeader() got: %v, want gccl key", xg[0]) } if !strings.Contains(xg[0], "gax/") { t.Errorf("withXGoogHeader() got: %v, want gax key", xg[0]) } if !strings.Contains(xg[0], "grpc/") { t.Errorf("withXGoogHeader() got: %v, want grpc key", xg[0]) } } } func TestInitializeAgent(t *testing.T) { oldConfig, oldMutexEnabled := config, mutexEnabled defer func() { config, mutexEnabled = oldConfig, oldMutexEnabled }() for _, tt := range []struct { config Config enableMutex bool wantProfileTypes []pb.ProfileType wantDeploymentLabels map[string]string wantProfileLabels map[string]string }{ { config: Config{ServiceVersion: testSvcVersion, Zone: testZone}, wantProfileTypes: []pb.ProfileType{pb.ProfileType_CPU, pb.ProfileType_HEAP, pb.ProfileType_THREADS, pb.ProfileType_HEAP_ALLOC}, wantDeploymentLabels: map[string]string{zoneNameLabel: testZone, versionLabel: testSvcVersion, languageLabel: "go"}, wantProfileLabels: map[string]string{}, }, { config: Config{Zone: testZone}, wantProfileTypes: []pb.ProfileType{pb.ProfileType_CPU, pb.ProfileType_HEAP, pb.ProfileType_THREADS, pb.ProfileType_HEAP_ALLOC}, wantDeploymentLabels: map[string]string{zoneNameLabel: testZone, languageLabel: "go"}, wantProfileLabels: map[string]string{}, }, { config: Config{ServiceVersion: testSvcVersion}, wantProfileTypes: []pb.ProfileType{pb.ProfileType_CPU, pb.ProfileType_HEAP, pb.ProfileType_THREADS, pb.ProfileType_HEAP_ALLOC}, wantDeploymentLabels: map[string]string{versionLabel: testSvcVersion, languageLabel: "go"}, wantProfileLabels: map[string]string{}, }, { config: Config{Instance: testInstance}, wantProfileTypes: []pb.ProfileType{pb.ProfileType_CPU, pb.ProfileType_HEAP, pb.ProfileType_THREADS, pb.ProfileType_HEAP_ALLOC}, wantDeploymentLabels: map[string]string{languageLabel: "go"}, wantProfileLabels: map[string]string{instanceLabel: testInstance}, }, { config: Config{Instance: testInstance}, enableMutex: true, wantProfileTypes: []pb.ProfileType{pb.ProfileType_CPU, pb.ProfileType_HEAP, pb.ProfileType_THREADS, pb.ProfileType_HEAP_ALLOC, pb.ProfileType_CONTENTION}, wantDeploymentLabels: map[string]string{languageLabel: "go"}, wantProfileLabels: map[string]string{instanceLabel: testInstance}, }, { config: Config{NoHeapProfiling: true}, wantProfileTypes: []pb.ProfileType{pb.ProfileType_CPU, pb.ProfileType_THREADS, pb.ProfileType_HEAP_ALLOC}, wantDeploymentLabels: map[string]string{languageLabel: "go"}, wantProfileLabels: map[string]string{}, }, { config: Config{NoHeapProfiling: true, NoGoroutineProfiling: true, NoAllocProfiling: true}, wantProfileTypes: []pb.ProfileType{pb.ProfileType_CPU}, wantDeploymentLabels: map[string]string{languageLabel: "go"}, wantProfileLabels: map[string]string{}, }, } { config = tt.config config.ProjectID = testProjectID config.Service = testService mutexEnabled = tt.enableMutex a := initializeAgent(nil) wantDeployment := &pb.Deployment{ ProjectId: testProjectID, Target: testService, Labels: tt.wantDeploymentLabels, } if !testutil.Equal(a.deployment, wantDeployment) { t.Errorf("initializeAgent() got deployment: %v, want %v", a.deployment, wantDeployment) } if !testutil.Equal(a.profileLabels, tt.wantProfileLabels) { t.Errorf("initializeAgent() got profile labels: %v, want %v", a.profileLabels, tt.wantProfileLabels) } if !testutil.Equal(a.profileTypes, tt.wantProfileTypes) { t.Errorf("initializeAgent() got profile types: %v, want %v", a.profileTypes, tt.wantProfileTypes) } } } func TestInitializeConfig(t *testing.T) { oldConfig, oldGAEService, oldGAEVersion, oldKnativeService, oldKnativeVersion, oldEnvProjectID, oldGetProjectID, oldGetInstanceName, oldGetZone, oldOnGCE := config, os.Getenv("GAE_SERVICE"), os.Getenv("GAE_VERSION"), os.Getenv("K_SERVICE"), os.Getenv("K_REVISION"), os.Getenv("GOOGLE_CLOUD_PROJECT"), getProjectID, getInstanceName, getZone, onGCE defer func() { config, getProjectID, getInstanceName, getZone, onGCE = oldConfig, oldGetProjectID, oldGetInstanceName, oldGetZone, oldOnGCE if err := os.Setenv("GAE_SERVICE", oldGAEService); err != nil { t.Fatal(err) } if err := os.Setenv("GAE_VERSION", oldGAEVersion); err != nil { t.Fatal(err) } if err := os.Setenv("K_SERVICE", oldKnativeService); err != nil { t.Fatal(err) } if err := os.Setenv("K_REVISION", oldKnativeVersion); err != nil { t.Fatal(err) } if err := os.Setenv("GOOGLE_CLOUD_PROJECT", oldEnvProjectID); err != nil { t.Fatal(err) } }() const ( testGAEService = "test-gae-service" testGAEVersion = "test-gae-version" testKnativeService = "test-knative-service" testKnativeVersion = "test-knative-version" testGCEProjectID = "test-gce-project-id" testEnvProjectID = "test-env-project-id" ) for _, tt := range []struct { desc string config Config wantConfig Config wantErrorString string onGAE bool onKnative bool onGCE bool envProjectID bool }{ { "accepts service name", Config{Service: testService}, Config{Service: testService, ProjectID: testGCEProjectID, Zone: testZone, Instance: testInstance}, "", false, false, true, false, }, { "env project overrides GCE project", Config{Service: testService}, Config{Service: testService, ProjectID: testEnvProjectID, Zone: testZone, Instance: testInstance}, "", false, false, true, true, }, { "requires service name", Config{}, Config{}, "service name must be configured", false, false, true, false, }, { "requires valid service name", Config{Service: "Service"}, Config{Service: "Service"}, "service name \"Service\" does not match regular expression ^[a-z]([-a-z0-9_.]{0,253}[a-z0-9])?$", false, false, true, false, }, { "accepts service name from config and service version from GAE", Config{Service: testService}, Config{Service: testService, ServiceVersion: testGAEVersion, ProjectID: testGCEProjectID, Zone: testZone, Instance: testInstance}, "", true, false, true, false, }, { "reads both service name and version from GAE env vars", Config{}, Config{Service: testGAEService, ServiceVersion: testGAEVersion, ProjectID: testGCEProjectID, Zone: testZone, Instance: testInstance}, "", true, false, true, false, }, { "reads both service name and version from Knative env vars", Config{}, Config{Service: testKnativeService, ServiceVersion: testKnativeVersion, ProjectID: testGCEProjectID, Zone: testZone, Instance: testInstance}, "", false, true, true, false, }, { "accepts service version from config", Config{Service: testService, ServiceVersion: testSvcVersion}, Config{Service: testService, ServiceVersion: testSvcVersion, ProjectID: testGCEProjectID, Zone: testZone, Instance: testInstance}, "", false, false, true, false, }, { "configured version has priority over GAE-provided version", Config{Service: testService, ServiceVersion: testSvcVersion}, Config{Service: testService, ServiceVersion: testSvcVersion, ProjectID: testGCEProjectID, Zone: testZone, Instance: testInstance}, "", true, false, true, false, }, { "configured version has priority over Knative-provided version", Config{Service: testService, ServiceVersion: testSvcVersion}, Config{Service: testService, ServiceVersion: testSvcVersion, ProjectID: testGCEProjectID, Zone: testZone, Instance: testInstance}, "", false, true, true, false, }, { "GAE version has priority over Knative-provided version", Config{}, Config{Service: testGAEService, ServiceVersion: testGAEVersion, ProjectID: testGCEProjectID, Zone: testZone, Instance: testInstance}, "", true, true, true, false, }, { "configured project ID has priority over metadata-provided project ID", Config{Service: testService, ProjectID: testProjectID}, Config{Service: testService, ProjectID: testProjectID, Zone: testZone, Instance: testInstance}, "", false, false, true, false, }, { "configured project ID has priority over environment project ID", Config{Service: testService, ProjectID: testProjectID}, Config{Service: testService, ProjectID: testProjectID}, "", false, false, false, true, }, { "requires project ID if not on GCE", Config{Service: testService}, Config{Service: testService}, "project ID must be specified in the configuration if running outside of GCP", false, false, false, false, }, { "configured zone has priority over metadata-provided zone", Config{Service: testService, ProjectID: testProjectID, Zone: testZone + "-override"}, Config{Service: testService, ProjectID: testProjectID, Zone: testZone + "-override", Instance: testInstance}, "", false, false, true, false, }, { "configured instance has priority over metadata-provided instance", Config{Service: testService, ProjectID: testProjectID, Instance: testInstance + "-override"}, Config{Service: testService, ProjectID: testProjectID, Zone: testZone, Instance: testInstance + "-override"}, "", false, false, true, false, }, } { t.Logf("Running test: %s", tt.desc) gaeEnvService, gaeEnvVersion := "", "" if tt.onGAE { gaeEnvService, gaeEnvVersion = testGAEService, testGAEVersion } if err := os.Setenv("GAE_SERVICE", gaeEnvService); err != nil { t.Fatal(err) } if err := os.Setenv("GAE_VERSION", gaeEnvVersion); err != nil { t.Fatal(err) } knEnvService, knEnvVersion := "", "" if tt.onKnative { knEnvService, knEnvVersion = testKnativeService, testKnativeVersion } if err := os.Setenv("K_SERVICE", knEnvService); err != nil { t.Fatal(err) } if err := os.Setenv("K_REVISION", knEnvVersion); err != nil { t.Fatal(err) } if tt.onGCE { onGCE = func() bool { return true } getProjectID = func() (string, error) { return testGCEProjectID, nil } getZone = func() (string, error) { return testZone, nil } getInstanceName = func() (string, error) { return testInstance, nil } } else { onGCE = func() bool { return false } getProjectID = func() (string, error) { return "", fmt.Errorf("test get project id error") } getZone = func() (string, error) { return "", fmt.Errorf("test get zone error") } getInstanceName = func() (string, error) { return "", fmt.Errorf("test get instance error") } } envProjectID := "" if tt.envProjectID { envProjectID = testEnvProjectID } if err := os.Setenv("GOOGLE_CLOUD_PROJECT", envProjectID); err != nil { t.Fatal(err) } errorString := "" if err := initializeConfig(tt.config); err != nil { errorString = err.Error() } if !strings.Contains(errorString, tt.wantErrorString) { t.Errorf("initializeConfig(%v) got error: %v, want contain %v", tt.config, errorString, tt.wantErrorString) } if tt.wantErrorString == "" { tt.wantConfig.APIAddr = apiAddress } if config != tt.wantConfig { t.Errorf("initializeConfig(%v) got: %v, want %v", tt.config, config, tt.wantConfig) } } for _, tt := range []struct { desc string wantErr bool getProjectIDError error getZoneError error getInstanceError error }{ { desc: "metadata returns error for project ID", wantErr: true, getProjectIDError: errors.New("fake get project ID error"), }, { desc: "metadata returns error for zone", wantErr: true, getZoneError: errors.New("fake get zone error"), }, { desc: "metadata returns error for instance", wantErr: true, getInstanceError: errors.New("fake get instance error"), }, { desc: "metadata returns NotDefinedError for instance", getInstanceError: gcemd.NotDefinedError("fake GCE metadata NotDefinedError error"), }, } { onGCE = func() bool { return true } getProjectID = func() (string, error) { return testGCEProjectID, tt.getProjectIDError } getZone = func() (string, error) { return testZone, tt.getZoneError } getInstanceName = func() (string, error) { return testInstance, tt.getInstanceError } if err := initializeConfig(Config{Service: testService}); (err != nil) != tt.wantErr { t.Errorf("%s: initializeConfig() got error: %v, want error %t", tt.desc, err, tt.wantErr) } } } type fakeProfilerServer struct { count int gotProfiles map[string][]byte done chan bool } func (fs *fakeProfilerServer) CreateProfile(ctx context.Context, in *pb.CreateProfileRequest) (*pb.Profile, error) { fs.count++ switch fs.count { case 1: return &pb.Profile{Name: "testCPU", ProfileType: pb.ProfileType_CPU, Duration: ptypes.DurationProto(testProfileDuration)}, nil case 2: return &pb.Profile{Name: "testHeap", ProfileType: pb.ProfileType_HEAP}, nil default: select {} } } func (fs *fakeProfilerServer) UpdateProfile(ctx context.Context, in *pb.UpdateProfileRequest) (*pb.Profile, error) { switch in.Profile.ProfileType { case pb.ProfileType_CPU: fs.gotProfiles["CPU"] = in.Profile.ProfileBytes case pb.ProfileType_HEAP: fs.gotProfiles["HEAP"] = in.Profile.ProfileBytes fs.done <- true } return in.Profile, nil } func (fs *fakeProfilerServer) CreateOfflineProfile(_ context.Context, _ *pb.CreateOfflineProfileRequest) (*pb.Profile, error) { return nil, status.Error(codes.Unimplemented, "") } func profileeLoop(quit chan bool) { for { select { case <-quit: return default: profileeWork() } } } func profileeWork() { data := make([]byte, 10*1024*1024) rand.Read(data) var b bytes.Buffer gz := gzip.NewWriter(&b) if _, err := gz.Write(data); err != nil { log.Println("failed to write to gzip stream", err) return } if err := gz.Flush(); err != nil { log.Println("failed to flush to gzip stream", err) return } if err := gz.Close(); err != nil { log.Println("failed to close gzip stream", err) } } func validateProfile(rawData []byte, wantFunctionName string) error { p, err := profile.ParseData(rawData) if err != nil { return fmt.Errorf("ParseData failed: %v", err) } if len(p.Sample) == 0 { return fmt.Errorf("profile contains zero samples: %v", p) } if len(p.Location) == 0 { return fmt.Errorf("profile contains zero locations: %v", p) } if len(p.Function) == 0 { return fmt.Errorf("profile contains zero functions: %v", p) } for _, l := range p.Location { if len(l.Line) > 0 && l.Line[0].Function != nil && strings.Contains(l.Line[0].Function.Name, wantFunctionName) { return nil } } return fmt.Errorf("wanted function name %s not found in the profile", wantFunctionName) } func TestDeltaMutexProfile(t *testing.T) { oldMutexEnabled, oldMaxProcs := mutexEnabled, runtime.GOMAXPROCS(10) defer func() { mutexEnabled = oldMutexEnabled runtime.GOMAXPROCS(oldMaxProcs) }() if mutexEnabled = enableMutexProfiling(); !mutexEnabled { t.Skip("Go too old - mutex profiling not supported.") } hog(time.Second, mutexHog) go func() { hog(2*time.Second, backgroundHog) }() var prof bytes.Buffer if err := deltaMutexProfile(context.Background(), time.Second, &prof); err != nil { t.Fatalf("deltaMutexProfile() got error: %v", err) } p, err := profile.Parse(&prof) if err != nil { t.Fatalf("profile.Parse() got error: %v", err) } if s := sum(p, "mutexHog"); s != 0 { t.Errorf("mutexHog found in the delta mutex profile (sum=%d):\n%s", s, p) } if s := sum(p, "backgroundHog"); s <= 0 { t.Errorf("backgroundHog not in the delta mutex profile (sum=%d):\n%s", s, p) } } // sum returns the sum of all mutex counts from the samples whose // stacks include the specified function name. func sum(p *profile.Profile, fname string) int64 { locIDs := map[*profile.Location]bool{} for _, loc := range p.Location { for _, l := range loc.Line { if strings.Contains(l.Function.Name, fname) { locIDs[loc] = true break } } } var s int64 for _, sample := range p.Sample { for _, loc := range sample.Location { if locIDs[loc] { s += sample.Value[0] break } } } return s } func mutexHog(mu1, mu2 *sync.Mutex, start time.Time, dt time.Duration) { for time.Since(start) < dt { mu1.Lock() runtime.Gosched() mu2.Lock() mu1.Unlock() mu2.Unlock() } } // backgroundHog is identical to mutexHog. We keep them separate // in order to distinguish them with function names in the stack trace. func backgroundHog(mu1, mu2 *sync.Mutex, start time.Time, dt time.Duration) { for time.Since(start) < dt { mu1.Lock() runtime.Gosched() mu2.Lock() mu1.Unlock() mu2.Unlock() } } func hog(dt time.Duration, hogger func(mu1, mu2 *sync.Mutex, start time.Time, dt time.Duration)) { start := time.Now() mu1 := new(sync.Mutex) mu2 := new(sync.Mutex) var wg sync.WaitGroup wg.Add(10) for i := 0; i < 10; i++ { go func() { defer wg.Done() hogger(mu1, mu2, start, dt) }() } wg.Wait() } func TestAgentWithServer(t *testing.T) { oldDialGRPC, oldConfig := dialGRPC, config defer func() { dialGRPC, config = oldDialGRPC, oldConfig }() srv, err := testutil.NewServer() if err != nil { t.Fatalf("testutil.NewServer(): %v", err) } fakeServer := &fakeProfilerServer{gotProfiles: map[string][]byte{}, done: make(chan bool)} pb.RegisterProfilerServiceServer(srv.Gsrv, fakeServer) srv.Start() dialGRPC = gtransport.DialInsecure if err := Start(Config{ Service: testService, ProjectID: testProjectID, APIAddr: srv.Addr, Instance: testInstance, Zone: testZone, }); err != nil { t.Fatalf("Start(): %v", err) } quitProfilee := make(chan bool) go profileeLoop(quitProfilee) select { case <-fakeServer.done: case <-time.After(testServerTimeout): t.Errorf("got timeout after %v, want fake server done", testServerTimeout) } quitProfilee <- true for _, pType := range []string{"CPU", "HEAP"} { if profile, ok := fakeServer.gotProfiles[pType]; !ok { t.Errorf("fakeServer.gotProfiles[%s] got no profile, want profile", pType) } else if err := validateProfile(profile, "profilee"); err != nil { t.Errorf("validateProfile(%s) got error: %v", pType, err) } } } google-cloud-go-0.49.0/profiler/proftest/000077500000000000000000000000001356504100700202605ustar00rootroot00000000000000google-cloud-go-0.49.0/profiler/proftest/proftest.go000066400000000000000000000365341356504100700224700ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // Package proftest contains test helpers for profiler agent integration tests. // This package is experimental. package proftest import ( "bytes" "context" "encoding/json" "errors" "fmt" "io/ioutil" "log" "net/http" "strings" "text/template" "time" "cloud.google.com/go/storage" gax "github.com/googleapis/gax-go/v2" compute "google.golang.org/api/compute/v1" container "google.golang.org/api/container/v1" "google.golang.org/api/googleapi" ) const ( monitorWriteScope = "https://www.googleapis.com/auth/monitoring.write" ) // BaseStartupTmpl is the common part of the startup script that // can be shared by multiple tests. var BaseStartupTmpl = template.Must(template.New("startupScript").Parse(` {{ define "prologue" -}} #! /bin/bash ( # Signal any unexpected error. trap 'echo "{{.ErrorString}}"' ERR # Shut down the VM in 5 minutes after this script exits # to stop accounting the VM for billing and cores quota. trap "sleep 300 && poweroff" EXIT retry() { for i in {1..3}; do "${@}" && return 0 done return 1 } # Fail on any error. set -eo pipefail # Display commands being run set -x {{- end }} {{ define "epilogue" -}} # Write output to serial port 2 with timestamp. ) 2>&1 | while read line; do echo "$(date): ${line}"; done >/dev/ttyS1 {{- end }} `)) // TestRunner has common elements used for testing profiling agents on a range // of environments. type TestRunner struct { Client *http.Client } // GCETestRunner supports testing a profiling agent on GCE. type GCETestRunner struct { TestRunner ComputeService *compute.Service } // GKETestRunner supports testing a profiling agent on GKE. type GKETestRunner struct { TestRunner ContainerService *container.Service StorageClient *storage.Client Dockerfile string } // ProfileResponse contains the response produced when querying profile server. type ProfileResponse struct { Profile ProfileData `json:"profile"` NumProfiles int32 `json:"numProfiles"` Deployments []interface{} `json:"deployments"` } // ProfileData has data of a single profile. type ProfileData struct { Samples []int32 `json:"samples"` SampleMetrics interface{} `json:"sampleMetrics"` DefaultMetricType string `json:"defaultMetricType"` TreeNodes interface{} `json:"treeNodes"` Functions functionArray `json:"functions"` SourceFiles sourceFileArray `json:"sourceFiles"` } type functionArray struct { Name []string `json:"name"` Sourcefile []int32 `json:"sourceFile"` } type sourceFileArray struct { Name []string `json:"name"` } // InstanceConfig is configuration for starting single GCE instance for // profiling agent test case. type InstanceConfig struct { ProjectID string Zone string Name string StartupScript string MachineType string ImageProject string ImageFamily string Scopes []string } // ClusterConfig is configuration for starting single GKE cluster for profiling // agent test case. type ClusterConfig struct { ProjectID string Zone string ClusterName string PodName string ImageSourceName string ImageName string Bucket string Dockerfile string } // queryProfileRequest is the request format for querying the profile server. type queryProfileRequest struct { StartTime string `json:"startTime"` EndTime string `json:"endTime"` ProfileType string `json:"profileType"` Target string `json:"target"` DeploymentLabels map[string]string `json:"deploymentLabels,omitempty"` } // CheckNonEmpty returns nil if the profile has a profiles and deployments // associated. Otherwise, returns a desciptive error. func (pr *ProfileResponse) CheckNonEmpty() error { if pr.NumProfiles == 0 { return fmt.Errorf("profile response contains zero profiles: %v", pr) } if len(pr.Deployments) == 0 { return fmt.Errorf("profile response contains zero deployments: %v", pr) } return nil } // HasFunction returns nil if the function is present, or, if the function is // not present, and error providing more details why the function is not // present. func (pr *ProfileResponse) HasFunction(functionName string) error { if err := pr.CheckNonEmpty(); err != nil { return fmt.Errorf("failed to find function name %s in profile: %v", functionName, err) } for _, name := range pr.Profile.Functions.Name { if strings.Contains(name, functionName) { return nil } } return fmt.Errorf("failed to find function name %s in profile", functionName) } // HasFunctionInFile returns nil if function is present in the specifed file, and an // error if the function/file combination is not present in the profile. func (pr *ProfileResponse) HasFunctionInFile(functionName string, filename string) error { if err := pr.CheckNonEmpty(); err != nil { return fmt.Errorf("failed to find function name %s in file %s in profile: %v", functionName, filename, err) } for i, name := range pr.Profile.Functions.Name { file := pr.Profile.SourceFiles.Name[pr.Profile.Functions.Sourcefile[i]] if strings.Contains(name, functionName) && strings.HasSuffix(file, filename) { return nil } } return fmt.Errorf("failed to find function name %s in file %s in profile", functionName, filename) } // HasSourceFile returns nil if the file (or file where the end of the file path // matches the filename) is present in the profile. Or, if the filename is not // present, an error is returned. func (pr *ProfileResponse) HasSourceFile(filename string) error { if err := pr.CheckNonEmpty(); err != nil { return fmt.Errorf("failed to find filename %s in profile: %v", filename, err) } for _, name := range pr.Profile.SourceFiles.Name { if strings.HasSuffix(name, filename) { return nil } } return fmt.Errorf("failed to find filename %s in profile", filename) } // StartInstance starts a GCE Instance with configs specified by inst, // and which runs the startup script specified in inst. If image project // is not specified, it defaults to "debian-cloud". If image family is // not specified, it defaults to "debian-9". func (tr *GCETestRunner) StartInstance(ctx context.Context, inst *InstanceConfig) error { imageProject, imageFamily := inst.ImageProject, inst.ImageFamily if imageProject == "" { imageProject = "debian-cloud" } if imageFamily == "" { imageFamily = "debian-9" } img, err := tr.ComputeService.Images.GetFromFamily(imageProject, imageFamily).Context(ctx).Do() if err != nil { return fmt.Errorf("failed to get image from family %q in project %q: %v", imageFamily, imageProject, err) } op, err := tr.ComputeService.Instances.Insert(inst.ProjectID, inst.Zone, &compute.Instance{ MachineType: fmt.Sprintf("zones/%s/machineTypes/%s", inst.Zone, inst.MachineType), Name: inst.Name, Disks: []*compute.AttachedDisk{{ AutoDelete: true, // delete the disk when the VM is deleted. Boot: true, Type: "PERSISTENT", Mode: "READ_WRITE", InitializeParams: &compute.AttachedDiskInitializeParams{ SourceImage: img.SelfLink, DiskType: fmt.Sprintf("https://www.googleapis.com/compute/v1/projects/%s/zones/%s/diskTypes/pd-standard", inst.ProjectID, inst.Zone), }, }}, NetworkInterfaces: []*compute.NetworkInterface{{ Network: fmt.Sprintf("https://www.googleapis.com/compute/v1/projects/%s/global/networks/default", inst.ProjectID), AccessConfigs: []*compute.AccessConfig{{ Name: "External NAT", }}, }}, Metadata: &compute.Metadata{ Items: []*compute.MetadataItems{{ Key: "startup-script", Value: googleapi.String(inst.StartupScript), }}, }, ServiceAccounts: []*compute.ServiceAccount{{ Email: "default", Scopes: append(inst.Scopes, monitorWriteScope), }}, }).Do() if err != nil { return fmt.Errorf("failed to create instance: %v", err) } // Poll status of the operation to create the instance. getOpCall := tr.ComputeService.ZoneOperations.Get(inst.ProjectID, inst.Zone, op.Name) for { if err := checkOpErrors(op); err != nil { return fmt.Errorf("failed to create instance: %v", err) } if op.Status == "DONE" { return nil } if err := gax.Sleep(ctx, 5*time.Second); err != nil { return err } op, err = getOpCall.Do() if err != nil { return fmt.Errorf("failed to get operation: %v", err) } } } // checkOpErrors returns nil if the operation does not have any errors and an // error summarizing all errors encountered if the operation has errored. func checkOpErrors(op *compute.Operation) error { if op.Error == nil || len(op.Error.Errors) == 0 { return nil } var errs []string for _, e := range op.Error.Errors { if e.Message != "" { errs = append(errs, e.Message) } else { errs = append(errs, e.Code) } } return errors.New(strings.Join(errs, ",")) } // DeleteInstance deletes an instance with project id, name, and zone matched // by inst. func (tr *GCETestRunner) DeleteInstance(ctx context.Context, inst *InstanceConfig) error { if _, err := tr.ComputeService.Instances.Delete(inst.ProjectID, inst.Zone, inst.Name).Context(ctx).Do(); err != nil { return fmt.Errorf("Instances.Delete(%s) got error: %v", inst.Name, err) } return nil } // PollForSerialOutput polls serial port 2 of the GCE instance specified by // inst and returns when the finishString appears in the serial output // of the instance, or when the context times out. func (tr *GCETestRunner) PollForSerialOutput(ctx context.Context, inst *InstanceConfig, finishString, errorString string) error { var output string defer func() { log.Printf("Serial port output for %s:\n%s", inst.Name, output) }() for { select { case <-ctx.Done(): return ctx.Err() case <-time.After(20 * time.Second): resp, err := tr.ComputeService.Instances.GetSerialPortOutput(inst.ProjectID, inst.Zone, inst.Name).Port(2).Context(ctx).Do() if err != nil { // Transient failure. log.Printf("Transient error getting serial port output from instance %s (will retry): %v", inst.Name, err) continue } if resp.Contents == "" { log.Printf("Ignoring empty serial port output from instance %s (will retry)", inst.Name) continue } if output = resp.Contents; strings.Contains(output, finishString) { return nil } if strings.Contains(output, errorString) { return fmt.Errorf("failed to execute the prober benchmark script") } } } } // QueryProfiles retrieves profiles of a specific type, from a specific time // range, associated with a particular service and project. func (tr *TestRunner) QueryProfiles(projectID, service, startTime, endTime, profileType string) (ProfileResponse, error) { return tr.QueryProfilesWithZone(projectID, service, startTime, endTime, profileType, "") } // QueryProfilesWithZone retrieves profiles of a specific type, from a specific // time range, in a specified zone, associated with a particular service // and project. func (tr *TestRunner) QueryProfilesWithZone(projectID, service, startTime, endTime, profileType, zone string) (ProfileResponse, error) { queryURL := fmt.Sprintf("https://cloudprofiler.googleapis.com/v2/projects/%s/profiles:query", projectID) deploymentLabels := map[string]string{} if zone != "" { deploymentLabels["zone"] = zone } qpr := queryProfileRequest{ StartTime: startTime, EndTime: endTime, ProfileType: profileType, Target: service, DeploymentLabels: deploymentLabels, } queryJSON, err := json.Marshal(qpr) if err != nil { return ProfileResponse{}, fmt.Errorf("failed to marshall request to JSON: %v", err) } req, err := http.NewRequest("POST", queryURL, bytes.NewReader(queryJSON)) if err != nil { return ProfileResponse{}, fmt.Errorf("failed to create an API request: %v", err) } req.Header = map[string][]string{ "X-Goog-User-Project": {projectID}, } resp, err := tr.Client.Do(req) if err != nil { return ProfileResponse{}, fmt.Errorf("failed to query API: %v", err) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return ProfileResponse{}, fmt.Errorf("failed to read response body: %v", err) } if resp.StatusCode != 200 { return ProfileResponse{}, fmt.Errorf("failed to query API: status: %s, response body: %s", resp.Status, string(body)) } var pr ProfileResponse if err := json.Unmarshal(body, &pr); err != nil { return ProfileResponse{}, err } return pr, nil } type imageResponse struct { Manifest map[string]interface{} `json:"manifest"` Name string `json:"name"` Tags []string `json:"tags"` } // deleteDockerImage deletes a docker image from Google Container Registry. func (tr *GKETestRunner) deleteDockerImage(ctx context.Context, ImageName string) []error { queryImageURL := fmt.Sprintf("https://gcr.io/v2/%s/tags/list", ImageName) resp, err := tr.Client.Get(queryImageURL) if err != nil { return []error{fmt.Errorf("failed to list tags: %v", err)} } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return []error{err} } var ir imageResponse if err := json.Unmarshal(body, &ir); err != nil { return []error{err} } const deleteImageURLFmt = "https://gcr.io/v2/%s/manifests/%s" var errs []error for _, tag := range ir.Tags { if err := deleteDockerImageResource(tr.Client, fmt.Sprintf(deleteImageURLFmt, ImageName, tag)); err != nil { errs = append(errs, fmt.Errorf("failed to delete tag %s: %v", tag, err)) } } for manifest := range ir.Manifest { if err := deleteDockerImageResource(tr.Client, fmt.Sprintf(deleteImageURLFmt, ImageName, manifest)); err != nil { errs = append(errs, fmt.Errorf("failed to delete manifest %s: %v", manifest, err)) } } return errs } func deleteDockerImageResource(client *http.Client, url string) error { req, err := http.NewRequest("DELETE", url, nil) if err != nil { return fmt.Errorf("failed to get request: %v", err) } resp, err := client.Do(req) if err != nil { return fmt.Errorf("failed to delete resource: %v", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusAccepted { return fmt.Errorf("failed to delete resource: status code = %d", resp.StatusCode) } return nil } // DeleteClusterAndImage deletes cluster and images used to create cluster. func (tr *GKETestRunner) DeleteClusterAndImage(ctx context.Context, cfg *ClusterConfig) []error { var errs []error if err := tr.StorageClient.Bucket(cfg.Bucket).Object(cfg.ImageSourceName).Delete(ctx); err != nil { errs = append(errs, fmt.Errorf("failed to delete storage client: %v", err)) } for _, err := range tr.deleteDockerImage(ctx, cfg.ImageName) { errs = append(errs, fmt.Errorf("failed to delete docker image: %v", err)) } if _, err := tr.ContainerService.Projects.Zones.Clusters.Delete(cfg.ProjectID, cfg.Zone, cfg.ClusterName).Context(ctx).Do(); err != nil { errs = append(errs, fmt.Errorf("failed to delete cluster %s: %v", cfg.ClusterName, err)) } return errs } google-cloud-go-0.49.0/profiler/symbolizer.go000066400000000000000000000071341356504100700211450ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package profiler import ( "bytes" "regexp" "runtime" "strings" "github.com/google/pprof/profile" ) var shouldAssumeSymbolized = isSymbolizedGoVersion(runtime.Version()) type function interface { Name() string FileLine(pc uintptr) (string, int) } // funcForPC is a wrapper for runtime.FuncForPC. Defined as var for testing. var funcForPC = func(pc uintptr) function { return runtime.FuncForPC(pc) } // parseAndSymbolize parses a profile from a buffer, symbolizes it // if it's not yet symbolized, and writes the profile back as a // gzip-compressed marshaled protobuf. func parseAndSymbolize(data *bytes.Buffer) error { p, err := profile.ParseData(data.Bytes()) if err != nil { return err } // Do nothing if the profile is already symbolized. if symbolized(p) { return nil } // Clear the profile functions to avoid creating duplicates. p.Function = nil symbolize(p) data.Reset() return p.Write(data) } // isSymbolizedGoVersion returns true if Go version equals to or is // higher than Go 1.9. Starting Go 1.9 the profiles are symbolized // by runtime/pprof. func isSymbolizedGoVersion(goVersion string) bool { r, err := regexp.Compile(`go(1\.9|1\.[1-9][0-9]|[2-9]).*`) if err == nil && r.MatchString(goVersion) { return true } return false } // symbolized checks if all locations have symbolized function // information. func symbolized(p *profile.Profile) bool { for _, l := range p.Location { if len(l.Line) == 0 || l.Line[0].Function == nil { return false } } return true } func symbolize(p *profile.Profile) { fns := profileFunctionMap{} for _, l := range p.Location { pc := uintptr(l.Address) f := funcForPC(pc) if f == nil { continue } file, lineno := f.FileLine(pc) l.Line = []profile.Line{ { Function: fns.findOrAddFunction(f.Name(), file, p), Line: int64(lineno), }, } } // Trim runtime functions. Always hide runtime.goexit. Other runtime // functions are only hidden for heap profile when they appear at the beginning. isHeapProfile := p.PeriodType != nil && p.PeriodType.Type == "space" for _, s := range p.Sample { show := !isHeapProfile var i int for _, l := range s.Location { if len(l.Line) > 0 && l.Line[0].Function != nil { name := l.Line[0].Function.Name if name == "runtime.goexit" || !show && strings.HasPrefix(name, "runtime.") { continue } } show = true s.Location[i] = l i++ } // If all locations of a sample are trimmed, keep the root location. if i == 0 && len(s.Location) > 0 { s.Location[0] = s.Location[len(s.Location)-1] i = 1 } s.Location = s.Location[:i] } } type profileFunctionMap map[profile.Function]*profile.Function func (fns profileFunctionMap) findOrAddFunction(name, filename string, p *profile.Profile) *profile.Function { f := profile.Function{ Name: name, SystemName: name, Filename: filename, } if fp := fns[f]; fp != nil { return fp } fp := new(profile.Function) fns[f] = fp *fp = f fp.ID = uint64(len(p.Function) + 1) p.Function = append(p.Function, fp) return fp } google-cloud-go-0.49.0/profiler/symbolizer_test.go000066400000000000000000000171631356504100700222070ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package profiler import ( "bytes" "testing" "cloud.google.com/go/internal/testutil" "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/pprof/profile" ) type fakeFunc struct { name string file string lineno int } func (f *fakeFunc) Name() string { return f.name } func (f *fakeFunc) FileLine(_ uintptr) (string, int) { return f.file, f.lineno } var cmpOpt = cmpopts.IgnoreUnexported(profile.Profile{}, profile.Function{}, profile.Line{}, profile.Location{}, profile.Sample{}, profile.ValueType{}) // TestRuntimeFunctionTrimming tests if symbolize trims runtime functions as intended. func TestRuntimeFunctionTrimming(t *testing.T) { fakeFuncMap := map[uintptr]*fakeFunc{ 0x10: {"runtime.goexit", "runtime.go", 10}, 0x20: {"runtime.other", "runtime.go", 20}, 0x30: {"foo", "foo.go", 30}, 0x40: {"bar", "bar.go", 40}, } backupFuncForPC := funcForPC funcForPC = func(pc uintptr) function { return fakeFuncMap[pc] } defer func() { funcForPC = backupFuncForPC }() testLoc := []*profile.Location{ {ID: 1, Address: 0x10}, {ID: 2, Address: 0x20}, {ID: 3, Address: 0x30}, {ID: 4, Address: 0x40}, } testProfile := &profile.Profile{ Sample: []*profile.Sample{ {Location: []*profile.Location{testLoc[0], testLoc[1], testLoc[3], testLoc[2]}}, {Location: []*profile.Location{testLoc[1], testLoc[3], testLoc[2]}}, {Location: []*profile.Location{testLoc[3], testLoc[2], testLoc[1]}}, {Location: []*profile.Location{testLoc[3], testLoc[2], testLoc[0]}}, {Location: []*profile.Location{testLoc[0], testLoc[1], testLoc[3], testLoc[0]}}, {Location: []*profile.Location{testLoc[1], testLoc[0]}}, }, Location: testLoc, } testProfiles := make([]*profile.Profile, 2) testProfiles[0] = testProfile.Copy() testProfiles[1] = testProfile.Copy() // Test case for CPU profile. testProfiles[0].PeriodType = &profile.ValueType{Type: "cpu", Unit: "nanoseconds"} // Test case for heap profile. testProfiles[1].PeriodType = &profile.ValueType{Type: "space", Unit: "bytes"} wantFunc := []*profile.Function{ {ID: 1, Name: "runtime.goexit", SystemName: "runtime.goexit", Filename: "runtime.go"}, {ID: 2, Name: "runtime.other", SystemName: "runtime.other", Filename: "runtime.go"}, {ID: 3, Name: "foo", SystemName: "foo", Filename: "foo.go"}, {ID: 4, Name: "bar", SystemName: "bar", Filename: "bar.go"}, } wantLoc := []*profile.Location{ {ID: 1, Address: 0x10, Line: []profile.Line{{Function: wantFunc[0], Line: 10}}}, {ID: 2, Address: 0x20, Line: []profile.Line{{Function: wantFunc[1], Line: 20}}}, {ID: 3, Address: 0x30, Line: []profile.Line{{Function: wantFunc[2], Line: 30}}}, {ID: 4, Address: 0x40, Line: []profile.Line{{Function: wantFunc[3], Line: 40}}}, } wantProfiles := []*profile.Profile{ { PeriodType: &profile.ValueType{Type: "cpu", Unit: "nanoseconds"}, Sample: []*profile.Sample{ {Location: []*profile.Location{wantLoc[1], wantLoc[3], wantLoc[2]}}, {Location: []*profile.Location{wantLoc[1], wantLoc[3], wantLoc[2]}}, {Location: []*profile.Location{wantLoc[3], wantLoc[2], wantLoc[1]}}, {Location: []*profile.Location{wantLoc[3], wantLoc[2]}}, {Location: []*profile.Location{wantLoc[1], wantLoc[3]}}, {Location: []*profile.Location{wantLoc[1]}}, }, Location: wantLoc, Function: wantFunc, }, { PeriodType: &profile.ValueType{Type: "space", Unit: "bytes"}, Sample: []*profile.Sample{ {Location: []*profile.Location{wantLoc[3], wantLoc[2]}}, {Location: []*profile.Location{wantLoc[3], wantLoc[2]}}, {Location: []*profile.Location{wantLoc[3], wantLoc[2], wantLoc[1]}}, {Location: []*profile.Location{wantLoc[3], wantLoc[2]}}, {Location: []*profile.Location{wantLoc[3]}}, {Location: []*profile.Location{wantLoc[0]}}, }, Location: wantLoc, Function: wantFunc, }, } for i := 0; i < 2; i++ { symbolize(testProfiles[i]) if !testutil.Equal(testProfiles[i], wantProfiles[i], cmpOpt) { t.Errorf("incorrect trimming (testcase = %d): got {%v}, want {%v}", i, testProfiles[i], wantProfiles[i]) } } } // TestParseAndSymbolize tests if parseAndSymbolize parses and symbolizes // profiles as intended. func TestParseAndSymbolize(t *testing.T) { fakeFuncMap := map[uintptr]*fakeFunc{ 0x10: {"foo", "foo.go", 10}, 0x20: {"bar", "bar.go", 20}, } backupFuncForPC := funcForPC funcForPC = func(pc uintptr) function { return fakeFuncMap[pc] } defer func() { funcForPC = backupFuncForPC }() testLoc := []*profile.Location{ {ID: 1, Address: 0x10}, {ID: 2, Address: 0x20}, } testProfile := &profile.Profile{ SampleType: []*profile.ValueType{ {Type: "cpu", Unit: "nanoseconds"}, }, PeriodType: &profile.ValueType{Type: "cpu", Unit: "nanoseconds"}, Sample: []*profile.Sample{ {Location: []*profile.Location{testLoc[0], testLoc[1]}, Value: []int64{1}}, {Location: []*profile.Location{testLoc[1]}, Value: []int64{1}}, }, Location: testLoc, } testProfiles := make([]*profile.Profile, 2) testProfiles[0] = testProfile.Copy() testProfiles[1] = testProfile.Copy() wantFunc := []*profile.Function{ {ID: 1, Name: "foo", SystemName: "foo", Filename: "foo.go"}, {ID: 2, Name: "bar", SystemName: "bar", Filename: "bar.go"}, } wantLoc := []*profile.Location{ {ID: 1, Address: 0x10, Line: []profile.Line{{Function: wantFunc[0], Line: 10}}}, {ID: 2, Address: 0x20, Line: []profile.Line{{Function: wantFunc[1], Line: 20}}}, } wantProfile := &profile.Profile{ SampleType: []*profile.ValueType{ {Type: "cpu", Unit: "nanoseconds"}, }, PeriodType: &profile.ValueType{Type: "cpu", Unit: "nanoseconds"}, Sample: []*profile.Sample{ {Location: []*profile.Location{wantLoc[0], wantLoc[1]}, Value: []int64{1}}, {Location: []*profile.Location{wantLoc[1]}, Value: []int64{1}}, }, Location: wantLoc, Function: wantFunc, } // Profile already symbolized. testProfiles[1].Location = []*profile.Location{ {ID: 1, Address: 0x10, Line: []profile.Line{{Function: wantFunc[0], Line: 10}}}, {ID: 2, Address: 0x20, Line: []profile.Line{{Function: wantFunc[1], Line: 20}}}, } testProfiles[1].Function = []*profile.Function{ {ID: 1, Name: "foo", SystemName: "foo", Filename: "foo.go"}, {ID: 2, Name: "bar", SystemName: "bar", Filename: "bar.go"}, } for i := 0; i < 2; i++ { var prof bytes.Buffer testProfiles[i].Write(&prof) parseAndSymbolize(&prof) gotProfile, err := profile.ParseData(prof.Bytes()) if err != nil { t.Errorf("parsing symbolized profile (testcase = %d) got err: %v, want no error", i, err) } if !testutil.Equal(gotProfile, wantProfile, cmpOpt) { t.Errorf("incorrect symbolization (testcase = %d): got {%v}, want {%v}", i, gotProfile, wantProfile) } } } func TestIsSymbolizedGoVersion(t *testing.T) { for _, tc := range []struct { input string want bool }{ {"go1.9beta2", true}, {"go1.9", true}, {"go1.9.1", true}, {"go1.10", true}, {"go1.10.1", true}, {"go2.0", true}, {"go3.1", true}, {"go1.8", false}, {"go1.8.1", false}, {"go1.7", false}, {"devel ", false}, } { if got := isSymbolizedGoVersion(tc.input); got != tc.want { t.Errorf("isSymbolizedGoVersion(%v) got %v, want %v", tc.input, got, tc.want) } } } google-cloud-go-0.49.0/profiler/testdata/000077500000000000000000000000001356504100700202235ustar00rootroot00000000000000google-cloud-go-0.49.0/profiler/testdata/testdata.go000066400000000000000000000067711356504100700223760ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package testdata provides some useful data sets for testing purposes. package testdata import ( "github.com/google/pprof/profile" ) var functions = []*profile.Function{ {ID: 1, Name: "main", SystemName: "main", Filename: "main.go"}, {ID: 2, Name: "foo", SystemName: "foo", Filename: "foo.go"}, {ID: 3, Name: "foo_caller", SystemName: "foo_caller", Filename: "foo.go"}, } const mainBinary = "/bin/main" var mappings = []*profile.Mapping{ { ID: 1, Start: 0x10000, Limit: 0x40000, File: mainBinary, HasFunctions: true, HasFilenames: true, HasLineNumbers: true, HasInlineFrames: true, }, { ID: 2, Start: 0x1000, Limit: 0x4000, File: "/lib/lib.so", HasFunctions: true, HasFilenames: true, HasLineNumbers: true, HasInlineFrames: true, }, } var locations = []*profile.Location{ { ID: 1, Mapping: mappings[1], Address: 0x1000, Line: []profile.Line{ {Function: functions[0], Line: 1}, }, }, { ID: 2, Mapping: mappings[0], Address: 0x2000, Line: []profile.Line{ {Function: functions[1], Line: 2}, {Function: functions[2], Line: 1}, }, }, } // HeapProfileCollected1 represents a heap profile which could be collected using // pprof.WriteHeapProfile(). var HeapProfileCollected1 = &profile.Profile{ DurationNanos: 10e9, SampleType: []*profile.ValueType{ {Type: "alloc_objects", Unit: "count"}, {Type: "alloc_space", Unit: "bytes"}, {Type: "inuse_objects", Unit: "count"}, {Type: "inuse_space", Unit: "bytes"}, }, Sample: []*profile.Sample{{ Location: []*profile.Location{locations[0], locations[1]}, Value: []int64{10, 160, 10, 160}, NumLabel: map[string][]int64{ "bytes": {16}, }, NumUnit: map[string][]string{ "bytes": {"bytes"}, }, }}, Location: locations, Function: functions, Mapping: mappings, } // HeapProfileUploaded represents the heap profile bytes we would expect to // be uploaded if HeapProfileCollected1 were returned when profiling. var HeapProfileUploaded = func() *profile.Profile { p := HeapProfileCollected1.Copy() p.Sample[0].Value = []int64{0, 0, 10, 160} return p }() // HeapProfileCollected2 represents a heap profile which could be collected using // pprof.WriteHeapProfile(). var HeapProfileCollected2 = func() *profile.Profile { p := HeapProfileCollected1.Copy() p.Sample[0].Value = []int64{11, 176, 11, 176} return p }() // AllocProfileUploaded represents the allocation profile bytes we would expect // to be uploaded if HeapProfileCollected1 was returned when first profiling // and HeapProfileCollect2 was return when profiling the second time. var AllocProfileUploaded = func() *profile.Profile { p := HeapProfileCollected1.Copy() p.DurationNanos = 5e9 p.SampleType = []*profile.ValueType{ {Type: "alloc_objects", Unit: "count"}, {Type: "alloc_space", Unit: "bytes"}, } p.Sample[0].Value = []int64{1, 16} return p }() google-cloud-go-0.49.0/pubsub/000077500000000000000000000000001356504100700160705ustar00rootroot00000000000000google-cloud-go-0.49.0/pubsub/.repo-metadata.json000066400000000000000000000006201356504100700215620ustar00rootroot00000000000000{ "name": "pubsub", "name_pretty": "Cloud Pub/Sub API", "product_documentation": "https://cloud.google.com/pubsub", "client_documentation": "https://godoc.org/cloud.google.com/go/pubsub", "release_level": "ga", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go/pubsub", "api_id": "pubsub.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/pubsub/CHANGES.md000066400000000000000000000007271356504100700174700ustar00rootroot00000000000000# Changes ## v1.1.0 - Limit default grpc connections to 4. - Fix issues with OpenCensus metric for pull count not including synchronous pull messages. - Fix issue with publish bundle size calculations. - Add ClearMessages method to pstest server. ## v1.0.1 Small fix to a package name. ## v1.0.0 This is the first tag to carve out pubsub as its own module. See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository. google-cloud-go-0.49.0/pubsub/README.md000066400000000000000000000024061356504100700173510ustar00rootroot00000000000000## Cloud Pub/Sub [![GoDoc](https://godoc.org/cloud.google.com/go/pubsub?status.svg)](https://godoc.org/cloud.google.com/go/pubsub) - [About Cloud Pubsub](https://cloud.google.com/pubsub/) - [API documentation](https://cloud.google.com/pubsub/docs) - [Go client documentation](https://godoc.org/cloud.google.com/go/pubsub) - [Complete sample programs](https://github.com/GoogleCloudPlatform/golang-samples/tree/master/pubsub) ### Example Usage First create a `pubsub.Client` to use throughout your application: [snip]:# (pubsub-1) ```go client, err := pubsub.NewClient(ctx, "project-id") if err != nil { log.Fatal(err) } ``` Then use the client to publish and subscribe: [snip]:# (pubsub-2) ```go // Publish "hello world" on topic1. topic := client.Topic("topic1") res := topic.Publish(ctx, &pubsub.Message{ Data: []byte("hello world"), }) // The publish happens asynchronously. // Later, you can get the result from res: ... msgID, err := res.Get(ctx) if err != nil { log.Fatal(err) } // Use a callback to receive messages via subscription1. sub := client.Subscription("subscription1") err = sub.Receive(ctx, func(ctx context.Context, m *pubsub.Message) { fmt.Println(m.Data) m.Ack() // Acknowledge that we've consumed the message. }) if err != nil { log.Println(err) } ```google-cloud-go-0.49.0/pubsub/apiv1/000077500000000000000000000000001356504100700171105ustar00rootroot00000000000000google-cloud-go-0.49.0/pubsub/apiv1/.repo-metadata.json000066400000000000000000000006261356504100700226100ustar00rootroot00000000000000{ "name": "pubsub", "name_pretty": "Cloud Pub/Sub API", "product_documentation": "https://cloud.google.com/pubsub", "client_documentation": "https://godoc.org/cloud.google.com/go/pubsub/apiv1", "release_level": "ga", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go/pubsub", "api_id": "pubsub.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/pubsub/apiv1/ListTopics_smoke_test.go000066400000000000000000000032111356504100700237660ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package pubsub import ( "context" "fmt" "strconv" "testing" "time" "cloud.google.com/go/internal/testutil" "google.golang.org/api/iterator" "google.golang.org/api/option" pubsubpb "google.golang.org/genproto/googleapis/pubsub/v1" ) var _ = fmt.Sprintf var _ = iterator.Done var _ = strconv.FormatUint var _ = time.Now func TestPublisherSmoke(t *testing.T) { if testing.Short() { t.Skip("skipping smoke test in short mode") } ctx := context.Background() ts := testutil.TokenSource(ctx, DefaultAuthScopes()...) if ts == nil { t.Skip("Integration tests skipped. See CONTRIBUTING.md for details") } projectId := testutil.ProjID() _ = projectId c, err := NewPublisherClient(ctx, option.WithTokenSource(ts)) if err != nil { t.Fatal(err) } var formattedProject string = fmt.Sprintf("projects/%s", projectId) var request = &pubsubpb.ListTopicsRequest{ Project: formattedProject, } iter := c.ListTopics(ctx, request) if _, err := iter.Next(); err != nil && err != iterator.Done { t.Error(err) } } google-cloud-go-0.49.0/pubsub/apiv1/doc.go000066400000000000000000000054161356504100700202120ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package pubsub is an auto-generated package for the // Google Cloud Pub/Sub API. // // Provides reliable, many-to-many, asynchronous messaging between // applications. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. // // Use the client at cloud.google.com/go/pubsub in preference to this. package pubsub // import "cloud.google.com/go/pubsub/apiv1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/pubsub", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191115" google-cloud-go-0.49.0/pubsub/apiv1/iam.go000066400000000000000000000024151356504100700202070ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package pubsub import ( "cloud.google.com/go/iam" pubsubpb "google.golang.org/genproto/googleapis/pubsub/v1" ) func (c *PublisherClient) SubscriptionIAM(subscription *pubsubpb.Subscription) *iam.Handle { return iam.InternalNewHandle(c.Connection(), subscription.Name) } func (c *PublisherClient) TopicIAM(topic *pubsubpb.Topic) *iam.Handle { return iam.InternalNewHandle(c.Connection(), topic.Name) } func (c *SubscriberClient) SubscriptionIAM(subscription *pubsubpb.Subscription) *iam.Handle { return iam.InternalNewHandle(c.Connection(), subscription.Name) } func (c *SubscriberClient) TopicIAM(topic *pubsubpb.Topic) *iam.Handle { return iam.InternalNewHandle(c.Connection(), topic.Name) } google-cloud-go-0.49.0/pubsub/apiv1/mock_test.go000066400000000000000000001502301356504100700214300ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package pubsub import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" timestamppb "github.com/golang/protobuf/ptypes/timestamp" "google.golang.org/api/option" pubsubpb "google.golang.org/genproto/googleapis/pubsub/v1" field_maskpb "google.golang.org/genproto/protobuf/field_mask" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockPublisherServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. pubsubpb.PublisherServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockPublisherServer) CreateTopic(ctx context.Context, req *pubsubpb.Topic) (*pubsubpb.Topic, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*pubsubpb.Topic), nil } func (s *mockPublisherServer) UpdateTopic(ctx context.Context, req *pubsubpb.UpdateTopicRequest) (*pubsubpb.Topic, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*pubsubpb.Topic), nil } func (s *mockPublisherServer) Publish(ctx context.Context, req *pubsubpb.PublishRequest) (*pubsubpb.PublishResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*pubsubpb.PublishResponse), nil } func (s *mockPublisherServer) GetTopic(ctx context.Context, req *pubsubpb.GetTopicRequest) (*pubsubpb.Topic, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*pubsubpb.Topic), nil } func (s *mockPublisherServer) ListTopics(ctx context.Context, req *pubsubpb.ListTopicsRequest) (*pubsubpb.ListTopicsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*pubsubpb.ListTopicsResponse), nil } func (s *mockPublisherServer) ListTopicSubscriptions(ctx context.Context, req *pubsubpb.ListTopicSubscriptionsRequest) (*pubsubpb.ListTopicSubscriptionsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*pubsubpb.ListTopicSubscriptionsResponse), nil } func (s *mockPublisherServer) DeleteTopic(ctx context.Context, req *pubsubpb.DeleteTopicRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } type mockSubscriberServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. pubsubpb.SubscriberServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockSubscriberServer) CreateSubscription(ctx context.Context, req *pubsubpb.Subscription) (*pubsubpb.Subscription, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*pubsubpb.Subscription), nil } func (s *mockSubscriberServer) GetSubscription(ctx context.Context, req *pubsubpb.GetSubscriptionRequest) (*pubsubpb.Subscription, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*pubsubpb.Subscription), nil } func (s *mockSubscriberServer) UpdateSubscription(ctx context.Context, req *pubsubpb.UpdateSubscriptionRequest) (*pubsubpb.Subscription, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*pubsubpb.Subscription), nil } func (s *mockSubscriberServer) ListSubscriptions(ctx context.Context, req *pubsubpb.ListSubscriptionsRequest) (*pubsubpb.ListSubscriptionsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*pubsubpb.ListSubscriptionsResponse), nil } func (s *mockSubscriberServer) DeleteSubscription(ctx context.Context, req *pubsubpb.DeleteSubscriptionRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockSubscriberServer) ModifyAckDeadline(ctx context.Context, req *pubsubpb.ModifyAckDeadlineRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockSubscriberServer) Acknowledge(ctx context.Context, req *pubsubpb.AcknowledgeRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockSubscriberServer) Pull(ctx context.Context, req *pubsubpb.PullRequest) (*pubsubpb.PullResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*pubsubpb.PullResponse), nil } func (s *mockSubscriberServer) StreamingPull(stream pubsubpb.Subscriber_StreamingPullServer) error { md, _ := metadata.FromIncomingContext(stream.Context()) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } for { if req, err := stream.Recv(); err == io.EOF { break } else if err != nil { return err } else { s.reqs = append(s.reqs, req) } } if s.err != nil { return s.err } for _, v := range s.resps { if err := stream.Send(v.(*pubsubpb.StreamingPullResponse)); err != nil { return err } } return nil } func (s *mockSubscriberServer) ModifyPushConfig(ctx context.Context, req *pubsubpb.ModifyPushConfigRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockSubscriberServer) ListSnapshots(ctx context.Context, req *pubsubpb.ListSnapshotsRequest) (*pubsubpb.ListSnapshotsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*pubsubpb.ListSnapshotsResponse), nil } func (s *mockSubscriberServer) CreateSnapshot(ctx context.Context, req *pubsubpb.CreateSnapshotRequest) (*pubsubpb.Snapshot, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*pubsubpb.Snapshot), nil } func (s *mockSubscriberServer) UpdateSnapshot(ctx context.Context, req *pubsubpb.UpdateSnapshotRequest) (*pubsubpb.Snapshot, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*pubsubpb.Snapshot), nil } func (s *mockSubscriberServer) DeleteSnapshot(ctx context.Context, req *pubsubpb.DeleteSnapshotRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockSubscriberServer) Seek(ctx context.Context, req *pubsubpb.SeekRequest) (*pubsubpb.SeekResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*pubsubpb.SeekResponse), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockPublisher mockPublisherServer mockSubscriber mockSubscriberServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() pubsubpb.RegisterPublisherServer(serv, &mockPublisher) pubsubpb.RegisterSubscriberServer(serv, &mockSubscriber) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestPublisherCreateTopic(t *testing.T) { var name2 string = "name2-1052831874" var kmsKeyName string = "kmsKeyName2094986649" var expectedResponse = &pubsubpb.Topic{ Name: name2, KmsKeyName: kmsKeyName, } mockPublisher.err = nil mockPublisher.reqs = nil mockPublisher.resps = append(mockPublisher.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/topics/%s", "[PROJECT]", "[TOPIC]") var request = &pubsubpb.Topic{ Name: formattedName, } c, err := NewPublisherClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateTopic(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockPublisher.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestPublisherCreateTopicError(t *testing.T) { errCode := codes.PermissionDenied mockPublisher.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/topics/%s", "[PROJECT]", "[TOPIC]") var request = &pubsubpb.Topic{ Name: formattedName, } c, err := NewPublisherClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateTopic(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestPublisherUpdateTopic(t *testing.T) { var name string = "name3373707" var kmsKeyName string = "kmsKeyName2094986649" var expectedResponse = &pubsubpb.Topic{ Name: name, KmsKeyName: kmsKeyName, } mockPublisher.err = nil mockPublisher.reqs = nil mockPublisher.resps = append(mockPublisher.resps[:0], expectedResponse) var topic *pubsubpb.Topic = &pubsubpb.Topic{} var updateMask *field_maskpb.FieldMask = &field_maskpb.FieldMask{} var request = &pubsubpb.UpdateTopicRequest{ Topic: topic, UpdateMask: updateMask, } c, err := NewPublisherClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateTopic(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockPublisher.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestPublisherUpdateTopicError(t *testing.T) { errCode := codes.PermissionDenied mockPublisher.err = gstatus.Error(errCode, "test error") var topic *pubsubpb.Topic = &pubsubpb.Topic{} var updateMask *field_maskpb.FieldMask = &field_maskpb.FieldMask{} var request = &pubsubpb.UpdateTopicRequest{ Topic: topic, UpdateMask: updateMask, } c, err := NewPublisherClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateTopic(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestPublisherPublish(t *testing.T) { var messageIdsElement string = "messageIdsElement-744837059" var messageIds = []string{messageIdsElement} var expectedResponse = &pubsubpb.PublishResponse{ MessageIds: messageIds, } mockPublisher.err = nil mockPublisher.reqs = nil mockPublisher.resps = append(mockPublisher.resps[:0], expectedResponse) var formattedTopic string = fmt.Sprintf("projects/%s/topics/%s", "[PROJECT]", "[TOPIC]") var data []byte = []byte("-86") var messagesElement = &pubsubpb.PubsubMessage{ Data: data, } var messages = []*pubsubpb.PubsubMessage{messagesElement} var request = &pubsubpb.PublishRequest{ Topic: formattedTopic, Messages: messages, } c, err := NewPublisherClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Publish(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockPublisher.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestPublisherPublishError(t *testing.T) { errCode := codes.PermissionDenied mockPublisher.err = gstatus.Error(errCode, "test error") var formattedTopic string = fmt.Sprintf("projects/%s/topics/%s", "[PROJECT]", "[TOPIC]") var data []byte = []byte("-86") var messagesElement = &pubsubpb.PubsubMessage{ Data: data, } var messages = []*pubsubpb.PubsubMessage{messagesElement} var request = &pubsubpb.PublishRequest{ Topic: formattedTopic, Messages: messages, } c, err := NewPublisherClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Publish(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestPublisherGetTopic(t *testing.T) { var name string = "name3373707" var kmsKeyName string = "kmsKeyName2094986649" var expectedResponse = &pubsubpb.Topic{ Name: name, KmsKeyName: kmsKeyName, } mockPublisher.err = nil mockPublisher.reqs = nil mockPublisher.resps = append(mockPublisher.resps[:0], expectedResponse) var formattedTopic string = fmt.Sprintf("projects/%s/topics/%s", "[PROJECT]", "[TOPIC]") var request = &pubsubpb.GetTopicRequest{ Topic: formattedTopic, } c, err := NewPublisherClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetTopic(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockPublisher.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestPublisherGetTopicError(t *testing.T) { errCode := codes.PermissionDenied mockPublisher.err = gstatus.Error(errCode, "test error") var formattedTopic string = fmt.Sprintf("projects/%s/topics/%s", "[PROJECT]", "[TOPIC]") var request = &pubsubpb.GetTopicRequest{ Topic: formattedTopic, } c, err := NewPublisherClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetTopic(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestPublisherListTopics(t *testing.T) { var nextPageToken string = "" var topicsElement *pubsubpb.Topic = &pubsubpb.Topic{} var topics = []*pubsubpb.Topic{topicsElement} var expectedResponse = &pubsubpb.ListTopicsResponse{ NextPageToken: nextPageToken, Topics: topics, } mockPublisher.err = nil mockPublisher.reqs = nil mockPublisher.resps = append(mockPublisher.resps[:0], expectedResponse) var formattedProject string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &pubsubpb.ListTopicsRequest{ Project: formattedProject, } c, err := NewPublisherClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListTopics(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockPublisher.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Topics[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestPublisherListTopicsError(t *testing.T) { errCode := codes.PermissionDenied mockPublisher.err = gstatus.Error(errCode, "test error") var formattedProject string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &pubsubpb.ListTopicsRequest{ Project: formattedProject, } c, err := NewPublisherClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListTopics(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestPublisherListTopicSubscriptions(t *testing.T) { var nextPageToken string = "" var subscriptionsElement string = "subscriptionsElement1698708147" var subscriptions = []string{subscriptionsElement} var expectedResponse = &pubsubpb.ListTopicSubscriptionsResponse{ NextPageToken: nextPageToken, Subscriptions: subscriptions, } mockPublisher.err = nil mockPublisher.reqs = nil mockPublisher.resps = append(mockPublisher.resps[:0], expectedResponse) var formattedTopic string = fmt.Sprintf("projects/%s/topics/%s", "[PROJECT]", "[TOPIC]") var request = &pubsubpb.ListTopicSubscriptionsRequest{ Topic: formattedTopic, } c, err := NewPublisherClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListTopicSubscriptions(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockPublisher.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Subscriptions[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestPublisherListTopicSubscriptionsError(t *testing.T) { errCode := codes.PermissionDenied mockPublisher.err = gstatus.Error(errCode, "test error") var formattedTopic string = fmt.Sprintf("projects/%s/topics/%s", "[PROJECT]", "[TOPIC]") var request = &pubsubpb.ListTopicSubscriptionsRequest{ Topic: formattedTopic, } c, err := NewPublisherClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListTopicSubscriptions(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestPublisherDeleteTopic(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockPublisher.err = nil mockPublisher.reqs = nil mockPublisher.resps = append(mockPublisher.resps[:0], expectedResponse) var formattedTopic string = fmt.Sprintf("projects/%s/topics/%s", "[PROJECT]", "[TOPIC]") var request = &pubsubpb.DeleteTopicRequest{ Topic: formattedTopic, } c, err := NewPublisherClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteTopic(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockPublisher.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestPublisherDeleteTopicError(t *testing.T) { errCode := codes.PermissionDenied mockPublisher.err = gstatus.Error(errCode, "test error") var formattedTopic string = fmt.Sprintf("projects/%s/topics/%s", "[PROJECT]", "[TOPIC]") var request = &pubsubpb.DeleteTopicRequest{ Topic: formattedTopic, } c, err := NewPublisherClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteTopic(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestSubscriberCreateSubscription(t *testing.T) { var name2 string = "name2-1052831874" var topic2 string = "topic2-1139259102" var ackDeadlineSeconds int32 = 2135351438 var retainAckedMessages bool = false var enableMessageOrdering bool = true var expectedResponse = &pubsubpb.Subscription{ Name: name2, Topic: topic2, AckDeadlineSeconds: ackDeadlineSeconds, RetainAckedMessages: retainAckedMessages, EnableMessageOrdering: enableMessageOrdering, } mockSubscriber.err = nil mockSubscriber.reqs = nil mockSubscriber.resps = append(mockSubscriber.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/subscriptions/%s", "[PROJECT]", "[SUBSCRIPTION]") var formattedTopic string = fmt.Sprintf("projects/%s/topics/%s", "[PROJECT]", "[TOPIC]") var request = &pubsubpb.Subscription{ Name: formattedName, Topic: formattedTopic, } c, err := NewSubscriberClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateSubscription(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSubscriber.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSubscriberCreateSubscriptionError(t *testing.T) { errCode := codes.PermissionDenied mockSubscriber.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/subscriptions/%s", "[PROJECT]", "[SUBSCRIPTION]") var formattedTopic string = fmt.Sprintf("projects/%s/topics/%s", "[PROJECT]", "[TOPIC]") var request = &pubsubpb.Subscription{ Name: formattedName, Topic: formattedTopic, } c, err := NewSubscriberClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateSubscription(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSubscriberGetSubscription(t *testing.T) { var name string = "name3373707" var topic string = "topic110546223" var ackDeadlineSeconds int32 = 2135351438 var retainAckedMessages bool = false var enableMessageOrdering bool = true var expectedResponse = &pubsubpb.Subscription{ Name: name, Topic: topic, AckDeadlineSeconds: ackDeadlineSeconds, RetainAckedMessages: retainAckedMessages, EnableMessageOrdering: enableMessageOrdering, } mockSubscriber.err = nil mockSubscriber.reqs = nil mockSubscriber.resps = append(mockSubscriber.resps[:0], expectedResponse) var formattedSubscription string = fmt.Sprintf("projects/%s/subscriptions/%s", "[PROJECT]", "[SUBSCRIPTION]") var request = &pubsubpb.GetSubscriptionRequest{ Subscription: formattedSubscription, } c, err := NewSubscriberClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetSubscription(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSubscriber.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSubscriberGetSubscriptionError(t *testing.T) { errCode := codes.PermissionDenied mockSubscriber.err = gstatus.Error(errCode, "test error") var formattedSubscription string = fmt.Sprintf("projects/%s/subscriptions/%s", "[PROJECT]", "[SUBSCRIPTION]") var request = &pubsubpb.GetSubscriptionRequest{ Subscription: formattedSubscription, } c, err := NewSubscriberClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetSubscription(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSubscriberUpdateSubscription(t *testing.T) { var name string = "name3373707" var topic string = "topic110546223" var ackDeadlineSeconds2 int32 = 921632575 var retainAckedMessages bool = false var enableMessageOrdering bool = true var expectedResponse = &pubsubpb.Subscription{ Name: name, Topic: topic, AckDeadlineSeconds: ackDeadlineSeconds2, RetainAckedMessages: retainAckedMessages, EnableMessageOrdering: enableMessageOrdering, } mockSubscriber.err = nil mockSubscriber.reqs = nil mockSubscriber.resps = append(mockSubscriber.resps[:0], expectedResponse) var ackDeadlineSeconds int32 = 42 var subscription = &pubsubpb.Subscription{ AckDeadlineSeconds: ackDeadlineSeconds, } var pathsElement string = "ack_deadline_seconds" var paths = []string{pathsElement} var updateMask = &field_maskpb.FieldMask{ Paths: paths, } var request = &pubsubpb.UpdateSubscriptionRequest{ Subscription: subscription, UpdateMask: updateMask, } c, err := NewSubscriberClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateSubscription(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSubscriber.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSubscriberUpdateSubscriptionError(t *testing.T) { errCode := codes.PermissionDenied mockSubscriber.err = gstatus.Error(errCode, "test error") var ackDeadlineSeconds int32 = 42 var subscription = &pubsubpb.Subscription{ AckDeadlineSeconds: ackDeadlineSeconds, } var pathsElement string = "ack_deadline_seconds" var paths = []string{pathsElement} var updateMask = &field_maskpb.FieldMask{ Paths: paths, } var request = &pubsubpb.UpdateSubscriptionRequest{ Subscription: subscription, UpdateMask: updateMask, } c, err := NewSubscriberClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateSubscription(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSubscriberListSubscriptions(t *testing.T) { var nextPageToken string = "" var subscriptionsElement *pubsubpb.Subscription = &pubsubpb.Subscription{} var subscriptions = []*pubsubpb.Subscription{subscriptionsElement} var expectedResponse = &pubsubpb.ListSubscriptionsResponse{ NextPageToken: nextPageToken, Subscriptions: subscriptions, } mockSubscriber.err = nil mockSubscriber.reqs = nil mockSubscriber.resps = append(mockSubscriber.resps[:0], expectedResponse) var formattedProject string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &pubsubpb.ListSubscriptionsRequest{ Project: formattedProject, } c, err := NewSubscriberClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListSubscriptions(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockSubscriber.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Subscriptions[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSubscriberListSubscriptionsError(t *testing.T) { errCode := codes.PermissionDenied mockSubscriber.err = gstatus.Error(errCode, "test error") var formattedProject string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &pubsubpb.ListSubscriptionsRequest{ Project: formattedProject, } c, err := NewSubscriberClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListSubscriptions(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSubscriberDeleteSubscription(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockSubscriber.err = nil mockSubscriber.reqs = nil mockSubscriber.resps = append(mockSubscriber.resps[:0], expectedResponse) var formattedSubscription string = fmt.Sprintf("projects/%s/subscriptions/%s", "[PROJECT]", "[SUBSCRIPTION]") var request = &pubsubpb.DeleteSubscriptionRequest{ Subscription: formattedSubscription, } c, err := NewSubscriberClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteSubscription(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSubscriber.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestSubscriberDeleteSubscriptionError(t *testing.T) { errCode := codes.PermissionDenied mockSubscriber.err = gstatus.Error(errCode, "test error") var formattedSubscription string = fmt.Sprintf("projects/%s/subscriptions/%s", "[PROJECT]", "[SUBSCRIPTION]") var request = &pubsubpb.DeleteSubscriptionRequest{ Subscription: formattedSubscription, } c, err := NewSubscriberClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteSubscription(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestSubscriberModifyAckDeadline(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockSubscriber.err = nil mockSubscriber.reqs = nil mockSubscriber.resps = append(mockSubscriber.resps[:0], expectedResponse) var formattedSubscription string = fmt.Sprintf("projects/%s/subscriptions/%s", "[PROJECT]", "[SUBSCRIPTION]") var ackIds []string = nil var ackDeadlineSeconds int32 = 2135351438 var request = &pubsubpb.ModifyAckDeadlineRequest{ Subscription: formattedSubscription, AckIds: ackIds, AckDeadlineSeconds: ackDeadlineSeconds, } c, err := NewSubscriberClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.ModifyAckDeadline(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSubscriber.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestSubscriberModifyAckDeadlineError(t *testing.T) { errCode := codes.PermissionDenied mockSubscriber.err = gstatus.Error(errCode, "test error") var formattedSubscription string = fmt.Sprintf("projects/%s/subscriptions/%s", "[PROJECT]", "[SUBSCRIPTION]") var ackIds []string = nil var ackDeadlineSeconds int32 = 2135351438 var request = &pubsubpb.ModifyAckDeadlineRequest{ Subscription: formattedSubscription, AckIds: ackIds, AckDeadlineSeconds: ackDeadlineSeconds, } c, err := NewSubscriberClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.ModifyAckDeadline(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestSubscriberAcknowledge(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockSubscriber.err = nil mockSubscriber.reqs = nil mockSubscriber.resps = append(mockSubscriber.resps[:0], expectedResponse) var formattedSubscription string = fmt.Sprintf("projects/%s/subscriptions/%s", "[PROJECT]", "[SUBSCRIPTION]") var ackIds []string = nil var request = &pubsubpb.AcknowledgeRequest{ Subscription: formattedSubscription, AckIds: ackIds, } c, err := NewSubscriberClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.Acknowledge(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSubscriber.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestSubscriberAcknowledgeError(t *testing.T) { errCode := codes.PermissionDenied mockSubscriber.err = gstatus.Error(errCode, "test error") var formattedSubscription string = fmt.Sprintf("projects/%s/subscriptions/%s", "[PROJECT]", "[SUBSCRIPTION]") var ackIds []string = nil var request = &pubsubpb.AcknowledgeRequest{ Subscription: formattedSubscription, AckIds: ackIds, } c, err := NewSubscriberClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.Acknowledge(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestSubscriberPull(t *testing.T) { var expectedResponse *pubsubpb.PullResponse = &pubsubpb.PullResponse{} mockSubscriber.err = nil mockSubscriber.reqs = nil mockSubscriber.resps = append(mockSubscriber.resps[:0], expectedResponse) var formattedSubscription string = fmt.Sprintf("projects/%s/subscriptions/%s", "[PROJECT]", "[SUBSCRIPTION]") var maxMessages int32 = 496131527 var request = &pubsubpb.PullRequest{ Subscription: formattedSubscription, MaxMessages: maxMessages, } c, err := NewSubscriberClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Pull(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSubscriber.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSubscriberPullError(t *testing.T) { errCode := codes.PermissionDenied mockSubscriber.err = gstatus.Error(errCode, "test error") var formattedSubscription string = fmt.Sprintf("projects/%s/subscriptions/%s", "[PROJECT]", "[SUBSCRIPTION]") var maxMessages int32 = 496131527 var request = &pubsubpb.PullRequest{ Subscription: formattedSubscription, MaxMessages: maxMessages, } c, err := NewSubscriberClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Pull(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSubscriberStreamingPull(t *testing.T) { var receivedMessagesElement *pubsubpb.ReceivedMessage = &pubsubpb.ReceivedMessage{} var receivedMessages = []*pubsubpb.ReceivedMessage{receivedMessagesElement} var expectedResponse = &pubsubpb.StreamingPullResponse{ ReceivedMessages: receivedMessages, } mockSubscriber.err = nil mockSubscriber.reqs = nil mockSubscriber.resps = append(mockSubscriber.resps[:0], expectedResponse) var formattedSubscription string = fmt.Sprintf("projects/%s/subscriptions/%s", "[PROJECT]", "[SUBSCRIPTION]") var streamAckDeadlineSeconds int32 = 1875467245 var request = &pubsubpb.StreamingPullRequest{ Subscription: formattedSubscription, StreamAckDeadlineSeconds: streamAckDeadlineSeconds, } c, err := NewSubscriberClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } stream, err := c.StreamingPull(context.Background()) if err != nil { t.Fatal(err) } if err := stream.Send(request); err != nil { t.Fatal(err) } if err := stream.CloseSend(); err != nil { t.Fatal(err) } resp, err := stream.Recv() if err != nil { t.Fatal(err) } if want, got := request, mockSubscriber.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSubscriberStreamingPullError(t *testing.T) { errCode := codes.PermissionDenied mockSubscriber.err = gstatus.Error(errCode, "test error") var formattedSubscription string = fmt.Sprintf("projects/%s/subscriptions/%s", "[PROJECT]", "[SUBSCRIPTION]") var streamAckDeadlineSeconds int32 = 1875467245 var request = &pubsubpb.StreamingPullRequest{ Subscription: formattedSubscription, StreamAckDeadlineSeconds: streamAckDeadlineSeconds, } c, err := NewSubscriberClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } stream, err := c.StreamingPull(context.Background()) if err != nil { t.Fatal(err) } if err := stream.Send(request); err != nil { t.Fatal(err) } if err := stream.CloseSend(); err != nil { t.Fatal(err) } resp, err := stream.Recv() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSubscriberModifyPushConfig(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockSubscriber.err = nil mockSubscriber.reqs = nil mockSubscriber.resps = append(mockSubscriber.resps[:0], expectedResponse) var formattedSubscription string = fmt.Sprintf("projects/%s/subscriptions/%s", "[PROJECT]", "[SUBSCRIPTION]") var pushConfig *pubsubpb.PushConfig = &pubsubpb.PushConfig{} var request = &pubsubpb.ModifyPushConfigRequest{ Subscription: formattedSubscription, PushConfig: pushConfig, } c, err := NewSubscriberClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.ModifyPushConfig(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSubscriber.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestSubscriberModifyPushConfigError(t *testing.T) { errCode := codes.PermissionDenied mockSubscriber.err = gstatus.Error(errCode, "test error") var formattedSubscription string = fmt.Sprintf("projects/%s/subscriptions/%s", "[PROJECT]", "[SUBSCRIPTION]") var pushConfig *pubsubpb.PushConfig = &pubsubpb.PushConfig{} var request = &pubsubpb.ModifyPushConfigRequest{ Subscription: formattedSubscription, PushConfig: pushConfig, } c, err := NewSubscriberClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.ModifyPushConfig(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestSubscriberListSnapshots(t *testing.T) { var nextPageToken string = "" var snapshotsElement *pubsubpb.Snapshot = &pubsubpb.Snapshot{} var snapshots = []*pubsubpb.Snapshot{snapshotsElement} var expectedResponse = &pubsubpb.ListSnapshotsResponse{ NextPageToken: nextPageToken, Snapshots: snapshots, } mockSubscriber.err = nil mockSubscriber.reqs = nil mockSubscriber.resps = append(mockSubscriber.resps[:0], expectedResponse) var formattedProject string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &pubsubpb.ListSnapshotsRequest{ Project: formattedProject, } c, err := NewSubscriberClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListSnapshots(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockSubscriber.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Snapshots[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSubscriberListSnapshotsError(t *testing.T) { errCode := codes.PermissionDenied mockSubscriber.err = gstatus.Error(errCode, "test error") var formattedProject string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &pubsubpb.ListSnapshotsRequest{ Project: formattedProject, } c, err := NewSubscriberClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListSnapshots(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSubscriberCreateSnapshot(t *testing.T) { var name2 string = "name2-1052831874" var topic string = "topic110546223" var expectedResponse = &pubsubpb.Snapshot{ Name: name2, Topic: topic, } mockSubscriber.err = nil mockSubscriber.reqs = nil mockSubscriber.resps = append(mockSubscriber.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/snapshots/%s", "[PROJECT]", "[SNAPSHOT]") var formattedSubscription string = fmt.Sprintf("projects/%s/subscriptions/%s", "[PROJECT]", "[SUBSCRIPTION]") var request = &pubsubpb.CreateSnapshotRequest{ Name: formattedName, Subscription: formattedSubscription, } c, err := NewSubscriberClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateSnapshot(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSubscriber.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSubscriberCreateSnapshotError(t *testing.T) { errCode := codes.PermissionDenied mockSubscriber.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/snapshots/%s", "[PROJECT]", "[SNAPSHOT]") var formattedSubscription string = fmt.Sprintf("projects/%s/subscriptions/%s", "[PROJECT]", "[SUBSCRIPTION]") var request = &pubsubpb.CreateSnapshotRequest{ Name: formattedName, Subscription: formattedSubscription, } c, err := NewSubscriberClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateSnapshot(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSubscriberUpdateSnapshot(t *testing.T) { var name string = "name3373707" var topic string = "topic110546223" var expectedResponse = &pubsubpb.Snapshot{ Name: name, Topic: topic, } mockSubscriber.err = nil mockSubscriber.reqs = nil mockSubscriber.resps = append(mockSubscriber.resps[:0], expectedResponse) var seconds int64 = 123456 var expireTime = ×tamppb.Timestamp{ Seconds: seconds, } var snapshot = &pubsubpb.Snapshot{ ExpireTime: expireTime, } var pathsElement string = "expire_time" var paths = []string{pathsElement} var updateMask = &field_maskpb.FieldMask{ Paths: paths, } var request = &pubsubpb.UpdateSnapshotRequest{ Snapshot: snapshot, UpdateMask: updateMask, } c, err := NewSubscriberClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateSnapshot(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSubscriber.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSubscriberUpdateSnapshotError(t *testing.T) { errCode := codes.PermissionDenied mockSubscriber.err = gstatus.Error(errCode, "test error") var seconds int64 = 123456 var expireTime = ×tamppb.Timestamp{ Seconds: seconds, } var snapshot = &pubsubpb.Snapshot{ ExpireTime: expireTime, } var pathsElement string = "expire_time" var paths = []string{pathsElement} var updateMask = &field_maskpb.FieldMask{ Paths: paths, } var request = &pubsubpb.UpdateSnapshotRequest{ Snapshot: snapshot, UpdateMask: updateMask, } c, err := NewSubscriberClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateSnapshot(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSubscriberDeleteSnapshot(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockSubscriber.err = nil mockSubscriber.reqs = nil mockSubscriber.resps = append(mockSubscriber.resps[:0], expectedResponse) var formattedSnapshot string = fmt.Sprintf("projects/%s/snapshots/%s", "[PROJECT]", "[SNAPSHOT]") var request = &pubsubpb.DeleteSnapshotRequest{ Snapshot: formattedSnapshot, } c, err := NewSubscriberClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteSnapshot(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSubscriber.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestSubscriberDeleteSnapshotError(t *testing.T) { errCode := codes.PermissionDenied mockSubscriber.err = gstatus.Error(errCode, "test error") var formattedSnapshot string = fmt.Sprintf("projects/%s/snapshots/%s", "[PROJECT]", "[SNAPSHOT]") var request = &pubsubpb.DeleteSnapshotRequest{ Snapshot: formattedSnapshot, } c, err := NewSubscriberClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteSnapshot(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestSubscriberSeek(t *testing.T) { var expectedResponse *pubsubpb.SeekResponse = &pubsubpb.SeekResponse{} mockSubscriber.err = nil mockSubscriber.reqs = nil mockSubscriber.resps = append(mockSubscriber.resps[:0], expectedResponse) var formattedSubscription string = fmt.Sprintf("projects/%s/subscriptions/%s", "[PROJECT]", "[SUBSCRIPTION]") var request = &pubsubpb.SeekRequest{ Subscription: formattedSubscription, } c, err := NewSubscriberClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Seek(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSubscriber.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSubscriberSeekError(t *testing.T) { errCode := codes.PermissionDenied mockSubscriber.err = gstatus.Error(errCode, "test error") var formattedSubscription string = fmt.Sprintf("projects/%s/subscriptions/%s", "[PROJECT]", "[SUBSCRIPTION]") var request = &pubsubpb.SeekRequest{ Subscription: formattedSubscription, } c, err := NewSubscriberClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Seek(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/pubsub/apiv1/path_funcs.go000066400000000000000000000044141356504100700215740ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package pubsub // PublisherProjectPath returns the path for the project resource. // // Deprecated: Use // fmt.Sprintf("projects/%s", project) // instead. func PublisherProjectPath(project string) string { return "" + "projects/" + project + "" } // PublisherTopicPath returns the path for the topic resource. // // Deprecated: Use // fmt.Sprintf("projects/%s/topics/%s", project, topic) // instead. func PublisherTopicPath(project, topic string) string { return "" + "projects/" + project + "/topics/" + topic + "" } // SubscriberProjectPath returns the path for the project resource. // // Deprecated: Use // fmt.Sprintf("projects/%s", project) // instead. func SubscriberProjectPath(project string) string { return "" + "projects/" + project + "" } // SubscriberSnapshotPath returns the path for the snapshot resource. // // Deprecated: Use // fmt.Sprintf("projects/%s/snapshots/%s", project, snapshot) // instead. func SubscriberSnapshotPath(project, snapshot string) string { return "" + "projects/" + project + "/snapshots/" + snapshot + "" } // SubscriberSubscriptionPath returns the path for the subscription resource. // // Deprecated: Use // fmt.Sprintf("projects/%s/subscriptions/%s", project, subscription) // instead. func SubscriberSubscriptionPath(project, subscription string) string { return "" + "projects/" + project + "/subscriptions/" + subscription + "" } // SubscriberTopicPath returns the path for the topic resource. // // Deprecated: Use // fmt.Sprintf("projects/%s/topics/%s", project, topic) // instead. func SubscriberTopicPath(project, topic string) string { return "" + "projects/" + project + "/topics/" + topic + "" } google-cloud-go-0.49.0/pubsub/apiv1/publisher_client.go000066400000000000000000000356201356504100700230000ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package pubsub import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" pubsubpb "google.golang.org/genproto/googleapis/pubsub/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // PublisherCallOptions contains the retry settings for each method of PublisherClient. type PublisherCallOptions struct { CreateTopic []gax.CallOption UpdateTopic []gax.CallOption Publish []gax.CallOption GetTopic []gax.CallOption ListTopics []gax.CallOption ListTopicSubscriptions []gax.CallOption DeleteTopic []gax.CallOption } func defaultPublisherClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("pubsub.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultPublisherCallOptions() *PublisherCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Aborted, codes.Unavailable, codes.Unknown, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, {"default", "non_idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, {"messaging", "publish"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Aborted, codes.Canceled, codes.DeadlineExceeded, codes.Internal, codes.ResourceExhausted, codes.Unavailable, codes.Unknown, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &PublisherCallOptions{ CreateTopic: retry[[2]string{"default", "non_idempotent"}], UpdateTopic: retry[[2]string{"default", "non_idempotent"}], Publish: retry[[2]string{"messaging", "publish"}], GetTopic: retry[[2]string{"default", "idempotent"}], ListTopics: retry[[2]string{"default", "idempotent"}], ListTopicSubscriptions: retry[[2]string{"default", "idempotent"}], DeleteTopic: retry[[2]string{"default", "non_idempotent"}], } } // PublisherClient is a client for interacting with Google Cloud Pub/Sub API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type PublisherClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. publisherClient pubsubpb.PublisherClient // The call options for this service. CallOptions *PublisherCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewPublisherClient creates a new publisher client. // // The service that an application uses to manipulate topics, and to send // messages to a topic. func NewPublisherClient(ctx context.Context, opts ...option.ClientOption) (*PublisherClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultPublisherClientOptions(), opts...)...) if err != nil { return nil, err } c := &PublisherClient{ conn: conn, CallOptions: defaultPublisherCallOptions(), publisherClient: pubsubpb.NewPublisherClient(conn), } c.SetGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *PublisherClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *PublisherClient) Close() error { return c.conn.Close() } // SetGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *PublisherClient) SetGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // CreateTopic creates the given topic with the given name. See the // // resource name rules. func (c *PublisherClient) CreateTopic(ctx context.Context, req *pubsubpb.Topic, opts ...gax.CallOption) (*pubsubpb.Topic, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateTopic[0:len(c.CallOptions.CreateTopic):len(c.CallOptions.CreateTopic)], opts...) var resp *pubsubpb.Topic err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.publisherClient.CreateTopic(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateTopic updates an existing topic. Note that certain properties of a // topic are not modifiable. func (c *PublisherClient) UpdateTopic(ctx context.Context, req *pubsubpb.UpdateTopicRequest, opts ...gax.CallOption) (*pubsubpb.Topic, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "topic.name", url.QueryEscape(req.GetTopic().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateTopic[0:len(c.CallOptions.UpdateTopic):len(c.CallOptions.UpdateTopic)], opts...) var resp *pubsubpb.Topic err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.publisherClient.UpdateTopic(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // Publish adds one or more messages to the topic. Returns NOT_FOUND if the topic // does not exist. func (c *PublisherClient) Publish(ctx context.Context, req *pubsubpb.PublishRequest, opts ...gax.CallOption) (*pubsubpb.PublishResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "topic", url.QueryEscape(req.GetTopic()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.Publish[0:len(c.CallOptions.Publish):len(c.CallOptions.Publish)], opts...) var resp *pubsubpb.PublishResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.publisherClient.Publish(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetTopic gets the configuration of a topic. func (c *PublisherClient) GetTopic(ctx context.Context, req *pubsubpb.GetTopicRequest, opts ...gax.CallOption) (*pubsubpb.Topic, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "topic", url.QueryEscape(req.GetTopic()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetTopic[0:len(c.CallOptions.GetTopic):len(c.CallOptions.GetTopic)], opts...) var resp *pubsubpb.Topic err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.publisherClient.GetTopic(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListTopics lists matching topics. func (c *PublisherClient) ListTopics(ctx context.Context, req *pubsubpb.ListTopicsRequest, opts ...gax.CallOption) *TopicIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "project", url.QueryEscape(req.GetProject()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListTopics[0:len(c.CallOptions.ListTopics):len(c.CallOptions.ListTopics)], opts...) it := &TopicIterator{} req = proto.Clone(req).(*pubsubpb.ListTopicsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*pubsubpb.Topic, string, error) { var resp *pubsubpb.ListTopicsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.publisherClient.ListTopics(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Topics, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // ListTopicSubscriptions lists the names of the subscriptions on this topic. func (c *PublisherClient) ListTopicSubscriptions(ctx context.Context, req *pubsubpb.ListTopicSubscriptionsRequest, opts ...gax.CallOption) *StringIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "topic", url.QueryEscape(req.GetTopic()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListTopicSubscriptions[0:len(c.CallOptions.ListTopicSubscriptions):len(c.CallOptions.ListTopicSubscriptions)], opts...) it := &StringIterator{} req = proto.Clone(req).(*pubsubpb.ListTopicSubscriptionsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]string, string, error) { var resp *pubsubpb.ListTopicSubscriptionsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.publisherClient.ListTopicSubscriptions(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Subscriptions, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // DeleteTopic deletes the topic with the given name. Returns NOT_FOUND if the topic // does not exist. After a topic is deleted, a new topic may be created with // the same name; this is an entirely new topic with none of the old // configuration or subscriptions. Existing subscriptions to this topic are // not deleted, but their topic field is set to _deleted-topic_. func (c *PublisherClient) DeleteTopic(ctx context.Context, req *pubsubpb.DeleteTopicRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "topic", url.QueryEscape(req.GetTopic()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteTopic[0:len(c.CallOptions.DeleteTopic):len(c.CallOptions.DeleteTopic)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.publisherClient.DeleteTopic(ctx, req, settings.GRPC...) return err }, opts...) return err } // StringIterator manages a stream of string. type StringIterator struct { items []string pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []string, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *StringIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *StringIterator) Next() (string, error) { var item string if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *StringIterator) bufLen() int { return len(it.items) } func (it *StringIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // TopicIterator manages a stream of *pubsubpb.Topic. type TopicIterator struct { items []*pubsubpb.Topic pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*pubsubpb.Topic, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *TopicIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *TopicIterator) Next() (*pubsubpb.Topic, error) { var item *pubsubpb.Topic if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *TopicIterator) bufLen() int { return len(it.items) } func (it *TopicIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/pubsub/apiv1/publisher_client_example_test.go000066400000000000000000000070331356504100700255470ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package pubsub_test import ( "context" pubsub "cloud.google.com/go/pubsub/apiv1" "google.golang.org/api/iterator" pubsubpb "google.golang.org/genproto/googleapis/pubsub/v1" ) func ExampleNewPublisherClient() { ctx := context.Background() c, err := pubsub.NewPublisherClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExamplePublisherClient_CreateTopic() { ctx := context.Background() c, err := pubsub.NewPublisherClient(ctx) if err != nil { // TODO: Handle error. } req := &pubsubpb.Topic{ // TODO: Fill request struct fields. } resp, err := c.CreateTopic(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExamplePublisherClient_UpdateTopic() { ctx := context.Background() c, err := pubsub.NewPublisherClient(ctx) if err != nil { // TODO: Handle error. } req := &pubsubpb.UpdateTopicRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateTopic(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExamplePublisherClient_Publish() { ctx := context.Background() c, err := pubsub.NewPublisherClient(ctx) if err != nil { // TODO: Handle error. } req := &pubsubpb.PublishRequest{ // TODO: Fill request struct fields. } resp, err := c.Publish(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExamplePublisherClient_GetTopic() { ctx := context.Background() c, err := pubsub.NewPublisherClient(ctx) if err != nil { // TODO: Handle error. } req := &pubsubpb.GetTopicRequest{ // TODO: Fill request struct fields. } resp, err := c.GetTopic(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExamplePublisherClient_ListTopics() { ctx := context.Background() c, err := pubsub.NewPublisherClient(ctx) if err != nil { // TODO: Handle error. } req := &pubsubpb.ListTopicsRequest{ // TODO: Fill request struct fields. } it := c.ListTopics(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExamplePublisherClient_ListTopicSubscriptions() { ctx := context.Background() c, err := pubsub.NewPublisherClient(ctx) if err != nil { // TODO: Handle error. } req := &pubsubpb.ListTopicSubscriptionsRequest{ // TODO: Fill request struct fields. } it := c.ListTopicSubscriptions(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExamplePublisherClient_DeleteTopic() { ctx := context.Background() c, err := pubsub.NewPublisherClient(ctx) if err != nil { // TODO: Handle error. } req := &pubsubpb.DeleteTopicRequest{ // TODO: Fill request struct fields. } err = c.DeleteTopic(ctx, req) if err != nil { // TODO: Handle error. } } google-cloud-go-0.49.0/pubsub/apiv1/pubsub_pull_example_test.go000066400000000000000000000054031356504100700245470ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package pubsub_test import ( "context" "fmt" "log" "time" pubsub "cloud.google.com/go/pubsub/apiv1" pubsubpb "google.golang.org/genproto/googleapis/pubsub/v1" ) func ExampleSubscriberClient_Pull_lengthyClientProcessing() { projectID := "some-project" subscriptionID := "some-subscription" ctx := context.Background() client, err := pubsub.NewSubscriberClient(ctx) if err != nil { log.Fatal(err) } defer client.Close() sub := fmt.Sprintf("projects/%s/subscriptions/%s", projectID, subscriptionID) // Be sure to tune the MaxMessages parameter per your project's needs, and accordingly // adjust the ack behavior below to batch acknowledgements. req := pubsubpb.PullRequest{ Subscription: sub, MaxMessages: 1, } fmt.Println("Listening..") for { res, err := client.Pull(ctx, &req) if err != nil { log.Fatal(err) } // client.Pull returns an empty list if there are no messages available in the // backlog. We should skip processing steps when that happens. if len(res.ReceivedMessages) == 0 { continue } var recvdAckIDs []string for _, m := range res.ReceivedMessages { recvdAckIDs = append(recvdAckIDs, m.AckId) } var done = make(chan struct{}) var delay = 0 * time.Second // Tick immediately upon reception var ackDeadline = 10 * time.Second // Continuously notify the server that processing is still happening on this batch. go func() { for { select { case <-ctx.Done(): return case <-done: return case <-time.After(delay): err := client.ModifyAckDeadline(ctx, &pubsubpb.ModifyAckDeadlineRequest{ Subscription: sub, AckIds: recvdAckIDs, AckDeadlineSeconds: int32(ackDeadline.Seconds()), }) if err != nil { log.Fatal(err) } delay = ackDeadline - 5*time.Second // 5 seconds grace period. } } }() for _, m := range res.ReceivedMessages { // Process the message here, possibly in a goroutine. log.Printf("Got message: %s", string(m.Message.Data)) err := client.Acknowledge(ctx, &pubsubpb.AcknowledgeRequest{ Subscription: sub, AckIds: []string{m.AckId}, }) if err != nil { log.Fatal(err) } } close(done) } } google-cloud-go-0.49.0/pubsub/apiv1/subscriber_client.go000066400000000000000000000661341356504100700231520ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package pubsub import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" pubsubpb "google.golang.org/genproto/googleapis/pubsub/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // SubscriberCallOptions contains the retry settings for each method of SubscriberClient. type SubscriberCallOptions struct { CreateSubscription []gax.CallOption GetSubscription []gax.CallOption UpdateSubscription []gax.CallOption ListSubscriptions []gax.CallOption DeleteSubscription []gax.CallOption ModifyAckDeadline []gax.CallOption Acknowledge []gax.CallOption Pull []gax.CallOption StreamingPull []gax.CallOption ModifyPushConfig []gax.CallOption ListSnapshots []gax.CallOption CreateSnapshot []gax.CallOption UpdateSnapshot []gax.CallOption DeleteSnapshot []gax.CallOption Seek []gax.CallOption } func defaultSubscriberClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("pubsub.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultSubscriberCallOptions() *SubscriberCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Aborted, codes.Unavailable, codes.Unknown, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, {"default", "non_idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, {"messaging", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Aborted, codes.Unavailable, codes.Unknown, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, {"messaging", "non_idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, {"streaming_messaging", "streaming_pull"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Aborted, codes.DeadlineExceeded, codes.Internal, codes.ResourceExhausted, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &SubscriberCallOptions{ CreateSubscription: retry[[2]string{"default", "idempotent"}], GetSubscription: retry[[2]string{"default", "idempotent"}], UpdateSubscription: retry[[2]string{"default", "non_idempotent"}], ListSubscriptions: retry[[2]string{"default", "idempotent"}], DeleteSubscription: retry[[2]string{"default", "non_idempotent"}], ModifyAckDeadline: retry[[2]string{"default", "non_idempotent"}], Acknowledge: retry[[2]string{"messaging", "non_idempotent"}], Pull: retry[[2]string{"messaging", "idempotent"}], StreamingPull: retry[[2]string{"streaming_messaging", "streaming_pull"}], ModifyPushConfig: retry[[2]string{"default", "non_idempotent"}], ListSnapshots: retry[[2]string{"default", "idempotent"}], CreateSnapshot: retry[[2]string{"default", "non_idempotent"}], UpdateSnapshot: retry[[2]string{"default", "non_idempotent"}], DeleteSnapshot: retry[[2]string{"default", "non_idempotent"}], Seek: retry[[2]string{"default", "idempotent"}], } } // SubscriberClient is a client for interacting with Google Cloud Pub/Sub API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type SubscriberClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. subscriberClient pubsubpb.SubscriberClient // The call options for this service. CallOptions *SubscriberCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewSubscriberClient creates a new subscriber client. // // The service that an application uses to manipulate subscriptions and to // consume messages from a subscription via the Pull method or by // establishing a bi-directional stream using the StreamingPull method. func NewSubscriberClient(ctx context.Context, opts ...option.ClientOption) (*SubscriberClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultSubscriberClientOptions(), opts...)...) if err != nil { return nil, err } c := &SubscriberClient{ conn: conn, CallOptions: defaultSubscriberCallOptions(), subscriberClient: pubsubpb.NewSubscriberClient(conn), } c.SetGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *SubscriberClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *SubscriberClient) Close() error { return c.conn.Close() } // SetGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *SubscriberClient) SetGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // CreateSubscription creates a subscription to a given topic. See the // // resource name rules. // If the subscription already exists, returns ALREADY_EXISTS. // If the corresponding topic doesn't exist, returns NOT_FOUND. // // If the name is not provided in the request, the server will assign a random // name for this subscription on the same project as the topic, conforming // to the // resource name // format (at https://cloud.google.com/pubsub/docs/admin#resource_names). The // generated name is populated in the returned Subscription object. Note that // for REST API requests, you must specify a name in the request. func (c *SubscriberClient) CreateSubscription(ctx context.Context, req *pubsubpb.Subscription, opts ...gax.CallOption) (*pubsubpb.Subscription, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateSubscription[0:len(c.CallOptions.CreateSubscription):len(c.CallOptions.CreateSubscription)], opts...) var resp *pubsubpb.Subscription err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.subscriberClient.CreateSubscription(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetSubscription gets the configuration details of a subscription. func (c *SubscriberClient) GetSubscription(ctx context.Context, req *pubsubpb.GetSubscriptionRequest, opts ...gax.CallOption) (*pubsubpb.Subscription, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "subscription", url.QueryEscape(req.GetSubscription()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetSubscription[0:len(c.CallOptions.GetSubscription):len(c.CallOptions.GetSubscription)], opts...) var resp *pubsubpb.Subscription err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.subscriberClient.GetSubscription(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateSubscription updates an existing subscription. Note that certain properties of a // subscription, such as its topic, are not modifiable. func (c *SubscriberClient) UpdateSubscription(ctx context.Context, req *pubsubpb.UpdateSubscriptionRequest, opts ...gax.CallOption) (*pubsubpb.Subscription, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "subscription.name", url.QueryEscape(req.GetSubscription().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateSubscription[0:len(c.CallOptions.UpdateSubscription):len(c.CallOptions.UpdateSubscription)], opts...) var resp *pubsubpb.Subscription err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.subscriberClient.UpdateSubscription(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListSubscriptions lists matching subscriptions. func (c *SubscriberClient) ListSubscriptions(ctx context.Context, req *pubsubpb.ListSubscriptionsRequest, opts ...gax.CallOption) *SubscriptionIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "project", url.QueryEscape(req.GetProject()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListSubscriptions[0:len(c.CallOptions.ListSubscriptions):len(c.CallOptions.ListSubscriptions)], opts...) it := &SubscriptionIterator{} req = proto.Clone(req).(*pubsubpb.ListSubscriptionsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*pubsubpb.Subscription, string, error) { var resp *pubsubpb.ListSubscriptionsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.subscriberClient.ListSubscriptions(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Subscriptions, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // DeleteSubscription deletes an existing subscription. All messages retained in the subscription // are immediately dropped. Calls to Pull after deletion will return // NOT_FOUND. After a subscription is deleted, a new one may be created with // the same name, but the new one has no association with the old // subscription or its topic unless the same topic is specified. func (c *SubscriberClient) DeleteSubscription(ctx context.Context, req *pubsubpb.DeleteSubscriptionRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "subscription", url.QueryEscape(req.GetSubscription()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteSubscription[0:len(c.CallOptions.DeleteSubscription):len(c.CallOptions.DeleteSubscription)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.subscriberClient.DeleteSubscription(ctx, req, settings.GRPC...) return err }, opts...) return err } // ModifyAckDeadline modifies the ack deadline for a specific message. This method is useful // to indicate that more time is needed to process a message by the // subscriber, or to make the message available for redelivery if the // processing was interrupted. Note that this does not modify the // subscription-level ackDeadlineSeconds used for subsequent messages. func (c *SubscriberClient) ModifyAckDeadline(ctx context.Context, req *pubsubpb.ModifyAckDeadlineRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "subscription", url.QueryEscape(req.GetSubscription()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ModifyAckDeadline[0:len(c.CallOptions.ModifyAckDeadline):len(c.CallOptions.ModifyAckDeadline)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.subscriberClient.ModifyAckDeadline(ctx, req, settings.GRPC...) return err }, opts...) return err } // Acknowledge acknowledges the messages associated with the ack_ids in the // AcknowledgeRequest. The Pub/Sub system can remove the relevant messages // from the subscription. // // Acknowledging a message whose ack deadline has expired may succeed, // but such a message may be redelivered later. Acknowledging a message more // than once will not result in an error. func (c *SubscriberClient) Acknowledge(ctx context.Context, req *pubsubpb.AcknowledgeRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "subscription", url.QueryEscape(req.GetSubscription()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.Acknowledge[0:len(c.CallOptions.Acknowledge):len(c.CallOptions.Acknowledge)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.subscriberClient.Acknowledge(ctx, req, settings.GRPC...) return err }, opts...) return err } // Pull pulls messages from the server. The server may return UNAVAILABLE if // there are too many concurrent pull requests pending for the given // subscription. func (c *SubscriberClient) Pull(ctx context.Context, req *pubsubpb.PullRequest, opts ...gax.CallOption) (*pubsubpb.PullResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "subscription", url.QueryEscape(req.GetSubscription()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.Pull[0:len(c.CallOptions.Pull):len(c.CallOptions.Pull)], opts...) var resp *pubsubpb.PullResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.subscriberClient.Pull(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // StreamingPull establishes a stream with the server, which sends messages down to the // client. The client streams acknowledgements and ack deadline modifications // back to the server. The server will close the stream and return the status // on any error. The server may close the stream with status UNAVAILABLE to // reassign server-side resources, in which case, the client should // re-establish the stream. Flow control can be achieved by configuring the // underlying RPC channel. func (c *SubscriberClient) StreamingPull(ctx context.Context, opts ...gax.CallOption) (pubsubpb.Subscriber_StreamingPullClient, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.StreamingPull[0:len(c.CallOptions.StreamingPull):len(c.CallOptions.StreamingPull)], opts...) var resp pubsubpb.Subscriber_StreamingPullClient err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.subscriberClient.StreamingPull(ctx, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ModifyPushConfig modifies the PushConfig for a specified subscription. // // This may be used to change a push subscription to a pull one (signified by // an empty PushConfig) or vice versa, or change the endpoint URL and other // attributes of a push subscription. Messages will accumulate for delivery // continuously through the call regardless of changes to the PushConfig. func (c *SubscriberClient) ModifyPushConfig(ctx context.Context, req *pubsubpb.ModifyPushConfigRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "subscription", url.QueryEscape(req.GetSubscription()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ModifyPushConfig[0:len(c.CallOptions.ModifyPushConfig):len(c.CallOptions.ModifyPushConfig)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.subscriberClient.ModifyPushConfig(ctx, req, settings.GRPC...) return err }, opts...) return err } // ListSnapshots lists the existing snapshots. Snapshots are used in // Seek // operations, which allow // you to manage message acknowledgments in bulk. That is, you can set the // acknowledgment state of messages in an existing subscription to the state // captured by a snapshot. func (c *SubscriberClient) ListSnapshots(ctx context.Context, req *pubsubpb.ListSnapshotsRequest, opts ...gax.CallOption) *SnapshotIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "project", url.QueryEscape(req.GetProject()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListSnapshots[0:len(c.CallOptions.ListSnapshots):len(c.CallOptions.ListSnapshots)], opts...) it := &SnapshotIterator{} req = proto.Clone(req).(*pubsubpb.ListSnapshotsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*pubsubpb.Snapshot, string, error) { var resp *pubsubpb.ListSnapshotsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.subscriberClient.ListSnapshots(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Snapshots, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // CreateSnapshot creates a snapshot from the requested subscription. Snapshots are used in // Seek // operations, which allow // you to manage message acknowledgments in bulk. That is, you can set the // acknowledgment state of messages in an existing subscription to the state // captured by a snapshot. //

If the snapshot already exists, returns ALREADY_EXISTS. // If the requested subscription doesn't exist, returns NOT_FOUND. // If the backlog in the subscription is too old -- and the resulting snapshot // would expire in less than 1 hour -- then FAILED_PRECONDITION is returned. // See also the Snapshot.expire_time field. If the name is not provided in // the request, the server will assign a random // name for this snapshot on the same project as the subscription, conforming // to the // resource name // format (at https://cloud.google.com/pubsub/docs/admin#resource_names). The // generated name is populated in the returned Snapshot object. Note that for // REST API requests, you must specify a name in the request. func (c *SubscriberClient) CreateSnapshot(ctx context.Context, req *pubsubpb.CreateSnapshotRequest, opts ...gax.CallOption) (*pubsubpb.Snapshot, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateSnapshot[0:len(c.CallOptions.CreateSnapshot):len(c.CallOptions.CreateSnapshot)], opts...) var resp *pubsubpb.Snapshot err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.subscriberClient.CreateSnapshot(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateSnapshot updates an existing snapshot. Snapshots are used in // Seek // operations, which allow // you to manage message acknowledgments in bulk. That is, you can set the // acknowledgment state of messages in an existing subscription to the state // captured by a snapshot. func (c *SubscriberClient) UpdateSnapshot(ctx context.Context, req *pubsubpb.UpdateSnapshotRequest, opts ...gax.CallOption) (*pubsubpb.Snapshot, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "snapshot.name", url.QueryEscape(req.GetSnapshot().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateSnapshot[0:len(c.CallOptions.UpdateSnapshot):len(c.CallOptions.UpdateSnapshot)], opts...) var resp *pubsubpb.Snapshot err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.subscriberClient.UpdateSnapshot(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteSnapshot removes an existing snapshot. Snapshots are used in // Seek // operations, which allow // you to manage message acknowledgments in bulk. That is, you can set the // acknowledgment state of messages in an existing subscription to the state // captured by a snapshot.

// When the snapshot is deleted, all messages retained in the snapshot // are immediately dropped. After a snapshot is deleted, a new one may be // created with the same name, but the new one has no association with the old // snapshot or its subscription, unless the same subscription is specified. func (c *SubscriberClient) DeleteSnapshot(ctx context.Context, req *pubsubpb.DeleteSnapshotRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "snapshot", url.QueryEscape(req.GetSnapshot()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteSnapshot[0:len(c.CallOptions.DeleteSnapshot):len(c.CallOptions.DeleteSnapshot)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.subscriberClient.DeleteSnapshot(ctx, req, settings.GRPC...) return err }, opts...) return err } // Seek seeks an existing subscription to a point in time or to a given snapshot, // whichever is provided in the request. Snapshots are used in // Seek // operations, which allow // you to manage message acknowledgments in bulk. That is, you can set the // acknowledgment state of messages in an existing subscription to the state // captured by a snapshot. Note that both the subscription and the snapshot // must be on the same topic. func (c *SubscriberClient) Seek(ctx context.Context, req *pubsubpb.SeekRequest, opts ...gax.CallOption) (*pubsubpb.SeekResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "subscription", url.QueryEscape(req.GetSubscription()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.Seek[0:len(c.CallOptions.Seek):len(c.CallOptions.Seek)], opts...) var resp *pubsubpb.SeekResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.subscriberClient.Seek(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // SnapshotIterator manages a stream of *pubsubpb.Snapshot. type SnapshotIterator struct { items []*pubsubpb.Snapshot pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*pubsubpb.Snapshot, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *SnapshotIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *SnapshotIterator) Next() (*pubsubpb.Snapshot, error) { var item *pubsubpb.Snapshot if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *SnapshotIterator) bufLen() int { return len(it.items) } func (it *SnapshotIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // SubscriptionIterator manages a stream of *pubsubpb.Subscription. type SubscriptionIterator struct { items []*pubsubpb.Subscription pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*pubsubpb.Subscription, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *SubscriptionIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *SubscriptionIterator) Next() (*pubsubpb.Subscription, error) { var item *pubsubpb.Subscription if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *SubscriptionIterator) bufLen() int { return len(it.items) } func (it *SubscriptionIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/pubsub/apiv1/subscriber_client_example_test.go000066400000000000000000000151151356504100700257150ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package pubsub_test import ( "context" "io" pubsub "cloud.google.com/go/pubsub/apiv1" "google.golang.org/api/iterator" pubsubpb "google.golang.org/genproto/googleapis/pubsub/v1" ) func ExampleNewSubscriberClient() { ctx := context.Background() c, err := pubsub.NewSubscriberClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleSubscriberClient_CreateSubscription() { ctx := context.Background() c, err := pubsub.NewSubscriberClient(ctx) if err != nil { // TODO: Handle error. } req := &pubsubpb.Subscription{ // TODO: Fill request struct fields. } resp, err := c.CreateSubscription(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleSubscriberClient_GetSubscription() { ctx := context.Background() c, err := pubsub.NewSubscriberClient(ctx) if err != nil { // TODO: Handle error. } req := &pubsubpb.GetSubscriptionRequest{ // TODO: Fill request struct fields. } resp, err := c.GetSubscription(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleSubscriberClient_UpdateSubscription() { ctx := context.Background() c, err := pubsub.NewSubscriberClient(ctx) if err != nil { // TODO: Handle error. } req := &pubsubpb.UpdateSubscriptionRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateSubscription(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleSubscriberClient_ListSubscriptions() { ctx := context.Background() c, err := pubsub.NewSubscriberClient(ctx) if err != nil { // TODO: Handle error. } req := &pubsubpb.ListSubscriptionsRequest{ // TODO: Fill request struct fields. } it := c.ListSubscriptions(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleSubscriberClient_DeleteSubscription() { ctx := context.Background() c, err := pubsub.NewSubscriberClient(ctx) if err != nil { // TODO: Handle error. } req := &pubsubpb.DeleteSubscriptionRequest{ // TODO: Fill request struct fields. } err = c.DeleteSubscription(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleSubscriberClient_ModifyAckDeadline() { ctx := context.Background() c, err := pubsub.NewSubscriberClient(ctx) if err != nil { // TODO: Handle error. } req := &pubsubpb.ModifyAckDeadlineRequest{ // TODO: Fill request struct fields. } err = c.ModifyAckDeadline(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleSubscriberClient_Acknowledge() { ctx := context.Background() c, err := pubsub.NewSubscriberClient(ctx) if err != nil { // TODO: Handle error. } req := &pubsubpb.AcknowledgeRequest{ // TODO: Fill request struct fields. } err = c.Acknowledge(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleSubscriberClient_Pull() { ctx := context.Background() c, err := pubsub.NewSubscriberClient(ctx) if err != nil { // TODO: Handle error. } req := &pubsubpb.PullRequest{ // TODO: Fill request struct fields. } resp, err := c.Pull(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleSubscriberClient_StreamingPull() { ctx := context.Background() c, err := pubsub.NewSubscriberClient(ctx) if err != nil { // TODO: Handle error. } stream, err := c.StreamingPull(ctx) if err != nil { // TODO: Handle error. } go func() { reqs := []*pubsubpb.StreamingPullRequest{ // TODO: Create requests. } for _, req := range reqs { if err := stream.Send(req); err != nil { // TODO: Handle error. } } stream.CloseSend() }() for { resp, err := stream.Recv() if err == io.EOF { break } if err != nil { // TODO: handle error. } // TODO: Use resp. _ = resp } } func ExampleSubscriberClient_ModifyPushConfig() { ctx := context.Background() c, err := pubsub.NewSubscriberClient(ctx) if err != nil { // TODO: Handle error. } req := &pubsubpb.ModifyPushConfigRequest{ // TODO: Fill request struct fields. } err = c.ModifyPushConfig(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleSubscriberClient_ListSnapshots() { ctx := context.Background() c, err := pubsub.NewSubscriberClient(ctx) if err != nil { // TODO: Handle error. } req := &pubsubpb.ListSnapshotsRequest{ // TODO: Fill request struct fields. } it := c.ListSnapshots(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleSubscriberClient_CreateSnapshot() { ctx := context.Background() c, err := pubsub.NewSubscriberClient(ctx) if err != nil { // TODO: Handle error. } req := &pubsubpb.CreateSnapshotRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateSnapshot(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleSubscriberClient_UpdateSnapshot() { ctx := context.Background() c, err := pubsub.NewSubscriberClient(ctx) if err != nil { // TODO: Handle error. } req := &pubsubpb.UpdateSnapshotRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateSnapshot(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleSubscriberClient_DeleteSnapshot() { ctx := context.Background() c, err := pubsub.NewSubscriberClient(ctx) if err != nil { // TODO: Handle error. } req := &pubsubpb.DeleteSnapshotRequest{ // TODO: Fill request struct fields. } err = c.DeleteSnapshot(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleSubscriberClient_Seek() { ctx := context.Background() c, err := pubsub.NewSubscriberClient(ctx) if err != nil { // TODO: Handle error. } req := &pubsubpb.SeekRequest{ // TODO: Fill request struct fields. } resp, err := c.Seek(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/pubsub/debug.go000066400000000000000000000030401356504100700175020ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // +build psdebug package pubsub import ( "sync" "time" ) var ( dmu sync.Mutex msgTraces = map[string][]Event{} ackIDToMsgID = map[string]string{} ) type Event struct { Desc string At time.Time } func MessageEvents(msgID string) []Event { dmu.Lock() defer dmu.Unlock() return msgTraces[msgID] } func addRecv(msgID, ackID string, t time.Time) { dmu.Lock() defer dmu.Unlock() ackIDToMsgID[ackID] = msgID addEvent(msgID, "recv", t) } func addAcks(ackIDs []string) { dmu.Lock() defer dmu.Unlock() now := time.Now() for _, id := range ackIDs { addEvent(ackIDToMsgID[id], "ack", now) } } func addModAcks(ackIDs []string, deadlineSecs int32) { dmu.Lock() defer dmu.Unlock() desc := "modack" if deadlineSecs == 0 { desc = "nack" } now := time.Now() for _, id := range ackIDs { addEvent(ackIDToMsgID[id], desc, now) } } func addEvent(msgID, desc string, t time.Time) { msgTraces[msgID] = append(msgTraces[msgID], Event{desc, t}) } google-cloud-go-0.49.0/pubsub/doc.go000066400000000000000000000132001356504100700171600ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. /* Package pubsub provides an easy way to publish and receive Google Cloud Pub/Sub messages, hiding the details of the underlying server RPCs. Google Cloud Pub/Sub is a many-to-many, asynchronous messaging system that decouples senders and receivers. More information about Google Cloud Pub/Sub is available at https://cloud.google.com/pubsub/docs See https://godoc.org/cloud.google.com/go for authentication, timeouts, connection pooling and similar aspects of this package. Publishing Google Cloud Pub/Sub messages are published to topics. Topics may be created using the pubsub package like so: topic, err := pubsubClient.CreateTopic(context.Background(), "topic-name") Messages may then be published to a topic: res := topic.Publish(ctx, &pubsub.Message{Data: []byte("payload")}) Publish queues the message for publishing and returns immediately. When enough messages have accumulated, or enough time has elapsed, the batch of messages is sent to the Pub/Sub service. Publish returns a PublishResult, which behaves like a future: its Get method blocks until the message has been sent to the service. The first time you call Publish on a topic, goroutines are started in the background. To clean up these goroutines, call Stop: topic.Stop() Receiving To receive messages published to a topic, clients create subscriptions to the topic. There may be more than one subscription per topic; each message that is published to the topic will be delivered to all of its subscriptions. Subsciptions may be created like so: sub, err := pubsubClient.CreateSubscription(context.Background(), "sub-name", pubsub.SubscriptionConfig{Topic: topic}) Messages are then consumed from a subscription via callback. err := sub.Receive(context.Background(), func(ctx context.Context, m *Message) { log.Printf("Got message: %s", m.Data) m.Ack() }) if err != nil { // Handle error. } The callback is invoked concurrently by multiple goroutines, maximizing throughput. To terminate a call to Receive, cancel its context. Once client code has processed the message, it must call Message.Ack or message.Nack, otherwise the message will eventually be redelivered. If the client cannot or doesn't want to process the message, it can call Message.Nack to speed redelivery. For more information and configuration options, see "Deadlines" below. Note: It is possible for Messages to be redelivered, even if Message.Ack has been called. Client code must be robust to multiple deliveries of messages. Note: This uses pubsub's streaming pull feature. This feature properties that may be surprising. Please take a look at https://cloud.google.com/pubsub/docs/pull#streamingpull for more details on how streaming pull behaves compared to the synchronous pull method. Deadlines The default pubsub deadlines are suitable for most use cases, but may be overridden. This section describes the tradeoffs that should be considered when overriding the defaults. Behind the scenes, each message returned by the Pub/Sub server has an associated lease, known as an "ACK deadline". Unless a message is acknowledged within the ACK deadline, or the client requests that the ACK deadline be extended, the message will become eligible for redelivery. As a convenience, the pubsub client will automatically extend deadlines until either: * Message.Ack or Message.Nack is called, or * The "MaxExtension" period elapses from the time the message is fetched from the server. ACK deadlines are extended periodically by the client. The initial ACK deadline given to messages is 10s. The period between extensions, as well as the length of the extension, automatically adjust depending on the time it takes to ack messages, up to 10m. This has the effect that subscribers that process messages quickly have their message ack deadlines extended for a short amount, whereas subscribers that process message slowly have their message ack deadlines extended for a large amount. The net effect is fewer RPCs sent from the client library. For example, consider a subscriber that takes 3 minutes to process each message. Since the library has already recorded several 3 minute "time to ack"s in a percentile distribution, future message extensions are sent with a value of 3 minutes, every 3 minutes. Suppose the application crashes 5 seconds after the library sends such an extension: the Pub/Sub server would wait the remaining 2m55s before re-sending the messages out to other subscribers. Please note that the client library does not use the subscription's AckDeadline by default. To enforce the subscription AckDeadline, set MaxExtension to the subscription's AckDeadline: cfg, err := sub.Config(ctx) if err != nil { // TODO: handle err } sub.ReceiveSettings.MaxExtension = cfg.AckDeadline Slow Message Processing For use cases where message processing exceeds 30 minutes, we recommend using the base client in a pull model, since long-lived streams are periodically killed by firewalls. See the example at https://godoc.org/cloud.google.com/go/pubsub/apiv1#example-SubscriberClient-Pull-LengthyClientProcessing */ package pubsub // import "cloud.google.com/go/pubsub" google-cloud-go-0.49.0/pubsub/example_subscription_iterator_test.go000066400000000000000000000025341356504100700256320ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package pubsub_test import ( "context" "fmt" "cloud.google.com/go/pubsub" "google.golang.org/api/iterator" ) func ExampleClient_Subscriptions() { ctx := context.Background() client, err := pubsub.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } // List all subscriptions of the project. it := client.Subscriptions(ctx) _ = it // TODO: iterate using Next. } func ExampleSubscriptionIterator_Next() { ctx := context.Background() client, err := pubsub.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } // List all subscriptions of the project. it := client.Subscriptions(ctx) for { sub, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } fmt.Println(sub) } } google-cloud-go-0.49.0/pubsub/example_test.go000066400000000000000000000304231356504100700211130ustar00rootroot00000000000000// Copyright 2014 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package pubsub_test import ( "context" "fmt" "time" "cloud.google.com/go/pubsub" "google.golang.org/api/iterator" ) func ExampleNewClient() { ctx := context.Background() _, err := pubsub.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } // See the other examples to learn how to use the Client. } func ExampleClient_CreateTopic() { ctx := context.Background() client, err := pubsub.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } // Create a new topic with the given name. topic, err := client.CreateTopic(ctx, "topicName") if err != nil { // TODO: Handle error. } _ = topic // TODO: use the topic. } func ExampleClient_CreateTopicWithConfig() { ctx := context.Background() client, err := pubsub.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } // Create a new topic with the given name and config. topicConfig := &pubsub.TopicConfig{ KMSKeyName: "projects/project-id/locations/global/keyRings/my-key-ring/cryptoKeys/my-key", MessageStoragePolicy: pubsub.MessageStoragePolicy{ AllowedPersistenceRegions: []string{"us-east1"}, }, } topic, err := client.CreateTopicWithConfig(ctx, "topicName", topicConfig) if err != nil { // TODO: Handle error. } _ = topic // TODO: use the topic. } // Use TopicInProject to refer to a topic that is not in the client's project, such // as a public topic. func ExampleClient_TopicInProject() { ctx := context.Background() client, err := pubsub.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } topic := client.TopicInProject("topicName", "another-project-id") _ = topic // TODO: use the topic. } func ExampleClient_CreateSubscription() { ctx := context.Background() client, err := pubsub.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } // Create a new topic with the given name. topic, err := client.CreateTopic(ctx, "topicName") if err != nil { // TODO: Handle error. } // Create a new subscription to the previously created topic // with the given name. sub, err := client.CreateSubscription(ctx, "subName", pubsub.SubscriptionConfig{ Topic: topic, AckDeadline: 10 * time.Second, ExpirationPolicy: 25 * time.Hour, }) if err != nil { // TODO: Handle error. } _ = sub // TODO: use the subscription. } func ExampleClient_CreateSubscription_neverExpire() { ctx := context.Background() client, err := pubsub.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } // Create a new topic with the given name. topic, err := client.CreateTopic(ctx, "topicName") if err != nil { // TODO: Handle error. } // Create a new subscription to the previously // created topic and ensure it never expires. sub, err := client.CreateSubscription(ctx, "subName", pubsub.SubscriptionConfig{ Topic: topic, AckDeadline: 10 * time.Second, ExpirationPolicy: time.Duration(0), }) if err != nil { // TODO: Handle error. } _ = sub // TODO: Use the subscription } func ExampleTopic_Delete() { ctx := context.Background() client, err := pubsub.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } topic := client.Topic("topicName") if err := topic.Delete(ctx); err != nil { // TODO: Handle error. } } func ExampleTopic_Exists() { ctx := context.Background() client, err := pubsub.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } topic := client.Topic("topicName") ok, err := topic.Exists(ctx) if err != nil { // TODO: Handle error. } if !ok { // Topic doesn't exist. } } func ExampleTopic_Publish() { ctx := context.Background() client, err := pubsub.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } topic := client.Topic("topicName") defer topic.Stop() var results []*pubsub.PublishResult r := topic.Publish(ctx, &pubsub.Message{ Data: []byte("hello world"), }) results = append(results, r) // Do other work ... for _, r := range results { id, err := r.Get(ctx) if err != nil { // TODO: Handle error. } fmt.Printf("Published a message with a message ID: %s\n", id) } } func ExampleTopic_Subscriptions() { ctx := context.Background() client, err := pubsub.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } topic := client.Topic("topic-name") // List all subscriptions of the topic (maybe of multiple projects). for subs := topic.Subscriptions(ctx); ; { sub, err := subs.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } _ = sub // TODO: use the subscription. } } func ExampleTopic_Update() { ctx := context.Background() client, err := pubsub.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error.V } topic := client.Topic("topic-name") topicConfig, err := topic.Update(ctx, pubsub.TopicConfigToUpdate{ MessageStoragePolicy: &pubsub.MessageStoragePolicy{ AllowedPersistenceRegions: []string{ "asia-east1", "asia-northeast1", "asia-southeast1", "australia-southeast1", "europe-north1", "europe-west1", "europe-west2", "europe-west3", "europe-west4", "us-central1", "us-central2", "us-east1", "us-east4", "us-west1", "us-west2"}, }, }) if err != nil { // TODO: Handle error. } _ = topicConfig // TODO: Use TopicConfig } func ExampleTopic_Update_resetMessageStoragePolicy() { ctx := context.Background() client, err := pubsub.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error.V } topic := client.Topic("topic-name") topicConfig, err := topic.Update(ctx, pubsub.TopicConfigToUpdate{ // Just use a non-nil MessageStoragePolicy without any fields. MessageStoragePolicy: &pubsub.MessageStoragePolicy{}, }) if err != nil { // TODO: Handle error. } _ = topicConfig // TODO: Use TopicConfig } func ExampleSubscription_Delete() { ctx := context.Background() client, err := pubsub.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } sub := client.Subscription("subName") if err := sub.Delete(ctx); err != nil { // TODO: Handle error. } } func ExampleSubscription_Exists() { ctx := context.Background() client, err := pubsub.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } sub := client.Subscription("subName") ok, err := sub.Exists(ctx) if err != nil { // TODO: Handle error. } if !ok { // Subscription doesn't exist. } } func ExampleSubscription_Config() { ctx := context.Background() client, err := pubsub.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } sub := client.Subscription("subName") config, err := sub.Config(ctx) if err != nil { // TODO: Handle error. } fmt.Println(config) } func ExampleSubscription_Receive() { ctx := context.Background() client, err := pubsub.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } sub := client.Subscription("subName") err = sub.Receive(ctx, func(ctx context.Context, m *pubsub.Message) { // TODO: Handle message. // NOTE: May be called concurrently; synchronize access to shared memory. m.Ack() }) if err != context.Canceled { // TODO: Handle error. } } // This example shows how to configure keepalive so that unacknoweldged messages // expire quickly, allowing other subscribers to take them. func ExampleSubscription_Receive_maxExtension() { ctx := context.Background() client, err := pubsub.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } sub := client.Subscription("subName") // This program is expected to process and acknowledge messages in 30 seconds. If // not, the Pub/Sub API will assume the message is not acknowledged. sub.ReceiveSettings.MaxExtension = 30 * time.Second err = sub.Receive(ctx, func(ctx context.Context, m *pubsub.Message) { // TODO: Handle message. m.Ack() }) if err != context.Canceled { // TODO: Handle error. } } // This example shows how to throttle Subscription.Receive, which aims for high // throughput by default. By limiting the number of messages and/or bytes being // processed at once, you can bound your program's resource consumption. func ExampleSubscription_Receive_maxOutstanding() { ctx := context.Background() client, err := pubsub.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } sub := client.Subscription("subName") sub.ReceiveSettings.MaxOutstandingMessages = 5 sub.ReceiveSettings.MaxOutstandingBytes = 10e6 err = sub.Receive(ctx, func(ctx context.Context, m *pubsub.Message) { // TODO: Handle message. m.Ack() }) if err != context.Canceled { // TODO: Handle error. } } func ExampleSubscription_Update() { ctx := context.Background() client, err := pubsub.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } sub := client.Subscription("subName") subConfig, err := sub.Update(ctx, pubsub.SubscriptionConfigToUpdate{ PushConfig: &pubsub.PushConfig{Endpoint: "https://example.com/push"}, // Make the subscription never expire. ExpirationPolicy: time.Duration(0), }) if err != nil { // TODO: Handle error. } _ = subConfig // TODO: Use SubscriptionConfig. } func ExampleSubscription_Update_pushConfigAuthenticationMethod() { ctx := context.Background() client, err := pubsub.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } sub := client.Subscription("subName") subConfig, err := sub.Update(ctx, pubsub.SubscriptionConfigToUpdate{ PushConfig: &pubsub.PushConfig{ Endpoint: "https://example.com/push", AuthenticationMethod: &pubsub.OIDCToken{ ServiceAccountEmail: "service-account-email", Audience: "client-12345", }, }, }) if err != nil { // TODO: Handle error. } _ = subConfig // TODO: Use SubscriptionConfig. } func ExampleSubscription_CreateSnapshot() { ctx := context.Background() client, err := pubsub.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } sub := client.Subscription("subName") snapConfig, err := sub.CreateSnapshot(ctx, "snapshotName") if err != nil { // TODO: Handle error. } _ = snapConfig // TODO: Use SnapshotConfig. } func ExampleSubscription_SeekToSnapshot() { ctx := context.Background() client, err := pubsub.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } sub := client.Subscription("subName") snap := client.Snapshot("snapshotName") if err := sub.SeekToSnapshot(ctx, snap); err != nil { // TODO: Handle error. } } func ExampleSubscription_SeekToTime() { ctx := context.Background() client, err := pubsub.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } sub := client.Subscription("subName") if err := sub.SeekToTime(ctx, time.Now().Add(-time.Hour)); err != nil { // TODO: Handle error. } } func ExampleSnapshot_Delete() { ctx := context.Background() client, err := pubsub.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } snap := client.Snapshot("snapshotName") if err := snap.Delete(ctx); err != nil { // TODO: Handle error. } } func ExampleClient_Snapshots() { ctx := context.Background() client, err := pubsub.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } // List all snapshots for the project. iter := client.Snapshots(ctx) _ = iter // TODO: iterate using Next. } func ExampleSnapshotConfigIterator_Next() { ctx := context.Background() client, err := pubsub.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } // List all snapshots for the project. iter := client.Snapshots(ctx) for { snapConfig, err := iter.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } _ = snapConfig // TODO: use the SnapshotConfig. } } // TODO(jba): write an example for PublishResult.Ready // TODO(jba): write an example for Subscription.IAM // TODO(jba): write an example for Topic.IAM // TODO(jba): write an example for Topic.Stop google-cloud-go-0.49.0/pubsub/example_topic_iterator_test.go000066400000000000000000000023731356504100700242250ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package pubsub_test import ( "context" "fmt" "cloud.google.com/go/pubsub" "google.golang.org/api/iterator" ) func ExampleClient_Topics() { ctx := context.Background() client, err := pubsub.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } it := client.Topics(ctx) _ = it // TODO: iterate using Next. } func ExampleTopicIterator_Next() { ctx := context.Background() client, err := pubsub.NewClient(ctx, "project-id") if err != nil { // TODO: Handle error. } // List all topics. it := client.Topics(ctx) for { t, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } fmt.Println(t) } } google-cloud-go-0.49.0/pubsub/flow_controller.go000066400000000000000000000065661356504100700216460ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package pubsub import ( "context" "sync/atomic" "golang.org/x/sync/semaphore" ) // flowController implements flow control for Subscription.Receive. type flowController struct { maxCount int maxSize int // max total size of messages semCount, semSize *semaphore.Weighted // enforces max number and size of messages // Number of calls to acquire - number of calls to release. This can go // negative if semCount == nil and a large acquire is followed by multiple // small releases. // Atomic. countRemaining int64 } // newFlowController creates a new flowController that ensures no more than // maxCount messages or maxSize bytes are outstanding at once. If maxCount or // maxSize is < 1, then an unlimited number of messages or bytes is permitted, // respectively. func newFlowController(maxCount, maxSize int) *flowController { fc := &flowController{ maxCount: maxCount, maxSize: maxSize, semCount: nil, semSize: nil, } if maxCount > 0 { fc.semCount = semaphore.NewWeighted(int64(maxCount)) } if maxSize > 0 { fc.semSize = semaphore.NewWeighted(int64(maxSize)) } return fc } // acquire blocks until one message of size bytes can proceed or ctx is done. // It returns nil in the first case, or ctx.Err() in the second. // // acquire allows large messages to proceed by treating a size greater than maxSize // as if it were equal to maxSize. func (f *flowController) acquire(ctx context.Context, size int) error { if f.semCount != nil { if err := f.semCount.Acquire(ctx, 1); err != nil { return err } } if f.semSize != nil { if err := f.semSize.Acquire(ctx, f.bound(size)); err != nil { if f.semCount != nil { f.semCount.Release(1) } return err } } atomic.AddInt64(&f.countRemaining, 1) return nil } // tryAcquire returns false if acquire would block. Otherwise, it behaves like // acquire and returns true. // // tryAcquire allows large messages to proceed by treating a size greater than // maxSize as if it were equal to maxSize. func (f *flowController) tryAcquire(size int) bool { if f.semCount != nil { if !f.semCount.TryAcquire(1) { return false } } if f.semSize != nil { if !f.semSize.TryAcquire(f.bound(size)) { if f.semCount != nil { f.semCount.Release(1) } return false } } atomic.AddInt64(&f.countRemaining, 1) return true } // release notes that one message of size bytes is no longer outstanding. func (f *flowController) release(size int) { atomic.AddInt64(&f.countRemaining, -1) if f.semCount != nil { f.semCount.Release(1) } if f.semSize != nil { f.semSize.Release(f.bound(size)) } } func (f *flowController) bound(size int) int64 { if size > f.maxSize { return int64(f.maxSize) } return int64(size) } func (f *flowController) count() int { return int(atomic.LoadInt64(&f.countRemaining)) } google-cloud-go-0.49.0/pubsub/flow_controller_test.go000066400000000000000000000145331356504100700226760ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package pubsub import ( "context" "errors" "fmt" "sync/atomic" "testing" "time" "golang.org/x/sync/errgroup" ) func TestFlowControllerCancel(t *testing.T) { // Test canceling a flow controller's context. t.Parallel() fc := newFlowController(3, 10) if err := fc.acquire(context.Background(), 5); err != nil { t.Fatal(err) } // Experiment: a context that times out should always return an error. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Millisecond) defer cancel() if err := fc.acquire(ctx, 6); err != context.DeadlineExceeded { t.Fatalf("got %v, expected DeadlineExceeded", err) } // Control: a context that is not done should always return nil. go func() { time.Sleep(5 * time.Millisecond) fc.release(5) }() if err := fc.acquire(context.Background(), 6); err != nil { t.Errorf("got %v, expected nil", err) } } func TestFlowControllerLargeRequest(t *testing.T) { // Large requests succeed, consuming the entire allotment. t.Parallel() fc := newFlowController(3, 10) err := fc.acquire(context.Background(), 11) if err != nil { t.Fatal(err) } } func TestFlowControllerNoStarve(t *testing.T) { // A large request won't starve, because the flowController is // (best-effort) FIFO. t.Parallel() ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() fc := newFlowController(10, 10) first := make(chan int) for i := 0; i < 20; i++ { go func() { for { if err := fc.acquire(ctx, 1); err != nil { if err != context.Canceled { t.Error(err) } return } select { case first <- 1: default: } fc.release(1) } }() } <-first // Wait until the flowController's state is non-zero. if err := fc.acquire(ctx, 11); err != nil { t.Errorf("got %v, want nil", err) } } func TestFlowControllerSaturation(t *testing.T) { t.Parallel() const ( maxCount = 6 maxSize = 10 ) for _, test := range []struct { acquireSize int wantCount, wantSize int64 }{ { // Many small acquires cause the flow controller to reach its max count. acquireSize: 1, wantCount: 6, wantSize: 6, }, { // Five acquires of size 2 will cause the flow controller to reach its max size, // but not its max count. acquireSize: 2, wantCount: 5, wantSize: 10, }, { // If the requests are the right size (relatively prime to maxSize), // the flow controller will not saturate on size. (In this case, not on count either.) acquireSize: 3, wantCount: 3, wantSize: 9, }, } { fc := newFlowController(maxCount, maxSize) // Atomically track flow controller state. // The flowController itself tracks count. var curSize int64 success := errors.New("") // Time out if wantSize or wantCount is never reached. ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() g, ctx := errgroup.WithContext(ctx) for i := 0; i < 10; i++ { g.Go(func() error { var hitCount, hitSize bool // Run at least until we hit the expected values, and at least // for enough iterations to exceed them if the flow controller // is broken. for i := 0; i < 100 || !hitCount || !hitSize; i++ { select { case <-ctx.Done(): return ctx.Err() default: } if err := fc.acquire(ctx, test.acquireSize); err != nil { return err } c := int64(fc.count()) if c > test.wantCount { return fmt.Errorf("count %d exceeds want %d", c, test.wantCount) } if c == test.wantCount { hitCount = true } s := atomic.AddInt64(&curSize, int64(test.acquireSize)) if s > test.wantSize { return fmt.Errorf("size %d exceeds want %d", s, test.wantSize) } if s == test.wantSize { hitSize = true } time.Sleep(5 * time.Millisecond) // Let other goroutines make progress. if atomic.AddInt64(&curSize, -int64(test.acquireSize)) < 0 { return errors.New("negative size") } fc.release(test.acquireSize) } return success }) } if err := g.Wait(); err != success { t.Errorf("%+v: %v", test, err) continue } } } func TestFlowControllerTryAcquire(t *testing.T) { t.Parallel() fc := newFlowController(3, 10) // Successfully tryAcquire 4 bytes. if !fc.tryAcquire(4) { t.Error("got false, wanted true") } // Fail to tryAcquire 7 bytes. if fc.tryAcquire(7) { t.Error("got true, wanted false") } // Successfully tryAcquire 6 byte. if !fc.tryAcquire(6) { t.Error("got false, wanted true") } } func TestFlowControllerUnboundedCount(t *testing.T) { t.Parallel() ctx := context.Background() fc := newFlowController(0, 10) // Successfully acquire 4 bytes. if err := fc.acquire(ctx, 4); err != nil { t.Errorf("got %v, wanted no error", err) } // Successfully tryAcquire 4 bytes. if !fc.tryAcquire(4) { t.Error("got false, wanted true") } // Fail to tryAcquire 3 bytes. if fc.tryAcquire(3) { t.Error("got true, wanted false") } } func TestFlowControllerUnboundedCount2(t *testing.T) { t.Parallel() ctx := context.Background() fc := newFlowController(0, 0) // Successfully acquire 4 bytes. if err := fc.acquire(ctx, 4); err != nil { t.Errorf("got %v, wanted no error", err) } fc.release(1) fc.release(1) fc.release(1) wantCount := int64(-2) c := int64(fc.count()) if c != wantCount { t.Fatalf("got count %d, want %d", c, wantCount) } } func TestFlowControllerUnboundedBytes(t *testing.T) { t.Parallel() ctx := context.Background() fc := newFlowController(2, 0) // Successfully acquire 4GB. if err := fc.acquire(ctx, 4e9); err != nil { t.Errorf("got %v, wanted no error", err) } // Successfully tryAcquire 4GB bytes. if !fc.tryAcquire(4e9) { t.Error("got false, wanted true") } // Fail to tryAcquire a third message. if fc.tryAcquire(3) { t.Error("got true, wanted false") } } google-cloud-go-0.49.0/pubsub/go.mod000066400000000000000000000013631356504100700172010ustar00rootroot00000000000000module cloud.google.com/go/pubsub go 1.11 require ( cloud.google.com/go v0.46.3 cloud.google.com/go/storage v1.0.0 // indirect github.com/golang/protobuf v1.3.2 github.com/google/go-cmp v0.3.0 github.com/googleapis/gax-go/v2 v2.0.5 go.opencensus.io v0.22.0 golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136 // indirect golang.org/x/lint v0.0.0-20190930215403-16217165b5de // indirect golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 golang.org/x/sync v0.0.0-20190423024810-112230192c58 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2 // indirect google.golang.org/api v0.14.0 google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9 google.golang.org/grpc v1.21.1 ) google-cloud-go-0.49.0/pubsub/go.sum000066400000000000000000000422411356504100700172260ustar00rootroot00000000000000cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1 h1:lRi0CHyU+ytlvylOlFKKq0af6JncuyoRh1J+QJBqQx0= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3 h1:AVXDdKsrtX33oR9fbCMu/+c1o8Ofjq6Ku/MInaLVg5Y= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go/bigquery v1.0.1 h1:hL+ycaJpVE9M7nLoiXb/Pn10ENE2u+oddxbD8uu0ZVU= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/datastore v1.0.0 h1:Kt+gOPPp2LEPWp8CSfxhsM8ik9CcyE/gYu+0r+RnZvM= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/storage v1.0.0 h1:VV2nUM3wwLLGh9lSABFgZMjInyUbJeaRSE64WuAIQ+4= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024 h1:rBMNdlhTLzJjJSDIjNEXX1Pz3Hmwmz91v+zycvx9PJc= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522 h1:OeRHuibLsmZkFj773W4LcfAGsSxJgfPONhr8cmO+eLA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979 h1:Agxu5KLo8o7Bb634SVDnhIfpTvxmzUwhbYAzBvXt6h4= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136 h1:A1gGSx58LAGVHUUsOf7IiR0u8Xb6W51gRwfDBhkdcaw= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422 h1:QzoH/1pFpZguR8NrRHLcO6jKqfv2zpuSqZLgdm7ZmjI= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac h1:8R1esu+8QioDxo4E4mX6bFztO+dMTM49DNAaWfO5OeY= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0 h1:HyfiK1WMnHj5FXFXatD+Qs1A/xC2Run6RzeW1SyHxpc= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0 h1:Dh6fw+p6FyRl5x/FvNswO1ji0lIGzm3KP8Y9VkS9PTE= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff h1:On1qIo75ByTwFJ4/W2bIqHcwJ9XAqtSWUs8GwRrIhtc= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2 h1:EtTFh6h4SAKemS+CURDMTDIANuduG5zKEXShyy18bGA= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0 h1:jbyannxz0XFD3zdjgrSUsaJbgpH4eTrkdhRChkHPfO8= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.14.0 h1:uMf5uLi4eQMRrMKhCplNik4U4H8Z6C1br3zOtAa/aDE= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51 h1:Ex1mq5jaJof+kRnYi3SlYJ8KKa9Ao3NHyIT5XJ1gF6U= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9 h1:6XzpBoANz1NqMNfDXzc2QmHmbb1vyMsvRfoP5rM+K1I= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1 h1:j6XxA85m/6txkUCHvzlV5f+HBNl/1r5cZ2A/3IEFOO8= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a h1:LJwr7TCTghdatWv40WobzlKXc9c4s8oGa7QKJUtHhWA= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= google-cloud-go-0.49.0/pubsub/go_mod_tidy_hack.go000066400000000000000000000016251356504100700217060ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // This file, and the cloud.google.com/go import, won't actually become part of // the resultant binary. // +build modhack package pubsub // Necessary for safely adding multi-module repo. See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository import _ "cloud.google.com/go" google-cloud-go-0.49.0/pubsub/integration_test.go000066400000000000000000000772671356504100700220240ustar00rootroot00000000000000// Copyright 2014 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package pubsub import ( "bytes" "context" "fmt" "strings" "testing" "time" "cloud.google.com/go/iam" "cloud.google.com/go/internal" "cloud.google.com/go/internal/testutil" "cloud.google.com/go/internal/uid" "cloud.google.com/go/internal/version" kms "cloud.google.com/go/kms/apiv1" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "golang.org/x/oauth2/google" "google.golang.org/api/iterator" "google.golang.org/api/option" kmspb "google.golang.org/genproto/googleapis/cloud/kms/v1" pb "google.golang.org/genproto/googleapis/pubsub/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" ) var ( topicIDs = uid.NewSpace("topic", nil) subIDs = uid.NewSpace("sub", nil) ) // messageData is used to hold the contents of a message so that it can be compared against the contents // of another message without regard to irrelevant fields. type messageData struct { ID string Data []byte Attributes map[string]string } func extractMessageData(m *Message) *messageData { return &messageData{ ID: m.ID, Data: m.Data, Attributes: m.Attributes, } } func withGRPCHeadersAssertion(t *testing.T, opts ...option.ClientOption) []option.ClientOption { grpcHeadersEnforcer := &testutil.HeadersEnforcer{ OnFailure: t.Errorf, Checkers: []*testutil.HeaderChecker{ testutil.XGoogClientHeaderChecker, }, } return append(grpcHeadersEnforcer.CallOptions(), opts...) } func integrationTestClient(ctx context.Context, t *testing.T) *Client { if testing.Short() { t.Skip("Integration tests skipped in short mode") } projID := testutil.ProjID() if projID == "" { t.Skip("Integration tests skipped. See CONTRIBUTING.md for details") } ts := testutil.TokenSource(ctx, ScopePubSub, ScopeCloudPlatform) if ts == nil { t.Skip("Integration tests skipped. See CONTRIBUTING.md for details") } opts := withGRPCHeadersAssertion(t, option.WithTokenSource(ts)) client, err := NewClient(ctx, projID, opts...) if err != nil { t.Fatalf("Creating client error: %v", err) } return client } func TestIntegration_All(t *testing.T) { t.Skip("https://github.com/googleapis/google-cloud-go/issues/1633") t.Parallel() ctx := context.Background() client := integrationTestClient(ctx, t) defer client.Close() topic, err := client.CreateTopic(ctx, topicIDs.New()) if err != nil { t.Errorf("CreateTopic error: %v", err) } defer topic.Stop() exists, err := topic.Exists(ctx) if err != nil { t.Fatalf("TopicExists error: %v", err) } if !exists { t.Errorf("topic %v should exist, but it doesn't", topic) } var sub *Subscription if sub, err = client.CreateSubscription(ctx, subIDs.New(), SubscriptionConfig{Topic: topic}); err != nil { t.Errorf("CreateSub error: %v", err) } exists, err = sub.Exists(ctx) if err != nil { t.Fatalf("SubExists error: %v", err) } if !exists { t.Errorf("subscription %s should exist, but it doesn't", sub.ID()) } for _, sync := range []bool{false, true} { for _, maxMsgs := range []int{0, 3, -1} { // MaxOutstandingMessages = default, 3, unlimited testPublishAndReceive(t, topic, sub, maxMsgs, sync, 10, 0) } // Tests for large messages (larger than the 4MB gRPC limit). testPublishAndReceive(t, topic, sub, 0, sync, 1, 5*1024*1024) } if msg, ok := testIAM(ctx, topic.IAM(), "pubsub.topics.get"); !ok { t.Errorf("topic IAM: %s", msg) } if msg, ok := testIAM(ctx, sub.IAM(), "pubsub.subscriptions.get"); !ok { t.Errorf("sub IAM: %s", msg) } snap, err := sub.CreateSnapshot(ctx, "") if err != nil { t.Fatalf("CreateSnapshot error: %v", err) } timeoutCtx, cancel := context.WithTimeout(ctx, time.Minute) defer cancel() err = internal.Retry(timeoutCtx, gax.Backoff{}, func() (bool, error) { snapIt := client.Snapshots(timeoutCtx) for { s, err := snapIt.Next() if err == nil && s.name == snap.name { return true, nil } if err == iterator.Done { return false, fmt.Errorf("cannot find snapshot: %q", snap.name) } if err != nil { return false, err } } }) if err != nil { t.Error(err) } err = internal.Retry(timeoutCtx, gax.Backoff{}, func() (bool, error) { err := sub.SeekToSnapshot(timeoutCtx, snap.Snapshot) return err == nil, err }) if err != nil { t.Error(err) } err = internal.Retry(timeoutCtx, gax.Backoff{}, func() (bool, error) { err := sub.SeekToTime(timeoutCtx, time.Now()) return err == nil, err }) if err != nil { t.Error(err) } err = internal.Retry(timeoutCtx, gax.Backoff{}, func() (bool, error) { snapHandle := client.Snapshot(snap.ID()) err := snapHandle.Delete(timeoutCtx) return err == nil, err }) if err != nil { t.Error(err) } if err := sub.Delete(ctx); err != nil { t.Errorf("DeleteSub error: %v", err) } if err := topic.Delete(ctx); err != nil { t.Errorf("DeleteTopic error: %v", err) } } // withGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request and returns the // updated context. func withGoogleClientInfo(ctx context.Context) context.Context { ctxMD, _ := metadata.FromOutgoingContext(ctx) kv := []string{ "gl-go", version.Go(), "gax", gax.Version, "grpc", grpc.Version, } allMDs := append([]metadata.MD{ctxMD}, metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))) return metadata.NewOutgoingContext(ctx, metadata.Join(allMDs...)) } func testPublishAndReceive(t *testing.T, topic *Topic, sub *Subscription, maxMsgs int, synchronous bool, numMsgs, extraBytes int) { ctx := context.Background() var msgs []*Message for i := 0; i < numMsgs; i++ { text := fmt.Sprintf("a message with an index %d - %s", i, strings.Repeat(".", extraBytes)) attrs := make(map[string]string) attrs["foo"] = "bar" msgs = append(msgs, &Message{ Data: []byte(text), Attributes: attrs, }) } // Publish some messages. type pubResult struct { m *Message r *PublishResult } var rs []pubResult for _, m := range msgs { r := topic.Publish(ctx, m) rs = append(rs, pubResult{m, r}) } want := make(map[string]*messageData) for _, res := range rs { id, err := res.r.Get(ctx) if err != nil { t.Fatal(err) } md := extractMessageData(res.m) md.ID = id want[md.ID] = md } sub.ReceiveSettings.MaxOutstandingMessages = maxMsgs sub.ReceiveSettings.Synchronous = synchronous // Use a timeout to ensure that Pull does not block indefinitely if there are // unexpectedly few messages available. now := time.Now() timeoutCtx, cancel := context.WithTimeout(ctx, time.Minute) defer cancel() gotMsgs, err := pullN(timeoutCtx, sub, len(want), func(ctx context.Context, m *Message) { m.Ack() }) if err != nil { if c := status.Convert(err); c.Code() == codes.Canceled { if time.Now().Sub(now) >= time.Minute { t.Fatal("pullN took too long") } } else { t.Fatalf("Pull: %v", err) } } got := make(map[string]*messageData) for _, m := range gotMsgs { md := extractMessageData(m) got[md.ID] = md } if !testutil.Equal(got, want) { t.Fatalf("MaxOutstandingMessages=%d, Synchronous=%t, messages got: %v, messages want: %v", maxMsgs, synchronous, got, want) } } // IAM tests. // NOTE: for these to succeed, the test runner identity must have the Pub/Sub Admin or Owner roles. // To set, visit https://console.developers.google.com, select "IAM & Admin" from the top-left // menu, choose the account, click the Roles dropdown, and select "Pub/Sub > Pub/Sub Admin". // TODO(jba): move this to a testing package within cloud.google.com/iam, so we can re-use it. func testIAM(ctx context.Context, h *iam.Handle, permission string) (msg string, ok bool) { // Manually adding withGoogleClientInfo here because this code only takes // a handle with a grpc.ClientConn that has the "x-goog-api-client" header enforcer, // but unfortunately not the underlying infrastructure that takes pre-set headers. ctx = withGoogleClientInfo(ctx) // Attempting to add an non-existent identity (e.g. "alice@example.com") causes the service // to return an internal error, so use a real identity. const member = "domain:google.com" var policy *iam.Policy var err error if policy, err = h.Policy(ctx); err != nil { return fmt.Sprintf("Policy: %v", err), false } // The resource is new, so the policy should be empty. if got := policy.Roles(); len(got) > 0 { return fmt.Sprintf("initially: got roles %v, want none", got), false } // Add a member, set the policy, then check that the member is present. policy.Add(member, iam.Viewer) if err := h.SetPolicy(ctx, policy); err != nil { return fmt.Sprintf("SetPolicy: %v", err), false } if policy, err = h.Policy(ctx); err != nil { return fmt.Sprintf("Policy: %v", err), false } if got, want := policy.Members(iam.Viewer), []string{member}; !testutil.Equal(got, want) { return fmt.Sprintf("after Add: got %v, want %v", got, want), false } // Now remove that member, set the policy, and check that it's empty again. policy.Remove(member, iam.Viewer) if err := h.SetPolicy(ctx, policy); err != nil { return fmt.Sprintf("SetPolicy: %v", err), false } if policy, err = h.Policy(ctx); err != nil { return fmt.Sprintf("Policy: %v", err), false } if got := policy.Roles(); len(got) > 0 { return fmt.Sprintf("after Remove: got roles %v, want none", got), false } // Call TestPermissions. // Because this user is an admin, it has all the permissions on the // resource type. Note: the service fails if we ask for inapplicable // permissions (e.g. a subscription permission on a topic, or a topic // create permission on a topic rather than its parent). wantPerms := []string{permission} gotPerms, err := h.TestPermissions(ctx, wantPerms) if err != nil { return fmt.Sprintf("TestPermissions: %v", err), false } if !testutil.Equal(gotPerms, wantPerms) { return fmt.Sprintf("TestPermissions: got %v, want %v", gotPerms, wantPerms), false } return "", true } func TestIntegration_LargePublishSize(t *testing.T) { t.Skip("https://github.com/googleapis/google-cloud-go/issues/1636") ctx := context.Background() client := integrationTestClient(ctx, t) defer client.Close() topic, err := client.CreateTopic(ctx, topicIDs.New()) if err != nil { t.Fatalf("CreateTopic error: %v", err) } defer topic.Delete(ctx) defer topic.Stop() // Calculate the largest possible message length that is still valid. // First, calculate the max length of the encoded message accounting for the topic name. length := MaxPublishRequestBytes - calcFieldSizeString(topic.String()) // Next, account for the overhead from encoding an individual PubsubMessage, // and the inner PubsubMessage.Data field. pbMsgOverhead := 1 + proto.SizeVarint(uint64(length)) dataOverhead := 1 + proto.SizeVarint(uint64(length-pbMsgOverhead)) maxLengthSingleMessage := length - pbMsgOverhead - dataOverhead publishReq := &pb.PublishRequest{ Topic: topic.String(), Messages: []*pb.PubsubMessage{ { Data: bytes.Repeat([]byte{'A'}, maxLengthSingleMessage), }, }, } if got := proto.Size(publishReq); got != MaxPublishRequestBytes { t.Fatalf("Created request size of %d bytes,\nwant %f bytes", got, MaxPublishRequestBytes) } // Publishing the max length message by itself should succeed. msg := &Message{ Data: bytes.Repeat([]byte{'A'}, maxLengthSingleMessage), } r := topic.Publish(ctx, msg) if _, err := r.Get(ctx); err != nil { t.Fatalf("Failed to publish max length message: %v", err) } // Publish a small message first and make sure the max length message // is added to its own bundle. smallMsg := &Message{ Data: []byte{'A'}, } topic.Publish(ctx, smallMsg) r = topic.Publish(ctx, msg) if _, err := r.Get(ctx); err != nil { t.Fatalf("Failed to publish max length message after a small message: %v", err) } // Increase the data byte string by 1 byte, which should cause the request to fail, // specifically due to exceeding the bundle byte limit. msg.Data = append(msg.Data, 'A') r = topic.Publish(ctx, msg) if _, err := r.Get(ctx); err != ErrOversizedMessage { t.Fatalf("Should throw item size too large error, got %v", err) } } func TestIntegration_CancelReceive(t *testing.T) { t.Skip("https://github.com/googleapis/google-cloud-go/issues/1666") t.Parallel() ctx, cancel := context.WithCancel(context.Background()) client := integrationTestClient(ctx, t) defer client.Close() topic, err := client.CreateTopic(ctx, topicIDs.New()) if err != nil { t.Fatal(err) } defer topic.Delete(ctx) defer topic.Stop() var sub *Subscription if sub, err = client.CreateSubscription(ctx, subIDs.New(), SubscriptionConfig{Topic: topic}); err != nil { t.Fatal(err) } defer sub.Delete(ctx) sub.ReceiveSettings.MaxOutstandingMessages = -1 sub.ReceiveSettings.MaxOutstandingBytes = -1 sub.ReceiveSettings.NumGoroutines = 1 doneReceiving := make(chan struct{}) // Publish the messages. go func() { for { select { case <-doneReceiving: return default: topic.Publish(ctx, &Message{Data: []byte("some msg")}) time.Sleep(time.Second) } } }() go func() { defer close(doneReceiving) err = sub.Receive(ctx, func(_ context.Context, msg *Message) { cancel() time.AfterFunc(5*time.Second, msg.Ack) }) if err != nil { t.Error(err) } }() select { case <-time.After(60 * time.Second): t.Fatalf("Waited 60 seconds for Receive to finish, should have finished sooner") case <-doneReceiving: } } func TestIntegration_CreateSubscription_NeverExpire(t *testing.T) { t.Parallel() ctx := context.Background() client := integrationTestClient(ctx, t) defer client.Close() topic, err := client.CreateTopic(ctx, topicIDs.New()) if err != nil { t.Fatalf("CreateTopic error: %v", err) } defer topic.Delete(ctx) defer topic.Stop() cfg := SubscriptionConfig{ Topic: topic, ExpirationPolicy: time.Duration(0), } var sub *Subscription if sub, err = client.CreateSubscription(ctx, subIDs.New(), cfg); err != nil { t.Fatalf("CreateSub error: %v", err) } defer sub.Delete(ctx) got, err := sub.Config(ctx) if err != nil { t.Fatal(err) } want := SubscriptionConfig{ Topic: topic, AckDeadline: 10 * time.Second, RetainAckedMessages: false, RetentionDuration: defaultRetentionDuration, ExpirationPolicy: time.Duration(0), } if diff := testutil.Diff(got, want); diff != "" { t.Fatalf("\ngot: - want: +\n%s", diff) } } // findServiceAccountEmail tries to find the service account using testutil // JWTConfig as well as the ADC credentials. It will only invoke t.Skip if // it successfully retrieves credentials but finds a blank JWTConfig JSON blob. // For all other errors, it will invoke t.Fatal. func findServiceAccountEmail(ctx context.Context, t *testing.T) string { jwtConf, err := testutil.JWTConfig() if err == nil && jwtConf != nil { return jwtConf.Email } creds := testutil.Credentials(ctx, ScopePubSub, ScopeCloudPlatform) if creds == nil { t.Fatal("Failed to retrieve credentials") } if len(creds.JSON) == 0 { t.Skip("No JWTConfig JSON was present so can't get serviceAccountEmail") } jwtConf, err = google.JWTConfigFromJSON(creds.JSON) if err != nil { t.Fatalf("Failed to parse Google JWTConfig from JSON: %v", err) } return jwtConf.Email } func TestIntegration_UpdateSubscription(t *testing.T) { t.Skip("https://github.com/googleapis/google-cloud-go/issues/1643") t.Parallel() ctx := context.Background() client := integrationTestClient(ctx, t) defer client.Close() serviceAccountEmail := findServiceAccountEmail(ctx, t) topic, err := client.CreateTopic(ctx, topicIDs.New()) if err != nil { t.Fatalf("CreateTopic error: %v", err) } defer topic.Delete(ctx) defer topic.Stop() var sub *Subscription projID := testutil.ProjID() sCfg := SubscriptionConfig{ Topic: topic, PushConfig: PushConfig{ Endpoint: "https://" + projID + ".appspot.com/_ah/push-handlers/push", AuthenticationMethod: &OIDCToken{ Audience: "client-12345", ServiceAccountEmail: serviceAccountEmail, }, }, } if sub, err = client.CreateSubscription(ctx, subIDs.New(), sCfg); err != nil { t.Fatalf("CreateSub error: %v", err) } defer sub.Delete(ctx) got, err := sub.Config(ctx) if err != nil { t.Fatal(err) } want := SubscriptionConfig{ Topic: topic, AckDeadline: 10 * time.Second, RetainAckedMessages: false, RetentionDuration: defaultRetentionDuration, ExpirationPolicy: defaultExpirationPolicy, PushConfig: PushConfig{ Endpoint: "https://" + projID + ".appspot.com/_ah/push-handlers/push", AuthenticationMethod: &OIDCToken{ Audience: "client-12345", ServiceAccountEmail: serviceAccountEmail, }, }, } if diff := testutil.Diff(got, want); diff != "" { t.Fatalf("\ngot: - want: +\n%s", diff) } // Add a PushConfig and change other fields. pc := PushConfig{ Endpoint: "https://" + projID + ".appspot.com/_ah/push-handlers/push", Attributes: map[string]string{"x-goog-version": "v1"}, AuthenticationMethod: &OIDCToken{ Audience: "client-updated-54321", ServiceAccountEmail: serviceAccountEmail, }, } got, err = sub.Update(ctx, SubscriptionConfigToUpdate{ PushConfig: &pc, AckDeadline: 2 * time.Minute, RetainAckedMessages: true, RetentionDuration: 2 * time.Hour, Labels: map[string]string{"label": "value"}, ExpirationPolicy: 25 * time.Hour, }) if err != nil { t.Fatal(err) } want = SubscriptionConfig{ Topic: topic, PushConfig: pc, AckDeadline: 2 * time.Minute, RetainAckedMessages: true, RetentionDuration: 2 * time.Hour, Labels: map[string]string{"label": "value"}, ExpirationPolicy: 25 * time.Hour, } if !testutil.Equal(got, want) { t.Fatalf("\ngot %+v\nwant %+v", got, want) } // Update ExpirationPolicy to never expire. got, err = sub.Update(ctx, SubscriptionConfigToUpdate{ ExpirationPolicy: time.Duration(0), }) if err != nil { t.Fatal(err) } want.ExpirationPolicy = time.Duration(0) if !testutil.Equal(got, want) { t.Fatalf("\ngot %+v\nwant %+v", got, want) } // Remove the PushConfig, turning the subscription back into pull mode. // Change AckDeadline, remove labels. pc = PushConfig{} got, err = sub.Update(ctx, SubscriptionConfigToUpdate{ PushConfig: &pc, AckDeadline: 30 * time.Second, Labels: map[string]string{}, }) if err != nil { t.Fatal(err) } want.PushConfig = pc want.AckDeadline = 30 * time.Second want.Labels = nil // service issue: PushConfig attributes are not removed. // TODO(jba): remove when issue resolved. want.PushConfig.Attributes = map[string]string{"x-goog-version": "v1"} if !testutil.Equal(got, want) { t.Fatalf("\ngot %+v\nwant %+v", got, want) } // If nothing changes, our client returns an error. _, err = sub.Update(ctx, SubscriptionConfigToUpdate{}) if err == nil { t.Fatal("got nil, wanted error") } } func TestIntegration_UpdateSubscription_ExpirationPolicy(t *testing.T) { t.Parallel() ctx := context.Background() client := integrationTestClient(ctx, t) defer client.Close() topic, err := client.CreateTopic(ctx, topicIDs.New()) if err != nil { t.Fatalf("CreateTopic error: %v", err) } defer topic.Delete(ctx) defer topic.Stop() var sub *Subscription if sub, err = client.CreateSubscription(ctx, subIDs.New(), SubscriptionConfig{Topic: topic}); err != nil { t.Fatalf("CreateSub error: %v", err) } defer sub.Delete(ctx) // Set ExpirationPolicy within the valid range. got, err := sub.Update(ctx, SubscriptionConfigToUpdate{ RetentionDuration: 2 * time.Hour, ExpirationPolicy: 25 * time.Hour, AckDeadline: 2 * time.Minute, }) if err != nil { t.Fatal(err) } want := SubscriptionConfig{ Topic: topic, AckDeadline: 2 * time.Minute, RetentionDuration: 2 * time.Hour, ExpirationPolicy: 25 * time.Hour, } // Pubsub service issue: PushConfig attributes are not removed. // TODO(jba): remove when issue resolved. want.PushConfig.Attributes = map[string]string{"x-goog-version": "v1"} if diff := testutil.Diff(got, want); diff != "" { t.Fatalf("\ngot: - want: +\n%s", diff) } // ExpirationPolicy to never expire. got, err = sub.Update(ctx, SubscriptionConfigToUpdate{ ExpirationPolicy: time.Duration(0), }) if err != nil { t.Fatalf("Unexpected error: %v\n", err) } want.ExpirationPolicy = time.Duration(0) if diff := testutil.Diff(got, want); diff != "" { t.Fatalf("\ngot: - want: +\n%s", diff) } // ExpirationPolicy when nil is passed in, should not cause any updates. got, err = sub.Update(ctx, SubscriptionConfigToUpdate{ ExpirationPolicy: nil, }) if err == nil || err.Error() != "pubsub: UpdateSubscription call with nothing to update" { t.Fatalf("Expected no attributes to be updated, error: %v", err) } // ExpirationPolicy of nil, with the previous value having been a non-zero value. _, err = sub.Update(ctx, SubscriptionConfigToUpdate{ ExpirationPolicy: 26 * time.Hour, }) if err != nil { t.Fatal(err) } // Now examine what setting it to nil produces. _, err = sub.Update(ctx, SubscriptionConfigToUpdate{ ExpirationPolicy: nil, }) if err == nil || err.Error() != "pubsub: UpdateSubscription call with nothing to update" { t.Fatalf("Expected no attributes to be updated, error: %v", err) } } // NOTE: This test should be skipped by open source contributors. It requires // whitelisting, a (gsuite) organization project, and specific permissions. func TestIntegration_UpdateTopicLabels(t *testing.T) { t.Skip("https://github.com/googleapis/google-cloud-go/issues/1669") t.Parallel() ctx := context.Background() client := integrationTestClient(ctx, t) defer client.Close() compareConfig := func(got TopicConfig, wantLabels map[string]string) bool { if !testutil.Equal(got.Labels, wantLabels) { return false } // For MessageStoragePolicy, we don't want to check for an exact set of regions. // That set may change at any time. Instead, just make sure that the set isn't empty. if len(got.MessageStoragePolicy.AllowedPersistenceRegions) == 0 { return false } return true } topic, err := client.CreateTopic(ctx, topicIDs.New()) if err != nil { t.Fatalf("CreateTopic error: %v", err) } defer topic.Delete(ctx) defer topic.Stop() got, err := topic.Config(ctx) if err != nil { t.Fatal(err) } if !compareConfig(got, nil) { t.Fatalf("\ngot %+v\nwant no labels", got) } labels := map[string]string{"label": "value"} got, err = topic.Update(ctx, TopicConfigToUpdate{Labels: labels}) if err != nil { t.Fatal(err) } if !compareConfig(got, labels) { t.Fatalf("\ngot %+v\nwant labels %+v", got, labels) } // Remove all labels. got, err = topic.Update(ctx, TopicConfigToUpdate{Labels: map[string]string{}}) if err != nil { t.Fatal(err) } if !compareConfig(got, nil) { t.Fatalf("\ngot %+v\nwant no labels", got) } } func TestIntegration_PublicTopic(t *testing.T) { t.Parallel() ctx := context.Background() client := integrationTestClient(ctx, t) defer client.Close() sub, err := client.CreateSubscription(ctx, subIDs.New(), SubscriptionConfig{ Topic: client.TopicInProject("taxirides-realtime", "pubsub-public-data"), }) if err != nil { t.Fatal(err) } defer sub.Delete(ctx) // Confirm that Receive works. It doesn't matter if we actually get any // messages. ctxt, cancel := context.WithTimeout(ctx, 5*time.Second) err = sub.Receive(ctxt, func(_ context.Context, msg *Message) { msg.Ack() cancel() }) if err != nil { t.Fatal(err) } } func TestIntegration_Errors(t *testing.T) { // Test various edge conditions. t.Parallel() ctx := context.Background() client := integrationTestClient(ctx, t) defer client.Close() topic, err := client.CreateTopic(ctx, topicIDs.New()) if err != nil { t.Fatalf("CreateTopic error: %v", err) } defer topic.Delete(ctx) defer topic.Stop() // Out-of-range retention duration. sub, err := client.CreateSubscription(ctx, subIDs.New(), SubscriptionConfig{ Topic: topic, RetentionDuration: 1 * time.Second, }) if want := codes.InvalidArgument; status.Code(err) != want { t.Errorf("got <%v>, want %s", err, want) } if err == nil { sub.Delete(ctx) } // Ack deadline less than minimum. sub, err = client.CreateSubscription(ctx, subIDs.New(), SubscriptionConfig{ Topic: topic, AckDeadline: 5 * time.Second, }) if want := codes.Unknown; status.Code(err) != want { t.Errorf("got <%v>, want %s", err, want) } if err == nil { sub.Delete(ctx) } // Updating a non-existent subscription. sub = client.Subscription(subIDs.New()) _, err = sub.Update(ctx, SubscriptionConfigToUpdate{AckDeadline: 20 * time.Second}) if want := codes.NotFound; status.Code(err) != want { t.Errorf("got <%v>, want %s", err, want) } // Deleting a non-existent subscription. err = sub.Delete(ctx) if want := codes.NotFound; status.Code(err) != want { t.Errorf("got <%v>, want %s", err, want) } // Updating out-of-range retention duration. sub, err = client.CreateSubscription(ctx, subIDs.New(), SubscriptionConfig{Topic: topic}) if err != nil { t.Fatal(err) } defer sub.Delete(ctx) _, err = sub.Update(ctx, SubscriptionConfigToUpdate{RetentionDuration: 1000 * time.Hour}) if want := codes.InvalidArgument; status.Code(err) != want { t.Errorf("got <%v>, want %s", err, want) } } func TestIntegration_MessageStoragePolicy_TopicLevel(t *testing.T) { t.Skip("https://github.com/googleapis/google-cloud-go/issues/1599") t.Parallel() ctx := context.Background() client := integrationTestClient(ctx, t) defer client.Close() topic, err := client.CreateTopic(ctx, topicIDs.New()) if err != nil { t.Fatalf("CreateTopic error: %v", err) } defer topic.Delete(ctx) defer topic.Stop() // Initially the message storage policy should just be non-empty got, err := topic.Config(ctx) if err != nil { t.Fatal(err) } if len(got.MessageStoragePolicy.AllowedPersistenceRegions) == 0 { t.Fatalf("Empty AllowedPersistenceRegions in :\n%+v", got) } // Specify some regions to set. regions := []string{"asia-east1", "us-east1"} got, err = topic.Update(ctx, TopicConfigToUpdate{ MessageStoragePolicy: &MessageStoragePolicy{ AllowedPersistenceRegions: regions, }, }) if err != nil { t.Fatal(err) } want := TopicConfig{ MessageStoragePolicy: MessageStoragePolicy{ AllowedPersistenceRegions: regions, }, } if !testutil.Equal(got, want) { t.Fatalf("\ngot %+v\nwant regions%+v", got, want) } // Reset all allowed regions to project default. got, err = topic.Update(ctx, TopicConfigToUpdate{ MessageStoragePolicy: &MessageStoragePolicy{}, }) if err != nil { t.Fatal(err) } if len(got.MessageStoragePolicy.AllowedPersistenceRegions) == 0 { t.Fatalf("Unexpectedly got empty MessageStoragePolicy.AllowedPersistenceRegions in:\n%+v", got) } // Removing all regions should fail updateCfg := TopicConfigToUpdate{ MessageStoragePolicy: &MessageStoragePolicy{ AllowedPersistenceRegions: []string{}, }, } if _, err = topic.Update(ctx, updateCfg); err == nil { t.Fatalf("Unexpected succeeded in removing all regions\n%+v\n", got) } } // NOTE: This test should be skipped by open source contributors. It requires // a (gsuite) organization project, and specific permissions. The test for MessageStoragePolicy // on a topic level can be run on any topic and is covered by the previous test. // // Googlers, see internal bug 77920644. Furthermore, be sure to add your // service account as an owner of ps-geofencing-test. func TestIntegration_MessageStoragePolicy_ProjectLevel(t *testing.T) { // Verify that the message storage policy is populated. if testing.Short() { t.Skip("Integration tests skipped in short mode") } ctx := context.Background() // If a message storage policy is not set on a topic, the policy depends on the Resource Location // Restriction which is specified on an organization level. The usual testing project is in the // google.com org, which has no resource location restrictions. Use a project in another org that // does have a restriction set ("us-east1"). projID := "ps-geofencing-test" // We can use the same creds as always because the service account of the default testing project // has permission to use the above project. This test will fail if a different service account // is used for testing. ts := testutil.TokenSource(ctx, ScopePubSub, ScopeCloudPlatform) if ts == nil { t.Skip("Integration tests skipped. See CONTRIBUTING.md for details") } opts := withGRPCHeadersAssertion(t, option.WithTokenSource(ts)) client, err := NewClient(ctx, projID, opts...) if err != nil { t.Fatalf("Creating client error: %v", err) } topic, err := client.CreateTopic(ctx, topicIDs.New()) if err != nil { t.Fatalf("CreateTopic error: %v", err) } defer topic.Delete(ctx) defer topic.Stop() config, err := topic.Config(ctx) if err != nil { t.Fatal(err) } got := config.MessageStoragePolicy.AllowedPersistenceRegions want := []string{"us-east1"} if !testutil.Equal(got, want) { t.Errorf("got %v, want %v", got, want) } } func TestIntegration_CreateTopic_KMS(t *testing.T) { t.Parallel() ctx := context.Background() client := integrationTestClient(ctx, t) defer client.Close() kmsClient, err := kms.NewKeyManagementClient(ctx) if err != nil { t.Fatal(err) } keyRingID := "test-key-ring" want := "test-key2" // Get the test KMS key ring, optionally creating it if it doesn't exist. keyRing, err := kmsClient.GetKeyRing(ctx, &kmspb.GetKeyRingRequest{ Name: fmt.Sprintf("projects/%s/locations/global/keyRings/%s", testutil.ProjID(), keyRingID), }) if err != nil { if status.Code(err) != codes.NotFound { t.Fatal(err) } createKeyRingReq := &kmspb.CreateKeyRingRequest{ Parent: fmt.Sprintf("projects/%s/locations/global", testutil.ProjID()), KeyRingId: keyRingID, } keyRing, err = kmsClient.CreateKeyRing(ctx, createKeyRingReq) if err != nil { t.Fatal(err) } } // Get the test KMS crypto key, optionally creating it if it doesn't exist. key, err := kmsClient.GetCryptoKey(ctx, &kmspb.GetCryptoKeyRequest{ Name: fmt.Sprintf("%s/cryptoKeys/%s", keyRing.GetName(), want), }) if err != nil { if status.Code(err) != codes.NotFound { t.Fatal(err) } createKeyReq := &kmspb.CreateCryptoKeyRequest{ Parent: keyRing.GetName(), CryptoKeyId: want, CryptoKey: &kmspb.CryptoKey{ Purpose: 1, // ENCRYPT_DECRYPT purpose }, } key, err = kmsClient.CreateCryptoKey(ctx, createKeyReq) if err != nil { t.Fatal(err) } } tc := TopicConfig{ KMSKeyName: key.GetName(), } topic, err := client.CreateTopicWithConfig(ctx, topicIDs.New(), &tc) if err != nil { t.Fatalf("CreateTopicWithConfig error: %v", err) } defer topic.Delete(ctx) defer topic.Stop() cfg, err := topic.Config(ctx) if err != nil { t.Fatal(err) } got := cfg.KMSKeyName if got != key.GetName() { t.Errorf("got %v, want %v", got, key.GetName()) } } func TestIntegration_CreateTopic_MessageStoragePolicy(t *testing.T) { t.Parallel() ctx := context.Background() client := integrationTestClient(ctx, t) defer client.Close() tc := TopicConfig{ MessageStoragePolicy: MessageStoragePolicy{ AllowedPersistenceRegions: []string{"us-east1"}, }, } topic, err := client.CreateTopicWithConfig(ctx, topicIDs.New(), &tc) if err != nil { t.Fatalf("CreateTopicWithConfig error: %v", err) } defer topic.Delete(ctx) defer topic.Stop() got, err := topic.Config(ctx) if err != nil { t.Fatal(err) } want := tc if diff := testutil.Diff(got, want); diff != "" { t.Fatalf("\ngot: - want: +\n%s", diff) } } google-cloud-go-0.49.0/pubsub/internal/000077500000000000000000000000001356504100700177045ustar00rootroot00000000000000google-cloud-go-0.49.0/pubsub/internal/benchwrapper/000077500000000000000000000000001356504100700223645ustar00rootroot00000000000000google-cloud-go-0.49.0/pubsub/internal/benchwrapper/README.md000066400000000000000000000004141356504100700236420ustar00rootroot00000000000000# Benchwrapper A small gRPC wrapper around the pubsub client library. This allows the benchmarking code to prod at pubsub without speaking Go. ## Running ```bash cd pubsub/internal/benchwrapper export PUBSUB_EMULATOR_HOST=localhost:8080 go run *.go --port=8081 ``` google-cloud-go-0.49.0/pubsub/internal/benchwrapper/main.go000066400000000000000000000041411356504100700236370ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package main wraps the client library in a gRPC interface that a benchmarker // can communicate through. package main import ( "context" "flag" "fmt" "log" "net" "os" "strings" "cloud.google.com/go/pubsub" pb "cloud.google.com/go/pubsub/internal/benchwrapper/proto" "google.golang.org/grpc" "google.golang.org/grpc/status" ) var port = flag.String("port", "", "specify a port to run on") func main() { flag.Parse() if *port == "" { log.Fatalf("usage: %s --port=8081", os.Args[0]) } if os.Getenv("PUBSUB_EMULATOR_HOST") == "" { log.Fatal("This benchmarking server only works when connected to an emulator. Please set PUBSUB_EMULATOR_HOST.") } ctx := context.Background() c, err := pubsub.NewClient(ctx, "someproject") if err != nil { log.Fatal(err) } lis, err := net.Listen("tcp", fmt.Sprintf(":%s", *port)) if err != nil { log.Fatal(err) } s := grpc.NewServer() pb.RegisterPubsubBenchWrapperServer(s, &server{ c: c, }) log.Printf("Running on localhost:%s\n", *port) log.Fatal(s.Serve(lis)) } type server struct { c *pubsub.Client } func (s *server) Recv(ctx context.Context, req *pb.PubsubRecv) (*pb.EmptyResponse, error) { sub := s.c.Subscription(req.SubName) err := sub.Receive(ctx, func(ctx context.Context, msg *pubsub.Message) { msg.Ack() }) if err != nil { s, _ := status.FromError(err) // Return success on server initiated EOF, which is expected. if strings.Contains(s.Message(), "EOF") { return &pb.EmptyResponse{}, nil } return nil, err } return &pb.EmptyResponse{}, nil } google-cloud-go-0.49.0/pubsub/internal/benchwrapper/proto/000077500000000000000000000000001356504100700235275ustar00rootroot00000000000000google-cloud-go-0.49.0/pubsub/internal/benchwrapper/proto/README.md000066400000000000000000000001541356504100700250060ustar00rootroot00000000000000# Regenerating protos ``` cd pubsub/internal/benchwrapper/proto protoc --go_out=plugins=grpc:. *.proto ``` google-cloud-go-0.49.0/pubsub/internal/benchwrapper/proto/pubsub.pb.go000066400000000000000000000162621356504100700257650ustar00rootroot00000000000000// Code generated by protoc-gen-go. DO NOT EDIT. // source: pubsub.proto package pubsub_bench import ( context "context" fmt "fmt" math "math" proto "github.com/golang/protobuf/proto" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" ) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal var _ = fmt.Errorf var _ = math.Inf // This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package type PubsubRecv struct { // The subscription identifier corresponding to number of messages sent. SubName string `protobuf:"bytes,1,opt,name=sub_name,json=subName,proto3" json:"sub_name,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *PubsubRecv) Reset() { *m = PubsubRecv{} } func (m *PubsubRecv) String() string { return proto.CompactTextString(m) } func (*PubsubRecv) ProtoMessage() {} func (*PubsubRecv) Descriptor() ([]byte, []int) { return fileDescriptor_91df006b05e20cf7, []int{0} } func (m *PubsubRecv) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PubsubRecv.Unmarshal(m, b) } func (m *PubsubRecv) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_PubsubRecv.Marshal(b, m, deterministic) } func (m *PubsubRecv) XXX_Merge(src proto.Message) { xxx_messageInfo_PubsubRecv.Merge(m, src) } func (m *PubsubRecv) XXX_Size() int { return xxx_messageInfo_PubsubRecv.Size(m) } func (m *PubsubRecv) XXX_DiscardUnknown() { xxx_messageInfo_PubsubRecv.DiscardUnknown(m) } var xxx_messageInfo_PubsubRecv proto.InternalMessageInfo func (m *PubsubRecv) GetSubName() string { if m != nil { return m.SubName } return "" } // TODO(deklerk): Replace with Google's canonical Empty. type EmptyResponse struct { XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *EmptyResponse) Reset() { *m = EmptyResponse{} } func (m *EmptyResponse) String() string { return proto.CompactTextString(m) } func (*EmptyResponse) ProtoMessage() {} func (*EmptyResponse) Descriptor() ([]byte, []int) { return fileDescriptor_91df006b05e20cf7, []int{1} } func (m *EmptyResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_EmptyResponse.Unmarshal(m, b) } func (m *EmptyResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_EmptyResponse.Marshal(b, m, deterministic) } func (m *EmptyResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_EmptyResponse.Merge(m, src) } func (m *EmptyResponse) XXX_Size() int { return xxx_messageInfo_EmptyResponse.Size(m) } func (m *EmptyResponse) XXX_DiscardUnknown() { xxx_messageInfo_EmptyResponse.DiscardUnknown(m) } var xxx_messageInfo_EmptyResponse proto.InternalMessageInfo func init() { proto.RegisterType((*PubsubRecv)(nil), "pubsub_bench.PubsubRecv") proto.RegisterType((*EmptyResponse)(nil), "pubsub_bench.EmptyResponse") } func init() { proto.RegisterFile("pubsub.proto", fileDescriptor_91df006b05e20cf7) } var fileDescriptor_91df006b05e20cf7 = []byte{ // 147 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x29, 0x28, 0x4d, 0x2a, 0x2e, 0x4d, 0xd2, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x82, 0xf2, 0xe2, 0x93, 0x52, 0xf3, 0x92, 0x33, 0x94, 0xd4, 0xb9, 0xb8, 0x02, 0xc0, 0xfc, 0xa0, 0xd4, 0xe4, 0x32, 0x21, 0x49, 0x2e, 0x0e, 0x90, 0x54, 0x5e, 0x62, 0x6e, 0xaa, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0x67, 0x10, 0x7b, 0x71, 0x69, 0x92, 0x5f, 0x62, 0x6e, 0xaa, 0x12, 0x3f, 0x17, 0xaf, 0x6b, 0x6e, 0x41, 0x49, 0x65, 0x50, 0x6a, 0x71, 0x41, 0x7e, 0x5e, 0x71, 0xaa, 0x51, 0x28, 0x97, 0x10, 0x44, 0xa7, 0x13, 0xc8, 0xa0, 0xf0, 0xa2, 0xc4, 0x82, 0x82, 0xd4, 0x22, 0x21, 0x7b, 0x2e, 0x16, 0xb0, 0x49, 0x12, 0x7a, 0xc8, 0xd6, 0xe8, 0x21, 0xec, 0x90, 0x92, 0x46, 0x95, 0x41, 0x31, 0x54, 0x89, 0xc1, 0x89, 0x29, 0x80, 0x31, 0x89, 0x0d, 0xec, 0x52, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe3, 0xea, 0xe3, 0xed, 0xb9, 0x00, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. var _ context.Context var _ grpc.ClientConn // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. const _ = grpc.SupportPackageIsVersion4 // PubsubBenchWrapperClient is the client API for PubsubBenchWrapper service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type PubsubBenchWrapperClient interface { // Recv represents opening a streaming pull stream to receive messages on. Recv(ctx context.Context, in *PubsubRecv, opts ...grpc.CallOption) (*EmptyResponse, error) } type pubsubBenchWrapperClient struct { cc *grpc.ClientConn } func NewPubsubBenchWrapperClient(cc *grpc.ClientConn) PubsubBenchWrapperClient { return &pubsubBenchWrapperClient{cc} } func (c *pubsubBenchWrapperClient) Recv(ctx context.Context, in *PubsubRecv, opts ...grpc.CallOption) (*EmptyResponse, error) { out := new(EmptyResponse) err := c.cc.Invoke(ctx, "/pubsub_bench.PubsubBenchWrapper/Recv", in, out, opts...) if err != nil { return nil, err } return out, nil } // PubsubBenchWrapperServer is the server API for PubsubBenchWrapper service. type PubsubBenchWrapperServer interface { // Recv represents opening a streaming pull stream to receive messages on. Recv(context.Context, *PubsubRecv) (*EmptyResponse, error) } // UnimplementedPubsubBenchWrapperServer can be embedded to have forward compatible implementations. type UnimplementedPubsubBenchWrapperServer struct { } func (*UnimplementedPubsubBenchWrapperServer) Recv(ctx context.Context, req *PubsubRecv) (*EmptyResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Recv not implemented") } func RegisterPubsubBenchWrapperServer(s *grpc.Server, srv PubsubBenchWrapperServer) { s.RegisterService(&_PubsubBenchWrapper_serviceDesc, srv) } func _PubsubBenchWrapper_Recv_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(PubsubRecv) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(PubsubBenchWrapperServer).Recv(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/pubsub_bench.PubsubBenchWrapper/Recv", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(PubsubBenchWrapperServer).Recv(ctx, req.(*PubsubRecv)) } return interceptor(ctx, in, info, handler) } var _PubsubBenchWrapper_serviceDesc = grpc.ServiceDesc{ ServiceName: "pubsub_bench.PubsubBenchWrapper", HandlerType: (*PubsubBenchWrapperServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "Recv", Handler: _PubsubBenchWrapper_Recv_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "pubsub.proto", } google-cloud-go-0.49.0/pubsub/internal/benchwrapper/proto/pubsub.proto000066400000000000000000000020061356504100700261120ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. syntax = "proto3"; package pubsub_bench; option java_multiple_files = true; message PubsubRecv { // The subscription identifier corresponding to number of messages sent. string sub_name = 1; } // TODO(deklerk): Replace with Google's canonical Empty. message EmptyResponse {} service PubsubBenchWrapper { // Recv represents opening a streaming pull stream to receive messages on. rpc Recv(PubsubRecv) returns (EmptyResponse) {} }google-cloud-go-0.49.0/pubsub/internal/distribution/000077500000000000000000000000001356504100700224235ustar00rootroot00000000000000google-cloud-go-0.49.0/pubsub/internal/distribution/distribution.go000066400000000000000000000043621356504100700254760ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package distribution import ( "log" "math" "sort" "sync" "sync/atomic" ) // D is a distribution. Methods of D can be called concurrently by multiple // goroutines. type D struct { buckets []uint64 // sumsReuse is the scratch space that is reused // to store sums during invocations of Percentile. // After an invocation of New(n): // len(buckets) == len(sumsReuse) == n sumsReuse []uint64 mu sync.Mutex } // New creates a new distribution capable of holding values from 0 to n-1. func New(n int) *D { return &D{ buckets: make([]uint64, n), sumsReuse: make([]uint64, n), } } // Record records value v to the distribution. // To help with distributions with long tails, if v is larger than the maximum value, // Record records the maximum value instead. // If v is negative, Record panics. func (d *D) Record(v int) { if v < 0 { log.Panicf("Record: value out of range: %d", v) } else if v >= len(d.buckets) { v = len(d.buckets) - 1 } atomic.AddUint64(&d.buckets[v], 1) } // Percentile computes the p-th percentile of the distribution where // p is between 0 and 1. This method may be called by multiple goroutines. func (d *D) Percentile(p float64) int { // NOTE: This implementation uses the nearest-rank method. // https://en.wikipedia.org/wiki/Percentile#The_nearest-rank_method if p < 0 || p > 1 { log.Panicf("Percentile: percentile out of range: %f", p) } d.mu.Lock() defer d.mu.Unlock() var sum uint64 for i := range d.sumsReuse { sum += atomic.LoadUint64(&d.buckets[i]) d.sumsReuse[i] = sum } target := uint64(math.Ceil(float64(sum) * p)) return sort.Search(len(d.sumsReuse), func(i int) bool { return d.sumsReuse[i] >= target }) } google-cloud-go-0.49.0/pubsub/internal/distribution/distribution_test.go000066400000000000000000000046151356504100700265360ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package distribution import ( "sync" "testing" ) func TestDistribution(t *testing.T) { // These tests come from examples in https://en.wikipedia.org/wiki/Percentile#The_nearest-rank_method tests := []struct { // values in distribution vals []int // percentiles and expected percentile values pp []float64 vv []int }{ { vals: []int{15, 20, 35, 40, 50}, pp: []float64{0.05, 0.3, 0.4, 0.5, 1}, vv: []int{15, 20, 20, 35, 50}, }, { vals: []int{3, 6, 7, 8, 8, 10, 13, 15, 16, 20}, pp: []float64{0.25, 0.5, 0.75, 1}, vv: []int{7, 8, 15, 20}, }, { vals: []int{3, 6, 7, 8, 8, 9, 10, 13, 15, 16, 20}, pp: []float64{0.25, 0.5, 0.75, 1}, vv: []int{7, 9, 15, 20}, }, } maxVal := 0 for _, tst := range tests { for _, v := range tst.vals { if maxVal < v { maxVal = v } } } for _, tst := range tests { d := New(maxVal + 1) for _, v := range tst.vals { d.Record(v) } for i, p := range tst.pp { got, want := d.Percentile(p), tst.vv[i] if got != want { t.Errorf("d=%v, d.Percentile(%f)=%d, want %d", d, p, got, want) } } } } func TestRace(t *testing.T) { const N int = 1e3 const parallel = 2 d := New(N) var wg sync.WaitGroup wg.Add(parallel) for i := 0; i < parallel; i++ { go func() { for i := 0; i < N; i++ { d.Record(i) } wg.Done() }() } for i := 0; i < N; i++ { if p := d.Percentile(0.5); p > N { t.Fatalf("d.Percentile(0.5)=%d, expected to be at most %d", p, N) } } } func BenchmarkDistribution(b *testing.B) { const N int = 1e3 d := New(N) for i := 0; i < N; i++ { d.Record(i) } b.ResetTimer() b.ReportAllocs() var index int for i := 0; i < b.N; i++ { if index = d.Percentile(0.5); index < 0 { b.Fatalf("Invalid index: %d", index) } } if index == 0 { b.Fatal("Benchmark did not run") } } google-cloud-go-0.49.0/pubsub/internal/longtest/000077500000000000000000000000001356504100700215435ustar00rootroot00000000000000google-cloud-go-0.49.0/pubsub/internal/longtest/endtoend_test.go000066400000000000000000000277101356504100700247400ustar00rootroot00000000000000// Copyright 2014 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package longtest_test import ( "context" "fmt" "log" "math/rand" "strconv" "strings" "sync" "testing" "time" "cloud.google.com/go/internal/testutil" "cloud.google.com/go/pubsub" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) const ( timeout = time.Minute * 10 ackDeadline = time.Second * 10 nMessages = 1e4 acceptableDupPercentage = 1 numAcceptableDups = int(nMessages * acceptableDupPercentage / 100) ) // The end-to-end pumps many messages into a topic and tests that they are all // delivered to each subscription for the topic. It also tests that messages // are not unexpectedly redelivered. func TestEndToEnd_Dupes(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() client, topic, cleanup := prepareEndToEndTest(ctx, t) defer cleanup() subPrefix := fmt.Sprintf("endtoend-%d", time.Now().UnixNano()) // Two subscriptions to the same topic. var err error var subs [2]*pubsub.Subscription for i := 0; i < len(subs); i++ { subs[i], err = client.CreateSubscription(ctx, fmt.Sprintf("%s-%d", subPrefix, i), pubsub.SubscriptionConfig{ Topic: topic, AckDeadline: ackDeadline, }) if err != nil { t.Fatalf("CreateSub error: %v", err) } defer subs[i].Delete(ctx) } err = publish(ctx, topic, nMessages) topic.Stop() if err != nil { t.Fatalf("publish: %v", err) } // recv provides an indication that messages are still arriving. recv := make(chan struct{}) // We have two subscriptions to our topic. // Each subscription will get a copy of each published message. var wg sync.WaitGroup cctx, cancel := context.WithTimeout(ctx, timeout) defer cancel() consumers := []*consumer{ { counts: make(map[string]int), recv: recv, durations: []time.Duration{time.Hour}, done: make(chan struct{}), }, { counts: make(map[string]int), recv: recv, durations: []time.Duration{ackDeadline, ackDeadline, ackDeadline / 2, ackDeadline / 2, time.Hour}, done: make(chan struct{}), }, } for i, con := range consumers { con := con sub := subs[i] wg.Add(1) go func() { defer wg.Done() con.consume(ctx, t, sub) }() } // Wait for a while after the last message before declaring quiescence. // We wait a multiple of the ack deadline, for two reasons: // 1. To detect if messages are redelivered after having their ack // deadline extended. // 2. To wait for redelivery of messages that were en route when a Receive // is canceled. This can take considerably longer than the ack deadline. quiescenceDur := ackDeadline * 6 quiescenceTimer := time.NewTimer(quiescenceDur) loop: for { select { case <-recv: // Reset timer so we wait quiescenceDur after the last message. // See https://godoc.org/time#Timer.Reset for why the Stop // and channel drain are necessary. if !quiescenceTimer.Stop() { <-quiescenceTimer.C } quiescenceTimer.Reset(quiescenceDur) case <-quiescenceTimer.C: cancel() log.Println("quiesced") break loop case <-cctx.Done(): t.Fatal("timed out") } } wg.Wait() for i, con := range consumers { var numDups int var zeroes int for _, v := range con.counts { if v == 0 { zeroes++ } numDups += v - 1 } if zeroes > 0 { t.Errorf("Consumer %d: %d messages never arrived", i, zeroes) } else if numDups > numAcceptableDups { t.Errorf("Consumer %d: Willing to accept %d dups (%v duplicated of %d messages), but got %d", i, numAcceptableDups, acceptableDupPercentage, int(nMessages), numDups) } } for i, con := range consumers { select { case <-con.done: case <-time.After(15 * time.Second): t.Fatalf("timed out waiting for consumer %d to finish", i) } } } func TestEndToEnd_LongProcessingTime(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() client, topic, cleanup := prepareEndToEndTest(ctx, t) defer cleanup() subPrefix := fmt.Sprintf("endtoend-%d", time.Now().UnixNano()) // Two subscriptions to the same topic. sub, err := client.CreateSubscription(ctx, subPrefix+"-00", pubsub.SubscriptionConfig{ Topic: topic, AckDeadline: ackDeadline, }) if err != nil { t.Fatalf("CreateSub error: %v", err) } defer sub.Delete(ctx) // Tests the issue found in https://github.com/googleapis/google-cloud-go/issues/1247. sub.ReceiveSettings.Synchronous = true sub.ReceiveSettings.MaxOutstandingMessages = 500 err = publish(ctx, topic, 1000) topic.Stop() if err != nil { t.Fatalf("publish: %v", err) } // recv provides an indication that messages are still arriving. recv := make(chan struct{}) consumer := consumer{ counts: make(map[string]int), recv: recv, durations: []time.Duration{time.Hour}, processingDelay: func() time.Duration { return time.Duration(1+rand.Int63n(120)) * time.Second }, done: make(chan struct{}), } go consumer.consume(ctx, t, sub) // Wait for a while after the last message before declaring quiescence. // We wait a multiple of the ack deadline, for two reasons: // 1. To detect if messages are redelivered after having their ack // deadline extended. // 2. To wait for redelivery of messages that were en route when a Receive // is canceled. This can take considerably longer than the ack deadline. quiescenceDur := ackDeadline * 6 quiescenceTimer := time.NewTimer(quiescenceDur) loop: for { select { case <-recv: // Reset timer so we wait quiescenceDur after the last message. // See https://godoc.org/time#Timer.Reset for why the Stop // and channel drain are necessary. if !quiescenceTimer.Stop() { <-quiescenceTimer.C } quiescenceTimer.Reset(quiescenceDur) case <-quiescenceTimer.C: cancel() log.Println("quiesced") break loop case <-ctx.Done(): t.Fatal("timed out") } } var numDups int var zeroes int for _, v := range consumer.counts { if v == 0 { zeroes++ } numDups += v - 1 } if zeroes > 0 { t.Errorf("%d messages never arrived", zeroes) } else if numDups > numAcceptableDups { t.Errorf("Willing to accept %d dups (%v duplicated of %d messages), but got %d", numAcceptableDups, acceptableDupPercentage, int(nMessages), numDups) } select { case <-consumer.done: case <-time.After(15 * time.Second): t.Fatal("timed out waiting for consumer to finish") } } // publish publishes n messages to topic. func publish(ctx context.Context, topic *pubsub.Topic, n int) error { var rs []*pubsub.PublishResult for i := 0; i < n; i++ { m := &pubsub.Message{Data: []byte(fmt.Sprintf("msg %d", i))} rs = append(rs, topic.Publish(ctx, m)) } for _, r := range rs { _, err := r.Get(ctx) if err != nil { return err } } return nil } // consumer consumes messages according to its configuration. type consumer struct { // A consumer will spin out a Receive for each duration, which will be // canceled after each duration and the next one spun up. For example, if // there are 5 3 second durations, then there will be 5 3 second Receives. durations []time.Duration // A value is sent to recv each time Inc is called. recv chan struct{} // How long to wait for before acking. processingDelay func() time.Duration mu sync.Mutex counts map[string]int // msgID: recvdAmt totalRecvd int // Done consuming. done chan struct{} } // consume reads messages from a subscription, and keeps track of what it receives in mc. // After consume returns, the caller should wait on wg to ensure that no more updates to mc will be made. func (c *consumer) consume(ctx context.Context, t *testing.T, sub *pubsub.Subscription) { defer close(c.done) for _, dur := range c.durations { ctx2, cancel := context.WithTimeout(ctx, dur) defer cancel() id := sub.String()[len(sub.String())-1:] t.Logf("%s: start receive", id) prev := c.totalRecvd err := sub.Receive(ctx2, c.process) t.Logf("%s: end receive; read %d", id, c.totalRecvd-prev) if serr, _ := status.FromError(err); err != nil && serr.Code() != codes.Canceled { panic(err) } select { case <-ctx.Done(): return default: } } } // process handles a message and records it in mc. func (c *consumer) process(_ context.Context, m *pubsub.Message) { c.mu.Lock() c.counts[m.ID]++ c.totalRecvd++ c.mu.Unlock() c.recv <- struct{}{} var delay time.Duration if c.processingDelay == nil { delay = time.Duration(rand.Intn(int(ackDeadline * 3))) } else { delay = c.processingDelay() } // Simulate time taken to process m, while continuing to process more messages. // Some messages will need to have their ack deadline extended due to this delay. time.AfterFunc(delay, func() { m.Ack() }) } // Remember to call cleanup! func prepareEndToEndTest(ctx context.Context, t *testing.T) (*pubsub.Client, *pubsub.Topic, func()) { if testing.Short() { t.Skip("Integration tests skipped in short mode") } ts := testutil.TokenSource(ctx, pubsub.ScopePubSub, pubsub.ScopeCloudPlatform) if ts == nil { t.Skip("Integration tests skipped. See CONTRIBUTING.md for details") } now := time.Now() topicName := fmt.Sprintf("endtoend-%d", now.UnixNano()) client, err := pubsub.NewClient(ctx, testutil.ProjID(), option.WithTokenSource(ts)) if err != nil { t.Fatalf("Creating client error: %v", err) } // Don't stop the test if cleanup failed. if err := cleanupSubscription(ctx, client); err != nil { t.Logf("Pre-test subscription cleanup failed: %v", err) } if err := cleanupTopic(ctx, client); err != nil { t.Logf("Pre-test topic cleanup failed: %v", err) } var topic *pubsub.Topic if topic, err = client.CreateTopic(ctx, topicName); err != nil { t.Fatalf("CreateTopic error: %v", err) } return client, topic, func() { topic.Delete(ctx) client.Close() } } // cleanupTopic deletes stale testing topics. func cleanupTopic(ctx context.Context, client *pubsub.Client) error { if testing.Short() { return nil // Don't clean up in short mode. } // Delete topics which were created a while ago. const expireAge = 24 * time.Hour it := client.Topics(ctx) for { t, err := it.Next() if err == iterator.Done { break } if err != nil { return err } // Take timestamp from id. tID := t.ID() p := strings.Split(tID, "-") tCreated := p[len(p)-1] timestamp, err := strconv.ParseInt(tCreated, 10, 64) if err != nil { continue } timeTCreated := time.Unix(0, timestamp) if time.Since(timeTCreated) > expireAge { log.Printf("deleting topic %q", tID) if err := t.Delete(ctx); err != nil { return fmt.Errorf("Delete topic: %v: %v", t.String(), err) } } } return nil } // cleanupSubscription deletes stale testing subscriptions. func cleanupSubscription(ctx context.Context, client *pubsub.Client) error { if testing.Short() { return nil // Don't clean up in short mode. } // Delete subscriptions which were created a while ago. const expireAge = 24 * time.Hour it := client.Subscriptions(ctx) for { s, err := it.Next() if err == iterator.Done { break } if err != nil { return err } sID := s.ID() p := strings.Split(sID, "-") sCreated := p[len(p)-2] timestamp, err := strconv.ParseInt(sCreated, 10, 64) if err != nil { continue } timeSCreated := time.Unix(0, timestamp) if time.Since(timeSCreated) > expireAge { log.Printf("deleting subscription %q", sID) if err := s.Delete(ctx); err != nil { return fmt.Errorf("Delete subscription: %v: %v", s.String(), err) } } } return nil } google-cloud-go-0.49.0/pubsub/iterator.go000066400000000000000000000404321356504100700202530ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package pubsub import ( "context" "io" "sync" "time" vkit "cloud.google.com/go/pubsub/apiv1" "cloud.google.com/go/pubsub/internal/distribution" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" pb "google.golang.org/genproto/googleapis/pubsub/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) // Between message receipt and ack (that is, the time spent processing a message) we want to extend the message // deadline by way of modack. However, we don't want to extend the deadline right as soon as the deadline expires; // instead, we'd want to extend the deadline a little bit of time ahead. gracePeriod is that amount of time ahead // of the actual deadline. const gracePeriod = 5 * time.Second type messageIterator struct { ctx context.Context cancel func() // the function that will cancel ctx; called in stop po *pullOptions ps *pullStream subc *vkit.SubscriberClient subName string kaTick <-chan time.Time // keep-alive (deadline extensions) ackTicker *time.Ticker // message acks nackTicker *time.Ticker // message nacks (more frequent than acks) pingTicker *time.Ticker // sends to the stream to keep it open failed chan struct{} // closed on stream error drained chan struct{} // closed when stopped && no more pending messages wg sync.WaitGroup mu sync.Mutex ackTimeDist *distribution.D // dist uses seconds // keepAliveDeadlines is a map of id to expiration time. This map is used in conjunction with // subscription.ReceiveSettings.MaxExtension to record the maximum amount of time (the // deadline, more specifically) we're willing to extend a message's ack deadline. As each // message arrives, we'll record now+MaxExtension in this table; whenever we have a chance // to update ack deadlines (via modack), we'll consult this table and only include IDs // that are not beyond their deadline. keepAliveDeadlines map[string]time.Time pendingAcks map[string]bool pendingNacks map[string]bool pendingModAcks map[string]bool // ack IDs whose ack deadline is to be modified err error // error from stream failure } // newMessageIterator starts and returns a new messageIterator. // subName is the full name of the subscription to pull messages from. // Stop must be called on the messageIterator when it is no longer needed. // The iterator always uses the background context for acking messages and extending message deadlines. func newMessageIterator(subc *vkit.SubscriberClient, subName string, po *pullOptions) *messageIterator { var ps *pullStream if !po.synchronous { ps = newPullStream(context.Background(), subc.StreamingPull, subName) } // The period will update each tick based on the distribution of acks. We'll start by arbitrarily sending // the first keepAlive halfway towards the minimum ack deadline. keepAlivePeriod := minAckDeadline / 2 // Ack promptly so users don't lose work if client crashes. ackTicker := time.NewTicker(100 * time.Millisecond) nackTicker := time.NewTicker(100 * time.Millisecond) pingTicker := time.NewTicker(30 * time.Second) cctx, cancel := context.WithCancel(context.Background()) it := &messageIterator{ ctx: cctx, cancel: cancel, ps: ps, po: po, subc: subc, subName: subName, kaTick: time.After(keepAlivePeriod), ackTicker: ackTicker, nackTicker: nackTicker, pingTicker: pingTicker, failed: make(chan struct{}), drained: make(chan struct{}), ackTimeDist: distribution.New(int(maxAckDeadline/time.Second) + 1), keepAliveDeadlines: map[string]time.Time{}, pendingAcks: map[string]bool{}, pendingNacks: map[string]bool{}, pendingModAcks: map[string]bool{}, } it.wg.Add(1) go it.sender() return it } // Subscription.receive will call stop on its messageIterator when finished with it. // Stop will block until Done has been called on all Messages that have been // returned by Next, or until the context with which the messageIterator was created // is cancelled or exceeds its deadline. func (it *messageIterator) stop() { it.cancel() it.mu.Lock() it.checkDrained() it.mu.Unlock() it.wg.Wait() } // checkDrained closes the drained channel if the iterator has been stopped and all // pending messages have either been n/acked or expired. // // Called with the lock held. func (it *messageIterator) checkDrained() { select { case <-it.drained: return default: } select { case <-it.ctx.Done(): if len(it.keepAliveDeadlines) == 0 { close(it.drained) } default: } } // Called when a message is acked/nacked. func (it *messageIterator) done(ackID string, ack bool, receiveTime time.Time) { it.ackTimeDist.Record(int(time.Since(receiveTime) / time.Second)) it.mu.Lock() defer it.mu.Unlock() delete(it.keepAliveDeadlines, ackID) if ack { it.pendingAcks[ackID] = true } else { it.pendingNacks[ackID] = true } it.checkDrained() } // fail is called when a stream method returns a permanent error. // fail returns it.err. This may be err, or it may be the error // set by an earlier call to fail. func (it *messageIterator) fail(err error) error { it.mu.Lock() defer it.mu.Unlock() if it.err == nil { it.err = err close(it.failed) } return it.err } // receive makes a call to the stream's Recv method, or the Pull RPC, and returns // its messages. // maxToPull is the maximum number of messages for the Pull RPC. func (it *messageIterator) receive(maxToPull int32) ([]*Message, error) { it.mu.Lock() ierr := it.err it.mu.Unlock() if ierr != nil { return nil, ierr } // Stop retrieving messages if the iterator's Stop method was called. select { case <-it.ctx.Done(): it.wg.Wait() return nil, io.EOF default: } var rmsgs []*pb.ReceivedMessage var err error if it.po.synchronous { rmsgs, err = it.pullMessages(maxToPull) } else { rmsgs, err = it.recvMessages() } // Any error here is fatal. if err != nil { return nil, it.fail(err) } recordStat(it.ctx, PullCount, int64(len(rmsgs))) msgs, err := convertMessages(rmsgs) if err != nil { return nil, it.fail(err) } // We received some messages. Remember them so we can keep them alive. Also, // do a receipt mod-ack when streaming. maxExt := time.Now().Add(it.po.maxExtension) ackIDs := map[string]bool{} it.mu.Lock() now := time.Now() for _, m := range msgs { m.receiveTime = now addRecv(m.ID, m.ackID, now) m.doneFunc = it.done it.keepAliveDeadlines[m.ackID] = maxExt // Don't change the mod-ack if the message is going to be nacked. This is // possible if there are retries. if !it.pendingNacks[m.ackID] { ackIDs[m.ackID] = true } } deadline := it.ackDeadline() it.mu.Unlock() if len(ackIDs) > 0 { if !it.sendModAck(ackIDs, deadline) { return nil, it.err } } return msgs, nil } // Get messages using the Pull RPC. // This may block indefinitely. It may also return zero messages, after some time waiting. func (it *messageIterator) pullMessages(maxToPull int32) ([]*pb.ReceivedMessage, error) { // Use it.ctx as the RPC context, so that if the iterator is stopped, the call // will return immediately. res, err := it.subc.Pull(it.ctx, &pb.PullRequest{ Subscription: it.subName, MaxMessages: maxToPull, }, gax.WithGRPCOptions(grpc.MaxCallRecvMsgSize(maxSendRecvBytes))) switch { case err == context.Canceled: return nil, nil case err != nil: return nil, err default: return res.ReceivedMessages, nil } } func (it *messageIterator) recvMessages() ([]*pb.ReceivedMessage, error) { res, err := it.ps.Recv() if err != nil { return nil, err } return res.ReceivedMessages, nil } // sender runs in a goroutine and handles all sends to the stream. func (it *messageIterator) sender() { defer it.wg.Done() defer it.ackTicker.Stop() defer it.nackTicker.Stop() defer it.pingTicker.Stop() defer func() { if it.ps != nil { it.ps.CloseSend() } }() done := false for !done { sendAcks := false sendNacks := false sendModAcks := false sendPing := false dl := it.ackDeadline() select { case <-it.failed: // Stream failed: nothing to do, so stop immediately. return case <-it.drained: // All outstanding messages have been marked done: // nothing left to do except make the final calls. it.mu.Lock() sendAcks = (len(it.pendingAcks) > 0) sendNacks = (len(it.pendingNacks) > 0) // No point in sending modacks. done = true case <-it.kaTick: it.mu.Lock() it.handleKeepAlives() sendModAcks = (len(it.pendingModAcks) > 0) nextTick := dl - gracePeriod if nextTick <= 0 { // If the deadline is <= gracePeriod, let's tick again halfway to // the deadline. nextTick = dl / 2 } it.kaTick = time.After(nextTick) case <-it.nackTicker.C: it.mu.Lock() sendNacks = (len(it.pendingNacks) > 0) case <-it.ackTicker.C: it.mu.Lock() sendAcks = (len(it.pendingAcks) > 0) case <-it.pingTicker.C: it.mu.Lock() // Ping only if we are processing messages via streaming. sendPing = !it.po.synchronous && (len(it.keepAliveDeadlines) > 0) } // Lock is held here. var acks, nacks, modAcks map[string]bool if sendAcks { acks = it.pendingAcks it.pendingAcks = map[string]bool{} } if sendNacks { nacks = it.pendingNacks it.pendingNacks = map[string]bool{} } if sendModAcks { modAcks = it.pendingModAcks it.pendingModAcks = map[string]bool{} } it.mu.Unlock() // Make Ack and ModAck RPCs. if sendAcks { if !it.sendAck(acks) { return } } if sendNacks { // Nack indicated by modifying the deadline to zero. if !it.sendModAck(nacks, 0) { return } } if sendModAcks { if !it.sendModAck(modAcks, dl) { return } } if sendPing { it.pingStream() } } } // handleKeepAlives modifies the pending request to include deadline extensions // for live messages. It also purges expired messages. // // Called with the lock held. func (it *messageIterator) handleKeepAlives() { now := time.Now() for id, expiry := range it.keepAliveDeadlines { if expiry.Before(now) { // This delete will not result in skipping any map items, as implied by // the spec at https://golang.org/ref/spec#For_statements, "For // statements with range clause", note 3, and stated explicitly at // https://groups.google.com/forum/#!msg/golang-nuts/UciASUb03Js/pzSq5iVFAQAJ. delete(it.keepAliveDeadlines, id) } else { // This will not conflict with a nack, because nacking removes the ID from keepAliveDeadlines. it.pendingModAcks[id] = true } } it.checkDrained() } func (it *messageIterator) sendAck(m map[string]bool) bool { // Account for the Subscription field. overhead := calcFieldSizeString(it.subName) return it.sendAckIDRPC(m, maxPayload-overhead, func(ids []string) error { recordStat(it.ctx, AckCount, int64(len(ids))) addAcks(ids) // Use context.Background() as the call's context, not it.ctx. We don't // want to cancel this RPC when the iterator is stopped. return it.subc.Acknowledge(context.Background(), &pb.AcknowledgeRequest{ Subscription: it.subName, AckIds: ids, }) }) } // The receipt mod-ack amount is derived from a percentile distribution based // on the time it takes to process messages. The percentile chosen is the 99%th // percentile in order to capture the highest amount of time necessary without // considering 1% outliers. func (it *messageIterator) sendModAck(m map[string]bool, deadline time.Duration) bool { deadlineSec := int32(deadline / time.Second) // Account for the Subscription and AckDeadlineSeconds fields. overhead := calcFieldSizeString(it.subName) + calcFieldSizeInt(int(deadlineSec)) return it.sendAckIDRPC(m, maxPayload-overhead, func(ids []string) error { if deadline == 0 { recordStat(it.ctx, NackCount, int64(len(ids))) } else { recordStat(it.ctx, ModAckCount, int64(len(ids))) } addModAcks(ids, deadlineSec) // Retry this RPC on Unavailable for a short amount of time, then give up // without returning a fatal error. The utility of this RPC is by nature // transient (since the deadline is relative to the current time) and it // isn't crucial for correctness (since expired messages will just be // resent). cctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() bo := gax.Backoff{ Initial: 100 * time.Millisecond, Max: time.Second, Multiplier: 2, } for { err := it.subc.ModifyAckDeadline(cctx, &pb.ModifyAckDeadlineRequest{ Subscription: it.subName, AckDeadlineSeconds: deadlineSec, AckIds: ids, }) switch status.Code(err) { case codes.Unavailable: if err := gax.Sleep(cctx, bo.Pause()); err == nil { continue } // Treat sleep timeout like RPC timeout. fallthrough case codes.DeadlineExceeded: // Timeout. Not a fatal error, but note that it happened. recordStat(it.ctx, ModAckTimeoutCount, 1) return nil default: // Any other error is fatal. return err } } }) } func (it *messageIterator) sendAckIDRPC(ackIDSet map[string]bool, maxSize int, call func([]string) error) bool { ackIDs := make([]string, 0, len(ackIDSet)) for k := range ackIDSet { ackIDs = append(ackIDs, k) } var toSend []string for len(ackIDs) > 0 { toSend, ackIDs = splitRequestIDs(ackIDs, maxSize) if err := call(toSend); err != nil { // The underlying client handles retries, so any error is fatal to the // iterator. it.fail(err) return false } } return true } // Send a message to the stream to keep it open. The stream will close if there's no // traffic on it for a while. By keeping it open, we delay the start of the // expiration timer on messages that are buffered by gRPC or elsewhere in the // network. This matters if it takes a long time to process messages relative to the // default ack deadline, and if the messages are small enough so that many can fit // into the buffer. func (it *messageIterator) pingStream() { // Ignore error; if the stream is broken, this doesn't matter anyway. _ = it.ps.Send(&pb.StreamingPullRequest{}) } // calcFieldSizeString returns the number of bytes string fields // will take up in an encoded proto message. func calcFieldSizeString(fields ...string) int { overhead := 0 for _, field := range fields { overhead += 1 + len(field) + proto.SizeVarint(uint64(len(field))) } return overhead } // calcFieldSizeInt returns the number of bytes int fields // will take up in an encoded proto message. func calcFieldSizeInt(fields ...int) int { overhead := 0 for _, field := range fields { overhead += 1 + proto.SizeVarint(uint64(field)) } return overhead } // splitRequestIDs takes a slice of ackIDs and returns two slices such that the first // ackID slice can be used in a request where the payload does not exceed maxSize. func splitRequestIDs(ids []string, maxSize int) (prefix, remainder []string) { size := 0 i := 0 // TODO(hongalex): Use binary search to find split index, since ackIDs are // fairly constant. for size < maxSize && i < len(ids) { size += calcFieldSizeString(ids[i]) i++ } if size > maxSize { i-- } return ids[:i], ids[i:] } // The deadline to ack is derived from a percentile distribution based // on the time it takes to process messages. The percentile chosen is the 99%th // percentile - that is, processing times up to the 99%th longest processing // times should be safe. The highest 1% may expire. This number was chosen // as a way to cover most users' usecases without losing the value of // expiration. func (it *messageIterator) ackDeadline() time.Duration { pt := time.Duration(it.ackTimeDist.Percentile(.99)) * time.Second if pt > maxAckDeadline { return maxAckDeadline } if pt < minAckDeadline { return minAckDeadline } return pt } google-cloud-go-0.49.0/pubsub/iterator_test.go000066400000000000000000000250621356504100700213140ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package pubsub import ( "bytes" "context" "errors" "fmt" "reflect" "sync" "sync/atomic" "testing" "time" "cloud.google.com/go/internal/testutil" "cloud.google.com/go/pubsub/pstest" "google.golang.org/api/option" pb "google.golang.org/genproto/googleapis/pubsub/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) var ( projName = "some-project" topicName = "some-topic" fullyQualifiedTopicName = fmt.Sprintf("projects/%s/topics/%s", projName, topicName) ) func TestSplitRequestIDs(t *testing.T) { t.Parallel() ids := []string{"aaaa", "bbbb", "cccc", "dddd", "eeee"} for _, test := range []struct { ids []string splitIndex int }{ {[]string{}, 0}, {ids, 2}, {ids[:2], 2}, } { got1, got2 := splitRequestIDs(test.ids, 15) want1, want2 := test.ids[:test.splitIndex], test.ids[test.splitIndex:] if !testutil.Equal(got1, want1) { t.Errorf("%v, 1: got %v, want %v", test, got1, want1) } if !testutil.Equal(got2, want2) { t.Errorf("%v, 2: got %v, want %v", test, got2, want2) } } } func TestCalcFieldSize(t *testing.T) { t.Parallel() // Create a mock ack request to test. req := &pb.AcknowledgeRequest{ Subscription: "sub", AckIds: []string{"aaa", "bbb", "ccc", "ddd", "eee"}, } size := calcFieldSizeString(req.Subscription) + calcFieldSizeString(req.AckIds...) // Proto encoding is calculated from 1 tag byte and 1 size byte for each string. want := (1 + 1) + len(req.Subscription) + // subscription field: 1 tag byte + 1 size byte 5*(1+1+3) // ackID size: 5 * [1 (tag byte) + 1 (size byte) + 3 (length of ackID)] if size != want { t.Errorf("pubsub: calculated ack req size of %d bytes, want %d", size, want) } req.Subscription = string(bytes.Repeat([]byte{'A'}, 300)) size = calcFieldSizeString(req.Subscription) + calcFieldSizeString(req.AckIds...) // With a longer subscription name, we use an extra size byte. want = (1 + 2) + len(req.Subscription) + // subscription field: 1 tag byte + 2 size bytes 5*(1+1+3) // ackID size: 5 * [1 (tag byte) + 1 (size byte) + 3 (length of ackID)] if size != want { t.Errorf("pubsub: calculated ack req size of %d bytes, want %d", size, want) } // Create a mock modack request to test. modAckReq := &pb.ModifyAckDeadlineRequest{ Subscription: "sub", AckIds: []string{"aaa", "bbb", "ccc", "ddd", "eee"}, AckDeadlineSeconds: 300, } size = calcFieldSizeString(modAckReq.Subscription) + calcFieldSizeString(modAckReq.AckIds...) + calcFieldSizeInt(int(modAckReq.AckDeadlineSeconds)) want = (1 + 1) + len(modAckReq.Subscription) + // subscription field: 1 tag byte + 1 size byte 5*(1+1+3) + // ackID size: 5 * [1 (tag byte) + 1 (size byte) + 3 (length of ackID)] (1 + 2) // ackDeadline: 1 tag byte + 2 size bytes if size != want { t.Errorf("pubsub: calculated modAck req size of %d bytes, want %d", size, want) } } func TestAckDistribution(t *testing.T) { if testing.Short() { t.SkipNow() } t.Skip("broken") ctx, cancel := context.WithCancel(context.Background()) defer cancel() minAckDeadline = 1 * time.Second pstest.SetMinAckDeadline(minAckDeadline) srv := pstest.NewServer() defer srv.Close() defer pstest.ResetMinAckDeadline() // Create the topic via a Publish. It's convenient to do it here as opposed to client.CreateTopic because the client // has not been established yet, and also because we want to create the topic once whereas the client is established // below twice. srv.Publish(fullyQualifiedTopicName, []byte("creating a topic"), nil) queuedMsgs := make(chan int32, 1024) go continuouslySend(ctx, srv, queuedMsgs) for _, testcase := range []struct { initialProcessSecs int32 finalProcessSecs int32 }{ {initialProcessSecs: 3, finalProcessSecs: 5}, // Process time goes up {initialProcessSecs: 5, finalProcessSecs: 3}, // Process time goes down } { t.Logf("Testing %d -> %d", testcase.initialProcessSecs, testcase.finalProcessSecs) // processTimeSecs is used by the sender to coordinate with the receiver how long the receiver should // pretend to process for. e.g. if we test 3s -> 5s, processTimeSecs will start at 3, causing receiver // to process messages received for 3s while sender sends the first batch. Then, as sender begins to // send the next batch, sender will swap processTimeSeconds to 5s and begin sending, and receiver will // process each message for 5s. In this way we simulate a client whose time-to-ack (process time) changes. processTimeSecs := testcase.initialProcessSecs s, client, err := initConn(ctx, srv.Addr) if err != nil { t.Fatal(err) } // recvdWg increments for each message sent, and decrements for each message received. recvdWg := &sync.WaitGroup{} go startReceiving(ctx, t, s, recvdWg, &processTimeSecs) startSending(t, queuedMsgs, &processTimeSecs, testcase.initialProcessSecs, testcase.finalProcessSecs, recvdWg) recvdWg.Wait() time.Sleep(100 * time.Millisecond) // Wait a bit more for resources to clean up err = client.Close() if err != nil { t.Fatal(err) } modacks := modacksByTime(srv.Messages()) u := modackDeadlines(modacks) initialDL := int32(minAckDeadline / time.Second) if !setsAreEqual(u, []int32{initialDL, testcase.initialProcessSecs, testcase.finalProcessSecs}) { t.Fatalf("Expected modack deadlines to contain (exactly, and only) %ds, %ds, %ds. Instead, got %v", initialDL, testcase.initialProcessSecs, testcase.finalProcessSecs, toSet(u)) } } } // modacksByTime buckets modacks by time. func modacksByTime(msgs []*pstest.Message) map[time.Time][]pstest.Modack { modacks := map[time.Time][]pstest.Modack{} for _, msg := range msgs { for _, m := range msg.Modacks { modacks[m.ReceivedAt] = append(modacks[m.ReceivedAt], m) } } return modacks } // setsAreEqual reports whether a and b contain the same values, ignoring duplicates. func setsAreEqual(haystack, needles []int32) bool { hMap := map[int32]bool{} nMap := map[int32]bool{} for _, n := range needles { nMap[n] = true } for _, n := range haystack { hMap[n] = true } return reflect.DeepEqual(nMap, hMap) } // startReceiving pretends to be a client. It calls s.Receive and acks messages after some random delay. It also // looks out for dupes - any message that arrives twice will cause a failure. func startReceiving(ctx context.Context, t *testing.T, s *Subscription, recvdWg *sync.WaitGroup, processTimeSecs *int32) { t.Log("Receiving..") var recvdMu sync.Mutex recvd := map[string]bool{} err := s.Receive(ctx, func(ctx context.Context, msg *Message) { msgData := string(msg.Data) recvdMu.Lock() _, ok := recvd[msgData] if ok { recvdMu.Unlock() t.Fatalf("already saw \"%s\"\n", msgData) return } recvd[msgData] = true recvdMu.Unlock() select { case <-ctx.Done(): msg.Nack() recvdWg.Done() case <-time.After(time.Duration(atomic.LoadInt32(processTimeSecs)) * time.Second): msg.Ack() recvdWg.Done() } }) if err != nil { if status.Code(err) != codes.Canceled { t.Error(err) } } } // startSending sends four batches of messages broken up by minDeadline, initialProcessSecs, and finalProcessSecs. func startSending(t *testing.T, queuedMsgs chan int32, processTimeSecs *int32, initialProcessSecs int32, finalProcessSecs int32, recvdWg *sync.WaitGroup) { var msg int32 // We must send this block to force the receiver to send its initially-configured modack time. The time that // gets sent should be ignorant of the distribution, since there haven't been enough (any, actually) messages // to create a distribution yet. t.Log("minAckDeadlineSecsSending an initial message") recvdWg.Add(1) msg++ queuedMsgs <- msg <-time.After(minAckDeadline) t.Logf("Sending some messages to update distribution to %d. This new distribution will be used "+ "when the next batch of messages go out.", initialProcessSecs) for i := 0; i < 10; i++ { recvdWg.Add(1) msg++ queuedMsgs <- msg } atomic.SwapInt32(processTimeSecs, finalProcessSecs) <-time.After(time.Duration(initialProcessSecs) * time.Second) t.Logf("Sending many messages to update distribution to %d. This new distribution will be used "+ "when the next batch of messages go out.", finalProcessSecs) for i := 0; i < 100; i++ { recvdWg.Add(1) msg++ queuedMsgs <- msg // Send many messages to drastically change distribution } <-time.After(time.Duration(finalProcessSecs) * time.Second) t.Logf("Last message going out, whose deadline should be %d.", finalProcessSecs) recvdWg.Add(1) msg++ queuedMsgs <- msg } // continuouslySend continuously sends messages that exist on the queuedMsgs chan. func continuouslySend(ctx context.Context, srv *pstest.Server, queuedMsgs chan int32) { for { select { case <-ctx.Done(): return case m := <-queuedMsgs: srv.Publish(fullyQualifiedTopicName, []byte(fmt.Sprintf("message %d", m)), nil) } } } func toSet(arr []int32) []int32 { var s []int32 m := map[int32]bool{} for _, v := range arr { _, ok := m[v] if !ok { s = append(s, v) m[v] = true } } return s } func initConn(ctx context.Context, addr string) (*Subscription, *Client, error) { conn, err := grpc.Dial(addr, grpc.WithInsecure()) if err != nil { return nil, nil, err } e := testutil.DefaultHeadersEnforcer() opts := append(e.CallOptions(), option.WithGRPCConn(conn)) client, err := NewClient(ctx, projName, opts...) if err != nil { return nil, nil, err } topic := client.Topic(topicName) s, err := client.CreateSubscription(ctx, fmt.Sprintf("sub-%d", time.Now().UnixNano()), SubscriptionConfig{Topic: topic}) if err != nil { return nil, nil, err } exists, err := s.Exists(ctx) if !exists { return nil, nil, errors.New("Subscription does not exist") } if err != nil { return nil, nil, err } return s, client, nil } // modackDeadlines takes a map of time => Modack, gathers all the Modack.AckDeadlines, // and returns them as a slice func modackDeadlines(m map[time.Time][]pstest.Modack) []int32 { var u []int32 for _, vv := range m { for _, v := range vv { u = append(u, v.AckDeadline) } } return u } google-cloud-go-0.49.0/pubsub/loadtest/000077500000000000000000000000001356504100700177075ustar00rootroot00000000000000google-cloud-go-0.49.0/pubsub/loadtest/benchmark_test.go000066400000000000000000000115571356504100700232400ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package loadtest // Performance benchmarks for pubsub. // Run with // go test -bench . -cpu 1 import ( "context" "log" "sync" "sync/atomic" "testing" "time" "cloud.google.com/go/internal/testutil" "cloud.google.com/go/pubsub" "google.golang.org/api/option" gtransport "google.golang.org/api/transport/grpc" pb "google.golang.org/genproto/googleapis/pubsub/v1" "google.golang.org/grpc" ) // These constants are designed to match the "throughput" test in // https://github.com/GoogleCloudPlatform/pubsub/blob/master/load-test-framework/run.py // and // https://github.com/GoogleCloudPlatform/pubsub/blob/master/load-test-framework/src/main/java/com/google/pubsub/clients/experimental/CPSPublisherTask.java const ( nMessages = 1e5 messageSize = 10000 // size of msg data in bytes batchSize = 10 batchDuration = 50 * time.Millisecond serverDelay = 200 * time.Millisecond maxOutstandingPublishes = 1600 // max_outstanding_messages in run.py ) func BenchmarkPublishThroughput(b *testing.B) { b.SetBytes(nMessages * messageSize) client := perfClient(serverDelay, 1, b) lts := &PubServer{ID: "xxx"} lts.init(client, "t", messageSize, batchSize, batchDuration) b.ResetTimer() for i := 0; i < b.N; i++ { runOnce(lts) } } func runOnce(lts *PubServer) { nRequests := int64(nMessages / batchSize) var nPublished int64 var wg sync.WaitGroup // The Java loadtest framework is rate-limited to 1 billion Execute calls a // second (each Execute call corresponding to a publishBatch call here), // but we can ignore this because of the following. // The framework runs 10,000 threads, each calling Execute in a loop, but // we can ignore this too. // The framework caps the number of outstanding calls to Execute at // maxOutstandingPublishes. That is what we simulate here. for i := 0; i < maxOutstandingPublishes; i++ { wg.Add(1) go func() { defer wg.Done() for atomic.AddInt64(&nRequests, -1) >= 0 { latencies, err := lts.publishBatch() if err != nil { log.Fatalf("publishBatch: %v", err) } atomic.AddInt64(&nPublished, int64(len(latencies))) } }() } wg.Wait() sent := atomic.LoadInt64(&nPublished) if sent != nMessages { log.Fatalf("sent %d messages, expected %d", sent, int(nMessages)) } } func perfClient(pubDelay time.Duration, nConns int, f interface { Fatal(...interface{}) }) *pubsub.Client { ctx := context.Background() srv, err := newPerfServer(pubDelay) if err != nil { f.Fatal(err) } conn, err := gtransport.DialInsecure(ctx, option.WithEndpoint(srv.Addr), option.WithGRPCConnectionPool(nConns), // TODO(grpc/grpc-go#1388) using connection pool without WithBlock // can cause RPCs to fail randomly. We can delete this after the issue is fixed. option.WithGRPCDialOption(grpc.WithBlock())) if err != nil { f.Fatal(err) } client, err := pubsub.NewClient(ctx, "projectID", option.WithGRPCConn(conn)) if err != nil { f.Fatal(err) } return client } type perfServer struct { pb.PublisherServer pb.SubscriberServer Addr string pubDelay time.Duration mu sync.Mutex activePubs int maxActivePubs int } func newPerfServer(pubDelay time.Duration) (*perfServer, error) { srv, err := testutil.NewServer(grpc.MaxMsgSize(pubsub.MaxPublishRequestBytes)) if err != nil { return nil, err } perf := &perfServer{Addr: srv.Addr, pubDelay: pubDelay} pb.RegisterPublisherServer(srv.Gsrv, perf) pb.RegisterSubscriberServer(srv.Gsrv, perf) srv.Start() return perf, nil } var doLog = false func (p *perfServer) incActivePubs(n int) (int, bool) { p.mu.Lock() defer p.mu.Unlock() p.activePubs += n newMax := false if p.activePubs > p.maxActivePubs { p.maxActivePubs = p.activePubs newMax = true } return p.activePubs, newMax } func (p *perfServer) Publish(ctx context.Context, req *pb.PublishRequest) (*pb.PublishResponse, error) { a, newMax := p.incActivePubs(1) defer p.incActivePubs(-1) if newMax && doLog { log.Printf("max %d active publish calls", a) } if doLog { log.Printf("%p -> Publish %d", p, len(req.Messages)) } res := &pb.PublishResponse{MessageIds: make([]string, len(req.Messages))} for i := range res.MessageIds { res.MessageIds[i] = "x" } time.Sleep(p.pubDelay) if doLog { log.Printf("%p <- Publish %d", p, len(req.Messages)) } return res, nil } google-cloud-go-0.49.0/pubsub/loadtest/cmd/000077500000000000000000000000001356504100700204525ustar00rootroot00000000000000google-cloud-go-0.49.0/pubsub/loadtest/cmd/loadtest.go000066400000000000000000000025041356504100700226210ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package main import ( "flag" "fmt" "log" "math/rand" "net" "strconv" "cloud.google.com/go/pubsub/loadtest" pb "cloud.google.com/go/pubsub/loadtest/pb" "google.golang.org/grpc" ) func main() { port := flag.Uint("worker_port", 6000, "port to bind worker to") role := flag.String("r", "", "role: pub/sub") flag.Parse() var lts pb.LoadtestWorkerServer switch *role { case "pub": lts = &loadtest.PubServer{ID: strconv.Itoa(rand.Int())} case "sub": lts = &loadtest.SubServer{} default: log.Fatalf("unknown role: %q", *role) } serv := grpc.NewServer() pb.RegisterLoadtestWorkerServer(serv, lts) lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port)) if err != nil { log.Fatalf("failed to listen: %v", err) } serv.Serve(lis) } google-cloud-go-0.49.0/pubsub/loadtest/loadtest.go000066400000000000000000000134421356504100700220610ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package loadtest implements load testing for pubsub, // following the interface defined in https://github.com/GoogleCloudPlatform/pubsub/tree/master/load-test-framework/ . // // This package is experimental. package loadtest import ( "bytes" "context" "errors" "log" "runtime" "strconv" "sync" "sync/atomic" "time" "cloud.google.com/go/pubsub" pb "cloud.google.com/go/pubsub/loadtest/pb" "github.com/golang/protobuf/ptypes" "golang.org/x/time/rate" ) type pubServerConfig struct { topic *pubsub.Topic msgData []byte batchSize int32 } // PubServer is a dummy Pub/Sub server for load testing. type PubServer struct { ID string cfg atomic.Value seqNum int32 } // Start starts the server. func (l *PubServer) Start(ctx context.Context, req *pb.StartRequest) (*pb.StartResponse, error) { log.Println("received start") c, err := pubsub.NewClient(ctx, req.Project) if err != nil { return nil, err } dur, err := ptypes.Duration(req.PublishBatchDuration) if err != nil { return nil, err } l.init(c, req.Topic, req.MessageSize, req.PublishBatchSize, dur) log.Println("started") return &pb.StartResponse{}, nil } func (l *PubServer) init(c *pubsub.Client, topicName string, msgSize, batchSize int32, batchDur time.Duration) { topic := c.Topic(topicName) topic.PublishSettings = pubsub.PublishSettings{ DelayThreshold: batchDur, CountThreshold: 950, ByteThreshold: 9500000, } l.cfg.Store(pubServerConfig{ topic: topic, msgData: bytes.Repeat([]byte{'A'}, int(msgSize)), batchSize: batchSize, }) } // Execute executes a request. func (l *PubServer) Execute(ctx context.Context, _ *pb.ExecuteRequest) (*pb.ExecuteResponse, error) { latencies, err := l.publishBatch() if err != nil { log.Printf("error: %v", err) return nil, err } return &pb.ExecuteResponse{Latencies: latencies}, nil } func (l *PubServer) publishBatch() ([]int64, error) { var cfg pubServerConfig if c, ok := l.cfg.Load().(pubServerConfig); ok { cfg = c } else { return nil, errors.New("config not loaded") } start := time.Now() latencies := make([]int64, cfg.batchSize) startStr := strconv.FormatInt(start.UnixNano()/1e6, 10) seqNum := atomic.AddInt32(&l.seqNum, cfg.batchSize) - cfg.batchSize rs := make([]*pubsub.PublishResult, cfg.batchSize) for i := int32(0); i < cfg.batchSize; i++ { rs[i] = cfg.topic.Publish(context.TODO(), &pubsub.Message{ Data: cfg.msgData, Attributes: map[string]string{ "sendTime": startStr, "clientId": l.ID, "sequenceNumber": strconv.Itoa(int(seqNum + i)), }, }) } for i, r := range rs { _, err := r.Get(context.Background()) if err != nil { return nil, err } // TODO(jba,pongad): fix latencies // Later values will be skewed by earlier ones, since we wait for the // results in order. (On the other hand, it may not matter much, since // messages are added to bundles in order and bundles get sent more or // less in order.) If we want more accurate values, we can either start // a goroutine for each result (similar to the original code using a // callback), or call reflect.Select with the Ready channels of the // results. latencies[i] = time.Since(start).Nanoseconds() / 1e6 } return latencies, nil } // SubServer is a dummy Pub/Sub server for load testing. type SubServer struct { // TODO(deklerk): what is this actually for? lim *rate.Limiter mu sync.Mutex idents []*pb.MessageIdentifier latencies []int64 } // Start starts the server. func (s *SubServer) Start(ctx context.Context, req *pb.StartRequest) (*pb.StartResponse, error) { log.Println("received start") s.lim = rate.NewLimiter(rate.Every(time.Second), 1) c, err := pubsub.NewClient(ctx, req.Project) if err != nil { return nil, err } // Load test API doesn't define any way to stop right now. go func() { sub := c.Subscription(req.GetPubsubOptions().Subscription) sub.ReceiveSettings.NumGoroutines = 10 * runtime.GOMAXPROCS(0) err := sub.Receive(context.Background(), s.callback) log.Fatal(err) }() log.Println("started") return &pb.StartResponse{}, nil } func (s *SubServer) callback(_ context.Context, m *pubsub.Message) { id, err := strconv.ParseInt(m.Attributes["clientId"], 10, 64) if err != nil { log.Println(err) m.Nack() return } seqNum, err := strconv.ParseInt(m.Attributes["sequenceNumber"], 10, 32) if err != nil { log.Println(err) m.Nack() return } sendTimeMillis, err := strconv.ParseInt(m.Attributes["sendTime"], 10, 64) if err != nil { log.Println(err) m.Nack() return } latency := time.Now().UnixNano()/1e6 - sendTimeMillis ident := &pb.MessageIdentifier{ PublisherClientId: id, SequenceNumber: int32(seqNum), } s.mu.Lock() s.idents = append(s.idents, ident) s.latencies = append(s.latencies, latency) s.mu.Unlock() m.Ack() } // Execute executes the request. func (s *SubServer) Execute(ctx context.Context, _ *pb.ExecuteRequest) (*pb.ExecuteResponse, error) { // Throttle so the load tester doesn't spam us and consume all our CPU. if err := s.lim.Wait(ctx); err != nil { return nil, err } s.mu.Lock() idents := s.idents s.idents = nil latencies := s.latencies s.latencies = nil s.mu.Unlock() return &pb.ExecuteResponse{ Latencies: latencies, ReceivedMessages: idents, }, nil } google-cloud-go-0.49.0/pubsub/loadtest/pb/000077500000000000000000000000001356504100700203105ustar00rootroot00000000000000google-cloud-go-0.49.0/pubsub/loadtest/pb/loadtest.pb.go000066400000000000000000000723401356504100700230640ustar00rootroot00000000000000// Code generated by protoc-gen-go. // source: loadtest.proto // DO NOT EDIT! /* Package google_pubsub_loadtest is a generated protocol buffer package. It is generated from these files: loadtest.proto It has these top-level messages: StartRequest StartResponse PubsubOptions KafkaOptions MessageIdentifier CheckRequest CheckResponse ExecuteRequest ExecuteResponse */ package google_pubsub_loadtest import ( fmt "fmt" proto "github.com/golang/protobuf/proto" math "math" google_protobuf "github.com/golang/protobuf/ptypes/duration" "context" google_protobuf1 "github.com/golang/protobuf/ptypes/timestamp" grpc "google.golang.org/grpc" ) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal var _ = fmt.Errorf var _ = math.Inf // This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package type StartRequest struct { // The GCP project. This must be set even for Kafka, as we use it to export metrics. Project string `protobuf:"bytes,1,opt,name=project" json:"project,omitempty"` // The Pub/Sub or Kafka topic name. Topic string `protobuf:"bytes,2,opt,name=topic" json:"topic,omitempty"` // The number of requests that can be made, each second, per client. RequestRate int32 `protobuf:"varint,3,opt,name=request_rate,json=requestRate" json:"request_rate,omitempty"` // The size of each user message to publish MessageSize int32 `protobuf:"varint,4,opt,name=message_size,json=messageSize" json:"message_size,omitempty"` // The maximum outstanding requests, per client. MaxOutstandingRequests int32 `protobuf:"varint,5,opt,name=max_outstanding_requests,json=maxOutstandingRequests" json:"max_outstanding_requests,omitempty"` // The time at which the load test should start. If this is less than the current time, we start immediately. StartTime *google_protobuf1.Timestamp `protobuf:"bytes,6,opt,name=start_time,json=startTime" json:"start_time,omitempty"` // The burn-in duration, before which results should not be reported. BurnInDuration *google_protobuf.Duration `protobuf:"bytes,12,opt,name=burn_in_duration,json=burnInDuration" json:"burn_in_duration,omitempty"` // The number of user messages of size message_size to publish together. PublishBatchSize int32 `protobuf:"varint,11,opt,name=publish_batch_size,json=publishBatchSize" json:"publish_batch_size,omitempty"` // The max duration for coalescing a batch of published messages. PublishBatchDuration *google_protobuf.Duration `protobuf:"bytes,13,opt,name=publish_batch_duration,json=publishBatchDuration" json:"publish_batch_duration,omitempty"` // Types that are valid to be assigned to StopConditions: // *StartRequest_TestDuration // *StartRequest_NumberOfMessages StopConditions isStartRequest_StopConditions `protobuf_oneof:"stop_conditions"` // Types that are valid to be assigned to Options: // *StartRequest_PubsubOptions // *StartRequest_KafkaOptions Options isStartRequest_Options `protobuf_oneof:"options"` } func (m *StartRequest) Reset() { *m = StartRequest{} } func (m *StartRequest) String() string { return proto.CompactTextString(m) } func (*StartRequest) ProtoMessage() {} func (*StartRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } type isStartRequest_StopConditions interface { isStartRequest_StopConditions() } type isStartRequest_Options interface { isStartRequest_Options() } type StartRequest_TestDuration struct { TestDuration *google_protobuf.Duration `protobuf:"bytes,7,opt,name=test_duration,json=testDuration,oneof"` } type StartRequest_NumberOfMessages struct { NumberOfMessages int32 `protobuf:"varint,8,opt,name=number_of_messages,json=numberOfMessages,oneof"` } type StartRequest_PubsubOptions struct { PubsubOptions *PubsubOptions `protobuf:"bytes,9,opt,name=pubsub_options,json=pubsubOptions,oneof"` } type StartRequest_KafkaOptions struct { KafkaOptions *KafkaOptions `protobuf:"bytes,10,opt,name=kafka_options,json=kafkaOptions,oneof"` } func (*StartRequest_TestDuration) isStartRequest_StopConditions() {} func (*StartRequest_NumberOfMessages) isStartRequest_StopConditions() {} func (*StartRequest_PubsubOptions) isStartRequest_Options() {} func (*StartRequest_KafkaOptions) isStartRequest_Options() {} func (m *StartRequest) GetStopConditions() isStartRequest_StopConditions { if m != nil { return m.StopConditions } return nil } func (m *StartRequest) GetOptions() isStartRequest_Options { if m != nil { return m.Options } return nil } func (m *StartRequest) GetProject() string { if m != nil { return m.Project } return "" } func (m *StartRequest) GetTopic() string { if m != nil { return m.Topic } return "" } func (m *StartRequest) GetRequestRate() int32 { if m != nil { return m.RequestRate } return 0 } func (m *StartRequest) GetMessageSize() int32 { if m != nil { return m.MessageSize } return 0 } func (m *StartRequest) GetMaxOutstandingRequests() int32 { if m != nil { return m.MaxOutstandingRequests } return 0 } func (m *StartRequest) GetStartTime() *google_protobuf1.Timestamp { if m != nil { return m.StartTime } return nil } func (m *StartRequest) GetBurnInDuration() *google_protobuf.Duration { if m != nil { return m.BurnInDuration } return nil } func (m *StartRequest) GetPublishBatchSize() int32 { if m != nil { return m.PublishBatchSize } return 0 } func (m *StartRequest) GetPublishBatchDuration() *google_protobuf.Duration { if m != nil { return m.PublishBatchDuration } return nil } func (m *StartRequest) GetTestDuration() *google_protobuf.Duration { if x, ok := m.GetStopConditions().(*StartRequest_TestDuration); ok { return x.TestDuration } return nil } func (m *StartRequest) GetNumberOfMessages() int32 { if x, ok := m.GetStopConditions().(*StartRequest_NumberOfMessages); ok { return x.NumberOfMessages } return 0 } func (m *StartRequest) GetPubsubOptions() *PubsubOptions { if x, ok := m.GetOptions().(*StartRequest_PubsubOptions); ok { return x.PubsubOptions } return nil } func (m *StartRequest) GetKafkaOptions() *KafkaOptions { if x, ok := m.GetOptions().(*StartRequest_KafkaOptions); ok { return x.KafkaOptions } return nil } // XXX_OneofFuncs is for the internal use of the proto package. func (*StartRequest) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { return _StartRequest_OneofMarshaler, _StartRequest_OneofUnmarshaler, _StartRequest_OneofSizer, []interface{}{ (*StartRequest_TestDuration)(nil), (*StartRequest_NumberOfMessages)(nil), (*StartRequest_PubsubOptions)(nil), (*StartRequest_KafkaOptions)(nil), } } func _StartRequest_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { m := msg.(*StartRequest) // stop_conditions switch x := m.StopConditions.(type) { case *StartRequest_TestDuration: b.EncodeVarint(7<<3 | proto.WireBytes) if err := b.EncodeMessage(x.TestDuration); err != nil { return err } case *StartRequest_NumberOfMessages: b.EncodeVarint(8<<3 | proto.WireVarint) b.EncodeVarint(uint64(x.NumberOfMessages)) case nil: default: return fmt.Errorf("StartRequest.StopConditions has unexpected type %T", x) } // options switch x := m.Options.(type) { case *StartRequest_PubsubOptions: b.EncodeVarint(9<<3 | proto.WireBytes) if err := b.EncodeMessage(x.PubsubOptions); err != nil { return err } case *StartRequest_KafkaOptions: b.EncodeVarint(10<<3 | proto.WireBytes) if err := b.EncodeMessage(x.KafkaOptions); err != nil { return err } case nil: default: return fmt.Errorf("StartRequest.Options has unexpected type %T", x) } return nil } func _StartRequest_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { m := msg.(*StartRequest) switch tag { case 7: // stop_conditions.test_duration if wire != proto.WireBytes { return true, proto.ErrInternalBadWireType } msg := new(google_protobuf.Duration) err := b.DecodeMessage(msg) m.StopConditions = &StartRequest_TestDuration{msg} return true, err case 8: // stop_conditions.number_of_messages if wire != proto.WireVarint { return true, proto.ErrInternalBadWireType } x, err := b.DecodeVarint() m.StopConditions = &StartRequest_NumberOfMessages{int32(x)} return true, err case 9: // options.pubsub_options if wire != proto.WireBytes { return true, proto.ErrInternalBadWireType } msg := new(PubsubOptions) err := b.DecodeMessage(msg) m.Options = &StartRequest_PubsubOptions{msg} return true, err case 10: // options.kafka_options if wire != proto.WireBytes { return true, proto.ErrInternalBadWireType } msg := new(KafkaOptions) err := b.DecodeMessage(msg) m.Options = &StartRequest_KafkaOptions{msg} return true, err default: return false, nil } } func _StartRequest_OneofSizer(msg proto.Message) (n int) { m := msg.(*StartRequest) // stop_conditions switch x := m.StopConditions.(type) { case *StartRequest_TestDuration: s := proto.Size(x.TestDuration) n += proto.SizeVarint(7<<3 | proto.WireBytes) n += proto.SizeVarint(uint64(s)) n += s case *StartRequest_NumberOfMessages: n += proto.SizeVarint(8<<3 | proto.WireVarint) n += proto.SizeVarint(uint64(x.NumberOfMessages)) case nil: default: panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) } // options switch x := m.Options.(type) { case *StartRequest_PubsubOptions: s := proto.Size(x.PubsubOptions) n += proto.SizeVarint(9<<3 | proto.WireBytes) n += proto.SizeVarint(uint64(s)) n += s case *StartRequest_KafkaOptions: s := proto.Size(x.KafkaOptions) n += proto.SizeVarint(10<<3 | proto.WireBytes) n += proto.SizeVarint(uint64(s)) n += s case nil: default: panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) } return n } type StartResponse struct { } func (m *StartResponse) Reset() { *m = StartResponse{} } func (m *StartResponse) String() string { return proto.CompactTextString(m) } func (*StartResponse) ProtoMessage() {} func (*StartResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } type PubsubOptions struct { // The Cloud Pub/Sub subscription name Subscription string `protobuf:"bytes,1,opt,name=subscription" json:"subscription,omitempty"` // The maximum number of messages to pull which each request. MaxMessagesPerPull int32 `protobuf:"varint,2,opt,name=max_messages_per_pull,json=maxMessagesPerPull" json:"max_messages_per_pull,omitempty"` } func (m *PubsubOptions) Reset() { *m = PubsubOptions{} } func (m *PubsubOptions) String() string { return proto.CompactTextString(m) } func (*PubsubOptions) ProtoMessage() {} func (*PubsubOptions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } func (m *PubsubOptions) GetSubscription() string { if m != nil { return m.Subscription } return "" } func (m *PubsubOptions) GetMaxMessagesPerPull() int32 { if m != nil { return m.MaxMessagesPerPull } return 0 } type KafkaOptions struct { // The network address of the Kafka broker. Broker string `protobuf:"bytes,1,opt,name=broker" json:"broker,omitempty"` // The length of time to poll for. PollDuration *google_protobuf.Duration `protobuf:"bytes,2,opt,name=poll_duration,json=pollDuration" json:"poll_duration,omitempty"` } func (m *KafkaOptions) Reset() { *m = KafkaOptions{} } func (m *KafkaOptions) String() string { return proto.CompactTextString(m) } func (*KafkaOptions) ProtoMessage() {} func (*KafkaOptions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } func (m *KafkaOptions) GetBroker() string { if m != nil { return m.Broker } return "" } func (m *KafkaOptions) GetPollDuration() *google_protobuf.Duration { if m != nil { return m.PollDuration } return nil } type MessageIdentifier struct { // The unique id of the client that published the message. PublisherClientId int64 `protobuf:"varint,1,opt,name=publisher_client_id,json=publisherClientId" json:"publisher_client_id,omitempty"` // Sequence number of the published message with the given publish_client_id. SequenceNumber int32 `protobuf:"varint,2,opt,name=sequence_number,json=sequenceNumber" json:"sequence_number,omitempty"` } func (m *MessageIdentifier) Reset() { *m = MessageIdentifier{} } func (m *MessageIdentifier) String() string { return proto.CompactTextString(m) } func (*MessageIdentifier) ProtoMessage() {} func (*MessageIdentifier) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } func (m *MessageIdentifier) GetPublisherClientId() int64 { if m != nil { return m.PublisherClientId } return 0 } func (m *MessageIdentifier) GetSequenceNumber() int32 { if m != nil { return m.SequenceNumber } return 0 } type CheckRequest struct { // Duplicate messages that should not be reported for throughput and latency. Duplicates []*MessageIdentifier `protobuf:"bytes,1,rep,name=duplicates" json:"duplicates,omitempty"` } func (m *CheckRequest) Reset() { *m = CheckRequest{} } func (m *CheckRequest) String() string { return proto.CompactTextString(m) } func (*CheckRequest) ProtoMessage() {} func (*CheckRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} } func (m *CheckRequest) GetDuplicates() []*MessageIdentifier { if m != nil { return m.Duplicates } return nil } type CheckResponse struct { // Histogram of latencies, each one a delta from the previous CheckResponse sent. BucketValues []int64 `protobuf:"varint,1,rep,packed,name=bucket_values,json=bucketValues" json:"bucket_values,omitempty"` // The duration from the start of the loadtest to its completion or now if is_finished is false. RunningDuration *google_protobuf.Duration `protobuf:"bytes,2,opt,name=running_duration,json=runningDuration" json:"running_duration,omitempty"` // True if the load test has finished running. IsFinished bool `protobuf:"varint,3,opt,name=is_finished,json=isFinished" json:"is_finished,omitempty"` // MessageIdentifiers of all received messages since the last Check ReceivedMessages []*MessageIdentifier `protobuf:"bytes,4,rep,name=received_messages,json=receivedMessages" json:"received_messages,omitempty"` } func (m *CheckResponse) Reset() { *m = CheckResponse{} } func (m *CheckResponse) String() string { return proto.CompactTextString(m) } func (*CheckResponse) ProtoMessage() {} func (*CheckResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} } func (m *CheckResponse) GetBucketValues() []int64 { if m != nil { return m.BucketValues } return nil } func (m *CheckResponse) GetRunningDuration() *google_protobuf.Duration { if m != nil { return m.RunningDuration } return nil } func (m *CheckResponse) GetIsFinished() bool { if m != nil { return m.IsFinished } return false } func (m *CheckResponse) GetReceivedMessages() []*MessageIdentifier { if m != nil { return m.ReceivedMessages } return nil } type ExecuteRequest struct { } func (m *ExecuteRequest) Reset() { *m = ExecuteRequest{} } func (m *ExecuteRequest) String() string { return proto.CompactTextString(m) } func (*ExecuteRequest) ProtoMessage() {} func (*ExecuteRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } type ExecuteResponse struct { // Latencies of the completed operations Latencies []int64 `protobuf:"varint,1,rep,packed,name=latencies" json:"latencies,omitempty"` // MessageIdentifiers of all received messages since the last Execute ReceivedMessages []*MessageIdentifier `protobuf:"bytes,2,rep,name=received_messages,json=receivedMessages" json:"received_messages,omitempty"` } func (m *ExecuteResponse) Reset() { *m = ExecuteResponse{} } func (m *ExecuteResponse) String() string { return proto.CompactTextString(m) } func (*ExecuteResponse) ProtoMessage() {} func (*ExecuteResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} } func (m *ExecuteResponse) GetLatencies() []int64 { if m != nil { return m.Latencies } return nil } func (m *ExecuteResponse) GetReceivedMessages() []*MessageIdentifier { if m != nil { return m.ReceivedMessages } return nil } func init() { proto.RegisterType((*StartRequest)(nil), "google.pubsub.loadtest.StartRequest") proto.RegisterType((*StartResponse)(nil), "google.pubsub.loadtest.StartResponse") proto.RegisterType((*PubsubOptions)(nil), "google.pubsub.loadtest.PubsubOptions") proto.RegisterType((*KafkaOptions)(nil), "google.pubsub.loadtest.KafkaOptions") proto.RegisterType((*MessageIdentifier)(nil), "google.pubsub.loadtest.MessageIdentifier") proto.RegisterType((*CheckRequest)(nil), "google.pubsub.loadtest.CheckRequest") proto.RegisterType((*CheckResponse)(nil), "google.pubsub.loadtest.CheckResponse") proto.RegisterType((*ExecuteRequest)(nil), "google.pubsub.loadtest.ExecuteRequest") proto.RegisterType((*ExecuteResponse)(nil), "google.pubsub.loadtest.ExecuteResponse") } // Reference imports to suppress errors if they are not otherwise used. var _ context.Context var _ grpc.ClientConn // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. const _ = grpc.SupportPackageIsVersion4 // Client API for Loadtest service type LoadtestClient interface { // Starts a load test Start(ctx context.Context, in *StartRequest, opts ...grpc.CallOption) (*StartResponse, error) // Checks the status of a load test Check(ctx context.Context, in *CheckRequest, opts ...grpc.CallOption) (*CheckResponse, error) } type loadtestClient struct { cc *grpc.ClientConn } func NewLoadtestClient(cc *grpc.ClientConn) LoadtestClient { return &loadtestClient{cc} } func (c *loadtestClient) Start(ctx context.Context, in *StartRequest, opts ...grpc.CallOption) (*StartResponse, error) { out := new(StartResponse) err := grpc.Invoke(ctx, "/google.pubsub.loadtest.Loadtest/Start", in, out, c.cc, opts...) if err != nil { return nil, err } return out, nil } func (c *loadtestClient) Check(ctx context.Context, in *CheckRequest, opts ...grpc.CallOption) (*CheckResponse, error) { out := new(CheckResponse) err := grpc.Invoke(ctx, "/google.pubsub.loadtest.Loadtest/Check", in, out, c.cc, opts...) if err != nil { return nil, err } return out, nil } // Server API for Loadtest service type LoadtestServer interface { // Starts a load test Start(context.Context, *StartRequest) (*StartResponse, error) // Checks the status of a load test Check(context.Context, *CheckRequest) (*CheckResponse, error) } func RegisterLoadtestServer(s *grpc.Server, srv LoadtestServer) { s.RegisterService(&_Loadtest_serviceDesc, srv) } func _Loadtest_Start_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(StartRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(LoadtestServer).Start(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/google.pubsub.loadtest.Loadtest/Start", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(LoadtestServer).Start(ctx, req.(*StartRequest)) } return interceptor(ctx, in, info, handler) } func _Loadtest_Check_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(CheckRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(LoadtestServer).Check(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/google.pubsub.loadtest.Loadtest/Check", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(LoadtestServer).Check(ctx, req.(*CheckRequest)) } return interceptor(ctx, in, info, handler) } var _Loadtest_serviceDesc = grpc.ServiceDesc{ ServiceName: "google.pubsub.loadtest.Loadtest", HandlerType: (*LoadtestServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "Start", Handler: _Loadtest_Start_Handler, }, { MethodName: "Check", Handler: _Loadtest_Check_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "loadtest.proto", } // Client API for LoadtestWorker service type LoadtestWorkerClient interface { // Starts a worker Start(ctx context.Context, in *StartRequest, opts ...grpc.CallOption) (*StartResponse, error) // Executes a command on the worker, returning the latencies of the operations. Since some // commands consist of multiple operations (i.e. pulls contain many received messages with // different end to end latencies) a single command can have multiple latencies returned. Execute(ctx context.Context, in *ExecuteRequest, opts ...grpc.CallOption) (*ExecuteResponse, error) } type loadtestWorkerClient struct { cc *grpc.ClientConn } func NewLoadtestWorkerClient(cc *grpc.ClientConn) LoadtestWorkerClient { return &loadtestWorkerClient{cc} } func (c *loadtestWorkerClient) Start(ctx context.Context, in *StartRequest, opts ...grpc.CallOption) (*StartResponse, error) { out := new(StartResponse) err := grpc.Invoke(ctx, "/google.pubsub.loadtest.LoadtestWorker/Start", in, out, c.cc, opts...) if err != nil { return nil, err } return out, nil } func (c *loadtestWorkerClient) Execute(ctx context.Context, in *ExecuteRequest, opts ...grpc.CallOption) (*ExecuteResponse, error) { out := new(ExecuteResponse) err := grpc.Invoke(ctx, "/google.pubsub.loadtest.LoadtestWorker/Execute", in, out, c.cc, opts...) if err != nil { return nil, err } return out, nil } // Server API for LoadtestWorker service type LoadtestWorkerServer interface { // Starts a worker Start(context.Context, *StartRequest) (*StartResponse, error) // Executes a command on the worker, returning the latencies of the operations. Since some // commands consist of multiple operations (i.e. pulls contain many received messages with // different end to end latencies) a single command can have multiple latencies returned. Execute(context.Context, *ExecuteRequest) (*ExecuteResponse, error) } func RegisterLoadtestWorkerServer(s *grpc.Server, srv LoadtestWorkerServer) { s.RegisterService(&_LoadtestWorker_serviceDesc, srv) } func _LoadtestWorker_Start_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(StartRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(LoadtestWorkerServer).Start(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/google.pubsub.loadtest.LoadtestWorker/Start", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(LoadtestWorkerServer).Start(ctx, req.(*StartRequest)) } return interceptor(ctx, in, info, handler) } func _LoadtestWorker_Execute_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ExecuteRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(LoadtestWorkerServer).Execute(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/google.pubsub.loadtest.LoadtestWorker/Execute", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(LoadtestWorkerServer).Execute(ctx, req.(*ExecuteRequest)) } return interceptor(ctx, in, info, handler) } var _LoadtestWorker_serviceDesc = grpc.ServiceDesc{ ServiceName: "google.pubsub.loadtest.LoadtestWorker", HandlerType: (*LoadtestWorkerServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "Start", Handler: _LoadtestWorker_Start_Handler, }, { MethodName: "Execute", Handler: _LoadtestWorker_Execute_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "loadtest.proto", } func init() { proto.RegisterFile("loadtest.proto", fileDescriptor0) } var fileDescriptor0 = []byte{ // 847 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0xdd, 0x6e, 0xdc, 0x44, 0x14, 0xae, 0x93, 0x6e, 0x92, 0x3d, 0x6b, 0xef, 0x6e, 0x86, 0x12, 0x99, 0x15, 0xd0, 0x60, 0x28, 0x0d, 0x12, 0x72, 0x45, 0xb8, 0x81, 0x1b, 0x84, 0x92, 0x82, 0x12, 0x15, 0x9a, 0xc8, 0x8d, 0x8a, 0xe0, 0x66, 0x34, 0xb6, 0x67, 0x93, 0x61, 0xed, 0x19, 0x33, 0x3f, 0x55, 0xd4, 0x17, 0xe0, 0x8d, 0x78, 0x00, 0x1e, 0x87, 0x5b, 0x5e, 0x00, 0xcd, 0x78, 0xbc, 0x3f, 0x6d, 0x57, 0x0b, 0x42, 0xbd, 0x3c, 0xdf, 0xf9, 0xce, 0x37, 0xe7, 0xd7, 0x86, 0x61, 0x25, 0x48, 0xa9, 0xa9, 0xd2, 0x69, 0x23, 0x85, 0x16, 0xe8, 0xe0, 0x5a, 0x88, 0xeb, 0x8a, 0xa6, 0x8d, 0xc9, 0x95, 0xc9, 0xd3, 0xce, 0x3b, 0xf9, 0xb0, 0xc5, 0x1f, 0x39, 0x56, 0x6e, 0xa6, 0x8f, 0x4a, 0x23, 0x89, 0x66, 0x82, 0xb7, 0x71, 0x93, 0xfb, 0xaf, 0xfa, 0x35, 0xab, 0xa9, 0xd2, 0xa4, 0x6e, 0x5a, 0x42, 0xf2, 0x57, 0x0f, 0xc2, 0x67, 0x9a, 0x48, 0x9d, 0xd1, 0xdf, 0x0c, 0x55, 0x1a, 0xc5, 0xb0, 0xdb, 0x48, 0xf1, 0x2b, 0x2d, 0x74, 0x1c, 0x1c, 0x06, 0x47, 0xfd, 0xac, 0x33, 0xd1, 0x3d, 0xe8, 0x69, 0xd1, 0xb0, 0x22, 0xde, 0x72, 0x78, 0x6b, 0xa0, 0x8f, 0x20, 0x94, 0x6d, 0x28, 0x96, 0x44, 0xd3, 0x78, 0xfb, 0x30, 0x38, 0xea, 0x65, 0x03, 0x8f, 0x65, 0x44, 0x53, 0x4b, 0xa9, 0xa9, 0x52, 0xe4, 0x9a, 0x62, 0xc5, 0x5e, 0xd2, 0xf8, 0x6e, 0x4b, 0xf1, 0xd8, 0x33, 0xf6, 0x92, 0xa2, 0xaf, 0x20, 0xae, 0xc9, 0x2d, 0x16, 0x46, 0x2b, 0x4d, 0x78, 0xc9, 0xf8, 0x35, 0xf6, 0x0a, 0x2a, 0xee, 0x39, 0xfa, 0x41, 0x4d, 0x6e, 0x2f, 0x16, 0x6e, 0x9f, 0xae, 0x42, 0x5f, 0x03, 0x28, 0x9b, 0x3f, 0xb6, 0x95, 0xc5, 0x3b, 0x87, 0xc1, 0xd1, 0xe0, 0x78, 0x92, 0x76, 0xed, 0xf2, 0x65, 0xa7, 0x57, 0x5d, 0xd9, 0x59, 0xdf, 0xb1, 0xad, 0x8d, 0x4e, 0x61, 0x9c, 0x1b, 0xc9, 0x31, 0xe3, 0xb8, 0x6b, 0x5b, 0x1c, 0x3a, 0x81, 0xf7, 0x5e, 0x13, 0x78, 0xec, 0x09, 0xd9, 0xd0, 0x86, 0x9c, 0xf3, 0xce, 0x46, 0x9f, 0x03, 0x6a, 0x4c, 0x5e, 0x31, 0x75, 0x83, 0x73, 0xa2, 0x8b, 0x9b, 0xb6, 0xc4, 0x81, 0xcb, 0x79, 0xec, 0x3d, 0x27, 0xd6, 0xe1, 0xea, 0xbc, 0x80, 0x83, 0x55, 0xf6, 0xfc, 0xe1, 0x68, 0xd3, 0xc3, 0xf7, 0x96, 0xc5, 0xe6, 0xcf, 0x7f, 0x0b, 0x91, 0x5d, 0x84, 0x85, 0xce, 0xee, 0x06, 0x9d, 0xb3, 0x3b, 0x59, 0x68, 0x23, 0xe6, 0x0a, 0x29, 0x20, 0x6e, 0xea, 0x9c, 0x4a, 0x2c, 0xa6, 0xd8, 0xcf, 0x44, 0xc5, 0x7b, 0xb6, 0x80, 0xb3, 0x3b, 0xd9, 0xb8, 0xf5, 0x5d, 0x4c, 0x7f, 0xf4, 0x1e, 0xf4, 0x14, 0x86, 0xed, 0x16, 0x62, 0xd1, 0x58, 0x01, 0x15, 0xf7, 0xdd, 0x93, 0x0f, 0xd2, 0x37, 0xef, 0x68, 0x7a, 0xe9, 0xec, 0x8b, 0x96, 0x7c, 0x16, 0x64, 0x51, 0xb3, 0x0c, 0xa0, 0x27, 0x10, 0xcd, 0xc8, 0x74, 0x46, 0xe6, 0x72, 0xe0, 0xe4, 0x3e, 0x59, 0x27, 0xf7, 0xc4, 0x92, 0x17, 0x6a, 0xe1, 0x6c, 0xc9, 0x3e, 0xd9, 0x87, 0x91, 0xd2, 0xa2, 0xc1, 0x85, 0xe0, 0x25, 0x6b, 0xa1, 0x3e, 0xec, 0x7a, 0xe5, 0x64, 0x04, 0x91, 0xdf, 0x75, 0xd5, 0x08, 0xae, 0x68, 0x32, 0x85, 0x68, 0x25, 0x3b, 0x94, 0x40, 0xa8, 0x4c, 0xae, 0x0a, 0xc9, 0x1c, 0xe0, 0x4f, 0x60, 0x05, 0x43, 0x5f, 0xc0, 0xbb, 0x76, 0x57, 0xbb, 0x56, 0xe1, 0x86, 0x4a, 0xdc, 0x98, 0xaa, 0x72, 0x77, 0xd1, 0xcb, 0x50, 0x4d, 0x6e, 0xbb, 0x66, 0x5d, 0x52, 0x79, 0x69, 0xaa, 0x2a, 0x99, 0x42, 0xb8, 0x9c, 0x36, 0x3a, 0x80, 0x9d, 0x5c, 0x8a, 0x19, 0x95, 0xfe, 0x01, 0x6f, 0xa1, 0x6f, 0x20, 0x6a, 0x44, 0x55, 0x2d, 0xa6, 0xb9, 0xb5, 0x69, 0x2b, 0x42, 0xcb, 0xef, 0xac, 0xa4, 0x82, 0x7d, 0xff, 0xf4, 0x79, 0x49, 0xb9, 0x66, 0x53, 0x46, 0x25, 0x4a, 0xe1, 0x1d, 0xbf, 0x3a, 0x54, 0xe2, 0xa2, 0x62, 0x94, 0x6b, 0xcc, 0x4a, 0xf7, 0xf2, 0x76, 0xb6, 0x3f, 0x77, 0x9d, 0x3a, 0xcf, 0x79, 0x89, 0x1e, 0xc2, 0x48, 0xd9, 0xeb, 0xe2, 0x05, 0xc5, 0xed, 0xf4, 0x7d, 0x65, 0xc3, 0x0e, 0x7e, 0xea, 0xd0, 0xe4, 0x67, 0x08, 0x4f, 0x6f, 0x68, 0x31, 0xeb, 0x3e, 0x1d, 0xe7, 0x00, 0xa5, 0x69, 0x2a, 0x56, 0x10, 0x4d, 0x55, 0x1c, 0x1c, 0x6e, 0x1f, 0x0d, 0x8e, 0x3f, 0x5b, 0x37, 0xc6, 0xd7, 0xf2, 0xcc, 0x96, 0x82, 0x93, 0xbf, 0x03, 0x88, 0xbc, 0x76, 0x3b, 0x2a, 0xf4, 0x31, 0x44, 0xb9, 0x29, 0x66, 0x54, 0xe3, 0x17, 0xa4, 0x32, 0x5e, 0x7f, 0x3b, 0x0b, 0x5b, 0xf0, 0xb9, 0xc3, 0xd0, 0x63, 0x18, 0x4b, 0xc3, 0xb9, 0xfd, 0x7c, 0xfc, 0xfb, 0x16, 0x8e, 0x7c, 0xc8, 0xfc, 0x22, 0xee, 0xc3, 0x80, 0x29, 0x3c, 0x65, 0xdc, 0xf6, 0xa5, 0x74, 0x5f, 0xb4, 0xbd, 0x0c, 0x98, 0xfa, 0xde, 0x23, 0xe8, 0x39, 0xec, 0x4b, 0x5a, 0x50, 0xf6, 0x82, 0x96, 0x8b, 0x8b, 0xb9, 0xfb, 0x5f, 0xeb, 0x1d, 0x77, 0x1a, 0xdd, 0xb6, 0x24, 0x63, 0x18, 0x7e, 0x77, 0x4b, 0x0b, 0xa3, 0xa9, 0x6f, 0x69, 0xf2, 0x7b, 0x00, 0xa3, 0x39, 0xe4, 0x3b, 0xf1, 0x3e, 0xf4, 0x2b, 0xa2, 0x29, 0x2f, 0xd8, 0xbc, 0x0b, 0x0b, 0xe0, 0xcd, 0xb9, 0x6d, 0xfd, 0xef, 0xdc, 0x8e, 0xff, 0x08, 0x60, 0xef, 0x07, 0x1f, 0x80, 0xae, 0xa0, 0xe7, 0x0e, 0x09, 0xad, 0xbd, 0xd2, 0xe5, 0x7f, 0xca, 0xe4, 0xc1, 0x06, 0x96, 0x2f, 0xec, 0x0a, 0x7a, 0x6e, 0xe6, 0xeb, 0x55, 0x97, 0xd7, 0x6d, 0xbd, 0xea, 0xca, 0xe2, 0x1c, 0xff, 0x19, 0xc0, 0xb0, 0x4b, 0xfc, 0x27, 0x21, 0xed, 0x99, 0xbd, 0x9d, 0xf4, 0x7f, 0x81, 0x5d, 0x3f, 0x2a, 0xf4, 0xe9, 0xba, 0x88, 0xd5, 0xf1, 0x4e, 0x1e, 0x6e, 0xe4, 0xb5, 0xda, 0x27, 0x29, 0x7c, 0x50, 0x88, 0xfa, 0x15, 0xf6, 0xb4, 0x62, 0x45, 0x5a, 0x88, 0xba, 0x16, 0xfc, 0x24, 0xea, 0x4a, 0xbc, 0x74, 0xfb, 0xbd, 0xe3, 0xd6, 0xfc, 0xcb, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0xc4, 0xfc, 0xdc, 0x27, 0x48, 0x08, 0x00, 0x00, } google-cloud-go-0.49.0/pubsub/message.go000066400000000000000000000060211356504100700200420ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package pubsub import ( "time" "github.com/golang/protobuf/ptypes" pb "google.golang.org/genproto/googleapis/pubsub/v1" ) // Message represents a Pub/Sub message. type Message struct { // ID identifies this message. // This ID is assigned by the server and is populated for Messages obtained from a subscription. // This field is read-only. ID string // Data is the actual data in the message. Data []byte // Attributes represents the key-value pairs the current message // is labelled with. Attributes map[string]string // ackID is the identifier to acknowledge this message. ackID string // The time at which the message was published. // This is populated by the server for Messages obtained from a subscription. // This field is read-only. PublishTime time.Time // receiveTime is the time the message was received by the client. receiveTime time.Time // size is the approximate size of the message's data and attributes. size int calledDone bool // The done method of the iterator that created this Message. doneFunc func(string, bool, time.Time) } func toMessage(resp *pb.ReceivedMessage) (*Message, error) { if resp.Message == nil { return &Message{ackID: resp.AckId}, nil } pubTime, err := ptypes.Timestamp(resp.Message.PublishTime) if err != nil { return nil, err } return &Message{ ackID: resp.AckId, Data: resp.Message.Data, Attributes: resp.Message.Attributes, ID: resp.Message.MessageId, PublishTime: pubTime, }, nil } // Ack indicates successful processing of a Message passed to the Subscriber.Receive callback. // It should not be called on any other Message value. // If message acknowledgement fails, the Message will be redelivered. // Client code must call Ack or Nack when finished for each received Message. // Calls to Ack or Nack have no effect after the first call. func (m *Message) Ack() { m.done(true) } // Nack indicates that the client will not or cannot process a Message passed to the Subscriber.Receive callback. // It should not be called on any other Message value. // Nack will result in the Message being redelivered more quickly than if it were allowed to expire. // Client code must call Ack or Nack when finished for each received Message. // Calls to Ack or Nack have no effect after the first call. func (m *Message) Nack() { m.done(false) } func (m *Message) done(ack bool) { if m.calledDone { return } m.calledDone = true m.doneFunc(m.ackID, ack, m.receiveTime) } google-cloud-go-0.49.0/pubsub/mock_test.go000066400000000000000000000112211356504100700204040ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package pubsub // This file provides a mock in-memory pubsub server for streaming pull testing. import ( "context" "io" "sync" "time" "cloud.google.com/go/internal/testutil" emptypb "github.com/golang/protobuf/ptypes/empty" pb "google.golang.org/genproto/googleapis/pubsub/v1" ) type mockServer struct { srv *testutil.Server pb.SubscriberServer Addr string mu sync.Mutex Acked map[string]bool // acked message IDs Deadlines map[string]int32 // deadlines by message ID pullResponses []*pullResponse ackErrs []error modAckErrs []error wg sync.WaitGroup sub *pb.Subscription } type pullResponse struct { msgs []*pb.ReceivedMessage err error } func newMockServer(port int) (*mockServer, error) { srv, err := testutil.NewServerWithPort(port) if err != nil { return nil, err } mock := &mockServer{ srv: srv, Addr: srv.Addr, Acked: map[string]bool{}, Deadlines: map[string]int32{}, sub: &pb.Subscription{ AckDeadlineSeconds: 10, PushConfig: &pb.PushConfig{}, }, } pb.RegisterSubscriberServer(srv.Gsrv, mock) srv.Start() return mock, nil } // Each call to addStreamingPullMessages results in one StreamingPullResponse. func (s *mockServer) addStreamingPullMessages(msgs []*pb.ReceivedMessage) { s.mu.Lock() s.pullResponses = append(s.pullResponses, &pullResponse{msgs, nil}) s.mu.Unlock() } func (s *mockServer) addStreamingPullError(err error) { s.mu.Lock() s.pullResponses = append(s.pullResponses, &pullResponse{nil, err}) s.mu.Unlock() } func (s *mockServer) addAckResponse(err error) { s.mu.Lock() s.ackErrs = append(s.ackErrs, err) s.mu.Unlock() } func (s *mockServer) addModAckResponse(err error) { s.mu.Lock() s.modAckErrs = append(s.modAckErrs, err) s.mu.Unlock() } func (s *mockServer) wait() { s.wg.Wait() } func (s *mockServer) StreamingPull(stream pb.Subscriber_StreamingPullServer) error { s.wg.Add(1) defer s.wg.Done() errc := make(chan error, 1) s.wg.Add(1) go func() { defer s.wg.Done() for { req, err := stream.Recv() if err != nil { errc <- err return } s.mu.Lock() for _, id := range req.AckIds { s.Acked[id] = true } for i, id := range req.ModifyDeadlineAckIds { s.Deadlines[id] = req.ModifyDeadlineSeconds[i] } s.mu.Unlock() } }() // Send responses. for { s.mu.Lock() if len(s.pullResponses) == 0 { s.mu.Unlock() // Nothing to send, so wait for the client to shut down the stream. err := <-errc // a real error, or at least EOF if err == io.EOF { return nil } return err } pr := s.pullResponses[0] s.pullResponses = s.pullResponses[1:] s.mu.Unlock() if pr.err != nil { // Add a slight delay to ensure the server receives any // messages en route from the client before shutting down the stream. // This reduces flakiness of tests involving retry. time.Sleep(200 * time.Millisecond) } if pr.err == io.EOF { return nil } if pr.err != nil { return pr.err } // Return any error from Recv. select { case err := <-errc: return err default: } res := &pb.StreamingPullResponse{ReceivedMessages: pr.msgs} if err := stream.Send(res); err != nil { return err } } } func (s *mockServer) Acknowledge(ctx context.Context, req *pb.AcknowledgeRequest) (*emptypb.Empty, error) { var err error s.mu.Lock() if len(s.ackErrs) > 0 { err = s.ackErrs[0] s.ackErrs = s.ackErrs[1:] } s.mu.Unlock() if err != nil { return nil, err } for _, id := range req.AckIds { s.Acked[id] = true } return &emptypb.Empty{}, nil } func (s *mockServer) ModifyAckDeadline(ctx context.Context, req *pb.ModifyAckDeadlineRequest) (*emptypb.Empty, error) { var err error s.mu.Lock() if len(s.modAckErrs) > 0 { err = s.modAckErrs[0] s.modAckErrs = s.modAckErrs[1:] } s.mu.Unlock() if err != nil { return nil, err } for _, id := range req.AckIds { s.Deadlines[id] = req.AckDeadlineSeconds } return &emptypb.Empty{}, nil } func (s *mockServer) GetSubscription(ctx context.Context, req *pb.GetSubscriptionRequest) (*pb.Subscription, error) { return s.sub, nil } google-cloud-go-0.49.0/pubsub/nodebug.go000066400000000000000000000013531356504100700200440ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // +build !psdebug package pubsub import "time" func addRecv(string, string, time.Time) {} func addAcks([]string) {} func addModAcks([]string, int32) {} google-cloud-go-0.49.0/pubsub/pstest/000077500000000000000000000000001356504100700174125ustar00rootroot00000000000000google-cloud-go-0.49.0/pubsub/pstest/examples_test.go000066400000000000000000000024261356504100700226220ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package pstest_test import ( "context" "cloud.google.com/go/pubsub" "cloud.google.com/go/pubsub/pstest" "google.golang.org/api/option" "google.golang.org/grpc" ) func ExampleNewServer() { ctx := context.Background() // Start a fake server running locally. srv := pstest.NewServer() defer srv.Close() // Connect to the server without using TLS. conn, err := grpc.Dial(srv.Addr, grpc.WithInsecure()) if err != nil { // TODO: Handle error. } defer conn.Close() // Use the connection when creating a pubsub client. client, err := pubsub.NewClient(ctx, "project", option.WithGRPCConn(conn)) if err != nil { // TODO: Handle error. } defer client.Close() _ = client // TODO: Use the client. } google-cloud-go-0.49.0/pubsub/pstest/fake.go000066400000000000000000000634271356504100700206630ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package pstest provides a fake Cloud PubSub service for testing. It implements a // simplified form of the service, suitable for unit tests. It may behave // differently from the actual service in ways in which the service is // non-deterministic or unspecified: timing, delivery order, etc. // // This package is EXPERIMENTAL and is subject to change without notice. // // See the example for usage. package pstest import ( "context" "fmt" "io" "path" "sort" "strings" "sync" "sync/atomic" "time" "cloud.google.com/go/internal/testutil" "github.com/golang/protobuf/ptypes" durpb "github.com/golang/protobuf/ptypes/duration" emptypb "github.com/golang/protobuf/ptypes/empty" pb "google.golang.org/genproto/googleapis/pubsub/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) // For testing. Note that even though changes to the now variable are atomic, a call // to the stored function can race with a change to that function. This could be a // problem if tests are run in parallel, or even if concurrent parts of the same test // change the value of the variable. var now atomic.Value func init() { now.Store(time.Now) ResetMinAckDeadline() } func timeNow() time.Time { return now.Load().(func() time.Time)() } // Server is a fake Pub/Sub server. type Server struct { srv *testutil.Server Addr string // The address that the server is listening on. GServer GServer // Not intended to be used directly. } // GServer is the underlying service implementor. It is not intended to be used // directly. type GServer struct { pb.PublisherServer pb.SubscriberServer mu sync.Mutex topics map[string]*topic subs map[string]*subscription msgs []*Message // all messages ever published msgsByID map[string]*Message wg sync.WaitGroup nextID int streamTimeout time.Duration } // NewServer creates a new fake server running in the current process. func NewServer() *Server { srv, err := testutil.NewServer() if err != nil { panic(fmt.Sprintf("pstest.NewServer: %v", err)) } s := &Server{ srv: srv, Addr: srv.Addr, GServer: GServer{ topics: map[string]*topic{}, subs: map[string]*subscription{}, msgsByID: map[string]*Message{}, }, } pb.RegisterPublisherServer(srv.Gsrv, &s.GServer) pb.RegisterSubscriberServer(srv.Gsrv, &s.GServer) srv.Start() return s } // Publish behaves as if the Publish RPC was called with a message with the given // data and attrs. It returns the ID of the message. // The topic will be created if it doesn't exist. // // Publish panics if there is an error, which is appropriate for testing. func (s *Server) Publish(topic string, data []byte, attrs map[string]string) string { const topicPattern = "projects/*/topics/*" ok, err := path.Match(topicPattern, topic) if err != nil { panic(err) } if !ok { panic(fmt.Sprintf("topic name must be of the form %q", topicPattern)) } _, _ = s.GServer.CreateTopic(context.TODO(), &pb.Topic{Name: topic}) req := &pb.PublishRequest{ Topic: topic, Messages: []*pb.PubsubMessage{{Data: data, Attributes: attrs}}, } res, err := s.GServer.Publish(context.TODO(), req) if err != nil { panic(fmt.Sprintf("pstest.Server.Publish: %v", err)) } return res.MessageIds[0] } // SetStreamTimeout sets the amount of time a stream will be active before it shuts // itself down. This mimics the real service's behavior of closing streams after 30 // minutes. If SetStreamTimeout is never called or is passed zero, streams never shut // down. func (s *Server) SetStreamTimeout(d time.Duration) { s.GServer.mu.Lock() defer s.GServer.mu.Unlock() s.GServer.streamTimeout = d } // A Message is a message that was published to the server. type Message struct { ID string Data []byte Attributes map[string]string PublishTime time.Time Deliveries int // number of times delivery of the message was attempted Acks int // number of acks received from clients // protected by server mutex deliveries int acks int Modacks []Modack // modacks received by server for this message } // Modack represents a modack sent to the server. type Modack struct { AckID string AckDeadline int32 ReceivedAt time.Time } // Messages returns information about all messages ever published. func (s *Server) Messages() []*Message { s.GServer.mu.Lock() defer s.GServer.mu.Unlock() var msgs []*Message for _, m := range s.GServer.msgs { m.Deliveries = m.deliveries m.Acks = m.acks msgs = append(msgs, m) } return msgs } // Message returns the message with the given ID, or nil if no message // with that ID was published. func (s *Server) Message(id string) *Message { s.GServer.mu.Lock() defer s.GServer.mu.Unlock() m := s.GServer.msgsByID[id] if m != nil { m.Deliveries = m.deliveries m.Acks = m.acks } return m } // Wait blocks until all server activity has completed. func (s *Server) Wait() { s.GServer.wg.Wait() } // ClearMessages removes all published messages // from internal containers. func (s *Server) ClearMessages() { s.GServer.mu.Lock() s.GServer.msgs = nil s.GServer.msgsByID = make(map[string]*Message) s.GServer.mu.Unlock() } // Close shuts down the server and releases all resources. func (s *Server) Close() error { s.srv.Close() s.GServer.mu.Lock() defer s.GServer.mu.Unlock() for _, sub := range s.GServer.subs { sub.stop() } return nil } func (s *GServer) CreateTopic(_ context.Context, t *pb.Topic) (*pb.Topic, error) { s.mu.Lock() defer s.mu.Unlock() if s.topics[t.Name] != nil { return nil, status.Errorf(codes.AlreadyExists, "topic %q", t.Name) } top := newTopic(t) s.topics[t.Name] = top return top.proto, nil } func (s *GServer) GetTopic(_ context.Context, req *pb.GetTopicRequest) (*pb.Topic, error) { s.mu.Lock() defer s.mu.Unlock() if t := s.topics[req.Topic]; t != nil { return t.proto, nil } return nil, status.Errorf(codes.NotFound, "topic %q", req.Topic) } func (s *GServer) UpdateTopic(_ context.Context, req *pb.UpdateTopicRequest) (*pb.Topic, error) { s.mu.Lock() defer s.mu.Unlock() t := s.topics[req.Topic.Name] if t == nil { return nil, status.Errorf(codes.NotFound, "topic %q", req.Topic.Name) } for _, path := range req.UpdateMask.Paths { switch path { case "labels": t.proto.Labels = req.Topic.Labels case "message_storage_policy": t.proto.MessageStoragePolicy = req.Topic.MessageStoragePolicy default: return nil, status.Errorf(codes.InvalidArgument, "unknown field name %q", path) } } return t.proto, nil } func (s *GServer) ListTopics(_ context.Context, req *pb.ListTopicsRequest) (*pb.ListTopicsResponse, error) { s.mu.Lock() defer s.mu.Unlock() var names []string for n := range s.topics { if strings.HasPrefix(n, req.Project) { names = append(names, n) } } sort.Strings(names) from, to, nextToken, err := testutil.PageBounds(int(req.PageSize), req.PageToken, len(names)) if err != nil { return nil, err } res := &pb.ListTopicsResponse{NextPageToken: nextToken} for i := from; i < to; i++ { res.Topics = append(res.Topics, s.topics[names[i]].proto) } return res, nil } func (s *GServer) ListTopicSubscriptions(_ context.Context, req *pb.ListTopicSubscriptionsRequest) (*pb.ListTopicSubscriptionsResponse, error) { s.mu.Lock() defer s.mu.Unlock() var names []string for name, sub := range s.subs { if sub.topic.proto.Name == req.Topic { names = append(names, name) } } sort.Strings(names) from, to, nextToken, err := testutil.PageBounds(int(req.PageSize), req.PageToken, len(names)) if err != nil { return nil, err } return &pb.ListTopicSubscriptionsResponse{ Subscriptions: names[from:to], NextPageToken: nextToken, }, nil } func (s *GServer) DeleteTopic(_ context.Context, req *pb.DeleteTopicRequest) (*emptypb.Empty, error) { s.mu.Lock() defer s.mu.Unlock() t := s.topics[req.Topic] if t == nil { return nil, status.Errorf(codes.NotFound, "topic %q", req.Topic) } t.stop() delete(s.topics, req.Topic) return &emptypb.Empty{}, nil } func (s *GServer) CreateSubscription(_ context.Context, ps *pb.Subscription) (*pb.Subscription, error) { s.mu.Lock() defer s.mu.Unlock() if ps.Name == "" { return nil, status.Errorf(codes.InvalidArgument, "missing name") } if s.subs[ps.Name] != nil { return nil, status.Errorf(codes.AlreadyExists, "subscription %q", ps.Name) } if ps.Topic == "" { return nil, status.Errorf(codes.InvalidArgument, "missing topic") } top := s.topics[ps.Topic] if top == nil { return nil, status.Errorf(codes.NotFound, "topic %q", ps.Topic) } if err := checkAckDeadline(ps.AckDeadlineSeconds); err != nil { return nil, err } if ps.MessageRetentionDuration == nil { ps.MessageRetentionDuration = defaultMessageRetentionDuration } if err := checkMRD(ps.MessageRetentionDuration); err != nil { return nil, err } if ps.PushConfig == nil { ps.PushConfig = &pb.PushConfig{} } sub := newSubscription(top, &s.mu, ps) top.subs[ps.Name] = sub s.subs[ps.Name] = sub sub.start(&s.wg) return ps, nil } // Can be set for testing. var minAckDeadlineSecs int32 // SetMinAckDeadline changes the minack deadline to n. Must be // greater than or equal to 1 second. Remember to reset this value // to the default after your test changes it. Example usage: // pstest.SetMinAckDeadlineSecs(1) // defer pstest.ResetMinAckDeadlineSecs() func SetMinAckDeadline(n time.Duration) { if n < time.Second { panic("SetMinAckDeadline expects a value greater than 1 second") } minAckDeadlineSecs = int32(n / time.Second) } // ResetMinAckDeadline resets the minack deadline to the default. func ResetMinAckDeadline() { minAckDeadlineSecs = 10 } func checkAckDeadline(ads int32) error { if ads < minAckDeadlineSecs || ads > 600 { // PubSub service returns Unknown. return status.Errorf(codes.Unknown, "bad ack_deadline_seconds: %d", ads) } return nil } const ( minMessageRetentionDuration = 10 * time.Minute maxMessageRetentionDuration = 168 * time.Hour ) var defaultMessageRetentionDuration = ptypes.DurationProto(maxMessageRetentionDuration) func checkMRD(pmrd *durpb.Duration) error { mrd, err := ptypes.Duration(pmrd) if err != nil || mrd < minMessageRetentionDuration || mrd > maxMessageRetentionDuration { return status.Errorf(codes.InvalidArgument, "bad message_retention_duration %+v", pmrd) } return nil } func (s *GServer) GetSubscription(_ context.Context, req *pb.GetSubscriptionRequest) (*pb.Subscription, error) { s.mu.Lock() defer s.mu.Unlock() sub, err := s.findSubscription(req.Subscription) if err != nil { return nil, err } return sub.proto, nil } func (s *GServer) UpdateSubscription(_ context.Context, req *pb.UpdateSubscriptionRequest) (*pb.Subscription, error) { if req.Subscription == nil { return nil, status.Errorf(codes.InvalidArgument, "missing subscription") } s.mu.Lock() defer s.mu.Unlock() sub, err := s.findSubscription(req.Subscription.Name) if err != nil { return nil, err } for _, path := range req.UpdateMask.Paths { switch path { case "push_config": sub.proto.PushConfig = req.Subscription.PushConfig case "ack_deadline_seconds": a := req.Subscription.AckDeadlineSeconds if err := checkAckDeadline(a); err != nil { return nil, err } sub.proto.AckDeadlineSeconds = a case "retain_acked_messages": sub.proto.RetainAckedMessages = req.Subscription.RetainAckedMessages case "message_retention_duration": if err := checkMRD(req.Subscription.MessageRetentionDuration); err != nil { return nil, err } sub.proto.MessageRetentionDuration = req.Subscription.MessageRetentionDuration case "labels": sub.proto.Labels = req.Subscription.Labels case "expiration_policy": sub.proto.ExpirationPolicy = req.Subscription.ExpirationPolicy default: return nil, status.Errorf(codes.InvalidArgument, "unknown field name %q", path) } } return sub.proto, nil } func (s *GServer) ListSubscriptions(_ context.Context, req *pb.ListSubscriptionsRequest) (*pb.ListSubscriptionsResponse, error) { s.mu.Lock() defer s.mu.Unlock() var names []string for name := range s.subs { if strings.HasPrefix(name, req.Project) { names = append(names, name) } } sort.Strings(names) from, to, nextToken, err := testutil.PageBounds(int(req.PageSize), req.PageToken, len(names)) if err != nil { return nil, err } res := &pb.ListSubscriptionsResponse{NextPageToken: nextToken} for i := from; i < to; i++ { res.Subscriptions = append(res.Subscriptions, s.subs[names[i]].proto) } return res, nil } func (s *GServer) DeleteSubscription(_ context.Context, req *pb.DeleteSubscriptionRequest) (*emptypb.Empty, error) { s.mu.Lock() defer s.mu.Unlock() sub, err := s.findSubscription(req.Subscription) if err != nil { return nil, err } sub.stop() delete(s.subs, req.Subscription) sub.topic.deleteSub(sub) return &emptypb.Empty{}, nil } func (s *GServer) Publish(_ context.Context, req *pb.PublishRequest) (*pb.PublishResponse, error) { s.mu.Lock() defer s.mu.Unlock() if req.Topic == "" { return nil, status.Errorf(codes.InvalidArgument, "missing topic") } top := s.topics[req.Topic] if top == nil { return nil, status.Errorf(codes.NotFound, "topic %q", req.Topic) } var ids []string for _, pm := range req.Messages { id := fmt.Sprintf("m%d", s.nextID) s.nextID++ pm.MessageId = id pubTime := timeNow() tsPubTime, err := ptypes.TimestampProto(pubTime) if err != nil { return nil, status.Errorf(codes.Internal, err.Error()) } pm.PublishTime = tsPubTime m := &Message{ ID: id, Data: pm.Data, Attributes: pm.Attributes, PublishTime: pubTime, } top.publish(pm, m) ids = append(ids, id) s.msgs = append(s.msgs, m) s.msgsByID[id] = m } return &pb.PublishResponse{MessageIds: ids}, nil } type topic struct { proto *pb.Topic subs map[string]*subscription } func newTopic(pt *pb.Topic) *topic { return &topic{ proto: pt, subs: map[string]*subscription{}, } } func (t *topic) stop() { for _, sub := range t.subs { sub.proto.Topic = "_deleted-topic_" sub.stop() } } func (t *topic) deleteSub(sub *subscription) { delete(t.subs, sub.proto.Name) } func (t *topic) publish(pm *pb.PubsubMessage, m *Message) { for _, s := range t.subs { s.msgs[pm.MessageId] = &message{ publishTime: m.PublishTime, proto: &pb.ReceivedMessage{ AckId: pm.MessageId, Message: pm, }, deliveries: &m.deliveries, acks: &m.acks, streamIndex: -1, } } } type subscription struct { topic *topic mu *sync.Mutex // the server mutex, here for convenience proto *pb.Subscription ackTimeout time.Duration msgs map[string]*message // unacked messages by message ID streams []*stream done chan struct{} } func newSubscription(t *topic, mu *sync.Mutex, ps *pb.Subscription) *subscription { at := time.Duration(ps.AckDeadlineSeconds) * time.Second if at == 0 { at = 10 * time.Second } return &subscription{ topic: t, mu: mu, proto: ps, ackTimeout: at, msgs: map[string]*message{}, done: make(chan struct{}), } } func (s *subscription) start(wg *sync.WaitGroup) { wg.Add(1) go func() { defer wg.Done() for { select { case <-s.done: return case <-time.After(10 * time.Millisecond): s.deliver() } } }() } func (s *subscription) stop() { close(s.done) } func (s *GServer) Acknowledge(_ context.Context, req *pb.AcknowledgeRequest) (*emptypb.Empty, error) { s.mu.Lock() defer s.mu.Unlock() sub, err := s.findSubscription(req.Subscription) if err != nil { return nil, err } for _, id := range req.AckIds { sub.ack(id) } return &emptypb.Empty{}, nil } func (s *GServer) ModifyAckDeadline(_ context.Context, req *pb.ModifyAckDeadlineRequest) (*emptypb.Empty, error) { s.mu.Lock() defer s.mu.Unlock() sub, err := s.findSubscription(req.Subscription) if err != nil { return nil, err } now := time.Now() for _, id := range req.AckIds { s.msgsByID[id].Modacks = append(s.msgsByID[id].Modacks, Modack{AckID: id, AckDeadline: req.AckDeadlineSeconds, ReceivedAt: now}) } dur := secsToDur(req.AckDeadlineSeconds) for _, id := range req.AckIds { sub.modifyAckDeadline(id, dur) } return &emptypb.Empty{}, nil } func (s *GServer) Pull(ctx context.Context, req *pb.PullRequest) (*pb.PullResponse, error) { s.mu.Lock() sub, err := s.findSubscription(req.Subscription) if err != nil { s.mu.Unlock() return nil, err } max := int(req.MaxMessages) if max < 0 { s.mu.Unlock() return nil, status.Error(codes.InvalidArgument, "MaxMessages cannot be negative") } if max == 0 { // MaxMessages not specified; use a default. max = 1000 } msgs := sub.pull(max) s.mu.Unlock() // Implement the spec from the pubsub proto: // "If ReturnImmediately set to true, the system will respond immediately even if // it there are no messages available to return in the `Pull` response. // Otherwise, the system may wait (for a bounded amount of time) until at // least one message is available, rather than returning no messages." if len(msgs) == 0 && !req.ReturnImmediately { // Wait for a short amount of time for a message. // TODO: signal when a message arrives, so we don't wait the whole time. select { case <-ctx.Done(): return nil, ctx.Err() case <-time.After(500 * time.Millisecond): s.mu.Lock() msgs = sub.pull(max) s.mu.Unlock() } } return &pb.PullResponse{ReceivedMessages: msgs}, nil } func (s *GServer) StreamingPull(sps pb.Subscriber_StreamingPullServer) error { // Receive initial message configuring the pull. req, err := sps.Recv() if err != nil { return err } s.mu.Lock() sub, err := s.findSubscription(req.Subscription) s.mu.Unlock() if err != nil { return err } // Create a new stream to handle the pull. st := sub.newStream(sps, s.streamTimeout) err = st.pull(&s.wg) sub.deleteStream(st) return err } func (s *GServer) Seek(ctx context.Context, req *pb.SeekRequest) (*pb.SeekResponse, error) { // Only handle time-based seeking for now. // This fake doesn't deal with snapshots. var target time.Time switch v := req.Target.(type) { case nil: return nil, status.Errorf(codes.InvalidArgument, "missing Seek target type") case *pb.SeekRequest_Time: var err error target, err = ptypes.Timestamp(v.Time) if err != nil { return nil, status.Errorf(codes.InvalidArgument, "bad Time target: %v", err) } default: return nil, status.Errorf(codes.Unimplemented, "unhandled Seek target type %T", v) } // The entire server must be locked while doing the work below, // because the messages don't have any other synchronization. s.mu.Lock() defer s.mu.Unlock() sub, err := s.findSubscription(req.Subscription) if err != nil { return nil, err } // Drop all messages from sub that were published before the target time. for id, m := range sub.msgs { if m.publishTime.Before(target) { delete(sub.msgs, id) (*m.acks)++ } } // Un-ack any already-acked messages after this time; // redelivering them to the subscription is the closest analogue here. for _, m := range s.msgs { if m.PublishTime.Before(target) { continue } sub.msgs[m.ID] = &message{ publishTime: m.PublishTime, proto: &pb.ReceivedMessage{ AckId: m.ID, // This was not preserved! //Message: pm, }, deliveries: &m.deliveries, acks: &m.acks, streamIndex: -1, } } return &pb.SeekResponse{}, nil } // Gets a subscription that must exist. // Must be called with the lock held. func (s *GServer) findSubscription(name string) (*subscription, error) { if name == "" { return nil, status.Errorf(codes.InvalidArgument, "missing subscription") } sub := s.subs[name] if sub == nil { return nil, status.Errorf(codes.NotFound, "subscription %s", name) } return sub, nil } // Must be called with the lock held. func (s *subscription) pull(max int) []*pb.ReceivedMessage { now := timeNow() s.maintainMessages(now) var msgs []*pb.ReceivedMessage for _, m := range s.msgs { if m.outstanding() { continue } (*m.deliveries)++ m.ackDeadline = now.Add(s.ackTimeout) msgs = append(msgs, m.proto) if len(msgs) >= max { break } } return msgs } func (s *subscription) deliver() { s.mu.Lock() defer s.mu.Unlock() now := timeNow() s.maintainMessages(now) // Try to deliver each remaining message. curIndex := 0 for _, m := range s.msgs { if m.outstanding() { continue } // If the message was never delivered before, start with the stream at // curIndex. If it was delivered before, start with the stream after the one // that owned it. if m.streamIndex < 0 { delIndex, ok := s.tryDeliverMessage(m, curIndex, now) if !ok { break } curIndex = delIndex + 1 m.streamIndex = curIndex } else { delIndex, ok := s.tryDeliverMessage(m, m.streamIndex, now) if !ok { break } m.streamIndex = delIndex } } } // tryDeliverMessage attempts to deliver m to the stream at index i. If it can't, it // tries streams i+1, i+2, ..., wrapping around. Once it's tried all streams, it // exits. // // It returns the index of the stream it delivered the message to, or 0, false if // it didn't deliver the message. // // Must be called with the lock held. func (s *subscription) tryDeliverMessage(m *message, start int, now time.Time) (int, bool) { for i := 0; i < len(s.streams); i++ { idx := (i + start) % len(s.streams) st := s.streams[idx] select { case <-st.done: s.streams = deleteStreamAt(s.streams, idx) i-- case st.msgc <- m.proto: (*m.deliveries)++ m.ackDeadline = now.Add(st.ackTimeout) return idx, true default: } } return 0, false } var retentionDuration = 10 * time.Minute // Must be called with the lock held. func (s *subscription) maintainMessages(now time.Time) { for id, m := range s.msgs { // Mark a message as re-deliverable if its ack deadline has expired. if m.outstanding() && now.After(m.ackDeadline) { m.makeAvailable() } pubTime, err := ptypes.Timestamp(m.proto.Message.PublishTime) if err != nil { panic(err) } // Remove messages that have been undelivered for a long time. if !m.outstanding() && now.Sub(pubTime) > retentionDuration { delete(s.msgs, id) } } } func (s *subscription) newStream(gs pb.Subscriber_StreamingPullServer, timeout time.Duration) *stream { st := &stream{ sub: s, done: make(chan struct{}), msgc: make(chan *pb.ReceivedMessage), gstream: gs, ackTimeout: s.ackTimeout, timeout: timeout, } s.mu.Lock() s.streams = append(s.streams, st) s.mu.Unlock() return st } func (s *subscription) deleteStream(st *stream) { s.mu.Lock() defer s.mu.Unlock() var i int for i = 0; i < len(s.streams); i++ { if s.streams[i] == st { break } } if i < len(s.streams) { s.streams = deleteStreamAt(s.streams, i) } } func deleteStreamAt(s []*stream, i int) []*stream { // Preserve order for round-robin delivery. return append(s[:i], s[i+1:]...) } type message struct { proto *pb.ReceivedMessage publishTime time.Time ackDeadline time.Time deliveries *int acks *int streamIndex int // index of stream that currently owns msg, for round-robin delivery } // A message is outstanding if it is owned by some stream. func (m *message) outstanding() bool { return !m.ackDeadline.IsZero() } func (m *message) makeAvailable() { m.ackDeadline = time.Time{} } type stream struct { sub *subscription done chan struct{} // closed when the stream is finished msgc chan *pb.ReceivedMessage gstream pb.Subscriber_StreamingPullServer ackTimeout time.Duration timeout time.Duration } // pull manages the StreamingPull interaction for the life of the stream. func (st *stream) pull(wg *sync.WaitGroup) error { errc := make(chan error, 2) wg.Add(2) go func() { defer wg.Done() errc <- st.sendLoop() }() go func() { defer wg.Done() errc <- st.recvLoop() }() var tchan <-chan time.Time if st.timeout > 0 { tchan = time.After(st.timeout) } // Wait until one of the goroutines returns an error, or we time out. var err error select { case err = <-errc: if err == io.EOF { err = nil } case <-tchan: } close(st.done) // stop the other goroutine return err } func (st *stream) sendLoop() error { for { select { case <-st.done: return nil case rm := <-st.msgc: res := &pb.StreamingPullResponse{ReceivedMessages: []*pb.ReceivedMessage{rm}} if err := st.gstream.Send(res); err != nil { return err } } } } func (st *stream) recvLoop() error { for { req, err := st.gstream.Recv() if err != nil { return err } st.sub.handleStreamingPullRequest(st, req) } } func (s *subscription) handleStreamingPullRequest(st *stream, req *pb.StreamingPullRequest) { // Lock the entire server. s.mu.Lock() defer s.mu.Unlock() for _, ackID := range req.AckIds { s.ack(ackID) } for i, id := range req.ModifyDeadlineAckIds { s.modifyAckDeadline(id, secsToDur(req.ModifyDeadlineSeconds[i])) } if req.StreamAckDeadlineSeconds > 0 { st.ackTimeout = secsToDur(req.StreamAckDeadlineSeconds) } } // Must be called with the lock held. func (s *subscription) ack(id string) { m := s.msgs[id] if m != nil { (*m.acks)++ delete(s.msgs, id) } } // Must be called with the lock held. func (s *subscription) modifyAckDeadline(id string, d time.Duration) { m := s.msgs[id] if m == nil { // already acked: ignore. return } if d == 0 { // nack m.makeAvailable() } else { // extend the deadline by d m.ackDeadline = timeNow().Add(d) } } func secsToDur(secs int32) time.Duration { return time.Duration(secs) * time.Second } google-cloud-go-0.49.0/pubsub/pstest/fake_test.go000066400000000000000000000531051356504100700217120ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package pstest import ( "context" "fmt" "io" "sync" "testing" "time" "cloud.google.com/go/internal/testutil" "github.com/golang/protobuf/ptypes" pb "google.golang.org/genproto/googleapis/pubsub/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) func TestTopics(t *testing.T) { pclient, _, server, cleanup := newFake(context.TODO(), t) defer cleanup() ctx := context.Background() var topics []*pb.Topic for i := 1; i < 3; i++ { topics = append(topics, mustCreateTopic(context.TODO(), t, pclient, &pb.Topic{ Name: fmt.Sprintf("projects/P/topics/T%d", i), Labels: map[string]string{"num": fmt.Sprintf("%d", i)}, })) } if got, want := len(server.GServer.topics), len(topics); got != want { t.Fatalf("got %d topics, want %d", got, want) } for _, top := range topics { got, err := pclient.GetTopic(ctx, &pb.GetTopicRequest{Topic: top.Name}) if err != nil { t.Fatal(err) } if !testutil.Equal(got, top) { t.Errorf("\ngot %+v\nwant %+v", got, top) } } res, err := pclient.ListTopics(ctx, &pb.ListTopicsRequest{Project: "projects/P"}) if err != nil { t.Fatal(err) } if got, want := res.Topics, topics; !testutil.Equal(got, want) { t.Errorf("\ngot %+v\nwant %+v", got, want) } for _, top := range topics { if _, err := pclient.DeleteTopic(ctx, &pb.DeleteTopicRequest{Topic: top.Name}); err != nil { t.Fatal(err) } } if got, want := len(server.GServer.topics), 0; got != want { t.Fatalf("got %d topics, want %d", got, want) } } func TestSubscriptions(t *testing.T) { pclient, sclient, server, cleanup := newFake(context.TODO(), t) defer cleanup() ctx := context.Background() topic := mustCreateTopic(context.TODO(), t, pclient, &pb.Topic{Name: "projects/P/topics/T"}) var subs []*pb.Subscription for i := 0; i < 3; i++ { subs = append(subs, mustCreateSubscription(context.TODO(), t, sclient, &pb.Subscription{ Name: fmt.Sprintf("projects/P/subscriptions/S%d", i), Topic: topic.Name, AckDeadlineSeconds: int32(10 * (i + 1)), })) } if got, want := len(server.GServer.subs), len(subs); got != want { t.Fatalf("got %d subscriptions, want %d", got, want) } for _, s := range subs { got, err := sclient.GetSubscription(ctx, &pb.GetSubscriptionRequest{Subscription: s.Name}) if err != nil { t.Fatal(err) } if !testutil.Equal(got, s) { t.Errorf("\ngot %+v\nwant %+v", got, s) } } res, err := sclient.ListSubscriptions(ctx, &pb.ListSubscriptionsRequest{Project: "projects/P"}) if err != nil { t.Fatal(err) } if got, want := res.Subscriptions, subs; !testutil.Equal(got, want) { t.Errorf("\ngot %+v\nwant %+v", got, want) } res2, err := pclient.ListTopicSubscriptions(ctx, &pb.ListTopicSubscriptionsRequest{Topic: topic.Name}) if err != nil { t.Fatal(err) } if got, want := len(res2.Subscriptions), len(subs); got != want { t.Fatalf("got %d subs, want %d", got, want) } for i, got := range res2.Subscriptions { want := subs[i].Name if !testutil.Equal(got, want) { t.Errorf("\ngot %+v\nwant %+v", got, want) } } for _, s := range subs { if _, err := sclient.DeleteSubscription(ctx, &pb.DeleteSubscriptionRequest{Subscription: s.Name}); err != nil { t.Fatal(err) } } if got, want := len(server.GServer.subs), 0; got != want { t.Fatalf("got %d subscriptions, want %d", got, want) } } func TestSubscriptionErrors(t *testing.T) { _, sclient, _, cleanup := newFake(context.TODO(), t) defer cleanup() ctx := context.Background() checkCode := func(err error, want codes.Code) { t.Helper() if status.Code(err) != want { t.Errorf("got %v, want code %s", err, want) } } _, err := sclient.GetSubscription(ctx, &pb.GetSubscriptionRequest{}) checkCode(err, codes.InvalidArgument) _, err = sclient.GetSubscription(ctx, &pb.GetSubscriptionRequest{Subscription: "s"}) checkCode(err, codes.NotFound) _, err = sclient.UpdateSubscription(ctx, &pb.UpdateSubscriptionRequest{}) checkCode(err, codes.InvalidArgument) _, err = sclient.UpdateSubscription(ctx, &pb.UpdateSubscriptionRequest{Subscription: &pb.Subscription{}}) checkCode(err, codes.InvalidArgument) _, err = sclient.UpdateSubscription(ctx, &pb.UpdateSubscriptionRequest{Subscription: &pb.Subscription{Name: "s"}}) checkCode(err, codes.NotFound) _, err = sclient.DeleteSubscription(ctx, &pb.DeleteSubscriptionRequest{}) checkCode(err, codes.InvalidArgument) _, err = sclient.DeleteSubscription(ctx, &pb.DeleteSubscriptionRequest{Subscription: "s"}) checkCode(err, codes.NotFound) _, err = sclient.Acknowledge(ctx, &pb.AcknowledgeRequest{}) checkCode(err, codes.InvalidArgument) _, err = sclient.Acknowledge(ctx, &pb.AcknowledgeRequest{Subscription: "s"}) checkCode(err, codes.NotFound) _, err = sclient.ModifyAckDeadline(ctx, &pb.ModifyAckDeadlineRequest{}) checkCode(err, codes.InvalidArgument) _, err = sclient.ModifyAckDeadline(ctx, &pb.ModifyAckDeadlineRequest{Subscription: "s"}) checkCode(err, codes.NotFound) _, err = sclient.Pull(ctx, &pb.PullRequest{}) checkCode(err, codes.InvalidArgument) _, err = sclient.Pull(ctx, &pb.PullRequest{Subscription: "s"}) checkCode(err, codes.NotFound) _, err = sclient.Seek(ctx, &pb.SeekRequest{}) checkCode(err, codes.InvalidArgument) srt := &pb.SeekRequest_Time{Time: ptypes.TimestampNow()} _, err = sclient.Seek(ctx, &pb.SeekRequest{Target: srt}) checkCode(err, codes.InvalidArgument) _, err = sclient.Seek(ctx, &pb.SeekRequest{Target: srt, Subscription: "s"}) checkCode(err, codes.NotFound) } func TestPublish(t *testing.T) { s := NewServer() defer s.Close() var ids []string for i := 0; i < 3; i++ { ids = append(ids, s.Publish("projects/p/topics/t", []byte("hello"), nil)) } s.Wait() ms := s.Messages() if got, want := len(ms), len(ids); got != want { t.Errorf("got %d messages, want %d", got, want) } for i, id := range ids { if got, want := ms[i].ID, id; got != want { t.Errorf("got %s, want %s", got, want) } } m := s.Message(ids[1]) if m == nil { t.Error("got nil, want a message") } } func TestClearMessages(t *testing.T) { s := NewServer() defer s.Close() for i := 0; i < 3; i++ { s.Publish("projects/p/topics/t", []byte("hello"), nil) } s.Wait() msgs := s.Messages() if got, want := len(msgs), 3; got != want { t.Errorf("got %d messages, want %d", got, want) } s.ClearMessages() msgs = s.Messages() if got, want := len(msgs), 0; got != want { t.Errorf("got %d messages, want %d", got, want) } } // Note: this sets the fake's "now" time, so it is sensitive to concurrent changes to "now". func publish(t *testing.T, pclient pb.PublisherClient, topic *pb.Topic, messages []*pb.PubsubMessage) map[string]*pb.PubsubMessage { pubTime := time.Now() now.Store(func() time.Time { return pubTime }) defer func() { now.Store(time.Now) }() res, err := pclient.Publish(context.Background(), &pb.PublishRequest{ Topic: topic.Name, Messages: messages, }) if err != nil { t.Fatal(err) } tsPubTime, err := ptypes.TimestampProto(pubTime) if err != nil { t.Fatal(err) } want := map[string]*pb.PubsubMessage{} for i, id := range res.MessageIds { want[id] = &pb.PubsubMessage{ Data: messages[i].Data, Attributes: messages[i].Attributes, MessageId: id, PublishTime: tsPubTime, } } return want } func TestPull(t *testing.T) { pclient, sclient, _, cleanup := newFake(context.TODO(), t) defer cleanup() top := mustCreateTopic(context.TODO(), t, pclient, &pb.Topic{Name: "projects/P/topics/T"}) sub := mustCreateSubscription(context.TODO(), t, sclient, &pb.Subscription{ Name: "projects/P/subscriptions/S", Topic: top.Name, AckDeadlineSeconds: 10, }) want := publish(t, pclient, top, []*pb.PubsubMessage{ {Data: []byte("d1")}, {Data: []byte("d2")}, {Data: []byte("d3")}, }) got := pubsubMessages(pullN(context.TODO(), t, len(want), sclient, sub)) if diff := testutil.Diff(got, want); diff != "" { t.Error(diff) } res, err := sclient.Pull(context.Background(), &pb.PullRequest{Subscription: sub.Name}) if err != nil { t.Fatal(err) } if len(res.ReceivedMessages) != 0 { t.Errorf("got %d messages, want zero", len(res.ReceivedMessages)) } } func TestStreamingPull(t *testing.T) { // A simple test of streaming pull. pclient, sclient, _, cleanup := newFake(context.TODO(), t) defer cleanup() top := mustCreateTopic(context.TODO(), t, pclient, &pb.Topic{Name: "projects/P/topics/T"}) sub := mustCreateSubscription(context.TODO(), t, sclient, &pb.Subscription{ Name: "projects/P/subscriptions/S", Topic: top.Name, AckDeadlineSeconds: 10, }) want := publish(t, pclient, top, []*pb.PubsubMessage{ {Data: []byte("d1")}, {Data: []byte("d2")}, {Data: []byte("d3")}, }) got := pubsubMessages(streamingPullN(context.TODO(), t, len(want), sclient, sub)) if diff := testutil.Diff(got, want); diff != "" { t.Error(diff) } } // This test acks each message as it arrives and makes sure we don't see dups. func TestStreamingPullAck(t *testing.T) { minAckDeadlineSecs = 1 pclient, sclient, _, cleanup := newFake(context.TODO(), t) defer cleanup() top := mustCreateTopic(context.TODO(), t, pclient, &pb.Topic{Name: "projects/P/topics/T"}) sub := mustCreateSubscription(context.TODO(), t, sclient, &pb.Subscription{ Name: "projects/P/subscriptions/S", Topic: top.Name, AckDeadlineSeconds: 1, }) _ = publish(t, pclient, top, []*pb.PubsubMessage{ {Data: []byte("d1")}, {Data: []byte("d2")}, {Data: []byte("d3")}, }) got := map[string]bool{} ctx, cancel := context.WithCancel(context.Background()) spc := mustStartStreamingPull(ctx, t, sclient, sub) time.AfterFunc(time.Duration(2*minAckDeadlineSecs)*time.Second, cancel) for i := 0; i < 4; i++ { res, err := spc.Recv() if err == io.EOF { break } if err != nil { if status.Code(err) == codes.Canceled { break } t.Fatal(err) } if i == 3 { t.Fatal("expected to only see 3 messages, got 4") } req := &pb.StreamingPullRequest{} for _, m := range res.ReceivedMessages { if got[m.Message.MessageId] { t.Fatal("duplicate message") } got[m.Message.MessageId] = true req.AckIds = append(req.AckIds, m.AckId) } if err := spc.Send(req); err != nil { t.Fatal(err) } } } func TestAcknowledge(t *testing.T) { ctx := context.Background() pclient, sclient, srv, cleanup := newFake(context.TODO(), t) defer cleanup() top := mustCreateTopic(context.TODO(), t, pclient, &pb.Topic{Name: "projects/P/topics/T"}) sub := mustCreateSubscription(context.TODO(), t, sclient, &pb.Subscription{ Name: "projects/P/subscriptions/S", Topic: top.Name, AckDeadlineSeconds: 10, }) publish(t, pclient, top, []*pb.PubsubMessage{ {Data: []byte("d1")}, {Data: []byte("d2")}, {Data: []byte("d3")}, }) msgs := streamingPullN(context.TODO(), t, 3, sclient, sub) var ackIDs []string for _, m := range msgs { ackIDs = append(ackIDs, m.AckId) } if _, err := sclient.Acknowledge(ctx, &pb.AcknowledgeRequest{ Subscription: sub.Name, AckIds: ackIDs, }); err != nil { t.Fatal(err) } smsgs := srv.Messages() if got, want := len(smsgs), 3; got != want { t.Fatalf("got %d messages, want %d", got, want) } for _, sm := range smsgs { if sm.Acks != 1 { t.Errorf("message %s: got %d acks, want 1", sm.ID, sm.Acks) } } } func TestModAck(t *testing.T) { ctx := context.Background() pclient, sclient, _, cleanup := newFake(context.TODO(), t) defer cleanup() top := mustCreateTopic(context.TODO(), t, pclient, &pb.Topic{Name: "projects/P/topics/T"}) sub := mustCreateSubscription(context.TODO(), t, sclient, &pb.Subscription{ Name: "projects/P/subscriptions/S", Topic: top.Name, AckDeadlineSeconds: 10, }) publish(t, pclient, top, []*pb.PubsubMessage{ {Data: []byte("d1")}, {Data: []byte("d2")}, {Data: []byte("d3")}, }) msgs := streamingPullN(context.TODO(), t, 3, sclient, sub) var ackIDs []string for _, m := range msgs { ackIDs = append(ackIDs, m.AckId) } if _, err := sclient.ModifyAckDeadline(ctx, &pb.ModifyAckDeadlineRequest{ Subscription: sub.Name, AckIds: ackIDs, AckDeadlineSeconds: 0, }); err != nil { t.Fatal(err) } // Having nacked all three messages, we should see them again. msgs = streamingPullN(context.TODO(), t, 3, sclient, sub) if got, want := len(msgs), 3; got != want { t.Errorf("got %d messages, want %d", got, want) } } func TestAckDeadline(t *testing.T) { // Messages should be resent after they expire. pclient, sclient, _, cleanup := newFake(context.TODO(), t) defer cleanup() minAckDeadlineSecs = 2 top := mustCreateTopic(context.TODO(), t, pclient, &pb.Topic{Name: "projects/P/topics/T"}) sub := mustCreateSubscription(context.TODO(), t, sclient, &pb.Subscription{ Name: "projects/P/subscriptions/S", Topic: top.Name, AckDeadlineSeconds: minAckDeadlineSecs, }) _ = publish(t, pclient, top, []*pb.PubsubMessage{ {Data: []byte("d1")}, {Data: []byte("d2")}, {Data: []byte("d3")}, }) got := map[string]int{} spc := mustStartStreamingPull(context.TODO(), t, sclient, sub) // In 5 seconds the ack deadline will expire twice, so we should see each message // exactly three times. time.AfterFunc(5*time.Second, func() { if err := spc.CloseSend(); err != nil { t.Errorf("CloseSend: %v", err) } }) for { res, err := spc.Recv() if err == io.EOF { break } if err != nil { t.Fatal(err) } for _, m := range res.ReceivedMessages { got[m.Message.MessageId]++ } } for id, n := range got { if n != 3 { t.Errorf("message %s: saw %d times, want 3", id, n) } } } func TestMultiSubs(t *testing.T) { // Each subscription gets every message. pclient, sclient, _, cleanup := newFake(context.TODO(), t) defer cleanup() top := mustCreateTopic(context.TODO(), t, pclient, &pb.Topic{Name: "projects/P/topics/T"}) sub1 := mustCreateSubscription(context.TODO(), t, sclient, &pb.Subscription{ Name: "projects/P/subscriptions/S1", Topic: top.Name, AckDeadlineSeconds: 10, }) sub2 := mustCreateSubscription(context.TODO(), t, sclient, &pb.Subscription{ Name: "projects/P/subscriptions/S2", Topic: top.Name, AckDeadlineSeconds: 10, }) want := publish(t, pclient, top, []*pb.PubsubMessage{ {Data: []byte("d1")}, {Data: []byte("d2")}, {Data: []byte("d3")}, }) got1 := pubsubMessages(streamingPullN(context.TODO(), t, len(want), sclient, sub1)) got2 := pubsubMessages(streamingPullN(context.TODO(), t, len(want), sclient, sub2)) if diff := testutil.Diff(got1, want); diff != "" { t.Error(diff) } if diff := testutil.Diff(got2, want); diff != "" { t.Error(diff) } } // Messages are handed out to all streams of a subscription in a best-effort // round-robin behavior. The fake server prefers to fail-fast onto another // stream when one stream is already busy, though, so we're unable to test // strict round robin behavior. func TestMultiStreams(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() pclient, sclient, _, cleanup := newFake(ctx, t) defer cleanup() top := mustCreateTopic(ctx, t, pclient, &pb.Topic{Name: "projects/P/topics/T"}) sub := mustCreateSubscription(ctx, t, sclient, &pb.Subscription{ Name: "projects/P/subscriptions/S", Topic: top.Name, AckDeadlineSeconds: 10, }) st1 := mustStartStreamingPull(ctx, t, sclient, sub) defer st1.CloseSend() st1Received := make(chan struct{}) go func() { _, err := st1.Recv() if err != nil { t.Error(err) } close(st1Received) }() st2 := mustStartStreamingPull(ctx, t, sclient, sub) defer st2.CloseSend() st2Received := make(chan struct{}) go func() { _, err := st2.Recv() if err != nil { t.Error(err) } close(st2Received) }() publish(t, pclient, top, []*pb.PubsubMessage{ {Data: []byte("d1")}, {Data: []byte("d2")}, }) timeout := time.After(5 * time.Second) select { case <-timeout: t.Fatal("timed out waiting for stream 1 to receive any message") case <-st1Received: } select { case <-timeout: t.Fatal("timed out waiting for stream 1 to receive any message") case <-st2Received: } } func TestStreamingPullTimeout(t *testing.T) { pclient, sclient, srv, cleanup := newFake(context.TODO(), t) defer cleanup() timeout := 200 * time.Millisecond srv.SetStreamTimeout(timeout) top := mustCreateTopic(context.TODO(), t, pclient, &pb.Topic{Name: "projects/P/topics/T"}) sub := mustCreateSubscription(context.TODO(), t, sclient, &pb.Subscription{ Name: "projects/P/subscriptions/S", Topic: top.Name, AckDeadlineSeconds: 10, }) stream := mustStartStreamingPull(context.TODO(), t, sclient, sub) time.Sleep(2 * timeout) _, err := stream.Recv() if err != io.EOF { t.Errorf("got %v, want io.EOF", err) } } func TestSeek(t *testing.T) { pclient, sclient, _, cleanup := newFake(context.TODO(), t) defer cleanup() top := mustCreateTopic(context.TODO(), t, pclient, &pb.Topic{Name: "projects/P/topics/T"}) sub := mustCreateSubscription(context.TODO(), t, sclient, &pb.Subscription{ Name: "projects/P/subscriptions/S", Topic: top.Name, AckDeadlineSeconds: 10, }) ts := ptypes.TimestampNow() _, err := sclient.Seek(context.Background(), &pb.SeekRequest{ Subscription: sub.Name, Target: &pb.SeekRequest_Time{Time: ts}, }) if err != nil { t.Errorf("Seeking: %v", err) } } func TestTryDeliverMessage(t *testing.T) { for _, test := range []struct { availStreamIdx int expectedOutIdx int }{ {availStreamIdx: 0, expectedOutIdx: 0}, // Stream 1 will always be marked for deletion. {availStreamIdx: 2, expectedOutIdx: 1}, // s0, s1 (deleted), s2, s3 becomes s0, s2, s3. So we expect outIdx=1. {availStreamIdx: 3, expectedOutIdx: 2}, // s0, s1 (deleted), s2, s3 becomes s0, s2, s3. So we expect outIdx=2. } { top := newTopic(&pb.Topic{Name: "some-topic"}) sub := newSubscription(top, &sync.Mutex{}, &pb.Subscription{Name: "some-sub", Topic: "some-topic"}) done := make(chan struct{}, 1) done <- struct{}{} sub.streams = []*stream{{}, {done: done}, {}, {}} msgc := make(chan *pb.ReceivedMessage, 1) sub.streams[test.availStreamIdx].msgc = msgc var d int idx, ok := sub.tryDeliverMessage(&message{deliveries: &d}, 0, time.Now()) if !ok { t.Fatalf("[avail=%d]: expected msg to be put on stream %d's channel, but it was not", test.availStreamIdx, test.expectedOutIdx) } if idx != test.expectedOutIdx { t.Fatalf("[avail=%d]: expected msg to be put on stream %d, but it was put on %d", test.availStreamIdx, test.expectedOutIdx, idx) } select { case <-msgc: default: t.Fatalf("[avail=%d]: expected msg to be put on stream %d's channel, but it was not", test.availStreamIdx, idx) } } } func mustStartStreamingPull(ctx context.Context, t *testing.T, sc pb.SubscriberClient, sub *pb.Subscription) pb.Subscriber_StreamingPullClient { spc, err := sc.StreamingPull(ctx) if err != nil { t.Fatal(err) } if err := spc.Send(&pb.StreamingPullRequest{Subscription: sub.Name}); err != nil { t.Fatal(err) } return spc } func pullN(ctx context.Context, t *testing.T, n int, sc pb.SubscriberClient, sub *pb.Subscription) map[string]*pb.ReceivedMessage { got := map[string]*pb.ReceivedMessage{} for i := 0; len(got) < n; i++ { res, err := sc.Pull(ctx, &pb.PullRequest{Subscription: sub.Name, MaxMessages: int32(n - len(got))}) if err != nil { t.Fatal(err) } for _, m := range res.ReceivedMessages { got[m.Message.MessageId] = m } } return got } func streamingPullN(ctx context.Context, t *testing.T, n int, sc pb.SubscriberClient, sub *pb.Subscription) map[string]*pb.ReceivedMessage { spc := mustStartStreamingPull(ctx, t, sc, sub) got := map[string]*pb.ReceivedMessage{} for i := 0; i < n; i++ { res, err := spc.Recv() if err != nil { t.Fatal(err) } for _, m := range res.ReceivedMessages { got[m.Message.MessageId] = m } } if err := spc.CloseSend(); err != nil { t.Fatal(err) } res, err := spc.Recv() if err != io.EOF { t.Fatalf("Recv returned <%v> instead of EOF; res = %v", err, res) } return got } func pubsubMessages(rms map[string]*pb.ReceivedMessage) map[string]*pb.PubsubMessage { ms := map[string]*pb.PubsubMessage{} for k, rm := range rms { ms[k] = rm.Message } return ms } func mustCreateTopic(ctx context.Context, t *testing.T, pc pb.PublisherClient, topic *pb.Topic) *pb.Topic { top, err := pc.CreateTopic(ctx, topic) if err != nil { t.Fatal(err) } return top } func mustCreateSubscription(ctx context.Context, t *testing.T, sc pb.SubscriberClient, sub *pb.Subscription) *pb.Subscription { sub, err := sc.CreateSubscription(ctx, sub) if err != nil { t.Fatal(err) } return sub } // newFake creates a new fake server along with a publisher and subscriber // client. Its final return is a cleanup function. // // Note: be sure to call cleanup! func newFake(ctx context.Context, t *testing.T) (pb.PublisherClient, pb.SubscriberClient, *Server, func()) { srv := NewServer() conn, err := grpc.DialContext(ctx, srv.Addr, grpc.WithInsecure()) if err != nil { t.Fatal(err) } return pb.NewPublisherClient(conn), pb.NewSubscriberClient(conn), srv, func() { srv.Close() conn.Close() } } google-cloud-go-0.49.0/pubsub/pstest_test.go000066400000000000000000000047561356504100700210140ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package pubsub_test import ( "context" "strconv" "sync" "testing" "cloud.google.com/go/internal/testutil" "cloud.google.com/go/pubsub" "cloud.google.com/go/pubsub/pstest" "google.golang.org/api/option" "google.golang.org/grpc" ) // withGRPCHeadersAssertionAlt is named differently than // withGRPCHeadersAssertion in integration_test.go, because integration_test.go // doesn't perform an external test i.e. its package name is "pubsub" while // this one's is "pubsub_test", and when using Go Modules, without this rename // go test won't find the function "withGRPCHeadersAssertion". func withGRPCHeadersAssertionAlt(t *testing.T, opts ...option.ClientOption) []option.ClientOption { grpcHeadersEnforcer := &testutil.HeadersEnforcer{ OnFailure: t.Fatalf, Checkers: []*testutil.HeaderChecker{ testutil.XGoogClientHeaderChecker, }, } return append(grpcHeadersEnforcer.CallOptions(), opts...) } func TestPSTest(t *testing.T) { t.Parallel() ctx := context.Background() srv := pstest.NewServer() defer srv.Close() conn, err := grpc.Dial(srv.Addr, grpc.WithInsecure()) if err != nil { panic(err) } defer conn.Close() opts := withGRPCHeadersAssertionAlt(t, option.WithGRPCConn(conn)) client, err := pubsub.NewClient(ctx, "some-project", opts...) if err != nil { panic(err) } defer client.Close() topic, err := client.CreateTopic(ctx, "test-topic") if err != nil { panic(err) } sub, err := client.CreateSubscription(ctx, "sub-name", pubsub.SubscriptionConfig{Topic: topic}) if err != nil { panic(err) } go func() { for i := 0; i < 10; i++ { srv.Publish("projects/some-project/topics/test-topic", []byte(strconv.Itoa(i)), nil) } }() ctx, cancel := context.WithCancel(ctx) var mu sync.Mutex count := 0 err = sub.Receive(ctx, func(ctx context.Context, m *pubsub.Message) { mu.Lock() count++ if count >= 10 { cancel() } mu.Unlock() m.Ack() }) if err != nil { panic(err) } } google-cloud-go-0.49.0/pubsub/pubsub.go000066400000000000000000000067051356504100700177270ustar00rootroot00000000000000// Copyright 2014 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package pubsub // import "cloud.google.com/go/pubsub" import ( "context" "fmt" "os" "runtime" "time" "cloud.google.com/go/internal/version" vkit "cloud.google.com/go/pubsub/apiv1" "google.golang.org/api/option" "google.golang.org/grpc" "google.golang.org/grpc/keepalive" ) const ( // ScopePubSub grants permissions to view and manage Pub/Sub // topics and subscriptions. ScopePubSub = "https://www.googleapis.com/auth/pubsub" // ScopeCloudPlatform grants permissions to view and manage your data // across Google Cloud Platform services. ScopeCloudPlatform = "https://www.googleapis.com/auth/cloud-platform" maxAckDeadline = 10 * time.Minute ) // Client is a Google Pub/Sub client scoped to a single project. // // Clients should be reused rather than being created as needed. // A Client may be shared by multiple goroutines. type Client struct { projectID string pubc *vkit.PublisherClient subc *vkit.SubscriberClient } // NewClient creates a new PubSub client. func NewClient(ctx context.Context, projectID string, opts ...option.ClientOption) (c *Client, err error) { var o []option.ClientOption // Environment variables for gcloud emulator: // https://cloud.google.com/sdk/gcloud/reference/beta/emulators/pubsub/ if addr := os.Getenv("PUBSUB_EMULATOR_HOST"); addr != "" { conn, err := grpc.Dial(addr, grpc.WithInsecure()) if err != nil { return nil, fmt.Errorf("grpc.Dial: %v", err) } o = []option.ClientOption{option.WithGRPCConn(conn)} } else { numConns := runtime.GOMAXPROCS(0) if numConns > 4 { numConns = 4 } o = []option.ClientOption{ // Create multiple connections to increase throughput. option.WithGRPCConnectionPool(numConns), option.WithGRPCDialOption(grpc.WithKeepaliveParams(keepalive.ClientParameters{ Time: 5 * time.Minute, })), } o = append(o, openCensusOptions()...) } o = append(o, opts...) pubc, err := vkit.NewPublisherClient(ctx, o...) if err != nil { return nil, fmt.Errorf("pubsub: %v", err) } subc, err := vkit.NewSubscriberClient(ctx, option.WithGRPCConn(pubc.Connection())) if err != nil { // Should never happen, since we are passing in the connection. // If it does, we cannot close, because the user may have passed in their // own connection originally. return nil, fmt.Errorf("pubsub: %v", err) } pubc.SetGoogleClientInfo("gccl", version.Repo) return &Client{ projectID: projectID, pubc: pubc, subc: subc, }, nil } // Close releases any resources held by the client, // such as memory and goroutines. // // If the client is available for the lifetime of the program, then Close need not be // called at exit. func (c *Client) Close() error { // Return the first error, because the first call closes the connection. err := c.pubc.Close() _ = c.subc.Close() return err } func (c *Client) fullyQualifiedProjectName() string { return fmt.Sprintf("projects/%s", c.projectID) } google-cloud-go-0.49.0/pubsub/pullstream.go000066400000000000000000000127521356504100700206160ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package pubsub import ( "context" "io" "sync" "time" gax "github.com/googleapis/gax-go/v2" pb "google.golang.org/genproto/googleapis/pubsub/v1" "google.golang.org/grpc" ) // A pullStream supports the methods of a StreamingPullClient, but re-opens // the stream on a retryable error. type pullStream struct { ctx context.Context open func() (pb.Subscriber_StreamingPullClient, error) mu sync.Mutex spc *pb.Subscriber_StreamingPullClient err error // permanent error } // for testing type streamingPullFunc func(context.Context, ...gax.CallOption) (pb.Subscriber_StreamingPullClient, error) func newPullStream(ctx context.Context, streamingPull streamingPullFunc, subName string) *pullStream { ctx = withSubscriptionKey(ctx, subName) return &pullStream{ ctx: ctx, open: func() (pb.Subscriber_StreamingPullClient, error) { spc, err := streamingPull(ctx, gax.WithGRPCOptions(grpc.MaxCallRecvMsgSize(maxSendRecvBytes))) if err == nil { recordStat(ctx, StreamRequestCount, 1) err = spc.Send(&pb.StreamingPullRequest{ Subscription: subName, // We modack messages when we receive them, so this value doesn't matter too much. StreamAckDeadlineSeconds: 60, }) } if err != nil { return nil, err } return spc, nil }, } } // get returns either a valid *StreamingPullClient (SPC), or a permanent error. // If the argument is nil, this is the first call for an RPC, and the current // SPC will be returned (or a new one will be opened). Otherwise, this call is a // request to re-open the stream because of a retryable error, and the argument // is a pointer to the SPC that returned the error. func (s *pullStream) get(spc *pb.Subscriber_StreamingPullClient) (*pb.Subscriber_StreamingPullClient, error) { s.mu.Lock() defer s.mu.Unlock() // A stored error is permanent. if s.err != nil { return nil, s.err } // If the context is done, so are we. s.err = s.ctx.Err() if s.err != nil { return nil, s.err } // If the current and argument SPCs differ, return the current one. This subsumes two cases: // 1. We have an SPC and the caller is getting the stream for the first time. // 2. The caller wants to retry, but they have an older SPC; we've already retried. if spc != s.spc { return s.spc, nil } // Either this is the very first call on this stream (s.spc == nil), or we have a valid // retry request. Either way, open a new stream. // The lock is held here for a long time, but it doesn't matter because no callers could get // anything done anyway. s.spc = new(pb.Subscriber_StreamingPullClient) *s.spc, s.err = s.openWithRetry() // Any error from openWithRetry is permanent. return s.spc, s.err } func (s *pullStream) openWithRetry() (pb.Subscriber_StreamingPullClient, error) { r := defaultRetryer{} for { recordStat(s.ctx, StreamOpenCount, 1) spc, err := s.open() bo, shouldRetry := r.Retry(err) if err != nil && shouldRetry { recordStat(s.ctx, StreamRetryCount, 1) if err := gax.Sleep(s.ctx, bo); err != nil { return nil, err } continue } return spc, err } } func (s *pullStream) call(f func(pb.Subscriber_StreamingPullClient) error, opts ...gax.CallOption) error { var settings gax.CallSettings for _, opt := range opts { opt.Resolve(&settings) } var r gax.Retryer = &defaultRetryer{} if settings.Retry != nil { r = settings.Retry() } var ( spc *pb.Subscriber_StreamingPullClient err error ) for { spc, err = s.get(spc) if err != nil { return err } start := time.Now() err = f(*spc) if err != nil { bo, shouldRetry := r.Retry(err) if shouldRetry { recordStat(s.ctx, StreamRetryCount, 1) if time.Since(start) < 30*time.Second { // don't sleep if we've been blocked for a while if err := gax.Sleep(s.ctx, bo); err != nil { return err } } continue } s.mu.Lock() s.err = err s.mu.Unlock() } return err } } func (s *pullStream) Send(req *pb.StreamingPullRequest) error { return s.call(func(spc pb.Subscriber_StreamingPullClient) error { recordStat(s.ctx, AckCount, int64(len(req.AckIds))) zeroes := 0 for _, mds := range req.ModifyDeadlineSeconds { if mds == 0 { zeroes++ } } recordStat(s.ctx, NackCount, int64(zeroes)) recordStat(s.ctx, ModAckCount, int64(len(req.ModifyDeadlineSeconds)-zeroes)) recordStat(s.ctx, StreamRequestCount, 1) return spc.Send(req) }) } func (s *pullStream) Recv() (*pb.StreamingPullResponse, error) { var res *pb.StreamingPullResponse err := s.call(func(spc pb.Subscriber_StreamingPullClient) error { var err error recordStat(s.ctx, StreamResponseCount, 1) res, err = spc.Recv() return err }, gax.WithRetry(func() gax.Retryer { return &streamingPullRetryer{defaultRetryer: &defaultRetryer{}} })) return res, err } func (s *pullStream) CloseSend() error { err := s.call(func(spc pb.Subscriber_StreamingPullClient) error { return spc.CloseSend() }) s.mu.Lock() s.err = io.EOF // should not be retried s.mu.Unlock() return err } google-cloud-go-0.49.0/pubsub/pullstream_test.go000066400000000000000000000073031356504100700216510ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package pubsub import ( "context" "testing" "time" "cloud.google.com/go/internal/testutil" "cloud.google.com/go/pubsub/pstest" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" pb "google.golang.org/genproto/googleapis/pubsub/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) func TestPullStreamGet(t *testing.T) { // Test that we retry on the initial Send call from pullstream.get. We don't do this // test with the server in fake_test.go because there's no clear way to get Send // to fail from the server. t.Parallel() for _, test := range []struct { desc string errors []error wantCode codes.Code }{ { desc: "nil error", errors: []error{nil}, wantCode: codes.OK, }, { desc: "non-retryable error", errors: []error{status.Errorf(codes.InvalidArgument, "")}, wantCode: codes.InvalidArgument, }, { desc: "retryable errors", errors: []error{ status.Errorf(codes.Unavailable, "first"), status.Errorf(codes.Unavailable, "second"), nil, }, wantCode: codes.OK, }, } { streamingPull := func(context.Context, ...gax.CallOption) (pb.Subscriber_StreamingPullClient, error) { if len(test.errors) == 0 { panic("out of errors") } err := test.errors[0] test.errors = test.errors[1:] return &testStreamingPullClient{sendError: err}, nil } ps := newPullStream(context.Background(), streamingPull, "") _, err := ps.get(nil) if got := status.Code(err); got != test.wantCode { t.Errorf("%s: got %s, want %s", test.desc, got, test.wantCode) } } } func TestPullStreamGet_ResourceUnavailable(t *testing.T) { ctx := context.Background() srv, err := testutil.NewServer() if err != nil { t.Fatal(err) } defer srv.Close() ps := pstest.NewServer() defer ps.Close() s := ExhaustedServer{&ps.GServer} pb.RegisterPublisherServer(srv.Gsrv, &s) pb.RegisterSubscriberServer(srv.Gsrv, &s) srv.Start() opts := withGRPCHeadersAssertion(t, option.WithEndpoint(srv.Addr), option.WithoutAuthentication(), option.WithGRPCDialOption(grpc.WithInsecure())) client, err := NewClient(ctx, "P", opts...) if err != nil { t.Fatal(err) } defer client.Close() errc := make(chan error) go func() { errc <- client.Subscription("foo").Receive(ctx, func(context.Context, *Message) { t.Error("should not have received any data") }) }() select { case <-time.After(5 * time.Second): t.Fatal("Receive should have failed immediately") case err := <-errc: if gerr, ok := status.FromError(err); ok { if gerr.Code() != codes.ResourceExhausted { t.Fatal("expected to receive a grpc ResourceExhausted error") } } else { t.Fatal("expected to receive a grpc ResourceExhausted error") } } } type ExhaustedServer struct { *pstest.GServer } func (*ExhaustedServer) StreamingPull(_ pb.Subscriber_StreamingPullServer) error { return status.Errorf(codes.ResourceExhausted, "This server is exhausted!") } type testStreamingPullClient struct { pb.Subscriber_StreamingPullClient sendError error } func (c *testStreamingPullClient) Send(*pb.StreamingPullRequest) error { return c.sendError } google-cloud-go-0.49.0/pubsub/service.go000066400000000000000000000056241356504100700200660ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package pubsub import ( "fmt" "math" "strings" "time" gax "github.com/googleapis/gax-go/v2" pb "google.golang.org/genproto/googleapis/pubsub/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) // maxPayload is the maximum number of bytes to devote to the // encoded AcknowledgementRequest / ModifyAckDeadline proto message. // // With gRPC there is no way for the client to know the server's max message size (it is // configurable on the server). We know from experience that it // it 512K. const ( maxPayload = 512 * 1024 maxSendRecvBytes = 20 * 1024 * 1024 // 20M ) func convertMessages(rms []*pb.ReceivedMessage) ([]*Message, error) { msgs := make([]*Message, 0, len(rms)) for i, m := range rms { msg, err := toMessage(m) if err != nil { return nil, fmt.Errorf("pubsub: cannot decode the retrieved message at index: %d, message: %+v", i, m) } msgs = append(msgs, msg) } return msgs, nil } func trunc32(i int64) int32 { if i > math.MaxInt32 { i = math.MaxInt32 } return int32(i) } type defaultRetryer struct { bo gax.Backoff } // Logic originally from // https://github.com/GoogleCloudPlatform/google-cloud-java/blob/master/google-cloud-clients/google-cloud-pubsub/src/main/java/com/google/cloud/pubsub/v1/StatusUtil.java func (r *defaultRetryer) Retry(err error) (pause time.Duration, shouldRetry bool) { s, ok := status.FromError(err) if !ok { // includes io.EOF, normal stream close, which causes us to reopen return r.bo.Pause(), true } switch s.Code() { case codes.DeadlineExceeded, codes.Internal, codes.ResourceExhausted, codes.Aborted: return r.bo.Pause(), true case codes.Unavailable: c := strings.Contains(s.Message(), "Server shutdownNow invoked") if !c { return r.bo.Pause(), true } return 0, false default: return 0, false } } type streamingPullRetryer struct { defaultRetryer gax.Retryer } // Does not retry ResourceExhausted. See: https://github.com/GoogleCloudPlatform/google-cloud-go/issues/1166#issuecomment-443744705 func (r *streamingPullRetryer) Retry(err error) (pause time.Duration, shouldRetry bool) { s, ok := status.FromError(err) if !ok { // call defaultRetryer so that its backoff can be used return r.defaultRetryer.Retry(err) } switch s.Code() { case codes.ResourceExhausted: return 0, false default: return r.defaultRetryer.Retry(err) } } google-cloud-go-0.49.0/pubsub/snapshot.go000066400000000000000000000122331356504100700202570ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package pubsub import ( "context" "fmt" "strings" "time" "github.com/golang/protobuf/ptypes" pb "google.golang.org/genproto/googleapis/pubsub/v1" ) // Snapshot is a reference to a PubSub snapshot. type Snapshot struct { c *Client // The fully qualified identifier for the snapshot, in the format "projects//snapshots/" name string } // ID returns the unique identifier of the snapshot within its project. func (s *Snapshot) ID() string { slash := strings.LastIndex(s.name, "/") if slash == -1 { // name is not a fully-qualified name. panic("bad snapshot name") } return s.name[slash+1:] } // SnapshotConfig contains the details of a Snapshot. type SnapshotConfig struct { *Snapshot Topic *Topic Expiration time.Time } // Snapshot creates a reference to a snapshot. func (c *Client) Snapshot(id string) *Snapshot { return &Snapshot{ c: c, name: fmt.Sprintf("projects/%s/snapshots/%s", c.projectID, id), } } // Snapshots returns an iterator which returns snapshots for this project. func (c *Client) Snapshots(ctx context.Context) *SnapshotConfigIterator { it := c.subc.ListSnapshots(ctx, &pb.ListSnapshotsRequest{ Project: c.fullyQualifiedProjectName(), }) next := func() (*SnapshotConfig, error) { snap, err := it.Next() if err != nil { return nil, err } return toSnapshotConfig(snap, c) } return &SnapshotConfigIterator{next: next} } // SnapshotConfigIterator is an iterator that returns a series of snapshots. type SnapshotConfigIterator struct { next func() (*SnapshotConfig, error) } // Next returns the next SnapshotConfig. Its second return value is iterator.Done if there are no more results. // Once Next returns iterator.Done, all subsequent calls will return iterator.Done. func (snaps *SnapshotConfigIterator) Next() (*SnapshotConfig, error) { return snaps.next() } // Delete deletes a snapshot. func (s *Snapshot) Delete(ctx context.Context) error { return s.c.subc.DeleteSnapshot(ctx, &pb.DeleteSnapshotRequest{Snapshot: s.name}) } // SeekToTime seeks the subscription to a point in time. // // Messages retained in the subscription that were published before this // time are marked as acknowledged, and messages retained in the // subscription that were published after this time are marked as // unacknowledged. Note that this operation affects only those messages // retained in the subscription (configured by SnapshotConfig). For example, // if `time` corresponds to a point before the message retention // window (or to a point before the system's notion of the subscription // creation time), only retained messages will be marked as unacknowledged, // and already-expunged messages will not be restored. func (s *Subscription) SeekToTime(ctx context.Context, t time.Time) error { ts, err := ptypes.TimestampProto(t) if err != nil { return err } _, err = s.c.subc.Seek(ctx, &pb.SeekRequest{ Subscription: s.name, Target: &pb.SeekRequest_Time{Time: ts}, }) return err } // CreateSnapshot creates a new snapshot from this subscription. // The snapshot will be for the topic this subscription is subscribed to. // If the name is empty string, a unique name is assigned. // // The created snapshot is guaranteed to retain: // (a) The existing backlog on the subscription. More precisely, this is // defined as the messages in the subscription's backlog that are // unacknowledged when Snapshot returns without error. // (b) Any messages published to the subscription's topic following // Snapshot returning without error. func (s *Subscription) CreateSnapshot(ctx context.Context, name string) (*SnapshotConfig, error) { if name != "" { name = fmt.Sprintf("projects/%s/snapshots/%s", strings.Split(s.name, "/")[1], name) } snap, err := s.c.subc.CreateSnapshot(ctx, &pb.CreateSnapshotRequest{ Name: name, Subscription: s.name, }) if err != nil { return nil, err } return toSnapshotConfig(snap, s.c) } // SeekToSnapshot seeks the subscription to a snapshot. // // The snapshot need not be created from this subscription, // but it must be for the topic this subscription is subscribed to. func (s *Subscription) SeekToSnapshot(ctx context.Context, snap *Snapshot) error { _, err := s.c.subc.Seek(ctx, &pb.SeekRequest{ Subscription: s.name, Target: &pb.SeekRequest_Snapshot{Snapshot: snap.name}, }) return err } func toSnapshotConfig(snap *pb.Snapshot, c *Client) (*SnapshotConfig, error) { exp, err := ptypes.Timestamp(snap.ExpireTime) if err != nil { return nil, err } return &SnapshotConfig{ Snapshot: &Snapshot{c: c, name: snap.Name}, Topic: newTopic(c, snap.Topic), Expiration: exp, }, nil } google-cloud-go-0.49.0/pubsub/streaming_pull_test.go000066400000000000000000000313441356504100700225100ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package pubsub // TODO(jba): test keepalive // TODO(jba): test that expired messages are not kept alive // TODO(jba): test that when all messages expire, Stop returns. import ( "context" "io" "strconv" "sync" "sync/atomic" "testing" "time" "cloud.google.com/go/internal/testutil" tspb "github.com/golang/protobuf/ptypes/timestamp" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "google.golang.org/api/option" pb "google.golang.org/genproto/googleapis/pubsub/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) var ( timestamp = &tspb.Timestamp{} testMessages = []*pb.ReceivedMessage{ {AckId: "0", Message: &pb.PubsubMessage{Data: []byte{1}, PublishTime: timestamp}}, {AckId: "1", Message: &pb.PubsubMessage{Data: []byte{2}, PublishTime: timestamp}}, {AckId: "2", Message: &pb.PubsubMessage{Data: []byte{3}, PublishTime: timestamp}}, } ) func TestStreamingPullBasic(t *testing.T) { client, server := newMock(t) defer server.srv.Close() defer client.Close() server.addStreamingPullMessages(testMessages) testStreamingPullIteration(t, client, server, testMessages) } func TestStreamingPullMultipleFetches(t *testing.T) { client, server := newMock(t) defer server.srv.Close() defer client.Close() server.addStreamingPullMessages(testMessages[:1]) server.addStreamingPullMessages(testMessages[1:]) testStreamingPullIteration(t, client, server, testMessages) } func testStreamingPullIteration(t *testing.T, client *Client, server *mockServer, msgs []*pb.ReceivedMessage) { sub := client.Subscription("S") gotMsgs, err := pullN(context.Background(), sub, len(msgs), func(_ context.Context, m *Message) { id, err := strconv.Atoi(m.ackID) if err != nil { panic(err) } // ack evens, nack odds if id%2 == 0 { m.Ack() } else { m.Nack() } }) if c := status.Convert(err); err != nil && c.Code() != codes.Canceled { t.Fatalf("Pull: %v", err) } gotMap := map[string]*Message{} for _, m := range gotMsgs { gotMap[m.ackID] = m } for i, msg := range msgs { want, err := toMessage(msg) if err != nil { t.Fatal(err) } want.calledDone = true got := gotMap[want.ackID] if got == nil { t.Errorf("%d: no message for ackID %q", i, want.ackID) continue } if !testutil.Equal(got, want, cmp.AllowUnexported(Message{}), cmpopts.IgnoreTypes(time.Time{}, func(string, bool, time.Time) {})) { t.Errorf("%d: got\n%#v\nwant\n%#v", i, got, want) } } server.wait() for i := 0; i < len(msgs); i++ { id := msgs[i].AckId if i%2 == 0 { if !server.Acked[id] { t.Errorf("msg %q should have been acked but wasn't", id) } } else { if dl, ok := server.Deadlines[id]; !ok || dl != 0 { t.Errorf("msg %q should have been nacked but wasn't", id) } } } } func TestStreamingPullError(t *testing.T) { // If an RPC to the service returns a non-retryable error, Pull should // return after all callbacks return, without waiting for messages to be // acked. client, server := newMock(t) defer server.srv.Close() defer client.Close() server.addStreamingPullMessages(testMessages[:1]) server.addStreamingPullError(status.Errorf(codes.Unknown, "")) sub := client.Subscription("S") // Use only one goroutine, since the fake server is configured to // return only one error. sub.ReceiveSettings.NumGoroutines = 1 callbackDone := make(chan struct{}) ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() err := sub.Receive(ctx, func(ctx context.Context, m *Message) { defer close(callbackDone) <-ctx.Done() }) select { case <-callbackDone: default: t.Fatal("Receive returned but callback was not done") } if want := codes.Unknown; status.Code(err) != want { t.Fatalf("got <%v>, want code %v", err, want) } } func TestStreamingPullCancel(t *testing.T) { // If Receive's context is canceled, it should return after all callbacks // return and all messages have been acked. client, server := newMock(t) defer server.srv.Close() defer client.Close() server.addStreamingPullMessages(testMessages) sub := client.Subscription("S") ctx, cancel := context.WithTimeout(context.Background(), time.Second) var n int32 err := sub.Receive(ctx, func(ctx2 context.Context, m *Message) { atomic.AddInt32(&n, 1) defer atomic.AddInt32(&n, -1) cancel() m.Ack() }) if got := atomic.LoadInt32(&n); got != 0 { t.Errorf("Receive returned with %d callbacks still running", got) } if err != nil { t.Fatalf("Receive got <%v>, want nil", err) } } func TestStreamingPullRetry(t *testing.T) { // Check that we retry on io.EOF or Unavailable. t.Parallel() client, server := newMock(t) defer server.srv.Close() defer client.Close() server.addStreamingPullMessages(testMessages[:1]) server.addStreamingPullError(io.EOF) server.addStreamingPullError(io.EOF) server.addStreamingPullMessages(testMessages[1:2]) server.addStreamingPullError(status.Errorf(codes.Unavailable, "")) server.addStreamingPullError(status.Errorf(codes.Unavailable, "")) server.addStreamingPullMessages(testMessages[2:]) testStreamingPullIteration(t, client, server, testMessages) } func TestStreamingPullOneActive(t *testing.T) { // Only one call to Pull can be active at a time. client, srv := newMock(t) defer client.Close() defer srv.srv.Close() srv.addStreamingPullMessages(testMessages[:1]) sub := client.Subscription("S") ctx, cancel := context.WithCancel(context.Background()) err := sub.Receive(ctx, func(ctx context.Context, m *Message) { m.Ack() err := sub.Receive(ctx, func(context.Context, *Message) {}) if err != errReceiveInProgress { t.Errorf("got <%v>, want <%v>", err, errReceiveInProgress) } cancel() }) if err != nil { t.Fatalf("got <%v>, want nil", err) } } func TestStreamingPullConcurrent(t *testing.T) { newMsg := func(i int) *pb.ReceivedMessage { return &pb.ReceivedMessage{ AckId: strconv.Itoa(i), Message: &pb.PubsubMessage{Data: []byte{byte(i)}, PublishTime: timestamp}, } } // Multiple goroutines should be able to read from the same iterator. client, server := newMock(t) defer server.srv.Close() defer client.Close() // Add a lot of messages, a few at a time, to make sure both threads get a chance. nMessages := 100 for i := 0; i < nMessages; i += 2 { server.addStreamingPullMessages([]*pb.ReceivedMessage{newMsg(i), newMsg(i + 1)}) } sub := client.Subscription("S") ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() gotMsgs, err := pullN(ctx, sub, nMessages, func(ctx context.Context, m *Message) { m.Ack() }) if c := status.Convert(err); err != nil && c.Code() != codes.Canceled { t.Fatalf("Pull: %v", err) } seen := map[string]bool{} for _, gm := range gotMsgs { if seen[gm.ackID] { t.Fatalf("duplicate ID %q", gm.ackID) } seen[gm.ackID] = true } if len(seen) != nMessages { t.Fatalf("got %d messages, want %d", len(seen), nMessages) } } func TestStreamingPullFlowControl(t *testing.T) { // Callback invocations should not occur if flow control limits are exceeded. client, server := newMock(t) defer server.srv.Close() defer client.Close() server.addStreamingPullMessages(testMessages) sub := client.Subscription("S") sub.ReceiveSettings.MaxOutstandingMessages = 2 ctx, cancel := context.WithCancel(context.Background()) activec := make(chan int) waitc := make(chan int) errc := make(chan error) go func() { errc <- sub.Receive(ctx, func(_ context.Context, m *Message) { activec <- 1 <-waitc m.Ack() }) }() // Here, two callbacks are active. Receive should be blocked in the flow // control acquire method on the third message. <-activec <-activec select { case <-activec: t.Fatal("third callback in progress") case <-time.After(100 * time.Millisecond): } cancel() // Receive still has not returned, because both callbacks are still blocked on waitc. select { case err := <-errc: t.Fatalf("Receive returned early with error %v", err) case <-time.After(100 * time.Millisecond): } // Let both callbacks proceed. waitc <- 1 waitc <- 1 // The third callback will never run, because acquire returned a non-nil // error, causing Receive to return. So now Receive should end. if err := <-errc; err != nil { t.Fatalf("got %v from Receive, want nil", err) } } func TestStreamingPull_ClosedClient(t *testing.T) { ctx := context.Background() client, server := newMock(t) defer server.srv.Close() defer client.Close() server.addStreamingPullMessages(testMessages) sub := client.Subscription("S") sub.ReceiveSettings.MaxOutstandingBytes = 1 recvFinished := make(chan error) go func() { err := sub.Receive(ctx, func(_ context.Context, m *Message) { m.Ack() }) recvFinished <- err }() // wait for receives to happen time.Sleep(100 * time.Millisecond) err := client.Close() if err != nil { t.Fatal(err) } // wait for things to close time.Sleep(100 * time.Millisecond) select { case recvErr := <-recvFinished: s, ok := status.FromError(recvErr) if !ok { t.Fatalf("Expected a gRPC failure, got %v", err) } if s.Code() != codes.Canceled { t.Fatalf("Expected canceled, got %v", s.Code()) } case <-time.After(time.Second): t.Fatal("Receive should have exited immediately after the client was closed, but it did not") } } func TestStreamingPull_RetriesAfterUnavailable(t *testing.T) { ctx := context.Background() client, server := newMock(t) defer server.srv.Close() defer client.Close() unavail := status.Error(codes.Unavailable, "There is no connection available") server.addStreamingPullMessages(testMessages) server.addStreamingPullError(unavail) server.addAckResponse(unavail) server.addModAckResponse(unavail) server.addStreamingPullMessages(testMessages) server.addStreamingPullError(unavail) sub := client.Subscription("S") sub.ReceiveSettings.MaxOutstandingBytes = 1 recvErr := make(chan error, 1) recvdMsgs := make(chan *Message, len(testMessages)*2) go func() { recvErr <- sub.Receive(ctx, func(_ context.Context, m *Message) { m.Ack() recvdMsgs <- m }) }() // wait for receive to happen var n int for { select { case <-time.After(10 * time.Second): t.Fatalf("timed out waiting for all message to arrive. got %d messages total", n) case err := <-recvErr: t.Fatal(err) case <-recvdMsgs: n++ if n == len(testMessages)*2 { return } } } } func TestStreamingPull_ReconnectsAfterServerDies(t *testing.T) { ctx := context.Background() client, server := newMock(t) defer server.srv.Close() defer client.Close() server.addStreamingPullMessages(testMessages) sub := client.Subscription("S") sub.ReceiveSettings.MaxOutstandingBytes = 1 recvErr := make(chan error, 1) recvdMsgs := make(chan interface{}, len(testMessages)*2) go func() { recvErr <- sub.Receive(ctx, func(_ context.Context, m *Message) { m.Ack() recvdMsgs <- struct{}{} }) }() // wait for receive to happen var n int for { select { case <-time.After(5 * time.Second): t.Fatalf("timed out waiting for all message to arrive. got %d messages total", n) case err := <-recvErr: t.Fatal(err) case <-recvdMsgs: n++ if n == len(testMessages) { // Restart the server server.srv.Close() server2, err := newMockServer(server.srv.Port) if err != nil { t.Fatal(err) } defer server2.srv.Close() server2.addStreamingPullMessages(testMessages) } if n == len(testMessages)*2 { return } } } } func newMock(t *testing.T) (*Client, *mockServer) { srv, err := newMockServer(0) if err != nil { t.Fatal(err) } conn, err := grpc.Dial(srv.Addr, grpc.WithInsecure()) if err != nil { t.Fatal(err) } opts := withGRPCHeadersAssertion(t, option.WithGRPCConn(conn)) client, err := NewClient(context.Background(), "P", opts...) if err != nil { t.Fatal(err) } return client, srv } // pullN calls sub.Receive until at least n messages are received. func pullN(ctx context.Context, sub *Subscription, n int, f func(context.Context, *Message)) ([]*Message, error) { var ( mu sync.Mutex msgs []*Message ) cctx, cancel := context.WithCancel(ctx) err := sub.Receive(cctx, func(ctx context.Context, m *Message) { mu.Lock() msgs = append(msgs, m) nSeen := len(msgs) mu.Unlock() f(ctx, m) if nSeen >= n { cancel() } }) if err != nil { return msgs, err } return msgs, nil } google-cloud-go-0.49.0/pubsub/subscription.go000066400000000000000000000642171356504100700211550ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package pubsub import ( "context" "errors" "fmt" "io" "strings" "sync" "time" "cloud.google.com/go/iam" "cloud.google.com/go/internal/optional" "github.com/golang/protobuf/ptypes" durpb "github.com/golang/protobuf/ptypes/duration" gax "github.com/googleapis/gax-go/v2" "golang.org/x/sync/errgroup" pb "google.golang.org/genproto/googleapis/pubsub/v1" fmpb "google.golang.org/genproto/protobuf/field_mask" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) // Subscription is a reference to a PubSub subscription. type Subscription struct { c *Client // The fully qualified identifier for the subscription, in the format "projects//subscriptions/" name string // Settings for pulling messages. Configure these before calling Receive. ReceiveSettings ReceiveSettings mu sync.Mutex receiveActive bool } // Subscription creates a reference to a subscription. func (c *Client) Subscription(id string) *Subscription { return c.SubscriptionInProject(id, c.projectID) } // SubscriptionInProject creates a reference to a subscription in a given project. func (c *Client) SubscriptionInProject(id, projectID string) *Subscription { return &Subscription{ c: c, name: fmt.Sprintf("projects/%s/subscriptions/%s", projectID, id), } } // String returns the globally unique printable name of the subscription. func (s *Subscription) String() string { return s.name } // ID returns the unique identifier of the subscription within its project. func (s *Subscription) ID() string { slash := strings.LastIndex(s.name, "/") if slash == -1 { // name is not a fully-qualified name. panic("bad subscription name") } return s.name[slash+1:] } // Subscriptions returns an iterator which returns all of the subscriptions for the client's project. func (c *Client) Subscriptions(ctx context.Context) *SubscriptionIterator { it := c.subc.ListSubscriptions(ctx, &pb.ListSubscriptionsRequest{ Project: c.fullyQualifiedProjectName(), }) return &SubscriptionIterator{ c: c, next: func() (string, error) { sub, err := it.Next() if err != nil { return "", err } return sub.Name, nil }, } } // SubscriptionIterator is an iterator that returns a series of subscriptions. type SubscriptionIterator struct { c *Client next func() (string, error) } // Next returns the next subscription. If there are no more subscriptions, iterator.Done will be returned. func (subs *SubscriptionIterator) Next() (*Subscription, error) { subName, err := subs.next() if err != nil { return nil, err } return &Subscription{c: subs.c, name: subName}, nil } // PushConfig contains configuration for subscriptions that operate in push mode. type PushConfig struct { // A URL locating the endpoint to which messages should be pushed. Endpoint string // Endpoint configuration attributes. See https://cloud.google.com/pubsub/docs/reference/rest/v1/projects.subscriptions#pushconfig for more details. Attributes map[string]string // AuthenticationMethod is used by push endpoints to verify the source // of push requests. // It can be used with push endpoints that are private by default to // allow requests only from the Cloud Pub/Sub system, for example. // This field is optional and should be set only by users interested in // authenticated push. // // It is EXPERIMENTAL and a part of a closed alpha that may not be // accessible to all users. This field is subject to change or removal // without notice. AuthenticationMethod AuthenticationMethod } func (pc *PushConfig) toProto() *pb.PushConfig { if pc == nil { return nil } pbCfg := &pb.PushConfig{ Attributes: pc.Attributes, PushEndpoint: pc.Endpoint, } if authMethod := pc.AuthenticationMethod; authMethod != nil { switch am := authMethod.(type) { case *OIDCToken: pbCfg.AuthenticationMethod = am.toProto() default: // TODO: add others here when GAIC adds more definitions. } } return pbCfg } // AuthenticationMethod is used by push points to verify the source of push requests. // This interface defines fields that are part of a closed alpha that may not be accessible // to all users. type AuthenticationMethod interface { isAuthMethod() bool } // OIDCToken allows PushConfigs to be authenticated using // the OpenID Connect protocol https://openid.net/connect/ type OIDCToken struct { // Audience to be used when generating OIDC token. The audience claim // identifies the recipients that the JWT is intended for. The audience // value is a single case-sensitive string. Having multiple values (array) // for the audience field is not supported. More info about the OIDC JWT // token audience here: https://tools.ietf.org/html/rfc7519#section-4.1.3 // Note: if not specified, the Push endpoint URL will be used. Audience string // The service account email to be used for generating the OpenID Connect token. // The caller of: // * CreateSubscription // * UpdateSubscription // * ModifyPushConfig // calls must have the iam.serviceAccounts.actAs permission for the service account. // See https://cloud.google.com/iam/docs/understanding-roles#service-accounts-roles. ServiceAccountEmail string } var _ AuthenticationMethod = (*OIDCToken)(nil) func (oidcToken *OIDCToken) isAuthMethod() bool { return true } func (oidcToken *OIDCToken) toProto() *pb.PushConfig_OidcToken_ { if oidcToken == nil { return nil } return &pb.PushConfig_OidcToken_{ OidcToken: &pb.PushConfig_OidcToken{ Audience: oidcToken.Audience, ServiceAccountEmail: oidcToken.ServiceAccountEmail, }, } } // SubscriptionConfig describes the configuration of a subscription. type SubscriptionConfig struct { Topic *Topic PushConfig PushConfig // The default maximum time after a subscriber receives a message before // the subscriber should acknowledge the message. Note: messages which are // obtained via Subscription.Receive need not be acknowledged within this // deadline, as the deadline will be automatically extended. AckDeadline time.Duration // Whether to retain acknowledged messages. If true, acknowledged messages // will not be expunged until they fall out of the RetentionDuration window. RetainAckedMessages bool // How long to retain messages in backlog, from the time of publish. If // RetainAckedMessages is true, this duration affects the retention of // acknowledged messages, otherwise only unacknowledged messages are retained. // Defaults to 7 days. Cannot be longer than 7 days or shorter than 10 minutes. RetentionDuration time.Duration // Expiration policy specifies the conditions for a subscription's expiration. // A subscription is considered active as long as any connected subscriber is // successfully consuming messages from the subscription or is issuing // operations on the subscription. If `expiration_policy` is not set, a // *default policy* with `ttl` of 31 days will be used. The minimum allowed // value for `expiration_policy.ttl` is 1 day. // // Use time.Duration(0) to indicate that the subscription should never expire. // // It is EXPERIMENTAL and subject to change or removal without notice. ExpirationPolicy optional.Duration // The set of labels for the subscription. Labels map[string]string } func (cfg *SubscriptionConfig) toProto(name string) *pb.Subscription { var pbPushConfig *pb.PushConfig if cfg.PushConfig.Endpoint != "" || len(cfg.PushConfig.Attributes) != 0 || cfg.PushConfig.AuthenticationMethod != nil { pbPushConfig = cfg.PushConfig.toProto() } var retentionDuration *durpb.Duration if cfg.RetentionDuration != 0 { retentionDuration = ptypes.DurationProto(cfg.RetentionDuration) } return &pb.Subscription{ Name: name, Topic: cfg.Topic.name, PushConfig: pbPushConfig, AckDeadlineSeconds: trunc32(int64(cfg.AckDeadline.Seconds())), RetainAckedMessages: cfg.RetainAckedMessages, MessageRetentionDuration: retentionDuration, Labels: cfg.Labels, ExpirationPolicy: expirationPolicyToProto(cfg.ExpirationPolicy), } } func protoToSubscriptionConfig(pbSub *pb.Subscription, c *Client) (SubscriptionConfig, error) { rd := time.Hour * 24 * 7 var err error if pbSub.MessageRetentionDuration != nil { rd, err = ptypes.Duration(pbSub.MessageRetentionDuration) if err != nil { return SubscriptionConfig{}, err } } var expirationPolicy time.Duration if ttl := pbSub.ExpirationPolicy.GetTtl(); ttl != nil { expirationPolicy, err = ptypes.Duration(ttl) if err != nil { return SubscriptionConfig{}, err } } subC := SubscriptionConfig{ Topic: newTopic(c, pbSub.Topic), AckDeadline: time.Second * time.Duration(pbSub.AckDeadlineSeconds), RetainAckedMessages: pbSub.RetainAckedMessages, RetentionDuration: rd, Labels: pbSub.Labels, ExpirationPolicy: expirationPolicy, } pc := protoToPushConfig(pbSub.PushConfig) if pc != nil { subC.PushConfig = *pc } return subC, nil } func protoToPushConfig(pbPc *pb.PushConfig) *PushConfig { if pbPc == nil { return nil } pc := &PushConfig{ Endpoint: pbPc.PushEndpoint, Attributes: pbPc.Attributes, } if am := pbPc.AuthenticationMethod; am != nil { if oidcToken, ok := am.(*pb.PushConfig_OidcToken_); ok && oidcToken != nil && oidcToken.OidcToken != nil { pc.AuthenticationMethod = &OIDCToken{ Audience: oidcToken.OidcToken.GetAudience(), ServiceAccountEmail: oidcToken.OidcToken.GetServiceAccountEmail(), } } } return pc } // ReceiveSettings configure the Receive method. // A zero ReceiveSettings will result in values equivalent to DefaultReceiveSettings. type ReceiveSettings struct { // MaxExtension is the maximum period for which the Subscription should // automatically extend the ack deadline for each message. // // The Subscription will automatically extend the ack deadline of all // fetched Messages up to the duration specified. Automatic deadline // extension beyond the initial receipt may be disabled by specifying a // duration less than 0. MaxExtension time.Duration // MaxOutstandingMessages is the maximum number of unprocessed messages // (unacknowledged but not yet expired). If MaxOutstandingMessages is 0, it // will be treated as if it were DefaultReceiveSettings.MaxOutstandingMessages. // If the value is negative, then there will be no limit on the number of // unprocessed messages. MaxOutstandingMessages int // MaxOutstandingBytes is the maximum size of unprocessed messages // (unacknowledged but not yet expired). If MaxOutstandingBytes is 0, it will // be treated as if it were DefaultReceiveSettings.MaxOutstandingBytes. If // the value is negative, then there will be no limit on the number of bytes // for unprocessed messages. MaxOutstandingBytes int // NumGoroutines is the number of goroutines Receive will spawn to pull // messages concurrently. If NumGoroutines is less than 1, it will be treated // as if it were DefaultReceiveSettings.NumGoroutines. // // NumGoroutines does not limit the number of messages that can be processed // concurrently. Even with one goroutine, many messages might be processed at // once, because that goroutine may continually receive messages and invoke the // function passed to Receive on them. To limit the number of messages being // processed concurrently, set MaxOutstandingMessages. NumGoroutines int // If Synchronous is true, then no more than MaxOutstandingMessages will be in // memory at one time. (In contrast, when Synchronous is false, more than // MaxOutstandingMessages may have been received from the service and in memory // before being processed.) MaxOutstandingBytes still refers to the total bytes // processed, rather than in memory. NumGoroutines is ignored. // The default is false. Synchronous bool } // For synchronous receive, the time to wait if we are already processing // MaxOutstandingMessages. There is no point calling Pull and asking for zero // messages, so we pause to allow some message-processing callbacks to finish. // // The wait time is large enough to avoid consuming significant CPU, but // small enough to provide decent throughput. Users who want better // throughput should not be using synchronous mode. // // Waiting might seem like polling, so it's natural to think we could do better by // noticing when a callback is finished and immediately calling Pull. But if // callbacks finish in quick succession, this will result in frequent Pull RPCs that // request a single message, which wastes network bandwidth. Better to wait for a few // callbacks to finish, so we make fewer RPCs fetching more messages. // // This value is unexported so the user doesn't have another knob to think about. Note that // it is the same value as the one used for nackTicker, so it matches this client's // idea of a duration that is short, but not so short that we perform excessive RPCs. const synchronousWaitTime = 100 * time.Millisecond // This is a var so that tests can change it. var minAckDeadline = 10 * time.Second // DefaultReceiveSettings holds the default values for ReceiveSettings. var DefaultReceiveSettings = ReceiveSettings{ MaxExtension: 10 * time.Minute, MaxOutstandingMessages: 1000, MaxOutstandingBytes: 1e9, // 1G NumGoroutines: 1, } // Delete deletes the subscription. func (s *Subscription) Delete(ctx context.Context) error { return s.c.subc.DeleteSubscription(ctx, &pb.DeleteSubscriptionRequest{Subscription: s.name}) } // Exists reports whether the subscription exists on the server. func (s *Subscription) Exists(ctx context.Context) (bool, error) { _, err := s.c.subc.GetSubscription(ctx, &pb.GetSubscriptionRequest{Subscription: s.name}) if err == nil { return true, nil } if status.Code(err) == codes.NotFound { return false, nil } return false, err } // Config fetches the current configuration for the subscription. func (s *Subscription) Config(ctx context.Context) (SubscriptionConfig, error) { pbSub, err := s.c.subc.GetSubscription(ctx, &pb.GetSubscriptionRequest{Subscription: s.name}) if err != nil { return SubscriptionConfig{}, err } cfg, err := protoToSubscriptionConfig(pbSub, s.c) if err != nil { return SubscriptionConfig{}, err } return cfg, nil } // SubscriptionConfigToUpdate describes how to update a subscription. type SubscriptionConfigToUpdate struct { // If non-nil, the push config is changed. PushConfig *PushConfig // If non-zero, the ack deadline is changed. AckDeadline time.Duration // If set, RetainAckedMessages is changed. RetainAckedMessages optional.Bool // If non-zero, RetentionDuration is changed. RetentionDuration time.Duration // If non-zero, Expiration is changed. ExpirationPolicy optional.Duration // If non-nil, the current set of labels is completely // replaced by the new set. // This field has beta status. It is not subject to the stability guarantee // and may change. Labels map[string]string } // Update changes an existing subscription according to the fields set in cfg. // It returns the new SubscriptionConfig. // // Update returns an error if no fields were modified. func (s *Subscription) Update(ctx context.Context, cfg SubscriptionConfigToUpdate) (SubscriptionConfig, error) { req := s.updateRequest(&cfg) if err := cfg.validate(); err != nil { return SubscriptionConfig{}, fmt.Errorf("pubsub: UpdateSubscription %v", err) } if len(req.UpdateMask.Paths) == 0 { return SubscriptionConfig{}, errors.New("pubsub: UpdateSubscription call with nothing to update") } rpsub, err := s.c.subc.UpdateSubscription(ctx, req) if err != nil { return SubscriptionConfig{}, err } return protoToSubscriptionConfig(rpsub, s.c) } func (s *Subscription) updateRequest(cfg *SubscriptionConfigToUpdate) *pb.UpdateSubscriptionRequest { psub := &pb.Subscription{Name: s.name} var paths []string if cfg.PushConfig != nil { psub.PushConfig = cfg.PushConfig.toProto() paths = append(paths, "push_config") } if cfg.AckDeadline != 0 { psub.AckDeadlineSeconds = trunc32(int64(cfg.AckDeadline.Seconds())) paths = append(paths, "ack_deadline_seconds") } if cfg.RetainAckedMessages != nil { psub.RetainAckedMessages = optional.ToBool(cfg.RetainAckedMessages) paths = append(paths, "retain_acked_messages") } if cfg.RetentionDuration != 0 { psub.MessageRetentionDuration = ptypes.DurationProto(cfg.RetentionDuration) paths = append(paths, "message_retention_duration") } if cfg.ExpirationPolicy != nil { psub.ExpirationPolicy = expirationPolicyToProto(cfg.ExpirationPolicy) paths = append(paths, "expiration_policy") } if cfg.Labels != nil { psub.Labels = cfg.Labels paths = append(paths, "labels") } return &pb.UpdateSubscriptionRequest{ Subscription: psub, UpdateMask: &fmpb.FieldMask{Paths: paths}, } } const ( // The minimum expiration policy duration is 1 day as per: // https://github.com/googleapis/googleapis/blob/51145ff7812d2bb44c1219d0b76dac92a8bd94b2/google/pubsub/v1/pubsub.proto#L606-L607 minExpirationPolicy = 24 * time.Hour // If an expiration policy is not specified, the default of 31 days is used as per: // https://github.com/googleapis/googleapis/blob/51145ff7812d2bb44c1219d0b76dac92a8bd94b2/google/pubsub/v1/pubsub.proto#L605-L606 defaultExpirationPolicy = 31 * 24 * time.Hour ) func (cfg *SubscriptionConfigToUpdate) validate() error { if cfg == nil || cfg.ExpirationPolicy == nil { return nil } policy, min := optional.ToDuration(cfg.ExpirationPolicy), minExpirationPolicy if policy == 0 || policy >= min { return nil } return fmt.Errorf("invalid expiration policy(%q) < minimum(%q)", policy, min) } func expirationPolicyToProto(expirationPolicy optional.Duration) *pb.ExpirationPolicy { if expirationPolicy == nil { return nil } dur := optional.ToDuration(expirationPolicy) var ttl *durpb.Duration // As per: // https://godoc.org/google.golang.org/genproto/googleapis/pubsub/v1#ExpirationPolicy.Ttl // if ExpirationPolicy.Ttl is set to nil, the expirationPolicy is toggled to NEVER expire. if dur != 0 { ttl = ptypes.DurationProto(dur) } return &pb.ExpirationPolicy{ Ttl: ttl, } } // IAM returns the subscription's IAM handle. func (s *Subscription) IAM() *iam.Handle { return iam.InternalNewHandle(s.c.subc.Connection(), s.name) } // CreateSubscription creates a new subscription on a topic. // // id is the name of the subscription to create. It must start with a letter, // and contain only letters ([A-Za-z]), numbers ([0-9]), dashes (-), // underscores (_), periods (.), tildes (~), plus (+) or percent signs (%). It // must be between 3 and 255 characters in length, and must not start with // "goog". // // cfg.Topic is the topic from which the subscription should receive messages. It // need not belong to the same project as the subscription. This field is required. // // cfg.AckDeadline is the maximum time after a subscriber receives a message before // the subscriber should acknowledge the message. It must be between 10 and 600 // seconds (inclusive), and is rounded down to the nearest second. If the // provided ackDeadline is 0, then the default value of 10 seconds is used. // Note: messages which are obtained via Subscription.Receive need not be // acknowledged within this deadline, as the deadline will be automatically // extended. // // cfg.PushConfig may be set to configure this subscription for push delivery. // // If the subscription already exists an error will be returned. func (c *Client) CreateSubscription(ctx context.Context, id string, cfg SubscriptionConfig) (*Subscription, error) { if cfg.Topic == nil { return nil, errors.New("pubsub: require non-nil Topic") } if cfg.AckDeadline == 0 { cfg.AckDeadline = 10 * time.Second } if d := cfg.AckDeadline; d < 10*time.Second || d > 600*time.Second { return nil, fmt.Errorf("ack deadline must be between 10 and 600 seconds; got: %v", d) } sub := c.Subscription(id) _, err := c.subc.CreateSubscription(ctx, cfg.toProto(sub.name)) if err != nil { return nil, err } return sub, nil } var errReceiveInProgress = errors.New("pubsub: Receive already in progress for this subscription") // Receive calls f with the outstanding messages from the subscription. // It blocks until ctx is done, or the service returns a non-retryable error. // // The standard way to terminate a Receive is to cancel its context: // // cctx, cancel := context.WithCancel(ctx) // err := sub.Receive(cctx, callback) // // Call cancel from callback, or another goroutine. // // If the service returns a non-retryable error, Receive returns that error after // all of the outstanding calls to f have returned. If ctx is done, Receive // returns nil after all of the outstanding calls to f have returned and // all messages have been acknowledged or have expired. // // Receive calls f concurrently from multiple goroutines. It is encouraged to // process messages synchronously in f, even if that processing is relatively // time-consuming; Receive will spawn new goroutines for incoming messages, // limited by MaxOutstandingMessages and MaxOutstandingBytes in ReceiveSettings. // // The context passed to f will be canceled when ctx is Done or there is a // fatal service error. // // Receive will send an ack deadline extension on message receipt, then // automatically extend the ack deadline of all fetched Messages up to the // period specified by s.ReceiveSettings.MaxExtension. // // Each Subscription may have only one invocation of Receive active at a time. func (s *Subscription) Receive(ctx context.Context, f func(context.Context, *Message)) error { s.mu.Lock() if s.receiveActive { s.mu.Unlock() return errReceiveInProgress } s.receiveActive = true s.mu.Unlock() defer func() { s.mu.Lock(); s.receiveActive = false; s.mu.Unlock() }() maxCount := s.ReceiveSettings.MaxOutstandingMessages if maxCount == 0 { maxCount = DefaultReceiveSettings.MaxOutstandingMessages } maxBytes := s.ReceiveSettings.MaxOutstandingBytes if maxBytes == 0 { maxBytes = DefaultReceiveSettings.MaxOutstandingBytes } maxExt := s.ReceiveSettings.MaxExtension if maxExt == 0 { maxExt = DefaultReceiveSettings.MaxExtension } else if maxExt < 0 { // If MaxExtension is negative, disable automatic extension. maxExt = 0 } var numGoroutines int switch { case s.ReceiveSettings.Synchronous: numGoroutines = 1 case s.ReceiveSettings.NumGoroutines >= 1: numGoroutines = s.ReceiveSettings.NumGoroutines default: numGoroutines = DefaultReceiveSettings.NumGoroutines } // TODO(jba): add tests that verify that ReceiveSettings are correctly processed. po := &pullOptions{ maxExtension: maxExt, maxPrefetch: trunc32(int64(maxCount)), synchronous: s.ReceiveSettings.Synchronous, } fc := newFlowController(maxCount, maxBytes) // Wait for all goroutines started by Receive to return, so instead of an // obscure goroutine leak we have an obvious blocked call to Receive. group, gctx := errgroup.WithContext(ctx) for i := 0; i < numGoroutines; i++ { group.Go(func() error { return s.receive(gctx, po, fc, f) }) } return group.Wait() } func (s *Subscription) receive(ctx context.Context, po *pullOptions, fc *flowController, f func(context.Context, *Message)) error { // Cancel a sub-context when we return, to kick the context-aware callbacks // and the goroutine below. ctx2, cancel := context.WithCancel(ctx) // The iterator does not use the context passed to Receive. If it did, canceling // that context would immediately stop the iterator without waiting for unacked // messages. iter := newMessageIterator(s.c.subc, s.name, po) // We cannot use errgroup from Receive here. Receive might already be calling group.Wait, // and group.Wait cannot be called concurrently with group.Go. We give each receive() its // own WaitGroup instead. // Since wg.Add is only called from the main goroutine, wg.Wait is guaranteed // to be called after all Adds. var wg sync.WaitGroup wg.Add(1) go func() { <-ctx2.Done() // Call stop when Receive's context is done. // Stop will block until all outstanding messages have been acknowledged // or there was a fatal service error. iter.stop() wg.Done() }() defer wg.Wait() defer cancel() for { var maxToPull int32 // maximum number of messages to pull if po.synchronous { if po.maxPrefetch < 0 { // If there is no limit on the number of messages to pull, use a reasonable default. maxToPull = 1000 } else { // Limit the number of messages in memory to MaxOutstandingMessages // (here, po.maxPrefetch). For each message currently in memory, we have // called fc.acquire but not fc.release: this is fc.count(). The next // call to Pull should fetch no more than the difference between these // values. maxToPull = po.maxPrefetch - int32(fc.count()) if maxToPull <= 0 { // Wait for some callbacks to finish. if err := gax.Sleep(ctx, synchronousWaitTime); err != nil { // Return nil if the context is done, not err. return nil } continue } } } msgs, err := iter.receive(maxToPull) if err == io.EOF { return nil } if err != nil { return err } for i, msg := range msgs { msg := msg // TODO(jba): call acquire closer to when the message is allocated. if err := fc.acquire(ctx, len(msg.Data)); err != nil { // TODO(jba): test that these "orphaned" messages are nacked immediately when ctx is done. for _, m := range msgs[i:] { m.Nack() } // Return nil if the context is done, not err. return nil } old := msg.doneFunc msgLen := len(msg.Data) msg.doneFunc = func(ackID string, ack bool, receiveTime time.Time) { defer fc.release(msgLen) old(ackID, ack, receiveTime) } wg.Add(1) go func() { defer wg.Done() f(ctx2, msg) }() } } } type pullOptions struct { maxExtension time.Duration maxPrefetch int32 // If true, use unary Pull instead of StreamingPull, and never pull more // than maxPrefetch messages. synchronous bool } google-cloud-go-0.49.0/pubsub/subscription_test.go000066400000000000000000000174501356504100700222110ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package pubsub import ( "context" "fmt" "testing" "time" "cloud.google.com/go/internal/testutil" "cloud.google.com/go/pubsub/pstest" "google.golang.org/api/iterator" "google.golang.org/api/option" pb "google.golang.org/genproto/googleapis/pubsub/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) // All returns the remaining subscriptions from this iterator. func slurpSubs(it *SubscriptionIterator) ([]*Subscription, error) { var subs []*Subscription for { switch sub, err := it.Next(); err { case nil: subs = append(subs, sub) case iterator.Done: return subs, nil default: return nil, err } } } func TestSubscriptionID(t *testing.T) { const id = "id" c := &Client{projectID: "projid"} s := c.Subscription(id) if got, want := s.ID(), id; got != want { t.Errorf("Subscription.ID() = %q; want %q", got, want) } } func TestListProjectSubscriptions(t *testing.T) { ctx := context.Background() c, srv := newFake(t) defer c.Close() defer srv.Close() topic := mustCreateTopic(t, c, "t") var want []string for i := 1; i <= 2; i++ { id := fmt.Sprintf("s%d", i) want = append(want, id) _, err := c.CreateSubscription(ctx, id, SubscriptionConfig{Topic: topic}) if err != nil { t.Fatal(err) } } subs, err := slurpSubs(c.Subscriptions(ctx)) if err != nil { t.Fatal(err) } got := getSubIDs(subs) if !testutil.Equal(got, want) { t.Errorf("got %v, want %v", got, want) } } func getSubIDs(subs []*Subscription) []string { var names []string for _, sub := range subs { names = append(names, sub.ID()) } return names } func TestListTopicSubscriptions(t *testing.T) { ctx := context.Background() c, srv := newFake(t) defer c.Close() defer srv.Close() topics := []*Topic{ mustCreateTopic(t, c, "t0"), mustCreateTopic(t, c, "t1"), } wants := make([][]string, 2) for i := 0; i < 5; i++ { id := fmt.Sprintf("s%d", i) sub, err := c.CreateSubscription(ctx, id, SubscriptionConfig{Topic: topics[i%2]}) if err != nil { t.Fatal(err) } wants[i%2] = append(wants[i%2], sub.ID()) } for i, topic := range topics { subs, err := slurpSubs(topic.Subscriptions(ctx)) if err != nil { t.Fatal(err) } got := getSubIDs(subs) if !testutil.Equal(got, wants[i]) { t.Errorf("#%d: got %v, want %v", i, got, wants[i]) } } } const defaultRetentionDuration = 168 * time.Hour func TestUpdateSubscription(t *testing.T) { ctx := context.Background() client, srv := newFake(t) defer client.Close() defer srv.Close() topic := mustCreateTopic(t, client, "t") sub, err := client.CreateSubscription(ctx, "s", SubscriptionConfig{ Topic: topic, ExpirationPolicy: 30 * time.Hour, PushConfig: PushConfig{ Endpoint: "https://example.com/push", AuthenticationMethod: &OIDCToken{ ServiceAccountEmail: "foo@example.com", Audience: "client-12345", }, }, }) if err != nil { t.Fatal(err) } cfg, err := sub.Config(ctx) if err != nil { t.Fatal(err) } want := SubscriptionConfig{ Topic: topic, AckDeadline: 10 * time.Second, RetainAckedMessages: false, RetentionDuration: defaultRetentionDuration, ExpirationPolicy: 30 * time.Hour, PushConfig: PushConfig{ Endpoint: "https://example.com/push", AuthenticationMethod: &OIDCToken{ ServiceAccountEmail: "foo@example.com", Audience: "client-12345", }, }, } if !testutil.Equal(cfg, want) { t.Fatalf("\ngot %+v\nwant %+v", cfg, want) } got, err := sub.Update(ctx, SubscriptionConfigToUpdate{ AckDeadline: 20 * time.Second, RetainAckedMessages: true, Labels: map[string]string{"label": "value"}, ExpirationPolicy: 72 * time.Hour, PushConfig: &PushConfig{ Endpoint: "https://example.com/push", AuthenticationMethod: &OIDCToken{ ServiceAccountEmail: "foo@example.com", Audience: "client-12345", }, }, }) if err != nil { t.Fatal(err) } want = SubscriptionConfig{ Topic: topic, AckDeadline: 20 * time.Second, RetainAckedMessages: true, RetentionDuration: defaultRetentionDuration, Labels: map[string]string{"label": "value"}, ExpirationPolicy: 72 * time.Hour, PushConfig: PushConfig{ Endpoint: "https://example.com/push", AuthenticationMethod: &OIDCToken{ ServiceAccountEmail: "foo@example.com", Audience: "client-12345", }, }, } if !testutil.Equal(got, want) { t.Fatalf("\ngot %+v\nwant %+v", got, want) } got, err = sub.Update(ctx, SubscriptionConfigToUpdate{ RetentionDuration: 2 * time.Hour, Labels: map[string]string{}, }) if err != nil { t.Fatal(err) } want.RetentionDuration = 2 * time.Hour want.Labels = nil if !testutil.Equal(got, want) { t.Fatalf("\ngot %+v\nwant %+v", got, want) } _, err = sub.Update(ctx, SubscriptionConfigToUpdate{}) if err == nil { t.Fatal("got nil, want error") } // Check ExpirationPolicy when set to never expire. got, err = sub.Update(ctx, SubscriptionConfigToUpdate{ ExpirationPolicy: time.Duration(0), }) if err != nil { t.Fatal(err) } want.ExpirationPolicy = time.Duration(0) if !testutil.Equal(got, want) { t.Fatalf("\ngot %+v\nwant %+v", got, want) } } func TestReceive(t *testing.T) { testReceive(t, true) testReceive(t, false) } func testReceive(t *testing.T, synchronous bool) { ctx := context.Background() client, srv := newFake(t) defer client.Close() defer srv.Close() topic := mustCreateTopic(t, client, "t") sub, err := client.CreateSubscription(ctx, "s", SubscriptionConfig{Topic: topic}) if err != nil { t.Fatal(err) } for i := 0; i < 256; i++ { srv.Publish(topic.name, []byte{byte(i)}, nil) } sub.ReceiveSettings.Synchronous = synchronous msgs, err := pullN(ctx, sub, 256, func(_ context.Context, m *Message) { m.Ack() }) if c := status.Convert(err); err != nil && c.Code() != codes.Canceled { t.Fatalf("Pull: %v", err) } var seen [256]bool for _, m := range msgs { seen[m.Data[0]] = true } for i, saw := range seen { if !saw { t.Errorf("sync=%t: did not see message #%d", synchronous, i) } } } func (t1 *Topic) Equal(t2 *Topic) bool { if t1 == nil && t2 == nil { return true } if t1 == nil || t2 == nil { return false } return t1.c == t2.c && t1.name == t2.name } // Note: be sure to close client and server! func newFake(t *testing.T) (*Client, *pstest.Server) { ctx := context.Background() srv := pstest.NewServer() client, err := NewClient(ctx, "P", option.WithEndpoint(srv.Addr), option.WithoutAuthentication(), option.WithGRPCDialOption(grpc.WithInsecure())) if err != nil { t.Fatal(err) } return client, srv } func TestPushConfigAuthenticationMethod_toProto(t *testing.T) { in := &PushConfig{ Endpoint: "https://example.com/push", AuthenticationMethod: &OIDCToken{ ServiceAccountEmail: "foo@example.com", Audience: "client-12345", }, } got := in.toProto() want := &pb.PushConfig{ PushEndpoint: "https://example.com/push", AuthenticationMethod: &pb.PushConfig_OidcToken_{ OidcToken: &pb.PushConfig_OidcToken{ ServiceAccountEmail: "foo@example.com", Audience: "client-12345", }, }, } if diff := testutil.Diff(got, want); diff != "" { t.Errorf("Roundtrip to Proto failed\ngot: - want: +\n%s", diff) } } google-cloud-go-0.49.0/pubsub/timeout_test.go000066400000000000000000000044241356504100700211500ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package pubsub import ( "context" "log" "sync/atomic" "testing" "time" "cloud.google.com/go/pubsub/pstest" "google.golang.org/api/option" "google.golang.org/grpc" ) // Using the fake PubSub server in the pstest package, verify that streaming // pull resumes if the server stream times out. func TestStreamTimeout(t *testing.T) { t.Parallel() log.SetFlags(log.Lmicroseconds) ctx := context.Background() srv := pstest.NewServer() defer srv.Close() srv.SetStreamTimeout(2 * time.Second) conn, err := grpc.Dial(srv.Addr, grpc.WithInsecure()) if err != nil { t.Fatal(err) } defer conn.Close() opts := withGRPCHeadersAssertion(t, option.WithGRPCConn(conn)) client, err := NewClient(ctx, "P", opts...) if err != nil { t.Fatal(err) } defer client.Close() topic, err := client.CreateTopic(ctx, "T") if err != nil { t.Fatal(err) } sub, err := client.CreateSubscription(ctx, "sub", SubscriptionConfig{Topic: topic, AckDeadline: 10 * time.Second}) if err != nil { t.Fatal(err) } const nPublish = 8 rctx, cancel := context.WithTimeout(ctx, 30*time.Second) defer cancel() errc := make(chan error) var nSeen int64 go func() { errc <- sub.Receive(rctx, func(ctx context.Context, m *Message) { m.Ack() n := atomic.AddInt64(&nSeen, 1) if n >= nPublish { cancel() } }) }() for i := 0; i < nPublish; i++ { pr := topic.Publish(ctx, &Message{Data: []byte("msg")}) _, err := pr.Get(ctx) if err != nil { t.Fatal(err) } time.Sleep(250 * time.Millisecond) } if err := <-errc; err != nil { t.Fatal(err) } if err := sub.Delete(ctx); err != nil { t.Fatal(err) } n := atomic.LoadInt64(&nSeen) if n < nPublish { t.Errorf("got %d messages, want %d", n, nPublish) } } google-cloud-go-0.49.0/pubsub/topic.go000066400000000000000000000434711356504100700175460ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package pubsub import ( "context" "errors" "fmt" "log" "runtime" "strings" "sync" "time" "cloud.google.com/go/iam" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "go.opencensus.io/stats" "go.opencensus.io/tag" "google.golang.org/api/support/bundler" pb "google.golang.org/genproto/googleapis/pubsub/v1" fmpb "google.golang.org/genproto/protobuf/field_mask" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) const ( // MaxPublishRequestCount is the maximum number of messages that can be in // a single publish request, as defined by the PubSub service. MaxPublishRequestCount = 1000 // MaxPublishRequestBytes is the maximum size of a single publish request // in bytes, as defined by the PubSub service. MaxPublishRequestBytes = 1e7 ) // ErrOversizedMessage indicates that a message's size exceeds MaxPublishRequestBytes. var ErrOversizedMessage = bundler.ErrOversizedItem // Topic is a reference to a PubSub topic. // // The methods of Topic are safe for use by multiple goroutines. type Topic struct { c *Client // The fully qualified identifier for the topic, in the format "projects//topics/" name string // Settings for publishing messages. All changes must be made before the // first call to Publish. The default is DefaultPublishSettings. PublishSettings PublishSettings mu sync.RWMutex stopped bool bundler *bundler.Bundler } // PublishSettings control the bundling of published messages. type PublishSettings struct { // Publish a non-empty batch after this delay has passed. DelayThreshold time.Duration // Publish a batch when it has this many messages. The maximum is // MaxPublishRequestCount. CountThreshold int // Publish a batch when its size in bytes reaches this value. ByteThreshold int // The number of goroutines that invoke the Publish RPC concurrently. // // Defaults to a multiple of GOMAXPROCS. NumGoroutines int // The maximum time that the client will attempt to publish a bundle of messages. Timeout time.Duration // The maximum number of bytes that the Bundler will keep in memory before // returning ErrOverflow. // // Defaults to DefaultPublishSettings.BufferedByteLimit. BufferedByteLimit int } // DefaultPublishSettings holds the default values for topics' PublishSettings. var DefaultPublishSettings = PublishSettings{ DelayThreshold: 1 * time.Millisecond, CountThreshold: 100, ByteThreshold: 1e6, Timeout: 60 * time.Second, // By default, limit the bundler to 10 times the max message size. The number 10 is // chosen as a reasonable amount of messages in the worst case whilst still // capping the number to a low enough value to not OOM users. BufferedByteLimit: 10 * MaxPublishRequestBytes, } // CreateTopic creates a new topic. // // The specified topic ID must start with a letter, and contain only letters // ([A-Za-z]), numbers ([0-9]), dashes (-), underscores (_), periods (.), // tildes (~), plus (+) or percent signs (%). It must be between 3 and 255 // characters in length, and must not start with "goog". For more information, // see: https://cloud.google.com/pubsub/docs/admin#resource_names // // If the topic already exists an error will be returned. func (c *Client) CreateTopic(ctx context.Context, topicID string) (*Topic, error) { t := c.Topic(topicID) _, err := c.pubc.CreateTopic(ctx, &pb.Topic{Name: t.name}) if err != nil { return nil, err } return t, nil } // CreateTopicWithConfig creates a topic from TopicConfig. // // The specified topic ID must start with a letter, and contain only letters // ([A-Za-z]), numbers ([0-9]), dashes (-), underscores (_), periods (.), // tildes (~), plus (+) or percent signs (%). It must be between 3 and 255 // characters in length, and must not start with "goog". For more information, // see: https://cloud.google.com/pubsub/docs/admin#resource_names. // // If the topic already exists, an error will be returned. func (c *Client) CreateTopicWithConfig(ctx context.Context, topicID string, tc *TopicConfig) (*Topic, error) { t := c.Topic(topicID) _, err := c.pubc.CreateTopic(ctx, &pb.Topic{ Name: t.name, Labels: tc.Labels, MessageStoragePolicy: messageStoragePolicyToProto(&tc.MessageStoragePolicy), KmsKeyName: tc.KMSKeyName, }) if err != nil { return nil, err } return t, nil } // Topic creates a reference to a topic in the client's project. // // If a Topic's Publish method is called, it has background goroutines // associated with it. Clean them up by calling Topic.Stop. // // Avoid creating many Topic instances if you use them to publish. func (c *Client) Topic(id string) *Topic { return c.TopicInProject(id, c.projectID) } // TopicInProject creates a reference to a topic in the given project. // // If a Topic's Publish method is called, it has background goroutines // associated with it. Clean them up by calling Topic.Stop. // // Avoid creating many Topic instances if you use them to publish. func (c *Client) TopicInProject(id, projectID string) *Topic { return newTopic(c, fmt.Sprintf("projects/%s/topics/%s", projectID, id)) } func newTopic(c *Client, name string) *Topic { return &Topic{ c: c, name: name, PublishSettings: DefaultPublishSettings, } } // TopicConfig describes the configuration of a topic. type TopicConfig struct { // The set of labels for the topic. Labels map[string]string // The topic's message storage policy. MessageStoragePolicy MessageStoragePolicy // The name of the Cloud KMS key to be used to protect access to messages // published to this topic, in the format // "projects/P/locations/L/keyRings/R/cryptoKeys/K". KMSKeyName string } // TopicConfigToUpdate describes how to update a topic. type TopicConfigToUpdate struct { // If non-nil, the current set of labels is completely // replaced by the new set. Labels map[string]string // If non-nil, the existing policy (containing the list of regions) // is completely replaced by the new policy. // // Use the zero value &MessageStoragePolicy{} to reset the topic back to // using the organization's Resource Location Restriction policy. // // If nil, the policy remains unchanged. // // This field has beta status. It is not subject to the stability guarantee // and may change. MessageStoragePolicy *MessageStoragePolicy } func protoToTopicConfig(pbt *pb.Topic) TopicConfig { return TopicConfig{ Labels: pbt.Labels, MessageStoragePolicy: protoToMessageStoragePolicy(pbt.MessageStoragePolicy), KMSKeyName: pbt.KmsKeyName, } } // MessageStoragePolicy constrains how messages published to the topic may be stored. It // is determined when the topic is created based on the policy configured at // the project level. type MessageStoragePolicy struct { // AllowedPersistenceRegions is the list of GCP regions where messages that are published // to the topic may be persisted in storage. Messages published by publishers running in // non-allowed GCP regions (or running outside of GCP altogether) will be // routed for storage in one of the allowed regions. // // If empty, it indicates a misconfiguration at the project or organization level, which // will result in all Publish operations failing. This field cannot be empty in updates. // // If nil, then the policy is not defined on a topic level. When used in updates, it resets // the regions back to the organization level Resource Location Restriction policy. // // For more information, see // https://cloud.google.com/pubsub/docs/resource-location-restriction#pubsub-storage-locations. AllowedPersistenceRegions []string } func protoToMessageStoragePolicy(msp *pb.MessageStoragePolicy) MessageStoragePolicy { if msp == nil { return MessageStoragePolicy{} } return MessageStoragePolicy{AllowedPersistenceRegions: msp.AllowedPersistenceRegions} } func messageStoragePolicyToProto(msp *MessageStoragePolicy) *pb.MessageStoragePolicy { if msp == nil || msp.AllowedPersistenceRegions == nil { return nil } return &pb.MessageStoragePolicy{AllowedPersistenceRegions: msp.AllowedPersistenceRegions} } // Config returns the TopicConfig for the topic. func (t *Topic) Config(ctx context.Context) (TopicConfig, error) { pbt, err := t.c.pubc.GetTopic(ctx, &pb.GetTopicRequest{Topic: t.name}) if err != nil { return TopicConfig{}, err } return protoToTopicConfig(pbt), nil } // Update changes an existing topic according to the fields set in cfg. It returns // the new TopicConfig. func (t *Topic) Update(ctx context.Context, cfg TopicConfigToUpdate) (TopicConfig, error) { req := t.updateRequest(cfg) if len(req.UpdateMask.Paths) == 0 { return TopicConfig{}, errors.New("pubsub: UpdateTopic call with nothing to update") } rpt, err := t.c.pubc.UpdateTopic(ctx, req) if err != nil { return TopicConfig{}, err } return protoToTopicConfig(rpt), nil } func (t *Topic) updateRequest(cfg TopicConfigToUpdate) *pb.UpdateTopicRequest { pt := &pb.Topic{Name: t.name} var paths []string if cfg.Labels != nil { pt.Labels = cfg.Labels paths = append(paths, "labels") } if cfg.MessageStoragePolicy != nil { pt.MessageStoragePolicy = messageStoragePolicyToProto(cfg.MessageStoragePolicy) paths = append(paths, "message_storage_policy") } return &pb.UpdateTopicRequest{ Topic: pt, UpdateMask: &fmpb.FieldMask{Paths: paths}, } } // Topics returns an iterator which returns all of the topics for the client's project. func (c *Client) Topics(ctx context.Context) *TopicIterator { it := c.pubc.ListTopics(ctx, &pb.ListTopicsRequest{Project: c.fullyQualifiedProjectName()}) return &TopicIterator{ c: c, next: func() (string, error) { topic, err := it.Next() if err != nil { return "", err } return topic.Name, nil }, } } // TopicIterator is an iterator that returns a series of topics. type TopicIterator struct { c *Client next func() (string, error) } // Next returns the next topic. If there are no more topics, iterator.Done will be returned. func (tps *TopicIterator) Next() (*Topic, error) { topicName, err := tps.next() if err != nil { return nil, err } return newTopic(tps.c, topicName), nil } // ID returns the unique identifier of the topic within its project. func (t *Topic) ID() string { slash := strings.LastIndex(t.name, "/") if slash == -1 { // name is not a fully-qualified name. panic("bad topic name") } return t.name[slash+1:] } // String returns the printable globally unique name for the topic. func (t *Topic) String() string { return t.name } // Delete deletes the topic. func (t *Topic) Delete(ctx context.Context) error { return t.c.pubc.DeleteTopic(ctx, &pb.DeleteTopicRequest{Topic: t.name}) } // Exists reports whether the topic exists on the server. func (t *Topic) Exists(ctx context.Context) (bool, error) { if t.name == "_deleted-topic_" { return false, nil } _, err := t.c.pubc.GetTopic(ctx, &pb.GetTopicRequest{Topic: t.name}) if err == nil { return true, nil } if status.Code(err) == codes.NotFound { return false, nil } return false, err } // IAM returns the topic's IAM handle. func (t *Topic) IAM() *iam.Handle { return iam.InternalNewHandle(t.c.pubc.Connection(), t.name) } // Subscriptions returns an iterator which returns the subscriptions for this topic. // // Some of the returned subscriptions may belong to a project other than t. func (t *Topic) Subscriptions(ctx context.Context) *SubscriptionIterator { it := t.c.pubc.ListTopicSubscriptions(ctx, &pb.ListTopicSubscriptionsRequest{ Topic: t.name, }) return &SubscriptionIterator{ c: t.c, next: it.Next, } } var errTopicStopped = errors.New("pubsub: Stop has been called for this topic") // Publish publishes msg to the topic asynchronously. Messages are batched and // sent according to the topic's PublishSettings. Publish never blocks. // // Publish returns a non-nil PublishResult which will be ready when the // message has been sent (or has failed to be sent) to the server. // // Publish creates goroutines for batching and sending messages. These goroutines // need to be stopped by calling t.Stop(). Once stopped, future calls to Publish // will immediately return a PublishResult with an error. func (t *Topic) Publish(ctx context.Context, msg *Message) *PublishResult { // Use a PublishRequest with only the Messages field to calculate the size // of an individual message. This accurately calculates the size of the // encoded proto message by accounting for the length of an individual // PubSubMessage and Data/Attributes field. // TODO(hongalex): if this turns out to take significant time, try to approximate it. msg.size = proto.Size(&pb.PublishRequest{ Messages: []*pb.PubsubMessage{ { Data: msg.Data, Attributes: msg.Attributes, }, }, }) r := &PublishResult{ready: make(chan struct{})} t.initBundler() t.mu.RLock() defer t.mu.RUnlock() // TODO(aboulhosn) [from bcmills] consider changing the semantics of bundler to perform this logic so we don't have to do it here if t.stopped { r.set("", errTopicStopped) return r } // TODO(jba) [from bcmills] consider using a shared channel per bundle // (requires Bundler API changes; would reduce allocations) err := t.bundler.Add(&bundledMessage{msg, r}, msg.size) if err != nil { r.set("", err) } return r } // Stop sends all remaining published messages and stop goroutines created for handling // publishing. Returns once all outstanding messages have been sent or have // failed to be sent. func (t *Topic) Stop() { t.mu.Lock() noop := t.stopped || t.bundler == nil t.stopped = true t.mu.Unlock() if noop { return } t.bundler.Flush() } // A PublishResult holds the result from a call to Publish. type PublishResult struct { ready chan struct{} serverID string err error } // Ready returns a channel that is closed when the result is ready. // When the Ready channel is closed, Get is guaranteed not to block. func (r *PublishResult) Ready() <-chan struct{} { return r.ready } // Get returns the server-generated message ID and/or error result of a Publish call. // Get blocks until the Publish call completes or the context is done. func (r *PublishResult) Get(ctx context.Context) (serverID string, err error) { // If the result is already ready, return it even if the context is done. select { case <-r.Ready(): return r.serverID, r.err default: } select { case <-ctx.Done(): return "", ctx.Err() case <-r.Ready(): return r.serverID, r.err } } func (r *PublishResult) set(sid string, err error) { r.serverID = sid r.err = err close(r.ready) } type bundledMessage struct { msg *Message res *PublishResult } func (t *Topic) initBundler() { t.mu.RLock() noop := t.stopped || t.bundler != nil t.mu.RUnlock() if noop { return } t.mu.Lock() defer t.mu.Unlock() // Must re-check, since we released the lock. if t.stopped || t.bundler != nil { return } timeout := t.PublishSettings.Timeout t.bundler = bundler.NewBundler(&bundledMessage{}, func(items interface{}) { // TODO(jba): use a context detached from the one passed to NewClient. ctx := context.TODO() if timeout != 0 { var cancel func() ctx, cancel = context.WithTimeout(ctx, timeout) defer cancel() } t.publishMessageBundle(ctx, items.([]*bundledMessage)) }) t.bundler.DelayThreshold = t.PublishSettings.DelayThreshold t.bundler.BundleCountThreshold = t.PublishSettings.CountThreshold if t.bundler.BundleCountThreshold > MaxPublishRequestCount { t.bundler.BundleCountThreshold = MaxPublishRequestCount } t.bundler.BundleByteThreshold = t.PublishSettings.ByteThreshold bufferedByteLimit := DefaultPublishSettings.BufferedByteLimit if t.PublishSettings.BufferedByteLimit > 0 { bufferedByteLimit = t.PublishSettings.BufferedByteLimit } t.bundler.BufferedByteLimit = bufferedByteLimit // Set the bundler's max size per payload, accounting for topic name's overhead. t.bundler.BundleByteLimit = MaxPublishRequestBytes - calcFieldSizeString(t.name) // Unless overridden, allow many goroutines per CPU to call the Publish RPC concurrently. // The default value was determined via extensive load testing (see the loadtest subdirectory). if t.PublishSettings.NumGoroutines > 0 { t.bundler.HandlerLimit = t.PublishSettings.NumGoroutines } else { t.bundler.HandlerLimit = 25 * runtime.GOMAXPROCS(0) } } func (t *Topic) publishMessageBundle(ctx context.Context, bms []*bundledMessage) { ctx, err := tag.New(ctx, tag.Insert(keyStatus, "OK"), tag.Upsert(keyTopic, t.name)) if err != nil { log.Printf("pubsub: cannot create context with tag in publishMessageBundle: %v", err) } pbMsgs := make([]*pb.PubsubMessage, len(bms)) for i, bm := range bms { pbMsgs[i] = &pb.PubsubMessage{ Data: bm.msg.Data, Attributes: bm.msg.Attributes, } bm.msg = nil // release bm.msg for GC } start := time.Now() res, err := t.c.pubc.Publish(ctx, &pb.PublishRequest{ Topic: t.name, Messages: pbMsgs, }, gax.WithGRPCOptions(grpc.MaxCallSendMsgSize(maxSendRecvBytes))) end := time.Now() if err != nil { // Update context with error tag for OpenCensus, // using same stats.Record() call as success case. ctx, _ = tag.New(ctx, tag.Upsert(keyStatus, "ERROR"), tag.Upsert(keyError, err.Error())) } stats.Record(ctx, PublishLatency.M(float64(end.Sub(start)/time.Millisecond)), PublishedMessages.M(int64(len(bms)))) for i, bm := range bms { if err != nil { bm.res.set("", err) } else { bm.res.set(res.MessageIds[i], nil) } } } google-cloud-go-0.49.0/pubsub/topic_test.go000066400000000000000000000157741356504100700206120ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package pubsub import ( "bytes" "context" "fmt" "testing" "time" "cloud.google.com/go/internal/testutil" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/support/bundler" pubsubpb "google.golang.org/genproto/googleapis/pubsub/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) func checkTopicListing(t *testing.T, c *Client, want []string) { topics, err := slurpTopics(c.Topics(context.Background())) if err != nil { t.Fatalf("error listing topics: %v", err) } var got []string for _, topic := range topics { got = append(got, topic.ID()) } if !testutil.Equal(got, want) { t.Errorf("topic list: got: %v, want: %v", got, want) } } // All returns the remaining topics from this iterator. func slurpTopics(it *TopicIterator) ([]*Topic, error) { var topics []*Topic for { switch topic, err := it.Next(); err { case nil: topics = append(topics, topic) case iterator.Done: return topics, nil default: return nil, err } } } func TestTopicID(t *testing.T) { const id = "id" c, srv := newFake(t) defer c.Close() defer srv.Close() s := c.Topic(id) if got, want := s.ID(), id; got != want { t.Errorf("Topic.ID() = %q; want %q", got, want) } } func TestCreateTopicWithConfig(t *testing.T) { c, srv := newFake(t) defer c.Close() defer srv.Close() id := "test-topic" want := TopicConfig{ Labels: map[string]string{"label": "value"}, MessageStoragePolicy: MessageStoragePolicy{ AllowedPersistenceRegions: []string{"us-east1"}, }, KMSKeyName: "projects/P/locations/L/keyRings/R/cryptoKeys/K", } topic := mustCreateTopicWithConfig(t, c, id, &want) got, err := topic.Config(context.Background()) if err != nil { t.Fatalf("error getting topic config: %v", err) } if !testutil.Equal(got, want) { t.Errorf("got %v, want %v", got, want) } } func TestListTopics(t *testing.T) { c, srv := newFake(t) defer c.Close() defer srv.Close() var ids []string for i := 1; i <= 4; i++ { id := fmt.Sprintf("t%d", i) ids = append(ids, id) mustCreateTopic(t, c, id) } checkTopicListing(t, c, ids) } func TestListCompletelyEmptyTopics(t *testing.T) { c, srv := newFake(t) defer c.Close() defer srv.Close() checkTopicListing(t, c, nil) } func TestStopPublishOrder(t *testing.T) { // Check that Stop doesn't panic if called before Publish. // Also that Publish after Stop returns the right error. ctx := context.Background() c := &Client{projectID: "projid"} topic := c.Topic("t") topic.Stop() r := topic.Publish(ctx, &Message{}) _, err := r.Get(ctx) if err != errTopicStopped { t.Errorf("got %v, want errTopicStopped", err) } } func TestPublishTimeout(t *testing.T) { ctx := context.Background() serv, err := testutil.NewServer() if err != nil { t.Fatal(err) } pubsubpb.RegisterPublisherServer(serv.Gsrv, &alwaysFailPublish{}) serv.Start() conn, err := grpc.Dial(serv.Addr, grpc.WithInsecure()) if err != nil { t.Fatal(err) } opts := withGRPCHeadersAssertion(t, option.WithGRPCConn(conn)) c, err := NewClient(ctx, "projectID", opts...) if err != nil { t.Fatal(err) } topic := c.Topic("t") topic.PublishSettings.Timeout = 3 * time.Second r := topic.Publish(ctx, &Message{}) defer topic.Stop() select { case <-r.Ready(): _, err = r.Get(ctx) if err != context.DeadlineExceeded { t.Fatalf("got %v, want context.DeadlineExceeded", err) } case <-time.After(2 * topic.PublishSettings.Timeout): t.Fatal("timed out") } } func TestPublishBufferedByteLimit(t *testing.T) { ctx := context.Background() client, srv := newFake(t) defer client.Close() defer srv.Close() topic := mustCreateTopic(t, client, "topic-small-buffered-byte-limit") defer topic.Stop() // Test setting BufferedByteLimit to small number of bytes that should fail. topic.PublishSettings.BufferedByteLimit = 100 const messageSizeBytes = 1000 msg := &Message{Data: bytes.Repeat([]byte{'A'}, int(messageSizeBytes))} res := topic.Publish(ctx, msg) _, err := res.Get(ctx) if err != bundler.ErrOverflow { t.Errorf("got %v, want ErrOverflow", err) } } func TestUpdateTopic_Label(t *testing.T) { ctx := context.Background() client, srv := newFake(t) defer client.Close() defer srv.Close() topic := mustCreateTopic(t, client, "T") config, err := topic.Config(ctx) if err != nil { t.Fatal(err) } want := TopicConfig{} if !testutil.Equal(config, want) { t.Errorf("got %+v, want %+v", config, want) } // replace labels labels := map[string]string{"label": "value"} config2, err := topic.Update(ctx, TopicConfigToUpdate{ Labels: labels, }) if err != nil { t.Fatal(err) } want = TopicConfig{ Labels: labels, } if !testutil.Equal(config2, want) { t.Errorf("got %+v, want %+v", config2, want) } // delete all labels labels = map[string]string{} config3, err := topic.Update(ctx, TopicConfigToUpdate{Labels: labels}) if err != nil { t.Fatal(err) } want.Labels = nil if !testutil.Equal(config3, want) { t.Errorf("got %+v, want %+v", config3, want) } } func TestUpdateTopic_MessageStoragePolicy(t *testing.T) { ctx := context.Background() client, srv := newFake(t) defer client.Close() defer srv.Close() topic := mustCreateTopic(t, client, "T") config, err := topic.Config(ctx) if err != nil { t.Fatal(err) } want := TopicConfig{} if !testutil.Equal(config, want) { t.Errorf("\ngot %+v\nwant %+v", config, want) } // Update message storage policy. msp := &MessageStoragePolicy{ AllowedPersistenceRegions: []string{"us-east1"}, } config2, err := topic.Update(ctx, TopicConfigToUpdate{MessageStoragePolicy: msp}) if err != nil { t.Fatal(err) } want.MessageStoragePolicy = MessageStoragePolicy{ AllowedPersistenceRegions: []string{"us-east1"}, } if !testutil.Equal(config2, want) { t.Errorf("\ngot %+v\nwant %+v", config2, want) } } type alwaysFailPublish struct { pubsubpb.PublisherServer } func (s *alwaysFailPublish) Publish(ctx context.Context, req *pubsubpb.PublishRequest) (*pubsubpb.PublishResponse, error) { return nil, status.Errorf(codes.Unavailable, "try again") } func mustCreateTopic(t *testing.T, c *Client, id string) *Topic { topic, err := c.CreateTopic(context.Background(), id) if err != nil { t.Fatal(err) } return topic } func mustCreateTopicWithConfig(t *testing.T, c *Client, id string, tc *TopicConfig) *Topic { if tc == nil { return mustCreateTopic(t, c, id) } topic, err := c.CreateTopicWithConfig(context.Background(), id, tc) if err != nil { t.Fatal(err) } return topic } google-cloud-go-0.49.0/pubsub/trace.go000066400000000000000000000213271356504100700175220ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package pubsub import ( "context" "log" "sync" "go.opencensus.io/plugin/ocgrpc" "go.opencensus.io/stats" "go.opencensus.io/stats/view" "go.opencensus.io/tag" "google.golang.org/api/option" "google.golang.org/grpc" ) func openCensusOptions() []option.ClientOption { return []option.ClientOption{ option.WithGRPCDialOption(grpc.WithStatsHandler(&ocgrpc.ClientHandler{})), } } // The following keys are used to tag requests with a specific topic/subscription ID. var ( keyTopic = tag.MustNewKey("topic") keySubscription = tag.MustNewKey("subscription") ) // In the following, errors are used if status is not "OK". var ( keyStatus = tag.MustNewKey("status") keyError = tag.MustNewKey("error") ) const statsPrefix = "cloud.google.com/go/pubsub/" // The following are measures recorded in publish/subscribe flows. var ( // PublishedMessages is a measure of the number of messages published, which may include errors. // It is EXPERIMENTAL and subject to change or removal without notice. PublishedMessages = stats.Int64(statsPrefix+"published_messages", "Number of PubSub message published", stats.UnitDimensionless) // PublishLatency is a measure of the number of milliseconds it took to publish a bundle, // which may consist of one or more messages. // It is EXPERIMENTAL and subject to change or removal without notice. PublishLatency = stats.Float64(statsPrefix+"publish_roundtrip_latency", "The latency in milliseconds per publish batch", stats.UnitMilliseconds) // PullCount is a measure of the number of messages pulled. // It is EXPERIMENTAL and subject to change or removal without notice. PullCount = stats.Int64(statsPrefix+"pull_count", "Number of PubSub messages pulled", stats.UnitDimensionless) // AckCount is a measure of the number of messages acked. // It is EXPERIMENTAL and subject to change or removal without notice. AckCount = stats.Int64(statsPrefix+"ack_count", "Number of PubSub messages acked", stats.UnitDimensionless) // NackCount is a measure of the number of messages nacked. // It is EXPERIMENTAL and subject to change or removal without notice. NackCount = stats.Int64(statsPrefix+"nack_count", "Number of PubSub messages nacked", stats.UnitDimensionless) // ModAckCount is a measure of the number of messages whose ack-deadline was modified. // It is EXPERIMENTAL and subject to change or removal without notice. ModAckCount = stats.Int64(statsPrefix+"mod_ack_count", "Number of ack-deadlines modified", stats.UnitDimensionless) // ModAckTimeoutCount is a measure of the number ModifyAckDeadline RPCs that timed out. // It is EXPERIMENTAL and subject to change or removal without notice. ModAckTimeoutCount = stats.Int64(statsPrefix+"mod_ack_timeout_count", "Number of ModifyAckDeadline RPCs that timed out", stats.UnitDimensionless) // StreamOpenCount is a measure of the number of times a streaming-pull stream was opened. // It is EXPERIMENTAL and subject to change or removal without notice. StreamOpenCount = stats.Int64(statsPrefix+"stream_open_count", "Number of calls opening a new streaming pull", stats.UnitDimensionless) // StreamRetryCount is a measure of the number of times a streaming-pull operation was retried. // It is EXPERIMENTAL and subject to change or removal without notice. StreamRetryCount = stats.Int64(statsPrefix+"stream_retry_count", "Number of retries of a stream send or receive", stats.UnitDimensionless) // StreamRequestCount is a measure of the number of requests sent on a streaming-pull stream. // It is EXPERIMENTAL and subject to change or removal without notice. StreamRequestCount = stats.Int64(statsPrefix+"stream_request_count", "Number gRPC StreamingPull request messages sent", stats.UnitDimensionless) // StreamResponseCount is a measure of the number of responses received on a streaming-pull stream. // It is EXPERIMENTAL and subject to change or removal without notice. StreamResponseCount = stats.Int64(statsPrefix+"stream_response_count", "Number of gRPC StreamingPull response messages received", stats.UnitDimensionless) ) var ( // PublishedMessagesView is a cumulative sum of PublishedMessages. // It is EXPERIMENTAL and subject to change or removal without notice. PublishedMessagesView *view.View // PublishLatencyView is a distribution of PublishLatency. // It is EXPERIMENTAL and subject to change or removal without notice. PublishLatencyView *view.View // PullCountView is a cumulative sum of PullCount. // It is EXPERIMENTAL and subject to change or removal without notice. PullCountView *view.View // AckCountView is a cumulative sum of AckCount. // It is EXPERIMENTAL and subject to change or removal without notice. AckCountView *view.View // NackCountView is a cumulative sum of NackCount. // It is EXPERIMENTAL and subject to change or removal without notice. NackCountView *view.View // ModAckCountView is a cumulative sum of ModAckCount. // It is EXPERIMENTAL and subject to change or removal without notice. ModAckCountView *view.View // ModAckTimeoutCountView is a cumulative sum of ModAckTimeoutCount. // It is EXPERIMENTAL and subject to change or removal without notice. ModAckTimeoutCountView *view.View // StreamOpenCountView is a cumulative sum of StreamOpenCount. // It is EXPERIMENTAL and subject to change or removal without notice. StreamOpenCountView *view.View // StreamRetryCountView is a cumulative sum of StreamRetryCount. // It is EXPERIMENTAL and subject to change or removal without notice. StreamRetryCountView *view.View // StreamRequestCountView is a cumulative sum of StreamRequestCount. // It is EXPERIMENTAL and subject to change or removal without notice. StreamRequestCountView *view.View // StreamResponseCountView is a cumulative sum of StreamResponseCount. // It is EXPERIMENTAL and subject to change or removal without notice. StreamResponseCountView *view.View ) func init() { PublishedMessagesView = createCountView(stats.Measure(PublishedMessages), keyTopic, keyStatus, keyError) PublishLatencyView = createDistView(PublishLatency, keyTopic, keyStatus, keyError) PullCountView = createCountView(PullCount, keySubscription) AckCountView = createCountView(AckCount, keySubscription) NackCountView = createCountView(NackCount, keySubscription) ModAckCountView = createCountView(ModAckCount, keySubscription) ModAckTimeoutCountView = createCountView(ModAckTimeoutCount, keySubscription) StreamOpenCountView = createCountView(StreamOpenCount, keySubscription) StreamRetryCountView = createCountView(StreamRetryCount, keySubscription) StreamRequestCountView = createCountView(StreamRequestCount, keySubscription) StreamResponseCountView = createCountView(StreamResponseCount, keySubscription) DefaultPublishViews = []*view.View{ PublishedMessagesView, PublishLatencyView, } DefaultSubscribeViews = []*view.View{ PullCountView, AckCountView, NackCountView, ModAckCountView, ModAckTimeoutCountView, StreamOpenCountView, StreamRetryCountView, StreamRequestCountView, StreamResponseCountView, } } // These arrays hold the default OpenCensus views that keep track of publish/subscribe operations. // It is EXPERIMENTAL and subject to change or removal without notice. var ( DefaultPublishViews []*view.View DefaultSubscribeViews []*view.View ) func createCountView(m stats.Measure, keys ...tag.Key) *view.View { return &view.View{ Name: m.Name(), Description: m.Description(), TagKeys: keys, Measure: m, Aggregation: view.Sum(), } } func createDistView(m stats.Measure, keys ...tag.Key) *view.View { return &view.View{ Name: m.Name(), Description: m.Description(), TagKeys: keys, Measure: m, Aggregation: view.Distribution(0, 25, 50, 75, 100, 200, 400, 600, 800, 1000, 2000, 4000, 6000), } } var logOnce sync.Once // withSubscriptionKey returns a new context modified with the subscriptionKey tag map. func withSubscriptionKey(ctx context.Context, subName string) context.Context { ctx, err := tag.New(ctx, tag.Upsert(keySubscription, subName)) if err != nil { logOnce.Do(func() { log.Printf("pubsub: error creating tag map for 'subscribe' key: %v", err) }) } return ctx } func recordStat(ctx context.Context, m *stats.Int64Measure, n int64) { stats.Record(ctx, m.M(n)) } google-cloud-go-0.49.0/recaptchaenterprise/000077500000000000000000000000001356504100700206235ustar00rootroot00000000000000google-cloud-go-0.49.0/recaptchaenterprise/apiv1beta1/000077500000000000000000000000001356504100700225605ustar00rootroot00000000000000google-cloud-go-0.49.0/recaptchaenterprise/apiv1beta1/.repo-metadata.json000066400000000000000000000007221356504100700262550ustar00rootroot00000000000000{ "name": "recaptchaenterprise", "name_pretty": "reCAPTCHA Enterprise API", "product_documentation": "https://cloud.google.com/recaptcha-enterprise", "client_documentation": "https://godoc.org/cloud.google.com/go/recaptchaenterprise/apiv1beta1", "release_level": "beta", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "recaptchaenterprise.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/recaptchaenterprise/apiv1beta1/doc.go000066400000000000000000000053071356504100700236610ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package recaptchaenterprise is an auto-generated package for the // reCAPTCHA Enterprise API. // // NOTE: This package is in beta. It is not stable, and may be subject to changes. // // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package recaptchaenterprise // import "cloud.google.com/go/recaptchaenterprise/apiv1beta1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191115" google-cloud-go-0.49.0/recaptchaenterprise/apiv1beta1/mock_test.go000066400000000000000000000171361356504100700251070ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package recaptchaenterprise import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" "google.golang.org/api/option" recaptchaenterprisepb "google.golang.org/genproto/googleapis/cloud/recaptchaenterprise/v1beta1" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockRecaptchaEnterpriseServiceV1Beta1Server struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. recaptchaenterprisepb.RecaptchaEnterpriseServiceV1Beta1Server reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockRecaptchaEnterpriseServiceV1Beta1Server) CreateAssessment(ctx context.Context, req *recaptchaenterprisepb.CreateAssessmentRequest) (*recaptchaenterprisepb.Assessment, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*recaptchaenterprisepb.Assessment), nil } func (s *mockRecaptchaEnterpriseServiceV1Beta1Server) AnnotateAssessment(ctx context.Context, req *recaptchaenterprisepb.AnnotateAssessmentRequest) (*recaptchaenterprisepb.AnnotateAssessmentResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*recaptchaenterprisepb.AnnotateAssessmentResponse), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockRecaptchaEnterpriseServiceV1Beta1 mockRecaptchaEnterpriseServiceV1Beta1Server ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() recaptchaenterprisepb.RegisterRecaptchaEnterpriseServiceV1Beta1Server(serv, &mockRecaptchaEnterpriseServiceV1Beta1) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestRecaptchaEnterpriseServiceV1Beta1CreateAssessment(t *testing.T) { var name string = "name3373707" var score float32 = 1.0926453e7 var expectedResponse = &recaptchaenterprisepb.Assessment{ Name: name, Score: score, } mockRecaptchaEnterpriseServiceV1Beta1.err = nil mockRecaptchaEnterpriseServiceV1Beta1.reqs = nil mockRecaptchaEnterpriseServiceV1Beta1.resps = append(mockRecaptchaEnterpriseServiceV1Beta1.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var assessment *recaptchaenterprisepb.Assessment = &recaptchaenterprisepb.Assessment{} var request = &recaptchaenterprisepb.CreateAssessmentRequest{ Parent: formattedParent, Assessment: assessment, } c, err := NewRecaptchaEnterpriseServiceV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateAssessment(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockRecaptchaEnterpriseServiceV1Beta1.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestRecaptchaEnterpriseServiceV1Beta1CreateAssessmentError(t *testing.T) { errCode := codes.PermissionDenied mockRecaptchaEnterpriseServiceV1Beta1.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var assessment *recaptchaenterprisepb.Assessment = &recaptchaenterprisepb.Assessment{} var request = &recaptchaenterprisepb.CreateAssessmentRequest{ Parent: formattedParent, Assessment: assessment, } c, err := NewRecaptchaEnterpriseServiceV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateAssessment(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestRecaptchaEnterpriseServiceV1Beta1AnnotateAssessment(t *testing.T) { var expectedResponse *recaptchaenterprisepb.AnnotateAssessmentResponse = &recaptchaenterprisepb.AnnotateAssessmentResponse{} mockRecaptchaEnterpriseServiceV1Beta1.err = nil mockRecaptchaEnterpriseServiceV1Beta1.reqs = nil mockRecaptchaEnterpriseServiceV1Beta1.resps = append(mockRecaptchaEnterpriseServiceV1Beta1.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/assessments/%s", "[PROJECT]", "[ASSESSMENT]") var annotation recaptchaenterprisepb.AnnotateAssessmentRequest_Annotation = recaptchaenterprisepb.AnnotateAssessmentRequest_ANNOTATION_UNSPECIFIED var request = &recaptchaenterprisepb.AnnotateAssessmentRequest{ Name: formattedName, Annotation: annotation, } c, err := NewRecaptchaEnterpriseServiceV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.AnnotateAssessment(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockRecaptchaEnterpriseServiceV1Beta1.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestRecaptchaEnterpriseServiceV1Beta1AnnotateAssessmentError(t *testing.T) { errCode := codes.PermissionDenied mockRecaptchaEnterpriseServiceV1Beta1.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/assessments/%s", "[PROJECT]", "[ASSESSMENT]") var annotation recaptchaenterprisepb.AnnotateAssessmentRequest_Annotation = recaptchaenterprisepb.AnnotateAssessmentRequest_ANNOTATION_UNSPECIFIED var request = &recaptchaenterprisepb.AnnotateAssessmentRequest{ Name: formattedName, Annotation: annotation, } c, err := NewRecaptchaEnterpriseServiceV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.AnnotateAssessment(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } recaptcha_enterprise_service_v1_beta1_client.go000066400000000000000000000140531356504100700337650ustar00rootroot00000000000000google-cloud-go-0.49.0/recaptchaenterprise/apiv1beta1// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package recaptchaenterprise import ( "context" "fmt" "math" "net/url" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" "google.golang.org/api/transport" recaptchaenterprisepb "google.golang.org/genproto/googleapis/cloud/recaptchaenterprise/v1beta1" "google.golang.org/grpc" "google.golang.org/grpc/metadata" ) // RecaptchaEnterpriseServiceV1Beta1CallOptions contains the retry settings for each method of RecaptchaEnterpriseServiceV1Beta1Client. type RecaptchaEnterpriseServiceV1Beta1CallOptions struct { CreateAssessment []gax.CallOption AnnotateAssessment []gax.CallOption } func defaultRecaptchaEnterpriseServiceV1Beta1ClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("recaptchaenterprise.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultRecaptchaEnterpriseServiceV1Beta1CallOptions() *RecaptchaEnterpriseServiceV1Beta1CallOptions { retry := map[[2]string][]gax.CallOption{} return &RecaptchaEnterpriseServiceV1Beta1CallOptions{ CreateAssessment: retry[[2]string{"default", "non_idempotent"}], AnnotateAssessment: retry[[2]string{"default", "non_idempotent"}], } } // RecaptchaEnterpriseServiceV1Beta1Client is a client for interacting with reCAPTCHA Enterprise API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type RecaptchaEnterpriseServiceV1Beta1Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. recaptchaEnterpriseServiceV1Beta1Client recaptchaenterprisepb.RecaptchaEnterpriseServiceV1Beta1Client // The call options for this service. CallOptions *RecaptchaEnterpriseServiceV1Beta1CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewRecaptchaEnterpriseServiceV1Beta1Client creates a new recaptcha enterprise service v1 beta1 client. // // Service to determine the likelihood an event is legitimate. func NewRecaptchaEnterpriseServiceV1Beta1Client(ctx context.Context, opts ...option.ClientOption) (*RecaptchaEnterpriseServiceV1Beta1Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultRecaptchaEnterpriseServiceV1Beta1ClientOptions(), opts...)...) if err != nil { return nil, err } c := &RecaptchaEnterpriseServiceV1Beta1Client{ conn: conn, CallOptions: defaultRecaptchaEnterpriseServiceV1Beta1CallOptions(), recaptchaEnterpriseServiceV1Beta1Client: recaptchaenterprisepb.NewRecaptchaEnterpriseServiceV1Beta1Client(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *RecaptchaEnterpriseServiceV1Beta1Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *RecaptchaEnterpriseServiceV1Beta1Client) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *RecaptchaEnterpriseServiceV1Beta1Client) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // CreateAssessment creates an Assessment of the likelihood an event is legitimate. func (c *RecaptchaEnterpriseServiceV1Beta1Client) CreateAssessment(ctx context.Context, req *recaptchaenterprisepb.CreateAssessmentRequest, opts ...gax.CallOption) (*recaptchaenterprisepb.Assessment, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateAssessment[0:len(c.CallOptions.CreateAssessment):len(c.CallOptions.CreateAssessment)], opts...) var resp *recaptchaenterprisepb.Assessment err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.recaptchaEnterpriseServiceV1Beta1Client.CreateAssessment(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // AnnotateAssessment annotates a previously created Assessment to provide additional information // on whether the event turned out to be authentic or fradulent. func (c *RecaptchaEnterpriseServiceV1Beta1Client) AnnotateAssessment(ctx context.Context, req *recaptchaenterprisepb.AnnotateAssessmentRequest, opts ...gax.CallOption) (*recaptchaenterprisepb.AnnotateAssessmentResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.AnnotateAssessment[0:len(c.CallOptions.AnnotateAssessment):len(c.CallOptions.AnnotateAssessment)], opts...) var resp *recaptchaenterprisepb.AnnotateAssessmentResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.recaptchaEnterpriseServiceV1Beta1Client.AnnotateAssessment(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } recaptcha_enterprise_service_v1_beta1_client_example_test.go000066400000000000000000000037331356504100700365420ustar00rootroot00000000000000google-cloud-go-0.49.0/recaptchaenterprise/apiv1beta1// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package recaptchaenterprise_test import ( "context" recaptchaenterprise "cloud.google.com/go/recaptchaenterprise/apiv1beta1" recaptchaenterprisepb "google.golang.org/genproto/googleapis/cloud/recaptchaenterprise/v1beta1" ) func ExampleNewRecaptchaEnterpriseServiceV1Beta1Client() { ctx := context.Background() c, err := recaptchaenterprise.NewRecaptchaEnterpriseServiceV1Beta1Client(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleRecaptchaEnterpriseServiceV1Beta1Client_CreateAssessment() { ctx := context.Background() c, err := recaptchaenterprise.NewRecaptchaEnterpriseServiceV1Beta1Client(ctx) if err != nil { // TODO: Handle error. } req := &recaptchaenterprisepb.CreateAssessmentRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateAssessment(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleRecaptchaEnterpriseServiceV1Beta1Client_AnnotateAssessment() { ctx := context.Background() c, err := recaptchaenterprise.NewRecaptchaEnterpriseServiceV1Beta1Client(ctx) if err != nil { // TODO: Handle error. } req := &recaptchaenterprisepb.AnnotateAssessmentRequest{ // TODO: Fill request struct fields. } resp, err := c.AnnotateAssessment(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/recommender/000077500000000000000000000000001356504100700170705ustar00rootroot00000000000000google-cloud-go-0.49.0/recommender/apiv1beta1/000077500000000000000000000000001356504100700210255ustar00rootroot00000000000000google-cloud-go-0.49.0/recommender/apiv1beta1/doc.go000066400000000000000000000052461356504100700221300ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package recommender is an auto-generated package for the // Recommender API. // // NOTE: This package is in beta. It is not stable, and may be subject to changes. // // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package recommender // import "cloud.google.com/go/recommender/apiv1beta1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191115" google-cloud-go-0.49.0/recommender/apiv1beta1/mock_test.go000066400000000000000000000360701356504100700233520ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package recommender import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" "google.golang.org/api/option" recommenderpb "google.golang.org/genproto/googleapis/cloud/recommender/v1beta1" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockRecommenderServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. recommenderpb.RecommenderServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockRecommenderServer) ListRecommendations(ctx context.Context, req *recommenderpb.ListRecommendationsRequest) (*recommenderpb.ListRecommendationsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*recommenderpb.ListRecommendationsResponse), nil } func (s *mockRecommenderServer) GetRecommendation(ctx context.Context, req *recommenderpb.GetRecommendationRequest) (*recommenderpb.Recommendation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*recommenderpb.Recommendation), nil } func (s *mockRecommenderServer) MarkRecommendationClaimed(ctx context.Context, req *recommenderpb.MarkRecommendationClaimedRequest) (*recommenderpb.Recommendation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*recommenderpb.Recommendation), nil } func (s *mockRecommenderServer) MarkRecommendationSucceeded(ctx context.Context, req *recommenderpb.MarkRecommendationSucceededRequest) (*recommenderpb.Recommendation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*recommenderpb.Recommendation), nil } func (s *mockRecommenderServer) MarkRecommendationFailed(ctx context.Context, req *recommenderpb.MarkRecommendationFailedRequest) (*recommenderpb.Recommendation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*recommenderpb.Recommendation), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockRecommender mockRecommenderServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() recommenderpb.RegisterRecommenderServer(serv, &mockRecommender) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestRecommenderListRecommendations(t *testing.T) { var nextPageToken string = "" var recommendationsElement *recommenderpb.Recommendation = &recommenderpb.Recommendation{} var recommendations = []*recommenderpb.Recommendation{recommendationsElement} var expectedResponse = &recommenderpb.ListRecommendationsResponse{ NextPageToken: nextPageToken, Recommendations: recommendations, } mockRecommender.err = nil mockRecommender.reqs = nil mockRecommender.resps = append(mockRecommender.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/recommenders/%s", "[PROJECT]", "[LOCATION]", "[RECOMMENDER]") var request = &recommenderpb.ListRecommendationsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListRecommendations(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockRecommender.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Recommendations[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestRecommenderListRecommendationsError(t *testing.T) { errCode := codes.PermissionDenied mockRecommender.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/recommenders/%s", "[PROJECT]", "[LOCATION]", "[RECOMMENDER]") var request = &recommenderpb.ListRecommendationsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListRecommendations(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestRecommenderGetRecommendation(t *testing.T) { var name2 string = "name2-1052831874" var description string = "description-1724546052" var recommenderSubtype string = "recommenderSubtype-1488504412" var etag string = "etag3123477" var expectedResponse = &recommenderpb.Recommendation{ Name: name2, Description: description, RecommenderSubtype: recommenderSubtype, Etag: etag, } mockRecommender.err = nil mockRecommender.reqs = nil mockRecommender.resps = append(mockRecommender.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/recommenders/%s/recommendations/%s", "[PROJECT]", "[LOCATION]", "[RECOMMENDER]", "[RECOMMENDATION]") var request = &recommenderpb.GetRecommendationRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetRecommendation(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockRecommender.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestRecommenderGetRecommendationError(t *testing.T) { errCode := codes.PermissionDenied mockRecommender.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/recommenders/%s/recommendations/%s", "[PROJECT]", "[LOCATION]", "[RECOMMENDER]", "[RECOMMENDATION]") var request = &recommenderpb.GetRecommendationRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetRecommendation(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestRecommenderMarkRecommendationClaimed(t *testing.T) { var name2 string = "name2-1052831874" var description string = "description-1724546052" var recommenderSubtype string = "recommenderSubtype-1488504412" var etag2 string = "etag2-1293302904" var expectedResponse = &recommenderpb.Recommendation{ Name: name2, Description: description, RecommenderSubtype: recommenderSubtype, Etag: etag2, } mockRecommender.err = nil mockRecommender.reqs = nil mockRecommender.resps = append(mockRecommender.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/recommenders/%s/recommendations/%s", "[PROJECT]", "[LOCATION]", "[RECOMMENDER]", "[RECOMMENDATION]") var etag string = "etag3123477" var request = &recommenderpb.MarkRecommendationClaimedRequest{ Name: formattedName, Etag: etag, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.MarkRecommendationClaimed(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockRecommender.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestRecommenderMarkRecommendationClaimedError(t *testing.T) { errCode := codes.PermissionDenied mockRecommender.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/recommenders/%s/recommendations/%s", "[PROJECT]", "[LOCATION]", "[RECOMMENDER]", "[RECOMMENDATION]") var etag string = "etag3123477" var request = &recommenderpb.MarkRecommendationClaimedRequest{ Name: formattedName, Etag: etag, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.MarkRecommendationClaimed(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestRecommenderMarkRecommendationSucceeded(t *testing.T) { var name2 string = "name2-1052831874" var description string = "description-1724546052" var recommenderSubtype string = "recommenderSubtype-1488504412" var etag2 string = "etag2-1293302904" var expectedResponse = &recommenderpb.Recommendation{ Name: name2, Description: description, RecommenderSubtype: recommenderSubtype, Etag: etag2, } mockRecommender.err = nil mockRecommender.reqs = nil mockRecommender.resps = append(mockRecommender.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/recommenders/%s/recommendations/%s", "[PROJECT]", "[LOCATION]", "[RECOMMENDER]", "[RECOMMENDATION]") var etag string = "etag3123477" var request = &recommenderpb.MarkRecommendationSucceededRequest{ Name: formattedName, Etag: etag, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.MarkRecommendationSucceeded(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockRecommender.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestRecommenderMarkRecommendationSucceededError(t *testing.T) { errCode := codes.PermissionDenied mockRecommender.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/recommenders/%s/recommendations/%s", "[PROJECT]", "[LOCATION]", "[RECOMMENDER]", "[RECOMMENDATION]") var etag string = "etag3123477" var request = &recommenderpb.MarkRecommendationSucceededRequest{ Name: formattedName, Etag: etag, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.MarkRecommendationSucceeded(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestRecommenderMarkRecommendationFailed(t *testing.T) { var name2 string = "name2-1052831874" var description string = "description-1724546052" var recommenderSubtype string = "recommenderSubtype-1488504412" var etag2 string = "etag2-1293302904" var expectedResponse = &recommenderpb.Recommendation{ Name: name2, Description: description, RecommenderSubtype: recommenderSubtype, Etag: etag2, } mockRecommender.err = nil mockRecommender.reqs = nil mockRecommender.resps = append(mockRecommender.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/recommenders/%s/recommendations/%s", "[PROJECT]", "[LOCATION]", "[RECOMMENDER]", "[RECOMMENDATION]") var etag string = "etag3123477" var request = &recommenderpb.MarkRecommendationFailedRequest{ Name: formattedName, Etag: etag, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.MarkRecommendationFailed(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockRecommender.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestRecommenderMarkRecommendationFailedError(t *testing.T) { errCode := codes.PermissionDenied mockRecommender.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/recommenders/%s/recommendations/%s", "[PROJECT]", "[LOCATION]", "[RECOMMENDER]", "[RECOMMENDATION]") var etag string = "etag3123477" var request = &recommenderpb.MarkRecommendationFailedRequest{ Name: formattedName, Etag: etag, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.MarkRecommendationFailed(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/recommender/apiv1beta1/recommender_client.go000066400000000000000000000301271356504100700252150ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package recommender import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" recommenderpb "google.golang.org/genproto/googleapis/cloud/recommender/v1beta1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // CallOptions contains the retry settings for each method of Client. type CallOptions struct { ListRecommendations []gax.CallOption GetRecommendation []gax.CallOption MarkRecommendationClaimed []gax.CallOption MarkRecommendationSucceeded []gax.CallOption MarkRecommendationFailed []gax.CallOption } func defaultClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("recommender.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultCallOptions() *CallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &CallOptions{ ListRecommendations: retry[[2]string{"default", "idempotent"}], GetRecommendation: retry[[2]string{"default", "idempotent"}], MarkRecommendationClaimed: retry[[2]string{"default", "non_idempotent"}], MarkRecommendationSucceeded: retry[[2]string{"default", "non_idempotent"}], MarkRecommendationFailed: retry[[2]string{"default", "non_idempotent"}], } } // Client is a client for interacting with Recommender API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. client recommenderpb.RecommenderClient // The call options for this service. CallOptions *CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewClient creates a new recommender client. // // Provides recommendations for cloud customers for various categories like // performance optimization, cost savings, reliability, feature discovery, etc. // These recommendations are generated automatically based on analysis of user // resources, configuration and monitoring metrics. func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultClientOptions(), opts...)...) if err != nil { return nil, err } c := &Client{ conn: conn, CallOptions: defaultCallOptions(), client: recommenderpb.NewRecommenderClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *Client) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *Client) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // ListRecommendations lists recommendations for a Cloud project. Requires the recommender.*.list // IAM permission for the specified recommender. func (c *Client) ListRecommendations(ctx context.Context, req *recommenderpb.ListRecommendationsRequest, opts ...gax.CallOption) *RecommendationIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListRecommendations[0:len(c.CallOptions.ListRecommendations):len(c.CallOptions.ListRecommendations)], opts...) it := &RecommendationIterator{} req = proto.Clone(req).(*recommenderpb.ListRecommendationsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*recommenderpb.Recommendation, string, error) { var resp *recommenderpb.ListRecommendationsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListRecommendations(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Recommendations, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetRecommendation gets the requested recommendation. Requires the recommender.*.get // IAM permission for the specified recommender. func (c *Client) GetRecommendation(ctx context.Context, req *recommenderpb.GetRecommendationRequest, opts ...gax.CallOption) (*recommenderpb.Recommendation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetRecommendation[0:len(c.CallOptions.GetRecommendation):len(c.CallOptions.GetRecommendation)], opts...) var resp *recommenderpb.Recommendation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetRecommendation(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // MarkRecommendationClaimed mark the Recommendation State as Claimed. Users can use this method to // indicate to the Recommender API that they are starting to apply the // recommendation themselves. This stops the recommendation content from being // updated. // // MarkRecommendationClaimed can be applied to recommendations in CLAIMED, // SUCCEEDED, FAILED, or ACTIVE state. // // Requires the recommender.*.update IAM permission for the specified // recommender. func (c *Client) MarkRecommendationClaimed(ctx context.Context, req *recommenderpb.MarkRecommendationClaimedRequest, opts ...gax.CallOption) (*recommenderpb.Recommendation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.MarkRecommendationClaimed[0:len(c.CallOptions.MarkRecommendationClaimed):len(c.CallOptions.MarkRecommendationClaimed)], opts...) var resp *recommenderpb.Recommendation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.MarkRecommendationClaimed(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // MarkRecommendationSucceeded mark the Recommendation State as Succeeded. Users can use this method to // indicate to the Recommender API that they have applied the recommendation // themselves, and the operation was successful. This stops the recommendation // content from being updated. // // MarkRecommendationSucceeded can be applied to recommendations in ACTIVE, // CLAIMED, SUCCEEDED, or FAILED state. // // Requires the recommender.*.update IAM permission for the specified // recommender. func (c *Client) MarkRecommendationSucceeded(ctx context.Context, req *recommenderpb.MarkRecommendationSucceededRequest, opts ...gax.CallOption) (*recommenderpb.Recommendation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.MarkRecommendationSucceeded[0:len(c.CallOptions.MarkRecommendationSucceeded):len(c.CallOptions.MarkRecommendationSucceeded)], opts...) var resp *recommenderpb.Recommendation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.MarkRecommendationSucceeded(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // MarkRecommendationFailed mark the Recommendation State as Failed. Users can use this method to // indicate to the Recommender API that they have applied the recommendation // themselves, and the operation failed. This stops the recommendation content // from being updated. // // MarkRecommendationFailed can be applied to recommendations in ACTIVE, // CLAIMED, SUCCEEDED, or FAILED state. // // Requires the recommender.*.update IAM permission for the specified // recommender. func (c *Client) MarkRecommendationFailed(ctx context.Context, req *recommenderpb.MarkRecommendationFailedRequest, opts ...gax.CallOption) (*recommenderpb.Recommendation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.MarkRecommendationFailed[0:len(c.CallOptions.MarkRecommendationFailed):len(c.CallOptions.MarkRecommendationFailed)], opts...) var resp *recommenderpb.Recommendation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.MarkRecommendationFailed(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // RecommendationIterator manages a stream of *recommenderpb.Recommendation. type RecommendationIterator struct { items []*recommenderpb.Recommendation pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*recommenderpb.Recommendation, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *RecommendationIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *RecommendationIterator) Next() (*recommenderpb.Recommendation, error) { var item *recommenderpb.Recommendation if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *RecommendationIterator) bufLen() int { return len(it.items) } func (it *RecommendationIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/recommender/apiv1beta1/recommender_client_example_test.go000066400000000000000000000057171356504100700277760ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package recommender_test import ( "context" recommender "cloud.google.com/go/recommender/apiv1beta1" "google.golang.org/api/iterator" recommenderpb "google.golang.org/genproto/googleapis/cloud/recommender/v1beta1" ) func ExampleNewClient() { ctx := context.Background() c, err := recommender.NewClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleClient_ListRecommendations() { ctx := context.Background() c, err := recommender.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &recommenderpb.ListRecommendationsRequest{ // TODO: Fill request struct fields. } it := c.ListRecommendations(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_GetRecommendation() { ctx := context.Background() c, err := recommender.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &recommenderpb.GetRecommendationRequest{ // TODO: Fill request struct fields. } resp, err := c.GetRecommendation(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_MarkRecommendationClaimed() { ctx := context.Background() c, err := recommender.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &recommenderpb.MarkRecommendationClaimedRequest{ // TODO: Fill request struct fields. } resp, err := c.MarkRecommendationClaimed(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_MarkRecommendationSucceeded() { ctx := context.Background() c, err := recommender.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &recommenderpb.MarkRecommendationSucceededRequest{ // TODO: Fill request struct fields. } resp, err := c.MarkRecommendationSucceeded(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_MarkRecommendationFailed() { ctx := context.Background() c, err := recommender.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &recommenderpb.MarkRecommendationFailedRequest{ // TODO: Fill request struct fields. } resp, err := c.MarkRecommendationFailed(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/redis/000077500000000000000000000000001356504100700156765ustar00rootroot00000000000000google-cloud-go-0.49.0/redis/apiv1/000077500000000000000000000000001356504100700167165ustar00rootroot00000000000000google-cloud-go-0.49.0/redis/apiv1/.repo-metadata.json000066400000000000000000000006551356504100700224200ustar00rootroot00000000000000{ "name": "redis", "name_pretty": "Cloud Memorystore for Redis API", "product_documentation": "https://cloud.google.com/memorystore/docs/redis", "client_documentation": "https://godoc.org/cloud.google.com/go/redis/apiv1", "release_level": "alpha", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "redis.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/redis/apiv1/cloud_redis_client.go000066400000000000000000001010271356504100700231000ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package redis import ( "context" "fmt" "math" "net/url" "time" "cloud.google.com/go/longrunning" lroauto "cloud.google.com/go/longrunning/autogen" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" redispb "google.golang.org/genproto/googleapis/cloud/redis/v1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" "google.golang.org/grpc" "google.golang.org/grpc/metadata" ) // CloudRedisCallOptions contains the retry settings for each method of CloudRedisClient. type CloudRedisCallOptions struct { ListInstances []gax.CallOption GetInstance []gax.CallOption CreateInstance []gax.CallOption UpdateInstance []gax.CallOption ImportInstance []gax.CallOption ExportInstance []gax.CallOption FailoverInstance []gax.CallOption DeleteInstance []gax.CallOption } func defaultCloudRedisClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("redis.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultCloudRedisCallOptions() *CloudRedisCallOptions { retry := map[[2]string][]gax.CallOption{} return &CloudRedisCallOptions{ ListInstances: retry[[2]string{"default", "non_idempotent"}], GetInstance: retry[[2]string{"default", "non_idempotent"}], CreateInstance: retry[[2]string{"default", "non_idempotent"}], UpdateInstance: retry[[2]string{"default", "non_idempotent"}], ImportInstance: retry[[2]string{"default", "non_idempotent"}], ExportInstance: retry[[2]string{"default", "non_idempotent"}], FailoverInstance: retry[[2]string{"default", "non_idempotent"}], DeleteInstance: retry[[2]string{"default", "non_idempotent"}], } } // CloudRedisClient is a client for interacting with Google Cloud Memorystore for Redis API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type CloudRedisClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. cloudRedisClient redispb.CloudRedisClient // LROClient is used internally to handle longrunning operations. // It is exposed so that its CallOptions can be modified if required. // Users should not Close this client. LROClient *lroauto.OperationsClient // The call options for this service. CallOptions *CloudRedisCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewCloudRedisClient creates a new cloud redis client. // // Configures and manages Cloud Memorystore for Redis instances // // Google Cloud Memorystore for Redis v1 // // The redis.googleapis.com service implements the Google Cloud Memorystore // for Redis API and defines the following resource model for managing Redis // instances: // // The service works with a collection of cloud projects, named: /projects/* // // Each project has a collection of available locations, named: /locations/* // // Each location has a collection of Redis instances, named: /instances/* // // As such, Redis instances are resources of the form: // /projects/{project_id}/locations/{location_id}/instances/{instance_id} // // Note that location_id must be referring to a GCP region; for example: // // projects/redpepper-1290/locations/us-central1/instances/my-redis func NewCloudRedisClient(ctx context.Context, opts ...option.ClientOption) (*CloudRedisClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultCloudRedisClientOptions(), opts...)...) if err != nil { return nil, err } c := &CloudRedisClient{ conn: conn, CallOptions: defaultCloudRedisCallOptions(), cloudRedisClient: redispb.NewCloudRedisClient(conn), } c.setGoogleClientInfo() c.LROClient, err = lroauto.NewOperationsClient(ctx, option.WithGRPCConn(conn)) if err != nil { // This error "should not happen", since we are just reusing old connection // and never actually need to dial. // If this does happen, we could leak conn. However, we cannot close conn: // If the user invoked the function with option.WithGRPCConn, // we would close a connection that's still in use. // TODO(pongad): investigate error conditions. return nil, err } return c, nil } // Connection returns the client's connection to the API service. func (c *CloudRedisClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *CloudRedisClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *CloudRedisClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // ListInstances lists all Redis instances owned by a project in either the specified // location (region) or all locations. // // The location should have the following format: // // projects/{project_id}/locations/{location_id} // // If location_id is specified as - (wildcard), then all regions // available to the project are queried, and the results are aggregated. func (c *CloudRedisClient) ListInstances(ctx context.Context, req *redispb.ListInstancesRequest, opts ...gax.CallOption) *InstanceIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListInstances[0:len(c.CallOptions.ListInstances):len(c.CallOptions.ListInstances)], opts...) it := &InstanceIterator{} req = proto.Clone(req).(*redispb.ListInstancesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*redispb.Instance, string, error) { var resp *redispb.ListInstancesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.cloudRedisClient.ListInstances(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Instances, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetInstance gets the details of a specific Redis instance. func (c *CloudRedisClient) GetInstance(ctx context.Context, req *redispb.GetInstanceRequest, opts ...gax.CallOption) (*redispb.Instance, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetInstance[0:len(c.CallOptions.GetInstance):len(c.CallOptions.GetInstance)], opts...) var resp *redispb.Instance err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.cloudRedisClient.GetInstance(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateInstance creates a Redis instance based on the specified tier and memory size. // // By default, the instance is accessible from the project's // default network (at /compute/docs/networks-and-firewalls#networks). // // The creation is executed asynchronously and callers may check the returned // operation to track its progress. Once the operation is completed the Redis // instance will be fully functional. Completed longrunning.Operation will // contain the new instance object in the response field. // // The returned operation is automatically deleted after a few hours, so there // is no need to call DeleteOperation. func (c *CloudRedisClient) CreateInstance(ctx context.Context, req *redispb.CreateInstanceRequest, opts ...gax.CallOption) (*CreateInstanceOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateInstance[0:len(c.CallOptions.CreateInstance):len(c.CallOptions.CreateInstance)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.cloudRedisClient.CreateInstance(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &CreateInstanceOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // UpdateInstance updates the metadata and configuration of a specific Redis instance. // // Completed longrunning.Operation will contain the new instance object // in the response field. The returned operation is automatically deleted // after a few hours, so there is no need to call DeleteOperation. func (c *CloudRedisClient) UpdateInstance(ctx context.Context, req *redispb.UpdateInstanceRequest, opts ...gax.CallOption) (*UpdateInstanceOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "instance.name", url.QueryEscape(req.GetInstance().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateInstance[0:len(c.CallOptions.UpdateInstance):len(c.CallOptions.UpdateInstance)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.cloudRedisClient.UpdateInstance(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &UpdateInstanceOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // ImportInstance import a Redis RDB snapshot file from Cloud Storage into a Redis instance. // // Redis may stop serving during this operation. Instance state will be // IMPORTING for entire operation. When complete, the instance will contain // only data from the imported file. // // The returned operation is automatically deleted after a few hours, so // there is no need to call DeleteOperation. func (c *CloudRedisClient) ImportInstance(ctx context.Context, req *redispb.ImportInstanceRequest, opts ...gax.CallOption) (*ImportInstanceOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ImportInstance[0:len(c.CallOptions.ImportInstance):len(c.CallOptions.ImportInstance)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.cloudRedisClient.ImportInstance(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &ImportInstanceOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // ExportInstance export Redis instance data into a Redis RDB format file in Cloud Storage. // // Redis will continue serving during this operation. // // The returned operation is automatically deleted after a few hours, so // there is no need to call DeleteOperation. func (c *CloudRedisClient) ExportInstance(ctx context.Context, req *redispb.ExportInstanceRequest, opts ...gax.CallOption) (*ExportInstanceOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ExportInstance[0:len(c.CallOptions.ExportInstance):len(c.CallOptions.ExportInstance)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.cloudRedisClient.ExportInstance(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &ExportInstanceOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // FailoverInstance initiates a failover of the master node to current replica node for a // specific STANDARD tier Cloud Memorystore for Redis instance. func (c *CloudRedisClient) FailoverInstance(ctx context.Context, req *redispb.FailoverInstanceRequest, opts ...gax.CallOption) (*FailoverInstanceOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.FailoverInstance[0:len(c.CallOptions.FailoverInstance):len(c.CallOptions.FailoverInstance)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.cloudRedisClient.FailoverInstance(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &FailoverInstanceOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // DeleteInstance deletes a specific Redis instance. Instance stops serving and data is // deleted. func (c *CloudRedisClient) DeleteInstance(ctx context.Context, req *redispb.DeleteInstanceRequest, opts ...gax.CallOption) (*DeleteInstanceOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteInstance[0:len(c.CallOptions.DeleteInstance):len(c.CallOptions.DeleteInstance)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.cloudRedisClient.DeleteInstance(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &DeleteInstanceOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // InstanceIterator manages a stream of *redispb.Instance. type InstanceIterator struct { items []*redispb.Instance pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*redispb.Instance, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *InstanceIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *InstanceIterator) Next() (*redispb.Instance, error) { var item *redispb.Instance if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *InstanceIterator) bufLen() int { return len(it.items) } func (it *InstanceIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // CreateInstanceOperation manages a long-running operation from CreateInstance. type CreateInstanceOperation struct { lro *longrunning.Operation } // CreateInstanceOperation returns a new CreateInstanceOperation from a given name. // The name must be that of a previously created CreateInstanceOperation, possibly from a different process. func (c *CloudRedisClient) CreateInstanceOperation(name string) *CreateInstanceOperation { return &CreateInstanceOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *CreateInstanceOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*redispb.Instance, error) { var resp redispb.Instance if err := op.lro.WaitWithInterval(ctx, &resp, 360000*time.Millisecond, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *CreateInstanceOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*redispb.Instance, error) { var resp redispb.Instance if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *CreateInstanceOperation) Metadata() (*redispb.OperationMetadata, error) { var meta redispb.OperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *CreateInstanceOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *CreateInstanceOperation) Name() string { return op.lro.Name() } // DeleteInstanceOperation manages a long-running operation from DeleteInstance. type DeleteInstanceOperation struct { lro *longrunning.Operation } // DeleteInstanceOperation returns a new DeleteInstanceOperation from a given name. // The name must be that of a previously created DeleteInstanceOperation, possibly from a different process. func (c *CloudRedisClient) DeleteInstanceOperation(name string) *DeleteInstanceOperation { return &DeleteInstanceOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning any error encountered. // // See documentation of Poll for error-handling information. func (op *DeleteInstanceOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { return op.lro.WaitWithInterval(ctx, nil, 360000*time.Millisecond, opts...) } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, op.Done will return true. func (op *DeleteInstanceOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Poll(ctx, nil, opts...) } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *DeleteInstanceOperation) Metadata() (*redispb.OperationMetadata, error) { var meta redispb.OperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *DeleteInstanceOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *DeleteInstanceOperation) Name() string { return op.lro.Name() } // ExportInstanceOperation manages a long-running operation from ExportInstance. type ExportInstanceOperation struct { lro *longrunning.Operation } // ExportInstanceOperation returns a new ExportInstanceOperation from a given name. // The name must be that of a previously created ExportInstanceOperation, possibly from a different process. func (c *CloudRedisClient) ExportInstanceOperation(name string) *ExportInstanceOperation { return &ExportInstanceOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *ExportInstanceOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*redispb.Instance, error) { var resp redispb.Instance if err := op.lro.WaitWithInterval(ctx, &resp, 360000*time.Millisecond, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *ExportInstanceOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*redispb.Instance, error) { var resp redispb.Instance if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *ExportInstanceOperation) Metadata() (*redispb.OperationMetadata, error) { var meta redispb.OperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *ExportInstanceOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *ExportInstanceOperation) Name() string { return op.lro.Name() } // FailoverInstanceOperation manages a long-running operation from FailoverInstance. type FailoverInstanceOperation struct { lro *longrunning.Operation } // FailoverInstanceOperation returns a new FailoverInstanceOperation from a given name. // The name must be that of a previously created FailoverInstanceOperation, possibly from a different process. func (c *CloudRedisClient) FailoverInstanceOperation(name string) *FailoverInstanceOperation { return &FailoverInstanceOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *FailoverInstanceOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*redispb.Instance, error) { var resp redispb.Instance if err := op.lro.WaitWithInterval(ctx, &resp, 360000*time.Millisecond, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *FailoverInstanceOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*redispb.Instance, error) { var resp redispb.Instance if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *FailoverInstanceOperation) Metadata() (*redispb.OperationMetadata, error) { var meta redispb.OperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *FailoverInstanceOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *FailoverInstanceOperation) Name() string { return op.lro.Name() } // ImportInstanceOperation manages a long-running operation from ImportInstance. type ImportInstanceOperation struct { lro *longrunning.Operation } // ImportInstanceOperation returns a new ImportInstanceOperation from a given name. // The name must be that of a previously created ImportInstanceOperation, possibly from a different process. func (c *CloudRedisClient) ImportInstanceOperation(name string) *ImportInstanceOperation { return &ImportInstanceOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *ImportInstanceOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*redispb.Instance, error) { var resp redispb.Instance if err := op.lro.WaitWithInterval(ctx, &resp, 360000*time.Millisecond, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *ImportInstanceOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*redispb.Instance, error) { var resp redispb.Instance if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *ImportInstanceOperation) Metadata() (*redispb.OperationMetadata, error) { var meta redispb.OperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *ImportInstanceOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *ImportInstanceOperation) Name() string { return op.lro.Name() } // UpdateInstanceOperation manages a long-running operation from UpdateInstance. type UpdateInstanceOperation struct { lro *longrunning.Operation } // UpdateInstanceOperation returns a new UpdateInstanceOperation from a given name. // The name must be that of a previously created UpdateInstanceOperation, possibly from a different process. func (c *CloudRedisClient) UpdateInstanceOperation(name string) *UpdateInstanceOperation { return &UpdateInstanceOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *UpdateInstanceOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*redispb.Instance, error) { var resp redispb.Instance if err := op.lro.WaitWithInterval(ctx, &resp, 360000*time.Millisecond, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *UpdateInstanceOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*redispb.Instance, error) { var resp redispb.Instance if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *UpdateInstanceOperation) Metadata() (*redispb.OperationMetadata, error) { var meta redispb.OperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *UpdateInstanceOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *UpdateInstanceOperation) Name() string { return op.lro.Name() } google-cloud-go-0.49.0/redis/apiv1/cloud_redis_client_example_test.go000066400000000000000000000104231356504100700256510ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package redis_test import ( "context" redis "cloud.google.com/go/redis/apiv1" "google.golang.org/api/iterator" redispb "google.golang.org/genproto/googleapis/cloud/redis/v1" ) func ExampleNewCloudRedisClient() { ctx := context.Background() c, err := redis.NewCloudRedisClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleCloudRedisClient_ListInstances() { ctx := context.Background() c, err := redis.NewCloudRedisClient(ctx) if err != nil { // TODO: Handle error. } req := &redispb.ListInstancesRequest{ // TODO: Fill request struct fields. } it := c.ListInstances(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleCloudRedisClient_GetInstance() { ctx := context.Background() c, err := redis.NewCloudRedisClient(ctx) if err != nil { // TODO: Handle error. } req := &redispb.GetInstanceRequest{ // TODO: Fill request struct fields. } resp, err := c.GetInstance(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleCloudRedisClient_CreateInstance() { ctx := context.Background() c, err := redis.NewCloudRedisClient(ctx) if err != nil { // TODO: Handle error. } req := &redispb.CreateInstanceRequest{ // TODO: Fill request struct fields. } op, err := c.CreateInstance(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleCloudRedisClient_UpdateInstance() { ctx := context.Background() c, err := redis.NewCloudRedisClient(ctx) if err != nil { // TODO: Handle error. } req := &redispb.UpdateInstanceRequest{ // TODO: Fill request struct fields. } op, err := c.UpdateInstance(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleCloudRedisClient_ImportInstance() { ctx := context.Background() c, err := redis.NewCloudRedisClient(ctx) if err != nil { // TODO: Handle error. } req := &redispb.ImportInstanceRequest{ // TODO: Fill request struct fields. } op, err := c.ImportInstance(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleCloudRedisClient_ExportInstance() { ctx := context.Background() c, err := redis.NewCloudRedisClient(ctx) if err != nil { // TODO: Handle error. } req := &redispb.ExportInstanceRequest{ // TODO: Fill request struct fields. } op, err := c.ExportInstance(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleCloudRedisClient_FailoverInstance() { ctx := context.Background() c, err := redis.NewCloudRedisClient(ctx) if err != nil { // TODO: Handle error. } req := &redispb.FailoverInstanceRequest{ // TODO: Fill request struct fields. } op, err := c.FailoverInstance(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleCloudRedisClient_DeleteInstance() { ctx := context.Background() c, err := redis.NewCloudRedisClient(ctx) if err != nil { // TODO: Handle error. } req := &redispb.DeleteInstanceRequest{ // TODO: Fill request struct fields. } op, err := c.DeleteInstance(ctx, req) if err != nil { // TODO: Handle error. } err = op.Wait(ctx) // TODO: Handle error. } google-cloud-go-0.49.0/redis/apiv1/doc.go000066400000000000000000000053461356504100700200220ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package redis is an auto-generated package for the // Google Cloud Memorystore for Redis API. // // NOTE: This package is in alpha. It is not stable, and is likely to change. // // Creates and manages Redis instances on the Google Cloud Platform. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package redis // import "cloud.google.com/go/redis/apiv1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191115" google-cloud-go-0.49.0/redis/apiv1/mock_test.go000066400000000000000000000740421356504100700212440ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package redis import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" "google.golang.org/api/option" redispb "google.golang.org/genproto/googleapis/cloud/redis/v1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" field_maskpb "google.golang.org/genproto/protobuf/field_mask" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockCloudRedisServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. redispb.CloudRedisServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockCloudRedisServer) ListInstances(ctx context.Context, req *redispb.ListInstancesRequest) (*redispb.ListInstancesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*redispb.ListInstancesResponse), nil } func (s *mockCloudRedisServer) GetInstance(ctx context.Context, req *redispb.GetInstanceRequest) (*redispb.Instance, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*redispb.Instance), nil } func (s *mockCloudRedisServer) CreateInstance(ctx context.Context, req *redispb.CreateInstanceRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockCloudRedisServer) UpdateInstance(ctx context.Context, req *redispb.UpdateInstanceRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockCloudRedisServer) ImportInstance(ctx context.Context, req *redispb.ImportInstanceRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockCloudRedisServer) ExportInstance(ctx context.Context, req *redispb.ExportInstanceRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockCloudRedisServer) FailoverInstance(ctx context.Context, req *redispb.FailoverInstanceRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockCloudRedisServer) DeleteInstance(ctx context.Context, req *redispb.DeleteInstanceRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockCloudRedis mockCloudRedisServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() redispb.RegisterCloudRedisServer(serv, &mockCloudRedis) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestCloudRedisListInstances(t *testing.T) { var nextPageToken string = "" var instancesElement *redispb.Instance = &redispb.Instance{} var instances = []*redispb.Instance{instancesElement} var expectedResponse = &redispb.ListInstancesResponse{ NextPageToken: nextPageToken, Instances: instances, } mockCloudRedis.err = nil mockCloudRedis.reqs = nil mockCloudRedis.resps = append(mockCloudRedis.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &redispb.ListInstancesRequest{ Parent: formattedParent, } c, err := NewCloudRedisClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListInstances(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockCloudRedis.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Instances[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudRedisListInstancesError(t *testing.T) { errCode := codes.PermissionDenied mockCloudRedis.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &redispb.ListInstancesRequest{ Parent: formattedParent, } c, err := NewCloudRedisClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListInstances(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudRedisGetInstance(t *testing.T) { var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var locationId string = "locationId552319461" var alternativeLocationId string = "alternativeLocationId-718920621" var redisVersion string = "redisVersion-685310444" var reservedIpRange string = "reservedIpRange-1082940580" var host string = "host3208616" var port int32 = 3446913 var currentLocationId string = "currentLocationId1312712735" var statusMessage string = "statusMessage-239442758" var memorySizeGb int32 = 34199707 var authorizedNetwork string = "authorizedNetwork-1733809270" var persistenceIamIdentity string = "persistenceIamIdentity1061944584" var expectedResponse = &redispb.Instance{ Name: name2, DisplayName: displayName, LocationId: locationId, AlternativeLocationId: alternativeLocationId, RedisVersion: redisVersion, ReservedIpRange: reservedIpRange, Host: host, Port: port, CurrentLocationId: currentLocationId, StatusMessage: statusMessage, MemorySizeGb: memorySizeGb, AuthorizedNetwork: authorizedNetwork, PersistenceIamIdentity: persistenceIamIdentity, } mockCloudRedis.err = nil mockCloudRedis.reqs = nil mockCloudRedis.resps = append(mockCloudRedis.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/instances/%s", "[PROJECT]", "[LOCATION]", "[INSTANCE]") var request = &redispb.GetInstanceRequest{ Name: formattedName, } c, err := NewCloudRedisClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetInstance(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudRedis.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudRedisGetInstanceError(t *testing.T) { errCode := codes.PermissionDenied mockCloudRedis.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/instances/%s", "[PROJECT]", "[LOCATION]", "[INSTANCE]") var request = &redispb.GetInstanceRequest{ Name: formattedName, } c, err := NewCloudRedisClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetInstance(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudRedisCreateInstance(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var locationId string = "locationId552319461" var alternativeLocationId string = "alternativeLocationId-718920621" var redisVersion string = "redisVersion-685310444" var reservedIpRange string = "reservedIpRange-1082940580" var host string = "host3208616" var port int32 = 3446913 var currentLocationId string = "currentLocationId1312712735" var statusMessage string = "statusMessage-239442758" var memorySizeGb2 int32 = 1493816946 var authorizedNetwork string = "authorizedNetwork-1733809270" var persistenceIamIdentity string = "persistenceIamIdentity1061944584" var expectedResponse = &redispb.Instance{ Name: name, DisplayName: displayName, LocationId: locationId, AlternativeLocationId: alternativeLocationId, RedisVersion: redisVersion, ReservedIpRange: reservedIpRange, Host: host, Port: port, CurrentLocationId: currentLocationId, StatusMessage: statusMessage, MemorySizeGb: memorySizeGb2, AuthorizedNetwork: authorizedNetwork, PersistenceIamIdentity: persistenceIamIdentity, } mockCloudRedis.err = nil mockCloudRedis.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockCloudRedis.resps = append(mockCloudRedis.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var instanceId string = "test_instance" var tier redispb.Instance_Tier = redispb.Instance_BASIC var memorySizeGb int32 = 1 var instance = &redispb.Instance{ Tier: tier, MemorySizeGb: memorySizeGb, } var request = &redispb.CreateInstanceRequest{ Parent: formattedParent, InstanceId: instanceId, Instance: instance, } c, err := NewCloudRedisClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.CreateInstance(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockCloudRedis.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudRedisCreateInstanceError(t *testing.T) { errCode := codes.PermissionDenied mockCloudRedis.err = nil mockCloudRedis.resps = append(mockCloudRedis.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var instanceId string = "test_instance" var tier redispb.Instance_Tier = redispb.Instance_BASIC var memorySizeGb int32 = 1 var instance = &redispb.Instance{ Tier: tier, MemorySizeGb: memorySizeGb, } var request = &redispb.CreateInstanceRequest{ Parent: formattedParent, InstanceId: instanceId, Instance: instance, } c, err := NewCloudRedisClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.CreateInstance(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudRedisUpdateInstance(t *testing.T) { var name string = "name3373707" var displayName2 string = "displayName21615000987" var locationId string = "locationId552319461" var alternativeLocationId string = "alternativeLocationId-718920621" var redisVersion string = "redisVersion-685310444" var reservedIpRange string = "reservedIpRange-1082940580" var host string = "host3208616" var port int32 = 3446913 var currentLocationId string = "currentLocationId1312712735" var statusMessage string = "statusMessage-239442758" var memorySizeGb int32 = 34199707 var authorizedNetwork string = "authorizedNetwork-1733809270" var persistenceIamIdentity string = "persistenceIamIdentity1061944584" var expectedResponse = &redispb.Instance{ Name: name, DisplayName: displayName2, LocationId: locationId, AlternativeLocationId: alternativeLocationId, RedisVersion: redisVersion, ReservedIpRange: reservedIpRange, Host: host, Port: port, CurrentLocationId: currentLocationId, StatusMessage: statusMessage, MemorySizeGb: memorySizeGb, AuthorizedNetwork: authorizedNetwork, PersistenceIamIdentity: persistenceIamIdentity, } mockCloudRedis.err = nil mockCloudRedis.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockCloudRedis.resps = append(mockCloudRedis.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var pathsElement string = "display_name" var pathsElement2 string = "memory_size_gb" var paths = []string{pathsElement, pathsElement2} var updateMask = &field_maskpb.FieldMask{ Paths: paths, } var displayName string = " instance.memory_size_gb=4" var instance = &redispb.Instance{ DisplayName: displayName, } var request = &redispb.UpdateInstanceRequest{ UpdateMask: updateMask, Instance: instance, } c, err := NewCloudRedisClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.UpdateInstance(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockCloudRedis.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudRedisUpdateInstanceError(t *testing.T) { errCode := codes.PermissionDenied mockCloudRedis.err = nil mockCloudRedis.resps = append(mockCloudRedis.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var pathsElement string = "display_name" var pathsElement2 string = "memory_size_gb" var paths = []string{pathsElement, pathsElement2} var updateMask = &field_maskpb.FieldMask{ Paths: paths, } var displayName string = " instance.memory_size_gb=4" var instance = &redispb.Instance{ DisplayName: displayName, } var request = &redispb.UpdateInstanceRequest{ UpdateMask: updateMask, Instance: instance, } c, err := NewCloudRedisClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.UpdateInstance(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudRedisImportInstance(t *testing.T) { var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var locationId string = "locationId552319461" var alternativeLocationId string = "alternativeLocationId-718920621" var redisVersion string = "redisVersion-685310444" var reservedIpRange string = "reservedIpRange-1082940580" var host string = "host3208616" var port int32 = 3446913 var currentLocationId string = "currentLocationId1312712735" var statusMessage string = "statusMessage-239442758" var memorySizeGb int32 = 34199707 var authorizedNetwork string = "authorizedNetwork-1733809270" var persistenceIamIdentity string = "persistenceIamIdentity1061944584" var expectedResponse = &redispb.Instance{ Name: name2, DisplayName: displayName, LocationId: locationId, AlternativeLocationId: alternativeLocationId, RedisVersion: redisVersion, ReservedIpRange: reservedIpRange, Host: host, Port: port, CurrentLocationId: currentLocationId, StatusMessage: statusMessage, MemorySizeGb: memorySizeGb, AuthorizedNetwork: authorizedNetwork, PersistenceIamIdentity: persistenceIamIdentity, } mockCloudRedis.err = nil mockCloudRedis.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockCloudRedis.resps = append(mockCloudRedis.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var name string = "name3373707" var inputConfig *redispb.InputConfig = &redispb.InputConfig{} var request = &redispb.ImportInstanceRequest{ Name: name, InputConfig: inputConfig, } c, err := NewCloudRedisClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.ImportInstance(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockCloudRedis.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudRedisImportInstanceError(t *testing.T) { errCode := codes.PermissionDenied mockCloudRedis.err = nil mockCloudRedis.resps = append(mockCloudRedis.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var name string = "name3373707" var inputConfig *redispb.InputConfig = &redispb.InputConfig{} var request = &redispb.ImportInstanceRequest{ Name: name, InputConfig: inputConfig, } c, err := NewCloudRedisClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.ImportInstance(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudRedisExportInstance(t *testing.T) { var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var locationId string = "locationId552319461" var alternativeLocationId string = "alternativeLocationId-718920621" var redisVersion string = "redisVersion-685310444" var reservedIpRange string = "reservedIpRange-1082940580" var host string = "host3208616" var port int32 = 3446913 var currentLocationId string = "currentLocationId1312712735" var statusMessage string = "statusMessage-239442758" var memorySizeGb int32 = 34199707 var authorizedNetwork string = "authorizedNetwork-1733809270" var persistenceIamIdentity string = "persistenceIamIdentity1061944584" var expectedResponse = &redispb.Instance{ Name: name2, DisplayName: displayName, LocationId: locationId, AlternativeLocationId: alternativeLocationId, RedisVersion: redisVersion, ReservedIpRange: reservedIpRange, Host: host, Port: port, CurrentLocationId: currentLocationId, StatusMessage: statusMessage, MemorySizeGb: memorySizeGb, AuthorizedNetwork: authorizedNetwork, PersistenceIamIdentity: persistenceIamIdentity, } mockCloudRedis.err = nil mockCloudRedis.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockCloudRedis.resps = append(mockCloudRedis.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var name string = "name3373707" var outputConfig *redispb.OutputConfig = &redispb.OutputConfig{} var request = &redispb.ExportInstanceRequest{ Name: name, OutputConfig: outputConfig, } c, err := NewCloudRedisClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.ExportInstance(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockCloudRedis.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudRedisExportInstanceError(t *testing.T) { errCode := codes.PermissionDenied mockCloudRedis.err = nil mockCloudRedis.resps = append(mockCloudRedis.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var name string = "name3373707" var outputConfig *redispb.OutputConfig = &redispb.OutputConfig{} var request = &redispb.ExportInstanceRequest{ Name: name, OutputConfig: outputConfig, } c, err := NewCloudRedisClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.ExportInstance(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudRedisFailoverInstance(t *testing.T) { var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var locationId string = "locationId552319461" var alternativeLocationId string = "alternativeLocationId-718920621" var redisVersion string = "redisVersion-685310444" var reservedIpRange string = "reservedIpRange-1082940580" var host string = "host3208616" var port int32 = 3446913 var currentLocationId string = "currentLocationId1312712735" var statusMessage string = "statusMessage-239442758" var memorySizeGb int32 = 34199707 var authorizedNetwork string = "authorizedNetwork-1733809270" var persistenceIamIdentity string = "persistenceIamIdentity1061944584" var expectedResponse = &redispb.Instance{ Name: name2, DisplayName: displayName, LocationId: locationId, AlternativeLocationId: alternativeLocationId, RedisVersion: redisVersion, ReservedIpRange: reservedIpRange, Host: host, Port: port, CurrentLocationId: currentLocationId, StatusMessage: statusMessage, MemorySizeGb: memorySizeGb, AuthorizedNetwork: authorizedNetwork, PersistenceIamIdentity: persistenceIamIdentity, } mockCloudRedis.err = nil mockCloudRedis.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockCloudRedis.resps = append(mockCloudRedis.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/instances/%s", "[PROJECT]", "[LOCATION]", "[INSTANCE]") var request = &redispb.FailoverInstanceRequest{ Name: formattedName, } c, err := NewCloudRedisClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.FailoverInstance(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockCloudRedis.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudRedisFailoverInstanceError(t *testing.T) { errCode := codes.PermissionDenied mockCloudRedis.err = nil mockCloudRedis.resps = append(mockCloudRedis.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/instances/%s", "[PROJECT]", "[LOCATION]", "[INSTANCE]") var request = &redispb.FailoverInstanceRequest{ Name: formattedName, } c, err := NewCloudRedisClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.FailoverInstance(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudRedisDeleteInstance(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockCloudRedis.err = nil mockCloudRedis.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockCloudRedis.resps = append(mockCloudRedis.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/instances/%s", "[PROJECT]", "[LOCATION]", "[INSTANCE]") var request = &redispb.DeleteInstanceRequest{ Name: formattedName, } c, err := NewCloudRedisClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.DeleteInstance(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockCloudRedis.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestCloudRedisDeleteInstanceError(t *testing.T) { errCode := codes.PermissionDenied mockCloudRedis.err = nil mockCloudRedis.resps = append(mockCloudRedis.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/instances/%s", "[PROJECT]", "[LOCATION]", "[INSTANCE]") var request = &redispb.DeleteInstanceRequest{ Name: formattedName, } c, err := NewCloudRedisClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.DeleteInstance(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } google-cloud-go-0.49.0/redis/apiv1beta1/000077500000000000000000000000001356504100700176335ustar00rootroot00000000000000google-cloud-go-0.49.0/redis/apiv1beta1/.repo-metadata.json000066400000000000000000000006611356504100700233320ustar00rootroot00000000000000{ "name": "redis", "name_pretty": "Cloud Memorystore for Redis API", "product_documentation": "https://cloud.google.com/memorystore/docs/redis", "client_documentation": "https://godoc.org/cloud.google.com/go/redis/apiv1beta1", "release_level": "beta", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "redis.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/redis/apiv1beta1/cloud_redis_client.go000066400000000000000000001006171356504100700240210ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package redis import ( "context" "fmt" "math" "net/url" "time" "cloud.google.com/go/longrunning" lroauto "cloud.google.com/go/longrunning/autogen" "github.com/golang/protobuf/proto" anypb "github.com/golang/protobuf/ptypes/any" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" redispb "google.golang.org/genproto/googleapis/cloud/redis/v1beta1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" "google.golang.org/grpc" "google.golang.org/grpc/metadata" ) // CloudRedisCallOptions contains the retry settings for each method of CloudRedisClient. type CloudRedisCallOptions struct { ListInstances []gax.CallOption GetInstance []gax.CallOption CreateInstance []gax.CallOption UpdateInstance []gax.CallOption ImportInstance []gax.CallOption ExportInstance []gax.CallOption FailoverInstance []gax.CallOption DeleteInstance []gax.CallOption } func defaultCloudRedisClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("redis.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultCloudRedisCallOptions() *CloudRedisCallOptions { retry := map[[2]string][]gax.CallOption{} return &CloudRedisCallOptions{ ListInstances: retry[[2]string{"default", "non_idempotent"}], GetInstance: retry[[2]string{"default", "non_idempotent"}], CreateInstance: retry[[2]string{"default", "non_idempotent"}], UpdateInstance: retry[[2]string{"default", "non_idempotent"}], ImportInstance: retry[[2]string{"default", "non_idempotent"}], ExportInstance: retry[[2]string{"default", "non_idempotent"}], FailoverInstance: retry[[2]string{"default", "non_idempotent"}], DeleteInstance: retry[[2]string{"default", "non_idempotent"}], } } // CloudRedisClient is a client for interacting with Google Cloud Memorystore for Redis API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type CloudRedisClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. cloudRedisClient redispb.CloudRedisClient // LROClient is used internally to handle longrunning operations. // It is exposed so that its CallOptions can be modified if required. // Users should not Close this client. LROClient *lroauto.OperationsClient // The call options for this service. CallOptions *CloudRedisCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewCloudRedisClient creates a new cloud redis client. // // Configures and manages Cloud Memorystore for Redis instances // // Google Cloud Memorystore for Redis v1beta1 // // The redis.googleapis.com service implements the Google Cloud Memorystore // for Redis API and defines the following resource model for managing Redis // instances: // // The service works with a collection of cloud projects, named: /projects/* // // Each project has a collection of available locations, named: /locations/* // // Each location has a collection of Redis instances, named: /instances/* // // As such, Redis instances are resources of the form: // /projects/{project_id}/locations/{location_id}/instances/{instance_id} // // Note that location_id must be refering to a GCP region; for example: // // projects/redpepper-1290/locations/us-central1/instances/my-redis func NewCloudRedisClient(ctx context.Context, opts ...option.ClientOption) (*CloudRedisClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultCloudRedisClientOptions(), opts...)...) if err != nil { return nil, err } c := &CloudRedisClient{ conn: conn, CallOptions: defaultCloudRedisCallOptions(), cloudRedisClient: redispb.NewCloudRedisClient(conn), } c.setGoogleClientInfo() c.LROClient, err = lroauto.NewOperationsClient(ctx, option.WithGRPCConn(conn)) if err != nil { // This error "should not happen", since we are just reusing old connection // and never actually need to dial. // If this does happen, we could leak conn. However, we cannot close conn: // If the user invoked the function with option.WithGRPCConn, // we would close a connection that's still in use. // TODO(pongad): investigate error conditions. return nil, err } return c, nil } // Connection returns the client's connection to the API service. func (c *CloudRedisClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *CloudRedisClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *CloudRedisClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // ListInstances lists all Redis instances owned by a project in either the specified // location (region) or all locations. // // The location should have the following format: // // projects/{project_id}/locations/{location_id} // // If location_id is specified as - (wildcard), then all regions // available to the project are queried, and the results are aggregated. func (c *CloudRedisClient) ListInstances(ctx context.Context, req *redispb.ListInstancesRequest, opts ...gax.CallOption) *InstanceIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListInstances[0:len(c.CallOptions.ListInstances):len(c.CallOptions.ListInstances)], opts...) it := &InstanceIterator{} req = proto.Clone(req).(*redispb.ListInstancesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*redispb.Instance, string, error) { var resp *redispb.ListInstancesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.cloudRedisClient.ListInstances(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Instances, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetInstance gets the details of a specific Redis instance. func (c *CloudRedisClient) GetInstance(ctx context.Context, req *redispb.GetInstanceRequest, opts ...gax.CallOption) (*redispb.Instance, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetInstance[0:len(c.CallOptions.GetInstance):len(c.CallOptions.GetInstance)], opts...) var resp *redispb.Instance err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.cloudRedisClient.GetInstance(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateInstance creates a Redis instance based on the specified tier and memory size. // // By default, the instance is accessible from the project's // default network (at /compute/docs/networks-and-firewalls#networks). // // The creation is executed asynchronously and callers may check the returned // operation to track its progress. Once the operation is completed the Redis // instance will be fully functional. Completed longrunning.Operation will // contain the new instance object in the response field. // // The returned operation is automatically deleted after a few hours, so there // is no need to call DeleteOperation. func (c *CloudRedisClient) CreateInstance(ctx context.Context, req *redispb.CreateInstanceRequest, opts ...gax.CallOption) (*CreateInstanceOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateInstance[0:len(c.CallOptions.CreateInstance):len(c.CallOptions.CreateInstance)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.cloudRedisClient.CreateInstance(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &CreateInstanceOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // UpdateInstance updates the metadata and configuration of a specific Redis instance. // // Completed longrunning.Operation will contain the new instance object // in the response field. The returned operation is automatically deleted // after a few hours, so there is no need to call DeleteOperation. func (c *CloudRedisClient) UpdateInstance(ctx context.Context, req *redispb.UpdateInstanceRequest, opts ...gax.CallOption) (*UpdateInstanceOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "instance.name", url.QueryEscape(req.GetInstance().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateInstance[0:len(c.CallOptions.UpdateInstance):len(c.CallOptions.UpdateInstance)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.cloudRedisClient.UpdateInstance(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &UpdateInstanceOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // ImportInstance import a Redis RDB snapshot file from Cloud Storage into a Redis instance. // // Redis may stop serving during this operation. Instance state will be // IMPORTING for entire operation. When complete, the instance will contain // only data from the imported file. // // The returned operation is automatically deleted after a few hours, so // there is no need to call DeleteOperation. func (c *CloudRedisClient) ImportInstance(ctx context.Context, req *redispb.ImportInstanceRequest, opts ...gax.CallOption) (*ImportInstanceOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ImportInstance[0:len(c.CallOptions.ImportInstance):len(c.CallOptions.ImportInstance)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.cloudRedisClient.ImportInstance(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &ImportInstanceOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // ExportInstance export Redis instance data into a Redis RDB format file in Cloud Storage. // // Redis will continue serving during this operation. // // The returned operation is automatically deleted after a few hours, so // there is no need to call DeleteOperation. func (c *CloudRedisClient) ExportInstance(ctx context.Context, req *redispb.ExportInstanceRequest, opts ...gax.CallOption) (*ExportInstanceOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ExportInstance[0:len(c.CallOptions.ExportInstance):len(c.CallOptions.ExportInstance)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.cloudRedisClient.ExportInstance(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &ExportInstanceOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // FailoverInstance initiates a failover of the master node to current replica node for a // specific STANDARD tier Cloud Memorystore for Redis instance. func (c *CloudRedisClient) FailoverInstance(ctx context.Context, req *redispb.FailoverInstanceRequest, opts ...gax.CallOption) (*FailoverInstanceOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.FailoverInstance[0:len(c.CallOptions.FailoverInstance):len(c.CallOptions.FailoverInstance)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.cloudRedisClient.FailoverInstance(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &FailoverInstanceOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // DeleteInstance deletes a specific Redis instance. Instance stops serving and data is // deleted. func (c *CloudRedisClient) DeleteInstance(ctx context.Context, req *redispb.DeleteInstanceRequest, opts ...gax.CallOption) (*DeleteInstanceOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteInstance[0:len(c.CallOptions.DeleteInstance):len(c.CallOptions.DeleteInstance)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.cloudRedisClient.DeleteInstance(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &DeleteInstanceOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // InstanceIterator manages a stream of *redispb.Instance. type InstanceIterator struct { items []*redispb.Instance pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*redispb.Instance, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *InstanceIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *InstanceIterator) Next() (*redispb.Instance, error) { var item *redispb.Instance if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *InstanceIterator) bufLen() int { return len(it.items) } func (it *InstanceIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // CreateInstanceOperation manages a long-running operation from CreateInstance. type CreateInstanceOperation struct { lro *longrunning.Operation } // CreateInstanceOperation returns a new CreateInstanceOperation from a given name. // The name must be that of a previously created CreateInstanceOperation, possibly from a different process. func (c *CloudRedisClient) CreateInstanceOperation(name string) *CreateInstanceOperation { return &CreateInstanceOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *CreateInstanceOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*redispb.Instance, error) { var resp redispb.Instance if err := op.lro.WaitWithInterval(ctx, &resp, 360000*time.Millisecond, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *CreateInstanceOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*redispb.Instance, error) { var resp redispb.Instance if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *CreateInstanceOperation) Metadata() (*anypb.Any, error) { var meta anypb.Any if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *CreateInstanceOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *CreateInstanceOperation) Name() string { return op.lro.Name() } // DeleteInstanceOperation manages a long-running operation from DeleteInstance. type DeleteInstanceOperation struct { lro *longrunning.Operation } // DeleteInstanceOperation returns a new DeleteInstanceOperation from a given name. // The name must be that of a previously created DeleteInstanceOperation, possibly from a different process. func (c *CloudRedisClient) DeleteInstanceOperation(name string) *DeleteInstanceOperation { return &DeleteInstanceOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning any error encountered. // // See documentation of Poll for error-handling information. func (op *DeleteInstanceOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { return op.lro.WaitWithInterval(ctx, nil, 360000*time.Millisecond, opts...) } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, op.Done will return true. func (op *DeleteInstanceOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Poll(ctx, nil, opts...) } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *DeleteInstanceOperation) Metadata() (*anypb.Any, error) { var meta anypb.Any if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *DeleteInstanceOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *DeleteInstanceOperation) Name() string { return op.lro.Name() } // ExportInstanceOperation manages a long-running operation from ExportInstance. type ExportInstanceOperation struct { lro *longrunning.Operation } // ExportInstanceOperation returns a new ExportInstanceOperation from a given name. // The name must be that of a previously created ExportInstanceOperation, possibly from a different process. func (c *CloudRedisClient) ExportInstanceOperation(name string) *ExportInstanceOperation { return &ExportInstanceOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *ExportInstanceOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*redispb.Instance, error) { var resp redispb.Instance if err := op.lro.WaitWithInterval(ctx, &resp, 360000*time.Millisecond, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *ExportInstanceOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*redispb.Instance, error) { var resp redispb.Instance if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *ExportInstanceOperation) Metadata() (*anypb.Any, error) { var meta anypb.Any if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *ExportInstanceOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *ExportInstanceOperation) Name() string { return op.lro.Name() } // FailoverInstanceOperation manages a long-running operation from FailoverInstance. type FailoverInstanceOperation struct { lro *longrunning.Operation } // FailoverInstanceOperation returns a new FailoverInstanceOperation from a given name. // The name must be that of a previously created FailoverInstanceOperation, possibly from a different process. func (c *CloudRedisClient) FailoverInstanceOperation(name string) *FailoverInstanceOperation { return &FailoverInstanceOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *FailoverInstanceOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*redispb.Instance, error) { var resp redispb.Instance if err := op.lro.WaitWithInterval(ctx, &resp, 360000*time.Millisecond, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *FailoverInstanceOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*redispb.Instance, error) { var resp redispb.Instance if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *FailoverInstanceOperation) Metadata() (*anypb.Any, error) { var meta anypb.Any if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *FailoverInstanceOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *FailoverInstanceOperation) Name() string { return op.lro.Name() } // ImportInstanceOperation manages a long-running operation from ImportInstance. type ImportInstanceOperation struct { lro *longrunning.Operation } // ImportInstanceOperation returns a new ImportInstanceOperation from a given name. // The name must be that of a previously created ImportInstanceOperation, possibly from a different process. func (c *CloudRedisClient) ImportInstanceOperation(name string) *ImportInstanceOperation { return &ImportInstanceOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *ImportInstanceOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*redispb.Instance, error) { var resp redispb.Instance if err := op.lro.WaitWithInterval(ctx, &resp, 360000*time.Millisecond, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *ImportInstanceOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*redispb.Instance, error) { var resp redispb.Instance if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *ImportInstanceOperation) Metadata() (*anypb.Any, error) { var meta anypb.Any if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *ImportInstanceOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *ImportInstanceOperation) Name() string { return op.lro.Name() } // UpdateInstanceOperation manages a long-running operation from UpdateInstance. type UpdateInstanceOperation struct { lro *longrunning.Operation } // UpdateInstanceOperation returns a new UpdateInstanceOperation from a given name. // The name must be that of a previously created UpdateInstanceOperation, possibly from a different process. func (c *CloudRedisClient) UpdateInstanceOperation(name string) *UpdateInstanceOperation { return &UpdateInstanceOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *UpdateInstanceOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*redispb.Instance, error) { var resp redispb.Instance if err := op.lro.WaitWithInterval(ctx, &resp, 360000*time.Millisecond, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *UpdateInstanceOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*redispb.Instance, error) { var resp redispb.Instance if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *UpdateInstanceOperation) Metadata() (*anypb.Any, error) { var meta anypb.Any if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *UpdateInstanceOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *UpdateInstanceOperation) Name() string { return op.lro.Name() } google-cloud-go-0.49.0/redis/apiv1beta1/cloud_redis_client_example_test.go000066400000000000000000000104351356504100700265710ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package redis_test import ( "context" redis "cloud.google.com/go/redis/apiv1beta1" "google.golang.org/api/iterator" redispb "google.golang.org/genproto/googleapis/cloud/redis/v1beta1" ) func ExampleNewCloudRedisClient() { ctx := context.Background() c, err := redis.NewCloudRedisClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleCloudRedisClient_ListInstances() { ctx := context.Background() c, err := redis.NewCloudRedisClient(ctx) if err != nil { // TODO: Handle error. } req := &redispb.ListInstancesRequest{ // TODO: Fill request struct fields. } it := c.ListInstances(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleCloudRedisClient_GetInstance() { ctx := context.Background() c, err := redis.NewCloudRedisClient(ctx) if err != nil { // TODO: Handle error. } req := &redispb.GetInstanceRequest{ // TODO: Fill request struct fields. } resp, err := c.GetInstance(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleCloudRedisClient_CreateInstance() { ctx := context.Background() c, err := redis.NewCloudRedisClient(ctx) if err != nil { // TODO: Handle error. } req := &redispb.CreateInstanceRequest{ // TODO: Fill request struct fields. } op, err := c.CreateInstance(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleCloudRedisClient_UpdateInstance() { ctx := context.Background() c, err := redis.NewCloudRedisClient(ctx) if err != nil { // TODO: Handle error. } req := &redispb.UpdateInstanceRequest{ // TODO: Fill request struct fields. } op, err := c.UpdateInstance(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleCloudRedisClient_ImportInstance() { ctx := context.Background() c, err := redis.NewCloudRedisClient(ctx) if err != nil { // TODO: Handle error. } req := &redispb.ImportInstanceRequest{ // TODO: Fill request struct fields. } op, err := c.ImportInstance(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleCloudRedisClient_ExportInstance() { ctx := context.Background() c, err := redis.NewCloudRedisClient(ctx) if err != nil { // TODO: Handle error. } req := &redispb.ExportInstanceRequest{ // TODO: Fill request struct fields. } op, err := c.ExportInstance(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleCloudRedisClient_FailoverInstance() { ctx := context.Background() c, err := redis.NewCloudRedisClient(ctx) if err != nil { // TODO: Handle error. } req := &redispb.FailoverInstanceRequest{ // TODO: Fill request struct fields. } op, err := c.FailoverInstance(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleCloudRedisClient_DeleteInstance() { ctx := context.Background() c, err := redis.NewCloudRedisClient(ctx) if err != nil { // TODO: Handle error. } req := &redispb.DeleteInstanceRequest{ // TODO: Fill request struct fields. } op, err := c.DeleteInstance(ctx, req) if err != nil { // TODO: Handle error. } err = op.Wait(ctx) // TODO: Handle error. } google-cloud-go-0.49.0/redis/apiv1beta1/doc.go000066400000000000000000000053571356504100700207410ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package redis is an auto-generated package for the // Google Cloud Memorystore for Redis API. // // NOTE: This package is in beta. It is not stable, and may be subject to changes. // // Creates and manages Redis instances on the Google Cloud Platform. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package redis // import "cloud.google.com/go/redis/apiv1beta1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "UNKNOWN" google-cloud-go-0.49.0/redis/apiv1beta1/mock_test.go000066400000000000000000000742131356504100700221610ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package redis import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" "google.golang.org/api/option" redispb "google.golang.org/genproto/googleapis/cloud/redis/v1beta1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" field_maskpb "google.golang.org/genproto/protobuf/field_mask" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockCloudRedisServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. redispb.CloudRedisServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockCloudRedisServer) ListInstances(ctx context.Context, req *redispb.ListInstancesRequest) (*redispb.ListInstancesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*redispb.ListInstancesResponse), nil } func (s *mockCloudRedisServer) GetInstance(ctx context.Context, req *redispb.GetInstanceRequest) (*redispb.Instance, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*redispb.Instance), nil } func (s *mockCloudRedisServer) CreateInstance(ctx context.Context, req *redispb.CreateInstanceRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockCloudRedisServer) UpdateInstance(ctx context.Context, req *redispb.UpdateInstanceRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockCloudRedisServer) ImportInstance(ctx context.Context, req *redispb.ImportInstanceRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockCloudRedisServer) ExportInstance(ctx context.Context, req *redispb.ExportInstanceRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockCloudRedisServer) FailoverInstance(ctx context.Context, req *redispb.FailoverInstanceRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockCloudRedisServer) DeleteInstance(ctx context.Context, req *redispb.DeleteInstanceRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockCloudRedis mockCloudRedisServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() redispb.RegisterCloudRedisServer(serv, &mockCloudRedis) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestCloudRedisListInstances(t *testing.T) { var nextPageToken string = "" var instancesElement *redispb.Instance = &redispb.Instance{} var instances = []*redispb.Instance{instancesElement} var expectedResponse = &redispb.ListInstancesResponse{ NextPageToken: nextPageToken, Instances: instances, } mockCloudRedis.err = nil mockCloudRedis.reqs = nil mockCloudRedis.resps = append(mockCloudRedis.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &redispb.ListInstancesRequest{ Parent: formattedParent, } c, err := NewCloudRedisClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListInstances(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockCloudRedis.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Instances[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudRedisListInstancesError(t *testing.T) { errCode := codes.PermissionDenied mockCloudRedis.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &redispb.ListInstancesRequest{ Parent: formattedParent, } c, err := NewCloudRedisClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListInstances(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudRedisGetInstance(t *testing.T) { var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var locationId string = "locationId552319461" var alternativeLocationId string = "alternativeLocationId-718920621" var redisVersion string = "redisVersion-685310444" var reservedIpRange string = "reservedIpRange-1082940580" var host string = "host3208616" var port int32 = 3446913 var currentLocationId string = "currentLocationId1312712735" var statusMessage string = "statusMessage-239442758" var memorySizeGb int32 = 34199707 var authorizedNetwork string = "authorizedNetwork-1733809270" var persistenceIamIdentity string = "persistenceIamIdentity1061944584" var expectedResponse = &redispb.Instance{ Name: name2, DisplayName: displayName, LocationId: locationId, AlternativeLocationId: alternativeLocationId, RedisVersion: redisVersion, ReservedIpRange: reservedIpRange, Host: host, Port: port, CurrentLocationId: currentLocationId, StatusMessage: statusMessage, MemorySizeGb: memorySizeGb, AuthorizedNetwork: authorizedNetwork, PersistenceIamIdentity: persistenceIamIdentity, } mockCloudRedis.err = nil mockCloudRedis.reqs = nil mockCloudRedis.resps = append(mockCloudRedis.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/instances/%s", "[PROJECT]", "[LOCATION]", "[INSTANCE]") var request = &redispb.GetInstanceRequest{ Name: formattedName, } c, err := NewCloudRedisClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetInstance(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudRedis.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudRedisGetInstanceError(t *testing.T) { errCode := codes.PermissionDenied mockCloudRedis.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/instances/%s", "[PROJECT]", "[LOCATION]", "[INSTANCE]") var request = &redispb.GetInstanceRequest{ Name: formattedName, } c, err := NewCloudRedisClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetInstance(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudRedisCreateInstance(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var locationId string = "locationId552319461" var alternativeLocationId string = "alternativeLocationId-718920621" var redisVersion string = "redisVersion-685310444" var reservedIpRange string = "reservedIpRange-1082940580" var host string = "host3208616" var port int32 = 3446913 var currentLocationId string = "currentLocationId1312712735" var statusMessage string = "statusMessage-239442758" var memorySizeGb2 int32 = 1493816946 var authorizedNetwork string = "authorizedNetwork-1733809270" var persistenceIamIdentity string = "persistenceIamIdentity1061944584" var expectedResponse = &redispb.Instance{ Name: name, DisplayName: displayName, LocationId: locationId, AlternativeLocationId: alternativeLocationId, RedisVersion: redisVersion, ReservedIpRange: reservedIpRange, Host: host, Port: port, CurrentLocationId: currentLocationId, StatusMessage: statusMessage, MemorySizeGb: memorySizeGb2, AuthorizedNetwork: authorizedNetwork, PersistenceIamIdentity: persistenceIamIdentity, } mockCloudRedis.err = nil mockCloudRedis.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockCloudRedis.resps = append(mockCloudRedis.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var instanceId string = "test_instance" var tier redispb.Instance_Tier = redispb.Instance_BASIC var memorySizeGb int32 = 1 var instance = &redispb.Instance{ Tier: tier, MemorySizeGb: memorySizeGb, } var request = &redispb.CreateInstanceRequest{ Parent: formattedParent, InstanceId: instanceId, Instance: instance, } c, err := NewCloudRedisClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.CreateInstance(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockCloudRedis.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudRedisCreateInstanceError(t *testing.T) { errCode := codes.PermissionDenied mockCloudRedis.err = nil mockCloudRedis.resps = append(mockCloudRedis.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var instanceId string = "test_instance" var tier redispb.Instance_Tier = redispb.Instance_BASIC var memorySizeGb int32 = 1 var instance = &redispb.Instance{ Tier: tier, MemorySizeGb: memorySizeGb, } var request = &redispb.CreateInstanceRequest{ Parent: formattedParent, InstanceId: instanceId, Instance: instance, } c, err := NewCloudRedisClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.CreateInstance(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudRedisUpdateInstance(t *testing.T) { var name string = "name3373707" var displayName2 string = "displayName21615000987" var locationId string = "locationId552319461" var alternativeLocationId string = "alternativeLocationId-718920621" var redisVersion string = "redisVersion-685310444" var reservedIpRange string = "reservedIpRange-1082940580" var host string = "host3208616" var port int32 = 3446913 var currentLocationId string = "currentLocationId1312712735" var statusMessage string = "statusMessage-239442758" var memorySizeGb2 int32 = 1493816946 var authorizedNetwork string = "authorizedNetwork-1733809270" var persistenceIamIdentity string = "persistenceIamIdentity1061944584" var expectedResponse = &redispb.Instance{ Name: name, DisplayName: displayName2, LocationId: locationId, AlternativeLocationId: alternativeLocationId, RedisVersion: redisVersion, ReservedIpRange: reservedIpRange, Host: host, Port: port, CurrentLocationId: currentLocationId, StatusMessage: statusMessage, MemorySizeGb: memorySizeGb2, AuthorizedNetwork: authorizedNetwork, PersistenceIamIdentity: persistenceIamIdentity, } mockCloudRedis.err = nil mockCloudRedis.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockCloudRedis.resps = append(mockCloudRedis.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var pathsElement string = "display_name" var pathsElement2 string = "memory_size_gb" var paths = []string{pathsElement, pathsElement2} var updateMask = &field_maskpb.FieldMask{ Paths: paths, } var displayName string = "UpdatedDisplayName" var memorySizeGb int32 = 4 var instance = &redispb.Instance{ DisplayName: displayName, MemorySizeGb: memorySizeGb, } var request = &redispb.UpdateInstanceRequest{ UpdateMask: updateMask, Instance: instance, } c, err := NewCloudRedisClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.UpdateInstance(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockCloudRedis.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudRedisUpdateInstanceError(t *testing.T) { errCode := codes.PermissionDenied mockCloudRedis.err = nil mockCloudRedis.resps = append(mockCloudRedis.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var pathsElement string = "display_name" var pathsElement2 string = "memory_size_gb" var paths = []string{pathsElement, pathsElement2} var updateMask = &field_maskpb.FieldMask{ Paths: paths, } var displayName string = "UpdatedDisplayName" var memorySizeGb int32 = 4 var instance = &redispb.Instance{ DisplayName: displayName, MemorySizeGb: memorySizeGb, } var request = &redispb.UpdateInstanceRequest{ UpdateMask: updateMask, Instance: instance, } c, err := NewCloudRedisClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.UpdateInstance(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudRedisImportInstance(t *testing.T) { var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var locationId string = "locationId552319461" var alternativeLocationId string = "alternativeLocationId-718920621" var redisVersion string = "redisVersion-685310444" var reservedIpRange string = "reservedIpRange-1082940580" var host string = "host3208616" var port int32 = 3446913 var currentLocationId string = "currentLocationId1312712735" var statusMessage string = "statusMessage-239442758" var memorySizeGb int32 = 34199707 var authorizedNetwork string = "authorizedNetwork-1733809270" var persistenceIamIdentity string = "persistenceIamIdentity1061944584" var expectedResponse = &redispb.Instance{ Name: name2, DisplayName: displayName, LocationId: locationId, AlternativeLocationId: alternativeLocationId, RedisVersion: redisVersion, ReservedIpRange: reservedIpRange, Host: host, Port: port, CurrentLocationId: currentLocationId, StatusMessage: statusMessage, MemorySizeGb: memorySizeGb, AuthorizedNetwork: authorizedNetwork, PersistenceIamIdentity: persistenceIamIdentity, } mockCloudRedis.err = nil mockCloudRedis.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockCloudRedis.resps = append(mockCloudRedis.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var name string = "name3373707" var inputConfig *redispb.InputConfig = &redispb.InputConfig{} var request = &redispb.ImportInstanceRequest{ Name: name, InputConfig: inputConfig, } c, err := NewCloudRedisClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.ImportInstance(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockCloudRedis.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudRedisImportInstanceError(t *testing.T) { errCode := codes.PermissionDenied mockCloudRedis.err = nil mockCloudRedis.resps = append(mockCloudRedis.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var name string = "name3373707" var inputConfig *redispb.InputConfig = &redispb.InputConfig{} var request = &redispb.ImportInstanceRequest{ Name: name, InputConfig: inputConfig, } c, err := NewCloudRedisClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.ImportInstance(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudRedisExportInstance(t *testing.T) { var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var locationId string = "locationId552319461" var alternativeLocationId string = "alternativeLocationId-718920621" var redisVersion string = "redisVersion-685310444" var reservedIpRange string = "reservedIpRange-1082940580" var host string = "host3208616" var port int32 = 3446913 var currentLocationId string = "currentLocationId1312712735" var statusMessage string = "statusMessage-239442758" var memorySizeGb int32 = 34199707 var authorizedNetwork string = "authorizedNetwork-1733809270" var persistenceIamIdentity string = "persistenceIamIdentity1061944584" var expectedResponse = &redispb.Instance{ Name: name2, DisplayName: displayName, LocationId: locationId, AlternativeLocationId: alternativeLocationId, RedisVersion: redisVersion, ReservedIpRange: reservedIpRange, Host: host, Port: port, CurrentLocationId: currentLocationId, StatusMessage: statusMessage, MemorySizeGb: memorySizeGb, AuthorizedNetwork: authorizedNetwork, PersistenceIamIdentity: persistenceIamIdentity, } mockCloudRedis.err = nil mockCloudRedis.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockCloudRedis.resps = append(mockCloudRedis.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var name string = "name3373707" var outputConfig *redispb.OutputConfig = &redispb.OutputConfig{} var request = &redispb.ExportInstanceRequest{ Name: name, OutputConfig: outputConfig, } c, err := NewCloudRedisClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.ExportInstance(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockCloudRedis.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudRedisExportInstanceError(t *testing.T) { errCode := codes.PermissionDenied mockCloudRedis.err = nil mockCloudRedis.resps = append(mockCloudRedis.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var name string = "name3373707" var outputConfig *redispb.OutputConfig = &redispb.OutputConfig{} var request = &redispb.ExportInstanceRequest{ Name: name, OutputConfig: outputConfig, } c, err := NewCloudRedisClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.ExportInstance(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudRedisFailoverInstance(t *testing.T) { var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var locationId string = "locationId552319461" var alternativeLocationId string = "alternativeLocationId-718920621" var redisVersion string = "redisVersion-685310444" var reservedIpRange string = "reservedIpRange-1082940580" var host string = "host3208616" var port int32 = 3446913 var currentLocationId string = "currentLocationId1312712735" var statusMessage string = "statusMessage-239442758" var memorySizeGb int32 = 34199707 var authorizedNetwork string = "authorizedNetwork-1733809270" var persistenceIamIdentity string = "persistenceIamIdentity1061944584" var expectedResponse = &redispb.Instance{ Name: name2, DisplayName: displayName, LocationId: locationId, AlternativeLocationId: alternativeLocationId, RedisVersion: redisVersion, ReservedIpRange: reservedIpRange, Host: host, Port: port, CurrentLocationId: currentLocationId, StatusMessage: statusMessage, MemorySizeGb: memorySizeGb, AuthorizedNetwork: authorizedNetwork, PersistenceIamIdentity: persistenceIamIdentity, } mockCloudRedis.err = nil mockCloudRedis.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockCloudRedis.resps = append(mockCloudRedis.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/instances/%s", "[PROJECT]", "[LOCATION]", "[INSTANCE]") var request = &redispb.FailoverInstanceRequest{ Name: formattedName, } c, err := NewCloudRedisClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.FailoverInstance(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockCloudRedis.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudRedisFailoverInstanceError(t *testing.T) { errCode := codes.PermissionDenied mockCloudRedis.err = nil mockCloudRedis.resps = append(mockCloudRedis.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/instances/%s", "[PROJECT]", "[LOCATION]", "[INSTANCE]") var request = &redispb.FailoverInstanceRequest{ Name: formattedName, } c, err := NewCloudRedisClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.FailoverInstance(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudRedisDeleteInstance(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockCloudRedis.err = nil mockCloudRedis.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockCloudRedis.resps = append(mockCloudRedis.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/instances/%s", "[PROJECT]", "[LOCATION]", "[INSTANCE]") var request = &redispb.DeleteInstanceRequest{ Name: formattedName, } c, err := NewCloudRedisClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.DeleteInstance(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockCloudRedis.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestCloudRedisDeleteInstanceError(t *testing.T) { errCode := codes.PermissionDenied mockCloudRedis.err = nil mockCloudRedis.resps = append(mockCloudRedis.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/instances/%s", "[PROJECT]", "[LOCATION]", "[INSTANCE]") var request = &redispb.DeleteInstanceRequest{ Name: formattedName, } c, err := NewCloudRedisClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.DeleteInstance(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } google-cloud-go-0.49.0/regen-gapic.sh000077500000000000000000000053641356504100700173200ustar00rootroot00000000000000#!/bin/bash # Copyright 2019 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # This script generates all GAPIC clients in this repo. # See instructions at go/yoshi-site. set -ex GOCLOUD_DIR="$(dirname "$0")" HOST_MOUNT="$PWD" # need to mount the /var/folders properly for macos # https://stackoverflow.com/questions/45122459/docker-mounts-denied-the-paths-are-not-shared-from-os-x-and-are-not-known/45123074 if [[ "$OSTYPE" == "darwin"* ]] && [[ "$HOST_MOUNT" == "/var/folders"* ]]; then HOST_MOUNT=/private$HOST_MOUNT fi microgen() { input=$1 options="${@:2}" # see https://github.com/googleapis/gapic-generator-go/blob/master/README.md#docker-wrapper for details docker run \ --user $UID \ --mount type=bind,source=$HOST_MOUNT,destination=/conf,readonly \ --mount type=bind,source=$HOST_MOUNT/$input,destination=/in/$input,readonly \ --mount type=bind,source=/tmp,destination=/out \ --rm \ gcr.io/gapic-images/gapic-generator-go:0.9.1 \ $options } for gencfg in $(cat $GOCLOUD_DIR/gapics.txt); do rm -rf artman-genfiles/* artman --config "$gencfg" generate go_gapic cp -r artman-genfiles/gapi-*/cloud.google.com/go/* $GOCLOUD_DIR done rm -rf /tmp/cloud.google.com { # skip the first line with column titles read -r while IFS=, read -r input mod retrycfg apicfg release do microgen $input "$mod" "$retrycfg" "$apicfg" "$release" done } < $GOCLOUD_DIR/microgens.csv # copy generated code if any was created [ -d "/tmp/cloud.google.com/go" ] && cp -r /tmp/cloud.google.com/go/* $GOCLOUD_DIR pushd $GOCLOUD_DIR gofmt -s -d -l -w . && goimports -w . # NOTE(pongad): `sed -i` doesn't work on Macs, because -i option needs an argument. # `-i ''` doesn't work on GNU, since the empty string is treated as a file name. # So we just create the backup and delete it after. ver=$(date +%Y%m%d) git ls-files -mo | while read modified; do dir=${modified%/*.*} find . -path "*/$dir/doc.go" -exec sed -i.backup -e "s/^const versionClient.*/const versionClient = \"$ver\"/" '{}' + done popd for manualdir in $(cat $GOCLOUD_DIR/manuals.txt); do find "$GOCLOUD_DIR/$manualdir" -name '*.go' -exec sed -i.backup -e 's/setGoogleClientInfo/SetGoogleClientInfo/g' '{}' '+' done find $GOCLOUD_DIR -name '*.backup' -delete google-cloud-go-0.49.0/rpcreplay/000077500000000000000000000000001356504100700165715ustar00rootroot00000000000000google-cloud-go-0.49.0/rpcreplay/Makefile000066400000000000000000000020431356504100700202300ustar00rootroot00000000000000# Copyright 2017 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Makefile for building Go files from protos. # Change these to match your environment. PROTOC=$(HOME)/bin/protoc PROTOC_GO_PLUGIN_DIR=$(GOPATH)/bin # The repo github.com/google/protobuf. PROTOBUF_REPO=$(HOME)/git-repos/google/protobuf gen-protos: sync-protobuf for d in proto/*; do \ PATH=$(PATH):$(PROTOC_GO_PLUGIN_DIR) \ $(PROTOC) --go_out=plugins=grpc:$$d \ -I $$d -I $(PROTOBUF_REPO)/src $$d/*.proto; \ done sync-protobuf: cd $(PROTOBUF_REPO); git pull google-cloud-go-0.49.0/rpcreplay/doc.go000066400000000000000000000132601356504100700176670ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. /* Package rpcreplay supports the capture and replay of gRPC calls. Its main goal is to improve testing. Once you capture the calls of a test that runs against a real service, you have an "automatic mock" that can be replayed against the same test, yielding a unit test that is fast and flake-free. This package is EXPERIMENTAL and subject to change without notice. Recording To record a sequence of gRPC calls to a file, create a Recorder and pass its DialOptions to grpc.Dial: rec, err := rpcreplay.NewRecorder("service.replay", nil) if err != nil { ... } defer func() { if err := rec.Close(); err != nil { ... } }() conn, err := grpc.Dial(serverAddress, rec.DialOptions()...) It is essential to close the Recorder when the interaction is finished. There is also a NewRecorderWriter function for capturing to an arbitrary io.Writer. Replaying Replaying a captured file looks almost identical: create a Replayer and use its DialOptions. (Since we're reading the file and not writing it, we don't have to be as careful about the error returned from Close). rep, err := rpcreplay.NewReplayer("service.replay") if err != nil { ... } defer rep.Close() conn, err := grpc.Dial(serverAddress, rep.DialOptions()...) Since a real connection isn't necessary for replay, you can get a fake one from the replayer instead of calling grpc.Dial: rep, err := rpcreplay.NewReplayer("service.replay") if err != nil { ... } defer rep.Close() conn, err := rep.Connection() Initial State A test might use random or time-sensitive values, for instance to create unique resources for isolation from other tests. The test therefore has initial values, such as the current time, or a random seed, that differ from run to run. You must record this initial state and re-establish it on replay. To record the initial state, serialize it into a []byte and pass it as the second argument to NewRecorder: timeNow := time.Now() b, err := timeNow.MarshalBinary() if err != nil { ... } rec, err := rpcreplay.NewRecorder("service.replay", b) On replay, get the bytes from Replayer.Initial: rep, err := rpcreplay.NewReplayer("service.replay") if err != nil { ... } defer rep.Close() err = timeNow.UnmarshalBinary(rep.Initial()) if err != nil { ... } Callbacks Recorders and replayers have support for running callbacks before messages are written to or read from the replay file. A Recorder has a BeforeFunc that can modify a request or response before it is written to the replay file. The actual RPCs sent to the service during recording remain unaltered; only what is saved in the replay file can be changed. A Replayer has a BeforeFunc that can modify a request before it is sent for matching. Example uses for these callbacks include customized logging, or scrubbing data before RPCs are written to the replay file. If requests are modified by the callbacks during recording, it is important to perform the same modifications to the requests when replaying, or RPC matching on replay will fail. A common way to analyze and modify the various messages is to use a type switch. // Assume these types implement proto.Message. type Greeting struct { line string } type Farewell struct { line string } func sayings(method string, msg proto.Message) error { switch m := msg.(type) { case Greeting: msg.line = "Hi!" return nil case Farewell: msg.line = "Bye bye!" return nil default: return fmt.Errorf("unknown message type") } } Nondeterminism A nondeterministic program may invoke RPCs in a different order each time it is run. The order in which RPCs are called during recording may differ from the order during replay. The replayer matches incoming to recorded requests by method name and request contents, so nondeterminism is only a concern for identical requests that result in different responses. A nondeterministic program whose behavior differs depending on the order of such RPCs probably has a race condition: since both the recorded sequence of RPCs and the sequence during replay are valid orderings, the program should behave the same under both. The same is not true of streaming RPCs. The replayer matches streams only by method name, since it has no other information at the time the stream is opened. Two streams with the same method name that are started concurrently may replay in the wrong order. Other Replayer Differences Besides the differences in replay mentioned above, other differences may cause issues for some programs. We list them here. The Replayer delivers a response to an RPC immediately, without waiting for other incoming RPCs. This can violate causality. For example, in a Pub/Sub program where one goroutine publishes and another subscribes, during replay the Subscribe call may finish before the Publish call begins. For streaming RPCs, the Replayer delivers the result of Send and Recv calls in the order they were recorded. No attempt is made to match message contents. At present, this package does not record or replay stream headers and trailers, or the result of the CloseSend method. */ package rpcreplay // import "cloud.google.com/go/rpcreplay" google-cloud-go-0.49.0/rpcreplay/example_test.go000066400000000000000000000025221356504100700216130ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package rpcreplay_test import ( "cloud.google.com/go/rpcreplay" "google.golang.org/grpc" ) var serverAddress string func Example_NewRecorder() { rec, err := rpcreplay.NewRecorder("service.replay", nil) if err != nil { // TODO: Handle error. } defer func() { if err := rec.Close(); err != nil { // TODO: Handle error. } }() conn, err := grpc.Dial(serverAddress, rec.DialOptions()...) if err != nil { // TODO: Handle error. } _ = conn // TODO: use connection } func Example_NewReplayer() { rep, err := rpcreplay.NewReplayer("service.replay") if err != nil { // TODO: Handle error. } defer rep.Close() conn, err := grpc.Dial(serverAddress, rep.DialOptions()...) if err != nil { // TODO: Handle error. } _ = conn // TODO: use connection } google-cloud-go-0.49.0/rpcreplay/fake_test.go000066400000000000000000000052461356504100700210740ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package rpcreplay import ( "context" "io" "log" "net" pb "cloud.google.com/go/rpcreplay/proto/intstore" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) // intStoreServer is an in-memory implementation of IntStore. type intStoreServer struct { pb.IntStoreServer Addr string l net.Listener gsrv *grpc.Server items map[string]int32 } func newIntStoreServer() *intStoreServer { l, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } s := &intStoreServer{ Addr: l.Addr().String(), l: l, gsrv: grpc.NewServer(), } pb.RegisterIntStoreServer(s.gsrv, s) go s.gsrv.Serve(s.l) return s } func (s *intStoreServer) stop() { s.gsrv.Stop() s.l.Close() } func (s *intStoreServer) Set(_ context.Context, item *pb.Item) (*pb.SetResponse, error) { old := s.setItem(item) return &pb.SetResponse{PrevValue: old}, nil } func (s *intStoreServer) setItem(item *pb.Item) int32 { if s.items == nil { s.items = map[string]int32{} } old := s.items[item.Name] s.items[item.Name] = item.Value return old } func (s *intStoreServer) Get(_ context.Context, req *pb.GetRequest) (*pb.Item, error) { val, ok := s.items[req.Name] if !ok { return nil, status.Errorf(codes.NotFound, "%q", req.Name) } return &pb.Item{Name: req.Name, Value: val}, nil } func (s *intStoreServer) ListItems(req *pb.ListItemsRequest, ss pb.IntStore_ListItemsServer) error { for name, val := range s.items { if val > req.GreaterThan { if err := ss.Send(&pb.Item{Name: name, Value: val}); err != nil { return err } } } return nil } func (s *intStoreServer) SetStream(ss pb.IntStore_SetStreamServer) error { n := 0 for { item, err := ss.Recv() if err == io.EOF { break } if err != nil { return err } s.setItem(item) n++ } return ss.SendAndClose(&pb.Summary{Count: int32(n)}) } func (s *intStoreServer) StreamChat(ss pb.IntStore_StreamChatServer) error { for { item, err := ss.Recv() if err == io.EOF { break } if err != nil { return err } if err := ss.Send(item); err != nil { return err } } return nil } google-cloud-go-0.49.0/rpcreplay/proto/000077500000000000000000000000001356504100700177345ustar00rootroot00000000000000google-cloud-go-0.49.0/rpcreplay/proto/intstore/000077500000000000000000000000001356504100700216035ustar00rootroot00000000000000google-cloud-go-0.49.0/rpcreplay/proto/intstore/intstore.pb.go000066400000000000000000000421601356504100700244040ustar00rootroot00000000000000// Code generated by protoc-gen-go. DO NOT EDIT. // source: intstore.proto package intstore import ( fmt "fmt" proto "github.com/golang/protobuf/proto" math "math" context "golang.org/x/net/context" grpc "google.golang.org/grpc" ) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal var _ = fmt.Errorf var _ = math.Inf // This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package type Item struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` Value int32 `protobuf:"varint,2,opt,name=value,proto3" json:"value,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *Item) Reset() { *m = Item{} } func (m *Item) String() string { return proto.CompactTextString(m) } func (*Item) ProtoMessage() {} func (*Item) Descriptor() ([]byte, []int) { return fileDescriptor_intstore_10c1c94979d47ae6, []int{0} } func (m *Item) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Item.Unmarshal(m, b) } func (m *Item) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Item.Marshal(b, m, deterministic) } func (dst *Item) XXX_Merge(src proto.Message) { xxx_messageInfo_Item.Merge(dst, src) } func (m *Item) XXX_Size() int { return xxx_messageInfo_Item.Size(m) } func (m *Item) XXX_DiscardUnknown() { xxx_messageInfo_Item.DiscardUnknown(m) } var xxx_messageInfo_Item proto.InternalMessageInfo func (m *Item) GetName() string { if m != nil { return m.Name } return "" } func (m *Item) GetValue() int32 { if m != nil { return m.Value } return 0 } type SetResponse struct { PrevValue int32 `protobuf:"varint,1,opt,name=prev_value,json=prevValue,proto3" json:"prev_value,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *SetResponse) Reset() { *m = SetResponse{} } func (m *SetResponse) String() string { return proto.CompactTextString(m) } func (*SetResponse) ProtoMessage() {} func (*SetResponse) Descriptor() ([]byte, []int) { return fileDescriptor_intstore_10c1c94979d47ae6, []int{1} } func (m *SetResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetResponse.Unmarshal(m, b) } func (m *SetResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SetResponse.Marshal(b, m, deterministic) } func (dst *SetResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_SetResponse.Merge(dst, src) } func (m *SetResponse) XXX_Size() int { return xxx_messageInfo_SetResponse.Size(m) } func (m *SetResponse) XXX_DiscardUnknown() { xxx_messageInfo_SetResponse.DiscardUnknown(m) } var xxx_messageInfo_SetResponse proto.InternalMessageInfo func (m *SetResponse) GetPrevValue() int32 { if m != nil { return m.PrevValue } return 0 } type GetRequest struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *GetRequest) Reset() { *m = GetRequest{} } func (m *GetRequest) String() string { return proto.CompactTextString(m) } func (*GetRequest) ProtoMessage() {} func (*GetRequest) Descriptor() ([]byte, []int) { return fileDescriptor_intstore_10c1c94979d47ae6, []int{2} } func (m *GetRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetRequest.Unmarshal(m, b) } func (m *GetRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_GetRequest.Marshal(b, m, deterministic) } func (dst *GetRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_GetRequest.Merge(dst, src) } func (m *GetRequest) XXX_Size() int { return xxx_messageInfo_GetRequest.Size(m) } func (m *GetRequest) XXX_DiscardUnknown() { xxx_messageInfo_GetRequest.DiscardUnknown(m) } var xxx_messageInfo_GetRequest proto.InternalMessageInfo func (m *GetRequest) GetName() string { if m != nil { return m.Name } return "" } type Summary struct { Count int32 `protobuf:"varint,1,opt,name=count,proto3" json:"count,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *Summary) Reset() { *m = Summary{} } func (m *Summary) String() string { return proto.CompactTextString(m) } func (*Summary) ProtoMessage() {} func (*Summary) Descriptor() ([]byte, []int) { return fileDescriptor_intstore_10c1c94979d47ae6, []int{3} } func (m *Summary) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Summary.Unmarshal(m, b) } func (m *Summary) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Summary.Marshal(b, m, deterministic) } func (dst *Summary) XXX_Merge(src proto.Message) { xxx_messageInfo_Summary.Merge(dst, src) } func (m *Summary) XXX_Size() int { return xxx_messageInfo_Summary.Size(m) } func (m *Summary) XXX_DiscardUnknown() { xxx_messageInfo_Summary.DiscardUnknown(m) } var xxx_messageInfo_Summary proto.InternalMessageInfo func (m *Summary) GetCount() int32 { if m != nil { return m.Count } return 0 } type ListItemsRequest struct { GreaterThan int32 `protobuf:"varint,1,opt,name=greaterThan,proto3" json:"greaterThan,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *ListItemsRequest) Reset() { *m = ListItemsRequest{} } func (m *ListItemsRequest) String() string { return proto.CompactTextString(m) } func (*ListItemsRequest) ProtoMessage() {} func (*ListItemsRequest) Descriptor() ([]byte, []int) { return fileDescriptor_intstore_10c1c94979d47ae6, []int{4} } func (m *ListItemsRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ListItemsRequest.Unmarshal(m, b) } func (m *ListItemsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ListItemsRequest.Marshal(b, m, deterministic) } func (dst *ListItemsRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_ListItemsRequest.Merge(dst, src) } func (m *ListItemsRequest) XXX_Size() int { return xxx_messageInfo_ListItemsRequest.Size(m) } func (m *ListItemsRequest) XXX_DiscardUnknown() { xxx_messageInfo_ListItemsRequest.DiscardUnknown(m) } var xxx_messageInfo_ListItemsRequest proto.InternalMessageInfo func (m *ListItemsRequest) GetGreaterThan() int32 { if m != nil { return m.GreaterThan } return 0 } func init() { proto.RegisterType((*Item)(nil), "intstore.Item") proto.RegisterType((*SetResponse)(nil), "intstore.SetResponse") proto.RegisterType((*GetRequest)(nil), "intstore.GetRequest") proto.RegisterType((*Summary)(nil), "intstore.Summary") proto.RegisterType((*ListItemsRequest)(nil), "intstore.ListItemsRequest") } // Reference imports to suppress errors if they are not otherwise used. var _ context.Context var _ grpc.ClientConn // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. const _ = grpc.SupportPackageIsVersion4 // IntStoreClient is the client API for IntStore service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type IntStoreClient interface { Set(ctx context.Context, in *Item, opts ...grpc.CallOption) (*SetResponse, error) Get(ctx context.Context, in *GetRequest, opts ...grpc.CallOption) (*Item, error) // A server-to-client streaming RPC. ListItems(ctx context.Context, in *ListItemsRequest, opts ...grpc.CallOption) (IntStore_ListItemsClient, error) // A client-to-server streaming RPC. SetStream(ctx context.Context, opts ...grpc.CallOption) (IntStore_SetStreamClient, error) // A Bidirectional streaming RPC. StreamChat(ctx context.Context, opts ...grpc.CallOption) (IntStore_StreamChatClient, error) } type intStoreClient struct { cc *grpc.ClientConn } func NewIntStoreClient(cc *grpc.ClientConn) IntStoreClient { return &intStoreClient{cc} } func (c *intStoreClient) Set(ctx context.Context, in *Item, opts ...grpc.CallOption) (*SetResponse, error) { out := new(SetResponse) err := c.cc.Invoke(ctx, "/intstore.IntStore/Set", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *intStoreClient) Get(ctx context.Context, in *GetRequest, opts ...grpc.CallOption) (*Item, error) { out := new(Item) err := c.cc.Invoke(ctx, "/intstore.IntStore/Get", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *intStoreClient) ListItems(ctx context.Context, in *ListItemsRequest, opts ...grpc.CallOption) (IntStore_ListItemsClient, error) { stream, err := c.cc.NewStream(ctx, &_IntStore_serviceDesc.Streams[0], "/intstore.IntStore/ListItems", opts...) if err != nil { return nil, err } x := &intStoreListItemsClient{stream} if err := x.ClientStream.SendMsg(in); err != nil { return nil, err } if err := x.ClientStream.CloseSend(); err != nil { return nil, err } return x, nil } type IntStore_ListItemsClient interface { Recv() (*Item, error) grpc.ClientStream } type intStoreListItemsClient struct { grpc.ClientStream } func (x *intStoreListItemsClient) Recv() (*Item, error) { m := new(Item) if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err } return m, nil } func (c *intStoreClient) SetStream(ctx context.Context, opts ...grpc.CallOption) (IntStore_SetStreamClient, error) { stream, err := c.cc.NewStream(ctx, &_IntStore_serviceDesc.Streams[1], "/intstore.IntStore/SetStream", opts...) if err != nil { return nil, err } x := &intStoreSetStreamClient{stream} return x, nil } type IntStore_SetStreamClient interface { Send(*Item) error CloseAndRecv() (*Summary, error) grpc.ClientStream } type intStoreSetStreamClient struct { grpc.ClientStream } func (x *intStoreSetStreamClient) Send(m *Item) error { return x.ClientStream.SendMsg(m) } func (x *intStoreSetStreamClient) CloseAndRecv() (*Summary, error) { if err := x.ClientStream.CloseSend(); err != nil { return nil, err } m := new(Summary) if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err } return m, nil } func (c *intStoreClient) StreamChat(ctx context.Context, opts ...grpc.CallOption) (IntStore_StreamChatClient, error) { stream, err := c.cc.NewStream(ctx, &_IntStore_serviceDesc.Streams[2], "/intstore.IntStore/StreamChat", opts...) if err != nil { return nil, err } x := &intStoreStreamChatClient{stream} return x, nil } type IntStore_StreamChatClient interface { Send(*Item) error Recv() (*Item, error) grpc.ClientStream } type intStoreStreamChatClient struct { grpc.ClientStream } func (x *intStoreStreamChatClient) Send(m *Item) error { return x.ClientStream.SendMsg(m) } func (x *intStoreStreamChatClient) Recv() (*Item, error) { m := new(Item) if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err } return m, nil } // IntStoreServer is the server API for IntStore service. type IntStoreServer interface { Set(context.Context, *Item) (*SetResponse, error) Get(context.Context, *GetRequest) (*Item, error) // A server-to-client streaming RPC. ListItems(*ListItemsRequest, IntStore_ListItemsServer) error // A client-to-server streaming RPC. SetStream(IntStore_SetStreamServer) error // A Bidirectional streaming RPC. StreamChat(IntStore_StreamChatServer) error } func RegisterIntStoreServer(s *grpc.Server, srv IntStoreServer) { s.RegisterService(&_IntStore_serviceDesc, srv) } func _IntStore_Set_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(Item) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(IntStoreServer).Set(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/intstore.IntStore/Set", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(IntStoreServer).Set(ctx, req.(*Item)) } return interceptor(ctx, in, info, handler) } func _IntStore_Get_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(GetRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(IntStoreServer).Get(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/intstore.IntStore/Get", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(IntStoreServer).Get(ctx, req.(*GetRequest)) } return interceptor(ctx, in, info, handler) } func _IntStore_ListItems_Handler(srv interface{}, stream grpc.ServerStream) error { m := new(ListItemsRequest) if err := stream.RecvMsg(m); err != nil { return err } return srv.(IntStoreServer).ListItems(m, &intStoreListItemsServer{stream}) } type IntStore_ListItemsServer interface { Send(*Item) error grpc.ServerStream } type intStoreListItemsServer struct { grpc.ServerStream } func (x *intStoreListItemsServer) Send(m *Item) error { return x.ServerStream.SendMsg(m) } func _IntStore_SetStream_Handler(srv interface{}, stream grpc.ServerStream) error { return srv.(IntStoreServer).SetStream(&intStoreSetStreamServer{stream}) } type IntStore_SetStreamServer interface { SendAndClose(*Summary) error Recv() (*Item, error) grpc.ServerStream } type intStoreSetStreamServer struct { grpc.ServerStream } func (x *intStoreSetStreamServer) SendAndClose(m *Summary) error { return x.ServerStream.SendMsg(m) } func (x *intStoreSetStreamServer) Recv() (*Item, error) { m := new(Item) if err := x.ServerStream.RecvMsg(m); err != nil { return nil, err } return m, nil } func _IntStore_StreamChat_Handler(srv interface{}, stream grpc.ServerStream) error { return srv.(IntStoreServer).StreamChat(&intStoreStreamChatServer{stream}) } type IntStore_StreamChatServer interface { Send(*Item) error Recv() (*Item, error) grpc.ServerStream } type intStoreStreamChatServer struct { grpc.ServerStream } func (x *intStoreStreamChatServer) Send(m *Item) error { return x.ServerStream.SendMsg(m) } func (x *intStoreStreamChatServer) Recv() (*Item, error) { m := new(Item) if err := x.ServerStream.RecvMsg(m); err != nil { return nil, err } return m, nil } var _IntStore_serviceDesc = grpc.ServiceDesc{ ServiceName: "intstore.IntStore", HandlerType: (*IntStoreServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "Set", Handler: _IntStore_Set_Handler, }, { MethodName: "Get", Handler: _IntStore_Get_Handler, }, }, Streams: []grpc.StreamDesc{ { StreamName: "ListItems", Handler: _IntStore_ListItems_Handler, ServerStreams: true, }, { StreamName: "SetStream", Handler: _IntStore_SetStream_Handler, ClientStreams: true, }, { StreamName: "StreamChat", Handler: _IntStore_StreamChat_Handler, ServerStreams: true, ClientStreams: true, }, }, Metadata: "intstore.proto", } func init() { proto.RegisterFile("intstore.proto", fileDescriptor_intstore_10c1c94979d47ae6) } var fileDescriptor_intstore_10c1c94979d47ae6 = []byte{ // 287 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x51, 0x4d, 0x4b, 0xc3, 0x40, 0x10, 0xed, 0xf6, 0x43, 0x9b, 0x29, 0x14, 0x1d, 0x2a, 0x94, 0x82, 0x18, 0xf6, 0x94, 0x83, 0x86, 0x50, 0xbd, 0x79, 0xf4, 0x50, 0x0a, 0x9e, 0xb2, 0xe2, 0x55, 0x56, 0x19, 0x6c, 0xc1, 0x6c, 0xe2, 0xee, 0xa4, 0xe0, 0x9f, 0xf0, 0x37, 0xcb, 0x26, 0x6d, 0x13, 0x1a, 0x6f, 0xfb, 0x66, 0xde, 0xbc, 0x79, 0x6f, 0x16, 0xa6, 0x5b, 0xc3, 0x8e, 0x73, 0x4b, 0x71, 0x61, 0x73, 0xce, 0x71, 0x7c, 0xc0, 0x32, 0x81, 0xe1, 0x9a, 0x29, 0x43, 0x84, 0xa1, 0xd1, 0x19, 0xcd, 0x45, 0x28, 0xa2, 0x20, 0xad, 0xde, 0x38, 0x83, 0xd1, 0x4e, 0x7f, 0x95, 0x34, 0xef, 0x87, 0x22, 0x1a, 0xa5, 0x35, 0x90, 0xb7, 0x30, 0x51, 0xc4, 0x29, 0xb9, 0x22, 0x37, 0x8e, 0xf0, 0x1a, 0xa0, 0xb0, 0xb4, 0x7b, 0xab, 0x99, 0xa2, 0x62, 0x06, 0xbe, 0xf2, 0x5a, 0xb1, 0x43, 0x80, 0x95, 0x67, 0x7f, 0x97, 0xe4, 0xf8, 0xbf, 0x2d, 0xf2, 0x06, 0xce, 0x55, 0x99, 0x65, 0xda, 0xfe, 0xf8, 0x85, 0x1f, 0x79, 0x69, 0x78, 0x2f, 0x53, 0x03, 0xf9, 0x00, 0x17, 0xcf, 0x5b, 0xc7, 0xde, 0xa6, 0x3b, 0x08, 0x85, 0x30, 0xf9, 0xb4, 0xa4, 0x99, 0xec, 0xcb, 0x46, 0x9b, 0x3d, 0xbf, 0x5d, 0x5a, 0xfe, 0xf6, 0x61, 0xbc, 0x36, 0xac, 0x7c, 0x4a, 0x8c, 0x61, 0xa0, 0x88, 0x71, 0x1a, 0x1f, 0xef, 0xe0, 0xd5, 0x16, 0x57, 0x0d, 0x6e, 0x45, 0x92, 0x3d, 0xbc, 0x83, 0xc1, 0x8a, 0x18, 0x67, 0x4d, 0xbf, 0x09, 0xb1, 0x38, 0x51, 0x91, 0x3d, 0x7c, 0x84, 0xe0, 0xe8, 0x10, 0x17, 0x4d, 0xfb, 0xd4, 0x76, 0x77, 0x34, 0x11, 0xb8, 0x84, 0x40, 0x11, 0x2b, 0xb6, 0xa4, 0xb3, 0x8e, 0xc3, 0xcb, 0x96, 0xc3, 0xfa, 0x48, 0xb2, 0x17, 0xf9, 0x19, 0xa8, 0x07, 0x9e, 0x36, 0xba, 0x1b, 0xab, 0xb3, 0x25, 0x12, 0x89, 0x78, 0x3f, 0xab, 0xbe, 0xfe, 0xfe, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x8f, 0x47, 0xc4, 0x86, 0x0c, 0x02, 0x00, 0x00, } google-cloud-go-0.49.0/rpcreplay/proto/intstore/intstore.proto000066400000000000000000000026131356504100700245410ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // IntStore is a service for testing the rpcreplay package. // It is a simple key-value store for integers. syntax = "proto3"; package intstore; service IntStore { rpc Set(Item) returns (SetResponse) {} rpc Get(GetRequest) returns (Item) {} // A server-to-client streaming RPC. rpc ListItems(ListItemsRequest) returns (stream Item) {} // A client-to-server streaming RPC. rpc SetStream(stream Item) returns (Summary) {} // A Bidirectional streaming RPC. rpc StreamChat(stream Item) returns (stream Item) {} } message Item { string name = 1; int32 value = 2; } message SetResponse { int32 prev_value = 1; } message GetRequest { string name = 1; } message Summary { int32 count = 1; } message ListItemsRequest { // Only list items whose value is greater than this. int32 greaterThan = 1; } google-cloud-go-0.49.0/rpcreplay/proto/rpcreplay/000077500000000000000000000000001356504100700217355ustar00rootroot00000000000000google-cloud-go-0.49.0/rpcreplay/proto/rpcreplay/rpcreplay.pb.go000066400000000000000000000147141356504100700246740ustar00rootroot00000000000000// Code generated by protoc-gen-go. DO NOT EDIT. // source: rpcreplay.proto package rpcreplay import ( fmt "fmt" proto "github.com/golang/protobuf/proto" math "math" any "github.com/golang/protobuf/ptypes/any" ) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal var _ = fmt.Errorf var _ = math.Inf // This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package type Entry_Kind int32 const ( Entry_TYPE_UNSPECIFIED Entry_Kind = 0 // A unary request. // method: the full name of the method // message: the request proto // is_error: false // ref_index: 0 Entry_REQUEST Entry_Kind = 1 // A unary response. // method: the full name of the method // message: // if is_error: a google.rpc.Status proto // else: the response proto // ref_index: index in the sequence of Entries of matching request (1-based) Entry_RESPONSE Entry_Kind = 2 // A method that creates a stream. // method: the full name of the method // message: // if is_error: a google.rpc.Status proto // else: nil // ref_index: 0 Entry_CREATE_STREAM Entry_Kind = 3 // A call to Send on the client returned by a stream-creating method. // method: unset // message: the proto being sent // is_error: false // ref_index: index of matching CREATE_STREAM entry (1-based) Entry_SEND Entry_Kind = 4 // A call to Recv on the client returned by a stream-creating method. // method: unset // message: // if is_error: a google.rpc.Status proto, or nil on EOF // else: the received message // ref_index: index of matching CREATE_STREAM entry Entry_RECV Entry_Kind = 5 ) var Entry_Kind_name = map[int32]string{ 0: "TYPE_UNSPECIFIED", 1: "REQUEST", 2: "RESPONSE", 3: "CREATE_STREAM", 4: "SEND", 5: "RECV", } var Entry_Kind_value = map[string]int32{ "TYPE_UNSPECIFIED": 0, "REQUEST": 1, "RESPONSE": 2, "CREATE_STREAM": 3, "SEND": 4, "RECV": 5, } func (x Entry_Kind) String() string { return proto.EnumName(Entry_Kind_name, int32(x)) } func (Entry_Kind) EnumDescriptor() ([]byte, []int) { return fileDescriptor_rpcreplay_7cb3daad2f518aa1, []int{0, 0} } // An Entry represents a single RPC activity, typically a request or response. type Entry struct { Kind Entry_Kind `protobuf:"varint,1,opt,name=kind,proto3,enum=rpcreplay.Entry_Kind" json:"kind,omitempty"` Method string `protobuf:"bytes,2,opt,name=method,proto3" json:"method,omitempty"` Message *any.Any `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"` IsError bool `protobuf:"varint,4,opt,name=is_error,json=isError,proto3" json:"is_error,omitempty"` RefIndex int32 `protobuf:"varint,5,opt,name=ref_index,json=refIndex,proto3" json:"ref_index,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *Entry) Reset() { *m = Entry{} } func (m *Entry) String() string { return proto.CompactTextString(m) } func (*Entry) ProtoMessage() {} func (*Entry) Descriptor() ([]byte, []int) { return fileDescriptor_rpcreplay_7cb3daad2f518aa1, []int{0} } func (m *Entry) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Entry.Unmarshal(m, b) } func (m *Entry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Entry.Marshal(b, m, deterministic) } func (dst *Entry) XXX_Merge(src proto.Message) { xxx_messageInfo_Entry.Merge(dst, src) } func (m *Entry) XXX_Size() int { return xxx_messageInfo_Entry.Size(m) } func (m *Entry) XXX_DiscardUnknown() { xxx_messageInfo_Entry.DiscardUnknown(m) } var xxx_messageInfo_Entry proto.InternalMessageInfo func (m *Entry) GetKind() Entry_Kind { if m != nil { return m.Kind } return Entry_TYPE_UNSPECIFIED } func (m *Entry) GetMethod() string { if m != nil { return m.Method } return "" } func (m *Entry) GetMessage() *any.Any { if m != nil { return m.Message } return nil } func (m *Entry) GetIsError() bool { if m != nil { return m.IsError } return false } func (m *Entry) GetRefIndex() int32 { if m != nil { return m.RefIndex } return 0 } func init() { proto.RegisterType((*Entry)(nil), "rpcreplay.Entry") proto.RegisterEnum("rpcreplay.Entry_Kind", Entry_Kind_name, Entry_Kind_value) } func init() { proto.RegisterFile("rpcreplay.proto", fileDescriptor_rpcreplay_7cb3daad2f518aa1) } var fileDescriptor_rpcreplay_7cb3daad2f518aa1 = []byte{ // 289 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x44, 0x8e, 0xdf, 0x4e, 0xc2, 0x30, 0x14, 0xc6, 0x2d, 0x6c, 0x30, 0x0e, 0xfe, 0xa9, 0x0d, 0x9a, 0xa1, 0x37, 0x0b, 0x57, 0xf3, 0xa6, 0x24, 0xf8, 0x04, 0x04, 0x8e, 0x09, 0x31, 0x22, 0xb6, 0xc3, 0xc4, 0x1b, 0x17, 0x70, 0x05, 0x17, 0xa1, 0x25, 0xdd, 0x4c, 0xdc, 0x6b, 0xf8, 0xc4, 0x66, 0x13, 0xf4, 0xae, 0xbf, 0x7e, 0xbf, 0x9c, 0xef, 0x83, 0x33, 0xbb, 0x7b, 0xb3, 0x6a, 0xb7, 0x59, 0x14, 0x7c, 0x67, 0x4d, 0x6e, 0x58, 0xeb, 0xef, 0xe3, 0xaa, 0xbb, 0x36, 0x66, 0xbd, 0x51, 0xfd, 0x2a, 0x58, 0x7e, 0xae, 0xfa, 0x0b, 0xbd, 0xb7, 0x7a, 0xdf, 0x35, 0x70, 0x51, 0xe7, 0xb6, 0x60, 0x37, 0xe0, 0x7c, 0xa4, 0x3a, 0xf1, 0x49, 0x40, 0xc2, 0xd3, 0xc1, 0x05, 0xff, 0xbf, 0x57, 0xe5, 0xfc, 0x3e, 0xd5, 0x89, 0xa8, 0x14, 0x76, 0x09, 0x8d, 0xad, 0xca, 0xdf, 0x4d, 0xe2, 0xd7, 0x02, 0x12, 0xb6, 0xc4, 0x9e, 0x18, 0x87, 0xe6, 0x56, 0x65, 0xd9, 0x62, 0xad, 0xfc, 0x7a, 0x40, 0xc2, 0xf6, 0xa0, 0xc3, 0x7f, 0x9b, 0xf9, 0xa1, 0x99, 0x0f, 0x75, 0x21, 0x0e, 0x12, 0xeb, 0x82, 0x97, 0x66, 0xb1, 0xb2, 0xd6, 0x58, 0xdf, 0x09, 0x48, 0xe8, 0x89, 0x66, 0x9a, 0x61, 0x89, 0xec, 0x1a, 0x5a, 0x56, 0xad, 0xe2, 0x54, 0x27, 0xea, 0xcb, 0x77, 0x03, 0x12, 0xba, 0xc2, 0xb3, 0x6a, 0x35, 0x29, 0xb9, 0xf7, 0x0a, 0x4e, 0xb9, 0x86, 0x75, 0x80, 0x46, 0x2f, 0x33, 0x8c, 0xe7, 0x53, 0x39, 0xc3, 0xd1, 0xe4, 0x6e, 0x82, 0x63, 0x7a, 0xc4, 0xda, 0xd0, 0x14, 0xf8, 0x34, 0x47, 0x19, 0x51, 0xc2, 0x8e, 0xc1, 0x13, 0x28, 0x67, 0x8f, 0x53, 0x89, 0xb4, 0xc6, 0xce, 0xe1, 0x64, 0x24, 0x70, 0x18, 0x61, 0x2c, 0x23, 0x81, 0xc3, 0x07, 0x5a, 0x67, 0x1e, 0x38, 0x12, 0xa7, 0x63, 0xea, 0x94, 0x2f, 0x81, 0xa3, 0x67, 0xea, 0x2e, 0x1b, 0xd5, 0xdc, 0xdb, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe7, 0x9b, 0x9d, 0x4f, 0x54, 0x01, 0x00, 0x00, } google-cloud-go-0.49.0/rpcreplay/proto/rpcreplay/rpcreplay.proto000066400000000000000000000045451356504100700250330ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. syntax = "proto3"; package rpcreplay; import "google/protobuf/any.proto"; // An Entry represents a single RPC activity, typically a request or response. message Entry { enum Kind { TYPE_UNSPECIFIED = 0; // A unary request. // method: the full name of the method // message: the request proto // is_error: false // ref_index: 0 REQUEST = 1; // A unary response. // method: the full name of the method // message: // if is_error: a google.rpc.Status proto // else: the response proto // ref_index: index in the sequence of Entries of matching request (1-based) RESPONSE = 2; // A method that creates a stream. // method: the full name of the method // message: // if is_error: a google.rpc.Status proto // else: nil // ref_index: 0 CREATE_STREAM = 3; // A call to Send on the client returned by a stream-creating method. // method: unset // message: the proto being sent // is_error: false // ref_index: index of matching CREATE_STREAM entry (1-based) SEND = 4; // message sent on stream // A call to Recv on the client returned by a stream-creating method. // method: unset // message: // if is_error: a google.rpc.Status proto, or nil on EOF // else: the received message // ref_index: index of matching CREATE_STREAM entry RECV = 5; // message received from stream } Kind kind = 1; string method = 2; // method name google.protobuf.Any message = 3; // request, response or error status bool is_error = 4; // was response an error? int32 ref_index = 5; // for RESPONSE, index of matching request; // for SEND/RECV, index of CREATE_STREAM } google-cloud-go-0.49.0/rpcreplay/rpcreplay.go000066400000000000000000000474161356504100700211350ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package rpcreplay import ( "bufio" "context" "encoding/binary" "errors" "fmt" "io" "log" "net" "os" "sync" pb "cloud.google.com/go/rpcreplay/proto/rpcreplay" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" "github.com/golang/protobuf/ptypes/any" spb "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" ) // A Recorder records RPCs for later playback. type Recorder struct { mu sync.Mutex w *bufio.Writer f *os.File next int err error // BeforeFunc defines a function that can inspect and modify requests and responses // written to the replay file. It does not modify messages sent to the service. // It is run once before a request is written to the replay file, and once before a response // is written to the replay file. // The function is called with the method name and the message that triggered the callback. // If the function returns an error, the error will be returned to the client. // This is only executed for unary RPCs; streaming RPCs are not supported. BeforeFunc func(string, proto.Message) error } // NewRecorder creates a recorder that writes to filename. The file will // also store the initial bytes for retrieval during replay. // // You must call Close on the Recorder to ensure that all data is written. func NewRecorder(filename string, initial []byte) (*Recorder, error) { f, err := os.Create(filename) if err != nil { return nil, err } rec, err := NewRecorderWriter(f, initial) if err != nil { _ = f.Close() return nil, err } rec.f = f return rec, nil } // NewRecorderWriter creates a recorder that writes to w. The initial // bytes will also be written to w for retrieval during replay. // // You must call Close on the Recorder to ensure that all data is written. func NewRecorderWriter(w io.Writer, initial []byte) (*Recorder, error) { bw := bufio.NewWriter(w) if err := writeHeader(bw, initial); err != nil { return nil, err } return &Recorder{w: bw, next: 1}, nil } // DialOptions returns the options that must be passed to grpc.Dial // to enable recording. func (r *Recorder) DialOptions() []grpc.DialOption { return []grpc.DialOption{ grpc.WithUnaryInterceptor(r.interceptUnary), grpc.WithStreamInterceptor(r.interceptStream), } } // Close saves any unwritten information. func (r *Recorder) Close() error { r.mu.Lock() defer r.mu.Unlock() if r.err != nil { return r.err } err := r.w.Flush() if r.f != nil { if err2 := r.f.Close(); err == nil { err = err2 } } return err } // Intercepts all unary (non-stream) RPCs. func (r *Recorder) interceptUnary(ctx context.Context, method string, req, res interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { ereq := &entry{ kind: pb.Entry_REQUEST, method: method, msg: message{msg: proto.Clone(req.(proto.Message))}, } if r.BeforeFunc != nil { if err := r.BeforeFunc(method, ereq.msg.msg); err != nil { return err } } refIndex, err := r.writeEntry(ereq) if err != nil { return err } ierr := invoker(ctx, method, req, res, cc, opts...) eres := &entry{ kind: pb.Entry_RESPONSE, refIndex: refIndex, } // If the error is not a gRPC status, then something more // serious is wrong. More significantly, we have no way // of serializing an arbitrary error. So just return it // without recording the response. if _, ok := status.FromError(ierr); !ok { r.mu.Lock() r.err = fmt.Errorf("saw non-status error in %s response: %v (%T)", method, ierr, ierr) r.mu.Unlock() return ierr } eres.msg.set(proto.Clone(res.(proto.Message)), ierr) if r.BeforeFunc != nil { if err := r.BeforeFunc(method, eres.msg.msg); err != nil { return err } } if _, err := r.writeEntry(eres); err != nil { return err } return ierr } func (r *Recorder) writeEntry(e *entry) (int, error) { r.mu.Lock() defer r.mu.Unlock() if r.err != nil { return 0, r.err } err := writeEntry(r.w, e) if err != nil { r.err = err return 0, err } n := r.next r.next++ return n, nil } func (r *Recorder) interceptStream(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) { cstream, serr := streamer(ctx, desc, cc, method, opts...) e := &entry{ kind: pb.Entry_CREATE_STREAM, method: method, } e.msg.set(nil, serr) refIndex, err := r.writeEntry(e) if err != nil { return nil, err } return &recClientStream{ ctx: ctx, rec: r, cstream: cstream, refIndex: refIndex, }, serr } // A recClientStream implements the gprc.ClientStream interface. // It behaves exactly like the default ClientStream, but also // records all messages sent and received. type recClientStream struct { ctx context.Context rec *Recorder cstream grpc.ClientStream refIndex int } func (rcs *recClientStream) Context() context.Context { return rcs.ctx } func (rcs *recClientStream) SendMsg(m interface{}) error { serr := rcs.cstream.SendMsg(m) e := &entry{ kind: pb.Entry_SEND, refIndex: rcs.refIndex, } e.msg.set(m, serr) if _, err := rcs.rec.writeEntry(e); err != nil { return err } return serr } func (rcs *recClientStream) RecvMsg(m interface{}) error { serr := rcs.cstream.RecvMsg(m) e := &entry{ kind: pb.Entry_RECV, refIndex: rcs.refIndex, } e.msg.set(m, serr) if _, err := rcs.rec.writeEntry(e); err != nil { return err } return serr } func (rcs *recClientStream) Header() (metadata.MD, error) { // TODO(jba): record. return rcs.cstream.Header() } func (rcs *recClientStream) Trailer() metadata.MD { // TODO(jba): record. return rcs.cstream.Trailer() } func (rcs *recClientStream) CloseSend() error { // TODO(jba): record. return rcs.cstream.CloseSend() } // A Replayer replays a set of RPCs saved by a Recorder. type Replayer struct { initial []byte // initial state log func(format string, v ...interface{}) // for debugging mu sync.Mutex calls []*call streams []*stream // BeforeFunc defines a function that can inspect and modify requests before they // are matched for responses from the replay file. // The function is called with the method name and the message that triggered the callback. // If the function returns an error, the error will be returned to the client. // This is only executed for unary RPCs; streaming RPCs are not supported. BeforeFunc func(string, proto.Message) error } // A call represents a unary RPC, with a request and response (or error). type call struct { method string request proto.Message response message } // A stream represents a gRPC stream, with an initial create-stream call, followed by // zero or more sends and/or receives. type stream struct { method string createIndex int createErr error // error from create call sends []message recvs []message } // NewReplayer creates a Replayer that reads from filename. func NewReplayer(filename string) (*Replayer, error) { f, err := os.Open(filename) if err != nil { return nil, err } defer f.Close() return NewReplayerReader(f) } // NewReplayerReader creates a Replayer that reads from r. func NewReplayerReader(r io.Reader) (*Replayer, error) { rep := &Replayer{ log: func(string, ...interface{}) {}, } if err := rep.read(r); err != nil { return nil, err } return rep, nil } // read reads the stream of recorded entries. // It matches requests with responses, with each pair grouped // into a call struct. func (rep *Replayer) read(r io.Reader) error { r = bufio.NewReader(r) bytes, err := readHeader(r) if err != nil { return err } rep.initial = bytes callsByIndex := map[int]*call{} streamsByIndex := map[int]*stream{} for i := 1; ; i++ { e, err := readEntry(r) if err != nil { return err } if e == nil { break } switch e.kind { case pb.Entry_REQUEST: callsByIndex[i] = &call{ method: e.method, request: e.msg.msg, } case pb.Entry_RESPONSE: call := callsByIndex[e.refIndex] if call == nil { return fmt.Errorf("replayer: no request for response #%d", i) } delete(callsByIndex, e.refIndex) call.response = e.msg rep.calls = append(rep.calls, call) case pb.Entry_CREATE_STREAM: s := &stream{method: e.method, createIndex: i} s.createErr = e.msg.err streamsByIndex[i] = s rep.streams = append(rep.streams, s) case pb.Entry_SEND: s := streamsByIndex[e.refIndex] if s == nil { return fmt.Errorf("replayer: no stream for send #%d", i) } s.sends = append(s.sends, e.msg) case pb.Entry_RECV: s := streamsByIndex[e.refIndex] if s == nil { return fmt.Errorf("replayer: no stream for recv #%d", i) } s.recvs = append(s.recvs, e.msg) default: return fmt.Errorf("replayer: unknown kind %s", e.kind) } } if len(callsByIndex) > 0 { return fmt.Errorf("replayer: %d unmatched requests", len(callsByIndex)) } return nil } // DialOptions returns the options that must be passed to grpc.Dial // to enable replaying. func (rep *Replayer) DialOptions() []grpc.DialOption { return []grpc.DialOption{ // On replay, we make no RPCs, which means the connection may be closed // before the normally async Dial completes. Making the Dial synchronous // fixes that. grpc.WithBlock(), grpc.WithUnaryInterceptor(rep.interceptUnary), grpc.WithStreamInterceptor(rep.interceptStream), } } // Connection returns a fake gRPC connection suitable for replaying. func (rep *Replayer) Connection() (*grpc.ClientConn, error) { // We don't need an actual connection, not even a loopback one. // But we do need something to attach gRPC interceptors to. // So we start a local server and connect to it, then close it down. srv := grpc.NewServer() l, err := net.Listen("tcp", "localhost:0") if err != nil { return nil, err } go func() { if err := srv.Serve(l); err != nil { panic(err) // we should never get an error because we just connect and stop } }() conn, err := grpc.Dial(l.Addr().String(), append([]grpc.DialOption{grpc.WithInsecure()}, rep.DialOptions()...)...) if err != nil { return nil, err } conn.Close() srv.Stop() return conn, nil } // Initial returns the initial state saved by the Recorder. func (rep *Replayer) Initial() []byte { return rep.initial } // SetLogFunc sets a function to be used for debug logging. The function // should be safe to be called from multiple goroutines. func (rep *Replayer) SetLogFunc(f func(format string, v ...interface{})) { rep.log = f } // Close closes the Replayer. func (rep *Replayer) Close() error { return nil } func (rep *Replayer) interceptUnary(_ context.Context, method string, req, res interface{}, _ *grpc.ClientConn, _ grpc.UnaryInvoker, _ ...grpc.CallOption) error { mreq := req.(proto.Message) if rep.BeforeFunc != nil { if err := rep.BeforeFunc(method, mreq); err != nil { return err } } rep.log("request %s (%s)", method, req) call := rep.extractCall(method, mreq) if call == nil { return fmt.Errorf("replayer: request not found: %s", mreq) } rep.log("returning %v", call.response) if call.response.err != nil { return call.response.err } proto.Merge(res.(proto.Message), call.response.msg) // copy msg into res return nil } func (rep *Replayer) interceptStream(ctx context.Context, _ *grpc.StreamDesc, _ *grpc.ClientConn, method string, _ grpc.Streamer, _ ...grpc.CallOption) (grpc.ClientStream, error) { rep.log("create-stream %s", method) return &repClientStream{ctx: ctx, rep: rep, method: method}, nil } type repClientStream struct { ctx context.Context rep *Replayer method string str *stream } func (rcs *repClientStream) Context() context.Context { return rcs.ctx } func (rcs *repClientStream) SendMsg(req interface{}) error { if rcs.str == nil { if err := rcs.setStream(rcs.method, req.(proto.Message)); err != nil { return err } } if len(rcs.str.sends) == 0 { return fmt.Errorf("replayer: no more sends for stream %s, created at index %d", rcs.str.method, rcs.str.createIndex) } // TODO(jba): Do not assume that the sends happen in the same order on replay. msg := rcs.str.sends[0] rcs.str.sends = rcs.str.sends[1:] return msg.err } func (rcs *repClientStream) setStream(method string, req proto.Message) error { str := rcs.rep.extractStream(method, req) if str == nil { return fmt.Errorf("replayer: stream not found for method %s and request %v", method, req) } if str.createErr != nil { return str.createErr } rcs.str = str return nil } func (rcs *repClientStream) RecvMsg(m interface{}) error { if rcs.str == nil { // Receive before send; fall back to matching stream by method only. if err := rcs.setStream(rcs.method, nil); err != nil { return err } } if len(rcs.str.recvs) == 0 { return fmt.Errorf("replayer: no more receives for stream %s, created at index %d", rcs.str.method, rcs.str.createIndex) } msg := rcs.str.recvs[0] rcs.str.recvs = rcs.str.recvs[1:] if msg.err != nil { return msg.err } proto.Merge(m.(proto.Message), msg.msg) // copy msg into m return nil } func (rcs *repClientStream) Header() (metadata.MD, error) { log.Printf("replay: stream metadata not supported") return nil, nil } func (rcs *repClientStream) Trailer() metadata.MD { log.Printf("replay: stream metadata not supported") return nil } func (rcs *repClientStream) CloseSend() error { return nil } // extractCall finds the first call in the list with the same method // and request. It returns nil if it can't find such a call. func (rep *Replayer) extractCall(method string, req proto.Message) *call { rep.mu.Lock() defer rep.mu.Unlock() for i, call := range rep.calls { if call == nil { continue } if method == call.method && proto.Equal(req, call.request) { rep.calls[i] = nil // nil out this call so we don't reuse it return call } } return nil } // extractStream find the first stream in the list with the same method and the same // first request sent. If req is nil, that means a receive occurred before a send, so // it matches only on method. func (rep *Replayer) extractStream(method string, req proto.Message) *stream { rep.mu.Lock() defer rep.mu.Unlock() for i, stream := range rep.streams { // Skip stream if it is nil (already extracted) or its method doesn't match. if stream == nil || stream.method != method { continue } // If there is a first request, skip stream if it has no requests or its first // request doesn't match. if req != nil && len(stream.sends) > 0 && !proto.Equal(req, stream.sends[0].msg) { continue } rep.streams[i] = nil // nil out this stream so we don't reuse it return stream } return nil } // Fprint reads the entries from filename and writes them to w in human-readable form. // It is intended for debugging. func Fprint(w io.Writer, filename string) error { f, err := os.Open(filename) if err != nil { return err } defer f.Close() return FprintReader(w, f) } // FprintReader reads the entries from r and writes them to w in human-readable form. // It is intended for debugging. func FprintReader(w io.Writer, r io.Reader) error { initial, err := readHeader(r) if err != nil { return err } fmt.Fprintf(w, "initial state: %q\n", string(initial)) for i := 1; ; i++ { e, err := readEntry(r) if err != nil { return err } if e == nil { return nil } fmt.Fprintf(w, "#%d: kind: %s, method: %s, ref index: %d", i, e.kind, e.method, e.refIndex) switch { case e.msg.msg != nil: fmt.Fprintf(w, ", message:\n") if err := proto.MarshalText(w, e.msg.msg); err != nil { return err } case e.msg.err != nil: fmt.Fprintf(w, ", error: %v\n", e.msg.err) default: fmt.Fprintln(w) } } } // An entry holds one gRPC action (request, response, etc.). type entry struct { kind pb.Entry_Kind method string msg message refIndex int // index of corresponding request or create-stream } func (e1 *entry) equal(e2 *entry) bool { if e1 == nil && e2 == nil { return true } if e1 == nil || e2 == nil { return false } return e1.kind == e2.kind && e1.method == e2.method && proto.Equal(e1.msg.msg, e2.msg.msg) && errEqual(e1.msg.err, e2.msg.err) && e1.refIndex == e2.refIndex } func errEqual(e1, e2 error) bool { if e1 == e2 { return true } s1, ok1 := status.FromError(e1) s2, ok2 := status.FromError(e2) if !ok1 || !ok2 { return false } return proto.Equal(s1.Proto(), s2.Proto()) } // message holds either a single proto.Message or an error. type message struct { msg proto.Message err error } func (m *message) set(msg interface{}, err error) { m.err = err if err != io.EOF && msg != nil { m.msg = msg.(proto.Message) } } // File format: // header // sequence of Entry protos // // Header format: // magic string // a record containing the bytes of the initial state const magic = "RPCReplay" func writeHeader(w io.Writer, initial []byte) error { if _, err := io.WriteString(w, magic); err != nil { return err } return writeRecord(w, initial) } func readHeader(r io.Reader) ([]byte, error) { var buf [len(magic)]byte if _, err := io.ReadFull(r, buf[:]); err != nil { if err == io.EOF { err = errors.New("rpcreplay: empty replay file") } return nil, err } if string(buf[:]) != magic { return nil, errors.New("rpcreplay: not a replay file (does not begin with magic string)") } bytes, err := readRecord(r) if err == io.EOF { err = errors.New("rpcreplay: missing initial state") } return bytes, err } func writeEntry(w io.Writer, e *entry) error { var m proto.Message if e.msg.err != nil && e.msg.err != io.EOF { s, ok := status.FromError(e.msg.err) if !ok { return fmt.Errorf("rpcreplay: error %v is not a Status", e.msg.err) } m = s.Proto() } else { m = e.msg.msg } var a *any.Any var err error if m != nil { a, err = ptypes.MarshalAny(m) if err != nil { return err } } pe := &pb.Entry{ Kind: e.kind, Method: e.method, Message: a, IsError: e.msg.err != nil, RefIndex: int32(e.refIndex), } bytes, err := proto.Marshal(pe) if err != nil { return err } return writeRecord(w, bytes) } func readEntry(r io.Reader) (*entry, error) { buf, err := readRecord(r) if err == io.EOF { return nil, nil } if err != nil { return nil, err } var pe pb.Entry if err := proto.Unmarshal(buf, &pe); err != nil { return nil, err } var msg message if pe.Message != nil { var any ptypes.DynamicAny if err := ptypes.UnmarshalAny(pe.Message, &any); err != nil { return nil, err } if pe.IsError { msg.err = status.ErrorProto(any.Message.(*spb.Status)) } else { msg.msg = any.Message } } else if pe.IsError { msg.err = io.EOF } else if pe.Kind != pb.Entry_CREATE_STREAM { return nil, errors.New("rpcreplay: entry with nil message and false is_error") } return &entry{ kind: pe.Kind, method: pe.Method, msg: msg, refIndex: int(pe.RefIndex), }, nil } // A record consists of an unsigned 32-bit little-endian length L followed by L // bytes. func writeRecord(w io.Writer, data []byte) error { if err := binary.Write(w, binary.LittleEndian, uint32(len(data))); err != nil { return err } _, err := w.Write(data) return err } func readRecord(r io.Reader) ([]byte, error) { var size uint32 if err := binary.Read(r, binary.LittleEndian, &size); err != nil { return nil, err } buf := make([]byte, size) if _, err := io.ReadFull(r, buf); err != nil { return nil, err } return buf, nil } google-cloud-go-0.49.0/rpcreplay/rpcreplay_test.go000066400000000000000000000345231356504100700221670ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package rpcreplay import ( "bytes" "context" "errors" "io" "strings" "testing" "cloud.google.com/go/internal/testutil" ipb "cloud.google.com/go/rpcreplay/proto/intstore" pb "cloud.google.com/go/rpcreplay/proto/intstore" rpb "cloud.google.com/go/rpcreplay/proto/rpcreplay" "github.com/golang/protobuf/proto" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) func TestRecordIO(t *testing.T) { buf := &bytes.Buffer{} want := []byte{1, 2, 3} if err := writeRecord(buf, want); err != nil { t.Fatal(err) } got, err := readRecord(buf) if err != nil { t.Fatal(err) } if !bytes.Equal(got, want) { t.Errorf("got %v, want %v", got, want) } } func TestHeaderIO(t *testing.T) { buf := &bytes.Buffer{} want := []byte{1, 2, 3} if err := writeHeader(buf, want); err != nil { t.Fatal(err) } got, err := readHeader(buf) if err != nil { t.Fatal(err) } if !testutil.Equal(got, want) { t.Errorf("got %v, want %v", got, want) } // readHeader errors for _, contents := range []string{"", "badmagic", "gRPCReplay"} { if _, err := readHeader(bytes.NewBufferString(contents)); err == nil { t.Errorf("%q: got nil, want error", contents) } } } func TestEntryIO(t *testing.T) { for i, want := range []*entry{ { kind: rpb.Entry_REQUEST, method: "method", msg: message{msg: &rpb.Entry{}}, refIndex: 7, }, { kind: rpb.Entry_RESPONSE, method: "method", msg: message{err: status.Error(codes.NotFound, "not found")}, refIndex: 8, }, { kind: rpb.Entry_RECV, method: "method", msg: message{err: io.EOF}, refIndex: 3, }, } { buf := &bytes.Buffer{} if err := writeEntry(buf, want); err != nil { t.Fatal(err) } got, err := readEntry(buf) if err != nil { t.Fatal(err) } if !got.equal(want) { t.Errorf("#%d: got %v, want %v", i, got, want) } } } var initialState = []byte{1, 2, 3} func TestRecord(t *testing.T) { buf := record(t, testService) gotIstate, err := readHeader(buf) if err != nil { t.Fatal(err) } if !testutil.Equal(gotIstate, initialState) { t.Fatalf("got %v, want %v", gotIstate, initialState) } item := &ipb.Item{Name: "a", Value: 1} wantEntries := []*entry{ // Set { kind: rpb.Entry_REQUEST, method: "/intstore.IntStore/Set", msg: message{msg: item}, }, { kind: rpb.Entry_RESPONSE, msg: message{msg: &ipb.SetResponse{PrevValue: 0}}, refIndex: 1, }, // Get { kind: rpb.Entry_REQUEST, method: "/intstore.IntStore/Get", msg: message{msg: &ipb.GetRequest{Name: "a"}}, }, { kind: rpb.Entry_RESPONSE, msg: message{msg: item}, refIndex: 3, }, { kind: rpb.Entry_REQUEST, method: "/intstore.IntStore/Get", msg: message{msg: &ipb.GetRequest{Name: "x"}}, }, { kind: rpb.Entry_RESPONSE, msg: message{err: status.Error(codes.NotFound, `"x"`)}, refIndex: 5, }, // ListItems { // entry #7 kind: rpb.Entry_CREATE_STREAM, method: "/intstore.IntStore/ListItems", }, { kind: rpb.Entry_SEND, msg: message{msg: &ipb.ListItemsRequest{}}, refIndex: 7, }, { kind: rpb.Entry_RECV, msg: message{msg: item}, refIndex: 7, }, { kind: rpb.Entry_RECV, msg: message{err: io.EOF}, refIndex: 7, }, // SetStream { // entry #11 kind: rpb.Entry_CREATE_STREAM, method: "/intstore.IntStore/SetStream", }, { kind: rpb.Entry_SEND, msg: message{msg: &ipb.Item{Name: "b", Value: 2}}, refIndex: 11, }, { kind: rpb.Entry_SEND, msg: message{msg: &ipb.Item{Name: "c", Value: 3}}, refIndex: 11, }, { kind: rpb.Entry_RECV, msg: message{msg: &ipb.Summary{Count: 2}}, refIndex: 11, }, // StreamChat { // entry #15 kind: rpb.Entry_CREATE_STREAM, method: "/intstore.IntStore/StreamChat", }, { kind: rpb.Entry_SEND, msg: message{msg: &ipb.Item{Name: "d", Value: 4}}, refIndex: 15, }, { kind: rpb.Entry_RECV, msg: message{msg: &ipb.Item{Name: "d", Value: 4}}, refIndex: 15, }, { kind: rpb.Entry_SEND, msg: message{msg: &ipb.Item{Name: "e", Value: 5}}, refIndex: 15, }, { kind: rpb.Entry_RECV, msg: message{msg: &ipb.Item{Name: "e", Value: 5}}, refIndex: 15, }, { kind: rpb.Entry_RECV, msg: message{err: io.EOF}, refIndex: 15, }, } for i, w := range wantEntries { g, err := readEntry(buf) if err != nil { t.Fatalf("#%d: %v", i+1, err) } if !g.equal(w) { t.Errorf("#%d:\ngot %+v\nwant %+v", i+1, g, w) } } g, err := readEntry(buf) if err != nil { t.Fatal(err) } if g != nil { t.Errorf("\ngot %+v\nwant nil", g) } } func TestReplay(t *testing.T) { buf := record(t, testService) replay(t, buf, testService) } func record(t *testing.T, run func(*testing.T, *grpc.ClientConn)) *bytes.Buffer { srv := newIntStoreServer() defer srv.stop() buf := &bytes.Buffer{} rec, err := NewRecorderWriter(buf, initialState) if err != nil { t.Fatal(err) } conn, err := grpc.Dial(srv.Addr, append([]grpc.DialOption{grpc.WithInsecure()}, rec.DialOptions()...)...) if err != nil { t.Fatal(err) } defer conn.Close() run(t, conn) if err := rec.Close(); err != nil { t.Fatal(err) } return buf } func replay(t *testing.T, buf *bytes.Buffer, run func(*testing.T, *grpc.ClientConn)) { rep, err := NewReplayerReader(buf) if err != nil { t.Fatal(err) } defer rep.Close() if got, want := rep.Initial(), initialState; !testutil.Equal(got, want) { t.Fatalf("got %v, want %v", got, want) } // Replay the test. conn, err := rep.Connection() if err != nil { t.Fatal(err) } defer conn.Close() run(t, conn) } func testService(t *testing.T, conn *grpc.ClientConn) { client := ipb.NewIntStoreClient(conn) ctx := context.Background() item := &ipb.Item{Name: "a", Value: 1} res, err := client.Set(ctx, item) if err != nil { t.Fatal(err) } if res.PrevValue != 0 { t.Errorf("got %d, want 0", res.PrevValue) } got, err := client.Get(ctx, &ipb.GetRequest{Name: "a"}) if err != nil { t.Fatal(err) } if !proto.Equal(got, item) { t.Errorf("got %v, want %v", got, item) } _, err = client.Get(ctx, &ipb.GetRequest{Name: "x"}) if err == nil { t.Fatal("got nil, want error") } if _, ok := status.FromError(err); !ok { t.Errorf("got error type %T, want a grpc/status.Status", err) } gotItems := listItems(t, client, 0) compareLists(t, gotItems, []*ipb.Item{item}) ssc, err := client.SetStream(ctx) if err != nil { t.Fatal(err) } must := func(err error) { if err != nil { t.Fatal(err) } } for i, name := range []string{"b", "c"} { must(ssc.Send(&ipb.Item{Name: name, Value: int32(i + 2)})) } summary, err := ssc.CloseAndRecv() if err != nil { t.Fatal(err) } if got, want := summary.Count, int32(2); got != want { t.Fatalf("got %d, want %d", got, want) } chatc, err := client.StreamChat(ctx) if err != nil { t.Fatal(err) } for i, name := range []string{"d", "e"} { item := &ipb.Item{Name: name, Value: int32(i + 4)} must(chatc.Send(item)) got, err := chatc.Recv() if err != nil { t.Fatal(err) } if !proto.Equal(got, item) { t.Errorf("got %v, want %v", got, item) } } must(chatc.CloseSend()) if _, err := chatc.Recv(); err != io.EOF { t.Fatalf("got %v, want EOF", err) } } func listItems(t *testing.T, client ipb.IntStoreClient, greaterThan int) []*ipb.Item { t.Helper() lic, err := client.ListItems(context.Background(), &ipb.ListItemsRequest{GreaterThan: int32(greaterThan)}) if err != nil { t.Fatal(err) } var items []*ipb.Item for i := 0; ; i++ { item, err := lic.Recv() if err == io.EOF { break } if err != nil { t.Fatal(err) } items = append(items, item) } return items } func compareLists(t *testing.T, got, want []*pb.Item) { t.Helper() diff := cmp.Diff(got, want, cmp.Comparer(proto.Equal), cmpopts.SortSlices(func(i1, i2 *pb.Item) bool { return i1.Value < i2.Value })) if diff != "" { t.Error(diff) } } func TestRecorderBeforeFunc(t *testing.T) { var tests = []struct { name string msg, wantRespMsg, wantEntryMsg *ipb.Item f func(string, proto.Message) error wantErr bool }{ { name: "BeforeFunc should modify messages saved, but not alter what is sent/received to/from services", msg: &ipb.Item{Name: "foo", Value: 1}, wantEntryMsg: &ipb.Item{Name: "bar", Value: 2}, wantRespMsg: &ipb.Item{Name: "foo", Value: 1}, f: func(method string, m proto.Message) error { // This callback only runs when Set is called. if !strings.HasSuffix(method, "Set") { return nil } if _, ok := m.(*ipb.Item); !ok { return nil } item := m.(*ipb.Item) item.Name = "bar" item.Value = 2 return nil }, }, { name: "BeforeFunc should not be able to alter returned responses", msg: &ipb.Item{Name: "foo", Value: 1}, wantRespMsg: &ipb.Item{Name: "foo", Value: 1}, f: func(method string, m proto.Message) error { // This callback only runs when Get is called. if !strings.HasSuffix(method, "Get") { return nil } if _, ok := m.(*ipb.Item); !ok { return nil } item := m.(*ipb.Item) item.Value = 2 return nil }, }, { name: "Errors should cause the RPC send to fail", msg: &ipb.Item{}, f: func(_ string, _ proto.Message) error { return errors.New("err") }, wantErr: true, }, } for _, tc := range tests { // Wrap test cases in a func so defers execute correctly. func() { srv := newIntStoreServer() defer srv.stop() var b bytes.Buffer r, err := NewRecorderWriter(&b, nil) if err != nil { t.Error(err) return } r.BeforeFunc = tc.f ctx := context.Background() conn, err := grpc.DialContext(ctx, srv.Addr, append([]grpc.DialOption{grpc.WithInsecure()}, r.DialOptions()...)...) if err != nil { t.Error(err) return } defer conn.Close() client := ipb.NewIntStoreClient(conn) _, err = client.Set(ctx, tc.msg) switch { case err != nil && !tc.wantErr: t.Error(err) return case err == nil && tc.wantErr: t.Errorf("got nil; want error") return case err != nil: // Error found as expected, don't check Get(). return } if tc.wantRespMsg != nil { got, err := client.Get(ctx, &ipb.GetRequest{Name: tc.msg.GetName()}) if err != nil { t.Error(err) return } if !cmp.Equal(got, tc.wantRespMsg) { t.Errorf("got %+v; want %+v", got, tc.wantRespMsg) } } r.Close() if tc.wantEntryMsg != nil { _, _ = readHeader(&b) e, err := readEntry(&b) if err != nil { t.Error(err) return } got := e.msg.msg.(*ipb.Item) if !cmp.Equal(got, tc.wantEntryMsg) { t.Errorf("got %v; want %v", got, tc.wantEntryMsg) } } }() } } func TestReplayerBeforeFunc(t *testing.T) { var tests = []struct { name string msg, reqMsg *ipb.Item f func(string, proto.Message) error wantErr bool }{ { name: "BeforeFunc should modify messages sent before they are passed to the replayer", msg: &ipb.Item{Name: "foo", Value: 1}, reqMsg: &ipb.Item{Name: "bar", Value: 1}, f: func(method string, m proto.Message) error { item := m.(*ipb.Item) item.Name = "foo" return nil }, }, { name: "Errors should cause the RPC send to fail", msg: &ipb.Item{}, f: func(_ string, _ proto.Message) error { return errors.New("err") }, wantErr: true, }, } for _, tc := range tests { // Wrap test cases in a func so defers execute correctly. func() { srv := newIntStoreServer() defer srv.stop() var b bytes.Buffer rec, err := NewRecorderWriter(&b, nil) if err != nil { t.Error(err) return } ctx := context.Background() conn, err := grpc.DialContext(ctx, srv.Addr, append([]grpc.DialOption{grpc.WithInsecure()}, rec.DialOptions()...)...) if err != nil { t.Error(err) return } defer conn.Close() client := ipb.NewIntStoreClient(conn) _, err = client.Set(ctx, tc.msg) if err != nil { t.Error(err) return } rec.Close() rep, err := NewReplayerReader(&b) if err != nil { t.Error(err) return } rep.BeforeFunc = tc.f conn, err = grpc.DialContext(ctx, srv.Addr, append([]grpc.DialOption{grpc.WithInsecure()}, rep.DialOptions()...)...) if err != nil { t.Error(err) return } defer conn.Close() client = ipb.NewIntStoreClient(conn) _, err = client.Set(ctx, tc.reqMsg) switch { case err != nil && !tc.wantErr: t.Error(err) case err == nil && tc.wantErr: t.Errorf("got nil; want error") } }() } } func TestOutOfOrderStreamReplay(t *testing.T) { // Check that streams are matched by method and first request sent, if any. items := []*ipb.Item{ {Name: "a", Value: 1}, {Name: "b", Value: 2}, {Name: "c", Value: 3}, } run := func(t *testing.T, conn *grpc.ClientConn, arg1, arg2 int) { client := ipb.NewIntStoreClient(conn) ctx := context.Background() // Set some items. for _, item := range items { _, err := client.Set(ctx, item) if err != nil { t.Fatal(err) } } // List them twice, with different requests. compareLists(t, listItems(t, client, arg1), items[arg1:]) compareLists(t, listItems(t, client, arg2), items[arg2:]) } srv := newIntStoreServer() defer srv.stop() // Replay in the same order. buf := record(t, func(t *testing.T, conn *grpc.ClientConn) { run(t, conn, 1, 2) }) replay(t, buf, func(t *testing.T, conn *grpc.ClientConn) { run(t, conn, 1, 2) }) // Replay in a different order. buf = record(t, func(t *testing.T, conn *grpc.ClientConn) { run(t, conn, 1, 2) }) replay(t, buf, func(t *testing.T, conn *grpc.ClientConn) { run(t, conn, 2, 1) }) } google-cloud-go-0.49.0/scheduler/000077500000000000000000000000001356504100700165465ustar00rootroot00000000000000google-cloud-go-0.49.0/scheduler/apiv1/000077500000000000000000000000001356504100700175665ustar00rootroot00000000000000google-cloud-go-0.49.0/scheduler/apiv1/.repo-metadata.json000066400000000000000000000006561356504100700232710ustar00rootroot00000000000000{ "name": "scheduler", "name_pretty": "Cloud Scheduler", "product_documentation": "https://cloud.google.com/scheduler", "client_documentation": "https://godoc.org/cloud.google.com/go/scheduler/apiv1", "release_level": "ga", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go/scheduler/apiv1", "api_id": "cloudscheduler.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/scheduler/apiv1/cloud_scheduler_client.go000066400000000000000000000336721356504100700246320ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go_gapic. DO NOT EDIT. package scheduler import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" schedulerpb "google.golang.org/genproto/googleapis/cloud/scheduler/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // CloudSchedulerCallOptions contains the retry settings for each method of CloudSchedulerClient. type CloudSchedulerCallOptions struct { ListJobs []gax.CallOption GetJob []gax.CallOption CreateJob []gax.CallOption UpdateJob []gax.CallOption DeleteJob []gax.CallOption PauseJob []gax.CallOption ResumeJob []gax.CallOption RunJob []gax.CallOption } func defaultCloudSchedulerClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("cloudscheduler.googleapis.com:443"), option.WithGRPCDialOption(grpc.WithDisableServiceConfig()), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultCloudSchedulerCallOptions() *CloudSchedulerCallOptions { return &CloudSchedulerCallOptions{ ListJobs: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, GetJob: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, CreateJob: []gax.CallOption{}, UpdateJob: []gax.CallOption{}, DeleteJob: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, PauseJob: []gax.CallOption{}, ResumeJob: []gax.CallOption{}, RunJob: []gax.CallOption{}, } } // CloudSchedulerClient is a client for interacting with Cloud Scheduler API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type CloudSchedulerClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. cloudSchedulerClient schedulerpb.CloudSchedulerClient // The call options for this service. CallOptions *CloudSchedulerCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewCloudSchedulerClient creates a new cloud scheduler client. // // The Cloud Scheduler API allows external entities to reliably // schedule asynchronous jobs. func NewCloudSchedulerClient(ctx context.Context, opts ...option.ClientOption) (*CloudSchedulerClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultCloudSchedulerClientOptions(), opts...)...) if err != nil { return nil, err } c := &CloudSchedulerClient{ conn: conn, CallOptions: defaultCloudSchedulerCallOptions(), cloudSchedulerClient: schedulerpb.NewCloudSchedulerClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *CloudSchedulerClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *CloudSchedulerClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *CloudSchedulerClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // ListJobs lists jobs. func (c *CloudSchedulerClient) ListJobs(ctx context.Context, req *schedulerpb.ListJobsRequest, opts ...gax.CallOption) *JobIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListJobs[0:len(c.CallOptions.ListJobs):len(c.CallOptions.ListJobs)], opts...) it := &JobIterator{} req = proto.Clone(req).(*schedulerpb.ListJobsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*schedulerpb.Job, string, error) { var resp *schedulerpb.ListJobsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.cloudSchedulerClient.ListJobs(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } it.Response = resp return resp.Jobs, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetJob gets a job. func (c *CloudSchedulerClient) GetJob(ctx context.Context, req *schedulerpb.GetJobRequest, opts ...gax.CallOption) (*schedulerpb.Job, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetJob[0:len(c.CallOptions.GetJob):len(c.CallOptions.GetJob)], opts...) var resp *schedulerpb.Job err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.cloudSchedulerClient.GetJob(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateJob creates a job. func (c *CloudSchedulerClient) CreateJob(ctx context.Context, req *schedulerpb.CreateJobRequest, opts ...gax.CallOption) (*schedulerpb.Job, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateJob[0:len(c.CallOptions.CreateJob):len(c.CallOptions.CreateJob)], opts...) var resp *schedulerpb.Job err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.cloudSchedulerClient.CreateJob(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateJob updates a job. // // If successful, the updated [Job][google.cloud.scheduler.v1.Job] is returned. If the job does // not exist, NOT_FOUND is returned. // // If UpdateJob does not successfully return, it is possible for the // job to be in an [Job.State.UPDATE_FAILED][google.cloud.scheduler.v1.Job.State.UPDATE_FAILED] state. A job in this state may // not be executed. If this happens, retry the UpdateJob request // until a successful response is received. func (c *CloudSchedulerClient) UpdateJob(ctx context.Context, req *schedulerpb.UpdateJobRequest, opts ...gax.CallOption) (*schedulerpb.Job, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.UpdateJob[0:len(c.CallOptions.UpdateJob):len(c.CallOptions.UpdateJob)], opts...) var resp *schedulerpb.Job err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.cloudSchedulerClient.UpdateJob(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteJob deletes a job. func (c *CloudSchedulerClient) DeleteJob(ctx context.Context, req *schedulerpb.DeleteJobRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteJob[0:len(c.CallOptions.DeleteJob):len(c.CallOptions.DeleteJob)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.cloudSchedulerClient.DeleteJob(ctx, req, settings.GRPC...) return err }, opts...) return err } // PauseJob pauses a job. // // If a job is paused then the system will stop executing the job // until it is re-enabled via [ResumeJob][google.cloud.scheduler.v1.CloudScheduler.ResumeJob]. The // state of the job is stored in [state][google.cloud.scheduler.v1.Job.state]; if paused it // will be set to [Job.State.PAUSED][google.cloud.scheduler.v1.Job.State.PAUSED]. A job must be in [Job.State.ENABLED][google.cloud.scheduler.v1.Job.State.ENABLED] // to be paused. func (c *CloudSchedulerClient) PauseJob(ctx context.Context, req *schedulerpb.PauseJobRequest, opts ...gax.CallOption) (*schedulerpb.Job, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.PauseJob[0:len(c.CallOptions.PauseJob):len(c.CallOptions.PauseJob)], opts...) var resp *schedulerpb.Job err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.cloudSchedulerClient.PauseJob(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ResumeJob resume a job. // // This method reenables a job after it has been [Job.State.PAUSED][google.cloud.scheduler.v1.Job.State.PAUSED]. The // state of a job is stored in [Job.state][google.cloud.scheduler.v1.Job.state]; after calling this method it // will be set to [Job.State.ENABLED][google.cloud.scheduler.v1.Job.State.ENABLED]. A job must be in // [Job.State.PAUSED][google.cloud.scheduler.v1.Job.State.PAUSED] to be resumed. func (c *CloudSchedulerClient) ResumeJob(ctx context.Context, req *schedulerpb.ResumeJobRequest, opts ...gax.CallOption) (*schedulerpb.Job, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ResumeJob[0:len(c.CallOptions.ResumeJob):len(c.CallOptions.ResumeJob)], opts...) var resp *schedulerpb.Job err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.cloudSchedulerClient.ResumeJob(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // RunJob forces a job to run now. // // When this method is called, Cloud Scheduler will dispatch the job, even // if the job is already running. func (c *CloudSchedulerClient) RunJob(ctx context.Context, req *schedulerpb.RunJobRequest, opts ...gax.CallOption) (*schedulerpb.Job, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.RunJob[0:len(c.CallOptions.RunJob):len(c.CallOptions.RunJob)], opts...) var resp *schedulerpb.Job err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.cloudSchedulerClient.RunJob(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // JobIterator manages a stream of *schedulerpb.Job. type JobIterator struct { items []*schedulerpb.Job pageInfo *iterator.PageInfo nextFunc func() error // Response is the raw response for the current page. // It must be cast to the RPC response type. // Calling Next() or InternalFetch() updates this value. Response interface{} // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*schedulerpb.Job, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *JobIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *JobIterator) Next() (*schedulerpb.Job, error) { var item *schedulerpb.Job if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *JobIterator) bufLen() int { return len(it.items) } func (it *JobIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/scheduler/apiv1/cloud_scheduler_client_example_test.go000066400000000000000000000110111356504100700273630ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go_gapic. DO NOT EDIT. package scheduler_test import ( "context" scheduler "cloud.google.com/go/scheduler/apiv1" "google.golang.org/api/iterator" schedulerpb "google.golang.org/genproto/googleapis/cloud/scheduler/v1" ) func ExampleNewCloudSchedulerClient() { ctx := context.Background() c, err := scheduler.NewCloudSchedulerClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleCloudSchedulerClient_ListJobs() { // import schedulerpb "google.golang.org/genproto/googleapis/cloud/scheduler/v1" // import "google.golang.org/api/iterator" ctx := context.Background() c, err := scheduler.NewCloudSchedulerClient(ctx) if err != nil { // TODO: Handle error. } req := &schedulerpb.ListJobsRequest{ // TODO: Fill request struct fields. } it := c.ListJobs(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleCloudSchedulerClient_GetJob() { // import schedulerpb "google.golang.org/genproto/googleapis/cloud/scheduler/v1" ctx := context.Background() c, err := scheduler.NewCloudSchedulerClient(ctx) if err != nil { // TODO: Handle error. } req := &schedulerpb.GetJobRequest{ // TODO: Fill request struct fields. } resp, err := c.GetJob(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleCloudSchedulerClient_CreateJob() { // import schedulerpb "google.golang.org/genproto/googleapis/cloud/scheduler/v1" ctx := context.Background() c, err := scheduler.NewCloudSchedulerClient(ctx) if err != nil { // TODO: Handle error. } req := &schedulerpb.CreateJobRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateJob(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleCloudSchedulerClient_UpdateJob() { // import schedulerpb "google.golang.org/genproto/googleapis/cloud/scheduler/v1" ctx := context.Background() c, err := scheduler.NewCloudSchedulerClient(ctx) if err != nil { // TODO: Handle error. } req := &schedulerpb.UpdateJobRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateJob(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleCloudSchedulerClient_DeleteJob() { ctx := context.Background() c, err := scheduler.NewCloudSchedulerClient(ctx) if err != nil { // TODO: Handle error. } req := &schedulerpb.DeleteJobRequest{ // TODO: Fill request struct fields. } err = c.DeleteJob(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleCloudSchedulerClient_PauseJob() { // import schedulerpb "google.golang.org/genproto/googleapis/cloud/scheduler/v1" ctx := context.Background() c, err := scheduler.NewCloudSchedulerClient(ctx) if err != nil { // TODO: Handle error. } req := &schedulerpb.PauseJobRequest{ // TODO: Fill request struct fields. } resp, err := c.PauseJob(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleCloudSchedulerClient_ResumeJob() { // import schedulerpb "google.golang.org/genproto/googleapis/cloud/scheduler/v1" ctx := context.Background() c, err := scheduler.NewCloudSchedulerClient(ctx) if err != nil { // TODO: Handle error. } req := &schedulerpb.ResumeJobRequest{ // TODO: Fill request struct fields. } resp, err := c.ResumeJob(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleCloudSchedulerClient_RunJob() { // import schedulerpb "google.golang.org/genproto/googleapis/cloud/scheduler/v1" ctx := context.Background() c, err := scheduler.NewCloudSchedulerClient(ctx) if err != nil { // TODO: Handle error. } req := &schedulerpb.RunJobRequest{ // TODO: Fill request struct fields. } resp, err := c.RunJob(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/scheduler/apiv1/doc.go000066400000000000000000000052151356504100700206650ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go_gapic. DO NOT EDIT. // Package scheduler is an auto-generated package for the // Cloud Scheduler API. // // Creates and manages jobs run on a regular recurring schedule. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package scheduler // import "cloud.google.com/go/scheduler/apiv1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) const versionClient = "20191115" func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return !strings.ContainsRune("0123456789.", r) } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } google-cloud-go-0.49.0/scheduler/apiv1/mock_test.go000066400000000000000000000501551356504100700221130ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package scheduler import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" "google.golang.org/api/option" schedulerpb "google.golang.org/genproto/googleapis/cloud/scheduler/v1" field_maskpb "google.golang.org/genproto/protobuf/field_mask" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockCloudSchedulerServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. schedulerpb.CloudSchedulerServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockCloudSchedulerServer) ListJobs(ctx context.Context, req *schedulerpb.ListJobsRequest) (*schedulerpb.ListJobsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*schedulerpb.ListJobsResponse), nil } func (s *mockCloudSchedulerServer) GetJob(ctx context.Context, req *schedulerpb.GetJobRequest) (*schedulerpb.Job, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*schedulerpb.Job), nil } func (s *mockCloudSchedulerServer) CreateJob(ctx context.Context, req *schedulerpb.CreateJobRequest) (*schedulerpb.Job, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*schedulerpb.Job), nil } func (s *mockCloudSchedulerServer) UpdateJob(ctx context.Context, req *schedulerpb.UpdateJobRequest) (*schedulerpb.Job, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*schedulerpb.Job), nil } func (s *mockCloudSchedulerServer) DeleteJob(ctx context.Context, req *schedulerpb.DeleteJobRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockCloudSchedulerServer) PauseJob(ctx context.Context, req *schedulerpb.PauseJobRequest) (*schedulerpb.Job, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*schedulerpb.Job), nil } func (s *mockCloudSchedulerServer) ResumeJob(ctx context.Context, req *schedulerpb.ResumeJobRequest) (*schedulerpb.Job, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*schedulerpb.Job), nil } func (s *mockCloudSchedulerServer) RunJob(ctx context.Context, req *schedulerpb.RunJobRequest) (*schedulerpb.Job, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*schedulerpb.Job), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockCloudScheduler mockCloudSchedulerServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() schedulerpb.RegisterCloudSchedulerServer(serv, &mockCloudScheduler) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestCloudSchedulerListJobs(t *testing.T) { var nextPageToken string = "" var jobsElement *schedulerpb.Job = &schedulerpb.Job{} var jobs = []*schedulerpb.Job{jobsElement} var expectedResponse = &schedulerpb.ListJobsResponse{ NextPageToken: nextPageToken, Jobs: jobs, } mockCloudScheduler.err = nil mockCloudScheduler.reqs = nil mockCloudScheduler.resps = append(mockCloudScheduler.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &schedulerpb.ListJobsRequest{ Parent: formattedParent, } c, err := NewCloudSchedulerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListJobs(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockCloudScheduler.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Jobs[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudSchedulerListJobsError(t *testing.T) { errCode := codes.PermissionDenied mockCloudScheduler.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &schedulerpb.ListJobsRequest{ Parent: formattedParent, } c, err := NewCloudSchedulerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListJobs(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudSchedulerGetJob(t *testing.T) { var name2 string = "name2-1052831874" var description string = "description-1724546052" var schedule string = "schedule-697920873" var timeZone string = "timeZone36848094" var expectedResponse = &schedulerpb.Job{ Name: name2, Description: description, Schedule: schedule, TimeZone: timeZone, } mockCloudScheduler.err = nil mockCloudScheduler.reqs = nil mockCloudScheduler.resps = append(mockCloudScheduler.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/jobs/%s", "[PROJECT]", "[LOCATION]", "[JOB]") var request = &schedulerpb.GetJobRequest{ Name: formattedName, } c, err := NewCloudSchedulerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetJob(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudScheduler.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudSchedulerGetJobError(t *testing.T) { errCode := codes.PermissionDenied mockCloudScheduler.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/jobs/%s", "[PROJECT]", "[LOCATION]", "[JOB]") var request = &schedulerpb.GetJobRequest{ Name: formattedName, } c, err := NewCloudSchedulerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetJob(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudSchedulerCreateJob(t *testing.T) { var name string = "name3373707" var description string = "description-1724546052" var schedule string = "schedule-697920873" var timeZone string = "timeZone36848094" var expectedResponse = &schedulerpb.Job{ Name: name, Description: description, Schedule: schedule, TimeZone: timeZone, } mockCloudScheduler.err = nil mockCloudScheduler.reqs = nil mockCloudScheduler.resps = append(mockCloudScheduler.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var job *schedulerpb.Job = &schedulerpb.Job{} var request = &schedulerpb.CreateJobRequest{ Parent: formattedParent, Job: job, } c, err := NewCloudSchedulerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateJob(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudScheduler.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudSchedulerCreateJobError(t *testing.T) { errCode := codes.PermissionDenied mockCloudScheduler.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var job *schedulerpb.Job = &schedulerpb.Job{} var request = &schedulerpb.CreateJobRequest{ Parent: formattedParent, Job: job, } c, err := NewCloudSchedulerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateJob(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudSchedulerUpdateJob(t *testing.T) { var name string = "name3373707" var description string = "description-1724546052" var schedule string = "schedule-697920873" var timeZone string = "timeZone36848094" var expectedResponse = &schedulerpb.Job{ Name: name, Description: description, Schedule: schedule, TimeZone: timeZone, } mockCloudScheduler.err = nil mockCloudScheduler.reqs = nil mockCloudScheduler.resps = append(mockCloudScheduler.resps[:0], expectedResponse) var job *schedulerpb.Job = &schedulerpb.Job{} var updateMask *field_maskpb.FieldMask = &field_maskpb.FieldMask{} var request = &schedulerpb.UpdateJobRequest{ Job: job, UpdateMask: updateMask, } c, err := NewCloudSchedulerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateJob(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudScheduler.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudSchedulerUpdateJobError(t *testing.T) { errCode := codes.PermissionDenied mockCloudScheduler.err = gstatus.Error(errCode, "test error") var job *schedulerpb.Job = &schedulerpb.Job{} var updateMask *field_maskpb.FieldMask = &field_maskpb.FieldMask{} var request = &schedulerpb.UpdateJobRequest{ Job: job, UpdateMask: updateMask, } c, err := NewCloudSchedulerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateJob(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudSchedulerDeleteJob(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockCloudScheduler.err = nil mockCloudScheduler.reqs = nil mockCloudScheduler.resps = append(mockCloudScheduler.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/jobs/%s", "[PROJECT]", "[LOCATION]", "[JOB]") var request = &schedulerpb.DeleteJobRequest{ Name: formattedName, } c, err := NewCloudSchedulerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteJob(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudScheduler.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestCloudSchedulerDeleteJobError(t *testing.T) { errCode := codes.PermissionDenied mockCloudScheduler.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/jobs/%s", "[PROJECT]", "[LOCATION]", "[JOB]") var request = &schedulerpb.DeleteJobRequest{ Name: formattedName, } c, err := NewCloudSchedulerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteJob(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestCloudSchedulerPauseJob(t *testing.T) { var name2 string = "name2-1052831874" var description string = "description-1724546052" var schedule string = "schedule-697920873" var timeZone string = "timeZone36848094" var expectedResponse = &schedulerpb.Job{ Name: name2, Description: description, Schedule: schedule, TimeZone: timeZone, } mockCloudScheduler.err = nil mockCloudScheduler.reqs = nil mockCloudScheduler.resps = append(mockCloudScheduler.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/jobs/%s", "[PROJECT]", "[LOCATION]", "[JOB]") var request = &schedulerpb.PauseJobRequest{ Name: formattedName, } c, err := NewCloudSchedulerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.PauseJob(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudScheduler.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudSchedulerPauseJobError(t *testing.T) { errCode := codes.PermissionDenied mockCloudScheduler.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/jobs/%s", "[PROJECT]", "[LOCATION]", "[JOB]") var request = &schedulerpb.PauseJobRequest{ Name: formattedName, } c, err := NewCloudSchedulerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.PauseJob(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudSchedulerResumeJob(t *testing.T) { var name2 string = "name2-1052831874" var description string = "description-1724546052" var schedule string = "schedule-697920873" var timeZone string = "timeZone36848094" var expectedResponse = &schedulerpb.Job{ Name: name2, Description: description, Schedule: schedule, TimeZone: timeZone, } mockCloudScheduler.err = nil mockCloudScheduler.reqs = nil mockCloudScheduler.resps = append(mockCloudScheduler.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/jobs/%s", "[PROJECT]", "[LOCATION]", "[JOB]") var request = &schedulerpb.ResumeJobRequest{ Name: formattedName, } c, err := NewCloudSchedulerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ResumeJob(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudScheduler.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudSchedulerResumeJobError(t *testing.T) { errCode := codes.PermissionDenied mockCloudScheduler.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/jobs/%s", "[PROJECT]", "[LOCATION]", "[JOB]") var request = &schedulerpb.ResumeJobRequest{ Name: formattedName, } c, err := NewCloudSchedulerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ResumeJob(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudSchedulerRunJob(t *testing.T) { var name2 string = "name2-1052831874" var description string = "description-1724546052" var schedule string = "schedule-697920873" var timeZone string = "timeZone36848094" var expectedResponse = &schedulerpb.Job{ Name: name2, Description: description, Schedule: schedule, TimeZone: timeZone, } mockCloudScheduler.err = nil mockCloudScheduler.reqs = nil mockCloudScheduler.resps = append(mockCloudScheduler.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/jobs/%s", "[PROJECT]", "[LOCATION]", "[JOB]") var request = &schedulerpb.RunJobRequest{ Name: formattedName, } c, err := NewCloudSchedulerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.RunJob(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudScheduler.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudSchedulerRunJobError(t *testing.T) { errCode := codes.PermissionDenied mockCloudScheduler.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/jobs/%s", "[PROJECT]", "[LOCATION]", "[JOB]") var request = &schedulerpb.RunJobRequest{ Name: formattedName, } c, err := NewCloudSchedulerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.RunJob(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/scheduler/apiv1beta1/000077500000000000000000000000001356504100700205035ustar00rootroot00000000000000google-cloud-go-0.49.0/scheduler/apiv1beta1/.repo-metadata.json000066400000000000000000000006651356504100700242060ustar00rootroot00000000000000{ "name": "scheduler", "name_pretty": "Cloud Scheduler", "product_documentation": "https://cloud.google.com/scheduler", "client_documentation": "https://godoc.org/cloud.google.com/go/scheduler/apiv1beta1", "release_level": "beta", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go/scheduler/apiv1", "api_id": "cloudscheduler.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/scheduler/apiv1beta1/cloud_scheduler_client.go000066400000000000000000000350151356504100700255400ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go_gapic. DO NOT EDIT. package scheduler import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" schedulerpb "google.golang.org/genproto/googleapis/cloud/scheduler/v1beta1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // CloudSchedulerCallOptions contains the retry settings for each method of CloudSchedulerClient. type CloudSchedulerCallOptions struct { ListJobs []gax.CallOption GetJob []gax.CallOption CreateJob []gax.CallOption UpdateJob []gax.CallOption DeleteJob []gax.CallOption PauseJob []gax.CallOption ResumeJob []gax.CallOption RunJob []gax.CallOption } func defaultCloudSchedulerClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("cloudscheduler.googleapis.com:443"), option.WithGRPCDialOption(grpc.WithDisableServiceConfig()), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultCloudSchedulerCallOptions() *CloudSchedulerCallOptions { return &CloudSchedulerCallOptions{ ListJobs: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, GetJob: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, CreateJob: []gax.CallOption{}, UpdateJob: []gax.CallOption{}, DeleteJob: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, PauseJob: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, ResumeJob: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, RunJob: []gax.CallOption{}, } } // CloudSchedulerClient is a client for interacting with Cloud Scheduler API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type CloudSchedulerClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. cloudSchedulerClient schedulerpb.CloudSchedulerClient // The call options for this service. CallOptions *CloudSchedulerCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewCloudSchedulerClient creates a new cloud scheduler client. // // The Cloud Scheduler API allows external entities to reliably // schedule asynchronous jobs. func NewCloudSchedulerClient(ctx context.Context, opts ...option.ClientOption) (*CloudSchedulerClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultCloudSchedulerClientOptions(), opts...)...) if err != nil { return nil, err } c := &CloudSchedulerClient{ conn: conn, CallOptions: defaultCloudSchedulerCallOptions(), cloudSchedulerClient: schedulerpb.NewCloudSchedulerClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *CloudSchedulerClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *CloudSchedulerClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *CloudSchedulerClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // ListJobs lists jobs. func (c *CloudSchedulerClient) ListJobs(ctx context.Context, req *schedulerpb.ListJobsRequest, opts ...gax.CallOption) *JobIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListJobs[0:len(c.CallOptions.ListJobs):len(c.CallOptions.ListJobs)], opts...) it := &JobIterator{} req = proto.Clone(req).(*schedulerpb.ListJobsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*schedulerpb.Job, string, error) { var resp *schedulerpb.ListJobsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.cloudSchedulerClient.ListJobs(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } it.Response = resp return resp.Jobs, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetJob gets a job. func (c *CloudSchedulerClient) GetJob(ctx context.Context, req *schedulerpb.GetJobRequest, opts ...gax.CallOption) (*schedulerpb.Job, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetJob[0:len(c.CallOptions.GetJob):len(c.CallOptions.GetJob)], opts...) var resp *schedulerpb.Job err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.cloudSchedulerClient.GetJob(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateJob creates a job. func (c *CloudSchedulerClient) CreateJob(ctx context.Context, req *schedulerpb.CreateJobRequest, opts ...gax.CallOption) (*schedulerpb.Job, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateJob[0:len(c.CallOptions.CreateJob):len(c.CallOptions.CreateJob)], opts...) var resp *schedulerpb.Job err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.cloudSchedulerClient.CreateJob(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateJob updates a job. // // If successful, the updated [Job][google.cloud.scheduler.v1beta1.Job] is returned. If the job does // not exist, NOT_FOUND is returned. // // If UpdateJob does not successfully return, it is possible for the // job to be in an [Job.State.UPDATE_FAILED][google.cloud.scheduler.v1beta1.Job.State.UPDATE_FAILED] state. A job in this state may // not be executed. If this happens, retry the UpdateJob request // until a successful response is received. func (c *CloudSchedulerClient) UpdateJob(ctx context.Context, req *schedulerpb.UpdateJobRequest, opts ...gax.CallOption) (*schedulerpb.Job, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.UpdateJob[0:len(c.CallOptions.UpdateJob):len(c.CallOptions.UpdateJob)], opts...) var resp *schedulerpb.Job err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.cloudSchedulerClient.UpdateJob(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteJob deletes a job. func (c *CloudSchedulerClient) DeleteJob(ctx context.Context, req *schedulerpb.DeleteJobRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteJob[0:len(c.CallOptions.DeleteJob):len(c.CallOptions.DeleteJob)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.cloudSchedulerClient.DeleteJob(ctx, req, settings.GRPC...) return err }, opts...) return err } // PauseJob pauses a job. // // If a job is paused then the system will stop executing the job // until it is re-enabled via [ResumeJob][google.cloud.scheduler.v1beta1.CloudScheduler.ResumeJob]. The // state of the job is stored in [state][google.cloud.scheduler.v1beta1.Job.state]; if paused it // will be set to [Job.State.PAUSED][google.cloud.scheduler.v1beta1.Job.State.PAUSED]. A job must be in [Job.State.ENABLED][google.cloud.scheduler.v1beta1.Job.State.ENABLED] // to be paused. func (c *CloudSchedulerClient) PauseJob(ctx context.Context, req *schedulerpb.PauseJobRequest, opts ...gax.CallOption) (*schedulerpb.Job, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.PauseJob[0:len(c.CallOptions.PauseJob):len(c.CallOptions.PauseJob)], opts...) var resp *schedulerpb.Job err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.cloudSchedulerClient.PauseJob(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ResumeJob resume a job. // // This method reenables a job after it has been [Job.State.PAUSED][google.cloud.scheduler.v1beta1.Job.State.PAUSED]. The // state of a job is stored in [Job.state][google.cloud.scheduler.v1beta1.Job.state]; after calling this method it // will be set to [Job.State.ENABLED][google.cloud.scheduler.v1beta1.Job.State.ENABLED]. A job must be in // [Job.State.PAUSED][google.cloud.scheduler.v1beta1.Job.State.PAUSED] to be resumed. func (c *CloudSchedulerClient) ResumeJob(ctx context.Context, req *schedulerpb.ResumeJobRequest, opts ...gax.CallOption) (*schedulerpb.Job, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ResumeJob[0:len(c.CallOptions.ResumeJob):len(c.CallOptions.ResumeJob)], opts...) var resp *schedulerpb.Job err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.cloudSchedulerClient.ResumeJob(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // RunJob forces a job to run now. // // When this method is called, Cloud Scheduler will dispatch the job, even // if the job is already running. func (c *CloudSchedulerClient) RunJob(ctx context.Context, req *schedulerpb.RunJobRequest, opts ...gax.CallOption) (*schedulerpb.Job, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.RunJob[0:len(c.CallOptions.RunJob):len(c.CallOptions.RunJob)], opts...) var resp *schedulerpb.Job err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.cloudSchedulerClient.RunJob(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // JobIterator manages a stream of *schedulerpb.Job. type JobIterator struct { items []*schedulerpb.Job pageInfo *iterator.PageInfo nextFunc func() error // Response is the raw response for the current page. // It must be cast to the RPC response type. // Calling Next() or InternalFetch() updates this value. Response interface{} // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*schedulerpb.Job, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *JobIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *JobIterator) Next() (*schedulerpb.Job, error) { var item *schedulerpb.Job if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *JobIterator) bufLen() int { return len(it.items) } func (it *JobIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/scheduler/apiv1beta1/cloud_scheduler_client_example_test.go000066400000000000000000000110661356504100700303120ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go_gapic. DO NOT EDIT. package scheduler_test import ( "context" scheduler "cloud.google.com/go/scheduler/apiv1beta1" "google.golang.org/api/iterator" schedulerpb "google.golang.org/genproto/googleapis/cloud/scheduler/v1beta1" ) func ExampleNewCloudSchedulerClient() { ctx := context.Background() c, err := scheduler.NewCloudSchedulerClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleCloudSchedulerClient_ListJobs() { // import schedulerpb "google.golang.org/genproto/googleapis/cloud/scheduler/v1beta1" // import "google.golang.org/api/iterator" ctx := context.Background() c, err := scheduler.NewCloudSchedulerClient(ctx) if err != nil { // TODO: Handle error. } req := &schedulerpb.ListJobsRequest{ // TODO: Fill request struct fields. } it := c.ListJobs(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleCloudSchedulerClient_GetJob() { // import schedulerpb "google.golang.org/genproto/googleapis/cloud/scheduler/v1beta1" ctx := context.Background() c, err := scheduler.NewCloudSchedulerClient(ctx) if err != nil { // TODO: Handle error. } req := &schedulerpb.GetJobRequest{ // TODO: Fill request struct fields. } resp, err := c.GetJob(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleCloudSchedulerClient_CreateJob() { // import schedulerpb "google.golang.org/genproto/googleapis/cloud/scheduler/v1beta1" ctx := context.Background() c, err := scheduler.NewCloudSchedulerClient(ctx) if err != nil { // TODO: Handle error. } req := &schedulerpb.CreateJobRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateJob(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleCloudSchedulerClient_UpdateJob() { // import schedulerpb "google.golang.org/genproto/googleapis/cloud/scheduler/v1beta1" ctx := context.Background() c, err := scheduler.NewCloudSchedulerClient(ctx) if err != nil { // TODO: Handle error. } req := &schedulerpb.UpdateJobRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateJob(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleCloudSchedulerClient_DeleteJob() { ctx := context.Background() c, err := scheduler.NewCloudSchedulerClient(ctx) if err != nil { // TODO: Handle error. } req := &schedulerpb.DeleteJobRequest{ // TODO: Fill request struct fields. } err = c.DeleteJob(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleCloudSchedulerClient_PauseJob() { // import schedulerpb "google.golang.org/genproto/googleapis/cloud/scheduler/v1beta1" ctx := context.Background() c, err := scheduler.NewCloudSchedulerClient(ctx) if err != nil { // TODO: Handle error. } req := &schedulerpb.PauseJobRequest{ // TODO: Fill request struct fields. } resp, err := c.PauseJob(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleCloudSchedulerClient_ResumeJob() { // import schedulerpb "google.golang.org/genproto/googleapis/cloud/scheduler/v1beta1" ctx := context.Background() c, err := scheduler.NewCloudSchedulerClient(ctx) if err != nil { // TODO: Handle error. } req := &schedulerpb.ResumeJobRequest{ // TODO: Fill request struct fields. } resp, err := c.ResumeJob(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleCloudSchedulerClient_RunJob() { // import schedulerpb "google.golang.org/genproto/googleapis/cloud/scheduler/v1beta1" ctx := context.Background() c, err := scheduler.NewCloudSchedulerClient(ctx) if err != nil { // TODO: Handle error. } req := &schedulerpb.RunJobRequest{ // TODO: Fill request struct fields. } resp, err := c.RunJob(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/scheduler/apiv1beta1/doc.go000066400000000000000000000053521356504100700216040ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go_gapic. DO NOT EDIT. // Package scheduler is an auto-generated package for the // Cloud Scheduler API. // // Creates and manages jobs run on a regular recurring schedule. // // NOTE: This package is in beta. It is not stable, and may be subject to changes. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package scheduler // import "cloud.google.com/go/scheduler/apiv1beta1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) const versionClient = "20191115" func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return !strings.ContainsRune("0123456789.", r) } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } google-cloud-go-0.49.0/scheduler/apiv1beta1/mock_test.go000066400000000000000000000475511356504100700230360ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package scheduler import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" "google.golang.org/api/option" schedulerpb "google.golang.org/genproto/googleapis/cloud/scheduler/v1beta1" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockCloudSchedulerServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. schedulerpb.CloudSchedulerServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockCloudSchedulerServer) ListJobs(ctx context.Context, req *schedulerpb.ListJobsRequest) (*schedulerpb.ListJobsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*schedulerpb.ListJobsResponse), nil } func (s *mockCloudSchedulerServer) GetJob(ctx context.Context, req *schedulerpb.GetJobRequest) (*schedulerpb.Job, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*schedulerpb.Job), nil } func (s *mockCloudSchedulerServer) CreateJob(ctx context.Context, req *schedulerpb.CreateJobRequest) (*schedulerpb.Job, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*schedulerpb.Job), nil } func (s *mockCloudSchedulerServer) UpdateJob(ctx context.Context, req *schedulerpb.UpdateJobRequest) (*schedulerpb.Job, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*schedulerpb.Job), nil } func (s *mockCloudSchedulerServer) DeleteJob(ctx context.Context, req *schedulerpb.DeleteJobRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockCloudSchedulerServer) PauseJob(ctx context.Context, req *schedulerpb.PauseJobRequest) (*schedulerpb.Job, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*schedulerpb.Job), nil } func (s *mockCloudSchedulerServer) ResumeJob(ctx context.Context, req *schedulerpb.ResumeJobRequest) (*schedulerpb.Job, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*schedulerpb.Job), nil } func (s *mockCloudSchedulerServer) RunJob(ctx context.Context, req *schedulerpb.RunJobRequest) (*schedulerpb.Job, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*schedulerpb.Job), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockCloudScheduler mockCloudSchedulerServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() schedulerpb.RegisterCloudSchedulerServer(serv, &mockCloudScheduler) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestCloudSchedulerListJobs(t *testing.T) { var nextPageToken string = "" var jobsElement *schedulerpb.Job = &schedulerpb.Job{} var jobs = []*schedulerpb.Job{jobsElement} var expectedResponse = &schedulerpb.ListJobsResponse{ NextPageToken: nextPageToken, Jobs: jobs, } mockCloudScheduler.err = nil mockCloudScheduler.reqs = nil mockCloudScheduler.resps = append(mockCloudScheduler.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &schedulerpb.ListJobsRequest{ Parent: formattedParent, } c, err := NewCloudSchedulerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListJobs(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockCloudScheduler.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Jobs[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudSchedulerListJobsError(t *testing.T) { errCode := codes.PermissionDenied mockCloudScheduler.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &schedulerpb.ListJobsRequest{ Parent: formattedParent, } c, err := NewCloudSchedulerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListJobs(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudSchedulerGetJob(t *testing.T) { var name2 string = "name2-1052831874" var description string = "description-1724546052" var schedule string = "schedule-697920873" var timeZone string = "timeZone36848094" var expectedResponse = &schedulerpb.Job{ Name: name2, Description: description, Schedule: schedule, TimeZone: timeZone, } mockCloudScheduler.err = nil mockCloudScheduler.reqs = nil mockCloudScheduler.resps = append(mockCloudScheduler.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/jobs/%s", "[PROJECT]", "[LOCATION]", "[JOB]") var request = &schedulerpb.GetJobRequest{ Name: formattedName, } c, err := NewCloudSchedulerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetJob(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudScheduler.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudSchedulerGetJobError(t *testing.T) { errCode := codes.PermissionDenied mockCloudScheduler.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/jobs/%s", "[PROJECT]", "[LOCATION]", "[JOB]") var request = &schedulerpb.GetJobRequest{ Name: formattedName, } c, err := NewCloudSchedulerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetJob(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudSchedulerCreateJob(t *testing.T) { var name string = "name3373707" var description string = "description-1724546052" var schedule string = "schedule-697920873" var timeZone string = "timeZone36848094" var expectedResponse = &schedulerpb.Job{ Name: name, Description: description, Schedule: schedule, TimeZone: timeZone, } mockCloudScheduler.err = nil mockCloudScheduler.reqs = nil mockCloudScheduler.resps = append(mockCloudScheduler.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var job *schedulerpb.Job = &schedulerpb.Job{} var request = &schedulerpb.CreateJobRequest{ Parent: formattedParent, Job: job, } c, err := NewCloudSchedulerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateJob(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudScheduler.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudSchedulerCreateJobError(t *testing.T) { errCode := codes.PermissionDenied mockCloudScheduler.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var job *schedulerpb.Job = &schedulerpb.Job{} var request = &schedulerpb.CreateJobRequest{ Parent: formattedParent, Job: job, } c, err := NewCloudSchedulerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateJob(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudSchedulerUpdateJob(t *testing.T) { var name string = "name3373707" var description string = "description-1724546052" var schedule string = "schedule-697920873" var timeZone string = "timeZone36848094" var expectedResponse = &schedulerpb.Job{ Name: name, Description: description, Schedule: schedule, TimeZone: timeZone, } mockCloudScheduler.err = nil mockCloudScheduler.reqs = nil mockCloudScheduler.resps = append(mockCloudScheduler.resps[:0], expectedResponse) var job *schedulerpb.Job = &schedulerpb.Job{} var request = &schedulerpb.UpdateJobRequest{ Job: job, } c, err := NewCloudSchedulerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateJob(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudScheduler.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudSchedulerUpdateJobError(t *testing.T) { errCode := codes.PermissionDenied mockCloudScheduler.err = gstatus.Error(errCode, "test error") var job *schedulerpb.Job = &schedulerpb.Job{} var request = &schedulerpb.UpdateJobRequest{ Job: job, } c, err := NewCloudSchedulerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateJob(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudSchedulerDeleteJob(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockCloudScheduler.err = nil mockCloudScheduler.reqs = nil mockCloudScheduler.resps = append(mockCloudScheduler.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/jobs/%s", "[PROJECT]", "[LOCATION]", "[JOB]") var request = &schedulerpb.DeleteJobRequest{ Name: formattedName, } c, err := NewCloudSchedulerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteJob(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudScheduler.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestCloudSchedulerDeleteJobError(t *testing.T) { errCode := codes.PermissionDenied mockCloudScheduler.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/jobs/%s", "[PROJECT]", "[LOCATION]", "[JOB]") var request = &schedulerpb.DeleteJobRequest{ Name: formattedName, } c, err := NewCloudSchedulerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteJob(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestCloudSchedulerPauseJob(t *testing.T) { var name2 string = "name2-1052831874" var description string = "description-1724546052" var schedule string = "schedule-697920873" var timeZone string = "timeZone36848094" var expectedResponse = &schedulerpb.Job{ Name: name2, Description: description, Schedule: schedule, TimeZone: timeZone, } mockCloudScheduler.err = nil mockCloudScheduler.reqs = nil mockCloudScheduler.resps = append(mockCloudScheduler.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/jobs/%s", "[PROJECT]", "[LOCATION]", "[JOB]") var request = &schedulerpb.PauseJobRequest{ Name: formattedName, } c, err := NewCloudSchedulerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.PauseJob(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudScheduler.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudSchedulerPauseJobError(t *testing.T) { errCode := codes.PermissionDenied mockCloudScheduler.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/jobs/%s", "[PROJECT]", "[LOCATION]", "[JOB]") var request = &schedulerpb.PauseJobRequest{ Name: formattedName, } c, err := NewCloudSchedulerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.PauseJob(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudSchedulerResumeJob(t *testing.T) { var name2 string = "name2-1052831874" var description string = "description-1724546052" var schedule string = "schedule-697920873" var timeZone string = "timeZone36848094" var expectedResponse = &schedulerpb.Job{ Name: name2, Description: description, Schedule: schedule, TimeZone: timeZone, } mockCloudScheduler.err = nil mockCloudScheduler.reqs = nil mockCloudScheduler.resps = append(mockCloudScheduler.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/jobs/%s", "[PROJECT]", "[LOCATION]", "[JOB]") var request = &schedulerpb.ResumeJobRequest{ Name: formattedName, } c, err := NewCloudSchedulerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ResumeJob(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudScheduler.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudSchedulerResumeJobError(t *testing.T) { errCode := codes.PermissionDenied mockCloudScheduler.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/jobs/%s", "[PROJECT]", "[LOCATION]", "[JOB]") var request = &schedulerpb.ResumeJobRequest{ Name: formattedName, } c, err := NewCloudSchedulerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ResumeJob(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCloudSchedulerRunJob(t *testing.T) { var name2 string = "name2-1052831874" var description string = "description-1724546052" var schedule string = "schedule-697920873" var timeZone string = "timeZone36848094" var expectedResponse = &schedulerpb.Job{ Name: name2, Description: description, Schedule: schedule, TimeZone: timeZone, } mockCloudScheduler.err = nil mockCloudScheduler.reqs = nil mockCloudScheduler.resps = append(mockCloudScheduler.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/jobs/%s", "[PROJECT]", "[LOCATION]", "[JOB]") var request = &schedulerpb.RunJobRequest{ Name: formattedName, } c, err := NewCloudSchedulerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.RunJob(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCloudScheduler.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCloudSchedulerRunJobError(t *testing.T) { errCode := codes.PermissionDenied mockCloudScheduler.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/jobs/%s", "[PROJECT]", "[LOCATION]", "[JOB]") var request = &schedulerpb.RunJobRequest{ Name: formattedName, } c, err := NewCloudSchedulerClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.RunJob(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/securitycenter/000077500000000000000000000000001356504100700176405ustar00rootroot00000000000000google-cloud-go-0.49.0/securitycenter/apiv1/000077500000000000000000000000001356504100700206605ustar00rootroot00000000000000google-cloud-go-0.49.0/securitycenter/apiv1/doc.go000066400000000000000000000054601356504100700217610ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package securitycenter is an auto-generated package for the // Cloud Security Command Center API. // // NOTE: This package is in alpha. It is not stable, and is likely to change. // // Cloud Security Command Center API provides access to temporal views of // assets and findings within an organization. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package securitycenter // import "cloud.google.com/go/securitycenter/apiv1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191115" google-cloud-go-0.49.0/securitycenter/apiv1/mock_test.go000066400000000000000000001334271356504100700232110ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package securitycenter import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" timestamppb "github.com/golang/protobuf/ptypes/timestamp" "google.golang.org/api/option" securitycenterpb "google.golang.org/genproto/googleapis/cloud/securitycenter/v1" iampb "google.golang.org/genproto/googleapis/iam/v1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockSecurityCenterServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. securitycenterpb.SecurityCenterServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockSecurityCenterServer) CreateSource(ctx context.Context, req *securitycenterpb.CreateSourceRequest) (*securitycenterpb.Source, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*securitycenterpb.Source), nil } func (s *mockSecurityCenterServer) CreateFinding(ctx context.Context, req *securitycenterpb.CreateFindingRequest) (*securitycenterpb.Finding, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*securitycenterpb.Finding), nil } func (s *mockSecurityCenterServer) GetIamPolicy(ctx context.Context, req *iampb.GetIamPolicyRequest) (*iampb.Policy, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iampb.Policy), nil } func (s *mockSecurityCenterServer) GetOrganizationSettings(ctx context.Context, req *securitycenterpb.GetOrganizationSettingsRequest) (*securitycenterpb.OrganizationSettings, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*securitycenterpb.OrganizationSettings), nil } func (s *mockSecurityCenterServer) GetSource(ctx context.Context, req *securitycenterpb.GetSourceRequest) (*securitycenterpb.Source, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*securitycenterpb.Source), nil } func (s *mockSecurityCenterServer) GroupAssets(ctx context.Context, req *securitycenterpb.GroupAssetsRequest) (*securitycenterpb.GroupAssetsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*securitycenterpb.GroupAssetsResponse), nil } func (s *mockSecurityCenterServer) GroupFindings(ctx context.Context, req *securitycenterpb.GroupFindingsRequest) (*securitycenterpb.GroupFindingsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*securitycenterpb.GroupFindingsResponse), nil } func (s *mockSecurityCenterServer) ListAssets(ctx context.Context, req *securitycenterpb.ListAssetsRequest) (*securitycenterpb.ListAssetsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*securitycenterpb.ListAssetsResponse), nil } func (s *mockSecurityCenterServer) ListFindings(ctx context.Context, req *securitycenterpb.ListFindingsRequest) (*securitycenterpb.ListFindingsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*securitycenterpb.ListFindingsResponse), nil } func (s *mockSecurityCenterServer) ListSources(ctx context.Context, req *securitycenterpb.ListSourcesRequest) (*securitycenterpb.ListSourcesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*securitycenterpb.ListSourcesResponse), nil } func (s *mockSecurityCenterServer) RunAssetDiscovery(ctx context.Context, req *securitycenterpb.RunAssetDiscoveryRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockSecurityCenterServer) SetFindingState(ctx context.Context, req *securitycenterpb.SetFindingStateRequest) (*securitycenterpb.Finding, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*securitycenterpb.Finding), nil } func (s *mockSecurityCenterServer) SetIamPolicy(ctx context.Context, req *iampb.SetIamPolicyRequest) (*iampb.Policy, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iampb.Policy), nil } func (s *mockSecurityCenterServer) TestIamPermissions(ctx context.Context, req *iampb.TestIamPermissionsRequest) (*iampb.TestIamPermissionsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iampb.TestIamPermissionsResponse), nil } func (s *mockSecurityCenterServer) UpdateFinding(ctx context.Context, req *securitycenterpb.UpdateFindingRequest) (*securitycenterpb.Finding, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*securitycenterpb.Finding), nil } func (s *mockSecurityCenterServer) UpdateOrganizationSettings(ctx context.Context, req *securitycenterpb.UpdateOrganizationSettingsRequest) (*securitycenterpb.OrganizationSettings, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*securitycenterpb.OrganizationSettings), nil } func (s *mockSecurityCenterServer) UpdateSource(ctx context.Context, req *securitycenterpb.UpdateSourceRequest) (*securitycenterpb.Source, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*securitycenterpb.Source), nil } func (s *mockSecurityCenterServer) UpdateSecurityMarks(ctx context.Context, req *securitycenterpb.UpdateSecurityMarksRequest) (*securitycenterpb.SecurityMarks, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*securitycenterpb.SecurityMarks), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockSecurityCenter mockSecurityCenterServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() securitycenterpb.RegisterSecurityCenterServer(serv, &mockSecurityCenter) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestSecurityCenterCreateSource(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var description string = "description-1724546052" var expectedResponse = &securitycenterpb.Source{ Name: name, DisplayName: displayName, Description: description, } mockSecurityCenter.err = nil mockSecurityCenter.reqs = nil mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]") var source *securitycenterpb.Source = &securitycenterpb.Source{} var request = &securitycenterpb.CreateSourceRequest{ Parent: formattedParent, Source: source, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateSource(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSecurityCenter.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSecurityCenterCreateSourceError(t *testing.T) { errCode := codes.PermissionDenied mockSecurityCenter.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]") var source *securitycenterpb.Source = &securitycenterpb.Source{} var request = &securitycenterpb.CreateSourceRequest{ Parent: formattedParent, Source: source, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateSource(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSecurityCenterCreateFinding(t *testing.T) { var name string = "name3373707" var parent2 string = "parent21175163357" var resourceName string = "resourceName979421212" var category string = "category50511102" var externalUri string = "externalUri-1385596168" var expectedResponse = &securitycenterpb.Finding{ Name: name, Parent: parent2, ResourceName: resourceName, Category: category, ExternalUri: externalUri, } mockSecurityCenter.err = nil mockSecurityCenter.reqs = nil mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]") var findingId string = "findingId728776081" var finding *securitycenterpb.Finding = &securitycenterpb.Finding{} var request = &securitycenterpb.CreateFindingRequest{ Parent: formattedParent, FindingId: findingId, Finding: finding, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateFinding(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSecurityCenter.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSecurityCenterCreateFindingError(t *testing.T) { errCode := codes.PermissionDenied mockSecurityCenter.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]") var findingId string = "findingId728776081" var finding *securitycenterpb.Finding = &securitycenterpb.Finding{} var request = &securitycenterpb.CreateFindingRequest{ Parent: formattedParent, FindingId: findingId, Finding: finding, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateFinding(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSecurityCenterGetIamPolicy(t *testing.T) { var version int32 = 351608024 var etag []byte = []byte("21") var expectedResponse = &iampb.Policy{ Version: version, Etag: etag, } mockSecurityCenter.err = nil mockSecurityCenter.reqs = nil mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], expectedResponse) var formattedResource string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]") var request = &iampb.GetIamPolicyRequest{ Resource: formattedResource, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetIamPolicy(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSecurityCenter.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSecurityCenterGetIamPolicyError(t *testing.T) { errCode := codes.PermissionDenied mockSecurityCenter.err = gstatus.Error(errCode, "test error") var formattedResource string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]") var request = &iampb.GetIamPolicyRequest{ Resource: formattedResource, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetIamPolicy(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSecurityCenterGetOrganizationSettings(t *testing.T) { var name2 string = "name2-1052831874" var enableAssetDiscovery bool = false var expectedResponse = &securitycenterpb.OrganizationSettings{ Name: name2, EnableAssetDiscovery: enableAssetDiscovery, } mockSecurityCenter.err = nil mockSecurityCenter.reqs = nil mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("organizations/%s/organizationSettings", "[ORGANIZATION]") var request = &securitycenterpb.GetOrganizationSettingsRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetOrganizationSettings(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSecurityCenter.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSecurityCenterGetOrganizationSettingsError(t *testing.T) { errCode := codes.PermissionDenied mockSecurityCenter.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("organizations/%s/organizationSettings", "[ORGANIZATION]") var request = &securitycenterpb.GetOrganizationSettingsRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetOrganizationSettings(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSecurityCenterGetSource(t *testing.T) { var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var description string = "description-1724546052" var expectedResponse = &securitycenterpb.Source{ Name: name2, DisplayName: displayName, Description: description, } mockSecurityCenter.err = nil mockSecurityCenter.reqs = nil mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]") var request = &securitycenterpb.GetSourceRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetSource(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSecurityCenter.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSecurityCenterGetSourceError(t *testing.T) { errCode := codes.PermissionDenied mockSecurityCenter.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]") var request = &securitycenterpb.GetSourceRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetSource(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSecurityCenterGroupAssets(t *testing.T) { var nextPageToken string = "" var totalSize int32 = 705419236 var groupByResultsElement *securitycenterpb.GroupResult = &securitycenterpb.GroupResult{} var groupByResults = []*securitycenterpb.GroupResult{groupByResultsElement} var expectedResponse = &securitycenterpb.GroupAssetsResponse{ NextPageToken: nextPageToken, TotalSize: totalSize, GroupByResults: groupByResults, } mockSecurityCenter.err = nil mockSecurityCenter.reqs = nil mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]") var groupBy string = "groupBy506361367" var request = &securitycenterpb.GroupAssetsRequest{ Parent: formattedParent, GroupBy: groupBy, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GroupAssets(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockSecurityCenter.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.GroupByResults[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSecurityCenterGroupAssetsError(t *testing.T) { errCode := codes.PermissionDenied mockSecurityCenter.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]") var groupBy string = "groupBy506361367" var request = &securitycenterpb.GroupAssetsRequest{ Parent: formattedParent, GroupBy: groupBy, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GroupAssets(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSecurityCenterGroupFindings(t *testing.T) { var nextPageToken string = "" var totalSize int32 = 705419236 var groupByResultsElement *securitycenterpb.GroupResult = &securitycenterpb.GroupResult{} var groupByResults = []*securitycenterpb.GroupResult{groupByResultsElement} var expectedResponse = &securitycenterpb.GroupFindingsResponse{ NextPageToken: nextPageToken, TotalSize: totalSize, GroupByResults: groupByResults, } mockSecurityCenter.err = nil mockSecurityCenter.reqs = nil mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]") var groupBy string = "groupBy506361367" var request = &securitycenterpb.GroupFindingsRequest{ Parent: formattedParent, GroupBy: groupBy, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GroupFindings(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockSecurityCenter.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.GroupByResults[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSecurityCenterGroupFindingsError(t *testing.T) { errCode := codes.PermissionDenied mockSecurityCenter.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]") var groupBy string = "groupBy506361367" var request = &securitycenterpb.GroupFindingsRequest{ Parent: formattedParent, GroupBy: groupBy, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GroupFindings(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSecurityCenterListAssets(t *testing.T) { var nextPageToken string = "" var totalSize int32 = 705419236 var listAssetsResultsElement *securitycenterpb.ListAssetsResponse_ListAssetsResult = &securitycenterpb.ListAssetsResponse_ListAssetsResult{} var listAssetsResults = []*securitycenterpb.ListAssetsResponse_ListAssetsResult{listAssetsResultsElement} var expectedResponse = &securitycenterpb.ListAssetsResponse{ NextPageToken: nextPageToken, TotalSize: totalSize, ListAssetsResults: listAssetsResults, } mockSecurityCenter.err = nil mockSecurityCenter.reqs = nil mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]") var request = &securitycenterpb.ListAssetsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListAssets(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockSecurityCenter.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.ListAssetsResults[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSecurityCenterListAssetsError(t *testing.T) { errCode := codes.PermissionDenied mockSecurityCenter.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]") var request = &securitycenterpb.ListAssetsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListAssets(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSecurityCenterListFindings(t *testing.T) { var nextPageToken string = "" var totalSize int32 = 705419236 var listFindingsResultsElement *securitycenterpb.ListFindingsResponse_ListFindingsResult = &securitycenterpb.ListFindingsResponse_ListFindingsResult{} var listFindingsResults = []*securitycenterpb.ListFindingsResponse_ListFindingsResult{listFindingsResultsElement} var expectedResponse = &securitycenterpb.ListFindingsResponse{ NextPageToken: nextPageToken, TotalSize: totalSize, ListFindingsResults: listFindingsResults, } mockSecurityCenter.err = nil mockSecurityCenter.reqs = nil mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]") var request = &securitycenterpb.ListFindingsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListFindings(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockSecurityCenter.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.ListFindingsResults[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSecurityCenterListFindingsError(t *testing.T) { errCode := codes.PermissionDenied mockSecurityCenter.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]") var request = &securitycenterpb.ListFindingsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListFindings(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSecurityCenterListSources(t *testing.T) { var nextPageToken string = "" var sourcesElement *securitycenterpb.Source = &securitycenterpb.Source{} var sources = []*securitycenterpb.Source{sourcesElement} var expectedResponse = &securitycenterpb.ListSourcesResponse{ NextPageToken: nextPageToken, Sources: sources, } mockSecurityCenter.err = nil mockSecurityCenter.reqs = nil mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]") var request = &securitycenterpb.ListSourcesRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListSources(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockSecurityCenter.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Sources[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSecurityCenterListSourcesError(t *testing.T) { errCode := codes.PermissionDenied mockSecurityCenter.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]") var request = &securitycenterpb.ListSourcesRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListSources(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSecurityCenterRunAssetDiscovery(t *testing.T) { var expectedResponse *securitycenterpb.RunAssetDiscoveryResponse = &securitycenterpb.RunAssetDiscoveryResponse{} mockSecurityCenter.err = nil mockSecurityCenter.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]") var request = &securitycenterpb.RunAssetDiscoveryRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.RunAssetDiscovery(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockSecurityCenter.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSecurityCenterRunAssetDiscoveryError(t *testing.T) { errCode := codes.PermissionDenied mockSecurityCenter.err = nil mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]") var request = &securitycenterpb.RunAssetDiscoveryRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.RunAssetDiscovery(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSecurityCenterSetFindingState(t *testing.T) { var name2 string = "name2-1052831874" var parent string = "parent-995424086" var resourceName string = "resourceName979421212" var category string = "category50511102" var externalUri string = "externalUri-1385596168" var expectedResponse = &securitycenterpb.Finding{ Name: name2, Parent: parent, ResourceName: resourceName, Category: category, ExternalUri: externalUri, } mockSecurityCenter.err = nil mockSecurityCenter.reqs = nil mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("organizations/%s/sources/%s/findings/%s", "[ORGANIZATION]", "[SOURCE]", "[FINDING]") var state securitycenterpb.Finding_State = securitycenterpb.Finding_STATE_UNSPECIFIED var startTime *timestamppb.Timestamp = ×tamppb.Timestamp{} var request = &securitycenterpb.SetFindingStateRequest{ Name: formattedName, State: state, StartTime: startTime, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetFindingState(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSecurityCenter.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSecurityCenterSetFindingStateError(t *testing.T) { errCode := codes.PermissionDenied mockSecurityCenter.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("organizations/%s/sources/%s/findings/%s", "[ORGANIZATION]", "[SOURCE]", "[FINDING]") var state securitycenterpb.Finding_State = securitycenterpb.Finding_STATE_UNSPECIFIED var startTime *timestamppb.Timestamp = ×tamppb.Timestamp{} var request = &securitycenterpb.SetFindingStateRequest{ Name: formattedName, State: state, StartTime: startTime, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetFindingState(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSecurityCenterSetIamPolicy(t *testing.T) { var version int32 = 351608024 var etag []byte = []byte("21") var expectedResponse = &iampb.Policy{ Version: version, Etag: etag, } mockSecurityCenter.err = nil mockSecurityCenter.reqs = nil mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], expectedResponse) var formattedResource string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]") var policy *iampb.Policy = &iampb.Policy{} var request = &iampb.SetIamPolicyRequest{ Resource: formattedResource, Policy: policy, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetIamPolicy(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSecurityCenter.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSecurityCenterSetIamPolicyError(t *testing.T) { errCode := codes.PermissionDenied mockSecurityCenter.err = gstatus.Error(errCode, "test error") var formattedResource string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]") var policy *iampb.Policy = &iampb.Policy{} var request = &iampb.SetIamPolicyRequest{ Resource: formattedResource, Policy: policy, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetIamPolicy(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSecurityCenterTestIamPermissions(t *testing.T) { var expectedResponse *iampb.TestIamPermissionsResponse = &iampb.TestIamPermissionsResponse{} mockSecurityCenter.err = nil mockSecurityCenter.reqs = nil mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], expectedResponse) var formattedResource string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]") var permissions []string = nil var request = &iampb.TestIamPermissionsRequest{ Resource: formattedResource, Permissions: permissions, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.TestIamPermissions(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSecurityCenter.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSecurityCenterTestIamPermissionsError(t *testing.T) { errCode := codes.PermissionDenied mockSecurityCenter.err = gstatus.Error(errCode, "test error") var formattedResource string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]") var permissions []string = nil var request = &iampb.TestIamPermissionsRequest{ Resource: formattedResource, Permissions: permissions, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.TestIamPermissions(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSecurityCenterUpdateFinding(t *testing.T) { var name string = "name3373707" var parent string = "parent-995424086" var resourceName string = "resourceName979421212" var category string = "category50511102" var externalUri string = "externalUri-1385596168" var expectedResponse = &securitycenterpb.Finding{ Name: name, Parent: parent, ResourceName: resourceName, Category: category, ExternalUri: externalUri, } mockSecurityCenter.err = nil mockSecurityCenter.reqs = nil mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], expectedResponse) var finding *securitycenterpb.Finding = &securitycenterpb.Finding{} var request = &securitycenterpb.UpdateFindingRequest{ Finding: finding, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateFinding(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSecurityCenter.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSecurityCenterUpdateFindingError(t *testing.T) { errCode := codes.PermissionDenied mockSecurityCenter.err = gstatus.Error(errCode, "test error") var finding *securitycenterpb.Finding = &securitycenterpb.Finding{} var request = &securitycenterpb.UpdateFindingRequest{ Finding: finding, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateFinding(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSecurityCenterUpdateOrganizationSettings(t *testing.T) { var name string = "name3373707" var enableAssetDiscovery bool = false var expectedResponse = &securitycenterpb.OrganizationSettings{ Name: name, EnableAssetDiscovery: enableAssetDiscovery, } mockSecurityCenter.err = nil mockSecurityCenter.reqs = nil mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], expectedResponse) var organizationSettings *securitycenterpb.OrganizationSettings = &securitycenterpb.OrganizationSettings{} var request = &securitycenterpb.UpdateOrganizationSettingsRequest{ OrganizationSettings: organizationSettings, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateOrganizationSettings(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSecurityCenter.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSecurityCenterUpdateOrganizationSettingsError(t *testing.T) { errCode := codes.PermissionDenied mockSecurityCenter.err = gstatus.Error(errCode, "test error") var organizationSettings *securitycenterpb.OrganizationSettings = &securitycenterpb.OrganizationSettings{} var request = &securitycenterpb.UpdateOrganizationSettingsRequest{ OrganizationSettings: organizationSettings, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateOrganizationSettings(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSecurityCenterUpdateSource(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var description string = "description-1724546052" var expectedResponse = &securitycenterpb.Source{ Name: name, DisplayName: displayName, Description: description, } mockSecurityCenter.err = nil mockSecurityCenter.reqs = nil mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], expectedResponse) var source *securitycenterpb.Source = &securitycenterpb.Source{} var request = &securitycenterpb.UpdateSourceRequest{ Source: source, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateSource(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSecurityCenter.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSecurityCenterUpdateSourceError(t *testing.T) { errCode := codes.PermissionDenied mockSecurityCenter.err = gstatus.Error(errCode, "test error") var source *securitycenterpb.Source = &securitycenterpb.Source{} var request = &securitycenterpb.UpdateSourceRequest{ Source: source, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateSource(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSecurityCenterUpdateSecurityMarks(t *testing.T) { var name string = "name3373707" var expectedResponse = &securitycenterpb.SecurityMarks{ Name: name, } mockSecurityCenter.err = nil mockSecurityCenter.reqs = nil mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], expectedResponse) var securityMarks *securitycenterpb.SecurityMarks = &securitycenterpb.SecurityMarks{} var request = &securitycenterpb.UpdateSecurityMarksRequest{ SecurityMarks: securityMarks, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateSecurityMarks(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSecurityCenter.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSecurityCenterUpdateSecurityMarksError(t *testing.T) { errCode := codes.PermissionDenied mockSecurityCenter.err = gstatus.Error(errCode, "test error") var securityMarks *securitycenterpb.SecurityMarks = &securitycenterpb.SecurityMarks{} var request = &securitycenterpb.UpdateSecurityMarksRequest{ SecurityMarks: securityMarks, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateSecurityMarks(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/securitycenter/apiv1/security_center_client.go000066400000000000000000001032761356504100700257650ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package securitycenter import ( "context" "fmt" "math" "net/url" "time" "cloud.google.com/go/longrunning" lroauto "cloud.google.com/go/longrunning/autogen" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" securitycenterpb "google.golang.org/genproto/googleapis/cloud/securitycenter/v1" iampb "google.golang.org/genproto/googleapis/iam/v1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // CallOptions contains the retry settings for each method of Client. type CallOptions struct { CreateSource []gax.CallOption CreateFinding []gax.CallOption GetIamPolicy []gax.CallOption GetOrganizationSettings []gax.CallOption GetSource []gax.CallOption GroupAssets []gax.CallOption GroupFindings []gax.CallOption ListAssets []gax.CallOption ListFindings []gax.CallOption ListSources []gax.CallOption RunAssetDiscovery []gax.CallOption SetFindingState []gax.CallOption SetIamPolicy []gax.CallOption TestIamPermissions []gax.CallOption UpdateFinding []gax.CallOption UpdateOrganizationSettings []gax.CallOption UpdateSource []gax.CallOption UpdateSecurityMarks []gax.CallOption } func defaultClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("securitycenter.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultCallOptions() *CallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &CallOptions{ CreateSource: retry[[2]string{"default", "non_idempotent"}], CreateFinding: retry[[2]string{"default", "non_idempotent"}], GetIamPolicy: retry[[2]string{"default", "idempotent"}], GetOrganizationSettings: retry[[2]string{"default", "idempotent"}], GetSource: retry[[2]string{"default", "idempotent"}], GroupAssets: retry[[2]string{"default", "idempotent"}], GroupFindings: retry[[2]string{"default", "idempotent"}], ListAssets: retry[[2]string{"default", "idempotent"}], ListFindings: retry[[2]string{"default", "idempotent"}], ListSources: retry[[2]string{"default", "idempotent"}], RunAssetDiscovery: retry[[2]string{"default", "non_idempotent"}], SetFindingState: retry[[2]string{"default", "non_idempotent"}], SetIamPolicy: retry[[2]string{"default", "non_idempotent"}], TestIamPermissions: retry[[2]string{"default", "idempotent"}], UpdateFinding: retry[[2]string{"default", "non_idempotent"}], UpdateOrganizationSettings: retry[[2]string{"default", "non_idempotent"}], UpdateSource: retry[[2]string{"default", "non_idempotent"}], UpdateSecurityMarks: retry[[2]string{"default", "non_idempotent"}], } } // Client is a client for interacting with Cloud Security Command Center API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. client securitycenterpb.SecurityCenterClient // LROClient is used internally to handle longrunning operations. // It is exposed so that its CallOptions can be modified if required. // Users should not Close this client. LROClient *lroauto.OperationsClient // The call options for this service. CallOptions *CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewClient creates a new security center client. // // V1 APIs for Security Center service. func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultClientOptions(), opts...)...) if err != nil { return nil, err } c := &Client{ conn: conn, CallOptions: defaultCallOptions(), client: securitycenterpb.NewSecurityCenterClient(conn), } c.setGoogleClientInfo() c.LROClient, err = lroauto.NewOperationsClient(ctx, option.WithGRPCConn(conn)) if err != nil { // This error "should not happen", since we are just reusing old connection // and never actually need to dial. // If this does happen, we could leak conn. However, we cannot close conn: // If the user invoked the function with option.WithGRPCConn, // we would close a connection that's still in use. // TODO(pongad): investigate error conditions. return nil, err } return c, nil } // Connection returns the client's connection to the API service. func (c *Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *Client) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *Client) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // CreateSource creates a source. func (c *Client) CreateSource(ctx context.Context, req *securitycenterpb.CreateSourceRequest, opts ...gax.CallOption) (*securitycenterpb.Source, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateSource[0:len(c.CallOptions.CreateSource):len(c.CallOptions.CreateSource)], opts...) var resp *securitycenterpb.Source err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CreateSource(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateFinding creates a finding. The corresponding source must exist for finding creation // to succeed. func (c *Client) CreateFinding(ctx context.Context, req *securitycenterpb.CreateFindingRequest, opts ...gax.CallOption) (*securitycenterpb.Finding, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateFinding[0:len(c.CallOptions.CreateFinding):len(c.CallOptions.CreateFinding)], opts...) var resp *securitycenterpb.Finding err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CreateFinding(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetIamPolicy gets the access control policy on the specified Source. func (c *Client) GetIamPolicy(ctx context.Context, req *iampb.GetIamPolicyRequest, opts ...gax.CallOption) (*iampb.Policy, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetIamPolicy[0:len(c.CallOptions.GetIamPolicy):len(c.CallOptions.GetIamPolicy)], opts...) var resp *iampb.Policy err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetIamPolicy(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetOrganizationSettings gets the settings for an organization. func (c *Client) GetOrganizationSettings(ctx context.Context, req *securitycenterpb.GetOrganizationSettingsRequest, opts ...gax.CallOption) (*securitycenterpb.OrganizationSettings, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetOrganizationSettings[0:len(c.CallOptions.GetOrganizationSettings):len(c.CallOptions.GetOrganizationSettings)], opts...) var resp *securitycenterpb.OrganizationSettings err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetOrganizationSettings(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetSource gets a source. func (c *Client) GetSource(ctx context.Context, req *securitycenterpb.GetSourceRequest, opts ...gax.CallOption) (*securitycenterpb.Source, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetSource[0:len(c.CallOptions.GetSource):len(c.CallOptions.GetSource)], opts...) var resp *securitycenterpb.Source err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetSource(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GroupAssets filters an organization's assets and groups them by their specified // properties. func (c *Client) GroupAssets(ctx context.Context, req *securitycenterpb.GroupAssetsRequest, opts ...gax.CallOption) *GroupResultIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GroupAssets[0:len(c.CallOptions.GroupAssets):len(c.CallOptions.GroupAssets)], opts...) it := &GroupResultIterator{} req = proto.Clone(req).(*securitycenterpb.GroupAssetsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*securitycenterpb.GroupResult, string, error) { var resp *securitycenterpb.GroupAssetsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GroupAssets(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.GroupByResults, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GroupFindings filters an organization or source's findings and groups them by their // specified properties. // // To group across all sources provide a - as the source id. // Example: /v1/organizations/123/sources/-/findings func (c *Client) GroupFindings(ctx context.Context, req *securitycenterpb.GroupFindingsRequest, opts ...gax.CallOption) *GroupResultIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GroupFindings[0:len(c.CallOptions.GroupFindings):len(c.CallOptions.GroupFindings)], opts...) it := &GroupResultIterator{} req = proto.Clone(req).(*securitycenterpb.GroupFindingsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*securitycenterpb.GroupResult, string, error) { var resp *securitycenterpb.GroupFindingsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GroupFindings(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.GroupByResults, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // ListAssets lists an organization's assets. func (c *Client) ListAssets(ctx context.Context, req *securitycenterpb.ListAssetsRequest, opts ...gax.CallOption) *ListAssetsResponse_ListAssetsResultIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListAssets[0:len(c.CallOptions.ListAssets):len(c.CallOptions.ListAssets)], opts...) it := &ListAssetsResponse_ListAssetsResultIterator{} req = proto.Clone(req).(*securitycenterpb.ListAssetsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*securitycenterpb.ListAssetsResponse_ListAssetsResult, string, error) { var resp *securitycenterpb.ListAssetsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListAssets(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.ListAssetsResults, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // ListFindings lists an organization or source's findings. // // To list across all sources provide a - as the source id. // Example: /v1/organizations/123/sources/-/findings func (c *Client) ListFindings(ctx context.Context, req *securitycenterpb.ListFindingsRequest, opts ...gax.CallOption) *ListFindingsResponse_ListFindingsResultIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListFindings[0:len(c.CallOptions.ListFindings):len(c.CallOptions.ListFindings)], opts...) it := &ListFindingsResponse_ListFindingsResultIterator{} req = proto.Clone(req).(*securitycenterpb.ListFindingsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*securitycenterpb.ListFindingsResponse_ListFindingsResult, string, error) { var resp *securitycenterpb.ListFindingsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListFindings(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.ListFindingsResults, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // ListSources lists all sources belonging to an organization. func (c *Client) ListSources(ctx context.Context, req *securitycenterpb.ListSourcesRequest, opts ...gax.CallOption) *SourceIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListSources[0:len(c.CallOptions.ListSources):len(c.CallOptions.ListSources)], opts...) it := &SourceIterator{} req = proto.Clone(req).(*securitycenterpb.ListSourcesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*securitycenterpb.Source, string, error) { var resp *securitycenterpb.ListSourcesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListSources(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Sources, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // RunAssetDiscovery runs asset discovery. The discovery is tracked with a long-running // operation. // // This API can only be called with limited frequency for an organization. If // it is called too frequently the caller will receive a TOO_MANY_REQUESTS // error. func (c *Client) RunAssetDiscovery(ctx context.Context, req *securitycenterpb.RunAssetDiscoveryRequest, opts ...gax.CallOption) (*RunAssetDiscoveryOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.RunAssetDiscovery[0:len(c.CallOptions.RunAssetDiscovery):len(c.CallOptions.RunAssetDiscovery)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.RunAssetDiscovery(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &RunAssetDiscoveryOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // SetFindingState updates the state of a finding. func (c *Client) SetFindingState(ctx context.Context, req *securitycenterpb.SetFindingStateRequest, opts ...gax.CallOption) (*securitycenterpb.Finding, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.SetFindingState[0:len(c.CallOptions.SetFindingState):len(c.CallOptions.SetFindingState)], opts...) var resp *securitycenterpb.Finding err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.SetFindingState(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // SetIamPolicy sets the access control policy on the specified Source. func (c *Client) SetIamPolicy(ctx context.Context, req *iampb.SetIamPolicyRequest, opts ...gax.CallOption) (*iampb.Policy, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.SetIamPolicy[0:len(c.CallOptions.SetIamPolicy):len(c.CallOptions.SetIamPolicy)], opts...) var resp *iampb.Policy err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.SetIamPolicy(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // TestIamPermissions returns the permissions that a caller has on the specified source. func (c *Client) TestIamPermissions(ctx context.Context, req *iampb.TestIamPermissionsRequest, opts ...gax.CallOption) (*iampb.TestIamPermissionsResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.TestIamPermissions[0:len(c.CallOptions.TestIamPermissions):len(c.CallOptions.TestIamPermissions)], opts...) var resp *iampb.TestIamPermissionsResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.TestIamPermissions(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateFinding creates or updates a finding. The corresponding source must exist for a // finding creation to succeed. func (c *Client) UpdateFinding(ctx context.Context, req *securitycenterpb.UpdateFindingRequest, opts ...gax.CallOption) (*securitycenterpb.Finding, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "finding.name", url.QueryEscape(req.GetFinding().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateFinding[0:len(c.CallOptions.UpdateFinding):len(c.CallOptions.UpdateFinding)], opts...) var resp *securitycenterpb.Finding err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.UpdateFinding(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateOrganizationSettings updates an organization's settings. func (c *Client) UpdateOrganizationSettings(ctx context.Context, req *securitycenterpb.UpdateOrganizationSettingsRequest, opts ...gax.CallOption) (*securitycenterpb.OrganizationSettings, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "organization_settings.name", url.QueryEscape(req.GetOrganizationSettings().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateOrganizationSettings[0:len(c.CallOptions.UpdateOrganizationSettings):len(c.CallOptions.UpdateOrganizationSettings)], opts...) var resp *securitycenterpb.OrganizationSettings err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.UpdateOrganizationSettings(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateSource updates a source. func (c *Client) UpdateSource(ctx context.Context, req *securitycenterpb.UpdateSourceRequest, opts ...gax.CallOption) (*securitycenterpb.Source, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "source.name", url.QueryEscape(req.GetSource().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateSource[0:len(c.CallOptions.UpdateSource):len(c.CallOptions.UpdateSource)], opts...) var resp *securitycenterpb.Source err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.UpdateSource(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateSecurityMarks updates security marks. func (c *Client) UpdateSecurityMarks(ctx context.Context, req *securitycenterpb.UpdateSecurityMarksRequest, opts ...gax.CallOption) (*securitycenterpb.SecurityMarks, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "security_marks.name", url.QueryEscape(req.GetSecurityMarks().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateSecurityMarks[0:len(c.CallOptions.UpdateSecurityMarks):len(c.CallOptions.UpdateSecurityMarks)], opts...) var resp *securitycenterpb.SecurityMarks err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.UpdateSecurityMarks(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GroupResultIterator manages a stream of *securitycenterpb.GroupResult. type GroupResultIterator struct { items []*securitycenterpb.GroupResult pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*securitycenterpb.GroupResult, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *GroupResultIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *GroupResultIterator) Next() (*securitycenterpb.GroupResult, error) { var item *securitycenterpb.GroupResult if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *GroupResultIterator) bufLen() int { return len(it.items) } func (it *GroupResultIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // ListAssetsResponse_ListAssetsResultIterator manages a stream of *securitycenterpb.ListAssetsResponse_ListAssetsResult. type ListAssetsResponse_ListAssetsResultIterator struct { items []*securitycenterpb.ListAssetsResponse_ListAssetsResult pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*securitycenterpb.ListAssetsResponse_ListAssetsResult, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *ListAssetsResponse_ListAssetsResultIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *ListAssetsResponse_ListAssetsResultIterator) Next() (*securitycenterpb.ListAssetsResponse_ListAssetsResult, error) { var item *securitycenterpb.ListAssetsResponse_ListAssetsResult if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *ListAssetsResponse_ListAssetsResultIterator) bufLen() int { return len(it.items) } func (it *ListAssetsResponse_ListAssetsResultIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // ListFindingsResponse_ListFindingsResultIterator manages a stream of *securitycenterpb.ListFindingsResponse_ListFindingsResult. type ListFindingsResponse_ListFindingsResultIterator struct { items []*securitycenterpb.ListFindingsResponse_ListFindingsResult pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*securitycenterpb.ListFindingsResponse_ListFindingsResult, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *ListFindingsResponse_ListFindingsResultIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *ListFindingsResponse_ListFindingsResultIterator) Next() (*securitycenterpb.ListFindingsResponse_ListFindingsResult, error) { var item *securitycenterpb.ListFindingsResponse_ListFindingsResult if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *ListFindingsResponse_ListFindingsResultIterator) bufLen() int { return len(it.items) } func (it *ListFindingsResponse_ListFindingsResultIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // SourceIterator manages a stream of *securitycenterpb.Source. type SourceIterator struct { items []*securitycenterpb.Source pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*securitycenterpb.Source, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *SourceIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *SourceIterator) Next() (*securitycenterpb.Source, error) { var item *securitycenterpb.Source if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *SourceIterator) bufLen() int { return len(it.items) } func (it *SourceIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // RunAssetDiscoveryOperation manages a long-running operation from RunAssetDiscovery. type RunAssetDiscoveryOperation struct { lro *longrunning.Operation } // RunAssetDiscoveryOperation returns a new RunAssetDiscoveryOperation from a given name. // The name must be that of a previously created RunAssetDiscoveryOperation, possibly from a different process. func (c *Client) RunAssetDiscoveryOperation(name string) *RunAssetDiscoveryOperation { return &RunAssetDiscoveryOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *RunAssetDiscoveryOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*securitycenterpb.RunAssetDiscoveryResponse, error) { var resp securitycenterpb.RunAssetDiscoveryResponse if err := op.lro.WaitWithInterval(ctx, &resp, 5000*time.Millisecond, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *RunAssetDiscoveryOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*securitycenterpb.RunAssetDiscoveryResponse, error) { var resp securitycenterpb.RunAssetDiscoveryResponse if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Done reports whether the long-running operation has completed. func (op *RunAssetDiscoveryOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *RunAssetDiscoveryOperation) Name() string { return op.lro.Name() } google-cloud-go-0.49.0/securitycenter/apiv1/security_center_client_example_test.go000066400000000000000000000176111356504100700305340ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package securitycenter_test import ( "context" securitycenter "cloud.google.com/go/securitycenter/apiv1" "google.golang.org/api/iterator" securitycenterpb "google.golang.org/genproto/googleapis/cloud/securitycenter/v1" iampb "google.golang.org/genproto/googleapis/iam/v1" ) func ExampleNewClient() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleClient_CreateSource() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &securitycenterpb.CreateSourceRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateSource(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_CreateFinding() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &securitycenterpb.CreateFindingRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateFinding(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_GetIamPolicy() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &iampb.GetIamPolicyRequest{ // TODO: Fill request struct fields. } resp, err := c.GetIamPolicy(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_GetOrganizationSettings() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &securitycenterpb.GetOrganizationSettingsRequest{ // TODO: Fill request struct fields. } resp, err := c.GetOrganizationSettings(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_GetSource() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &securitycenterpb.GetSourceRequest{ // TODO: Fill request struct fields. } resp, err := c.GetSource(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_GroupAssets() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &securitycenterpb.GroupAssetsRequest{ // TODO: Fill request struct fields. } it := c.GroupAssets(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_GroupFindings() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &securitycenterpb.GroupFindingsRequest{ // TODO: Fill request struct fields. } it := c.GroupFindings(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_ListAssets() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &securitycenterpb.ListAssetsRequest{ // TODO: Fill request struct fields. } it := c.ListAssets(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_ListFindings() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &securitycenterpb.ListFindingsRequest{ // TODO: Fill request struct fields. } it := c.ListFindings(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_ListSources() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &securitycenterpb.ListSourcesRequest{ // TODO: Fill request struct fields. } it := c.ListSources(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_RunAssetDiscovery() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &securitycenterpb.RunAssetDiscoveryRequest{ // TODO: Fill request struct fields. } op, err := c.RunAssetDiscovery(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_SetFindingState() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &securitycenterpb.SetFindingStateRequest{ // TODO: Fill request struct fields. } resp, err := c.SetFindingState(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_SetIamPolicy() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &iampb.SetIamPolicyRequest{ // TODO: Fill request struct fields. } resp, err := c.SetIamPolicy(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_TestIamPermissions() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &iampb.TestIamPermissionsRequest{ // TODO: Fill request struct fields. } resp, err := c.TestIamPermissions(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_UpdateFinding() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &securitycenterpb.UpdateFindingRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateFinding(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_UpdateOrganizationSettings() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &securitycenterpb.UpdateOrganizationSettingsRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateOrganizationSettings(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_UpdateSource() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &securitycenterpb.UpdateSourceRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateSource(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_UpdateSecurityMarks() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &securitycenterpb.UpdateSecurityMarksRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateSecurityMarks(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/securitycenter/apiv1beta1/000077500000000000000000000000001356504100700215755ustar00rootroot00000000000000google-cloud-go-0.49.0/securitycenter/apiv1beta1/doc.go000066400000000000000000000054711356504100700227000ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package securitycenter is an auto-generated package for the // Cloud Security Command Center API. // // NOTE: This package is in beta. It is not stable, and may be subject to changes. // // Cloud Security Command Center API provides access to temporal views of // assets and findings within an organization. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package securitycenter // import "cloud.google.com/go/securitycenter/apiv1beta1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "UNKNOWN" google-cloud-go-0.49.0/securitycenter/apiv1beta1/mock_test.go000066400000000000000000001325351356504100700241250ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package securitycenter import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" timestamppb "github.com/golang/protobuf/ptypes/timestamp" "google.golang.org/api/option" securitycenterpb "google.golang.org/genproto/googleapis/cloud/securitycenter/v1beta1" iampb "google.golang.org/genproto/googleapis/iam/v1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockSecurityCenterServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. securitycenterpb.SecurityCenterServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockSecurityCenterServer) CreateSource(ctx context.Context, req *securitycenterpb.CreateSourceRequest) (*securitycenterpb.Source, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*securitycenterpb.Source), nil } func (s *mockSecurityCenterServer) CreateFinding(ctx context.Context, req *securitycenterpb.CreateFindingRequest) (*securitycenterpb.Finding, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*securitycenterpb.Finding), nil } func (s *mockSecurityCenterServer) GetIamPolicy(ctx context.Context, req *iampb.GetIamPolicyRequest) (*iampb.Policy, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iampb.Policy), nil } func (s *mockSecurityCenterServer) GetOrganizationSettings(ctx context.Context, req *securitycenterpb.GetOrganizationSettingsRequest) (*securitycenterpb.OrganizationSettings, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*securitycenterpb.OrganizationSettings), nil } func (s *mockSecurityCenterServer) GetSource(ctx context.Context, req *securitycenterpb.GetSourceRequest) (*securitycenterpb.Source, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*securitycenterpb.Source), nil } func (s *mockSecurityCenterServer) GroupAssets(ctx context.Context, req *securitycenterpb.GroupAssetsRequest) (*securitycenterpb.GroupAssetsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*securitycenterpb.GroupAssetsResponse), nil } func (s *mockSecurityCenterServer) GroupFindings(ctx context.Context, req *securitycenterpb.GroupFindingsRequest) (*securitycenterpb.GroupFindingsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*securitycenterpb.GroupFindingsResponse), nil } func (s *mockSecurityCenterServer) ListAssets(ctx context.Context, req *securitycenterpb.ListAssetsRequest) (*securitycenterpb.ListAssetsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*securitycenterpb.ListAssetsResponse), nil } func (s *mockSecurityCenterServer) ListFindings(ctx context.Context, req *securitycenterpb.ListFindingsRequest) (*securitycenterpb.ListFindingsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*securitycenterpb.ListFindingsResponse), nil } func (s *mockSecurityCenterServer) ListSources(ctx context.Context, req *securitycenterpb.ListSourcesRequest) (*securitycenterpb.ListSourcesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*securitycenterpb.ListSourcesResponse), nil } func (s *mockSecurityCenterServer) RunAssetDiscovery(ctx context.Context, req *securitycenterpb.RunAssetDiscoveryRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockSecurityCenterServer) SetFindingState(ctx context.Context, req *securitycenterpb.SetFindingStateRequest) (*securitycenterpb.Finding, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*securitycenterpb.Finding), nil } func (s *mockSecurityCenterServer) SetIamPolicy(ctx context.Context, req *iampb.SetIamPolicyRequest) (*iampb.Policy, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iampb.Policy), nil } func (s *mockSecurityCenterServer) TestIamPermissions(ctx context.Context, req *iampb.TestIamPermissionsRequest) (*iampb.TestIamPermissionsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iampb.TestIamPermissionsResponse), nil } func (s *mockSecurityCenterServer) UpdateFinding(ctx context.Context, req *securitycenterpb.UpdateFindingRequest) (*securitycenterpb.Finding, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*securitycenterpb.Finding), nil } func (s *mockSecurityCenterServer) UpdateOrganizationSettings(ctx context.Context, req *securitycenterpb.UpdateOrganizationSettingsRequest) (*securitycenterpb.OrganizationSettings, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*securitycenterpb.OrganizationSettings), nil } func (s *mockSecurityCenterServer) UpdateSource(ctx context.Context, req *securitycenterpb.UpdateSourceRequest) (*securitycenterpb.Source, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*securitycenterpb.Source), nil } func (s *mockSecurityCenterServer) UpdateSecurityMarks(ctx context.Context, req *securitycenterpb.UpdateSecurityMarksRequest) (*securitycenterpb.SecurityMarks, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*securitycenterpb.SecurityMarks), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockSecurityCenter mockSecurityCenterServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() securitycenterpb.RegisterSecurityCenterServer(serv, &mockSecurityCenter) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestSecurityCenterCreateSource(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var description string = "description-1724546052" var expectedResponse = &securitycenterpb.Source{ Name: name, DisplayName: displayName, Description: description, } mockSecurityCenter.err = nil mockSecurityCenter.reqs = nil mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]") var source *securitycenterpb.Source = &securitycenterpb.Source{} var request = &securitycenterpb.CreateSourceRequest{ Parent: formattedParent, Source: source, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateSource(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSecurityCenter.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSecurityCenterCreateSourceError(t *testing.T) { errCode := codes.PermissionDenied mockSecurityCenter.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]") var source *securitycenterpb.Source = &securitycenterpb.Source{} var request = &securitycenterpb.CreateSourceRequest{ Parent: formattedParent, Source: source, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateSource(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSecurityCenterCreateFinding(t *testing.T) { var name string = "name3373707" var parent2 string = "parent21175163357" var resourceName string = "resourceName979421212" var category string = "category50511102" var externalUri string = "externalUri-1385596168" var expectedResponse = &securitycenterpb.Finding{ Name: name, Parent: parent2, ResourceName: resourceName, Category: category, ExternalUri: externalUri, } mockSecurityCenter.err = nil mockSecurityCenter.reqs = nil mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]") var findingId string = "findingId728776081" var finding *securitycenterpb.Finding = &securitycenterpb.Finding{} var request = &securitycenterpb.CreateFindingRequest{ Parent: formattedParent, FindingId: findingId, Finding: finding, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateFinding(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSecurityCenter.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSecurityCenterCreateFindingError(t *testing.T) { errCode := codes.PermissionDenied mockSecurityCenter.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]") var findingId string = "findingId728776081" var finding *securitycenterpb.Finding = &securitycenterpb.Finding{} var request = &securitycenterpb.CreateFindingRequest{ Parent: formattedParent, FindingId: findingId, Finding: finding, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateFinding(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSecurityCenterGetIamPolicy(t *testing.T) { var version int32 = 351608024 var etag []byte = []byte("21") var expectedResponse = &iampb.Policy{ Version: version, Etag: etag, } mockSecurityCenter.err = nil mockSecurityCenter.reqs = nil mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], expectedResponse) var formattedResource string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]") var request = &iampb.GetIamPolicyRequest{ Resource: formattedResource, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetIamPolicy(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSecurityCenter.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSecurityCenterGetIamPolicyError(t *testing.T) { errCode := codes.PermissionDenied mockSecurityCenter.err = gstatus.Error(errCode, "test error") var formattedResource string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]") var request = &iampb.GetIamPolicyRequest{ Resource: formattedResource, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetIamPolicy(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSecurityCenterGetOrganizationSettings(t *testing.T) { var name2 string = "name2-1052831874" var enableAssetDiscovery bool = false var expectedResponse = &securitycenterpb.OrganizationSettings{ Name: name2, EnableAssetDiscovery: enableAssetDiscovery, } mockSecurityCenter.err = nil mockSecurityCenter.reqs = nil mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("organizations/%s/organizationSettings", "[ORGANIZATION]") var request = &securitycenterpb.GetOrganizationSettingsRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetOrganizationSettings(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSecurityCenter.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSecurityCenterGetOrganizationSettingsError(t *testing.T) { errCode := codes.PermissionDenied mockSecurityCenter.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("organizations/%s/organizationSettings", "[ORGANIZATION]") var request = &securitycenterpb.GetOrganizationSettingsRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetOrganizationSettings(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSecurityCenterGetSource(t *testing.T) { var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var description string = "description-1724546052" var expectedResponse = &securitycenterpb.Source{ Name: name2, DisplayName: displayName, Description: description, } mockSecurityCenter.err = nil mockSecurityCenter.reqs = nil mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]") var request = &securitycenterpb.GetSourceRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetSource(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSecurityCenter.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSecurityCenterGetSourceError(t *testing.T) { errCode := codes.PermissionDenied mockSecurityCenter.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]") var request = &securitycenterpb.GetSourceRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetSource(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSecurityCenterGroupAssets(t *testing.T) { var nextPageToken string = "" var groupByResultsElement *securitycenterpb.GroupResult = &securitycenterpb.GroupResult{} var groupByResults = []*securitycenterpb.GroupResult{groupByResultsElement} var expectedResponse = &securitycenterpb.GroupAssetsResponse{ NextPageToken: nextPageToken, GroupByResults: groupByResults, } mockSecurityCenter.err = nil mockSecurityCenter.reqs = nil mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]") var groupBy string = "groupBy506361367" var request = &securitycenterpb.GroupAssetsRequest{ Parent: formattedParent, GroupBy: groupBy, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GroupAssets(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockSecurityCenter.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.GroupByResults[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSecurityCenterGroupAssetsError(t *testing.T) { errCode := codes.PermissionDenied mockSecurityCenter.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]") var groupBy string = "groupBy506361367" var request = &securitycenterpb.GroupAssetsRequest{ Parent: formattedParent, GroupBy: groupBy, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GroupAssets(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSecurityCenterGroupFindings(t *testing.T) { var nextPageToken string = "" var groupByResultsElement *securitycenterpb.GroupResult = &securitycenterpb.GroupResult{} var groupByResults = []*securitycenterpb.GroupResult{groupByResultsElement} var expectedResponse = &securitycenterpb.GroupFindingsResponse{ NextPageToken: nextPageToken, GroupByResults: groupByResults, } mockSecurityCenter.err = nil mockSecurityCenter.reqs = nil mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]") var groupBy string = "groupBy506361367" var request = &securitycenterpb.GroupFindingsRequest{ Parent: formattedParent, GroupBy: groupBy, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GroupFindings(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockSecurityCenter.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.GroupByResults[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSecurityCenterGroupFindingsError(t *testing.T) { errCode := codes.PermissionDenied mockSecurityCenter.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]") var groupBy string = "groupBy506361367" var request = &securitycenterpb.GroupFindingsRequest{ Parent: formattedParent, GroupBy: groupBy, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GroupFindings(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSecurityCenterListAssets(t *testing.T) { var nextPageToken string = "" var totalSize int32 = 705419236 var listAssetsResultsElement *securitycenterpb.ListAssetsResponse_ListAssetsResult = &securitycenterpb.ListAssetsResponse_ListAssetsResult{} var listAssetsResults = []*securitycenterpb.ListAssetsResponse_ListAssetsResult{listAssetsResultsElement} var expectedResponse = &securitycenterpb.ListAssetsResponse{ NextPageToken: nextPageToken, TotalSize: totalSize, ListAssetsResults: listAssetsResults, } mockSecurityCenter.err = nil mockSecurityCenter.reqs = nil mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]") var request = &securitycenterpb.ListAssetsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListAssets(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockSecurityCenter.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.ListAssetsResults[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSecurityCenterListAssetsError(t *testing.T) { errCode := codes.PermissionDenied mockSecurityCenter.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]") var request = &securitycenterpb.ListAssetsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListAssets(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSecurityCenterListFindings(t *testing.T) { var nextPageToken string = "" var totalSize int32 = 705419236 var findingsElement *securitycenterpb.Finding = &securitycenterpb.Finding{} var findings = []*securitycenterpb.Finding{findingsElement} var expectedResponse = &securitycenterpb.ListFindingsResponse{ NextPageToken: nextPageToken, TotalSize: totalSize, Findings: findings, } mockSecurityCenter.err = nil mockSecurityCenter.reqs = nil mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]") var request = &securitycenterpb.ListFindingsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListFindings(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockSecurityCenter.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Findings[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSecurityCenterListFindingsError(t *testing.T) { errCode := codes.PermissionDenied mockSecurityCenter.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]") var request = &securitycenterpb.ListFindingsRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListFindings(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSecurityCenterListSources(t *testing.T) { var nextPageToken string = "" var sourcesElement *securitycenterpb.Source = &securitycenterpb.Source{} var sources = []*securitycenterpb.Source{sourcesElement} var expectedResponse = &securitycenterpb.ListSourcesResponse{ NextPageToken: nextPageToken, Sources: sources, } mockSecurityCenter.err = nil mockSecurityCenter.reqs = nil mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]") var request = &securitycenterpb.ListSourcesRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListSources(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockSecurityCenter.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Sources[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSecurityCenterListSourcesError(t *testing.T) { errCode := codes.PermissionDenied mockSecurityCenter.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]") var request = &securitycenterpb.ListSourcesRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListSources(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSecurityCenterRunAssetDiscovery(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockSecurityCenter.err = nil mockSecurityCenter.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]") var request = &securitycenterpb.RunAssetDiscoveryRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.RunAssetDiscovery(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockSecurityCenter.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestSecurityCenterRunAssetDiscoveryError(t *testing.T) { errCode := codes.PermissionDenied mockSecurityCenter.err = nil mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]") var request = &securitycenterpb.RunAssetDiscoveryRequest{ Parent: formattedParent, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.RunAssetDiscovery(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestSecurityCenterSetFindingState(t *testing.T) { var name2 string = "name2-1052831874" var parent string = "parent-995424086" var resourceName string = "resourceName979421212" var category string = "category50511102" var externalUri string = "externalUri-1385596168" var expectedResponse = &securitycenterpb.Finding{ Name: name2, Parent: parent, ResourceName: resourceName, Category: category, ExternalUri: externalUri, } mockSecurityCenter.err = nil mockSecurityCenter.reqs = nil mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("organizations/%s/sources/%s/findings/%s", "[ORGANIZATION]", "[SOURCE]", "[FINDING]") var state securitycenterpb.Finding_State = securitycenterpb.Finding_STATE_UNSPECIFIED var startTime *timestamppb.Timestamp = ×tamppb.Timestamp{} var request = &securitycenterpb.SetFindingStateRequest{ Name: formattedName, State: state, StartTime: startTime, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetFindingState(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSecurityCenter.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSecurityCenterSetFindingStateError(t *testing.T) { errCode := codes.PermissionDenied mockSecurityCenter.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("organizations/%s/sources/%s/findings/%s", "[ORGANIZATION]", "[SOURCE]", "[FINDING]") var state securitycenterpb.Finding_State = securitycenterpb.Finding_STATE_UNSPECIFIED var startTime *timestamppb.Timestamp = ×tamppb.Timestamp{} var request = &securitycenterpb.SetFindingStateRequest{ Name: formattedName, State: state, StartTime: startTime, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetFindingState(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSecurityCenterSetIamPolicy(t *testing.T) { var version int32 = 351608024 var etag []byte = []byte("21") var expectedResponse = &iampb.Policy{ Version: version, Etag: etag, } mockSecurityCenter.err = nil mockSecurityCenter.reqs = nil mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], expectedResponse) var formattedResource string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]") var policy *iampb.Policy = &iampb.Policy{} var request = &iampb.SetIamPolicyRequest{ Resource: formattedResource, Policy: policy, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetIamPolicy(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSecurityCenter.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSecurityCenterSetIamPolicyError(t *testing.T) { errCode := codes.PermissionDenied mockSecurityCenter.err = gstatus.Error(errCode, "test error") var formattedResource string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]") var policy *iampb.Policy = &iampb.Policy{} var request = &iampb.SetIamPolicyRequest{ Resource: formattedResource, Policy: policy, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetIamPolicy(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSecurityCenterTestIamPermissions(t *testing.T) { var expectedResponse *iampb.TestIamPermissionsResponse = &iampb.TestIamPermissionsResponse{} mockSecurityCenter.err = nil mockSecurityCenter.reqs = nil mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], expectedResponse) var formattedResource string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]") var permissions []string = nil var request = &iampb.TestIamPermissionsRequest{ Resource: formattedResource, Permissions: permissions, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.TestIamPermissions(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSecurityCenter.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSecurityCenterTestIamPermissionsError(t *testing.T) { errCode := codes.PermissionDenied mockSecurityCenter.err = gstatus.Error(errCode, "test error") var formattedResource string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]") var permissions []string = nil var request = &iampb.TestIamPermissionsRequest{ Resource: formattedResource, Permissions: permissions, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.TestIamPermissions(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSecurityCenterUpdateFinding(t *testing.T) { var name string = "name3373707" var parent string = "parent-995424086" var resourceName string = "resourceName979421212" var category string = "category50511102" var externalUri string = "externalUri-1385596168" var expectedResponse = &securitycenterpb.Finding{ Name: name, Parent: parent, ResourceName: resourceName, Category: category, ExternalUri: externalUri, } mockSecurityCenter.err = nil mockSecurityCenter.reqs = nil mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], expectedResponse) var finding *securitycenterpb.Finding = &securitycenterpb.Finding{} var request = &securitycenterpb.UpdateFindingRequest{ Finding: finding, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateFinding(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSecurityCenter.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSecurityCenterUpdateFindingError(t *testing.T) { errCode := codes.PermissionDenied mockSecurityCenter.err = gstatus.Error(errCode, "test error") var finding *securitycenterpb.Finding = &securitycenterpb.Finding{} var request = &securitycenterpb.UpdateFindingRequest{ Finding: finding, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateFinding(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSecurityCenterUpdateOrganizationSettings(t *testing.T) { var name string = "name3373707" var enableAssetDiscovery bool = false var expectedResponse = &securitycenterpb.OrganizationSettings{ Name: name, EnableAssetDiscovery: enableAssetDiscovery, } mockSecurityCenter.err = nil mockSecurityCenter.reqs = nil mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], expectedResponse) var organizationSettings *securitycenterpb.OrganizationSettings = &securitycenterpb.OrganizationSettings{} var request = &securitycenterpb.UpdateOrganizationSettingsRequest{ OrganizationSettings: organizationSettings, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateOrganizationSettings(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSecurityCenter.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSecurityCenterUpdateOrganizationSettingsError(t *testing.T) { errCode := codes.PermissionDenied mockSecurityCenter.err = gstatus.Error(errCode, "test error") var organizationSettings *securitycenterpb.OrganizationSettings = &securitycenterpb.OrganizationSettings{} var request = &securitycenterpb.UpdateOrganizationSettingsRequest{ OrganizationSettings: organizationSettings, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateOrganizationSettings(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSecurityCenterUpdateSource(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var description string = "description-1724546052" var expectedResponse = &securitycenterpb.Source{ Name: name, DisplayName: displayName, Description: description, } mockSecurityCenter.err = nil mockSecurityCenter.reqs = nil mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], expectedResponse) var source *securitycenterpb.Source = &securitycenterpb.Source{} var request = &securitycenterpb.UpdateSourceRequest{ Source: source, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateSource(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSecurityCenter.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSecurityCenterUpdateSourceError(t *testing.T) { errCode := codes.PermissionDenied mockSecurityCenter.err = gstatus.Error(errCode, "test error") var source *securitycenterpb.Source = &securitycenterpb.Source{} var request = &securitycenterpb.UpdateSourceRequest{ Source: source, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateSource(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSecurityCenterUpdateSecurityMarks(t *testing.T) { var name string = "name3373707" var expectedResponse = &securitycenterpb.SecurityMarks{ Name: name, } mockSecurityCenter.err = nil mockSecurityCenter.reqs = nil mockSecurityCenter.resps = append(mockSecurityCenter.resps[:0], expectedResponse) var securityMarks *securitycenterpb.SecurityMarks = &securitycenterpb.SecurityMarks{} var request = &securitycenterpb.UpdateSecurityMarksRequest{ SecurityMarks: securityMarks, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateSecurityMarks(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSecurityCenter.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSecurityCenterUpdateSecurityMarksError(t *testing.T) { errCode := codes.PermissionDenied mockSecurityCenter.err = gstatus.Error(errCode, "test error") var securityMarks *securitycenterpb.SecurityMarks = &securitycenterpb.SecurityMarks{} var request = &securitycenterpb.UpdateSecurityMarksRequest{ SecurityMarks: securityMarks, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateSecurityMarks(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/securitycenter/apiv1beta1/security_center_client.go000066400000000000000000001013701356504100700266730ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package securitycenter import ( "context" "fmt" "math" "net/url" "time" "cloud.google.com/go/longrunning" lroauto "cloud.google.com/go/longrunning/autogen" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" securitycenterpb "google.golang.org/genproto/googleapis/cloud/securitycenter/v1beta1" iampb "google.golang.org/genproto/googleapis/iam/v1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // CallOptions contains the retry settings for each method of Client. type CallOptions struct { CreateSource []gax.CallOption CreateFinding []gax.CallOption GetIamPolicy []gax.CallOption GetOrganizationSettings []gax.CallOption GetSource []gax.CallOption GroupAssets []gax.CallOption GroupFindings []gax.CallOption ListAssets []gax.CallOption ListFindings []gax.CallOption ListSources []gax.CallOption RunAssetDiscovery []gax.CallOption SetFindingState []gax.CallOption SetIamPolicy []gax.CallOption TestIamPermissions []gax.CallOption UpdateFinding []gax.CallOption UpdateOrganizationSettings []gax.CallOption UpdateSource []gax.CallOption UpdateSecurityMarks []gax.CallOption } func defaultClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("securitycenter.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultCallOptions() *CallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &CallOptions{ CreateSource: retry[[2]string{"default", "non_idempotent"}], CreateFinding: retry[[2]string{"default", "non_idempotent"}], GetIamPolicy: retry[[2]string{"default", "idempotent"}], GetOrganizationSettings: retry[[2]string{"default", "idempotent"}], GetSource: retry[[2]string{"default", "idempotent"}], GroupAssets: retry[[2]string{"default", "idempotent"}], GroupFindings: retry[[2]string{"default", "idempotent"}], ListAssets: retry[[2]string{"default", "idempotent"}], ListFindings: retry[[2]string{"default", "idempotent"}], ListSources: retry[[2]string{"default", "idempotent"}], RunAssetDiscovery: retry[[2]string{"default", "non_idempotent"}], SetFindingState: retry[[2]string{"default", "non_idempotent"}], SetIamPolicy: retry[[2]string{"default", "non_idempotent"}], TestIamPermissions: retry[[2]string{"default", "idempotent"}], UpdateFinding: retry[[2]string{"default", "non_idempotent"}], UpdateOrganizationSettings: retry[[2]string{"default", "non_idempotent"}], UpdateSource: retry[[2]string{"default", "non_idempotent"}], UpdateSecurityMarks: retry[[2]string{"default", "non_idempotent"}], } } // Client is a client for interacting with Cloud Security Command Center API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. client securitycenterpb.SecurityCenterClient // LROClient is used internally to handle longrunning operations. // It is exposed so that its CallOptions can be modified if required. // Users should not Close this client. LROClient *lroauto.OperationsClient // The call options for this service. CallOptions *CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewClient creates a new security center client. // // V1 Beta APIs for Security Center service. func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultClientOptions(), opts...)...) if err != nil { return nil, err } c := &Client{ conn: conn, CallOptions: defaultCallOptions(), client: securitycenterpb.NewSecurityCenterClient(conn), } c.setGoogleClientInfo() c.LROClient, err = lroauto.NewOperationsClient(ctx, option.WithGRPCConn(conn)) if err != nil { // This error "should not happen", since we are just reusing old connection // and never actually need to dial. // If this does happen, we could leak conn. However, we cannot close conn: // If the user invoked the function with option.WithGRPCConn, // we would close a connection that's still in use. // TODO(pongad): investigate error conditions. return nil, err } return c, nil } // Connection returns the client's connection to the API service. func (c *Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *Client) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *Client) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // CreateSource creates a source. func (c *Client) CreateSource(ctx context.Context, req *securitycenterpb.CreateSourceRequest, opts ...gax.CallOption) (*securitycenterpb.Source, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateSource[0:len(c.CallOptions.CreateSource):len(c.CallOptions.CreateSource)], opts...) var resp *securitycenterpb.Source err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CreateSource(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateFinding creates a finding. The corresponding source must exist for finding creation // to succeed. func (c *Client) CreateFinding(ctx context.Context, req *securitycenterpb.CreateFindingRequest, opts ...gax.CallOption) (*securitycenterpb.Finding, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateFinding[0:len(c.CallOptions.CreateFinding):len(c.CallOptions.CreateFinding)], opts...) var resp *securitycenterpb.Finding err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CreateFinding(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetIamPolicy gets the access control policy on the specified Source. func (c *Client) GetIamPolicy(ctx context.Context, req *iampb.GetIamPolicyRequest, opts ...gax.CallOption) (*iampb.Policy, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetIamPolicy[0:len(c.CallOptions.GetIamPolicy):len(c.CallOptions.GetIamPolicy)], opts...) var resp *iampb.Policy err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetIamPolicy(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetOrganizationSettings gets the settings for an organization. func (c *Client) GetOrganizationSettings(ctx context.Context, req *securitycenterpb.GetOrganizationSettingsRequest, opts ...gax.CallOption) (*securitycenterpb.OrganizationSettings, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetOrganizationSettings[0:len(c.CallOptions.GetOrganizationSettings):len(c.CallOptions.GetOrganizationSettings)], opts...) var resp *securitycenterpb.OrganizationSettings err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetOrganizationSettings(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetSource gets a source. func (c *Client) GetSource(ctx context.Context, req *securitycenterpb.GetSourceRequest, opts ...gax.CallOption) (*securitycenterpb.Source, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetSource[0:len(c.CallOptions.GetSource):len(c.CallOptions.GetSource)], opts...) var resp *securitycenterpb.Source err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetSource(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GroupAssets filters an organization's assets and groups them by their specified // properties. func (c *Client) GroupAssets(ctx context.Context, req *securitycenterpb.GroupAssetsRequest, opts ...gax.CallOption) *GroupResultIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GroupAssets[0:len(c.CallOptions.GroupAssets):len(c.CallOptions.GroupAssets)], opts...) it := &GroupResultIterator{} req = proto.Clone(req).(*securitycenterpb.GroupAssetsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*securitycenterpb.GroupResult, string, error) { var resp *securitycenterpb.GroupAssetsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GroupAssets(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.GroupByResults, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GroupFindings filters an organization or source's findings and groups them by their // specified properties. // // To group across all sources provide a - as the source id. // Example: /v1beta1/organizations/123/sources/-/findings func (c *Client) GroupFindings(ctx context.Context, req *securitycenterpb.GroupFindingsRequest, opts ...gax.CallOption) *GroupResultIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GroupFindings[0:len(c.CallOptions.GroupFindings):len(c.CallOptions.GroupFindings)], opts...) it := &GroupResultIterator{} req = proto.Clone(req).(*securitycenterpb.GroupFindingsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*securitycenterpb.GroupResult, string, error) { var resp *securitycenterpb.GroupFindingsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GroupFindings(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.GroupByResults, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // ListAssets lists an organization's assets. func (c *Client) ListAssets(ctx context.Context, req *securitycenterpb.ListAssetsRequest, opts ...gax.CallOption) *ListAssetsResponse_ListAssetsResultIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListAssets[0:len(c.CallOptions.ListAssets):len(c.CallOptions.ListAssets)], opts...) it := &ListAssetsResponse_ListAssetsResultIterator{} req = proto.Clone(req).(*securitycenterpb.ListAssetsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*securitycenterpb.ListAssetsResponse_ListAssetsResult, string, error) { var resp *securitycenterpb.ListAssetsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListAssets(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.ListAssetsResults, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // ListFindings lists an organization or source's findings. // // To list across all sources provide a - as the source id. // Example: /v1beta1/organizations/123/sources/-/findings func (c *Client) ListFindings(ctx context.Context, req *securitycenterpb.ListFindingsRequest, opts ...gax.CallOption) *FindingIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListFindings[0:len(c.CallOptions.ListFindings):len(c.CallOptions.ListFindings)], opts...) it := &FindingIterator{} req = proto.Clone(req).(*securitycenterpb.ListFindingsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*securitycenterpb.Finding, string, error) { var resp *securitycenterpb.ListFindingsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListFindings(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Findings, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // ListSources lists all sources belonging to an organization. func (c *Client) ListSources(ctx context.Context, req *securitycenterpb.ListSourcesRequest, opts ...gax.CallOption) *SourceIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListSources[0:len(c.CallOptions.ListSources):len(c.CallOptions.ListSources)], opts...) it := &SourceIterator{} req = proto.Clone(req).(*securitycenterpb.ListSourcesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*securitycenterpb.Source, string, error) { var resp *securitycenterpb.ListSourcesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListSources(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Sources, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // RunAssetDiscovery runs asset discovery. The discovery is tracked with a long-running // operation. // // This API can only be called with limited frequency for an organization. If // it is called too frequently the caller will receive a TOO_MANY_REQUESTS // error. func (c *Client) RunAssetDiscovery(ctx context.Context, req *securitycenterpb.RunAssetDiscoveryRequest, opts ...gax.CallOption) (*RunAssetDiscoveryOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.RunAssetDiscovery[0:len(c.CallOptions.RunAssetDiscovery):len(c.CallOptions.RunAssetDiscovery)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.RunAssetDiscovery(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &RunAssetDiscoveryOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // SetFindingState updates the state of a finding. func (c *Client) SetFindingState(ctx context.Context, req *securitycenterpb.SetFindingStateRequest, opts ...gax.CallOption) (*securitycenterpb.Finding, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.SetFindingState[0:len(c.CallOptions.SetFindingState):len(c.CallOptions.SetFindingState)], opts...) var resp *securitycenterpb.Finding err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.SetFindingState(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // SetIamPolicy sets the access control policy on the specified Source. func (c *Client) SetIamPolicy(ctx context.Context, req *iampb.SetIamPolicyRequest, opts ...gax.CallOption) (*iampb.Policy, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.SetIamPolicy[0:len(c.CallOptions.SetIamPolicy):len(c.CallOptions.SetIamPolicy)], opts...) var resp *iampb.Policy err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.SetIamPolicy(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // TestIamPermissions returns the permissions that a caller has on the specified source. func (c *Client) TestIamPermissions(ctx context.Context, req *iampb.TestIamPermissionsRequest, opts ...gax.CallOption) (*iampb.TestIamPermissionsResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.TestIamPermissions[0:len(c.CallOptions.TestIamPermissions):len(c.CallOptions.TestIamPermissions)], opts...) var resp *iampb.TestIamPermissionsResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.TestIamPermissions(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateFinding creates or updates a finding. The corresponding source must exist for a // finding creation to succeed. func (c *Client) UpdateFinding(ctx context.Context, req *securitycenterpb.UpdateFindingRequest, opts ...gax.CallOption) (*securitycenterpb.Finding, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "finding.name", url.QueryEscape(req.GetFinding().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateFinding[0:len(c.CallOptions.UpdateFinding):len(c.CallOptions.UpdateFinding)], opts...) var resp *securitycenterpb.Finding err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.UpdateFinding(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateOrganizationSettings updates an organization's settings. func (c *Client) UpdateOrganizationSettings(ctx context.Context, req *securitycenterpb.UpdateOrganizationSettingsRequest, opts ...gax.CallOption) (*securitycenterpb.OrganizationSettings, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "organization_settings.name", url.QueryEscape(req.GetOrganizationSettings().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateOrganizationSettings[0:len(c.CallOptions.UpdateOrganizationSettings):len(c.CallOptions.UpdateOrganizationSettings)], opts...) var resp *securitycenterpb.OrganizationSettings err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.UpdateOrganizationSettings(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateSource updates a source. func (c *Client) UpdateSource(ctx context.Context, req *securitycenterpb.UpdateSourceRequest, opts ...gax.CallOption) (*securitycenterpb.Source, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "source.name", url.QueryEscape(req.GetSource().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateSource[0:len(c.CallOptions.UpdateSource):len(c.CallOptions.UpdateSource)], opts...) var resp *securitycenterpb.Source err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.UpdateSource(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateSecurityMarks updates security marks. func (c *Client) UpdateSecurityMarks(ctx context.Context, req *securitycenterpb.UpdateSecurityMarksRequest, opts ...gax.CallOption) (*securitycenterpb.SecurityMarks, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "security_marks.name", url.QueryEscape(req.GetSecurityMarks().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateSecurityMarks[0:len(c.CallOptions.UpdateSecurityMarks):len(c.CallOptions.UpdateSecurityMarks)], opts...) var resp *securitycenterpb.SecurityMarks err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.UpdateSecurityMarks(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // FindingIterator manages a stream of *securitycenterpb.Finding. type FindingIterator struct { items []*securitycenterpb.Finding pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*securitycenterpb.Finding, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *FindingIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *FindingIterator) Next() (*securitycenterpb.Finding, error) { var item *securitycenterpb.Finding if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *FindingIterator) bufLen() int { return len(it.items) } func (it *FindingIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // GroupResultIterator manages a stream of *securitycenterpb.GroupResult. type GroupResultIterator struct { items []*securitycenterpb.GroupResult pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*securitycenterpb.GroupResult, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *GroupResultIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *GroupResultIterator) Next() (*securitycenterpb.GroupResult, error) { var item *securitycenterpb.GroupResult if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *GroupResultIterator) bufLen() int { return len(it.items) } func (it *GroupResultIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // ListAssetsResponse_ListAssetsResultIterator manages a stream of *securitycenterpb.ListAssetsResponse_ListAssetsResult. type ListAssetsResponse_ListAssetsResultIterator struct { items []*securitycenterpb.ListAssetsResponse_ListAssetsResult pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*securitycenterpb.ListAssetsResponse_ListAssetsResult, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *ListAssetsResponse_ListAssetsResultIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *ListAssetsResponse_ListAssetsResultIterator) Next() (*securitycenterpb.ListAssetsResponse_ListAssetsResult, error) { var item *securitycenterpb.ListAssetsResponse_ListAssetsResult if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *ListAssetsResponse_ListAssetsResultIterator) bufLen() int { return len(it.items) } func (it *ListAssetsResponse_ListAssetsResultIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // SourceIterator manages a stream of *securitycenterpb.Source. type SourceIterator struct { items []*securitycenterpb.Source pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*securitycenterpb.Source, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *SourceIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *SourceIterator) Next() (*securitycenterpb.Source, error) { var item *securitycenterpb.Source if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *SourceIterator) bufLen() int { return len(it.items) } func (it *SourceIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // RunAssetDiscoveryOperation manages a long-running operation from RunAssetDiscovery. type RunAssetDiscoveryOperation struct { lro *longrunning.Operation } // RunAssetDiscoveryOperation returns a new RunAssetDiscoveryOperation from a given name. // The name must be that of a previously created RunAssetDiscoveryOperation, possibly from a different process. func (c *Client) RunAssetDiscoveryOperation(name string) *RunAssetDiscoveryOperation { return &RunAssetDiscoveryOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning any error encountered. // // See documentation of Poll for error-handling information. func (op *RunAssetDiscoveryOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { return op.lro.WaitWithInterval(ctx, nil, 5000*time.Millisecond, opts...) } // Poll fetches the latest state of the long-running operation. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, op.Done will return true. func (op *RunAssetDiscoveryOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Poll(ctx, nil, opts...) } // Done reports whether the long-running operation has completed. func (op *RunAssetDiscoveryOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *RunAssetDiscoveryOperation) Name() string { return op.lro.Name() } google-cloud-go-0.49.0/securitycenter/apiv1beta1/security_center_client_example_test.go000066400000000000000000000175311356504100700314520ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package securitycenter_test import ( "context" securitycenter "cloud.google.com/go/securitycenter/apiv1beta1" "google.golang.org/api/iterator" securitycenterpb "google.golang.org/genproto/googleapis/cloud/securitycenter/v1beta1" iampb "google.golang.org/genproto/googleapis/iam/v1" ) func ExampleNewClient() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleClient_CreateSource() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &securitycenterpb.CreateSourceRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateSource(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_CreateFinding() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &securitycenterpb.CreateFindingRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateFinding(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_GetIamPolicy() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &iampb.GetIamPolicyRequest{ // TODO: Fill request struct fields. } resp, err := c.GetIamPolicy(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_GetOrganizationSettings() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &securitycenterpb.GetOrganizationSettingsRequest{ // TODO: Fill request struct fields. } resp, err := c.GetOrganizationSettings(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_GetSource() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &securitycenterpb.GetSourceRequest{ // TODO: Fill request struct fields. } resp, err := c.GetSource(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_GroupAssets() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &securitycenterpb.GroupAssetsRequest{ // TODO: Fill request struct fields. } it := c.GroupAssets(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_GroupFindings() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &securitycenterpb.GroupFindingsRequest{ // TODO: Fill request struct fields. } it := c.GroupFindings(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_ListAssets() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &securitycenterpb.ListAssetsRequest{ // TODO: Fill request struct fields. } it := c.ListAssets(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_ListFindings() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &securitycenterpb.ListFindingsRequest{ // TODO: Fill request struct fields. } it := c.ListFindings(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_ListSources() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &securitycenterpb.ListSourcesRequest{ // TODO: Fill request struct fields. } it := c.ListSources(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_RunAssetDiscovery() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &securitycenterpb.RunAssetDiscoveryRequest{ // TODO: Fill request struct fields. } op, err := c.RunAssetDiscovery(ctx, req) if err != nil { // TODO: Handle error. } err = op.Wait(ctx) // TODO: Handle error. } func ExampleClient_SetFindingState() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &securitycenterpb.SetFindingStateRequest{ // TODO: Fill request struct fields. } resp, err := c.SetFindingState(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_SetIamPolicy() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &iampb.SetIamPolicyRequest{ // TODO: Fill request struct fields. } resp, err := c.SetIamPolicy(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_TestIamPermissions() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &iampb.TestIamPermissionsRequest{ // TODO: Fill request struct fields. } resp, err := c.TestIamPermissions(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_UpdateFinding() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &securitycenterpb.UpdateFindingRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateFinding(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_UpdateOrganizationSettings() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &securitycenterpb.UpdateOrganizationSettingsRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateOrganizationSettings(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_UpdateSource() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &securitycenterpb.UpdateSourceRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateSource(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_UpdateSecurityMarks() { ctx := context.Background() c, err := securitycenter.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &securitycenterpb.UpdateSecurityMarksRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateSecurityMarks(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/spanner/000077500000000000000000000000001356504100700162365ustar00rootroot00000000000000google-cloud-go-0.49.0/spanner/.repo-metadata.json000066400000000000000000000006251356504100700217350ustar00rootroot00000000000000{ "name": "spanner", "name_pretty": "Cloud Spanner API", "product_documentation": "https://cloud.google.com/spanner", "client_documentation": "https://godoc.org/cloud.google.com/go/spanner", "release_level": "ga", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go/spanner", "api_id": "spanner.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/spanner/CHANGES.md000066400000000000000000000034441356504100700176350ustar00rootroot00000000000000# Changes ## v1.1.0 - The String() method of NullString, NullTime and NullDate will now return an unquoted string instead of a quoted string. This is a BREAKING CHANGE. If you relied on the old behavior, please use fmt.Sprintf("%q", T). - The Spanner client will now use the new BatchCreateSessions RPC to initialize the session pool. This will improve the startup time of clients that are initialized with a minimum number of sessions greater than zero (i.e. SessionPoolConfig.MinOpened>0). - Spanner clients that are created with the NewClient method will now default to a minimum of 100 opened sessions in the pool (i.e. SessionPoolConfig.MinOpened=100). This will improve the performance of the first transaction/query that is executed by an application, as a session will normally not have to be created as part of the transaction. Spanner clients that are created with the NewClientWithConfig method are not affected by this change. - Spanner clients that are created with the NewClient method will now default to a write sessions fraction of 0.2 in the pool (i.e. SessionPoolConfig.WriteSessions=0.2). Creating Spanner clients for read-only purposes should be done using NewClientWithConfig with SessionPoolConfig.WriteSessions=0.0. Spanner clients that are created with the NewClientWithConfig method are not affected by this change. - The session pool maintenance worker has been improved so it keeps better track of the actual number of sessions needed. It will now less often delete and re-create sessions. This can improve the overall performance of applications with a low transaction rate. ## v1.0.0 This is the first tag to carve out spanner as its own module. See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository. google-cloud-go-0.49.0/spanner/README.md000066400000000000000000000016341356504100700175210ustar00rootroot00000000000000## Cloud Spanner [![GoDoc](https://godoc.org/cloud.google.com/go/spanner?status.svg)](https://godoc.org/cloud.google.com/go/spanner) - [About Cloud Spanner](https://cloud.google.com/spanner/) - [API documentation](https://cloud.google.com/spanner/docs) - [Go client documentation](https://godoc.org/cloud.google.com/go/spanner) ### Example Usage First create a `spanner.Client` to use throughout your application: [snip]:# (spanner-1) ```go client, err := spanner.NewClient(ctx, "projects/P/instances/I/databases/D") if err != nil { log.Fatal(err) } ``` [snip]:# (spanner-2) ```go // Simple Reads And Writes _, err = client.Apply(ctx, []*spanner.Mutation{ spanner.Insert("Users", []string{"name", "email"}, []interface{}{"alice", "a@example.com"})}) if err != nil { log.Fatal(err) } row, err := client.Single().ReadRow(ctx, "Users", spanner.Key{"alice"}, []string{"email"}) if err != nil { log.Fatal(err) } ```google-cloud-go-0.49.0/spanner/admin/000077500000000000000000000000001356504100700173265ustar00rootroot00000000000000google-cloud-go-0.49.0/spanner/admin/database/000077500000000000000000000000001356504100700210725ustar00rootroot00000000000000google-cloud-go-0.49.0/spanner/admin/database/apiv1/000077500000000000000000000000001356504100700221125ustar00rootroot00000000000000google-cloud-go-0.49.0/spanner/admin/database/apiv1/.repo-metadata.json000066400000000000000000000006451356504100700256130ustar00rootroot00000000000000{ "name": "spanner", "name_pretty": "Cloud Spanner API", "product_documentation": "https://cloud.google.com/spanner", "client_documentation": "https://godoc.org/cloud.google.com/go/spanner/admin/database/apiv1", "release_level": "alpha", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "spanner.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/spanner/admin/database/apiv1/database_admin_client.go000066400000000000000000000540371356504100700267240ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package database import ( "context" "fmt" "math" "net/url" "time" "cloud.google.com/go/longrunning" lroauto "cloud.google.com/go/longrunning/autogen" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" iampb "google.golang.org/genproto/googleapis/iam/v1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" databasepb "google.golang.org/genproto/googleapis/spanner/admin/database/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // DatabaseAdminCallOptions contains the retry settings for each method of DatabaseAdminClient. type DatabaseAdminCallOptions struct { CreateDatabase []gax.CallOption GetDatabase []gax.CallOption UpdateDatabaseDdl []gax.CallOption DropDatabase []gax.CallOption GetDatabaseDdl []gax.CallOption SetIamPolicy []gax.CallOption GetIamPolicy []gax.CallOption TestIamPermissions []gax.CallOption ListDatabases []gax.CallOption } func defaultDatabaseAdminClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("spanner.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultDatabaseAdminCallOptions() *DatabaseAdminCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 1000 * time.Millisecond, Max: 32000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &DatabaseAdminCallOptions{ CreateDatabase: retry[[2]string{"default", "non_idempotent"}], GetDatabase: retry[[2]string{"default", "idempotent"}], UpdateDatabaseDdl: retry[[2]string{"default", "idempotent"}], DropDatabase: retry[[2]string{"default", "idempotent"}], GetDatabaseDdl: retry[[2]string{"default", "idempotent"}], SetIamPolicy: retry[[2]string{"default", "non_idempotent"}], GetIamPolicy: retry[[2]string{"default", "idempotent"}], TestIamPermissions: retry[[2]string{"default", "non_idempotent"}], ListDatabases: retry[[2]string{"default", "idempotent"}], } } // DatabaseAdminClient is a client for interacting with Cloud Spanner Database Admin API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type DatabaseAdminClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. databaseAdminClient databasepb.DatabaseAdminClient // LROClient is used internally to handle longrunning operations. // It is exposed so that its CallOptions can be modified if required. // Users should not Close this client. LROClient *lroauto.OperationsClient // The call options for this service. CallOptions *DatabaseAdminCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewDatabaseAdminClient creates a new database admin client. // // Cloud Spanner Database Admin API // // The Cloud Spanner Database Admin API can be used to create, drop, and // list databases. It also enables updating the schema of pre-existing // databases. func NewDatabaseAdminClient(ctx context.Context, opts ...option.ClientOption) (*DatabaseAdminClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultDatabaseAdminClientOptions(), opts...)...) if err != nil { return nil, err } c := &DatabaseAdminClient{ conn: conn, CallOptions: defaultDatabaseAdminCallOptions(), databaseAdminClient: databasepb.NewDatabaseAdminClient(conn), } c.setGoogleClientInfo() c.LROClient, err = lroauto.NewOperationsClient(ctx, option.WithGRPCConn(conn)) if err != nil { // This error "should not happen", since we are just reusing old connection // and never actually need to dial. // If this does happen, we could leak conn. However, we cannot close conn: // If the user invoked the function with option.WithGRPCConn, // we would close a connection that's still in use. // TODO(pongad): investigate error conditions. return nil, err } return c, nil } // Connection returns the client's connection to the API service. func (c *DatabaseAdminClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *DatabaseAdminClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *DatabaseAdminClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // CreateDatabase creates a new Cloud Spanner database and starts to prepare it for serving. // The returned [long-running operation][google.longrunning.Operation] will // have a name of the format /operations/ and // can be used to track preparation of the database. The // [metadata][google.longrunning.Operation.metadata] field type is // [CreateDatabaseMetadata][google.spanner.admin.database.v1.CreateDatabaseMetadata]. // The [response][google.longrunning.Operation.response] field type is // [Database][google.spanner.admin.database.v1.Database], if successful. func (c *DatabaseAdminClient) CreateDatabase(ctx context.Context, req *databasepb.CreateDatabaseRequest, opts ...gax.CallOption) (*CreateDatabaseOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateDatabase[0:len(c.CallOptions.CreateDatabase):len(c.CallOptions.CreateDatabase)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.databaseAdminClient.CreateDatabase(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &CreateDatabaseOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // GetDatabase gets the state of a Cloud Spanner database. func (c *DatabaseAdminClient) GetDatabase(ctx context.Context, req *databasepb.GetDatabaseRequest, opts ...gax.CallOption) (*databasepb.Database, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetDatabase[0:len(c.CallOptions.GetDatabase):len(c.CallOptions.GetDatabase)], opts...) var resp *databasepb.Database err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.databaseAdminClient.GetDatabase(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateDatabaseDdl updates the schema of a Cloud Spanner database by // creating/altering/dropping tables, columns, indexes, etc. The returned // [long-running operation][google.longrunning.Operation] will have a name of // the format /operations/ and can be used to // track execution of the schema change(s). The // [metadata][google.longrunning.Operation.metadata] field type is // [UpdateDatabaseDdlMetadata][google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata]. // The operation has no response. func (c *DatabaseAdminClient) UpdateDatabaseDdl(ctx context.Context, req *databasepb.UpdateDatabaseDdlRequest, opts ...gax.CallOption) (*UpdateDatabaseDdlOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "database", url.QueryEscape(req.GetDatabase()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateDatabaseDdl[0:len(c.CallOptions.UpdateDatabaseDdl):len(c.CallOptions.UpdateDatabaseDdl)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.databaseAdminClient.UpdateDatabaseDdl(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &UpdateDatabaseDdlOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // DropDatabase drops (aka deletes) a Cloud Spanner database. func (c *DatabaseAdminClient) DropDatabase(ctx context.Context, req *databasepb.DropDatabaseRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "database", url.QueryEscape(req.GetDatabase()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DropDatabase[0:len(c.CallOptions.DropDatabase):len(c.CallOptions.DropDatabase)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.databaseAdminClient.DropDatabase(ctx, req, settings.GRPC...) return err }, opts...) return err } // GetDatabaseDdl returns the schema of a Cloud Spanner database as a list of formatted // DDL statements. This method does not show pending schema updates, those may // be queried using the [Operations][google.longrunning.Operations] API. func (c *DatabaseAdminClient) GetDatabaseDdl(ctx context.Context, req *databasepb.GetDatabaseDdlRequest, opts ...gax.CallOption) (*databasepb.GetDatabaseDdlResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "database", url.QueryEscape(req.GetDatabase()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetDatabaseDdl[0:len(c.CallOptions.GetDatabaseDdl):len(c.CallOptions.GetDatabaseDdl)], opts...) var resp *databasepb.GetDatabaseDdlResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.databaseAdminClient.GetDatabaseDdl(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // SetIamPolicy sets the access control policy on a database resource. // Replaces any existing policy. // // Authorization requires spanner.databases.setIamPolicy // permission on [resource][google.iam.v1.SetIamPolicyRequest.resource]. func (c *DatabaseAdminClient) SetIamPolicy(ctx context.Context, req *iampb.SetIamPolicyRequest, opts ...gax.CallOption) (*iampb.Policy, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.SetIamPolicy[0:len(c.CallOptions.SetIamPolicy):len(c.CallOptions.SetIamPolicy)], opts...) var resp *iampb.Policy err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.databaseAdminClient.SetIamPolicy(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetIamPolicy gets the access control policy for a database resource. // Returns an empty policy if a database exists but does // not have a policy set. // // Authorization requires spanner.databases.getIamPolicy permission on // [resource][google.iam.v1.GetIamPolicyRequest.resource]. func (c *DatabaseAdminClient) GetIamPolicy(ctx context.Context, req *iampb.GetIamPolicyRequest, opts ...gax.CallOption) (*iampb.Policy, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetIamPolicy[0:len(c.CallOptions.GetIamPolicy):len(c.CallOptions.GetIamPolicy)], opts...) var resp *iampb.Policy err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.databaseAdminClient.GetIamPolicy(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // TestIamPermissions returns permissions that the caller has on the specified database resource. // // Attempting this RPC on a non-existent Cloud Spanner database will // result in a NOT_FOUND error if the user has // spanner.databases.list permission on the containing Cloud // Spanner instance. Otherwise returns an empty set of permissions. func (c *DatabaseAdminClient) TestIamPermissions(ctx context.Context, req *iampb.TestIamPermissionsRequest, opts ...gax.CallOption) (*iampb.TestIamPermissionsResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.TestIamPermissions[0:len(c.CallOptions.TestIamPermissions):len(c.CallOptions.TestIamPermissions)], opts...) var resp *iampb.TestIamPermissionsResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.databaseAdminClient.TestIamPermissions(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListDatabases lists Cloud Spanner databases. func (c *DatabaseAdminClient) ListDatabases(ctx context.Context, req *databasepb.ListDatabasesRequest, opts ...gax.CallOption) *DatabaseIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListDatabases[0:len(c.CallOptions.ListDatabases):len(c.CallOptions.ListDatabases)], opts...) it := &DatabaseIterator{} req = proto.Clone(req).(*databasepb.ListDatabasesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*databasepb.Database, string, error) { var resp *databasepb.ListDatabasesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.databaseAdminClient.ListDatabases(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Databases, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // DatabaseIterator manages a stream of *databasepb.Database. type DatabaseIterator struct { items []*databasepb.Database pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*databasepb.Database, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *DatabaseIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *DatabaseIterator) Next() (*databasepb.Database, error) { var item *databasepb.Database if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *DatabaseIterator) bufLen() int { return len(it.items) } func (it *DatabaseIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // CreateDatabaseOperation manages a long-running operation from CreateDatabase. type CreateDatabaseOperation struct { lro *longrunning.Operation } // CreateDatabaseOperation returns a new CreateDatabaseOperation from a given name. // The name must be that of a previously created CreateDatabaseOperation, possibly from a different process. func (c *DatabaseAdminClient) CreateDatabaseOperation(name string) *CreateDatabaseOperation { return &CreateDatabaseOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *CreateDatabaseOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*databasepb.Database, error) { var resp databasepb.Database if err := op.lro.WaitWithInterval(ctx, &resp, 45000*time.Millisecond, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *CreateDatabaseOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*databasepb.Database, error) { var resp databasepb.Database if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *CreateDatabaseOperation) Metadata() (*databasepb.CreateDatabaseMetadata, error) { var meta databasepb.CreateDatabaseMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *CreateDatabaseOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *CreateDatabaseOperation) Name() string { return op.lro.Name() } // UpdateDatabaseDdlOperation manages a long-running operation from UpdateDatabaseDdl. type UpdateDatabaseDdlOperation struct { lro *longrunning.Operation } // UpdateDatabaseDdlOperation returns a new UpdateDatabaseDdlOperation from a given name. // The name must be that of a previously created UpdateDatabaseDdlOperation, possibly from a different process. func (c *DatabaseAdminClient) UpdateDatabaseDdlOperation(name string) *UpdateDatabaseDdlOperation { return &UpdateDatabaseDdlOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning any error encountered. // // See documentation of Poll for error-handling information. func (op *UpdateDatabaseDdlOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { return op.lro.WaitWithInterval(ctx, nil, 45000*time.Millisecond, opts...) } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, op.Done will return true. func (op *UpdateDatabaseDdlOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Poll(ctx, nil, opts...) } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *UpdateDatabaseDdlOperation) Metadata() (*databasepb.UpdateDatabaseDdlMetadata, error) { var meta databasepb.UpdateDatabaseDdlMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *UpdateDatabaseDdlOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *UpdateDatabaseDdlOperation) Name() string { return op.lro.Name() } google-cloud-go-0.49.0/spanner/admin/database/apiv1/database_admin_client_example_test.go000066400000000000000000000107761356504100700315000ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package database_test import ( "context" database "cloud.google.com/go/spanner/admin/database/apiv1" "google.golang.org/api/iterator" iampb "google.golang.org/genproto/googleapis/iam/v1" databasepb "google.golang.org/genproto/googleapis/spanner/admin/database/v1" ) func ExampleNewDatabaseAdminClient() { ctx := context.Background() c, err := database.NewDatabaseAdminClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleDatabaseAdminClient_CreateDatabase() { ctx := context.Background() c, err := database.NewDatabaseAdminClient(ctx) if err != nil { // TODO: Handle error. } req := &databasepb.CreateDatabaseRequest{ // TODO: Fill request struct fields. } op, err := c.CreateDatabase(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleDatabaseAdminClient_GetDatabase() { ctx := context.Background() c, err := database.NewDatabaseAdminClient(ctx) if err != nil { // TODO: Handle error. } req := &databasepb.GetDatabaseRequest{ // TODO: Fill request struct fields. } resp, err := c.GetDatabase(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleDatabaseAdminClient_UpdateDatabaseDdl() { ctx := context.Background() c, err := database.NewDatabaseAdminClient(ctx) if err != nil { // TODO: Handle error. } req := &databasepb.UpdateDatabaseDdlRequest{ // TODO: Fill request struct fields. } op, err := c.UpdateDatabaseDdl(ctx, req) if err != nil { // TODO: Handle error. } err = op.Wait(ctx) // TODO: Handle error. } func ExampleDatabaseAdminClient_DropDatabase() { ctx := context.Background() c, err := database.NewDatabaseAdminClient(ctx) if err != nil { // TODO: Handle error. } req := &databasepb.DropDatabaseRequest{ // TODO: Fill request struct fields. } err = c.DropDatabase(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleDatabaseAdminClient_GetDatabaseDdl() { ctx := context.Background() c, err := database.NewDatabaseAdminClient(ctx) if err != nil { // TODO: Handle error. } req := &databasepb.GetDatabaseDdlRequest{ // TODO: Fill request struct fields. } resp, err := c.GetDatabaseDdl(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleDatabaseAdminClient_SetIamPolicy() { ctx := context.Background() c, err := database.NewDatabaseAdminClient(ctx) if err != nil { // TODO: Handle error. } req := &iampb.SetIamPolicyRequest{ // TODO: Fill request struct fields. } resp, err := c.SetIamPolicy(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleDatabaseAdminClient_GetIamPolicy() { ctx := context.Background() c, err := database.NewDatabaseAdminClient(ctx) if err != nil { // TODO: Handle error. } req := &iampb.GetIamPolicyRequest{ // TODO: Fill request struct fields. } resp, err := c.GetIamPolicy(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleDatabaseAdminClient_TestIamPermissions() { ctx := context.Background() c, err := database.NewDatabaseAdminClient(ctx) if err != nil { // TODO: Handle error. } req := &iampb.TestIamPermissionsRequest{ // TODO: Fill request struct fields. } resp, err := c.TestIamPermissions(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleDatabaseAdminClient_ListDatabases() { ctx := context.Background() c, err := database.NewDatabaseAdminClient(ctx) if err != nil { // TODO: Handle error. } req := &databasepb.ListDatabasesRequest{ // TODO: Fill request struct fields. } it := c.ListDatabases(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } google-cloud-go-0.49.0/spanner/admin/database/apiv1/doc.go000066400000000000000000000053451356504100700232150ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package database is an auto-generated package for the // Cloud Spanner Database Admin API. // // NOTE: This package is in alpha. It is not stable, and is likely to change. // // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package database // import "cloud.google.com/go/spanner/admin/database/apiv1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/spanner.admin", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191115" google-cloud-go-0.49.0/spanner/admin/database/apiv1/mock_test.go000066400000000000000000000550241356504100700244370ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package database import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" "google.golang.org/api/option" iampb "google.golang.org/genproto/googleapis/iam/v1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" databasepb "google.golang.org/genproto/googleapis/spanner/admin/database/v1" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockDatabaseAdminServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. databasepb.DatabaseAdminServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockDatabaseAdminServer) ListDatabases(ctx context.Context, req *databasepb.ListDatabasesRequest) (*databasepb.ListDatabasesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*databasepb.ListDatabasesResponse), nil } func (s *mockDatabaseAdminServer) CreateDatabase(ctx context.Context, req *databasepb.CreateDatabaseRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockDatabaseAdminServer) GetDatabase(ctx context.Context, req *databasepb.GetDatabaseRequest) (*databasepb.Database, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*databasepb.Database), nil } func (s *mockDatabaseAdminServer) UpdateDatabaseDdl(ctx context.Context, req *databasepb.UpdateDatabaseDdlRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockDatabaseAdminServer) DropDatabase(ctx context.Context, req *databasepb.DropDatabaseRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockDatabaseAdminServer) GetDatabaseDdl(ctx context.Context, req *databasepb.GetDatabaseDdlRequest) (*databasepb.GetDatabaseDdlResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*databasepb.GetDatabaseDdlResponse), nil } func (s *mockDatabaseAdminServer) SetIamPolicy(ctx context.Context, req *iampb.SetIamPolicyRequest) (*iampb.Policy, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iampb.Policy), nil } func (s *mockDatabaseAdminServer) GetIamPolicy(ctx context.Context, req *iampb.GetIamPolicyRequest) (*iampb.Policy, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iampb.Policy), nil } func (s *mockDatabaseAdminServer) TestIamPermissions(ctx context.Context, req *iampb.TestIamPermissionsRequest) (*iampb.TestIamPermissionsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iampb.TestIamPermissionsResponse), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockDatabaseAdmin mockDatabaseAdminServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() databasepb.RegisterDatabaseAdminServer(serv, &mockDatabaseAdmin) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestDatabaseAdminCreateDatabase(t *testing.T) { var name string = "name3373707" var expectedResponse = &databasepb.Database{ Name: name, } mockDatabaseAdmin.err = nil mockDatabaseAdmin.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockDatabaseAdmin.resps = append(mockDatabaseAdmin.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedParent string = fmt.Sprintf("projects/%s/instances/%s", "[PROJECT]", "[INSTANCE]") var createStatement string = "createStatement552974828" var request = &databasepb.CreateDatabaseRequest{ Parent: formattedParent, CreateStatement: createStatement, } c, err := NewDatabaseAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.CreateDatabase(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockDatabaseAdmin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDatabaseAdminCreateDatabaseError(t *testing.T) { errCode := codes.PermissionDenied mockDatabaseAdmin.err = nil mockDatabaseAdmin.resps = append(mockDatabaseAdmin.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedParent string = fmt.Sprintf("projects/%s/instances/%s", "[PROJECT]", "[INSTANCE]") var createStatement string = "createStatement552974828" var request = &databasepb.CreateDatabaseRequest{ Parent: formattedParent, CreateStatement: createStatement, } c, err := NewDatabaseAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.CreateDatabase(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDatabaseAdminGetDatabase(t *testing.T) { var name2 string = "name2-1052831874" var expectedResponse = &databasepb.Database{ Name: name2, } mockDatabaseAdmin.err = nil mockDatabaseAdmin.reqs = nil mockDatabaseAdmin.resps = append(mockDatabaseAdmin.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/instances/%s/databases/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]") var request = &databasepb.GetDatabaseRequest{ Name: formattedName, } c, err := NewDatabaseAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetDatabase(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDatabaseAdmin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDatabaseAdminGetDatabaseError(t *testing.T) { errCode := codes.PermissionDenied mockDatabaseAdmin.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/instances/%s/databases/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]") var request = &databasepb.GetDatabaseRequest{ Name: formattedName, } c, err := NewDatabaseAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetDatabase(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDatabaseAdminUpdateDatabaseDdl(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockDatabaseAdmin.err = nil mockDatabaseAdmin.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockDatabaseAdmin.resps = append(mockDatabaseAdmin.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedDatabase string = fmt.Sprintf("projects/%s/instances/%s/databases/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]") var statements []string = nil var request = &databasepb.UpdateDatabaseDdlRequest{ Database: formattedDatabase, Statements: statements, } c, err := NewDatabaseAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.UpdateDatabaseDdl(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockDatabaseAdmin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestDatabaseAdminUpdateDatabaseDdlError(t *testing.T) { errCode := codes.PermissionDenied mockDatabaseAdmin.err = nil mockDatabaseAdmin.resps = append(mockDatabaseAdmin.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedDatabase string = fmt.Sprintf("projects/%s/instances/%s/databases/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]") var statements []string = nil var request = &databasepb.UpdateDatabaseDdlRequest{ Database: formattedDatabase, Statements: statements, } c, err := NewDatabaseAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.UpdateDatabaseDdl(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestDatabaseAdminDropDatabase(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockDatabaseAdmin.err = nil mockDatabaseAdmin.reqs = nil mockDatabaseAdmin.resps = append(mockDatabaseAdmin.resps[:0], expectedResponse) var formattedDatabase string = fmt.Sprintf("projects/%s/instances/%s/databases/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]") var request = &databasepb.DropDatabaseRequest{ Database: formattedDatabase, } c, err := NewDatabaseAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DropDatabase(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDatabaseAdmin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestDatabaseAdminDropDatabaseError(t *testing.T) { errCode := codes.PermissionDenied mockDatabaseAdmin.err = gstatus.Error(errCode, "test error") var formattedDatabase string = fmt.Sprintf("projects/%s/instances/%s/databases/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]") var request = &databasepb.DropDatabaseRequest{ Database: formattedDatabase, } c, err := NewDatabaseAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DropDatabase(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestDatabaseAdminGetDatabaseDdl(t *testing.T) { var expectedResponse *databasepb.GetDatabaseDdlResponse = &databasepb.GetDatabaseDdlResponse{} mockDatabaseAdmin.err = nil mockDatabaseAdmin.reqs = nil mockDatabaseAdmin.resps = append(mockDatabaseAdmin.resps[:0], expectedResponse) var formattedDatabase string = fmt.Sprintf("projects/%s/instances/%s/databases/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]") var request = &databasepb.GetDatabaseDdlRequest{ Database: formattedDatabase, } c, err := NewDatabaseAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetDatabaseDdl(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDatabaseAdmin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDatabaseAdminGetDatabaseDdlError(t *testing.T) { errCode := codes.PermissionDenied mockDatabaseAdmin.err = gstatus.Error(errCode, "test error") var formattedDatabase string = fmt.Sprintf("projects/%s/instances/%s/databases/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]") var request = &databasepb.GetDatabaseDdlRequest{ Database: formattedDatabase, } c, err := NewDatabaseAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetDatabaseDdl(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDatabaseAdminSetIamPolicy(t *testing.T) { var version int32 = 351608024 var etag []byte = []byte("21") var expectedResponse = &iampb.Policy{ Version: version, Etag: etag, } mockDatabaseAdmin.err = nil mockDatabaseAdmin.reqs = nil mockDatabaseAdmin.resps = append(mockDatabaseAdmin.resps[:0], expectedResponse) var resource string = "resource-341064690" var policy *iampb.Policy = &iampb.Policy{} var request = &iampb.SetIamPolicyRequest{ Resource: resource, Policy: policy, } c, err := NewDatabaseAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetIamPolicy(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDatabaseAdmin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDatabaseAdminSetIamPolicyError(t *testing.T) { errCode := codes.PermissionDenied mockDatabaseAdmin.err = gstatus.Error(errCode, "test error") var resource string = "resource-341064690" var policy *iampb.Policy = &iampb.Policy{} var request = &iampb.SetIamPolicyRequest{ Resource: resource, Policy: policy, } c, err := NewDatabaseAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetIamPolicy(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDatabaseAdminGetIamPolicy(t *testing.T) { var version int32 = 351608024 var etag []byte = []byte("21") var expectedResponse = &iampb.Policy{ Version: version, Etag: etag, } mockDatabaseAdmin.err = nil mockDatabaseAdmin.reqs = nil mockDatabaseAdmin.resps = append(mockDatabaseAdmin.resps[:0], expectedResponse) var resource string = "resource-341064690" var request = &iampb.GetIamPolicyRequest{ Resource: resource, } c, err := NewDatabaseAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetIamPolicy(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDatabaseAdmin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDatabaseAdminGetIamPolicyError(t *testing.T) { errCode := codes.PermissionDenied mockDatabaseAdmin.err = gstatus.Error(errCode, "test error") var resource string = "resource-341064690" var request = &iampb.GetIamPolicyRequest{ Resource: resource, } c, err := NewDatabaseAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetIamPolicy(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDatabaseAdminTestIamPermissions(t *testing.T) { var expectedResponse *iampb.TestIamPermissionsResponse = &iampb.TestIamPermissionsResponse{} mockDatabaseAdmin.err = nil mockDatabaseAdmin.reqs = nil mockDatabaseAdmin.resps = append(mockDatabaseAdmin.resps[:0], expectedResponse) var resource string = "resource-341064690" var permissions []string = nil var request = &iampb.TestIamPermissionsRequest{ Resource: resource, Permissions: permissions, } c, err := NewDatabaseAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.TestIamPermissions(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockDatabaseAdmin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDatabaseAdminTestIamPermissionsError(t *testing.T) { errCode := codes.PermissionDenied mockDatabaseAdmin.err = gstatus.Error(errCode, "test error") var resource string = "resource-341064690" var permissions []string = nil var request = &iampb.TestIamPermissionsRequest{ Resource: resource, Permissions: permissions, } c, err := NewDatabaseAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.TestIamPermissions(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestDatabaseAdminListDatabases(t *testing.T) { var nextPageToken string = "" var databasesElement *databasepb.Database = &databasepb.Database{} var databases = []*databasepb.Database{databasesElement} var expectedResponse = &databasepb.ListDatabasesResponse{ NextPageToken: nextPageToken, Databases: databases, } mockDatabaseAdmin.err = nil mockDatabaseAdmin.reqs = nil mockDatabaseAdmin.resps = append(mockDatabaseAdmin.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/instances/%s", "[PROJECT]", "[INSTANCE]") var request = &databasepb.ListDatabasesRequest{ Parent: formattedParent, } c, err := NewDatabaseAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListDatabases(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockDatabaseAdmin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Databases[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestDatabaseAdminListDatabasesError(t *testing.T) { errCode := codes.PermissionDenied mockDatabaseAdmin.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/instances/%s", "[PROJECT]", "[INSTANCE]") var request = &databasepb.ListDatabasesRequest{ Parent: formattedParent, } c, err := NewDatabaseAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListDatabases(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/spanner/admin/database/apiv1/path_funcs.go000066400000000000000000000024301356504100700245720ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package database // DatabaseAdminInstancePath returns the path for the instance resource. // // Deprecated: Use // fmt.Sprintf("projects/%s/instances/%s", project, instance) // instead. func DatabaseAdminInstancePath(project, instance string) string { return "" + "projects/" + project + "/instances/" + instance + "" } // DatabaseAdminDatabasePath returns the path for the database resource. // // Deprecated: Use // fmt.Sprintf("projects/%s/instances/%s/databases/%s", project, instance, database) // instead. func DatabaseAdminDatabasePath(project, instance, database string) string { return "" + "projects/" + project + "/instances/" + instance + "/databases/" + database + "" } google-cloud-go-0.49.0/spanner/admin/instance/000077500000000000000000000000001356504100700211325ustar00rootroot00000000000000google-cloud-go-0.49.0/spanner/admin/instance/apiv1/000077500000000000000000000000001356504100700221525ustar00rootroot00000000000000google-cloud-go-0.49.0/spanner/admin/instance/apiv1/.repo-metadata.json000066400000000000000000000006451356504100700256530ustar00rootroot00000000000000{ "name": "spanner", "name_pretty": "Cloud Spanner API", "product_documentation": "https://cloud.google.com/spanner", "client_documentation": "https://godoc.org/cloud.google.com/go/spanner/admin/instance/apiv1", "release_level": "alpha", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "spanner.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/spanner/admin/instance/apiv1/doc.go000066400000000000000000000053451356504100700232550ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package instance is an auto-generated package for the // Cloud Spanner Instance Admin API. // // NOTE: This package is in alpha. It is not stable, and is likely to change. // // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package instance // import "cloud.google.com/go/spanner/admin/instance/apiv1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/spanner.admin", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191115" google-cloud-go-0.49.0/spanner/admin/instance/apiv1/instance_admin_client.go000066400000000000000000000720761356504100700270270ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package instance import ( "context" "fmt" "math" "net/url" "time" "cloud.google.com/go/longrunning" lroauto "cloud.google.com/go/longrunning/autogen" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" iampb "google.golang.org/genproto/googleapis/iam/v1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" instancepb "google.golang.org/genproto/googleapis/spanner/admin/instance/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // InstanceAdminCallOptions contains the retry settings for each method of InstanceAdminClient. type InstanceAdminCallOptions struct { ListInstanceConfigs []gax.CallOption GetInstanceConfig []gax.CallOption ListInstances []gax.CallOption GetInstance []gax.CallOption CreateInstance []gax.CallOption UpdateInstance []gax.CallOption DeleteInstance []gax.CallOption SetIamPolicy []gax.CallOption GetIamPolicy []gax.CallOption TestIamPermissions []gax.CallOption } func defaultInstanceAdminClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("spanner.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultInstanceAdminCallOptions() *InstanceAdminCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 1000 * time.Millisecond, Max: 32000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &InstanceAdminCallOptions{ ListInstanceConfigs: retry[[2]string{"default", "idempotent"}], GetInstanceConfig: retry[[2]string{"default", "idempotent"}], ListInstances: retry[[2]string{"default", "idempotent"}], GetInstance: retry[[2]string{"default", "idempotent"}], CreateInstance: retry[[2]string{"default", "non_idempotent"}], UpdateInstance: retry[[2]string{"default", "non_idempotent"}], DeleteInstance: retry[[2]string{"default", "idempotent"}], SetIamPolicy: retry[[2]string{"default", "non_idempotent"}], GetIamPolicy: retry[[2]string{"default", "idempotent"}], TestIamPermissions: retry[[2]string{"default", "non_idempotent"}], } } // InstanceAdminClient is a client for interacting with Cloud Spanner Instance Admin API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type InstanceAdminClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. instanceAdminClient instancepb.InstanceAdminClient // LROClient is used internally to handle longrunning operations. // It is exposed so that its CallOptions can be modified if required. // Users should not Close this client. LROClient *lroauto.OperationsClient // The call options for this service. CallOptions *InstanceAdminCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewInstanceAdminClient creates a new instance admin client. // // Cloud Spanner Instance Admin API // // The Cloud Spanner Instance Admin API can be used to create, delete, // modify and list instances. Instances are dedicated Cloud Spanner serving // and storage resources to be used by Cloud Spanner databases. // // Each instance has a "configuration", which dictates where the // serving resources for the Cloud Spanner instance are located (e.g., // US-central, Europe). Configurations are created by Google based on // resource availability. // // Cloud Spanner billing is based on the instances that exist and their // sizes. After an instance exists, there are no additional // per-database or per-operation charges for use of the instance // (though there may be additional network bandwidth charges). // Instances offer isolation: problems with databases in one instance // will not affect other instances. However, within an instance // databases can affect each other. For example, if one database in an // instance receives a lot of requests and consumes most of the // instance resources, fewer resources are available for other // databases in that instance, and their performance may suffer. func NewInstanceAdminClient(ctx context.Context, opts ...option.ClientOption) (*InstanceAdminClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultInstanceAdminClientOptions(), opts...)...) if err != nil { return nil, err } c := &InstanceAdminClient{ conn: conn, CallOptions: defaultInstanceAdminCallOptions(), instanceAdminClient: instancepb.NewInstanceAdminClient(conn), } c.setGoogleClientInfo() c.LROClient, err = lroauto.NewOperationsClient(ctx, option.WithGRPCConn(conn)) if err != nil { // This error "should not happen", since we are just reusing old connection // and never actually need to dial. // If this does happen, we could leak conn. However, we cannot close conn: // If the user invoked the function with option.WithGRPCConn, // we would close a connection that's still in use. // TODO(pongad): investigate error conditions. return nil, err } return c, nil } // Connection returns the client's connection to the API service. func (c *InstanceAdminClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *InstanceAdminClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *InstanceAdminClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // ListInstanceConfigs lists the supported instance configurations for a given project. func (c *InstanceAdminClient) ListInstanceConfigs(ctx context.Context, req *instancepb.ListInstanceConfigsRequest, opts ...gax.CallOption) *InstanceConfigIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListInstanceConfigs[0:len(c.CallOptions.ListInstanceConfigs):len(c.CallOptions.ListInstanceConfigs)], opts...) it := &InstanceConfigIterator{} req = proto.Clone(req).(*instancepb.ListInstanceConfigsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*instancepb.InstanceConfig, string, error) { var resp *instancepb.ListInstanceConfigsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.instanceAdminClient.ListInstanceConfigs(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.InstanceConfigs, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetInstanceConfig gets information about a particular instance configuration. func (c *InstanceAdminClient) GetInstanceConfig(ctx context.Context, req *instancepb.GetInstanceConfigRequest, opts ...gax.CallOption) (*instancepb.InstanceConfig, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetInstanceConfig[0:len(c.CallOptions.GetInstanceConfig):len(c.CallOptions.GetInstanceConfig)], opts...) var resp *instancepb.InstanceConfig err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.instanceAdminClient.GetInstanceConfig(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListInstances lists all instances in the given project. func (c *InstanceAdminClient) ListInstances(ctx context.Context, req *instancepb.ListInstancesRequest, opts ...gax.CallOption) *InstanceIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListInstances[0:len(c.CallOptions.ListInstances):len(c.CallOptions.ListInstances)], opts...) it := &InstanceIterator{} req = proto.Clone(req).(*instancepb.ListInstancesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*instancepb.Instance, string, error) { var resp *instancepb.ListInstancesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.instanceAdminClient.ListInstances(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Instances, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetInstance gets information about a particular instance. func (c *InstanceAdminClient) GetInstance(ctx context.Context, req *instancepb.GetInstanceRequest, opts ...gax.CallOption) (*instancepb.Instance, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetInstance[0:len(c.CallOptions.GetInstance):len(c.CallOptions.GetInstance)], opts...) var resp *instancepb.Instance err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.instanceAdminClient.GetInstance(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // CreateInstance creates an instance and begins preparing it to begin serving. The // returned [long-running operation][google.longrunning.Operation] // can be used to track the progress of preparing the new // instance. The instance name is assigned by the caller. If the // named instance already exists, CreateInstance returns // ALREADY_EXISTS. // // Immediately upon completion of this request: // // The instance is readable via the API, with all requested attributes // but no allocated resources. Its state is CREATING. // // Until completion of the returned operation: // // Cancelling the operation renders the instance immediately unreadable // via the API. // // The instance can be deleted. // // All other attempts to modify the instance are rejected. // // Upon completion of the returned operation: // // Billing for all successfully-allocated resources begins (some types // may have lower than the requested levels). // // Databases can be created in the instance. // // The instance's allocated resource levels are readable via the API. // // The instance's state becomes READY. // // The returned [long-running operation][google.longrunning.Operation] will // have a name of the format /operations/ and // can be used to track creation of the instance. The // [metadata][google.longrunning.Operation.metadata] field type is // [CreateInstanceMetadata][google.spanner.admin.instance.v1.CreateInstanceMetadata]. // The [response][google.longrunning.Operation.response] field type is // [Instance][google.spanner.admin.instance.v1.Instance], if successful. func (c *InstanceAdminClient) CreateInstance(ctx context.Context, req *instancepb.CreateInstanceRequest, opts ...gax.CallOption) (*CreateInstanceOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateInstance[0:len(c.CallOptions.CreateInstance):len(c.CallOptions.CreateInstance)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.instanceAdminClient.CreateInstance(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &CreateInstanceOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // UpdateInstance updates an instance, and begins allocating or releasing resources // as requested. The returned [long-running // operation][google.longrunning.Operation] can be used to track the // progress of updating the instance. If the named instance does not // exist, returns NOT_FOUND. // // Immediately upon completion of this request: // // For resource types for which a decrease in the instance's allocation // has been requested, billing is based on the newly-requested level. // // Until completion of the returned operation: // // Cancelling the operation sets its metadata's // [cancel_time][google.spanner.admin.instance.v1.UpdateInstanceMetadata.cancel_time], and begins // restoring resources to their pre-request values. The operation // is guaranteed to succeed at undoing all resource changes, // after which point it terminates with a CANCELLED status. // // All other attempts to modify the instance are rejected. // // Reading the instance via the API continues to give the pre-request // resource levels. // // Upon completion of the returned operation: // // Billing begins for all successfully-allocated resources (some types // may have lower than the requested levels). // // All newly-reserved resources are available for serving the instance's // tables. // // The instance's new resource levels are readable via the API. // // The returned [long-running operation][google.longrunning.Operation] will // have a name of the format /operations/ and // can be used to track the instance modification. The // [metadata][google.longrunning.Operation.metadata] field type is // [UpdateInstanceMetadata][google.spanner.admin.instance.v1.UpdateInstanceMetadata]. // The [response][google.longrunning.Operation.response] field type is // [Instance][google.spanner.admin.instance.v1.Instance], if successful. // // Authorization requires spanner.instances.update permission on // resource [name][google.spanner.admin.instance.v1.Instance.name]. func (c *InstanceAdminClient) UpdateInstance(ctx context.Context, req *instancepb.UpdateInstanceRequest, opts ...gax.CallOption) (*UpdateInstanceOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "instance.name", url.QueryEscape(req.GetInstance().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateInstance[0:len(c.CallOptions.UpdateInstance):len(c.CallOptions.UpdateInstance)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.instanceAdminClient.UpdateInstance(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &UpdateInstanceOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // DeleteInstance deletes an instance. // // Immediately upon completion of the request: // // Billing ceases for all of the instance's reserved resources. // // Soon afterward: // // The instance and all of its databases immediately and // irrevocably disappear from the API. All data in the databases // is permanently deleted. func (c *InstanceAdminClient) DeleteInstance(ctx context.Context, req *instancepb.DeleteInstanceRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteInstance[0:len(c.CallOptions.DeleteInstance):len(c.CallOptions.DeleteInstance)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.instanceAdminClient.DeleteInstance(ctx, req, settings.GRPC...) return err }, opts...) return err } // SetIamPolicy sets the access control policy on an instance resource. Replaces any // existing policy. // // Authorization requires spanner.instances.setIamPolicy on // [resource][google.iam.v1.SetIamPolicyRequest.resource]. func (c *InstanceAdminClient) SetIamPolicy(ctx context.Context, req *iampb.SetIamPolicyRequest, opts ...gax.CallOption) (*iampb.Policy, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.SetIamPolicy[0:len(c.CallOptions.SetIamPolicy):len(c.CallOptions.SetIamPolicy)], opts...) var resp *iampb.Policy err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.instanceAdminClient.SetIamPolicy(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetIamPolicy gets the access control policy for an instance resource. Returns an empty // policy if an instance exists but does not have a policy set. // // Authorization requires spanner.instances.getIamPolicy on // [resource][google.iam.v1.GetIamPolicyRequest.resource]. func (c *InstanceAdminClient) GetIamPolicy(ctx context.Context, req *iampb.GetIamPolicyRequest, opts ...gax.CallOption) (*iampb.Policy, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetIamPolicy[0:len(c.CallOptions.GetIamPolicy):len(c.CallOptions.GetIamPolicy)], opts...) var resp *iampb.Policy err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.instanceAdminClient.GetIamPolicy(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // TestIamPermissions returns permissions that the caller has on the specified instance resource. // // Attempting this RPC on a non-existent Cloud Spanner instance resource will // result in a NOT_FOUND error if the user has spanner.instances.list // permission on the containing Google Cloud Project. Otherwise returns an // empty set of permissions. func (c *InstanceAdminClient) TestIamPermissions(ctx context.Context, req *iampb.TestIamPermissionsRequest, opts ...gax.CallOption) (*iampb.TestIamPermissionsResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.TestIamPermissions[0:len(c.CallOptions.TestIamPermissions):len(c.CallOptions.TestIamPermissions)], opts...) var resp *iampb.TestIamPermissionsResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.instanceAdminClient.TestIamPermissions(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // InstanceConfigIterator manages a stream of *instancepb.InstanceConfig. type InstanceConfigIterator struct { items []*instancepb.InstanceConfig pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*instancepb.InstanceConfig, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *InstanceConfigIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *InstanceConfigIterator) Next() (*instancepb.InstanceConfig, error) { var item *instancepb.InstanceConfig if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *InstanceConfigIterator) bufLen() int { return len(it.items) } func (it *InstanceConfigIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // InstanceIterator manages a stream of *instancepb.Instance. type InstanceIterator struct { items []*instancepb.Instance pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*instancepb.Instance, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *InstanceIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *InstanceIterator) Next() (*instancepb.Instance, error) { var item *instancepb.Instance if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *InstanceIterator) bufLen() int { return len(it.items) } func (it *InstanceIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // CreateInstanceOperation manages a long-running operation from CreateInstance. type CreateInstanceOperation struct { lro *longrunning.Operation } // CreateInstanceOperation returns a new CreateInstanceOperation from a given name. // The name must be that of a previously created CreateInstanceOperation, possibly from a different process. func (c *InstanceAdminClient) CreateInstanceOperation(name string) *CreateInstanceOperation { return &CreateInstanceOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *CreateInstanceOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*instancepb.Instance, error) { var resp instancepb.Instance if err := op.lro.WaitWithInterval(ctx, &resp, 45000*time.Millisecond, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *CreateInstanceOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*instancepb.Instance, error) { var resp instancepb.Instance if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *CreateInstanceOperation) Metadata() (*instancepb.CreateInstanceMetadata, error) { var meta instancepb.CreateInstanceMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *CreateInstanceOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *CreateInstanceOperation) Name() string { return op.lro.Name() } // UpdateInstanceOperation manages a long-running operation from UpdateInstance. type UpdateInstanceOperation struct { lro *longrunning.Operation } // UpdateInstanceOperation returns a new UpdateInstanceOperation from a given name. // The name must be that of a previously created UpdateInstanceOperation, possibly from a different process. func (c *InstanceAdminClient) UpdateInstanceOperation(name string) *UpdateInstanceOperation { return &UpdateInstanceOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *UpdateInstanceOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*instancepb.Instance, error) { var resp instancepb.Instance if err := op.lro.WaitWithInterval(ctx, &resp, 45000*time.Millisecond, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *UpdateInstanceOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*instancepb.Instance, error) { var resp instancepb.Instance if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *UpdateInstanceOperation) Metadata() (*instancepb.UpdateInstanceMetadata, error) { var meta instancepb.UpdateInstanceMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *UpdateInstanceOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *UpdateInstanceOperation) Name() string { return op.lro.Name() } google-cloud-go-0.49.0/spanner/admin/instance/apiv1/instance_admin_client_example_test.go000066400000000000000000000120211356504100700315610ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package instance_test import ( "context" instance "cloud.google.com/go/spanner/admin/instance/apiv1" "google.golang.org/api/iterator" iampb "google.golang.org/genproto/googleapis/iam/v1" instancepb "google.golang.org/genproto/googleapis/spanner/admin/instance/v1" ) func ExampleNewInstanceAdminClient() { ctx := context.Background() c, err := instance.NewInstanceAdminClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleInstanceAdminClient_ListInstanceConfigs() { ctx := context.Background() c, err := instance.NewInstanceAdminClient(ctx) if err != nil { // TODO: Handle error. } req := &instancepb.ListInstanceConfigsRequest{ // TODO: Fill request struct fields. } it := c.ListInstanceConfigs(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleInstanceAdminClient_GetInstanceConfig() { ctx := context.Background() c, err := instance.NewInstanceAdminClient(ctx) if err != nil { // TODO: Handle error. } req := &instancepb.GetInstanceConfigRequest{ // TODO: Fill request struct fields. } resp, err := c.GetInstanceConfig(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleInstanceAdminClient_ListInstances() { ctx := context.Background() c, err := instance.NewInstanceAdminClient(ctx) if err != nil { // TODO: Handle error. } req := &instancepb.ListInstancesRequest{ // TODO: Fill request struct fields. } it := c.ListInstances(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleInstanceAdminClient_GetInstance() { ctx := context.Background() c, err := instance.NewInstanceAdminClient(ctx) if err != nil { // TODO: Handle error. } req := &instancepb.GetInstanceRequest{ // TODO: Fill request struct fields. } resp, err := c.GetInstance(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleInstanceAdminClient_CreateInstance() { ctx := context.Background() c, err := instance.NewInstanceAdminClient(ctx) if err != nil { // TODO: Handle error. } req := &instancepb.CreateInstanceRequest{ // TODO: Fill request struct fields. } op, err := c.CreateInstance(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleInstanceAdminClient_UpdateInstance() { ctx := context.Background() c, err := instance.NewInstanceAdminClient(ctx) if err != nil { // TODO: Handle error. } req := &instancepb.UpdateInstanceRequest{ // TODO: Fill request struct fields. } op, err := c.UpdateInstance(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleInstanceAdminClient_DeleteInstance() { ctx := context.Background() c, err := instance.NewInstanceAdminClient(ctx) if err != nil { // TODO: Handle error. } req := &instancepb.DeleteInstanceRequest{ // TODO: Fill request struct fields. } err = c.DeleteInstance(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleInstanceAdminClient_SetIamPolicy() { ctx := context.Background() c, err := instance.NewInstanceAdminClient(ctx) if err != nil { // TODO: Handle error. } req := &iampb.SetIamPolicyRequest{ // TODO: Fill request struct fields. } resp, err := c.SetIamPolicy(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleInstanceAdminClient_GetIamPolicy() { ctx := context.Background() c, err := instance.NewInstanceAdminClient(ctx) if err != nil { // TODO: Handle error. } req := &iampb.GetIamPolicyRequest{ // TODO: Fill request struct fields. } resp, err := c.GetIamPolicy(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleInstanceAdminClient_TestIamPermissions() { ctx := context.Background() c, err := instance.NewInstanceAdminClient(ctx) if err != nil { // TODO: Handle error. } req := &iampb.TestIamPermissionsRequest{ // TODO: Fill request struct fields. } resp, err := c.TestIamPermissions(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/spanner/admin/instance/apiv1/mock_test.go000066400000000000000000000633461356504100700245050ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package instance import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" "google.golang.org/api/option" iampb "google.golang.org/genproto/googleapis/iam/v1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" instancepb "google.golang.org/genproto/googleapis/spanner/admin/instance/v1" field_maskpb "google.golang.org/genproto/protobuf/field_mask" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockInstanceAdminServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. instancepb.InstanceAdminServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockInstanceAdminServer) ListInstanceConfigs(ctx context.Context, req *instancepb.ListInstanceConfigsRequest) (*instancepb.ListInstanceConfigsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*instancepb.ListInstanceConfigsResponse), nil } func (s *mockInstanceAdminServer) GetInstanceConfig(ctx context.Context, req *instancepb.GetInstanceConfigRequest) (*instancepb.InstanceConfig, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*instancepb.InstanceConfig), nil } func (s *mockInstanceAdminServer) ListInstances(ctx context.Context, req *instancepb.ListInstancesRequest) (*instancepb.ListInstancesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*instancepb.ListInstancesResponse), nil } func (s *mockInstanceAdminServer) GetInstance(ctx context.Context, req *instancepb.GetInstanceRequest) (*instancepb.Instance, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*instancepb.Instance), nil } func (s *mockInstanceAdminServer) CreateInstance(ctx context.Context, req *instancepb.CreateInstanceRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockInstanceAdminServer) UpdateInstance(ctx context.Context, req *instancepb.UpdateInstanceRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockInstanceAdminServer) DeleteInstance(ctx context.Context, req *instancepb.DeleteInstanceRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockInstanceAdminServer) SetIamPolicy(ctx context.Context, req *iampb.SetIamPolicyRequest) (*iampb.Policy, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iampb.Policy), nil } func (s *mockInstanceAdminServer) GetIamPolicy(ctx context.Context, req *iampb.GetIamPolicyRequest) (*iampb.Policy, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iampb.Policy), nil } func (s *mockInstanceAdminServer) TestIamPermissions(ctx context.Context, req *iampb.TestIamPermissionsRequest) (*iampb.TestIamPermissionsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*iampb.TestIamPermissionsResponse), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockInstanceAdmin mockInstanceAdminServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() instancepb.RegisterInstanceAdminServer(serv, &mockInstanceAdmin) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestInstanceAdminListInstanceConfigs(t *testing.T) { var nextPageToken string = "" var instanceConfigsElement *instancepb.InstanceConfig = &instancepb.InstanceConfig{} var instanceConfigs = []*instancepb.InstanceConfig{instanceConfigsElement} var expectedResponse = &instancepb.ListInstanceConfigsResponse{ NextPageToken: nextPageToken, InstanceConfigs: instanceConfigs, } mockInstanceAdmin.err = nil mockInstanceAdmin.reqs = nil mockInstanceAdmin.resps = append(mockInstanceAdmin.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &instancepb.ListInstanceConfigsRequest{ Parent: formattedParent, } c, err := NewInstanceAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListInstanceConfigs(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockInstanceAdmin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.InstanceConfigs[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestInstanceAdminListInstanceConfigsError(t *testing.T) { errCode := codes.PermissionDenied mockInstanceAdmin.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &instancepb.ListInstanceConfigsRequest{ Parent: formattedParent, } c, err := NewInstanceAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListInstanceConfigs(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestInstanceAdminGetInstanceConfig(t *testing.T) { var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var expectedResponse = &instancepb.InstanceConfig{ Name: name2, DisplayName: displayName, } mockInstanceAdmin.err = nil mockInstanceAdmin.reqs = nil mockInstanceAdmin.resps = append(mockInstanceAdmin.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/instanceConfigs/%s", "[PROJECT]", "[INSTANCE_CONFIG]") var request = &instancepb.GetInstanceConfigRequest{ Name: formattedName, } c, err := NewInstanceAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetInstanceConfig(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockInstanceAdmin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestInstanceAdminGetInstanceConfigError(t *testing.T) { errCode := codes.PermissionDenied mockInstanceAdmin.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/instanceConfigs/%s", "[PROJECT]", "[INSTANCE_CONFIG]") var request = &instancepb.GetInstanceConfigRequest{ Name: formattedName, } c, err := NewInstanceAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetInstanceConfig(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestInstanceAdminListInstances(t *testing.T) { var nextPageToken string = "" var instancesElement *instancepb.Instance = &instancepb.Instance{} var instances = []*instancepb.Instance{instancesElement} var expectedResponse = &instancepb.ListInstancesResponse{ NextPageToken: nextPageToken, Instances: instances, } mockInstanceAdmin.err = nil mockInstanceAdmin.reqs = nil mockInstanceAdmin.resps = append(mockInstanceAdmin.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &instancepb.ListInstancesRequest{ Parent: formattedParent, } c, err := NewInstanceAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListInstances(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockInstanceAdmin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Instances[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestInstanceAdminListInstancesError(t *testing.T) { errCode := codes.PermissionDenied mockInstanceAdmin.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &instancepb.ListInstancesRequest{ Parent: formattedParent, } c, err := NewInstanceAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListInstances(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestInstanceAdminGetInstance(t *testing.T) { var name2 string = "name2-1052831874" var config string = "config-1354792126" var displayName string = "displayName1615086568" var nodeCount int32 = 1539922066 var expectedResponse = &instancepb.Instance{ Name: name2, Config: config, DisplayName: displayName, NodeCount: nodeCount, } mockInstanceAdmin.err = nil mockInstanceAdmin.reqs = nil mockInstanceAdmin.resps = append(mockInstanceAdmin.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/instances/%s", "[PROJECT]", "[INSTANCE]") var request = &instancepb.GetInstanceRequest{ Name: formattedName, } c, err := NewInstanceAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetInstance(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockInstanceAdmin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestInstanceAdminGetInstanceError(t *testing.T) { errCode := codes.PermissionDenied mockInstanceAdmin.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/instances/%s", "[PROJECT]", "[INSTANCE]") var request = &instancepb.GetInstanceRequest{ Name: formattedName, } c, err := NewInstanceAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetInstance(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestInstanceAdminCreateInstance(t *testing.T) { var name string = "name3373707" var config string = "config-1354792126" var displayName string = "displayName1615086568" var nodeCount int32 = 1539922066 var expectedResponse = &instancepb.Instance{ Name: name, Config: config, DisplayName: displayName, NodeCount: nodeCount, } mockInstanceAdmin.err = nil mockInstanceAdmin.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockInstanceAdmin.resps = append(mockInstanceAdmin.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var instanceId string = "instanceId-2101995259" var instance *instancepb.Instance = &instancepb.Instance{} var request = &instancepb.CreateInstanceRequest{ Parent: formattedParent, InstanceId: instanceId, Instance: instance, } c, err := NewInstanceAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.CreateInstance(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockInstanceAdmin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestInstanceAdminCreateInstanceError(t *testing.T) { errCode := codes.PermissionDenied mockInstanceAdmin.err = nil mockInstanceAdmin.resps = append(mockInstanceAdmin.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var instanceId string = "instanceId-2101995259" var instance *instancepb.Instance = &instancepb.Instance{} var request = &instancepb.CreateInstanceRequest{ Parent: formattedParent, InstanceId: instanceId, Instance: instance, } c, err := NewInstanceAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.CreateInstance(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestInstanceAdminUpdateInstance(t *testing.T) { var name string = "name3373707" var config string = "config-1354792126" var displayName string = "displayName1615086568" var nodeCount int32 = 1539922066 var expectedResponse = &instancepb.Instance{ Name: name, Config: config, DisplayName: displayName, NodeCount: nodeCount, } mockInstanceAdmin.err = nil mockInstanceAdmin.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockInstanceAdmin.resps = append(mockInstanceAdmin.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var instance *instancepb.Instance = &instancepb.Instance{} var fieldMask *field_maskpb.FieldMask = &field_maskpb.FieldMask{} var request = &instancepb.UpdateInstanceRequest{ Instance: instance, FieldMask: fieldMask, } c, err := NewInstanceAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.UpdateInstance(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockInstanceAdmin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestInstanceAdminUpdateInstanceError(t *testing.T) { errCode := codes.PermissionDenied mockInstanceAdmin.err = nil mockInstanceAdmin.resps = append(mockInstanceAdmin.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var instance *instancepb.Instance = &instancepb.Instance{} var fieldMask *field_maskpb.FieldMask = &field_maskpb.FieldMask{} var request = &instancepb.UpdateInstanceRequest{ Instance: instance, FieldMask: fieldMask, } c, err := NewInstanceAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.UpdateInstance(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestInstanceAdminDeleteInstance(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockInstanceAdmin.err = nil mockInstanceAdmin.reqs = nil mockInstanceAdmin.resps = append(mockInstanceAdmin.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/instances/%s", "[PROJECT]", "[INSTANCE]") var request = &instancepb.DeleteInstanceRequest{ Name: formattedName, } c, err := NewInstanceAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteInstance(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockInstanceAdmin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestInstanceAdminDeleteInstanceError(t *testing.T) { errCode := codes.PermissionDenied mockInstanceAdmin.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/instances/%s", "[PROJECT]", "[INSTANCE]") var request = &instancepb.DeleteInstanceRequest{ Name: formattedName, } c, err := NewInstanceAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteInstance(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestInstanceAdminSetIamPolicy(t *testing.T) { var version int32 = 351608024 var etag []byte = []byte("21") var expectedResponse = &iampb.Policy{ Version: version, Etag: etag, } mockInstanceAdmin.err = nil mockInstanceAdmin.reqs = nil mockInstanceAdmin.resps = append(mockInstanceAdmin.resps[:0], expectedResponse) var resource string = "resource-341064690" var policy *iampb.Policy = &iampb.Policy{} var request = &iampb.SetIamPolicyRequest{ Resource: resource, Policy: policy, } c, err := NewInstanceAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetIamPolicy(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockInstanceAdmin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestInstanceAdminSetIamPolicyError(t *testing.T) { errCode := codes.PermissionDenied mockInstanceAdmin.err = gstatus.Error(errCode, "test error") var resource string = "resource-341064690" var policy *iampb.Policy = &iampb.Policy{} var request = &iampb.SetIamPolicyRequest{ Resource: resource, Policy: policy, } c, err := NewInstanceAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SetIamPolicy(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestInstanceAdminGetIamPolicy(t *testing.T) { var version int32 = 351608024 var etag []byte = []byte("21") var expectedResponse = &iampb.Policy{ Version: version, Etag: etag, } mockInstanceAdmin.err = nil mockInstanceAdmin.reqs = nil mockInstanceAdmin.resps = append(mockInstanceAdmin.resps[:0], expectedResponse) var resource string = "resource-341064690" var request = &iampb.GetIamPolicyRequest{ Resource: resource, } c, err := NewInstanceAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetIamPolicy(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockInstanceAdmin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestInstanceAdminGetIamPolicyError(t *testing.T) { errCode := codes.PermissionDenied mockInstanceAdmin.err = gstatus.Error(errCode, "test error") var resource string = "resource-341064690" var request = &iampb.GetIamPolicyRequest{ Resource: resource, } c, err := NewInstanceAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetIamPolicy(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestInstanceAdminTestIamPermissions(t *testing.T) { var expectedResponse *iampb.TestIamPermissionsResponse = &iampb.TestIamPermissionsResponse{} mockInstanceAdmin.err = nil mockInstanceAdmin.reqs = nil mockInstanceAdmin.resps = append(mockInstanceAdmin.resps[:0], expectedResponse) var resource string = "resource-341064690" var permissions []string = nil var request = &iampb.TestIamPermissionsRequest{ Resource: resource, Permissions: permissions, } c, err := NewInstanceAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.TestIamPermissions(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockInstanceAdmin.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestInstanceAdminTestIamPermissionsError(t *testing.T) { errCode := codes.PermissionDenied mockInstanceAdmin.err = gstatus.Error(errCode, "test error") var resource string = "resource-341064690" var permissions []string = nil var request = &iampb.TestIamPermissionsRequest{ Resource: resource, Permissions: permissions, } c, err := NewInstanceAdminClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.TestIamPermissions(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/spanner/admin/instance/apiv1/path_funcs.go000066400000000000000000000030031356504100700246270ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package instance // InstanceAdminProjectPath returns the path for the project resource. // // Deprecated: Use // fmt.Sprintf("projects/%s", project) // instead. func InstanceAdminProjectPath(project string) string { return "" + "projects/" + project + "" } // InstanceAdminInstanceConfigPath returns the path for the instance config resource. // // Deprecated: Use // fmt.Sprintf("projects/%s/instanceConfigs/%s", project, instanceConfig) // instead. func InstanceAdminInstanceConfigPath(project, instanceConfig string) string { return "" + "projects/" + project + "/instanceConfigs/" + instanceConfig + "" } // InstanceAdminInstancePath returns the path for the instance resource. // // Deprecated: Use // fmt.Sprintf("projects/%s/instances/%s", project, instance) // instead. func InstanceAdminInstancePath(project, instance string) string { return "" + "projects/" + project + "/instances/" + instance + "" } google-cloud-go-0.49.0/spanner/apiv1/000077500000000000000000000000001356504100700172565ustar00rootroot00000000000000google-cloud-go-0.49.0/spanner/apiv1/doc.go000066400000000000000000000054571356504100700203650ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package spanner is an auto-generated package for the // Cloud Spanner API. // // Cloud Spanner is a managed, mission-critical, globally consistent and // scalable relational database service. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. // // Use the client at cloud.google.com/go/spanner in preference to this. package spanner // import "cloud.google.com/go/spanner/apiv1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/spanner.data", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191115" google-cloud-go-0.49.0/spanner/apiv1/mock_test.go000066400000000000000000001074121356504100700216020ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package spanner import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" "google.golang.org/api/option" spannerpb "google.golang.org/genproto/googleapis/spanner/v1" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockSpannerServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. spannerpb.SpannerServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockSpannerServer) CreateSession(ctx context.Context, req *spannerpb.CreateSessionRequest) (*spannerpb.Session, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*spannerpb.Session), nil } func (s *mockSpannerServer) BatchCreateSessions(ctx context.Context, req *spannerpb.BatchCreateSessionsRequest) (*spannerpb.BatchCreateSessionsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*spannerpb.BatchCreateSessionsResponse), nil } func (s *mockSpannerServer) GetSession(ctx context.Context, req *spannerpb.GetSessionRequest) (*spannerpb.Session, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*spannerpb.Session), nil } func (s *mockSpannerServer) ListSessions(ctx context.Context, req *spannerpb.ListSessionsRequest) (*spannerpb.ListSessionsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*spannerpb.ListSessionsResponse), nil } func (s *mockSpannerServer) DeleteSession(ctx context.Context, req *spannerpb.DeleteSessionRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockSpannerServer) ExecuteSql(ctx context.Context, req *spannerpb.ExecuteSqlRequest) (*spannerpb.ResultSet, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*spannerpb.ResultSet), nil } func (s *mockSpannerServer) ExecuteStreamingSql(req *spannerpb.ExecuteSqlRequest, stream spannerpb.Spanner_ExecuteStreamingSqlServer) error { md, _ := metadata.FromIncomingContext(stream.Context()) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return s.err } for _, v := range s.resps { if err := stream.Send(v.(*spannerpb.PartialResultSet)); err != nil { return err } } return nil } func (s *mockSpannerServer) ExecuteBatchDml(ctx context.Context, req *spannerpb.ExecuteBatchDmlRequest) (*spannerpb.ExecuteBatchDmlResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*spannerpb.ExecuteBatchDmlResponse), nil } func (s *mockSpannerServer) Read(ctx context.Context, req *spannerpb.ReadRequest) (*spannerpb.ResultSet, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*spannerpb.ResultSet), nil } func (s *mockSpannerServer) StreamingRead(req *spannerpb.ReadRequest, stream spannerpb.Spanner_StreamingReadServer) error { md, _ := metadata.FromIncomingContext(stream.Context()) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return s.err } for _, v := range s.resps { if err := stream.Send(v.(*spannerpb.PartialResultSet)); err != nil { return err } } return nil } func (s *mockSpannerServer) BeginTransaction(ctx context.Context, req *spannerpb.BeginTransactionRequest) (*spannerpb.Transaction, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*spannerpb.Transaction), nil } func (s *mockSpannerServer) Commit(ctx context.Context, req *spannerpb.CommitRequest) (*spannerpb.CommitResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*spannerpb.CommitResponse), nil } func (s *mockSpannerServer) Rollback(ctx context.Context, req *spannerpb.RollbackRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockSpannerServer) PartitionQuery(ctx context.Context, req *spannerpb.PartitionQueryRequest) (*spannerpb.PartitionResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*spannerpb.PartitionResponse), nil } func (s *mockSpannerServer) PartitionRead(ctx context.Context, req *spannerpb.PartitionReadRequest) (*spannerpb.PartitionResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*spannerpb.PartitionResponse), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockSpanner mockSpannerServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() spannerpb.RegisterSpannerServer(serv, &mockSpanner) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestSpannerCreateSession(t *testing.T) { var name string = "name3373707" var expectedResponse = &spannerpb.Session{ Name: name, } mockSpanner.err = nil mockSpanner.reqs = nil mockSpanner.resps = append(mockSpanner.resps[:0], expectedResponse) var formattedDatabase string = fmt.Sprintf("projects/%s/instances/%s/databases/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]") var request = &spannerpb.CreateSessionRequest{ Database: formattedDatabase, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateSession(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSpanner.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSpannerCreateSessionError(t *testing.T) { errCode := codes.PermissionDenied mockSpanner.err = gstatus.Error(errCode, "test error") var formattedDatabase string = fmt.Sprintf("projects/%s/instances/%s/databases/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]") var request = &spannerpb.CreateSessionRequest{ Database: formattedDatabase, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateSession(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSpannerBatchCreateSessions(t *testing.T) { var expectedResponse *spannerpb.BatchCreateSessionsResponse = &spannerpb.BatchCreateSessionsResponse{} mockSpanner.err = nil mockSpanner.reqs = nil mockSpanner.resps = append(mockSpanner.resps[:0], expectedResponse) var formattedDatabase string = fmt.Sprintf("projects/%s/instances/%s/databases/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]") var sessionCount int32 = 185691686 var request = &spannerpb.BatchCreateSessionsRequest{ Database: formattedDatabase, SessionCount: sessionCount, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.BatchCreateSessions(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSpanner.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSpannerBatchCreateSessionsError(t *testing.T) { errCode := codes.PermissionDenied mockSpanner.err = gstatus.Error(errCode, "test error") var formattedDatabase string = fmt.Sprintf("projects/%s/instances/%s/databases/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]") var sessionCount int32 = 185691686 var request = &spannerpb.BatchCreateSessionsRequest{ Database: formattedDatabase, SessionCount: sessionCount, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.BatchCreateSessions(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSpannerGetSession(t *testing.T) { var name2 string = "name2-1052831874" var expectedResponse = &spannerpb.Session{ Name: name2, } mockSpanner.err = nil mockSpanner.reqs = nil mockSpanner.resps = append(mockSpanner.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/instances/%s/databases/%s/sessions/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]") var request = &spannerpb.GetSessionRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetSession(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSpanner.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSpannerGetSessionError(t *testing.T) { errCode := codes.PermissionDenied mockSpanner.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/instances/%s/databases/%s/sessions/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]") var request = &spannerpb.GetSessionRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetSession(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSpannerListSessions(t *testing.T) { var nextPageToken string = "" var sessionsElement *spannerpb.Session = &spannerpb.Session{} var sessions = []*spannerpb.Session{sessionsElement} var expectedResponse = &spannerpb.ListSessionsResponse{ NextPageToken: nextPageToken, Sessions: sessions, } mockSpanner.err = nil mockSpanner.reqs = nil mockSpanner.resps = append(mockSpanner.resps[:0], expectedResponse) var formattedDatabase string = fmt.Sprintf("projects/%s/instances/%s/databases/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]") var request = &spannerpb.ListSessionsRequest{ Database: formattedDatabase, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListSessions(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockSpanner.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Sessions[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSpannerListSessionsError(t *testing.T) { errCode := codes.PermissionDenied mockSpanner.err = gstatus.Error(errCode, "test error") var formattedDatabase string = fmt.Sprintf("projects/%s/instances/%s/databases/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]") var request = &spannerpb.ListSessionsRequest{ Database: formattedDatabase, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListSessions(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSpannerDeleteSession(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockSpanner.err = nil mockSpanner.reqs = nil mockSpanner.resps = append(mockSpanner.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/instances/%s/databases/%s/sessions/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]") var request = &spannerpb.DeleteSessionRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteSession(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSpanner.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestSpannerDeleteSessionError(t *testing.T) { errCode := codes.PermissionDenied mockSpanner.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/instances/%s/databases/%s/sessions/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]") var request = &spannerpb.DeleteSessionRequest{ Name: formattedName, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteSession(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestSpannerExecuteSql(t *testing.T) { var expectedResponse *spannerpb.ResultSet = &spannerpb.ResultSet{} mockSpanner.err = nil mockSpanner.reqs = nil mockSpanner.resps = append(mockSpanner.resps[:0], expectedResponse) var formattedSession string = fmt.Sprintf("projects/%s/instances/%s/databases/%s/sessions/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]") var sql string = "sql114126" var request = &spannerpb.ExecuteSqlRequest{ Session: formattedSession, Sql: sql, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ExecuteSql(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSpanner.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSpannerExecuteSqlError(t *testing.T) { errCode := codes.PermissionDenied mockSpanner.err = gstatus.Error(errCode, "test error") var formattedSession string = fmt.Sprintf("projects/%s/instances/%s/databases/%s/sessions/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]") var sql string = "sql114126" var request = &spannerpb.ExecuteSqlRequest{ Session: formattedSession, Sql: sql, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ExecuteSql(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSpannerExecuteStreamingSql(t *testing.T) { var chunkedValue bool = true var resumeToken []byte = []byte("103") var expectedResponse = &spannerpb.PartialResultSet{ ChunkedValue: chunkedValue, ResumeToken: resumeToken, } mockSpanner.err = nil mockSpanner.reqs = nil mockSpanner.resps = append(mockSpanner.resps[:0], expectedResponse) var formattedSession string = fmt.Sprintf("projects/%s/instances/%s/databases/%s/sessions/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]") var sql string = "sql114126" var request = &spannerpb.ExecuteSqlRequest{ Session: formattedSession, Sql: sql, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } stream, err := c.ExecuteStreamingSql(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := stream.Recv() if err != nil { t.Fatal(err) } if want, got := request, mockSpanner.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSpannerExecuteStreamingSqlError(t *testing.T) { errCode := codes.PermissionDenied mockSpanner.err = gstatus.Error(errCode, "test error") var formattedSession string = fmt.Sprintf("projects/%s/instances/%s/databases/%s/sessions/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]") var sql string = "sql114126" var request = &spannerpb.ExecuteSqlRequest{ Session: formattedSession, Sql: sql, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } stream, err := c.ExecuteStreamingSql(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := stream.Recv() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSpannerExecuteBatchDml(t *testing.T) { var expectedResponse *spannerpb.ExecuteBatchDmlResponse = &spannerpb.ExecuteBatchDmlResponse{} mockSpanner.err = nil mockSpanner.reqs = nil mockSpanner.resps = append(mockSpanner.resps[:0], expectedResponse) var formattedSession string = fmt.Sprintf("projects/%s/instances/%s/databases/%s/sessions/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]") var transaction *spannerpb.TransactionSelector = &spannerpb.TransactionSelector{} var statements []*spannerpb.ExecuteBatchDmlRequest_Statement = nil var seqno int64 = 109325920 var request = &spannerpb.ExecuteBatchDmlRequest{ Session: formattedSession, Transaction: transaction, Statements: statements, Seqno: seqno, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ExecuteBatchDml(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSpanner.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSpannerExecuteBatchDmlError(t *testing.T) { errCode := codes.PermissionDenied mockSpanner.err = gstatus.Error(errCode, "test error") var formattedSession string = fmt.Sprintf("projects/%s/instances/%s/databases/%s/sessions/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]") var transaction *spannerpb.TransactionSelector = &spannerpb.TransactionSelector{} var statements []*spannerpb.ExecuteBatchDmlRequest_Statement = nil var seqno int64 = 109325920 var request = &spannerpb.ExecuteBatchDmlRequest{ Session: formattedSession, Transaction: transaction, Statements: statements, Seqno: seqno, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ExecuteBatchDml(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSpannerRead(t *testing.T) { var expectedResponse *spannerpb.ResultSet = &spannerpb.ResultSet{} mockSpanner.err = nil mockSpanner.reqs = nil mockSpanner.resps = append(mockSpanner.resps[:0], expectedResponse) var formattedSession string = fmt.Sprintf("projects/%s/instances/%s/databases/%s/sessions/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]") var table string = "table110115790" var columns []string = nil var keySet *spannerpb.KeySet = &spannerpb.KeySet{} var request = &spannerpb.ReadRequest{ Session: formattedSession, Table: table, Columns: columns, KeySet: keySet, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Read(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSpanner.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSpannerReadError(t *testing.T) { errCode := codes.PermissionDenied mockSpanner.err = gstatus.Error(errCode, "test error") var formattedSession string = fmt.Sprintf("projects/%s/instances/%s/databases/%s/sessions/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]") var table string = "table110115790" var columns []string = nil var keySet *spannerpb.KeySet = &spannerpb.KeySet{} var request = &spannerpb.ReadRequest{ Session: formattedSession, Table: table, Columns: columns, KeySet: keySet, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Read(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSpannerStreamingRead(t *testing.T) { var chunkedValue bool = true var resumeToken []byte = []byte("103") var expectedResponse = &spannerpb.PartialResultSet{ ChunkedValue: chunkedValue, ResumeToken: resumeToken, } mockSpanner.err = nil mockSpanner.reqs = nil mockSpanner.resps = append(mockSpanner.resps[:0], expectedResponse) var formattedSession string = fmt.Sprintf("projects/%s/instances/%s/databases/%s/sessions/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]") var table string = "table110115790" var columns []string = nil var keySet *spannerpb.KeySet = &spannerpb.KeySet{} var request = &spannerpb.ReadRequest{ Session: formattedSession, Table: table, Columns: columns, KeySet: keySet, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } stream, err := c.StreamingRead(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := stream.Recv() if err != nil { t.Fatal(err) } if want, got := request, mockSpanner.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSpannerStreamingReadError(t *testing.T) { errCode := codes.PermissionDenied mockSpanner.err = gstatus.Error(errCode, "test error") var formattedSession string = fmt.Sprintf("projects/%s/instances/%s/databases/%s/sessions/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]") var table string = "table110115790" var columns []string = nil var keySet *spannerpb.KeySet = &spannerpb.KeySet{} var request = &spannerpb.ReadRequest{ Session: formattedSession, Table: table, Columns: columns, KeySet: keySet, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } stream, err := c.StreamingRead(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := stream.Recv() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSpannerBeginTransaction(t *testing.T) { var id []byte = []byte("27") var expectedResponse = &spannerpb.Transaction{ Id: id, } mockSpanner.err = nil mockSpanner.reqs = nil mockSpanner.resps = append(mockSpanner.resps[:0], expectedResponse) var formattedSession string = fmt.Sprintf("projects/%s/instances/%s/databases/%s/sessions/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]") var options *spannerpb.TransactionOptions = &spannerpb.TransactionOptions{} var request = &spannerpb.BeginTransactionRequest{ Session: formattedSession, Options: options, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.BeginTransaction(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSpanner.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSpannerBeginTransactionError(t *testing.T) { errCode := codes.PermissionDenied mockSpanner.err = gstatus.Error(errCode, "test error") var formattedSession string = fmt.Sprintf("projects/%s/instances/%s/databases/%s/sessions/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]") var options *spannerpb.TransactionOptions = &spannerpb.TransactionOptions{} var request = &spannerpb.BeginTransactionRequest{ Session: formattedSession, Options: options, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.BeginTransaction(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSpannerCommit(t *testing.T) { var expectedResponse *spannerpb.CommitResponse = &spannerpb.CommitResponse{} mockSpanner.err = nil mockSpanner.reqs = nil mockSpanner.resps = append(mockSpanner.resps[:0], expectedResponse) var formattedSession string = fmt.Sprintf("projects/%s/instances/%s/databases/%s/sessions/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]") var request = &spannerpb.CommitRequest{ Session: formattedSession, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Commit(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSpanner.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSpannerCommitError(t *testing.T) { errCode := codes.PermissionDenied mockSpanner.err = gstatus.Error(errCode, "test error") var formattedSession string = fmt.Sprintf("projects/%s/instances/%s/databases/%s/sessions/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]") var request = &spannerpb.CommitRequest{ Session: formattedSession, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Commit(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSpannerRollback(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockSpanner.err = nil mockSpanner.reqs = nil mockSpanner.resps = append(mockSpanner.resps[:0], expectedResponse) var formattedSession string = fmt.Sprintf("projects/%s/instances/%s/databases/%s/sessions/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]") var transactionId []byte = []byte("28") var request = &spannerpb.RollbackRequest{ Session: formattedSession, TransactionId: transactionId, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.Rollback(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSpanner.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestSpannerRollbackError(t *testing.T) { errCode := codes.PermissionDenied mockSpanner.err = gstatus.Error(errCode, "test error") var formattedSession string = fmt.Sprintf("projects/%s/instances/%s/databases/%s/sessions/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]") var transactionId []byte = []byte("28") var request = &spannerpb.RollbackRequest{ Session: formattedSession, TransactionId: transactionId, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.Rollback(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestSpannerPartitionQuery(t *testing.T) { var expectedResponse *spannerpb.PartitionResponse = &spannerpb.PartitionResponse{} mockSpanner.err = nil mockSpanner.reqs = nil mockSpanner.resps = append(mockSpanner.resps[:0], expectedResponse) var formattedSession string = fmt.Sprintf("projects/%s/instances/%s/databases/%s/sessions/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]") var sql string = "sql114126" var request = &spannerpb.PartitionQueryRequest{ Session: formattedSession, Sql: sql, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.PartitionQuery(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSpanner.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSpannerPartitionQueryError(t *testing.T) { errCode := codes.PermissionDenied mockSpanner.err = gstatus.Error(errCode, "test error") var formattedSession string = fmt.Sprintf("projects/%s/instances/%s/databases/%s/sessions/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]") var sql string = "sql114126" var request = &spannerpb.PartitionQueryRequest{ Session: formattedSession, Sql: sql, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.PartitionQuery(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSpannerPartitionRead(t *testing.T) { var expectedResponse *spannerpb.PartitionResponse = &spannerpb.PartitionResponse{} mockSpanner.err = nil mockSpanner.reqs = nil mockSpanner.resps = append(mockSpanner.resps[:0], expectedResponse) var formattedSession string = fmt.Sprintf("projects/%s/instances/%s/databases/%s/sessions/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]") var table string = "table110115790" var keySet *spannerpb.KeySet = &spannerpb.KeySet{} var request = &spannerpb.PartitionReadRequest{ Session: formattedSession, Table: table, KeySet: keySet, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.PartitionRead(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSpanner.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSpannerPartitionReadError(t *testing.T) { errCode := codes.PermissionDenied mockSpanner.err = gstatus.Error(errCode, "test error") var formattedSession string = fmt.Sprintf("projects/%s/instances/%s/databases/%s/sessions/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]", "[SESSION]") var table string = "table110115790" var keySet *spannerpb.KeySet = &spannerpb.KeySet{} var request = &spannerpb.PartitionReadRequest{ Session: formattedSession, Table: table, KeySet: keySet, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.PartitionRead(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/spanner/apiv1/path_funcs.go000066400000000000000000000025331356504100700217420ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package spanner // DatabasePath returns the path for the database resource. // // Deprecated: Use // fmt.Sprintf("projects/%s/instances/%s/databases/%s", project, instance, database) // instead. func DatabasePath(project, instance, database string) string { return "" + "projects/" + project + "/instances/" + instance + "/databases/" + database + "" } // SessionPath returns the path for the session resource. // // Deprecated: Use // fmt.Sprintf("projects/%s/instances/%s/databases/%s/sessions/%s", project, instance, database, session) // instead. func SessionPath(project, instance, database, session string) string { return "" + "projects/" + project + "/instances/" + instance + "/databases/" + database + "/sessions/" + session + "" } google-cloud-go-0.49.0/spanner/apiv1/spanner_client.go000066400000000000000000000612761356504100700226250ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package spanner import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" spannerpb "google.golang.org/genproto/googleapis/spanner/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // CallOptions contains the retry settings for each method of Client. type CallOptions struct { CreateSession []gax.CallOption BatchCreateSessions []gax.CallOption GetSession []gax.CallOption ListSessions []gax.CallOption DeleteSession []gax.CallOption ExecuteSql []gax.CallOption ExecuteStreamingSql []gax.CallOption ExecuteBatchDml []gax.CallOption Read []gax.CallOption StreamingRead []gax.CallOption BeginTransaction []gax.CallOption Commit []gax.CallOption Rollback []gax.CallOption PartitionQuery []gax.CallOption PartitionRead []gax.CallOption } func defaultClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("spanner.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultCallOptions() *CallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, }, gax.Backoff{ Initial: 250 * time.Millisecond, Max: 32000 * time.Millisecond, Multiplier: 1.3, }) }), }, {"long_running", "long_running"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, }, gax.Backoff{ Initial: 250 * time.Millisecond, Max: 32000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &CallOptions{ CreateSession: retry[[2]string{"default", "idempotent"}], BatchCreateSessions: retry[[2]string{"default", "idempotent"}], GetSession: retry[[2]string{"default", "idempotent"}], ListSessions: retry[[2]string{"default", "idempotent"}], DeleteSession: retry[[2]string{"default", "idempotent"}], ExecuteSql: retry[[2]string{"default", "idempotent"}], ExecuteStreamingSql: retry[[2]string{"streaming", "non_idempotent"}], ExecuteBatchDml: retry[[2]string{"default", "idempotent"}], Read: retry[[2]string{"default", "idempotent"}], StreamingRead: retry[[2]string{"streaming", "non_idempotent"}], BeginTransaction: retry[[2]string{"default", "idempotent"}], Commit: retry[[2]string{"long_running", "long_running"}], Rollback: retry[[2]string{"default", "idempotent"}], PartitionQuery: retry[[2]string{"default", "idempotent"}], PartitionRead: retry[[2]string{"default", "idempotent"}], } } // Client is a client for interacting with Cloud Spanner API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. client spannerpb.SpannerClient // The call options for this service. CallOptions *CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewClient creates a new spanner client. // // Cloud Spanner API // // The Cloud Spanner API can be used to manage sessions and execute // transactions on data stored in Cloud Spanner databases. func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultClientOptions(), opts...)...) if err != nil { return nil, err } c := &Client{ conn: conn, CallOptions: defaultCallOptions(), client: spannerpb.NewSpannerClient(conn), } c.SetGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *Client) Close() error { return c.conn.Close() } // SetGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *Client) SetGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // CreateSession creates a new session. A session can be used to perform // transactions that read and/or modify data in a Cloud Spanner database. // Sessions are meant to be reused for many consecutive // transactions. // // Sessions can only execute one transaction at a time. To execute // multiple concurrent read-write/write-only transactions, create // multiple sessions. Note that standalone reads and queries use a // transaction internally, and count toward the one transaction // limit. // // Active sessions use additional server resources, so it is a good idea to // delete idle and unneeded sessions. // Aside from explicit deletes, Cloud Spanner can delete sessions for which no // operations are sent for more than an hour. If a session is deleted, // requests to it return NOT_FOUND. // // Idle sessions can be kept alive by sending a trivial SQL query // periodically, e.g., "SELECT 1". func (c *Client) CreateSession(ctx context.Context, req *spannerpb.CreateSessionRequest, opts ...gax.CallOption) (*spannerpb.Session, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "database", url.QueryEscape(req.GetDatabase()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateSession[0:len(c.CallOptions.CreateSession):len(c.CallOptions.CreateSession)], opts...) var resp *spannerpb.Session err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CreateSession(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // BatchCreateSessions creates multiple new sessions. // // This API can be used to initialize a session cache on the clients. // See https://goo.gl/TgSFN2 for best practices on session cache management. func (c *Client) BatchCreateSessions(ctx context.Context, req *spannerpb.BatchCreateSessionsRequest, opts ...gax.CallOption) (*spannerpb.BatchCreateSessionsResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "database", url.QueryEscape(req.GetDatabase()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.BatchCreateSessions[0:len(c.CallOptions.BatchCreateSessions):len(c.CallOptions.BatchCreateSessions)], opts...) var resp *spannerpb.BatchCreateSessionsResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.BatchCreateSessions(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetSession gets a session. Returns NOT_FOUND if the session does not exist. // This is mainly useful for determining whether a session is still // alive. func (c *Client) GetSession(ctx context.Context, req *spannerpb.GetSessionRequest, opts ...gax.CallOption) (*spannerpb.Session, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetSession[0:len(c.CallOptions.GetSession):len(c.CallOptions.GetSession)], opts...) var resp *spannerpb.Session err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetSession(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListSessions lists all sessions in a given database. func (c *Client) ListSessions(ctx context.Context, req *spannerpb.ListSessionsRequest, opts ...gax.CallOption) *SessionIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "database", url.QueryEscape(req.GetDatabase()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListSessions[0:len(c.CallOptions.ListSessions):len(c.CallOptions.ListSessions)], opts...) it := &SessionIterator{} req = proto.Clone(req).(*spannerpb.ListSessionsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*spannerpb.Session, string, error) { var resp *spannerpb.ListSessionsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListSessions(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Sessions, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // DeleteSession ends a session, releasing server resources associated with it. This will // asynchronously trigger cancellation of any operations that are running with // this session. func (c *Client) DeleteSession(ctx context.Context, req *spannerpb.DeleteSessionRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteSession[0:len(c.CallOptions.DeleteSession):len(c.CallOptions.DeleteSession)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.client.DeleteSession(ctx, req, settings.GRPC...) return err }, opts...) return err } // ExecuteSql executes an SQL statement, returning all results in a single reply. This // method cannot be used to return a result set larger than 10 MiB; // if the query yields more data than that, the query fails with // a FAILED_PRECONDITION error. // // Operations inside read-write transactions might return ABORTED. If // this occurs, the application should restart the transaction from // the beginning. See [Transaction][google.spanner.v1.Transaction] for more // details. // // Larger result sets can be fetched in streaming fashion by calling // [ExecuteStreamingSql][google.spanner.v1.Spanner.ExecuteStreamingSql] // instead. func (c *Client) ExecuteSql(ctx context.Context, req *spannerpb.ExecuteSqlRequest, opts ...gax.CallOption) (*spannerpb.ResultSet, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "session", url.QueryEscape(req.GetSession()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ExecuteSql[0:len(c.CallOptions.ExecuteSql):len(c.CallOptions.ExecuteSql)], opts...) var resp *spannerpb.ResultSet err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ExecuteSql(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ExecuteStreamingSql like [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql], except returns the // result set as a stream. Unlike // [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql], there is no limit on // the size of the returned result set. However, no individual row in the // result set can exceed 100 MiB, and no column value can exceed 10 MiB. func (c *Client) ExecuteStreamingSql(ctx context.Context, req *spannerpb.ExecuteSqlRequest, opts ...gax.CallOption) (spannerpb.Spanner_ExecuteStreamingSqlClient, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "session", url.QueryEscape(req.GetSession()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ExecuteStreamingSql[0:len(c.CallOptions.ExecuteStreamingSql):len(c.CallOptions.ExecuteStreamingSql)], opts...) var resp spannerpb.Spanner_ExecuteStreamingSqlClient err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ExecuteStreamingSql(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ExecuteBatchDml executes a batch of SQL DML statements. This method allows many statements // to be run with lower latency than submitting them sequentially with // [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql]. // // Statements are executed in sequential order. A request can succeed even if // a statement fails. The // [ExecuteBatchDmlResponse.status][google.spanner.v1.ExecuteBatchDmlResponse.status] // field in the response provides information about the statement that failed. // Clients must inspect this field to determine whether an error occurred. // // Execution stops after the first failed statement; the remaining statements // are not executed. func (c *Client) ExecuteBatchDml(ctx context.Context, req *spannerpb.ExecuteBatchDmlRequest, opts ...gax.CallOption) (*spannerpb.ExecuteBatchDmlResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "session", url.QueryEscape(req.GetSession()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ExecuteBatchDml[0:len(c.CallOptions.ExecuteBatchDml):len(c.CallOptions.ExecuteBatchDml)], opts...) var resp *spannerpb.ExecuteBatchDmlResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ExecuteBatchDml(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // Read reads rows from the database using key lookups and scans, as a // simple key/value style alternative to // [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql]. This method cannot be // used to return a result set larger than 10 MiB; if the read matches more // data than that, the read fails with a FAILED_PRECONDITION // error. // // Reads inside read-write transactions might return ABORTED. If // this occurs, the application should restart the transaction from // the beginning. See [Transaction][google.spanner.v1.Transaction] for more // details. // // Larger result sets can be yielded in streaming fashion by calling // [StreamingRead][google.spanner.v1.Spanner.StreamingRead] instead. func (c *Client) Read(ctx context.Context, req *spannerpb.ReadRequest, opts ...gax.CallOption) (*spannerpb.ResultSet, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "session", url.QueryEscape(req.GetSession()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.Read[0:len(c.CallOptions.Read):len(c.CallOptions.Read)], opts...) var resp *spannerpb.ResultSet err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.Read(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // StreamingRead like [Read][google.spanner.v1.Spanner.Read], except returns the result set // as a stream. Unlike [Read][google.spanner.v1.Spanner.Read], there is no // limit on the size of the returned result set. However, no individual row in // the result set can exceed 100 MiB, and no column value can exceed // 10 MiB. func (c *Client) StreamingRead(ctx context.Context, req *spannerpb.ReadRequest, opts ...gax.CallOption) (spannerpb.Spanner_StreamingReadClient, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "session", url.QueryEscape(req.GetSession()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.StreamingRead[0:len(c.CallOptions.StreamingRead):len(c.CallOptions.StreamingRead)], opts...) var resp spannerpb.Spanner_StreamingReadClient err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.StreamingRead(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // BeginTransaction begins a new transaction. This step can often be skipped: // [Read][google.spanner.v1.Spanner.Read], // [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql] and // [Commit][google.spanner.v1.Spanner.Commit] can begin a new transaction as a // side-effect. func (c *Client) BeginTransaction(ctx context.Context, req *spannerpb.BeginTransactionRequest, opts ...gax.CallOption) (*spannerpb.Transaction, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "session", url.QueryEscape(req.GetSession()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.BeginTransaction[0:len(c.CallOptions.BeginTransaction):len(c.CallOptions.BeginTransaction)], opts...) var resp *spannerpb.Transaction err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.BeginTransaction(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // Commit commits a transaction. The request includes the mutations to be // applied to rows in the database. // // Commit might return an ABORTED error. This can occur at any time; // commonly, the cause is conflicts with concurrent // transactions. However, it can also happen for a variety of other // reasons. If Commit returns ABORTED, the caller should re-attempt // the transaction from the beginning, re-using the same session. func (c *Client) Commit(ctx context.Context, req *spannerpb.CommitRequest, opts ...gax.CallOption) (*spannerpb.CommitResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "session", url.QueryEscape(req.GetSession()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.Commit[0:len(c.CallOptions.Commit):len(c.CallOptions.Commit)], opts...) var resp *spannerpb.CommitResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.Commit(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // Rollback rolls back a transaction, releasing any locks it holds. It is a good // idea to call this for any transaction that includes one or more // [Read][google.spanner.v1.Spanner.Read] or // [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql] requests and ultimately // decides not to commit. // // Rollback returns OK if it successfully aborts the transaction, the // transaction was already aborted, or the transaction is not // found. Rollback never returns ABORTED. func (c *Client) Rollback(ctx context.Context, req *spannerpb.RollbackRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "session", url.QueryEscape(req.GetSession()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.Rollback[0:len(c.CallOptions.Rollback):len(c.CallOptions.Rollback)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.client.Rollback(ctx, req, settings.GRPC...) return err }, opts...) return err } // PartitionQuery creates a set of partition tokens that can be used to execute a query // operation in parallel. Each of the returned partition tokens can be used // by [ExecuteStreamingSql][google.spanner.v1.Spanner.ExecuteStreamingSql] to // specify a subset of the query result to read. The same session and // read-only transaction must be used by the PartitionQueryRequest used to // create the partition tokens and the ExecuteSqlRequests that use the // partition tokens. // // Partition tokens become invalid when the session used to create them // is deleted, is idle for too long, begins a new transaction, or becomes too // old. When any of these happen, it is not possible to resume the query, and // the whole operation must be restarted from the beginning. func (c *Client) PartitionQuery(ctx context.Context, req *spannerpb.PartitionQueryRequest, opts ...gax.CallOption) (*spannerpb.PartitionResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "session", url.QueryEscape(req.GetSession()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.PartitionQuery[0:len(c.CallOptions.PartitionQuery):len(c.CallOptions.PartitionQuery)], opts...) var resp *spannerpb.PartitionResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.PartitionQuery(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // PartitionRead creates a set of partition tokens that can be used to execute a read // operation in parallel. Each of the returned partition tokens can be used // by [StreamingRead][google.spanner.v1.Spanner.StreamingRead] to specify a // subset of the read result to read. The same session and read-only // transaction must be used by the PartitionReadRequest used to create the // partition tokens and the ReadRequests that use the partition tokens. There // are no ordering guarantees on rows returned among the returned partition // tokens, or even within each individual StreamingRead call issued with a // partition_token. // // Partition tokens become invalid when the session used to create them // is deleted, is idle for too long, begins a new transaction, or becomes too // old. When any of these happen, it is not possible to resume the read, and // the whole operation must be restarted from the beginning. func (c *Client) PartitionRead(ctx context.Context, req *spannerpb.PartitionReadRequest, opts ...gax.CallOption) (*spannerpb.PartitionResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "session", url.QueryEscape(req.GetSession()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.PartitionRead[0:len(c.CallOptions.PartitionRead):len(c.CallOptions.PartitionRead)], opts...) var resp *spannerpb.PartitionResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.PartitionRead(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // SessionIterator manages a stream of *spannerpb.Session. type SessionIterator struct { items []*spannerpb.Session pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*spannerpb.Session, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *SessionIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *SessionIterator) Next() (*spannerpb.Session, error) { var item *spannerpb.Session if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *SessionIterator) bufLen() int { return len(it.items) } func (it *SessionIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/spanner/apiv1/spanner_client_example_test.go000066400000000000000000000144061356504100700253700ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package spanner_test import ( "context" "io" spanner "cloud.google.com/go/spanner/apiv1" "google.golang.org/api/iterator" spannerpb "google.golang.org/genproto/googleapis/spanner/v1" ) func ExampleNewClient() { ctx := context.Background() c, err := spanner.NewClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleClient_CreateSession() { ctx := context.Background() c, err := spanner.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &spannerpb.CreateSessionRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateSession(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_BatchCreateSessions() { ctx := context.Background() c, err := spanner.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &spannerpb.BatchCreateSessionsRequest{ // TODO: Fill request struct fields. } resp, err := c.BatchCreateSessions(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_GetSession() { ctx := context.Background() c, err := spanner.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &spannerpb.GetSessionRequest{ // TODO: Fill request struct fields. } resp, err := c.GetSession(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ListSessions() { ctx := context.Background() c, err := spanner.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &spannerpb.ListSessionsRequest{ // TODO: Fill request struct fields. } it := c.ListSessions(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_DeleteSession() { ctx := context.Background() c, err := spanner.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &spannerpb.DeleteSessionRequest{ // TODO: Fill request struct fields. } err = c.DeleteSession(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleClient_ExecuteSql() { ctx := context.Background() c, err := spanner.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &spannerpb.ExecuteSqlRequest{ // TODO: Fill request struct fields. } resp, err := c.ExecuteSql(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ExecuteStreamingSql() { ctx := context.Background() c, err := spanner.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &spannerpb.ExecuteSqlRequest{ // TODO: Fill request struct fields. } stream, err := c.ExecuteStreamingSql(ctx, req) if err != nil { // TODO: Handle error. } for { resp, err := stream.Recv() if err == io.EOF { break } if err != nil { // TODO: handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_ExecuteBatchDml() { ctx := context.Background() c, err := spanner.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &spannerpb.ExecuteBatchDmlRequest{ // TODO: Fill request struct fields. } resp, err := c.ExecuteBatchDml(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_Read() { ctx := context.Background() c, err := spanner.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &spannerpb.ReadRequest{ // TODO: Fill request struct fields. } resp, err := c.Read(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_StreamingRead() { ctx := context.Background() c, err := spanner.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &spannerpb.ReadRequest{ // TODO: Fill request struct fields. } stream, err := c.StreamingRead(ctx, req) if err != nil { // TODO: Handle error. } for { resp, err := stream.Recv() if err == io.EOF { break } if err != nil { // TODO: handle error. } // TODO: Use resp. _ = resp } } func ExampleClient_BeginTransaction() { ctx := context.Background() c, err := spanner.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &spannerpb.BeginTransactionRequest{ // TODO: Fill request struct fields. } resp, err := c.BeginTransaction(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_Commit() { ctx := context.Background() c, err := spanner.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &spannerpb.CommitRequest{ // TODO: Fill request struct fields. } resp, err := c.Commit(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_Rollback() { ctx := context.Background() c, err := spanner.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &spannerpb.RollbackRequest{ // TODO: Fill request struct fields. } err = c.Rollback(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleClient_PartitionQuery() { ctx := context.Background() c, err := spanner.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &spannerpb.PartitionQueryRequest{ // TODO: Fill request struct fields. } resp, err := c.PartitionQuery(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_PartitionRead() { ctx := context.Background() c, err := spanner.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &spannerpb.PartitionReadRequest{ // TODO: Fill request struct fields. } resp, err := c.PartitionRead(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/spanner/appengine.go000066400000000000000000000013071356504100700205340ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // +build appengine package spanner // numChannels is the default value for NumChannels of client const numChannels = 1 google-cloud-go-0.49.0/spanner/batch.go000066400000000000000000000243411356504100700176520ustar00rootroot00000000000000/* Copyright 2018 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spanner import ( "bytes" "context" "encoding/gob" "log" "time" "github.com/golang/protobuf/proto" sppb "google.golang.org/genproto/googleapis/spanner/v1" ) // BatchReadOnlyTransaction is a ReadOnlyTransaction that allows for exporting // arbitrarily large amounts of data from Cloud Spanner databases. // BatchReadOnlyTransaction partitions a read/query request. Read/query request // can then be executed independently over each partition while observing the // same snapshot of the database. BatchReadOnlyTransaction can also be shared // across multiple clients by passing around the BatchReadOnlyTransactionID and // then recreating the transaction using Client.BatchReadOnlyTransactionFromID. // // Note: if a client is used only to run partitions, you can // create it using a ClientConfig with both MinOpened and MaxIdle set to // zero to avoid creating unnecessary sessions. You can also avoid excess // gRPC channels by setting ClientConfig.NumChannels to the number of // concurrently active BatchReadOnlyTransactions you expect to have. type BatchReadOnlyTransaction struct { ReadOnlyTransaction ID BatchReadOnlyTransactionID } // BatchReadOnlyTransactionID is a unique identifier for a // BatchReadOnlyTransaction. It can be used to re-create a // BatchReadOnlyTransaction on a different machine or process by calling // Client.BatchReadOnlyTransactionFromID. type BatchReadOnlyTransactionID struct { // unique ID for the transaction. tid transactionID // sid is the id of the Cloud Spanner session used for this transaction. sid string // rts is the read timestamp of this transaction. rts time.Time } // Partition defines a segment of data to be read in a batch read or query. A // partition can be serialized and processed across several different machines // or processes. type Partition struct { pt []byte qreq *sppb.ExecuteSqlRequest rreq *sppb.ReadRequest } // PartitionOptions specifies options for a PartitionQueryRequest and // PartitionReadRequest. See // https://godoc.org/google.golang.org/genproto/googleapis/spanner/v1#PartitionOptions // for more details. type PartitionOptions struct { // The desired data size for each partition generated. PartitionBytes int64 // The desired maximum number of partitions to return. MaxPartitions int64 } // toProto converts a spanner.PartitionOptions into a sppb.PartitionOptions func (opt PartitionOptions) toProto() *sppb.PartitionOptions { return &sppb.PartitionOptions{ PartitionSizeBytes: opt.PartitionBytes, MaxPartitions: opt.MaxPartitions, } } // PartitionRead returns a list of Partitions that can be used to read rows from // the database. These partitions can be executed across multiple processes, // even across different machines. The partition size and count hints can be // configured using PartitionOptions. func (t *BatchReadOnlyTransaction) PartitionRead(ctx context.Context, table string, keys KeySet, columns []string, opt PartitionOptions) ([]*Partition, error) { return t.PartitionReadUsingIndex(ctx, table, "", keys, columns, opt) } // PartitionReadUsingIndex returns a list of Partitions that can be used to read // rows from the database using an index. func (t *BatchReadOnlyTransaction) PartitionReadUsingIndex(ctx context.Context, table, index string, keys KeySet, columns []string, opt PartitionOptions) ([]*Partition, error) { sh, ts, err := t.acquire(ctx) if err != nil { return nil, err } sid, client := sh.getID(), sh.getClient() var ( kset *sppb.KeySet resp *sppb.PartitionResponse partitions []*Partition ) kset, err = keys.keySetProto() // Request partitions. if err != nil { return nil, err } resp, err = client.PartitionRead(ctx, &sppb.PartitionReadRequest{ Session: sid, Transaction: ts, Table: table, Index: index, Columns: columns, KeySet: kset, PartitionOptions: opt.toProto(), }) // Prepare ReadRequest. req := &sppb.ReadRequest{ Session: sid, Transaction: ts, Table: table, Index: index, Columns: columns, KeySet: kset, } // Generate partitions. for _, p := range resp.GetPartitions() { partitions = append(partitions, &Partition{ pt: p.PartitionToken, rreq: req, }) } return partitions, err } // PartitionQuery returns a list of Partitions that can be used to execute a // query against the database. func (t *BatchReadOnlyTransaction) PartitionQuery(ctx context.Context, statement Statement, opt PartitionOptions) ([]*Partition, error) { sh, ts, err := t.acquire(ctx) if err != nil { return nil, err } sid, client := sh.getID(), sh.getClient() params, paramTypes, err := statement.convertParams() if err != nil { return nil, err } // request Partitions req := &sppb.PartitionQueryRequest{ Session: sid, Transaction: ts, Sql: statement.SQL, PartitionOptions: opt.toProto(), Params: params, ParamTypes: paramTypes, } resp, err := client.PartitionQuery(ctx, req) // prepare ExecuteSqlRequest r := &sppb.ExecuteSqlRequest{ Session: sid, Transaction: ts, Sql: statement.SQL, Params: params, ParamTypes: paramTypes, } // generate Partitions var partitions []*Partition for _, p := range resp.GetPartitions() { partitions = append(partitions, &Partition{ pt: p.PartitionToken, qreq: r, }) } return partitions, err } // release implements txReadEnv.release, noop. func (t *BatchReadOnlyTransaction) release(err error) { } // setTimestamp implements txReadEnv.setTimestamp, noop. // // read timestamp is ready on txn initialization, avoid contending writing to it // with future partitions. func (t *BatchReadOnlyTransaction) setTimestamp(ts time.Time) { } // Close marks the txn as closed. func (t *BatchReadOnlyTransaction) Close() { t.mu.Lock() defer t.mu.Unlock() t.state = txClosed } // Cleanup cleans up all the resources used by this transaction and makes // it unusable. Once this method is invoked, the transaction is no longer // usable anywhere, including other clients/processes with which this // transaction was shared. // // Calling Cleanup is optional, but recommended. If Cleanup is not called, the // transaction's resources will be freed when the session expires on the backend // and is deleted. For more information about recycled sessions, see // https://cloud.google.com/spanner/docs/sessions. func (t *BatchReadOnlyTransaction) Cleanup(ctx context.Context) { t.Close() t.mu.Lock() defer t.mu.Unlock() sh := t.sh if sh == nil { return } t.sh = nil sid, client := sh.getID(), sh.getClient() err := client.DeleteSession(ctx, &sppb.DeleteSessionRequest{Name: sid}) if err != nil { log.Printf("Failed to delete session %v. Error: %v", sid, err) } } // Execute runs a single Partition obtained from PartitionRead or // PartitionQuery. func (t *BatchReadOnlyTransaction) Execute(ctx context.Context, p *Partition) *RowIterator { var ( sh *sessionHandle err error rpc func(ct context.Context, resumeToken []byte) (streamingReceiver, error) ) if sh, _, err = t.acquire(ctx); err != nil { return &RowIterator{err: err} } client := sh.getClient() if client == nil { // Might happen if transaction is closed in the middle of a API call. return &RowIterator{err: errSessionClosed(sh)} } // Read or query partition. if p.rreq != nil { p.rreq.PartitionToken = p.pt rpc = func(ctx context.Context, resumeToken []byte) (streamingReceiver, error) { p.rreq.ResumeToken = resumeToken return client.StreamingRead(ctx, p.rreq) } } else { p.qreq.PartitionToken = p.pt rpc = func(ctx context.Context, resumeToken []byte) (streamingReceiver, error) { p.qreq.ResumeToken = resumeToken return client.ExecuteStreamingSql(ctx, p.qreq) } } return stream( contextWithOutgoingMetadata(ctx, sh.getMetadata()), rpc, t.setTimestamp, t.release) } // MarshalBinary implements BinaryMarshaler. func (tid BatchReadOnlyTransactionID) MarshalBinary() (data []byte, err error) { var buf bytes.Buffer enc := gob.NewEncoder(&buf) if err := enc.Encode(tid.tid); err != nil { return nil, err } if err := enc.Encode(tid.sid); err != nil { return nil, err } if err := enc.Encode(tid.rts); err != nil { return nil, err } return buf.Bytes(), nil } // UnmarshalBinary implements BinaryUnmarshaler. func (tid *BatchReadOnlyTransactionID) UnmarshalBinary(data []byte) error { dec := gob.NewDecoder(bytes.NewReader(data)) if err := dec.Decode(&tid.tid); err != nil { return err } if err := dec.Decode(&tid.sid); err != nil { return err } return dec.Decode(&tid.rts) } // MarshalBinary implements BinaryMarshaler. func (p Partition) MarshalBinary() (data []byte, err error) { var buf bytes.Buffer enc := gob.NewEncoder(&buf) if err := enc.Encode(p.pt); err != nil { return nil, err } var isReadPartition bool var req proto.Message if p.rreq != nil { isReadPartition = true req = p.rreq } else { isReadPartition = false req = p.qreq } if err := enc.Encode(isReadPartition); err != nil { return nil, err } if data, err = proto.Marshal(req); err != nil { return nil, err } if err := enc.Encode(data); err != nil { return nil, err } return buf.Bytes(), nil } // UnmarshalBinary implements BinaryUnmarshaler. func (p *Partition) UnmarshalBinary(data []byte) error { var ( isReadPartition bool d []byte err error ) dec := gob.NewDecoder(bytes.NewReader(data)) if err := dec.Decode(&p.pt); err != nil { return err } if err := dec.Decode(&isReadPartition); err != nil { return err } if err := dec.Decode(&d); err != nil { return err } if isReadPartition { p.rreq = &sppb.ReadRequest{} err = proto.Unmarshal(d, p.rreq) } else { p.qreq = &sppb.ExecuteSqlRequest{} err = proto.Unmarshal(d, p.qreq) } return err } google-cloud-go-0.49.0/spanner/batch_test.go000066400000000000000000000033701356504100700207100ustar00rootroot00000000000000/* Copyright 2018 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spanner import ( "testing" "time" sppb "google.golang.org/genproto/googleapis/spanner/v1" ) func TestPartitionRoundTrip(t *testing.T) { t.Parallel() for i, want := range []Partition{ {rreq: &sppb.ReadRequest{Table: "t"}}, {qreq: &sppb.ExecuteSqlRequest{Sql: "sql"}}, } { got := serdesPartition(t, i, &want) if !testEqual(got, want) { t.Errorf("got: %#v\nwant:%#v", got, want) } } } func TestBROTIDRoundTrip(t *testing.T) { t.Parallel() tm := time.Now() want := BatchReadOnlyTransactionID{ tid: []byte("tid"), sid: "sid", rts: tm, } data, err := want.MarshalBinary() if err != nil { t.Fatal(err) } var got BatchReadOnlyTransactionID if err := got.UnmarshalBinary(data); err != nil { t.Fatal(err) } if !testEqual(got, want) { t.Errorf("got: %#v\nwant:%#v", got, want) } } // serdesPartition is a helper that serialize a Partition then deserialize it. func serdesPartition(t *testing.T, i int, p1 *Partition) (p2 Partition) { var ( data []byte err error ) if data, err = p1.MarshalBinary(); err != nil { t.Fatalf("#%d: encoding failed %v", i, err) } if err = p2.UnmarshalBinary(data); err != nil { t.Fatalf("#%d: decoding failed %v", i, err) } return p2 } google-cloud-go-0.49.0/spanner/big_pdml_test.go000066400000000000000000000032511356504100700214020ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // +build bigtest // An integration test for PDML using a relatively large database. package spanner import ( "context" "fmt" "testing" ) func TestIntegration_BigPDML(t *testing.T) { const nRows int = 1e4 ctx := context.Background() client, _, cleanup := prepareIntegrationTest(ctx, t, singerDBStatements) defer cleanup() columns := []string{"SingerId", "FirstName", "LastName"} // Populate the Singers table with random data. const rowsPerApply = 1000 for i := 0; i < nRows; i += rowsPerApply { var muts []*Mutation for j := 0; j < rowsPerApply; j++ { id := i + j row := []interface{}{id, fmt.Sprintf("FirstName%d", id), fmt.Sprintf("LastName%d", id)} muts = append(muts, Insert("Singers", columns, row)) } if _, err := client.Apply(ctx, muts); err != nil { t.Fatal(err) } } // Run a PDML statement. count, err := client.PartitionedUpdate(ctx, Statement{ SQL: `UPDATE Singers SET Singers.FirstName = "changed" WHERE Singers.SingerId != -1`, }) if err != nil { t.Fatal(err) } if want := int64(nRows); count != want { t.Errorf("got %d, want %d", count, want) } } google-cloud-go-0.49.0/spanner/client.go000066400000000000000000000330521356504100700200460ustar00rootroot00000000000000/* Copyright 2017 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spanner import ( "context" "fmt" "os" "regexp" "time" "cloud.google.com/go/internal/trace" vkit "cloud.google.com/go/spanner/apiv1" "google.golang.org/api/option" sppb "google.golang.org/genproto/googleapis/spanner/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) const ( endpoint = "spanner.googleapis.com:443" // resourcePrefixHeader is the name of the metadata header used to indicate // the resource being operated on. resourcePrefixHeader = "google-cloud-resource-prefix" ) const ( // Scope is the scope for Cloud Spanner Data API. Scope = "https://www.googleapis.com/auth/spanner.data" // AdminScope is the scope for Cloud Spanner Admin APIs. AdminScope = "https://www.googleapis.com/auth/spanner.admin" ) var ( validDBPattern = regexp.MustCompile("^projects/[^/]+/instances/[^/]+/databases/[^/]+$") ) func validDatabaseName(db string) error { if matched := validDBPattern.MatchString(db); !matched { return fmt.Errorf("database name %q should conform to pattern %q", db, validDBPattern.String()) } return nil } // Client is a client for reading and writing data to a Cloud Spanner database. // A client is safe to use concurrently, except for its Close method. type Client struct { sc *sessionClient idleSessions *sessionPool } // ClientConfig has configurations for the client. type ClientConfig struct { // NumChannels is the number of gRPC channels. // If zero, a reasonable default is used based on the execution environment. NumChannels int // SessionPoolConfig is the configuration for session pool. SessionPoolConfig // SessionLabels for the sessions created by this client. // See https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.v1#session // for more info. SessionLabels map[string]string } // errDial returns error for dialing to Cloud Spanner. func errDial(ci int, err error) error { e := toSpannerError(err).(*Error) e.decorate(fmt.Sprintf("dialing fails for channel[%v]", ci)) return e } func contextWithOutgoingMetadata(ctx context.Context, md metadata.MD) context.Context { existing, ok := metadata.FromOutgoingContext(ctx) if ok { md = metadata.Join(existing, md) } return metadata.NewOutgoingContext(ctx, md) } // NewClient creates a client to a database. A valid database name has the // form projects/PROJECT_ID/instances/INSTANCE_ID/databases/DATABASE_ID. It uses // a default configuration. func NewClient(ctx context.Context, database string, opts ...option.ClientOption) (*Client, error) { return NewClientWithConfig(ctx, database, ClientConfig{SessionPoolConfig: DefaultSessionPoolConfig}, opts...) } // NewClientWithConfig creates a client to a database. A valid database name has // the form projects/PROJECT_ID/instances/INSTANCE_ID/databases/DATABASE_ID. func NewClientWithConfig(ctx context.Context, database string, config ClientConfig, opts ...option.ClientOption) (c *Client, err error) { // Prepare gRPC channels. if config.NumChannels == 0 { config.NumChannels = numChannels } // Default configs for session pool. if config.MaxOpened == 0 { config.MaxOpened = uint64(config.NumChannels * 100) } if config.MaxBurst == 0 { config.MaxBurst = DefaultSessionPoolConfig.MaxBurst } // Validate database path. if err := validDatabaseName(database); err != nil { return nil, err } ctx = trace.StartSpan(ctx, "cloud.google.com/go/spanner.NewClient") defer func() { trace.EndSpan(ctx, err) }() // Append emulator options if SPANNER_EMULATOR_HOST has been set. if emulatorAddr := os.Getenv("SPANNER_EMULATOR_HOST"); emulatorAddr != "" { emulatorOpts := []option.ClientOption{ option.WithEndpoint(emulatorAddr), option.WithGRPCDialOption(grpc.WithInsecure()), option.WithoutAuthentication(), } opts = append(opts, emulatorOpts...) } // gRPC options. allOpts := []option.ClientOption{ option.WithEndpoint(endpoint), option.WithScopes(Scope), option.WithGRPCDialOption( grpc.WithDefaultCallOptions( grpc.MaxCallSendMsgSize(100<<20), grpc.MaxCallRecvMsgSize(100<<20), ), ), } allOpts = append(allOpts, opts...) // TODO(deklerk): This should be replaced with a balancer with // config.NumChannels connections, instead of config.NumChannels // clients. var clients []*vkit.Client for i := 0; i < config.NumChannels; i++ { client, err := vkit.NewClient(ctx, allOpts...) if err != nil { return nil, errDial(i, err) } clients = append(clients, client) } // TODO(loite): Remove as the original map cannot be changed by the user // anyways, and the client library is also not changing it. // Make a copy of labels. sessionLabels := make(map[string]string) for k, v := range config.SessionLabels { sessionLabels[k] = v } // Create a session client. sc := newSessionClient(clients, database, sessionLabels, metadata.Pairs(resourcePrefixHeader, database)) // Create a session pool. config.SessionPoolConfig.sessionLabels = sessionLabels sp, err := newSessionPool(sc, config.SessionPoolConfig) if err != nil { sc.close() return nil, err } c = &Client{ sc: sc, idleSessions: sp, } return c, nil } // Close closes the client. func (c *Client) Close() { if c.idleSessions != nil { c.idleSessions.close() } c.sc.close() } // Single provides a read-only snapshot transaction optimized for the case // where only a single read or query is needed. This is more efficient than // using ReadOnlyTransaction() for a single read or query. // // Single will use a strong TimestampBound by default. Use // ReadOnlyTransaction.WithTimestampBound to specify a different // TimestampBound. A non-strong bound can be used to reduce latency, or // "time-travel" to prior versions of the database, see the documentation of // TimestampBound for details. func (c *Client) Single() *ReadOnlyTransaction { t := &ReadOnlyTransaction{singleUse: true, sp: c.idleSessions} t.txReadOnly.txReadEnv = t return t } // ReadOnlyTransaction returns a ReadOnlyTransaction that can be used for // multiple reads from the database. You must call Close() when the // ReadOnlyTransaction is no longer needed to release resources on the server. // // ReadOnlyTransaction will use a strong TimestampBound by default. Use // ReadOnlyTransaction.WithTimestampBound to specify a different // TimestampBound. A non-strong bound can be used to reduce latency, or // "time-travel" to prior versions of the database, see the documentation of // TimestampBound for details. func (c *Client) ReadOnlyTransaction() *ReadOnlyTransaction { t := &ReadOnlyTransaction{ singleUse: false, sp: c.idleSessions, txReadyOrClosed: make(chan struct{}), } t.txReadOnly.txReadEnv = t return t } // BatchReadOnlyTransaction returns a BatchReadOnlyTransaction that can be used // for partitioned reads or queries from a snapshot of the database. This is // useful in batch processing pipelines where one wants to divide the work of // reading from the database across multiple machines. // // Note: This transaction does not use the underlying session pool but creates a // new session each time, and the session is reused across clients. // // You should call Close() after the txn is no longer needed on local // client, and call Cleanup() when the txn is finished for all clients, to free // the session. func (c *Client) BatchReadOnlyTransaction(ctx context.Context, tb TimestampBound) (*BatchReadOnlyTransaction, error) { var ( tx transactionID rts time.Time s *session sh *sessionHandle err error ) defer func() { if err != nil && sh != nil { s.delete(ctx) } }() // Create session. s, err = c.sc.createSession(ctx) if err != nil { return nil, err } sh = &sessionHandle{session: s} // Begin transaction. res, err := sh.getClient().BeginTransaction(contextWithOutgoingMetadata(ctx, sh.getMetadata()), &sppb.BeginTransactionRequest{ Session: sh.getID(), Options: &sppb.TransactionOptions{ Mode: &sppb.TransactionOptions_ReadOnly_{ ReadOnly: buildTransactionOptionsReadOnly(tb, true), }, }, }) if err != nil { return nil, toSpannerError(err) } tx = res.Id if res.ReadTimestamp != nil { rts = time.Unix(res.ReadTimestamp.Seconds, int64(res.ReadTimestamp.Nanos)) } t := &BatchReadOnlyTransaction{ ReadOnlyTransaction: ReadOnlyTransaction{ tx: tx, txReadyOrClosed: make(chan struct{}), state: txActive, sh: sh, rts: rts, }, ID: BatchReadOnlyTransactionID{ tid: tx, sid: sh.getID(), rts: rts, }, } t.txReadOnly.txReadEnv = t return t, nil } // BatchReadOnlyTransactionFromID reconstruct a BatchReadOnlyTransaction from // BatchReadOnlyTransactionID func (c *Client) BatchReadOnlyTransactionFromID(tid BatchReadOnlyTransactionID) *BatchReadOnlyTransaction { s := c.sc.sessionWithID(tid.sid) sh := &sessionHandle{session: s} t := &BatchReadOnlyTransaction{ ReadOnlyTransaction: ReadOnlyTransaction{ tx: tid.tid, txReadyOrClosed: make(chan struct{}), state: txActive, sh: sh, rts: tid.rts, }, ID: tid, } t.txReadOnly.txReadEnv = t return t } type transactionInProgressKey struct{} func checkNestedTxn(ctx context.Context) error { if ctx.Value(transactionInProgressKey{}) != nil { return spannerErrorf(codes.FailedPrecondition, "Cloud Spanner does not support nested transactions") } return nil } // ReadWriteTransaction executes a read-write transaction, with retries as // necessary. // // The function f will be called one or more times. It must not maintain // any state between calls. // // If the transaction cannot be committed or if f returns an ABORTED error, // ReadWriteTransaction will call f again. It will continue to call f until the // transaction can be committed or the Context times out or is cancelled. If f // returns an error other than ABORTED, ReadWriteTransaction will abort the // transaction and return the error. // // To limit the number of retries, set a deadline on the Context rather than // using a fixed limit on the number of attempts. ReadWriteTransaction will // retry as needed until that deadline is met. // // See https://godoc.org/cloud.google.com/go/spanner#ReadWriteTransaction for // more details. func (c *Client) ReadWriteTransaction(ctx context.Context, f func(context.Context, *ReadWriteTransaction) error) (commitTimestamp time.Time, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/spanner.ReadWriteTransaction") defer func() { trace.EndSpan(ctx, err) }() if err := checkNestedTxn(ctx); err != nil { return time.Time{}, err } var ( ts time.Time sh *sessionHandle ) err = runWithRetryOnAborted(ctx, func(ctx context.Context) error { var ( err error t *ReadWriteTransaction ) if sh == nil || sh.getID() == "" || sh.getClient() == nil { // Session handle hasn't been allocated or has been destroyed. sh, err = c.idleSessions.takeWriteSession(ctx) if err != nil { // If session retrieval fails, just fail the transaction. return err } t = &ReadWriteTransaction{ sh: sh, tx: sh.getTransactionID(), } } else { t = &ReadWriteTransaction{ sh: sh, } } t.txReadOnly.txReadEnv = t trace.TracePrintf(ctx, map[string]interface{}{"transactionID": string(sh.getTransactionID())}, "Starting transaction attempt") if err = t.begin(ctx); err != nil { return err } ts, err = t.runInTransaction(ctx, f) return err }) if sh != nil { sh.recycle() } return ts, err } // applyOption controls the behavior of Client.Apply. type applyOption struct { // If atLeastOnce == true, Client.Apply will execute the mutations on Cloud // Spanner at least once. atLeastOnce bool } // An ApplyOption is an optional argument to Apply. type ApplyOption func(*applyOption) // ApplyAtLeastOnce returns an ApplyOption that removes replay protection. // // With this option, Apply may attempt to apply mutations more than once; if // the mutations are not idempotent, this may lead to a failure being reported // when the mutation was applied more than once. For example, an insert may // fail with ALREADY_EXISTS even though the row did not exist before Apply was // called. For this reason, most users of the library will prefer not to use // this option. However, ApplyAtLeastOnce requires only a single RPC, whereas // Apply's default replay protection may require an additional RPC. So this // option may be appropriate for latency sensitive and/or high throughput blind // writing. func ApplyAtLeastOnce() ApplyOption { return func(ao *applyOption) { ao.atLeastOnce = true } } // Apply applies a list of mutations atomically to the database. func (c *Client) Apply(ctx context.Context, ms []*Mutation, opts ...ApplyOption) (commitTimestamp time.Time, err error) { ao := &applyOption{} for _, opt := range opts { opt(ao) } if !ao.atLeastOnce { return c.ReadWriteTransaction(ctx, func(ctx context.Context, t *ReadWriteTransaction) error { return t.BufferWrite(ms) }) } ctx = trace.StartSpan(ctx, "cloud.google.com/go/spanner.Apply") defer func() { trace.EndSpan(ctx, err) }() t := &writeOnlyTransaction{c.idleSessions} return t.applyAtLeastOnce(ctx, ms...) } google-cloud-go-0.49.0/spanner/client_test.go000066400000000000000000000476511356504100700211170ustar00rootroot00000000000000/* Copyright 2017 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spanner import ( "context" "fmt" "io" "strings" "testing" "time" itestutil "cloud.google.com/go/internal/testutil" . "cloud.google.com/go/spanner/internal/testutil" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) func setupMockedTestServer(t *testing.T) (server *MockedSpannerInMemTestServer, client *Client, teardown func()) { return setupMockedTestServerWithConfig(t, ClientConfig{}) } func setupMockedTestServerWithConfig(t *testing.T, config ClientConfig) (server *MockedSpannerInMemTestServer, client *Client, teardown func()) { return setupMockedTestServerWithConfigAndClientOptions(t, config, []option.ClientOption{}) } func setupMockedTestServerWithConfigAndClientOptions(t *testing.T, config ClientConfig, clientOptions []option.ClientOption) (server *MockedSpannerInMemTestServer, client *Client, teardown func()) { grpcHeaderChecker := &itestutil.HeadersEnforcer{ OnFailure: t.Fatalf, Checkers: []*itestutil.HeaderChecker{ { Key: "x-goog-api-client", ValuesValidator: func(token ...string) error { if len(token) != 1 { return spannerErrorf(codes.Internal, "unexpected number of api client token headers: %v", len(token)) } if !strings.HasPrefix(token[0], "gl-go/") { return spannerErrorf(codes.Internal, "unexpected api client token: %v", token[0]) } return nil }, }, }, } clientOptions = append(clientOptions, grpcHeaderChecker.CallOptions()...) server, opts, serverTeardown := NewMockedSpannerInMemTestServer(t) opts = append(opts, clientOptions...) ctx := context.Background() var formattedDatabase = fmt.Sprintf("projects/%s/instances/%s/databases/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]") client, err := NewClientWithConfig(ctx, formattedDatabase, config, opts...) if err != nil { t.Fatal(err) } return server, client, func() { client.Close() serverTeardown() } } // Test validDatabaseName() func TestValidDatabaseName(t *testing.T) { validDbURI := "projects/spanner-cloud-test/instances/foo/databases/foodb" invalidDbUris := []string{ // Completely wrong DB URI. "foobarDB", // Project ID contains "/". "projects/spanner-cloud/test/instances/foo/databases/foodb", // No instance ID. "projects/spanner-cloud-test/instances//databases/foodb", } if err := validDatabaseName(validDbURI); err != nil { t.Errorf("validateDatabaseName(%q) = %v, want nil", validDbURI, err) } for _, d := range invalidDbUris { if err, wantErr := validDatabaseName(d), "should conform to pattern"; !strings.Contains(err.Error(), wantErr) { t.Errorf("validateDatabaseName(%q) = %q, want error pattern %q", validDbURI, err, wantErr) } } } func TestReadOnlyTransactionClose(t *testing.T) { // Closing a ReadOnlyTransaction shouldn't panic. c := &Client{} tx := c.ReadOnlyTransaction() tx.Close() } func TestClient_Single(t *testing.T) { t.Parallel() err := testSingleQuery(t, nil) if err != nil { t.Fatal(err) } } func TestClient_Single_Unavailable(t *testing.T) { t.Parallel() err := testSingleQuery(t, status.Error(codes.Unavailable, "Temporary unavailable")) if err != nil { t.Fatal(err) } } func TestClient_Single_InvalidArgument(t *testing.T) { t.Parallel() err := testSingleQuery(t, status.Error(codes.InvalidArgument, "Invalid argument")) if status.Code(err) != codes.InvalidArgument { t.Fatalf("got unexpected exception %v, expected InvalidArgument", err) } } func TestClient_Single_RetryableErrorOnPartialResultSet(t *testing.T) { t.Parallel() server, client, teardown := setupMockedTestServer(t) defer teardown() // Add two errors that will be returned by the mock server when the client // is trying to fetch a partial result set. Both errors are retryable. // The errors are not 'sticky' on the mocked server, i.e. once the error // has been returned once, the next call for the same partial result set // will succeed. // When the client is fetching the partial result set with resume token 2, // the mock server will respond with an internal error with the message // 'stream terminated by RST_STREAM'. The client will retry the call to get // this partial result set. server.TestSpanner.AddPartialResultSetError( SelectSingerIDAlbumIDAlbumTitleFromAlbums, PartialResultSetExecutionTime{ ResumeToken: EncodeResumeToken(2), Err: spannerErrorf(codes.Internal, "stream terminated by RST_STREAM"), }, ) // When the client is fetching the partial result set with resume token 3, // the mock server will respond with a 'Unavailable' error. The client will // retry the call to get this partial result set. server.TestSpanner.AddPartialResultSetError( SelectSingerIDAlbumIDAlbumTitleFromAlbums, PartialResultSetExecutionTime{ ResumeToken: EncodeResumeToken(3), Err: spannerErrorf(codes.Unavailable, "server is unavailable"), }, ) ctx := context.Background() if err := executeSingerQuery(ctx, client.Single()); err != nil { t.Fatal(err) } } func TestClient_Single_NonRetryableErrorOnPartialResultSet(t *testing.T) { t.Parallel() server, client, teardown := setupMockedTestServer(t) defer teardown() // Add two errors that will be returned by the mock server when the client // is trying to fetch a partial result set. The first error is retryable, // the second is not. // This error will automatically be retried. server.TestSpanner.AddPartialResultSetError( SelectSingerIDAlbumIDAlbumTitleFromAlbums, PartialResultSetExecutionTime{ ResumeToken: EncodeResumeToken(2), Err: spannerErrorf(codes.Internal, "stream terminated by RST_STREAM"), }, ) // 'Session not found' is not retryable and the error will be returned to // the user. server.TestSpanner.AddPartialResultSetError( SelectSingerIDAlbumIDAlbumTitleFromAlbums, PartialResultSetExecutionTime{ ResumeToken: EncodeResumeToken(3), Err: spannerErrorf(codes.NotFound, "Session not found"), }, ) ctx := context.Background() err := executeSingerQuery(ctx, client.Single()) if status.Code(err) != codes.NotFound { t.Fatalf("Error mismatch:\ngot: %v\nwant: %v", err, codes.NotFound) } } func TestClient_Single_DeadlineExceeded_NoErrors(t *testing.T) { t.Parallel() server, client, teardown := setupMockedTestServer(t) defer teardown() server.TestSpanner.PutExecutionTime(MethodExecuteStreamingSql, SimulatedExecutionTime{ MinimumExecutionTime: 50 * time.Millisecond, }) ctx := context.Background() ctx, cancel := context.WithDeadline(ctx, time.Now().Add(5*time.Millisecond)) defer cancel() err := executeSingerQuery(ctx, client.Single()) if status.Code(err) != codes.DeadlineExceeded { t.Fatalf("Error mismatch:\ngot: %v\nwant: %v", err, codes.DeadlineExceeded) } } func TestClient_Single_DeadlineExceeded_WithErrors(t *testing.T) { t.Parallel() server, client, teardown := setupMockedTestServer(t) defer teardown() server.TestSpanner.AddPartialResultSetError( SelectSingerIDAlbumIDAlbumTitleFromAlbums, PartialResultSetExecutionTime{ ResumeToken: EncodeResumeToken(2), Err: spannerErrorf(codes.Internal, "stream terminated by RST_STREAM"), }, ) server.TestSpanner.AddPartialResultSetError( SelectSingerIDAlbumIDAlbumTitleFromAlbums, PartialResultSetExecutionTime{ ResumeToken: EncodeResumeToken(3), Err: spannerErrorf(codes.Unavailable, "server is unavailable"), ExecutionTime: 50 * time.Millisecond, }, ) ctx := context.Background() ctx, cancel := context.WithDeadline(ctx, time.Now().Add(25*time.Millisecond)) defer cancel() err := executeSingerQuery(ctx, client.Single()) if status.Code(err) != codes.DeadlineExceeded { t.Fatalf("got unexpected error %v, expected DeadlineExceeded", err) } } func TestClient_Single_ContextCanceled_noDeclaredServerErrors(t *testing.T) { t.Parallel() _, client, teardown := setupMockedTestServer(t) defer teardown() ctx := context.Background() ctx, cancel := context.WithCancel(ctx) cancel() err := executeSingerQuery(ctx, client.Single()) if status.Code(err) != codes.Canceled { t.Fatalf("got unexpected error %v, expected Canceled", err) } } func TestClient_Single_ContextCanceled_withDeclaredServerErrors(t *testing.T) { t.Parallel() server, client, teardown := setupMockedTestServer(t) defer teardown() server.TestSpanner.AddPartialResultSetError( SelectSingerIDAlbumIDAlbumTitleFromAlbums, PartialResultSetExecutionTime{ ResumeToken: EncodeResumeToken(2), Err: spannerErrorf(codes.Internal, "stream terminated by RST_STREAM"), }, ) server.TestSpanner.AddPartialResultSetError( SelectSingerIDAlbumIDAlbumTitleFromAlbums, PartialResultSetExecutionTime{ ResumeToken: EncodeResumeToken(3), Err: spannerErrorf(codes.Unavailable, "server is unavailable"), }, ) ctx := context.Background() ctx, cancel := context.WithCancel(ctx) defer cancel() f := func(rowCount int64) error { if rowCount == 2 { cancel() } return nil } iter := client.Single().Query(ctx, NewStatement(SelectSingerIDAlbumIDAlbumTitleFromAlbums)) defer iter.Stop() err := executeSingerQueryWithRowFunc(ctx, client.Single(), f) if status.Code(err) != codes.Canceled { t.Fatalf("got unexpected error %v, expected Canceled", err) } } func testSingleQuery(t *testing.T, serverError error) error { ctx := context.Background() server, client, teardown := setupMockedTestServer(t) defer teardown() if serverError != nil { server.TestSpanner.SetError(serverError) } return executeSingerQuery(ctx, client.Single()) } func executeSingerQuery(ctx context.Context, tx *ReadOnlyTransaction) error { return executeSingerQueryWithRowFunc(ctx, tx, nil) } func executeSingerQueryWithRowFunc(ctx context.Context, tx *ReadOnlyTransaction, f func(rowCount int64) error) error { iter := tx.Query(ctx, NewStatement(SelectSingerIDAlbumIDAlbumTitleFromAlbums)) defer iter.Stop() rowCount := int64(0) for { row, err := iter.Next() if err == iterator.Done { break } if err != nil { return err } var singerID, albumID int64 var albumTitle string if err := row.Columns(&singerID, &albumID, &albumTitle); err != nil { return err } rowCount++ if f != nil { if err := f(rowCount); err != nil { return err } } } if rowCount != SelectSingerIDAlbumIDAlbumTitleFromAlbumsRowCount { return spannerErrorf(codes.Internal, "Row count mismatch, got %v, expected %v", rowCount, SelectSingerIDAlbumIDAlbumTitleFromAlbumsRowCount) } return nil } func createSimulatedExecutionTimeWithTwoUnavailableErrors(method string) map[string]SimulatedExecutionTime { errors := make([]error, 2) errors[0] = status.Error(codes.Unavailable, "Temporary unavailable") errors[1] = status.Error(codes.Unavailable, "Temporary unavailable") executionTimes := make(map[string]SimulatedExecutionTime) executionTimes[method] = SimulatedExecutionTime{ Errors: errors, } return executionTimes } func TestClient_ReadOnlyTransaction(t *testing.T) { t.Parallel() if err := testReadOnlyTransaction(t, make(map[string]SimulatedExecutionTime)); err != nil { t.Fatal(err) } } func TestClient_ReadOnlyTransaction_UnavailableOnSessionCreate(t *testing.T) { t.Parallel() if err := testReadOnlyTransaction(t, createSimulatedExecutionTimeWithTwoUnavailableErrors(MethodCreateSession)); err != nil { t.Fatal(err) } } func TestClient_ReadOnlyTransaction_UnavailableOnBeginTransaction(t *testing.T) { t.Parallel() if err := testReadOnlyTransaction(t, createSimulatedExecutionTimeWithTwoUnavailableErrors(MethodBeginTransaction)); err != nil { t.Fatal(err) } } func TestClient_ReadOnlyTransaction_UnavailableOnExecuteStreamingSql(t *testing.T) { t.Parallel() if err := testReadOnlyTransaction(t, createSimulatedExecutionTimeWithTwoUnavailableErrors(MethodExecuteStreamingSql)); err != nil { t.Fatal(err) } } func TestClient_ReadOnlyTransaction_UnavailableOnCreateSessionAndBeginTransaction(t *testing.T) { t.Parallel() exec := map[string]SimulatedExecutionTime{ MethodCreateSession: {Errors: []error{status.Error(codes.Unavailable, "Temporary unavailable")}}, MethodBeginTransaction: {Errors: []error{status.Error(codes.Unavailable, "Temporary unavailable")}}, } if err := testReadOnlyTransaction(t, exec); err != nil { t.Fatal(err) } } func TestClient_ReadOnlyTransaction_UnavailableOnCreateSessionAndInvalidArgumentOnBeginTransaction(t *testing.T) { t.Parallel() exec := map[string]SimulatedExecutionTime{ MethodCreateSession: {Errors: []error{status.Error(codes.Unavailable, "Temporary unavailable")}}, MethodBeginTransaction: {Errors: []error{status.Error(codes.InvalidArgument, "Invalid argument")}}, } if err := testReadOnlyTransaction(t, exec); err == nil { t.Fatalf("Missing expected exception") } else if status.Code(err) != codes.InvalidArgument { t.Fatalf("Got unexpected exception: %v", err) } } func testReadOnlyTransaction(t *testing.T, executionTimes map[string]SimulatedExecutionTime) error { server, client, teardown := setupMockedTestServer(t) defer teardown() for method, exec := range executionTimes { server.TestSpanner.PutExecutionTime(method, exec) } tx := client.ReadOnlyTransaction() defer tx.Close() ctx := context.Background() return executeSingerQuery(ctx, tx) } func TestClient_ReadWriteTransaction(t *testing.T) { t.Parallel() if err := testReadWriteTransaction(t, make(map[string]SimulatedExecutionTime), 1); err != nil { t.Fatal(err) } } func TestClient_ReadWriteTransactionCommitAborted(t *testing.T) { t.Parallel() if err := testReadWriteTransaction(t, map[string]SimulatedExecutionTime{ MethodCommitTransaction: {Errors: []error{status.Error(codes.Aborted, "Transaction aborted")}}, }, 2); err != nil { t.Fatal(err) } } func TestClient_ReadWriteTransactionExecuteStreamingSqlAborted(t *testing.T) { t.Parallel() if err := testReadWriteTransaction(t, map[string]SimulatedExecutionTime{ MethodExecuteStreamingSql: {Errors: []error{status.Error(codes.Aborted, "Transaction aborted")}}, }, 2); err != nil { t.Fatal(err) } } func TestClient_ReadWriteTransaction_UnavailableOnBeginTransaction(t *testing.T) { t.Parallel() if err := testReadWriteTransaction(t, map[string]SimulatedExecutionTime{ MethodBeginTransaction: {Errors: []error{status.Error(codes.Unavailable, "Unavailable")}}, }, 1); err != nil { t.Fatal(err) } } func TestClient_ReadWriteTransaction_UnavailableOnBeginAndAbortOnCommit(t *testing.T) { if err := testReadWriteTransaction(t, map[string]SimulatedExecutionTime{ MethodBeginTransaction: {Errors: []error{status.Error(codes.Unavailable, "Unavailable")}}, MethodCommitTransaction: {Errors: []error{status.Error(codes.Aborted, "Aborted")}}, }, 2); err != nil { t.Fatal(err) } } func TestClient_ReadWriteTransaction_UnavailableOnExecuteStreamingSql(t *testing.T) { t.Parallel() if err := testReadWriteTransaction(t, map[string]SimulatedExecutionTime{ MethodExecuteStreamingSql: {Errors: []error{status.Error(codes.Unavailable, "Unavailable")}}, }, 1); err != nil { t.Fatal(err) } } func TestClient_ReadWriteTransaction_UnavailableOnBeginAndExecuteStreamingSqlAndTwiceAbortOnCommit(t *testing.T) { t.Parallel() if err := testReadWriteTransaction(t, map[string]SimulatedExecutionTime{ MethodBeginTransaction: {Errors: []error{status.Error(codes.Unavailable, "Unavailable")}}, MethodExecuteStreamingSql: {Errors: []error{status.Error(codes.Unavailable, "Unavailable")}}, MethodCommitTransaction: {Errors: []error{status.Error(codes.Aborted, "Aborted"), status.Error(codes.Aborted, "Aborted")}}, }, 3); err != nil { t.Fatal(err) } } func TestClient_ReadWriteTransaction_AbortedOnExecuteStreamingSqlAndCommit(t *testing.T) { t.Parallel() if err := testReadWriteTransaction(t, map[string]SimulatedExecutionTime{ MethodExecuteStreamingSql: {Errors: []error{status.Error(codes.Aborted, "Aborted")}}, MethodCommitTransaction: {Errors: []error{status.Error(codes.Aborted, "Aborted"), status.Error(codes.Aborted, "Aborted")}}, }, 4); err != nil { t.Fatal(err) } } func TestClient_ReadWriteTransactionCommitAbortedAndUnavailable(t *testing.T) { t.Parallel() if err := testReadWriteTransaction(t, map[string]SimulatedExecutionTime{ MethodCommitTransaction: { Errors: []error{ status.Error(codes.Aborted, "Transaction aborted"), status.Error(codes.Unavailable, "Unavailable"), }, }, }, 2); err != nil { t.Fatal(err) } } func TestClient_ReadWriteTransactionCommitAlreadyExists(t *testing.T) { t.Parallel() if err := testReadWriteTransaction(t, map[string]SimulatedExecutionTime{ MethodCommitTransaction: {Errors: []error{status.Error(codes.AlreadyExists, "A row with this key already exists")}}, }, 1); err != nil { if status.Code(err) != codes.AlreadyExists { t.Fatalf("Got unexpected error %v, expected %v", err, codes.AlreadyExists) } } else { t.Fatalf("Missing expected exception") } } func testReadWriteTransaction(t *testing.T, executionTimes map[string]SimulatedExecutionTime, expectedAttempts int) error { server, client, teardown := setupMockedTestServer(t) defer teardown() for method, exec := range executionTimes { server.TestSpanner.PutExecutionTime(method, exec) } ctx := context.Background() var attempts int _, err := client.ReadWriteTransaction(ctx, func(ctx context.Context, tx *ReadWriteTransaction) error { attempts++ iter := tx.Query(ctx, NewStatement(SelectSingerIDAlbumIDAlbumTitleFromAlbums)) defer iter.Stop() rowCount := int64(0) for { row, err := iter.Next() if err == iterator.Done { break } if err != nil { return err } var singerID, albumID int64 var albumTitle string if err := row.Columns(&singerID, &albumID, &albumTitle); err != nil { return err } rowCount++ } if rowCount != SelectSingerIDAlbumIDAlbumTitleFromAlbumsRowCount { return spannerErrorf(codes.FailedPrecondition, "Row count mismatch, got %v, expected %v", rowCount, SelectSingerIDAlbumIDAlbumTitleFromAlbumsRowCount) } return nil }) if err != nil { return err } if expectedAttempts != attempts { t.Fatalf("unexpected number of attempts: %d, expected %d", attempts, expectedAttempts) } return nil } func TestClient_ApplyAtLeastOnce(t *testing.T) { t.Parallel() server, client, teardown := setupMockedTestServer(t) defer teardown() ms := []*Mutation{ Insert("Accounts", []string{"AccountId", "Nickname", "Balance"}, []interface{}{int64(1), "Foo", int64(50)}), Insert("Accounts", []string{"AccountId", "Nickname", "Balance"}, []interface{}{int64(2), "Bar", int64(1)}), } server.TestSpanner.PutExecutionTime(MethodCommitTransaction, SimulatedExecutionTime{ Errors: []error{status.Error(codes.Aborted, "Transaction aborted")}, }) _, err := client.Apply(context.Background(), ms, ApplyAtLeastOnce()) if err != nil { t.Fatal(err) } } func TestReadWriteTransaction_ErrUnexpectedEOF(t *testing.T) { _, client, teardown := setupMockedTestServer(t) defer teardown() ctx := context.Background() var attempts int _, err := client.ReadWriteTransaction(ctx, func(ctx context.Context, tx *ReadWriteTransaction) error { attempts++ iter := tx.Query(ctx, NewStatement(SelectSingerIDAlbumIDAlbumTitleFromAlbums)) defer iter.Stop() for { row, err := iter.Next() if err == iterator.Done { break } if err != nil { return err } var singerID, albumID int64 var albumTitle string if err := row.Columns(&singerID, &albumID, &albumTitle); err != nil { return err } } return io.ErrUnexpectedEOF }) if err != io.ErrUnexpectedEOF { t.Fatalf("Missing expected error %v, got %v", io.ErrUnexpectedEOF, err) } if attempts != 1 { t.Fatalf("unexpected number of attempts: %d, expected %d", attempts, 1) } } google-cloud-go-0.49.0/spanner/cmp_test.go000066400000000000000000000015771356504100700204150ustar00rootroot00000000000000/* Copyright 2018 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spanner import ( "cloud.google.com/go/internal/testutil" "github.com/google/go-cmp/cmp" ) // TODO(deklerk): move this to internal/testutil func testEqual(a, b interface{}) bool { return testutil.Equal(a, b, cmp.AllowUnexported(TimestampBound{}, Error{}, Mutation{}, Row{}, Partition{}, BatchReadOnlyTransactionID{})) } google-cloud-go-0.49.0/spanner/doc.go000066400000000000000000000270621356504100700173410ustar00rootroot00000000000000/* Copyright 2017 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Package spanner provides a client for reading and writing to Cloud Spanner databases. See the packages under admin for clients that operate on databases and instances. See https://cloud.google.com/spanner/docs/getting-started/go/ for an introduction to Cloud Spanner and additional help on using this API. See https://godoc.org/cloud.google.com/go for authentication, timeouts, connection pooling and similar aspects of this package. Creating a Client To start working with this package, create a client that refers to the database of interest: ctx := context.Background() client, err := spanner.NewClient(ctx, "projects/P/instances/I/databases/D") if err != nil { // TODO: Handle error. } defer client.Close() Remember to close the client after use to free up the sessions in the session pool. Simple Reads and Writes Two Client methods, Apply and Single, work well for simple reads and writes. As a quick introduction, here we write a new row to the database and read it back: _, err := client.Apply(ctx, []*spanner.Mutation{ spanner.Insert("Users", []string{"name", "email"}, []interface{}{"alice", "a@example.com"})}) if err != nil { // TODO: Handle error. } row, err := client.Single().ReadRow(ctx, "Users", spanner.Key{"alice"}, []string{"email"}) if err != nil { // TODO: Handle error. } All the methods used above are discussed in more detail below. Keys Every Cloud Spanner row has a unique key, composed of one or more columns. Construct keys with a literal of type Key: key1 := spanner.Key{"alice"} KeyRanges The keys of a Cloud Spanner table are ordered. You can specify ranges of keys using the KeyRange type: kr1 := spanner.KeyRange{Start: key1, End: key2} By default, a KeyRange includes its start key but not its end key. Use the Kind field to specify other boundary conditions: // include both keys kr2 := spanner.KeyRange{Start: key1, End: key2, Kind: spanner.ClosedClosed} KeySets A KeySet represents a set of keys. A single Key or KeyRange can act as a KeySet. Use the KeySets function to build the union of several KeySets: ks1 := spanner.KeySets(key1, key2, kr1, kr2) AllKeys returns a KeySet that refers to all the keys in a table: ks2 := spanner.AllKeys() Transactions All Cloud Spanner reads and writes occur inside transactions. There are two types of transactions, read-only and read-write. Read-only transactions cannot change the database, do not acquire locks, and may access either the current database state or states in the past. Read-write transactions can read the database before writing to it, and always apply to the most recent database state. Single Reads The simplest and fastest transaction is a ReadOnlyTransaction that supports a single read operation. Use Client.Single to create such a transaction. You can chain the call to Single with a call to a Read method. When you only want one row whose key you know, use ReadRow. Provide the table name, key, and the columns you want to read: row, err := client.Single().ReadRow(ctx, "Accounts", spanner.Key{"alice"}, []string{"balance"}) Read multiple rows with the Read method. It takes a table name, KeySet, and list of columns: iter := client.Single().Read(ctx, "Accounts", keyset1, columns) Read returns a RowIterator. You can call the Do method on the iterator and pass a callback: err := iter.Do(func(row *Row) error { // TODO: use row return nil }) RowIterator also follows the standard pattern for the Google Cloud Client Libraries: defer iter.Stop() for { row, err := iter.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: use row } Always call Stop when you finish using an iterator this way, whether or not you iterate to the end. (Failing to call Stop could lead you to exhaust the database's session quota.) To read rows with an index, use ReadUsingIndex. Statements The most general form of reading uses SQL statements. Construct a Statement with NewStatement, setting any parameters using the Statement's Params map: stmt := spanner.NewStatement("SELECT First, Last FROM SINGERS WHERE Last >= @start") stmt.Params["start"] = "Dylan" You can also construct a Statement directly with a struct literal, providing your own map of parameters. Use the Query method to run the statement and obtain an iterator: iter := client.Single().Query(ctx, stmt) Rows Once you have a Row, via an iterator or a call to ReadRow, you can extract column values in several ways. Pass in a pointer to a Go variable of the appropriate type when you extract a value. You can extract by column position or name: err := row.Column(0, &name) err = row.ColumnByName("balance", &balance) You can extract all the columns at once: err = row.Columns(&name, &balance) Or you can define a Go struct that corresponds to your columns, and extract into that: var s struct { Name string; Balance int64 } err = row.ToStruct(&s) For Cloud Spanner columns that may contain NULL, use one of the NullXXX types, like NullString: var ns spanner.NullString if err := row.Column(0, &ns); err != nil { // TODO: Handle error. } if ns.Valid { fmt.Println(ns.StringVal) } else { fmt.Println("column is NULL") } Multiple Reads To perform more than one read in a transaction, use ReadOnlyTransaction: txn := client.ReadOnlyTransaction() defer txn.Close() iter := txn.Query(ctx, stmt1) // ... iter = txn.Query(ctx, stmt2) // ... You must call Close when you are done with the transaction. Timestamps and Timestamp Bounds Cloud Spanner read-only transactions conceptually perform all their reads at a single moment in time, called the transaction's read timestamp. Once a read has started, you can call ReadOnlyTransaction's Timestamp method to obtain the read timestamp. By default, a transaction will pick the most recent time (a time where all previously committed transactions are visible) for its reads. This provides the freshest data, but may involve some delay. You can often get a quicker response if you are willing to tolerate "stale" data. You can control the read timestamp selected by a transaction by calling the WithTimestampBound method on the transaction before using it. For example, to perform a query on data that is at most one minute stale, use client.Single(). WithTimestampBound(spanner.MaxStaleness(1*time.Minute)). Query(ctx, stmt) See the documentation of TimestampBound for more details. Mutations To write values to a Cloud Spanner database, construct a Mutation. The spanner package has functions for inserting, updating and deleting rows. Except for the Delete methods, which take a Key or KeyRange, each mutation-building function comes in three varieties. One takes lists of columns and values along with the table name: m1 := spanner.Insert("Users", []string{"name", "email"}, []interface{}{"alice", "a@example.com"}) One takes a map from column names to values: m2 := spanner.InsertMap("Users", map[string]interface{}{ "name": "alice", "email": "a@example.com", }) And the third accepts a struct value, and determines the columns from the struct field names: type User struct { Name, Email string } u := User{Name: "alice", Email: "a@example.com"} m3, err := spanner.InsertStruct("Users", u) Writes To apply a list of mutations to the database, use Apply: _, err := client.Apply(ctx, []*spanner.Mutation{m1, m2, m3}) If you need to read before writing in a single transaction, use a ReadWriteTransaction. ReadWriteTransactions may abort and need to be retried. You pass in a function to ReadWriteTransaction, and the client will handle the retries automatically. Use the transaction's BufferWrite method to buffer mutations, which will all be executed at the end of the transaction: _, err := client.ReadWriteTransaction(ctx, func(ctx context.Context, txn *spanner.ReadWriteTransaction) error { var balance int64 row, err := txn.ReadRow(ctx, "Accounts", spanner.Key{"alice"}, []string{"balance"}) if err != nil { // This function will be called again if this is an IsAborted error. return err } if err := row.Column(0, &balance); err != nil { return err } if balance <= 10 { return errors.New("insufficient funds in account") } balance -= 10 m := spanner.Update("Accounts", []string{"user", "balance"}, []interface{}{"alice", balance}) txn.BufferWrite([]*spanner.Mutation{m}) // The buffered mutation will be committed. If the commit // fails with an IsAborted error, this function will be called // again. return nil }) Structs Cloud Spanner STRUCT (aka STRUCT) values (https://cloud.google.com/spanner/docs/data-types#struct-type) can be represented by a Go struct value. A proto StructType is built from the field types and field tag information of the Go struct. If a field in the struct type definition has a "spanner:" tag, then the value of the "spanner" key in the tag is used as the name for that field in the built StructType, otherwise the field name in the struct definition is used. To specify a field with an empty field name in a Cloud Spanner STRUCT type, use the `spanner:""` tag annotation against the corresponding field in the Go struct's type definition. A STRUCT value can contain STRUCT-typed and Array-of-STRUCT typed fields and these can be specified using named struct-typed and []struct-typed fields inside a Go struct. However, embedded struct fields are not allowed. Unexported struct fields are ignored. NULL STRUCT values in Cloud Spanner are typed. A nil pointer to a Go struct value can be used to specify a NULL STRUCT value of the corresponding StructType. Nil and empty slices of a Go STRUCT type can be used to specify NULL and empty array values respectively of the corresponding StructType. A slice of pointers to a Go struct type can be used to specify an array of NULL-able STRUCT values. DML and Partitioned DML Spanner supports DML statements like INSERT, UPDATE and DELETE. Use ReadWriteTransaction.Update to run DML statements. It returns the number of rows affected. (You can call use ReadWriteTransaction.Query with a DML statement. The first call to Next on the resulting RowIterator will return iterator.Done, and the RowCount field of the iterator will hold the number of affected rows.) For large databases, it may be more efficient to partition the DML statement. Use client.PartitionedUpdate to run a DML statement in this way. Not all DML statements can be partitioned. Tracing This client has been instrumented to use OpenCensus tracing (http://opencensus.io). To enable tracing, see "Enabling Tracing for a Program" at https://godoc.org/go.opencensus.io/trace. OpenCensus tracing requires Go 1.8 or higher. */ package spanner // import "cloud.google.com/go/spanner" google-cloud-go-0.49.0/spanner/errors.go000066400000000000000000000065201356504100700201040ustar00rootroot00000000000000/* Copyright 2017 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spanner import ( "context" "fmt" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" ) // Error is the structured error returned by Cloud Spanner client. type Error struct { // Code is the canonical error code for describing the nature of a // particular error. Code codes.Code // Desc explains more details of the error. Desc string // trailers are the trailers returned in the response, if any. trailers metadata.MD } // Error implements error.Error. func (e *Error) Error() string { if e == nil { return fmt.Sprintf("spanner: OK") } return fmt.Sprintf("spanner: code = %q, desc = %q", e.Code, e.Desc) } // GRPCStatus returns the corresponding gRPC Status of this Spanner error. // This allows the error to be converted to a gRPC status using // `status.Convert(error)`. func (e *Error) GRPCStatus() *status.Status { return status.New(e.Code, e.Desc) } // decorate decorates an existing spanner.Error with more information. func (e *Error) decorate(info string) { e.Desc = fmt.Sprintf("%v, %v", info, e.Desc) } // spannerErrorf generates a *spanner.Error with the given error code and // description. func spannerErrorf(ec codes.Code, format string, args ...interface{}) error { return &Error{ Code: ec, Desc: fmt.Sprintf(format, args...), } } // toSpannerError converts general Go error to *spanner.Error. func toSpannerError(err error) error { return toSpannerErrorWithMetadata(err, nil) } // toSpannerErrorWithMetadata converts general Go error and grpc trailers to // *spanner.Error. // // Note: modifies original error if trailers aren't nil. func toSpannerErrorWithMetadata(err error, trailers metadata.MD) error { if err == nil { return nil } if se, ok := err.(*Error); ok { if trailers != nil { se.trailers = metadata.Join(se.trailers, trailers) } return se } switch { case err == context.DeadlineExceeded: return &Error{codes.DeadlineExceeded, err.Error(), trailers} case err == context.Canceled: return &Error{codes.Canceled, err.Error(), trailers} case status.Code(err) == codes.Unknown: return &Error{codes.Unknown, err.Error(), trailers} default: return &Error{status.Code(err), grpc.ErrorDesc(err), trailers} } } // ErrCode extracts the canonical error code from a Go error. func ErrCode(err error) codes.Code { se, ok := toSpannerError(err).(*Error) if !ok { return codes.Unknown } return se.Code } // ErrDesc extracts the Cloud Spanner error description from a Go error. func ErrDesc(err error) string { se, ok := toSpannerError(err).(*Error) if !ok { return err.Error() } return se.Desc } // errTrailers extracts the grpc trailers if present from a Go error. func errTrailers(err error) metadata.MD { se, ok := err.(*Error) if !ok { return nil } return se.trailers } google-cloud-go-0.49.0/spanner/errors_test.go000066400000000000000000000026231356504100700211430ustar00rootroot00000000000000/* Copyright 2017 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spanner import ( "context" "errors" "testing" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) func TestToSpannerError(t *testing.T) { for _, test := range []struct { err error wantCode codes.Code }{ {errors.New("wha?"), codes.Unknown}, {context.Canceled, codes.Canceled}, {context.DeadlineExceeded, codes.DeadlineExceeded}, {status.Errorf(codes.ResourceExhausted, "so tired"), codes.ResourceExhausted}, {spannerErrorf(codes.InvalidArgument, "bad"), codes.InvalidArgument}, } { err := toSpannerError(test.err) if got, want := err.(*Error).Code, test.wantCode; got != want { t.Errorf("%v: got %s, want %s", test.err, got, want) } converted := status.Convert(err) if converted.Code() != test.wantCode { t.Errorf("%v: got status %v, want status %v", test.err, converted.Code(), test.wantCode) } } } google-cloud-go-0.49.0/spanner/examples_test.go000066400000000000000000000445211356504100700214500ustar00rootroot00000000000000/* Copyright 2017 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spanner_test import ( "context" "errors" "fmt" "sync" "time" "cloud.google.com/go/spanner" "google.golang.org/api/iterator" sppb "google.golang.org/genproto/googleapis/spanner/v1" ) func ExampleNewClient() { ctx := context.Background() const myDB = "projects/my-project/instances/my-instance/database/my-db" client, err := spanner.NewClient(ctx, myDB) if err != nil { // TODO: Handle error. } _ = client // TODO: Use client. } const myDB = "projects/my-project/instances/my-instance/database/my-db" func ExampleNewClientWithConfig() { ctx := context.Background() const myDB = "projects/my-project/instances/my-instance/database/my-db" client, err := spanner.NewClientWithConfig(ctx, myDB, spanner.ClientConfig{ NumChannels: 10, }) if err != nil { // TODO: Handle error. } _ = client // TODO: Use client. client.Close() // Close client when done. } func ExampleClient_Single() { ctx := context.Background() client, err := spanner.NewClient(ctx, myDB) if err != nil { // TODO: Handle error. } iter := client.Single().Query(ctx, spanner.NewStatement("SELECT FirstName FROM Singers")) _ = iter // TODO: iterate using Next or Do. } func ExampleClient_ReadOnlyTransaction() { ctx := context.Background() client, err := spanner.NewClient(ctx, myDB) if err != nil { // TODO: Handle error. } t := client.ReadOnlyTransaction() defer t.Close() // TODO: Read with t using Read, ReadRow, ReadUsingIndex, or Query. } func ExampleClient_ReadWriteTransaction() { ctx := context.Background() client, err := spanner.NewClient(ctx, myDB) if err != nil { // TODO: Handle error. } _, err = client.ReadWriteTransaction(ctx, func(ctx context.Context, txn *spanner.ReadWriteTransaction) error { var balance int64 row, err := txn.ReadRow(ctx, "Accounts", spanner.Key{"alice"}, []string{"balance"}) if err != nil { // This function will be called again if this is an IsAborted error. return err } if err := row.Column(0, &balance); err != nil { return err } if balance <= 10 { return errors.New("insufficient funds in account") } balance -= 10 m := spanner.Update("Accounts", []string{"user", "balance"}, []interface{}{"alice", balance}) return txn.BufferWrite([]*spanner.Mutation{m}) // The buffered mutation will be committed. If the commit fails with an // IsAborted error, this function will be called again. }) if err != nil { // TODO: Handle error. } } func ExampleUpdate() { ctx := context.Background() client, err := spanner.NewClient(ctx, myDB) if err != nil { // TODO: Handle error. } _, err = client.ReadWriteTransaction(ctx, func(ctx context.Context, txn *spanner.ReadWriteTransaction) error { row, err := txn.ReadRow(ctx, "Accounts", spanner.Key{"alice"}, []string{"balance"}) if err != nil { return err } var balance int64 if err := row.Column(0, &balance); err != nil { return err } return txn.BufferWrite([]*spanner.Mutation{ spanner.Update("Accounts", []string{"user", "balance"}, []interface{}{"alice", balance + 10}), }) }) if err != nil { // TODO: Handle error. } } // This example is the same as the one for Update, except for the use of UpdateMap. func ExampleUpdateMap() { ctx := context.Background() client, err := spanner.NewClient(ctx, myDB) if err != nil { // TODO: Handle error. } _, err = client.ReadWriteTransaction(ctx, func(ctx context.Context, txn *spanner.ReadWriteTransaction) error { row, err := txn.ReadRow(ctx, "Accounts", spanner.Key{"alice"}, []string{"balance"}) if err != nil { return err } var balance int64 if err := row.Column(0, &balance); err != nil { return err } return txn.BufferWrite([]*spanner.Mutation{ spanner.UpdateMap("Accounts", map[string]interface{}{ "user": "alice", "balance": balance + 10, }), }) }) if err != nil { // TODO: Handle error. } } // This example is the same as the one for Update, except for the use of // UpdateStruct. func ExampleUpdateStruct() { ctx := context.Background() client, err := spanner.NewClient(ctx, myDB) if err != nil { // TODO: Handle error. } type account struct { User string `spanner:"user"` Balance int64 `spanner:"balance"` } _, err = client.ReadWriteTransaction(ctx, func(ctx context.Context, txn *spanner.ReadWriteTransaction) error { row, err := txn.ReadRow(ctx, "Accounts", spanner.Key{"alice"}, []string{"balance"}) if err != nil { return err } var balance int64 if err := row.Column(0, &balance); err != nil { return err } m, err := spanner.UpdateStruct("Accounts", account{ User: "alice", Balance: balance + 10, }) if err != nil { return err } return txn.BufferWrite([]*spanner.Mutation{m}) }) if err != nil { // TODO: Handle error. } } func ExampleClient_Apply() { ctx := context.Background() client, err := spanner.NewClient(ctx, myDB) if err != nil { // TODO: Handle error. } m := spanner.Update("Users", []string{"name", "email"}, []interface{}{"alice", "a@example.com"}) _, err = client.Apply(ctx, []*spanner.Mutation{m}) if err != nil { // TODO: Handle error. } } func ExampleInsert() { m := spanner.Insert("Users", []string{"name", "email"}, []interface{}{"alice", "a@example.com"}) _ = m // TODO: use with Client.Apply or in a ReadWriteTransaction. } func ExampleInsertMap() { m := spanner.InsertMap("Users", map[string]interface{}{ "name": "alice", "email": "a@example.com", }) _ = m // TODO: use with Client.Apply or in a ReadWriteTransaction. } func ExampleInsertStruct() { type User struct { Name, Email string } u := User{Name: "alice", Email: "a@example.com"} m, err := spanner.InsertStruct("Users", u) if err != nil { // TODO: Handle error. } _ = m // TODO: use with Client.Apply or in a ReadWriteTransaction. } func ExampleDelete() { m := spanner.Delete("Users", spanner.Key{"alice"}) _ = m // TODO: use with Client.Apply or in a ReadWriteTransaction. } func ExampleDelete_keyRange() { m := spanner.Delete("Users", spanner.KeyRange{ Start: spanner.Key{"alice"}, End: spanner.Key{"bob"}, Kind: spanner.ClosedClosed, }) _ = m // TODO: use with Client.Apply or in a ReadWriteTransaction. } func ExampleRowIterator_Next() { ctx := context.Background() client, err := spanner.NewClient(ctx, myDB) if err != nil { // TODO: Handle error. } iter := client.Single().Query(ctx, spanner.NewStatement("SELECT FirstName FROM Singers")) defer iter.Stop() for { row, err := iter.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } var firstName string if err := row.Column(0, &firstName); err != nil { // TODO: Handle error. } fmt.Println(firstName) } } func ExampleRowIterator_Do() { ctx := context.Background() client, err := spanner.NewClient(ctx, myDB) if err != nil { // TODO: Handle error. } iter := client.Single().Query(ctx, spanner.NewStatement("SELECT FirstName FROM Singers")) err = iter.Do(func(r *spanner.Row) error { var firstName string if err := r.Column(0, &firstName); err != nil { return err } fmt.Println(firstName) return nil }) if err != nil { // TODO: Handle error. } } func ExampleRow_Size() { ctx := context.Background() client, err := spanner.NewClient(ctx, myDB) if err != nil { // TODO: Handle error. } row, err := client.Single().ReadRow(ctx, "Accounts", spanner.Key{"alice"}, []string{"name", "balance"}) if err != nil { // TODO: Handle error. } fmt.Println(row.Size()) // 2 } func ExampleRow_ColumnName() { ctx := context.Background() client, err := spanner.NewClient(ctx, myDB) if err != nil { // TODO: Handle error. } row, err := client.Single().ReadRow(ctx, "Accounts", spanner.Key{"alice"}, []string{"name", "balance"}) if err != nil { // TODO: Handle error. } fmt.Println(row.ColumnName(1)) // "balance" } func ExampleRow_ColumnIndex() { ctx := context.Background() client, err := spanner.NewClient(ctx, myDB) if err != nil { // TODO: Handle error. } row, err := client.Single().ReadRow(ctx, "Accounts", spanner.Key{"alice"}, []string{"name", "balance"}) if err != nil { // TODO: Handle error. } index, err := row.ColumnIndex("balance") if err != nil { // TODO: Handle error. } fmt.Println(index) } func ExampleRow_ColumnNames() { ctx := context.Background() client, err := spanner.NewClient(ctx, myDB) if err != nil { // TODO: Handle error. } row, err := client.Single().ReadRow(ctx, "Accounts", spanner.Key{"alice"}, []string{"name", "balance"}) if err != nil { // TODO: Handle error. } fmt.Println(row.ColumnNames()) } func ExampleRow_ColumnByName() { ctx := context.Background() client, err := spanner.NewClient(ctx, myDB) if err != nil { // TODO: Handle error. } row, err := client.Single().ReadRow(ctx, "Accounts", spanner.Key{"alice"}, []string{"name", "balance"}) if err != nil { // TODO: Handle error. } var balance int64 if err := row.ColumnByName("balance", &balance); err != nil { // TODO: Handle error. } fmt.Println(balance) } func ExampleRow_Columns() { ctx := context.Background() client, err := spanner.NewClient(ctx, myDB) if err != nil { // TODO: Handle error. } row, err := client.Single().ReadRow(ctx, "Accounts", spanner.Key{"alice"}, []string{"name", "balance"}) if err != nil { // TODO: Handle error. } var name string var balance int64 if err := row.Columns(&name, &balance); err != nil { // TODO: Handle error. } fmt.Println(name, balance) } func ExampleRow_ToStruct() { ctx := context.Background() client, err := spanner.NewClient(ctx, myDB) if err != nil { // TODO: Handle error. } row, err := client.Single().ReadRow(ctx, "Accounts", spanner.Key{"alice"}, []string{"name", "balance"}) if err != nil { // TODO: Handle error. } type Account struct { Name string Balance int64 } var acct Account if err := row.ToStruct(&acct); err != nil { // TODO: Handle error. } fmt.Println(acct) } func ExampleReadOnlyTransaction_Read() { ctx := context.Background() client, err := spanner.NewClient(ctx, myDB) if err != nil { // TODO: Handle error. } iter := client.Single().Read(ctx, "Users", spanner.KeySets(spanner.Key{"alice"}, spanner.Key{"bob"}), []string{"name", "email"}) _ = iter // TODO: iterate using Next or Do. } func ExampleReadOnlyTransaction_ReadUsingIndex() { ctx := context.Background() client, err := spanner.NewClient(ctx, myDB) if err != nil { // TODO: Handle error. } iter := client.Single().ReadUsingIndex(ctx, "Users", "UsersByEmail", spanner.KeySets(spanner.Key{"a@example.com"}, spanner.Key{"b@example.com"}), []string{"name", "email"}) _ = iter // TODO: iterate using Next or Do. } func ExampleReadOnlyTransaction_ReadWithOptions() { ctx := context.Background() client, err := spanner.NewClient(ctx, myDB) if err != nil { // TODO: Handle error. } // Use an index, and limit to 100 rows at most. iter := client.Single().ReadWithOptions(ctx, "Users", spanner.KeySets(spanner.Key{"a@example.com"}, spanner.Key{"b@example.com"}), []string{"name", "email"}, &spanner.ReadOptions{ Index: "UsersByEmail", Limit: 100, }) _ = iter // TODO: iterate using Next or Do. } func ExampleReadOnlyTransaction_ReadRow() { ctx := context.Background() client, err := spanner.NewClient(ctx, myDB) if err != nil { // TODO: Handle error. } row, err := client.Single().ReadRow(ctx, "Users", spanner.Key{"alice"}, []string{"name", "email"}) if err != nil { // TODO: Handle error. } _ = row // TODO: use row } func ExampleReadOnlyTransaction_Query() { ctx := context.Background() client, err := spanner.NewClient(ctx, myDB) if err != nil { // TODO: Handle error. } iter := client.Single().Query(ctx, spanner.NewStatement("SELECT FirstName FROM Singers")) _ = iter // TODO: iterate using Next or Do. } func ExampleNewStatement() { stmt := spanner.NewStatement("SELECT FirstName, LastName FROM SINGERS WHERE LastName >= @start") stmt.Params["start"] = "Dylan" // TODO: Use stmt in Query. } func ExampleNewStatement_structLiteral() { stmt := spanner.Statement{ SQL: `SELECT FirstName, LastName FROM SINGERS WHERE LastName = ("Lea", "Martin")`, } _ = stmt // TODO: Use stmt in Query. } func ExampleStructParam() { stmt := spanner.Statement{ SQL: "SELECT * FROM SINGERS WHERE (FirstName, LastName) = @singerinfo", Params: map[string]interface{}{ "singerinfo": struct { FirstName string LastName string }{"Bob", "Dylan"}, }, } _ = stmt // TODO: Use stmt in Query. } func ExampleArrayOfStructParam() { stmt := spanner.Statement{ SQL: "SELECT * FROM SINGERS WHERE (FirstName, LastName) IN UNNEST(@singerinfo)", Params: map[string]interface{}{ "singerinfo": []struct { FirstName string LastName string }{ {"Ringo", "Starr"}, {"John", "Lennon"}, }, }, } _ = stmt // TODO: Use stmt in Query. } func ExampleReadOnlyTransaction_Timestamp() { ctx := context.Background() client, err := spanner.NewClient(ctx, myDB) if err != nil { // TODO: Handle error. } txn := client.Single() row, err := txn.ReadRow(ctx, "Users", spanner.Key{"alice"}, []string{"name", "email"}) if err != nil { // TODO: Handle error. } readTimestamp, err := txn.Timestamp() if err != nil { // TODO: Handle error. } fmt.Println("read happened at", readTimestamp) _ = row // TODO: use row } func ExampleReadOnlyTransaction_WithTimestampBound() { ctx := context.Background() client, err := spanner.NewClient(ctx, myDB) if err != nil { // TODO: Handle error. } txn := client.Single().WithTimestampBound(spanner.MaxStaleness(30 * time.Second)) row, err := txn.ReadRow(ctx, "Users", spanner.Key{"alice"}, []string{"name", "email"}) if err != nil { // TODO: Handle error. } _ = row // TODO: use row readTimestamp, err := txn.Timestamp() if err != nil { // TODO: Handle error. } fmt.Println("read happened at", readTimestamp) } func ExampleGenericColumnValue_Decode() { // In real applications, rows can be retrieved by methods like client.Single().ReadRow(). row, err := spanner.NewRow([]string{"intCol", "strCol"}, []interface{}{42, "my-text"}) if err != nil { // TODO: Handle error. } for i := 0; i < row.Size(); i++ { var col spanner.GenericColumnValue if err := row.Column(i, &col); err != nil { // TODO: Handle error. } switch col.Type.Code { case sppb.TypeCode_INT64: var v int64 if err := col.Decode(&v); err != nil { // TODO: Handle error. } fmt.Println("int", v) case sppb.TypeCode_STRING: var v string if err := col.Decode(&v); err != nil { // TODO: Handle error. } fmt.Println("string", v) } } // Output: // int 42 // string my-text } func ExampleClient_BatchReadOnlyTransaction() { ctx := context.Background() var ( client *spanner.Client txn *spanner.BatchReadOnlyTransaction err error ) if client, err = spanner.NewClient(ctx, myDB); err != nil { // TODO: Handle error. } defer client.Close() if txn, err = client.BatchReadOnlyTransaction(ctx, spanner.StrongRead()); err != nil { // TODO: Handle error. } defer txn.Close() // Singer represents the elements in a row from the Singers table. type Singer struct { SingerID int64 FirstName string LastName string SingerInfo []byte } stmt := spanner.Statement{SQL: "SELECT * FROM Singers;"} partitions, err := txn.PartitionQuery(ctx, stmt, spanner.PartitionOptions{}) if err != nil { // TODO: Handle error. } // Note: here we use multiple goroutines, but you should use separate // processes/machines. wg := sync.WaitGroup{} for i, p := range partitions { wg.Add(1) go func(i int, p *spanner.Partition) { defer wg.Done() iter := txn.Execute(ctx, p) defer iter.Stop() for { row, err := iter.Next() if err == iterator.Done { break } else if err != nil { // TODO: Handle error. } var s Singer if err := row.ToStruct(&s); err != nil { // TODO: Handle error. } _ = s // TODO: Process the row. } }(i, p) } wg.Wait() } func ExampleCommitTimestamp() { ctx := context.Background() client, err := spanner.NewClient(ctx, myDB) if err != nil { // TODO: Handle error. } type account struct { User string Creation spanner.NullTime // time.Time can also be used if column isNOT NULL } a := account{User: "Joe", Creation: spanner.NullTime{spanner.CommitTimestamp, true}} m, err := spanner.InsertStruct("Accounts", a) if err != nil { // TODO: Handle error. } _, err = client.Apply(ctx, []*spanner.Mutation{m}, spanner.ApplyAtLeastOnce()) if err != nil { // TODO: Handle error. } if r, e := client.Single().ReadRow(ctx, "Accounts", spanner.Key{"Joe"}, []string{"User", "Creation"}); e != nil { // TODO: Handle error. } else { var got account if err := r.ToStruct(&got); err != nil { // TODO: Handle error. } _ = got // TODO: Process row. } } func ExampleStatement_regexpContains() { // Search for accounts with valid emails using regexp as per: // https://cloud.google.com/spanner/docs/functions-and-operators#regexp_contains stmt := spanner.Statement{ SQL: `SELECT * FROM users WHERE REGEXP_CONTAINS(email, @valid_email)`, Params: map[string]interface{}{ "valid_email": `\Q@\E`, }, } _ = stmt // TODO: Use stmt in a query. } func ExampleKeySets() { ctx := context.Background() client, err := spanner.NewClient(ctx, myDB) if err != nil { // TODO: Handle error. } // Get some rows from the Accounts table using a secondary index. In this case we get all users who are in Georgia. iter := client.Single().ReadUsingIndex(context.Background(), "Accounts", "idx_state", spanner.Key{"GA"}, []string{"state"}) // Create a empty KeySet by calling the KeySets function with no parameters. ks := spanner.KeySets() // Loop the results of a previous query iterator. for { row, err := iter.Next() if err == iterator.Done { break } else if err != nil { // TODO: Handle error. } var id string err = row.ColumnByName("User", &id) if err != nil { // TODO: Handle error. } ks = spanner.KeySets(spanner.KeySets(spanner.Key{id}, ks)) } _ = ks //TODO: Go use the KeySet in another query. } google-cloud-go-0.49.0/spanner/go.mod000066400000000000000000000011201356504100700173360ustar00rootroot00000000000000module cloud.google.com/go/spanner go 1.11 require ( cloud.google.com/go v0.46.3 cloud.google.com/go/storage v1.0.0 // indirect github.com/golang/protobuf v1.3.2 github.com/google/go-cmp v0.3.0 github.com/googleapis/gax-go/v2 v2.0.5 go.opencensus.io v0.22.0 golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136 // indirect golang.org/x/lint v0.0.0-20190930215403-16217165b5de // indirect golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2 // indirect google.golang.org/api v0.14.0 google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9 google.golang.org/grpc v1.21.1 ) google-cloud-go-0.49.0/spanner/go.sum000066400000000000000000000410771356504100700174020ustar00rootroot00000000000000cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3 h1:AVXDdKsrtX33oR9fbCMu/+c1o8Ofjq6Ku/MInaLVg5Y= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go/bigquery v1.0.1 h1:hL+ycaJpVE9M7nLoiXb/Pn10ENE2u+oddxbD8uu0ZVU= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/datastore v1.0.0 h1:Kt+gOPPp2LEPWp8CSfxhsM8ik9CcyE/gYu+0r+RnZvM= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/pubsub v1.0.1 h1:W9tAK3E57P75u0XLLR82LZyw8VpAnhmyTOxW9qzmyj8= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/storage v1.0.0 h1:VV2nUM3wwLLGh9lSABFgZMjInyUbJeaRSE64WuAIQ+4= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024 h1:rBMNdlhTLzJjJSDIjNEXX1Pz3Hmwmz91v+zycvx9PJc= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979 h1:Agxu5KLo8o7Bb634SVDnhIfpTvxmzUwhbYAzBvXt6h4= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136 h1:A1gGSx58LAGVHUUsOf7IiR0u8Xb6W51gRwfDBhkdcaw= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac h1:8R1esu+8QioDxo4E4mX6bFztO+dMTM49DNAaWfO5OeY= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0 h1:HyfiK1WMnHj5FXFXatD+Qs1A/xC2Run6RzeW1SyHxpc= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff h1:On1qIo75ByTwFJ4/W2bIqHcwJ9XAqtSWUs8GwRrIhtc= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2 h1:EtTFh6h4SAKemS+CURDMTDIANuduG5zKEXShyy18bGA= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0 h1:jbyannxz0XFD3zdjgrSUsaJbgpH4eTrkdhRChkHPfO8= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.14.0 h1:uMf5uLi4eQMRrMKhCplNik4U4H8Z6C1br3zOtAa/aDE= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51 h1:Ex1mq5jaJof+kRnYi3SlYJ8KKa9Ao3NHyIT5XJ1gF6U= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9 h1:6XzpBoANz1NqMNfDXzc2QmHmbb1vyMsvRfoP5rM+K1I= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1 h1:j6XxA85m/6txkUCHvzlV5f+HBNl/1r5cZ2A/3IEFOO8= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= google-cloud-go-0.49.0/spanner/go_mod_tidy_hack.go000066400000000000000000000016261356504100700220550ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // This file, and the cloud.google.com/go import, won't actually become part of // the resultant binary. // +build modhack package spanner // Necessary for safely adding multi-module repo. See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository import _ "cloud.google.com/go" google-cloud-go-0.49.0/spanner/integration_test.go000066400000000000000000002412231356504100700221530ustar00rootroot00000000000000/* Copyright 2017 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spanner import ( "context" "errors" "flag" "fmt" "log" "math" "os" "reflect" "strings" "sync" "testing" "time" "cloud.google.com/go/civil" "cloud.google.com/go/internal/testutil" "cloud.google.com/go/internal/uid" database "cloud.google.com/go/spanner/admin/database/apiv1" instance "cloud.google.com/go/spanner/admin/instance/apiv1" "google.golang.org/api/iterator" "google.golang.org/api/option" adminpb "google.golang.org/genproto/googleapis/spanner/admin/database/v1" instancepb "google.golang.org/genproto/googleapis/spanner/admin/instance/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) var ( // testProjectID specifies the project used for testing. It can be changed // by setting environment variable GCLOUD_TESTS_GOLANG_PROJECT_ID. testProjectID = testutil.ProjID() dbNameSpace = uid.NewSpace("gotest", &uid.Options{Sep: '_', Short: true}) instanceNameSpace = uid.NewSpace("gotest", &uid.Options{Sep: '-', Short: true}) testInstanceID = instanceNameSpace.New() testTable = "TestTable" testTableIndex = "TestTableByValue" testTableColumns = []string{"Key", "StringValue"} databaseAdmin *database.DatabaseAdminClient instanceAdmin *instance.InstanceAdminClient singerDBStatements = []string{ `CREATE TABLE Singers ( SingerId INT64 NOT NULL, FirstName STRING(1024), LastName STRING(1024), SingerInfo BYTES(MAX) ) PRIMARY KEY (SingerId)`, `CREATE INDEX SingerByName ON Singers(FirstName, LastName)`, `CREATE TABLE Accounts ( AccountId INT64 NOT NULL, Nickname STRING(100), Balance INT64 NOT NULL, ) PRIMARY KEY (AccountId)`, `CREATE INDEX AccountByNickname ON Accounts(Nickname) STORING (Balance)`, `CREATE TABLE Types ( RowID INT64 NOT NULL, String STRING(MAX), StringArray ARRAY, Bytes BYTES(MAX), BytesArray ARRAY, Int64a INT64, Int64Array ARRAY, Bool BOOL, BoolArray ARRAY, Float64 FLOAT64, Float64Array ARRAY, Date DATE, DateArray ARRAY, Timestamp TIMESTAMP, TimestampArray ARRAY, ) PRIMARY KEY (RowID)`, } readDBStatements = []string{ `CREATE TABLE TestTable ( Key STRING(MAX) NOT NULL, StringValue STRING(MAX) ) PRIMARY KEY (Key)`, `CREATE INDEX TestTableByValue ON TestTable(StringValue)`, `CREATE INDEX TestTableByValueDesc ON TestTable(StringValue DESC)`, } simpleDBStatements = []string{ `CREATE TABLE test ( a STRING(1024), b STRING(1024), ) PRIMARY KEY (a)`, } simpleDBTableColumns = []string{"a", "b"} ctsDBStatements = []string{ `CREATE TABLE TestTable ( Key STRING(MAX) NOT NULL, Ts TIMESTAMP OPTIONS (allow_commit_timestamp = true), ) PRIMARY KEY (Key)`, } ) const ( str1 = "alice" str2 = "a@example.com" ) func TestMain(m *testing.M) { cleanup := initIntegrationTests() res := m.Run() cleanup() os.Exit(res) } var grpcHeaderChecker = testutil.DefaultHeadersEnforcer() func initIntegrationTests() (cleanup func()) { ctx := context.Background() flag.Parse() // Needed for testing.Short(). noop := func() {} if testing.Short() { log.Println("Integration tests skipped in -short mode.") return noop } if testProjectID == "" { log.Println("Integration tests skipped: GCLOUD_TESTS_GOLANG_PROJECT_ID is missing") return noop } ts := testutil.TokenSource(ctx, AdminScope, Scope) if ts == nil { log.Printf("Integration test skipped: cannot get service account credential from environment variable %v", "GCLOUD_TESTS_GOLANG_KEY") return noop } var err error opts := append(grpcHeaderChecker.CallOptions(), option.WithTokenSource(ts), option.WithEndpoint(endpoint)) // Create InstanceAdmin and DatabaseAdmin clients. instanceAdmin, err = instance.NewInstanceAdminClient(ctx, opts...) if err != nil { log.Fatalf("cannot create instance databaseAdmin client: %v", err) } databaseAdmin, err = database.NewDatabaseAdminClient(ctx, opts...) if err != nil { log.Fatalf("cannot create databaseAdmin client: %v", err) } // Get the list of supported instance configs for the project that is used // for the integration tests. The supported instance configs can differ per // project. The integration tests will use the first instance config that // is returned by Cloud Spanner. This will normally be the regional config // that is physically the closest to where the request is coming from. configIterator := instanceAdmin.ListInstanceConfigs(ctx, &instancepb.ListInstanceConfigsRequest{ Parent: fmt.Sprintf("projects/%s", testProjectID), }) config, err := configIterator.Next() if err != nil { log.Fatalf("Cannot get any instance configurations.\nPlease make sure the Cloud Spanner API is enabled for the test project.\nGet error: %v", err) } // Create a test instance to use for this test run. op, err := instanceAdmin.CreateInstance(ctx, &instancepb.CreateInstanceRequest{ Parent: fmt.Sprintf("projects/%s", testProjectID), InstanceId: testInstanceID, Instance: &instancepb.Instance{ Config: config.Name, DisplayName: testInstanceID, NodeCount: 1, }, }) if err != nil { log.Fatalf("could not create instance with id %s: %v", fmt.Sprintf("projects/%s/instances/%s", testProjectID, testInstanceID), err) } // Wait for the instance creation to finish. i, err := op.Wait(ctx) if err != nil { log.Fatalf("waiting for instance creation to finish failed: %v", err) } if i.State != instancepb.Instance_READY { log.Printf("instance state is not READY, it might be that the test instance will cause problems during tests. Got state %v\n", i.State) } return func() { // Delete this test instance. instanceName := fmt.Sprintf("projects/%v/instances/%v", testProjectID, testInstanceID) if err = instanceAdmin.DeleteInstance(ctx, &instancepb.DeleteInstanceRequest{ Name: instanceName, }); err != nil { log.Printf("failed to drop instance %s (error %v), might need a manual removal", instanceName, err) } // Delete other test instances that may be lingering around. cleanupInstances() databaseAdmin.Close() instanceAdmin.Close() } } func TestIntegration_InitSessionPool(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() // Set up testing environment. client, _, cleanup := prepareIntegrationTest(ctx, t, DefaultSessionPoolConfig, singerDBStatements) defer cleanup() sp := client.idleSessions sp.mu.Lock() want := sp.MinOpened sp.mu.Unlock() var numOpened int for { select { case <-ctx.Done(): t.Fatalf("timed out, got %d session(s), want %d", numOpened, want) default: sp.mu.Lock() numOpened = sp.idleList.Len() + sp.idleWriteList.Len() sp.mu.Unlock() if uint64(numOpened) == want { return } } } } // Test SingleUse transaction. func TestIntegration_SingleUse(t *testing.T) { t.Parallel() ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() // Set up testing environment. client, _, cleanup := prepareIntegrationTest(ctx, t, DefaultSessionPoolConfig, singerDBStatements) defer cleanup() writes := []struct { row []interface{} ts time.Time }{ {row: []interface{}{1, "Marc", "Foo"}}, {row: []interface{}{2, "Tars", "Bar"}}, {row: []interface{}{3, "Alpha", "Beta"}}, {row: []interface{}{4, "Last", "End"}}, } // Try to write four rows through the Apply API. for i, w := range writes { var err error m := InsertOrUpdate("Singers", []string{"SingerId", "FirstName", "LastName"}, w.row) if writes[i].ts, err = client.Apply(ctx, []*Mutation{m}, ApplyAtLeastOnce()); err != nil { t.Fatal(err) } } // Calculate time difference between Cloud Spanner server and localhost to // use to determine the exact staleness value to use. timeDiff := maxDuration(time.Now().Sub(writes[0].ts), 0) // Test reading rows with different timestamp bounds. for i, test := range []struct { name string want [][]interface{} tb TimestampBound checkTs func(time.Time) error }{ { name: "strong", want: [][]interface{}{{int64(1), "Marc", "Foo"}, {int64(3), "Alpha", "Beta"}, {int64(4), "Last", "End"}}, tb: StrongRead(), checkTs: func(ts time.Time) error { // writes[3] is the last write, all subsequent strong read // should have a timestamp larger than that. if ts.Before(writes[3].ts) { return fmt.Errorf("read got timestamp %v, want it to be no later than %v", ts, writes[3].ts) } return nil }, }, { name: "min_read_timestamp", want: [][]interface{}{{int64(1), "Marc", "Foo"}, {int64(3), "Alpha", "Beta"}, {int64(4), "Last", "End"}}, tb: MinReadTimestamp(writes[3].ts), checkTs: func(ts time.Time) error { if ts.Before(writes[3].ts) { return fmt.Errorf("read got timestamp %v, want it to be no later than %v", ts, writes[3].ts) } return nil }, }, { name: "max_staleness", want: [][]interface{}{{int64(1), "Marc", "Foo"}, {int64(3), "Alpha", "Beta"}, {int64(4), "Last", "End"}}, tb: MaxStaleness(time.Second), checkTs: func(ts time.Time) error { if ts.Before(writes[3].ts) { return fmt.Errorf("read got timestamp %v, want it to be no later than %v", ts, writes[3].ts) } return nil }, }, { name: "read_timestamp", want: [][]interface{}{{int64(1), "Marc", "Foo"}, {int64(3), "Alpha", "Beta"}}, tb: ReadTimestamp(writes[2].ts), checkTs: func(ts time.Time) error { if ts != writes[2].ts { return fmt.Errorf("read got timestamp %v, want %v", ts, writes[2].ts) } return nil }, }, { name: "exact_staleness", want: nil, // Specify a staleness which should be already before this test. tb: ExactStaleness(time.Now().Sub(writes[0].ts) + timeDiff + 30*time.Second), checkTs: func(ts time.Time) error { if !ts.Before(writes[0].ts) { return fmt.Errorf("read got timestamp %v, want it to be earlier than %v", ts, writes[0].ts) } return nil }, }, } { t.Run(test.name, func(t *testing.T) { // SingleUse.Query su := client.Single().WithTimestampBound(test.tb) got, err := readAll(su.Query( ctx, Statement{ "SELECT SingerId, FirstName, LastName FROM Singers WHERE SingerId IN (@id1, @id3, @id4)", map[string]interface{}{"id1": int64(1), "id3": int64(3), "id4": int64(4)}, })) if err != nil { t.Fatalf("%d: SingleUse.Query returns error %v, want nil", i, err) } rts, err := su.Timestamp() if err != nil { t.Fatalf("%d: SingleUse.Query doesn't return a timestamp, error: %v", i, err) } if err := test.checkTs(rts); err != nil { t.Fatalf("%d: SingleUse.Query doesn't return expected timestamp: %v", i, err) } if !testEqual(got, test.want) { t.Fatalf("%d: got unexpected result from SingleUse.Query: %v, want %v", i, got, test.want) } // SingleUse.Read su = client.Single().WithTimestampBound(test.tb) got, err = readAll(su.Read(ctx, "Singers", KeySets(Key{1}, Key{3}, Key{4}), []string{"SingerId", "FirstName", "LastName"})) if err != nil { t.Fatalf("%d: SingleUse.Read returns error %v, want nil", i, err) } rts, err = su.Timestamp() if err != nil { t.Fatalf("%d: SingleUse.Read doesn't return a timestamp, error: %v", i, err) } if err := test.checkTs(rts); err != nil { t.Fatalf("%d: SingleUse.Read doesn't return expected timestamp: %v", i, err) } if !testEqual(got, test.want) { t.Fatalf("%d: got unexpected result from SingleUse.Read: %v, want %v", i, got, test.want) } // SingleUse.ReadRow got = nil for _, k := range []Key{{1}, {3}, {4}} { su = client.Single().WithTimestampBound(test.tb) r, err := su.ReadRow(ctx, "Singers", k, []string{"SingerId", "FirstName", "LastName"}) if err != nil { continue } v, err := rowToValues(r) if err != nil { continue } got = append(got, v) rts, err = su.Timestamp() if err != nil { t.Fatalf("%d: SingleUse.ReadRow(%v) doesn't return a timestamp, error: %v", i, k, err) } if err := test.checkTs(rts); err != nil { t.Fatalf("%d: SingleUse.ReadRow(%v) doesn't return expected timestamp: %v", i, k, err) } } if !testEqual(got, test.want) { t.Fatalf("%d: got unexpected results from SingleUse.ReadRow: %v, want %v", i, got, test.want) } // SingleUse.ReadUsingIndex su = client.Single().WithTimestampBound(test.tb) got, err = readAll(su.ReadUsingIndex(ctx, "Singers", "SingerByName", KeySets(Key{"Marc", "Foo"}, Key{"Alpha", "Beta"}, Key{"Last", "End"}), []string{"SingerId", "FirstName", "LastName"})) if err != nil { t.Fatalf("%d: SingleUse.ReadUsingIndex returns error %v, want nil", i, err) } // The results from ReadUsingIndex is sorted by the index rather than primary key. if len(got) != len(test.want) { t.Fatalf("%d: got unexpected result from SingleUse.ReadUsingIndex: %v, want %v", i, got, test.want) } for j, g := range got { if j > 0 { prev := got[j-1][1].(string) + got[j-1][2].(string) curr := got[j][1].(string) + got[j][2].(string) if strings.Compare(prev, curr) > 0 { t.Fatalf("%d: SingleUse.ReadUsingIndex fails to order rows by index keys, %v should be after %v", i, got[j-1], got[j]) } } found := false for _, w := range test.want { if testEqual(g, w) { found = true } } if !found { t.Fatalf("%d: got unexpected result from SingleUse.ReadUsingIndex: %v, want %v", i, got, test.want) break } } rts, err = su.Timestamp() if err != nil { t.Fatalf("%d: SingleUse.ReadUsingIndex doesn't return a timestamp, error: %v", i, err) } if err := test.checkTs(rts); err != nil { t.Fatalf("%d: SingleUse.ReadUsingIndex doesn't return expected timestamp: %v", i, err) } }) } } func TestIntegration_SingleUse_ReadingWithLimit(t *testing.T) { t.Parallel() ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() // Set up testing environment. client, _, cleanup := prepareIntegrationTest(ctx, t, DefaultSessionPoolConfig, singerDBStatements) defer cleanup() writes := []struct { row []interface{} ts time.Time }{ {row: []interface{}{1, "Marc", "Foo"}}, {row: []interface{}{2, "Tars", "Bar"}}, {row: []interface{}{3, "Alpha", "Beta"}}, {row: []interface{}{4, "Last", "End"}}, } // Try to write four rows through the Apply API. for i, w := range writes { var err error m := InsertOrUpdate("Singers", []string{"SingerId", "FirstName", "LastName"}, w.row) if writes[i].ts, err = client.Apply(ctx, []*Mutation{m}, ApplyAtLeastOnce()); err != nil { t.Fatal(err) } } su := client.Single() const limit = 1 gotRows, err := readAll(su.ReadWithOptions(ctx, "Singers", KeySets(Key{1}, Key{3}, Key{4}), []string{"SingerId", "FirstName", "LastName"}, &ReadOptions{Limit: limit})) if err != nil { t.Errorf("SingleUse.ReadWithOptions returns error %v, want nil", err) } if got, want := len(gotRows), limit; got != want { t.Errorf("got %d, want %d", got, want) } } // Test ReadOnlyTransaction. The testsuite is mostly like SingleUse, except it // also tests for a single timestamp across multiple reads. func TestIntegration_ReadOnlyTransaction(t *testing.T) { t.Parallel() ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() // Set up testing environment. client, _, cleanup := prepareIntegrationTest(ctx, t, DefaultSessionPoolConfig, singerDBStatements) defer cleanup() writes := []struct { row []interface{} ts time.Time }{ {row: []interface{}{1, "Marc", "Foo"}}, {row: []interface{}{2, "Tars", "Bar"}}, {row: []interface{}{3, "Alpha", "Beta"}}, {row: []interface{}{4, "Last", "End"}}, } // Try to write four rows through the Apply API. for i, w := range writes { var err error m := InsertOrUpdate("Singers", []string{"SingerId", "FirstName", "LastName"}, w.row) if writes[i].ts, err = client.Apply(ctx, []*Mutation{m}, ApplyAtLeastOnce()); err != nil { t.Fatal(err) } } // For testing timestamp bound staleness. <-time.After(time.Second) // Test reading rows with different timestamp bounds. for i, test := range []struct { want [][]interface{} tb TimestampBound checkTs func(time.Time) error }{ // Note: min_read_timestamp and max_staleness are not supported by // ReadOnlyTransaction. See API document for more details. { // strong [][]interface{}{{int64(1), "Marc", "Foo"}, {int64(3), "Alpha", "Beta"}, {int64(4), "Last", "End"}}, StrongRead(), func(ts time.Time) error { if ts.Before(writes[3].ts) { return fmt.Errorf("read got timestamp %v, want it to be no later than %v", ts, writes[3].ts) } return nil }, }, { // read_timestamp [][]interface{}{{int64(1), "Marc", "Foo"}, {int64(3), "Alpha", "Beta"}}, ReadTimestamp(writes[2].ts), func(ts time.Time) error { if ts != writes[2].ts { return fmt.Errorf("read got timestamp %v, expect %v", ts, writes[2].ts) } return nil }, }, { // exact_staleness nil, // Specify a staleness which should be already before this test // because context timeout is set to be 10s. ExactStaleness(11 * time.Second), func(ts time.Time) error { if ts.After(writes[0].ts) { return fmt.Errorf("read got timestamp %v, want it to be no earlier than %v", ts, writes[0].ts) } return nil }, }, } { // ReadOnlyTransaction.Query ro := client.ReadOnlyTransaction().WithTimestampBound(test.tb) got, err := readAll(ro.Query( ctx, Statement{ "SELECT SingerId, FirstName, LastName FROM Singers WHERE SingerId IN (@id1, @id3, @id4)", map[string]interface{}{"id1": int64(1), "id3": int64(3), "id4": int64(4)}, })) if err != nil { t.Errorf("%d: ReadOnlyTransaction.Query returns error %v, want nil", i, err) } if !testEqual(got, test.want) { t.Errorf("%d: got unexpected result from ReadOnlyTransaction.Query: %v, want %v", i, got, test.want) } rts, err := ro.Timestamp() if err != nil { t.Errorf("%d: ReadOnlyTransaction.Query doesn't return a timestamp, error: %v", i, err) } if err := test.checkTs(rts); err != nil { t.Errorf("%d: ReadOnlyTransaction.Query doesn't return expected timestamp: %v", i, err) } roTs := rts // ReadOnlyTransaction.Read got, err = readAll(ro.Read(ctx, "Singers", KeySets(Key{1}, Key{3}, Key{4}), []string{"SingerId", "FirstName", "LastName"})) if err != nil { t.Errorf("%d: ReadOnlyTransaction.Read returns error %v, want nil", i, err) } if !testEqual(got, test.want) { t.Errorf("%d: got unexpected result from ReadOnlyTransaction.Read: %v, want %v", i, got, test.want) } rts, err = ro.Timestamp() if err != nil { t.Errorf("%d: ReadOnlyTransaction.Read doesn't return a timestamp, error: %v", i, err) } if err := test.checkTs(rts); err != nil { t.Errorf("%d: ReadOnlyTransaction.Read doesn't return expected timestamp: %v", i, err) } if roTs != rts { t.Errorf("%d: got two read timestamps: %v, %v, want ReadOnlyTransaction to return always the same read timestamp", i, roTs, rts) } // ReadOnlyTransaction.ReadRow got = nil for _, k := range []Key{{1}, {3}, {4}} { r, err := ro.ReadRow(ctx, "Singers", k, []string{"SingerId", "FirstName", "LastName"}) if err != nil { continue } v, err := rowToValues(r) if err != nil { continue } got = append(got, v) rts, err = ro.Timestamp() if err != nil { t.Errorf("%d: ReadOnlyTransaction.ReadRow(%v) doesn't return a timestamp, error: %v", i, k, err) } if err := test.checkTs(rts); err != nil { t.Errorf("%d: ReadOnlyTransaction.ReadRow(%v) doesn't return expected timestamp: %v", i, k, err) } if roTs != rts { t.Errorf("%d: got two read timestamps: %v, %v, want ReadOnlyTransaction to return always the same read timestamp", i, roTs, rts) } } if !testEqual(got, test.want) { t.Errorf("%d: got unexpected results from ReadOnlyTransaction.ReadRow: %v, want %v", i, got, test.want) } // SingleUse.ReadUsingIndex got, err = readAll(ro.ReadUsingIndex(ctx, "Singers", "SingerByName", KeySets(Key{"Marc", "Foo"}, Key{"Alpha", "Beta"}, Key{"Last", "End"}), []string{"SingerId", "FirstName", "LastName"})) if err != nil { t.Errorf("%d: ReadOnlyTransaction.ReadUsingIndex returns error %v, want nil", i, err) } // The results from ReadUsingIndex is sorted by the index rather than // primary key. if len(got) != len(test.want) { t.Errorf("%d: got unexpected result from ReadOnlyTransaction.ReadUsingIndex: %v, want %v", i, got, test.want) } for j, g := range got { if j > 0 { prev := got[j-1][1].(string) + got[j-1][2].(string) curr := got[j][1].(string) + got[j][2].(string) if strings.Compare(prev, curr) > 0 { t.Errorf("%d: ReadOnlyTransaction.ReadUsingIndex fails to order rows by index keys, %v should be after %v", i, got[j-1], got[j]) } } found := false for _, w := range test.want { if testEqual(g, w) { found = true } } if !found { t.Errorf("%d: got unexpected result from ReadOnlyTransaction.ReadUsingIndex: %v, want %v", i, got, test.want) break } } rts, err = ro.Timestamp() if err != nil { t.Errorf("%d: ReadOnlyTransaction.ReadUsingIndex doesn't return a timestamp, error: %v", i, err) } if err := test.checkTs(rts); err != nil { t.Errorf("%d: ReadOnlyTransaction.ReadUsingIndex doesn't return expected timestamp: %v", i, err) } if roTs != rts { t.Errorf("%d: got two read timestamps: %v, %v, want ReadOnlyTransaction to return always the same read timestamp", i, roTs, rts) } ro.Close() } } // Test ReadOnlyTransaction with different timestamp bound when there's an // update at the same time. func TestIntegration_UpdateDuringRead(t *testing.T) { t.Parallel() ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() client, _, cleanup := prepareIntegrationTest(ctx, t, DefaultSessionPoolConfig, singerDBStatements) defer cleanup() for i, tb := range []TimestampBound{ StrongRead(), ReadTimestamp(time.Now().Add(-time.Minute * 30)), // version GC is 1 hour ExactStaleness(time.Minute * 30), } { ro := client.ReadOnlyTransaction().WithTimestampBound(tb) _, err := ro.ReadRow(ctx, "Singers", Key{i}, []string{"SingerId"}) if ErrCode(err) != codes.NotFound { t.Errorf("%d: ReadOnlyTransaction.ReadRow before write returns error: %v, want NotFound", i, err) } m := InsertOrUpdate("Singers", []string{"SingerId"}, []interface{}{i}) if _, err := client.Apply(ctx, []*Mutation{m}, ApplyAtLeastOnce()); err != nil { t.Fatal(err) } _, err = ro.ReadRow(ctx, "Singers", Key{i}, []string{"SingerId"}) if ErrCode(err) != codes.NotFound { t.Errorf("%d: ReadOnlyTransaction.ReadRow after write returns error: %v, want NotFound", i, err) } } } // Test ReadWriteTransaction. func TestIntegration_ReadWriteTransaction(t *testing.T) { t.Parallel() // Give a longer deadline because of transaction backoffs. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() client, _, cleanup := prepareIntegrationTest(ctx, t, DefaultSessionPoolConfig, singerDBStatements) defer cleanup() // Set up two accounts accounts := []*Mutation{ Insert("Accounts", []string{"AccountId", "Nickname", "Balance"}, []interface{}{int64(1), "Foo", int64(50)}), Insert("Accounts", []string{"AccountId", "Nickname", "Balance"}, []interface{}{int64(2), "Bar", int64(1)}), } if _, err := client.Apply(ctx, accounts, ApplyAtLeastOnce()); err != nil { t.Fatal(err) } wg := sync.WaitGroup{} readBalance := func(iter *RowIterator) (int64, error) { defer iter.Stop() var bal int64 for { row, err := iter.Next() if err == iterator.Done { return bal, nil } if err != nil { return 0, err } if err := row.Column(0, &bal); err != nil { return 0, err } } } for i := 0; i < 20; i++ { wg.Add(1) go func(iter int) { defer wg.Done() _, err := client.ReadWriteTransaction(ctx, func(ctx context.Context, tx *ReadWriteTransaction) error { // Query Foo's balance and Bar's balance. bf, e := readBalance(tx.Query(ctx, Statement{"SELECT Balance FROM Accounts WHERE AccountId = @id", map[string]interface{}{"id": int64(1)}})) if e != nil { return e } bb, e := readBalance(tx.Read(ctx, "Accounts", KeySets(Key{int64(2)}), []string{"Balance"})) if e != nil { return e } if bf <= 0 { return nil } bf-- bb++ return tx.BufferWrite([]*Mutation{ Update("Accounts", []string{"AccountId", "Balance"}, []interface{}{int64(1), bf}), Update("Accounts", []string{"AccountId", "Balance"}, []interface{}{int64(2), bb}), }) }) if err != nil { t.Errorf("%d: failed to execute transaction: %v", iter, err) } }(i) } // Because of context timeout, all goroutines will eventually return. wg.Wait() _, err := client.ReadWriteTransaction(ctx, func(ctx context.Context, tx *ReadWriteTransaction) error { var bf, bb int64 r, e := tx.ReadRow(ctx, "Accounts", Key{int64(1)}, []string{"Balance"}) if e != nil { return e } if ce := r.Column(0, &bf); ce != nil { return ce } bb, e = readBalance(tx.ReadUsingIndex(ctx, "Accounts", "AccountByNickname", KeySets(Key{"Bar"}), []string{"Balance"})) if e != nil { return e } if bf != 30 || bb != 21 { t.Errorf("Foo's balance is now %v and Bar's balance is now %v, want %v and %v", bf, bb, 30, 21) } return nil }) if err != nil { t.Errorf("failed to check balances: %v", err) } } func TestIntegration_Reads(t *testing.T) { t.Parallel() ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() // Set up testing environment. client, _, cleanup := prepareIntegrationTest(ctx, t, DefaultSessionPoolConfig, readDBStatements) defer cleanup() // Includes k0..k14. Strings sort lexically, eg "k1" < "k10" < "k2". var ms []*Mutation for i := 0; i < 15; i++ { ms = append(ms, InsertOrUpdate(testTable, testTableColumns, []interface{}{fmt.Sprintf("k%d", i), fmt.Sprintf("v%d", i)})) } // Don't use ApplyAtLeastOnce, so we can test the other code path. if _, err := client.Apply(ctx, ms); err != nil { t.Fatal(err) } // Empty read. rows, err := readAllTestTable(client.Single().Read(ctx, testTable, KeyRange{Start: Key{"k99"}, End: Key{"z"}}, testTableColumns)) if err != nil { t.Fatal(err) } if got, want := len(rows), 0; got != want { t.Errorf("got %d, want %d", got, want) } // Index empty read. rows, err = readAllTestTable(client.Single().ReadUsingIndex(ctx, testTable, testTableIndex, KeyRange{Start: Key{"v99"}, End: Key{"z"}}, testTableColumns)) if err != nil { t.Fatal(err) } if got, want := len(rows), 0; got != want { t.Errorf("got %d, want %d", got, want) } // Point read. row, err := client.Single().ReadRow(ctx, testTable, Key{"k1"}, testTableColumns) if err != nil { t.Fatal(err) } var got testTableRow if err := row.ToStruct(&got); err != nil { t.Fatal(err) } if want := (testTableRow{"k1", "v1"}); got != want { t.Errorf("got %v, want %v", got, want) } // Point read not found. _, err = client.Single().ReadRow(ctx, testTable, Key{"k999"}, testTableColumns) if ErrCode(err) != codes.NotFound { t.Fatalf("got %v, want NotFound", err) } // No index point read not found, because Go does not have ReadRowUsingIndex. rangeReads(ctx, t, client) indexRangeReads(ctx, t, client) } func TestIntegration_EarlyTimestamp(t *testing.T) { t.Parallel() // Test that we can get the timestamp from a read-only transaction as // soon as we have read at least one row. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() // Set up testing environment. client, _, cleanup := prepareIntegrationTest(ctx, t, DefaultSessionPoolConfig, readDBStatements) defer cleanup() var ms []*Mutation for i := 0; i < 3; i++ { ms = append(ms, InsertOrUpdate(testTable, testTableColumns, []interface{}{fmt.Sprintf("k%d", i), fmt.Sprintf("v%d", i)})) } if _, err := client.Apply(ctx, ms, ApplyAtLeastOnce()); err != nil { t.Fatal(err) } txn := client.Single() iter := txn.Read(ctx, testTable, AllKeys(), testTableColumns) defer iter.Stop() // In single-use transaction, we should get an error before reading anything. if _, err := txn.Timestamp(); err == nil { t.Error("wanted error, got nil") } // After reading one row, the timestamp should be available. _, err := iter.Next() if err != nil { t.Fatal(err) } if _, err := txn.Timestamp(); err != nil { t.Errorf("got %v, want nil", err) } txn = client.ReadOnlyTransaction() defer txn.Close() iter = txn.Read(ctx, testTable, AllKeys(), testTableColumns) defer iter.Stop() // In an ordinary read-only transaction, the timestamp should be // available immediately. if _, err := txn.Timestamp(); err != nil { t.Errorf("got %v, want nil", err) } } func TestIntegration_NestedTransaction(t *testing.T) { t.Parallel() // You cannot use a transaction from inside a read-write transaction. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() client, _, cleanup := prepareIntegrationTest(ctx, t, DefaultSessionPoolConfig, singerDBStatements) defer cleanup() _, err := client.ReadWriteTransaction(ctx, func(ctx context.Context, tx *ReadWriteTransaction) error { _, err := client.ReadWriteTransaction(ctx, func(context.Context, *ReadWriteTransaction) error { return nil }) if ErrCode(err) != codes.FailedPrecondition { t.Fatalf("got %v, want FailedPrecondition", err) } _, err = client.Single().ReadRow(ctx, "Singers", Key{1}, []string{"SingerId"}) if ErrCode(err) != codes.FailedPrecondition { t.Fatalf("got %v, want FailedPrecondition", err) } rot := client.ReadOnlyTransaction() defer rot.Close() _, err = rot.ReadRow(ctx, "Singers", Key{1}, []string{"SingerId"}) if ErrCode(err) != codes.FailedPrecondition { t.Fatalf("got %v, want FailedPrecondition", err) } return nil }) if err != nil { t.Fatal(err) } } // Test client recovery on database recreation. func TestIntegration_DbRemovalRecovery(t *testing.T) { t.Parallel() ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() // Create a client with MinOpened=0 to prevent the session pool maintainer // from repeatedly trying to create sessions for the invalid database. client, dbPath, cleanup := prepareIntegrationTest(ctx, t, SessionPoolConfig{}, singerDBStatements) defer cleanup() // Drop the testing database. if err := databaseAdmin.DropDatabase(ctx, &adminpb.DropDatabaseRequest{Database: dbPath}); err != nil { t.Fatalf("failed to drop testing database %v: %v", dbPath, err) } // Now, send the query. iter := client.Single().Query(ctx, Statement{SQL: "SELECT SingerId FROM Singers"}) defer iter.Stop() if _, err := iter.Next(); err == nil { t.Errorf("client sends query to removed database successfully, want it to fail") } // Recreate database and table. dbName := dbPath[strings.LastIndex(dbPath, "/")+1:] op, err := databaseAdmin.CreateDatabase(ctx, &adminpb.CreateDatabaseRequest{ Parent: fmt.Sprintf("projects/%v/instances/%v", testProjectID, testInstanceID), CreateStatement: "CREATE DATABASE " + dbName, ExtraStatements: []string{ `CREATE TABLE Singers ( SingerId INT64 NOT NULL, FirstName STRING(1024), LastName STRING(1024), SingerInfo BYTES(MAX) ) PRIMARY KEY (SingerId)`, }, }) if err != nil { t.Fatalf("cannot recreate testing DB %v: %v", dbPath, err) } if _, err := op.Wait(ctx); err != nil { t.Fatalf("cannot recreate testing DB %v: %v", dbPath, err) } // Now, send the query again. iter = client.Single().Query(ctx, Statement{SQL: "SELECT SingerId FROM Singers"}) defer iter.Stop() _, err = iter.Next() if err != nil && err != iterator.Done { t.Errorf("failed to send query to database %v: %v", dbPath, err) } } // Test encoding/decoding non-struct Cloud Spanner types. func TestIntegration_BasicTypes(t *testing.T) { t.Parallel() ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() client, _, cleanup := prepareIntegrationTest(ctx, t, DefaultSessionPoolConfig, singerDBStatements) defer cleanup() t1, _ := time.Parse(time.RFC3339Nano, "2016-11-15T15:04:05.999999999Z") // Boundaries t2, _ := time.Parse(time.RFC3339Nano, "0001-01-01T00:00:00.000000000Z") t3, _ := time.Parse(time.RFC3339Nano, "9999-12-31T23:59:59.999999999Z") d1, _ := civil.ParseDate("2016-11-15") // Boundaries d2, _ := civil.ParseDate("0001-01-01") d3, _ := civil.ParseDate("9999-12-31") tests := []struct { col string val interface{} want interface{} }{ {col: "String", val: ""}, {col: "String", val: "", want: NullString{"", true}}, {col: "String", val: "foo"}, {col: "String", val: "foo", want: NullString{"foo", true}}, {col: "String", val: NullString{"bar", true}, want: "bar"}, {col: "String", val: NullString{"bar", false}, want: NullString{"", false}}, {col: "String", val: nil, want: NullString{}}, {col: "StringArray", val: []string(nil), want: []NullString(nil)}, {col: "StringArray", val: []string{}, want: []NullString{}}, {col: "StringArray", val: []string{"foo", "bar"}, want: []NullString{{"foo", true}, {"bar", true}}}, {col: "StringArray", val: []NullString(nil)}, {col: "StringArray", val: []NullString{}}, {col: "StringArray", val: []NullString{{"foo", true}, {}}}, {col: "Bytes", val: []byte{}}, {col: "Bytes", val: []byte{1, 2, 3}}, {col: "Bytes", val: []byte(nil)}, {col: "BytesArray", val: [][]byte(nil)}, {col: "BytesArray", val: [][]byte{}}, {col: "BytesArray", val: [][]byte{{1}, {2, 3}}}, {col: "Int64a", val: 0, want: int64(0)}, {col: "Int64a", val: -1, want: int64(-1)}, {col: "Int64a", val: 2, want: int64(2)}, {col: "Int64a", val: int64(3)}, {col: "Int64a", val: 4, want: NullInt64{4, true}}, {col: "Int64a", val: NullInt64{5, true}, want: int64(5)}, {col: "Int64a", val: NullInt64{6, true}, want: int64(6)}, {col: "Int64a", val: NullInt64{7, false}, want: NullInt64{0, false}}, {col: "Int64a", val: nil, want: NullInt64{}}, {col: "Int64Array", val: []int(nil), want: []NullInt64(nil)}, {col: "Int64Array", val: []int{}, want: []NullInt64{}}, {col: "Int64Array", val: []int{1, 2}, want: []NullInt64{{1, true}, {2, true}}}, {col: "Int64Array", val: []int64(nil), want: []NullInt64(nil)}, {col: "Int64Array", val: []int64{}, want: []NullInt64{}}, {col: "Int64Array", val: []int64{1, 2}, want: []NullInt64{{1, true}, {2, true}}}, {col: "Int64Array", val: []NullInt64(nil)}, {col: "Int64Array", val: []NullInt64{}}, {col: "Int64Array", val: []NullInt64{{1, true}, {}}}, {col: "Bool", val: false}, {col: "Bool", val: true}, {col: "Bool", val: false, want: NullBool{false, true}}, {col: "Bool", val: true, want: NullBool{true, true}}, {col: "Bool", val: NullBool{true, true}}, {col: "Bool", val: NullBool{false, false}}, {col: "Bool", val: nil, want: NullBool{}}, {col: "BoolArray", val: []bool(nil), want: []NullBool(nil)}, {col: "BoolArray", val: []bool{}, want: []NullBool{}}, {col: "BoolArray", val: []bool{true, false}, want: []NullBool{{true, true}, {false, true}}}, {col: "BoolArray", val: []NullBool(nil)}, {col: "BoolArray", val: []NullBool{}}, {col: "BoolArray", val: []NullBool{{false, true}, {true, true}, {}}}, {col: "Float64", val: 0.0}, {col: "Float64", val: 3.14}, {col: "Float64", val: math.NaN()}, {col: "Float64", val: math.Inf(1)}, {col: "Float64", val: math.Inf(-1)}, {col: "Float64", val: 2.78, want: NullFloat64{2.78, true}}, {col: "Float64", val: NullFloat64{2.71, true}, want: 2.71}, {col: "Float64", val: NullFloat64{1.41, true}, want: NullFloat64{1.41, true}}, {col: "Float64", val: NullFloat64{0, false}}, {col: "Float64", val: nil, want: NullFloat64{}}, {col: "Float64Array", val: []float64(nil), want: []NullFloat64(nil)}, {col: "Float64Array", val: []float64{}, want: []NullFloat64{}}, {col: "Float64Array", val: []float64{2.72, 3.14, math.Inf(1)}, want: []NullFloat64{{2.72, true}, {3.14, true}, {math.Inf(1), true}}}, {col: "Float64Array", val: []NullFloat64(nil)}, {col: "Float64Array", val: []NullFloat64{}}, {col: "Float64Array", val: []NullFloat64{{2.72, true}, {math.Inf(1), true}, {}}}, {col: "Date", val: d1}, {col: "Date", val: d1, want: NullDate{d1, true}}, {col: "Date", val: NullDate{d1, true}}, {col: "Date", val: NullDate{d1, true}, want: d1}, {col: "Date", val: NullDate{civil.Date{}, false}}, {col: "DateArray", val: []civil.Date(nil), want: []NullDate(nil)}, {col: "DateArray", val: []civil.Date{}, want: []NullDate{}}, {col: "DateArray", val: []civil.Date{d1, d2, d3}, want: []NullDate{{d1, true}, {d2, true}, {d3, true}}}, {col: "Timestamp", val: t1}, {col: "Timestamp", val: t1, want: NullTime{t1, true}}, {col: "Timestamp", val: NullTime{t1, true}}, {col: "Timestamp", val: NullTime{t1, true}, want: t1}, {col: "Timestamp", val: NullTime{}}, {col: "Timestamp", val: nil, want: NullTime{}}, {col: "TimestampArray", val: []time.Time(nil), want: []NullTime(nil)}, {col: "TimestampArray", val: []time.Time{}, want: []NullTime{}}, {col: "TimestampArray", val: []time.Time{t1, t2, t3}, want: []NullTime{{t1, true}, {t2, true}, {t3, true}}}, } // Write rows into table first. var muts []*Mutation for i, test := range tests { muts = append(muts, InsertOrUpdate("Types", []string{"RowID", test.col}, []interface{}{i, test.val})) } if _, err := client.Apply(ctx, muts, ApplyAtLeastOnce()); err != nil { t.Fatal(err) } for i, test := range tests { row, err := client.Single().ReadRow(ctx, "Types", []interface{}{i}, []string{test.col}) if err != nil { t.Fatalf("Unable to fetch row %v: %v", i, err) } // Create new instance of type of test.want. want := test.want if want == nil { want = test.val } gotp := reflect.New(reflect.TypeOf(want)) if err := row.Column(0, gotp.Interface()); err != nil { t.Errorf("%d: col:%v val:%#v, %v", i, test.col, test.val, err) continue } got := reflect.Indirect(gotp).Interface() // One of the test cases is checking NaN handling. Given // NaN!=NaN, we can't use reflect to test for it. if isNaN(got) && isNaN(want) { continue } // Check non-NaN cases. if !testEqual(got, want) { t.Errorf("%d: col:%v val:%#v, got %#v, want %#v", i, test.col, test.val, got, want) continue } } } // Test decoding Cloud Spanner STRUCT type. func TestIntegration_StructTypes(t *testing.T) { t.Parallel() ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() client, _, cleanup := prepareIntegrationTest(ctx, t, DefaultSessionPoolConfig, singerDBStatements) defer cleanup() tests := []struct { q Statement want func(r *Row) error }{ { q: Statement{SQL: `SELECT ARRAY(SELECT STRUCT(1, 2))`}, want: func(r *Row) error { // Test STRUCT ARRAY decoding to []NullRow. var rows []NullRow if err := r.Column(0, &rows); err != nil { return err } if len(rows) != 1 { return fmt.Errorf("len(rows) = %d; want 1", len(rows)) } if !rows[0].Valid { return fmt.Errorf("rows[0] is NULL") } var i, j int64 if err := rows[0].Row.Columns(&i, &j); err != nil { return err } if i != 1 || j != 2 { return fmt.Errorf("got (%d,%d), want (1,2)", i, j) } return nil }, }, { q: Statement{SQL: `SELECT ARRAY(SELECT STRUCT(1 as foo, 2 as bar)) as col1`}, want: func(r *Row) error { // Test Row.ToStruct. s := struct { Col1 []*struct { Foo int64 `spanner:"foo"` Bar int64 `spanner:"bar"` } `spanner:"col1"` }{} if err := r.ToStruct(&s); err != nil { return err } want := struct { Col1 []*struct { Foo int64 `spanner:"foo"` Bar int64 `spanner:"bar"` } `spanner:"col1"` }{ Col1: []*struct { Foo int64 `spanner:"foo"` Bar int64 `spanner:"bar"` }{ { Foo: 1, Bar: 2, }, }, } if !testEqual(want, s) { return fmt.Errorf("unexpected decoding result: %v, want %v", s, want) } return nil }, }, } for i, test := range tests { iter := client.Single().Query(ctx, test.q) defer iter.Stop() row, err := iter.Next() if err != nil { t.Errorf("%d: %v", i, err) continue } if err := test.want(row); err != nil { t.Errorf("%d: %v", i, err) continue } } } func TestIntegration_StructParametersUnsupported(t *testing.T) { t.Parallel() ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() client, _, cleanup := prepareIntegrationTest(ctx, t, DefaultSessionPoolConfig, nil) defer cleanup() for _, test := range []struct { param interface{} wantCode codes.Code wantMsgPart string }{ { struct { Field int }{10}, codes.Unimplemented, "Unsupported query shape: " + "A struct value cannot be returned as a column value. " + "Rewrite the query to flatten the struct fields in the result.", }, { []struct { Field int }{{10}, {20}}, codes.Unimplemented, "Unsupported query shape: " + "This query can return a null-valued array of struct, " + "which is not supported by Spanner.", }, } { iter := client.Single().Query(ctx, Statement{ SQL: "SELECT @p", Params: map[string]interface{}{"p": test.param}, }) _, err := iter.Next() iter.Stop() if msg, ok := matchError(err, test.wantCode, test.wantMsgPart); !ok { t.Fatal(msg) } } } // Test queries of the form "SELECT expr". func TestIntegration_QueryExpressions(t *testing.T) { t.Parallel() ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() client, _, cleanup := prepareIntegrationTest(ctx, t, DefaultSessionPoolConfig, nil) defer cleanup() newRow := func(vals []interface{}) *Row { row, err := NewRow(make([]string, len(vals)), vals) if err != nil { t.Fatal(err) } return row } tests := []struct { expr string want interface{} }{ {"1", int64(1)}, {"[1, 2, 3]", []NullInt64{{1, true}, {2, true}, {3, true}}}, {"[1, NULL, 3]", []NullInt64{{1, true}, {0, false}, {3, true}}}, {"IEEE_DIVIDE(1, 0)", math.Inf(1)}, {"IEEE_DIVIDE(-1, 0)", math.Inf(-1)}, {"IEEE_DIVIDE(0, 0)", math.NaN()}, // TODO(jba): add IEEE_DIVIDE(0, 0) to the following array when we have a better equality predicate. {"[IEEE_DIVIDE(1, 0), IEEE_DIVIDE(-1, 0)]", []NullFloat64{{math.Inf(1), true}, {math.Inf(-1), true}}}, {"ARRAY(SELECT AS STRUCT * FROM (SELECT 'a', 1) WHERE 0 = 1)", []NullRow{}}, {"ARRAY(SELECT STRUCT(1, 2))", []NullRow{{Row: *newRow([]interface{}{1, 2}), Valid: true}}}, } for _, test := range tests { iter := client.Single().Query(ctx, Statement{SQL: "SELECT " + test.expr}) defer iter.Stop() row, err := iter.Next() if err != nil { t.Errorf("%q: %v", test.expr, err) continue } // Create new instance of type of test.want. gotp := reflect.New(reflect.TypeOf(test.want)) if err := row.Column(0, gotp.Interface()); err != nil { t.Errorf("%q: Column returned error %v", test.expr, err) continue } got := reflect.Indirect(gotp).Interface() // TODO(jba): remove isNaN special case when we have a better equality predicate. if isNaN(got) && isNaN(test.want) { continue } if !testEqual(got, test.want) { t.Errorf("%q\n got %#v\nwant %#v", test.expr, got, test.want) } } } func TestIntegration_QueryStats(t *testing.T) { t.Parallel() ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() client, _, cleanup := prepareIntegrationTest(ctx, t, DefaultSessionPoolConfig, singerDBStatements) defer cleanup() accounts := []*Mutation{ Insert("Accounts", []string{"AccountId", "Nickname", "Balance"}, []interface{}{int64(1), "Foo", int64(50)}), Insert("Accounts", []string{"AccountId", "Nickname", "Balance"}, []interface{}{int64(2), "Bar", int64(1)}), } if _, err := client.Apply(ctx, accounts, ApplyAtLeastOnce()); err != nil { t.Fatal(err) } const sql = "SELECT Balance FROM Accounts" qp, err := client.Single().AnalyzeQuery(ctx, Statement{sql, nil}) if err != nil { t.Fatal(err) } if len(qp.PlanNodes) == 0 { t.Error("got zero plan nodes, expected at least one") } iter := client.Single().QueryWithStats(ctx, Statement{sql, nil}) defer iter.Stop() for { _, err := iter.Next() if err == iterator.Done { break } if err != nil { t.Fatal(err) } } if iter.QueryPlan == nil { t.Error("got nil QueryPlan, expected one") } if iter.QueryStats == nil { t.Error("got nil QueryStats, expected some") } } func TestIntegration_InvalidDatabase(t *testing.T) { t.Parallel() if databaseAdmin == nil { t.Skip("Integration tests skipped") } ctx := context.Background() dbPath := fmt.Sprintf("projects/%v/instances/%v/databases/invalid", testProjectID, testInstanceID) c, err := createClient(ctx, dbPath, SessionPoolConfig{}) // Client creation should succeed even if the database is invalid. if err != nil { t.Fatal(err) } _, err = c.Single().ReadRow(ctx, "TestTable", Key{1}, []string{"col1"}) if msg, ok := matchError(err, codes.NotFound, ""); !ok { t.Fatal(msg) } } func TestIntegration_ReadErrors(t *testing.T) { t.Parallel() ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() client, _, cleanup := prepareIntegrationTest(ctx, t, DefaultSessionPoolConfig, readDBStatements) defer cleanup() // Read over invalid table fails _, err := client.Single().ReadRow(ctx, "badTable", Key{1}, []string{"StringValue"}) if msg, ok := matchError(err, codes.NotFound, "badTable"); !ok { t.Error(msg) } // Read over invalid column fails _, err = client.Single().ReadRow(ctx, "TestTable", Key{1}, []string{"badcol"}) if msg, ok := matchError(err, codes.NotFound, "badcol"); !ok { t.Error(msg) } // Invalid query fails iter := client.Single().Query(ctx, Statement{SQL: "SELECT Apples AND Oranges"}) defer iter.Stop() _, err = iter.Next() if msg, ok := matchError(err, codes.InvalidArgument, "unrecognized name"); !ok { t.Error(msg) } // Read should fail on cancellation. cctx, cancel := context.WithCancel(ctx) cancel() _, err = client.Single().ReadRow(cctx, "TestTable", Key{1}, []string{"StringValue"}) if msg, ok := matchError(err, codes.Canceled, ""); !ok { t.Error(msg) } // Read should fail if deadline exceeded. dctx, cancel := context.WithTimeout(ctx, time.Nanosecond) defer cancel() <-dctx.Done() _, err = client.Single().ReadRow(dctx, "TestTable", Key{1}, []string{"StringValue"}) if msg, ok := matchError(err, codes.DeadlineExceeded, ""); !ok { t.Error(msg) } } // Test TransactionRunner. Test that transactions are aborted and retried as // expected. func TestIntegration_TransactionRunner(t *testing.T) { t.Parallel() ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() client, _, cleanup := prepareIntegrationTest(ctx, t, DefaultSessionPoolConfig, singerDBStatements) defer cleanup() // Test 1: User error should abort the transaction. _, _ = client.ReadWriteTransaction(ctx, func(ctx context.Context, tx *ReadWriteTransaction) error { tx.BufferWrite([]*Mutation{ Insert("Accounts", []string{"AccountId", "Nickname", "Balance"}, []interface{}{int64(1), "Foo", int64(50)})}) return errors.New("user error") }) // Empty read. rows, err := readAllTestTable(client.Single().Read(ctx, "Accounts", Key{1}, []string{"AccountId", "Nickname", "Balance"})) if err != nil { t.Fatal(err) } if got, want := len(rows), 0; got != want { t.Errorf("Empty read, got %d, want %d.", got, want) } // Test 2: Expect abort and retry. // We run two ReadWriteTransactions concurrently and make txn1 abort txn2 by // committing writes to the column txn2 have read, and expect the following // read to abort and txn2 retries. // Set up two accounts accounts := []*Mutation{ Insert("Accounts", []string{"AccountId", "Balance"}, []interface{}{int64(1), int64(0)}), Insert("Accounts", []string{"AccountId", "Balance"}, []interface{}{int64(2), int64(1)}), } if _, err := client.Apply(ctx, accounts, ApplyAtLeastOnce()); err != nil { t.Fatal(err) } var ( cTxn1Start = make(chan struct{}) cTxn1Commit = make(chan struct{}) cTxn2Start = make(chan struct{}) wg sync.WaitGroup ) // read balance, check error if we don't expect abort. readBalance := func(tx interface { ReadRow(ctx context.Context, table string, key Key, columns []string) (*Row, error) }, key int64, expectAbort bool) (int64, error) { var b int64 r, e := tx.ReadRow(ctx, "Accounts", Key{int64(key)}, []string{"Balance"}) if e != nil { if expectAbort && !isAbortErr(e) { t.Errorf("ReadRow got %v, want Abort error.", e) } return b, e } if ce := r.Column(0, &b); ce != nil { return b, ce } return b, nil } wg.Add(2) // Txn 1 go func() { defer wg.Done() var once sync.Once _, e := client.ReadWriteTransaction(ctx, func(ctx context.Context, tx *ReadWriteTransaction) error { b, e := readBalance(tx, 1, false) if e != nil { return e } // txn 1 can abort, in that case we skip closing the channel on // retry. once.Do(func() { close(cTxn1Start) }) e = tx.BufferWrite([]*Mutation{ Update("Accounts", []string{"AccountId", "Balance"}, []interface{}{int64(1), int64(b + 1)})}) if e != nil { return e } // Wait for second transaction. <-cTxn2Start return nil }) close(cTxn1Commit) if e != nil { t.Errorf("Transaction 1 commit, got %v, want nil.", e) } }() // Txn 2 go func() { // Wait until txn 1 starts. <-cTxn1Start defer wg.Done() var ( once sync.Once b1 int64 b2 int64 e error ) _, e = client.ReadWriteTransaction(ctx, func(ctx context.Context, tx *ReadWriteTransaction) error { if b1, e = readBalance(tx, 1, false); e != nil { return e } // Skip closing channel on retry. once.Do(func() { close(cTxn2Start) }) // Wait until txn 1 successfully commits. <-cTxn1Commit // Txn1 has committed and written a balance to the account. Now this // transaction (txn2) reads and re-writes the balance. The first // time through, it will abort because it overlaps with txn1. Then // it will retry after txn1 commits, and succeed. if b2, e = readBalance(tx, 2, true); e != nil { return e } return tx.BufferWrite([]*Mutation{ Update("Accounts", []string{"AccountId", "Balance"}, []interface{}{int64(2), int64(b1 + b2)})}) }) if e != nil { t.Errorf("Transaction 2 commit, got %v, want nil.", e) } }() wg.Wait() // Check that both transactions' effects are visible. for i := int64(1); i <= int64(2); i++ { if b, e := readBalance(client.Single(), i, false); e != nil { t.Fatalf("ReadBalance for key %d error %v.", i, e) } else if b != i { t.Errorf("Balance for key %d, got %d, want %d.", i, b, i) } } } // Test PartitionQuery of BatchReadOnlyTransaction, create partitions then // serialize and deserialize both transaction and partition to be used in // execution on another client, and compare results. func TestIntegration_BatchQuery(t *testing.T) { t.Parallel() // Set up testing environment. var ( client2 *Client err error ) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() client, dbPath, cleanup := prepareIntegrationTest(ctx, t, DefaultSessionPoolConfig, simpleDBStatements) defer cleanup() if err = populate(ctx, client); err != nil { t.Fatal(err) } if client2, err = createClient(ctx, dbPath, SessionPoolConfig{}); err != nil { t.Fatal(err) } defer client2.Close() // PartitionQuery var ( txn *BatchReadOnlyTransaction partitions []*Partition stmt = Statement{SQL: "SELECT * FROM test;"} ) if txn, err = client.BatchReadOnlyTransaction(ctx, StrongRead()); err != nil { t.Fatal(err) } defer txn.Cleanup(ctx) if partitions, err = txn.PartitionQuery(ctx, stmt, PartitionOptions{0, 3}); err != nil { t.Fatal(err) } // Reconstruct BatchReadOnlyTransactionID and execute partitions var ( tid2 BatchReadOnlyTransactionID data []byte gotResult bool // if we get matching result from two separate txns ) if data, err = txn.ID.MarshalBinary(); err != nil { t.Fatalf("encoding failed %v", err) } if err = tid2.UnmarshalBinary(data); err != nil { t.Fatalf("decoding failed %v", err) } txn2 := client2.BatchReadOnlyTransactionFromID(tid2) // Execute Partitions and compare results for i, p := range partitions { iter := txn.Execute(ctx, p) defer iter.Stop() p2 := serdesPartition(t, i, p) iter2 := txn2.Execute(ctx, &p2) defer iter2.Stop() row1, err1 := iter.Next() row2, err2 := iter2.Next() if err1 != err2 { t.Fatalf("execution failed for different reasons: %v, %v", err1, err2) continue } if !testEqual(row1, row2) { t.Fatalf("execution returned different values: %v, %v", row1, row2) continue } if row1 == nil { continue } var a, b string if err = row1.Columns(&a, &b); err != nil { t.Fatalf("failed to parse row %v", err) continue } if a == str1 && b == str2 { gotResult = true } } if !gotResult { t.Fatalf("execution didn't return expected values") } } // Test PartitionRead of BatchReadOnlyTransaction, similar to TestBatchQuery func TestIntegration_BatchRead(t *testing.T) { t.Parallel() // Set up testing environment. var ( client2 *Client err error ) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() client, dbPath, cleanup := prepareIntegrationTest(ctx, t, DefaultSessionPoolConfig, simpleDBStatements) defer cleanup() if err = populate(ctx, client); err != nil { t.Fatal(err) } if client2, err = createClient(ctx, dbPath, SessionPoolConfig{}); err != nil { t.Fatal(err) } defer client2.Close() // PartitionRead var ( txn *BatchReadOnlyTransaction partitions []*Partition ) if txn, err = client.BatchReadOnlyTransaction(ctx, StrongRead()); err != nil { t.Fatal(err) } defer txn.Cleanup(ctx) if partitions, err = txn.PartitionRead(ctx, "test", AllKeys(), simpleDBTableColumns, PartitionOptions{0, 3}); err != nil { t.Fatal(err) } // Reconstruct BatchReadOnlyTransactionID and execute partitions. var ( tid2 BatchReadOnlyTransactionID data []byte gotResult bool // if we get matching result from two separate txns ) if data, err = txn.ID.MarshalBinary(); err != nil { t.Fatalf("encoding failed %v", err) } if err = tid2.UnmarshalBinary(data); err != nil { t.Fatalf("decoding failed %v", err) } txn2 := client2.BatchReadOnlyTransactionFromID(tid2) // Execute Partitions and compare results. for i, p := range partitions { iter := txn.Execute(ctx, p) defer iter.Stop() p2 := serdesPartition(t, i, p) iter2 := txn2.Execute(ctx, &p2) defer iter2.Stop() row1, err1 := iter.Next() row2, err2 := iter2.Next() if err1 != err2 { t.Fatalf("execution failed for different reasons: %v, %v", err1, err2) continue } if !testEqual(row1, row2) { t.Fatalf("execution returned different values: %v, %v", row1, row2) continue } if row1 == nil { continue } var a, b string if err = row1.Columns(&a, &b); err != nil { t.Fatalf("failed to parse row %v", err) continue } if a == str1 && b == str2 { gotResult = true } } if !gotResult { t.Fatalf("execution didn't return expected values") } } // Test normal txReadEnv method on BatchReadOnlyTransaction. func TestIntegration_BROTNormal(t *testing.T) { t.Parallel() // Set up testing environment and create txn. var ( txn *BatchReadOnlyTransaction err error row *Row i int64 ) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() client, _, cleanup := prepareIntegrationTest(ctx, t, DefaultSessionPoolConfig, simpleDBStatements) defer cleanup() if txn, err = client.BatchReadOnlyTransaction(ctx, StrongRead()); err != nil { t.Fatal(err) } defer txn.Cleanup(ctx) if _, err := txn.PartitionRead(ctx, "test", AllKeys(), simpleDBTableColumns, PartitionOptions{0, 3}); err != nil { t.Fatal(err) } // Normal query should work with BatchReadOnlyTransaction. stmt2 := Statement{SQL: "SELECT 1"} iter := txn.Query(ctx, stmt2) defer iter.Stop() row, err = iter.Next() if err != nil { t.Errorf("query failed with %v", err) } if err = row.Columns(&i); err != nil { t.Errorf("failed to parse row %v", err) } } func TestIntegration_CommitTimestamp(t *testing.T) { t.Parallel() ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() client, _, cleanup := prepareIntegrationTest(ctx, t, DefaultSessionPoolConfig, ctsDBStatements) defer cleanup() type testTableRow struct { Key string Ts NullTime } var ( cts1, cts2, ts1, ts2 time.Time err error ) // Apply mutation in sequence, expect to see commit timestamp in good order, // check also the commit timestamp returned for _, it := range []struct { k string t *time.Time }{ {"a", &cts1}, {"b", &cts2}, } { tt := testTableRow{Key: it.k, Ts: NullTime{CommitTimestamp, true}} m, err := InsertStruct("TestTable", tt) if err != nil { t.Fatal(err) } *it.t, err = client.Apply(ctx, []*Mutation{m}, ApplyAtLeastOnce()) if err != nil { t.Fatal(err) } } txn := client.ReadOnlyTransaction() for _, it := range []struct { k string t *time.Time }{ {"a", &ts1}, {"b", &ts2}, } { if r, e := txn.ReadRow(ctx, "TestTable", Key{it.k}, []string{"Ts"}); e != nil { t.Fatal(err) } else { var got testTableRow if err := r.ToStruct(&got); err != nil { t.Fatal(err) } *it.t = got.Ts.Time } } if !cts1.Equal(ts1) { t.Errorf("Expect commit timestamp returned and read to match for txn1, got %v and %v.", cts1, ts1) } if !cts2.Equal(ts2) { t.Errorf("Expect commit timestamp returned and read to match for txn2, got %v and %v.", cts2, ts2) } // Try writing a timestamp in the future to commit timestamp, expect error. _, err = client.Apply(ctx, []*Mutation{InsertOrUpdate("TestTable", []string{"Key", "Ts"}, []interface{}{"a", time.Now().Add(time.Hour)})}, ApplyAtLeastOnce()) if msg, ok := matchError(err, codes.FailedPrecondition, "Cannot write timestamps in the future"); !ok { t.Error(msg) } } func TestIntegration_DML(t *testing.T) { t.Parallel() ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() client, _, cleanup := prepareIntegrationTest(ctx, t, DefaultSessionPoolConfig, singerDBStatements) defer cleanup() // Function that reads a single row's first name from within a transaction. readFirstName := func(tx *ReadWriteTransaction, key int) (string, error) { row, err := tx.ReadRow(ctx, "Singers", Key{key}, []string{"FirstName"}) if err != nil { return "", err } var fn string if err := row.Column(0, &fn); err != nil { return "", err } return fn, nil } // Function that reads multiple rows' first names from outside a read/write // transaction. readFirstNames := func(keys ...int) []string { var ks []KeySet for _, k := range keys { ks = append(ks, Key{k}) } iter := client.Single().Read(ctx, "Singers", KeySets(ks...), []string{"FirstName"}) var got []string var fn string err := iter.Do(func(row *Row) error { if err := row.Column(0, &fn); err != nil { return err } got = append(got, fn) return nil }) if err != nil { t.Fatalf("readFirstNames(%v): %v", keys, err) } return got } // Use ReadWriteTransaction.Query to execute a DML statement. _, err := client.ReadWriteTransaction(ctx, func(ctx context.Context, tx *ReadWriteTransaction) error { iter := tx.Query(ctx, Statement{ SQL: `INSERT INTO Singers (SingerId, FirstName, LastName) VALUES (1, "Umm", "Kulthum")`, }) defer iter.Stop() if row, err := iter.Next(); err != iterator.Done { t.Fatalf("got results from iterator, want none: %#v, err = %v\n", row, err) } if iter.RowCount != 1 { t.Errorf("row count: got %d, want 1", iter.RowCount) } // The results of the DML statement should be visible to the transaction. got, err := readFirstName(tx, 1) if err != nil { return err } if want := "Umm"; got != want { t.Errorf("got %q, want %q", got, want) } return nil }) if err != nil { t.Fatal(err) } // Use ReadWriteTransaction.Update to execute a DML statement. _, err = client.ReadWriteTransaction(ctx, func(ctx context.Context, tx *ReadWriteTransaction) error { count, err := tx.Update(ctx, Statement{ SQL: `Insert INTO Singers (SingerId, FirstName, LastName) VALUES (2, "Eduard", "Khil")`, }) if err != nil { t.Fatal(err) } if count != 1 { t.Errorf("row count: got %d, want 1", count) } got, err := readFirstName(tx, 2) if err != nil { return err } if want := "Eduard"; got != want { t.Errorf("got %q, want %q", got, want) } return nil }) if err != nil { t.Fatal(err) } // Roll back a DML statement and confirm that it didn't happen. var fail = errors.New("fail") _, err = client.ReadWriteTransaction(ctx, func(ctx context.Context, tx *ReadWriteTransaction) error { _, err := tx.Update(ctx, Statement{ SQL: `INSERT INTO Singers (SingerId, FirstName, LastName) VALUES (3, "Audra", "McDonald")`, }) if err != nil { return err } return fail }) if err != fail { t.Fatalf("rolling back: got error %v, want the error 'fail'", err) } _, err = client.Single().ReadRow(ctx, "Singers", Key{3}, []string{"FirstName"}) if got, want := ErrCode(err), codes.NotFound; got != want { t.Errorf("got %s, want %s", got, want) } // Run two DML statements in the same transaction. _, err = client.ReadWriteTransaction(ctx, func(ctx context.Context, tx *ReadWriteTransaction) error { _, err := tx.Update(ctx, Statement{SQL: `UPDATE Singers SET FirstName = "Oum" WHERE SingerId = 1`}) if err != nil { return err } _, err = tx.Update(ctx, Statement{SQL: `UPDATE Singers SET FirstName = "Eddie" WHERE SingerId = 2`}) if err != nil { return err } return nil }) if err != nil { t.Fatal(err) } got := readFirstNames(1, 2) want := []string{"Oum", "Eddie"} if !testEqual(got, want) { t.Errorf("got %v, want %v", got, want) } // Run a DML statement and an ordinary mutation in the same transaction. _, err = client.ReadWriteTransaction(ctx, func(ctx context.Context, tx *ReadWriteTransaction) error { _, err := tx.Update(ctx, Statement{ SQL: `INSERT INTO Singers (SingerId, FirstName, LastName) VALUES (3, "Audra", "McDonald")`, }) if err != nil { return err } return tx.BufferWrite([]*Mutation{ Insert("Singers", []string{"SingerId", "FirstName", "LastName"}, []interface{}{4, "Andy", "Irvine"}), }) }) if err != nil { t.Fatal(err) } got = readFirstNames(3, 4) want = []string{"Audra", "Andy"} if !testEqual(got, want) { t.Errorf("got %v, want %v", got, want) } // Attempt to run a query using update. _, err = client.ReadWriteTransaction(ctx, func(ctx context.Context, tx *ReadWriteTransaction) error { _, err := tx.Update(ctx, Statement{SQL: `SELECT FirstName from Singers`}) return err }) if got, want := ErrCode(err), codes.InvalidArgument; got != want { t.Errorf("got %s, want %s", got, want) } } func TestIntegration_StructParametersBind(t *testing.T) { t.Parallel() ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() client, _, cleanup := prepareIntegrationTest(ctx, t, DefaultSessionPoolConfig, nil) defer cleanup() type tRow []interface{} type tRows []struct{ trow tRow } type allFields struct { Stringf string Intf int Boolf bool Floatf float64 Bytef []byte Timef time.Time Datef civil.Date } allColumns := []string{ "Stringf", "Intf", "Boolf", "Floatf", "Bytef", "Timef", "Datef", } s1 := allFields{"abc", 300, false, 3.45, []byte("foo"), t1, d1} s2 := allFields{"def", -300, false, -3.45, []byte("bar"), t2, d2} dynamicStructType := reflect.StructOf([]reflect.StructField{ {Name: "A", Type: reflect.TypeOf(t1), Tag: `spanner:"ff1"`}, }) s3 := reflect.New(dynamicStructType) s3.Elem().Field(0).Set(reflect.ValueOf(t1)) for i, test := range []struct { param interface{} sql string cols []string trows tRows }{ // Struct value. { s1, "SELECT" + " @p.Stringf," + " @p.Intf," + " @p.Boolf," + " @p.Floatf," + " @p.Bytef," + " @p.Timef," + " @p.Datef", allColumns, tRows{ {tRow{"abc", 300, false, 3.45, []byte("foo"), t1, d1}}, }, }, // Array of struct value. { []allFields{s1, s2}, "SELECT * FROM UNNEST(@p)", allColumns, tRows{ {tRow{"abc", 300, false, 3.45, []byte("foo"), t1, d1}}, {tRow{"def", -300, false, -3.45, []byte("bar"), t2, d2}}, }, }, // Null struct. { (*allFields)(nil), "SELECT @p IS NULL", []string{""}, tRows{ {tRow{true}}, }, }, // Null Array of struct. { []allFields(nil), "SELECT @p IS NULL", []string{""}, tRows{ {tRow{true}}, }, }, // Empty struct. { struct{}{}, "SELECT @p IS NULL ", []string{""}, tRows{ {tRow{false}}, }, }, // Empty array of struct. { []allFields{}, "SELECT * FROM UNNEST(@p) ", allColumns, tRows{}, }, // Struct with duplicate fields. { struct { A int `spanner:"field"` B int `spanner:"field"` }{10, 20}, "SELECT * FROM UNNEST([@p]) ", []string{"field", "field"}, tRows{ {tRow{10, 20}}, }, }, // Struct with unnamed fields. { struct { A string `spanner:""` }{"hello"}, "SELECT * FROM UNNEST([@p]) ", []string{""}, tRows{ {tRow{"hello"}}, }, }, // Mixed struct. { struct { DynamicStructField interface{} `spanner:"f1"` ArrayStructField []*allFields `spanner:"f2"` }{ DynamicStructField: s3.Interface(), ArrayStructField: []*allFields{nil}, }, "SELECT @p.f1.ff1, ARRAY_LENGTH(@p.f2), @p.f2[OFFSET(0)] IS NULL ", []string{"ff1", "", ""}, tRows{ {tRow{t1, 1, true}}, }, }, } { iter := client.Single().Query(ctx, Statement{ SQL: test.sql, Params: map[string]interface{}{"p": test.param}, }) var gotRows []*Row err := iter.Do(func(r *Row) error { gotRows = append(gotRows, r) return nil }) if err != nil { t.Errorf("Failed to execute test case %d, error: %v", i, err) } var wantRows []*Row for j, row := range test.trows { r, err := NewRow(test.cols, row.trow) if err != nil { t.Errorf("Invalid row %d in test case %d", j, i) } wantRows = append(wantRows, r) } if !testEqual(gotRows, wantRows) { t.Errorf("%d: Want result %v, got result %v", i, wantRows, gotRows) } } } func TestIntegration_PDML(t *testing.T) { t.Parallel() ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() client, _, cleanup := prepareIntegrationTest(ctx, t, DefaultSessionPoolConfig, singerDBStatements) defer cleanup() columns := []string{"SingerId", "FirstName", "LastName"} // Populate the Singers table. var muts []*Mutation for _, row := range [][]interface{}{ {1, "Umm", "Kulthum"}, {2, "Eduard", "Khil"}, {3, "Audra", "McDonald"}, {4, "Enrique", "Iglesias"}, {5, "Shakira", "Ripoll"}, } { muts = append(muts, Insert("Singers", columns, row)) } if _, err := client.Apply(ctx, muts); err != nil { t.Fatal(err) } // Identifiers in PDML statements must be fully qualified. // TODO(jba): revisit the above. count, err := client.PartitionedUpdate(ctx, Statement{ SQL: `UPDATE Singers SET Singers.FirstName = "changed" WHERE Singers.SingerId >= 1 AND Singers.SingerId <= @end`, Params: map[string]interface{}{ "end": 3, }, }) if err != nil { t.Fatal(err) } if want := int64(3); count != want { t.Fatalf("got %d, want %d", count, want) } got, err := readAll(client.Single().Read(ctx, "Singers", AllKeys(), columns)) if err != nil { t.Fatal(err) } want := [][]interface{}{ {int64(1), "changed", "Kulthum"}, {int64(2), "changed", "Khil"}, {int64(3), "changed", "McDonald"}, {int64(4), "Enrique", "Iglesias"}, {int64(5), "Shakira", "Ripoll"}, } if !testEqual(got, want) { t.Errorf("\ngot %v\nwant%v", got, want) } } func TestBatchDML(t *testing.T) { t.Parallel() ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() client, _, cleanup := prepareIntegrationTest(ctx, t, DefaultSessionPoolConfig, singerDBStatements) defer cleanup() columns := []string{"SingerId", "FirstName", "LastName"} // Populate the Singers table. var muts []*Mutation for _, row := range [][]interface{}{ {1, "Umm", "Kulthum"}, {2, "Eduard", "Khil"}, {3, "Audra", "McDonald"}, } { muts = append(muts, Insert("Singers", columns, row)) } if _, err := client.Apply(ctx, muts); err != nil { t.Fatal(err) } var counts []int64 _, err := client.ReadWriteTransaction(ctx, func(ctx context.Context, tx *ReadWriteTransaction) (err error) { counts, err = tx.BatchUpdate(ctx, []Statement{ {SQL: `UPDATE Singers SET Singers.FirstName = "changed 1" WHERE Singers.SingerId = 1`}, {SQL: `UPDATE Singers SET Singers.FirstName = "changed 2" WHERE Singers.SingerId = 2`}, {SQL: `UPDATE Singers SET Singers.FirstName = "changed 3" WHERE Singers.SingerId = 3`}, }) return err }) if err != nil { t.Fatal(err) } if want := []int64{1, 1, 1}; !testEqual(counts, want) { t.Fatalf("got %d, want %d", counts, want) } got, err := readAll(client.Single().Read(ctx, "Singers", AllKeys(), columns)) if err != nil { t.Fatal(err) } want := [][]interface{}{ {int64(1), "changed 1", "Kulthum"}, {int64(2), "changed 2", "Khil"}, {int64(3), "changed 3", "McDonald"}, } if !testEqual(got, want) { t.Errorf("\ngot %v\nwant%v", got, want) } } func TestBatchDML_NoStatements(t *testing.T) { t.Parallel() ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() client, _, cleanup := prepareIntegrationTest(ctx, t, DefaultSessionPoolConfig, singerDBStatements) defer cleanup() _, err := client.ReadWriteTransaction(ctx, func(ctx context.Context, tx *ReadWriteTransaction) (err error) { _, err = tx.BatchUpdate(ctx, []Statement{}) return err }) if err == nil { t.Fatal("expected error, got nil") } if s, ok := status.FromError(err); ok { if s.Code() != codes.InvalidArgument { t.Fatalf("expected InvalidArgument, got %v", err) } } else { t.Fatalf("expected InvalidArgument, got %v", err) } } func TestBatchDML_TwoStatements(t *testing.T) { t.Parallel() ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() client, _, cleanup := prepareIntegrationTest(ctx, t, DefaultSessionPoolConfig, singerDBStatements) defer cleanup() columns := []string{"SingerId", "FirstName", "LastName"} // Populate the Singers table. var muts []*Mutation for _, row := range [][]interface{}{ {1, "Umm", "Kulthum"}, {2, "Eduard", "Khil"}, {3, "Audra", "McDonald"}, } { muts = append(muts, Insert("Singers", columns, row)) } if _, err := client.Apply(ctx, muts); err != nil { t.Fatal(err) } var updateCount int64 var batchCounts []int64 _, err := client.ReadWriteTransaction(ctx, func(ctx context.Context, tx *ReadWriteTransaction) (err error) { batchCounts, err = tx.BatchUpdate(ctx, []Statement{ {SQL: `UPDATE Singers SET Singers.FirstName = "changed 1" WHERE Singers.SingerId = 1`}, {SQL: `UPDATE Singers SET Singers.FirstName = "changed 2" WHERE Singers.SingerId = 2`}, {SQL: `UPDATE Singers SET Singers.FirstName = "changed 3" WHERE Singers.SingerId = 3`}, }) if err != nil { return err } updateCount, err = tx.Update(ctx, Statement{SQL: `UPDATE Singers SET Singers.FirstName = "changed 1" WHERE Singers.SingerId = 1`}) return err }) if err != nil { t.Fatal(err) } if want := []int64{1, 1, 1}; !testEqual(batchCounts, want) { t.Fatalf("got %d, want %d", batchCounts, want) } if updateCount != 1 { t.Fatalf("got %v, want 1", updateCount) } } // TODO(deklerk): this currently does not work because the transaction appears to // get rolled back after a single statement fails. b/120158761 func TestBatchDML_Error(t *testing.T) { t.Parallel() ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() client, _, cleanup := prepareIntegrationTest(ctx, t, DefaultSessionPoolConfig, singerDBStatements) defer cleanup() columns := []string{"SingerId", "FirstName", "LastName"} // Populate the Singers table. var muts []*Mutation for _, row := range [][]interface{}{ {1, "Umm", "Kulthum"}, {2, "Eduard", "Khil"}, {3, "Audra", "McDonald"}, } { muts = append(muts, Insert("Singers", columns, row)) } if _, err := client.Apply(ctx, muts); err != nil { t.Fatal(err) } _, err := client.ReadWriteTransaction(ctx, func(ctx context.Context, tx *ReadWriteTransaction) (err error) { counts, err := tx.BatchUpdate(ctx, []Statement{ {SQL: `UPDATE Singers SET Singers.FirstName = "changed 1" WHERE Singers.SingerId = 1`}, {SQL: `some illegal statement`}, {SQL: `UPDATE Singers SET Singers.FirstName = "changed 3" WHERE Singers.SingerId = 3`}, }) if err == nil { t.Fatal("expected err, got nil") } if want := []int64{1}; !testEqual(counts, want) { t.Fatalf("got %d, want %d", counts, want) } got, err := readAll(tx.Read(ctx, "Singers", AllKeys(), columns)) if err != nil { t.Fatal(err) } want := [][]interface{}{ {int64(1), "changed 1", "Kulthum"}, {int64(2), "Eduard", "Khil"}, {int64(3), "Audra", "McDonald"}, } if !testEqual(got, want) { t.Errorf("\ngot %v\nwant%v", got, want) } return nil }) if err != nil { t.Fatal(err) } } // Prepare initializes Cloud Spanner testing DB and clients. func prepareIntegrationTest(ctx context.Context, t *testing.T, spc SessionPoolConfig, statements []string) (*Client, string, func()) { if databaseAdmin == nil { t.Skip("Integration tests skipped") } // Construct a unique test DB name. dbName := dbNameSpace.New() dbPath := fmt.Sprintf("projects/%v/instances/%v/databases/%v", testProjectID, testInstanceID, dbName) // Create database and tables. op, err := databaseAdmin.CreateDatabase(ctx, &adminpb.CreateDatabaseRequest{ Parent: fmt.Sprintf("projects/%v/instances/%v", testProjectID, testInstanceID), CreateStatement: "CREATE DATABASE " + dbName, ExtraStatements: statements, }) if err != nil { t.Fatalf("cannot create testing DB %v: %v", dbPath, err) } if _, err := op.Wait(ctx); err != nil { t.Fatalf("cannot create testing DB %v: %v", dbPath, err) } client, err := createClient(ctx, dbPath, spc) if err != nil { t.Fatalf("cannot create data client on DB %v: %v", dbPath, err) } return client, dbPath, func() { client.Close() } } func cleanupInstances() { if instanceAdmin == nil { // Integration tests skipped. return } ctx := context.Background() parent := fmt.Sprintf("projects/%v", testProjectID) iter := instanceAdmin.ListInstances(ctx, &instancepb.ListInstancesRequest{ Parent: parent, Filter: "name:gotest-", }) expireAge := 24 * time.Hour for { inst, err := iter.Next() if err == iterator.Done { break } if err != nil { panic(err) } if instanceNameSpace.Older(inst.Name, expireAge) { log.Printf("Deleting instance %s", inst.Name) if err := instanceAdmin.DeleteInstance(ctx, &instancepb.DeleteInstanceRequest{Name: inst.Name}); err != nil { log.Printf("failed to delete instance %s (error %v), might need a manual removal", inst.Name, err) } } } } func rangeReads(ctx context.Context, t *testing.T, client *Client) { checkRange := func(ks KeySet, wantNums ...int) { if msg, ok := compareRows(client.Single().Read(ctx, testTable, ks, testTableColumns), wantNums); !ok { t.Errorf("key set %+v: %s", ks, msg) } } checkRange(Key{"k1"}, 1) checkRange(KeyRange{Key{"k3"}, Key{"k5"}, ClosedOpen}, 3, 4) checkRange(KeyRange{Key{"k3"}, Key{"k5"}, ClosedClosed}, 3, 4, 5) checkRange(KeyRange{Key{"k3"}, Key{"k5"}, OpenClosed}, 4, 5) checkRange(KeyRange{Key{"k3"}, Key{"k5"}, OpenOpen}, 4) // Partial key specification. checkRange(KeyRange{Key{"k7"}, Key{}, ClosedClosed}, 7, 8, 9) checkRange(KeyRange{Key{"k7"}, Key{}, OpenClosed}, 8, 9) checkRange(KeyRange{Key{}, Key{"k11"}, ClosedOpen}, 0, 1, 10) checkRange(KeyRange{Key{}, Key{"k11"}, ClosedClosed}, 0, 1, 10, 11) // The following produce empty ranges. // TODO(jba): Consider a multi-part key to illustrate partial key behavior. // checkRange(KeyRange{Key{"k7"}, Key{}, ClosedOpen}) // checkRange(KeyRange{Key{"k7"}, Key{}, OpenOpen}) // checkRange(KeyRange{Key{}, Key{"k11"}, OpenOpen}) // checkRange(KeyRange{Key{}, Key{"k11"}, OpenClosed}) // Prefix is component-wise, not string prefix. checkRange(Key{"k1"}.AsPrefix(), 1) checkRange(KeyRange{Key{"k1"}, Key{"k2"}, ClosedOpen}, 1, 10, 11, 12, 13, 14) checkRange(AllKeys(), 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14) } func indexRangeReads(ctx context.Context, t *testing.T, client *Client) { checkRange := func(ks KeySet, wantNums ...int) { if msg, ok := compareRows(client.Single().ReadUsingIndex(ctx, testTable, testTableIndex, ks, testTableColumns), wantNums); !ok { t.Errorf("key set %+v: %s", ks, msg) } } checkRange(Key{"v1"}, 1) checkRange(KeyRange{Key{"v3"}, Key{"v5"}, ClosedOpen}, 3, 4) checkRange(KeyRange{Key{"v3"}, Key{"v5"}, ClosedClosed}, 3, 4, 5) checkRange(KeyRange{Key{"v3"}, Key{"v5"}, OpenClosed}, 4, 5) checkRange(KeyRange{Key{"v3"}, Key{"v5"}, OpenOpen}, 4) // // Partial key specification. checkRange(KeyRange{Key{"v7"}, Key{}, ClosedClosed}, 7, 8, 9) checkRange(KeyRange{Key{"v7"}, Key{}, OpenClosed}, 8, 9) checkRange(KeyRange{Key{}, Key{"v11"}, ClosedOpen}, 0, 1, 10) checkRange(KeyRange{Key{}, Key{"v11"}, ClosedClosed}, 0, 1, 10, 11) // // The following produce empty ranges. // checkRange(KeyRange{Key{"v7"}, Key{}, ClosedOpen}) // checkRange(KeyRange{Key{"v7"}, Key{}, OpenOpen}) // checkRange(KeyRange{Key{}, Key{"v11"}, OpenOpen}) // checkRange(KeyRange{Key{}, Key{"v11"}, OpenClosed}) // // Prefix is component-wise, not string prefix. checkRange(Key{"v1"}.AsPrefix(), 1) checkRange(KeyRange{Key{"v1"}, Key{"v2"}, ClosedOpen}, 1, 10, 11, 12, 13, 14) checkRange(AllKeys(), 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14) // Read from an index with DESC ordering. wantNums := []int{14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0} if msg, ok := compareRows(client.Single().ReadUsingIndex(ctx, testTable, "TestTableByValueDesc", AllKeys(), testTableColumns), wantNums); !ok { t.Errorf("desc: %s", msg) } } type testTableRow struct{ Key, StringValue string } func compareRows(iter *RowIterator, wantNums []int) (string, bool) { rows, err := readAllTestTable(iter) if err != nil { return err.Error(), false } want := map[string]string{} for _, n := range wantNums { want[fmt.Sprintf("k%d", n)] = fmt.Sprintf("v%d", n) } got := map[string]string{} for _, r := range rows { got[r.Key] = r.StringValue } if !testEqual(got, want) { return fmt.Sprintf("got %v, want %v", got, want), false } return "", true } func isNaN(x interface{}) bool { f, ok := x.(float64) if !ok { return false } return math.IsNaN(f) } // createClient creates Cloud Spanner data client. func createClient(ctx context.Context, dbPath string, spc SessionPoolConfig) (client *Client, err error) { client, err = NewClientWithConfig(ctx, dbPath, ClientConfig{ SessionPoolConfig: spc, }, option.WithTokenSource(testutil.TokenSource(ctx, Scope)), option.WithEndpoint(endpoint)) if err != nil { return nil, fmt.Errorf("cannot create data client on DB %v: %v", dbPath, err) } return client, nil } // populate prepares the database with some data. func populate(ctx context.Context, client *Client) error { // Populate data var err error m := InsertMap("test", map[string]interface{}{ "a": str1, "b": str2, }) _, err = client.Apply(ctx, []*Mutation{m}) return err } func matchError(got error, wantCode codes.Code, wantMsgPart string) (string, bool) { if ErrCode(got) != wantCode || !strings.Contains(strings.ToLower(ErrDesc(got)), strings.ToLower(wantMsgPart)) { return fmt.Sprintf("got error <%v>\n"+`want `, got, wantCode, wantMsgPart), false } return "", true } func rowToValues(r *Row) ([]interface{}, error) { var x int64 var y, z string if err := r.Column(0, &x); err != nil { return nil, err } if err := r.Column(1, &y); err != nil { return nil, err } if err := r.Column(2, &z); err != nil { return nil, err } return []interface{}{x, y, z}, nil } func readAll(iter *RowIterator) ([][]interface{}, error) { defer iter.Stop() var vals [][]interface{} for { row, err := iter.Next() if err == iterator.Done { return vals, nil } if err != nil { return nil, err } v, err := rowToValues(row) if err != nil { return nil, err } vals = append(vals, v) } } func readAllTestTable(iter *RowIterator) ([]testTableRow, error) { defer iter.Stop() var vals []testTableRow for { row, err := iter.Next() if err == iterator.Done { return vals, nil } if err != nil { return nil, err } var ttr testTableRow if err := row.ToStruct(&ttr); err != nil { return nil, err } vals = append(vals, ttr) } } func maxDuration(a, b time.Duration) time.Duration { if a > b { return a } return b } google-cloud-go-0.49.0/spanner/internal/000077500000000000000000000000001356504100700200525ustar00rootroot00000000000000google-cloud-go-0.49.0/spanner/internal/backoff/000077500000000000000000000000001356504100700214455ustar00rootroot00000000000000google-cloud-go-0.49.0/spanner/internal/backoff/backoff.go000066400000000000000000000026671356504100700234020ustar00rootroot00000000000000/* Copyright 2017 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package backoff import ( "math/rand" "time" ) const ( // minBackoff is the minimum backoff used by default. minBackoff = 20 * time.Millisecond // maxBackoff is the maximum backoff used by default. maxBackoff = 32 * time.Second // jitter is the jitter factor. jitter = 0.4 // rate is the rate of exponential increase in the backoff. rate = 1.3 ) var DefaultBackoff = ExponentialBackoff{minBackoff, maxBackoff} type ExponentialBackoff struct { Min, Max time.Duration } // delay calculates the delay that should happen at n-th // exponential backoff in a series. func (b ExponentialBackoff) Delay(retries int) time.Duration { min, max := float64(b.Min), float64(b.Max) delay := min for delay < max && retries > 0 { delay *= rate retries-- } if delay > max { delay = max } delay -= delay * jitter * rand.Float64() if delay < min { delay = min } return time.Duration(delay) } google-cloud-go-0.49.0/spanner/internal/backoff/backoff_test.go000066400000000000000000000030461356504100700244310ustar00rootroot00000000000000/* Copyright 2017 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package backoff import ( "math" "testing" "time" ) // Test if exponential backoff helper can produce correct series of // retry delays. func TestBackoff(t *testing.T) { b := ExponentialBackoff{minBackoff, maxBackoff} tests := []struct { retries int min time.Duration max time.Duration }{ { retries: 0, min: minBackoff, max: minBackoff, }, { retries: 1, min: minBackoff, max: time.Duration(rate * float64(minBackoff)), }, { retries: 3, min: time.Duration(math.Pow(rate, 3) * (1 - jitter) * float64(minBackoff)), max: time.Duration(math.Pow(rate, 3) * float64(minBackoff)), }, { retries: 1000, min: time.Duration((1 - jitter) * float64(maxBackoff)), max: maxBackoff, }, } for _, test := range tests { got := b.Delay(test.retries) if float64(got) < float64(test.min) || float64(got) > float64(test.max) { t.Errorf("delay(%v) = %v, want in range [%v, %v]", test.retries, got, test.min, test.max) } } } google-cloud-go-0.49.0/spanner/internal/benchwrapper/000077500000000000000000000000001356504100700225325ustar00rootroot00000000000000google-cloud-go-0.49.0/spanner/internal/benchwrapper/README.md000066400000000000000000000004141356504100700240100ustar00rootroot00000000000000# Benchwrapper A small gRPC wrapper around the spanner client library. This allows the benchmarking code to prod at spanner without speaking Go. ## Running ``` cd spanner/internal/benchwrapper export SPANNER_EMULATOR_HOST=localhost:8080 go run *.go --port=8081 ``` google-cloud-go-0.49.0/spanner/internal/benchwrapper/main.go000066400000000000000000000056761356504100700240230ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package main wraps the client library in a gRPC interface that a benchmarker // can communicate through. package main import ( "context" "flag" "fmt" "log" "net" "os" "cloud.google.com/go/spanner" pb "cloud.google.com/go/spanner/internal/benchwrapper/proto" "google.golang.org/api/iterator" "google.golang.org/grpc" ) var port = flag.String("port", "", "specify a port to run on") func main() { flag.Parse() if *port == "" { log.Fatalf("usage: %s --port=8081", os.Args[0]) } if os.Getenv("SPANNER_EMULATOR_HOST") == "" { log.Fatal("This benchmarking server only works when connected to an emulator. Please set SPANNER_EMULATOR_HOST.") } ctx := context.Background() c, err := spanner.NewClient(ctx, "projects/someproject/instances/someinstance/databases/somedatabase") if err != nil { log.Fatal(err) } lis, err := net.Listen("tcp", fmt.Sprintf(":%s", *port)) if err != nil { log.Fatal(err) } s := grpc.NewServer() pb.RegisterSpannerBenchWrapperServer(s, &server{ c: c, }) log.Printf("Running on localhost:%s\n", *port) log.Fatal(s.Serve(lis)) } type server struct { c *spanner.Client } func (s *server) Read(ctx context.Context, req *pb.ReadQuery) (*pb.EmptyResponse, error) { it := s.c.ReadOnlyTransaction().Query(context.Background(), spanner.Statement{SQL: req.Query}) for { _, err := it.Next() if err == iterator.Done { break } if err != nil { log.Fatal(err) } // Do nothing with the data. } return &pb.EmptyResponse{}, nil } func (s *server) Insert(ctx context.Context, req *pb.InsertQuery) (*pb.EmptyResponse, error) { var muts []*spanner.Mutation for _, i := range req.Users { muts = append(muts, spanner.Insert("sometable", []string{"name", "age"}, []interface{}{i.Name, i.Age})) } if _, err := s.c.Apply(context.Background(), muts); err != nil { log.Fatal(err) } // Do nothing with the data. return &pb.EmptyResponse{}, nil } func (s *server) Update(ctx context.Context, req *pb.UpdateQuery) (*pb.EmptyResponse, error) { var stmts []spanner.Statement for _, q := range req.Queries { stmts = append(stmts, spanner.Statement{SQL: q}) } if _, err := s.c.ReadWriteTransaction(context.Background(), func(ctx2 context.Context, tx *spanner.ReadWriteTransaction) error { _, err := tx.BatchUpdate(ctx2, stmts) return err }); err != nil { log.Fatal(err) } // Do nothing with the data. return &pb.EmptyResponse{}, nil } google-cloud-go-0.49.0/spanner/internal/benchwrapper/proto/000077500000000000000000000000001356504100700236755ustar00rootroot00000000000000google-cloud-go-0.49.0/spanner/internal/benchwrapper/proto/README.md000066400000000000000000000001541356504100700251540ustar00rootroot00000000000000# Regenerating protos ``` cd spanner/internal/benchwrapper/proto protoc --go_out=plugins=grpc:. *.proto ```google-cloud-go-0.49.0/spanner/internal/benchwrapper/proto/spanner.pb.go000066400000000000000000000370061356504100700263000ustar00rootroot00000000000000// Code generated by protoc-gen-go. DO NOT EDIT. // source: spanner.proto package spanner_bench import ( context "context" fmt "fmt" math "math" proto "github.com/golang/protobuf/proto" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" ) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal var _ = fmt.Errorf var _ = math.Inf // This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package type ReadQuery struct { // The query to use in the read call. Query string `protobuf:"bytes,1,opt,name=Query,proto3" json:"Query,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *ReadQuery) Reset() { *m = ReadQuery{} } func (m *ReadQuery) String() string { return proto.CompactTextString(m) } func (*ReadQuery) ProtoMessage() {} func (*ReadQuery) Descriptor() ([]byte, []int) { return fileDescriptor_879d3e919e93c6ba, []int{0} } func (m *ReadQuery) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ReadQuery.Unmarshal(m, b) } func (m *ReadQuery) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ReadQuery.Marshal(b, m, deterministic) } func (m *ReadQuery) XXX_Merge(src proto.Message) { xxx_messageInfo_ReadQuery.Merge(m, src) } func (m *ReadQuery) XXX_Size() int { return xxx_messageInfo_ReadQuery.Size(m) } func (m *ReadQuery) XXX_DiscardUnknown() { xxx_messageInfo_ReadQuery.DiscardUnknown(m) } var xxx_messageInfo_ReadQuery proto.InternalMessageInfo func (m *ReadQuery) GetQuery() string { if m != nil { return m.Query } return "" } type User struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` Age int64 `protobuf:"varint,2,opt,name=age,proto3" json:"age,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *User) Reset() { *m = User{} } func (m *User) String() string { return proto.CompactTextString(m) } func (*User) ProtoMessage() {} func (*User) Descriptor() ([]byte, []int) { return fileDescriptor_879d3e919e93c6ba, []int{1} } func (m *User) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_User.Unmarshal(m, b) } func (m *User) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_User.Marshal(b, m, deterministic) } func (m *User) XXX_Merge(src proto.Message) { xxx_messageInfo_User.Merge(m, src) } func (m *User) XXX_Size() int { return xxx_messageInfo_User.Size(m) } func (m *User) XXX_DiscardUnknown() { xxx_messageInfo_User.DiscardUnknown(m) } var xxx_messageInfo_User proto.InternalMessageInfo func (m *User) GetName() string { if m != nil { return m.Name } return "" } func (m *User) GetAge() int64 { if m != nil { return m.Age } return 0 } type InsertQuery struct { // The query to use in the insert call. Users []*User `protobuf:"bytes,1,rep,name=users,proto3" json:"users,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *InsertQuery) Reset() { *m = InsertQuery{} } func (m *InsertQuery) String() string { return proto.CompactTextString(m) } func (*InsertQuery) ProtoMessage() {} func (*InsertQuery) Descriptor() ([]byte, []int) { return fileDescriptor_879d3e919e93c6ba, []int{2} } func (m *InsertQuery) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_InsertQuery.Unmarshal(m, b) } func (m *InsertQuery) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_InsertQuery.Marshal(b, m, deterministic) } func (m *InsertQuery) XXX_Merge(src proto.Message) { xxx_messageInfo_InsertQuery.Merge(m, src) } func (m *InsertQuery) XXX_Size() int { return xxx_messageInfo_InsertQuery.Size(m) } func (m *InsertQuery) XXX_DiscardUnknown() { xxx_messageInfo_InsertQuery.DiscardUnknown(m) } var xxx_messageInfo_InsertQuery proto.InternalMessageInfo func (m *InsertQuery) GetUsers() []*User { if m != nil { return m.Users } return nil } type UpdateQuery struct { // The queries to use in the update call. Queries []string `protobuf:"bytes,1,rep,name=Queries,proto3" json:"Queries,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *UpdateQuery) Reset() { *m = UpdateQuery{} } func (m *UpdateQuery) String() string { return proto.CompactTextString(m) } func (*UpdateQuery) ProtoMessage() {} func (*UpdateQuery) Descriptor() ([]byte, []int) { return fileDescriptor_879d3e919e93c6ba, []int{3} } func (m *UpdateQuery) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_UpdateQuery.Unmarshal(m, b) } func (m *UpdateQuery) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_UpdateQuery.Marshal(b, m, deterministic) } func (m *UpdateQuery) XXX_Merge(src proto.Message) { xxx_messageInfo_UpdateQuery.Merge(m, src) } func (m *UpdateQuery) XXX_Size() int { return xxx_messageInfo_UpdateQuery.Size(m) } func (m *UpdateQuery) XXX_DiscardUnknown() { xxx_messageInfo_UpdateQuery.DiscardUnknown(m) } var xxx_messageInfo_UpdateQuery proto.InternalMessageInfo func (m *UpdateQuery) GetQueries() []string { if m != nil { return m.Queries } return nil } type EmptyResponse struct { XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *EmptyResponse) Reset() { *m = EmptyResponse{} } func (m *EmptyResponse) String() string { return proto.CompactTextString(m) } func (*EmptyResponse) ProtoMessage() {} func (*EmptyResponse) Descriptor() ([]byte, []int) { return fileDescriptor_879d3e919e93c6ba, []int{4} } func (m *EmptyResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_EmptyResponse.Unmarshal(m, b) } func (m *EmptyResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_EmptyResponse.Marshal(b, m, deterministic) } func (m *EmptyResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_EmptyResponse.Merge(m, src) } func (m *EmptyResponse) XXX_Size() int { return xxx_messageInfo_EmptyResponse.Size(m) } func (m *EmptyResponse) XXX_DiscardUnknown() { xxx_messageInfo_EmptyResponse.DiscardUnknown(m) } var xxx_messageInfo_EmptyResponse proto.InternalMessageInfo func init() { proto.RegisterType((*ReadQuery)(nil), "spanner_bench.ReadQuery") proto.RegisterType((*User)(nil), "spanner_bench.User") proto.RegisterType((*InsertQuery)(nil), "spanner_bench.InsertQuery") proto.RegisterType((*UpdateQuery)(nil), "spanner_bench.UpdateQuery") proto.RegisterType((*EmptyResponse)(nil), "spanner_bench.EmptyResponse") } func init() { proto.RegisterFile("spanner.proto", fileDescriptor_879d3e919e93c6ba) } var fileDescriptor_879d3e919e93c6ba = []byte{ // 254 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x91, 0xb1, 0x4e, 0xc3, 0x30, 0x10, 0x86, 0x31, 0x49, 0x8b, 0x72, 0x51, 0x05, 0xba, 0x32, 0x58, 0x15, 0x43, 0xf0, 0x42, 0x90, 0x50, 0x86, 0xb2, 0x30, 0x22, 0x04, 0x03, 0x23, 0x46, 0x15, 0x23, 0x72, 0xe9, 0x09, 0x18, 0xea, 0x58, 0xb6, 0x3b, 0xf4, 0x79, 0x79, 0x11, 0xe4, 0x1c, 0x45, 0x6d, 0x18, 0xe8, 0xf6, 0xff, 0xf2, 0xdd, 0x77, 0xfa, 0x64, 0x18, 0x05, 0x67, 0xac, 0x25, 0xdf, 0x38, 0xdf, 0xc6, 0x16, 0x37, 0xf5, 0x75, 0x4e, 0xf6, 0xed, 0x43, 0x9d, 0x43, 0xa1, 0xc9, 0x2c, 0x9e, 0x56, 0xe4, 0xd7, 0x78, 0x0a, 0x83, 0x2e, 0x48, 0x51, 0x89, 0xba, 0xd0, 0x5c, 0xd4, 0x15, 0xe4, 0xb3, 0x40, 0x1e, 0x11, 0x72, 0x6b, 0x96, 0xf4, 0xf3, 0xd8, 0x65, 0x3c, 0x81, 0xcc, 0xbc, 0x93, 0x3c, 0xac, 0x44, 0x9d, 0xe9, 0x14, 0xd5, 0x0d, 0x94, 0x8f, 0x36, 0x90, 0x8f, 0x8c, 0xbc, 0x84, 0xc1, 0x2a, 0x90, 0x0f, 0x52, 0x54, 0x59, 0x5d, 0x4e, 0xc7, 0xcd, 0xce, 0xf9, 0x26, 0x81, 0x35, 0x4f, 0xa8, 0x0b, 0x28, 0x67, 0x6e, 0x61, 0x22, 0xf1, 0xa6, 0x84, 0xa3, 0x14, 0x3e, 0x89, 0x77, 0x0b, 0xbd, 0xa9, 0xea, 0x18, 0x46, 0x0f, 0x4b, 0x17, 0xd7, 0x9a, 0x82, 0x6b, 0x6d, 0xa0, 0xe9, 0x97, 0x80, 0xf1, 0x33, 0x73, 0xef, 0x12, 0xf6, 0xc5, 0x1b, 0xe7, 0xc8, 0xe3, 0x2d, 0xe4, 0x49, 0x0e, 0x65, 0xef, 0xea, 0xaf, 0xf1, 0xe4, 0xac, 0xf7, 0xb2, 0xc3, 0x55, 0x07, 0x78, 0x0f, 0x43, 0xb6, 0xc1, 0x49, 0x6f, 0x72, 0x4b, 0x72, 0x1f, 0x0a, 0x9b, 0xfd, 0xa1, 0x6c, 0x09, 0xff, 0x47, 0x99, 0x0f, 0xbb, 0x0f, 0xbc, 0xfe, 0x0e, 0x00, 0x00, 0xff, 0xff, 0x1e, 0x2e, 0xa6, 0x11, 0xd1, 0x01, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. var _ context.Context var _ grpc.ClientConn // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. const _ = grpc.SupportPackageIsVersion4 // SpannerBenchWrapperClient is the client API for SpannerBenchWrapper service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type SpannerBenchWrapperClient interface { // Read represents operations like Go's ReadOnlyTransaction.Query, Java's // ReadOnlyTransaction.executeQuery, Python's snapshot.read, and Node's // Transaction.Read. // // It will typically be used to read many items. Read(ctx context.Context, in *ReadQuery, opts ...grpc.CallOption) (*EmptyResponse, error) // Insert represents operations like Go's Client.Apply, Java's // DatabaseClient.writeAtLeastOnce, Python's transaction.commit, and Node's // Transaction.Commit. // // It will typically be used to insert many items. Insert(ctx context.Context, in *InsertQuery, opts ...grpc.CallOption) (*EmptyResponse, error) // Update represents operations like Go's ReadWriteTransaction.BatchUpdate, // Java's TransactionRunner.run, Python's Batch.update, and Node's // Transaction.BatchUpdate. // // It will typically be used to update many items. Update(ctx context.Context, in *UpdateQuery, opts ...grpc.CallOption) (*EmptyResponse, error) } type spannerBenchWrapperClient struct { cc *grpc.ClientConn } func NewSpannerBenchWrapperClient(cc *grpc.ClientConn) SpannerBenchWrapperClient { return &spannerBenchWrapperClient{cc} } func (c *spannerBenchWrapperClient) Read(ctx context.Context, in *ReadQuery, opts ...grpc.CallOption) (*EmptyResponse, error) { out := new(EmptyResponse) err := c.cc.Invoke(ctx, "/spanner_bench.SpannerBenchWrapper/Read", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *spannerBenchWrapperClient) Insert(ctx context.Context, in *InsertQuery, opts ...grpc.CallOption) (*EmptyResponse, error) { out := new(EmptyResponse) err := c.cc.Invoke(ctx, "/spanner_bench.SpannerBenchWrapper/Insert", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *spannerBenchWrapperClient) Update(ctx context.Context, in *UpdateQuery, opts ...grpc.CallOption) (*EmptyResponse, error) { out := new(EmptyResponse) err := c.cc.Invoke(ctx, "/spanner_bench.SpannerBenchWrapper/Update", in, out, opts...) if err != nil { return nil, err } return out, nil } // SpannerBenchWrapperServer is the server API for SpannerBenchWrapper service. type SpannerBenchWrapperServer interface { // Read represents operations like Go's ReadOnlyTransaction.Query, Java's // ReadOnlyTransaction.executeQuery, Python's snapshot.read, and Node's // Transaction.Read. // // It will typically be used to read many items. Read(context.Context, *ReadQuery) (*EmptyResponse, error) // Insert represents operations like Go's Client.Apply, Java's // DatabaseClient.writeAtLeastOnce, Python's transaction.commit, and Node's // Transaction.Commit. // // It will typically be used to insert many items. Insert(context.Context, *InsertQuery) (*EmptyResponse, error) // Update represents operations like Go's ReadWriteTransaction.BatchUpdate, // Java's TransactionRunner.run, Python's Batch.update, and Node's // Transaction.BatchUpdate. // // It will typically be used to update many items. Update(context.Context, *UpdateQuery) (*EmptyResponse, error) } // UnimplementedSpannerBenchWrapperServer can be embedded to have forward compatible implementations. type UnimplementedSpannerBenchWrapperServer struct { } func (*UnimplementedSpannerBenchWrapperServer) Read(ctx context.Context, req *ReadQuery) (*EmptyResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Read not implemented") } func (*UnimplementedSpannerBenchWrapperServer) Insert(ctx context.Context, req *InsertQuery) (*EmptyResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Insert not implemented") } func (*UnimplementedSpannerBenchWrapperServer) Update(ctx context.Context, req *UpdateQuery) (*EmptyResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Update not implemented") } func RegisterSpannerBenchWrapperServer(s *grpc.Server, srv SpannerBenchWrapperServer) { s.RegisterService(&_SpannerBenchWrapper_serviceDesc, srv) } func _SpannerBenchWrapper_Read_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ReadQuery) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(SpannerBenchWrapperServer).Read(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/spanner_bench.SpannerBenchWrapper/Read", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(SpannerBenchWrapperServer).Read(ctx, req.(*ReadQuery)) } return interceptor(ctx, in, info, handler) } func _SpannerBenchWrapper_Insert_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(InsertQuery) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(SpannerBenchWrapperServer).Insert(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/spanner_bench.SpannerBenchWrapper/Insert", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(SpannerBenchWrapperServer).Insert(ctx, req.(*InsertQuery)) } return interceptor(ctx, in, info, handler) } func _SpannerBenchWrapper_Update_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(UpdateQuery) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(SpannerBenchWrapperServer).Update(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/spanner_bench.SpannerBenchWrapper/Update", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(SpannerBenchWrapperServer).Update(ctx, req.(*UpdateQuery)) } return interceptor(ctx, in, info, handler) } var _SpannerBenchWrapper_serviceDesc = grpc.ServiceDesc{ ServiceName: "spanner_bench.SpannerBenchWrapper", HandlerType: (*SpannerBenchWrapperServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "Read", Handler: _SpannerBenchWrapper_Read_Handler, }, { MethodName: "Insert", Handler: _SpannerBenchWrapper_Insert_Handler, }, { MethodName: "Update", Handler: _SpannerBenchWrapper_Update_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "spanner.proto", } google-cloud-go-0.49.0/spanner/internal/benchwrapper/proto/spanner.proto000066400000000000000000000035071356504100700264350ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. syntax = "proto3"; package spanner_bench; message ReadQuery{ // The query to use in the read call. string Query = 1; } message User{ string name = 1; int64 age = 2; } message InsertQuery{ // The query to use in the insert call. repeated User users = 1; } message UpdateQuery{ // The queries to use in the update call. repeated string Queries = 1; } message EmptyResponse{ } service SpannerBenchWrapper{ // Read represents operations like Go's ReadOnlyTransaction.Query, Java's // ReadOnlyTransaction.executeQuery, Python's snapshot.read, and Node's // Transaction.Read. // // It will typically be used to read many items. rpc Read(ReadQuery) returns (EmptyResponse) {} // Insert represents operations like Go's Client.Apply, Java's // DatabaseClient.writeAtLeastOnce, Python's transaction.commit, and Node's // Transaction.Commit. // // It will typically be used to insert many items. rpc Insert(InsertQuery) returns (EmptyResponse){} // Update represents operations like Go's ReadWriteTransaction.BatchUpdate, // Java's TransactionRunner.run, Python's Batch.update, and Node's // Transaction.BatchUpdate. // // It will typically be used to update many items. rpc Update(UpdateQuery) returns (EmptyResponse){} } google-cloud-go-0.49.0/spanner/internal/testutil/000077500000000000000000000000001356504100700217275ustar00rootroot00000000000000google-cloud-go-0.49.0/spanner/internal/testutil/inmem_spanner_server.go000066400000000000000000000717111356504100700265060ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package testutil import ( "bytes" "context" "fmt" "math/rand" "sort" "strings" "sync" "time" emptypb "github.com/golang/protobuf/ptypes/empty" structpb "github.com/golang/protobuf/ptypes/struct" "github.com/golang/protobuf/ptypes/timestamp" "google.golang.org/genproto/googleapis/rpc/status" spannerpb "google.golang.org/genproto/googleapis/spanner/v1" "google.golang.org/grpc/codes" gstatus "google.golang.org/grpc/status" ) // StatementResultType indicates the type of result returned by a SQL // statement. type StatementResultType int const ( // StatementResultError indicates that the sql statement returns an error. StatementResultError StatementResultType = 0 // StatementResultResultSet indicates that the sql statement returns a // result set. StatementResultResultSet StatementResultType = 1 // StatementResultUpdateCount indicates that the sql statement returns an // update count. StatementResultUpdateCount StatementResultType = 2 // MaxRowsPerPartialResultSet is the maximum number of rows returned in // each PartialResultSet. This number is deliberately set to a low value to // ensure that most queries return more than one PartialResultSet. MaxRowsPerPartialResultSet = 1 ) // The method names that can be used to register execution times and errors. const ( MethodBeginTransaction string = "BEGIN_TRANSACTION" MethodCommitTransaction string = "COMMIT_TRANSACTION" MethodBatchCreateSession string = "BATCH_CREATE_SESSION" MethodCreateSession string = "CREATE_SESSION" MethodDeleteSession string = "DELETE_SESSION" MethodGetSession string = "GET_SESSION" MethodExecuteSql string = "EXECUTE_SQL" MethodExecuteStreamingSql string = "EXECUTE_STREAMING_SQL" ) // StatementResult represents a mocked result on the test server. The result is // either of: a ResultSet, an update count or an error. type StatementResult struct { Type StatementResultType Err error ResultSet *spannerpb.ResultSet UpdateCount int64 } // PartialResultSetExecutionTime represents execution times and errors that // should be used when a PartialResult at the specified resume token is to // be returned. type PartialResultSetExecutionTime struct { ResumeToken []byte ExecutionTime time.Duration Err error } // Converts a ResultSet to a PartialResultSet. This method is used to convert // a mocked result to a PartialResultSet when one of the streaming methods are // called. func (s *StatementResult) toPartialResultSets(resumeToken []byte) (result []*spannerpb.PartialResultSet, err error) { var startIndex uint64 if len(resumeToken) > 0 { if startIndex, err = DecodeResumeToken(resumeToken); err != nil { return nil, err } } totalRows := uint64(len(s.ResultSet.Rows)) for { rowCount := min(totalRows-startIndex, uint64(MaxRowsPerPartialResultSet)) rows := s.ResultSet.Rows[startIndex : startIndex+rowCount] values := make([]*structpb.Value, len(rows)*len(s.ResultSet.Metadata.RowType.Fields)) var idx int for _, row := range rows { for colIdx := range s.ResultSet.Metadata.RowType.Fields { values[idx] = row.Values[colIdx] idx++ } } result = append(result, &spannerpb.PartialResultSet{ Metadata: s.ResultSet.Metadata, Values: values, ResumeToken: EncodeResumeToken(startIndex + rowCount), }) startIndex += rowCount if startIndex == totalRows { break } } return result, nil } func min(x, y uint64) uint64 { if x > y { return y } return x } func (s *StatementResult) updateCountToPartialResultSet(exact bool) *spannerpb.PartialResultSet { return &spannerpb.PartialResultSet{ Stats: s.convertUpdateCountToResultSet(exact).Stats, } } // Converts an update count to a ResultSet, as DML statements also return the // update count as the statistics of a ResultSet. func (s *StatementResult) convertUpdateCountToResultSet(exact bool) *spannerpb.ResultSet { if exact { return &spannerpb.ResultSet{ Stats: &spannerpb.ResultSetStats{ RowCount: &spannerpb.ResultSetStats_RowCountExact{ RowCountExact: s.UpdateCount, }, }, } } return &spannerpb.ResultSet{ Stats: &spannerpb.ResultSetStats{ RowCount: &spannerpb.ResultSetStats_RowCountLowerBound{ RowCountLowerBound: s.UpdateCount, }, }, } } // SimulatedExecutionTime represents the time the execution of a method // should take, and any errors that should be returned by the method. type SimulatedExecutionTime struct { MinimumExecutionTime time.Duration RandomExecutionTime time.Duration Errors []error // Keep error after execution. The error will continue to be returned until // it is cleared. KeepError bool } // InMemSpannerServer contains the SpannerServer interface plus a couple // of specific methods for adding mocked results and resetting the server. type InMemSpannerServer interface { spannerpb.SpannerServer // Stops this server. Stop() // Resets the in-mem server to its default state, deleting all sessions and // transactions that have been created on the server. Mocked results are // not deleted. Reset() // Sets an error that will be returned by the next server call. The server // call will also automatically clear the error. SetError(err error) // Puts a mocked result on the server for a specific sql statement. The // server does not parse the SQL string in any way, it is merely used as // a key to the mocked result. The result will be used for all methods that // expect a SQL statement, including (batch) DML methods. PutStatementResult(sql string, result *StatementResult) error // Adds a PartialResultSetExecutionTime to the server that should be returned // for the specified SQL string. AddPartialResultSetError(sql string, err PartialResultSetExecutionTime) // Removes a mocked result on the server for a specific sql statement. RemoveStatementResult(sql string) // Aborts the specified transaction . This method can be used to test // transaction retry logic. AbortTransaction(id []byte) // Puts a simulated execution time for one of the Spanner methods. PutExecutionTime(method string, executionTime SimulatedExecutionTime) // Freeze stalls all requests. Freeze() // Unfreeze restores processing requests. Unfreeze() TotalSessionsCreated() uint TotalSessionsDeleted() uint SetMaxSessionsReturnedByServerPerBatchRequest(sessionCount int32) SetMaxSessionsReturnedByServerInTotal(sessionCount int32) ReceivedRequests() chan interface{} DumpSessions() map[string]bool ClearPings() DumpPings() []string } type inMemSpannerServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. spannerpb.SpannerServer mu sync.Mutex // Set to true when this server been stopped. This is the end state of a // server, a stopped server cannot be restarted. stopped bool // If set, all calls return this error. err error // The mock server creates session IDs using this counter. sessionCounter uint64 // The sessions that have been created on this mock server. sessions map[string]*spannerpb.Session // Last use times per session. sessionLastUseTime map[string]time.Time // The mock server creates transaction IDs per session using these // counters. transactionCounters map[string]*uint64 // The transactions that have been created on this mock server. transactions map[string]*spannerpb.Transaction // The transactions that have been (manually) aborted on the server. abortedTransactions map[string]bool // The transactions that are marked as PartitionedDMLTransaction partitionedDmlTransactions map[string]bool // The mocked results for this server. statementResults map[string]*StatementResult // The simulated execution times per method. executionTimes map[string]*SimulatedExecutionTime // The simulated errors for partial result sets partialResultSetErrors map[string][]*PartialResultSetExecutionTime totalSessionsCreated uint totalSessionsDeleted uint // The maximum number of sessions that will be created per batch request. maxSessionsReturnedByServerPerBatchRequest int32 maxSessionsReturnedByServerInTotal int32 receivedRequests chan interface{} // Session ping history. pings []string // Server will stall on any requests. freezed chan struct{} } // NewInMemSpannerServer creates a new in-mem test server. func NewInMemSpannerServer() InMemSpannerServer { res := &inMemSpannerServer{} res.initDefaults() res.statementResults = make(map[string]*StatementResult) res.executionTimes = make(map[string]*SimulatedExecutionTime) res.partialResultSetErrors = make(map[string][]*PartialResultSetExecutionTime) res.receivedRequests = make(chan interface{}, 1000000) // Produce a closed channel, so the default action of ready is to not block. res.Freeze() res.Unfreeze() return res } func (s *inMemSpannerServer) Stop() { s.mu.Lock() defer s.mu.Unlock() s.stopped = true close(s.receivedRequests) } // Resets the test server to its initial state, deleting all sessions and // transactions that have been created on the server. This method will not // remove mocked results. func (s *inMemSpannerServer) Reset() { s.mu.Lock() defer s.mu.Unlock() close(s.receivedRequests) s.receivedRequests = make(chan interface{}, 1000000) s.initDefaults() } func (s *inMemSpannerServer) SetError(err error) { s.mu.Lock() defer s.mu.Unlock() s.err = err } // Registers a mocked result for a SQL statement on the server. func (s *inMemSpannerServer) PutStatementResult(sql string, result *StatementResult) error { s.mu.Lock() defer s.mu.Unlock() s.statementResults[sql] = result return nil } func (s *inMemSpannerServer) RemoveStatementResult(sql string) { s.mu.Lock() defer s.mu.Unlock() delete(s.statementResults, sql) } func (s *inMemSpannerServer) AbortTransaction(id []byte) { s.mu.Lock() defer s.mu.Unlock() s.abortedTransactions[string(id)] = true } func (s *inMemSpannerServer) PutExecutionTime(method string, executionTime SimulatedExecutionTime) { s.mu.Lock() defer s.mu.Unlock() s.executionTimes[method] = &executionTime } func (s *inMemSpannerServer) AddPartialResultSetError(sql string, partialResultSetError PartialResultSetExecutionTime) { s.mu.Lock() defer s.mu.Unlock() s.partialResultSetErrors[sql] = append(s.partialResultSetErrors[sql], &partialResultSetError) } // Freeze stalls all requests. func (s *inMemSpannerServer) Freeze() { s.mu.Lock() defer s.mu.Unlock() s.freezed = make(chan struct{}) } // Unfreeze restores processing requests. func (s *inMemSpannerServer) Unfreeze() { s.mu.Lock() defer s.mu.Unlock() close(s.freezed) } // ready checks conditions before executing requests func (s *inMemSpannerServer) ready() { s.mu.Lock() freezed := s.freezed s.mu.Unlock() // check if server should be freezed <-freezed } func (s *inMemSpannerServer) TotalSessionsCreated() uint { s.mu.Lock() defer s.mu.Unlock() return s.totalSessionsCreated } func (s *inMemSpannerServer) TotalSessionsDeleted() uint { s.mu.Lock() defer s.mu.Unlock() return s.totalSessionsDeleted } func (s *inMemSpannerServer) SetMaxSessionsReturnedByServerPerBatchRequest(sessionCount int32) { s.mu.Lock() defer s.mu.Unlock() s.maxSessionsReturnedByServerPerBatchRequest = sessionCount } func (s *inMemSpannerServer) SetMaxSessionsReturnedByServerInTotal(sessionCount int32) { s.mu.Lock() defer s.mu.Unlock() s.maxSessionsReturnedByServerInTotal = sessionCount } func (s *inMemSpannerServer) ReceivedRequests() chan interface{} { return s.receivedRequests } // ClearPings clears the ping history from the server. func (s *inMemSpannerServer) ClearPings() { s.mu.Lock() defer s.mu.Unlock() s.pings = nil } // DumpPings dumps the ping history. func (s *inMemSpannerServer) DumpPings() []string { s.mu.Lock() defer s.mu.Unlock() return append([]string(nil), s.pings...) } // DumpSessions dumps the internal session table. func (s *inMemSpannerServer) DumpSessions() map[string]bool { s.mu.Lock() defer s.mu.Unlock() st := map[string]bool{} for s := range s.sessions { st[s] = true } return st } func (s *inMemSpannerServer) initDefaults() { s.sessionCounter = 0 s.maxSessionsReturnedByServerPerBatchRequest = 100 s.sessions = make(map[string]*spannerpb.Session) s.sessionLastUseTime = make(map[string]time.Time) s.transactions = make(map[string]*spannerpb.Transaction) s.abortedTransactions = make(map[string]bool) s.partitionedDmlTransactions = make(map[string]bool) s.transactionCounters = make(map[string]*uint64) } func (s *inMemSpannerServer) generateSessionNameLocked(database string) string { s.sessionCounter++ return fmt.Sprintf("%s/sessions/%d", database, s.sessionCounter) } func (s *inMemSpannerServer) findSession(name string) (*spannerpb.Session, error) { s.mu.Lock() defer s.mu.Unlock() session := s.sessions[name] if session == nil { return nil, gstatus.Error(codes.NotFound, fmt.Sprintf("Session %s not found", name)) } return session, nil } func (s *inMemSpannerServer) updateSessionLastUseTime(session string) { s.mu.Lock() defer s.mu.Unlock() s.sessionLastUseTime[session] = time.Now() } func getCurrentTimestamp() *timestamp.Timestamp { t := time.Now() return ×tamp.Timestamp{Seconds: t.Unix(), Nanos: int32(t.Nanosecond())} } // Gets the transaction id from the transaction selector. If the selector // specifies that a new transaction should be started, this method will start // a new transaction and return the id of that transaction. func (s *inMemSpannerServer) getTransactionID(session *spannerpb.Session, txSelector *spannerpb.TransactionSelector) []byte { var res []byte if txSelector.GetBegin() != nil { // Start a new transaction. res = s.beginTransaction(session, txSelector.GetBegin()).Id } else if txSelector.GetId() != nil { res = txSelector.GetId() } return res } func (s *inMemSpannerServer) generateTransactionName(session string) string { s.mu.Lock() defer s.mu.Unlock() counter, ok := s.transactionCounters[session] if !ok { counter = new(uint64) s.transactionCounters[session] = counter } *counter++ return fmt.Sprintf("%s/transactions/%d", session, *counter) } func (s *inMemSpannerServer) beginTransaction(session *spannerpb.Session, options *spannerpb.TransactionOptions) *spannerpb.Transaction { id := s.generateTransactionName(session.Name) res := &spannerpb.Transaction{ Id: []byte(id), ReadTimestamp: getCurrentTimestamp(), } s.mu.Lock() s.transactions[id] = res s.partitionedDmlTransactions[id] = options.GetPartitionedDml() != nil s.mu.Unlock() return res } func (s *inMemSpannerServer) getTransactionByID(id []byte) (*spannerpb.Transaction, error) { s.mu.Lock() defer s.mu.Unlock() tx, ok := s.transactions[string(id)] if !ok { return nil, gstatus.Error(codes.NotFound, "Transaction not found") } aborted, ok := s.abortedTransactions[string(id)] if ok && aborted { return nil, gstatus.Error(codes.Aborted, "Transaction has been aborted") } return tx, nil } func (s *inMemSpannerServer) removeTransaction(tx *spannerpb.Transaction) { s.mu.Lock() defer s.mu.Unlock() delete(s.transactions, string(tx.Id)) delete(s.partitionedDmlTransactions, string(tx.Id)) } func (s *inMemSpannerServer) getStatementResult(sql string) (*StatementResult, error) { s.mu.Lock() defer s.mu.Unlock() result, ok := s.statementResults[sql] if !ok { return nil, gstatus.Error(codes.Internal, fmt.Sprintf("No result found for statement %v", sql)) } return result, nil } func (s *inMemSpannerServer) simulateExecutionTime(method string, req interface{}) error { s.mu.Lock() if s.stopped { s.mu.Unlock() return gstatus.Error(codes.Unavailable, "server has been stopped") } s.receivedRequests <- req s.mu.Unlock() s.ready() s.mu.Lock() if s.err != nil { err := s.err s.err = nil s.mu.Unlock() return err } executionTime, ok := s.executionTimes[method] s.mu.Unlock() if ok { var randTime int64 if executionTime.RandomExecutionTime > 0 { randTime = rand.Int63n(int64(executionTime.RandomExecutionTime)) } totalExecutionTime := time.Duration(int64(executionTime.MinimumExecutionTime) + randTime) <-time.After(totalExecutionTime) s.mu.Lock() if executionTime.Errors != nil && len(executionTime.Errors) > 0 { err := executionTime.Errors[0] if !executionTime.KeepError { executionTime.Errors = executionTime.Errors[1:] } s.mu.Unlock() return err } s.mu.Unlock() } return nil } func (s *inMemSpannerServer) CreateSession(ctx context.Context, req *spannerpb.CreateSessionRequest) (*spannerpb.Session, error) { if err := s.simulateExecutionTime(MethodCreateSession, req); err != nil { return nil, err } if req.Database == "" { return nil, gstatus.Error(codes.InvalidArgument, "Missing database") } s.mu.Lock() defer s.mu.Unlock() if s.maxSessionsReturnedByServerInTotal > int32(0) && int32(len(s.sessions)) == s.maxSessionsReturnedByServerInTotal { return nil, gstatus.Error(codes.ResourceExhausted, "No more sessions available") } sessionName := s.generateSessionNameLocked(req.Database) ts := getCurrentTimestamp() session := &spannerpb.Session{Name: sessionName, CreateTime: ts, ApproximateLastUseTime: ts} s.totalSessionsCreated++ s.sessions[sessionName] = session return session, nil } func (s *inMemSpannerServer) BatchCreateSessions(ctx context.Context, req *spannerpb.BatchCreateSessionsRequest) (*spannerpb.BatchCreateSessionsResponse, error) { if err := s.simulateExecutionTime(MethodBatchCreateSession, req); err != nil { return nil, err } if req.Database == "" { return nil, gstatus.Error(codes.InvalidArgument, "Missing database") } if req.SessionCount <= 0 { return nil, gstatus.Error(codes.InvalidArgument, "Session count must be >= 0") } sessionsToCreate := req.SessionCount s.mu.Lock() defer s.mu.Unlock() if s.maxSessionsReturnedByServerInTotal > int32(0) && int32(len(s.sessions)) >= s.maxSessionsReturnedByServerInTotal { return nil, gstatus.Error(codes.ResourceExhausted, "No more sessions available") } if sessionsToCreate > s.maxSessionsReturnedByServerPerBatchRequest { sessionsToCreate = s.maxSessionsReturnedByServerPerBatchRequest } if s.maxSessionsReturnedByServerInTotal > int32(0) && (sessionsToCreate+int32(len(s.sessions))) > s.maxSessionsReturnedByServerInTotal { sessionsToCreate = s.maxSessionsReturnedByServerInTotal - int32(len(s.sessions)) } sessions := make([]*spannerpb.Session, sessionsToCreate) for i := int32(0); i < sessionsToCreate; i++ { sessionName := s.generateSessionNameLocked(req.Database) ts := getCurrentTimestamp() sessions[i] = &spannerpb.Session{Name: sessionName, CreateTime: ts, ApproximateLastUseTime: ts} s.totalSessionsCreated++ s.sessions[sessionName] = sessions[i] } return &spannerpb.BatchCreateSessionsResponse{Session: sessions}, nil } func (s *inMemSpannerServer) GetSession(ctx context.Context, req *spannerpb.GetSessionRequest) (*spannerpb.Session, error) { if err := s.simulateExecutionTime(MethodGetSession, req); err != nil { return nil, err } s.mu.Lock() s.pings = append(s.pings, req.Name) s.mu.Unlock() if req.Name == "" { return nil, gstatus.Error(codes.InvalidArgument, "Missing session name") } session, err := s.findSession(req.Name) if err != nil { return nil, err } return session, nil } func (s *inMemSpannerServer) ListSessions(ctx context.Context, req *spannerpb.ListSessionsRequest) (*spannerpb.ListSessionsResponse, error) { s.mu.Lock() if s.stopped { s.mu.Unlock() return nil, gstatus.Error(codes.Unavailable, "server has been stopped") } s.receivedRequests <- req s.mu.Unlock() if req.Database == "" { return nil, gstatus.Error(codes.InvalidArgument, "Missing database") } expectedSessionName := req.Database + "/sessions/" var sessions []*spannerpb.Session s.mu.Lock() for _, session := range s.sessions { if strings.Index(session.Name, expectedSessionName) == 0 { sessions = append(sessions, session) } } s.mu.Unlock() sort.Slice(sessions[:], func(i, j int) bool { return sessions[i].Name < sessions[j].Name }) res := &spannerpb.ListSessionsResponse{Sessions: sessions} return res, nil } func (s *inMemSpannerServer) DeleteSession(ctx context.Context, req *spannerpb.DeleteSessionRequest) (*emptypb.Empty, error) { if err := s.simulateExecutionTime(MethodDeleteSession, req); err != nil { return nil, err } if req.Name == "" { return nil, gstatus.Error(codes.InvalidArgument, "Missing session name") } if _, err := s.findSession(req.Name); err != nil { return nil, err } s.mu.Lock() defer s.mu.Unlock() s.totalSessionsDeleted++ delete(s.sessions, req.Name) return &emptypb.Empty{}, nil } func (s *inMemSpannerServer) ExecuteSql(ctx context.Context, req *spannerpb.ExecuteSqlRequest) (*spannerpb.ResultSet, error) { if err := s.simulateExecutionTime(MethodExecuteSql, req); err != nil { return nil, err } if req.Session == "" { return nil, gstatus.Error(codes.InvalidArgument, "Missing session name") } session, err := s.findSession(req.Session) if err != nil { return nil, err } var id []byte s.updateSessionLastUseTime(session.Name) if id = s.getTransactionID(session, req.Transaction); id != nil { _, err = s.getTransactionByID(id) if err != nil { return nil, err } } statementResult, err := s.getStatementResult(req.Sql) if err != nil { return nil, err } s.mu.Lock() isPartitionedDml := s.partitionedDmlTransactions[string(id)] s.mu.Unlock() switch statementResult.Type { case StatementResultError: return nil, statementResult.Err case StatementResultResultSet: return statementResult.ResultSet, nil case StatementResultUpdateCount: return statementResult.convertUpdateCountToResultSet(!isPartitionedDml), nil } return nil, gstatus.Error(codes.Internal, "Unknown result type") } func (s *inMemSpannerServer) ExecuteStreamingSql(req *spannerpb.ExecuteSqlRequest, stream spannerpb.Spanner_ExecuteStreamingSqlServer) error { if err := s.simulateExecutionTime(MethodExecuteStreamingSql, req); err != nil { return err } if req.Session == "" { return gstatus.Error(codes.InvalidArgument, "Missing session name") } session, err := s.findSession(req.Session) if err != nil { return err } s.updateSessionLastUseTime(session.Name) var id []byte if id = s.getTransactionID(session, req.Transaction); id != nil { _, err = s.getTransactionByID(id) if err != nil { return err } } statementResult, err := s.getStatementResult(req.Sql) if err != nil { return err } s.mu.Lock() isPartitionedDml := s.partitionedDmlTransactions[string(id)] s.mu.Unlock() switch statementResult.Type { case StatementResultError: return statementResult.Err case StatementResultResultSet: parts, err := statementResult.toPartialResultSets(req.ResumeToken) if err != nil { return err } var nextPartialResultSetError *PartialResultSetExecutionTime s.mu.Lock() pErrors := s.partialResultSetErrors[req.Sql] if len(pErrors) > 0 { nextPartialResultSetError = pErrors[0] s.partialResultSetErrors[req.Sql] = pErrors[1:] } s.mu.Unlock() for _, part := range parts { if nextPartialResultSetError != nil && bytes.Equal(part.ResumeToken, nextPartialResultSetError.ResumeToken) { if nextPartialResultSetError.ExecutionTime > 0 { <-time.After(nextPartialResultSetError.ExecutionTime) } if nextPartialResultSetError.Err != nil { return nextPartialResultSetError.Err } } if err := stream.Send(part); err != nil { return err } } return nil case StatementResultUpdateCount: part := statementResult.updateCountToPartialResultSet(!isPartitionedDml) if err := stream.Send(part); err != nil { return err } return nil } return gstatus.Error(codes.Internal, "Unknown result type") } func (s *inMemSpannerServer) ExecuteBatchDml(ctx context.Context, req *spannerpb.ExecuteBatchDmlRequest) (*spannerpb.ExecuteBatchDmlResponse, error) { s.mu.Lock() if s.stopped { s.mu.Unlock() return nil, gstatus.Error(codes.Unavailable, "server has been stopped") } s.receivedRequests <- req s.mu.Unlock() if req.Session == "" { return nil, gstatus.Error(codes.InvalidArgument, "Missing session name") } session, err := s.findSession(req.Session) if err != nil { return nil, err } s.updateSessionLastUseTime(session.Name) var id []byte if id = s.getTransactionID(session, req.Transaction); id != nil { _, err = s.getTransactionByID(id) if err != nil { return nil, err } } s.mu.Lock() isPartitionedDml := s.partitionedDmlTransactions[string(id)] s.mu.Unlock() resp := &spannerpb.ExecuteBatchDmlResponse{} resp.ResultSets = make([]*spannerpb.ResultSet, len(req.Statements)) for idx, batchStatement := range req.Statements { statementResult, err := s.getStatementResult(batchStatement.Sql) if err != nil { return nil, err } switch statementResult.Type { case StatementResultError: resp.Status = &status.Status{Code: int32(codes.Unknown)} case StatementResultResultSet: return nil, gstatus.Error(codes.InvalidArgument, fmt.Sprintf("Not an update statement: %v", batchStatement.Sql)) case StatementResultUpdateCount: resp.ResultSets[idx] = statementResult.convertUpdateCountToResultSet(!isPartitionedDml) resp.Status = &status.Status{Code: int32(codes.OK)} } } return resp, nil } func (s *inMemSpannerServer) Read(ctx context.Context, req *spannerpb.ReadRequest) (*spannerpb.ResultSet, error) { s.mu.Lock() if s.stopped { s.mu.Unlock() return nil, gstatus.Error(codes.Unavailable, "server has been stopped") } s.receivedRequests <- req s.mu.Unlock() return nil, gstatus.Error(codes.Unimplemented, "Method not yet implemented") } func (s *inMemSpannerServer) StreamingRead(req *spannerpb.ReadRequest, stream spannerpb.Spanner_StreamingReadServer) error { s.mu.Lock() if s.stopped { s.mu.Unlock() return gstatus.Error(codes.Unavailable, "server has been stopped") } s.receivedRequests <- req s.mu.Unlock() return gstatus.Error(codes.Unimplemented, "Method not yet implemented") } func (s *inMemSpannerServer) BeginTransaction(ctx context.Context, req *spannerpb.BeginTransactionRequest) (*spannerpb.Transaction, error) { if err := s.simulateExecutionTime(MethodBeginTransaction, req); err != nil { return nil, err } if req.Session == "" { return nil, gstatus.Error(codes.InvalidArgument, "Missing session name") } session, err := s.findSession(req.Session) if err != nil { return nil, err } s.updateSessionLastUseTime(session.Name) tx := s.beginTransaction(session, req.Options) return tx, nil } func (s *inMemSpannerServer) Commit(ctx context.Context, req *spannerpb.CommitRequest) (*spannerpb.CommitResponse, error) { if err := s.simulateExecutionTime(MethodCommitTransaction, req); err != nil { return nil, err } if req.Session == "" { return nil, gstatus.Error(codes.InvalidArgument, "Missing session name") } session, err := s.findSession(req.Session) if err != nil { return nil, err } s.updateSessionLastUseTime(session.Name) var tx *spannerpb.Transaction if req.GetSingleUseTransaction() != nil { tx = s.beginTransaction(session, req.GetSingleUseTransaction()) } else if req.GetTransactionId() != nil { tx, err = s.getTransactionByID(req.GetTransactionId()) if err != nil { return nil, err } } else { return nil, gstatus.Error(codes.InvalidArgument, "Missing transaction in commit request") } s.removeTransaction(tx) return &spannerpb.CommitResponse{CommitTimestamp: getCurrentTimestamp()}, nil } func (s *inMemSpannerServer) Rollback(ctx context.Context, req *spannerpb.RollbackRequest) (*emptypb.Empty, error) { s.mu.Lock() if s.stopped { s.mu.Unlock() return nil, gstatus.Error(codes.Unavailable, "server has been stopped") } s.receivedRequests <- req s.mu.Unlock() if req.Session == "" { return nil, gstatus.Error(codes.InvalidArgument, "Missing session name") } session, err := s.findSession(req.Session) if err != nil { return nil, err } s.updateSessionLastUseTime(session.Name) tx, err := s.getTransactionByID(req.TransactionId) if err != nil { return nil, err } s.removeTransaction(tx) return &emptypb.Empty{}, nil } func (s *inMemSpannerServer) PartitionQuery(ctx context.Context, req *spannerpb.PartitionQueryRequest) (*spannerpb.PartitionResponse, error) { s.mu.Lock() if s.stopped { s.mu.Unlock() return nil, gstatus.Error(codes.Unavailable, "server has been stopped") } s.receivedRequests <- req s.mu.Unlock() return nil, gstatus.Error(codes.Unimplemented, "Method not yet implemented") } func (s *inMemSpannerServer) PartitionRead(ctx context.Context, req *spannerpb.PartitionReadRequest) (*spannerpb.PartitionResponse, error) { s.mu.Lock() if s.stopped { s.mu.Unlock() return nil, gstatus.Error(codes.Unavailable, "server has been stopped") } s.receivedRequests <- req s.mu.Unlock() return nil, gstatus.Error(codes.Unimplemented, "Method not yet implemented") } google-cloud-go-0.49.0/spanner/internal/testutil/inmem_spanner_server_test.go000066400000000000000000000430561356504100700275460ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package testutil_test import ( "strconv" . "cloud.google.com/go/spanner/internal/testutil" "context" "flag" "fmt" "log" "net" "os" "strings" "testing" structpb "github.com/golang/protobuf/ptypes/struct" spannerpb "google.golang.org/genproto/googleapis/spanner/v1" "google.golang.org/grpc/codes" apiv1 "cloud.google.com/go/spanner/apiv1" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/grpc" gstatus "google.golang.org/grpc/status" ) // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var serverAddress string var clientOpt option.ClientOption var testSpanner InMemSpannerServer // Mocked selectSQL statement. const selectSQL = "SELECT FOO FROM BAR" const selectRowCount int64 = 2 const selectColCount int = 1 var selectValues = [...]int64{1, 2} // Mocked DML statement. const updateSQL = "UPDATE FOO SET BAR=1 WHERE ID=ID" const updateRowCount int64 = 2 func TestMain(m *testing.M) { flag.Parse() testSpanner = NewInMemSpannerServer() serv := grpc.NewServer() spannerpb.RegisterSpannerServer(serv, testSpanner) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) serverAddress = lis.Addr().String() conn, err := grpc.Dial(serverAddress, grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } // Resets the mock server to its default values and registers a mocked result // for the statements "SELECT FOO FROM BAR" and // "UPDATE FOO SET BAR=1 WHERE ID=ID". func setup() { testSpanner.Reset() fields := make([]*spannerpb.StructType_Field, selectColCount) fields[0] = &spannerpb.StructType_Field{ Name: "FOO", Type: &spannerpb.Type{Code: spannerpb.TypeCode_INT64}, } rowType := &spannerpb.StructType{ Fields: fields, } metadata := &spannerpb.ResultSetMetadata{ RowType: rowType, } rows := make([]*structpb.ListValue, selectRowCount) for idx, value := range selectValues { rowValue := make([]*structpb.Value, selectColCount) rowValue[0] = &structpb.Value{ Kind: &structpb.Value_StringValue{StringValue: strconv.FormatInt(value, 10)}, } rows[idx] = &structpb.ListValue{ Values: rowValue, } } resultSet := &spannerpb.ResultSet{ Metadata: metadata, Rows: rows, } result := &StatementResult{Type: StatementResultResultSet, ResultSet: resultSet} testSpanner.PutStatementResult(selectSQL, result) updateResult := &StatementResult{Type: StatementResultUpdateCount, UpdateCount: updateRowCount} testSpanner.PutStatementResult(updateSQL, updateResult) } func TestSpannerCreateSession(t *testing.T) { testSpanner.Reset() var expectedName = fmt.Sprintf("projects/%s/instances/%s/databases/%s/sessions/", "[PROJECT]", "[INSTANCE]", "[DATABASE]") var formattedDatabase = fmt.Sprintf("projects/%s/instances/%s/databases/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]") var request = &spannerpb.CreateSessionRequest{ Database: formattedDatabase, } c, err := apiv1.NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateSession(context.Background(), request) if err != nil { t.Fatal(err) } if strings.Index(resp.Name, expectedName) != 0 { t.Errorf("Session name mismatch\nGot: %s\nWant: Name should start with %s)", resp.Name, expectedName) } } func TestSpannerCreateSession_Unavailable(t *testing.T) { testSpanner.Reset() var expectedName = fmt.Sprintf("projects/%s/instances/%s/databases/%s/sessions/", "[PROJECT]", "[INSTANCE]", "[DATABASE]") var formattedDatabase = fmt.Sprintf("projects/%s/instances/%s/databases/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]") var request = &spannerpb.CreateSessionRequest{ Database: formattedDatabase, } c, err := apiv1.NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } testSpanner.SetError(gstatus.Error(codes.Unavailable, "Temporary unavailable")) resp, err := c.CreateSession(context.Background(), request) if err != nil { t.Fatal(err) } if strings.Index(resp.Name, expectedName) != 0 { t.Errorf("Session name mismatch\nGot: %s\nWant: Name should start with %s)", resp.Name, expectedName) } } func TestSpannerGetSession(t *testing.T) { testSpanner.Reset() var formattedDatabase = fmt.Sprintf("projects/%s/instances/%s/databases/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]") var createRequest = &spannerpb.CreateSessionRequest{ Database: formattedDatabase, } c, err := apiv1.NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } createResp, err := c.CreateSession(context.Background(), createRequest) if err != nil { t.Fatal(err) } var getRequest = &spannerpb.GetSessionRequest{ Name: createResp.Name, } getResp, err := c.GetSession(context.Background(), getRequest) if err != nil { t.Fatal(err) } if getResp.Name != getRequest.Name { t.Errorf("Session name mismatch\nGot: %s\nWant: Name should start with %s)", getResp.Name, getRequest.Name) } } func TestSpannerListSessions(t *testing.T) { testSpanner.Reset() const expectedNumberOfSessions = 5 var expectedName = fmt.Sprintf("projects/%s/instances/%s/databases/%s/sessions/", "[PROJECT]", "[INSTANCE]", "[DATABASE]") var formattedDatabase = fmt.Sprintf("projects/%s/instances/%s/databases/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]") var createRequest = &spannerpb.CreateSessionRequest{ Database: formattedDatabase, } c, err := apiv1.NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } for i := 0; i < expectedNumberOfSessions; i++ { _, err := c.CreateSession(context.Background(), createRequest) if err != nil { t.Fatal(err) } } var listRequest = &spannerpb.ListSessionsRequest{ Database: formattedDatabase, } var sessionCount int listResp := c.ListSessions(context.Background(), listRequest) for { session, err := listResp.Next() if err == iterator.Done { break } if err != nil { t.Fatal(err) } if strings.Index(session.Name, expectedName) != 0 { t.Errorf("Session name mismatch\nGot: %s\nWant: Name should start with %s)", session.Name, expectedName) } sessionCount++ } if sessionCount != expectedNumberOfSessions { t.Errorf("Session count mismatch\nGot: %d\nWant: %d", sessionCount, expectedNumberOfSessions) } } func TestSpannerDeleteSession(t *testing.T) { testSpanner.Reset() const expectedNumberOfSessions = 5 var formattedDatabase = fmt.Sprintf("projects/%s/instances/%s/databases/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]") var createRequest = &spannerpb.CreateSessionRequest{ Database: formattedDatabase, } c, err := apiv1.NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } for i := 0; i < expectedNumberOfSessions; i++ { _, err := c.CreateSession(context.Background(), createRequest) if err != nil { t.Fatal(err) } } var listRequest = &spannerpb.ListSessionsRequest{ Database: formattedDatabase, } var sessionCount int listResp := c.ListSessions(context.Background(), listRequest) for { session, err := listResp.Next() if err == iterator.Done { break } if err != nil { t.Fatal(err) } var deleteRequest = &spannerpb.DeleteSessionRequest{ Name: session.Name, } c.DeleteSession(context.Background(), deleteRequest) sessionCount++ } if sessionCount != expectedNumberOfSessions { t.Errorf("Session count mismatch\nGot: %d\nWant: %d", sessionCount, expectedNumberOfSessions) } // Re-list all sessions. This should now be empty. listResp = c.ListSessions(context.Background(), listRequest) _, err = listResp.Next() if err != iterator.Done { t.Errorf("expected empty session iterator") } } func TestSpannerExecuteSql(t *testing.T) { setup() c, err := apiv1.NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } var formattedDatabase = fmt.Sprintf("projects/%s/instances/%s/databases/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]") var createRequest = &spannerpb.CreateSessionRequest{ Database: formattedDatabase, } session, err := c.CreateSession(context.Background(), createRequest) if err != nil { t.Fatal(err) } request := &spannerpb.ExecuteSqlRequest{ Session: session.Name, Sql: selectSQL, Transaction: &spannerpb.TransactionSelector{ Selector: &spannerpb.TransactionSelector_SingleUse{ SingleUse: &spannerpb.TransactionOptions{ Mode: &spannerpb.TransactionOptions_ReadOnly_{ ReadOnly: &spannerpb.TransactionOptions_ReadOnly{ ReturnReadTimestamp: false, TimestampBound: &spannerpb.TransactionOptions_ReadOnly_Strong{ Strong: true, }, }, }, }, }, }, Seqno: 1, QueryMode: spannerpb.ExecuteSqlRequest_NORMAL, } response, err := c.ExecuteSql(context.Background(), request) if err != nil { t.Fatal(err) } var rowCount int64 for _, row := range response.Rows { if len(row.Values) != selectColCount { t.Fatalf("Column count mismatch\nGot: %d\nWant: %d", len(row.Values), selectColCount) } rowCount++ } if rowCount != selectRowCount { t.Fatalf("Row count mismatch\nGot: %d\nWant: %d", rowCount, selectRowCount) } } func TestSpannerExecuteSqlDml(t *testing.T) { setup() c, err := apiv1.NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } var formattedDatabase = fmt.Sprintf("projects/%s/instances/%s/databases/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]") var createRequest = &spannerpb.CreateSessionRequest{ Database: formattedDatabase, } session, err := c.CreateSession(context.Background(), createRequest) if err != nil { t.Fatal(err) } request := &spannerpb.ExecuteSqlRequest{ Session: session.Name, Sql: updateSQL, Transaction: &spannerpb.TransactionSelector{ Selector: &spannerpb.TransactionSelector_Begin{ Begin: &spannerpb.TransactionOptions{ Mode: &spannerpb.TransactionOptions_ReadWrite_{ ReadWrite: &spannerpb.TransactionOptions_ReadWrite{}, }, }, }, }, Seqno: 1, QueryMode: spannerpb.ExecuteSqlRequest_NORMAL, } response, err := c.ExecuteSql(context.Background(), request) if err != nil { t.Fatal(err) } var rowCount int64 = response.Stats.GetRowCountExact() if rowCount != updateRowCount { t.Fatalf("Update count mismatch\nGot: %d\nWant: %d", rowCount, updateRowCount) } } func TestSpannerExecuteStreamingSql(t *testing.T) { setup() c, err := apiv1.NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } var formattedDatabase = fmt.Sprintf("projects/%s/instances/%s/databases/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]") var createRequest = &spannerpb.CreateSessionRequest{ Database: formattedDatabase, } session, err := c.CreateSession(context.Background(), createRequest) if err != nil { t.Fatal(err) } request := &spannerpb.ExecuteSqlRequest{ Session: session.Name, Sql: selectSQL, Transaction: &spannerpb.TransactionSelector{ Selector: &spannerpb.TransactionSelector_SingleUse{ SingleUse: &spannerpb.TransactionOptions{ Mode: &spannerpb.TransactionOptions_ReadOnly_{ ReadOnly: &spannerpb.TransactionOptions_ReadOnly{ ReturnReadTimestamp: false, TimestampBound: &spannerpb.TransactionOptions_ReadOnly_Strong{ Strong: true, }, }, }, }, }, }, Seqno: 1, QueryMode: spannerpb.ExecuteSqlRequest_NORMAL, } response, err := c.ExecuteStreamingSql(context.Background(), request) if err != nil { t.Fatal(err) } var rowIndex int64 var colCount int for { for rowIndexInPartial := int64(0); rowIndexInPartial < MaxRowsPerPartialResultSet; rowIndexInPartial++ { partial, err := response.Recv() if err != nil { t.Fatal(err) } if rowIndex == 0 { colCount = len(partial.Metadata.RowType.Fields) if colCount != selectColCount { t.Fatalf("Column count mismatch\nGot: %d\nWant: %d", colCount, selectColCount) } } for col := 0; col < colCount; col++ { pIndex := rowIndexInPartial*int64(colCount) + int64(col) val, err := strconv.ParseInt(partial.Values[pIndex].GetStringValue(), 10, 64) if err != nil { t.Fatalf("Error parsing integer at #%d: %v", pIndex, err) } if val != selectValues[rowIndex] { t.Fatalf("Value mismatch at index %d\nGot: %d\nWant: %d", rowIndex, val, selectValues[rowIndex]) } } rowIndex++ } if rowIndex == selectRowCount { break } } if rowIndex != selectRowCount { t.Fatalf("Row count mismatch\nGot: %d\nWant: %d", rowIndex, selectRowCount) } } func TestSpannerExecuteBatchDml(t *testing.T) { setup() c, err := apiv1.NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } var formattedDatabase = fmt.Sprintf("projects/%s/instances/%s/databases/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]") var createRequest = &spannerpb.CreateSessionRequest{ Database: formattedDatabase, } session, err := c.CreateSession(context.Background(), createRequest) if err != nil { t.Fatal(err) } statements := make([]*spannerpb.ExecuteBatchDmlRequest_Statement, 3) for idx := 0; idx < len(statements); idx++ { statements[idx] = &spannerpb.ExecuteBatchDmlRequest_Statement{Sql: updateSQL} } executeBatchDmlRequest := &spannerpb.ExecuteBatchDmlRequest{ Session: session.Name, Statements: statements, Transaction: &spannerpb.TransactionSelector{ Selector: &spannerpb.TransactionSelector_Begin{ Begin: &spannerpb.TransactionOptions{ Mode: &spannerpb.TransactionOptions_ReadWrite_{ ReadWrite: &spannerpb.TransactionOptions_ReadWrite{}, }, }, }, }, Seqno: 1, } response, err := c.ExecuteBatchDml(context.Background(), executeBatchDmlRequest) if err != nil { t.Fatal(err) } var totalRowCount int64 for _, res := range response.ResultSets { var rowCount int64 = res.Stats.GetRowCountExact() if rowCount != updateRowCount { t.Fatalf("Update count mismatch\nGot: %d\nWant: %d", rowCount, updateRowCount) } totalRowCount += rowCount } if totalRowCount != updateRowCount*int64(len(statements)) { t.Fatalf("Total update count mismatch\nGot: %d\nWant: %d", totalRowCount, updateRowCount*int64(len(statements))) } } func TestBeginTransaction(t *testing.T) { setup() c, err := apiv1.NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } var formattedDatabase = fmt.Sprintf("projects/%s/instances/%s/databases/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]") var createRequest = &spannerpb.CreateSessionRequest{ Database: formattedDatabase, } session, err := c.CreateSession(context.Background(), createRequest) if err != nil { t.Fatal(err) } beginRequest := &spannerpb.BeginTransactionRequest{ Session: session.Name, Options: &spannerpb.TransactionOptions{ Mode: &spannerpb.TransactionOptions_ReadWrite_{ ReadWrite: &spannerpb.TransactionOptions_ReadWrite{}, }, }, } tx, err := c.BeginTransaction(context.Background(), beginRequest) if err != nil { t.Fatal(err) } expectedName := fmt.Sprintf("%s/transactions/", session.Name) if strings.Index(string(tx.Id), expectedName) != 0 { t.Errorf("Transaction name mismatch\nGot: %s\nWant: Name should start with %s)", string(tx.Id), expectedName) } } func TestCommitTransaction(t *testing.T) { setup() c, err := apiv1.NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } var formattedDatabase = fmt.Sprintf("projects/%s/instances/%s/databases/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]") var createRequest = &spannerpb.CreateSessionRequest{ Database: formattedDatabase, } session, err := c.CreateSession(context.Background(), createRequest) if err != nil { t.Fatal(err) } beginRequest := &spannerpb.BeginTransactionRequest{ Session: session.Name, Options: &spannerpb.TransactionOptions{ Mode: &spannerpb.TransactionOptions_ReadWrite_{ ReadWrite: &spannerpb.TransactionOptions_ReadWrite{}, }, }, } tx, err := c.BeginTransaction(context.Background(), beginRequest) if err != nil { t.Fatal(err) } commitRequest := &spannerpb.CommitRequest{ Session: session.Name, Transaction: &spannerpb.CommitRequest_TransactionId{ TransactionId: tx.Id, }, } resp, err := c.Commit(context.Background(), commitRequest) if err != nil { t.Fatal(err) } if resp.CommitTimestamp == nil { t.Fatalf("No commit timestamp returned") } } func TestRollbackTransaction(t *testing.T) { setup() c, err := apiv1.NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } var formattedDatabase = fmt.Sprintf("projects/%s/instances/%s/databases/%s", "[PROJECT]", "[INSTANCE]", "[DATABASE]") var createRequest = &spannerpb.CreateSessionRequest{ Database: formattedDatabase, } session, err := c.CreateSession(context.Background(), createRequest) if err != nil { t.Fatal(err) } beginRequest := &spannerpb.BeginTransactionRequest{ Session: session.Name, Options: &spannerpb.TransactionOptions{ Mode: &spannerpb.TransactionOptions_ReadWrite_{ ReadWrite: &spannerpb.TransactionOptions_ReadWrite{}, }, }, } tx, err := c.BeginTransaction(context.Background(), beginRequest) if err != nil { t.Fatal(err) } rollbackRequest := &spannerpb.RollbackRequest{ Session: session.Name, TransactionId: tx.Id, } err = c.Rollback(context.Background(), rollbackRequest) if err != nil { t.Fatal(err) } } google-cloud-go-0.49.0/spanner/internal/testutil/mockclient.go000066400000000000000000000225561356504100700244200ustar00rootroot00000000000000/* Copyright 2017 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package testutil import ( "context" "errors" "fmt" "sync" "testing" "time" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes/empty" proto3 "github.com/golang/protobuf/ptypes/struct" pbt "github.com/golang/protobuf/ptypes/timestamp" pbs "google.golang.org/genproto/googleapis/rpc/status" sppb "google.golang.org/genproto/googleapis/spanner/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) // MockCloudSpannerClient is a mock implementation of sppb.SpannerClient. type MockCloudSpannerClient struct { sppb.SpannerClient mu sync.Mutex t *testing.T // Live sessions on the client. sessions map[string]bool // Session ping history. pings []string // Client will stall on any requests. freezed chan struct{} // Expected set of actions that have been executed by the client. These // interfaces should be type reflected against with *Request types in sppb, // such as sppb.GetSessionRequest. Buffered to a large degree. ReceivedRequests chan interface{} } // NewMockCloudSpannerClient creates new MockCloudSpannerClient instance. func NewMockCloudSpannerClient(t *testing.T) *MockCloudSpannerClient { mc := &MockCloudSpannerClient{ t: t, sessions: map[string]bool{}, ReceivedRequests: make(chan interface{}, 100000), } // Produce a closed channel, so the default action of ready is to not block. mc.Freeze() mc.Unfreeze() return mc } // DumpPings dumps the ping history. func (m *MockCloudSpannerClient) DumpPings() []string { m.mu.Lock() defer m.mu.Unlock() return append([]string(nil), m.pings...) } // DumpSessions dumps the internal session table. func (m *MockCloudSpannerClient) DumpSessions() map[string]bool { m.mu.Lock() defer m.mu.Unlock() st := map[string]bool{} for s, v := range m.sessions { st[s] = v } return st } // CreateSession is a placeholder for SpannerClient.CreateSession. func (m *MockCloudSpannerClient) CreateSession(ctx context.Context, r *sppb.CreateSessionRequest, opts ...grpc.CallOption) (*sppb.Session, error) { m.ready() m.ReceivedRequests <- r m.mu.Lock() defer m.mu.Unlock() s := &sppb.Session{} if r.Database != "mockdb" { // Reject other databases return s, status.Errorf(codes.NotFound, fmt.Sprintf("database not found: %v", r.Database)) } // Generate & record session name. s.Name = fmt.Sprintf("mockdb-%v", time.Now().UnixNano()) m.sessions[s.Name] = true return s, nil } // GetSession is a placeholder for SpannerClient.GetSession. func (m *MockCloudSpannerClient) GetSession(ctx context.Context, r *sppb.GetSessionRequest, opts ...grpc.CallOption) (*sppb.Session, error) { m.ready() m.ReceivedRequests <- r m.mu.Lock() defer m.mu.Unlock() m.pings = append(m.pings, r.Name) if _, ok := m.sessions[r.Name]; !ok { return nil, status.Errorf(codes.NotFound, fmt.Sprintf("Session not found: %v", r.Name)) } return &sppb.Session{Name: r.Name}, nil } // DeleteSession is a placeholder for SpannerClient.DeleteSession. func (m *MockCloudSpannerClient) DeleteSession(ctx context.Context, r *sppb.DeleteSessionRequest, opts ...grpc.CallOption) (*empty.Empty, error) { m.ready() m.ReceivedRequests <- r m.mu.Lock() defer m.mu.Unlock() if _, ok := m.sessions[r.Name]; !ok { // Session not found. return &empty.Empty{}, status.Errorf(codes.NotFound, fmt.Sprintf("Session not found: %v", r.Name)) } // Delete session from in-memory table. delete(m.sessions, r.Name) return &empty.Empty{}, nil } // ExecuteSql is a placeholder for SpannerClient.ExecuteSql. func (m *MockCloudSpannerClient) ExecuteSql(ctx context.Context, r *sppb.ExecuteSqlRequest, opts ...grpc.CallOption) (*sppb.ResultSet, error) { m.ready() m.ReceivedRequests <- r m.mu.Lock() defer m.mu.Unlock() return &sppb.ResultSet{Stats: &sppb.ResultSetStats{RowCount: &sppb.ResultSetStats_RowCountExact{7}}}, nil } // ExecuteBatchDml is a placeholder for SpannerClient.ExecuteBatchDml. func (m *MockCloudSpannerClient) ExecuteBatchDml(ctx context.Context, r *sppb.ExecuteBatchDmlRequest, opts ...grpc.CallOption) (*sppb.ExecuteBatchDmlResponse, error) { m.ready() m.ReceivedRequests <- r m.mu.Lock() defer m.mu.Unlock() return &sppb.ExecuteBatchDmlResponse{Status: &pbs.Status{Code: 0}, ResultSets: []*sppb.ResultSet{}}, nil } // ExecuteStreamingSql is a mock implementation of SpannerClient.ExecuteStreamingSql. func (m *MockCloudSpannerClient) ExecuteStreamingSql(ctx context.Context, r *sppb.ExecuteSqlRequest, opts ...grpc.CallOption) (sppb.Spanner_ExecuteStreamingSqlClient, error) { m.ready() m.ReceivedRequests <- r m.mu.Lock() defer m.mu.Unlock() wantReq := &sppb.ExecuteSqlRequest{ Session: "mocksession", Transaction: &sppb.TransactionSelector{ Selector: &sppb.TransactionSelector_SingleUse{ SingleUse: &sppb.TransactionOptions{ Mode: &sppb.TransactionOptions_ReadOnly_{ ReadOnly: &sppb.TransactionOptions_ReadOnly{ TimestampBound: &sppb.TransactionOptions_ReadOnly_Strong{ Strong: true, }, ReturnReadTimestamp: false, }, }, }, }, }, Sql: "mockquery", Params: &proto3.Struct{ Fields: map[string]*proto3.Value{"var1": {Kind: &proto3.Value_StringValue{StringValue: "abc"}}}, }, ParamTypes: map[string]*sppb.Type{"var1": {Code: sppb.TypeCode_STRING}}, } if !proto.Equal(r, wantReq) { return nil, fmt.Errorf("got query request: %v, want: %v", r, wantReq) } return nil, errors.New("query never succeeds on mock client") } // StreamingRead is a placeholder for SpannerClient.StreamingRead. func (m *MockCloudSpannerClient) StreamingRead(ctx context.Context, r *sppb.ReadRequest, opts ...grpc.CallOption) (sppb.Spanner_StreamingReadClient, error) { m.ready() m.ReceivedRequests <- r m.mu.Lock() defer m.mu.Unlock() wantReq := &sppb.ReadRequest{ Session: "mocksession", Transaction: &sppb.TransactionSelector{ Selector: &sppb.TransactionSelector_SingleUse{ SingleUse: &sppb.TransactionOptions{ Mode: &sppb.TransactionOptions_ReadOnly_{ ReadOnly: &sppb.TransactionOptions_ReadOnly{ TimestampBound: &sppb.TransactionOptions_ReadOnly_Strong{ Strong: true, }, ReturnReadTimestamp: false, }, }, }, }, }, Table: "t_mock", Columns: []string{"col1", "col2"}, KeySet: &sppb.KeySet{ Keys: []*proto3.ListValue{ { Values: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: "foo"}}, }, }, }, Ranges: []*sppb.KeyRange{}, All: false, }, } if !proto.Equal(r, wantReq) { return nil, fmt.Errorf("got query request: %v, want: %v", r, wantReq) } return nil, errors.New("read never succeeds on mock client") } // BeginTransaction is a placeholder for SpannerClient.BeginTransaction. func (m *MockCloudSpannerClient) BeginTransaction(ctx context.Context, r *sppb.BeginTransactionRequest, opts ...grpc.CallOption) (*sppb.Transaction, error) { m.ready() m.ReceivedRequests <- r m.mu.Lock() defer m.mu.Unlock() resp := &sppb.Transaction{Id: []byte("transaction-1")} if _, ok := r.Options.Mode.(*sppb.TransactionOptions_ReadOnly_); ok { resp.ReadTimestamp = &pbt.Timestamp{Seconds: 3, Nanos: 4} } return resp, nil } // Commit is a placeholder for SpannerClient.Commit. func (m *MockCloudSpannerClient) Commit(ctx context.Context, r *sppb.CommitRequest, opts ...grpc.CallOption) (*sppb.CommitResponse, error) { m.ready() m.ReceivedRequests <- r m.mu.Lock() defer m.mu.Unlock() return &sppb.CommitResponse{CommitTimestamp: &pbt.Timestamp{Seconds: 1, Nanos: 2}}, nil } // Rollback is a placeholder for SpannerClient.Rollback. func (m *MockCloudSpannerClient) Rollback(ctx context.Context, r *sppb.RollbackRequest, opts ...grpc.CallOption) (*empty.Empty, error) { m.ready() m.ReceivedRequests <- r m.mu.Lock() defer m.mu.Unlock() return nil, nil } // PartitionQuery is a placeholder for SpannerServer.PartitionQuery. func (m *MockCloudSpannerClient) PartitionQuery(ctx context.Context, r *sppb.PartitionQueryRequest, opts ...grpc.CallOption) (*sppb.PartitionResponse, error) { m.ready() m.ReceivedRequests <- r return nil, errors.New("Unimplemented") } // PartitionRead is a placeholder for SpannerServer.PartitionRead. func (m *MockCloudSpannerClient) PartitionRead(ctx context.Context, r *sppb.PartitionReadRequest, opts ...grpc.CallOption) (*sppb.PartitionResponse, error) { m.ready() m.ReceivedRequests <- r return nil, errors.New("Unimplemented") } // Freeze stalls all requests. func (m *MockCloudSpannerClient) Freeze() { m.mu.Lock() defer m.mu.Unlock() m.freezed = make(chan struct{}) } // Unfreeze restores processing requests. func (m *MockCloudSpannerClient) Unfreeze() { m.mu.Lock() defer m.mu.Unlock() close(m.freezed) } // ready checks conditions before executing requests // TODO: add checks for injected errors, actions func (m *MockCloudSpannerClient) ready() { m.mu.Lock() freezed := m.freezed m.mu.Unlock() // check if client should be freezed <-freezed } google-cloud-go-0.49.0/spanner/internal/testutil/mocked_inmem_server.go000066400000000000000000000140601356504100700262740ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package testutil import ( "fmt" "net" "strconv" "testing" structpb "github.com/golang/protobuf/ptypes/struct" "google.golang.org/api/option" spannerpb "google.golang.org/genproto/googleapis/spanner/v1" "google.golang.org/grpc" ) // SelectFooFromBar is a SELECT statement that is added to the mocked test // server and will return a one-col-two-rows result set containing the INT64 // values 1 and 2. const SelectFooFromBar = "SELECT FOO FROM BAR" const selectFooFromBarRowCount int64 = 2 const selectFooFromBarColCount int = 1 var selectFooFromBarResults = [...]int64{1, 2} // SelectSingerIDAlbumIDAlbumTitleFromAlbums i a SELECT statement that is added // to the mocked test server and will return a 3-cols-3-rows result set. const SelectSingerIDAlbumIDAlbumTitleFromAlbums = "SELECT SingerId, AlbumId, AlbumTitle FROM Albums" // SelectSingerIDAlbumIDAlbumTitleFromAlbumsRowCount is the number of rows // returned by the SelectSingerIDAlbumIDAlbumTitleFromAlbums statement. const SelectSingerIDAlbumIDAlbumTitleFromAlbumsRowCount int64 = 3 // SelectSingerIDAlbumIDAlbumTitleFromAlbumsColCount is the number of cols // returned by the SelectSingerIDAlbumIDAlbumTitleFromAlbums statement. const SelectSingerIDAlbumIDAlbumTitleFromAlbumsColCount int = 3 // UpdateBarSetFoo is an UPDATE statement that is added to the mocked test // server that will return an update count of 5. const UpdateBarSetFoo = "UPDATE FOO SET BAR=1 WHERE BAZ=2" // UpdateBarSetFooRowCount is the constant update count value returned by the // statement defined in UpdateBarSetFoo. const UpdateBarSetFooRowCount = 5 // MockedSpannerInMemTestServer is an InMemSpannerServer with results for a // number of SQL statements readily mocked. type MockedSpannerInMemTestServer struct { TestSpanner InMemSpannerServer server *grpc.Server } // NewMockedSpannerInMemTestServer creates a MockedSpannerInMemTestServer and // returns client options that can be used to connect to it. func NewMockedSpannerInMemTestServer(t *testing.T) (mockedServer *MockedSpannerInMemTestServer, opts []option.ClientOption, teardown func()) { mockedServer = &MockedSpannerInMemTestServer{} opts = mockedServer.setupMockedServer(t) return mockedServer, opts, func() { mockedServer.TestSpanner.Stop() mockedServer.server.Stop() } } func (s *MockedSpannerInMemTestServer) setupMockedServer(t *testing.T) []option.ClientOption { s.TestSpanner = NewInMemSpannerServer() s.setupFooResults() s.setupSingersResults() s.server = grpc.NewServer() spannerpb.RegisterSpannerServer(s.server, s.TestSpanner) lis, err := net.Listen("tcp", "localhost:0") if err != nil { t.Fatal(err) } go s.server.Serve(lis) serverAddress := lis.Addr().String() opts := []option.ClientOption{ option.WithEndpoint(serverAddress), option.WithGRPCDialOption(grpc.WithInsecure()), option.WithoutAuthentication(), } return opts } func (s *MockedSpannerInMemTestServer) setupFooResults() { fields := make([]*spannerpb.StructType_Field, selectFooFromBarColCount) fields[0] = &spannerpb.StructType_Field{ Name: "FOO", Type: &spannerpb.Type{Code: spannerpb.TypeCode_INT64}, } rowType := &spannerpb.StructType{ Fields: fields, } metadata := &spannerpb.ResultSetMetadata{ RowType: rowType, } rows := make([]*structpb.ListValue, selectFooFromBarRowCount) for idx, value := range selectFooFromBarResults { rowValue := make([]*structpb.Value, selectFooFromBarColCount) rowValue[0] = &structpb.Value{ Kind: &structpb.Value_StringValue{StringValue: strconv.FormatInt(value, 10)}, } rows[idx] = &structpb.ListValue{ Values: rowValue, } } resultSet := &spannerpb.ResultSet{ Metadata: metadata, Rows: rows, } result := &StatementResult{Type: StatementResultResultSet, ResultSet: resultSet} s.TestSpanner.PutStatementResult(SelectFooFromBar, result) s.TestSpanner.PutStatementResult(UpdateBarSetFoo, &StatementResult{ Type: StatementResultUpdateCount, UpdateCount: UpdateBarSetFooRowCount, }) } func (s *MockedSpannerInMemTestServer) setupSingersResults() { fields := make([]*spannerpb.StructType_Field, SelectSingerIDAlbumIDAlbumTitleFromAlbumsColCount) fields[0] = &spannerpb.StructType_Field{ Name: "SingerId", Type: &spannerpb.Type{Code: spannerpb.TypeCode_INT64}, } fields[1] = &spannerpb.StructType_Field{ Name: "AlbumId", Type: &spannerpb.Type{Code: spannerpb.TypeCode_INT64}, } fields[2] = &spannerpb.StructType_Field{ Name: "AlbumTitle", Type: &spannerpb.Type{Code: spannerpb.TypeCode_STRING}, } rowType := &spannerpb.StructType{ Fields: fields, } metadata := &spannerpb.ResultSetMetadata{ RowType: rowType, } rows := make([]*structpb.ListValue, SelectSingerIDAlbumIDAlbumTitleFromAlbumsRowCount) var idx int64 for idx = 0; idx < SelectSingerIDAlbumIDAlbumTitleFromAlbumsRowCount; idx++ { rowValue := make([]*structpb.Value, SelectSingerIDAlbumIDAlbumTitleFromAlbumsColCount) rowValue[0] = &structpb.Value{ Kind: &structpb.Value_StringValue{StringValue: strconv.FormatInt(idx+1, 10)}, } rowValue[1] = &structpb.Value{ Kind: &structpb.Value_StringValue{StringValue: strconv.FormatInt(idx*10+idx, 10)}, } rowValue[2] = &structpb.Value{ Kind: &structpb.Value_StringValue{StringValue: fmt.Sprintf("Album title %d", idx)}, } rows[idx] = &structpb.ListValue{ Values: rowValue, } } resultSet := &spannerpb.ResultSet{ Metadata: metadata, Rows: rows, } result := &StatementResult{Type: StatementResultResultSet, ResultSet: resultSet} s.TestSpanner.PutStatementResult(SelectSingerIDAlbumIDAlbumTitleFromAlbums, result) } google-cloud-go-0.49.0/spanner/internal/testutil/mockserver.go000066400000000000000000000154441356504100700244460ustar00rootroot00000000000000/* Copyright 2017 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package testutil import ( "context" "encoding/binary" "fmt" "io" "net" "sync" "testing" "time" "github.com/golang/protobuf/ptypes/empty" proto3 "github.com/golang/protobuf/ptypes/struct" pbt "github.com/golang/protobuf/ptypes/timestamp" sppb "google.golang.org/genproto/googleapis/spanner/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) var ( // KvMeta is the Metadata for mocked KV table. KvMeta = sppb.ResultSetMetadata{ RowType: &sppb.StructType{ Fields: []*sppb.StructType_Field{ { Name: "Key", Type: &sppb.Type{Code: sppb.TypeCode_STRING}, }, { Name: "Value", Type: &sppb.Type{Code: sppb.TypeCode_STRING}, }, }, }, } ) // MockCtlMsg encapsulates PartialResultSet/error that might be sent to // client type MockCtlMsg struct { // If ResumeToken == true, mock server will generate a row with // resume token. ResumeToken bool // If Err != nil, mock server will return error in RPC response. Err error } // MockCloudSpanner is a mock implementation of SpannerServer interface. // TODO: make MockCloudSpanner a full-fleged Cloud Spanner implementation. type MockCloudSpanner struct { sppb.SpannerServer s *grpc.Server t *testing.T addr string msgs chan MockCtlMsg readTs time.Time mu sync.Mutex next int nextSession int sessions map[string]*sppb.Session } // Addr returns the listening address of mock server. func (m *MockCloudSpanner) Addr() string { return m.addr } // AddMsg generates a new mocked row which can be received by client. func (m *MockCloudSpanner) AddMsg(err error, resumeToken bool) { msg := MockCtlMsg{ ResumeToken: resumeToken, Err: err, } if err == io.EOF { close(m.msgs) } else { m.msgs <- msg } } // Done signals an end to a mocked stream. func (m *MockCloudSpanner) Done() { close(m.msgs) } // CreateSession is a placeholder for SpannerServer.CreateSession. func (m *MockCloudSpanner) CreateSession(c context.Context, r *sppb.CreateSessionRequest) (*sppb.Session, error) { m.mu.Lock() defer m.mu.Unlock() name := fmt.Sprintf("session-%d", m.nextSession) m.nextSession++ s := &sppb.Session{Name: name} m.sessions[name] = s return s, nil } // GetSession is a placeholder for SpannerServer.GetSession. func (m *MockCloudSpanner) GetSession(c context.Context, r *sppb.GetSessionRequest) (*sppb.Session, error) { m.mu.Lock() defer m.mu.Unlock() if s, ok := m.sessions[r.Name]; ok { return s, nil } return nil, status.Errorf(codes.NotFound, "not found") } // DeleteSession is a placeholder for SpannerServer.DeleteSession. func (m *MockCloudSpanner) DeleteSession(c context.Context, r *sppb.DeleteSessionRequest) (*empty.Empty, error) { m.mu.Lock() defer m.mu.Unlock() delete(m.sessions, r.Name) return &empty.Empty{}, nil } // EncodeResumeToken return mock resume token encoding for an uint64 integer. func EncodeResumeToken(t uint64) []byte { rt := make([]byte, 16) binary.PutUvarint(rt, t) return rt } // DecodeResumeToken decodes a mock resume token into an uint64 integer. func DecodeResumeToken(t []byte) (uint64, error) { s, n := binary.Uvarint(t) if n <= 0 { return 0, fmt.Errorf("invalid resume token: %v", t) } return s, nil } // ExecuteStreamingSql is a mock implementation of SpannerServer.ExecuteStreamingSql. func (m *MockCloudSpanner) ExecuteStreamingSql(r *sppb.ExecuteSqlRequest, s sppb.Spanner_ExecuteStreamingSqlServer) error { switch r.Sql { case "SELECT * from t_unavailable": return status.Errorf(codes.Unavailable, "mock table unavailable") case "UPDATE t SET x = 2 WHERE x = 1": err := s.Send(&sppb.PartialResultSet{ Stats: &sppb.ResultSetStats{RowCount: &sppb.ResultSetStats_RowCountLowerBound{3}}, }) if err != nil { panic(err) } return nil case "SELECT t.key key, t.value value FROM t_mock t": if r.ResumeToken != nil { s, err := DecodeResumeToken(r.ResumeToken) if err != nil { return err } m.mu.Lock() m.next = int(s) + 1 m.mu.Unlock() } for { msg, more := <-m.msgs if !more { break } if msg.Err == nil { var rt []byte if msg.ResumeToken { m.mu.Lock() rt = EncodeResumeToken(uint64(m.next)) m.mu.Unlock() } meta := KvMeta meta.Transaction = &sppb.Transaction{ ReadTimestamp: &pbt.Timestamp{ Seconds: m.readTs.Unix(), Nanos: int32(m.readTs.Nanosecond()), }, } m.mu.Lock() next := m.next m.next++ m.mu.Unlock() err := s.Send(&sppb.PartialResultSet{ Metadata: &meta, Values: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: fmt.Sprintf("foo-%02d", next)}}, {Kind: &proto3.Value_StringValue{StringValue: fmt.Sprintf("bar-%02d", next)}}, }, ResumeToken: rt, }) if err != nil { return err } continue } return msg.Err } return nil default: return fmt.Errorf("unsupported SQL: %v", r.Sql) } } // StreamingRead is a placeholder for SpannerServer.StreamingRead. func (m *MockCloudSpanner) StreamingRead(r *sppb.ReadRequest, s sppb.Spanner_StreamingReadServer) error { return s.Send(&sppb.PartialResultSet{}) } // Serve runs a MockCloudSpanner listening on a random localhost address. func (m *MockCloudSpanner) Serve() { m.s = grpc.NewServer() if m.addr == "" { m.addr = "localhost:0" } lis, err := net.Listen("tcp", m.addr) if err != nil { m.t.Fatalf("Failed to listen: %v", err) } _, port, err := net.SplitHostPort(lis.Addr().String()) if err != nil { m.t.Fatalf("Failed to parse listener address: %v", err) } sppb.RegisterSpannerServer(m.s, m) m.addr = "localhost:" + port go m.s.Serve(lis) } // BeginTransaction is a placeholder for SpannerServer.BeginTransaction. func (m *MockCloudSpanner) BeginTransaction(_ context.Context, r *sppb.BeginTransactionRequest) (*sppb.Transaction, error) { m.mu.Lock() defer m.mu.Unlock() return &sppb.Transaction{}, nil } // Stop terminates MockCloudSpanner and closes the serving port. func (m *MockCloudSpanner) Stop() { m.s.Stop() } // NewMockCloudSpanner creates a new MockCloudSpanner instance. func NewMockCloudSpanner(t *testing.T, ts time.Time) *MockCloudSpanner { mcs := &MockCloudSpanner{ t: t, msgs: make(chan MockCtlMsg, 1000), readTs: ts, sessions: map[string]*sppb.Session{}, } return mcs } google-cloud-go-0.49.0/spanner/key.go000066400000000000000000000301731356504100700173610ustar00rootroot00000000000000/* Copyright 2017 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spanner import ( "bytes" "fmt" "time" "cloud.google.com/go/civil" proto3 "github.com/golang/protobuf/ptypes/struct" sppb "google.golang.org/genproto/googleapis/spanner/v1" "google.golang.org/grpc/codes" ) // A Key can be either a Cloud Spanner row's primary key or a secondary index // key. It is essentially an interface{} array, which represents a set of Cloud // Spanner columns. A Key can be used as: // // - A primary key which uniquely identifies a Cloud Spanner row. // - A secondary index key which maps to a set of Cloud Spanner rows indexed under it. // - An endpoint of primary key/secondary index ranges; see the KeyRange type. // // Rows that are identified by the Key type are outputs of read operation or // targets of delete operation in a mutation. Note that for // Insert/Update/InsertOrUpdate/Update mutation types, although they don't // require a primary key explicitly, the column list provided must contain // enough columns that can comprise a primary key. // // Keys are easy to construct. For example, suppose you have a table with a // primary key of username and product ID. To make a key for this table: // // key := spanner.Key{"john", 16} // // See the description of Row and Mutation types for how Go types are mapped to // Cloud Spanner types. For convenience, Key type supports a wide range of Go // types: // - int, int8, int16, int32, int64, and NullInt64 are mapped to Cloud Spanner's INT64 type. // - uint8, uint16 and uint32 are also mapped to Cloud Spanner's INT64 type. // - float32, float64, NullFloat64 are mapped to Cloud Spanner's FLOAT64 type. // - bool and NullBool are mapped to Cloud Spanner's BOOL type. // - []byte is mapped to Cloud Spanner's BYTES type. // - string and NullString are mapped to Cloud Spanner's STRING type. // - time.Time and NullTime are mapped to Cloud Spanner's TIMESTAMP type. // - civil.Date and NullDate are mapped to Cloud Spanner's DATE type. type Key []interface{} // errInvdKeyPartType returns error for unsupported key part type. func errInvdKeyPartType(part interface{}) error { return spannerErrorf(codes.InvalidArgument, "key part has unsupported type %T", part) } // keyPartValue converts a part of the Key (which is a valid Cloud Spanner type) // into a proto3.Value. Used for encoding Key type into protobuf. func keyPartValue(part interface{}) (pb *proto3.Value, err error) { switch v := part.(type) { case int: pb, _, err = encodeValue(int64(v)) case int8: pb, _, err = encodeValue(int64(v)) case int16: pb, _, err = encodeValue(int64(v)) case int32: pb, _, err = encodeValue(int64(v)) case uint8: pb, _, err = encodeValue(int64(v)) case uint16: pb, _, err = encodeValue(int64(v)) case uint32: pb, _, err = encodeValue(int64(v)) case float32: pb, _, err = encodeValue(float64(v)) case int64, float64, NullInt64, NullFloat64, bool, NullBool, []byte, string, NullString, time.Time, civil.Date, NullTime, NullDate: pb, _, err = encodeValue(v) default: return nil, errInvdKeyPartType(v) } return pb, err } // proto converts a spanner.Key into a proto3.ListValue. func (key Key) proto() (*proto3.ListValue, error) { lv := &proto3.ListValue{} lv.Values = make([]*proto3.Value, 0, len(key)) for _, part := range key { v, err := keyPartValue(part) if err != nil { return nil, err } lv.Values = append(lv.Values, v) } return lv, nil } // keySetProto lets a single Key act as a KeySet. func (key Key) keySetProto() (*sppb.KeySet, error) { kp, err := key.proto() if err != nil { return nil, err } return &sppb.KeySet{Keys: []*proto3.ListValue{kp}}, nil } // String implements fmt.Stringer for Key. For string, []byte and NullString, it // prints the uninterpreted bytes of their contents, leaving caller with the // opportunity to escape the output. func (key Key) String() string { b := &bytes.Buffer{} fmt.Fprint(b, "(") for i, part := range []interface{}(key) { if i != 0 { fmt.Fprint(b, ",") } switch v := part.(type) { case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, float32, float64, bool: // Use %v to print numeric types and bool. fmt.Fprintf(b, "%v", v) case string: fmt.Fprintf(b, "%q", v) case []byte: if v != nil { fmt.Fprintf(b, "%q", v) } else { fmt.Fprint(b, nullString) } case NullInt64, NullFloat64, NullBool: // The above types implement fmt.Stringer. fmt.Fprintf(b, "%s", v) case NullString, NullDate, NullTime: // Quote the returned string if it is not null. if v.(NullableValue).IsNull() { fmt.Fprintf(b, "%s", nullString) } else { fmt.Fprintf(b, "%q", v) } case civil.Date: fmt.Fprintf(b, "%q", v) case time.Time: fmt.Fprintf(b, "%q", v.Format(time.RFC3339Nano)) default: fmt.Fprintf(b, "%v", v) } } fmt.Fprint(b, ")") return b.String() } // AsPrefix returns a KeyRange for all keys where k is the prefix. func (key Key) AsPrefix() KeyRange { return KeyRange{ Start: key, End: key, Kind: ClosedClosed, } } // KeyRangeKind describes the kind of interval represented by a KeyRange: // whether it is open or closed on the left and right. type KeyRangeKind int const ( // ClosedOpen is closed on the left and open on the right: the Start // key is included, the End key is excluded. ClosedOpen KeyRangeKind = iota // ClosedClosed is closed on the left and the right: both keys are included. ClosedClosed // OpenClosed is open on the left and closed on the right: the Start // key is excluded, the End key is included. OpenClosed // OpenOpen is open on the left and the right: neither key is included. OpenOpen ) // A KeyRange represents a range of rows in a table or index. // // A range has a Start key and an End key. IncludeStart and IncludeEnd // indicate whether the Start and End keys are included in the range. // // For example, consider the following table definition: // // CREATE TABLE UserEvents ( // UserName STRING(MAX), // EventDate STRING(10), // ) PRIMARY KEY(UserName, EventDate); // // The following keys name rows in this table: // // spanner.Key{"Bob", "2014-09-23"} // spanner.Key{"Alfred", "2015-06-12"} // // Since the UserEvents table's PRIMARY KEY clause names two columns, each // UserEvents key has two elements; the first is the UserName, and the second // is the EventDate. // // Key ranges with multiple components are interpreted lexicographically by // component using the table or index key's declared sort order. For example, // the following range returns all events for user "Bob" that occurred in the // year 2015: // // spanner.KeyRange{ // Start: spanner.Key{"Bob", "2015-01-01"}, // End: spanner.Key{"Bob", "2015-12-31"}, // Kind: ClosedClosed, // } // // Start and end keys can omit trailing key components. This affects the // inclusion and exclusion of rows that exactly match the provided key // components: if IncludeStart is true, then rows that exactly match the // provided components of the Start key are included; if IncludeStart is false // then rows that exactly match are not included. IncludeEnd and End key // behave in the same fashion. // // For example, the following range includes all events for "Bob" that occurred // during and after the year 2000: // // spanner.KeyRange{ // Start: spanner.Key{"Bob", "2000-01-01"}, // End: spanner.Key{"Bob"}, // Kind: ClosedClosed, // } // // The next example retrieves all events for "Bob": // // spanner.Key{"Bob"}.AsPrefix() // // To retrieve events before the year 2000: // // spanner.KeyRange{ // Start: spanner.Key{"Bob"}, // End: spanner.Key{"Bob", "2000-01-01"}, // Kind: ClosedOpen, // } // // Although we specified a Kind for this KeyRange, we didn't need to, because // the default is ClosedOpen. In later examples we'll omit Kind if it is // ClosedOpen. // // The following range includes all rows in a table or under a // index: // // spanner.AllKeys() // // This range returns all users whose UserName begins with any // character from A to C: // // spanner.KeyRange{ // Start: spanner.Key{"A"}, // End: spanner.Key{"D"}, // } // // This range returns all users whose UserName begins with B: // // spanner.KeyRange{ // Start: spanner.Key{"B"}, // End: spanner.Key{"C"}, // } // // Key ranges honor column sort order. For example, suppose a table is defined // as follows: // // CREATE TABLE DescendingSortedTable { // Key INT64, // ... // ) PRIMARY KEY(Key DESC); // // The following range retrieves all rows with key values between 1 and 100 // inclusive: // // spanner.KeyRange{ // Start: spanner.Key{100}, // End: spanner.Key{1}, // Kind: ClosedClosed, // } // // Note that 100 is passed as the start, and 1 is passed as the end, because // Key is a descending column in the schema. type KeyRange struct { // Start specifies the left boundary of the key range; End specifies // the right boundary of the key range. Start, End Key // Kind describes whether the boundaries of the key range include // their keys. Kind KeyRangeKind } // String implements fmt.Stringer for KeyRange type. func (r KeyRange) String() string { var left, right string switch r.Kind { case ClosedClosed: left, right = "[", "]" case ClosedOpen: left, right = "[", ")" case OpenClosed: left, right = "(", "]" case OpenOpen: left, right = "(", ")" default: left, right = "?", "?" } return fmt.Sprintf("%s%s,%s%s", left, r.Start, r.End, right) } // proto converts KeyRange into sppb.KeyRange. func (r KeyRange) proto() (*sppb.KeyRange, error) { var err error var start, end *proto3.ListValue pb := &sppb.KeyRange{} if start, err = r.Start.proto(); err != nil { return nil, err } if end, err = r.End.proto(); err != nil { return nil, err } if r.Kind == ClosedClosed || r.Kind == ClosedOpen { pb.StartKeyType = &sppb.KeyRange_StartClosed{StartClosed: start} } else { pb.StartKeyType = &sppb.KeyRange_StartOpen{StartOpen: start} } if r.Kind == ClosedClosed || r.Kind == OpenClosed { pb.EndKeyType = &sppb.KeyRange_EndClosed{EndClosed: end} } else { pb.EndKeyType = &sppb.KeyRange_EndOpen{EndOpen: end} } return pb, nil } // keySetProto lets a KeyRange act as a KeySet. func (r KeyRange) keySetProto() (*sppb.KeySet, error) { rp, err := r.proto() if err != nil { return nil, err } return &sppb.KeySet{Ranges: []*sppb.KeyRange{rp}}, nil } // A KeySet defines a collection of Cloud Spanner keys and/or key ranges. All // the keys are expected to be in the same table or index. The keys need not be // sorted in any particular way. // // An individual Key can act as a KeySet, as can a KeyRange. Use the KeySets // function to create a KeySet consisting of multiple Keys and KeyRanges. To // obtain an empty KeySet, call KeySets with no arguments. // // If the same key is specified multiple times in the set (for example if two // ranges, two keys, or a key and a range overlap), the Cloud Spanner backend // behaves as if the key were only specified once. type KeySet interface { keySetProto() (*sppb.KeySet, error) } // AllKeys returns a KeySet that represents all Keys of a table or a index. func AllKeys() KeySet { return all{} } type all struct{} func (all) keySetProto() (*sppb.KeySet, error) { return &sppb.KeySet{All: true}, nil } // KeySets returns the union of the KeySets. If any of the KeySets is AllKeys, // then the resulting KeySet will be equivalent to AllKeys. func KeySets(keySets ...KeySet) KeySet { u := make(union, len(keySets)) copy(u, keySets) return u } type union []KeySet func (u union) keySetProto() (*sppb.KeySet, error) { upb := &sppb.KeySet{} for _, ks := range u { pb, err := ks.keySetProto() if err != nil { return nil, err } if pb.All { return pb, nil } upb.Keys = append(upb.Keys, pb.Keys...) upb.Ranges = append(upb.Ranges, pb.Ranges...) } return upb, nil } google-cloud-go-0.49.0/spanner/key_test.go000066400000000000000000000232741356504100700204240ustar00rootroot00000000000000/* Copyright 2017 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spanner import ( "testing" "time" "cloud.google.com/go/civil" proto3 "github.com/golang/protobuf/ptypes/struct" sppb "google.golang.org/genproto/googleapis/spanner/v1" ) // Test Key.String() and Key.proto(). func TestKey(t *testing.T) { tm, _ := time.Parse(time.RFC3339Nano, "2016-11-15T15:04:05.999999999Z") dt, _ := civil.ParseDate("2016-11-15") for _, test := range []struct { k Key wantProto *proto3.ListValue wantStr string }{ { k: Key{int(1)}, wantProto: listValueProto(stringProto("1")), wantStr: "(1)", }, { k: Key{int8(1)}, wantProto: listValueProto(stringProto("1")), wantStr: "(1)", }, { k: Key{int16(1)}, wantProto: listValueProto(stringProto("1")), wantStr: "(1)", }, { k: Key{int32(1)}, wantProto: listValueProto(stringProto("1")), wantStr: "(1)", }, { k: Key{int64(1)}, wantProto: listValueProto(stringProto("1")), wantStr: "(1)", }, { k: Key{uint8(1)}, wantProto: listValueProto(stringProto("1")), wantStr: "(1)", }, { k: Key{uint16(1)}, wantProto: listValueProto(stringProto("1")), wantStr: "(1)", }, { k: Key{uint32(1)}, wantProto: listValueProto(stringProto("1")), wantStr: "(1)", }, { k: Key{true}, wantProto: listValueProto(boolProto(true)), wantStr: "(true)", }, { k: Key{float32(1.5)}, wantProto: listValueProto(floatProto(1.5)), wantStr: "(1.5)", }, { k: Key{float64(1.5)}, wantProto: listValueProto(floatProto(1.5)), wantStr: "(1.5)", }, { k: Key{"value"}, wantProto: listValueProto(stringProto("value")), wantStr: `("value")`, }, { k: Key{[]byte(nil)}, wantProto: listValueProto(nullProto()), wantStr: "()", }, { k: Key{[]byte{}}, wantProto: listValueProto(stringProto("")), wantStr: `("")`, }, { k: Key{tm}, wantProto: listValueProto(stringProto("2016-11-15T15:04:05.999999999Z")), wantStr: `("2016-11-15T15:04:05.999999999Z")`, }, {k: Key{dt}, wantProto: listValueProto(stringProto("2016-11-15")), wantStr: `("2016-11-15")`, }, { k: Key{[]byte("value")}, wantProto: listValueProto(bytesProto([]byte("value"))), wantStr: `("value")`, }, { k: Key{NullInt64{1, true}}, wantProto: listValueProto(stringProto("1")), wantStr: "(1)", }, { k: Key{NullInt64{2, false}}, wantProto: listValueProto(nullProto()), wantStr: "()", }, { k: Key{NullFloat64{1.5, true}}, wantProto: listValueProto(floatProto(1.5)), wantStr: "(1.5)", }, { k: Key{NullFloat64{2.0, false}}, wantProto: listValueProto(nullProto()), wantStr: "()", }, { k: Key{NullBool{true, true}}, wantProto: listValueProto(boolProto(true)), wantStr: "(true)", }, { k: Key{NullBool{true, false}}, wantProto: listValueProto(nullProto()), wantStr: "()", }, { k: Key{NullString{"value", true}}, wantProto: listValueProto(stringProto("value")), wantStr: `("value")`, }, { k: Key{NullString{"value", false}}, wantProto: listValueProto(nullProto()), wantStr: "()", }, { k: Key{NullTime{tm, true}}, wantProto: listValueProto(timeProto(tm)), wantStr: `("2016-11-15T15:04:05.999999999Z")`, }, { k: Key{NullTime{time.Now(), false}}, wantProto: listValueProto(nullProto()), wantStr: "()", }, { k: Key{NullDate{dt, true}}, wantProto: listValueProto(dateProto(dt)), wantStr: `("2016-11-15")`, }, { k: Key{NullDate{civil.Date{}, false}}, wantProto: listValueProto(nullProto()), wantStr: "()", }, { k: Key{int(1), NullString{"value", false}, "value", 1.5, true}, wantProto: listValueProto(stringProto("1"), nullProto(), stringProto("value"), floatProto(1.5), boolProto(true)), wantStr: `(1,,"value",1.5,true)`, }, } { if got := test.k.String(); got != test.wantStr { t.Errorf("%v.String() = %v, want %v", test.k, got, test.wantStr) } gotProto, err := test.k.proto() if err != nil { t.Errorf("%v.proto() returns error %v; want nil error", test.k, err) } if !testEqual(gotProto, test.wantProto) { t.Errorf("%v.proto() = \n%v\nwant:\n%v", test.k, gotProto, test.wantProto) } } } // Test KeyRange.String() and KeyRange.proto(). func TestKeyRange(t *testing.T) { for _, test := range []struct { kr KeyRange wantProto *sppb.KeyRange wantStr string }{ { kr: KeyRange{Key{"A"}, Key{"D"}, OpenOpen}, wantProto: &sppb.KeyRange{ StartKeyType: &sppb.KeyRange_StartOpen{StartOpen: listValueProto(stringProto("A"))}, EndKeyType: &sppb.KeyRange_EndOpen{EndOpen: listValueProto(stringProto("D"))}, }, wantStr: `(("A"),("D"))`, }, { kr: KeyRange{Key{1}, Key{10}, OpenClosed}, wantProto: &sppb.KeyRange{ StartKeyType: &sppb.KeyRange_StartOpen{StartOpen: listValueProto(stringProto("1"))}, EndKeyType: &sppb.KeyRange_EndClosed{EndClosed: listValueProto(stringProto("10"))}, }, wantStr: "((1),(10)]", }, { kr: KeyRange{Key{1.5, 2.1, 0.2}, Key{1.9, 0.7}, ClosedOpen}, wantProto: &sppb.KeyRange{ StartKeyType: &sppb.KeyRange_StartClosed{StartClosed: listValueProto(floatProto(1.5), floatProto(2.1), floatProto(0.2))}, EndKeyType: &sppb.KeyRange_EndOpen{EndOpen: listValueProto(floatProto(1.9), floatProto(0.7))}, }, wantStr: "[(1.5,2.1,0.2),(1.9,0.7))", }, { kr: KeyRange{Key{NullInt64{1, true}}, Key{10}, ClosedClosed}, wantProto: &sppb.KeyRange{ StartKeyType: &sppb.KeyRange_StartClosed{StartClosed: listValueProto(stringProto("1"))}, EndKeyType: &sppb.KeyRange_EndClosed{EndClosed: listValueProto(stringProto("10"))}, }, wantStr: "[(1),(10)]", }, } { if got := test.kr.String(); got != test.wantStr { t.Errorf("%v.String() = %v, want %v", test.kr, got, test.wantStr) } gotProto, err := test.kr.proto() if err != nil { t.Errorf("%v.proto() returns error %v; want nil error", test.kr, err) } if !testEqual(gotProto, test.wantProto) { t.Errorf("%v.proto() = \n%v\nwant:\n%v", test.kr, gotProto.String(), test.wantProto.String()) } } } func TestPrefixRange(t *testing.T) { got := Key{1}.AsPrefix() want := KeyRange{Start: Key{1}, End: Key{1}, Kind: ClosedClosed} if !testEqual(got, want) { t.Errorf("got %v, want %v", got, want) } } func TestKeySets(t *testing.T) { int1 := intProto(1) int2 := intProto(2) int3 := intProto(3) int4 := intProto(4) for i, test := range []struct { ks KeySet wantProto *sppb.KeySet }{ { KeySets(), &sppb.KeySet{}, }, { Key{4}, &sppb.KeySet{ Keys: []*proto3.ListValue{listValueProto(int4)}, }, }, { AllKeys(), &sppb.KeySet{All: true}, }, { KeySets(Key{1, 2}, Key{3, 4}), &sppb.KeySet{ Keys: []*proto3.ListValue{ listValueProto(int1, int2), listValueProto(int3, int4), }, }, }, { KeyRange{Key{1}, Key{2}, ClosedOpen}, &sppb.KeySet{Ranges: []*sppb.KeyRange{ { StartKeyType: &sppb.KeyRange_StartClosed{StartClosed: listValueProto(int1)}, EndKeyType: &sppb.KeyRange_EndOpen{EndOpen: listValueProto(int2)}, }, }}, }, { Key{2}.AsPrefix(), &sppb.KeySet{Ranges: []*sppb.KeyRange{ { StartKeyType: &sppb.KeyRange_StartClosed{StartClosed: listValueProto(int2)}, EndKeyType: &sppb.KeyRange_EndClosed{EndClosed: listValueProto(int2)}, }, }}, }, { KeySets( KeyRange{Key{1}, Key{2}, ClosedClosed}, KeyRange{Key{3}, Key{4}, OpenClosed}, ), &sppb.KeySet{ Ranges: []*sppb.KeyRange{ { StartKeyType: &sppb.KeyRange_StartClosed{StartClosed: listValueProto(int1)}, EndKeyType: &sppb.KeyRange_EndClosed{EndClosed: listValueProto(int2)}, }, { StartKeyType: &sppb.KeyRange_StartOpen{StartOpen: listValueProto(int3)}, EndKeyType: &sppb.KeyRange_EndClosed{EndClosed: listValueProto(int4)}, }, }, }, }, { KeySets( Key{1}, KeyRange{Key{2}, Key{3}, ClosedClosed}, KeyRange{Key{4}, Key{5}, OpenClosed}, KeySets(), Key{6}), &sppb.KeySet{ Keys: []*proto3.ListValue{ listValueProto(int1), listValueProto(intProto(6)), }, Ranges: []*sppb.KeyRange{ { StartKeyType: &sppb.KeyRange_StartClosed{StartClosed: listValueProto(int2)}, EndKeyType: &sppb.KeyRange_EndClosed{EndClosed: listValueProto(int3)}, }, { StartKeyType: &sppb.KeyRange_StartOpen{StartOpen: listValueProto(int4)}, EndKeyType: &sppb.KeyRange_EndClosed{EndClosed: listValueProto(intProto(5))}, }, }, }, }, { KeySets( Key{1}, KeyRange{Key{2}, Key{3}, ClosedClosed}, AllKeys(), KeyRange{Key{4}, Key{5}, OpenClosed}, Key{6}), &sppb.KeySet{All: true}, }, } { gotProto, err := test.ks.keySetProto() if err != nil { t.Errorf("#%d: %v.proto() returns error %v; want nil error", i, test.ks, err) } if !testEqual(gotProto, test.wantProto) { t.Errorf("#%d: %v.proto() = \n%v\nwant:\n%v", i, test.ks, gotProto.String(), test.wantProto.String()) } } } google-cloud-go-0.49.0/spanner/mutation.go000066400000000000000000000334561356504100700204400ustar00rootroot00000000000000/* Copyright 2017 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spanner import ( "reflect" proto3 "github.com/golang/protobuf/ptypes/struct" sppb "google.golang.org/genproto/googleapis/spanner/v1" "google.golang.org/grpc/codes" ) // op is the mutation operation. type op int const ( // opDelete removes a row from a table. Succeeds whether or not the // key was present. opDelete op = iota // opInsert inserts a row into a table. If the row already exists, the // write or transaction fails. opInsert // opInsertOrUpdate inserts a row into a table. If the row already // exists, it updates it instead. Any column values not explicitly // written are preserved. opInsertOrUpdate // opReplace inserts a row into a table, deleting any existing row. // Unlike InsertOrUpdate, this means any values not explicitly written // become NULL. opReplace // opUpdate updates a row in a table. If the row does not already // exist, the write or transaction fails. opUpdate ) // A Mutation describes a modification to one or more Cloud Spanner rows. The // mutation represents an insert, update, delete, etc on a table. // // Many mutations can be applied in a single atomic commit. For purposes of // constraint checking (such as foreign key constraints), the operations can be // viewed as applying in the same order as the mutations are provided (so that, // e.g., a row and its logical "child" can be inserted in the same commit). // // The Apply function applies series of mutations. For example, // // m := spanner.Insert("User", // []string{"user_id", "profile"}, // []interface{}{UserID, profile}) // _, err := client.Apply(ctx, []*spanner.Mutation{m}) // // inserts a new row into the User table. The primary key // for the new row is UserID (presuming that "user_id" has been declared as the // primary key of the "User" table). // // To apply a series of mutations as part of an atomic read-modify-write // operation, use ReadWriteTransaction. // // Updating a row // // Changing the values of columns in an existing row is very similar to // inserting a new row: // // m := spanner.Update("User", // []string{"user_id", "profile"}, // []interface{}{UserID, profile}) // _, err := client.Apply(ctx, []*spanner.Mutation{m}) // // Deleting a row // // To delete a row, use spanner.Delete: // // m := spanner.Delete("User", spanner.Key{UserId}) // _, err := client.Apply(ctx, []*spanner.Mutation{m}) // // spanner.Delete accepts a KeySet, so you can also pass in a KeyRange, or use // the spanner.KeySets function to build any combination of Keys and KeyRanges. // // Note that deleting a row in a table may also delete rows from other tables // if cascading deletes are specified in those tables' schemas. Delete does // nothing if the named row does not exist (does not yield an error). // // Deleting a field // // To delete/clear a field within a row, use spanner.Update with the value nil: // // m := spanner.Update("User", // []string{"user_id", "profile"}, // []interface{}{UserID, nil}) // _, err := client.Apply(ctx, []*spanner.Mutation{m}) // // The valid Go types and their corresponding Cloud Spanner types that can be // used in the Insert/Update/InsertOrUpdate functions are: // // string, NullString - STRING // []string, []NullString - STRING ARRAY // []byte - BYTES // [][]byte - BYTES ARRAY // int, int64, NullInt64 - INT64 // []int, []int64, []NullInt64 - INT64 ARRAY // bool, NullBool - BOOL // []bool, []NullBool - BOOL ARRAY // float64, NullFloat64 - FLOAT64 // []float64, []NullFloat64 - FLOAT64 ARRAY // time.Time, NullTime - TIMESTAMP // []time.Time, []NullTime - TIMESTAMP ARRAY // Date, NullDate - DATE // []Date, []NullDate - DATE ARRAY // // To compare two Mutations for testing purposes, use reflect.DeepEqual. type Mutation struct { // op is the operation type of the mutation. // See documentation for spanner.op for more details. op op // Table is the name of the target table to be modified. table string // keySet is a set of primary keys that names the rows // in a delete operation. keySet KeySet // columns names the set of columns that are going to be // modified by Insert, InsertOrUpdate, Replace or Update // operations. columns []string // values specifies the new values for the target columns // named by Columns. values []interface{} } // mapToMutationParams converts Go map into mutation parameters. func mapToMutationParams(in map[string]interface{}) ([]string, []interface{}) { cols := []string{} vals := []interface{}{} for k, v := range in { cols = append(cols, k) vals = append(vals, v) } return cols, vals } // errNotStruct returns error for not getting a go struct type. func errNotStruct(in interface{}) error { return spannerErrorf(codes.InvalidArgument, "%T is not a go struct type", in) } // structToMutationParams converts Go struct into mutation parameters. // If the input is not a valid Go struct type, structToMutationParams // returns error. func structToMutationParams(in interface{}) ([]string, []interface{}, error) { if in == nil { return nil, nil, errNotStruct(in) } v := reflect.ValueOf(in) t := v.Type() if t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Struct { // t is a pointer to a struct. if v.IsNil() { // Return empty results. return nil, nil, nil } // Get the struct value that in points to. v = v.Elem() t = t.Elem() } if t.Kind() != reflect.Struct { return nil, nil, errNotStruct(in) } fields, err := fieldCache.Fields(t) if err != nil { return nil, nil, toSpannerError(err) } var cols []string var vals []interface{} for _, f := range fields { cols = append(cols, f.Name) vals = append(vals, v.FieldByIndex(f.Index).Interface()) } return cols, vals, nil } // Insert returns a Mutation to insert a row into a table. If the row already // exists, the write or transaction fails with codes.AlreadyExists. func Insert(table string, cols []string, vals []interface{}) *Mutation { return &Mutation{ op: opInsert, table: table, columns: cols, values: vals, } } // InsertMap returns a Mutation to insert a row into a table, specified by // a map of column name to value. If the row already exists, the write or // transaction fails with codes.AlreadyExists. func InsertMap(table string, in map[string]interface{}) *Mutation { cols, vals := mapToMutationParams(in) return Insert(table, cols, vals) } // InsertStruct returns a Mutation to insert a row into a table, specified by // a Go struct. If the row already exists, the write or transaction fails with // codes.AlreadyExists. // // The in argument must be a struct or a pointer to a struct. Its exported // fields specify the column names and values. Use a field tag like "spanner:name" // to provide an alternative column name, or use "spanner:-" to ignore the field. func InsertStruct(table string, in interface{}) (*Mutation, error) { cols, vals, err := structToMutationParams(in) if err != nil { return nil, err } return Insert(table, cols, vals), nil } // Update returns a Mutation to update a row in a table. If the row does not // already exist, the write or transaction fails. func Update(table string, cols []string, vals []interface{}) *Mutation { return &Mutation{ op: opUpdate, table: table, columns: cols, values: vals, } } // UpdateMap returns a Mutation to update a row in a table, specified by // a map of column to value. If the row does not already exist, the write or // transaction fails. func UpdateMap(table string, in map[string]interface{}) *Mutation { cols, vals := mapToMutationParams(in) return Update(table, cols, vals) } // UpdateStruct returns a Mutation to update a row in a table, specified by a Go // struct. If the row does not already exist, the write or transaction fails. func UpdateStruct(table string, in interface{}) (*Mutation, error) { cols, vals, err := structToMutationParams(in) if err != nil { return nil, err } return Update(table, cols, vals), nil } // InsertOrUpdate returns a Mutation to insert a row into a table. If the row // already exists, it updates it instead. Any column values not explicitly // written are preserved. // // For a similar example, See Update. func InsertOrUpdate(table string, cols []string, vals []interface{}) *Mutation { return &Mutation{ op: opInsertOrUpdate, table: table, columns: cols, values: vals, } } // InsertOrUpdateMap returns a Mutation to insert a row into a table, // specified by a map of column to value. If the row already exists, it // updates it instead. Any column values not explicitly written are preserved. // // For a similar example, See UpdateMap. func InsertOrUpdateMap(table string, in map[string]interface{}) *Mutation { cols, vals := mapToMutationParams(in) return InsertOrUpdate(table, cols, vals) } // InsertOrUpdateStruct returns a Mutation to insert a row into a table, // specified by a Go struct. If the row already exists, it updates it instead. // Any column values not explicitly written are preserved. // // The in argument must be a struct or a pointer to a struct. Its exported // fields specify the column names and values. Use a field tag like // "spanner:name" to provide an alternative column name, or use "spanner:-" to // ignore the field. // // For a similar example, See UpdateStruct. func InsertOrUpdateStruct(table string, in interface{}) (*Mutation, error) { cols, vals, err := structToMutationParams(in) if err != nil { return nil, err } return InsertOrUpdate(table, cols, vals), nil } // Replace returns a Mutation to insert a row into a table, deleting any // existing row. Unlike InsertOrUpdate, this means any values not explicitly // written become NULL. // // For a similar example, See Update. func Replace(table string, cols []string, vals []interface{}) *Mutation { return &Mutation{ op: opReplace, table: table, columns: cols, values: vals, } } // ReplaceMap returns a Mutation to insert a row into a table, deleting any // existing row. Unlike InsertOrUpdateMap, this means any values not explicitly // written become NULL. The row is specified by a map of column to value. // // For a similar example, See UpdateMap. func ReplaceMap(table string, in map[string]interface{}) *Mutation { cols, vals := mapToMutationParams(in) return Replace(table, cols, vals) } // ReplaceStruct returns a Mutation to insert a row into a table, deleting any // existing row. Unlike InsertOrUpdateMap, this means any values not explicitly // written become NULL. The row is specified by a Go struct. // // The in argument must be a struct or a pointer to a struct. Its exported // fields specify the column names and values. Use a field tag like "spanner:name" // to provide an alternative column name, or use "spanner:-" to ignore the field. // // For a similar example, See UpdateStruct. func ReplaceStruct(table string, in interface{}) (*Mutation, error) { cols, vals, err := structToMutationParams(in) if err != nil { return nil, err } return Replace(table, cols, vals), nil } // Delete removes the rows described by the KeySet from the table. It succeeds // whether or not the keys were present. func Delete(table string, ks KeySet) *Mutation { return &Mutation{ op: opDelete, table: table, keySet: ks, } } // prepareWrite generates sppb.Mutation_Write from table name, column names // and new column values. func prepareWrite(table string, columns []string, vals []interface{}) (*sppb.Mutation_Write, error) { v, err := encodeValueArray(vals) if err != nil { return nil, err } return &sppb.Mutation_Write{ Table: table, Columns: columns, Values: []*proto3.ListValue{v}, }, nil } // errInvdMutationOp returns error for unrecognized mutation operation. func errInvdMutationOp(m Mutation) error { return spannerErrorf(codes.InvalidArgument, "Unknown op type: %d", m.op) } // proto converts spanner.Mutation to sppb.Mutation, in preparation to send // RPCs. func (m Mutation) proto() (*sppb.Mutation, error) { var pb *sppb.Mutation switch m.op { case opDelete: var kp *sppb.KeySet if m.keySet != nil { var err error kp, err = m.keySet.keySetProto() if err != nil { return nil, err } } pb = &sppb.Mutation{ Operation: &sppb.Mutation_Delete_{ Delete: &sppb.Mutation_Delete{ Table: m.table, KeySet: kp, }, }, } case opInsert: w, err := prepareWrite(m.table, m.columns, m.values) if err != nil { return nil, err } pb = &sppb.Mutation{Operation: &sppb.Mutation_Insert{Insert: w}} case opInsertOrUpdate: w, err := prepareWrite(m.table, m.columns, m.values) if err != nil { return nil, err } pb = &sppb.Mutation{Operation: &sppb.Mutation_InsertOrUpdate{InsertOrUpdate: w}} case opReplace: w, err := prepareWrite(m.table, m.columns, m.values) if err != nil { return nil, err } pb = &sppb.Mutation{Operation: &sppb.Mutation_Replace{Replace: w}} case opUpdate: w, err := prepareWrite(m.table, m.columns, m.values) if err != nil { return nil, err } pb = &sppb.Mutation{Operation: &sppb.Mutation_Update{Update: w}} default: return nil, errInvdMutationOp(m) } return pb, nil } // mutationsProto turns a spanner.Mutation array into a sppb.Mutation array, // it is convenient for sending batch mutations to Cloud Spanner. func mutationsProto(ms []*Mutation) ([]*sppb.Mutation, error) { l := make([]*sppb.Mutation, 0, len(ms)) for _, m := range ms { pb, err := m.proto() if err != nil { return nil, err } l = append(l, pb) } return l, nil } google-cloud-go-0.49.0/spanner/mutation_test.go000066400000000000000000000376241356504100700215000ustar00rootroot00000000000000/* Copyright 2017 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spanner import ( "sort" "strings" "testing" proto3 "github.com/golang/protobuf/ptypes/struct" sppb "google.golang.org/genproto/googleapis/spanner/v1" ) // keysetProto returns protobuf encoding of valid spanner.KeySet. func keysetProto(t *testing.T, ks KeySet) *sppb.KeySet { k, err := ks.keySetProto() if err != nil { t.Fatalf("cannot convert keyset %v to protobuf: %v", ks, err) } return k } // Test encoding from spanner.Mutation to protobuf. func TestMutationToProto(t *testing.T) { for i, test := range []struct { m *Mutation want *sppb.Mutation }{ // Delete Mutation { &Mutation{opDelete, "t_foo", Key{"foo"}, nil, nil}, &sppb.Mutation{ Operation: &sppb.Mutation_Delete_{ Delete: &sppb.Mutation_Delete{ Table: "t_foo", KeySet: keysetProto(t, Key{"foo"}), }, }, }, }, // Insert Mutation { &Mutation{opInsert, "t_foo", KeySets(), []string{"col1", "col2"}, []interface{}{int64(1), int64(2)}}, &sppb.Mutation{ Operation: &sppb.Mutation_Insert{ Insert: &sppb.Mutation_Write{ Table: "t_foo", Columns: []string{"col1", "col2"}, Values: []*proto3.ListValue{ { Values: []*proto3.Value{intProto(1), intProto(2)}, }, }, }, }, }, }, // InsertOrUpdate Mutation { &Mutation{opInsertOrUpdate, "t_foo", KeySets(), []string{"col1", "col2"}, []interface{}{1.0, 2.0}}, &sppb.Mutation{ Operation: &sppb.Mutation_InsertOrUpdate{ InsertOrUpdate: &sppb.Mutation_Write{ Table: "t_foo", Columns: []string{"col1", "col2"}, Values: []*proto3.ListValue{ { Values: []*proto3.Value{floatProto(1.0), floatProto(2.0)}, }, }, }, }, }, }, // Replace Mutation { &Mutation{opReplace, "t_foo", KeySets(), []string{"col1", "col2"}, []interface{}{"one", 2.0}}, &sppb.Mutation{ Operation: &sppb.Mutation_Replace{ Replace: &sppb.Mutation_Write{ Table: "t_foo", Columns: []string{"col1", "col2"}, Values: []*proto3.ListValue{ { Values: []*proto3.Value{stringProto("one"), floatProto(2.0)}, }, }, }, }, }, }, // Update Mutation { &Mutation{opUpdate, "t_foo", KeySets(), []string{"col1", "col2"}, []interface{}{"one", []byte(nil)}}, &sppb.Mutation{ Operation: &sppb.Mutation_Update{ Update: &sppb.Mutation_Write{ Table: "t_foo", Columns: []string{"col1", "col2"}, Values: []*proto3.ListValue{ { Values: []*proto3.Value{stringProto("one"), nullProto()}, }, }, }, }, }, }, } { if got, err := test.m.proto(); err != nil || !testEqual(got, test.want) { t.Errorf("%d: (%#v).proto() = (%v, %v), want (%v, nil)", i, test.m, got, err, test.want) } } } // mutationColumnSorter implements sort.Interface for sorting column-value pairs in a Mutation by column names. type mutationColumnSorter struct { Mutation } // newMutationColumnSorter creates new instance of mutationColumnSorter by duplicating the input Mutation so that // sorting won't change the input Mutation. func newMutationColumnSorter(m *Mutation) *mutationColumnSorter { return &mutationColumnSorter{ Mutation{ m.op, m.table, m.keySet, append([]string(nil), m.columns...), append([]interface{}(nil), m.values...), }, } } // Len implements sort.Interface.Len. func (ms *mutationColumnSorter) Len() int { return len(ms.columns) } // Swap implements sort.Interface.Swap. func (ms *mutationColumnSorter) Swap(i, j int) { ms.columns[i], ms.columns[j] = ms.columns[j], ms.columns[i] ms.values[i], ms.values[j] = ms.values[j], ms.values[i] } // Less implements sort.Interface.Less. func (ms *mutationColumnSorter) Less(i, j int) bool { return strings.Compare(ms.columns[i], ms.columns[j]) < 0 } // mutationEqual returns true if two mutations in question are equal // to each other. func mutationEqual(t *testing.T, m1, m2 Mutation) bool { // Two mutations are considered to be equal even if their column values have different // orders. ms1 := newMutationColumnSorter(&m1) ms2 := newMutationColumnSorter(&m2) sort.Sort(ms1) sort.Sort(ms2) return testEqual(ms1, ms2) } // Test helper functions which help to generate spanner.Mutation. func TestMutationHelpers(t *testing.T) { for _, test := range []struct { m string got *Mutation want *Mutation }{ { "Insert", Insert("t_foo", []string{"col1", "col2"}, []interface{}{int64(1), int64(2)}), &Mutation{opInsert, "t_foo", nil, []string{"col1", "col2"}, []interface{}{int64(1), int64(2)}}, }, { "InsertMap", InsertMap("t_foo", map[string]interface{}{"col1": int64(1), "col2": int64(2)}), &Mutation{opInsert, "t_foo", nil, []string{"col1", "col2"}, []interface{}{int64(1), int64(2)}}, }, { "InsertStruct", func() *Mutation { m, err := InsertStruct( "t_foo", struct { notCol bool Col1 int64 `spanner:"col1"` Col2 int64 `spanner:"col2"` }{false, int64(1), int64(2)}, ) if err != nil { t.Errorf("cannot convert struct into mutation: %v", err) } return m }(), &Mutation{opInsert, "t_foo", nil, []string{"col1", "col2"}, []interface{}{int64(1), int64(2)}}, }, { "Update", Update("t_foo", []string{"col1", "col2"}, []interface{}{"one", []byte(nil)}), &Mutation{opUpdate, "t_foo", nil, []string{"col1", "col2"}, []interface{}{"one", []byte(nil)}}, }, { "UpdateMap", UpdateMap("t_foo", map[string]interface{}{"col1": "one", "col2": []byte(nil)}), &Mutation{opUpdate, "t_foo", nil, []string{"col1", "col2"}, []interface{}{"one", []byte(nil)}}, }, { "UpdateStruct", func() *Mutation { m, err := UpdateStruct( "t_foo", struct { Col1 string `spanner:"col1"` notCol int Col2 []byte `spanner:"col2"` }{"one", 1, nil}, ) if err != nil { t.Errorf("cannot convert struct into mutation: %v", err) } return m }(), &Mutation{opUpdate, "t_foo", nil, []string{"col1", "col2"}, []interface{}{"one", []byte(nil)}}, }, { "InsertOrUpdate", InsertOrUpdate("t_foo", []string{"col1", "col2"}, []interface{}{1.0, 2.0}), &Mutation{opInsertOrUpdate, "t_foo", nil, []string{"col1", "col2"}, []interface{}{1.0, 2.0}}, }, { "InsertOrUpdateMap", InsertOrUpdateMap("t_foo", map[string]interface{}{"col1": 1.0, "col2": 2.0}), &Mutation{opInsertOrUpdate, "t_foo", nil, []string{"col1", "col2"}, []interface{}{1.0, 2.0}}, }, { "InsertOrUpdateStruct", func() *Mutation { m, err := InsertOrUpdateStruct( "t_foo", struct { Col1 float64 `spanner:"col1"` Col2 float64 `spanner:"col2"` notCol float64 }{1.0, 2.0, 3.0}, ) if err != nil { t.Errorf("cannot convert struct into mutation: %v", err) } return m }(), &Mutation{opInsertOrUpdate, "t_foo", nil, []string{"col1", "col2"}, []interface{}{1.0, 2.0}}, }, { "Replace", Replace("t_foo", []string{"col1", "col2"}, []interface{}{"one", 2.0}), &Mutation{opReplace, "t_foo", nil, []string{"col1", "col2"}, []interface{}{"one", 2.0}}, }, { "ReplaceMap", ReplaceMap("t_foo", map[string]interface{}{"col1": "one", "col2": 2.0}), &Mutation{opReplace, "t_foo", nil, []string{"col1", "col2"}, []interface{}{"one", 2.0}}, }, { "ReplaceStruct", func() *Mutation { m, err := ReplaceStruct( "t_foo", struct { Col1 string `spanner:"col1"` Col2 float64 `spanner:"col2"` notCol string }{"one", 2.0, "foo"}, ) if err != nil { t.Errorf("cannot convert struct into mutation: %v", err) } return m }(), &Mutation{opReplace, "t_foo", nil, []string{"col1", "col2"}, []interface{}{"one", 2.0}}, }, { "Delete", Delete("t_foo", Key{"foo"}), &Mutation{opDelete, "t_foo", Key{"foo"}, nil, nil}, }, { "DeleteRange", Delete("t_foo", KeyRange{Key{"bar"}, Key{"foo"}, ClosedClosed}), &Mutation{opDelete, "t_foo", KeyRange{Key{"bar"}, Key{"foo"}, ClosedClosed}, nil, nil}, }, } { if !mutationEqual(t, *test.got, *test.want) { t.Errorf("%v: got Mutation %v, want %v", test.m, test.got, test.want) } } } // Test encoding non-struct types by using *Struct helpers. func TestBadStructs(t *testing.T) { val := "i_am_not_a_struct" wantErr := errNotStruct(val) if _, gotErr := InsertStruct("t_test", val); !testEqual(gotErr, wantErr) { t.Errorf("InsertStruct(%q) returns error %v, want %v", val, gotErr, wantErr) } if _, gotErr := InsertOrUpdateStruct("t_test", val); !testEqual(gotErr, wantErr) { t.Errorf("InsertOrUpdateStruct(%q) returns error %v, want %v", val, gotErr, wantErr) } if _, gotErr := UpdateStruct("t_test", val); !testEqual(gotErr, wantErr) { t.Errorf("UpdateStruct(%q) returns error %v, want %v", val, gotErr, wantErr) } if _, gotErr := ReplaceStruct("t_test", val); !testEqual(gotErr, wantErr) { t.Errorf("ReplaceStruct(%q) returns error %v, want %v", val, gotErr, wantErr) } } func TestStructToMutationParams(t *testing.T) { // Tests cases not covered elsewhere. type S struct{ F interface{} } for _, test := range []struct { in interface{} wantCols []string wantVals []interface{} wantErr error }{ {nil, nil, nil, errNotStruct(nil)}, {3, nil, nil, errNotStruct(3)}, {(*S)(nil), nil, nil, nil}, {&S{F: 1}, []string{"F"}, []interface{}{1}, nil}, {&S{F: CommitTimestamp}, []string{"F"}, []interface{}{CommitTimestamp}, nil}, } { gotCols, gotVals, gotErr := structToMutationParams(test.in) if !testEqual(gotCols, test.wantCols) { t.Errorf("%#v: got cols %v, want %v", test.in, gotCols, test.wantCols) } if !testEqual(gotVals, test.wantVals) { t.Errorf("%#v: got vals %v, want %v", test.in, gotVals, test.wantVals) } if !testEqual(gotErr, test.wantErr) { t.Errorf("%#v: got err %v, want %v", test.in, gotErr, test.wantErr) } } } // Test encoding Mutation into proto. func TestEncodeMutation(t *testing.T) { for _, test := range []struct { name string mutation Mutation wantProto *sppb.Mutation wantErr error }{ { "OpDelete", Mutation{opDelete, "t_test", Key{1}, nil, nil}, &sppb.Mutation{ Operation: &sppb.Mutation_Delete_{ Delete: &sppb.Mutation_Delete{ Table: "t_test", KeySet: &sppb.KeySet{ Keys: []*proto3.ListValue{listValueProto(intProto(1))}, }, }, }, }, nil, }, { "OpDelete - Key error", Mutation{opDelete, "t_test", Key{struct{}{}}, nil, nil}, &sppb.Mutation{ Operation: &sppb.Mutation_Delete_{ Delete: &sppb.Mutation_Delete{ Table: "t_test", KeySet: &sppb.KeySet{}, }, }, }, errInvdKeyPartType(struct{}{}), }, { "OpInsert", Mutation{opInsert, "t_test", nil, []string{"key", "val"}, []interface{}{"foo", 1}}, &sppb.Mutation{ Operation: &sppb.Mutation_Insert{ Insert: &sppb.Mutation_Write{ Table: "t_test", Columns: []string{"key", "val"}, Values: []*proto3.ListValue{listValueProto(stringProto("foo"), intProto(1))}, }, }, }, nil, }, { "OpInsert - Value Type Error", Mutation{opInsert, "t_test", nil, []string{"key", "val"}, []interface{}{struct{}{}, 1}}, &sppb.Mutation{ Operation: &sppb.Mutation_Insert{ Insert: &sppb.Mutation_Write{}, }, }, errEncoderUnsupportedType(struct{}{}), }, { "OpInsertOrUpdate", Mutation{opInsertOrUpdate, "t_test", nil, []string{"key", "val"}, []interface{}{"foo", 1}}, &sppb.Mutation{ Operation: &sppb.Mutation_InsertOrUpdate{ InsertOrUpdate: &sppb.Mutation_Write{ Table: "t_test", Columns: []string{"key", "val"}, Values: []*proto3.ListValue{listValueProto(stringProto("foo"), intProto(1))}, }, }, }, nil, }, { "OpInsertOrUpdate - Value Type Error", Mutation{opInsertOrUpdate, "t_test", nil, []string{"key", "val"}, []interface{}{struct{}{}, 1}}, &sppb.Mutation{ Operation: &sppb.Mutation_InsertOrUpdate{ InsertOrUpdate: &sppb.Mutation_Write{}, }, }, errEncoderUnsupportedType(struct{}{}), }, { "OpReplace", Mutation{opReplace, "t_test", nil, []string{"key", "val"}, []interface{}{"foo", 1}}, &sppb.Mutation{ Operation: &sppb.Mutation_Replace{ Replace: &sppb.Mutation_Write{ Table: "t_test", Columns: []string{"key", "val"}, Values: []*proto3.ListValue{listValueProto(stringProto("foo"), intProto(1))}, }, }, }, nil, }, { "OpReplace - Value Type Error", Mutation{opReplace, "t_test", nil, []string{"key", "val"}, []interface{}{struct{}{}, 1}}, &sppb.Mutation{ Operation: &sppb.Mutation_Replace{ Replace: &sppb.Mutation_Write{}, }, }, errEncoderUnsupportedType(struct{}{}), }, { "OpUpdate", Mutation{opUpdate, "t_test", nil, []string{"key", "val"}, []interface{}{"foo", 1}}, &sppb.Mutation{ Operation: &sppb.Mutation_Update{ Update: &sppb.Mutation_Write{ Table: "t_test", Columns: []string{"key", "val"}, Values: []*proto3.ListValue{listValueProto(stringProto("foo"), intProto(1))}, }, }, }, nil, }, { "OpUpdate - Value Type Error", Mutation{opUpdate, "t_test", nil, []string{"key", "val"}, []interface{}{struct{}{}, 1}}, &sppb.Mutation{ Operation: &sppb.Mutation_Update{ Update: &sppb.Mutation_Write{}, }, }, errEncoderUnsupportedType(struct{}{}), }, { "OpKnown - Unknown Mutation Operation Code", Mutation{op(100), "t_test", nil, nil, nil}, &sppb.Mutation{}, errInvdMutationOp(Mutation{op(100), "t_test", nil, nil, nil}), }, } { gotProto, gotErr := test.mutation.proto() if gotErr != nil { if !testEqual(gotErr, test.wantErr) { t.Errorf("%s: %v.proto() returns error %v, want %v", test.name, test.mutation, gotErr, test.wantErr) } continue } if !testEqual(gotProto, test.wantProto) { t.Errorf("%s: %v.proto() = (%v, nil), want (%v, nil)", test.name, test.mutation, gotProto, test.wantProto) } } } // Test Encoding an array of mutations. func TestEncodeMutationArray(t *testing.T) { for _, test := range []struct { name string ms []*Mutation want []*sppb.Mutation wantErr error }{ { "Multiple Mutations", []*Mutation{ {opDelete, "t_test", Key{"bar"}, nil, nil}, {opInsertOrUpdate, "t_test", nil, []string{"key", "val"}, []interface{}{"foo", 1}}, }, []*sppb.Mutation{ { Operation: &sppb.Mutation_Delete_{ Delete: &sppb.Mutation_Delete{ Table: "t_test", KeySet: &sppb.KeySet{ Keys: []*proto3.ListValue{listValueProto(stringProto("bar"))}, }, }, }, }, { Operation: &sppb.Mutation_InsertOrUpdate{ InsertOrUpdate: &sppb.Mutation_Write{ Table: "t_test", Columns: []string{"key", "val"}, Values: []*proto3.ListValue{listValueProto(stringProto("foo"), intProto(1))}, }, }, }, }, nil, }, { "Multiple Mutations - Bad Mutation", []*Mutation{ {opDelete, "t_test", Key{"bar"}, nil, nil}, {opInsertOrUpdate, "t_test", nil, []string{"key", "val"}, []interface{}{"foo", struct{}{}}}, }, []*sppb.Mutation{}, errEncoderUnsupportedType(struct{}{}), }, } { gotProto, gotErr := mutationsProto(test.ms) if gotErr != nil { if !testEqual(gotErr, test.wantErr) { t.Errorf("%v: mutationsProto(%v) returns error %v, want %v", test.name, test.ms, gotErr, test.wantErr) } continue } if !testEqual(gotProto, test.want) { t.Errorf("%v: mutationsProto(%v) = (%v, nil), want (%v, nil)", test.name, test.ms, gotProto, test.want) } } } google-cloud-go-0.49.0/spanner/not_appengine.go000066400000000000000000000013101356504100700214060ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // +build !appengine package spanner // numChannels is the default value for NumChannels of client const numChannels = 4 google-cloud-go-0.49.0/spanner/oc_test.go000066400000000000000000000030501356504100700202230ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package spanner import ( "context" "testing" "time" "cloud.google.com/go/internal/testutil" stestutil "cloud.google.com/go/spanner/internal/testutil" "google.golang.org/api/option" "google.golang.org/grpc" ) // Check that stats are being exported. func TestOCStats(t *testing.T) { te := testutil.NewTestExporter() defer te.Unregister() ms := stestutil.NewMockCloudSpanner(t, trxTs) ms.Serve() ctx := context.Background() c, err := NewClientWithConfig(ctx, "projects/P/instances/I/databases/D", ClientConfig{SessionPoolConfig: SessionPoolConfig{ MinOpened: 0, }}, option.WithEndpoint(ms.Addr()), option.WithGRPCDialOption(grpc.WithInsecure()), option.WithoutAuthentication()) if err != nil { t.Fatal(err) } defer c.Close() c.Single().ReadRow(ctx, "Users", Key{"alice"}, []string{"email"}) // Wait until we see data from the view. select { case <-te.Stats: case <-time.After(1 * time.Second): t.Fatal("no stats were exported before timeout") } } google-cloud-go-0.49.0/spanner/pdml.go000066400000000000000000000102221356504100700175160ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package spanner import ( "context" "cloud.google.com/go/internal/trace" "github.com/googleapis/gax-go/v2" sppb "google.golang.org/genproto/googleapis/spanner/v1" "google.golang.org/grpc/codes" ) // PartitionedUpdate executes a DML statement in parallel across the database, // using separate, internal transactions that commit independently. The DML // statement must be fully partitionable: it must be expressible as the union // of many statements each of which accesses only a single row of the table. The // statement should also be idempotent, because it may be applied more than once. // // PartitionedUpdate returns an estimated count of the number of rows affected. // The actual number of affected rows may be greater than the estimate. func (c *Client) PartitionedUpdate(ctx context.Context, statement Statement) (count int64, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/spanner.PartitionedUpdate") defer func() { trace.EndSpan(ctx, err) }() if err := checkNestedTxn(ctx); err != nil { return 0, err } var ( s *session sh *sessionHandle ) // Create session. s, err = c.sc.createSession(ctx) if err != nil { return 0, toSpannerError(err) } // Delete the session at the end of the request. If the PDML statement // timed out or was cancelled, the DeleteSession request might not succeed, // but the session will eventually be garbage collected by the server. defer s.delete(ctx) sh = &sessionHandle{session: s} // Create the parameters and the SQL request, but without a transaction. // The transaction reference will be added by the executePdml method. params, paramTypes, err := statement.convertParams() if err != nil { return 0, toSpannerError(err) } req := &sppb.ExecuteSqlRequest{ Session: sh.getID(), Sql: statement.SQL, Params: params, ParamTypes: paramTypes, } // Make a retryer for Aborted errors. // TODO: use generic Aborted retryer when merged with master retryer := gax.OnCodes([]codes.Code{codes.Aborted}, DefaultRetryBackoff) // Execute the PDML and retry if the transaction is aborted. executePdmlWithRetry := func(ctx context.Context) (int64, error) { for { count, err := executePdml(ctx, sh, req) if err == nil { return count, nil } delay, shouldRetry := retryer.Retry(err) if !shouldRetry { return 0, err } if err := gax.Sleep(ctx, delay); err != nil { return 0, err } } } return executePdmlWithRetry(ctx) } // executePdml executes the following steps: // 1. Begin a PDML transaction // 2. Add the ID of the PDML transaction to the SQL request. // 3. Execute the update statement on the PDML transaction // // Note that PDML transactions cannot be committed or rolled back. func executePdml(ctx context.Context, sh *sessionHandle, req *sppb.ExecuteSqlRequest) (count int64, err error) { // Begin transaction. res, err := sh.getClient().BeginTransaction(contextWithOutgoingMetadata(ctx, sh.getMetadata()), &sppb.BeginTransactionRequest{ Session: sh.getID(), Options: &sppb.TransactionOptions{ Mode: &sppb.TransactionOptions_PartitionedDml_{PartitionedDml: &sppb.TransactionOptions_PartitionedDml{}}, }, }) if err != nil { return 0, toSpannerError(err) } // Add a reference to the PDML transaction on the ExecuteSql request. req.Transaction = &sppb.TransactionSelector{ Selector: &sppb.TransactionSelector_Id{Id: res.Id}, } resultSet, err := sh.getClient().ExecuteSql(ctx, req) if err != nil { return 0, err } if resultSet.Stats == nil { return 0, spannerErrorf(codes.InvalidArgument, "query passed to Update: %q", req.Sql) } return extractRowCount(resultSet.Stats) } google-cloud-go-0.49.0/spanner/pdml_test.go000066400000000000000000000075131356504100700205660ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package spanner import ( "bytes" "context" "testing" "time" . "cloud.google.com/go/spanner/internal/testutil" sppb "google.golang.org/genproto/googleapis/spanner/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) func TestMockPartitionedUpdate(t *testing.T) { t.Parallel() ctx := context.Background() _, client, teardown := setupMockedTestServer(t) defer teardown() stmt := NewStatement(UpdateBarSetFoo) rowCount, err := client.PartitionedUpdate(ctx, stmt) if err != nil { t.Fatal(err) } want := int64(UpdateBarSetFooRowCount) if rowCount != want { t.Errorf("got %d, want %d", rowCount, want) } } func TestMockPartitionedUpdateWithQuery(t *testing.T) { t.Parallel() ctx := context.Background() _, client, teardown := setupMockedTestServer(t) defer teardown() stmt := NewStatement(SelectFooFromBar) _, err := client.PartitionedUpdate(ctx, stmt) wantCode := codes.InvalidArgument if serr, ok := err.(*Error); !ok || serr.Code != wantCode { t.Errorf("got error %v, want code %s", err, wantCode) } } // PDML should be retried if the transaction is aborted. func TestPartitionedUpdate_Aborted(t *testing.T) { t.Parallel() ctx := context.Background() server, client, teardown := setupMockedTestServer(t) defer teardown() server.TestSpanner.PutExecutionTime(MethodExecuteSql, SimulatedExecutionTime{ Errors: []error{status.Error(codes.Aborted, "Transaction aborted")}, }) stmt := NewStatement(UpdateBarSetFoo) rowCount, err := client.PartitionedUpdate(ctx, stmt) if err != nil { t.Fatal(err) } want := int64(UpdateBarSetFooRowCount) if rowCount != want { t.Errorf("Row count mismatch\ngot: %d\nwant: %d", rowCount, want) } gotReqs, err := shouldHaveReceived(server.TestSpanner, []interface{}{ &sppb.CreateSessionRequest{}, &sppb.BeginTransactionRequest{}, &sppb.ExecuteSqlRequest{}, &sppb.BeginTransactionRequest{}, &sppb.ExecuteSqlRequest{}, &sppb.DeleteSessionRequest{}, }) if err != nil { t.Fatal(err) } id1 := gotReqs[2].(*sppb.ExecuteSqlRequest).Transaction.GetId() id2 := gotReqs[4].(*sppb.ExecuteSqlRequest).Transaction.GetId() if bytes.Equal(id1, id2) { t.Errorf("same transaction used twice, expected two different transactions\ngot tx1: %q\ngot tx2: %q", id1, id2) } } // Test that a deadline is respected by PDML, and that the session that was // created is also deleted, even though the update timed out. func TestPartitionedUpdate_WithDeadline(t *testing.T) { t.Parallel() server, client, teardown := setupMockedTestServer(t) defer teardown() ctx := context.Background() ctx, cancel := context.WithDeadline(ctx, time.Now().Add(50*time.Millisecond)) defer cancel() server.TestSpanner.PutExecutionTime(MethodExecuteSql, SimulatedExecutionTime{ MinimumExecutionTime: 100 * time.Millisecond, }) stmt := NewStatement(UpdateBarSetFoo) // The following update will cause a 'Failed to delete session' warning to // be logged. This is expected. Once each client has its own logger, we // should temporarily turn off logging to prevent this warning to be // logged. _, err := client.PartitionedUpdate(ctx, stmt) if err == nil { t.Fatalf("missing expected error") } wantCode := codes.DeadlineExceeded if status.Code(err) != wantCode { t.Fatalf("got error %v, want code %s", err, wantCode) } } google-cloud-go-0.49.0/spanner/protoutils.go000066400000000000000000000057301356504100700210160ustar00rootroot00000000000000/* Copyright 2017 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spanner import ( "encoding/base64" "strconv" "time" "cloud.google.com/go/civil" proto3 "github.com/golang/protobuf/ptypes/struct" sppb "google.golang.org/genproto/googleapis/spanner/v1" ) // Helpers to generate protobuf values and Cloud Spanner types. func stringProto(s string) *proto3.Value { return &proto3.Value{Kind: stringKind(s)} } func stringKind(s string) *proto3.Value_StringValue { return &proto3.Value_StringValue{StringValue: s} } func stringType() *sppb.Type { return &sppb.Type{Code: sppb.TypeCode_STRING} } func boolProto(b bool) *proto3.Value { return &proto3.Value{Kind: &proto3.Value_BoolValue{BoolValue: b}} } func boolType() *sppb.Type { return &sppb.Type{Code: sppb.TypeCode_BOOL} } func intProto(n int64) *proto3.Value { return &proto3.Value{Kind: &proto3.Value_StringValue{StringValue: strconv.FormatInt(n, 10)}} } func intType() *sppb.Type { return &sppb.Type{Code: sppb.TypeCode_INT64} } func floatProto(n float64) *proto3.Value { return &proto3.Value{Kind: &proto3.Value_NumberValue{NumberValue: n}} } func floatType() *sppb.Type { return &sppb.Type{Code: sppb.TypeCode_FLOAT64} } func bytesProto(b []byte) *proto3.Value { return &proto3.Value{Kind: &proto3.Value_StringValue{StringValue: base64.StdEncoding.EncodeToString(b)}} } func bytesType() *sppb.Type { return &sppb.Type{Code: sppb.TypeCode_BYTES} } func timeProto(t time.Time) *proto3.Value { return stringProto(t.UTC().Format(time.RFC3339Nano)) } func timeType() *sppb.Type { return &sppb.Type{Code: sppb.TypeCode_TIMESTAMP} } func dateProto(d civil.Date) *proto3.Value { return stringProto(d.String()) } func dateType() *sppb.Type { return &sppb.Type{Code: sppb.TypeCode_DATE} } func listProto(p ...*proto3.Value) *proto3.Value { return &proto3.Value{Kind: &proto3.Value_ListValue{ListValue: &proto3.ListValue{Values: p}}} } func listValueProto(p ...*proto3.Value) *proto3.ListValue { return &proto3.ListValue{Values: p} } func listType(t *sppb.Type) *sppb.Type { return &sppb.Type{Code: sppb.TypeCode_ARRAY, ArrayElementType: t} } func mkField(n string, t *sppb.Type) *sppb.StructType_Field { return &sppb.StructType_Field{Name: n, Type: t} } func structType(fields ...*sppb.StructType_Field) *sppb.Type { return &sppb.Type{Code: sppb.TypeCode_STRUCT, StructType: &sppb.StructType{Fields: fields}} } func nullProto() *proto3.Value { return &proto3.Value{Kind: &proto3.Value_NullValue{NullValue: proto3.NullValue_NULL_VALUE}} } google-cloud-go-0.49.0/spanner/read.go000066400000000000000000000572051356504100700175110ustar00rootroot00000000000000/* Copyright 2017 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spanner import ( "bytes" "context" "io" "log" "sync/atomic" "time" "cloud.google.com/go/internal/protostruct" "cloud.google.com/go/internal/trace" "github.com/golang/protobuf/proto" proto3 "github.com/golang/protobuf/ptypes/struct" "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" sppb "google.golang.org/genproto/googleapis/spanner/v1" "google.golang.org/grpc/codes" ) // streamingReceiver is the interface for receiving data from a client side // stream. type streamingReceiver interface { Recv() (*sppb.PartialResultSet, error) } // errEarlyReadEnd returns error for read finishes when gRPC stream is still // active. func errEarlyReadEnd() error { return spannerErrorf(codes.FailedPrecondition, "read completed with active stream") } // stream is the internal fault tolerant method for streaming data from Cloud // Spanner. func stream(ctx context.Context, rpc func(ct context.Context, resumeToken []byte) (streamingReceiver, error), setTimestamp func(time.Time), release func(error)) *RowIterator { ctx, cancel := context.WithCancel(ctx) ctx = trace.StartSpan(ctx, "cloud.google.com/go/spanner.RowIterator") return &RowIterator{ streamd: newResumableStreamDecoder(ctx, rpc), rowd: &partialResultSetDecoder{}, setTimestamp: setTimestamp, release: release, cancel: cancel, } } // RowIterator is an iterator over Rows. type RowIterator struct { // The plan for the query. Available after RowIterator.Next returns // iterator.Done if QueryWithStats was called. QueryPlan *sppb.QueryPlan // Execution statistics for the query. Available after RowIterator.Next // returns iterator.Done if QueryWithStats was called. QueryStats map[string]interface{} // For a DML statement, the number of rows affected. For PDML, this is a // lower bound. Available for DML statements after RowIterator.Next returns // iterator.Done. RowCount int64 streamd *resumableStreamDecoder rowd *partialResultSetDecoder setTimestamp func(time.Time) release func(error) cancel func() err error rows []*Row sawStats bool } // Next returns the next result. Its second return value is iterator.Done if // there are no more results. Once Next returns Done, all subsequent calls // will return Done. func (r *RowIterator) Next() (*Row, error) { if r.err != nil { return nil, r.err } for len(r.rows) == 0 && r.streamd.next() { prs := r.streamd.get() if prs.Stats != nil { r.sawStats = true r.QueryPlan = prs.Stats.QueryPlan r.QueryStats = protostruct.DecodeToMap(prs.Stats.QueryStats) if prs.Stats.RowCount != nil { rc, err := extractRowCount(prs.Stats) if err != nil { return nil, err } r.RowCount = rc } } r.rows, r.err = r.rowd.add(prs) if r.err != nil { return nil, r.err } if !r.rowd.ts.IsZero() && r.setTimestamp != nil { r.setTimestamp(r.rowd.ts) r.setTimestamp = nil } } if len(r.rows) > 0 { row := r.rows[0] r.rows = r.rows[1:] return row, nil } if err := r.streamd.lastErr(); err != nil { r.err = toSpannerError(err) } else if !r.rowd.done() { r.err = errEarlyReadEnd() } else { r.err = iterator.Done } return nil, r.err } func extractRowCount(stats *sppb.ResultSetStats) (int64, error) { if stats.RowCount == nil { return 0, spannerErrorf(codes.Internal, "missing RowCount") } switch rc := stats.RowCount.(type) { case *sppb.ResultSetStats_RowCountExact: return rc.RowCountExact, nil case *sppb.ResultSetStats_RowCountLowerBound: return rc.RowCountLowerBound, nil default: return 0, spannerErrorf(codes.Internal, "unknown RowCount type %T", stats.RowCount) } } // Do calls the provided function once in sequence for each row in the // iteration. If the function returns a non-nil error, Do immediately returns // that error. // // If there are no rows in the iterator, Do will return nil without calling the // provided function. // // Do always calls Stop on the iterator. func (r *RowIterator) Do(f func(r *Row) error) error { defer r.Stop() for { row, err := r.Next() switch err { case iterator.Done: return nil case nil: if err = f(row); err != nil { return err } default: return err } } } // Stop terminates the iteration. It should be called after you finish using the // iterator. func (r *RowIterator) Stop() { if r.streamd != nil { defer trace.EndSpan(r.streamd.ctx, r.err) } if r.cancel != nil { r.cancel() } if r.release != nil { r.release(r.err) if r.err == nil { r.err = spannerErrorf(codes.FailedPrecondition, "Next called after Stop") } r.release = nil } } // partialResultQueue implements a simple FIFO queue. The zero value is a valid // queue. type partialResultQueue struct { q []*sppb.PartialResultSet first int last int n int // number of elements in queue } // empty returns if the partialResultQueue is empty. func (q *partialResultQueue) empty() bool { return q.n == 0 } // errEmptyQueue returns error for dequeuing an empty queue. func errEmptyQueue() error { return spannerErrorf(codes.OutOfRange, "empty partialResultQueue") } // peekLast returns the last item in partialResultQueue; if the queue // is empty, it returns error. func (q *partialResultQueue) peekLast() (*sppb.PartialResultSet, error) { if q.empty() { return nil, errEmptyQueue() } return q.q[(q.last+cap(q.q)-1)%cap(q.q)], nil } // push adds an item to the tail of partialResultQueue. func (q *partialResultQueue) push(r *sppb.PartialResultSet) { if q.q == nil { q.q = make([]*sppb.PartialResultSet, 8 /* arbitrary */) } if q.n == cap(q.q) { buf := make([]*sppb.PartialResultSet, cap(q.q)*2) for i := 0; i < q.n; i++ { buf[i] = q.q[(q.first+i)%cap(q.q)] } q.q = buf q.first = 0 q.last = q.n } q.q[q.last] = r q.last = (q.last + 1) % cap(q.q) q.n++ } // pop removes an item from the head of partialResultQueue and returns it. func (q *partialResultQueue) pop() *sppb.PartialResultSet { if q.n == 0 { return nil } r := q.q[q.first] q.q[q.first] = nil q.first = (q.first + 1) % cap(q.q) q.n-- return r } // clear empties partialResultQueue. func (q *partialResultQueue) clear() { *q = partialResultQueue{} } // dump retrieves all items from partialResultQueue and return them in a slice. // It is used only in tests. func (q *partialResultQueue) dump() []*sppb.PartialResultSet { var dq []*sppb.PartialResultSet for i := q.first; len(dq) < q.n; i = (i + 1) % cap(q.q) { dq = append(dq, q.q[i]) } return dq } // resumableStreamDecoderState encodes resumableStreamDecoder's status. See also // the comments for resumableStreamDecoder.Next. type resumableStreamDecoderState int const ( unConnected resumableStreamDecoderState = iota // 0 queueingRetryable // 1 queueingUnretryable // 2 aborted // 3 finished // 4 ) // resumableStreamDecoder provides a resumable interface for receiving // sppb.PartialResultSet(s) from a given query wrapped by // resumableStreamDecoder.rpc(). type resumableStreamDecoder struct { // state is the current status of resumableStreamDecoder, see also // the comments for resumableStreamDecoder.Next. state resumableStreamDecoderState // stateWitness when non-nil is called to observe state change, // used for testing. stateWitness func(resumableStreamDecoderState) // ctx is the caller's context, used for cancel/timeout Next(). ctx context.Context // rpc is a factory of streamingReceiver, which might resume // a previous stream from the point encoded in restartToken. // rpc is always a wrapper of a Cloud Spanner query which is // resumable. rpc func(ctx context.Context, restartToken []byte) (streamingReceiver, error) // stream is the current RPC streaming receiver. stream streamingReceiver // q buffers received yet undecoded partial results. q partialResultQueue // bytesBetweenResumeTokens is the proxy of the byte size of // PartialResultSets being queued between two resume tokens. Once // bytesBetweenResumeTokens is greater than maxBytesBetweenResumeTokens, // resumableStreamDecoder goes into queueingUnretryable state. bytesBetweenResumeTokens int32 // maxBytesBetweenResumeTokens is the max number of bytes that can be // buffered between two resume tokens. It is always copied from the global // maxBytesBetweenResumeTokens atomically. maxBytesBetweenResumeTokens int32 // np is the next sppb.PartialResultSet ready to be returned // to caller of resumableStreamDecoder.Get(). np *sppb.PartialResultSet // resumeToken stores the resume token that resumableStreamDecoder has // last revealed to caller. resumeToken []byte // err is the last error resumableStreamDecoder has encountered so far. err error // backoff is used for the retry settings backoff gax.Backoff } // newResumableStreamDecoder creates a new resumeableStreamDecoder instance. // Parameter rpc should be a function that creates a new stream beginning at the // restartToken if non-nil. func newResumableStreamDecoder(ctx context.Context, rpc func(ct context.Context, restartToken []byte) (streamingReceiver, error)) *resumableStreamDecoder { return &resumableStreamDecoder{ ctx: ctx, rpc: rpc, maxBytesBetweenResumeTokens: atomic.LoadInt32(&maxBytesBetweenResumeTokens), backoff: DefaultRetryBackoff, } } // changeState fulfills state transition for resumableStateDecoder. func (d *resumableStreamDecoder) changeState(target resumableStreamDecoderState) { if d.state == queueingRetryable && d.state != target { // Reset bytesBetweenResumeTokens because it is only meaningful/changed // under queueingRetryable state. d.bytesBetweenResumeTokens = 0 } d.state = target if d.stateWitness != nil { d.stateWitness(target) } } // isNewResumeToken returns if the observed resume token is different from // the one returned from server last time. func (d *resumableStreamDecoder) isNewResumeToken(rt []byte) bool { if rt == nil { return false } if bytes.Equal(rt, d.resumeToken) { return false } return true } // Next advances to the next available partial result set. If error or no // more, returns false, call Err to determine if an error was encountered. // The following diagram illustrates the state machine of resumableStreamDecoder // that Next() implements. Note that state transition can be only triggered by // RPC activities. /* rpc() fails retryable +---------+ | | rpc() fails unretryable/ctx timeouts or cancelled | | +------------------------------------------------+ | | | | | v | v | +---+---+---+ +--------+ +------+--+ +-----+unConnected| |finished| | aborted |<----+ | | ++-----+-+ +------+--+ | +---+----+--+ ^ ^ ^ | | ^ | | | | | | | | recv() fails | | | | | | | | |recv() fails retryable | | | | | |with valid ctx | | | | | | | | | | rpc() succeeds | +-----------------------+ | | | | | | recv EOF recv EOF | | | | | | | | v | | Queue size exceeds | | | +---+----+---+----+threshold +-------+-----------+ | | +---------->+ +--------------->+ +-+ | | |queueingRetryable| |queueingUnretryable| | | | +<---------------+ | | | +---+----------+--+ pop() returns +--+----+-----------+ | | | | resume token | ^ | | | | | | | | | | | | | +---------------+ | | | | recv() succeeds | +----+ | | recv() succeeds | | | | | | | | | | | +--------------------------------------------------+ recv() fails unretryable */ var ( // maxBytesBetweenResumeTokens is the maximum amount of bytes that // resumableStreamDecoder in queueingRetryable state can use to queue // PartialResultSets before getting into queueingUnretryable state. maxBytesBetweenResumeTokens = int32(128 * 1024 * 1024) ) func (d *resumableStreamDecoder) next() bool { retryer := gax.OnCodes([]codes.Code{codes.Unavailable, codes.Internal}, d.backoff) for { switch d.state { case unConnected: // If no gRPC stream is available, try to initiate one. d.stream, d.err = d.rpc(d.ctx, d.resumeToken) if d.err == nil { d.changeState(queueingRetryable) continue } delay, shouldRetry := retryer.Retry(d.err) if !shouldRetry { d.changeState(aborted) continue } trace.TracePrintf(d.ctx, nil, "Backing off stream read for %s", delay) if err := gax.Sleep(d.ctx, delay); err == nil { // Be explicit about state transition, although the // state doesn't actually change. State transition // will be triggered only by RPC activity, regardless of // whether there is an actual state change or not. d.changeState(unConnected) } else { d.err = err d.changeState(aborted) } continue case queueingRetryable: fallthrough case queueingUnretryable: // Receiving queue is not empty. last, err := d.q.peekLast() if err != nil { // Only the case that receiving queue is empty could cause // peekLast to return error and in such case, we should try to // receive from stream. d.tryRecv(retryer) continue } if d.isNewResumeToken(last.ResumeToken) { // Got new resume token, return buffered sppb.PartialResultSets // to caller. d.np = d.q.pop() if d.q.empty() { d.bytesBetweenResumeTokens = 0 // The new resume token was just popped out from queue, // record it. d.resumeToken = d.np.ResumeToken d.changeState(queueingRetryable) } return true } if d.bytesBetweenResumeTokens >= d.maxBytesBetweenResumeTokens && d.state == queueingRetryable { d.changeState(queueingUnretryable) continue } if d.state == queueingUnretryable { // When there is no resume token observed, only yield // sppb.PartialResultSets to caller under queueingUnretryable // state. d.np = d.q.pop() return true } // Needs to receive more from gRPC stream till a new resume token // is observed. d.tryRecv(retryer) continue case aborted: // Discard all pending items because none of them should be yield // to caller. d.q.clear() return false case finished: // If query has finished, check if there are still buffered messages. if d.q.empty() { // No buffered PartialResultSet. return false } // Although query has finished, there are still buffered // PartialResultSets. d.np = d.q.pop() return true default: log.Printf("Unexpected resumableStreamDecoder.state: %v", d.state) return false } } } // tryRecv attempts to receive a PartialResultSet from gRPC stream. func (d *resumableStreamDecoder) tryRecv(retryer gax.Retryer) { var res *sppb.PartialResultSet res, d.err = d.stream.Recv() if d.err == nil { d.q.push(res) if d.state == queueingRetryable && !d.isNewResumeToken(res.ResumeToken) { d.bytesBetweenResumeTokens += int32(proto.Size(res)) } d.changeState(d.state) return } if d.err == io.EOF { d.err = nil d.changeState(finished) return } delay, shouldRetry := retryer.Retry(d.err) if !shouldRetry || d.state != queueingRetryable { d.changeState(aborted) return } if err := gax.Sleep(d.ctx, delay); err != nil { d.err = err d.changeState(aborted) return } // Clear error and retry the stream. d.err = nil // Discard all queue items (none have resume tokens). d.q.clear() d.stream = nil d.changeState(unConnected) } // get returns the most recent PartialResultSet generated by a call to next. func (d *resumableStreamDecoder) get() *sppb.PartialResultSet { return d.np } // lastErr returns the last non-EOF error encountered. func (d *resumableStreamDecoder) lastErr() error { return d.err } // partialResultSetDecoder assembles PartialResultSet(s) into Cloud Spanner // Rows. type partialResultSetDecoder struct { row Row tx *sppb.Transaction chunked bool // if true, next value should be merged with last values // entry. ts time.Time // read timestamp } // yield checks we have a complete row, and if so returns it. A row is not // complete if it doesn't have enough columns, or if this is a chunked response // and there are no further values to process. func (p *partialResultSetDecoder) yield(chunked, last bool) *Row { if len(p.row.vals) == len(p.row.fields) && (!chunked || !last) { // When partialResultSetDecoder gets enough number of Column values. // There are two cases that a new Row should be yield: // // 1. The incoming PartialResultSet is not chunked; // 2. The incoming PartialResultSet is chunked, but the // proto3.Value being merged is not the last one in // the PartialResultSet. // // Use a fresh Row to simplify clients that want to use yielded results // after the next row is retrieved. Note that fields is never changed // so it doesn't need to be copied. fresh := Row{ fields: p.row.fields, vals: make([]*proto3.Value, len(p.row.vals)), } copy(fresh.vals, p.row.vals) p.row.vals = p.row.vals[:0] // empty and reuse slice return &fresh } return nil } // yieldTx returns transaction information via caller supplied callback. func errChunkedEmptyRow() error { return spannerErrorf(codes.FailedPrecondition, "got invalid chunked PartialResultSet with empty Row") } // add tries to merge a new PartialResultSet into buffered Row. It returns any // rows that have been completed as a result. func (p *partialResultSetDecoder) add(r *sppb.PartialResultSet) ([]*Row, error) { var rows []*Row if r.Metadata != nil { // Metadata should only be returned in the first result. if p.row.fields == nil { p.row.fields = r.Metadata.RowType.Fields } if p.tx == nil && r.Metadata.Transaction != nil { p.tx = r.Metadata.Transaction if p.tx.ReadTimestamp != nil { p.ts = time.Unix(p.tx.ReadTimestamp.Seconds, int64(p.tx.ReadTimestamp.Nanos)) } } } if len(r.Values) == 0 { return nil, nil } if p.chunked { p.chunked = false // Try to merge first value in r.Values into uncompleted row. last := len(p.row.vals) - 1 if last < 0 { // sanity check return nil, errChunkedEmptyRow() } var err error // If p is chunked, then we should always try to merge p.last with // r.first. if p.row.vals[last], err = p.merge(p.row.vals[last], r.Values[0]); err != nil { return nil, err } r.Values = r.Values[1:] // Merge is done, try to yield a complete Row. if row := p.yield(r.ChunkedValue, len(r.Values) == 0); row != nil { rows = append(rows, row) } } for i, v := range r.Values { // The rest values in r can be appened into p directly. p.row.vals = append(p.row.vals, v) // Again, check to see if a complete Row can be yielded because of the // newly added value. if row := p.yield(r.ChunkedValue, i == len(r.Values)-1); row != nil { rows = append(rows, row) } } if r.ChunkedValue { // After dealing with all values in r, if r is chunked then p must be // also chunked. p.chunked = true } return rows, nil } // isMergeable returns if a protobuf Value can be potentially merged with other // protobuf Values. func (p *partialResultSetDecoder) isMergeable(a *proto3.Value) bool { switch a.Kind.(type) { case *proto3.Value_StringValue: return true case *proto3.Value_ListValue: return true default: return false } } // errIncompatibleMergeTypes returns error for incompatible protobuf types that // cannot be merged by partialResultSetDecoder. func errIncompatibleMergeTypes(a, b *proto3.Value) error { return spannerErrorf(codes.FailedPrecondition, "incompatible type in chunked PartialResultSet. expected (%T), got (%T)", a.Kind, b.Kind) } // errUnsupportedMergeType returns error for protobuf type that cannot be merged // to other protobufs. func errUnsupportedMergeType(a *proto3.Value) error { return spannerErrorf(codes.FailedPrecondition, "unsupported type merge (%T)", a.Kind) } // merge tries to combine two protobuf Values if possible. func (p *partialResultSetDecoder) merge(a, b *proto3.Value) (*proto3.Value, error) { var err error typeErr := errIncompatibleMergeTypes(a, b) switch t := a.Kind.(type) { case *proto3.Value_StringValue: s, ok := b.Kind.(*proto3.Value_StringValue) if !ok { return nil, typeErr } return &proto3.Value{ Kind: &proto3.Value_StringValue{StringValue: t.StringValue + s.StringValue}, }, nil case *proto3.Value_ListValue: l, ok := b.Kind.(*proto3.Value_ListValue) if !ok { return nil, typeErr } if l.ListValue == nil || len(l.ListValue.Values) <= 0 { // b is an empty list, just return a. return a, nil } if t.ListValue == nil || len(t.ListValue.Values) <= 0 { // a is an empty list, just return b. return b, nil } if la := len(t.ListValue.Values) - 1; p.isMergeable(t.ListValue.Values[la]) { // When the last item in a is of type String, List or Struct // (encoded into List by Cloud Spanner), try to Merge last item in // a and first item in b. t.ListValue.Values[la], err = p.merge(t.ListValue.Values[la], l.ListValue.Values[0]) if err != nil { return nil, err } l.ListValue.Values = l.ListValue.Values[1:] } return &proto3.Value{ Kind: &proto3.Value_ListValue{ ListValue: &proto3.ListValue{ Values: append(t.ListValue.Values, l.ListValue.Values...), }, }, }, nil default: return nil, errUnsupportedMergeType(a) } } // Done returns if partialResultSetDecoder has already done with all buffered // values. func (p *partialResultSetDecoder) done() bool { // There is no explicit end of stream marker, but ending part way through a // row is obviously bad, or ending with the last column still awaiting // completion. return len(p.row.vals) == 0 && !p.chunked } google-cloud-go-0.49.0/spanner/read_test.go000066400000000000000000001414651356504100700205520ustar00rootroot00000000000000/* Copyright 2017 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spanner import ( "context" "errors" "fmt" "io" "sync/atomic" "testing" "time" . "cloud.google.com/go/spanner/internal/testutil" "github.com/golang/protobuf/proto" proto3 "github.com/golang/protobuf/ptypes/struct" "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" sppb "google.golang.org/genproto/googleapis/spanner/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) var ( // Mocked transaction timestamp. trxTs = time.Unix(1, 2) // Metadata for mocked KV table, its rows are returned by SingleUse // transactions. kvMeta = func() *sppb.ResultSetMetadata { meta := KvMeta meta.Transaction = &sppb.Transaction{ ReadTimestamp: timestampProto(trxTs), } return &meta }() // Metadata for mocked ListKV table, which uses List for its key and value. // Its rows are returned by snapshot readonly transactions, as indicated in // the transaction metadata. kvListMeta = &sppb.ResultSetMetadata{ RowType: &sppb.StructType{ Fields: []*sppb.StructType_Field{ { Name: "Key", Type: &sppb.Type{ Code: sppb.TypeCode_ARRAY, ArrayElementType: &sppb.Type{ Code: sppb.TypeCode_STRING, }, }, }, { Name: "Value", Type: &sppb.Type{ Code: sppb.TypeCode_ARRAY, ArrayElementType: &sppb.Type{ Code: sppb.TypeCode_STRING, }, }, }, }, }, Transaction: &sppb.Transaction{ Id: transactionID{5, 6, 7, 8, 9}, ReadTimestamp: timestampProto(trxTs), }, } // Metadata for mocked schema of a query result set, which has two struct // columns named "Col1" and "Col2", the struct's schema is like the // following: // // STRUCT { // INT // LIST // } // // Its rows are returned in readwrite transaction, as indicated in the // transaction metadata. kvObjectMeta = &sppb.ResultSetMetadata{ RowType: &sppb.StructType{ Fields: []*sppb.StructType_Field{ { Name: "Col1", Type: &sppb.Type{ Code: sppb.TypeCode_STRUCT, StructType: &sppb.StructType{ Fields: []*sppb.StructType_Field{ { Name: "foo-f1", Type: &sppb.Type{ Code: sppb.TypeCode_INT64, }, }, { Name: "foo-f2", Type: &sppb.Type{ Code: sppb.TypeCode_ARRAY, ArrayElementType: &sppb.Type{ Code: sppb.TypeCode_STRING, }, }, }, }, }, }, }, { Name: "Col2", Type: &sppb.Type{ Code: sppb.TypeCode_STRUCT, StructType: &sppb.StructType{ Fields: []*sppb.StructType_Field{ { Name: "bar-f1", Type: &sppb.Type{ Code: sppb.TypeCode_INT64, }, }, { Name: "bar-f2", Type: &sppb.Type{ Code: sppb.TypeCode_ARRAY, ArrayElementType: &sppb.Type{ Code: sppb.TypeCode_STRING, }, }, }, }, }, }, }, }, }, Transaction: &sppb.Transaction{ Id: transactionID{1, 2, 3, 4, 5}, }, } ) // String implements fmt.stringer. func (r *Row) String() string { return fmt.Sprintf("{fields: %s, val: %s}", r.fields, r.vals) } func describeRows(l []*Row) string { // generate a nice test failure description var s = "[" for i, r := range l { if i != 0 { s += ",\n " } s += fmt.Sprint(r) } s += "]" return s } // Helper for generating proto3 Value_ListValue instances, making test code // shorter and readable. func genProtoListValue(v ...string) *proto3.Value_ListValue { r := &proto3.Value_ListValue{ ListValue: &proto3.ListValue{ Values: []*proto3.Value{}, }, } for _, e := range v { r.ListValue.Values = append( r.ListValue.Values, &proto3.Value{ Kind: &proto3.Value_StringValue{StringValue: e}, }, ) } return r } // Test Row generation logics of partialResultSetDecoder. func TestPartialResultSetDecoder(t *testing.T) { restore := setMaxBytesBetweenResumeTokens() defer restore() var tests = []struct { input []*sppb.PartialResultSet wantF []*Row wantTxID transactionID wantTs time.Time wantD bool }{ { // Empty input. wantD: true, }, // String merging examples. { // Single KV result. input: []*sppb.PartialResultSet{ { Metadata: kvMeta, Values: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: "foo"}}, {Kind: &proto3.Value_StringValue{StringValue: "bar"}}, }, }, }, wantF: []*Row{ { fields: kvMeta.RowType.Fields, vals: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: "foo"}}, {Kind: &proto3.Value_StringValue{StringValue: "bar"}}, }, }, }, wantTs: trxTs, wantD: true, }, { // Incomplete partial result. input: []*sppb.PartialResultSet{ { Metadata: kvMeta, Values: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: "foo"}}, }, }, }, wantTs: trxTs, wantD: false, }, { // Complete splitted result. input: []*sppb.PartialResultSet{ { Metadata: kvMeta, Values: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: "foo"}}, }, }, { Values: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: "bar"}}, }, }, }, wantF: []*Row{ { fields: kvMeta.RowType.Fields, vals: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: "foo"}}, {Kind: &proto3.Value_StringValue{StringValue: "bar"}}, }, }, }, wantTs: trxTs, wantD: true, }, { // Multi-row example with splitted row in the middle. input: []*sppb.PartialResultSet{ { Metadata: kvMeta, Values: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: "foo"}}, {Kind: &proto3.Value_StringValue{StringValue: "bar"}}, {Kind: &proto3.Value_StringValue{StringValue: "A"}}, }, }, { Values: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: "1"}}, {Kind: &proto3.Value_StringValue{StringValue: "B"}}, {Kind: &proto3.Value_StringValue{StringValue: "2"}}, }, }, }, wantF: []*Row{ { fields: kvMeta.RowType.Fields, vals: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: "foo"}}, {Kind: &proto3.Value_StringValue{StringValue: "bar"}}, }, }, { fields: kvMeta.RowType.Fields, vals: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: "A"}}, {Kind: &proto3.Value_StringValue{StringValue: "1"}}, }, }, { fields: kvMeta.RowType.Fields, vals: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: "B"}}, {Kind: &proto3.Value_StringValue{StringValue: "2"}}, }, }, }, wantTs: trxTs, wantD: true, }, { // Merging example in result_set.proto. input: []*sppb.PartialResultSet{ { Metadata: kvMeta, Values: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: "Hello"}}, {Kind: &proto3.Value_StringValue{StringValue: "W"}}, }, ChunkedValue: true, }, { Values: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: "orl"}}, }, ChunkedValue: true, }, { Values: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: "d"}}, }, }, }, wantF: []*Row{ { fields: kvMeta.RowType.Fields, vals: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: "Hello"}}, {Kind: &proto3.Value_StringValue{StringValue: "World"}}, }, }, }, wantTs: trxTs, wantD: true, }, { // More complex example showing completing a merge and // starting a new merge in the same partialResultSet. input: []*sppb.PartialResultSet{ { Metadata: kvMeta, Values: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: "Hello"}}, {Kind: &proto3.Value_StringValue{StringValue: "W"}}, // start split in value }, ChunkedValue: true, }, { Values: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: "orld"}}, // complete value {Kind: &proto3.Value_StringValue{StringValue: "i"}}, // start split in key }, ChunkedValue: true, }, { Values: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: "s"}}, // complete key {Kind: &proto3.Value_StringValue{StringValue: "not"}}, {Kind: &proto3.Value_StringValue{StringValue: "a"}}, {Kind: &proto3.Value_StringValue{StringValue: "qu"}}, // split in value }, ChunkedValue: true, }, { Values: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: "estion"}}, // complete value }, }, }, wantF: []*Row{ { fields: kvMeta.RowType.Fields, vals: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: "Hello"}}, {Kind: &proto3.Value_StringValue{StringValue: "World"}}, }, }, { fields: kvMeta.RowType.Fields, vals: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: "is"}}, {Kind: &proto3.Value_StringValue{StringValue: "not"}}, }, }, { fields: kvMeta.RowType.Fields, vals: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: "a"}}, {Kind: &proto3.Value_StringValue{StringValue: "question"}}, }, }, }, wantTs: trxTs, wantD: true, }, // List merging examples. { // Non-splitting Lists. input: []*sppb.PartialResultSet{ { Metadata: kvListMeta, Values: []*proto3.Value{ { Kind: genProtoListValue("foo-1", "foo-2"), }, }, }, { Values: []*proto3.Value{ { Kind: genProtoListValue("bar-1", "bar-2"), }, }, }, }, wantF: []*Row{ { fields: kvListMeta.RowType.Fields, vals: []*proto3.Value{ { Kind: genProtoListValue("foo-1", "foo-2"), }, { Kind: genProtoListValue("bar-1", "bar-2"), }, }, }, }, wantTxID: transactionID{5, 6, 7, 8, 9}, wantTs: trxTs, wantD: true, }, { // Simple List merge case: splitted string element. input: []*sppb.PartialResultSet{ { Metadata: kvListMeta, Values: []*proto3.Value{ { Kind: genProtoListValue("foo-1", "foo-"), }, }, ChunkedValue: true, }, { Values: []*proto3.Value{ { Kind: genProtoListValue("2"), }, }, }, { Values: []*proto3.Value{ { Kind: genProtoListValue("bar-1", "bar-2"), }, }, }, }, wantF: []*Row{ { fields: kvListMeta.RowType.Fields, vals: []*proto3.Value{ { Kind: genProtoListValue("foo-1", "foo-2"), }, { Kind: genProtoListValue("bar-1", "bar-2"), }, }, }, }, wantTxID: transactionID{5, 6, 7, 8, 9}, wantTs: trxTs, wantD: true, }, { // Struct merging is also implemented by List merging. Note that // Cloud Spanner uses proto.ListValue to encode Structs as well. input: []*sppb.PartialResultSet{ { Metadata: kvObjectMeta, Values: []*proto3.Value{ { Kind: &proto3.Value_ListValue{ ListValue: &proto3.ListValue{ Values: []*proto3.Value{ {Kind: &proto3.Value_NumberValue{NumberValue: 23}}, {Kind: genProtoListValue("foo-1", "fo")}, }, }, }, }, }, ChunkedValue: true, }, { Values: []*proto3.Value{ { Kind: &proto3.Value_ListValue{ ListValue: &proto3.ListValue{ Values: []*proto3.Value{ {Kind: genProtoListValue("o-2", "f")}, }, }, }, }, }, ChunkedValue: true, }, { Values: []*proto3.Value{ { Kind: &proto3.Value_ListValue{ ListValue: &proto3.ListValue{ Values: []*proto3.Value{ {Kind: genProtoListValue("oo-3")}, }, }, }, }, { Kind: &proto3.Value_ListValue{ ListValue: &proto3.ListValue{ Values: []*proto3.Value{ {Kind: &proto3.Value_NumberValue{NumberValue: 45}}, {Kind: genProtoListValue("bar-1")}, }, }, }, }, }, }, }, wantF: []*Row{ { fields: kvObjectMeta.RowType.Fields, vals: []*proto3.Value{ { Kind: &proto3.Value_ListValue{ ListValue: &proto3.ListValue{ Values: []*proto3.Value{ {Kind: &proto3.Value_NumberValue{NumberValue: 23}}, {Kind: genProtoListValue("foo-1", "foo-2", "foo-3")}, }, }, }, }, { Kind: &proto3.Value_ListValue{ ListValue: &proto3.ListValue{ Values: []*proto3.Value{ {Kind: &proto3.Value_NumberValue{NumberValue: 45}}, {Kind: genProtoListValue("bar-1")}, }, }, }, }, }, }, }, wantTxID: transactionID{1, 2, 3, 4, 5}, wantD: true, }, } nextTest: for i, test := range tests { var rows []*Row p := &partialResultSetDecoder{} for j, v := range test.input { rs, err := p.add(v) if err != nil { t.Errorf("test %d.%d: partialResultSetDecoder.add(%v) = %v; want nil", i, j, v, err) continue nextTest } rows = append(rows, rs...) } if !testEqual(p.ts, test.wantTs) { t.Errorf("got transaction(%v), want %v", p.ts, test.wantTs) } if !testEqual(rows, test.wantF) { t.Errorf("test %d: rows=\n%v\n; want\n%v\n; p.row:\n%v\n", i, describeRows(rows), describeRows(test.wantF), p.row) } if got := p.done(); got != test.wantD { t.Errorf("test %d: partialResultSetDecoder.done() = %v", i, got) } } } const ( // max number of PartialResultSets that will be buffered in tests. maxBuffers = 16 ) // setMaxBytesBetweenResumeTokens sets the global maxBytesBetweenResumeTokens to // a smaller value more suitable for tests. It returns a function which should // be called to restore the maxBytesBetweenResumeTokens to its old value. func setMaxBytesBetweenResumeTokens() func() { o := atomic.LoadInt32(&maxBytesBetweenResumeTokens) atomic.StoreInt32(&maxBytesBetweenResumeTokens, int32(maxBuffers*proto.Size(&sppb.PartialResultSet{ Metadata: kvMeta, Values: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: keyStr(0)}}, {Kind: &proto3.Value_StringValue{StringValue: valStr(0)}}, }, }))) return func() { atomic.StoreInt32(&maxBytesBetweenResumeTokens, o) } } // keyStr generates key string for kvMeta schema. func keyStr(i int) string { return fmt.Sprintf("foo-%02d", i) } // valStr generates value string for kvMeta schema. func valStr(i int) string { return fmt.Sprintf("bar-%02d", i) } // Test state transitions of resumableStreamDecoder where state machine ends up // to a non-blocking state(resumableStreamDecoder.Next returns on non-blocking // state). func TestRsdNonblockingStates(t *testing.T) { restore := setMaxBytesBetweenResumeTokens() defer restore() tests := []struct { name string msgs []MockCtlMsg rpc func(ct context.Context, resumeToken []byte) (streamingReceiver, error) sql string // Expected values want []*sppb.PartialResultSet // PartialResultSets that should be returned to caller queue []*sppb.PartialResultSet // PartialResultSets that should be buffered resumeToken []byte // Resume token that is maintained by resumableStreamDecoder stateHistory []resumableStreamDecoderState // State transition history of resumableStreamDecoder wantErr error }{ { // unConnected->queueingRetryable->finished name: "unConnected->queueingRetryable->finished", msgs: []MockCtlMsg{ {}, {}, {Err: io.EOF, ResumeToken: false}, }, sql: "SELECT t.key key, t.value value FROM t_mock t", want: []*sppb.PartialResultSet{ { Metadata: kvMeta, Values: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: keyStr(0)}}, {Kind: &proto3.Value_StringValue{StringValue: valStr(0)}}, }, }, }, queue: []*sppb.PartialResultSet{ { Metadata: kvMeta, Values: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: keyStr(1)}}, {Kind: &proto3.Value_StringValue{StringValue: valStr(1)}}, }, }, }, stateHistory: []resumableStreamDecoderState{ queueingRetryable, // do RPC queueingRetryable, // got foo-00 queueingRetryable, // got foo-01 finished, // got EOF }, }, { // unConnected->queueingRetryable->aborted name: "unConnected->queueingRetryable->aborted", msgs: []MockCtlMsg{ {}, {Err: nil, ResumeToken: true}, {}, {Err: errors.New("I quit"), ResumeToken: false}, }, sql: "SELECT t.key key, t.value value FROM t_mock t", want: []*sppb.PartialResultSet{ { Metadata: kvMeta, Values: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: keyStr(0)}}, {Kind: &proto3.Value_StringValue{StringValue: valStr(0)}}, }, }, { Metadata: kvMeta, Values: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: keyStr(1)}}, {Kind: &proto3.Value_StringValue{StringValue: valStr(1)}}, }, ResumeToken: EncodeResumeToken(1), }, }, stateHistory: []resumableStreamDecoderState{ queueingRetryable, // do RPC queueingRetryable, // got foo-00 queueingRetryable, // got foo-01 queueingRetryable, // foo-01, resume token queueingRetryable, // got foo-02 aborted, // got error }, wantErr: status.Errorf(codes.Unknown, "I quit"), }, { // unConnected->queueingRetryable->queueingUnretryable->queueingUnretryable name: "unConnected->queueingRetryable->queueingUnretryable->queueingUnretryable", msgs: func() (m []MockCtlMsg) { for i := 0; i < maxBuffers+1; i++ { m = append(m, MockCtlMsg{}) } return m }(), sql: "SELECT t.key key, t.value value FROM t_mock t", want: func() (s []*sppb.PartialResultSet) { for i := 0; i < maxBuffers+1; i++ { s = append(s, &sppb.PartialResultSet{ Metadata: kvMeta, Values: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: keyStr(i)}}, {Kind: &proto3.Value_StringValue{StringValue: valStr(i)}}, }, }) } return s }(), stateHistory: func() (s []resumableStreamDecoderState) { s = append(s, queueingRetryable) // RPC for i := 0; i < maxBuffers; i++ { s = append(s, queueingRetryable) // the internal queue of resumableStreamDecoder fills up } // the first item fills up the queue and triggers state transition; // the second item is received under queueingUnretryable state. s = append(s, queueingUnretryable) s = append(s, queueingUnretryable) return s }(), }, { // unConnected->queueingRetryable->queueingUnretryable->aborted name: "unConnected->queueingRetryable->queueingUnretryable->aborted", msgs: func() (m []MockCtlMsg) { for i := 0; i < maxBuffers; i++ { m = append(m, MockCtlMsg{}) } m = append(m, MockCtlMsg{Err: errors.New("Just Abort It"), ResumeToken: false}) return m }(), sql: "SELECT t.key key, t.value value FROM t_mock t", want: func() (s []*sppb.PartialResultSet) { for i := 0; i < maxBuffers; i++ { s = append(s, &sppb.PartialResultSet{ Metadata: kvMeta, Values: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: keyStr(i)}}, {Kind: &proto3.Value_StringValue{StringValue: valStr(i)}}, }, }) } return s }(), stateHistory: func() (s []resumableStreamDecoderState) { s = append(s, queueingRetryable) // RPC for i := 0; i < maxBuffers; i++ { s = append(s, queueingRetryable) // internal queue of resumableStreamDecoder fills up } s = append(s, queueingUnretryable) // the last row triggers state change s = append(s, aborted) // Error happens return s }(), wantErr: status.Errorf(codes.Unknown, "Just Abort It"), }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { ms := NewMockCloudSpanner(t, trxTs) ms.Serve() mc := sppb.NewSpannerClient(dialMock(t, ms)) if test.rpc == nil { test.rpc = func(ct context.Context, resumeToken []byte) (streamingReceiver, error) { return mc.ExecuteStreamingSql(ct, &sppb.ExecuteSqlRequest{ Sql: test.sql, ResumeToken: resumeToken, }) } } ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() r := newResumableStreamDecoder( ctx, test.rpc, ) st := []resumableStreamDecoderState{} var lastErr error // Once the expected number of state transitions are observed, // send a signal by setting stateDone = true. stateDone := false // Set stateWitness to listen to state changes. hl := len(test.stateHistory) // To avoid data race on test. r.stateWitness = func(rs resumableStreamDecoderState) { if !stateDone { // Record state transitions. st = append(st, rs) if len(st) == hl { lastErr = r.lastErr() stateDone = true } } } // Let mock server stream given messages to resumableStreamDecoder. for _, m := range test.msgs { ms.AddMsg(m.Err, m.ResumeToken) } var rs []*sppb.PartialResultSet for { select { case <-ctx.Done(): t.Fatal("context cancelled or timeout during test") default: } if stateDone { // Check if resumableStreamDecoder carried out expected // state transitions. if !testEqual(st, test.stateHistory) { t.Fatalf("observed state transitions: \n%v\n, want \n%v\n", st, test.stateHistory) } // Check if resumableStreamDecoder returns expected array of // PartialResultSets. if !testEqual(rs, test.want) { t.Fatalf("received PartialResultSets: \n%v\n, want \n%v\n", rs, test.want) } // Verify that resumableStreamDecoder's internal buffering is // also correct. var q []*sppb.PartialResultSet for { item := r.q.pop() if item == nil { break } q = append(q, item) } if !testEqual(q, test.queue) { t.Fatalf("PartialResultSets still queued: \n%v\n, want \n%v\n", q, test.queue) } // Verify resume token. if test.resumeToken != nil && !testEqual(r.resumeToken, test.resumeToken) { t.Fatalf("Resume token is %v, want %v\n", r.resumeToken, test.resumeToken) } // Verify error message. if !testEqual(lastErr, test.wantErr) { t.Fatalf("got error %v, want %v", lastErr, test.wantErr) } return } // Receive next decoded item. if r.next() { rs = append(rs, r.get()) } } }) } } // Test state transitions of resumableStreamDecoder where state machine // ends up to a blocking state(resumableStreamDecoder.Next blocks // on blocking state). func TestRsdBlockingStates(t *testing.T) { restore := setMaxBytesBetweenResumeTokens() defer restore() for _, test := range []struct { name string msgs []MockCtlMsg rpc func(ct context.Context, resumeToken []byte) (streamingReceiver, error) sql string // Expected values want []*sppb.PartialResultSet // PartialResultSets that should be returned to caller queue []*sppb.PartialResultSet // PartialResultSets that should be buffered resumeToken []byte // Resume token that is maintained by resumableStreamDecoder stateHistory []resumableStreamDecoderState // State transition history of resumableStreamDecoder wantErr error }{ { // unConnected -> unConnected name: "unConnected -> unConnected", rpc: func(ct context.Context, resumeToken []byte) (streamingReceiver, error) { return nil, status.Errorf(codes.Unavailable, "trust me: server is unavailable") }, sql: "SELECT * from t_whatever", stateHistory: []resumableStreamDecoderState{unConnected, unConnected, unConnected}, wantErr: status.Errorf(codes.Unavailable, "trust me: server is unavailable"), }, { // unConnected -> queueingRetryable name: "unConnected -> queueingRetryable", sql: "SELECT t.key key, t.value value FROM t_mock t", stateHistory: []resumableStreamDecoderState{queueingRetryable}, }, { // unConnected->queueingRetryable->queueingRetryable name: "unConnected->queueingRetryable->queueingRetryable", msgs: []MockCtlMsg{ {}, {Err: nil, ResumeToken: true}, {Err: nil, ResumeToken: true}, {}, }, sql: "SELECT t.key key, t.value value FROM t_mock t", want: []*sppb.PartialResultSet{ { Metadata: kvMeta, Values: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: keyStr(0)}}, {Kind: &proto3.Value_StringValue{StringValue: valStr(0)}}, }, }, { Metadata: kvMeta, Values: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: keyStr(1)}}, {Kind: &proto3.Value_StringValue{StringValue: valStr(1)}}, }, ResumeToken: EncodeResumeToken(1), }, { Metadata: kvMeta, Values: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: keyStr(2)}}, {Kind: &proto3.Value_StringValue{StringValue: valStr(2)}}, }, ResumeToken: EncodeResumeToken(2), }, }, queue: []*sppb.PartialResultSet{ { Metadata: kvMeta, Values: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: keyStr(3)}}, {Kind: &proto3.Value_StringValue{StringValue: valStr(3)}}, }, }, }, resumeToken: EncodeResumeToken(2), stateHistory: []resumableStreamDecoderState{ queueingRetryable, // do RPC queueingRetryable, // got foo-00 queueingRetryable, // got foo-01 queueingRetryable, // foo-01, resume token queueingRetryable, // got foo-02 queueingRetryable, // foo-02, resume token queueingRetryable, // got foo-03 }, }, { // unConnected->queueingRetryable->queueingUnretryable->queueingRetryable->queueingRetryable name: "unConnected->queueingRetryable->queueingUnretryable->queueingRetryable->queueingRetryable", msgs: func() (m []MockCtlMsg) { for i := 0; i < maxBuffers+1; i++ { m = append(m, MockCtlMsg{}) } m = append(m, MockCtlMsg{Err: nil, ResumeToken: true}) m = append(m, MockCtlMsg{}) return m }(), sql: "SELECT t.key key, t.value value FROM t_mock t", want: func() (s []*sppb.PartialResultSet) { for i := 0; i < maxBuffers+2; i++ { s = append(s, &sppb.PartialResultSet{ Metadata: kvMeta, Values: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: keyStr(i)}}, {Kind: &proto3.Value_StringValue{StringValue: valStr(i)}}, }, }) } s[maxBuffers+1].ResumeToken = EncodeResumeToken(maxBuffers + 1) return s }(), resumeToken: EncodeResumeToken(maxBuffers + 1), queue: []*sppb.PartialResultSet{ { Metadata: kvMeta, Values: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: keyStr(maxBuffers + 2)}}, {Kind: &proto3.Value_StringValue{StringValue: valStr(maxBuffers + 2)}}, }, }, }, stateHistory: func() (s []resumableStreamDecoderState) { s = append(s, queueingRetryable) // RPC for i := 0; i < maxBuffers; i++ { s = append(s, queueingRetryable) // internal queue of resumableStreamDecoder filles up } for i := maxBuffers - 1; i < maxBuffers+1; i++ { // the first item fills up the queue and triggers state // change; the second item is received under // queueingUnretryable state. s = append(s, queueingUnretryable) } s = append(s, queueingUnretryable) // got (maxBuffers+1)th row under Unretryable state s = append(s, queueingRetryable) // (maxBuffers+1)th row has resume token s = append(s, queueingRetryable) // (maxBuffers+2)th row has no resume token return s }(), }, { // unConnected->queueingRetryable->queueingUnretryable->finished name: "unConnected->queueingRetryable->queueingUnretryable->finished", msgs: func() (m []MockCtlMsg) { for i := 0; i < maxBuffers; i++ { m = append(m, MockCtlMsg{}) } m = append(m, MockCtlMsg{Err: io.EOF, ResumeToken: false}) return m }(), sql: "SELECT t.key key, t.value value FROM t_mock t", want: func() (s []*sppb.PartialResultSet) { for i := 0; i < maxBuffers; i++ { s = append(s, &sppb.PartialResultSet{ Metadata: kvMeta, Values: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: keyStr(i)}}, {Kind: &proto3.Value_StringValue{StringValue: valStr(i)}}, }, }) } return s }(), stateHistory: func() (s []resumableStreamDecoderState) { s = append(s, queueingRetryable) // RPC for i := 0; i < maxBuffers; i++ { s = append(s, queueingRetryable) // internal queue of resumableStreamDecoder fills up } s = append(s, queueingUnretryable) // last row triggers state change s = append(s, finished) // query finishes return s }(), }, } { t.Run(test.name, func(t *testing.T) { ms := NewMockCloudSpanner(t, trxTs) ms.Serve() cc := dialMock(t, ms) mc := sppb.NewSpannerClient(cc) if test.rpc == nil { // Avoid using test.sql directly in closure because for loop changes // test. sql := test.sql test.rpc = func(ct context.Context, resumeToken []byte) (streamingReceiver, error) { return mc.ExecuteStreamingSql(ct, &sppb.ExecuteSqlRequest{ Sql: sql, ResumeToken: resumeToken, }) } } ctx, cancel := context.WithCancel(context.Background()) defer cancel() r := newResumableStreamDecoder( ctx, test.rpc, ) // Override backoff to make the test run faster. r.backoff = gax.Backoff{ Initial: 1 * time.Nanosecond, Max: 1 * time.Nanosecond, Multiplier: 1.3, } // st is the set of observed state transitions. st := []resumableStreamDecoderState{} // q is the content of the decoder's partial result queue when expected // number of state transitions are done. q := []*sppb.PartialResultSet{} var lastErr error // Once the expected number of state transitions are observed, send a // signal to channel stateDone. stateDone := make(chan int) // Set stateWitness to listen to state changes. hl := len(test.stateHistory) // To avoid data race on test. r.stateWitness = func(rs resumableStreamDecoderState) { select { case <-stateDone: // Noop after expected number of state transitions default: // Record state transitions. st = append(st, rs) if len(st) == hl { lastErr = r.lastErr() q = r.q.dump() close(stateDone) } } } // Let mock server stream given messages to resumableStreamDecoder. for _, m := range test.msgs { ms.AddMsg(m.Err, m.ResumeToken) } var rs []*sppb.PartialResultSet go func() { for { if !r.next() { // Note that r.Next also exits on context cancel/timeout. return } rs = append(rs, r.get()) } }() // Verify that resumableStreamDecoder reaches expected state. select { case <-stateDone: // Note that at this point, receiver is still blockingon r.next(). // Check if resumableStreamDecoder carried out expected state // transitions. if !testEqual(st, test.stateHistory) { t.Fatalf("observed state transitions: \n%v\n, want \n%v\n", st, test.stateHistory) } // Check if resumableStreamDecoder returns expected array of // PartialResultSets. if !testEqual(rs, test.want) { t.Fatalf("received PartialResultSets: \n%v\n, want \n%v\n", rs, test.want) } // Verify that resumableStreamDecoder's internal buffering is also // correct. if !testEqual(q, test.queue) { t.Fatalf("PartialResultSets still queued: \n%v\n, want \n%v\n", q, test.queue) } // Verify resume token. if test.resumeToken != nil && !testEqual(r.resumeToken, test.resumeToken) { t.Fatalf("Resume token is %v, want %v\n", r.resumeToken, test.resumeToken) } // Verify error message. if !testEqual(lastErr, test.wantErr) { t.Fatalf("got error %v, want %v", lastErr, test.wantErr) } case <-time.After(1 * time.Second): t.Fatal("Timeout in waiting for state change") } ms.Stop() if err := cc.Close(); err != nil { t.Fatal(err) } }) } } // sReceiver signals every receiving attempt through a channel, used by // TestResumeToken to determine if the receiving of a certain PartialResultSet // will be attempted next. type sReceiver struct { c chan int rpcReceiver sppb.Spanner_ExecuteStreamingSqlClient } // Recv() implements streamingReceiver.Recv for sReceiver. func (sr *sReceiver) Recv() (*sppb.PartialResultSet, error) { sr.c <- 1 return sr.rpcReceiver.Recv() } // waitn waits for nth receiving attempt from now on, until the signal for nth // Recv() attempts is received or timeout. Note that because the way stream() // works, the signal for the nth Recv() means that the previous n - 1 // PartialResultSets has already been returned to caller or queued, if no error // happened. func (sr *sReceiver) waitn(n int) error { for i := 0; i < n; i++ { select { case <-sr.c: case <-time.After(10 * time.Second): return fmt.Errorf("timeout in waiting for %v-th Recv()", i+1) } } return nil } // Test the handling of resumableStreamDecoder.bytesBetweenResumeTokens. func TestQueueBytes(t *testing.T) { restore := setMaxBytesBetweenResumeTokens() defer restore() ms := NewMockCloudSpanner(t, trxTs) ms.Serve() defer ms.Stop() cc := dialMock(t, ms) defer cc.Close() mc := sppb.NewSpannerClient(cc) sr := &sReceiver{ c: make(chan int, 1000), // will never block in this test } wantQueueBytes := 0 ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() r := newResumableStreamDecoder( ctx, func(ct context.Context, resumeToken []byte) (streamingReceiver, error) { r, err := mc.ExecuteStreamingSql(ct, &sppb.ExecuteSqlRequest{ Sql: "SELECT t.key key, t.value value FROM t_mock t", ResumeToken: resumeToken, }) sr.rpcReceiver = r return sr, err }, ) go func() { for r.next() { } }() // Let server send maxBuffers / 2 rows. for i := 0; i < maxBuffers/2; i++ { wantQueueBytes += proto.Size(&sppb.PartialResultSet{ Metadata: kvMeta, Values: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: keyStr(i)}}, {Kind: &proto3.Value_StringValue{StringValue: valStr(i)}}, }, }) ms.AddMsg(nil, false) } if err := sr.waitn(maxBuffers/2 + 1); err != nil { t.Fatalf("failed to wait for the first %v recv() calls: %v", maxBuffers, err) } if int32(wantQueueBytes) != r.bytesBetweenResumeTokens { t.Errorf("r.bytesBetweenResumeTokens = %v, want %v", r.bytesBetweenResumeTokens, wantQueueBytes) } // Now send a resume token to drain the queue. ms.AddMsg(nil, true) // Wait for all rows to be processes. if err := sr.waitn(1); err != nil { t.Fatalf("failed to wait for rows to be processed: %v", err) } if r.bytesBetweenResumeTokens != 0 { t.Errorf("r.bytesBetweenResumeTokens = %v, want 0", r.bytesBetweenResumeTokens) } // Let server send maxBuffers - 1 rows. wantQueueBytes = 0 for i := 0; i < maxBuffers-1; i++ { wantQueueBytes += proto.Size(&sppb.PartialResultSet{ Metadata: kvMeta, Values: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: keyStr(i)}}, {Kind: &proto3.Value_StringValue{StringValue: valStr(i)}}, }, }) ms.AddMsg(nil, false) } if err := sr.waitn(maxBuffers - 1); err != nil { t.Fatalf("failed to wait for %v rows to be processed: %v", maxBuffers-1, err) } if int32(wantQueueBytes) != r.bytesBetweenResumeTokens { t.Errorf("r.bytesBetweenResumeTokens = %v, want 0", r.bytesBetweenResumeTokens) } // Trigger a state transition: queueingRetryable -> queueingUnretryable. ms.AddMsg(nil, false) if err := sr.waitn(1); err != nil { t.Fatalf("failed to wait for state transition: %v", err) } if r.bytesBetweenResumeTokens != 0 { t.Errorf("r.bytesBetweenResumeTokens = %v, want 0", r.bytesBetweenResumeTokens) } } // Verify that client can deal with resume token correctly func TestResumeToken(t *testing.T) { restore := setMaxBytesBetweenResumeTokens() defer restore() ms := NewMockCloudSpanner(t, trxTs) ms.Serve() defer ms.Stop() cc := dialMock(t, ms) defer cc.Close() mc := sppb.NewSpannerClient(cc) sr := &sReceiver{ c: make(chan int, 1000), // will never block in this test } rows := []*Row{} done := make(chan error) streaming := func() { // Establish a stream to mock cloud spanner server. iter := stream(context.Background(), func(ct context.Context, resumeToken []byte) (streamingReceiver, error) { r, err := mc.ExecuteStreamingSql(ct, &sppb.ExecuteSqlRequest{ Sql: "SELECT t.key key, t.value value FROM t_mock t", ResumeToken: resumeToken, }) sr.rpcReceiver = r return sr, err }, nil, func(error) {}) defer iter.Stop() var err error for { var row *Row row, err = iter.Next() if err == iterator.Done { err = nil break } if err != nil { break } rows = append(rows, row) } done <- err } go streaming() // Server streaming row 0 - 2, only row 1 has resume token. // Client will receive row 0 - 2, so it will try receiving for // 4 times (the last recv will block), and only row 0 - 1 will // be yielded. for i := 0; i < 3; i++ { if i == 1 { ms.AddMsg(nil, true) } else { ms.AddMsg(nil, false) } } // Wait for 4 receive attempts, as explained above. if err := sr.waitn(4); err != nil { t.Fatalf("failed to wait for row 0 - 2: %v", err) } want := []*Row{ { fields: kvMeta.RowType.Fields, vals: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: keyStr(0)}}, {Kind: &proto3.Value_StringValue{StringValue: valStr(0)}}, }, }, { fields: kvMeta.RowType.Fields, vals: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: keyStr(1)}}, {Kind: &proto3.Value_StringValue{StringValue: valStr(1)}}, }, }, } if !testEqual(rows, want) { t.Errorf("received rows: \n%v\n; but want\n%v\n", rows, want) } // Inject resumable failure. ms.AddMsg( status.Errorf(codes.Unavailable, "mock server unavailable"), false, ) // Test if client detects the resumable failure and retries. if err := sr.waitn(1); err != nil { t.Fatalf("failed to wait for client to retry: %v", err) } // Client has resumed the query, now server resend row 2. ms.AddMsg(nil, true) if err := sr.waitn(1); err != nil { t.Fatalf("failed to wait for resending row 2: %v", err) } // Now client should have received row 0 - 2. want = append(want, &Row{ fields: kvMeta.RowType.Fields, vals: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: keyStr(2)}}, {Kind: &proto3.Value_StringValue{StringValue: valStr(2)}}, }, }) if !testEqual(rows, want) { t.Errorf("received rows: \n%v\n, want\n%v\n", rows, want) } // Sending 3rd - (maxBuffers+1)th rows without resume tokens, client should buffer them. for i := 3; i < maxBuffers+2; i++ { ms.AddMsg(nil, false) } if err := sr.waitn(maxBuffers - 1); err != nil { t.Fatalf("failed to wait for row 3-%v: %v", maxBuffers+1, err) } // Received rows should be unchanged. if !testEqual(rows, want) { t.Errorf("receive rows: \n%v\n, want\n%v\n", rows, want) } // Send (maxBuffers+2)th row to trigger state change of resumableStreamDecoder: // queueingRetryable -> queueingUnretryable ms.AddMsg(nil, false) if err := sr.waitn(1); err != nil { t.Fatalf("failed to wait for row %v: %v", maxBuffers+2, err) } // Client should yield row 3rd - (maxBuffers+2)th to application. Therefore, // application should see row 0 - (maxBuffers+2)th so far. for i := 3; i < maxBuffers+3; i++ { want = append(want, &Row{ fields: kvMeta.RowType.Fields, vals: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: keyStr(i)}}, {Kind: &proto3.Value_StringValue{StringValue: valStr(i)}}, }, }) } if !testEqual(rows, want) { t.Errorf("received rows: \n%v\n; want\n%v\n", rows, want) } // Inject resumable error, but since resumableStreamDecoder is already at // queueingUnretryable state, query will just fail. ms.AddMsg( status.Errorf(codes.Unavailable, "mock server wants some sleep"), false, ) var gotErr error select { case gotErr = <-done: case <-time.After(10 * time.Second): t.Fatalf("timeout in waiting for failed query to return.") } if wantErr := toSpannerError(status.Errorf(codes.Unavailable, "mock server wants some sleep")); !testEqual(gotErr, wantErr) { t.Fatalf("stream() returns error: %v, but want error: %v", gotErr, wantErr) } // Reconnect to mock Cloud Spanner. rows = []*Row{} go streaming() // Let server send two rows without resume token. for i := maxBuffers + 3; i < maxBuffers+5; i++ { ms.AddMsg(nil, false) } if err := sr.waitn(3); err != nil { t.Fatalf("failed to wait for row %v - %v: %v", maxBuffers+3, maxBuffers+5, err) } if len(rows) > 0 { t.Errorf("client received some rows unexpectedly: %v, want nothing", rows) } // Let server end the query. ms.AddMsg(io.EOF, false) select { case gotErr = <-done: case <-time.After(10 * time.Second): t.Fatalf("timeout in waiting for failed query to return") } if gotErr != nil { t.Fatalf("stream() returns unexpected error: %v, but want no error", gotErr) } // Verify if a normal server side EOF flushes all queued rows. want = []*Row{ { fields: kvMeta.RowType.Fields, vals: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: keyStr(maxBuffers + 3)}}, {Kind: &proto3.Value_StringValue{StringValue: valStr(maxBuffers + 3)}}, }, }, { fields: kvMeta.RowType.Fields, vals: []*proto3.Value{ {Kind: &proto3.Value_StringValue{StringValue: keyStr(maxBuffers + 4)}}, {Kind: &proto3.Value_StringValue{StringValue: valStr(maxBuffers + 4)}}, }, }, } if !testEqual(rows, want) { t.Errorf("received rows: \n%v\n; but want\n%v\n", rows, want) } } // Verify that streaming query get retried upon real gRPC server transport // failures. func TestGrpcReconnect(t *testing.T) { restore := setMaxBytesBetweenResumeTokens() defer restore() ms := NewMockCloudSpanner(t, trxTs) ms.Serve() defer ms.Stop() cc := dialMock(t, ms) defer cc.Close() mc := sppb.NewSpannerClient(cc) retry := make(chan int) row := make(chan int) var err error go func() { r := 0 // Establish a stream to mock cloud spanner server. iter := stream(context.Background(), func(ct context.Context, resumeToken []byte) (streamingReceiver, error) { if r > 0 { // This RPC attempt is a retry, signal it. retry <- r } r++ return mc.ExecuteStreamingSql(ct, &sppb.ExecuteSqlRequest{ Sql: "SELECT t.key key, t.value value FROM t_mock t", ResumeToken: resumeToken, }) }, nil, func(error) {}) defer iter.Stop() for { _, err = iter.Next() if err == iterator.Done { err = nil break } if err != nil { break } row <- 0 } }() // Add a message and wait for the receipt. ms.AddMsg(nil, true) select { case <-row: case <-time.After(10 * time.Second): t.Fatalf("expect stream to be established within 10 seconds, but it didn't") } // Error injection: force server to close all connections. ms.Stop() // Test to see if client respond to the real RPC failure correctly by // retrying RPC. select { case r, ok := <-retry: if ok && r == 1 { break } t.Errorf("retry count = %v, want 1", r) case <-time.After(10 * time.Second): t.Errorf("client library failed to respond after 10 seconds, aborting") return } } // Test cancel/timeout for client operations. func TestCancelTimeout(t *testing.T) { restore := setMaxBytesBetweenResumeTokens() defer restore() ms := NewMockCloudSpanner(t, trxTs) ms.Serve() defer ms.Stop() cc := dialMock(t, ms) defer cc.Close() mc := sppb.NewSpannerClient(cc) done := make(chan int) go func() { for { ms.AddMsg(nil, true) } }() // Test cancelling query. ctx, cancel := context.WithCancel(context.Background()) var err error go func() { // Establish a stream to mock cloud spanner server. iter := stream(ctx, func(ct context.Context, resumeToken []byte) (streamingReceiver, error) { return mc.ExecuteStreamingSql(ct, &sppb.ExecuteSqlRequest{ Sql: "SELECT t.key key, t.value value FROM t_mock t", ResumeToken: resumeToken, }) }, nil, func(error) {}) defer iter.Stop() for { _, err = iter.Next() if err == iterator.Done { break } if err != nil { done <- 0 break } } }() cancel() select { case <-done: if ErrCode(err) != codes.Canceled { t.Errorf("streaming query is canceled and returns error %v, want error code %v", err, codes.Canceled) } case <-time.After(1 * time.Second): t.Errorf("query doesn't exit timely after being cancelled") } // Test query timeout. ctx, cancel = context.WithTimeout(context.Background(), 1*time.Second) defer cancel() go func() { // Establish a stream to mock cloud spanner server. iter := stream(ctx, func(ct context.Context, resumeToken []byte) (streamingReceiver, error) { return mc.ExecuteStreamingSql(ct, &sppb.ExecuteSqlRequest{ Sql: "SELECT t.key key, t.value value FROM t_mock t", ResumeToken: resumeToken, }) }, nil, func(error) {}) defer iter.Stop() for { _, err = iter.Next() if err == iterator.Done { err = nil break } if err != nil { break } } done <- 0 }() select { case <-done: if wantErr := codes.DeadlineExceeded; ErrCode(err) != wantErr { t.Errorf("streaming query timeout returns error %v, want error code %v", err, wantErr) } case <-time.After(2 * time.Second): t.Errorf("query doesn't timeout as expected") } } func TestRowIteratorDo(t *testing.T) { restore := setMaxBytesBetweenResumeTokens() defer restore() ms := NewMockCloudSpanner(t, trxTs) ms.Serve() defer ms.Stop() cc := dialMock(t, ms) defer cc.Close() mc := sppb.NewSpannerClient(cc) for i := 0; i < 3; i++ { ms.AddMsg(nil, false) } ms.AddMsg(io.EOF, true) nRows := 0 iter := stream(context.Background(), func(ct context.Context, resumeToken []byte) (streamingReceiver, error) { return mc.ExecuteStreamingSql(ct, &sppb.ExecuteSqlRequest{ Sql: "SELECT t.key key, t.value value FROM t_mock t", ResumeToken: resumeToken, }) }, nil, func(error) {}) err := iter.Do(func(r *Row) error { nRows++; return nil }) if err != nil { t.Errorf("Using Do: %v", err) } if nRows != 3 { t.Errorf("got %d rows, want 3", nRows) } } func TestRowIteratorDoWithError(t *testing.T) { restore := setMaxBytesBetweenResumeTokens() defer restore() ms := NewMockCloudSpanner(t, trxTs) ms.Serve() defer ms.Stop() cc := dialMock(t, ms) defer cc.Close() mc := sppb.NewSpannerClient(cc) for i := 0; i < 3; i++ { ms.AddMsg(nil, false) } ms.AddMsg(io.EOF, true) iter := stream(context.Background(), func(ct context.Context, resumeToken []byte) (streamingReceiver, error) { return mc.ExecuteStreamingSql(ct, &sppb.ExecuteSqlRequest{ Sql: "SELECT t.key key, t.value value FROM t_mock t", ResumeToken: resumeToken, }) }, nil, func(error) {}) injected := errors.New("Failed iterator") err := iter.Do(func(r *Row) error { return injected }) if err != injected { t.Errorf("got <%v>, want <%v>", err, injected) } } func TestIteratorStopEarly(t *testing.T) { ctx := context.Background() restore := setMaxBytesBetweenResumeTokens() defer restore() ms := NewMockCloudSpanner(t, trxTs) ms.Serve() defer ms.Stop() cc := dialMock(t, ms) defer cc.Close() mc := sppb.NewSpannerClient(cc) ms.AddMsg(nil, false) ms.AddMsg(nil, false) ms.AddMsg(io.EOF, true) iter := stream(ctx, func(ct context.Context, resumeToken []byte) (streamingReceiver, error) { return mc.ExecuteStreamingSql(ct, &sppb.ExecuteSqlRequest{ Sql: "SELECT t.key key, t.value value FROM t_mock t", ResumeToken: resumeToken, }) }, nil, func(error) {}) _, err := iter.Next() if err != nil { t.Fatalf("before Stop: %v", err) } iter.Stop() // Stop sets r.err to the FailedPrecondition error "Next called after Stop". _, err = iter.Next() if g, w := ErrCode(err), codes.FailedPrecondition; g != w { t.Errorf("after Stop: got: %v, want: %v", g, w) } } func TestIteratorWithError(t *testing.T) { injected := errors.New("Failed iterator") iter := RowIterator{err: injected} defer iter.Stop() if _, err := iter.Next(); err != injected { t.Fatalf("Expected error: %v, got %v", injected, err) } } func dialMock(t *testing.T, ms *MockCloudSpanner) *grpc.ClientConn { cc, err := grpc.Dial(ms.Addr(), grpc.WithInsecure(), grpc.WithBlock()) if err != nil { t.Fatalf("Dial(%q) = %v", ms.Addr(), err) } return cc } google-cloud-go-0.49.0/spanner/retry.go000066400000000000000000000065101356504100700177340ustar00rootroot00000000000000/* Copyright 2017 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spanner import ( "context" "time" "cloud.google.com/go/internal/trace" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" "github.com/googleapis/gax-go/v2" edpb "google.golang.org/genproto/googleapis/rpc/errdetails" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) const ( retryInfoKey = "google.rpc.retryinfo-bin" ) // DefaultRetryBackoff is used for retryers as a fallback value when the server // did not return any retry information. var DefaultRetryBackoff = gax.Backoff{ Initial: 20 * time.Millisecond, Max: 32 * time.Second, Multiplier: 1.3, } // spannerRetryer extends the generic gax Retryer, but also checks for any // retry info returned by Cloud Spanner and uses that if present. type spannerRetryer struct { gax.Retryer } // onCodes returns a spannerRetryer that will retry on the specified error // codes. func onCodes(bo gax.Backoff, cc ...codes.Code) gax.Retryer { return &spannerRetryer{ Retryer: gax.OnCodes(cc, bo), } } // Retry returns the retry delay returned by Cloud Spanner if that is present. // Otherwise it returns the retry delay calculated by the generic gax Retryer. func (r *spannerRetryer) Retry(err error) (time.Duration, bool) { delay, shouldRetry := r.Retryer.Retry(err) if !shouldRetry { return 0, false } if serverDelay, hasServerDelay := extractRetryDelay(err); hasServerDelay { delay = serverDelay } return delay, true } // runWithRetryOnAborted executes the given function and retries it if it // returns an Aborted error. The delay between retries is the delay returned // by Cloud Spanner, and if none is returned, the calculated delay with a // minimum of 10ms and maximum of 32s. func runWithRetryOnAborted(ctx context.Context, f func(context.Context) error) error { retryer := onCodes(DefaultRetryBackoff, codes.Aborted) funcWithRetry := func(ctx context.Context) error { for { err := f(ctx) if err == nil { return nil } delay, shouldRetry := retryer.Retry(err) if !shouldRetry { return err } trace.TracePrintf(ctx, nil, "Backing off after ABORTED for %s, then retrying", delay) if err := gax.Sleep(ctx, delay); err != nil { return err } } } return funcWithRetry(ctx) } // extractRetryDelay extracts retry backoff if present. func extractRetryDelay(err error) (time.Duration, bool) { trailers := errTrailers(err) if trailers == nil { return 0, false } elem, ok := trailers[retryInfoKey] if !ok || len(elem) <= 0 { return 0, false } _, b, err := metadata.DecodeKeyValue(retryInfoKey, elem[0]) if err != nil { return 0, false } var retryInfo edpb.RetryInfo if proto.Unmarshal([]byte(b), &retryInfo) != nil { return 0, false } delay, err := ptypes.Duration(retryInfo.RetryDelay) if err != nil { return 0, false } return delay, true } google-cloud-go-0.49.0/spanner/retry_test.go000066400000000000000000000037051356504100700207760ustar00rootroot00000000000000/* Copyright 2017 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spanner import ( "testing" "time" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" "github.com/googleapis/gax-go/v2" edpb "google.golang.org/genproto/googleapis/rpc/errdetails" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" ) func TestRetryInfo(t *testing.T) { b, _ := proto.Marshal(&edpb.RetryInfo{ RetryDelay: ptypes.DurationProto(time.Second), }) trailers := map[string]string{ retryInfoKey: string(b), } gotDelay, ok := extractRetryDelay(toSpannerErrorWithMetadata(status.Errorf(codes.Aborted, ""), metadata.New(trailers))) if !ok || !testEqual(time.Second, gotDelay) { t.Errorf(" = <%t, %v>, want ", ok, gotDelay, time.Second) } } func TestRetryerRespectsServerDelay(t *testing.T) { t.Parallel() serverDelay := 50 * time.Millisecond b, _ := proto.Marshal(&edpb.RetryInfo{ RetryDelay: ptypes.DurationProto(serverDelay), }) trailers := map[string]string{ retryInfoKey: string(b), } retryer := onCodes(gax.Backoff{}, codes.Aborted) err := toSpannerErrorWithMetadata(spannerErrorf(codes.Aborted, "transaction was aborted"), metadata.New(trailers)) maxSeenDelay, shouldRetry := retryer.Retry(err) if !shouldRetry { t.Fatalf("expected shouldRetry to be true") } if maxSeenDelay != serverDelay { t.Fatalf("Retry delay mismatch:\ngot: %v\nwant: %v", maxSeenDelay, serverDelay) } } google-cloud-go-0.49.0/spanner/row.go000066400000000000000000000244201356504100700173760ustar00rootroot00000000000000/* Copyright 2017 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spanner import ( "fmt" "reflect" proto3 "github.com/golang/protobuf/ptypes/struct" sppb "google.golang.org/genproto/googleapis/spanner/v1" "google.golang.org/grpc/codes" ) // A Row is a view of a row of data returned by a Cloud Spanner read. // It consists of a number of columns; the number depends on the columns // used to construct the read. // // The column values can be accessed by index. For instance, if the read specified // []string{"photo_id", "caption"}, then each row will contain two // columns: "photo_id" with index 0, and "caption" with index 1. // // Column values are decoded by using one of the Column, ColumnByName, or // Columns methods. The valid values passed to these methods depend on the // column type. For example: // // var photoID int64 // err := row.Column(0, &photoID) // Decode column 0 as an integer. // // var caption string // err := row.Column(1, &caption) // Decode column 1 as a string. // // // Decode all the columns. // err := row.Columns(&photoID, &caption) // // Supported types and their corresponding Cloud Spanner column type(s) are: // // *string(not NULL), *NullString - STRING // *[]string, *[]NullString - STRING ARRAY // *[]byte - BYTES // *[][]byte - BYTES ARRAY // *int64(not NULL), *NullInt64 - INT64 // *[]int64, *[]NullInt64 - INT64 ARRAY // *bool(not NULL), *NullBool - BOOL // *[]bool, *[]NullBool - BOOL ARRAY // *float64(not NULL), *NullFloat64 - FLOAT64 // *[]float64, *[]NullFloat64 - FLOAT64 ARRAY // *time.Time(not NULL), *NullTime - TIMESTAMP // *[]time.Time, *[]NullTime - TIMESTAMP ARRAY // *Date(not NULL), *NullDate - DATE // *[]civil.Date, *[]NullDate - DATE ARRAY // *[]*some_go_struct, *[]NullRow - STRUCT ARRAY // *GenericColumnValue - any Cloud Spanner type // // For TIMESTAMP columns, the returned time.Time object will be in UTC. // // To fetch an array of BYTES, pass a *[][]byte. To fetch an array of (sub)rows, pass // a *[]spanner.NullRow or a *[]*some_go_struct where some_go_struct holds all // information of the subrow, see spanner.Row.ToStruct for the mapping between a // Cloud Spanner row and a Go struct. To fetch an array of other types, pass a // *[]spanner.NullXXX type of the appropriate type. Use GenericColumnValue when you // don't know in advance what column type to expect. // // Row decodes the row contents lazily; as a result, each call to a getter has // a chance of returning an error. // // A column value may be NULL if the corresponding value is not present in // Cloud Spanner. The spanner.NullXXX types (spanner.NullInt64 et al.) allow fetching // values that may be null. A NULL BYTES can be fetched into a *[]byte as nil. // It is an error to fetch a NULL value into any other type. type Row struct { fields []*sppb.StructType_Field vals []*proto3.Value // keep decoded for now } // errNamesValuesMismatch returns error for when columnNames count is not equal // to columnValues count. func errNamesValuesMismatch(columnNames []string, columnValues []interface{}) error { return spannerErrorf(codes.FailedPrecondition, "different number of names(%v) and values(%v)", len(columnNames), len(columnValues)) } // NewRow returns a Row containing the supplied data. This can be useful for // mocking Cloud Spanner Read and Query responses for unit testing. func NewRow(columnNames []string, columnValues []interface{}) (*Row, error) { if len(columnValues) != len(columnNames) { return nil, errNamesValuesMismatch(columnNames, columnValues) } r := Row{ fields: make([]*sppb.StructType_Field, len(columnValues)), vals: make([]*proto3.Value, len(columnValues)), } for i := range columnValues { val, typ, err := encodeValue(columnValues[i]) if err != nil { return nil, err } r.fields[i] = &sppb.StructType_Field{ Name: columnNames[i], Type: typ, } r.vals[i] = val } return &r, nil } // Size is the number of columns in the row. func (r *Row) Size() int { return len(r.fields) } // ColumnName returns the name of column i, or empty string for invalid column. func (r *Row) ColumnName(i int) string { if i < 0 || i >= len(r.fields) { return "" } return r.fields[i].Name } // ColumnIndex returns the index of the column with the given name. The // comparison is case-sensitive. func (r *Row) ColumnIndex(name string) (int, error) { found := false var index int if len(r.vals) != len(r.fields) { return 0, errFieldsMismatchVals(r) } for i, f := range r.fields { if f == nil { return 0, errNilColType(i) } if name == f.Name { if found { return 0, errDupColName(name) } found = true index = i } } if !found { return 0, errColNotFound(name) } return index, nil } // ColumnNames returns all column names of the row. func (r *Row) ColumnNames() []string { var n []string for _, c := range r.fields { n = append(n, c.Name) } return n } // errColIdxOutOfRange returns error for requested column index is out of the // range of the target Row's columns. func errColIdxOutOfRange(i int, r *Row) error { return spannerErrorf(codes.OutOfRange, "column index %d out of range [0,%d)", i, len(r.vals)) } // errDecodeColumn returns error for not being able to decode a indexed column. func errDecodeColumn(i int, err error) error { if err == nil { return nil } se, ok := toSpannerError(err).(*Error) if !ok { return spannerErrorf(codes.InvalidArgument, "failed to decode column %v, error = <%v>", i, err) } se.decorate(fmt.Sprintf("failed to decode column %v", i)) return se } // errFieldsMismatchVals returns error for field count isn't equal to value count in a Row. func errFieldsMismatchVals(r *Row) error { return spannerErrorf(codes.FailedPrecondition, "row has different number of fields(%v) and values(%v)", len(r.fields), len(r.vals)) } // errNilColType returns error for column type for column i being nil in the row. func errNilColType(i int) error { return spannerErrorf(codes.FailedPrecondition, "column(%v)'s type is nil", i) } // Column fetches the value from the ith column, decoding it into ptr. // See the Row documentation for the list of acceptable argument types. // see Client.ReadWriteTransaction for an example. func (r *Row) Column(i int, ptr interface{}) error { if len(r.vals) != len(r.fields) { return errFieldsMismatchVals(r) } if i < 0 || i >= len(r.fields) { return errColIdxOutOfRange(i, r) } if r.fields[i] == nil { return errNilColType(i) } if err := decodeValue(r.vals[i], r.fields[i].Type, ptr); err != nil { return errDecodeColumn(i, err) } return nil } // errDupColName returns error for duplicated column name in the same row. func errDupColName(n string) error { return spannerErrorf(codes.FailedPrecondition, "ambiguous column name %q", n) } // errColNotFound returns error for not being able to find a named column. func errColNotFound(n string) error { return spannerErrorf(codes.NotFound, "column %q not found", n) } // ColumnByName fetches the value from the named column, decoding it into ptr. // See the Row documentation for the list of acceptable argument types. func (r *Row) ColumnByName(name string, ptr interface{}) error { index, err := r.ColumnIndex(name) if err != nil { return err } return r.Column(index, ptr) } // errNumOfColValue returns error for providing wrong number of values to Columns. func errNumOfColValue(n int, r *Row) error { return spannerErrorf(codes.InvalidArgument, "Columns(): number of arguments (%d) does not match row size (%d)", n, len(r.vals)) } // Columns fetches all the columns in the row at once. // // The value of the kth column will be decoded into the kth argument to Columns. See // Row for the list of acceptable argument types. The number of arguments must be // equal to the number of columns. Pass nil to specify that a column should be // ignored. func (r *Row) Columns(ptrs ...interface{}) error { if len(ptrs) != len(r.vals) { return errNumOfColValue(len(ptrs), r) } if len(r.vals) != len(r.fields) { return errFieldsMismatchVals(r) } for i, p := range ptrs { if p == nil { continue } if err := r.Column(i, p); err != nil { return err } } return nil } // errToStructArgType returns error for p not having the correct data type(pointer to Go struct) to // be the argument of Row.ToStruct. func errToStructArgType(p interface{}) error { return spannerErrorf(codes.InvalidArgument, "ToStruct(): type %T is not a valid pointer to Go struct", p) } // ToStruct fetches the columns in a row into the fields of a struct. // The rules for mapping a row's columns into a struct's exported fields // are: // // 1. If a field has a `spanner: "column_name"` tag, then decode column // 'column_name' into the field. A special case is the `spanner: "-"` // tag, which instructs ToStruct to ignore the field during decoding. // // 2. Otherwise, if the name of a field matches the name of a column (ignoring case), // decode the column into the field. // // The fields of the destination struct can be of any type that is acceptable // to spanner.Row.Column. // // Slice and pointer fields will be set to nil if the source column is NULL, and a // non-nil value if the column is not NULL. To decode NULL values of other types, use // one of the spanner.NullXXX types as the type of the destination field. // // If ToStruct returns an error, the contents of p are undefined. Some fields may // have been successfully populated, while others were not; you should not use any of // the fields. func (r *Row) ToStruct(p interface{}) error { // Check if p is a pointer to a struct if t := reflect.TypeOf(p); t == nil || t.Kind() != reflect.Ptr || t.Elem().Kind() != reflect.Struct { return errToStructArgType(p) } if len(r.vals) != len(r.fields) { return errFieldsMismatchVals(r) } // Call decodeStruct directly to decode the row as a typed proto.ListValue. return decodeStruct( &sppb.StructType{Fields: r.fields}, &proto3.ListValue{Values: r.vals}, p, ) } google-cloud-go-0.49.0/spanner/row_test.go000066400000000000000000001302341356504100700204360ustar00rootroot00000000000000/* Copyright 2017 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spanner import ( "encoding/base64" "reflect" "strconv" "strings" "testing" "time" "cloud.google.com/go/civil" proto "github.com/golang/protobuf/proto" proto3 "github.com/golang/protobuf/ptypes/struct" sppb "google.golang.org/genproto/googleapis/spanner/v1" ) var ( tm = time.Date(2016, 11, 15, 0, 0, 0, 0, time.UTC) dt, _ = civil.ParseDate("2016-11-15") // row contains a column for each unique Cloud Spanner type. row = Row{ []*sppb.StructType_Field{ // STRING / STRING ARRAY {Name: "STRING", Type: stringType()}, {Name: "NULL_STRING", Type: stringType()}, {Name: "STRING_ARRAY", Type: listType(stringType())}, {Name: "NULL_STRING_ARRAY", Type: listType(stringType())}, // BYTES / BYTES ARRAY {Name: "BYTES", Type: bytesType()}, {Name: "NULL_BYTES", Type: bytesType()}, {Name: "BYTES_ARRAY", Type: listType(bytesType())}, {Name: "NULL_BYTES_ARRAY", Type: listType(bytesType())}, // INT64 / INT64 ARRAY {Name: "INT64", Type: intType()}, {Name: "NULL_INT64", Type: intType()}, {Name: "INT64_ARRAY", Type: listType(intType())}, {Name: "NULL_INT64_ARRAY", Type: listType(intType())}, // BOOL / BOOL ARRAY {Name: "BOOL", Type: boolType()}, {Name: "NULL_BOOL", Type: boolType()}, {Name: "BOOL_ARRAY", Type: listType(boolType())}, {Name: "NULL_BOOL_ARRAY", Type: listType(boolType())}, // FLOAT64 / FLOAT64 ARRAY {Name: "FLOAT64", Type: floatType()}, {Name: "NULL_FLOAT64", Type: floatType()}, {Name: "FLOAT64_ARRAY", Type: listType(floatType())}, {Name: "NULL_FLOAT64_ARRAY", Type: listType(floatType())}, // TIMESTAMP / TIMESTAMP ARRAY {Name: "TIMESTAMP", Type: timeType()}, {Name: "NULL_TIMESTAMP", Type: timeType()}, {Name: "TIMESTAMP_ARRAY", Type: listType(timeType())}, {Name: "NULL_TIMESTAMP_ARRAY", Type: listType(timeType())}, // DATE / DATE ARRAY {Name: "DATE", Type: dateType()}, {Name: "NULL_DATE", Type: dateType()}, {Name: "DATE_ARRAY", Type: listType(dateType())}, {Name: "NULL_DATE_ARRAY", Type: listType(dateType())}, // STRUCT ARRAY { Name: "STRUCT_ARRAY", Type: listType( structType( mkField("Col1", intType()), mkField("Col2", floatType()), mkField("Col3", stringType()), ), ), }, { Name: "NULL_STRUCT_ARRAY", Type: listType( structType( mkField("Col1", intType()), mkField("Col2", floatType()), mkField("Col3", stringType()), ), ), }, }, []*proto3.Value{ // STRING / STRING ARRAY stringProto("value"), nullProto(), listProto(stringProto("value1"), nullProto(), stringProto("value3")), nullProto(), // BYTES / BYTES ARRAY bytesProto([]byte("value")), nullProto(), listProto(bytesProto([]byte("value1")), nullProto(), bytesProto([]byte("value3"))), nullProto(), // INT64 / INT64 ARRAY intProto(17), nullProto(), listProto(intProto(1), intProto(2), nullProto()), nullProto(), // BOOL / BOOL ARRAY boolProto(true), nullProto(), listProto(nullProto(), boolProto(true), boolProto(false)), nullProto(), // FLOAT64 / FLOAT64 ARRAY floatProto(1.7), nullProto(), listProto(nullProto(), nullProto(), floatProto(1.7)), nullProto(), // TIMESTAMP / TIMESTAMP ARRAY timeProto(tm), nullProto(), listProto(nullProto(), timeProto(tm)), nullProto(), // DATE / DATE ARRAY dateProto(dt), nullProto(), listProto(nullProto(), dateProto(dt)), nullProto(), // STRUCT ARRAY listProto( nullProto(), listProto(intProto(3), floatProto(33.3), stringProto("three")), nullProto(), ), nullProto(), }, } ) // Test helpers for getting column values. func TestColumnValues(t *testing.T) { vals := []interface{}{} wantVals := []interface{}{} // Test getting column values. for i, wants := range [][]interface{}{ // STRING / STRING ARRAY {"value", NullString{"value", true}}, {NullString{}}, {[]NullString{{"value1", true}, {}, {"value3", true}}}, {[]NullString(nil)}, // BYTES / BYTES ARRAY {[]byte("value")}, {[]byte(nil)}, {[][]byte{[]byte("value1"), nil, []byte("value3")}}, {[][]byte(nil)}, // INT64 / INT64 ARRAY {int64(17), NullInt64{17, true}}, {NullInt64{}}, {[]NullInt64{{1, true}, {2, true}, {}}}, {[]NullInt64(nil)}, // BOOL / BOOL ARRAY {true, NullBool{true, true}}, {NullBool{}}, {[]NullBool{{}, {true, true}, {false, true}}}, {[]NullBool(nil)}, // FLOAT64 / FLOAT64 ARRAY {1.7, NullFloat64{1.7, true}}, {NullFloat64{}}, {[]NullFloat64{{}, {}, {1.7, true}}}, {[]NullFloat64(nil)}, // TIMESTAMP / TIMESTAMP ARRAY {tm, NullTime{tm, true}}, {NullTime{}}, {[]NullTime{{}, {tm, true}}}, {[]NullTime(nil)}, // DATE / DATE ARRAY {dt, NullDate{dt, true}}, {NullDate{}}, {[]NullDate{{}, {dt, true}}}, {[]NullDate(nil)}, // STRUCT ARRAY { []*struct { Col1 NullInt64 Col2 NullFloat64 Col3 string }{ nil, { NullInt64{3, true}, NullFloat64{33.3, true}, "three", }, nil, }, []NullRow{ {}, { Row: Row{ fields: []*sppb.StructType_Field{ mkField("Col1", intType()), mkField("Col2", floatType()), mkField("Col3", stringType()), }, vals: []*proto3.Value{ intProto(3), floatProto(33.3), stringProto("three"), }, }, Valid: true, }, {}, }, }, { []*struct { Col1 NullInt64 Col2 NullFloat64 Col3 string }(nil), []NullRow(nil), }, } { for j, want := range wants { // Prepare Value vector to test Row.Columns. if j == 0 { vals = append(vals, reflect.New(reflect.TypeOf(want)).Interface()) wantVals = append(wantVals, want) } // Column gotp := reflect.New(reflect.TypeOf(want)) err := row.Column(i, gotp.Interface()) if err != nil { t.Errorf("\t row.Column(%v, %T) returns error: %v, want nil", i, gotp.Interface(), err) } if got := reflect.Indirect(gotp).Interface(); !testEqual(got, want) { t.Errorf("\t row.Column(%v, %T) retrives %v, want %v", i, gotp.Interface(), got, want) } // ColumnByName gotp = reflect.New(reflect.TypeOf(want)) err = row.ColumnByName(row.fields[i].Name, gotp.Interface()) if err != nil { t.Errorf("\t row.ColumnByName(%v, %T) returns error: %v, want nil", row.fields[i].Name, gotp.Interface(), err) } if got := reflect.Indirect(gotp).Interface(); !testEqual(got, want) { t.Errorf("\t row.ColumnByName(%v, %T) retrives %v, want %v", row.fields[i].Name, gotp.Interface(), got, want) } } } // Test Row.Columns. if err := row.Columns(vals...); err != nil { t.Errorf("row.Columns() returns error: %v, want nil", err) } for i, want := range wantVals { if got := reflect.Indirect(reflect.ValueOf(vals[i])).Interface(); !testEqual(got, want) { t.Errorf("\t got %v(%T) for column[%v], want %v(%T)", got, got, row.fields[i].Name, want, want) } } } // Test decoding into nil destination. func TestNilDst(t *testing.T) { for i, test := range []struct { r *Row dst interface{} wantErr error structDst interface{} wantToStructErr error }{ { &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: stringType()}, }, []*proto3.Value{stringProto("value")}, }, nil, errDecodeColumn(0, errNilDst(nil)), nil, errToStructArgType(nil), }, { &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: stringType()}, }, []*proto3.Value{stringProto("value")}, }, (*string)(nil), errDecodeColumn(0, errNilDst((*string)(nil))), (*struct{ STRING string })(nil), errNilDst((*struct{ STRING string })(nil)), }, { &Row{ []*sppb.StructType_Field{ { Name: "Col0", Type: listType( structType( mkField("Col1", intType()), mkField("Col2", floatType()), ), ), }, }, []*proto3.Value{listProto( listProto(intProto(3), floatProto(33.3)), )}, }, (*[]*struct { Col1 int Col2 float64 })(nil), errDecodeColumn(0, errNilDst((*[]*struct { Col1 int Col2 float64 })(nil))), (*struct { StructArray []*struct { Col1 int Col2 float64 } `spanner:"STRUCT_ARRAY"` })(nil), errNilDst((*struct { StructArray []*struct { Col1 int Col2 float64 } `spanner:"STRUCT_ARRAY"` })(nil)), }, } { if gotErr := test.r.Column(0, test.dst); !testEqual(gotErr, test.wantErr) { t.Errorf("%v: test.r.Column() returns error %v, want %v", i, gotErr, test.wantErr) } if gotErr := test.r.ColumnByName("Col0", test.dst); !testEqual(gotErr, test.wantErr) { t.Errorf("%v: test.r.ColumnByName() returns error %v, want %v", i, gotErr, test.wantErr) } // Row.Columns(T) should return nil on T == nil, otherwise, it should return test.wantErr. wantColumnsErr := test.wantErr if test.dst == nil { wantColumnsErr = nil } if gotErr := test.r.Columns(test.dst); !testEqual(gotErr, wantColumnsErr) { t.Errorf("%v: test.r.Columns() returns error %v, want %v", i, gotErr, wantColumnsErr) } if gotErr := test.r.ToStruct(test.structDst); !testEqual(gotErr, test.wantToStructErr) { t.Errorf("%v: test.r.ToStruct() returns error %v, want %v", i, gotErr, test.wantToStructErr) } } } // Test decoding NULL columns using Go types that don't support NULL. func TestNullTypeErr(t *testing.T) { var tm time.Time ntoi := func(n string) int { for i, f := range row.fields { if f.Name == n { return i } } t.Errorf("cannot find column name %q in row", n) return 0 } for _, test := range []struct { colName string dst interface{} }{ { "NULL_STRING", proto.String(""), }, { "NULL_INT64", proto.Int64(0), }, { "NULL_BOOL", proto.Bool(false), }, { "NULL_FLOAT64", proto.Float64(0.0), }, { "NULL_TIMESTAMP", &tm, }, { "NULL_DATE", &dt, }, } { wantErr := errDecodeColumn(ntoi(test.colName), errDstNotForNull(test.dst)) if gotErr := row.ColumnByName(test.colName, test.dst); !testEqual(gotErr, wantErr) { t.Errorf("row.ColumnByName(%v) returns error %v, want %v", test.colName, gotErr, wantErr) } } } // Test using wrong destination type in column decoders. func TestColumnTypeErr(t *testing.T) { // badDst cannot hold any of the column values. badDst := &struct{}{} for i, f := range row.fields { // For each of the columns, try to decode it into badDst. tc := f.Type.Code var etc sppb.TypeCode if strings.Contains(f.Name, "ARRAY") { etc = f.Type.ArrayElementType.Code } wantErr := errDecodeColumn(i, errTypeMismatch(tc, etc, badDst)) if gotErr := row.Column(i, badDst); !testEqual(gotErr, wantErr) { t.Errorf("Column(%v): decoding into destination with wrong type %T returns error %v, want %v", i, badDst, gotErr, wantErr) } if gotErr := row.ColumnByName(f.Name, badDst); !testEqual(gotErr, wantErr) { t.Errorf("ColumnByName(%v): decoding into destination with wrong type %T returns error %v, want %v", f.Name, badDst, gotErr, wantErr) } } wantErr := errDecodeColumn(1, errTypeMismatch(sppb.TypeCode_STRING, sppb.TypeCode_TYPE_CODE_UNSPECIFIED, badDst)) // badDst is used to receive column 1. vals := []interface{}{nil, badDst} // Row.Column() is expected to fail at column 1. // Skip decoding the rest columns by providing nils as the destinations. for i := 2; i < len(row.fields); i++ { vals = append(vals, nil) } if gotErr := row.Columns(vals...); !testEqual(gotErr, wantErr) { t.Errorf("Columns(): decoding column 1 with wrong type %T returns error %v, want %v", badDst, gotErr, wantErr) } } // Test the handling of invalid column decoding requests which cannot be mapped to correct column(s). func TestInvalidColumnRequest(t *testing.T) { for _, test := range []struct { desc string f func() error wantErr error }{ { "Request column index is out of range", func() error { return row.Column(10000, &struct{}{}) }, errColIdxOutOfRange(10000, &row), }, { "Cannot find the named column", func() error { return row.ColumnByName("string", &struct{}{}) }, errColNotFound("string"), }, { "Not enough arguments to call row.Columns()", func() error { return row.Columns(nil, nil) }, errNumOfColValue(2, &row), }, { "Call ColumnByName on row with duplicated column names", func() error { var s string r := &Row{ []*sppb.StructType_Field{ {Name: "Val", Type: stringType()}, {Name: "Val", Type: stringType()}, }, []*proto3.Value{stringProto("value1"), stringProto("value2")}, } return r.ColumnByName("Val", &s) }, errDupColName("Val"), }, { "Call ToStruct on row with duplicated column names", func() error { s := &struct { Val string }{} r := &Row{ []*sppb.StructType_Field{ {Name: "Val", Type: stringType()}, {Name: "Val", Type: stringType()}, }, []*proto3.Value{stringProto("value1"), stringProto("value2")}, } return r.ToStruct(s) }, errDupSpannerField("Val", &sppb.StructType{ Fields: []*sppb.StructType_Field{ {Name: "Val", Type: stringType()}, {Name: "Val", Type: stringType()}, }, }), }, { "Call ToStruct on a row with unnamed field", func() error { s := &struct { Val string }{} r := &Row{ []*sppb.StructType_Field{ {Name: "", Type: stringType()}, }, []*proto3.Value{stringProto("value1")}, } return r.ToStruct(s) }, errUnnamedField(&sppb.StructType{Fields: []*sppb.StructType_Field{ {Name: "", Type: stringType()}, }}, 0), }, } { if gotErr := test.f(); !testEqual(gotErr, test.wantErr) { t.Errorf("%v: test.f() returns error %v, want %v", test.desc, gotErr, test.wantErr) } } } // Test decoding the row with row.ToStruct into an invalid destination. func TestToStructInvalidDst(t *testing.T) { for _, test := range []struct { desc string dst interface{} wantErr error }{ { "Decode row as STRUCT into int32", proto.Int(1), errToStructArgType(proto.Int(1)), }, { "Decode row as STRUCT to nil Go struct", (*struct{})(nil), errNilDst((*struct{})(nil)), }, { "Decode row as STRUCT to Go struct with duplicated fields for the PK column", &struct { PK1 string `spanner:"STRING"` PK2 string `spanner:"STRING"` }{}, errNoOrDupGoField(&struct { PK1 string `spanner:"STRING"` PK2 string `spanner:"STRING"` }{}, "STRING"), }, { "Decode row as STRUCT to Go struct with no field for the PK column", &struct { PK1 string `spanner:"_STRING"` }{}, errNoOrDupGoField(&struct { PK1 string `spanner:"_STRING"` }{}, "STRING"), }, { "Decode row as STRUCT to Go struct with wrong type for the PK column", &struct { PK1 int64 `spanner:"STRING"` }{}, errDecodeStructField(&sppb.StructType{Fields: row.fields}, "STRING", errTypeMismatch(sppb.TypeCode_STRING, sppb.TypeCode_TYPE_CODE_UNSPECIFIED, proto.Int64(0))), }, } { if gotErr := row.ToStruct(test.dst); !testEqual(gotErr, test.wantErr) { t.Errorf("%v: decoding:\ngot %v\nwant %v", test.desc, gotErr, test.wantErr) } } } // Test decoding a broken row. func TestBrokenRow(t *testing.T) { for i, test := range []struct { row *Row dst interface{} wantErr error }{ { // A row with no field. &Row{ []*sppb.StructType_Field{}, []*proto3.Value{stringProto("value")}, }, &NullString{"value", true}, errFieldsMismatchVals(&Row{ []*sppb.StructType_Field{}, []*proto3.Value{stringProto("value")}, }), }, { // A row with nil field. &Row{ []*sppb.StructType_Field{nil}, []*proto3.Value{stringProto("value")}, }, &NullString{"value", true}, errNilColType(0), }, { // Field is not nil, but its type is nil. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: nil}, }, []*proto3.Value{listProto(stringProto("value1"), stringProto("value2"))}, }, &[]NullString{}, errDecodeColumn(0, errNilSpannerType()), }, { // Field is not nil, field type is not nil, but it is an array and its array element type is nil. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: &sppb.Type{Code: sppb.TypeCode_ARRAY}}, }, []*proto3.Value{listProto(stringProto("value1"), stringProto("value2"))}, }, &[]NullString{}, errDecodeColumn(0, errNilArrElemType(&sppb.Type{Code: sppb.TypeCode_ARRAY})), }, { // Field specifies valid type, value is nil. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: intType()}, }, []*proto3.Value{nil}, }, &NullInt64{1, true}, errDecodeColumn(0, errNilSrc()), }, { // Field specifies INT64 type, value is having a nil Kind. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: intType()}, }, []*proto3.Value{{Kind: (*proto3.Value_StringValue)(nil)}}, }, &NullInt64{1, true}, errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_StringValue)(nil)}, "String")), }, { // Field specifies INT64 type, but value is for Number type. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: intType()}, }, []*proto3.Value{floatProto(1.0)}, }, &NullInt64{1, true}, errDecodeColumn(0, errSrcVal(floatProto(1.0), "String")), }, { // Field specifies INT64 type, but value is wrongly encoded. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: intType()}, }, []*proto3.Value{stringProto("&1")}, }, proto.Int64(0), errDecodeColumn(0, errBadEncoding(stringProto("&1"), func() error { _, err := strconv.ParseInt("&1", 10, 64) return err }())), }, { // Field specifies INT64 type, but value is wrongly encoded. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: intType()}, }, []*proto3.Value{stringProto("&1")}, }, &NullInt64{}, errDecodeColumn(0, errBadEncoding(stringProto("&1"), func() error { _, err := strconv.ParseInt("&1", 10, 64) return err }())), }, { // Field specifies STRING type, but value is having a nil Kind. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: stringType()}, }, []*proto3.Value{{Kind: (*proto3.Value_StringValue)(nil)}}, }, &NullString{"value", true}, errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_StringValue)(nil)}, "String")), }, { // Field specifies STRING type, but value is for ARRAY type. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: stringType()}, }, []*proto3.Value{listProto(stringProto("value"))}, }, &NullString{"value", true}, errDecodeColumn(0, errSrcVal(listProto(stringProto("value")), "String")), }, { // Field specifies FLOAT64 type, value is having a nil Kind. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: floatType()}, }, []*proto3.Value{{Kind: (*proto3.Value_NumberValue)(nil)}}, }, &NullFloat64{1.0, true}, errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_NumberValue)(nil)}, "Number")), }, { // Field specifies FLOAT64 type, but value is for BOOL type. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: floatType()}, }, []*proto3.Value{boolProto(true)}, }, &NullFloat64{1.0, true}, errDecodeColumn(0, errSrcVal(boolProto(true), "Number")), }, { // Field specifies FLOAT64 type, but value is wrongly encoded. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: floatType()}, }, []*proto3.Value{stringProto("nan")}, }, &NullFloat64{}, errDecodeColumn(0, errUnexpectedNumStr("nan")), }, { // Field specifies FLOAT64 type, but value is wrongly encoded. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: floatType()}, }, []*proto3.Value{stringProto("nan")}, }, proto.Float64(0), errDecodeColumn(0, errUnexpectedNumStr("nan")), }, { // Field specifies BYTES type, value is having a nil Kind. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: bytesType()}, }, []*proto3.Value{{Kind: (*proto3.Value_StringValue)(nil)}}, }, &[]byte{}, errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_StringValue)(nil)}, "String")), }, { // Field specifies BYTES type, but value is for BOOL type. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: bytesType()}, }, []*proto3.Value{boolProto(false)}, }, &[]byte{}, errDecodeColumn(0, errSrcVal(boolProto(false), "String")), }, { // Field specifies BYTES type, but value is wrongly encoded. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: bytesType()}, }, []*proto3.Value{stringProto("&&")}, }, &[]byte{}, errDecodeColumn(0, errBadEncoding(stringProto("&&"), func() error { _, err := base64.StdEncoding.DecodeString("&&") return err }())), }, { // Field specifies BOOL type, value is having a nil Kind. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: boolType()}, }, []*proto3.Value{{Kind: (*proto3.Value_BoolValue)(nil)}}, }, &NullBool{false, true}, errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_BoolValue)(nil)}, "Bool")), }, { // Field specifies BOOL type, but value is for STRING type. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: boolType()}, }, []*proto3.Value{stringProto("false")}, }, &NullBool{false, true}, errDecodeColumn(0, errSrcVal(stringProto("false"), "Bool")), }, { // Field specifies TIMESTAMP type, value is having a nil Kind. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: timeType()}, }, []*proto3.Value{{Kind: (*proto3.Value_StringValue)(nil)}}, }, &NullTime{time.Now(), true}, errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_StringValue)(nil)}, "String")), }, { // Field specifies TIMESTAMP type, but value is for BOOL type. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: timeType()}, }, []*proto3.Value{boolProto(false)}, }, &NullTime{time.Now(), true}, errDecodeColumn(0, errSrcVal(boolProto(false), "String")), }, { // Field specifies TIMESTAMP type, but value is invalid timestamp. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: timeType()}, }, []*proto3.Value{stringProto("junk")}, }, &NullTime{time.Now(), true}, errDecodeColumn(0, errBadEncoding(stringProto("junk"), func() error { _, err := time.Parse(time.RFC3339Nano, "junk") return err }())), }, { // Field specifies DATE type, value is having a nil Kind. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: dateType()}, }, []*proto3.Value{{Kind: (*proto3.Value_StringValue)(nil)}}, }, &NullDate{civil.Date{}, true}, errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_StringValue)(nil)}, "String")), }, { // Field specifies DATE type, but value is for BOOL type. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: dateType()}, }, []*proto3.Value{boolProto(false)}, }, &NullDate{civil.Date{}, true}, errDecodeColumn(0, errSrcVal(boolProto(false), "String")), }, { // Field specifies DATE type, but value is invalid timestamp. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: dateType()}, }, []*proto3.Value{stringProto("junk")}, }, &NullDate{civil.Date{}, true}, errDecodeColumn(0, errBadEncoding(stringProto("junk"), func() error { _, err := civil.ParseDate("junk") return err }())), }, { // Field specifies ARRAY type, value is having a nil Kind. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: listType(intType())}, }, []*proto3.Value{{Kind: (*proto3.Value_ListValue)(nil)}}, }, &[]NullInt64{}, errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_ListValue)(nil)}, "List")), }, { // Field specifies ARRAY type, value is having a nil ListValue. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: listType(intType())}, }, []*proto3.Value{{Kind: &proto3.Value_ListValue{}}}, }, &[]NullInt64{}, errDecodeColumn(0, errNilListValue("INT64")), }, { // Field specifies ARRAY type, but value is for BYTES type. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: listType(intType())}, }, []*proto3.Value{bytesProto([]byte("value"))}, }, &[]NullInt64{}, errDecodeColumn(0, errSrcVal(bytesProto([]byte("value")), "List")), }, { // Field specifies ARRAY type, but value is for ARRAY type. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: listType(intType())}, }, []*proto3.Value{listProto(boolProto(true))}, }, &[]NullInt64{}, errDecodeColumn(0, errDecodeArrayElement(0, boolProto(true), "INT64", errSrcVal(boolProto(true), "String"))), }, { // Field specifies ARRAY type, value is having a nil Kind. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: listType(stringType())}, }, []*proto3.Value{{Kind: (*proto3.Value_ListValue)(nil)}}, }, &[]NullString{}, errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_ListValue)(nil)}, "List")), }, { // Field specifies ARRAY type, value is having a nil ListValue. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: listType(stringType())}, }, []*proto3.Value{{Kind: &proto3.Value_ListValue{}}}, }, &[]NullString{}, errDecodeColumn(0, errNilListValue("STRING")), }, { // Field specifies ARRAY type, but value is for BOOL type. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: listType(stringType())}, }, []*proto3.Value{boolProto(true)}, }, &[]NullString{}, errDecodeColumn(0, errSrcVal(boolProto(true), "List")), }, { // Field specifies ARRAY type, but value is for ARRAY type. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: listType(stringType())}, }, []*proto3.Value{listProto(boolProto(true))}, }, &[]NullString{}, errDecodeColumn(0, errDecodeArrayElement(0, boolProto(true), "STRING", errSrcVal(boolProto(true), "String"))), }, { // Field specifies ARRAY type, value is having a nil Kind. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: listType(floatType())}, }, []*proto3.Value{{Kind: (*proto3.Value_ListValue)(nil)}}, }, &[]NullFloat64{}, errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_ListValue)(nil)}, "List")), }, { // Field specifies ARRAY type, value is having a nil ListValue. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: listType(floatType())}, }, []*proto3.Value{{Kind: &proto3.Value_ListValue{}}}, }, &[]NullFloat64{}, errDecodeColumn(0, errNilListValue("FLOAT64")), }, { // Field specifies ARRAY type, but value is for STRING type. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: listType(floatType())}, }, []*proto3.Value{stringProto("value")}, }, &[]NullFloat64{}, errDecodeColumn(0, errSrcVal(stringProto("value"), "List")), }, { // Field specifies ARRAY type, but value is for ARRAY type. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: listType(floatType())}, }, []*proto3.Value{listProto(boolProto(true))}, }, &[]NullFloat64{}, errDecodeColumn(0, errDecodeArrayElement(0, boolProto(true), "FLOAT64", errSrcVal(boolProto(true), "Number"))), }, { // Field specifies ARRAY type, value is having a nil Kind. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: listType(bytesType())}, }, []*proto3.Value{{Kind: (*proto3.Value_ListValue)(nil)}}, }, &[][]byte{}, errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_ListValue)(nil)}, "List")), }, { // Field specifies ARRAY type, value is having a nil ListValue. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: listType(bytesType())}, }, []*proto3.Value{{Kind: &proto3.Value_ListValue{}}}, }, &[][]byte{}, errDecodeColumn(0, errNilListValue("BYTES")), }, { // Field specifies ARRAY type, but value is for FLOAT64 type. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: listType(bytesType())}, }, []*proto3.Value{floatProto(1.0)}, }, &[][]byte{}, errDecodeColumn(0, errSrcVal(floatProto(1.0), "List")), }, { // Field specifies ARRAY type, but value is for ARRAY type. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: listType(bytesType())}, }, []*proto3.Value{listProto(floatProto(1.0))}, }, &[][]byte{}, errDecodeColumn(0, errDecodeArrayElement(0, floatProto(1.0), "BYTES", errSrcVal(floatProto(1.0), "String"))), }, { // Field specifies ARRAY type, value is having a nil Kind. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: listType(boolType())}, }, []*proto3.Value{{Kind: (*proto3.Value_ListValue)(nil)}}, }, &[]NullBool{}, errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_ListValue)(nil)}, "List")), }, { // Field specifies ARRAY type, value is having a nil ListValue. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: listType(boolType())}, }, []*proto3.Value{{Kind: &proto3.Value_ListValue{}}}, }, &[]NullBool{}, errDecodeColumn(0, errNilListValue("BOOL")), }, { // Field specifies ARRAY type, but value is for FLOAT64 type. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: listType(boolType())}, }, []*proto3.Value{floatProto(1.0)}, }, &[]NullBool{}, errDecodeColumn(0, errSrcVal(floatProto(1.0), "List")), }, { // Field specifies ARRAY type, but value is for ARRAY type. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: listType(boolType())}, }, []*proto3.Value{listProto(floatProto(1.0))}, }, &[]NullBool{}, errDecodeColumn(0, errDecodeArrayElement(0, floatProto(1.0), "BOOL", errSrcVal(floatProto(1.0), "Bool"))), }, { // Field specifies ARRAY type, value is having a nil Kind. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: listType(timeType())}, }, []*proto3.Value{{Kind: (*proto3.Value_ListValue)(nil)}}, }, &[]NullTime{}, errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_ListValue)(nil)}, "List")), }, { // Field specifies ARRAY type, value is having a nil ListValue. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: listType(timeType())}, }, []*proto3.Value{{Kind: &proto3.Value_ListValue{}}}, }, &[]NullTime{}, errDecodeColumn(0, errNilListValue("TIMESTAMP")), }, { // Field specifies ARRAY type, but value is for FLOAT64 type. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: listType(timeType())}, }, []*proto3.Value{floatProto(1.0)}, }, &[]NullTime{}, errDecodeColumn(0, errSrcVal(floatProto(1.0), "List")), }, { // Field specifies ARRAY type, but value is for ARRAY type. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: listType(timeType())}, }, []*proto3.Value{listProto(floatProto(1.0))}, }, &[]NullTime{}, errDecodeColumn(0, errDecodeArrayElement(0, floatProto(1.0), "TIMESTAMP", errSrcVal(floatProto(1.0), "String"))), }, { // Field specifies ARRAY type, value is having a nil Kind. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: listType(dateType())}, }, []*proto3.Value{{Kind: (*proto3.Value_ListValue)(nil)}}, }, &[]NullDate{}, errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_ListValue)(nil)}, "List")), }, { // Field specifies ARRAY type, value is having a nil ListValue. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: listType(dateType())}, }, []*proto3.Value{{Kind: &proto3.Value_ListValue{}}}, }, &[]NullDate{}, errDecodeColumn(0, errNilListValue("DATE")), }, { // Field specifies ARRAY type, but value is for FLOAT64 type. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: listType(dateType())}, }, []*proto3.Value{floatProto(1.0)}, }, &[]NullDate{}, errDecodeColumn(0, errSrcVal(floatProto(1.0), "List")), }, { // Field specifies ARRAY type, but value is for ARRAY type. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: listType(dateType())}, }, []*proto3.Value{listProto(floatProto(1.0))}, }, &[]NullDate{}, errDecodeColumn(0, errDecodeArrayElement(0, floatProto(1.0), "DATE", errSrcVal(floatProto(1.0), "String"))), }, { // Field specifies ARRAY type, value is having a nil Kind. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: listType(structType( mkField("Col1", intType()), mkField("Col2", floatType()), mkField("Col3", stringType()), ))}, }, []*proto3.Value{{Kind: (*proto3.Value_ListValue)(nil)}}, }, &[]*struct { Col1 int64 Col2 float64 Col3 string }{}, errDecodeColumn(0, errSrcVal(&proto3.Value{Kind: (*proto3.Value_ListValue)(nil)}, "List")), }, { // Field specifies ARRAY type, value is having a nil ListValue. &Row{ []*sppb.StructType_Field{ {Name: "Col0", Type: listType(structType( mkField("Col1", intType()), mkField("Col2", floatType()), mkField("Col3", stringType()), ))}, }, []*proto3.Value{{Kind: &proto3.Value_ListValue{}}}, }, &[]*struct { Col1 int64 Col2 float64 Col3 string }{}, errDecodeColumn(0, errNilListValue("STRUCT")), }, { // Field specifies ARRAY type, value is having a nil ListValue. &Row{ []*sppb.StructType_Field{ { Name: "Col0", Type: listType( structType( mkField("Col1", intType()), mkField("Col2", floatType()), mkField("Col3", stringType()), ), ), }, }, []*proto3.Value{{Kind: &proto3.Value_ListValue{}}}, }, &[]NullRow{}, errDecodeColumn(0, errNilListValue("STRUCT")), }, { // Field specifies ARRAY type, value is for BYTES type. &Row{ []*sppb.StructType_Field{ { Name: "Col0", Type: listType( structType( mkField("Col1", intType()), mkField("Col2", floatType()), mkField("Col3", stringType()), ), ), }, }, []*proto3.Value{bytesProto([]byte("value"))}, }, &[]*struct { Col1 int64 Col2 float64 Col3 string }{}, errDecodeColumn(0, errSrcVal(bytesProto([]byte("value")), "List")), }, { // Field specifies ARRAY type, value is for BYTES type. &Row{ []*sppb.StructType_Field{ { Name: "Col0", Type: listType( structType( mkField("Col1", intType()), mkField("Col2", floatType()), mkField("Col3", stringType()), ), ), }, }, []*proto3.Value{listProto(bytesProto([]byte("value")))}, }, &[]NullRow{}, errDecodeColumn(0, errNotStructElement(0, bytesProto([]byte("value")))), }, { // Field specifies ARRAY type, value is for ARRAY type. &Row{ []*sppb.StructType_Field{ { Name: "Col0", Type: listType( structType( mkField("Col1", intType()), mkField("Col2", floatType()), mkField("Col3", stringType()), ), ), }, }, []*proto3.Value{listProto(bytesProto([]byte("value")))}, }, &[]*struct { Col1 int64 Col2 float64 Col3 string }{}, errDecodeColumn(0, errDecodeArrayElement(0, bytesProto([]byte("value")), "STRUCT", errSrcVal(bytesProto([]byte("value")), "List"))), }, { // Field specifies ARRAY, but is having nil StructType. &Row{ []*sppb.StructType_Field{ { Name: "Col0", Type: listType(&sppb.Type{Code: sppb.TypeCode_STRUCT}), }, }, []*proto3.Value{listProto(listProto(intProto(1), floatProto(2.0), stringProto("3")))}, }, &[]*struct { Col1 int64 Col2 float64 Col3 string }{}, errDecodeColumn(0, errDecodeArrayElement(0, listProto(intProto(1), floatProto(2.0), stringProto("3")), "STRUCT", errNilSpannerStructType())), }, { // Field specifies ARRAY, but the second struct value is for BOOL type instead of FLOAT64. &Row{ []*sppb.StructType_Field{ { Name: "Col0", Type: listType( structType( mkField("Col1", intType()), mkField("Col2", floatType()), mkField("Col3", stringType()), ), ), }, }, []*proto3.Value{listProto(listProto(intProto(1), boolProto(true), stringProto("3")))}, }, &[]*struct { Col1 int64 Col2 float64 Col3 string }{}, errDecodeColumn( 0, errDecodeArrayElement( 0, listProto(intProto(1), boolProto(true), stringProto("3")), "STRUCT", errDecodeStructField( &sppb.StructType{ Fields: []*sppb.StructType_Field{ mkField("Col1", intType()), mkField("Col2", floatType()), mkField("Col3", stringType()), }, }, "Col2", errSrcVal(boolProto(true), "Number"), ), ), ), }, } { if gotErr := test.row.Column(0, test.dst); !testEqual(gotErr, test.wantErr) { t.Errorf("%v: test.row.Column(0) got error %v, want %v", i, gotErr, test.wantErr) } if gotErr := test.row.ColumnByName("Col0", test.dst); !testEqual(gotErr, test.wantErr) { t.Errorf("%v: test.row.ColumnByName(%q) got error %v, want %v", i, "Col0", gotErr, test.wantErr) } if gotErr := test.row.Columns(test.dst); !testEqual(gotErr, test.wantErr) { t.Errorf("%v: test.row.Columns(%T) got error %v, want %v", i, test.dst, gotErr, test.wantErr) } } } // Test Row.ToStruct(). func TestToStruct(t *testing.T) { s := []struct { // STRING / STRING ARRAY PrimaryKey string `spanner:"STRING"` NullString NullString `spanner:"NULL_STRING"` StringArray []NullString `spanner:"STRING_ARRAY"` NullStringArray []NullString `spanner:"NULL_STRING_ARRAY"` // BYTES / BYTES ARRAY Bytes []byte `spanner:"BYTES"` NullBytes []byte `spanner:"NULL_BYTES"` BytesArray [][]byte `spanner:"BYTES_ARRAY"` NullBytesArray [][]byte `spanner:"NULL_BYTES_ARRAY"` // INT64 / INT64 ARRAY Int64 int64 `spanner:"INT64"` NullInt64 NullInt64 `spanner:"NULL_INT64"` Int64Array []NullInt64 `spanner:"INT64_ARRAY"` NullInt64Array []NullInt64 `spanner:"NULL_INT64_ARRAY"` // BOOL / BOOL ARRAY Bool bool `spanner:"BOOL"` NullBool NullBool `spanner:"NULL_BOOL"` BoolArray []NullBool `spanner:"BOOL_ARRAY"` NullBoolArray []NullBool `spanner:"NULL_BOOL_ARRAY"` // FLOAT64 / FLOAT64 ARRAY Float64 float64 `spanner:"FLOAT64"` NullFloat64 NullFloat64 `spanner:"NULL_FLOAT64"` Float64Array []NullFloat64 `spanner:"FLOAT64_ARRAY"` NullFloat64Array []NullFloat64 `spanner:"NULL_FLOAT64_ARRAY"` // TIMESTAMP / TIMESTAMP ARRAY Timestamp time.Time `spanner:"TIMESTAMP"` NullTimestamp NullTime `spanner:"NULL_TIMESTAMP"` TimestampArray []NullTime `spanner:"TIMESTAMP_ARRAY"` NullTimestampArray []NullTime `spanner:"NULL_TIMESTAMP_ARRAY"` // DATE / DATE ARRAY Date civil.Date `spanner:"DATE"` NullDate NullDate `spanner:"NULL_DATE"` DateArray []NullDate `spanner:"DATE_ARRAY"` NullDateArray []NullDate `spanner:"NULL_DATE_ARRAY"` // STRUCT ARRAY StructArray []*struct { Col1 int64 Col2 float64 Col3 string } `spanner:"STRUCT_ARRAY"` NullStructArray []*struct { Col1 int64 Col2 float64 Col3 string } `spanner:"NULL_STRUCT_ARRAY"` }{ {}, // got { // STRING / STRING ARRAY "value", NullString{}, []NullString{{"value1", true}, {}, {"value3", true}}, []NullString(nil), // BYTES / BYTES ARRAY []byte("value"), []byte(nil), [][]byte{[]byte("value1"), nil, []byte("value3")}, [][]byte(nil), // INT64 / INT64 ARRAY int64(17), NullInt64{}, []NullInt64{{int64(1), true}, {int64(2), true}, {}}, []NullInt64(nil), // BOOL / BOOL ARRAY true, NullBool{}, []NullBool{{}, {true, true}, {false, true}}, []NullBool(nil), // FLOAT64 / FLOAT64 ARRAY 1.7, NullFloat64{}, []NullFloat64{{}, {}, {1.7, true}}, []NullFloat64(nil), // TIMESTAMP / TIMESTAMP ARRAY tm, NullTime{}, []NullTime{{}, {tm, true}}, []NullTime(nil), // DATE / DATE ARRAY dt, NullDate{}, []NullDate{{}, {dt, true}}, []NullDate(nil), // STRUCT ARRAY []*struct { Col1 int64 Col2 float64 Col3 string }{ nil, {3, 33.3, "three"}, nil, }, []*struct { Col1 int64 Col2 float64 Col3 string }(nil), }, // want } err := row.ToStruct(&s[0]) if err != nil { t.Errorf("row.ToStruct() returns error: %v, want nil", err) } else if !testEqual(s[0], s[1]) { t.Errorf("row.ToStruct() fetches struct %v, want %v", s[0], s[1]) } } func TestToStructEmbedded(t *testing.T) { type ( S1 struct{ F1 string } S2 struct { S1 F2 string } ) r := Row{ []*sppb.StructType_Field{ {Name: "F1", Type: stringType()}, {Name: "F2", Type: stringType()}, }, []*proto3.Value{ stringProto("v1"), stringProto("v2"), }, } var got S2 if err := r.ToStruct(&got); err != nil { t.Fatal(err) } want := S2{S1: S1{F1: "v1"}, F2: "v2"} if !testEqual(got, want) { t.Errorf("got %+v, want %+v", got, want) } } // Test helpers for getting column names. func TestColumnNameAndIndex(t *testing.T) { // Test Row.Size(). if rs := row.Size(); rs != len(row.fields) { t.Errorf("row.Size() returns %v, want %v", rs, len(row.fields)) } // Test Row.Size() on empty Row. if rs := (&Row{}).Size(); rs != 0 { t.Errorf("empty_row.Size() returns %v, want %v", rs, 0) } // Test Row.ColumnName() for i, col := range row.fields { if cn := row.ColumnName(i); cn != col.Name { t.Errorf("row.ColumnName(%v) returns %q, want %q", i, cn, col.Name) } goti, err := row.ColumnIndex(col.Name) if err != nil { t.Errorf("ColumnIndex(%q) error %v", col.Name, err) continue } if goti != i { t.Errorf("ColumnIndex(%q) = %d, want %d", col.Name, goti, i) } } // Test Row.ColumnName on empty Row. if cn := (&Row{}).ColumnName(0); cn != "" { t.Errorf("empty_row.ColumnName(%v) returns %q, want %q", 0, cn, "") } // Test Row.ColumnIndex on empty Row. if _, err := (&Row{}).ColumnIndex(""); err == nil { t.Error("empty_row.ColumnIndex returns nil, want error") } } func TestNewRow(t *testing.T) { for _, test := range []struct { names []string values []interface{} want *Row wantErr error }{ { want: &Row{fields: []*sppb.StructType_Field{}, vals: []*proto3.Value{}}, }, { names: []string{}, values: []interface{}{}, want: &Row{fields: []*sppb.StructType_Field{}, vals: []*proto3.Value{}}, }, { names: []string{"a", "b"}, values: []interface{}{}, want: nil, wantErr: errNamesValuesMismatch([]string{"a", "b"}, []interface{}{}), }, { names: []string{"a", "b", "c"}, values: []interface{}{5, "abc", GenericColumnValue{listType(intType()), listProto(intProto(91), nullProto(), intProto(87))}}, want: &Row{ []*sppb.StructType_Field{ {Name: "a", Type: intType()}, {Name: "b", Type: stringType()}, {Name: "c", Type: listType(intType())}, }, []*proto3.Value{ intProto(5), stringProto("abc"), listProto(intProto(91), nullProto(), intProto(87)), }, }, }, } { got, err := NewRow(test.names, test.values) if !testEqual(err, test.wantErr) { t.Errorf("NewRow(%v,%v).err = %s, want %s", test.names, test.values, err, test.wantErr) continue } if !testEqual(got, test.want) { t.Errorf("NewRow(%v,%v) = %s, want %s", test.names, test.values, got, test.want) continue } } } func BenchmarkColumn(b *testing.B) { var s string for i := 0; i < b.N; i++ { if err := row.Column(0, &s); err != nil { b.Fatal(err) } } } google-cloud-go-0.49.0/spanner/session.go000066400000000000000000001315061356504100700202560ustar00rootroot00000000000000/* Copyright 2017 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spanner import ( "container/heap" "container/list" "context" "fmt" "log" "math" "math/rand" "strings" "sync" "time" "cloud.google.com/go/internal/trace" vkit "cloud.google.com/go/spanner/apiv1" sppb "google.golang.org/genproto/googleapis/spanner/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // sessionHandle is an interface for transactions to access Cloud Spanner // sessions safely. It is generated by sessionPool.take(). type sessionHandle struct { // mu guarantees that the inner session object is returned / destroyed only // once. mu sync.Mutex // session is a pointer to a session object. Transactions never need to // access it directly. session *session } // recycle gives the inner session object back to its home session pool. It is // safe to call recycle multiple times but only the first one would take effect. func (sh *sessionHandle) recycle() { sh.mu.Lock() defer sh.mu.Unlock() if sh.session == nil { // sessionHandle has already been recycled. return } sh.session.recycle() sh.session = nil } // getID gets the Cloud Spanner session ID from the internal session object. // getID returns empty string if the sessionHandle is nil or the inner session // object has been released by recycle / destroy. func (sh *sessionHandle) getID() string { sh.mu.Lock() defer sh.mu.Unlock() if sh.session == nil { // sessionHandle has already been recycled/destroyed. return "" } return sh.session.getID() } // getClient gets the Cloud Spanner RPC client associated with the session ID // in sessionHandle. func (sh *sessionHandle) getClient() *vkit.Client { sh.mu.Lock() defer sh.mu.Unlock() if sh.session == nil { return nil } return sh.session.client } // getMetadata returns the metadata associated with the session in sessionHandle. func (sh *sessionHandle) getMetadata() metadata.MD { sh.mu.Lock() defer sh.mu.Unlock() if sh.session == nil { return nil } return sh.session.md } // getTransactionID returns the transaction id in the session if available. func (sh *sessionHandle) getTransactionID() transactionID { sh.mu.Lock() defer sh.mu.Unlock() if sh.session == nil { return nil } return sh.session.tx } // destroy destroys the inner session object. It is safe to call destroy // multiple times and only the first call would attempt to // destroy the inner session object. func (sh *sessionHandle) destroy() { sh.mu.Lock() s := sh.session sh.session = nil sh.mu.Unlock() if s == nil { // sessionHandle has already been destroyed.. return } s.destroy(false) } // session wraps a Cloud Spanner session ID through which transactions are // created and executed. type session struct { // client is the RPC channel to Cloud Spanner. It is set only once during // session's creation. client *vkit.Client // id is the unique id of the session in Cloud Spanner. It is set only once // during session's creation. id string // pool is the session's home session pool where it was created. It is set // only once during session's creation. pool *sessionPool // createTime is the timestamp of the session's creation. It is set only // once during session's creation. createTime time.Time // mu protects the following fields from concurrent access: both // healthcheck workers and transactions can modify them. mu sync.Mutex // valid marks the validity of a session. valid bool // hcIndex is the index of the session inside the global healthcheck queue. // If hcIndex < 0, session has been unregistered from the queue. hcIndex int // idleList is the linkedlist node which links the session to its home // session pool's idle list. If idleList == nil, the // session is not in idle list. idleList *list.Element // nextCheck is the timestamp of next scheduled healthcheck of the session. // It is maintained by the global health checker. nextCheck time.Time // checkingHelath is true if currently this session is being processed by // health checker. Must be modified under health checker lock. checkingHealth bool // md is the Metadata to be sent with each request. md metadata.MD // tx contains the transaction id if the session has been prepared for // write. tx transactionID } // isValid returns true if the session is still valid for use. func (s *session) isValid() bool { s.mu.Lock() defer s.mu.Unlock() return s.valid } // isWritePrepared returns true if the session is prepared for write. func (s *session) isWritePrepared() bool { s.mu.Lock() defer s.mu.Unlock() return s.tx != nil } // String implements fmt.Stringer for session. func (s *session) String() string { s.mu.Lock() defer s.mu.Unlock() return fmt.Sprintf("", s.id, s.hcIndex, s.idleList, s.valid, s.createTime, s.nextCheck) } // ping verifies if the session is still alive in Cloud Spanner. func (s *session) ping() error { ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() // s.getID is safe even when s is invalid. _, err := s.client.GetSession(contextWithOutgoingMetadata(ctx, s.md), &sppb.GetSessionRequest{Name: s.getID()}) return err } // setHcIndex atomically sets the session's index in the healthcheck queue and // returns the old index. func (s *session) setHcIndex(i int) int { s.mu.Lock() defer s.mu.Unlock() oi := s.hcIndex s.hcIndex = i return oi } // setIdleList atomically sets the session's idle list link and returns the old // link. func (s *session) setIdleList(le *list.Element) *list.Element { s.mu.Lock() defer s.mu.Unlock() old := s.idleList s.idleList = le return old } // invalidate marks a session as invalid and returns the old validity. func (s *session) invalidate() bool { s.mu.Lock() defer s.mu.Unlock() ov := s.valid s.valid = false return ov } // setNextCheck sets the timestamp for next healthcheck on the session. func (s *session) setNextCheck(t time.Time) { s.mu.Lock() defer s.mu.Unlock() s.nextCheck = t } // setTransactionID sets the transaction id in the session func (s *session) setTransactionID(tx transactionID) { s.mu.Lock() defer s.mu.Unlock() s.tx = tx } // getID returns the session ID which uniquely identifies the session in Cloud // Spanner. func (s *session) getID() string { s.mu.Lock() defer s.mu.Unlock() return s.id } // getHcIndex returns the session's index into the global healthcheck priority // queue. func (s *session) getHcIndex() int { s.mu.Lock() defer s.mu.Unlock() return s.hcIndex } // getIdleList returns the session's link in its home session pool's idle list. func (s *session) getIdleList() *list.Element { s.mu.Lock() defer s.mu.Unlock() return s.idleList } // getNextCheck returns the timestamp for next healthcheck on the session. func (s *session) getNextCheck() time.Time { s.mu.Lock() defer s.mu.Unlock() return s.nextCheck } // recycle turns the session back to its home session pool. func (s *session) recycle() { s.setTransactionID(nil) if !s.pool.recycle(s) { // s is rejected by its home session pool because it expired and the // session pool currently has enough open sessions. s.destroy(false) } } // destroy removes the session from its home session pool, healthcheck queue // and Cloud Spanner service. func (s *session) destroy(isExpire bool) bool { // Remove s from session pool. if !s.pool.remove(s, isExpire) { return false } // Unregister s from healthcheck queue. s.pool.hc.unregister(s) // Remove s from Cloud Spanner service. ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) defer cancel() s.delete(ctx) return true } func (s *session) delete(ctx context.Context) { // Ignore the error because even if we fail to explicitly destroy the // session, it will be eventually garbage collected by Cloud Spanner. err := s.client.DeleteSession(ctx, &sppb.DeleteSessionRequest{Name: s.getID()}) if err != nil { log.Printf("Failed to delete session %v. Error: %v", s.getID(), err) } } // prepareForWrite prepares the session for write if it is not already in that // state. func (s *session) prepareForWrite(ctx context.Context) error { if s.isWritePrepared() { return nil } tx, err := beginTransaction(contextWithOutgoingMetadata(ctx, s.md), s.getID(), s.client) s.pool.mu.Lock() s.pool.disableBackgroundPrepareSessions = isPermissionDeniedError(err) || isDatabaseNotFoundError(err) s.pool.mu.Unlock() if err != nil { return err } s.setTransactionID(tx) return nil } // SessionPoolConfig stores configurations of a session pool. type SessionPoolConfig struct { // MaxOpened is the maximum number of opened sessions allowed by the session // pool. If the client tries to open a session and there are already // MaxOpened sessions, it will block until one becomes available or the // context passed to the client method is canceled or times out. // // Defaults to NumChannels * 100. MaxOpened uint64 // MinOpened is the minimum number of opened sessions that the session pool // tries to maintain. Session pool won't continue to expire sessions if // number of opened connections drops below MinOpened. However, if a session // is found to be broken, it will still be evicted from the session pool, // therefore it is posssible that the number of opened sessions drops below // MinOpened. // // Defaults to 100. MinOpened uint64 // MaxIdle is the maximum number of idle sessions, pool is allowed to keep. // // Defaults to 0. MaxIdle uint64 // MaxBurst is the maximum number of concurrent session creation requests. // // Defaults to 10. MaxBurst uint64 // WriteSessions is the fraction of sessions we try to keep prepared for // write. // // Defaults to 0.2. WriteSessions float64 // HealthCheckWorkers is number of workers used by health checker for this // pool. // // Defaults to 10. HealthCheckWorkers int // HealthCheckInterval is how often the health checker pings a session. // // Defaults to 5m. HealthCheckInterval time.Duration // healthCheckSampleInterval is how often the health checker samples live // session (for use in maintaining session pool size). // // Defaults to 1m. healthCheckSampleInterval time.Duration // sessionLabels for the sessions created in the session pool. sessionLabels map[string]string } // DefaultSessionPoolConfig is the default configuration for the session pool // that will be used for a Spanner client, unless the user supplies a specific // session pool config. var DefaultSessionPoolConfig = SessionPoolConfig{ MinOpened: 100, MaxOpened: numChannels * 100, MaxBurst: 10, WriteSessions: 0.2, HealthCheckWorkers: 10, HealthCheckInterval: 5 * time.Minute, } // errMinOpenedGTMapOpened returns error for SessionPoolConfig.MaxOpened < SessionPoolConfig.MinOpened when SessionPoolConfig.MaxOpened is set. func errMinOpenedGTMaxOpened(maxOpened, minOpened uint64) error { return spannerErrorf(codes.InvalidArgument, "require SessionPoolConfig.MaxOpened >= SessionPoolConfig.MinOpened, got %d and %d", maxOpened, minOpened) } // errWriteFractionOutOfRange returns error for // SessionPoolConfig.WriteFraction < 0 or SessionPoolConfig.WriteFraction > 1 func errWriteFractionOutOfRange(writeFraction float64) error { return spannerErrorf(codes.InvalidArgument, "require SessionPoolConfig.WriteSessions >= 0.0 && SessionPoolConfig.WriteSessions <= 1.0, got %.2f", writeFraction) } // errHealthCheckWorkersNegative returns error for // SessionPoolConfig.HealthCheckWorkers < 0 func errHealthCheckWorkersNegative(workers int) error { return spannerErrorf(codes.InvalidArgument, "require SessionPoolConfig.HealthCheckWorkers >= 0, got %d", workers) } // errHealthCheckIntervalNegative returns error for // SessionPoolConfig.HealthCheckInterval < 0 func errHealthCheckIntervalNegative(interval time.Duration) error { return spannerErrorf(codes.InvalidArgument, "require SessionPoolConfig.HealthCheckInterval >= 0, got %v", interval) } // validate verifies that the SessionPoolConfig is good for use. func (spc *SessionPoolConfig) validate() error { if spc.MinOpened > spc.MaxOpened && spc.MaxOpened > 0 { return errMinOpenedGTMaxOpened(spc.MaxOpened, spc.MinOpened) } if spc.WriteSessions < 0.0 || spc.WriteSessions > 1.0 { return errWriteFractionOutOfRange(spc.WriteSessions) } if spc.HealthCheckWorkers < 0 { return errHealthCheckWorkersNegative(spc.HealthCheckWorkers) } if spc.HealthCheckInterval < 0 { return errHealthCheckIntervalNegative(spc.HealthCheckInterval) } return nil } // sessionPool creates and caches Cloud Spanner sessions. type sessionPool struct { // mu protects sessionPool from concurrent access. mu sync.Mutex // valid marks the validity of the session pool. valid bool // sc is used to create the sessions for the pool. sc *sessionClient // idleList caches idle session IDs. Session IDs in this list can be // allocated for use. idleList list.List // idleWriteList caches idle sessions which have been prepared for write. idleWriteList list.List // mayGetSession is for broadcasting that session retrival/creation may // proceed. mayGetSession chan struct{} // numOpened is the total number of open sessions from the session pool. numOpened uint64 // createReqs is the number of ongoing session creation requests. createReqs uint64 // prepareReqs is the number of ongoing session preparation request. prepareReqs uint64 // disableBackgroundPrepareSessions indicates that the BeginTransaction // call for a read/write transaction failed with a permanent error, such as // PermissionDenied or `Database not found`. Further background calls to // prepare sessions will be disabled. disableBackgroundPrepareSessions bool // configuration of the session pool. SessionPoolConfig // hc is the health checker hc *healthChecker // mw is the maintenance window containing statistics for the max number of // sessions checked out of the pool during the last 10 minutes. mw *maintenanceWindow } // newSessionPool creates a new session pool. func newSessionPool(sc *sessionClient, config SessionPoolConfig) (*sessionPool, error) { if err := config.validate(); err != nil { return nil, err } pool := &sessionPool{ sc: sc, valid: true, mayGetSession: make(chan struct{}), SessionPoolConfig: config, mw: newMaintenanceWindow(config.MaxOpened), } if config.HealthCheckWorkers == 0 { // With 10 workers and assuming average latency of 5ms for // BeginTransaction, we will be able to prepare 2000 tx/sec in advance. // If the rate of takeWriteSession is more than that, it will degrade to // doing BeginTransaction inline. // // TODO: consider resizing the worker pool dynamically according to the load. config.HealthCheckWorkers = 10 } if config.HealthCheckInterval == 0 { config.HealthCheckInterval = 5 * time.Minute } if config.healthCheckSampleInterval == 0 { config.healthCheckSampleInterval = time.Minute } // On GCE VM, within the same region an healthcheck ping takes on average // 10ms to finish, given a 5 minutes interval and 10 healthcheck workers, a // healthChecker can effectively mantain // 100 checks_per_worker/sec * 10 workers * 300 seconds = 300K sessions. pool.hc = newHealthChecker(config.HealthCheckInterval, config.HealthCheckWorkers, config.healthCheckSampleInterval, pool) // First initialize the pool before we indicate that the healthchecker is // ready. This prevents the maintainer from starting before the pool has // been initialized, which means that we guarantee that the initial // sessions are created using BatchCreateSessions. if config.MinOpened > 0 { numSessions := minUint64(config.MinOpened, math.MaxInt32) if err := pool.initPool(int32(numSessions)); err != nil { return nil, err } } close(pool.hc.ready) return pool, nil } func (p *sessionPool) initPool(numSessions int32) error { p.mu.Lock() // Take budget before the actual session creation. p.numOpened += uint64(numSessions) recordStat(context.Background(), OpenSessionCount, int64(p.numOpened)) p.createReqs += uint64(numSessions) p.mu.Unlock() // Asynchronously create the initial sessions for the pool. return p.sc.batchCreateSessions(numSessions, p) } // sessionReady is executed by the SessionClient when a session has been // created and is ready to use. This method will add the new session to the // pool and decrease the number of sessions that is being created. func (p *sessionPool) sessionReady(s *session) { p.mu.Lock() defer p.mu.Unlock() // Set this pool as the home pool of the session and register it with the // health checker. s.pool = p p.hc.register(s) p.createReqs-- // Insert the session at a random position in the pool to prevent all // sessions affiliated with a channel to be placed at sequentially in the // pool. if p.idleList.Len() > 0 { pos := rand.Intn(p.idleList.Len()) before := p.idleList.Front() for i := 0; i < pos; i++ { before = before.Next() } s.setIdleList(p.idleList.InsertBefore(s, before)) } else { s.setIdleList(p.idleList.PushBack(s)) } // Notify other waiters blocking on session creation. close(p.mayGetSession) p.mayGetSession = make(chan struct{}) } // sessionCreationFailed is called by the SessionClient when the creation of one // or more requested sessions finished with an error. sessionCreationFailed will // decrease the number of sessions being created and notify any waiters that // the session creation failed. func (p *sessionPool) sessionCreationFailed(err error, numSessions int32) { p.mu.Lock() defer p.mu.Unlock() p.createReqs -= uint64(numSessions) p.numOpened -= uint64(numSessions) recordStat(context.Background(), OpenSessionCount, int64(p.numOpened)) // Notify other waiters blocking on session creation. close(p.mayGetSession) p.mayGetSession = make(chan struct{}) } // isValid checks if the session pool is still valid. func (p *sessionPool) isValid() bool { if p == nil { return false } p.mu.Lock() defer p.mu.Unlock() return p.valid } // close marks the session pool as closed. func (p *sessionPool) close() { if p == nil { return } p.mu.Lock() if !p.valid { p.mu.Unlock() return } p.valid = false p.mu.Unlock() p.hc.close() // destroy all the sessions p.hc.mu.Lock() allSessions := make([]*session, len(p.hc.queue.sessions)) copy(allSessions, p.hc.queue.sessions) p.hc.mu.Unlock() for _, s := range allSessions { s.destroy(false) } } // errInvalidSessionPool returns error for using an invalid session pool. func errInvalidSessionPool() error { return spannerErrorf(codes.InvalidArgument, "invalid session pool") } // errGetSessionTimeout returns error for context timeout during // sessionPool.take(). func errGetSessionTimeout() error { return spannerErrorf(codes.Canceled, "timeout / context canceled during getting session") } // shouldPrepareWriteLocked returns true if we should prepare more sessions for write. func (p *sessionPool) shouldPrepareWriteLocked() bool { return !p.disableBackgroundPrepareSessions && float64(p.numOpened)*p.WriteSessions > float64(p.idleWriteList.Len()+int(p.prepareReqs)) } func (p *sessionPool) createSession(ctx context.Context) (*session, error) { trace.TracePrintf(ctx, nil, "Creating a new session") doneCreate := func(done bool) { p.mu.Lock() if !done { // Session creation failed, give budget back. p.numOpened-- recordStat(ctx, OpenSessionCount, int64(p.numOpened)) } p.createReqs-- // Notify other waiters blocking on session creation. close(p.mayGetSession) p.mayGetSession = make(chan struct{}) p.mu.Unlock() } s, err := p.sc.createSession(ctx) if err != nil { doneCreate(false) // Should return error directly because of the previous retries on // CreateSession RPC. // If the error is a timeout, there is a chance that the session was // created on the server but is not known to the session pool. This // session will then be garbage collected by the server after 1 hour. return nil, err } s.pool = p p.hc.register(s) doneCreate(true) return s, nil } func (p *sessionPool) isHealthy(s *session) bool { if s.getNextCheck().Add(2 * p.hc.getInterval()).Before(time.Now()) { // TODO: figure out if we need to schedule a new healthcheck worker here. if err := s.ping(); shouldDropSession(err) { // The session is already bad, continue to fetch/create a new one. s.destroy(false) return false } p.hc.scheduledHC(s) } return true } // take returns a cached session if there are available ones; if there isn't // any, it tries to allocate a new one. Session returned by take should be used // for read operations. func (p *sessionPool) take(ctx context.Context) (*sessionHandle, error) { trace.TracePrintf(ctx, nil, "Acquiring a read-only session") for { var ( s *session err error ) p.mu.Lock() if !p.valid { p.mu.Unlock() return nil, errInvalidSessionPool() } if p.idleList.Len() > 0 { // Idle sessions are available, get one from the top of the idle // list. s = p.idleList.Remove(p.idleList.Front()).(*session) trace.TracePrintf(ctx, map[string]interface{}{"sessionID": s.getID()}, "Acquired read-only session") } else if p.idleWriteList.Len() > 0 { s = p.idleWriteList.Remove(p.idleWriteList.Front()).(*session) trace.TracePrintf(ctx, map[string]interface{}{"sessionID": s.getID()}, "Acquired read-write session") } if s != nil { s.setIdleList(nil) numCheckedOut := p.currSessionsCheckedOutLocked() p.mu.Unlock() p.mw.updateMaxSessionsCheckedOutDuringWindow(numCheckedOut) // From here, session is no longer in idle list, so healthcheck // workers won't destroy it. If healthcheck workers failed to // schedule healthcheck for the session timely, do the check here. // Because session check is still much cheaper than session // creation, they should be reused as much as possible. if !p.isHealthy(s) { continue } return &sessionHandle{session: s}, nil } // Idle list is empty, block if session pool has reached max session // creation concurrency or max number of open sessions. if (p.MaxOpened > 0 && p.numOpened >= p.MaxOpened) || (p.MaxBurst > 0 && p.createReqs >= p.MaxBurst) { mayGetSession := p.mayGetSession p.mu.Unlock() trace.TracePrintf(ctx, nil, "Waiting for read-only session to become available") select { case <-ctx.Done(): trace.TracePrintf(ctx, nil, "Context done waiting for session") return nil, errGetSessionTimeout() case <-mayGetSession: } continue } // Take budget before the actual session creation. p.numOpened++ // Creating a new session that will be returned directly to the client // means that the max number of sessions in use also increases. numCheckedOut := p.currSessionsCheckedOutLocked() recordStat(ctx, OpenSessionCount, int64(p.numOpened)) p.createReqs++ p.mu.Unlock() p.mw.updateMaxSessionsCheckedOutDuringWindow(numCheckedOut) if s, err = p.createSession(ctx); err != nil { trace.TracePrintf(ctx, nil, "Error creating session: %v", err) return nil, toSpannerError(err) } trace.TracePrintf(ctx, map[string]interface{}{"sessionID": s.getID()}, "Created session") return &sessionHandle{session: s}, nil } } // takeWriteSession returns a write prepared cached session if there are // available ones; if there isn't any, it tries to allocate a new one. Session // returned should be used for read write transactions. func (p *sessionPool) takeWriteSession(ctx context.Context) (*sessionHandle, error) { trace.TracePrintf(ctx, nil, "Acquiring a read-write session") for { var ( s *session err error ) p.mu.Lock() if !p.valid { p.mu.Unlock() return nil, errInvalidSessionPool() } if p.idleWriteList.Len() > 0 { // Idle sessions are available, get one from the top of the idle // list. s = p.idleWriteList.Remove(p.idleWriteList.Front()).(*session) trace.TracePrintf(ctx, map[string]interface{}{"sessionID": s.getID()}, "Acquired read-write session") } else if p.idleList.Len() > 0 { s = p.idleList.Remove(p.idleList.Front()).(*session) trace.TracePrintf(ctx, map[string]interface{}{"sessionID": s.getID()}, "Acquired read-only session") } if s != nil { s.setIdleList(nil) numCheckedOut := p.currSessionsCheckedOutLocked() p.mu.Unlock() p.mw.updateMaxSessionsCheckedOutDuringWindow(numCheckedOut) // From here, session is no longer in idle list, so healthcheck // workers won't destroy it. If healthcheck workers failed to // schedule healthcheck for the session timely, do the check here. // Because session check is still much cheaper than session // creation, they should be reused as much as possible. if !p.isHealthy(s) { continue } } else { // Idle list is empty, block if session pool has reached max session // creation concurrency or max number of open sessions. if (p.MaxOpened > 0 && p.numOpened >= p.MaxOpened) || (p.MaxBurst > 0 && p.createReqs >= p.MaxBurst) { mayGetSession := p.mayGetSession p.mu.Unlock() trace.TracePrintf(ctx, nil, "Waiting for read-write session to become available") select { case <-ctx.Done(): trace.TracePrintf(ctx, nil, "Context done waiting for session") return nil, errGetSessionTimeout() case <-mayGetSession: } continue } // Take budget before the actual session creation. p.numOpened++ // Creating a new session that will be returned directly to the client // means that the max number of sessions in use also increases. numCheckedOut := p.currSessionsCheckedOutLocked() recordStat(ctx, OpenSessionCount, int64(p.numOpened)) p.createReqs++ p.mu.Unlock() p.mw.updateMaxSessionsCheckedOutDuringWindow(numCheckedOut) if s, err = p.createSession(ctx); err != nil { trace.TracePrintf(ctx, nil, "Error creating session: %v", err) return nil, toSpannerError(err) } trace.TracePrintf(ctx, map[string]interface{}{"sessionID": s.getID()}, "Created session") } if !s.isWritePrepared() { if err = s.prepareForWrite(ctx); err != nil { s.recycle() trace.TracePrintf(ctx, map[string]interface{}{"sessionID": s.getID()}, "Error preparing session for write") return nil, toSpannerError(err) } } return &sessionHandle{session: s}, nil } } // recycle puts session s back to the session pool's idle list, it returns true // if the session pool successfully recycles session s. func (p *sessionPool) recycle(s *session) bool { p.mu.Lock() defer p.mu.Unlock() if !s.isValid() || !p.valid { // Reject the session if session is invalid or pool itself is invalid. return false } // Put session at the back of the list to round robin for load balancing // across channels. if s.isWritePrepared() { s.setIdleList(p.idleWriteList.PushBack(s)) } else { s.setIdleList(p.idleList.PushBack(s)) } // Broadcast that a session has been returned to idle list. close(p.mayGetSession) p.mayGetSession = make(chan struct{}) return true } // remove atomically removes session s from the session pool and invalidates s. // If isExpire == true, the removal is triggered by session expiration and in // such cases, only idle sessions can be removed. func (p *sessionPool) remove(s *session, isExpire bool) bool { p.mu.Lock() defer p.mu.Unlock() if isExpire && (p.numOpened <= p.MinOpened || s.getIdleList() == nil) { // Don't expire session if the session is not in idle list (in use), or // if number of open sessions is going below p.MinOpened. return false } ol := s.setIdleList(nil) // If the session is in the idlelist, remove it. if ol != nil { // Remove from whichever list it is in. p.idleList.Remove(ol) p.idleWriteList.Remove(ol) } if s.invalidate() { // Decrease the number of opened sessions. p.numOpened-- recordStat(context.Background(), OpenSessionCount, int64(p.numOpened)) // Broadcast that a session has been destroyed. close(p.mayGetSession) p.mayGetSession = make(chan struct{}) return true } return false } func (p *sessionPool) currSessionsCheckedOutLocked() uint64 { return p.numOpened - uint64(p.idleList.Len()) - uint64(p.idleWriteList.Len()) } // hcHeap implements heap.Interface. It is used to create the priority queue for // session healthchecks. type hcHeap struct { sessions []*session } // Len implements heap.Interface.Len. func (h hcHeap) Len() int { return len(h.sessions) } // Less implements heap.Interface.Less. func (h hcHeap) Less(i, j int) bool { return h.sessions[i].getNextCheck().Before(h.sessions[j].getNextCheck()) } // Swap implements heap.Interface.Swap. func (h hcHeap) Swap(i, j int) { h.sessions[i], h.sessions[j] = h.sessions[j], h.sessions[i] h.sessions[i].setHcIndex(i) h.sessions[j].setHcIndex(j) } // Push implements heap.Interface.Push. func (h *hcHeap) Push(s interface{}) { ns := s.(*session) ns.setHcIndex(len(h.sessions)) h.sessions = append(h.sessions, ns) } // Pop implements heap.Interface.Pop. func (h *hcHeap) Pop() interface{} { old := h.sessions n := len(old) s := old[n-1] h.sessions = old[:n-1] s.setHcIndex(-1) return s } // maintenanceWindowSize specifies the number of health check cycles that // defines a maintenance window. The maintenance window keeps track of a // rolling set of numbers for the number of maximum checked out sessions during // the maintenance window. This is used by the maintainer to determine the // number of sessions to create or delete at the end of each health check // cycle. const maintenanceWindowSize = 10 // maintenanceWindow contains the statistics that are gathered during a health // check maintenance window. type maintenanceWindow struct { mu sync.Mutex // maxSessionsCheckedOut contains the maximum number of sessions that was // checked out of the session pool during a health check cycle. This number // indicates the number of sessions that was actually needed by the pool to // serve the load during that cycle. The values are kept as a rolling set // containing the values for the past 10 cycles (minutes). The maintainer // uses these values to determine the number of sessions to keep at the end // of each cycle. maxSessionsCheckedOut [maintenanceWindowSize]uint64 } // maxSessionsCheckedOutDuringWindow returns the maximum number of sessions // that has been checked out during the last maintenance window of 10 cycles // (minutes). func (mw *maintenanceWindow) maxSessionsCheckedOutDuringWindow() uint64 { mw.mu.Lock() defer mw.mu.Unlock() var max uint64 for _, cycleMax := range mw.maxSessionsCheckedOut { max = maxUint64(max, cycleMax) } return max } // updateMaxSessionsCheckedOutDuringWindow updates the maximum number of // sessions that has been checked out of the pool during the current // cycle of the maintenance window. A maintenance window consists of 10 // maintenance cycles. Each cycle keeps track of the max number of sessions in // use during that cycle. The rolling maintenance window of 10 cycles is used // to determine the number of sessions to keep at the end of a cycle by // calculating the max in use during the last 10 cycles. func (mw *maintenanceWindow) updateMaxSessionsCheckedOutDuringWindow(currNumSessionsCheckedOut uint64) { mw.mu.Lock() defer mw.mu.Unlock() mw.maxSessionsCheckedOut[0] = maxUint64(currNumSessionsCheckedOut, mw.maxSessionsCheckedOut[0]) } // startNewCycle starts a new health check cycle with the specified number of // checked out sessions as its initial value. func (mw *maintenanceWindow) startNewCycle(currNumSessionsCheckedOut uint64) { mw.mu.Lock() defer mw.mu.Unlock() copy(mw.maxSessionsCheckedOut[1:], mw.maxSessionsCheckedOut[:9]) mw.maxSessionsCheckedOut[0] = currNumSessionsCheckedOut } // newMaintenanceWindow creates a new maintenance window with all values for // maxSessionsCheckedOut set to maxOpened. This ensures that a complete // maintenance window must pass before the maintainer will start to delete any // sessions. func newMaintenanceWindow(maxOpened uint64) *maintenanceWindow { mw := &maintenanceWindow{} // Initialize the rolling window with max values to prevent the maintainer // from deleting sessions before a complete window of 10 cycles has // finished. for i := 0; i < maintenanceWindowSize; i++ { mw.maxSessionsCheckedOut[i] = maxOpened } return mw } // healthChecker performs periodical healthchecks on registered sessions. type healthChecker struct { // mu protects concurrent access to healthChecker. mu sync.Mutex // queue is the priority queue for session healthchecks. Sessions with lower // nextCheck rank higher in the queue. queue hcHeap // interval is the average interval between two healthchecks on a session. interval time.Duration // workers is the number of concurrent healthcheck workers. workers int // waitWorkers waits for all healthcheck workers to exit waitWorkers sync.WaitGroup // pool is the underlying session pool. pool *sessionPool // sampleInterval is the interval of sampling by the maintainer. sampleInterval time.Duration // ready is used to signal that maintainer can start running. ready chan struct{} // done is used to signal that health checker should be closed. done chan struct{} // once is used for closing channel done only once. once sync.Once maintainerCancel func() } // newHealthChecker initializes new instance of healthChecker. func newHealthChecker(interval time.Duration, workers int, sampleInterval time.Duration, pool *sessionPool) *healthChecker { if workers <= 0 { workers = 1 } hc := &healthChecker{ interval: interval, workers: workers, pool: pool, sampleInterval: sampleInterval, ready: make(chan struct{}), done: make(chan struct{}), maintainerCancel: func() {}, } hc.waitWorkers.Add(1) go hc.maintainer() for i := 1; i <= hc.workers; i++ { hc.waitWorkers.Add(1) go hc.worker(i) } return hc } // close closes the healthChecker and waits for all healthcheck workers to exit. func (hc *healthChecker) close() { hc.mu.Lock() hc.maintainerCancel() hc.mu.Unlock() hc.once.Do(func() { close(hc.done) }) hc.waitWorkers.Wait() } // isClosing checks if a healthChecker is already closing. func (hc *healthChecker) isClosing() bool { select { case <-hc.done: return true default: return false } } // getInterval gets the healthcheck interval. func (hc *healthChecker) getInterval() time.Duration { hc.mu.Lock() defer hc.mu.Unlock() return hc.interval } // scheduledHCLocked schedules next healthcheck on session s with the assumption // that hc.mu is being held. func (hc *healthChecker) scheduledHCLocked(s *session) { // The next healthcheck will be scheduled after // [interval*0.5, interval*1.5) ns. nsFromNow := rand.Int63n(int64(hc.interval)) + int64(hc.interval)/2 s.setNextCheck(time.Now().Add(time.Duration(nsFromNow))) if hi := s.getHcIndex(); hi != -1 { // Session is still being tracked by healthcheck workers. heap.Fix(&hc.queue, hi) } } // scheduledHC schedules next healthcheck on session s. It is safe to be called // concurrently. func (hc *healthChecker) scheduledHC(s *session) { hc.mu.Lock() defer hc.mu.Unlock() hc.scheduledHCLocked(s) } // register registers a session with healthChecker for periodical healthcheck. func (hc *healthChecker) register(s *session) { hc.mu.Lock() defer hc.mu.Unlock() hc.scheduledHCLocked(s) heap.Push(&hc.queue, s) } // unregister unregisters a session from healthcheck queue. func (hc *healthChecker) unregister(s *session) { hc.mu.Lock() defer hc.mu.Unlock() oi := s.setHcIndex(-1) if oi >= 0 { heap.Remove(&hc.queue, oi) } } // markDone marks that health check for session has been performed. func (hc *healthChecker) markDone(s *session) { hc.mu.Lock() defer hc.mu.Unlock() s.checkingHealth = false } // healthCheck checks the health of the session and pings it if needed. func (hc *healthChecker) healthCheck(s *session) { defer hc.markDone(s) if !s.pool.isValid() { // Session pool is closed, perform a garbage collection. s.destroy(false) return } if err := s.ping(); shouldDropSession(err) { // Ping failed, destroy the session. s.destroy(false) } } // worker performs the healthcheck on sessions in healthChecker's priority // queue. func (hc *healthChecker) worker(i int) { // Returns a session which we should ping to keep it alive. getNextForPing := func() *session { hc.pool.mu.Lock() defer hc.pool.mu.Unlock() hc.mu.Lock() defer hc.mu.Unlock() if hc.queue.Len() <= 0 { // Queue is empty. return nil } s := hc.queue.sessions[0] if s.getNextCheck().After(time.Now()) && hc.pool.valid { // All sessions have been checked recently. return nil } hc.scheduledHCLocked(s) if !s.checkingHealth { s.checkingHealth = true return s } return nil } // Returns a session which we should prepare for write. getNextForTx := func() *session { hc.pool.mu.Lock() defer hc.pool.mu.Unlock() if hc.pool.shouldPrepareWriteLocked() { if hc.pool.idleList.Len() > 0 && hc.pool.valid { hc.mu.Lock() defer hc.mu.Unlock() if hc.pool.idleList.Front().Value.(*session).checkingHealth { return nil } session := hc.pool.idleList.Remove(hc.pool.idleList.Front()).(*session) session.checkingHealth = true hc.pool.prepareReqs++ return session } } return nil } for { if hc.isClosing() { // Exit when the pool has been closed and all sessions have been // destroyed or when health checker has been closed. hc.waitWorkers.Done() return } ws := getNextForTx() if ws != nil { ctx, cancel := context.WithTimeout(context.Background(), time.Second) err := ws.prepareForWrite(ctx) cancel() if err != nil { // Skip handling prepare error, session can be prepared in next // cycle. log.Printf("Failed to prepare session, error: %v", toSpannerError(err)) } hc.pool.recycle(ws) hc.pool.mu.Lock() hc.pool.prepareReqs-- hc.pool.mu.Unlock() hc.markDone(ws) } rs := getNextForPing() if rs == nil { if ws == nil { // No work to be done so sleep to avoid burning CPU. pause := int64(100 * time.Millisecond) if pause > int64(hc.interval) { pause = int64(hc.interval) } select { case <-time.After(time.Duration(rand.Int63n(pause) + pause/2)): case <-hc.done: } } continue } hc.healthCheck(rs) } } // maintainer maintains the number of sessions in the pool based on the session // pool configuration and the current and historical number of sessions checked // out of the pool. The maintainer will: // 1. Ensure that the session pool contains at least MinOpened sessions. // 2. If the current number of sessions in the pool exceeds the greatest number // of checked out sessions (=sessions in use) during the last 10 minutes, // and the delta is larger than MaxIdleSessions, the maintainer will reduce // the number of sessions to maxSessionsInUseDuringWindow+MaxIdleSessions. func (hc *healthChecker) maintainer() { // Wait until the pool is ready. <-hc.ready for iteration := uint64(0); ; iteration++ { if hc.isClosing() { hc.waitWorkers.Done() return } hc.pool.mu.Lock() currSessionsOpened := hc.pool.numOpened maxIdle := hc.pool.MaxIdle minOpened := hc.pool.MinOpened hc.pool.mu.Unlock() // Get the maximum number of sessions in use during the current // maintenance window. maxSessionsInUseDuringWindow := hc.pool.mw.maxSessionsCheckedOutDuringWindow() hc.mu.Lock() ctx, cancel := context.WithTimeout(context.Background(), hc.sampleInterval) hc.maintainerCancel = cancel hc.mu.Unlock() // Grow or shrink pool if needed. // The number of sessions in the pool should be in the range // [Config.MinOpened, Config.MaxIdle+maxSessionsInUseDuringWindow] if currSessionsOpened < minOpened { hc.growPool(ctx, minOpened) } else if maxIdle+maxSessionsInUseDuringWindow < currSessionsOpened { hc.shrinkPool(ctx, maxIdle+maxSessionsInUseDuringWindow) } select { case <-ctx.Done(): case <-hc.done: cancel() } // Cycle the maintenance window. This will remove the oldest cycle and // add a new cycle at the beginning of the maintenance window with the // currently checked out number of sessions as the max number of // sessions in use in this cycle. This value will be increased during // the next cycle if it increases. hc.pool.mu.Lock() currSessionsInUse := hc.pool.currSessionsCheckedOutLocked() hc.pool.mu.Unlock() hc.pool.mw.startNewCycle(currSessionsInUse) } } // growPool grows the number of sessions in the pool to the specified number of // sessions. It timeouts on sampleInterval. func (hc *healthChecker) growPool(ctx context.Context, growToNumSessions uint64) { // Calculate the max number of sessions to create as a safeguard against // other processes that could be deleting sessions concurrently. hc.pool.mu.Lock() maxSessionsToCreate := int(growToNumSessions - hc.pool.numOpened) hc.pool.mu.Unlock() var created int for { if ctx.Err() != nil { return } p := hc.pool p.mu.Lock() // Take budget before the actual session creation. if growToNumSessions <= p.numOpened || created >= maxSessionsToCreate { p.mu.Unlock() break } p.numOpened++ recordStat(ctx, OpenSessionCount, int64(p.numOpened)) p.createReqs++ shouldPrepareWrite := p.shouldPrepareWriteLocked() p.mu.Unlock() var ( s *session err error ) createContext, cancel := context.WithTimeout(context.Background(), time.Minute) if s, err = p.createSession(createContext); err != nil { cancel() log.Printf("Failed to create session, error: %v", toSpannerError(err)) continue } cancel() created++ if shouldPrepareWrite { prepareContext, cancel := context.WithTimeout(context.Background(), time.Minute) if err = s.prepareForWrite(prepareContext); err != nil { cancel() p.recycle(s) log.Printf("Failed to prepare session, error: %v", toSpannerError(err)) continue } cancel() } p.recycle(s) } } // shrinkPool scales down the session pool. The method will stop deleting // sessions when shrinkToNumSessions number of sessions in the pool has // been reached. The method will also stop deleting sessions if it detects that // another process has started creating sessions for the pool again, for // example through the take() method. func (hc *healthChecker) shrinkPool(ctx context.Context, shrinkToNumSessions uint64) { hc.pool.mu.Lock() maxSessionsToDelete := int(hc.pool.numOpened - shrinkToNumSessions) hc.pool.mu.Unlock() var deleted int var prevNumOpened uint64 = math.MaxUint64 for { if ctx.Err() != nil { return } p := hc.pool p.mu.Lock() // Check if the number of open sessions has increased. If it has, we // should stop deleting sessions, as the load has increased and // additional sessions are needed. if p.numOpened >= prevNumOpened { p.mu.Unlock() break } prevNumOpened = p.numOpened // Check on both whether we have reached the number of open sessions as // well as the number of sessions to delete, in case sessions have been // deleted by other methods because they have expired or deemed // invalid. if shrinkToNumSessions >= p.numOpened || deleted >= maxSessionsToDelete { p.mu.Unlock() break } var s *session if p.idleList.Len() > 0 { s = p.idleList.Front().Value.(*session) } else if p.idleWriteList.Len() > 0 { s = p.idleWriteList.Front().Value.(*session) } p.mu.Unlock() if s != nil { deleted++ // destroy session as expire. s.destroy(true) } else { break } } } // shouldDropSession returns true if a particular error leads to the removal of // a session func shouldDropSession(err error) bool { if err == nil { return false } // If a Cloud Spanner can no longer locate the session (for example, if // session is garbage collected), then caller should not try to return the // session back into the session pool. // // TODO: once gRPC can return auxiliary error information, stop parsing the error message. if ErrCode(err) == codes.NotFound && strings.Contains(ErrDesc(err), "Session not found") { return true } return false } // maxUint64 returns the maximum of two uint64. func maxUint64(a, b uint64) uint64 { if a > b { return a } return b } // minUint64 returns the minimum of two uint64. func minUint64(a, b uint64) uint64 { if a > b { return b } return a } // isPermissionDeniedError returns true if the given error has code // PermissionDenied. func isPermissionDeniedError(err error) bool { return ErrCode(err) == codes.PermissionDenied } // isDatabaseNotFoundError returns true if the given error is a // `Database not found` error. func isDatabaseNotFoundError(err error) bool { // We are checking specifically for the error message `Database not found`, // as the error could also be a `Session not found`. The former should // cause the session pool to stop preparing sessions for read/write // transactions, while the latter should not. return ErrCode(err) == codes.NotFound && strings.Contains(err.Error(), "Database not found") } google-cloud-go-0.49.0/spanner/session_test.go000066400000000000000000001351331356504100700213150ustar00rootroot00000000000000/* Copyright 2017 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spanner import ( "bytes" "container/heap" "context" "fmt" "math/rand" "testing" "time" . "cloud.google.com/go/spanner/internal/testutil" sppb "google.golang.org/genproto/googleapis/spanner/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) // TestSessionPoolConfigValidation tests session pool config validation. func TestSessionPoolConfigValidation(t *testing.T) { t.Parallel() _, client, teardown := setupMockedTestServer(t) defer teardown() for _, test := range []struct { spc SessionPoolConfig err error }{ { SessionPoolConfig{ MinOpened: 10, MaxOpened: 5, }, errMinOpenedGTMaxOpened(5, 10), }, { SessionPoolConfig{ WriteSessions: -0.1, }, errWriteFractionOutOfRange(-0.1), }, { SessionPoolConfig{ WriteSessions: 2.0, }, errWriteFractionOutOfRange(2.0), }, { SessionPoolConfig{ HealthCheckWorkers: -1, }, errHealthCheckWorkersNegative(-1), }, { SessionPoolConfig{ HealthCheckInterval: -time.Second, }, errHealthCheckIntervalNegative(-time.Second), }, } { if _, err := newSessionPool(client.sc, test.spc); !testEqual(err, test.err) { t.Fatalf("want %v, got %v", test.err, err) } } } // TestSessionCreation tests session creation during sessionPool.Take(). func TestSessionCreation(t *testing.T) { t.Parallel() ctx := context.Background() server, client, teardown := setupMockedTestServer(t) defer teardown() sp := client.idleSessions // Take three sessions from session pool, this should trigger session pool // to create three new sessions. shs := make([]*sessionHandle, 3) // gotDs holds the unique sessions taken from session pool. gotDs := map[string]bool{} for i := 0; i < len(shs); i++ { var err error shs[i], err = sp.take(ctx) if err != nil { t.Fatalf("failed to get session(%v): %v", i, err) } gotDs[shs[i].getID()] = true } if len(gotDs) != len(shs) { t.Fatalf("session pool created %v sessions, want %v", len(gotDs), len(shs)) } if wantDs := server.TestSpanner.DumpSessions(); !testEqual(gotDs, wantDs) { t.Fatalf("session pool creates sessions %v, want %v", gotDs, wantDs) } // Verify that created sessions are recorded correctly in session pool. sp.mu.Lock() if int(sp.numOpened) != len(shs) { t.Fatalf("session pool reports %v open sessions, want %v", sp.numOpened, len(shs)) } if sp.createReqs != 0 { t.Fatalf("session pool reports %v session create requests, want 0", int(sp.createReqs)) } sp.mu.Unlock() // Verify that created sessions are tracked correctly by healthcheck queue. hc := sp.hc hc.mu.Lock() if hc.queue.Len() != len(shs) { t.Fatalf("healthcheck queue length = %v, want %v", hc.queue.Len(), len(shs)) } for _, s := range hc.queue.sessions { if !gotDs[s.getID()] { t.Fatalf("session %v is in healthcheck queue, but it is not created by session pool", s.getID()) } } hc.mu.Unlock() } // TestTakeFromIdleList tests taking sessions from session pool's idle list. func TestTakeFromIdleList(t *testing.T) { t.Parallel() ctx := context.Background() // Make sure maintainer keeps the idle sessions. server, client, teardown := setupMockedTestServerWithConfig(t, ClientConfig{ SessionPoolConfig: SessionPoolConfig{MaxIdle: 10}, }) defer teardown() sp := client.idleSessions // Take ten sessions from session pool and recycle them. shs := make([]*sessionHandle, 10) for i := 0; i < len(shs); i++ { var err error shs[i], err = sp.take(ctx) if err != nil { t.Fatalf("failed to get session(%v): %v", i, err) } } // Make sure it's sampled once before recycling, otherwise it will be // cleaned up. <-time.After(sp.SessionPoolConfig.healthCheckSampleInterval) for i := 0; i < len(shs); i++ { shs[i].recycle() } // Further session requests from session pool won't cause mockclient to // create more sessions. wantSessions := server.TestSpanner.DumpSessions() // Take ten sessions from session pool again, this time all sessions should // come from idle list. gotSessions := map[string]bool{} for i := 0; i < len(shs); i++ { sh, err := sp.take(ctx) if err != nil { t.Fatalf("cannot take session from session pool: %v", err) } gotSessions[sh.getID()] = true } if len(gotSessions) != 10 { t.Fatalf("got %v unique sessions, want 10", len(gotSessions)) } if !testEqual(gotSessions, wantSessions) { t.Fatalf("got sessions: %v, want %v", gotSessions, wantSessions) } } // TesttakeWriteSessionFromIdleList tests taking write sessions from session // pool's idle list. func TestTakeWriteSessionFromIdleList(t *testing.T) { t.Parallel() ctx := context.Background() // Make sure maintainer keeps the idle sessions. server, client, teardown := setupMockedTestServerWithConfig(t, ClientConfig{ SessionPoolConfig: SessionPoolConfig{MaxIdle: 20}, }) defer teardown() sp := client.idleSessions // Take ten sessions from session pool and recycle them. shs := make([]*sessionHandle, 10) for i := 0; i < len(shs); i++ { var err error shs[i], err = sp.takeWriteSession(ctx) if err != nil { t.Fatalf("failed to get session(%v): %v", i, err) } } // Make sure it's sampled once before recycling, otherwise it will be // cleaned up. <-time.After(sp.SessionPoolConfig.healthCheckSampleInterval) for i := 0; i < len(shs); i++ { shs[i].recycle() } // Further session requests from session pool won't cause mockclient to // create more sessions. wantSessions := server.TestSpanner.DumpSessions() // Take ten sessions from session pool again, this time all sessions should // come from idle list. gotSessions := map[string]bool{} for i := 0; i < len(shs); i++ { sh, err := sp.takeWriteSession(ctx) if err != nil { t.Fatalf("cannot take session from session pool: %v", err) } gotSessions[sh.getID()] = true } if len(gotSessions) != 10 { t.Fatalf("got %v unique sessions, want 10", len(gotSessions)) } if !testEqual(gotSessions, wantSessions) { t.Fatalf("got sessions: %v, want %v", gotSessions, wantSessions) } } // TestTakeFromIdleListChecked tests taking sessions from session pool's idle // list, but with a extra ping check. func TestTakeFromIdleListChecked(t *testing.T) { t.Parallel() ctx := context.Background() // Make sure maintainer keeps the idle sessions. server, client, teardown := setupMockedTestServerWithConfig(t, ClientConfig{ SessionPoolConfig: SessionPoolConfig{ MaxIdle: 1, HealthCheckInterval: 50 * time.Millisecond, healthCheckSampleInterval: 10 * time.Millisecond, }, }) defer teardown() sp := client.idleSessions // Stop healthcheck workers to simulate slow pings. sp.hc.close() // Create a session and recycle it. sh, err := sp.take(ctx) if err != nil { t.Fatalf("failed to get session: %v", err) } // Force ping during the first take() by setting check time to the past. sh.session.nextCheck = time.Now().Add(-time.Minute) wantSid := sh.getID() sh.recycle() // Two back-to-back session requests, both of them should return the same // session created before, but only the first of them should trigger a session ping. for i := 0; i < 2; i++ { // Take the session from the idle list and recycle it. sh, err = sp.take(ctx) if err != nil { t.Fatalf("%v - failed to get session: %v", i, err) } if gotSid := sh.getID(); gotSid != wantSid { t.Fatalf("%v - got session id: %v, want %v", i, gotSid, wantSid) } // The two back-to-back session requests shouldn't trigger any session // pings because sessionPool.Take reschedules the next healthcheck. if got, want := server.TestSpanner.DumpPings(), ([]string{wantSid}); !testEqual(got, want) { t.Fatalf("%v - got ping session requests: %v, want %v", i, got, want) } sh.recycle() } // Inject session error to server stub, and take the session from the // session pool, the old session should be destroyed and the session pool // will create a new session. server.TestSpanner.PutExecutionTime(MethodGetSession, SimulatedExecutionTime{ Errors: []error{status.Errorf(codes.NotFound, "Session not found")}, }) // Force ping by setting check time in the past. s := sp.idleList.Front().Value.(*session) s.nextCheck = time.Now().Add(-time.Minute) // take will take the idle session. Then it will send a GetSession request // to check if it's healthy. It'll discover that it's not healthy // (NotFound), drop it, and create a new session. sh, err = sp.take(ctx) if err != nil { t.Fatalf("failed to get session: %v", err) } ds := server.TestSpanner.DumpSessions() if len(ds) != 1 { t.Fatalf("dumped sessions from mockclient: %v, want %v", ds, sh.getID()) } if sh.getID() == wantSid { t.Fatalf("sessionPool.Take still returns the same session %v, want it to create a new one", wantSid) } } // TestTakeFromIdleWriteListChecked tests taking sessions from session pool's // idle list, but with a extra ping check. func TestTakeFromIdleWriteListChecked(t *testing.T) { t.Parallel() ctx := context.Background() // Make sure maintainer keeps the idle sessions. server, client, teardown := setupMockedTestServerWithConfig(t, ClientConfig{ SessionPoolConfig: SessionPoolConfig{ MaxIdle: 1, HealthCheckInterval: 50 * time.Millisecond, healthCheckSampleInterval: 10 * time.Millisecond, }, }) defer teardown() sp := client.idleSessions // Stop healthcheck workers to simulate slow pings. sp.hc.close() // Create a session and recycle it. sh, err := sp.takeWriteSession(ctx) if err != nil { t.Fatalf("failed to get session: %v", err) } wantSid := sh.getID() // Set the next check in the past to ensure the next take() call will // trigger a health check. sh.session.nextCheck = time.Now().Add(-time.Minute) sh.recycle() // Two back-to-back session requests, both of them should return the same // session created before and only the first of them should trigger a // session ping. for i := 0; i < 2; i++ { // Take the session from the idle list and recycle it. sh, err = sp.takeWriteSession(ctx) if err != nil { t.Fatalf("%v - failed to get session: %v", i, err) } if gotSid := sh.getID(); gotSid != wantSid { t.Fatalf("%v - got session id: %v, want %v", i, gotSid, wantSid) } // The two back-to-back session requests shouldn't trigger any session // pings because sessionPool.Take reschedules the next healthcheck. if got, want := server.TestSpanner.DumpPings(), ([]string{wantSid}); !testEqual(got, want) { t.Fatalf("%v - got ping session requests: %v, want %v", i, got, want) } sh.recycle() } // Inject session error to mockclient, and take the session from the // session pool, the old session should be destroyed and the session pool // will create a new session. server.TestSpanner.PutExecutionTime(MethodGetSession, SimulatedExecutionTime{ Errors: []error{status.Errorf(codes.NotFound, "Session not found")}, }) // Force ping by setting check time in the past. s := sp.idleList.Front().Value.(*session) s.nextCheck = time.Now().Add(-time.Minute) sh, err = sp.takeWriteSession(ctx) if err != nil { t.Fatalf("failed to get session: %v", err) } ds := server.TestSpanner.DumpSessions() if len(ds) != 1 { t.Fatalf("dumped sessions from mockclient: %v, want %v", ds, sh.getID()) } if sh.getID() == wantSid { t.Fatalf("sessionPool.Take still returns the same session %v, want it to create a new one", wantSid) } } // TestMaxOpenedSessions tests max open sessions constraint. func TestMaxOpenedSessions(t *testing.T) { t.Parallel() ctx := context.Background() _, client, teardown := setupMockedTestServerWithConfig(t, ClientConfig{ SessionPoolConfig: SessionPoolConfig{ MaxOpened: 1, }, }) defer teardown() sp := client.idleSessions sh1, err := sp.take(ctx) if err != nil { t.Fatalf("cannot take session from session pool: %v", err) } // Session request will timeout due to the max open sessions constraint. ctx2, cancel := context.WithTimeout(ctx, 10*time.Millisecond) defer cancel() _, gotErr := sp.take(ctx2) if wantErr := errGetSessionTimeout(); !testEqual(gotErr, wantErr) { t.Fatalf("the second session retrival returns error %v, want %v", gotErr, wantErr) } doneWaiting := make(chan struct{}) go func() { // Destroy the first session to allow the next session request to // proceed. <-doneWaiting sh1.destroy() }() go func() { // Wait a short random time before destroying the session handle. <-time.After(10 * time.Millisecond) close(doneWaiting) }() // Now session request can be processed because the first session will be // destroyed. ctx3, cancel := context.WithTimeout(ctx, time.Second) defer cancel() sh2, err := sp.take(ctx3) if err != nil { t.Fatalf("after the first session is destroyed, session retrival still returns error %v, want nil", err) } if !sh2.session.isValid() || sh2.getID() == "" { t.Fatalf("got invalid session: %v", sh2.session) } } // TestMinOpenedSessions tests min open session constraint. func TestMinOpenedSessions(t *testing.T) { t.Parallel() ctx := context.Background() _, client, teardown := setupMockedTestServerWithConfig(t, ClientConfig{ SessionPoolConfig: SessionPoolConfig{ MinOpened: 1, healthCheckSampleInterval: time.Millisecond, }, }) defer teardown() sp := client.idleSessions // Take ten sessions from session pool and recycle them. var ss []*session var shs []*sessionHandle for i := 0; i < 10; i++ { sh, err := sp.take(ctx) if err != nil { t.Fatalf("failed to get session(%v): %v", i, err) } ss = append(ss, sh.session) shs = append(shs, sh) sh.recycle() } for _, sh := range shs { sh.recycle() } // Simulate session expiration. for _, s := range ss { s.destroy(true) } // Wait until the maintainer has had a chance to replenish the pool. for i := 0; i < 10; i++ { sp.mu.Lock() if sp.numOpened > 0 { sp.mu.Unlock() break } sp.mu.Unlock() <-time.After(sp.healthCheckSampleInterval) } sp.mu.Lock() defer sp.mu.Unlock() // There should be still one session left in either the idle list or in one // of the other opened states due to the min open sessions constraint. if (sp.idleList.Len() + sp.idleWriteList.Len() + int(sp.prepareReqs) + int(sp.createReqs)) != 1 { t.Fatalf( "got %v sessions in idle lists, want 1. Opened: %d, read: %d, "+ "write: %d, in preparation: %d, in creation: %d", sp.idleList.Len()+sp.idleWriteList.Len(), sp.numOpened, sp.idleList.Len(), sp.idleWriteList.Len(), sp.prepareReqs, sp.createReqs) } } // TestMaxBurst tests max burst constraint. func TestMaxBurst(t *testing.T) { t.Parallel() ctx := context.Background() server, client, teardown := setupMockedTestServerWithConfig(t, ClientConfig{ SessionPoolConfig: SessionPoolConfig{ MaxBurst: 1, }, }) defer teardown() sp := client.idleSessions // Will cause session creation RPC to be retried forever. server.TestSpanner.PutExecutionTime(MethodCreateSession, SimulatedExecutionTime{ Errors: []error{status.Errorf(codes.Unavailable, "try later")}, KeepError: true, }) // This session request will never finish until the injected error is // cleared. go sp.take(ctx) // Poll for the execution of the first session request. for { sp.mu.Lock() cr := sp.createReqs sp.mu.Unlock() if cr == 0 { <-time.After(time.Second) continue } // The first session request is being executed. break } ctx2, cancel := context.WithTimeout(ctx, time.Second) defer cancel() _, gotErr := sp.take(ctx2) // Since MaxBurst == 1, the second session request should block. if wantErr := errGetSessionTimeout(); !testEqual(gotErr, wantErr) { t.Fatalf("session retrival returns error %v, want %v", gotErr, wantErr) } // Let the first session request succeed. server.TestSpanner.Freeze() server.TestSpanner.PutExecutionTime(MethodCreateSession, SimulatedExecutionTime{}) //close(allowRequests) server.TestSpanner.Unfreeze() // Now new session request can proceed because the first session request will eventually succeed. sh, err := sp.take(ctx) if err != nil { t.Fatalf("session retrival returns error %v, want nil", err) } if !sh.session.isValid() || sh.getID() == "" { t.Fatalf("got invalid session: %v", sh.session) } } // TestSessionRecycle tests recycling sessions. func TestSessionRecycle(t *testing.T) { t.Parallel() ctx := context.Background() // Set MaxBurst=MinOpened to prevent additional sessions to be created // while session pool initialization is still running. _, client, teardown := setupMockedTestServerWithConfig(t, ClientConfig{ SessionPoolConfig: SessionPoolConfig{ MinOpened: 1, MaxIdle: 5, MaxBurst: 1, }, }) defer teardown() sp := client.idleSessions // Test session is correctly recycled and reused. for i := 0; i < 20; i++ { s, err := sp.take(ctx) if err != nil { t.Fatalf("cannot get the session %v: %v", i, err) } s.recycle() } sp.mu.Lock() defer sp.mu.Unlock() // The session pool should only contain 1 session, as there is no minimum // configured. In addition, there has never been more than one session in // use at any time, so there's no need for the session pool to create a // second session. The session has also been in use all the time, so there // also no reason for the session pool to delete the session. if sp.numOpened != 1 { t.Fatalf("Expect session pool size 1, got %d", sp.numOpened) } } // TestSessionDestroy tests destroying sessions. func TestSessionDestroy(t *testing.T) { t.Parallel() ctx := context.Background() _, client, teardown := setupMockedTestServerWithConfig(t, ClientConfig{ SessionPoolConfig: SessionPoolConfig{ MinOpened: 1, MaxBurst: 1, }, }) defer teardown() sp := client.idleSessions // Creating a session pool with MinSessions=1 will automatically start the // creation of 1 session when the session pool is created. As MaxBurst=1, // the session pool will never create more than 1 session at a time, so the // take() method will wait if the initial session has not yet been created. sh, err := sp.take(ctx) if err != nil { t.Fatalf("cannot get session from session pool: %v", err) } s := sh.session sh.recycle() if d := s.destroy(true); d || !s.isValid() { // Session should be remaining because of min open sessions constraint. t.Fatalf("session %s invalid, want it to stay alive. (destroy in expiration mode, success: %v)", s.id, d) } if d := s.destroy(false); !d || s.isValid() { // Session should be destroyed. t.Fatalf("failed to destroy session %s. (destroy in default mode, success: %v)", s.id, d) } } // TestHcHeap tests heap operation on top of hcHeap. func TestHcHeap(t *testing.T) { in := []*session{ {nextCheck: time.Unix(10, 0)}, {nextCheck: time.Unix(0, 5)}, {nextCheck: time.Unix(1, 8)}, {nextCheck: time.Unix(11, 7)}, {nextCheck: time.Unix(6, 3)}, } want := []*session{ {nextCheck: time.Unix(1, 8), hcIndex: 0}, {nextCheck: time.Unix(6, 3), hcIndex: 1}, {nextCheck: time.Unix(8, 2), hcIndex: 2}, {nextCheck: time.Unix(10, 0), hcIndex: 3}, {nextCheck: time.Unix(11, 7), hcIndex: 4}, } hh := hcHeap{} for _, s := range in { heap.Push(&hh, s) } // Change top of the heap and do a adjustment. hh.sessions[0].nextCheck = time.Unix(8, 2) heap.Fix(&hh, 0) for idx := 0; hh.Len() > 0; idx++ { got := heap.Pop(&hh).(*session) want[idx].hcIndex = -1 if !testEqual(got, want[idx]) { t.Fatalf("%v: heap.Pop returns %v, want %v", idx, got, want[idx]) } } } // TestHealthCheckScheduler tests if healthcheck workers can schedule and // perform healthchecks properly. func TestHealthCheckScheduler(t *testing.T) { t.Parallel() ctx := context.Background() server, client, teardown := setupMockedTestServerWithConfig(t, ClientConfig{ SessionPoolConfig: SessionPoolConfig{ HealthCheckInterval: 50 * time.Millisecond, healthCheckSampleInterval: 10 * time.Millisecond, }, }) defer teardown() sp := client.idleSessions // Create 50 sessions. for i := 0; i < 50; i++ { _, err := sp.take(ctx) if err != nil { t.Fatalf("cannot get session from session pool: %v", err) } } // Make sure we start with a ping history to avoid that the first // sessions that were created have not already exceeded the maximum // number of pings. server.TestSpanner.ClearPings() // Wait for 10-30 pings per session. waitFor(t, func() error { // Only check actually live sessions and ignore any sessions the // session pool may have deleted in the meantime. liveSessions := server.TestSpanner.DumpSessions() dp := server.TestSpanner.DumpPings() gotPings := map[string]int64{} for _, p := range dp { gotPings[p]++ } for s := range liveSessions { want := int64(20) if got := gotPings[s]; got < want/2 || got > want+want/2 { // This is an unnacceptable amount of pings. return fmt.Errorf("got %v healthchecks on session %v, want it between (%v, %v)", got, s, want/2, want+want/2) } } return nil }) } // Tests that a fractions of sessions are prepared for write by health checker. func TestWriteSessionsPrepared(t *testing.T) { t.Parallel() ctx := context.Background() _, client, teardown := setupMockedTestServerWithConfig(t, ClientConfig{ SessionPoolConfig: SessionPoolConfig{ WriteSessions: 0.5, MaxIdle: 20, HealthCheckInterval: time.Nanosecond, }, }) defer teardown() sp := client.idleSessions shs := make([]*sessionHandle, 10) var err error for i := 0; i < 10; i++ { shs[i], err = sp.take(ctx) if err != nil { t.Fatalf("cannot get session from session pool: %v", err) } } // Now there are 10 sessions in the pool. Release them. for _, sh := range shs { sh.recycle() } // Take 5 write sessions. The write sessions will be taken from either the // list of prepared sessions (idleWriteList), or they will be prepared // during the takeWriteSession method. wshs := make([]*sessionHandle, 5) for i := 0; i < 5; i++ { wshs[i], err = sp.takeWriteSession(ctx) if err != nil { t.Fatalf("cannot get session from session pool: %v", err) } if wshs[i].getTransactionID() == nil { t.Fatalf("got nil transaction id from session pool") } } // Return the session to the pool. for _, sh := range wshs { sh.recycle() } // Now force creation of 10 more sessions. shs = make([]*sessionHandle, 20) for i := 0; i < 20; i++ { shs[i], err = sp.take(ctx) if err != nil { t.Fatalf("cannot get session from session pool: %v", err) } } // Now there are 20 sessions in the pool. Release them. for _, sh := range shs { sh.recycle() } // The health checker should eventually prepare 10 of the 20 sessions with // a r/w tx. waitUntil := time.After(time.Second) var numWritePrepared int for numWritePrepared < 10 { select { case <-waitUntil: break default: } sp.mu.Lock() numWritePrepared = sp.idleWriteList.Len() sp.mu.Unlock() } sp.mu.Lock() defer sp.mu.Unlock() if sp.idleWriteList.Len() != 10 { t.Fatalf("Expect 10 write prepared session, got: %d", sp.idleWriteList.Len()) } } // TestTakeFromWriteQueue tests that sessionPool.take() returns write prepared // sessions as well. func TestTakeFromWriteQueue(t *testing.T) { t.Parallel() ctx := context.Background() _, client, teardown := setupMockedTestServerWithConfig(t, ClientConfig{ SessionPoolConfig: SessionPoolConfig{ MaxOpened: 1, WriteSessions: 1.0, MaxIdle: 1, HealthCheckInterval: time.Nanosecond, }, }) defer teardown() sp := client.idleSessions sh, err := sp.take(ctx) if err != nil { t.Fatalf("cannot get session from session pool: %v", err) } sh.recycle() // Wait until the health checker has write-prepared the session. waitUntil := time.After(time.Second) var numWritePrepared int for numWritePrepared == 0 { select { case <-waitUntil: break default: } sp.mu.Lock() numWritePrepared = sp.idleWriteList.Len() sp.mu.Unlock() } // The session should now be in write queue but take should also return it. sp.mu.Lock() if sp.idleWriteList.Len() == 0 { t.Fatalf("write queue unexpectedly empty") } if sp.idleList.Len() != 0 { t.Fatalf("read queue not empty") } sp.mu.Unlock() sh, err = sp.take(ctx) if err != nil { t.Fatalf("cannot get session from session pool: %v", err) } sh.recycle() } // The session pool should stop trying to create write-prepared sessions if a // permanent error occurs while trying to begin a transaction. Possible // permanent errors are PermissionDenied or `Database not found`. func TestPermanentErrorOnPrepareSession(t *testing.T) { t.Parallel() permanentErrors := []error{ status.Errorf(codes.PermissionDenied, "Caller is missing IAM permission spanner.databases.beginOrRollbackReadWriteTransaction on resource"), status.Errorf(codes.NotFound, `Database not found: projects//instances//databases/ resource_type: "type.googleapis.com/google.spanner.admin.database.v1.Database" resource_name: "projects//instances//databases/" description: "Database does not exist."`), } for _, permanentError := range permanentErrors { ctx := context.Background() server, client, teardown := setupMockedTestServerWithConfig(t, ClientConfig{ SessionPoolConfig: SessionPoolConfig{ MinOpened: 10, MaxOpened: 10, WriteSessions: 0.5, HealthCheckInterval: time.Millisecond, }, }) defer teardown() server.TestSpanner.PutExecutionTime(MethodBeginTransaction, SimulatedExecutionTime{ Errors: []error{permanentError}, KeepError: true, }) sp := client.idleSessions // Wait until the health checker has tried to write-prepare a session. // This will cause the session pool to write some errors to the log that // preparing sessions failed. waitUntil := time.After(time.Second) var prepareDisabled bool var numOpened int for !prepareDisabled || numOpened < 10 { select { case <-waitUntil: break default: } sp.mu.Lock() prepareDisabled = sp.disableBackgroundPrepareSessions numOpened = sp.idleList.Len() sp.mu.Unlock() } // There should be no write-prepared sessions. sp.mu.Lock() if sp.idleWriteList.Len() != 0 { sp.mu.Unlock() t.Fatalf("write queue unexpectedly not empty") } // All sessions should be in the read idle list. if g, w := sp.idleList.Len(), 10; g != w { sp.mu.Unlock() t.Fatalf("session count mismatch:\nWant: %v\nGot: %v", w, g) } sp.mu.Unlock() // Take a read session should succeed. sh, err := sp.take(ctx) if err != nil { t.Fatalf("cannot get session from session pool: %v", err) } sh.recycle() // Take a write session should fail with the permanent error. _, err = sp.takeWriteSession(ctx) if ErrCode(err) != ErrCode(permanentError) { t.Fatalf("take write session failed with unexpected error.\nGot: %v\nWant: %v\n", err, permanentError) } // Clearing the error on the server (or granting the permission to the // credentials in use) should allow us to take a write session. server.TestSpanner.PutExecutionTime(MethodBeginTransaction, SimulatedExecutionTime{}) sh, err = sp.takeWriteSession(ctx) if err != nil { t.Fatalf("cannot get write session from session pool: %v", err) } sh.recycle() // The maintainer should also pick this up and prepare 50% of the sessions. waitUntil = time.After(time.Second) var numPrepared int for numPrepared < 5 { select { case <-waitUntil: break default: } sp.mu.Lock() numPrepared = sp.idleWriteList.Len() sp.mu.Unlock() } sp.mu.Lock() if g, w := sp.idleWriteList.Len(), 5; g != w { sp.mu.Unlock() t.Fatalf("write session count mismatch:\nWant: %v\nGot: %v", w, g) } sp.mu.Unlock() } } // TestSessionHealthCheck tests healthchecking cases. func TestSessionHealthCheck(t *testing.T) { t.Parallel() ctx := context.Background() server, client, teardown := setupMockedTestServerWithConfig(t, ClientConfig{ SessionPoolConfig: SessionPoolConfig{ HealthCheckInterval: time.Nanosecond, healthCheckSampleInterval: 10 * time.Millisecond, }, }) defer teardown() sp := client.idleSessions // Test pinging sessions. sh, err := sp.take(ctx) if err != nil { t.Fatalf("cannot get session from session pool: %v", err) } // Wait for healthchecker to send pings to session. waitFor(t, func() error { pings := server.TestSpanner.DumpPings() if len(pings) == 0 || pings[0] != sh.getID() { return fmt.Errorf("healthchecker didn't send any ping to session %v", sh.getID()) } return nil }) // Test broken session detection. sh, err = sp.take(ctx) if err != nil { t.Fatalf("cannot get session from session pool: %v", err) } server.TestSpanner.Freeze() server.TestSpanner.PutExecutionTime(MethodGetSession, SimulatedExecutionTime{ Errors: []error{status.Errorf(codes.NotFound, "Session not found")}, KeepError: true, }) server.TestSpanner.Unfreeze() s := sh.session waitFor(t, func() error { if sh.session.isValid() { return fmt.Errorf("session(%v) is still alive, want it to be dropped by healthcheck workers", s) } return nil }) server.TestSpanner.Freeze() server.TestSpanner.PutExecutionTime(MethodGetSession, SimulatedExecutionTime{}) server.TestSpanner.Unfreeze() // Test garbage collection. sh, err = sp.take(ctx) if err != nil { t.Fatalf("cannot get session from session pool: %v", err) } sp.close() if sh.session.isValid() { t.Fatalf("session(%v) is still alive, want it to be garbage collected", s) } } // TestStressSessionPool does stress test on session pool by the following concurrent operations: // 1) Test worker gets a session from the pool. // 2) Test worker turns a session back into the pool. // 3) Test worker destroys a session got from the pool. // 4) Healthcheck destroys a broken session (because a worker has already destroyed it). // 5) Test worker closes the session pool. // // During the test, the session pool maintainer maintains the number of sessions, // and it is expected that all sessions that are taken from session pool remains valid. // When all test workers and healthcheck workers exit, mockclient, session pool // and healthchecker should be in consistent state. func TestStressSessionPool(t *testing.T) { t.Parallel() // Use concurrent workers to test different session pool built from different configurations. for ti, cfg := range []SessionPoolConfig{ {}, {MinOpened: 10, MaxOpened: 100}, {MaxBurst: 50}, {MinOpened: 10, MaxOpened: 200, MaxBurst: 5}, {MinOpened: 10, MaxOpened: 200, MaxBurst: 5, WriteSessions: 0.2}, } { // Create a more aggressive session healthchecker to increase test concurrency. cfg.HealthCheckInterval = 50 * time.Millisecond cfg.healthCheckSampleInterval = 10 * time.Millisecond cfg.HealthCheckWorkers = 50 server, client, teardown := setupMockedTestServerWithConfig(t, ClientConfig{ SessionPoolConfig: cfg, }) sp := client.idleSessions // Create a test group for this configuration and schedule 100 sub // sub tests within the group. t.Run(fmt.Sprintf("TestStressSessionPoolGroup%v", ti), func(t *testing.T) { for i := 0; i < 100; i++ { idx := i t.Logf("TestStressSessionPoolWithCfg%dWorker%03d", ti, idx) testStressSessionPool(t, cfg, ti, idx, sp, client) } }) sp.hc.close() // Here the states of healthchecker, session pool and mockclient are // stable. idleSessions := map[string]bool{} hcSessions := map[string]bool{} mockSessions := server.TestSpanner.DumpSessions() // Dump session pool's idle list. for sl := sp.idleList.Front(); sl != nil; sl = sl.Next() { s := sl.Value.(*session) if idleSessions[s.getID()] { t.Fatalf("%v: found duplicated session in idle list: %v", ti, s.getID()) } idleSessions[s.getID()] = true } for sl := sp.idleWriteList.Front(); sl != nil; sl = sl.Next() { s := sl.Value.(*session) if idleSessions[s.getID()] { t.Fatalf("%v: found duplicated session in idle write list: %v", ti, s.getID()) } idleSessions[s.getID()] = true } sp.mu.Lock() if int(sp.numOpened) != len(idleSessions) { t.Fatalf("%v: number of opened sessions (%v) != number of idle sessions (%v)", ti, sp.numOpened, len(idleSessions)) } if sp.createReqs != 0 { t.Fatalf("%v: number of pending session creations = %v, want 0", ti, sp.createReqs) } // Dump healthcheck queue. for _, s := range sp.hc.queue.sessions { if hcSessions[s.getID()] { t.Fatalf("%v: found duplicated session in healthcheck queue: %v", ti, s.getID()) } hcSessions[s.getID()] = true } sp.mu.Unlock() // Verify that idleSessions == hcSessions == mockSessions. if !testEqual(idleSessions, hcSessions) { t.Fatalf("%v: sessions in idle list (%v) != sessions in healthcheck queue (%v)", ti, idleSessions, hcSessions) } // The server may contain more sessions than the health check queue. // This can be caused by a timeout client side during a CreateSession // request. The request may still be received and executed by the // server, but the session pool will not register the session. for id, b := range hcSessions { if b && !mockSessions[id] { t.Fatalf("%v: session in healthcheck queue (%v) was not found on server", ti, id) } } sp.close() mockSessions = server.TestSpanner.DumpSessions() for id, b := range hcSessions { if b && mockSessions[id] { t.Fatalf("Found session from pool still live on server: %v", id) } } teardown() } } func testStressSessionPool(t *testing.T, cfg SessionPoolConfig, ti int, idx int, pool *sessionPool, client *Client) { ctx := context.Background() // Test worker iterates 1K times and tries different // session / session pool operations. for j := 0; j < 1000; j++ { if idx%10 == 0 && j >= 900 { // Close the pool in selected set of workers during the // middle of the test. pool.close() } // Take a write sessions ~ 20% of the times. takeWrite := rand.Intn(5) == 4 var ( sh *sessionHandle gotErr error ) wasValid := pool.isValid() if takeWrite { sh, gotErr = pool.takeWriteSession(ctx) } else { sh, gotErr = pool.take(ctx) } if gotErr != nil { if pool.isValid() { t.Fatalf("%v.%v: pool.take returns error when pool is still valid: %v", ti, idx, gotErr) } // If the session pool was closed when we tried to take a session // from the pool, then we should have gotten a specific error. // If the session pool was closed between the take() and now (or // even during a take()) then an error is ok. if !wasValid { if wantErr := errInvalidSessionPool(); !testEqual(gotErr, wantErr) { t.Fatalf("%v.%v: got error when pool is closed: %v, want %v", ti, idx, gotErr, wantErr) } } continue } // Verify if session is valid when session pool is valid. // Note that if session pool is invalid after sh is taken, // then sh might be invalidated by healthcheck workers. if (sh.getID() == "" || sh.session == nil || !sh.session.isValid()) && pool.isValid() { t.Fatalf("%v.%v.%v: pool.take returns invalid session %v", ti, idx, takeWrite, sh.session) } if takeWrite && sh.getTransactionID() == nil { t.Fatalf("%v.%v: pool.takeWriteSession returns session %v without transaction", ti, idx, sh.session) } if rand.Intn(100) < idx { // Random sleep before destroying/recycling the session, // to give healthcheck worker a chance to step in. <-time.After(time.Duration(rand.Int63n(int64(cfg.HealthCheckInterval)))) } if rand.Intn(100) < idx { // destroy the session. sh.destroy() continue } // recycle the session. sh.recycle() } } // TestMaintainer checks the session pool maintainer maintains the number of // sessions in the following cases: // // 1. On initialization of session pool, replenish session pool to meet // MinOpened or MaxIdle. // 2. On increased session usage, provision extra MaxIdle sessions. // 3. After the surge passes, scale down the session pool accordingly. func TestMaintainer(t *testing.T) { t.Parallel() ctx := context.Background() minOpened := uint64(5) maxIdle := uint64(4) _, client, teardown := setupMockedTestServerWithConfig(t, ClientConfig{ SessionPoolConfig: SessionPoolConfig{ MinOpened: minOpened, MaxIdle: maxIdle, healthCheckSampleInterval: time.Millisecond, }, }) defer teardown() sp := client.idleSessions waitFor(t, func() error { sp.mu.Lock() defer sp.mu.Unlock() if sp.numOpened != 5 { return fmt.Errorf("Replenish. Expect %d open, got %d", sp.MinOpened, sp.numOpened) } return nil }) // To save test time, we are not creating many sessions, because the time // to create sessions will have impact on the decision on sessionsToKeep. // We also parallelize the take and recycle process. shs := make([]*sessionHandle, 20) for i := 0; i < len(shs); i++ { var err error shs[i], err = sp.take(ctx) if err != nil { t.Fatalf("cannot get session from session pool: %v", err) } } sp.mu.Lock() if sp.numOpened != 20 { t.Fatalf("Scale out from normal use. Expect %d open, got %d", 20, sp.numOpened) } sp.mu.Unlock() // Return 14 sessions to the pool. There are still 6 sessions checked out. for _, sh := range shs[:14] { sh.recycle() } // The pool should scale down to sessionsInUse + MaxIdle = 6 + 4 = 10. waitFor(t, func() error { sp.mu.Lock() defer sp.mu.Unlock() if sp.numOpened != 10 { return fmt.Errorf("Keep extra MaxIdle sessions. Expect %d open, got %d", 10, sp.numOpened) } return nil }) // Return the remaining 6 sessions. // The pool should now scale down to minOpened + maxIdle. for _, sh := range shs[14:] { sh.recycle() } waitFor(t, func() error { sp.mu.Lock() defer sp.mu.Unlock() if sp.numOpened != minOpened { return fmt.Errorf("Scale down. Expect %d open, got %d", minOpened+maxIdle, sp.numOpened) } return nil }) } // Tests that the session pool creates up to MinOpened connections. // // Historical context: This test also checks that a low // healthCheckSampleInterval does not prevent it from opening connections. // The low healthCheckSampleInterval will however sometimes cause session // creations to time out. That should not be considered a problem, but it // could cause the test case to fail if it happens too often. // See: https://github.com/googleapis/google-cloud-go/issues/1259 func TestInit_CreatesSessions(t *testing.T) { t.Parallel() spc := SessionPoolConfig{ MinOpened: 10, MaxIdle: 10, WriteSessions: 0.0, healthCheckSampleInterval: 20 * time.Millisecond, } server, client, teardown := setupMockedTestServerWithConfig(t, ClientConfig{ SessionPoolConfig: spc, NumChannels: 4, }) defer teardown() sp := client.idleSessions timeout := time.After(4 * time.Second) var numOpened int loop: for { select { case <-timeout: t.Fatalf("timed out, got %d session(s), want %d", numOpened, spc.MinOpened) default: sp.mu.Lock() numOpened = sp.idleList.Len() + sp.idleWriteList.Len() sp.mu.Unlock() if numOpened == 10 { break loop } } } _, err := shouldHaveReceived(server.TestSpanner, []interface{}{ &sppb.BatchCreateSessionsRequest{}, &sppb.BatchCreateSessionsRequest{}, &sppb.BatchCreateSessionsRequest{}, &sppb.BatchCreateSessionsRequest{}, }) if err != nil { t.Fatal(err) } } // Tests that the session pool with a MinSessions>0 also prepares WriteSessions // sessions. func TestInit_PreparesSessions(t *testing.T) { t.Parallel() spc := SessionPoolConfig{ MinOpened: 10, MaxIdle: 10, WriteSessions: 0.5, healthCheckSampleInterval: 20 * time.Millisecond, } _, client, teardown := setupMockedTestServerWithConfig(t, ClientConfig{ SessionPoolConfig: spc, }) defer teardown() sp := client.idleSessions timeoutAmt := 4 * time.Second timeout := time.After(timeoutAmt) var numPrepared int want := int(spc.WriteSessions * float64(spc.MinOpened)) loop: for { select { case <-timeout: t.Fatalf("timed out after %v, got %d write-prepared session(s), want %d", timeoutAmt, numPrepared, want) default: sp.mu.Lock() numPrepared = sp.idleWriteList.Len() sp.mu.Unlock() if numPrepared == want { break loop } } } } func (s1 *session) Equal(s2 *session) bool { return s1.client == s2.client && s1.id == s2.id && s1.pool == s2.pool && s1.createTime == s2.createTime && s1.valid == s2.valid && s1.hcIndex == s2.hcIndex && s1.idleList == s2.idleList && s1.nextCheck.Equal(s2.nextCheck) && s1.checkingHealth == s2.checkingHealth && testEqual(s1.md, s2.md) && bytes.Equal(s1.tx, s2.tx) } func waitFor(t *testing.T, assert func() error) { t.Helper() timeout := 15 * time.Second ta := time.After(timeout) for { select { case <-ta: if err := assert(); err != nil { t.Fatalf("after %v waiting, got %v", timeout, err) } return default: } if err := assert(); err != nil { // Fail. Let's pause and retry. time.Sleep(10 * time.Millisecond) continue } return } } // Tests that maintainer only deletes sessions after a full maintenance window // of 10 cycles has finished. func TestMaintainer_DeletesSessions(t *testing.T) { t.Parallel() ctx := context.Background() const sampleInterval = time.Millisecond * 10 _, client, teardown := setupMockedTestServerWithConfig(t, ClientConfig{ SessionPoolConfig: SessionPoolConfig{healthCheckSampleInterval: sampleInterval}, }) defer teardown() sp := client.idleSessions // Take two sessions from the pool. // This will cause max sessions in use to be 2 during this window. sh1 := takeSession(ctx, t, sp) sh2 := takeSession(ctx, t, sp) wantSessions := map[string]bool{} wantSessions[sh1.getID()] = true wantSessions[sh2.getID()] = true // Return the sessions to the pool and then assure that they // are not deleted while still within the maintenance window. sh1.recycle() sh2.recycle() // Wait for 20 milliseconds, i.e. approx 2 iterations of the // maintainer. The sessions should still be in the pool. <-time.After(sampleInterval * 2) sh3 := takeSession(ctx, t, sp) sh4 := takeSession(ctx, t, sp) // Check that the returned sessions are equal to the sessions that we got // the first time from the session pool. gotSessions := map[string]bool{} gotSessions[sh3.getID()] = true gotSessions[sh4.getID()] = true testEqual(wantSessions, gotSessions) // Return the sessions to the pool. sh3.recycle() sh4.recycle() // Now wait for the maintenance window to finish. This will cause the // maintainer to enter a new window and reset the max number of sessions in // use to the currently number of checked out sessions. That is 0, as all // sessions have been returned to the pool. That again will cause the // maintainer to delete these sessions at the next iteration, unless we // checkout new sessions during the first iteration. waitFor(t, func() error { sp.mu.Lock() defer sp.mu.Unlock() if sp.numOpened > 0 { return fmt.Errorf("session pool still contains more than 0 sessions") } return nil }) sh5 := takeSession(ctx, t, sp) sh6 := takeSession(ctx, t, sp) // Assure that these sessions are new sessions. if gotSessions[sh5.getID()] || gotSessions[sh6.getID()] { t.Fatal("got unexpected existing session from pool") } } func takeSession(ctx context.Context, t *testing.T, sp *sessionPool) *sessionHandle { sh, err := sp.take(ctx) if err != nil { t.Fatalf("cannot get session from session pool: %v", err) } return sh } func TestMaintenanceWindow_CycleAndUpdateMaxCheckedOut(t *testing.T) { t.Parallel() maxOpened := uint64(1000) mw := newMaintenanceWindow(maxOpened) for _, m := range mw.maxSessionsCheckedOut { if m < maxOpened { t.Fatalf("Max sessions checked out mismatch.\nGot: %v\nWant: %v", m, maxOpened) } } // Do one cycle and simulate that there are currently no sessions checked // out of the pool. mw.startNewCycle(0) if g, w := mw.maxSessionsCheckedOut[0], uint64(0); g != w { t.Fatalf("Max sessions checked out mismatch.\nGot: %d\nWant: %d", g, w) } for _, m := range mw.maxSessionsCheckedOut[1:] { if m < maxOpened { t.Fatalf("Max sessions checked out mismatch.\nGot: %v\nWant: %v", m, maxOpened) } } // Check that the max checked out during the entire window is still // maxOpened. if g, w := mw.maxSessionsCheckedOutDuringWindow(), maxOpened; g != w { t.Fatalf("Max sessions checked out during window mismatch.\nGot: %d\nWant: %d", g, w) } // Update the max number checked out for the current cycle. mw.updateMaxSessionsCheckedOutDuringWindow(uint64(10)) if g, w := mw.maxSessionsCheckedOut[0], uint64(10); g != w { t.Fatalf("Max sessions checked out mismatch.\nGot: %d\nWant: %d", g, w) } // The max of the entire window should still not change. if g, w := mw.maxSessionsCheckedOutDuringWindow(), maxOpened; g != w { t.Fatalf("Max sessions checked out during window mismatch.\nGot: %d\nWant: %d", g, w) } // Now pass enough cycles to complete a maintenance window. Each cycle has // no sessions checked out. We start at 1, as we have already passed one // cycle. This should then be the last cycle still in the maintenance // window, and the only one with a maxSessionsCheckedOut greater than 0. for i := 1; i < maintenanceWindowSize; i++ { mw.startNewCycle(0) } for _, m := range mw.maxSessionsCheckedOut[:9] { if m != 0 { t.Fatalf("Max sessions checked out mismatch.\nGot: %v\nWant: %v", m, 0) } } // The oldest cycle in the window should have max=10. if g, w := mw.maxSessionsCheckedOut[maintenanceWindowSize-1], uint64(10); g != w { t.Fatalf("Max sessions checked out mismatch.\nGot: %d\nWant: %d", g, w) } // The max of the entire window should now be 10. if g, w := mw.maxSessionsCheckedOutDuringWindow(), uint64(10); g != w { t.Fatalf("Max sessions checked out during window mismatch.\nGot: %d\nWant: %d", g, w) } // Do another cycle with max=0. mw.startNewCycle(0) // The max of the entire window should now be 0. if g, w := mw.maxSessionsCheckedOutDuringWindow(), uint64(0); g != w { t.Fatalf("Max sessions checked out during window mismatch.\nGot: %d\nWant: %d", g, w) } // Do another cycle with 5 sessions as max. This should now be the new // window max. mw.startNewCycle(5) if g, w := mw.maxSessionsCheckedOutDuringWindow(), uint64(5); g != w { t.Fatalf("Max sessions checked out during window mismatch.\nGot: %d\nWant: %d", g, w) } // Do a couple of cycles so that the only non-zero value is in the middle. // The max for the entire window should still be 5. for i := 0; i < maintenanceWindowSize/2; i++ { mw.startNewCycle(0) } if g, w := mw.maxSessionsCheckedOutDuringWindow(), uint64(5); g != w { t.Fatalf("Max sessions checked out during window mismatch.\nGot: %d\nWant: %d", g, w) } } google-cloud-go-0.49.0/spanner/sessionclient.go000066400000000000000000000215371356504100700214570ustar00rootroot00000000000000/* Copyright 2019 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spanner import ( "context" "fmt" "sync" "time" "cloud.google.com/go/internal/trace" vkit "cloud.google.com/go/spanner/apiv1" sppb "google.golang.org/genproto/googleapis/spanner/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // sessionConsumer is passed to the batchCreateSessions method and will receive // the sessions that are created as they become available. A sessionConsumer // implementation must be safe for concurrent use. // // The interface is implemented by sessionPool and is used for testing the // sessionClient. type sessionConsumer interface { // sessionReady is called when a session has been created and is ready for // use. sessionReady(s *session) // sessionCreationFailed is called when the creation of a sub-batch of // sessions failed. The numSessions argument specifies the number of // sessions that could not be created as a result of this error. A // consumer may receive multiple errors per batch. sessionCreationFailed(err error, numSessions int32) } // sessionClient creates sessions for a database, either in batches or one at a // time. Each session will be affiliated with a gRPC channel. sessionClient // will ensure that the sessions that are created are evenly distributed over // all available channels. type sessionClient struct { mu sync.Mutex rr int closed bool gapicClients []*vkit.Client database string sessionLabels map[string]string md metadata.MD batchTimeout time.Duration } // newSessionClient creates a session client to use for a database. func newSessionClient(gapicClients []*vkit.Client, database string, sessionLabels map[string]string, md metadata.MD) *sessionClient { return &sessionClient{ gapicClients: gapicClients, database: database, sessionLabels: sessionLabels, md: md, batchTimeout: time.Minute, } } func (sc *sessionClient) close() error { sc.mu.Lock() defer sc.mu.Unlock() sc.closed = true var errs []error for _, gpc := range sc.gapicClients { if err := gpc.Close(); err != nil { errs = append(errs, err) } } switch len(errs) { case 0: return nil case 1: return errs[0] default: return fmt.Errorf("closing gapic clients returned multiple errors: %v", errs) } } // createSession creates one session for the database of the sessionClient. The // session is created using one synchronous RPC. func (sc *sessionClient) createSession(ctx context.Context) (*session, error) { ctx = contextWithOutgoingMetadata(ctx, sc.md) sc.mu.Lock() if sc.closed { return nil, spannerErrorf(codes.FailedPrecondition, "SessionClient is closed") } client := sc.rrNextGapicClientLocked() sc.mu.Unlock() sid, err := client.CreateSession(ctx, &sppb.CreateSessionRequest{ Database: sc.database, Session: &sppb.Session{Labels: sc.sessionLabels}, }) if err != nil { return nil, toSpannerError(err) } return &session{valid: true, client: client, id: sid.Name, createTime: time.Now(), md: sc.md}, nil } // batchCreateSessions creates a batch of sessions for the database of the // sessionClient and returns these to the given sessionConsumer. // // createSessionCount is the number of sessions that should be created. The // sessionConsumer is guaranteed to receive the requested number of sessions if // no error occurs. If one or more errors occur, the sessionConsumer will // receive any number of sessions + any number of errors, where each error will // include the number of sessions that could not be created as a result of the // error. The sum of returned sessions and errored sessions will be equal to // the number of requested sessions. func (sc *sessionClient) batchCreateSessions(createSessionCount int32, consumer sessionConsumer) error { // The sessions that we create should be evenly distributed over all the // channels (gapic clients) that are used by the client. Each gapic client // will do a request for a fraction of the total. sessionCountPerChannel := createSessionCount / int32(len(sc.gapicClients)) // The remainder of the calculation will be added to the number of sessions // that will be created for the first channel, to ensure that we create the // exact number of requested sessions. remainder := createSessionCount % int32(len(sc.gapicClients)) sc.mu.Lock() defer sc.mu.Unlock() if sc.closed { return spannerErrorf(codes.FailedPrecondition, "SessionClient is closed") } // Spread the session creation over all available gRPC channels. Spanner // will maintain server side caches for a session on the gRPC channel that // is used by the session. A session should therefore always use the same // channel, and the sessions should be as evenly distributed as possible // over the channels. for i := 0; i < len(sc.gapicClients); i++ { client := sc.rrNextGapicClientLocked() // Determine the number of sessions that should be created for this // channel. The createCount for the first channel will be increased // with the remainder of the division of the total number of sessions // with the number of channels. All other channels will just use the // result of the division over all channels. createCountForChannel := sessionCountPerChannel if i == 0 { // We add the remainder to the first gRPC channel we use. We could // also spread the remainder over all channels, but this ensures // that small batches of sessions (i.e. less than numChannels) are // created in one RPC. createCountForChannel += remainder } if createCountForChannel > 0 { go sc.executeBatchCreateSessions(client, createCountForChannel, sc.sessionLabels, sc.md, consumer) } } return nil } // executeBatchCreateSessions executes the gRPC call for creating a batch of // sessions. func (sc *sessionClient) executeBatchCreateSessions(client *vkit.Client, createCount int32, labels map[string]string, md metadata.MD, consumer sessionConsumer) { ctx, cancel := context.WithTimeout(context.Background(), sc.batchTimeout) defer cancel() ctx = contextWithOutgoingMetadata(ctx, sc.md) ctx = trace.StartSpan(ctx, "cloud.google.com/go/spanner.BatchCreateSessions") defer func() { trace.EndSpan(ctx, nil) }() trace.TracePrintf(ctx, nil, "Creating a batch of %d sessions", createCount) remainingCreateCount := createCount for { sc.mu.Lock() closed := sc.closed sc.mu.Unlock() if closed { err := spannerErrorf(codes.Canceled, "Session client closed") trace.TracePrintf(ctx, nil, "Session client closed while creating a batch of %d sessions: %v", createCount, err) consumer.sessionCreationFailed(err, remainingCreateCount) break } if ctx.Err() != nil { trace.TracePrintf(ctx, nil, "Context error while creating a batch of %d sessions: %v", createCount, ctx.Err()) consumer.sessionCreationFailed(ctx.Err(), remainingCreateCount) break } response, err := client.BatchCreateSessions(ctx, &sppb.BatchCreateSessionsRequest{ SessionCount: remainingCreateCount, Database: sc.database, SessionTemplate: &sppb.Session{Labels: labels}, }) if err != nil { trace.TracePrintf(ctx, nil, "Error creating a batch of %d sessions: %v", remainingCreateCount, err) consumer.sessionCreationFailed(err, remainingCreateCount) break } actuallyCreated := int32(len(response.Session)) trace.TracePrintf(ctx, nil, "Received a batch of %d sessions", actuallyCreated) for _, s := range response.Session { consumer.sessionReady(&session{valid: true, client: client, id: s.Name, createTime: time.Now(), md: md}) } if actuallyCreated < remainingCreateCount { // Spanner could return less sessions than requested. In that case, we // should do another call using the same gRPC channel. remainingCreateCount -= actuallyCreated } else { trace.TracePrintf(ctx, nil, "Finished creating %d sessions", createCount) break } } } func (sc *sessionClient) sessionWithID(id string) *session { sc.mu.Lock() defer sc.mu.Unlock() return &session{valid: true, client: sc.rrNextGapicClientLocked(), id: id, createTime: time.Now(), md: sc.md} } // rrNextGapicClientLocked returns the next gRPC client to use for session creation. The // client is set on the session, and used by all subsequent gRPC calls on the // session. Using the same channel for all gRPC calls for a session ensures the // optimal usage of server side caches. func (sc *sessionClient) rrNextGapicClientLocked() *vkit.Client { sc.rr = (sc.rr + 1) % len(sc.gapicClients) return sc.gapicClients[sc.rr] } google-cloud-go-0.49.0/spanner/sessionclient_test.go000066400000000000000000000245411356504100700225140ustar00rootroot00000000000000/* Copyright 2019 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spanner import ( "context" "sync" "testing" "time" vkit "cloud.google.com/go/spanner/apiv1" . "cloud.google.com/go/spanner/internal/testutil" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) type testSessionCreateError struct { err error num int32 } type testConsumer struct { numExpected int32 mu sync.Mutex sessions []*session errors []*testSessionCreateError numErr int32 receivedAll chan struct{} } func (tc *testConsumer) sessionReady(s *session) { tc.mu.Lock() defer tc.mu.Unlock() tc.sessions = append(tc.sessions, s) tc.checkReceivedAll() } func (tc *testConsumer) sessionCreationFailed(err error, num int32) { tc.mu.Lock() defer tc.mu.Unlock() tc.errors = append(tc.errors, &testSessionCreateError{ err: err, num: num, }) tc.numErr += num tc.checkReceivedAll() } func (tc *testConsumer) checkReceivedAll() { if int32(len(tc.sessions))+tc.numErr == tc.numExpected { close(tc.receivedAll) } } func newTestConsumer(numExpected int32) *testConsumer { return &testConsumer{ numExpected: numExpected, receivedAll: make(chan struct{}), } } func TestCreateAndCloseSession(t *testing.T) { t.Parallel() server, client, teardown := setupMockedTestServerWithConfig(t, ClientConfig{ SessionPoolConfig: SessionPoolConfig{ MinOpened: 0, MaxOpened: 100, }, }) defer teardown() s, err := client.sc.createSession(context.Background()) if err != nil { t.Fatalf("batch.next() return error mismatch\ngot: %v\nwant: nil", err) } if s == nil { t.Fatalf("batch.next() return value mismatch\ngot: %v\nwant: any session", s) } if server.TestSpanner.TotalSessionsCreated() != 1 { t.Fatalf("number of sessions created mismatch\ngot: %v\nwant: %v", server.TestSpanner.TotalSessionsCreated(), 1) } s.delete(context.Background()) if server.TestSpanner.TotalSessionsDeleted() != 1 { t.Fatalf("number of sessions deleted mismatch\ngot: %v\nwant: %v", server.TestSpanner.TotalSessionsDeleted(), 1) } } func TestBatchCreateAndCloseSession(t *testing.T) { t.Parallel() numSessions := int32(100) server, opts, serverTeardown := NewMockedSpannerInMemTestServer(t) defer serverTeardown() for numChannels := 1; numChannels <= 32; numChannels *= 2 { prevCreated := server.TestSpanner.TotalSessionsCreated() prevDeleted := server.TestSpanner.TotalSessionsDeleted() client, err := NewClientWithConfig(context.Background(), "projects/p/instances/i/databases/d", ClientConfig{ NumChannels: numChannels, SessionPoolConfig: SessionPoolConfig{ MinOpened: 0, MaxOpened: 400, }}, opts...) if err != nil { t.Fatal(err) } consumer := newTestConsumer(numSessions) client.sc.batchCreateSessions(numSessions, consumer) <-consumer.receivedAll if len(consumer.sessions) != int(numSessions) { t.Fatalf("returned number of sessions mismatch\ngot: %v\nwant: %v", len(consumer.sessions), numSessions) } created := server.TestSpanner.TotalSessionsCreated() - prevCreated if created != uint(numSessions) { t.Fatalf("number of sessions created mismatch\ngot: %v\nwant: %v", created, numSessions) } // Check that all channels are used evenly. channelCounts := make(map[*vkit.Client]int32) for _, s := range consumer.sessions { channelCounts[s.client]++ } if len(channelCounts) != numChannels { t.Fatalf("number of channels used mismatch\ngot: %v\nwant: %v", len(channelCounts), numChannels) } for _, c := range channelCounts { if c < numSessions/int32(numChannels) || c > numSessions/int32(numChannels)+(numSessions%int32(numChannels)) { t.Fatalf("channel used an unexpected number of times\ngot: %v\nwant between %v and %v", c, numSessions/int32(numChannels), numSessions/int32(numChannels)+1) } } // Delete the sessions. for _, s := range consumer.sessions { s.delete(context.Background()) } deleted := server.TestSpanner.TotalSessionsDeleted() - prevDeleted if deleted != uint(numSessions) { t.Fatalf("number of sessions deleted mismatch\ngot: %v\nwant %v", deleted, numSessions) } client.Close() } } func TestBatchCreateSessionsWithExceptions(t *testing.T) { t.Parallel() numSessions := int32(100) server, opts, serverTeardown := NewMockedSpannerInMemTestServer(t) defer serverTeardown() // Run the test with everything between 1 and numChannels errors. for numErrors := int32(1); numErrors <= numChannels; numErrors++ { // Make sure that the error is not always the first call. for firstErrorAt := numErrors - 1; firstErrorAt < numChannels-numErrors+1; firstErrorAt++ { client, err := NewClientWithConfig(context.Background(), "projects/p/instances/i/databases/d", ClientConfig{ NumChannels: numChannels, SessionPoolConfig: SessionPoolConfig{ MinOpened: 0, MaxOpened: 400, }}, opts...) if err != nil { t.Fatal(err) } // Register the errors on the server. errors := make([]error, numErrors+firstErrorAt) for i := firstErrorAt; i < numErrors+firstErrorAt; i++ { errors[i] = spannerErrorf(codes.FailedPrecondition, "session creation failed") } server.TestSpanner.PutExecutionTime(MethodBatchCreateSession, SimulatedExecutionTime{ Errors: errors, }) consumer := newTestConsumer(numSessions) client.sc.batchCreateSessions(numSessions, consumer) <-consumer.receivedAll sessionsReturned := int32(len(consumer.sessions)) if int32(len(consumer.errors)) != numErrors { t.Fatalf("Error count mismatch\nGot: %d\nWant: %d", len(consumer.errors), numErrors) } for _, e := range consumer.errors { if g, w := status.Code(e.err), codes.FailedPrecondition; g != w { t.Fatalf("error code mismatch\ngot: %v\nwant: %v", g, w) } } maxExpectedSessions := numSessions - numErrors*(numSessions/numChannels) minExpectedSessions := numSessions - numErrors*(numSessions/numChannels+1) if sessionsReturned < minExpectedSessions || sessionsReturned > maxExpectedSessions { t.Fatalf("session count mismatch\ngot: %v\nwant between %v and %v", sessionsReturned, minExpectedSessions, maxExpectedSessions) } client.Close() } } } func TestBatchCreateSessions_ServerReturnsLessThanRequestedSessions(t *testing.T) { t.Parallel() numChannels := 4 server, client, teardown := setupMockedTestServerWithConfig(t, ClientConfig{ NumChannels: numChannels, SessionPoolConfig: SessionPoolConfig{ MinOpened: 0, MaxOpened: 100, }, }) defer teardown() // Ensure that the server will never return more than 10 sessions per batch // create request. server.TestSpanner.SetMaxSessionsReturnedByServerPerBatchRequest(10) numSessions := int32(100) // Request a batch of sessions that is larger than will be returned by the // server in one request. The server will return at most 10 sessions per // request. The sessionCreator will spread these requests over the 4 // channels that are available, i.e. do requests for 25 sessions in each // request. The batch should still return 100 sessions. consumer := newTestConsumer(numSessions) client.sc.batchCreateSessions(numSessions, consumer) <-consumer.receivedAll if len(consumer.errors) > 0 { t.Fatalf("Error count mismatch\nGot: %d\nWant: %d", len(consumer.errors), 0) } returnedSessionCount := int32(len(consumer.sessions)) if returnedSessionCount != numSessions { t.Fatalf("Returned sessions mismatch\nGot: %v\nWant: %v", returnedSessionCount, numSessions) } } func TestBatchCreateSessions_ServerExhausted(t *testing.T) { t.Parallel() numChannels := 4 server, client, teardown := setupMockedTestServerWithConfig(t, ClientConfig{ NumChannels: numChannels, SessionPoolConfig: SessionPoolConfig{ MinOpened: 0, MaxOpened: 100, }, }) defer teardown() numSessions := int32(100) maxSessions := int32(50) // Ensure that the server will never return more than 50 sessions in total. server.TestSpanner.SetMaxSessionsReturnedByServerInTotal(maxSessions) consumer := newTestConsumer(numSessions) client.sc.batchCreateSessions(numSessions, consumer) <-consumer.receivedAll // Session creation should end with at least one RESOURCE_EXHAUSTED error. if len(consumer.errors) == 0 { t.Fatalf("Error count mismatch\nGot: %d\nWant: > %d", len(consumer.errors), 0) } for _, e := range consumer.errors { if g, w := status.Code(e.err), codes.ResourceExhausted; g != w { t.Fatalf("Error code mismath\nGot: %v\nWant: %v", g, w) } } // The number of returned sessions should be equal to the max of the // server. returnedSessionCount := int32(len(consumer.sessions)) if returnedSessionCount != maxSessions { t.Fatalf("Returned sessions mismatch\nGot: %v\nWant: %v", returnedSessionCount, maxSessions) } if consumer.numErr != (numSessions - maxSessions) { t.Fatalf("Num errored sessions mismatch\nGot: %v\nWant: %v", consumer.numErr, numSessions-maxSessions) } } func TestBatchCreateSessions_WithTimeout(t *testing.T) { t.Parallel() numSessions := int32(100) server, opts, serverTeardown := NewMockedSpannerInMemTestServer(t) defer serverTeardown() server.TestSpanner.PutExecutionTime(MethodBatchCreateSession, SimulatedExecutionTime{ MinimumExecutionTime: time.Second, }) client, err := NewClientWithConfig(context.Background(), "projects/p/instances/i/databases/d", ClientConfig{ SessionPoolConfig: SessionPoolConfig{ MinOpened: 0, MaxOpened: 400, }}, opts...) if err != nil { t.Fatal(err) } client.sc.batchTimeout = 10 * time.Millisecond consumer := newTestConsumer(numSessions) client.sc.batchCreateSessions(numSessions, consumer) <-consumer.receivedAll if len(consumer.sessions) > 0 { t.Fatalf("Returned number of sessions mismatch\ngot: %v\nwant: %v", len(consumer.sessions), 0) } if len(consumer.errors) != numChannels { t.Fatalf("Returned number of errors mismatch\ngot: %v\nwant: %v", len(consumer.errors), numChannels) } for _, e := range consumer.errors { if g, w := status.Code(e.err), codes.DeadlineExceeded; g != w { t.Fatalf("Error code mismatch\ngot: %v\nwant: %v", g, w) } } client.Close() } google-cloud-go-0.49.0/spanner/spannertest/000077500000000000000000000000001356504100700206045ustar00rootroot00000000000000google-cloud-go-0.49.0/spanner/spannertest/README.md000066400000000000000000000024001356504100700220570ustar00rootroot00000000000000This directory contains spannertest, an in-memory fake Cloud Spanner. A sibling directory, spansql, contains types and parser for the Cloud Spanner SQL dialect. spansql is reusable for anything that interacts with Cloud Spanner on a syntactic basis, such as tools for handling Spanner schema (DDL). spannertest builds on spansql for testing code that uses Cloud Spanner client libraries. Neither of these packages aims to be performant nor exact replicas of the production Cloud Spanner. They are reasonable for building tools, or writing unit or integration tests. Full-scale performance testing or serious workloads should use the production Cloud Spanner instead. Here's a list of features that are missing or incomplete. It is roughly ordered by ascending esotericism: - SELECT GROUP BY - SELECT HAVING - arithmetic expressions (operators, parens) - transaction simulation - DML statements - case insensitivity - alternate literal types (esp. strings) - TIMESTAMP types - STRUCT types - expression functions - expression type casting, coercion - joins - query offset - SELECT aliases - subselects - set operations (UNION, INTERSECT, EXCEPT) - SELECT star expressions - partition support - conditional expressions - table sampling (implementation) - hints for table/joins google-cloud-go-0.49.0/spanner/spannertest/db.go000066400000000000000000000426271356504100700215330ustar00rootroot00000000000000/* Copyright 2019 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spannertest // This file contains the implementation of the Spanner fake itself, // namely the part behind the RPC interface. // TODO: missing transactionality in a serious way! import ( "bytes" "fmt" "sort" "strconv" "sync" "time" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" structpb "github.com/golang/protobuf/ptypes/struct" "cloud.google.com/go/spanner/spansql" ) type database struct { mu sync.Mutex tables map[string]*table indexes map[string]struct{} // only record their existence } type table struct { mu sync.Mutex // Information about the table columns. // They are reordered on table creation so the primary key columns come first. cols []colInfo colIndex map[string]int // col name to index pkCols int // number of primary key columns (may be 0) // Rows are stored in primary key order. rows []row } // colInfo represents information about a column in a table or result set. type colInfo struct { Name string Type spansql.Type } /* row represents a list of data elements. The mapping between Spanner types and Go types internal to this package are: BOOL bool INT64 int64 FLOAT64 float64 STRING string BYTES []byte DATE string (RFC 3339 date; "YYYY-MM-DD") TIMESTAMP TODO ARRAY []T STRUCT TODO */ type row []interface{} func (r row) copyDataElem(index int) interface{} { v := r[index] if is, ok := v.([]interface{}); ok { // Deep-copy array values. v = append([]interface{}(nil), is...) } return v } // copyData returns a copy of a subset of a row. func (r row) copyData(indexes []int) row { if len(indexes) == 0 { return nil } dst := make(row, 0, len(indexes)) for _, i := range indexes { dst = append(dst, r.copyDataElem(i)) } return dst } func (d *database) ApplyDDL(stmt spansql.DDLStmt) *status.Status { d.mu.Lock() defer d.mu.Unlock() // Lazy init. if d.tables == nil { d.tables = make(map[string]*table) } if d.indexes == nil { d.indexes = make(map[string]struct{}) } switch stmt := stmt.(type) { default: return status.Newf(codes.Unimplemented, "unhandled DDL statement type %T", stmt) case spansql.CreateTable: if _, ok := d.tables[stmt.Name]; ok { return status.Newf(codes.AlreadyExists, "table %s already exists", stmt.Name) } // TODO: check stmt.Interleave details. // Move primary keys first, preserving their order. pk := make(map[string]int) for i, kp := range stmt.PrimaryKey { pk[kp.Column] = -1000 + i } sort.SliceStable(stmt.Columns, func(i, j int) bool { a, b := pk[stmt.Columns[i].Name], pk[stmt.Columns[j].Name] return a < b }) t := &table{ colIndex: make(map[string]int), pkCols: len(pk), } for _, cd := range stmt.Columns { if st := t.addColumn(cd); st.Code() != codes.OK { return st } } for col := range pk { if _, ok := t.colIndex[col]; !ok { return status.Newf(codes.InvalidArgument, "primary key column %q not in table", col) } } d.tables[stmt.Name] = t return nil case spansql.CreateIndex: if _, ok := d.indexes[stmt.Name]; ok { return status.Newf(codes.AlreadyExists, "index %s already exists", stmt.Name) } d.indexes[stmt.Name] = struct{}{} return nil case spansql.DropTable: if _, ok := d.tables[stmt.Name]; !ok { return status.Newf(codes.NotFound, "no table named %s", stmt.Name) } // TODO: check for indexes on this table. delete(d.tables, stmt.Name) return nil case spansql.DropIndex: if _, ok := d.indexes[stmt.Name]; !ok { return status.Newf(codes.NotFound, "no index named %s", stmt.Name) } delete(d.indexes, stmt.Name) return nil case spansql.AlterTable: t, ok := d.tables[stmt.Name] if !ok { return status.Newf(codes.NotFound, "no table named %s", stmt.Name) } switch alt := stmt.Alteration.(type) { default: return status.Newf(codes.Unimplemented, "unhandled DDL table alteration type %T", alt) case spansql.AddColumn: if alt.Def.NotNull { return status.Newf(codes.InvalidArgument, "new non-key columns cannot be NOT NULL") } if st := t.addColumn(alt.Def); st.Code() != codes.OK { return st } return nil } } } func (d *database) table(tbl string) (*table, error) { d.mu.Lock() defer d.mu.Unlock() t, ok := d.tables[tbl] if !ok { return nil, status.Errorf(codes.NotFound, "no table named %s", tbl) } return t, nil } // writeValues executes a write option (Insert, Update, etc.). func (d *database) writeValues(tbl string, cols []string, values []*structpb.ListValue, f func(t *table, colIndexes []int, r row) error) error { t, err := d.table(tbl) if err != nil { return err } t.mu.Lock() defer t.mu.Unlock() colIndexes, err := t.colIndexes(cols) if err != nil { return err } revIndex := make(map[int]int) // table index to col index for j, i := range colIndexes { revIndex[i] = j } for pki := 0; pki < t.pkCols; pki++ { _, ok := revIndex[pki] if !ok { return status.Errorf(codes.InvalidArgument, "primary key column %s not included in write", t.cols[pki].Name) } } for _, vs := range values { if len(vs.Values) != len(colIndexes) { return status.Errorf(codes.InvalidArgument, "row of %d values can't be written to %d columns", len(vs.Values), len(colIndexes)) } r := make(row, len(t.cols)) for j, v := range vs.Values { i := colIndexes[j] x, err := valForType(v, t.cols[i].Type) if err != nil { return err } r[i] = x } // TODO: enforce NOT NULL? if err := f(t, colIndexes, r); err != nil { return err } } return nil } func (d *database) Insert(tbl string, cols []string, values []*structpb.ListValue) error { return d.writeValues(tbl, cols, values, func(t *table, colIndexes []int, r row) error { pk := r[:t.pkCols] rowNum, found := t.rowForPK(pk) if found { return status.Errorf(codes.AlreadyExists, "row already in table") } t.insertRow(rowNum, r) return nil }) } func (d *database) Update(tbl string, cols []string, values []*structpb.ListValue) error { return d.writeValues(tbl, cols, values, func(t *table, colIndexes []int, r row) error { if t.pkCols == 0 { return status.Errorf(codes.InvalidArgument, "cannot update table %s with no columns in primary key", tbl) } pk := r[:t.pkCols] rowNum, found := t.rowForPK(pk) if !found { // TODO: is this the right way to return `NOT_FOUND`? return status.Errorf(codes.NotFound, "row not in table") } for _, i := range colIndexes { t.rows[rowNum][i] = r[i] } return nil }) } func (d *database) InsertOrUpdate(tbl string, cols []string, values []*structpb.ListValue) error { return d.writeValues(tbl, cols, values, func(t *table, colIndexes []int, r row) error { pk := r[:t.pkCols] rowNum, found := t.rowForPK(pk) if !found { // New row; do an insert. t.insertRow(rowNum, r) } else { // Existing row; do an update. for _, i := range colIndexes { t.rows[rowNum][i] = r[i] } } return nil }) } // TODO: Replace func (d *database) Delete(table string, keys []*structpb.ListValue, keyRanges keyRangeList, all bool) error { t, err := d.table(table) if err != nil { return err } t.mu.Lock() defer t.mu.Unlock() if all { t.rows = nil return nil } for _, key := range keys { pk, err := t.primaryKey(key.Values) if err != nil { return err } // Not an error if the key does not exist. rowNum, found := t.rowForPK(pk) if found { copy(t.rows[rowNum:], t.rows[rowNum+1:]) t.rows = t.rows[:len(t.rows)-1] } } for _, r := range keyRanges { r.startKey, err = t.primaryKeyPrefix(r.start.Values) if err != nil { return err } r.endKey, err = t.primaryKeyPrefix(r.end.Values) if err != nil { return err } startRow, endRow := t.findRange(r) if n := endRow - startRow; n > 0 { copy(t.rows[startRow:], t.rows[endRow:]) t.rows = t.rows[:len(t.rows)-n] } } return nil } // resultIter is returned by reads and queries. // Use its Next method to iterate over the result rows. type resultIter struct { // Cols is the metadata about the returned data. Cols []colInfo // rows holds the result data itself. rows []resultRow } type resultRow struct { data []interface{} // aux is any auxiliary values evaluated for the row. // When a query has an ORDER BY clause, this will contain the values for those expressions. aux []interface{} } func (ri *resultIter) Next() ([]interface{}, bool) { if len(ri.rows) == 0 { return nil, false } res := ri.rows[0] ri.rows = ri.rows[1:] return res.data, true } func (ri *resultIter) add(src row, colIndexes []int) { ri.rows = append(ri.rows, resultRow{ data: src.copyData(colIndexes), }) } // readTable executes a read option (Read, ReadAll). func (d *database) readTable(table string, cols []string, f func(*table, *resultIter, []int) error) (*resultIter, error) { t, err := d.table(table) if err != nil { return nil, err } t.mu.Lock() defer t.mu.Unlock() colIndexes, err := t.colIndexes(cols) if err != nil { return nil, err } ri := &resultIter{} for _, i := range colIndexes { ri.Cols = append(ri.Cols, t.cols[i]) } return ri, f(t, ri, colIndexes) } func (d *database) Read(tbl string, cols []string, keys []*structpb.ListValue, limit int64) (*resultIter, error) { return d.readTable(tbl, cols, func(t *table, ri *resultIter, colIndexes []int) error { for _, key := range keys { pk, err := t.primaryKey(key.Values) if err != nil { return err } // Not an error if the key does not exist. rowNum, found := t.rowForPK(pk) if !found { continue } ri.add(t.rows[rowNum], colIndexes) if limit > 0 && len(ri.rows) >= int(limit) { break } } return nil }) } func (d *database) ReadAll(tbl string, cols []string, limit int64) (*resultIter, error) { return d.readTable(tbl, cols, func(t *table, ri *resultIter, colIndexes []int) error { for _, r := range t.rows { ri.add(r, colIndexes) if limit > 0 && len(ri.rows) >= int(limit) { break } } return nil }) } type queryParams map[string]interface{} func (d *database) Query(q spansql.Query, params queryParams) (*resultIter, error) { // If there's an ORDER BY clause, prepare the list of auxiliary data we need. // This is provided to evalSelect to evaluate with each row. var aux []spansql.Expr var desc []bool if len(q.Order) > 0 { if len(q.Select.From) == 0 { return nil, fmt.Errorf("ORDER BY doesn't work without a table") } for _, o := range q.Order { aux = append(aux, o.Expr) desc = append(desc, o.Desc) } } ri, err := d.evalSelect(q.Select, params, aux) if err != nil { return nil, err } if len(q.Order) > 0 { sort.Slice(ri.rows, func(one, two int) bool { r1, r2 := ri.rows[one], ri.rows[two] for i := range r1.aux { cmp := compareVals(r1.aux[i], r2.aux[i]) if desc[i] { cmp = -cmp } if cmp == 0 { continue } return cmp < 0 } return false }) } if q.Limit != nil { lim, err := evalLimit(q.Limit, params) if err != nil { return nil, err } if n := int(lim); n < len(ri.rows) { ri.rows = ri.rows[:n] } } return ri, nil } func (t *table) addColumn(cd spansql.ColumnDef) *status.Status { t.mu.Lock() defer t.mu.Unlock() if len(t.rows) > 0 { if cd.NotNull { // TODO: what happens in this case? return status.Newf(codes.Unimplemented, "can't add NOT NULL columns to non-empty tables yet") } for i := range t.rows { t.rows[i] = append(t.rows[i], nil) } } t.cols = append(t.cols, colInfo{ Name: cd.Name, Type: cd.Type, }) t.colIndex[cd.Name] = len(t.cols) - 1 return nil } func (t *table) insertRow(rowNum int, r row) { t.rows = append(t.rows, nil) copy(t.rows[rowNum+1:], t.rows[rowNum:]) t.rows[rowNum] = r } // findRange finds the rows included in the key range, // reporting it as a half-open interval. // r.startKey and r.endKey should be populated. func (t *table) findRange(r *keyRange) (int, int) { // TODO: This is incorrect for primary keys with descending order. // It might be sufficient for the caller to switch start/end in that case. // startRow is the first row matching the range. startRow := sort.Search(len(t.rows), func(i int) bool { return rowCmp(r.startKey, t.rows[i][:t.pkCols]) <= 0 }) if startRow == len(t.rows) { return startRow, startRow } if !r.startClosed && rowCmp(r.startKey, t.rows[startRow][:t.pkCols]) == 0 { startRow++ } // endRow is one more than the last row matching the range. endRow := sort.Search(len(t.rows), func(i int) bool { return rowCmp(r.endKey, t.rows[i][:t.pkCols]) < 0 }) if !r.endClosed && rowCmp(r.endKey, t.rows[endRow-1][:t.pkCols]) == 0 { endRow-- } return startRow, endRow } // colIndexes returns the indexes for the named columns. func (t *table) colIndexes(cols []string) ([]int, error) { var is []int for _, col := range cols { i, ok := t.colIndex[col] if !ok { return nil, status.Errorf(codes.InvalidArgument, "column %s not in table", col) } is = append(is, i) } return is, nil } // primaryKey constructs the internal representation of a primary key. // The list of given values must be in 1:1 correspondence with the primary key of the table. func (t *table) primaryKey(values []*structpb.Value) ([]interface{}, error) { if len(values) != t.pkCols { return nil, status.Errorf(codes.InvalidArgument, "primary key length mismatch: got %d values, table has %d", len(values), t.pkCols) } return t.primaryKeyPrefix(values) } // primaryKeyPrefix constructs the internal representation of a primary key prefix. func (t *table) primaryKeyPrefix(values []*structpb.Value) ([]interface{}, error) { if len(values) > t.pkCols { return nil, status.Errorf(codes.InvalidArgument, "primary key length too long: got %d values, table has %d", len(values), t.pkCols) } var pk []interface{} for i, value := range values { v, err := valForType(value, t.cols[i].Type) if err != nil { return nil, err } pk = append(pk, v) } return pk, nil } // rowForPK returns the index of t.rows that holds the row for the given primary key, and true. // If the given primary key isn't found, it returns the row that should hold it, and false. func (t *table) rowForPK(pk []interface{}) (row int, found bool) { if len(pk) != t.pkCols { panic(fmt.Sprintf("primary key length mismatch: got %d values, table has %d", len(pk), t.pkCols)) } i := sort.Search(len(t.rows), func(i int) bool { return rowCmp(pk, t.rows[i][:t.pkCols]) <= 0 }) if i == len(t.rows) { return i, false } return i, rowCmp(pk, t.rows[i][:t.pkCols]) == 0 } // rowCmp compares two rows, returning -1/0/+1. // This is used for primary key matching and so doesn't support array/struct types. // a is permitted to be shorter than b. func rowCmp(a, b []interface{}) int { for i := 0; i < len(a); i++ { if cmp := compareVals(a[i], b[i]); cmp != 0 { return cmp } } return 0 } func valForType(v *structpb.Value, t spansql.Type) (interface{}, error) { if _, ok := v.Kind.(*structpb.Value_NullValue); ok { // TODO: enforce NOT NULL constraints? return nil, nil } if lv, ok := v.Kind.(*structpb.Value_ListValue); ok && t.Array { et := t // element type et.Array = false // Construct the non-nil slice for the list. arr := make([]interface{}, 0, len(lv.ListValue.Values)) for _, v := range lv.ListValue.Values { x, err := valForType(v, et) if err != nil { return nil, err } arr = append(arr, x) } return arr, nil } switch t.Base { case spansql.Bool: bv, ok := v.Kind.(*structpb.Value_BoolValue) if ok { return bv.BoolValue, nil } case spansql.Int64: // The Spanner protocol encodes int64 as a decimal string. sv, ok := v.Kind.(*structpb.Value_StringValue) if ok { x, err := strconv.ParseInt(sv.StringValue, 10, 64) if err != nil { return nil, fmt.Errorf("bad int64 string %q: %v", sv.StringValue, err) } return x, nil } case spansql.Float64: nv, ok := v.Kind.(*structpb.Value_NumberValue) if ok { return nv.NumberValue, nil } case spansql.String: sv, ok := v.Kind.(*structpb.Value_StringValue) if ok { return sv.StringValue, nil } case spansql.Date: // The Spanner protocol encodes DATE in RFC 3339 date format. sv, ok := v.Kind.(*structpb.Value_StringValue) if ok { // Store it internally as a string, but validate its value. s := sv.StringValue if _, err := time.Parse("2006-01-02", s); err != nil { return nil, fmt.Errorf("bad DATE string %q: %v", s, err) } return s, nil } } return nil, fmt.Errorf("unsupported inserting value kind %T into column of type %s", v.Kind, t.SQL()) } type keyRange struct { start, end *structpb.ListValue startClosed, endClosed bool // These are populated during an operation // when we know what table this keyRange applies to. startKey, endKey []interface{} } func (r *keyRange) String() string { var sb bytes.Buffer // TODO: Switch to strings.Builder when we drop support for Go 1.9. if r.startClosed { sb.WriteString("[") } else { sb.WriteString("(") } fmt.Fprintf(&sb, "%v,%v", r.startKey, r.endKey) if r.endClosed { sb.WriteString("]") } else { sb.WriteString(")") } return sb.String() } type keyRangeList []*keyRange google-cloud-go-0.49.0/spanner/spannertest/db_eval.go000066400000000000000000000247141356504100700225370ustar00rootroot00000000000000/* Copyright 2019 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spannertest // This file contains the part of the Spanner fake that evaluates expressions. import ( "fmt" "regexp" "strconv" "strings" "cloud.google.com/go/spanner/spansql" ) // evalContext represents the context for evaluating an expression. type evalContext struct { table *table // may be nil row row // set if table is set, only during expr evaluation params queryParams } func (d *database) evalSelect(sel spansql.Select, params queryParams, aux []spansql.Expr) (ri *resultIter, evalErr error) { // TODO: weave this in below. if len(sel.From) == 0 && sel.Where == nil { // Simple expressions. ri := &resultIter{} ec := evalContext{ params: params, } var r row for _, e := range sel.List { ci, err := ec.colInfo(e) if err != nil { return nil, err } // TODO: set column names? ri.Cols = append(ri.Cols, ci) x, err := ec.evalExpr(e) if err != nil { return nil, err } r = append(r, x) } ri.rows = []resultRow{{data: r}} return ri, nil } if len(sel.From) != 1 { return nil, fmt.Errorf("selecting from more than one table not supported") } tableName := sel.From[0].Table t, err := d.table(tableName) if err != nil { return nil, err } ri = &resultIter{} // Handle COUNT(*) specially. // TODO: Handle aggregation more generally. if len(sel.List) == 1 && isCountStar(sel.List[0]) { // Replace the `COUNT(*)` with `1`, then aggregate on the way out. sel.List[0] = spansql.IntegerLiteral(1) defer func() { if evalErr != nil { return } count := int64(len(ri.rows)) ri.rows = []resultRow{ {data: []interface{}{count}}, } }() } // TODO: Support table sampling. t.mu.Lock() defer t.mu.Unlock() ec := evalContext{ table: t, params: params, } for _, e := range sel.List { ci, err := ec.colInfo(e) if err != nil { return nil, err } // TODO: deal with ci.Name == ""? ri.Cols = append(ri.Cols, ci) } for _, r := range t.rows { ec.row = r // See if we want this row. if sel.Where != nil { b, err := ec.evalBoolExpr(sel.Where) if err != nil { return nil, err } if !b { continue } } // Evaluate SELECT expression list on the row. out, err := ec.evalExprList(sel.List) if err != nil { return nil, err } a, err := ec.evalExprList(aux) if err != nil { return nil, err } ri.rows = append(ri.rows, resultRow{data: out, aux: a}) } return ri, nil } func (ec evalContext) evalExprList(list []spansql.Expr) ([]interface{}, error) { var out []interface{} for _, e := range list { x, err := ec.evalExpr(e) if err != nil { return nil, err } out = append(out, x) } return out, nil } func (ec evalContext) evalBoolExpr(be spansql.BoolExpr) (bool, error) { switch be := be.(type) { default: return false, fmt.Errorf("unhandled BoolExpr %T", be) case spansql.BoolLiteral: return bool(be), nil case spansql.ID, spansql.Paren: e, err := ec.evalExpr(be) if err != nil { return false, err } if e == nil { // NULL is a false boolean. return false, nil } b, ok := e.(bool) if !ok { return false, fmt.Errorf("got %T, want bool", e) } return b, nil case spansql.LogicalOp: var lhs, rhs bool var err error if be.LHS != nil { lhs, err = ec.evalBoolExpr(be.LHS) if err != nil { return false, err } } rhs, err = ec.evalBoolExpr(be.RHS) if err != nil { return false, err } switch be.Op { case spansql.And: return lhs && rhs, nil case spansql.Or: return lhs || rhs, nil case spansql.Not: return !rhs, nil default: return false, fmt.Errorf("unhandled LogicalOp %d", be.Op) } case spansql.ComparisonOp: var lhs, rhs interface{} var err error lhs, err = ec.evalExpr(be.LHS) if err != nil { return false, err } rhs, err = ec.evalExpr(be.RHS) if err != nil { return false, err } switch be.Op { default: return false, fmt.Errorf("TODO: ComparisonOp %d", be.Op) case spansql.Lt: return compareVals(lhs, rhs) < 0, nil case spansql.Le: return compareVals(lhs, rhs) <= 0, nil case spansql.Gt: return compareVals(lhs, rhs) > 0, nil case spansql.Ge: return compareVals(lhs, rhs) >= 0, nil case spansql.Eq: return compareVals(lhs, rhs) == 0, nil case spansql.Ne: return compareVals(lhs, rhs) != 0, nil case spansql.Like, spansql.NotLike: left, ok := lhs.(string) if !ok { // TODO: byte works here too? return false, fmt.Errorf("LHS of LIKE is %T, not string", lhs) } right, ok := rhs.(string) if !ok { // TODO: byte works here too? return false, fmt.Errorf("RHS of LIKE is %T, not string", rhs) } match := evalLike(left, right) if be.Op == spansql.NotLike { match = !match } return match, nil case spansql.Between, spansql.NotBetween: rhs2, err := ec.evalExpr(be.RHS2) if err != nil { return false, err } b := compareVals(rhs, lhs) <= 0 && compareVals(lhs, rhs2) <= 0 if be.Op == spansql.NotBetween { b = !b } return b, nil } case spansql.IsOp: lhs, err := ec.evalExpr(be.LHS) if err != nil { return false, err } var b bool switch rhs := be.RHS.(type) { default: return false, fmt.Errorf("unhandled IsOp %T", rhs) case spansql.BoolLiteral: lhsBool, ok := lhs.(bool) if !ok { return false, fmt.Errorf("non-bool value %T on LHS for %s", lhs, be.SQL()) } b = (lhsBool == bool(rhs)) case spansql.NullLiteral: b = (lhs == nil) } if be.Neg { b = !b } return b, nil } } func (ec evalContext) evalExpr(e spansql.Expr) (interface{}, error) { switch e := e.(type) { default: return nil, fmt.Errorf("TODO: evalExpr(%s %T)", e.SQL(), e) case spansql.ID: return ec.evalID(e) case spansql.Param: v, ok := ec.params[string(e)] if !ok { return 0, fmt.Errorf("unbound param %s", e.SQL()) } return v, nil case spansql.IntegerLiteral: return int64(e), nil case spansql.FloatLiteral: return float64(e), nil case spansql.StringLiteral: return string(e), nil case spansql.BytesLiteral: return []byte(e), nil case spansql.NullLiteral: return nil, nil case spansql.BoolLiteral: return bool(e), nil case spansql.Paren: return ec.evalExpr(e.Expr) case spansql.LogicalOp: return ec.evalBoolExpr(e) case spansql.IsOp: return ec.evalBoolExpr(e) } } func (ec evalContext) evalID(id spansql.ID) (interface{}, error) { // TODO: look beyond column names. if ec.table == nil { return nil, fmt.Errorf("identifier %s when not SELECTing on a table is not supported", string(id)) } i, ok := ec.table.colIndex[string(id)] if !ok { return nil, fmt.Errorf("couldn't resolve identifier %s", string(id)) } return ec.row.copyDataElem(i), nil } func evalLimit(lim spansql.Limit, params queryParams) (int64, error) { switch lim := lim.(type) { case spansql.IntegerLiteral: return int64(lim), nil case spansql.Param: return paramAsInteger(lim, params) default: return 0, fmt.Errorf("LIMIT with %T not supported", lim) } } func paramAsInteger(p spansql.Param, params queryParams) (int64, error) { v, ok := params[string(p)] if !ok { return 0, fmt.Errorf("unbound param %s", p.SQL()) } switch v := v.(type) { default: return 0, fmt.Errorf("can't interpret parameter %s value of type %T as integer", p.SQL(), v) case int64: return v, nil case string: x, err := strconv.ParseInt(v, 10, 64) if err != nil { return 0, fmt.Errorf("bad int64 string %q: %v", v, err) } return x, nil } } func compareVals(x, y interface{}) int { // NULL is always the minimum possible value. if x == nil && y == nil { return 0 } else if x == nil { return -1 } else if y == nil { return 1 } // TODO: coerce between comparable types (e.g. int64/float64). switch x := x.(type) { default: panic(fmt.Sprintf("unhandled comparison on %T", x)) case bool: // false < true y := y.(bool) if !x && y { return -1 } else if x && !y { return 1 } return 0 case int64: if s, ok := y.(string); ok { var err error y, err = strconv.ParseInt(s, 10, 64) if err != nil { panic(fmt.Sprintf("bad int64 string %q: %v", s, err)) } } y := y.(int64) if x < y { return -1 } else if x > y { return 1 } return 0 case float64: y := y.(float64) if x < y { return -1 } else if x > y { return 1 } return 0 case string: // This handles DATE too. return strings.Compare(x, y.(string)) } } func (ec evalContext) colInfo(e spansql.Expr) (colInfo, error) { // TODO: more types switch e := e.(type) { case spansql.IntegerLiteral: return colInfo{Type: spansql.Type{Base: spansql.Int64}}, nil case spansql.StringLiteral: return colInfo{Type: spansql.Type{Base: spansql.String}}, nil case spansql.BytesLiteral: return colInfo{Type: spansql.Type{Base: spansql.Bytes}}, nil case spansql.LogicalOp, spansql.ComparisonOp, spansql.IsOp: return colInfo{Type: spansql.Type{Base: spansql.Bool}}, nil case spansql.ID: // TODO: support more than only naming a table column. name := string(e) if ec.table != nil { if i, ok := ec.table.colIndex[name]; ok { return ec.table.cols[i], nil } } case spansql.Paren: return ec.colInfo(e.Expr) case spansql.NullLiteral: // There isn't necessarily something sensible here. // Empirically, though, the real Spanner returns Int64. return colInfo{Type: spansql.Type{Base: spansql.Int64}}, nil } return colInfo{}, fmt.Errorf("can't deduce column type from expression [%s]", e.SQL()) } func evalLike(str, pat string) bool { /* % matches any number of chars. _ matches a single char. TODO: handle escaping */ // Lean on regexp for simplicity. pat = regexp.QuoteMeta(pat) pat = strings.Replace(pat, "%", ".*", -1) pat = strings.Replace(pat, "_", ".", -1) match, err := regexp.MatchString(pat, str) if err != nil { panic(fmt.Sprintf("internal error: constructed bad regexp /%s/: %v", pat, err)) } return match } func isCountStar(e spansql.Expr) bool { f, ok := e.(spansql.Func) if !ok { return false } if f.Name != "COUNT" || len(f.Args) != 1 { return false } return f.Args[0] == spansql.Star } google-cloud-go-0.49.0/spanner/spannertest/db_test.go000066400000000000000000000317551356504100700225720ustar00rootroot00000000000000/* Copyright 2019 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spannertest import ( "reflect" "testing" "google.golang.org/grpc/codes" structpb "github.com/golang/protobuf/ptypes/struct" "cloud.google.com/go/spanner/spansql" ) var stdTestTable = spansql.CreateTable{ Name: "Staff", Columns: []spansql.ColumnDef{ {Name: "Tenure", Type: spansql.Type{Base: spansql.Int64}}, {Name: "ID", Type: spansql.Type{Base: spansql.Int64}}, {Name: "Name", Type: spansql.Type{Base: spansql.String}}, {Name: "Cool", Type: spansql.Type{Base: spansql.Bool}}, {Name: "Height", Type: spansql.Type{Base: spansql.Float64}}, }, PrimaryKey: []spansql.KeyPart{{Column: "Name"}, {Column: "ID"}}, } func TestTableCreation(t *testing.T) { var db database st := db.ApplyDDL(stdTestTable) if st.Code() != codes.OK { t.Fatalf("Creating table: %v", st.Err()) } // Snoop inside to check that it was constructed correctly. got, ok := db.tables["Staff"] if !ok { t.Fatal("Table didn't get registered") } want := table{ cols: []colInfo{ {Name: "Name", Type: spansql.Type{Base: spansql.String}}, {Name: "ID", Type: spansql.Type{Base: spansql.Int64}}, {Name: "Tenure", Type: spansql.Type{Base: spansql.Int64}}, {Name: "Cool", Type: spansql.Type{Base: spansql.Bool}}, {Name: "Height", Type: spansql.Type{Base: spansql.Float64}}, }, colIndex: map[string]int{ "Tenure": 2, "ID": 1, "Cool": 3, "Name": 0, "Height": 4, }, pkCols: 2, } if !reflect.DeepEqual(got.cols, want.cols) { t.Errorf("table.cols incorrect.\n got %v\nwant %v", got.cols, want.cols) } if !reflect.DeepEqual(got.colIndex, want.colIndex) { t.Errorf("table.colIndex incorrect.\n got %v\nwant %v", got.colIndex, want.colIndex) } if got.pkCols != want.pkCols { t.Errorf("table.pkCols incorrect.\n got %d\nwant %d", got.pkCols, want.pkCols) } } func TestTableData(t *testing.T) { var db database st := db.ApplyDDL(stdTestTable) if st.Code() != codes.OK { t.Fatalf("Creating table: %v", st.Err()) } // Insert a subset of columns. err := db.Insert("Staff", []string{"ID", "Name", "Tenure", "Height"}, []*structpb.ListValue{ // int64 arrives as a decimal string. listV(stringV("1"), stringV("Jack"), stringV("10"), floatV(1.85)), listV(stringV("2"), stringV("Daniel"), stringV("11"), floatV(1.83)), }) if err != nil { t.Fatalf("Inserting data: %v", err) } // Insert a different set of columns. err = db.Insert("Staff", []string{"Name", "ID", "Cool", "Tenure", "Height"}, []*structpb.ListValue{ listV(stringV("Sam"), stringV("3"), boolV(false), stringV("9"), floatV(1.75)), listV(stringV("Teal'c"), stringV("4"), boolV(true), stringV("8"), floatV(1.91)), listV(stringV("George"), stringV("5"), nullV(), stringV("6"), floatV(1.73)), listV(stringV("Harry"), stringV("6"), boolV(true), nullV(), nullV()), }) if err != nil { t.Fatalf("Inserting more data: %v", err) } // Delete that last one. err = db.Delete("Staff", []*structpb.ListValue{listV(stringV("Harry"), stringV("6"))}, nil, false) if err != nil { t.Fatalf("Deleting a row: %v", err) } // Turns out this guy isn't cool after all. err = db.Update("Staff", []string{"Name", "ID", "Cool"}, []*structpb.ListValue{ // Missing columns should be left alone. listV(stringV("Daniel"), stringV("2"), boolV(false)), }) if err != nil { t.Fatalf("Updating a row: %v", err) } // Read some specific keys. ri, err := db.Read("Staff", []string{"Name", "Tenure"}, []*structpb.ListValue{ listV(stringV("George"), stringV("5")), listV(stringV("Harry"), stringV("6")), // should be silently ignored. listV(stringV("Sam"), stringV("3")), }, 0) if err != nil { t.Fatalf("Reading keys: %v", err) } all := slurp(ri) wantAll := [][]interface{}{ {"George", int64(6)}, {"Sam", int64(9)}, } if !reflect.DeepEqual(all, wantAll) { t.Errorf("Read data wrong.\n got %v\nwant %v", all, wantAll) } // Read a subset of all rows, with a limit. ri, err = db.ReadAll("Staff", []string{"Tenure", "Name", "Height"}, 4) if err != nil { t.Fatalf("ReadAll: %v", err) } wantCols := []colInfo{ {Name: "Tenure", Type: spansql.Type{Base: spansql.Int64}}, {Name: "Name", Type: spansql.Type{Base: spansql.String}}, {Name: "Height", Type: spansql.Type{Base: spansql.Float64}}, } if !reflect.DeepEqual(ri.Cols, wantCols) { t.Errorf("ReadAll cols wrong.\n got %v\nwant %v", ri.Cols, wantCols) } all = slurp(ri) wantAll = [][]interface{}{ // Primary key is (Name, ID), so results should come back sorted by Name then ID. {int64(11), "Daniel", 1.83}, {int64(6), "George", 1.73}, {int64(10), "Jack", 1.85}, {int64(9), "Sam", 1.75}, } if !reflect.DeepEqual(all, wantAll) { t.Errorf("ReadAll data wrong.\n got %v\nwant %v", all, wantAll) } // Add a DATE column, populate it with some data. st = db.ApplyDDL(spansql.AlterTable{ Name: "Staff", Alteration: spansql.AddColumn{Def: spansql.ColumnDef{ Name: "FirstSeen", Type: spansql.Type{Base: spansql.Date}, }}, }) if st.Code() != codes.OK { t.Fatalf("Adding column: %v", st.Err()) } err = db.Update("Staff", []string{"Name", "ID", "FirstSeen"}, []*structpb.ListValue{ listV(stringV("Jack"), stringV("1"), stringV("1994-10-28")), listV(stringV("Daniel"), stringV("2"), stringV("1994-10-28")), listV(stringV("George"), stringV("5"), stringV("1997-07-27")), }) if err != nil { t.Fatalf("Updating rows: %v", err) } // Add some more data, then delete it with a KeyRange. // The queries below ensure that this was all deleted. err = db.Insert("Staff", []string{"Name", "ID"}, []*structpb.ListValue{ listV(stringV("01"), stringV("1")), listV(stringV("03"), stringV("3")), listV(stringV("06"), stringV("6")), }) if err != nil { t.Fatalf("Inserting data: %v", err) } err = db.Delete("Staff", nil, keyRangeList{{ start: listV(stringV("01"), stringV("1")), startClosed: true, end: listV(stringV("9")), }}, false) if err != nil { t.Fatalf("Deleting key range: %v", err) } // Do some complex queries. tests := []struct { q string params queryParams want [][]interface{} }{ { `SELECT 17, "sweet", TRUE AND FALSE, NULL, B"hello"`, nil, [][]interface{}{{int64(17), "sweet", false, nil, []byte("hello")}}, }, { `SELECT Name FROM Staff WHERE Cool`, nil, [][]interface{}{{"Teal'c"}}, }, { `SELECT ID FROM Staff WHERE Cool IS NOT NULL ORDER BY ID DESC`, nil, [][]interface{}{{int64(4)}, {int64(3)}, {int64(2)}}, }, { `SELECT Name, Tenure FROM Staff WHERE Cool IS NULL OR Cool ORDER BY Name LIMIT 2`, nil, [][]interface{}{ {"George", int64(6)}, {"Jack", int64(10)}, }, }, { `SELECT Name, ID FROM Staff WHERE @min <= Tenure AND Tenure < @lim ORDER BY Cool, Name DESC LIMIT @numResults`, queryParams{"min": int64(9), "lim": int64(11), "numResults": "100"}, [][]interface{}{ {"Jack", int64(1)}, {"Sam", int64(3)}, }, }, { // Expression in SELECT list. `SELECT Name, Cool IS NOT NULL FROM Staff WHERE Tenure > 8 ORDER BY NOT Cool, Name`, nil, [][]interface{}{ {"Daniel", true}, // Daniel has Cool==true {"Jack", false}, // Jack has NULL Cool {"Sam", true}, // Sam has Cool==false }, }, { `SELECT Name, Height FROM Staff ORDER BY Height DESC LIMIT 2`, nil, [][]interface{}{ {"Teal'c", 1.91}, {"Jack", 1.85}, }, }, { `SELECT Name FROM Staff WHERE Name LIKE "J%k" OR Name LIKE "_am"`, nil, [][]interface{}{ {"Jack"}, {"Sam"}, }, }, { `SELECT Name, Height FROM Staff WHERE Height BETWEEN @min AND @max ORDER BY Height DESC`, queryParams{"min": 1.75, "max": 1.85}, [][]interface{}{ {"Jack", 1.85}, {"Daniel", 1.83}, {"Sam", 1.75}, }, }, { `SELECT COUNT(*) FROM Staff WHERE Name < "T"`, nil, [][]interface{}{ {int64(4)}, }, }, { `SELECT Name FROM Staff WHERE FirstSeen >= @min`, queryParams{"min": "1996-01-01"}, [][]interface{}{ {"George"}, }, }, } for _, test := range tests { q, err := spansql.ParseQuery(test.q) if err != nil { t.Errorf("ParseQuery(%q): %v", test.q, err) continue } ri, err := db.Query(q, test.params) if err != nil { t.Errorf("Query(%q, %v): %v", test.q, test.params, err) continue } all := slurp(ri) if !reflect.DeepEqual(all, test.want) { t.Errorf("Results from Query(%q, %v) are wrong.\n got %v\nwant %v", test.q, test.params, all, test.want) } } } func slurp(ri *resultIter) (all [][]interface{}) { for { row, ok := ri.Next() if !ok { return } all = append(all, row) } } func listV(vs ...*structpb.Value) *structpb.ListValue { return &structpb.ListValue{Values: vs} } func stringV(s string) *structpb.Value { return &structpb.Value{Kind: &structpb.Value_StringValue{s}} } func floatV(f float64) *structpb.Value { return &structpb.Value{Kind: &structpb.Value_NumberValue{f}} } func boolV(b bool) *structpb.Value { return &structpb.Value{Kind: &structpb.Value_BoolValue{b}} } func nullV() *structpb.Value { return &structpb.Value{Kind: &structpb.Value_NullValue{}} } func TestRowCmp(t *testing.T) { r := func(x ...interface{}) []interface{} { return x } tests := []struct { a, b []interface{} want int }{ {r(int64(1), "foo", 1.6), r(int64(1), "foo", 1.6), 0}, {r(int64(1), "foo"), r(int64(1), "foo", 1.6), 0}, // first is shorter {r(int64(1), "bar", 1.8), r(int64(1), "foo", 1.6), -1}, {r(int64(1), "foo", 1.6), r(int64(1), "bar", 1.8), 1}, } for _, test := range tests { if got := rowCmp(test.a, test.b); got != test.want { t.Errorf("rowCmp(%v, %v) = %d, want %d", test.a, test.b, got, test.want) } } } func TestKeyRange(t *testing.T) { r := func(x ...interface{}) []interface{} { return x } closedClosed := func(start, end []interface{}) *keyRange { return &keyRange{ startKey: start, endKey: end, startClosed: true, endClosed: true, } } halfOpen := func(start, end []interface{}) *keyRange { return &keyRange{ startKey: start, endKey: end, startClosed: true, } } openOpen := func(start, end []interface{}) *keyRange { return &keyRange{ startKey: start, endKey: end, } } tests := []struct { kr *keyRange include [][]interface{} exclude [][]interface{} }{ // Examples from google/spanner/v1/keys.proto. { kr: closedClosed(r("Bob", "2015-01-01"), r("Bob", "2015-12-31")), include: [][]interface{}{ r("Bob", "2015-01-01"), r("Bob", "2015-07-07"), r("Bob", "2015-12-31"), }, exclude: [][]interface{}{ r("Alice", "2015-07-07"), r("Bob", "2014-12-31"), r("Bob", "2016-01-01"), }, }, { kr: closedClosed(r("Bob", "2000-01-01"), r("Bob")), include: [][]interface{}{ r("Bob", "2000-01-01"), r("Bob", "2022-07-07"), }, exclude: [][]interface{}{ r("Alice", "2015-07-07"), r("Bob", "1999-11-07"), }, }, { kr: closedClosed(r("Bob"), r("Bob")), include: [][]interface{}{ r("Bob", "2000-01-01"), }, exclude: [][]interface{}{ r("Alice", "2015-07-07"), r("Charlie", "1999-11-07"), }, }, { kr: halfOpen(r("Bob"), r("Bob", "2000-01-01")), include: [][]interface{}{ r("Bob", "1999-11-07"), }, exclude: [][]interface{}{ r("Alice", "1999-11-07"), r("Bob", "2000-01-01"), r("Bob", "2004-07-07"), r("Charlie", "1999-11-07"), }, }, { kr: openOpen(r("Bob", "1999-11-06"), r("Bob", "2000-01-01")), include: [][]interface{}{ r("Bob", "1999-11-07"), }, exclude: [][]interface{}{ r("Alice", "1999-11-07"), r("Bob", "1999-11-06"), r("Bob", "2000-01-01"), r("Bob", "2004-07-07"), r("Charlie", "1999-11-07"), }, }, { kr: closedClosed(r(), r()), include: [][]interface{}{ r("Alice", "1999-11-07"), r("Bob", "1999-11-07"), r("Charlie", "1999-11-07"), }, }, { kr: halfOpen(r("A"), r("D")), include: [][]interface{}{ r("Alice", "1999-11-07"), r("Bob", "1999-11-07"), r("Charlie", "1999-11-07"), }, exclude: [][]interface{}{ r("0day", "1999-11-07"), r("Doris", "1999-11-07"), }, }, } for _, test := range tests { tbl := &table{ pkCols: 2, } for _, pk := range append(test.include, test.exclude...) { rowNum, _ := tbl.rowForPK(pk) tbl.insertRow(rowNum, pk) } start, end := tbl.findRange(test.kr) has := func(pk []interface{}) bool { n, _ := tbl.rowForPK(pk) return start <= n && n < end } for _, pk := range test.include { if !has(pk) { t.Errorf("keyRange %v does not include %v", test.kr, pk) } } for _, pk := range test.exclude { if has(pk) { t.Errorf("keyRange %v includes %v", test.kr, pk) } } } } google-cloud-go-0.49.0/spanner/spannertest/inmem.go000066400000000000000000000502771356504100700222530ustar00rootroot00000000000000/* Copyright 2019 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Package spannertest contains test helpers for working with Cloud Spanner. This package is EXPERIMENTAL, and is lacking many features. See the README.md file in this directory for more details. In-memory fake This package has an in-memory fake implementation of spanner. To use it, create a Server, and then connect to it with no security: srv, err := spannertest.NewServer("localhost:0") ... conn, err := grpc.DialContext(ctx, srv.Addr, grpc.WithInsecure()) ... client, err := spanner.NewClient(ctx, db, option.WithGRPCConn(conn)) ... Alternatively, create a Server, then set the SPANNER_EMULATOR_HOST environment variable and use the regular spanner.NewClient: srv, err := spannertest.NewServer("localhost:0") ... os.Setenv("SPANNER_EMULATOR_HOST", srv.Addr) client, err := spanner.NewClient(ctx, db) ... The same server also supports database admin operations for use with the cloud.google.com/go/spanner/admin/database/apiv1 package. */ package spannertest import ( "context" "encoding/base64" "fmt" "log" "math/rand" "net" "strconv" "sync" "time" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" anypb "github.com/golang/protobuf/ptypes/any" emptypb "github.com/golang/protobuf/ptypes/empty" structpb "github.com/golang/protobuf/ptypes/struct" timestamppb "github.com/golang/protobuf/ptypes/timestamp" lropb "google.golang.org/genproto/googleapis/longrunning" adminpb "google.golang.org/genproto/googleapis/spanner/admin/database/v1" spannerpb "google.golang.org/genproto/googleapis/spanner/v1" "cloud.google.com/go/spanner/spansql" ) // Server is an in-memory Cloud Spanner fake. // It is unauthenticated, non-performant, and only a rough approximation. type Server struct { Addr string l net.Listener srv *grpc.Server s *server } // server is the real implementation of the fake. // It is a separate and unexported type so the API won't be cluttered with // methods that are only relevant to the fake's implementation. type server struct { logf Logger db database mu sync.Mutex sessions map[string]*session lros map[string]*lro // Any unimplemented methods will cause a panic. // TODO: Switch to Unimplemented at some point? spannerpb would need regenerating. adminpb.DatabaseAdminServer spannerpb.SpannerServer lropb.OperationsServer } type session struct { name string creation time.Time // This context tracks the lifetime of this session. // It is canceled in DeleteSession. ctx context.Context cancel func() mu sync.Mutex lastUse time.Time transactions map[string]*transaction } func (s *session) Proto() *spannerpb.Session { s.mu.Lock() defer s.mu.Unlock() m := &spannerpb.Session{ Name: s.name, CreateTime: timestampProto(s.creation), ApproximateLastUseTime: timestampProto(s.lastUse), } return m } // timestampProto returns a valid timestamp.Timestamp, // or nil if the given time is zero or isn't representable. func timestampProto(t time.Time) *timestamppb.Timestamp { if t.IsZero() { return nil } ts, err := ptypes.TimestampProto(t) if err != nil { return nil } return ts } type transaction struct { // TODO: connect this with db.go. } func (t *transaction) Commit() error { return nil } func (t *transaction) Rollback() error { return nil } func (t *transaction) finish() { } // lro represents a Long-Running Operation, generally a schema change. type lro struct { mu sync.Mutex state *lropb.Operation } func (l *lro) State() *lropb.Operation { l.mu.Lock() defer l.mu.Unlock() return proto.Clone(l.state).(*lropb.Operation) } // Logger is something that can be used for logging. // It is matched by log.Printf and testing.T.Logf. type Logger func(format string, args ...interface{}) // NewServer creates a new Server. // The Server will be listening for gRPC connections, without TLS, on the provided TCP address. // The resolved address is available in the Addr field. func NewServer(laddr string) (*Server, error) { l, err := net.Listen("tcp", laddr) if err != nil { return nil, err } s := &Server{ Addr: l.Addr().String(), l: l, srv: grpc.NewServer(), s: &server{ logf: func(format string, args ...interface{}) { log.Printf("spannertest.inmem: "+format, args...) }, sessions: make(map[string]*session), lros: make(map[string]*lro), }, } adminpb.RegisterDatabaseAdminServer(s.srv, s.s) spannerpb.RegisterSpannerServer(s.srv, s.s) lropb.RegisterOperationsServer(s.srv, s.s) go s.srv.Serve(s.l) return s, nil } // SetLogger sets a logger for the server. // You can use a *testing.T as this argument to collate extra information // from the execution of the server. func (s *Server) SetLogger(l Logger) { s.s.logf = l } // Close shuts down the server. func (s *Server) Close() { s.srv.Stop() s.l.Close() } func genRandomSession() string { var b [4]byte rand.Read(b[:]) return fmt.Sprintf("%x", b) } func genRandomTransaction() string { var b [6]byte rand.Read(b[:]) return fmt.Sprintf("tx-%x", b) } func genRandomOperation() string { var b [3]byte rand.Read(b[:]) return fmt.Sprintf("op-%x", b) } func (s *server) GetOperation(ctx context.Context, req *lropb.GetOperationRequest) (*lropb.Operation, error) { s.mu.Lock() lro, ok := s.lros[req.Name] s.mu.Unlock() if !ok { return nil, status.Errorf(codes.NotFound, "unknown LRO %q", req.Name) } return lro.State(), nil } // UpdateDDL applies the given DDL to the server. // // This is a convenience method for tests that may assume an existing schema. // The more general approach is to dial this server using an admin client, and // use the UpdateDatabaseDdl RPC method. func (s *Server) UpdateDDL(ddl spansql.DDL) error { ctx := context.Background() for _, stmt := range ddl.List { if st := s.s.runOneDDL(ctx, stmt); st.Code() != codes.OK { return st.Err() } } return nil } func (s *server) UpdateDatabaseDdl(ctx context.Context, req *adminpb.UpdateDatabaseDdlRequest) (*lropb.Operation, error) { // Parse all the DDL statements first. var stmts []spansql.DDLStmt for _, s := range req.Statements { stmt, err := spansql.ParseDDLStmt(s) if err != nil { // TODO: check what code the real Spanner returns here. return nil, status.Errorf(codes.InvalidArgument, "bad DDL statement %q: %v", s, err) } stmts = append(stmts, stmt) } // Nothing should be depending on the exact structure of this, // but it is specified in google/spanner/admin/database/v1/spanner_database_admin.proto. id := "projects/fake-proj/instances/fake-instance/databases/fake-db/operations/" + genRandomOperation() lro := &lro{ state: &lropb.Operation{ Name: id, }, } s.mu.Lock() s.lros[id] = lro s.mu.Unlock() go lro.Run(s, stmts) return lro.State(), nil } func (l *lro) Run(s *server, stmts []spansql.DDLStmt) { ctx := context.Background() for _, stmt := range stmts { time.Sleep(100 * time.Millisecond) if st := s.runOneDDL(ctx, stmt); st.Code() != codes.OK { l.mu.Lock() l.state.Done = true l.state.Result = &lropb.Operation_Error{st.Proto()} l.mu.Unlock() return } } l.mu.Lock() l.state.Done = true l.state.Result = &lropb.Operation_Response{&anypb.Any{}} l.mu.Unlock() } func (s *server) runOneDDL(ctx context.Context, stmt spansql.DDLStmt) *status.Status { return s.db.ApplyDDL(stmt) } func (s *server) CreateSession(ctx context.Context, req *spannerpb.CreateSessionRequest) (*spannerpb.Session, error) { //s.logf("CreateSession(%q)", req.Database) return s.newSession(), nil } func (s *server) newSession() *spannerpb.Session { id := genRandomSession() now := time.Now() sess := &session{ name: id, creation: now, lastUse: now, transactions: make(map[string]*transaction), } sess.ctx, sess.cancel = context.WithCancel(context.Background()) s.mu.Lock() s.sessions[id] = sess s.mu.Unlock() return sess.Proto() } func (s *server) BatchCreateSessions(ctx context.Context, req *spannerpb.BatchCreateSessionsRequest) (*spannerpb.BatchCreateSessionsResponse, error) { //s.logf("BatchCreateSessions(%q)", req.Database) var sessions []*spannerpb.Session for i := int32(0); i < req.GetSessionCount(); i++ { sessions = append(sessions, s.newSession()) } return &spannerpb.BatchCreateSessionsResponse{Session: sessions}, nil } func (s *server) GetSession(ctx context.Context, req *spannerpb.GetSessionRequest) (*spannerpb.Session, error) { s.mu.Lock() sess, ok := s.sessions[req.Name] s.mu.Unlock() if !ok { // TODO: what error does the real Spanner return? return nil, status.Errorf(codes.NotFound, "unknown session %q", req.Name) } return sess.Proto(), nil } // TODO: ListSessions func (s *server) DeleteSession(ctx context.Context, req *spannerpb.DeleteSessionRequest) (*emptypb.Empty, error) { //s.logf("DeleteSession(%q)", req.Name) s.mu.Lock() sess, ok := s.sessions[req.Name] delete(s.sessions, req.Name) s.mu.Unlock() if !ok { // TODO: what error does the real Spanner return? return nil, status.Errorf(codes.NotFound, "unknown session %q", req.Name) } // Terminate any operations in this session. sess.cancel() return &emptypb.Empty{}, nil } // popTx returns an existing transaction, removing it from the session. // This is called when a transaction is finishing (Commit, Rollback). func (s *server) popTx(sessionID, tid string) (tx *transaction, cleanup func(), err error) { s.mu.Lock() sess, ok := s.sessions[sessionID] s.mu.Unlock() if !ok { // TODO: what error does the real Spanner return? return nil, nil, status.Errorf(codes.NotFound, "unknown session %q", sessionID) } sess.mu.Lock() sess.lastUse = time.Now() tx, ok = sess.transactions[tid] if ok { delete(sess.transactions, tid) } sess.mu.Unlock() if !ok { // TODO: what error does the real Spanner return? return nil, nil, status.Errorf(codes.NotFound, "unknown transaction ID %q", tid) } return tx, tx.finish, nil } // readTx returns a transaction for the given session and transaction selector. // It is used by read/query operations (ExecuteStreamingSql, StreamingRead). func (s *server) readTx(ctx context.Context, session string, tsel *spannerpb.TransactionSelector) (tx *transaction, cleanup func(), err error) { s.mu.Lock() sess, ok := s.sessions[session] s.mu.Unlock() if !ok { // TODO: what error does the real Spanner return? return nil, nil, status.Errorf(codes.NotFound, "unknown session %q", session) } sess.mu.Lock() sess.lastUse = time.Now() sess.mu.Unlock() singleUse := func() (*transaction, func(), error) { tx := &transaction{} return tx, tx.finish, nil } singleUseReadOnly := func() (*transaction, func(), error) { // TODO: figure out a way to make this read-only. return singleUse() } if tsel.GetSelector() == nil { return singleUseReadOnly() } switch sel := tsel.Selector.(type) { default: return nil, nil, fmt.Errorf("TransactionSelector type %T not supported", sel) case *spannerpb.TransactionSelector_SingleUse: // Ignore options (e.g. timestamps). switch mode := sel.SingleUse.Mode.(type) { case *spannerpb.TransactionOptions_ReadOnly_: return singleUseReadOnly() case *spannerpb.TransactionOptions_ReadWrite_: return singleUse() default: return nil, nil, fmt.Errorf("single use transaction in mode %T not supported", mode) } case *spannerpb.TransactionSelector_Id: id := sel.Id // []byte _ = id // TODO: lookup an existing transaction by ID. tx := &transaction{} return tx, tx.finish, nil } } func (s *server) ExecuteSql(ctx context.Context, req *spannerpb.ExecuteSqlRequest) (*spannerpb.ResultSet, error) { return nil, status.Errorf(codes.Unimplemented, "ExecuteSql not implemented yet") } func (s *server) ExecuteStreamingSql(req *spannerpb.ExecuteSqlRequest, stream spannerpb.Spanner_ExecuteStreamingSqlServer) error { tx, cleanup, err := s.readTx(stream.Context(), req.Session, req.Transaction) if err != nil { return err } defer cleanup() q, err := spansql.ParseQuery(req.Sql) if err != nil { // TODO: check what code the real Spanner returns here. return status.Errorf(codes.InvalidArgument, "bad query: %v", err) } params := make(queryParams) for k, v := range req.GetParams().GetFields() { switch v := v.Kind.(type) { default: return fmt.Errorf("unsupported well-known type value kind %T", v) case *structpb.Value_NullValue: params[k] = nil case *structpb.Value_NumberValue: params[k] = v.NumberValue case *structpb.Value_StringValue: params[k] = v.StringValue } } s.logf("Querying: %s", q.SQL()) if len(params) > 0 { s.logf(" â–¹ %v", params) } ri, err := s.db.Query(q, params) if err != nil { return err } return s.readStream(stream.Context(), tx, stream.Send, ri) } // TODO: Read func (s *server) StreamingRead(req *spannerpb.ReadRequest, stream spannerpb.Spanner_StreamingReadServer) error { tx, cleanup, err := s.readTx(stream.Context(), req.Session, req.Transaction) if err != nil { return err } defer cleanup() // Bail out if various advanced features are being used. if req.Index != "" { return fmt.Errorf("index reads (%q) not supported", req.Index) } if len(req.ResumeToken) > 0 { // This should only happen if we send resume_token ourselves. return fmt.Errorf("read resumption not supported") } if len(req.PartitionToken) > 0 { return fmt.Errorf("partition restrictions not supported") } // TODO: other KeySet types. if len(req.KeySet.Ranges) > 0 { return fmt.Errorf("reading with ranges not supported") } var ri *resultIter if req.KeySet.All { s.logf("Reading all from %s (cols: %v)", req.Table, req.Columns) ri, err = s.db.ReadAll(req.Table, req.Columns, req.Limit) } else { s.logf("Reading %d rows from from %s (cols: %v)", len(req.KeySet.Keys), req.Table, req.Columns) ri, err = s.db.Read(req.Table, req.Columns, req.KeySet.Keys, req.Limit) } if err != nil { return err } // TODO: Figure out the right contexts to use here. There's the session one (sess.ctx), // but also this specific RPC one (stream.Context()). Which takes precedence? // They appear to be independent. return s.readStream(stream.Context(), tx, stream.Send, ri) } func (s *server) readStream(ctx context.Context, tx *transaction, send func(*spannerpb.PartialResultSet) error, ri *resultIter) error { // Build the result set metadata. rsm := &spannerpb.ResultSetMetadata{ RowType: &spannerpb.StructType{}, // TODO: transaction info? } for _, ci := range ri.Cols { st, err := spannerTypeFromType(ci.Type) if err != nil { return err } rsm.RowType.Fields = append(rsm.RowType.Fields, &spannerpb.StructType_Field{ Name: ci.Name, Type: st, }) } for { row, ok := ri.Next() if !ok { break } values := make([]*structpb.Value, len(row)) for i, x := range row { v, err := spannerValueFromValue(x) if err != nil { return err } values[i] = v } prs := &spannerpb.PartialResultSet{ Metadata: rsm, Values: values, } if err := send(prs); err != nil { return err } // ResultSetMetadata is only set for the first PartialResultSet. rsm = nil } return nil } func (s *server) BeginTransaction(ctx context.Context, req *spannerpb.BeginTransactionRequest) (*spannerpb.Transaction, error) { //s.logf("BeginTransaction(%v)", req) s.mu.Lock() sess, ok := s.sessions[req.Session] s.mu.Unlock() if !ok { // TODO: what error does the real Spanner return? return nil, status.Errorf(codes.NotFound, "unknown session %q", req.Session) } id := genRandomTransaction() tx := &transaction{} sess.mu.Lock() sess.lastUse = time.Now() sess.transactions[id] = tx sess.mu.Unlock() return &spannerpb.Transaction{Id: []byte(id)}, nil } func (s *server) Commit(ctx context.Context, req *spannerpb.CommitRequest) (*spannerpb.CommitResponse, error) { //s.logf("Commit(%q, %q)", req.Session, req.Transaction) obj, ok := req.Transaction.(*spannerpb.CommitRequest_TransactionId) if !ok { return nil, fmt.Errorf("unsupported transaction type %T", req.Transaction) } tid := string(obj.TransactionId) tx, cleanup, err := s.popTx(req.Session, tid) if err != nil { return nil, err } defer cleanup() for _, m := range req.Mutations { switch op := m.Operation.(type) { default: return nil, fmt.Errorf("unsupported mutation operation type %T", op) case *spannerpb.Mutation_Insert: ins := op.Insert err := s.db.Insert(ins.Table, ins.Columns, ins.Values) if err != nil { return nil, err } case *spannerpb.Mutation_Update: up := op.Update err := s.db.Update(up.Table, up.Columns, up.Values) if err != nil { return nil, err } case *spannerpb.Mutation_InsertOrUpdate: iou := op.InsertOrUpdate err := s.db.InsertOrUpdate(iou.Table, iou.Columns, iou.Values) if err != nil { return nil, err } case *spannerpb.Mutation_Delete_: del := op.Delete ks := del.KeySet err := s.db.Delete(del.Table, ks.Keys, makeKeyRangeList(ks.Ranges), ks.All) if err != nil { return nil, err } } } if err := tx.Commit(); err != nil { return nil, err } // TODO: return timestamp? return &spannerpb.CommitResponse{}, nil } func (s *server) Rollback(ctx context.Context, req *spannerpb.RollbackRequest) (*emptypb.Empty, error) { s.logf("Rollback(%v)", req) tx, cleanup, err := s.popTx(req.Session, string(req.TransactionId)) if err != nil { return nil, err } defer cleanup() if err := tx.Rollback(); err != nil { return nil, err } return &emptypb.Empty{}, nil } // TODO: PartitionQuery, PartitionRead func spannerTypeFromType(typ spansql.Type) (*spannerpb.Type, error) { var code spannerpb.TypeCode switch typ.Base { default: return nil, fmt.Errorf("unhandled base type %d", typ.Base) case spansql.Bool: code = spannerpb.TypeCode_BOOL case spansql.Int64: code = spannerpb.TypeCode_INT64 case spansql.Float64: code = spannerpb.TypeCode_FLOAT64 case spansql.String: code = spannerpb.TypeCode_STRING case spansql.Bytes: code = spannerpb.TypeCode_BYTES case spansql.Date: code = spannerpb.TypeCode_DATE } st := &spannerpb.Type{Code: code} if typ.Array { st = &spannerpb.Type{ Code: spannerpb.TypeCode_ARRAY, ArrayElementType: st, } } return st, nil } func spannerValueFromValue(x interface{}) (*structpb.Value, error) { switch x := x.(type) { default: return nil, fmt.Errorf("unhandled database value type %T", x) case bool: return &structpb.Value{Kind: &structpb.Value_BoolValue{x}}, nil case int64: // The Spanner int64 is actually a decimal string. s := strconv.FormatInt(x, 10) return &structpb.Value{Kind: &structpb.Value_StringValue{s}}, nil case float64: return &structpb.Value{Kind: &structpb.Value_NumberValue{x}}, nil case string: return &structpb.Value{Kind: &structpb.Value_StringValue{x}}, nil case []byte: return &structpb.Value{Kind: &structpb.Value_StringValue{base64.StdEncoding.EncodeToString(x)}}, nil case nil: return &structpb.Value{Kind: &structpb.Value_NullValue{}}, nil case []interface{}: var vs []*structpb.Value for _, elem := range x { v, err := spannerValueFromValue(elem) if err != nil { return nil, err } vs = append(vs, v) } return &structpb.Value{Kind: &structpb.Value_ListValue{ &structpb.ListValue{Values: vs}, }}, nil } } func makeKeyRangeList(ranges []*spannerpb.KeyRange) keyRangeList { var krl keyRangeList for _, r := range ranges { krl = append(krl, makeKeyRange(r)) } return krl } func makeKeyRange(r *spannerpb.KeyRange) *keyRange { var kr keyRange switch s := r.StartKeyType.(type) { case *spannerpb.KeyRange_StartClosed: kr.start = s.StartClosed kr.startClosed = true case *spannerpb.KeyRange_StartOpen: kr.start = s.StartOpen } switch e := r.EndKeyType.(type) { case *spannerpb.KeyRange_EndClosed: kr.end = e.EndClosed kr.endClosed = true case *spannerpb.KeyRange_EndOpen: kr.end = e.EndOpen } return &kr } google-cloud-go-0.49.0/spanner/spannertest/integration_test.go000066400000000000000000000257261356504100700245310ustar00rootroot00000000000000/* Copyright 2019 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* This file holds tests for the in-memory fake for comparing it against a real Cloud Spanner. By default it uses the Spanner client against the in-memory fake; set the -test_db flag to "projects/P/instances/I/databases/D" to make it use a real Cloud Spanner database instead. You may need to provide -timeout=5m too. */ package spannertest import ( "context" "flag" "reflect" "testing" "time" "cloud.google.com/go/spanner" dbadmin "cloud.google.com/go/spanner/admin/database/apiv1" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" dbadminpb "google.golang.org/genproto/googleapis/spanner/admin/database/v1" ) var testDBFlag = flag.String("test_db", "", "Fully-qualified database name to test against; empty means use an in-memory fake.") func dbName() string { if *testDBFlag != "" { return *testDBFlag } return "projects/fake-proj/instances/fake-instance/databases/fake-db" } func makeClient(t *testing.T) (*spanner.Client, *dbadmin.DatabaseAdminClient, func()) { // Despite the docs, this context is also used for auth, // so it needs to be long-lived. ctx := context.Background() if *testDBFlag != "" { t.Logf("Using real Spanner DB %s", *testDBFlag) dialOpt := option.WithGRPCDialOption(grpc.WithTimeout(5 * time.Second)) client, err := spanner.NewClient(ctx, *testDBFlag, dialOpt) if err != nil { t.Fatalf("Connecting to %s: %v", *testDBFlag, err) } adminClient, err := dbadmin.NewDatabaseAdminClient(ctx, dialOpt) if err != nil { client.Close() t.Fatalf("Connecting DB admin client: %v", err) } return client, adminClient, func() { client.Close(); adminClient.Close() } } // Don't use SPANNER_EMULATOR_HOST because we need the raw connection for // the database admin client anyway. t.Logf("Using in-memory fake Spanner DB") srv, err := NewServer("localhost:0") if err != nil { t.Fatalf("Starting in-memory fake: %v", err) } srv.SetLogger(t.Logf) dialCtx, cancel := context.WithTimeout(ctx, 1*time.Second) defer cancel() conn, err := grpc.DialContext(dialCtx, srv.Addr, grpc.WithInsecure()) if err != nil { srv.Close() t.Fatalf("Dialing in-memory fake: %v", err) } client, err := spanner.NewClient(ctx, dbName(), option.WithGRPCConn(conn)) if err != nil { srv.Close() t.Fatalf("Connecting to in-memory fake: %v", err) } adminClient, err := dbadmin.NewDatabaseAdminClient(ctx, option.WithGRPCConn(conn)) if err != nil { srv.Close() t.Fatalf("Connecting to in-memory fake DB admin: %v", err) } return client, adminClient, func() { client.Close() adminClient.Close() conn.Close() srv.Close() } } func TestIntegration_SpannerBasics(t *testing.T) { client, adminClient, cleanup := makeClient(t) defer cleanup() ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() // Do a trivial query to verify the connection works. it := client.Single().Query(ctx, spanner.NewStatement("SELECT 1")) row, err := it.Next() if err != nil { t.Fatalf("Getting first row of trivial query: %v", err) } var value int64 if err := row.Column(0, &value); err != nil { t.Fatalf("Decoding row data from trivial query: %v", err) } if value != 1 { t.Errorf("Trivial query gave %d, want 1", value) } // There shouldn't be a next row. _, err = it.Next() if err != iterator.Done { t.Errorf("Reading second row of trivial query gave %v, want iterator.Done", err) } it.Stop() // Drop any previous test table/index, and make a fresh one in a few stages. const tableName = "Characters" err = updateDDL(t, adminClient, "DROP INDEX AgeIndex") // NotFound is an acceptable failure mode here. if st, _ := status.FromError(err); st.Code() == codes.NotFound { err = nil } if err != nil { t.Fatalf("Dropping old index: %v", err) } err = updateDDL(t, adminClient, "DROP TABLE "+tableName) // NotFound is an acceptable failure mode here. if st, _ := status.FromError(err); st.Code() == codes.NotFound { err = nil } if err != nil { t.Fatalf("Dropping old table: %v", err) } err = updateDDL(t, adminClient, `CREATE TABLE `+tableName+` ( FirstName STRING(20) NOT NULL, LastName STRING(20) NOT NULL, Alias STRING(MAX), ) PRIMARY KEY (FirstName, LastName)`) if err != nil { t.Fatalf("Setting up fresh table: %v", err) } err = updateDDL(t, adminClient, `ALTER TABLE `+tableName+` ADD COLUMN Age INT64`, `CREATE INDEX AgeIndex ON `+tableName+` (Age DESC)`) if err != nil { t.Fatalf("Adding new column: %v", err) } // Insert some data. _, err = client.Apply(ctx, []*spanner.Mutation{ spanner.Insert(tableName, []string{"FirstName", "LastName", "Alias", "Age"}, []interface{}{"Steve", "Rogers", "Captain America", 101}), spanner.Insert(tableName, []string{"LastName", "FirstName", "Age", "Alias"}, []interface{}{"Romanoff", "Natasha", 35, "Black Widow"}), spanner.Insert(tableName, []string{"Age", "Alias", "FirstName", "LastName"}, []interface{}{49, "Iron Man", "Tony", "Stark"}), spanner.Insert(tableName, []string{"FirstName", "Alias", "LastName"}, // no Age []interface{}{"Clark", "Superman", "Kent"}), // Two rows with the same value in one column, // but with distinct primary keys. spanner.Insert(tableName, []string{"FirstName", "LastName", "Alias"}, []interface{}{"Peter", "Parker", "Spider-Man"}), spanner.Insert(tableName, []string{"FirstName", "LastName", "Alias"}, []interface{}{"Peter", "Quill", "Star-Lord"}), }) if err != nil { t.Fatalf("Applying mutations: %v", err) } // Delete some data. _, err = client.Apply(ctx, []*spanner.Mutation{ // Whoops. DC, not MCU. spanner.Delete(tableName, spanner.Key{"Clark", "Kent"}), }) if err != nil { t.Fatalf("Applying mutations: %v", err) } // Read a single row. row, err = client.Single().ReadRow(ctx, tableName, spanner.Key{"Tony", "Stark"}, []string{"Alias", "Age"}) if err != nil { t.Fatalf("Reading single row: %v", err) } var alias string var age int64 if err := row.Columns(&alias, &age); err != nil { t.Fatalf("Decoding single row: %v", err) } if alias != "Iron Man" || age != 49 { t.Errorf(`Single row read gave (%q, %d), want ("Iron Man", 49)`, alias, age) } // Read all rows, and do a local age sum. rows := client.Single().Read(ctx, tableName, spanner.AllKeys(), []string{"Age"}) var ageSum int64 err = rows.Do(func(row *spanner.Row) error { var age spanner.NullInt64 if err := row.Columns(&age); err != nil { return err } if age.Valid { ageSum += age.Int64 } return nil }) if err != nil { t.Fatalf("Iterating over all row read: %v", err) } if want := int64(101 + 35 + 49); ageSum != want { t.Errorf("Age sum after iterating over all rows = %d, want %d", ageSum, want) } // Do a more complex query to find the aliases of the two oldest non-centenarian characters. stmt := spanner.NewStatement(`SELECT Alias FROM ` + tableName + ` WHERE Age < @ageLimit AND Alias IS NOT NULL ORDER BY Age DESC LIMIT @limit`) stmt.Params = map[string]interface{}{ "ageLimit": 100, "limit": 2, } rows = client.Single().Query(ctx, stmt) var oldFolk []string err = rows.Do(func(row *spanner.Row) error { var alias string if err := row.Columns(&alias); err != nil { return err } oldFolk = append(oldFolk, alias) return nil }) if err != nil { t.Fatalf("Iterating over complex query: %v", err) } if want := []string{"Iron Man", "Black Widow"}; !reflect.DeepEqual(oldFolk, want) { t.Errorf("Complex query results = %v, want %v", oldFolk, want) } // Apply an update. _, err = client.Apply(ctx, []*spanner.Mutation{ spanner.Update(tableName, []string{"FirstName", "LastName", "Age"}, []interface{}{"Steve", "Rogers", 102}), }) if err != nil { t.Fatalf("Applying mutations: %v", err) } row, err = client.Single().ReadRow(ctx, tableName, spanner.Key{"Steve", "Rogers"}, []string{"Age"}) if err != nil { t.Fatalf("Reading single row: %v", err) } if err := row.Columns(&age); err != nil { t.Fatalf("Decoding single row: %v", err) } if age != 102 { t.Errorf("After updating Captain America, age = %d, want 102", age) } // Do a query where the result type isn't deducible from the first row. stmt = spanner.NewStatement(`SELECT Age FROM ` + tableName + ` WHERE FirstName = "Peter"`) rows = client.Single().Query(ctx, stmt) var nullPeters int err = rows.Do(func(row *spanner.Row) error { var age spanner.NullInt64 if err := row.Column(0, &age); err != nil { return err } if age.Valid { t.Errorf("Got non-NULL Age %d for a Peter", age.Int64) } else { nullPeters++ } return nil }) if err != nil { t.Fatalf("Counting Peters with NULL Ages: %v", err) } if nullPeters != 2 { t.Errorf("Found %d Peters with NULL Ages, want 2", nullPeters) } // Check handling of array types. err = updateDDL(t, adminClient, `ALTER TABLE `+tableName+` ADD COLUMN Allies ARRAY`) if err != nil { t.Fatalf("Adding new array-typed column: %v", err) } _, err = client.Apply(ctx, []*spanner.Mutation{ spanner.Update(tableName, []string{"FirstName", "LastName", "Allies"}, []interface{}{"Steve", "Rogers", []string{}}), spanner.Update(tableName, []string{"FirstName", "LastName", "Allies"}, []interface{}{"Tony", "Stark", []string{"Black Widow", "Spider-Man"}}), }) if err != nil { t.Fatalf("Applying mutations: %v", err) } row, err = client.Single().ReadRow(ctx, tableName, spanner.Key{"Tony", "Stark"}, []string{"Allies"}) if err != nil { t.Fatalf("Reading row with array value: %v", err) } var names []string if err := row.Column(0, &names); err != nil { t.Fatalf("Unpacking array value: %v", err) } if want := []string{"Black Widow", "Spider-Man"}; !reflect.DeepEqual(names, want) { t.Errorf("Read array value: got %q, want %q", names, want) } row, err = client.Single().ReadRow(ctx, tableName, spanner.Key{"Steve", "Rogers"}, []string{"Allies"}) if err != nil { t.Fatalf("Reading row with empty array value: %v", err) } if err := row.Column(0, &names); err != nil { t.Fatalf("Unpacking empty array value: %v", err) } if len(names) > 0 { t.Errorf("Read empty array value: got %q", names) } } func updateDDL(t *testing.T, adminClient *dbadmin.DatabaseAdminClient, statements ...string) error { t.Helper() ctx := context.Background() t.Logf("DDL update: %q", statements) op, err := adminClient.UpdateDatabaseDdl(ctx, &dbadminpb.UpdateDatabaseDdlRequest{ Database: dbName(), Statements: statements, }) if err != nil { t.Fatalf("Starting DDL update: %v", err) } return op.Wait(ctx) } google-cloud-go-0.49.0/spanner/spansql/000077500000000000000000000000001356504100700177175ustar00rootroot00000000000000google-cloud-go-0.49.0/spanner/spansql/parser.go000066400000000000000000001121011356504100700215360ustar00rootroot00000000000000/* Copyright 2019 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Package spansql contains types and a parser for the Cloud Spanner SQL dialect. To parse, use one of the Parse functions (ParseDDL, ParseDDLStmt, ParseQuery, etc.). Sources: https://cloud.google.com/spanner/docs/lexical https://cloud.google.com/spanner/docs/query-syntax https://cloud.google.com/spanner/docs/data-definition-language */ package spansql /* This file is structured as follows: - There are several exported ParseFoo functions that accept an input string and return a type defined in types.go. This is the principal API of this package. These functions are implemented as wrappers around the lower-level functions, with additional checks to ensure things such as input exhaustion. - The token and parser types are defined. These constitute the lexical token and parser machinery. parser.next is the main way that other functions get the next token, with parser.back providing a single token rewind, and parser.sniff, parser.eat and parser.expect providing lookahead helpers. - The parseFoo methods are defined, matching the SQL grammar. Each consumes its namesake production from the parser. There are also some fooParser helper vars defined that abbreviate the parsing of some of the regular productions. */ import ( "fmt" "io" "os" "strconv" "strings" "unicode/utf8" ) const debug = false func debugf(format string, args ...interface{}) { if !debug { return } fmt.Fprintf(os.Stderr, "spansql debug: "+format+"\n", args...) } // ParseDDL parses a DDL file. func ParseDDL(s string) (DDL, error) { p := newParser(s) var ddl DDL for { p.skipSpace() if p.done { break } stmt, err := p.parseDDLStmt() if err != nil { return DDL{}, err } ddl.List = append(ddl.List, stmt) tok := p.next() if tok.err == io.EOF { break } else if tok.err != nil { return DDL{}, tok.err } if tok.value == ";" { continue } else { return DDL{}, p.errorf("unexpected token %q", tok.value) } } if p.Rem() != "" { return DDL{}, fmt.Errorf("unexpected trailing contents %q", p.Rem()) } return ddl, nil } // ParseDDLStmt parses a single DDL statement. func ParseDDLStmt(s string) (DDLStmt, error) { p := newParser(s) stmt, err := p.parseDDLStmt() if err != nil { return nil, err } if p.Rem() != "" { return nil, fmt.Errorf("unexpected trailing contents %q", p.Rem()) } return stmt, nil } // ParseQuery parses a query string. func ParseQuery(s string) (Query, error) { p := newParser(s) q, err := p.parseQuery() if err != nil { return Query{}, err } if p.Rem() != "" { return Query{}, fmt.Errorf("unexpected trailing query contents %q", p.Rem()) } return q, nil } type token struct { value string err error typ tokenType int64 int64 float64 float64 string string // unquoted form } type tokenType int const ( unknownToken tokenType = iota int64Token float64Token stringToken bytesToken ) func (t *token) String() string { if t.err != nil { return fmt.Sprintf("parse error: %v", t.err) } return strconv.Quote(t.value) } type parser struct { s string // Remaining input. done bool // Whether the parsing is finished (success or error). backed bool // Whether back() was called. cur token } func newParser(s string) *parser { return &parser{ s: s, } } // Rem returns the unparsed remainder, ignoring space. func (p *parser) Rem() string { rem := p.s if p.backed { rem = p.cur.value + rem } i := 0 for ; i < len(rem); i++ { if !isSpace(rem[i]) { break } } return rem[i:] } func (p *parser) String() string { if p.backed { return fmt.Sprintf("next tok: %s (rem: %q)", &p.cur, p.s) } return fmt.Sprintf("rem: %q", p.s) } func (p *parser) errorf(format string, args ...interface{}) error { err := fmt.Errorf(format, args...) p.cur.err = err p.done = true return err } func isInitialIdentifierChar(c byte) bool { // https://cloud.google.com/spanner/docs/lexical#identifiers switch { case 'A' <= c && c <= 'Z': return true case 'a' <= c && c <= 'z': return true case c == '_': return true } return false } func isIdentifierChar(c byte) bool { // https://cloud.google.com/spanner/docs/lexical#identifiers // This doesn't apply the restriction that an identifier cannot start with [0-9], // nor does it check against reserved keywords. switch { case 'A' <= c && c <= 'Z': return true case 'a' <= c && c <= 'z': return true case '0' <= c && c <= '9': return true case c == '_': return true } return false } func isHexDigit(c byte) bool { return '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' } func isOctalDigit(c byte) bool { return '0' <= c && c <= '7' } func (p *parser) consumeNumber() { /* int64_value: { decimal_value | hex_value } decimal_value: [-]0—9+ hex_value: [-]0[xX]{0—9|a—f|A—F}+ (float64_value is not formally specified) float64_value := [+-]DIGITS.[DIGITS][e[+-]DIGITS] | [DIGITS].DIGITS[e[+-]DIGITS] | DIGITSe[+-]DIGITS */ i, neg, base := 0, false, 10 float, e, dot := false, false, false if p.s[i] == '-' { neg = true i++ } else if p.s[i] == '+' { // This isn't in the formal grammar, but is mentioned informally. // https://cloud.google.com/spanner/docs/lexical#integer-literals i++ } if strings.HasPrefix(p.s[i:], "0x") || strings.HasPrefix(p.s[i:], "0X") { base = 16 i += 2 } d0 := i digitLoop: for i < len(p.s) { switch c := p.s[i]; { case '0' <= c && c <= '9': i++ case base == 16 && 'A' <= c && c <= 'F': i++ case base == 16 && 'a' <= c && c <= 'f': i++ case base == 10 && (c == 'e' || c == 'E'): if e { p.errorf("bad token %q", p.s[:i]) return } // Switch to consuming float. float, e = true, true i++ if i < len(p.s) && (p.s[i] == '+' || p.s[i] == '-') { i++ } case base == 10 && c == '.': if dot || e { // any dot must come before E p.errorf("bad token %q", p.s[:i]) return } // Switch to consuming float. float, dot = true, true i++ default: break digitLoop } } if d0 == i { p.errorf("no digits in numeric literal") return } sign := "" if neg { sign = "-" } p.cur.value, p.s = p.s[:i], p.s[i:] var err error if float { p.cur.typ = float64Token p.cur.float64, err = strconv.ParseFloat(sign+p.cur.value[d0:], 64) } else { p.cur.typ = int64Token p.cur.int64, err = strconv.ParseInt(sign+p.cur.value[d0:], base, 64) } if err != nil { p.errorf("bad numeric literal %q: %v", p.cur.value, err) } } func (p *parser) consumeString() { // https://cloud.google.com/spanner/docs/lexical#string-and-bytes-literals delim := p.stringDelimiter() if p.cur.err != nil { return } p.cur.string, p.cur.err = p.consumeStringContent(delim, false, true, "string literal") p.cur.typ = stringToken } func (p *parser) consumeRawString() { // https://cloud.google.com/spanner/docs/lexical#string-and-bytes-literals p.s = p.s[1:] // consume 'R' delim := p.stringDelimiter() if p.cur.err != nil { return } p.cur.string, p.cur.err = p.consumeStringContent(delim, true, true, "raw string literal") p.cur.typ = stringToken } func (p *parser) consumeBytes() { // https://cloud.google.com/spanner/docs/lexical#string-and-bytes-literals p.s = p.s[1:] // consume 'B' delim := p.stringDelimiter() if p.cur.err != nil { return } p.cur.string, p.cur.err = p.consumeStringContent(delim, false, false, "bytes literal") p.cur.typ = bytesToken } func (p *parser) consumeRawBytes() { // https://cloud.google.com/spanner/docs/lexical#string-and-bytes-literals p.s = p.s[2:] // consume 'RB' delim := p.stringDelimiter() if p.cur.err != nil { return } p.cur.string, p.cur.err = p.consumeStringContent(delim, true, false, "raw bytes literal") p.cur.typ = bytesToken } // stringDelimiter returns the opening string delimiter. func (p *parser) stringDelimiter() string { c := p.s[0] if c != '"' && c != '\'' { p.errorf("invalid string literal") return "" } // Look for triple. if len(p.s) >= 3 && p.s[1] == c && p.s[2] == c { return p.s[:3] } return p.s[:1] } // consumeStringContent consumes a string-like literal, including its delimiters. // // - delim is opening delimiter. // - raw is true on consuming raw string, otherwise it is false. // - unicode is true if unicode escape sequence (\uXXXX or \UXXXXXXXX), otherwise it is false. // - name is current consuming token name. // // It is designed for consuming string, bytes literals, and also backquoted identifiers. func (p *parser) consumeStringContent(delim string, raw, unicode bool, name string) (string, error) { // https://cloud.google.com/spanner/docs/lexical#string-and-bytes-literals if len(delim) == 3 { name = "triple-quoted " + name } i := len(delim) var content []byte for i < len(p.s) { if strings.HasPrefix(p.s[i:], delim) { i += len(delim) p.s = p.s[i:] return string(content), nil } if p.s[i] == '\\' { i++ if i >= len(p.s) { return "", p.errorf("unclosed %s", name) } if raw { content = append(content, '\\', p.s[i]) i++ continue } switch p.s[i] { case 'a': i++ content = append(content, '\a') case 'b': i++ content = append(content, '\b') case 'f': i++ content = append(content, '\f') case 'n': i++ content = append(content, '\n') case 'r': i++ content = append(content, '\r') case 't': i++ content = append(content, '\t') case 'v': i++ content = append(content, '\v') case '\\': i++ content = append(content, '\\') case '?': i++ content = append(content, '?') case '"': i++ content = append(content, '"') case '\'': i++ content = append(content, '\'') case '`': i++ content = append(content, '`') case 'x', 'X': i++ if !(i+1 < len(p.s) && isHexDigit(p.s[i]) && isHexDigit(p.s[i+1])) { return "", p.errorf("illegal escape sequence: hex escape sequence must be followed by 2 hex digits") } c, err := strconv.ParseUint(p.s[i:i+2], 16, 64) if err != nil { return "", p.errorf("illegal escape sequence: invalid hex digits: %q: %v", p.s[i:i+2], err) } content = append(content, byte(c)) i += 2 case 'u', 'U': t := p.s[i] if !unicode { return "", p.errorf("illegal escape sequence: \\%c", t) } i++ size := 4 if t == 'U' { size = 8 } if i+size-1 >= len(p.s) { return "", p.errorf("illegal escape sequence: \\%c escape sequence must be followed by %d hex digits", t, size) } for j := 0; j < size; j++ { if !isHexDigit(p.s[i+j]) { return "", p.errorf("illegal escape sequence: \\%c escape sequence must be followed by %d hex digits", t, size) } } c, err := strconv.ParseUint(p.s[i:i+size], 16, 64) if err != nil { return "", p.errorf("illegal escape sequence: invalid \\%c digits: %q: %v", t, p.s[i:i+size], err) } if 0xD800 <= c && c <= 0xDFFF || 0x10FFFF < c { return "", p.errorf("illegal escape sequence: invalid codepoint: %x", c) } var buf [utf8.UTFMax]byte n := utf8.EncodeRune(buf[:], rune(c)) content = append(content, buf[:n]...) i += size case '0', '1', '2', '3', '4', '5', '6', '7': if !(i+2 < len(p.s) && isOctalDigit(p.s[i+1]) && isOctalDigit(p.s[i+2])) { return "", p.errorf("illegal escape sequence: octal escape sequence must be followed by 3 octal digits") } c, err := strconv.ParseUint(p.s[i:i+3], 8, 64) if err != nil { return "", p.errorf("illegal escape sequence: invalid octal digits: %q: %v", p.s[i:i+3], err) } if c >= 256 { return "", p.errorf("illegal escape sequence: octal digits overflow: %q (%d)", p.s[i:i+3], c) } content = append(content, byte(c)) i += 3 default: return "", p.errorf("illegal escape sequence: \\%c", p.s[i]) } continue } if p.s[i] == '\n' && len(delim) != 3 { // newline is only allowed inside triple-quoted. return "", p.errorf("newline forbidden in %s", name) } content = append(content, p.s[i]) i++ } return "", p.errorf("unclosed %s", name) } var operators = map[string]bool{ // TODO: There's duplication here with symbolicOperators, // but this should go away with more bespoke handling inside parser.advance. "<": true, "<=": true, ">": true, ">=": true, "=": true, "!=": true, "<>": true, } func isSpace(c byte) bool { // Per https://cloud.google.com/spanner/docs/lexical, informally, // whitespace is defined as "space, backspace, tab, newline". switch c { case ' ', '\b', '\t', '\n': return true } return false } // skipSpace skips past any space or comments. func (p *parser) skipSpace() bool { i := 0 for i < len(p.s) { if isSpace(p.s[i]) { i++ continue } // Comments. term := "" if p.s[i] == '#' { term = "\n" } else if i+1 < len(p.s) && p.s[i] == '-' && p.s[i+1] == '-' { term = "\n" } else if i+1 < len(p.s) && p.s[i] == '/' && p.s[i+1] == '*' { term = "*/" } if term == "" { break } ti := strings.Index(p.s[i:], term) if ti < 0 { p.errorf("unterminated comment") return false } i += ti + len(term) } p.s = p.s[i:] if p.s == "" { p.done = true } return i > 0 } // advance moves the parser to the next token, which will be available in p.cur. func (p *parser) advance() { p.skipSpace() if p.done { return } p.cur.err = nil p.cur.typ = unknownToken // TODO: backtick (`) for quoted identifiers. // TODO: array, struct, date, timestamp literals switch p.s[0] { case ',', ';', '(', ')', '*': // Single character symbol. p.cur.value, p.s = p.s[:1], p.s[1:] return // String literal prefix. case 'B', 'b', 'R', 'r', '"', '\'': // "B", "b", "BR", "Rb" etc are valid string literal prefix, however "BB", "rR" etc are not. raw, bytes := false, false for i := 0; i < 4 && i < len(p.s); i++ { switch { case !raw && (p.s[i] == 'R' || p.s[i] == 'r'): raw = true continue case !bytes && (p.s[i] == 'B' || p.s[i] == 'b'): bytes = true continue case p.s[i] == '"' || p.s[i] == '\'': switch { case raw && bytes: p.consumeRawBytes() case raw: p.consumeRawString() case bytes: p.consumeBytes() default: p.consumeString() } return } break } } if p.s[0] == '@' || isInitialIdentifierChar(p.s[0]) { // Start consuming identifier. i := 1 for i < len(p.s) && isIdentifierChar(p.s[i]) { i++ } p.cur.value, p.s = p.s[:i], p.s[i:] return } if len(p.s) >= 2 && (p.s[0] == '+' || p.s[0] == '-' || p.s[0] == '.') && ('0' <= p.s[1] && p.s[1] <= '9') { // [-+.] followed by a digit. p.consumeNumber() return } if '0' <= p.s[0] && p.s[0] <= '9' { p.consumeNumber() return } // More single character symbols. // These are deliberately below the numeric literal parsing. switch p.s[0] { case '-', '+': p.cur.value, p.s = p.s[:1], p.s[1:] return } // Look for operator (two or one bytes). for i := 2; i >= 1; i-- { if i <= len(p.s) && operators[p.s[:i]] { p.cur.value, p.s = p.s[:i], p.s[i:] return } } p.errorf("unexpected byte %#x", p.s[0]) } // back steps the parser back one token. It cannot be called twice in succession. func (p *parser) back() { if p.backed { panic("parser backed up twice") } p.done = false p.backed = true // If an error was being recovered, we wish to ignore the error. // Don't do that for io.EOF since that'll be returned next. if p.cur.err != io.EOF { p.cur.err = nil } } // next returns the next token. func (p *parser) next() *token { if p.backed || p.done { p.backed = false return &p.cur } p.advance() if p.done && p.cur.err == nil { p.cur.value = "" p.cur.err = io.EOF } return &p.cur } // sniff reports whether the next N tokens are as specified. func (p *parser) sniff(want ...string) bool { // Store current parser state and restore on the way out. orig := *p defer func() { *p = orig }() for _, w := range want { tok := p.next() if tok.err != nil || tok.value != w { return false } } return true } // eat reports whether the next N tokens are as specified, // then consumes them. func (p *parser) eat(want ...string) bool { // Store current parser state so we can restore if we get a failure. orig := *p for _, w := range want { tok := p.next() if tok.err != nil || tok.value != w { // Mismatch. *p = orig return false } } return true } func (p *parser) expect(want string) error { tok := p.next() if tok.err != nil { return tok.err } if tok.value != want { return p.errorf("got %q while expecting %q", tok.value, want) } return nil } func (p *parser) parseDDLStmt() (DDLStmt, error) { debugf("parseDDLStmt: %v", p) /* statement: { create_database | create_table | create_index | alter_table | drop_table | drop_index } */ // TODO: support create_database if p.sniff("CREATE", "TABLE") { ct, err := p.parseCreateTable() return ct, err } else if p.sniff("CREATE") { // The only other statement starting with CREATE is CREATE INDEX, // which can have UNIQUE or NULL_FILTERED as the token after CREATE. ci, err := p.parseCreateIndex() return ci, err } else if p.sniff("ALTER", "TABLE") { a, err := p.parseAlterTable() return a, err } else if p.eat("DROP") { // These statements are simple. // DROP TABLE table_name // DROP INDEX index_name tok := p.next() if tok.err != nil { return nil, tok.err } kind := tok.value if kind != "TABLE" && kind != "INDEX" { return nil, p.errorf("got %q, want TABLE or INDEX", kind) } name, err := p.parseTableOrIndexOrColumnName() if err != nil { return nil, err } if kind == "TABLE" { return DropTable{Name: name}, nil } return DropIndex{Name: name}, nil } return nil, p.errorf("unknown DDL statement") } func (p *parser) parseCreateTable() (CreateTable, error) { debugf("parseCreateTable: %v", p) /* CREATE TABLE table_name( [column_def, ...] ) primary_key [, cluster] primary_key: PRIMARY KEY ( [key_part, ...] ) cluster: INTERLEAVE IN PARENT table_name [ ON DELETE { CASCADE | NO ACTION } ] */ if err := p.expect("CREATE"); err != nil { return CreateTable{}, err } if err := p.expect("TABLE"); err != nil { return CreateTable{}, err } tname, err := p.parseTableOrIndexOrColumnName() if err != nil { return CreateTable{}, err } ct := CreateTable{Name: tname} err = p.parseCommaList(func(p *parser) error { cd, err := p.parseColumnDef() if err != nil { return err } ct.Columns = append(ct.Columns, cd) return nil }) if err != nil { return CreateTable{}, err } if err := p.expect("PRIMARY"); err != nil { return CreateTable{}, err } if err := p.expect("KEY"); err != nil { return CreateTable{}, err } ct.PrimaryKey, err = p.parseKeyPartList() if err != nil { return CreateTable{}, err } if p.eat(",", "INTERLEAVE") { if err := p.expect("IN"); err != nil { return CreateTable{}, err } if err := p.expect("PARENT"); err != nil { return CreateTable{}, err } pname, err := p.parseTableOrIndexOrColumnName() if err != nil { return CreateTable{}, err } ct.Interleave = &Interleave{ Parent: pname, OnDelete: NoActionOnDelete, } // The ON DELETE clause is optional; it defaults to NoActionOnDelete. if p.eat("ON", "DELETE") { od, err := p.parseOnDelete() if err != nil { return CreateTable{}, err } ct.Interleave.OnDelete = od } } return ct, nil } func (p *parser) parseCreateIndex() (CreateIndex, error) { debugf("parseCreateIndex: %v", p) /* CREATE [UNIQUE] [NULL_FILTERED] INDEX index_name ON table_name ( key_part [, ...] ) [ storing_clause ] [ , interleave_clause ] index_name: {a—z|A—Z}[{a—z|A—Z|0—9|_}+] storing_clause: STORING ( column_name [, ...] ) interleave_clause: INTERLEAVE IN table_name */ var unique, nullFiltered bool if err := p.expect("CREATE"); err != nil { return CreateIndex{}, err } if p.eat("UNIQUE") { unique = true } if p.eat("NULL_FILTERED") { nullFiltered = true } if err := p.expect("INDEX"); err != nil { return CreateIndex{}, err } iname, err := p.parseTableOrIndexOrColumnName() if err != nil { return CreateIndex{}, err } if err := p.expect("ON"); err != nil { return CreateIndex{}, err } tname, err := p.parseTableOrIndexOrColumnName() if err != nil { return CreateIndex{}, err } ci := CreateIndex{ Name: iname, Table: tname, Unique: unique, NullFiltered: nullFiltered, } ci.Columns, err = p.parseKeyPartList() if err != nil { return CreateIndex{}, err } if p.eat("STORING") { ci.Storing, err = p.parseColumnNameList() if err != nil { return CreateIndex{}, err } } if p.eat(",", "INTERLEAVE", "IN") { ci.Interleave, err = p.parseTableOrIndexOrColumnName() if err != nil { return CreateIndex{}, err } } return ci, nil } func (p *parser) parseAlterTable() (AlterTable, error) { debugf("parseAlterTable: %v", p) /* alter_table: ALTER TABLE table_name { table_alteration | table_column_alteration } table_alteration: { ADD COLUMN column_def | DROP COLUMN column_name | SET ON DELETE { CASCADE | NO ACTION } } table_column_alteration: ALTER COLUMN column_name { { scalar_type | array_type } [NOT NULL] | SET options_def } */ if err := p.expect("ALTER"); err != nil { return AlterTable{}, err } if err := p.expect("TABLE"); err != nil { return AlterTable{}, err } tname, err := p.parseTableOrIndexOrColumnName() if err != nil { return AlterTable{}, err } a := AlterTable{Name: tname} tok := p.next() if tok.err != nil { return AlterTable{}, tok.err } switch tok.value { default: return AlterTable{}, p.errorf("got %q, expected ADD or DROP or SET or ALTER", tok.value) case "ADD": if err := p.expect("COLUMN"); err != nil { return AlterTable{}, err } cd, err := p.parseColumnDef() if err != nil { return AlterTable{}, err } a.Alteration = AddColumn{Def: cd} return a, nil case "DROP": if err := p.expect("COLUMN"); err != nil { return AlterTable{}, err } name, err := p.parseTableOrIndexOrColumnName() if err != nil { return AlterTable{}, err } a.Alteration = DropColumn{Name: name} return a, nil case "SET": if err := p.expect("ON"); err != nil { return AlterTable{}, err } if err := p.expect("DELETE"); err != nil { return AlterTable{}, err } od, err := p.parseOnDelete() if err != nil { return AlterTable{}, err } a.Alteration = SetOnDelete{Action: od} return a, nil } // TODO: "ALTER" } func (p *parser) parseColumnDef() (ColumnDef, error) { debugf("parseColumnDef: %v", p) /* column_def: column_name {scalar_type | array_type} [NOT NULL] [options_def] */ name, err := p.parseTableOrIndexOrColumnName() if err != nil { return ColumnDef{}, err } cd := ColumnDef{Name: name} cd.Type, err = p.parseType() if err != nil { return ColumnDef{}, err } tok := p.next() if tok.err != nil || tok.value != "NOT" { // End of the column_def. p.back() return cd, nil } if err := p.expect("NULL"); err != nil { return ColumnDef{}, err } cd.NotNull = true return cd, nil } func (p *parser) parseKeyPartList() ([]KeyPart, error) { var list []KeyPart err := p.parseCommaList(func(p *parser) error { kp, err := p.parseKeyPart() if err != nil { return err } list = append(list, kp) return nil }) return list, err } func (p *parser) parseKeyPart() (KeyPart, error) { debugf("parseKeyPart: %v", p) /* key_part: column_name [{ ASC | DESC }] */ name, err := p.parseTableOrIndexOrColumnName() if err != nil { return KeyPart{}, err } kp := KeyPart{Column: name} tok := p.next() if tok.err != nil { // End of the key_part. p.back() return kp, nil } switch tok.value { case "ASC": case "DESC": kp.Desc = true default: p.back() } return kp, nil } func (p *parser) parseColumnNameList() ([]string, error) { var list []string err := p.parseCommaList(func(p *parser) error { n, err := p.parseTableOrIndexOrColumnName() if err != nil { return err } list = append(list, n) return nil }) return list, err } var baseTypes = map[string]TypeBase{ "BOOL": Bool, "INT64": Int64, "FLOAT64": Float64, "STRING": String, "BYTES": Bytes, "DATE": Date, "TIMESTAMP": Timestamp, } func (p *parser) parseType() (Type, error) { debugf("parseType: %v", p) /* array_type: ARRAY< scalar_type > scalar_type: { BOOL | INT64 | FLOAT64 | STRING( length ) | BYTES( length ) | DATE | TIMESTAMP } length: { int64_value | MAX } */ var t Type tok := p.next() if tok.err != nil { return Type{}, tok.err } if tok.value == "ARRAY" { t.Array = true if err := p.expect("<"); err != nil { return Type{}, err } tok = p.next() if tok.err != nil { return Type{}, tok.err } } base, ok := baseTypes[tok.value] if !ok { return Type{}, p.errorf("got %q, want scalar type", tok.value) } t.Base = base if t.Base == String || t.Base == Bytes { if err := p.expect("("); err != nil { return Type{}, err } tok = p.next() if tok.err != nil { return Type{}, tok.err } if tok.value == "MAX" { t.Len = MaxLen } else if tok.typ == int64Token { t.Len = tok.int64 } else { return Type{}, p.errorf("got %q, want MAX or int64", tok.value) } if err := p.expect(")"); err != nil { return Type{}, err } } if t.Array { if err := p.expect(">"); err != nil { return Type{}, err } } return t, nil } func (p *parser) parseQuery() (Query, error) { debugf("parseQuery: %v", p) /* query_statement: [ table_hint_expr ][ join_hint_expr ] query_expr query_expr: { select | ( query_expr ) | query_expr set_op query_expr } [ ORDER BY expression [{ ASC | DESC }] [, ...] ] [ LIMIT count [ OFFSET skip_rows ] ] */ // TODO: hints, sub-selects, etc. // TODO: use a case-insensitive select. if err := p.expect("SELECT"); err != nil { return Query{}, err } p.back() sel, err := p.parseSelect() if err != nil { return Query{}, err } q := Query{Select: sel} if p.eat("ORDER", "BY") { for { o, err := p.parseOrder() if err != nil { return Query{}, err } q.Order = append(q.Order, o) if !p.eat(",") { break } } } if p.eat("LIMIT") { lim, err := p.parseLimitCount() if err != nil { return Query{}, err } q.Limit = lim } return q, nil } func (p *parser) parseSelect() (Select, error) { debugf("parseSelect: %v", p) /* select: SELECT [{ ALL | DISTINCT }] { [ expression. ]* | expression [ [ AS ] alias ] } [, ...] [ FROM from_item [ tablesample_type ] [, ...] ] [ WHERE bool_expression ] [ GROUP BY expression [, ...] ] [ HAVING bool_expression ] */ if err := p.expect("SELECT"); err != nil { return Select{}, err } var sel Select // TODO: ALL|DISTINCT // Read expressions for the SELECT list. for { expr, err := p.parseExpr() if err != nil { return Select{}, err } sel.List = append(sel.List, expr) if p.eat(",") { continue } break } if p.eat("FROM") { for { from, err := p.parseSelectFrom() if err != nil { return Select{}, err } if p.sniff("TABLESAMPLE") { ts, err := p.parseTableSample() if err != nil { return Select{}, err } from.TableSample = &ts } sel.From = append(sel.From, from) if p.eat(",") { continue } break } } if p.eat("WHERE") { where, err := p.parseBoolExpr() if err != nil { return Select{}, err } sel.Where = where } // TODO: GROUP BY, HAVING return sel, nil } func (p *parser) parseSelectFrom() (SelectFrom, error) { // TODO: support more than a single table name. tname, err := p.parseTableOrIndexOrColumnName() return SelectFrom{Table: tname}, err } func (p *parser) parseTableSample() (TableSample, error) { var ts TableSample if err := p.expect("TABLESAMPLE"); err != nil { return ts, err } tok := p.next() switch { case tok.err != nil: return ts, tok.err case tok.value == "BERNOULLI": ts.Method = Bernoulli case tok.value == "RESERVOIR": ts.Method = Reservoir default: return ts, p.errorf("got %q, want BERNOULLI or RESERVOIR", tok.value) } if err := p.expect("("); err != nil { return ts, err } // The docs say "numeric_value_expression" here, // but that doesn't appear to be defined anywhere. size, err := p.parseExpr() if err != nil { return ts, err } ts.Size = size tok = p.next() switch { case tok.err != nil: return ts, tok.err case tok.value == "PERCENT": ts.SizeType = PercentTableSample case tok.value == "ROWS": ts.SizeType = RowsTableSample default: return ts, p.errorf("got %q, want PERCENT or ROWS", tok.value) } if err := p.expect(")"); err != nil { return ts, err } return ts, nil } func (p *parser) parseOrder() (Order, error) { /* expression [{ ASC | DESC }] */ expr, err := p.parseExpr() if err != nil { return Order{}, err } o := Order{Expr: expr} tok := p.next() switch { case tok.err == nil && tok.value == "ASC": case tok.err == nil && tok.value == "DESC": o.Desc = true default: p.back() } return o, nil } func (p *parser) parseLimitCount() (Limit, error) { // "only literal or parameter values" // https://cloud.google.com/spanner/docs/query-syntax#limit-clause-and-offset-clause tok := p.next() if tok.err != nil { return nil, tok.err } if tok.typ == int64Token { return IntegerLiteral(tok.int64), nil } // TODO: check character sets. if strings.HasPrefix(tok.value, "@") { return Param(tok.value[1:]), nil } return nil, p.errorf("got %q, want literal or parameter", tok.value) } func (p *parser) parseExprList() ([]Expr, error) { var list []Expr err := p.parseCommaList(func(p *parser) error { e, err := p.parseExpr() if err != nil { return err } list = append(list, e) return nil }) return list, err } /* Expressions Cloud Spanner expressions are not formally specified. The set of operators and their precedence is listed in https://cloud.google.com/spanner/docs/functions-and-operators#operators. parseExpr works as a classical recursive descent parser, splitting precedence levels into separate methods, where the call stack is in ascending order of precedence: parseExpr orParser andParser parseIsOp parseComparisonOp parseArithOp parseLit TODO: there are more levels to break out, esp. in parseArithOp */ func (p *parser) parseExpr() (Expr, error) { debugf("parseExpr: %v", p) return orParser.parse(p) } // binOpParser is a generic meta-parser for binary operations. // It assumes the operation is left associative. type binOpParser struct { LHS, RHS func(*parser) (Expr, error) Op string ArgCheck func(Expr) error Combiner func(lhs, rhs Expr) Expr } func (bin binOpParser) parse(p *parser) (Expr, error) { expr, err := bin.LHS(p) if err != nil { return nil, err } for { if !p.eat(bin.Op) { break } rhs, err := bin.RHS(p) if err != nil { return nil, err } if bin.ArgCheck != nil { if err := bin.ArgCheck(expr); err != nil { return nil, p.errorf("%v", err) } if err := bin.ArgCheck(rhs); err != nil { return nil, p.errorf("%v", err) } } expr = bin.Combiner(expr, rhs) } return expr, nil } // Break initialisation loop. func init() { orParser = orParserShim } var ( boolExprCheck = func(expr Expr) error { if _, ok := expr.(BoolExpr); !ok { return fmt.Errorf("got %T, want a boolean expression", expr) } return nil } orParser binOpParser orParserShim = binOpParser{ LHS: andParser.parse, RHS: andParser.parse, Op: "OR", ArgCheck: boolExprCheck, Combiner: func(lhs, rhs Expr) Expr { return LogicalOp{LHS: lhs.(BoolExpr), Op: Or, RHS: rhs.(BoolExpr)} }, } andParser = binOpParser{ LHS: (*parser).parseLogicalNot, RHS: (*parser).parseLogicalNot, Op: "AND", ArgCheck: boolExprCheck, Combiner: func(lhs, rhs Expr) Expr { return LogicalOp{LHS: lhs.(BoolExpr), Op: And, RHS: rhs.(BoolExpr)} }, } ) func (p *parser) parseLogicalNot() (Expr, error) { if !p.eat("NOT") { return p.parseIsOp() } be, err := p.parseBoolExpr() if err != nil { return nil, err } return LogicalOp{Op: Not, RHS: be}, nil } func (p *parser) parseIsOp() (Expr, error) { debugf("parseIsOp: %v", p) expr, err := p.parseComparisonOp() if err != nil { return nil, err } tok := p.next() if tok.err != nil || tok.value != "IS" { p.back() return expr, nil } isOp := IsOp{LHS: expr} if p.eat("NOT") { isOp.Neg = true } tok = p.next() if tok.err != nil { return nil, tok.err } switch tok.value { case "NULL": isOp.RHS = Null case "TRUE": isOp.RHS = True case "FALSE": isOp.RHS = False default: return nil, p.errorf("got %q, want NULL or TRUE or FALSE", tok.value) } return isOp, nil } var symbolicOperators = map[string]ComparisonOperator{ "<": Lt, "<=": Le, ">": Gt, ">=": Ge, "=": Eq, "!=": Ne, "<>": Ne, } func (p *parser) parseComparisonOp() (Expr, error) { debugf("parseComparisonOp: %v", p) expr, err := p.parseArithOp() if err != nil { return nil, err } for { tok := p.next() if tok.err != nil { p.back() break } var op ComparisonOperator var ok, rhs2 bool if tok.value == "NOT" { tok := p.next() switch { case tok.err != nil: // TODO: Does this need to push back two? return nil, err case tok.value == "LIKE": op, ok = NotLike, true case tok.value == "BETWEEN": op, ok, rhs2 = NotBetween, true, true default: // TODO: Does this need to push back two? return nil, p.errorf("got %q, want LIKE or BETWEEN", tok.value) } } else if tok.value == "LIKE" { op, ok = Like, true } else if tok.value == "BETWEEN" { op, ok, rhs2 = Between, true, true } else { op, ok = symbolicOperators[tok.value] } if !ok { p.back() break } rhs, err := p.parseArithOp() if err != nil { return nil, err } co := ComparisonOp{LHS: expr, Op: op, RHS: rhs} if rhs2 { if err := p.expect("AND"); err != nil { return nil, err } rhs2, err := p.parseArithOp() if err != nil { return nil, err } co.RHS2 = rhs2 } expr = co } return expr, nil } func (p *parser) parseArithOp() (Expr, error) { // TODO: actually parse arithmetic operations. if p.eat("(") { e, err := p.parseExpr() if err != nil { return nil, err } if err := p.expect(")"); err != nil { return nil, err } return Paren{Expr: e}, nil } lit, err := p.parseLit() if err != nil { return nil, err } // If the literal was an identifier, and there's an open paren next, // this is a function invocation. if id, ok := lit.(ID); ok && p.sniff("(") { list, err := p.parseExprList() if err != nil { return nil, err } return Func{ Name: string(id), Args: list, }, nil } return lit, nil } func (p *parser) parseLit() (Expr, error) { tok := p.next() if tok.err != nil { return nil, tok.err } switch tok.typ { case int64Token: return IntegerLiteral(tok.int64), nil case float64Token: return FloatLiteral(tok.float64), nil case stringToken: return StringLiteral(tok.string), nil case bytesToken: return BytesLiteral(tok.string), nil } // Handle some reserved keywords and special tokens that become specific values. // TODO: Handle the other 92 keywords. switch tok.value { case "TRUE": return True, nil case "FALSE": return False, nil case "NULL": return Null, nil case "*": return Star, nil } // TODO: more types of literals (array, struct, date, timestamp). // Try a parameter. // TODO: check character sets. if strings.HasPrefix(tok.value, "@") { return Param(tok.value[1:]), nil } return ID(tok.value), nil } func (p *parser) parseBoolExpr() (BoolExpr, error) { expr, err := p.parseExpr() if err != nil { return nil, err } be, ok := expr.(BoolExpr) if !ok { return nil, p.errorf("got non-bool expression %T", expr) } return be, nil } func (p *parser) parseTableOrIndexOrColumnName() (string, error) { /* table_name and column_name and index_name: {a—z|A—Z}[{a—z|A—Z|0—9|_}+] */ tok := p.next() if tok.err != nil { return "", tok.err } // TODO: enforce restrictions return tok.value, nil } func (p *parser) parseOnDelete() (OnDelete, error) { /* CASCADE NO ACTION */ tok := p.next() if tok.err != nil { return 0, tok.err } if tok.value == "CASCADE" { return CascadeOnDelete, nil } if tok.value != "NO" { return 0, p.errorf("got %q, want NO or CASCADE", tok.value) } if err := p.expect("ACTION"); err != nil { return 0, err } return NoActionOnDelete, nil } // parseCommaList parses a parenthesized comma-separated list, // delegating to f for the individual element parsing. func (p *parser) parseCommaList(f func(*parser) error) error { if err := p.expect("("); err != nil { return err } for { if p.eat(")") { return nil } err := f(p) if err != nil { return err } // ")" or "," should be next. tok := p.next() if tok.err != nil { return err } if tok.value == ")" { return nil } else if tok.value == "," { continue } else { return p.errorf(`got %q, want ")" or ","`, tok.value) } } } google-cloud-go-0.49.0/spanner/spansql/parser_test.go000066400000000000000000000275341356504100700226140ustar00rootroot00000000000000/* Copyright 2019 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spansql import ( "fmt" "math" "reflect" "testing" ) func TestParseQuery(t *testing.T) { tests := []struct { in string want Query }{ {`SELECT 17`, Query{Select: Select{List: []Expr{IntegerLiteral(17)}}}}, {`SELECT Alias FROM Characters WHERE Age < @ageLimit AND Alias IS NOT NULL ORDER BY Age DESC LIMIT @limit` + "\n\t", Query{ Select: Select{ List: []Expr{ID("Alias")}, From: []SelectFrom{{ Table: "Characters", }}, Where: LogicalOp{ Op: And, LHS: ComparisonOp{ LHS: ID("Age"), Op: Lt, RHS: Param("ageLimit"), }, RHS: IsOp{ LHS: ID("Alias"), Neg: true, RHS: Null, }, }, }, Order: []Order{{ Expr: ID("Age"), Desc: true, }}, Limit: Param("limit"), }, }, {`SELECT COUNT(*) FROM Packages`, Query{ Select: Select{ List: []Expr{ Func{ Name: "COUNT", Args: []Expr{Star}, }, }, From: []SelectFrom{{Table: "Packages"}}, }, }, }, } for _, test := range tests { got, err := ParseQuery(test.in) if err != nil { t.Errorf("ParseQuery(%q): %v", test.in, err) continue } if !reflect.DeepEqual(got, test.want) { t.Errorf("ParseQuery(%q) incorrect.\n got %#v\nwant %#v", test.in, got, test.want) } } } func TestParseExpr(t *testing.T) { tests := []struct { in string want Expr }{ {`17`, IntegerLiteral(17)}, {`-1`, IntegerLiteral(-1)}, {fmt.Sprintf(`%d`, math.MaxInt64), IntegerLiteral(math.MaxInt64)}, {fmt.Sprintf(`%d`, math.MinInt64), IntegerLiteral(math.MinInt64)}, {"1.797693134862315708145274237317043567981e+308", FloatLiteral(math.MaxFloat64)}, {`4.940656458412465441765687928682213723651e-324`, FloatLiteral(math.SmallestNonzeroFloat64)}, {`0xf00d`, IntegerLiteral(0xf00d)}, {`-0xbeef`, IntegerLiteral(-0xbeef)}, {`0XabCD`, IntegerLiteral(0xabcd)}, {`-0XBEEF`, IntegerLiteral(-0xbeef)}, {`123.456e-67`, FloatLiteral(123.456e-67)}, {`-123.456e-67`, FloatLiteral(-123.456e-67)}, {`.1E4`, FloatLiteral(0.1e4)}, {`58.`, FloatLiteral(58)}, {`4e2`, FloatLiteral(4e2)}, {`Count > 0`, ComparisonOp{LHS: ID("Count"), Op: Gt, RHS: IntegerLiteral(0)}}, {`Name LIKE "Eve %"`, ComparisonOp{LHS: ID("Name"), Op: Like, RHS: StringLiteral("Eve %")}}, {`Speech NOT LIKE "_oo"`, ComparisonOp{LHS: ID("Speech"), Op: NotLike, RHS: StringLiteral("_oo")}}, {`A AND NOT B`, LogicalOp{LHS: ID("A"), Op: And, RHS: LogicalOp{Op: Not, RHS: ID("B")}}}, {`X BETWEEN Y AND Z`, ComparisonOp{LHS: ID("X"), Op: Between, RHS: ID("Y"), RHS2: ID("Z")}}, // String literal: // Accept double quote and single quote. {`"hello"`, StringLiteral("hello")}, {`'hello'`, StringLiteral("hello")}, // Accept triple-quote. {`""" "hello" "world" """`, StringLiteral(` "hello" "world" `)}, {"''' 'hello'\n'world' '''", StringLiteral(" 'hello'\n'world' ")}, // Simple escape sequence {`"\a\b\f\n\r\t\v\\\?\"\'"`, StringLiteral("\a\b\f\n\r\t\v\\?\"'")}, {`'\a\b\f\n\r\t\v\\\?\"\''`, StringLiteral("\a\b\f\n\r\t\v\\?\"'")}, {"'\\`'", StringLiteral("`")}, // Hex and unicode escape sequence {`"\060\x30\X30\u0030\U00000030"`, StringLiteral("00000")}, {`'\060\x30\X30\u0030\U00000030'`, StringLiteral("00000")}, {`"\uBEAF\ubeaf"`, StringLiteral("\ubeaf\ubeaf")}, {`'\uBEAF\ubeaf'`, StringLiteral("\ubeaf\ubeaf")}, // Escape sequence in triple quote is allowed. {`"""\u0030"""`, StringLiteral("0")}, {`'''\u0030'''`, StringLiteral("0")}, // Raw string literal {`R"\\"`, StringLiteral("\\\\")}, {`R'\\'`, StringLiteral("\\\\")}, {`r"\\"`, StringLiteral("\\\\")}, {`r'\\'`, StringLiteral("\\\\")}, {`R"\\\""`, StringLiteral("\\\\\\\"")}, {`R"""\\//\\//"""`, StringLiteral("\\\\//\\\\//")}, {"R'''\\\\//\n\\\\//'''", StringLiteral("\\\\//\n\\\\//")}, // Bytes literal: {`B"hello"`, BytesLiteral("hello")}, {`B'hello'`, BytesLiteral("hello")}, {`b"hello"`, BytesLiteral("hello")}, {`b'hello'`, BytesLiteral("hello")}, {`B""" "hello" "world" """`, BytesLiteral(` "hello" "world" `)}, {`B''' 'hello' 'world' '''`, BytesLiteral(` 'hello' 'world' `)}, {`B"\a\b\f\n\r\t\v\\\?\"\'"`, BytesLiteral("\a\b\f\n\r\t\v\\?\"'")}, {`B'\a\b\f\n\r\t\v\\\?\"\''`, BytesLiteral("\a\b\f\n\r\t\v\\?\"'")}, {"B'''\n'''", BytesLiteral("\n")}, {`br"\\"`, BytesLiteral("\\\\")}, {`br'\\'`, BytesLiteral("\\\\")}, {`rb"\\"`, BytesLiteral("\\\\")}, {`rb'\\'`, BytesLiteral("\\\\")}, {`RB"\\"`, BytesLiteral("\\\\")}, {`RB'\\'`, BytesLiteral("\\\\")}, {`BR"\\"`, BytesLiteral("\\\\")}, {`BR'\\'`, BytesLiteral("\\\\")}, {`RB"""\\//\\//"""`, BytesLiteral("\\\\//\\\\//")}, {"RB'''\\\\//\n\\\\//'''", BytesLiteral("\\\\//\n\\\\//")}, // OR is lower precedence than AND. {`A AND B OR C`, LogicalOp{LHS: LogicalOp{LHS: ID("A"), Op: And, RHS: ID("B")}, Op: Or, RHS: ID("C")}}, {`A OR B AND C`, LogicalOp{LHS: ID("A"), Op: Or, RHS: LogicalOp{LHS: ID("B"), Op: And, RHS: ID("C")}}}, // Parens to override normal precedence. {`A OR (B AND C)`, LogicalOp{LHS: ID("A"), Op: Or, RHS: Paren{Expr: LogicalOp{LHS: ID("B"), Op: And, RHS: ID("C")}}}}, // This is the same as the WHERE clause from the test in ParseQuery. {`Age < @ageLimit AND Alias IS NOT NULL`, LogicalOp{ LHS: ComparisonOp{LHS: ID("Age"), Op: Lt, RHS: Param("ageLimit")}, Op: And, RHS: IsOp{LHS: ID("Alias"), Neg: true, RHS: Null}, }, }, // This used to be broken because the lexer didn't reset the token type. {`C < "whelp" AND D IS NOT NULL`, LogicalOp{ LHS: ComparisonOp{LHS: ID("C"), Op: Lt, RHS: StringLiteral("whelp")}, Op: And, RHS: IsOp{LHS: ID("D"), Neg: true, RHS: Null}, }, }, // Reserved keywords. {`TRUE AND FALSE`, LogicalOp{LHS: True, Op: And, RHS: False}}, {`NULL`, Null}, } for _, test := range tests { p := newParser(test.in) got, err := p.parseExpr() if err != nil { t.Errorf("[%s]: %v", test.in, err) continue } if !reflect.DeepEqual(got, test.want) { t.Errorf("[%s]: incorrect parse\n got <%T> %#v\nwant <%T> %#v", test.in, got, got, test.want, test.want) } if p.s != "" { t.Errorf("[%s]: Unparsed [%s]", test.in, p.s) } } } func TestParseDDL(t *testing.T) { tests := []struct { in string want DDL }{ {`CREATE TABLE FooBar ( System STRING(MAX) NOT NULL, # This is a comment. RepoPath STRING(MAX) NOT NULL, -- This is another comment. Count INT64, /* This is a * multiline comment. */ ) PRIMARY KEY(System, RepoPath); CREATE UNIQUE INDEX MyFirstIndex ON FooBar ( Count DESC ) STORING (Count), INTERLEAVE IN SomeTable; CREATE TABLE FooBarAux ( System STRING(MAX) NOT NULL, RepoPath STRING(MAX) NOT NULL, Author STRING(MAX) NOT NULL, ) PRIMARY KEY(System, RepoPath, Author), INTERLEAVE IN PARENT FooBar ON DELETE CASCADE; ALTER TABLE FooBar ADD COLUMN TZ BYTES(20); ALTER TABLE FooBar DROP COLUMN TZ; ALTER TABLE FooBar SET ON DELETE NO ACTION; DROP INDEX MyFirstIndex; DROP TABLE FooBar; CREATE TABLE NonScalars ( Dummy INT64 NOT NULL, Ids ARRAY, Names ARRAY, ) PRIMARY KEY (Dummy); `, DDL{List: []DDLStmt{ CreateTable{ Name: "FooBar", Columns: []ColumnDef{ {Name: "System", Type: Type{Base: String, Len: MaxLen}, NotNull: true}, {Name: "RepoPath", Type: Type{Base: String, Len: MaxLen}, NotNull: true}, {Name: "Count", Type: Type{Base: Int64}}, }, PrimaryKey: []KeyPart{ {Column: "System"}, {Column: "RepoPath"}, }, }, CreateIndex{ Name: "MyFirstIndex", Table: "FooBar", Columns: []KeyPart{{Column: "Count", Desc: true}}, Unique: true, Storing: []string{"Count"}, Interleave: "SomeTable", }, CreateTable{ Name: "FooBarAux", Columns: []ColumnDef{ {Name: "System", Type: Type{Base: String, Len: MaxLen}, NotNull: true}, {Name: "RepoPath", Type: Type{Base: String, Len: MaxLen}, NotNull: true}, {Name: "Author", Type: Type{Base: String, Len: MaxLen}, NotNull: true}, }, PrimaryKey: []KeyPart{ {Column: "System"}, {Column: "RepoPath"}, {Column: "Author"}, }, Interleave: &Interleave{ Parent: "FooBar", OnDelete: CascadeOnDelete, }, }, AlterTable{Name: "FooBar", Alteration: AddColumn{ Def: ColumnDef{Name: "TZ", Type: Type{Base: Bytes, Len: 20}}, }}, AlterTable{Name: "FooBar", Alteration: DropColumn{Name: "TZ"}}, AlterTable{Name: "FooBar", Alteration: SetOnDelete{Action: NoActionOnDelete}}, DropIndex{Name: "MyFirstIndex"}, DropTable{Name: "FooBar"}, CreateTable{ Name: "NonScalars", Columns: []ColumnDef{ {Name: "Dummy", Type: Type{Base: Int64}, NotNull: true}, {Name: "Ids", Type: Type{Array: true, Base: Int64}}, {Name: "Names", Type: Type{Array: true, Base: String, Len: MaxLen}}, }, PrimaryKey: []KeyPart{{Column: "Dummy"}}, }, }}}, // No trailing comma: {`ALTER TABLE T ADD COLUMN C2 INT64`, DDL{List: []DDLStmt{ AlterTable{Name: "T", Alteration: AddColumn{ Def: ColumnDef{Name: "C2", Type: Type{Base: Int64}}, }}, }}}, } for _, test := range tests { got, err := ParseDDL(test.in) if err != nil { t.Errorf("ParseDDL(%q): %v", test.in, err) continue } if !reflect.DeepEqual(got, test.want) { t.Errorf("ParseDDL(%q) incorrect.\n got %v\nwant %v", test.in, got, test.want) } } } func TestParseFailures(t *testing.T) { expr := func(p *parser) error { _, err := p.parseExpr() return err } tests := []struct { f func(p *parser) error in string desc string }{ {expr, `0b337`, "binary literal"}, {expr, `"foo\`, "unterminated string"}, {expr, `"\i"`, "invalid escape sequence"}, {expr, `"\0"`, "invalid escape sequence"}, {expr, `"\099"`, "invalid escape sequence"}, {expr, `"\400"`, "invalid escape sequence: octal digits overflow"}, {expr, `"\x"`, "invalid escape sequence"}, {expr, `"\xFZ"`, "invalid escape sequence"}, {expr, `"\u"`, "invalid escape sequence"}, {expr, `"\uFFFZ"`, "invalid escape sequence"}, {expr, `"\uD800"`, "invalid unicode character (surrogate)"}, {expr, `"\U"`, "invalid escape sequence"}, {expr, `"\UFFFFFFFZ"`, "invalid escape sequence"}, {expr, `"\U00110000"`, "invalid unicode character (out of range)"}, {expr, "\"\n\"", "unterminated string by newline (double quote)"}, {expr, "'\n'", "unterminated string by newline (single quote)"}, {expr, "R\"\n\"", "unterminated raw string by newline (double quote)"}, {expr, "R'\n'", "unterminated raw string by newline (single quote)"}, {expr, `B"\u0030"`, "\\uXXXX sequence is not supported in bytes literal (double quote)"}, {expr, `B'\u0030'`, "\\uXXXX sequence is not supported in bytes literal (double quote)"}, {expr, `B"\U00000030"`, "\\UXXXXXXXX sequence is not supported in bytes literal (double quote)"}, {expr, `B'\U00000030'`, "\\UXXXXXXXX sequence is not supported in bytes literal (double quote)"}, {expr, `BB""`, "invalid string-like literal prefix"}, {expr, `rr""`, "invalid string-like literal prefix"}, {expr, `"""\"""`, "unterminated triple-quoted string by last backslash (double quote)"}, {expr, `'''\'''`, "unterminated triple-quoted string by last backslash (single quote)"}, {expr, `"foo" AND "bar"`, "logical operation on string literals"}, } for _, test := range tests { p := newParser(test.in) if test.f(p) == nil && p.Rem() == "" { t.Errorf("%s: parsing [%s] succeeded, should have failed", test.desc, test.in) } } } google-cloud-go-0.49.0/spanner/spansql/sql.go000066400000000000000000000127371356504100700210570ustar00rootroot00000000000000/* Copyright 2019 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spansql // This file holds SQL methods for rendering the types in types.go // as the SQL dialect that this package parses. import ( "strconv" "strings" ) func (ct CreateTable) SQL() string { str := "CREATE TABLE " + ct.Name + " (\n" for _, c := range ct.Columns { str += " " + c.SQL() + ",\n" } str += ") PRIMARY KEY(" for i, c := range ct.PrimaryKey { if i > 0 { str += ", " } str += c.SQL() } str += ")" if il := ct.Interleave; il != nil { str += ",\n INTERLEAVE IN PARENT " + il.Parent + " ON DELETE " + il.OnDelete.SQL() } return str } func (ci CreateIndex) SQL() string { str := "CREATE" if ci.Unique { str += " UNIQUE" } if ci.NullFiltered { str += " NULL_FILTERED" } str += " INDEX " + ci.Name + " ON " + ci.Table + "(" for i, c := range ci.Columns { if i > 0 { str += ", " } str += c.SQL() } str += ")" if len(ci.Storing) > 0 { str += " STORING (" str += strings.Join(ci.Storing, ", ") str += ")" } if ci.Interleave != "" { str += ", INTERLEAVE IN " + ci.Interleave } return str } func (dt DropTable) SQL() string { return "DROP TABLE " + dt.Name } func (di DropIndex) SQL() string { return "DROP INDEX " + di.Name } func (at AlterTable) SQL() string { return "ALTER TABLE " + at.Name + " " + at.Alteration.SQL() } func (ac AddColumn) SQL() string { return "ADD COLUMN " + ac.Def.SQL() } func (dc DropColumn) SQL() string { return "DROP COLUMN " + dc.Name } func (sod SetOnDelete) SQL() string { return "SET ON DELETE " + sod.Action.SQL() } func (od OnDelete) SQL() string { switch od { case NoActionOnDelete: return "NO ACTION" case CascadeOnDelete: return "CASCADE" } panic("unknown OnDelete") } // TODO func (ac AlterColumn) SQL() string { } func (cd ColumnDef) SQL() string { str := cd.Name + " " + cd.Type.SQL() if cd.NotNull { str += " NOT NULL" } return str } func (t Type) SQL() string { str := t.Base.SQL() if t.Base == String || t.Base == Bytes { str += "(" if t.Len == MaxLen { str += "MAX" } else { str += strconv.FormatInt(t.Len, 10) } str += ")" } if t.Array { str = "ARRAY<" + str + ">" } return str } func (tb TypeBase) SQL() string { switch tb { case Bool: return "BOOL" case Int64: return "INT64" case Float64: return "FLOAT64" case String: return "STRING" case Bytes: return "BYTES" case Date: return "DATE" case Timestamp: return "TIMESTAMP" } panic("unknown TypeBase") } func (kp KeyPart) SQL() string { str := kp.Column if kp.Desc { str += " DESC" } return str } func (q Query) SQL() string { str := q.Select.SQL() if len(q.Order) > 0 { str += " ORDER BY " for i, o := range q.Order { if i > 0 { str += ", " } str += o.SQL() } } if q.Limit != nil { str += " LIMIT " + q.Limit.SQL() } return str } func (sel Select) SQL() string { str := "SELECT " for i, e := range sel.List { if i > 0 { str += ", " } str += e.SQL() } if len(sel.From) > 0 { str += " FROM " for i, f := range sel.From { if i > 0 { str += ", " } str += f.Table } } if sel.Where != nil { str += " WHERE " + sel.Where.SQL() } return str } func (o Order) SQL() string { str := o.Expr.SQL() if o.Desc { str += " DESC" } return str } func (lo LogicalOp) SQL() string { switch lo.Op { default: panic("unknown LogicalOp") case And: return lo.LHS.SQL() + " AND " + lo.RHS.SQL() case Or: return lo.LHS.SQL() + " OR " + lo.RHS.SQL() case Not: return "NOT " + lo.RHS.SQL() } } var compOps = map[ComparisonOperator]string{ Lt: "<", Le: "<=", Gt: ">", Ge: ">=", Eq: "=", Ne: "!=", Like: "LIKE", NotLike: "NOT LIKE", Between: "BETWEEN", NotBetween: "NOT BETWEEN", } func (co ComparisonOp) SQL() string { op, ok := compOps[co.Op] if !ok { panic("unknown ComparisonOp") } s := co.LHS.SQL() + " " + op + " " + co.RHS.SQL() if co.Op == Between || co.Op == NotBetween { s += " AND " + co.RHS2.SQL() } return s } func (io IsOp) SQL() string { str := io.LHS.SQL() + " IS " if io.Neg { str += "NOT " } str += io.RHS.SQL() return str } func (f Func) SQL() string { str := f.Name + "(" for i, e := range f.Args { if i > 0 { str += ", " } str += e.SQL() } str += ")" return str } func (p Paren) SQL() string { return "(" + p.Expr.SQL() + ")" } func (id ID) SQL() string { return string(id) } func (p Param) SQL() string { return "@" + string(p) } func (b BoolLiteral) SQL() string { if b { return "TRUE" } return "FALSE" } func (n NullLiteral) SQL() string { return "NULL" } func (StarExpr) SQL() string { return "*" } func (il IntegerLiteral) SQL() string { return strconv.Itoa(int(il)) } func (fl FloatLiteral) SQL() string { return strconv.FormatFloat(float64(fl), 'g', -1, 64) } // TODO: provide correct string quote method and use it. func (sl StringLiteral) SQL() string { return strconv.Quote(string(sl)) } func (bl BytesLiteral) SQL() string { return "B" + strconv.Quote(string(bl)) } google-cloud-go-0.49.0/spanner/spansql/sql_test.go000066400000000000000000000115531356504100700221110ustar00rootroot00000000000000/* Copyright 2019 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spansql import ( "reflect" "testing" ) func TestSQL(t *testing.T) { reparseDDL := func(s string) (interface{}, error) { ddl, err := ParseDDLStmt(s) return ddl, err } reparseQuery := func(s string) (interface{}, error) { q, err := ParseQuery(s) return q, err } reparseExpr := func(s string) (interface{}, error) { e, err := newParser(s).parseExpr() return e, err } tests := []struct { data interface{ SQL() string } sql string reparse func(string) (interface{}, error) }{ { CreateTable{ Name: "Ta", Columns: []ColumnDef{ {Name: "Ca", Type: Type{Base: Bool}, NotNull: true}, {Name: "Cb", Type: Type{Base: Int64}}, {Name: "Cc", Type: Type{Base: Float64}}, {Name: "Cd", Type: Type{Base: String, Len: 17}}, {Name: "Ce", Type: Type{Base: String, Len: MaxLen}}, {Name: "Cf", Type: Type{Base: Bytes, Len: 4711}}, {Name: "Cg", Type: Type{Base: Bytes, Len: MaxLen}}, {Name: "Ch", Type: Type{Base: Date}}, {Name: "Ci", Type: Type{Base: Timestamp}}, {Name: "Cj", Type: Type{Array: true, Base: Int64}}, {Name: "Ck", Type: Type{Array: true, Base: String, Len: MaxLen}}, }, PrimaryKey: []KeyPart{ {Column: "Ca"}, {Column: "Cb", Desc: true}, }, }, `CREATE TABLE Ta ( Ca BOOL NOT NULL, Cb INT64, Cc FLOAT64, Cd STRING(17), Ce STRING(MAX), Cf BYTES(4711), Cg BYTES(MAX), Ch DATE, Ci TIMESTAMP, Cj ARRAY, Ck ARRAY, ) PRIMARY KEY(Ca, Cb DESC)`, reparseDDL, }, { CreateTable{ Name: "Tsub", Columns: []ColumnDef{ {Name: "SomeId", Type: Type{Base: Int64}, NotNull: true}, {Name: "OtherId", Type: Type{Base: Int64}, NotNull: true}, }, PrimaryKey: []KeyPart{ {Column: "SomeId"}, {Column: "OtherId"}, }, Interleave: &Interleave{ Parent: "Ta", OnDelete: CascadeOnDelete, }, }, `CREATE TABLE Tsub ( SomeId INT64 NOT NULL, OtherId INT64 NOT NULL, ) PRIMARY KEY(SomeId, OtherId), INTERLEAVE IN PARENT Ta ON DELETE CASCADE`, reparseDDL, }, { DropTable{ Name: "Ta", }, "DROP TABLE Ta", reparseDDL, }, { CreateIndex{ Name: "Ia", Table: "Ta", Columns: []KeyPart{ {Column: "Ca"}, {Column: "Cb", Desc: true}, }, }, "CREATE INDEX Ia ON Ta(Ca, Cb DESC)", reparseDDL, }, { DropIndex{ Name: "Ia", }, "DROP INDEX Ia", reparseDDL, }, { AlterTable{ Name: "Ta", Alteration: AddColumn{Def: ColumnDef{Name: "Ca", Type: Type{Base: Bool}}}, }, "ALTER TABLE Ta ADD COLUMN Ca BOOL", reparseDDL, }, { AlterTable{ Name: "Ta", Alteration: DropColumn{Name: "Ca"}, }, "ALTER TABLE Ta DROP COLUMN Ca", reparseDDL, }, { AlterTable{ Name: "Ta", Alteration: SetOnDelete{Action: NoActionOnDelete}, }, "ALTER TABLE Ta SET ON DELETE NO ACTION", reparseDDL, }, { AlterTable{ Name: "Ta", Alteration: SetOnDelete{Action: CascadeOnDelete}, }, "ALTER TABLE Ta SET ON DELETE CASCADE", reparseDDL, }, { Query{ Select: Select{ List: []Expr{ID("A"), ID("B")}, From: []SelectFrom{{Table: "Table"}}, Where: LogicalOp{ LHS: ComparisonOp{ LHS: ID("C"), Op: Lt, RHS: StringLiteral("whelp"), }, Op: And, RHS: IsOp{ LHS: ID("D"), Neg: true, RHS: Null, }, }, }, Order: []Order{{Expr: ID("OCol"), Desc: true}}, Limit: IntegerLiteral(1000), }, `SELECT A, B FROM Table WHERE C < "whelp" AND D IS NOT NULL ORDER BY OCol DESC LIMIT 1000`, reparseQuery, }, { Query{ Select: Select{ List: []Expr{IntegerLiteral(7)}, }, }, `SELECT 7`, reparseQuery, }, { ComparisonOp{LHS: ID("X"), Op: NotBetween, RHS: ID("Y"), RHS2: ID("Z")}, `X NOT BETWEEN Y AND Z`, reparseExpr, }, } for _, test := range tests { sql := test.data.SQL() if sql != test.sql { t.Errorf("%v.SQL() wrong.\n got %s\nwant %s", test.data, sql, test.sql) continue } // As a sanity check, confirm that parsing the SQL produces the original input. data, err := test.reparse(sql) if err != nil { t.Errorf("Reparsing %q: %v", sql, err) continue } if !reflect.DeepEqual(data, test.data) { t.Errorf("Reparsing %q wrong.\n got %v\nwant %v", sql, data, test.data) } } } google-cloud-go-0.49.0/spanner/spansql/types.go000066400000000000000000000161751356504100700214240ustar00rootroot00000000000000/* Copyright 2019 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spansql // This file holds the type definitions for the SQL dialect. import ( "math" ) // CreateTable represents a CREATE TABLE statement. // https://cloud.google.com/spanner/docs/data-definition-language#create_table type CreateTable struct { Name string Columns []ColumnDef PrimaryKey []KeyPart Interleave *Interleave } // Interleave represents an interleave clause of a CREATE TABLE statement. type Interleave struct { Parent string OnDelete OnDelete } // CreateIndex represents a CREATE INDEX statement. // https://cloud.google.com/spanner/docs/data-definition-language#create-index type CreateIndex struct { Name string Table string Columns []KeyPart Unique bool NullFiltered bool Storing []string Interleave string } // DropTable represents a DROP TABLE statement. // https://cloud.google.com/spanner/docs/data-definition-language#drop_table type DropTable struct{ Name string } // DropIndex represents a DROP INDEX statement. // https://cloud.google.com/spanner/docs/data-definition-language#drop-index type DropIndex struct{ Name string } // AlterTable represents an ALTER TABLE statement. // https://cloud.google.com/spanner/docs/data-definition-language#alter_table type AlterTable struct { Name string Alteration TableAlteration } // TableAlteration is satisfied by AddColumn, DropColumn and SetOnDelete. type TableAlteration interface { isTableAlteration() SQL() string } func (AddColumn) isTableAlteration() {} func (DropColumn) isTableAlteration() {} func (SetOnDelete) isTableAlteration() {} //func (AlterColumn) isTableAlteration() {} type AddColumn struct{ Def ColumnDef } type DropColumn struct{ Name string } type SetOnDelete struct{ Action OnDelete } type OnDelete int const ( NoActionOnDelete OnDelete = iota CascadeOnDelete ) /* TODO type AlterColumn struct { } */ // ColumnDef represents a column definition as part of a CREATE TABLE // or ALTER TABLE statement. type ColumnDef struct { Name string Type Type NotNull bool } // Type represents a column type. type Type struct { Array bool Base TypeBase // Bool, Int64, Float64, String, Bytes, Date, Timestamp Len int64 // if Base is String or Bytes; may be MaxLen } // MaxLen is a sentinel for Type's Len field, representing the MAX value. const MaxLen = math.MaxInt64 type TypeBase int const ( Bool TypeBase = iota Int64 Float64 String Bytes Date Timestamp ) // KeyPart represents a column specification as part of a primary key or index definition. type KeyPart struct { Column string Desc bool } // Query represents a query statement. // https://cloud.google.com/spanner/docs/query-syntax#sql-syntax type Query struct { Select Select Order []Order Limit Limit } // Select represents a SELECT statement. // https://cloud.google.com/spanner/docs/query-syntax#select-list type Select struct { List []Expr From []SelectFrom Where BoolExpr // TODO: GroupBy, Having } type SelectFrom struct { // This only supports a FROM clause directly from a table. Table string TableSample *TableSample } type Order struct { Expr Expr Desc bool } type TableSample struct { Method TableSampleMethod Size Expr SizeType TableSampleSizeType } type TableSampleMethod int const ( Bernoulli TableSampleMethod = iota Reservoir ) type TableSampleSizeType int const ( PercentTableSample TableSampleSizeType = iota RowsTableSample ) type BoolExpr interface { isBoolExpr() Expr } type Expr interface { isExpr() SQL() string } type Limit interface { isLimit() SQL() string } type LogicalOp struct { Op LogicalOperator LHS, RHS BoolExpr // only RHS is set for Not } func (LogicalOp) isBoolExpr() {} func (LogicalOp) isExpr() {} type LogicalOperator int const ( And LogicalOperator = iota Or Not ) type ComparisonOp struct { LHS, RHS Expr Op ComparisonOperator // RHS2 is the third operand for BETWEEN. // " BETWEEN AND ". RHS2 Expr } func (ComparisonOp) isBoolExpr() {} func (ComparisonOp) isExpr() {} type ComparisonOperator int const ( Lt ComparisonOperator = iota Le Gt Ge Eq Ne // both "!=" and "<>" Like NotLike Between NotBetween ) type IsOp struct { LHS Expr Neg bool RHS IsExpr } func (IsOp) isBoolExpr() {} func (IsOp) isExpr() {} type IsExpr interface { isIsExpr() isExpr() SQL() string } // Func represents a function call. type Func struct { Name string Args []Expr // TODO: various functions permit as-expressions, which might warrant different types in here. } func (Func) isBoolExpr() {} // possibly bool func (Func) isExpr() {} // Paren represents a parenthesised expression. type Paren struct { Expr Expr } func (Paren) isBoolExpr() {} // possibly bool func (Paren) isExpr() {} // ID represents an identifier. type ID string func (ID) isBoolExpr() {} // possibly bool func (ID) isExpr() {} // Param represents a query parameter. type Param string func (Param) isBoolExpr() {} // possibly bool func (Param) isExpr() {} func (Param) isLimit() {} type BoolLiteral bool const ( True = BoolLiteral(true) False = BoolLiteral(false) ) func (BoolLiteral) isBoolExpr() {} func (BoolLiteral) isIsExpr() {} func (BoolLiteral) isExpr() {} type NullLiteral int const Null = NullLiteral(0) func (NullLiteral) isIsExpr() {} func (NullLiteral) isExpr() {} // IntegerLiteral represents an integer literal. // https://cloud.google.com/spanner/docs/lexical#integer-literals type IntegerLiteral int64 func (IntegerLiteral) isLimit() {} func (IntegerLiteral) isExpr() {} // FloatLiteral represents a floating point literal. // https://cloud.google.com/spanner/docs/lexical#floating-point-literals type FloatLiteral float64 func (FloatLiteral) isExpr() {} // StringLiteral represents a string literal. // https://cloud.google.com/spanner/docs/lexical#string-and-bytes-literals type StringLiteral string func (StringLiteral) isExpr() {} // BytesLiteral represents a bytes literal. // https://cloud.google.com/spanner/docs/lexical#string-and-bytes-literals type BytesLiteral string func (BytesLiteral) isExpr() {} type StarExpr int // Star represents a "*" in an expression. const Star = StarExpr(0) func (StarExpr) isExpr() {} // DDL // https://cloud.google.com/spanner/docs/data-definition-language#ddl_syntax // DDL represents a Data Definition Language (DDL) file. type DDL struct { List []DDLStmt } // DDLStmt is satisfied by a type that can appear in a DDL. type DDLStmt interface { isDDLStmt() SQL() string } func (CreateTable) isDDLStmt() {} func (CreateIndex) isDDLStmt() {} func (AlterTable) isDDLStmt() {} func (DropTable) isDDLStmt() {} func (DropIndex) isDDLStmt() {} google-cloud-go-0.49.0/spanner/statement.go000066400000000000000000000056141356504100700205770ustar00rootroot00000000000000/* Copyright 2017 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spanner import ( "errors" "fmt" proto3 "github.com/golang/protobuf/ptypes/struct" structpb "github.com/golang/protobuf/ptypes/struct" sppb "google.golang.org/genproto/googleapis/spanner/v1" "google.golang.org/grpc/codes" ) // A Statement is a SQL query with named parameters. // // A parameter placeholder consists of '@' followed by the parameter name. // Parameter names consist of any combination of letters, numbers, and // underscores. Names may be entirely numeric (e.g., "WHERE m.id = @5"). // Parameters may appear anywhere that a literal value is expected. The same // parameter name may be used more than once. It is an error to execute a // statement with unbound parameters. On the other hand, it is allowable to // bind parameter names that are not used. // // See the documentation of the Row type for how Go types are mapped to Cloud // Spanner types. type Statement struct { SQL string Params map[string]interface{} } // NewStatement returns a Statement with the given SQL and an empty Params map. func NewStatement(sql string) Statement { return Statement{SQL: sql, Params: map[string]interface{}{}} } var ( errNilParam = errors.New("use T(nil), not nil") errNoType = errors.New("no type information") ) // convertParams converts a statement's parameters into proto Param and // ParamTypes. func (s *Statement) convertParams() (*structpb.Struct, map[string]*sppb.Type, error) { params := &proto3.Struct{ Fields: map[string]*proto3.Value{}, } paramTypes := map[string]*sppb.Type{} for k, v := range s.Params { if v == nil { return nil, nil, errBindParam(k, v, errNilParam) } val, t, err := encodeValue(v) if err != nil { return nil, nil, errBindParam(k, v, err) } if t == nil { // should not happen, because of nil check above return nil, nil, errBindParam(k, v, errNoType) } params.Fields[k] = val paramTypes[k] = t } return params, paramTypes, nil } // errBindParam returns error for not being able to bind parameter to query // request. func errBindParam(k string, v interface{}, err error) error { if err == nil { return nil } se, ok := toSpannerError(err).(*Error) if !ok { return spannerErrorf(codes.InvalidArgument, "failed to bind query parameter(name: %q, value: %v), error = <%v>", k, v, err) } se.decorate(fmt.Sprintf("failed to bind query parameter(name: %q, value: %v)", k, v)) return se } google-cloud-go-0.49.0/spanner/statement_test.go000066400000000000000000000157051356504100700216400ustar00rootroot00000000000000/* Copyright 2017 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spanner import ( "math" "testing" "time" "cloud.google.com/go/civil" "github.com/golang/protobuf/proto" proto3 "github.com/golang/protobuf/ptypes/struct" sppb "google.golang.org/genproto/googleapis/spanner/v1" ) func TestConvertParams(t *testing.T) { st := Statement{ SQL: "SELECT id from t_foo WHERE col = @var", Params: map[string]interface{}{"var": nil}, } var ( t1, _ = time.Parse(time.RFC3339Nano, "2016-11-15T15:04:05.999999999Z") // Boundaries t2, _ = time.Parse(time.RFC3339Nano, "0001-01-01T00:00:00.000000000Z") t3, _ = time.Parse(time.RFC3339Nano, "9999-12-31T23:59:59.999999999Z") d1, _ = civil.ParseDate("2016-11-15") // Boundaries d2, _ = civil.ParseDate("0001-01-01") d3, _ = civil.ParseDate("9999-12-31") ) type staticStruct struct { Field int `spanner:"field"` } var ( s1 = staticStruct{10} s2 = staticStruct{20} ) for _, test := range []struct { val interface{} wantField *proto3.Value wantType *sppb.Type }{ // bool {true, boolProto(true), boolType()}, {NullBool{true, true}, boolProto(true), boolType()}, {NullBool{true, false}, nullProto(), boolType()}, {[]bool(nil), nullProto(), listType(boolType())}, {[]bool{}, listProto(), listType(boolType())}, {[]bool{true, false}, listProto(boolProto(true), boolProto(false)), listType(boolType())}, {[]NullBool(nil), nullProto(), listType(boolType())}, {[]NullBool{}, listProto(), listType(boolType())}, {[]NullBool{{true, true}, {}}, listProto(boolProto(true), nullProto()), listType(boolType())}, // int {int(1), intProto(1), intType()}, {[]int(nil), nullProto(), listType(intType())}, {[]int{}, listProto(), listType(intType())}, {[]int{1, 2}, listProto(intProto(1), intProto(2)), listType(intType())}, // int64 {int64(1), intProto(1), intType()}, {NullInt64{5, true}, intProto(5), intType()}, {NullInt64{5, false}, nullProto(), intType()}, {[]int64(nil), nullProto(), listType(intType())}, {[]int64{}, listProto(), listType(intType())}, {[]int64{1, 2}, listProto(intProto(1), intProto(2)), listType(intType())}, {[]NullInt64(nil), nullProto(), listType(intType())}, {[]NullInt64{}, listProto(), listType(intType())}, {[]NullInt64{{1, true}, {}}, listProto(intProto(1), nullProto()), listType(intType())}, // float64 {0.0, floatProto(0.0), floatType()}, {math.Inf(1), floatProto(math.Inf(1)), floatType()}, {math.Inf(-1), floatProto(math.Inf(-1)), floatType()}, {math.NaN(), floatProto(math.NaN()), floatType()}, {NullFloat64{2.71, true}, floatProto(2.71), floatType()}, {NullFloat64{1.41, false}, nullProto(), floatType()}, {[]float64(nil), nullProto(), listType(floatType())}, {[]float64{}, listProto(), listType(floatType())}, {[]float64{2.72, math.Inf(1)}, listProto(floatProto(2.72), floatProto(math.Inf(1))), listType(floatType())}, {[]NullFloat64(nil), nullProto(), listType(floatType())}, {[]NullFloat64{}, listProto(), listType(floatType())}, {[]NullFloat64{{2.72, true}, {}}, listProto(floatProto(2.72), nullProto()), listType(floatType())}, // string {"", stringProto(""), stringType()}, {"foo", stringProto("foo"), stringType()}, {NullString{"bar", true}, stringProto("bar"), stringType()}, {NullString{"bar", false}, nullProto(), stringType()}, {[]string(nil), nullProto(), listType(stringType())}, {[]string{}, listProto(), listType(stringType())}, {[]string{"foo", "bar"}, listProto(stringProto("foo"), stringProto("bar")), listType(stringType())}, {[]NullString(nil), nullProto(), listType(stringType())}, {[]NullString{}, listProto(), listType(stringType())}, {[]NullString{{"foo", true}, {}}, listProto(stringProto("foo"), nullProto()), listType(stringType())}, // bytes {[]byte{}, bytesProto([]byte{}), bytesType()}, {[]byte{1, 2, 3}, bytesProto([]byte{1, 2, 3}), bytesType()}, {[]byte(nil), nullProto(), bytesType()}, {[][]byte(nil), nullProto(), listType(bytesType())}, {[][]byte{}, listProto(), listType(bytesType())}, {[][]byte{{1}, []byte(nil)}, listProto(bytesProto([]byte{1}), nullProto()), listType(bytesType())}, // date {d1, dateProto(d1), dateType()}, {NullDate{civil.Date{}, false}, nullProto(), dateType()}, {[]civil.Date(nil), nullProto(), listType(dateType())}, {[]civil.Date{}, listProto(), listType(dateType())}, {[]civil.Date{d1, d2, d3}, listProto(dateProto(d1), dateProto(d2), dateProto(d3)), listType(dateType())}, {[]NullDate{{d2, true}, {}}, listProto(dateProto(d2), nullProto()), listType(dateType())}, // timestamp {t1, timeProto(t1), timeType()}, {NullTime{}, nullProto(), timeType()}, {[]time.Time(nil), nullProto(), listType(timeType())}, {[]time.Time{}, listProto(), listType(timeType())}, {[]time.Time{t1, t2, t3}, listProto(timeProto(t1), timeProto(t2), timeProto(t3)), listType(timeType())}, {[]NullTime{{t2, true}, {}}, listProto(timeProto(t2), nullProto()), listType(timeType())}, // Struct { s1, listProto(intProto(10)), structType(mkField("field", intType())), }, { (*struct { F1 civil.Date `spanner:""` F2 bool })(nil), nullProto(), structType( mkField("", dateType()), mkField("F2", boolType())), }, // Array-of-struct { []staticStruct{s1, s2}, listProto(listProto(intProto(10)), listProto(intProto(20))), listType(structType(mkField("field", intType()))), }, } { st.Params["var"] = test.val gotParams, gotParamTypes, gotErr := st.convertParams() if gotErr != nil { t.Error(gotErr) continue } gotParamField := gotParams.Fields["var"] if !proto.Equal(gotParamField, test.wantField) { // handle NaN if test.wantType.Code == floatType().Code && proto.MarshalTextString(gotParamField) == proto.MarshalTextString(test.wantField) { continue } t.Errorf("%#v: got %v, want %v\n", test.val, gotParamField, test.wantField) } gotParamType := gotParamTypes["var"] if !proto.Equal(gotParamType, test.wantType) { t.Errorf("%#v: got %v, want %v\n", test.val, gotParamType, test.wantField) } } // Verify type error reporting. for _, test := range []struct { val interface{} wantErr error }{ { nil, errBindParam("var", nil, errNilParam), }, } { st.Params["var"] = test.val _, _, gotErr := st.convertParams() if !testEqual(gotErr, test.wantErr) { t.Errorf("value %#v:\ngot: %v\nwant: %v", test.val, gotErr, test.wantErr) } } } func TestNewStatement(t *testing.T) { s := NewStatement("query") if got, want := s.SQL, "query"; got != want { t.Errorf("got %q, want %q", got, want) } } google-cloud-go-0.49.0/spanner/stats.go000066400000000000000000000026751356504100700177350ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package spanner import ( "context" "go.opencensus.io/stats" "go.opencensus.io/stats/view" ) const statsPrefix = "cloud.google.com/go/spanner/" func recordStat(ctx context.Context, m *stats.Int64Measure, n int64) { stats.Record(ctx, m.M(n)) } var ( // OpenSessionCount is a measure of the number of sessions currently opened. // It is EXPERIMENTAL and subject to change or removal without notice. OpenSessionCount = stats.Int64(statsPrefix+"open_session_count", "Number of sessions currently opened", stats.UnitDimensionless) // OpenSessionCountView is a view of the last value of OpenSessionCount. // It is EXPERIMENTAL and subject to change or removal without notice. OpenSessionCountView = &view.View{ Name: OpenSessionCount.Name(), Description: OpenSessionCount.Description(), Measure: OpenSessionCount, Aggregation: view.LastValue(), } ) google-cloud-go-0.49.0/spanner/timestampbound.go000066400000000000000000000214441356504100700216250ustar00rootroot00000000000000/* Copyright 2017 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spanner import ( "fmt" "time" pbd "github.com/golang/protobuf/ptypes/duration" pbt "github.com/golang/protobuf/ptypes/timestamp" sppb "google.golang.org/genproto/googleapis/spanner/v1" ) // timestampBoundType specifies the timestamp bound mode. type timestampBoundType int const ( strong timestampBoundType = iota // strong reads exactStaleness // read with exact staleness maxStaleness // read with max staleness minReadTimestamp // read with min freshness readTimestamp // read data at exact timestamp ) // TimestampBound defines how Cloud Spanner will choose a timestamp for a single // read/query or read-only transaction. // // There are three types of timestamp bound: strong, bounded staleness and exact // staleness. Strong is the default. // // If the Cloud Spanner database to be read is geographically distributed, stale // read-only transactions can execute more quickly than strong or read-write // transactions, because they are able to execute far from the leader replica. // // Each type of timestamp bound is discussed in detail below. A TimestampBound // can be specified when creating transactions, see the documentation of // spanner.Client for an example. // // Strong reads // // Strong reads are guaranteed to see the effects of all transactions that have // committed before the start of the read. Furthermore, all rows yielded by a // single read are consistent with each other: if any part of the read // observes a transaction, all parts of the read see the transaction. // // Strong reads are not repeatable: two consecutive strong read-only // transactions might return inconsistent results if there are concurrent // writes. If consistency across reads is required, the reads should be // executed within a transaction or at an exact read timestamp. // // Use StrongRead to create a bound of this type. // // Exact staleness // // An exact staleness timestamp bound executes reads at a user-specified // timestamp. Reads at a timestamp are guaranteed to see a consistent prefix of // the global transaction history: they observe modifications done by all // transactions with a commit timestamp less than or equal to the read // timestamp, and observe none of the modifications done by transactions with a // larger commit timestamp. They will block until all conflicting transactions // that may be assigned commit timestamps less than or equal to the read // timestamp have finished. // // The timestamp can either be expressed as an absolute Cloud Spanner commit // timestamp or a staleness relative to the current time. // // These modes do not require a "negotiation phase" to pick a timestamp. As a // result, they execute slightly faster than the equivalent boundedly stale // concurrency modes. On the other hand, boundedly stale reads usually return // fresher results. // // Use ReadTimestamp and ExactStaleness to create a bound of this type. // // Bounded staleness // // Bounded staleness modes allow Cloud Spanner to pick the read timestamp, // subject to a user-provided staleness bound. Cloud Spanner chooses the newest // timestamp within the staleness bound that allows execution of the reads at // the closest available replica without blocking. // // All rows yielded are consistent with each other: if any part of the read // observes a transaction, all parts of the read see the transaction. Boundedly // stale reads are not repeatable: two stale reads, even if they use the same // staleness bound, can execute at different timestamps and thus return // inconsistent results. // // Boundedly stale reads execute in two phases. The first phase negotiates a // timestamp among all replicas needed to serve the read. In the second phase, // reads are executed at the negotiated timestamp. // // As a result of this two-phase execution, bounded staleness reads are usually // a little slower than comparable exact staleness reads. However, they are // typically able to return fresher results, and are more likely to execute at // the closest replica. // // Because the timestamp negotiation requires up-front knowledge of which rows // will be read, it can only be used with single-use reads and single-use // read-only transactions. // // Use MinReadTimestamp and MaxStaleness to create a bound of this type. // // Old read timestamps and garbage collection // // Cloud Spanner continuously garbage collects deleted and overwritten data in // the background to reclaim storage space. This process is known as "version // GC". By default, version GC reclaims versions after they are four hours // old. Because of this, Cloud Spanner cannot perform reads at read timestamps // more than four hours in the past. This restriction also applies to // in-progress reads and/or SQL queries whose timestamps become too old while // executing. Reads and SQL queries with too-old read timestamps fail with the // error ErrorCode.FAILED_PRECONDITION. type TimestampBound struct { mode timestampBoundType d time.Duration t time.Time } // StrongRead returns a TimestampBound that will perform reads and queries at a // timestamp where all previously committed transactions are visible. func StrongRead() TimestampBound { return TimestampBound{mode: strong} } // ExactStaleness returns a TimestampBound that will perform reads and queries // at an exact staleness. func ExactStaleness(d time.Duration) TimestampBound { return TimestampBound{ mode: exactStaleness, d: d, } } // MaxStaleness returns a TimestampBound that will perform reads and queries at // a time chosen to be at most "d" stale. func MaxStaleness(d time.Duration) TimestampBound { return TimestampBound{ mode: maxStaleness, d: d, } } // MinReadTimestamp returns a TimestampBound that bound that will perform reads // and queries at a time chosen to be at least "t". func MinReadTimestamp(t time.Time) TimestampBound { return TimestampBound{ mode: minReadTimestamp, t: t, } } // ReadTimestamp returns a TimestampBound that will peform reads and queries at // the given time. func ReadTimestamp(t time.Time) TimestampBound { return TimestampBound{ mode: readTimestamp, t: t, } } func (tb TimestampBound) String() string { switch tb.mode { case strong: return fmt.Sprintf("(strong)") case exactStaleness: return fmt.Sprintf("(exactStaleness: %s)", tb.d) case maxStaleness: return fmt.Sprintf("(maxStaleness: %s)", tb.d) case minReadTimestamp: return fmt.Sprintf("(minReadTimestamp: %s)", tb.t) case readTimestamp: return fmt.Sprintf("(readTimestamp: %s)", tb.t) default: return fmt.Sprintf("{mode=%v, d=%v, t=%v}", tb.mode, tb.d, tb.t) } } // durationProto takes a time.Duration and converts it into pdb.Duration for // calling gRPC APIs. func durationProto(d time.Duration) *pbd.Duration { n := d.Nanoseconds() return &pbd.Duration{ Seconds: n / int64(time.Second), Nanos: int32(n % int64(time.Second)), } } // timestampProto takes a time.Time and converts it into pbt.Timestamp for // calling gRPC APIs. func timestampProto(t time.Time) *pbt.Timestamp { return &pbt.Timestamp{ Seconds: t.Unix(), Nanos: int32(t.Nanosecond()), } } // buildTransactionOptionsReadOnly converts a spanner.TimestampBound into a // sppb.TransactionOptions_ReadOnly transaction option, which is then used in // transactional reads. func buildTransactionOptionsReadOnly(tb TimestampBound, returnReadTimestamp bool) *sppb.TransactionOptions_ReadOnly { pb := &sppb.TransactionOptions_ReadOnly{ ReturnReadTimestamp: returnReadTimestamp, } switch tb.mode { case strong: pb.TimestampBound = &sppb.TransactionOptions_ReadOnly_Strong{ Strong: true, } case exactStaleness: pb.TimestampBound = &sppb.TransactionOptions_ReadOnly_ExactStaleness{ ExactStaleness: durationProto(tb.d), } case maxStaleness: pb.TimestampBound = &sppb.TransactionOptions_ReadOnly_MaxStaleness{ MaxStaleness: durationProto(tb.d), } case minReadTimestamp: pb.TimestampBound = &sppb.TransactionOptions_ReadOnly_MinReadTimestamp{ MinReadTimestamp: timestampProto(tb.t), } case readTimestamp: pb.TimestampBound = &sppb.TransactionOptions_ReadOnly_ReadTimestamp{ ReadTimestamp: timestampProto(tb.t), } default: panic(fmt.Sprintf("buildTransactionOptionsReadOnly(%v,%v)", tb, returnReadTimestamp)) } return pb } google-cloud-go-0.49.0/spanner/timestampbound_test.go000066400000000000000000000136161356504100700226660ustar00rootroot00000000000000/* Copyright 2017 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spanner import ( "testing" "time" pbd "github.com/golang/protobuf/ptypes/duration" pbt "github.com/golang/protobuf/ptypes/timestamp" sppb "google.golang.org/genproto/googleapis/spanner/v1" ) // Test generating TimestampBound for strong reads. func TestStrong(t *testing.T) { got := StrongRead() want := TimestampBound{mode: strong} if !testEqual(got, want) { t.Errorf("Strong() = %v; want %v", got, want) } } // Test generating TimestampBound for reads with exact staleness. func TestExactStaleness(t *testing.T) { got := ExactStaleness(10 * time.Second) want := TimestampBound{mode: exactStaleness, d: 10 * time.Second} if !testEqual(got, want) { t.Errorf("ExactStaleness(10*time.Second) = %v; want %v", got, want) } } // Test generating TimestampBound for reads with max staleness. func TestMaxStaleness(t *testing.T) { got := MaxStaleness(10 * time.Second) want := TimestampBound{mode: maxStaleness, d: 10 * time.Second} if !testEqual(got, want) { t.Errorf("MaxStaleness(10*time.Second) = %v; want %v", got, want) } } // Test generating TimestampBound for reads with minimum freshness requirement. func TestMinReadTimestamp(t *testing.T) { ts := time.Now() got := MinReadTimestamp(ts) want := TimestampBound{mode: minReadTimestamp, t: ts} if !testEqual(got, want) { t.Errorf("MinReadTimestamp(%v) = %v; want %v", ts, got, want) } } // Test generating TimestampBound for reads requesting data at a exact timestamp. func TestReadTimestamp(t *testing.T) { ts := time.Now() got := ReadTimestamp(ts) want := TimestampBound{mode: readTimestamp, t: ts} if !testEqual(got, want) { t.Errorf("ReadTimestamp(%v) = %v; want %v", ts, got, want) } } // Test TimestampBound.String. func TestTimestampBoundString(t *testing.T) { ts := time.Unix(1136239445, 0).UTC() var tests = []struct { tb TimestampBound want string }{ { tb: TimestampBound{mode: strong}, want: "(strong)", }, { tb: TimestampBound{mode: exactStaleness, d: 10 * time.Second}, want: "(exactStaleness: 10s)", }, { tb: TimestampBound{mode: maxStaleness, d: 10 * time.Second}, want: "(maxStaleness: 10s)", }, { tb: TimestampBound{mode: minReadTimestamp, t: ts}, want: "(minReadTimestamp: 2006-01-02 22:04:05 +0000 UTC)", }, { tb: TimestampBound{mode: readTimestamp, t: ts}, want: "(readTimestamp: 2006-01-02 22:04:05 +0000 UTC)", }, } for _, test := range tests { got := test.tb.String() if got != test.want { t.Errorf("%#v.String():\ngot %q\nwant %q", test.tb, got, test.want) } } } // Test time.Duration to pdb.Duration conversion. func TestDurationProto(t *testing.T) { var tests = []struct { d time.Duration want pbd.Duration }{ {time.Duration(0), pbd.Duration{Seconds: 0, Nanos: 0}}, {time.Second, pbd.Duration{Seconds: 1, Nanos: 0}}, {time.Millisecond, pbd.Duration{Seconds: 0, Nanos: 1e6}}, {15 * time.Nanosecond, pbd.Duration{Seconds: 0, Nanos: 15}}, {42 * time.Hour, pbd.Duration{Seconds: 151200}}, {-(1*time.Hour + 4*time.Millisecond), pbd.Duration{Seconds: -3600, Nanos: -4e6}}, } for _, test := range tests { got := durationProto(test.d) if !testEqual(got, &test.want) { t.Errorf("durationProto(%v) = %v; want %v", test.d, got, test.want) } } } // Test time.Time to pbt.Timestamp conversion. func TestTimeProto(t *testing.T) { var tests = []struct { t time.Time want pbt.Timestamp }{ {time.Unix(0, 0), pbt.Timestamp{}}, {time.Unix(1136239445, 12345), pbt.Timestamp{Seconds: 1136239445, Nanos: 12345}}, {time.Unix(-1000, 12345), pbt.Timestamp{Seconds: -1000, Nanos: 12345}}, } for _, test := range tests { got := timestampProto(test.t) if !testEqual(got, &test.want) { t.Errorf("timestampProto(%v) = %v; want %v", test.t, got, test.want) } } } // Test readonly transaction option builder. func TestBuildTransactionOptionsReadOnly(t *testing.T) { ts := time.Unix(1136239445, 12345) var tests = []struct { tb TimestampBound ts bool want sppb.TransactionOptions_ReadOnly }{ { StrongRead(), false, sppb.TransactionOptions_ReadOnly{ TimestampBound: &sppb.TransactionOptions_ReadOnly_Strong{ Strong: true}, ReturnReadTimestamp: false, }, }, { ExactStaleness(10 * time.Second), true, sppb.TransactionOptions_ReadOnly{ TimestampBound: &sppb.TransactionOptions_ReadOnly_ExactStaleness{ ExactStaleness: &pbd.Duration{Seconds: 10}}, ReturnReadTimestamp: true, }, }, { MaxStaleness(10 * time.Second), true, sppb.TransactionOptions_ReadOnly{ TimestampBound: &sppb.TransactionOptions_ReadOnly_MaxStaleness{ MaxStaleness: &pbd.Duration{Seconds: 10}}, ReturnReadTimestamp: true, }, }, { MinReadTimestamp(ts), true, sppb.TransactionOptions_ReadOnly{ TimestampBound: &sppb.TransactionOptions_ReadOnly_MinReadTimestamp{ MinReadTimestamp: &pbt.Timestamp{Seconds: 1136239445, Nanos: 12345}}, ReturnReadTimestamp: true, }, }, { ReadTimestamp(ts), true, sppb.TransactionOptions_ReadOnly{ TimestampBound: &sppb.TransactionOptions_ReadOnly_ReadTimestamp{ ReadTimestamp: &pbt.Timestamp{Seconds: 1136239445, Nanos: 12345}}, ReturnReadTimestamp: true, }, }, } for _, test := range tests { got := buildTransactionOptionsReadOnly(test.tb, test.ts) if !testEqual(got, &test.want) { t.Errorf("buildTransactionOptionsReadOnly(%v,%v) = %v; want %v", test.tb, test.ts, got, test.want) } } } google-cloud-go-0.49.0/spanner/transaction.go000066400000000000000000000764121356504100700211240ustar00rootroot00000000000000/* Copyright 2017 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spanner import ( "context" "sync" "sync/atomic" "time" "github.com/googleapis/gax-go/v2" "cloud.google.com/go/internal/trace" vkit "cloud.google.com/go/spanner/apiv1" "google.golang.org/api/iterator" sppb "google.golang.org/genproto/googleapis/spanner/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // transactionID stores a transaction ID which uniquely identifies a transaction // in Cloud Spanner. type transactionID []byte // txReadEnv manages a read-transaction environment consisting of a session // handle and a transaction selector. type txReadEnv interface { // acquire returns a read-transaction environment that can be used to // perform a transactional read. acquire(ctx context.Context) (*sessionHandle, *sppb.TransactionSelector, error) // sets the transaction's read timestamp setTimestamp(time.Time) // release should be called at the end of every transactional read to deal // with session recycling. release(error) } // txReadOnly contains methods for doing transactional reads. type txReadOnly struct { // read-transaction environment for performing transactional read // operations. txReadEnv // Atomic. Only needed for DML statements, but used forall. sequenceNumber int64 } // errSessionClosed returns error for using a recycled/destroyed session func errSessionClosed(sh *sessionHandle) error { return spannerErrorf(codes.FailedPrecondition, "session is already recycled / destroyed: session_id = %q, rpc_client = %v", sh.getID(), sh.getClient()) } // Read returns a RowIterator for reading multiple rows from the database. func (t *txReadOnly) Read(ctx context.Context, table string, keys KeySet, columns []string) *RowIterator { return t.ReadWithOptions(ctx, table, keys, columns, nil) } // ReadUsingIndex calls ReadWithOptions with ReadOptions{Index: index}. func (t *txReadOnly) ReadUsingIndex(ctx context.Context, table, index string, keys KeySet, columns []string) (ri *RowIterator) { return t.ReadWithOptions(ctx, table, keys, columns, &ReadOptions{Index: index}) } // ReadOptions provides options for reading rows from a database. type ReadOptions struct { // The index to use for reading. If non-empty, you can only read columns // that are part of the index key, part of the primary key, or stored in the // index due to a STORING clause in the index definition. Index string // The maximum number of rows to read. A limit value less than 1 means no // limit. Limit int } // ReadWithOptions returns a RowIterator for reading multiple rows from the // database. Pass a ReadOptions to modify the read operation. func (t *txReadOnly) ReadWithOptions(ctx context.Context, table string, keys KeySet, columns []string, opts *ReadOptions) (ri *RowIterator) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/spanner.Read") defer func() { trace.EndSpan(ctx, ri.err) }() var ( sh *sessionHandle ts *sppb.TransactionSelector err error ) kset, err := keys.keySetProto() if err != nil { return &RowIterator{err: err} } if sh, ts, err = t.acquire(ctx); err != nil { return &RowIterator{err: err} } // Cloud Spanner will return "Session not found" on bad sessions. sid, client := sh.getID(), sh.getClient() if sid == "" || client == nil { // Might happen if transaction is closed in the middle of a API call. return &RowIterator{err: errSessionClosed(sh)} } index := "" limit := 0 if opts != nil { index = opts.Index if opts.Limit > 0 { limit = opts.Limit } } return stream( contextWithOutgoingMetadata(ctx, sh.getMetadata()), func(ctx context.Context, resumeToken []byte) (streamingReceiver, error) { return client.StreamingRead(ctx, &sppb.ReadRequest{ Session: sid, Transaction: ts, Table: table, Index: index, Columns: columns, KeySet: kset, ResumeToken: resumeToken, Limit: int64(limit), }) }, t.setTimestamp, t.release, ) } // errRowNotFound returns error for not being able to read the row identified by // key. func errRowNotFound(table string, key Key) error { return spannerErrorf(codes.NotFound, "row not found(Table: %v, PrimaryKey: %v)", table, key) } // ReadRow reads a single row from the database. // // If no row is present with the given key, then ReadRow returns an error where // spanner.ErrCode(err) is codes.NotFound. func (t *txReadOnly) ReadRow(ctx context.Context, table string, key Key, columns []string) (*Row, error) { iter := t.Read(ctx, table, key, columns) defer iter.Stop() row, err := iter.Next() switch err { case iterator.Done: return nil, errRowNotFound(table, key) case nil: return row, nil default: return nil, err } } // Query executes a query against the database. It returns a RowIterator for // retrieving the resulting rows. // // Query returns only row data, without a query plan or execution statistics. // Use QueryWithStats to get rows along with the plan and statistics. Use // AnalyzeQuery to get just the plan. func (t *txReadOnly) Query(ctx context.Context, statement Statement) *RowIterator { return t.query(ctx, statement, sppb.ExecuteSqlRequest_NORMAL) } // Query executes a SQL statement against the database. It returns a RowIterator // for retrieving the resulting rows. The RowIterator will also be populated // with a query plan and execution statistics. func (t *txReadOnly) QueryWithStats(ctx context.Context, statement Statement) *RowIterator { return t.query(ctx, statement, sppb.ExecuteSqlRequest_PROFILE) } // AnalyzeQuery returns the query plan for statement. func (t *txReadOnly) AnalyzeQuery(ctx context.Context, statement Statement) (*sppb.QueryPlan, error) { iter := t.query(ctx, statement, sppb.ExecuteSqlRequest_PLAN) defer iter.Stop() for { _, err := iter.Next() if err == iterator.Done { break } if err != nil { return nil, err } } if iter.QueryPlan == nil { return nil, spannerErrorf(codes.Internal, "query plan unavailable") } return iter.QueryPlan, nil } func (t *txReadOnly) query(ctx context.Context, statement Statement, mode sppb.ExecuteSqlRequest_QueryMode) (ri *RowIterator) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/spanner.Query") defer func() { trace.EndSpan(ctx, ri.err) }() req, sh, err := t.prepareExecuteSQL(ctx, statement, mode) if err != nil { return &RowIterator{err: err} } client := sh.getClient() return stream( contextWithOutgoingMetadata(ctx, sh.getMetadata()), func(ctx context.Context, resumeToken []byte) (streamingReceiver, error) { req.ResumeToken = resumeToken return client.ExecuteStreamingSql(ctx, req) }, t.setTimestamp, t.release) } func (t *txReadOnly) prepareExecuteSQL(ctx context.Context, stmt Statement, mode sppb.ExecuteSqlRequest_QueryMode) (*sppb.ExecuteSqlRequest, *sessionHandle, error) { sh, ts, err := t.acquire(ctx) if err != nil { return nil, nil, err } // Cloud Spanner will return "Session not found" on bad sessions. sid := sh.getID() if sid == "" { // Might happen if transaction is closed in the middle of a API call. return nil, nil, errSessionClosed(sh) } params, paramTypes, err := stmt.convertParams() if err != nil { return nil, nil, err } req := &sppb.ExecuteSqlRequest{ Session: sid, Transaction: ts, Sql: stmt.SQL, QueryMode: mode, Seqno: atomic.AddInt64(&t.sequenceNumber, 1), Params: params, ParamTypes: paramTypes, } return req, sh, nil } // txState is the status of a transaction. type txState int const ( // transaction is new, waiting to be initialized.. txNew txState = iota // transaction is being initialized. txInit // transaction is active and can perform read/write. txActive // transaction is closed, cannot be used anymore. txClosed ) // errRtsUnavailable returns error for read transaction's read timestamp being // unavailable. func errRtsUnavailable() error { return spannerErrorf(codes.Internal, "read timestamp is unavailable") } // errTxClosed returns error for using a closed transaction. func errTxClosed() error { return spannerErrorf(codes.InvalidArgument, "cannot use a closed transaction") } // errUnexpectedTxState returns error for transaction enters an unexpected state. func errUnexpectedTxState(ts txState) error { return spannerErrorf(codes.FailedPrecondition, "unexpected transaction state: %v", ts) } // ReadOnlyTransaction provides a snapshot transaction with guaranteed // consistency across reads, but does not allow writes. Read-only transactions // can be configured to read at timestamps in the past. // // Read-only transactions do not take locks. Instead, they work by choosing a // Cloud Spanner timestamp, then executing all reads at that timestamp. Since // they do not acquire locks, they do not block concurrent read-write // transactions. // // Unlike locking read-write transactions, read-only transactions never abort. // They can fail if the chosen read timestamp is garbage collected; however, the // default garbage collection policy is generous enough that most applications // do not need to worry about this in practice. See the documentation of // TimestampBound for more details. // // A ReadOnlyTransaction consumes resources on the server until Close is called. type ReadOnlyTransaction struct { // mu protects concurrent access to the internal states of ReadOnlyTransaction. mu sync.Mutex // txReadOnly contains methods for performing transactional reads. txReadOnly // singleUse indicates that the transaction can be used for only one read. singleUse bool // sp is the session pool for allocating a session to execute the read-only // transaction. It is set only once during initialization of the // ReadOnlyTransaction. sp *sessionPool // tx is the transaction ID in Cloud Spanner that uniquely identifies the // ReadOnlyTransaction. tx transactionID // txReadyOrClosed is for broadcasting that transaction ID has been returned // by Cloud Spanner or that transaction is closed. txReadyOrClosed chan struct{} // state is the current transaction status of the ReadOnly transaction. state txState // sh is the sessionHandle allocated from sp. sh *sessionHandle // rts is the read timestamp returned by transactional reads. rts time.Time // tb is the read staleness bound specification for transactional reads. tb TimestampBound } // errTxInitTimeout returns error for timeout in waiting for initialization of // the transaction. func errTxInitTimeout() error { return spannerErrorf(codes.Canceled, "timeout/context canceled in waiting for transaction's initialization") } // getTimestampBound returns the read staleness bound specified for the // ReadOnlyTransaction. func (t *ReadOnlyTransaction) getTimestampBound() TimestampBound { t.mu.Lock() defer t.mu.Unlock() return t.tb } // begin starts a snapshot read-only Transaction on Cloud Spanner. func (t *ReadOnlyTransaction) begin(ctx context.Context) error { var ( locked bool tx transactionID rts time.Time sh *sessionHandle err error ) defer func() { if !locked { t.mu.Lock() // Not necessary, just to make it clear that t.mu is being held when // locked == true. locked = true } if t.state != txClosed { // Signal other initialization routines. close(t.txReadyOrClosed) t.txReadyOrClosed = make(chan struct{}) } t.mu.Unlock() if err != nil && sh != nil { // Got a valid session handle, but failed to initialize transaction= // on Cloud Spanner. if shouldDropSession(err) { sh.destroy() } // If sh.destroy was already executed, this becomes a noop. sh.recycle() } }() sh, err = t.sp.take(ctx) if err != nil { return err } res, err := sh.getClient().BeginTransaction(contextWithOutgoingMetadata(ctx, sh.getMetadata()), &sppb.BeginTransactionRequest{ Session: sh.getID(), Options: &sppb.TransactionOptions{ Mode: &sppb.TransactionOptions_ReadOnly_{ ReadOnly: buildTransactionOptionsReadOnly(t.getTimestampBound(), true), }, }, }) if err == nil { tx = res.Id if res.ReadTimestamp != nil { rts = time.Unix(res.ReadTimestamp.Seconds, int64(res.ReadTimestamp.Nanos)) } } else { err = toSpannerError(err) } t.mu.Lock() // defer function will be executed with t.mu being held. locked = true // During the execution of t.begin(), t.Close() was invoked. if t.state == txClosed { return errSessionClosed(sh) } // If begin() fails, this allows other queries to take over the // initialization. t.tx = nil if err == nil { t.tx = tx t.rts = rts t.sh = sh // State transite to txActive. t.state = txActive } return err } // acquire implements txReadEnv.acquire. func (t *ReadOnlyTransaction) acquire(ctx context.Context) (*sessionHandle, *sppb.TransactionSelector, error) { if err := checkNestedTxn(ctx); err != nil { return nil, nil, err } if t.singleUse { return t.acquireSingleUse(ctx) } return t.acquireMultiUse(ctx) } func (t *ReadOnlyTransaction) acquireSingleUse(ctx context.Context) (*sessionHandle, *sppb.TransactionSelector, error) { t.mu.Lock() defer t.mu.Unlock() switch t.state { case txClosed: // A closed single-use transaction can never be reused. return nil, nil, errTxClosed() case txNew: t.state = txClosed ts := &sppb.TransactionSelector{ Selector: &sppb.TransactionSelector_SingleUse{ SingleUse: &sppb.TransactionOptions{ Mode: &sppb.TransactionOptions_ReadOnly_{ ReadOnly: buildTransactionOptionsReadOnly(t.tb, true), }, }, }, } sh, err := t.sp.take(ctx) if err != nil { return nil, nil, err } // Install session handle into t, which can be used for readonly // operations later. t.sh = sh return sh, ts, nil } us := t.state // SingleUse transaction should only be in either txNew state or txClosed // state. return nil, nil, errUnexpectedTxState(us) } func (t *ReadOnlyTransaction) acquireMultiUse(ctx context.Context) (*sessionHandle, *sppb.TransactionSelector, error) { for { t.mu.Lock() switch t.state { case txClosed: t.mu.Unlock() return nil, nil, errTxClosed() case txNew: // State transit to txInit so that no further TimestampBound change // is accepted. t.state = txInit t.mu.Unlock() continue case txInit: if t.tx != nil { // Wait for a transaction ID to become ready. txReadyOrClosed := t.txReadyOrClosed t.mu.Unlock() select { case <-txReadyOrClosed: // Need to check transaction state again. continue case <-ctx.Done(): // The waiting for initialization is timeout, return error // directly. return nil, nil, errTxInitTimeout() } } // Take the ownership of initializing the transaction. t.tx = transactionID{} t.mu.Unlock() // Begin a read-only transaction. // // TODO: consider adding a transaction option which allow queries to // initiate transactions by themselves. Note that this option might // not be always good because the ID of the new transaction won't // be ready till the query returns some data or completes. if err := t.begin(ctx); err != nil { return nil, nil, err } // If t.begin() succeeded, t.state should have been changed to // txActive, so we can just continue here. continue case txActive: sh := t.sh ts := &sppb.TransactionSelector{ Selector: &sppb.TransactionSelector_Id{ Id: t.tx, }, } t.mu.Unlock() return sh, ts, nil } state := t.state t.mu.Unlock() return nil, nil, errUnexpectedTxState(state) } } func (t *ReadOnlyTransaction) setTimestamp(ts time.Time) { t.mu.Lock() defer t.mu.Unlock() if t.rts.IsZero() { t.rts = ts } } // release implements txReadEnv.release. func (t *ReadOnlyTransaction) release(err error) { t.mu.Lock() sh := t.sh t.mu.Unlock() if sh != nil { // sh could be nil if t.acquire() fails. if shouldDropSession(err) { sh.destroy() } if t.singleUse { // If session handle is already destroyed, this becomes a noop. sh.recycle() } } } // Close closes a ReadOnlyTransaction, the transaction cannot perform any reads // after being closed. func (t *ReadOnlyTransaction) Close() { if t.singleUse { return } t.mu.Lock() if t.state != txClosed { t.state = txClosed close(t.txReadyOrClosed) } sh := t.sh t.mu.Unlock() if sh == nil { return } // If session handle is already destroyed, this becomes a noop. If there are // still active queries and if the recycled session is reused before they // complete, Cloud Spanner will cancel them on behalf of the new transaction // on the session. if sh != nil { sh.recycle() } } // Timestamp returns the timestamp chosen to perform reads and queries in this // transaction. The value can only be read after some read or query has either // returned some data or completed without returning any data. func (t *ReadOnlyTransaction) Timestamp() (time.Time, error) { t.mu.Lock() defer t.mu.Unlock() if t.rts.IsZero() { return t.rts, errRtsUnavailable() } return t.rts, nil } // WithTimestampBound specifies the TimestampBound to use for read or query. // This can only be used before the first read or query is invoked. Note: // bounded staleness is not available with general ReadOnlyTransactions; use a // single-use ReadOnlyTransaction instead. // // The returned value is the ReadOnlyTransaction so calls can be chained. func (t *ReadOnlyTransaction) WithTimestampBound(tb TimestampBound) *ReadOnlyTransaction { t.mu.Lock() defer t.mu.Unlock() if t.state == txNew { // Only allow to set TimestampBound before the first query. t.tb = tb } return t } // ReadWriteTransaction provides a locking read-write transaction. // // This type of transaction is the only way to write data into Cloud Spanner; // (*Client).Apply, (*Client).ApplyAtLeastOnce, (*Client).PartitionedUpdate use // transactions internally. These transactions rely on pessimistic locking and, // if necessary, two-phase commit. Locking read-write transactions may abort, // requiring the application to retry. However, the interface exposed by // (*Client).ReadWriteTransaction eliminates the need for applications to write // retry loops explicitly. // // Locking transactions may be used to atomically read-modify-write data // anywhere in a database. This type of transaction is externally consistent. // // Clients should attempt to minimize the amount of time a transaction is // active. Faster transactions commit with higher probability and cause less // contention. Cloud Spanner attempts to keep read locks active as long as the // transaction continues to do reads. Long periods of inactivity at the client // may cause Cloud Spanner to release a transaction's locks and abort it. // // Reads performed within a transaction acquire locks on the data being // read. Writes can only be done at commit time, after all reads have been // completed. Conceptually, a read-write transaction consists of zero or more // reads or SQL queries followed by a commit. // // See (*Client).ReadWriteTransaction for an example. // // Semantics // // Cloud Spanner can commit the transaction if all read locks it acquired are // still valid at commit time, and it is able to acquire write locks for all // writes. Cloud Spanner can abort the transaction for any reason. If a commit // attempt returns ABORTED, Cloud Spanner guarantees that the transaction has // not modified any user data in Cloud Spanner. // // Unless the transaction commits, Cloud Spanner makes no guarantees about how // long the transaction's locks were held for. It is an error to use Cloud // Spanner locks for any sort of mutual exclusion other than between Cloud // Spanner transactions themselves. // // Aborted transactions // // Application code does not need to retry explicitly; RunInTransaction will // automatically retry a transaction if an attempt results in an abort. The lock // priority of a transaction increases after each prior aborted transaction, // meaning that the next attempt has a slightly better chance of success than // before. // // Under some circumstances (e.g., many transactions attempting to modify the // same row(s)), a transaction can abort many times in a short period before // successfully committing. Thus, it is not a good idea to cap the number of // retries a transaction can attempt; instead, it is better to limit the total // amount of wall time spent retrying. // // Idle transactions // // A transaction is considered idle if it has no outstanding reads or SQL // queries and has not started a read or SQL query within the last 10 // seconds. Idle transactions can be aborted by Cloud Spanner so that they don't // hold on to locks indefinitely. In that case, the commit will fail with error // ABORTED. // // If this behavior is undesirable, periodically executing a simple SQL query // in the transaction (e.g., SELECT 1) prevents the transaction from becoming // idle. type ReadWriteTransaction struct { // txReadOnly contains methods for performing transactional reads. txReadOnly // sh is the sessionHandle allocated from sp. It is set only once during the // initialization of ReadWriteTransaction. sh *sessionHandle // tx is the transaction ID in Cloud Spanner that uniquely identifies the // ReadWriteTransaction. It is set only once in ReadWriteTransaction.begin() // during the initialization of ReadWriteTransaction. tx transactionID // mu protects concurrent access to the internal states of // ReadWriteTransaction. mu sync.Mutex // state is the current transaction status of the read-write transaction. state txState // wb is the set of buffered mutations waiting to be committed. wb []*Mutation } // BufferWrite adds a list of mutations to the set of updates that will be // applied when the transaction is committed. It does not actually apply the // write until the transaction is committed, so the operation does not block. // The effects of the write won't be visible to any reads (including reads done // in the same transaction) until the transaction commits. // // See the example for Client.ReadWriteTransaction. func (t *ReadWriteTransaction) BufferWrite(ms []*Mutation) error { t.mu.Lock() defer t.mu.Unlock() if t.state == txClosed { return errTxClosed() } if t.state != txActive { return errUnexpectedTxState(t.state) } t.wb = append(t.wb, ms...) return nil } // Update executes a DML statement against the database. It returns the number // of affected rows. Update returns an error if the statement is a query. // However, the query is executed, and any data read will be validated upon // commit. func (t *ReadWriteTransaction) Update(ctx context.Context, stmt Statement) (rowCount int64, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/spanner.Update") defer func() { trace.EndSpan(ctx, err) }() req, sh, err := t.prepareExecuteSQL(ctx, stmt, sppb.ExecuteSqlRequest_NORMAL) if err != nil { return 0, err } resultSet, err := sh.getClient().ExecuteSql(ctx, req) if err != nil { return 0, err } if resultSet.Stats == nil { return 0, spannerErrorf(codes.InvalidArgument, "query passed to Update: %q", stmt.SQL) } return extractRowCount(resultSet.Stats) } // BatchUpdate groups one or more DML statements and sends them to Spanner in a // single RPC. This is an efficient way to execute multiple DML statements. // // A slice of counts is returned, where each count represents the number of // affected rows for the given query at the same index. If an error occurs, // counts will be returned up to the query that encountered the error. func (t *ReadWriteTransaction) BatchUpdate(ctx context.Context, stmts []Statement) (_ []int64, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/spanner.BatchUpdate") defer func() { trace.EndSpan(ctx, err) }() sh, ts, err := t.acquire(ctx) if err != nil { return nil, err } // Cloud Spanner will return "Session not found" on bad sessions. sid := sh.getID() if sid == "" { // Might happen if transaction is closed in the middle of a API call. return nil, errSessionClosed(sh) } var sppbStmts []*sppb.ExecuteBatchDmlRequest_Statement for _, st := range stmts { params, paramTypes, err := st.convertParams() if err != nil { return nil, err } sppbStmts = append(sppbStmts, &sppb.ExecuteBatchDmlRequest_Statement{ Sql: st.SQL, Params: params, ParamTypes: paramTypes, }) } resp, err := sh.getClient().ExecuteBatchDml(ctx, &sppb.ExecuteBatchDmlRequest{ Session: sh.getID(), Transaction: ts, Statements: sppbStmts, Seqno: atomic.AddInt64(&t.sequenceNumber, 1), }) if err != nil { return nil, err } var counts []int64 for _, rs := range resp.ResultSets { count, err := extractRowCount(rs.Stats) if err != nil { return nil, err } counts = append(counts, count) } if resp.Status.Code != 0 { return counts, spannerErrorf(codes.Code(uint32(resp.Status.Code)), resp.Status.Message) } return counts, nil } // acquire implements txReadEnv.acquire. func (t *ReadWriteTransaction) acquire(ctx context.Context) (*sessionHandle, *sppb.TransactionSelector, error) { ts := &sppb.TransactionSelector{ Selector: &sppb.TransactionSelector_Id{ Id: t.tx, }, } t.mu.Lock() defer t.mu.Unlock() switch t.state { case txClosed: return nil, nil, errTxClosed() case txActive: return t.sh, ts, nil } return nil, nil, errUnexpectedTxState(t.state) } // release implements txReadEnv.release. func (t *ReadWriteTransaction) release(err error) { t.mu.Lock() sh := t.sh t.mu.Unlock() if sh != nil && shouldDropSession(err) { sh.destroy() } } func beginTransaction(ctx context.Context, sid string, client *vkit.Client) (transactionID, error) { res, err := client.BeginTransaction(ctx, &sppb.BeginTransactionRequest{ Session: sid, Options: &sppb.TransactionOptions{ Mode: &sppb.TransactionOptions_ReadWrite_{ ReadWrite: &sppb.TransactionOptions_ReadWrite{}, }, }, }) if err != nil { return nil, err } return res.Id, nil } // begin starts a read-write transacton on Cloud Spanner, it is always called // before any of the public APIs. func (t *ReadWriteTransaction) begin(ctx context.Context) error { if t.tx != nil { t.state = txActive return nil } tx, err := beginTransaction(contextWithOutgoingMetadata(ctx, t.sh.getMetadata()), t.sh.getID(), t.sh.getClient()) if err == nil { t.tx = tx t.state = txActive return nil } if shouldDropSession(err) { t.sh.destroy() } return err } // commit tries to commit a readwrite transaction to Cloud Spanner. It also // returns the commit timestamp for the transactions. func (t *ReadWriteTransaction) commit(ctx context.Context) (time.Time, error) { var ts time.Time t.mu.Lock() t.state = txClosed // No further operations after commit. mPb, err := mutationsProto(t.wb) t.mu.Unlock() if err != nil { return ts, err } // In case that sessionHandle was destroyed but transaction body fails to // report it. sid, client := t.sh.getID(), t.sh.getClient() if sid == "" || client == nil { return ts, errSessionClosed(t.sh) } var trailer metadata.MD res, e := client.Commit(contextWithOutgoingMetadata(ctx, t.sh.getMetadata()), &sppb.CommitRequest{ Session: sid, Transaction: &sppb.CommitRequest_TransactionId{ TransactionId: t.tx, }, Mutations: mPb, }, gax.WithGRPCOptions(grpc.Trailer(&trailer))) if e != nil { return ts, toSpannerErrorWithMetadata(e, trailer) } if tstamp := res.GetCommitTimestamp(); tstamp != nil { ts = time.Unix(tstamp.Seconds, int64(tstamp.Nanos)) } if shouldDropSession(err) { t.sh.destroy() } return ts, err } // rollback is called when a commit is aborted or the transaction body runs // into error. func (t *ReadWriteTransaction) rollback(ctx context.Context) { t.mu.Lock() // Forbid further operations on rollbacked transaction. t.state = txClosed t.mu.Unlock() // In case that sessionHandle was destroyed but transaction body fails to // report it. sid, client := t.sh.getID(), t.sh.getClient() if sid == "" || client == nil { return } err := client.Rollback(contextWithOutgoingMetadata(ctx, t.sh.getMetadata()), &sppb.RollbackRequest{ Session: sid, TransactionId: t.tx, }) if shouldDropSession(err) { t.sh.destroy() } } // runInTransaction executes f under a read-write transaction context. func (t *ReadWriteTransaction) runInTransaction(ctx context.Context, f func(context.Context, *ReadWriteTransaction) error) (time.Time, error) { var ( ts time.Time err error ) if err = f(context.WithValue(ctx, transactionInProgressKey{}, 1), t); err == nil { // Try to commit if transaction body returns no error. ts, err = t.commit(ctx) } if err != nil { if isAbortErr(err) { // Retry the transaction using the same session on ABORT error. // Cloud Spanner will create the new transaction with the previous // one's wound-wait priority. return ts, err } // Not going to commit, according to API spec, should rollback the // transaction. t.rollback(ctx) return ts, err } // err == nil, return commit timestamp. return ts, nil } // writeOnlyTransaction provides the most efficient way of doing write-only // transactions. It essentially does blind writes to Cloud Spanner. type writeOnlyTransaction struct { // sp is the session pool which writeOnlyTransaction uses to get Cloud // Spanner sessions for blind writes. sp *sessionPool } // applyAtLeastOnce commits a list of mutations to Cloud Spanner at least once, // unless one of the following happens: // // 1) Context times out. // 2) An unretryable error (e.g. database not found) occurs. // 3) There is a malformed Mutation object. func (t *writeOnlyTransaction) applyAtLeastOnce(ctx context.Context, ms ...*Mutation) (time.Time, error) { var ( ts time.Time sh *sessionHandle ) mPb, err := mutationsProto(ms) if err != nil { // Malformed mutation found, just return the error. return ts, err } var trailers metadata.MD // Retry-loop for aborted transactions. // TODO: Replace with generic retryer. for { if sh == nil || sh.getID() == "" || sh.getClient() == nil { // No usable session for doing the commit, take one from pool. sh, err = t.sp.take(ctx) if err != nil { // sessionPool.Take already retries for session // creations/retrivals. return ts, err } } res, err := sh.getClient().Commit(contextWithOutgoingMetadata(ctx, sh.getMetadata()), &sppb.CommitRequest{ Session: sh.getID(), Transaction: &sppb.CommitRequest_SingleUseTransaction{ SingleUseTransaction: &sppb.TransactionOptions{ Mode: &sppb.TransactionOptions_ReadWrite_{ ReadWrite: &sppb.TransactionOptions_ReadWrite{}, }, }, }, Mutations: mPb, }, gax.WithGRPCOptions(grpc.Trailer(&trailers))) if err != nil && !isAbortErr(err) { if shouldDropSession(err) { // Discard the bad session. sh.destroy() } return ts, toSpannerError(err) } else if err == nil { if tstamp := res.GetCommitTimestamp(); tstamp != nil { ts = time.Unix(tstamp.Seconds, int64(tstamp.Nanos)) } break } } if sh != nil { sh.recycle() } return ts, toSpannerError(err) } // isAbortedErr returns true if the error indicates that an gRPC call is // aborted on the server side. func isAbortErr(err error) bool { if err == nil { return false } if ErrCode(err) == codes.Aborted { return true } return false } google-cloud-go-0.49.0/spanner/transaction_test.go000066400000000000000000000260701356504100700221560ustar00rootroot00000000000000/* Copyright 2017 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spanner import ( "context" "errors" "fmt" "reflect" "sync" "testing" "time" . "cloud.google.com/go/spanner/internal/testutil" sppb "google.golang.org/genproto/googleapis/spanner/v1" "google.golang.org/grpc/codes" gstatus "google.golang.org/grpc/status" ) // Single can only be used once. func TestSingle(t *testing.T) { t.Parallel() ctx := context.Background() server, client, teardown := setupMockedTestServer(t) defer teardown() txn := client.Single() defer txn.Close() _, _, e := txn.acquire(ctx) if e != nil { t.Fatalf("Acquire for single use, got %v, want nil.", e) } _, _, e = txn.acquire(ctx) if wantErr := errTxClosed(); !testEqual(e, wantErr) { t.Fatalf("Second acquire for single use, got %v, want %v.", e, wantErr) } // Only one CreateSessionRequest is sent. if _, err := shouldHaveReceived(server.TestSpanner, []interface{}{&sppb.CreateSessionRequest{}}); err != nil { t.Fatal(err) } } // Re-using ReadOnlyTransaction: can recover from acquire failure. func TestReadOnlyTransaction_RecoverFromFailure(t *testing.T) { t.Parallel() ctx := context.Background() server, client, teardown := setupMockedTestServer(t) defer teardown() txn := client.ReadOnlyTransaction() defer txn.Close() // First request will fail. errUsr := gstatus.Error(codes.Unknown, "error") server.TestSpanner.PutExecutionTime(MethodBeginTransaction, SimulatedExecutionTime{ Errors: []error{errUsr}, }) _, _, e := txn.acquire(ctx) if wantErr := toSpannerError(errUsr); !testEqual(e, wantErr) { t.Fatalf("Acquire for multi use, got %v, want %v.", e, wantErr) } _, _, e = txn.acquire(ctx) if e != nil { t.Fatalf("Acquire for multi use, got %v, want nil.", e) } } // ReadOnlyTransaction: can not be used after close. func TestReadOnlyTransaction_UseAfterClose(t *testing.T) { t.Parallel() ctx := context.Background() _, client, teardown := setupMockedTestServer(t) defer teardown() txn := client.ReadOnlyTransaction() txn.Close() _, _, e := txn.acquire(ctx) if wantErr := errTxClosed(); !testEqual(e, wantErr) { t.Fatalf("Second acquire for multi use, got %v, want %v.", e, wantErr) } } // ReadOnlyTransaction: can be acquired concurrently. func TestReadOnlyTransaction_Concurrent(t *testing.T) { t.Parallel() ctx := context.Background() server, client, teardown := setupMockedTestServer(t) defer teardown() txn := client.ReadOnlyTransaction() defer txn.Close() server.TestSpanner.Freeze() var ( sh1 *sessionHandle sh2 *sessionHandle ts1 *sppb.TransactionSelector ts2 *sppb.TransactionSelector wg = sync.WaitGroup{} ) acquire := func(sh **sessionHandle, ts **sppb.TransactionSelector) { defer wg.Done() var e error *sh, *ts, e = txn.acquire(ctx) if e != nil { t.Errorf("Concurrent acquire for multiuse, got %v, expect nil.", e) } } wg.Add(2) go acquire(&sh1, &ts1) go acquire(&sh2, &ts2) // TODO(deklerk): Get rid of this. <-time.After(100 * time.Millisecond) server.TestSpanner.Unfreeze() wg.Wait() if sh1.session.id != sh2.session.id { t.Fatalf("Expected acquire to get same session handle, got %v and %v.", sh1, sh2) } if !testEqual(ts1, ts2) { t.Fatalf("Expected acquire to get same transaction selector, got %v and %v.", ts1, ts2) } } func TestApply_Single(t *testing.T) { t.Parallel() ctx := context.Background() server, client, teardown := setupMockedTestServer(t) defer teardown() ms := []*Mutation{ Insert("Accounts", []string{"AccountId", "Nickname", "Balance"}, []interface{}{int64(1), "Foo", int64(50)}), Insert("Accounts", []string{"AccountId", "Nickname", "Balance"}, []interface{}{int64(2), "Bar", int64(1)}), } if _, e := client.Apply(ctx, ms, ApplyAtLeastOnce()); e != nil { t.Fatalf("applyAtLeastOnce retry on abort, got %v, want nil.", e) } if _, err := shouldHaveReceived(server.TestSpanner, []interface{}{ &sppb.CreateSessionRequest{}, &sppb.CommitRequest{}, }); err != nil { t.Fatal(err) } } // Transaction retries on abort. func TestApply_RetryOnAbort(t *testing.T) { ctx := context.Background() t.Parallel() server, client, teardown := setupMockedTestServer(t) defer teardown() // First commit will fail, and the retry will begin a new transaction. errAbrt := spannerErrorf(codes.Aborted, "") server.TestSpanner.PutExecutionTime(MethodCommitTransaction, SimulatedExecutionTime{ Errors: []error{errAbrt}, }) ms := []*Mutation{ Insert("Accounts", []string{"AccountId"}, []interface{}{int64(1)}), } if _, e := client.Apply(ctx, ms); e != nil { t.Fatalf("ReadWriteTransaction retry on abort, got %v, want nil.", e) } if _, err := shouldHaveReceived(server.TestSpanner, []interface{}{ &sppb.CreateSessionRequest{}, &sppb.BeginTransactionRequest{}, &sppb.CommitRequest{}, // First commit fails. &sppb.BeginTransactionRequest{}, &sppb.CommitRequest{}, // Second commit succeeds. }); err != nil { t.Fatal(err) } } // Tests that NotFound errors cause failures, and aren't retried. func TestTransaction_NotFound(t *testing.T) { t.Parallel() ctx := context.Background() server, client, teardown := setupMockedTestServer(t) defer teardown() wantErr := spannerErrorf(codes.NotFound, "Session not found") server.TestSpanner.PutExecutionTime(MethodBeginTransaction, SimulatedExecutionTime{ Errors: []error{wantErr, wantErr, wantErr}, }) server.TestSpanner.PutExecutionTime(MethodCommitTransaction, SimulatedExecutionTime{ Errors: []error{wantErr, wantErr, wantErr}, }) txn := client.ReadOnlyTransaction() defer txn.Close() if _, _, got := txn.acquire(ctx); !testEqual(wantErr, got) { t.Fatalf("Expect acquire to fail, got %v, want %v.", got, wantErr) } // The failure should recycle the session, we expect it to be used in // following requests. if got := txn.Query(ctx, NewStatement("SELECT 1")); !testEqual(wantErr, got.err) { t.Fatalf("Expect Query to fail, got %v, want %v.", got.err, wantErr) } if got := txn.Read(ctx, "Users", KeySets(Key{"alice"}, Key{"bob"}), []string{"name", "email"}); !testEqual(wantErr, got.err) { t.Fatalf("Expect Read to fail, got %v, want %v.", got.err, wantErr) } ms := []*Mutation{ Insert("Accounts", []string{"AccountId", "Nickname", "Balance"}, []interface{}{int64(1), "Foo", int64(50)}), Insert("Accounts", []string{"AccountId", "Nickname", "Balance"}, []interface{}{int64(2), "Bar", int64(1)}), } if _, got := client.Apply(ctx, ms, ApplyAtLeastOnce()); !testEqual(wantErr, got) { t.Fatalf("Expect Apply to fail, got %v, want %v.", got, wantErr) } } // When an error is returned from the closure sent into ReadWriteTransaction, it // kicks off a rollback. func TestReadWriteTransaction_ErrorReturned(t *testing.T) { t.Parallel() ctx := context.Background() server, client, teardown := setupMockedTestServer(t) defer teardown() want := errors.New("an error") _, got := client.ReadWriteTransaction(ctx, func(context.Context, *ReadWriteTransaction) error { return want }) if got != want { t.Fatalf("got %+v, want %+v", got, want) } requests := drainRequestsFromServer(server.TestSpanner) if err := compareRequests([]interface{}{ &sppb.CreateSessionRequest{}, &sppb.BeginTransactionRequest{}, &sppb.RollbackRequest{}}, requests); err != nil { // TODO: remove this once the session pool maintainer has been changed // so that is doesn't delete sessions already during the first // maintenance window. // If we failed to get 3, it might have because - due to timing - we got // a fourth request. If this request is DeleteSession, that's OK and // expected. if err := compareRequests([]interface{}{ &sppb.CreateSessionRequest{}, &sppb.BeginTransactionRequest{}, &sppb.RollbackRequest{}, &sppb.DeleteSessionRequest{}}, requests); err != nil { t.Fatal(err) } } } func TestBatchDML_WithMultipleDML(t *testing.T) { t.Parallel() ctx := context.Background() server, client, teardown := setupMockedTestServer(t) defer teardown() _, err := client.ReadWriteTransaction(ctx, func(ctx context.Context, tx *ReadWriteTransaction) (err error) { if _, err = tx.Update(ctx, Statement{SQL: UpdateBarSetFoo}); err != nil { return err } if _, err = tx.BatchUpdate(ctx, []Statement{{SQL: UpdateBarSetFoo}, {SQL: UpdateBarSetFoo}}); err != nil { return err } if _, err = tx.Update(ctx, Statement{SQL: UpdateBarSetFoo}); err != nil { return err } _, err = tx.BatchUpdate(ctx, []Statement{{SQL: UpdateBarSetFoo}}) return err }) if err != nil { t.Fatal(err) } gotReqs, err := shouldHaveReceived(server.TestSpanner, []interface{}{ &sppb.CreateSessionRequest{}, &sppb.BeginTransactionRequest{}, &sppb.ExecuteSqlRequest{}, &sppb.ExecuteBatchDmlRequest{}, &sppb.ExecuteSqlRequest{}, &sppb.ExecuteBatchDmlRequest{}, &sppb.CommitRequest{}, }) if err != nil { t.Fatal(err) } if got, want := gotReqs[2].(*sppb.ExecuteSqlRequest).Seqno, int64(1); got != want { t.Errorf("got %d, want %d", got, want) } if got, want := gotReqs[3].(*sppb.ExecuteBatchDmlRequest).Seqno, int64(2); got != want { t.Errorf("got %d, want %d", got, want) } if got, want := gotReqs[4].(*sppb.ExecuteSqlRequest).Seqno, int64(3); got != want { t.Errorf("got %d, want %d", got, want) } if got, want := gotReqs[5].(*sppb.ExecuteBatchDmlRequest).Seqno, int64(4); got != want { t.Errorf("got %d, want %d", got, want) } } // shouldHaveReceived asserts that exactly expectedRequests were present in // the server's ReceivedRequests channel. It only looks at type, not contents. // // Note: this in-place modifies serverClientMock by popping items off the // ReceivedRequests channel. func shouldHaveReceived(server InMemSpannerServer, want []interface{}) ([]interface{}, error) { got := drainRequestsFromServer(server) return got, compareRequests(want, got) } // Compares expected requests (want) with actual requests (got). func compareRequests(want []interface{}, got []interface{}) error { if len(got) != len(want) { var gotMsg string for _, r := range got { gotMsg += fmt.Sprintf("%v: %+v]\n", reflect.TypeOf(r), r) } var wantMsg string for _, r := range want { wantMsg += fmt.Sprintf("%v: %+v]\n", reflect.TypeOf(r), r) } return fmt.Errorf("got %d requests, want %d requests:\ngot:\n%s\nwant:\n%s", len(got), len(want), gotMsg, wantMsg) } for i, want := range want { if reflect.TypeOf(got[i]) != reflect.TypeOf(want) { return fmt.Errorf("request %d: got %+v, want %+v", i, reflect.TypeOf(got[i]), reflect.TypeOf(want)) } } return nil } func drainRequestsFromServer(server InMemSpannerServer) []interface{} { var reqs []interface{} loop: for { select { case req := <-server.ReceivedRequests(): reqs = append(reqs, req) default: break loop } } return reqs } google-cloud-go-0.49.0/spanner/value.go000066400000000000000000001212611356504100700177040ustar00rootroot00000000000000/* Copyright 2017 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spanner import ( "encoding/base64" "fmt" "math" "reflect" "strconv" "time" "cloud.google.com/go/civil" "cloud.google.com/go/internal/fields" proto "github.com/golang/protobuf/proto" proto3 "github.com/golang/protobuf/ptypes/struct" sppb "google.golang.org/genproto/googleapis/spanner/v1" "google.golang.org/grpc/codes" ) // nullString is returned by the String methods of NullableValues when the // underlying database value is null. const nullString = "" const commitTimestampPlaceholderString = "spanner.commit_timestamp()" var ( // CommitTimestamp is a special value used to tell Cloud Spanner to insert // the commit timestamp of the transaction into a column. It can be used in // a Mutation, or directly used in InsertStruct or InsertMap. See // ExampleCommitTimestamp. This is just a placeholder and the actual value // stored in this variable has no meaning. CommitTimestamp = commitTimestamp commitTimestamp = time.Unix(0, 0).In(time.FixedZone("CommitTimestamp placeholder", 0xDB)) ) // NullableValue is the interface implemented by all null value wrapper types. type NullableValue interface { // IsNull returns true if the underlying database value is null. IsNull() bool } // NullInt64 represents a Cloud Spanner INT64 that may be NULL. type NullInt64 struct { Int64 int64 Valid bool // Valid is true if Int64 is not NULL. } // IsNull implements NullableValue.IsNull for NullInt64. func (n NullInt64) IsNull() bool { return !n.Valid } // String implements Stringer.String for NullInt64 func (n NullInt64) String() string { if !n.Valid { return nullString } return fmt.Sprintf("%v", n.Int64) } // NullString represents a Cloud Spanner STRING that may be NULL. type NullString struct { StringVal string Valid bool // Valid is true if StringVal is not NULL. } // IsNull implements NullableValue.IsNull for NullString. func (n NullString) IsNull() bool { return !n.Valid } // String implements Stringer.String for NullString func (n NullString) String() string { if !n.Valid { return nullString } return n.StringVal } // NullFloat64 represents a Cloud Spanner FLOAT64 that may be NULL. type NullFloat64 struct { Float64 float64 Valid bool // Valid is true if Float64 is not NULL. } // IsNull implements NullableValue.IsNull for NullFloat64. func (n NullFloat64) IsNull() bool { return !n.Valid } // String implements Stringer.String for NullFloat64 func (n NullFloat64) String() string { if !n.Valid { return nullString } return fmt.Sprintf("%v", n.Float64) } // NullBool represents a Cloud Spanner BOOL that may be NULL. type NullBool struct { Bool bool Valid bool // Valid is true if Bool is not NULL. } // IsNull implements NullableValue.IsNull for NullBool. func (n NullBool) IsNull() bool { return !n.Valid } // String implements Stringer.String for NullBool func (n NullBool) String() string { if !n.Valid { return nullString } return fmt.Sprintf("%v", n.Bool) } // NullTime represents a Cloud Spanner TIMESTAMP that may be null. type NullTime struct { Time time.Time Valid bool // Valid is true if Time is not NULL. } // IsNull implements NullableValue.IsNull for NullTime. func (n NullTime) IsNull() bool { return !n.Valid } // String implements Stringer.String for NullTime func (n NullTime) String() string { if !n.Valid { return nullString } return n.Time.Format(time.RFC3339Nano) } // NullDate represents a Cloud Spanner DATE that may be null. type NullDate struct { Date civil.Date Valid bool // Valid is true if Date is not NULL. } // IsNull implements NullableValue.IsNull for NullDate. func (n NullDate) IsNull() bool { return !n.Valid } // String implements Stringer.String for NullDate func (n NullDate) String() string { if !n.Valid { return nullString } return n.Date.String() } // NullRow represents a Cloud Spanner STRUCT that may be NULL. // See also the document for Row. // Note that NullRow is not a valid Cloud Spanner column Type. type NullRow struct { Row Row Valid bool // Valid is true if Row is not NULL. } // GenericColumnValue represents the generic encoded value and type of the // column. See google.spanner.v1.ResultSet proto for details. This can be // useful for proxying query results when the result types are not known in // advance. // // If you populate a GenericColumnValue from a row using Row.Column or related // methods, do not modify the contents of Type and Value. type GenericColumnValue struct { Type *sppb.Type Value *proto3.Value } // Decode decodes a GenericColumnValue. The ptr argument should be a pointer // to a Go value that can accept v. func (v GenericColumnValue) Decode(ptr interface{}) error { return decodeValue(v.Value, v.Type, ptr) } // NewGenericColumnValue creates a GenericColumnValue from Go value that is // valid for Cloud Spanner. func newGenericColumnValue(v interface{}) (*GenericColumnValue, error) { value, typ, err := encodeValue(v) if err != nil { return nil, err } return &GenericColumnValue{Value: value, Type: typ}, nil } // errTypeMismatch returns error for destination not having a compatible type // with source Cloud Spanner type. func errTypeMismatch(srcCode, elCode sppb.TypeCode, dst interface{}) error { s := srcCode.String() if srcCode == sppb.TypeCode_ARRAY { s = fmt.Sprintf("%v[%v]", srcCode, elCode) } return spannerErrorf(codes.InvalidArgument, "type %T cannot be used for decoding %s", dst, s) } // errNilSpannerType returns error for nil Cloud Spanner type in decoding. func errNilSpannerType() error { return spannerErrorf(codes.FailedPrecondition, "unexpected nil Cloud Spanner data type in decoding") } // errNilSrc returns error for decoding from nil proto value. func errNilSrc() error { return spannerErrorf(codes.FailedPrecondition, "unexpected nil Cloud Spanner value in decoding") } // errNilDst returns error for decoding into nil interface{}. func errNilDst(dst interface{}) error { return spannerErrorf(codes.InvalidArgument, "cannot decode into nil type %T", dst) } // errNilArrElemType returns error for input Cloud Spanner data type being a array but without a // non-nil array element type. func errNilArrElemType(t *sppb.Type) error { return spannerErrorf(codes.FailedPrecondition, "array type %v is with nil array element type", t) } func errUnsupportedEmbeddedStructFields(fname string) error { return spannerErrorf(codes.InvalidArgument, "Embedded field: %s. Embedded and anonymous fields are not allowed "+ "when converting Go structs to Cloud Spanner STRUCT values. To create a STRUCT value with an "+ "unnamed field, use a `spanner:\"\"` field tag.", fname) } // errDstNotForNull returns error for decoding a SQL NULL value into a destination which doesn't // support NULL values. func errDstNotForNull(dst interface{}) error { return spannerErrorf(codes.InvalidArgument, "destination %T cannot support NULL SQL values", dst) } // errBadEncoding returns error for decoding wrongly encoded types. func errBadEncoding(v *proto3.Value, err error) error { return spannerErrorf(codes.FailedPrecondition, "%v wasn't correctly encoded: <%v>", v, err) } func parseNullTime(v *proto3.Value, p *NullTime, code sppb.TypeCode, isNull bool) error { if p == nil { return errNilDst(p) } if code != sppb.TypeCode_TIMESTAMP { return errTypeMismatch(code, sppb.TypeCode_TYPE_CODE_UNSPECIFIED, p) } if isNull { *p = NullTime{} return nil } x, err := getStringValue(v) if err != nil { return err } y, err := time.Parse(time.RFC3339Nano, x) if err != nil { return errBadEncoding(v, err) } p.Valid = true p.Time = y return nil } // decodeValue decodes a protobuf Value into a pointer to a Go value, as // specified by sppb.Type. func decodeValue(v *proto3.Value, t *sppb.Type, ptr interface{}) error { if v == nil { return errNilSrc() } if t == nil { return errNilSpannerType() } code := t.Code acode := sppb.TypeCode_TYPE_CODE_UNSPECIFIED if code == sppb.TypeCode_ARRAY { if t.ArrayElementType == nil { return errNilArrElemType(t) } acode = t.ArrayElementType.Code } _, isNull := v.Kind.(*proto3.Value_NullValue) // Do the decoding based on the type of ptr. switch p := ptr.(type) { case nil: return errNilDst(nil) case *string: if p == nil { return errNilDst(p) } if code != sppb.TypeCode_STRING { return errTypeMismatch(code, acode, ptr) } if isNull { return errDstNotForNull(ptr) } x, err := getStringValue(v) if err != nil { return err } *p = x case *NullString: if p == nil { return errNilDst(p) } if code != sppb.TypeCode_STRING { return errTypeMismatch(code, acode, ptr) } if isNull { *p = NullString{} break } x, err := getStringValue(v) if err != nil { return err } p.Valid = true p.StringVal = x case *[]NullString: if p == nil { return errNilDst(p) } if acode != sppb.TypeCode_STRING { return errTypeMismatch(code, acode, ptr) } if isNull { *p = nil break } x, err := getListValue(v) if err != nil { return err } y, err := decodeNullStringArray(x) if err != nil { return err } *p = y case *[]string: if p == nil { return errNilDst(p) } if acode != sppb.TypeCode_STRING { return errTypeMismatch(code, acode, ptr) } if isNull { *p = nil break } x, err := getListValue(v) if err != nil { return err } y, err := decodeStringArray(x) if err != nil { return err } *p = y case *[]byte: if p == nil { return errNilDst(p) } if code != sppb.TypeCode_BYTES { return errTypeMismatch(code, acode, ptr) } if isNull { *p = nil break } x, err := getStringValue(v) if err != nil { return err } y, err := base64.StdEncoding.DecodeString(x) if err != nil { return errBadEncoding(v, err) } *p = y case *[][]byte: if p == nil { return errNilDst(p) } if acode != sppb.TypeCode_BYTES { return errTypeMismatch(code, acode, ptr) } if isNull { *p = nil break } x, err := getListValue(v) if err != nil { return err } y, err := decodeByteArray(x) if err != nil { return err } *p = y case *int64: if p == nil { return errNilDst(p) } if code != sppb.TypeCode_INT64 { return errTypeMismatch(code, acode, ptr) } if isNull { return errDstNotForNull(ptr) } x, err := getStringValue(v) if err != nil { return err } y, err := strconv.ParseInt(x, 10, 64) if err != nil { return errBadEncoding(v, err) } *p = y case *NullInt64: if p == nil { return errNilDst(p) } if code != sppb.TypeCode_INT64 { return errTypeMismatch(code, acode, ptr) } if isNull { *p = NullInt64{} break } x, err := getStringValue(v) if err != nil { return err } y, err := strconv.ParseInt(x, 10, 64) if err != nil { return errBadEncoding(v, err) } p.Valid = true p.Int64 = y case *[]NullInt64: if p == nil { return errNilDst(p) } if acode != sppb.TypeCode_INT64 { return errTypeMismatch(code, acode, ptr) } if isNull { *p = nil break } x, err := getListValue(v) if err != nil { return err } y, err := decodeNullInt64Array(x) if err != nil { return err } *p = y case *[]int64: if p == nil { return errNilDst(p) } if acode != sppb.TypeCode_INT64 { return errTypeMismatch(code, acode, ptr) } if isNull { *p = nil break } x, err := getListValue(v) if err != nil { return err } y, err := decodeInt64Array(x) if err != nil { return err } *p = y case *bool: if p == nil { return errNilDst(p) } if code != sppb.TypeCode_BOOL { return errTypeMismatch(code, acode, ptr) } if isNull { return errDstNotForNull(ptr) } x, err := getBoolValue(v) if err != nil { return err } *p = x case *NullBool: if p == nil { return errNilDst(p) } if code != sppb.TypeCode_BOOL { return errTypeMismatch(code, acode, ptr) } if isNull { *p = NullBool{} break } x, err := getBoolValue(v) if err != nil { return err } p.Valid = true p.Bool = x case *[]NullBool: if p == nil { return errNilDst(p) } if acode != sppb.TypeCode_BOOL { return errTypeMismatch(code, acode, ptr) } if isNull { *p = nil break } x, err := getListValue(v) if err != nil { return err } y, err := decodeNullBoolArray(x) if err != nil { return err } *p = y case *[]bool: if p == nil { return errNilDst(p) } if acode != sppb.TypeCode_BOOL { return errTypeMismatch(code, acode, ptr) } if isNull { *p = nil break } x, err := getListValue(v) if err != nil { return err } y, err := decodeBoolArray(x) if err != nil { return err } *p = y case *float64: if p == nil { return errNilDst(p) } if code != sppb.TypeCode_FLOAT64 { return errTypeMismatch(code, acode, ptr) } if isNull { return errDstNotForNull(ptr) } x, err := getFloat64Value(v) if err != nil { return err } *p = x case *NullFloat64: if p == nil { return errNilDst(p) } if code != sppb.TypeCode_FLOAT64 { return errTypeMismatch(code, acode, ptr) } if isNull { *p = NullFloat64{} break } x, err := getFloat64Value(v) if err != nil { return err } p.Valid = true p.Float64 = x case *[]NullFloat64: if p == nil { return errNilDst(p) } if acode != sppb.TypeCode_FLOAT64 { return errTypeMismatch(code, acode, ptr) } if isNull { *p = nil break } x, err := getListValue(v) if err != nil { return err } y, err := decodeNullFloat64Array(x) if err != nil { return err } *p = y case *[]float64: if p == nil { return errNilDst(p) } if acode != sppb.TypeCode_FLOAT64 { return errTypeMismatch(code, acode, ptr) } if isNull { *p = nil break } x, err := getListValue(v) if err != nil { return err } y, err := decodeFloat64Array(x) if err != nil { return err } *p = y case *time.Time: var nt NullTime if isNull { return errDstNotForNull(ptr) } err := parseNullTime(v, &nt, code, isNull) if err != nil { return err } *p = nt.Time case *NullTime: err := parseNullTime(v, p, code, isNull) if err != nil { return err } case *[]NullTime: if p == nil { return errNilDst(p) } if acode != sppb.TypeCode_TIMESTAMP { return errTypeMismatch(code, acode, ptr) } if isNull { *p = nil break } x, err := getListValue(v) if err != nil { return err } y, err := decodeNullTimeArray(x) if err != nil { return err } *p = y case *[]time.Time: if p == nil { return errNilDst(p) } if acode != sppb.TypeCode_TIMESTAMP { return errTypeMismatch(code, acode, ptr) } if isNull { *p = nil break } x, err := getListValue(v) if err != nil { return err } y, err := decodeTimeArray(x) if err != nil { return err } *p = y case *civil.Date: if p == nil { return errNilDst(p) } if code != sppb.TypeCode_DATE { return errTypeMismatch(code, acode, ptr) } if isNull { return errDstNotForNull(ptr) } x, err := getStringValue(v) if err != nil { return err } y, err := civil.ParseDate(x) if err != nil { return errBadEncoding(v, err) } *p = y case *NullDate: if p == nil { return errNilDst(p) } if code != sppb.TypeCode_DATE { return errTypeMismatch(code, acode, ptr) } if isNull { *p = NullDate{} break } x, err := getStringValue(v) if err != nil { return err } y, err := civil.ParseDate(x) if err != nil { return errBadEncoding(v, err) } p.Valid = true p.Date = y case *[]NullDate: if p == nil { return errNilDst(p) } if acode != sppb.TypeCode_DATE { return errTypeMismatch(code, acode, ptr) } if isNull { *p = nil break } x, err := getListValue(v) if err != nil { return err } y, err := decodeNullDateArray(x) if err != nil { return err } *p = y case *[]civil.Date: if p == nil { return errNilDst(p) } if acode != sppb.TypeCode_DATE { return errTypeMismatch(code, acode, ptr) } if isNull { *p = nil break } x, err := getListValue(v) if err != nil { return err } y, err := decodeDateArray(x) if err != nil { return err } *p = y case *[]NullRow: if p == nil { return errNilDst(p) } if acode != sppb.TypeCode_STRUCT { return errTypeMismatch(code, acode, ptr) } if isNull { *p = nil break } x, err := getListValue(v) if err != nil { return err } y, err := decodeRowArray(t.ArrayElementType.StructType, x) if err != nil { return err } *p = y case *GenericColumnValue: *p = GenericColumnValue{Type: t, Value: v} default: // Check if the proto encoding is for an array of structs. if !(code == sppb.TypeCode_ARRAY && acode == sppb.TypeCode_STRUCT) { return errTypeMismatch(code, acode, ptr) } vp := reflect.ValueOf(p) if !vp.IsValid() { return errNilDst(p) } if !isPtrStructPtrSlice(vp.Type()) { // The container is not a pointer to a struct pointer slice. return errTypeMismatch(code, acode, ptr) } // Only use reflection for nil detection on slow path. // Also, IsNil panics on many types, so check it after the type check. if vp.IsNil() { return errNilDst(p) } if isNull { // The proto Value is encoding NULL, set the pointer to struct // slice to nil as well. vp.Elem().Set(reflect.Zero(vp.Elem().Type())) break } x, err := getListValue(v) if err != nil { return err } if err = decodeStructArray(t.ArrayElementType.StructType, x, p); err != nil { return err } } return nil } // errSrvVal returns an error for getting a wrong source protobuf value in decoding. func errSrcVal(v *proto3.Value, want string) error { return spannerErrorf(codes.FailedPrecondition, "cannot use %v(Kind: %T) as %s Value", v, v.GetKind(), want) } // getStringValue returns the string value encoded in proto3.Value v whose // kind is proto3.Value_StringValue. func getStringValue(v *proto3.Value) (string, error) { if x, ok := v.GetKind().(*proto3.Value_StringValue); ok && x != nil { return x.StringValue, nil } return "", errSrcVal(v, "String") } // getBoolValue returns the bool value encoded in proto3.Value v whose // kind is proto3.Value_BoolValue. func getBoolValue(v *proto3.Value) (bool, error) { if x, ok := v.GetKind().(*proto3.Value_BoolValue); ok && x != nil { return x.BoolValue, nil } return false, errSrcVal(v, "Bool") } // getListValue returns the proto3.ListValue contained in proto3.Value v whose // kind is proto3.Value_ListValue. func getListValue(v *proto3.Value) (*proto3.ListValue, error) { if x, ok := v.GetKind().(*proto3.Value_ListValue); ok && x != nil { return x.ListValue, nil } return nil, errSrcVal(v, "List") } // errUnexpectedNumStr returns error for decoder getting a unexpected string for // representing special float values. func errUnexpectedNumStr(s string) error { return spannerErrorf(codes.FailedPrecondition, "unexpected string value %q for number", s) } // getFloat64Value returns the float64 value encoded in proto3.Value v whose // kind is proto3.Value_NumberValue / proto3.Value_StringValue. // Cloud Spanner uses string to encode NaN, Infinity and -Infinity. func getFloat64Value(v *proto3.Value) (float64, error) { switch x := v.GetKind().(type) { case *proto3.Value_NumberValue: if x == nil { break } return x.NumberValue, nil case *proto3.Value_StringValue: if x == nil { break } switch x.StringValue { case "NaN": return math.NaN(), nil case "Infinity": return math.Inf(1), nil case "-Infinity": return math.Inf(-1), nil default: return 0, errUnexpectedNumStr(x.StringValue) } } return 0, errSrcVal(v, "Number") } // errNilListValue returns error for unexpected nil ListValue in decoding Cloud Spanner ARRAYs. func errNilListValue(sqlType string) error { return spannerErrorf(codes.FailedPrecondition, "unexpected nil ListValue in decoding %v array", sqlType) } // errDecodeArrayElement returns error for failure in decoding single array element. func errDecodeArrayElement(i int, v proto.Message, sqlType string, err error) error { se, ok := toSpannerError(err).(*Error) if !ok { return spannerErrorf(codes.Unknown, "cannot decode %v(array element %v) as %v, error = <%v>", v, i, sqlType, err) } se.decorate(fmt.Sprintf("cannot decode %v(array element %v) as %v", v, i, sqlType)) return se } // decodeNullStringArray decodes proto3.ListValue pb into a NullString slice. func decodeNullStringArray(pb *proto3.ListValue) ([]NullString, error) { if pb == nil { return nil, errNilListValue("STRING") } a := make([]NullString, len(pb.Values)) for i, v := range pb.Values { if err := decodeValue(v, stringType(), &a[i]); err != nil { return nil, errDecodeArrayElement(i, v, "STRING", err) } } return a, nil } // decodeStringArray decodes proto3.ListValue pb into a string slice. func decodeStringArray(pb *proto3.ListValue) ([]string, error) { if pb == nil { return nil, errNilListValue("STRING") } a := make([]string, len(pb.Values)) st := stringType() for i, v := range pb.Values { if err := decodeValue(v, st, &a[i]); err != nil { return nil, errDecodeArrayElement(i, v, "STRING", err) } } return a, nil } // decodeNullInt64Array decodes proto3.ListValue pb into a NullInt64 slice. func decodeNullInt64Array(pb *proto3.ListValue) ([]NullInt64, error) { if pb == nil { return nil, errNilListValue("INT64") } a := make([]NullInt64, len(pb.Values)) for i, v := range pb.Values { if err := decodeValue(v, intType(), &a[i]); err != nil { return nil, errDecodeArrayElement(i, v, "INT64", err) } } return a, nil } // decodeInt64Array decodes proto3.ListValue pb into a int64 slice. func decodeInt64Array(pb *proto3.ListValue) ([]int64, error) { if pb == nil { return nil, errNilListValue("INT64") } a := make([]int64, len(pb.Values)) for i, v := range pb.Values { if err := decodeValue(v, intType(), &a[i]); err != nil { return nil, errDecodeArrayElement(i, v, "INT64", err) } } return a, nil } // decodeNullBoolArray decodes proto3.ListValue pb into a NullBool slice. func decodeNullBoolArray(pb *proto3.ListValue) ([]NullBool, error) { if pb == nil { return nil, errNilListValue("BOOL") } a := make([]NullBool, len(pb.Values)) for i, v := range pb.Values { if err := decodeValue(v, boolType(), &a[i]); err != nil { return nil, errDecodeArrayElement(i, v, "BOOL", err) } } return a, nil } // decodeBoolArray decodes proto3.ListValue pb into a bool slice. func decodeBoolArray(pb *proto3.ListValue) ([]bool, error) { if pb == nil { return nil, errNilListValue("BOOL") } a := make([]bool, len(pb.Values)) for i, v := range pb.Values { if err := decodeValue(v, boolType(), &a[i]); err != nil { return nil, errDecodeArrayElement(i, v, "BOOL", err) } } return a, nil } // decodeNullFloat64Array decodes proto3.ListValue pb into a NullFloat64 slice. func decodeNullFloat64Array(pb *proto3.ListValue) ([]NullFloat64, error) { if pb == nil { return nil, errNilListValue("FLOAT64") } a := make([]NullFloat64, len(pb.Values)) for i, v := range pb.Values { if err := decodeValue(v, floatType(), &a[i]); err != nil { return nil, errDecodeArrayElement(i, v, "FLOAT64", err) } } return a, nil } // decodeFloat64Array decodes proto3.ListValue pb into a float64 slice. func decodeFloat64Array(pb *proto3.ListValue) ([]float64, error) { if pb == nil { return nil, errNilListValue("FLOAT64") } a := make([]float64, len(pb.Values)) for i, v := range pb.Values { if err := decodeValue(v, floatType(), &a[i]); err != nil { return nil, errDecodeArrayElement(i, v, "FLOAT64", err) } } return a, nil } // decodeByteArray decodes proto3.ListValue pb into a slice of byte slice. func decodeByteArray(pb *proto3.ListValue) ([][]byte, error) { if pb == nil { return nil, errNilListValue("BYTES") } a := make([][]byte, len(pb.Values)) for i, v := range pb.Values { if err := decodeValue(v, bytesType(), &a[i]); err != nil { return nil, errDecodeArrayElement(i, v, "BYTES", err) } } return a, nil } // decodeNullTimeArray decodes proto3.ListValue pb into a NullTime slice. func decodeNullTimeArray(pb *proto3.ListValue) ([]NullTime, error) { if pb == nil { return nil, errNilListValue("TIMESTAMP") } a := make([]NullTime, len(pb.Values)) for i, v := range pb.Values { if err := decodeValue(v, timeType(), &a[i]); err != nil { return nil, errDecodeArrayElement(i, v, "TIMESTAMP", err) } } return a, nil } // decodeTimeArray decodes proto3.ListValue pb into a time.Time slice. func decodeTimeArray(pb *proto3.ListValue) ([]time.Time, error) { if pb == nil { return nil, errNilListValue("TIMESTAMP") } a := make([]time.Time, len(pb.Values)) for i, v := range pb.Values { if err := decodeValue(v, timeType(), &a[i]); err != nil { return nil, errDecodeArrayElement(i, v, "TIMESTAMP", err) } } return a, nil } // decodeNullDateArray decodes proto3.ListValue pb into a NullDate slice. func decodeNullDateArray(pb *proto3.ListValue) ([]NullDate, error) { if pb == nil { return nil, errNilListValue("DATE") } a := make([]NullDate, len(pb.Values)) for i, v := range pb.Values { if err := decodeValue(v, dateType(), &a[i]); err != nil { return nil, errDecodeArrayElement(i, v, "DATE", err) } } return a, nil } // decodeDateArray decodes proto3.ListValue pb into a civil.Date slice. func decodeDateArray(pb *proto3.ListValue) ([]civil.Date, error) { if pb == nil { return nil, errNilListValue("DATE") } a := make([]civil.Date, len(pb.Values)) for i, v := range pb.Values { if err := decodeValue(v, dateType(), &a[i]); err != nil { return nil, errDecodeArrayElement(i, v, "DATE", err) } } return a, nil } func errNotStructElement(i int, v *proto3.Value) error { return errDecodeArrayElement(i, v, "STRUCT", spannerErrorf(codes.FailedPrecondition, "%v(type: %T) doesn't encode Cloud Spanner STRUCT", v, v)) } // decodeRowArray decodes proto3.ListValue pb into a NullRow slice according to // the structural information given in sppb.StructType ty. func decodeRowArray(ty *sppb.StructType, pb *proto3.ListValue) ([]NullRow, error) { if pb == nil { return nil, errNilListValue("STRUCT") } a := make([]NullRow, len(pb.Values)) for i := range pb.Values { switch v := pb.Values[i].GetKind().(type) { case *proto3.Value_ListValue: a[i] = NullRow{ Row: Row{ fields: ty.Fields, vals: v.ListValue.Values, }, Valid: true, } // Null elements not currently supported by the server, see // https://cloud.google.com/spanner/docs/query-syntax#using-structs-with-select case *proto3.Value_NullValue: // no-op, a[i] is NullRow{} already default: return nil, errNotStructElement(i, pb.Values[i]) } } return a, nil } // errNilSpannerStructType returns error for unexpected nil Cloud Spanner STRUCT // schema type in decoding. func errNilSpannerStructType() error { return spannerErrorf(codes.FailedPrecondition, "unexpected nil StructType in decoding Cloud Spanner STRUCT") } // errUnnamedField returns error for decoding a Cloud Spanner STRUCT with // unnamed field into a Go struct. func errUnnamedField(ty *sppb.StructType, i int) error { return spannerErrorf(codes.InvalidArgument, "unnamed field %v in Cloud Spanner STRUCT %+v", i, ty) } // errNoOrDupGoField returns error for decoding a Cloud Spanner // STRUCT into a Go struct which is either missing a field, or has duplicate // fields. func errNoOrDupGoField(s interface{}, f string) error { return spannerErrorf(codes.InvalidArgument, "Go struct %+v(type %T) has no or duplicate fields for Cloud Spanner STRUCT field %v", s, s, f) } // errDupColNames returns error for duplicated Cloud Spanner STRUCT field names // found in decoding a Cloud Spanner STRUCT into a Go struct. func errDupSpannerField(f string, ty *sppb.StructType) error { return spannerErrorf(codes.InvalidArgument, "duplicated field name %q in Cloud Spanner STRUCT %+v", f, ty) } // errDecodeStructField returns error for failure in decoding a single field of // a Cloud Spanner STRUCT. func errDecodeStructField(ty *sppb.StructType, f string, err error) error { se, ok := toSpannerError(err).(*Error) if !ok { return spannerErrorf(codes.Unknown, "cannot decode field %v of Cloud Spanner STRUCT %+v, error = <%v>", f, ty, err) } se.decorate(fmt.Sprintf("cannot decode field %v of Cloud Spanner STRUCT %+v", f, ty)) return se } // decodeStruct decodes proto3.ListValue pb into struct referenced by pointer // ptr, according to // the structural information given in sppb.StructType ty. func decodeStruct(ty *sppb.StructType, pb *proto3.ListValue, ptr interface{}) error { if reflect.ValueOf(ptr).IsNil() { return errNilDst(ptr) } if ty == nil { return errNilSpannerStructType() } // t holds the structural information of ptr. t := reflect.TypeOf(ptr).Elem() // v is the actual value that ptr points to. v := reflect.ValueOf(ptr).Elem() fields, err := fieldCache.Fields(t) if err != nil { return toSpannerError(err) } seen := map[string]bool{} for i, f := range ty.Fields { if f.Name == "" { return errUnnamedField(ty, i) } sf := fields.Match(f.Name) if sf == nil { return errNoOrDupGoField(ptr, f.Name) } if seen[f.Name] { // We don't allow duplicated field name. return errDupSpannerField(f.Name, ty) } // Try to decode a single field. if err := decodeValue(pb.Values[i], f.Type, v.FieldByIndex(sf.Index).Addr().Interface()); err != nil { return errDecodeStructField(ty, f.Name, err) } // Mark field f.Name as processed. seen[f.Name] = true } return nil } // isPtrStructPtrSlice returns true if ptr is a pointer to a slice of struct pointers. func isPtrStructPtrSlice(t reflect.Type) bool { if t.Kind() != reflect.Ptr || t.Elem().Kind() != reflect.Slice { // t is not a pointer to a slice. return false } if t = t.Elem(); t.Elem().Kind() != reflect.Ptr || t.Elem().Elem().Kind() != reflect.Struct { // the slice that t points to is not a slice of struct pointers. return false } return true } // decodeStructArray decodes proto3.ListValue pb into struct slice referenced by // pointer ptr, according to the // structural information given in a sppb.StructType. func decodeStructArray(ty *sppb.StructType, pb *proto3.ListValue, ptr interface{}) error { if pb == nil { return errNilListValue("STRUCT") } // Type of the struct pointers stored in the slice that ptr points to. ts := reflect.TypeOf(ptr).Elem().Elem() // The slice that ptr points to, might be nil at this point. v := reflect.ValueOf(ptr).Elem() // Allocate empty slice. v.Set(reflect.MakeSlice(v.Type(), 0, len(pb.Values))) // Decode every struct in pb.Values. for i, pv := range pb.Values { // Check if pv is a NULL value. if _, isNull := pv.Kind.(*proto3.Value_NullValue); isNull { // Append a nil pointer to the slice. v.Set(reflect.Append(v, reflect.New(ts).Elem())) continue } // Allocate empty struct. s := reflect.New(ts.Elem()) // Get proto3.ListValue l from proto3.Value pv. l, err := getListValue(pv) if err != nil { return errDecodeArrayElement(i, pv, "STRUCT", err) } // Decode proto3.ListValue l into struct referenced by s.Interface(). if err = decodeStruct(ty, l, s.Interface()); err != nil { return errDecodeArrayElement(i, pv, "STRUCT", err) } // Append the decoded struct back into the slice. v.Set(reflect.Append(v, s)) } return nil } // errEncoderUnsupportedType returns error for not being able to encode a value // of certain type. func errEncoderUnsupportedType(v interface{}) error { return spannerErrorf(codes.InvalidArgument, "client doesn't support type %T", v) } // encodeValue encodes a Go native type into a proto3.Value. func encodeValue(v interface{}) (*proto3.Value, *sppb.Type, error) { pb := &proto3.Value{ Kind: &proto3.Value_NullValue{NullValue: proto3.NullValue_NULL_VALUE}, } var pt *sppb.Type var err error switch v := v.(type) { case nil: case string: pb.Kind = stringKind(v) pt = stringType() case NullString: if v.Valid { return encodeValue(v.StringVal) } pt = stringType() case []string: if v != nil { pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] }) if err != nil { return nil, nil, err } } pt = listType(stringType()) case []NullString: if v != nil { pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] }) if err != nil { return nil, nil, err } } pt = listType(stringType()) case []byte: if v != nil { pb.Kind = stringKind(base64.StdEncoding.EncodeToString(v)) } pt = bytesType() case [][]byte: if v != nil { pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] }) if err != nil { return nil, nil, err } } pt = listType(bytesType()) case int: pb.Kind = stringKind(strconv.FormatInt(int64(v), 10)) pt = intType() case []int: if v != nil { pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] }) if err != nil { return nil, nil, err } } pt = listType(intType()) case int64: pb.Kind = stringKind(strconv.FormatInt(v, 10)) pt = intType() case []int64: if v != nil { pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] }) if err != nil { return nil, nil, err } } pt = listType(intType()) case NullInt64: if v.Valid { return encodeValue(v.Int64) } pt = intType() case []NullInt64: if v != nil { pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] }) if err != nil { return nil, nil, err } } pt = listType(intType()) case bool: pb.Kind = &proto3.Value_BoolValue{BoolValue: v} pt = boolType() case []bool: if v != nil { pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] }) if err != nil { return nil, nil, err } } pt = listType(boolType()) case NullBool: if v.Valid { return encodeValue(v.Bool) } pt = boolType() case []NullBool: if v != nil { pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] }) if err != nil { return nil, nil, err } } pt = listType(boolType()) case float64: pb.Kind = &proto3.Value_NumberValue{NumberValue: v} pt = floatType() case []float64: if v != nil { pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] }) if err != nil { return nil, nil, err } } pt = listType(floatType()) case NullFloat64: if v.Valid { return encodeValue(v.Float64) } pt = floatType() case []NullFloat64: if v != nil { pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] }) if err != nil { return nil, nil, err } } pt = listType(floatType()) case time.Time: if v == commitTimestamp { pb.Kind = stringKind(commitTimestampPlaceholderString) } else { pb.Kind = stringKind(v.UTC().Format(time.RFC3339Nano)) } pt = timeType() case []time.Time: if v != nil { pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] }) if err != nil { return nil, nil, err } } pt = listType(timeType()) case NullTime: if v.Valid { return encodeValue(v.Time) } pt = timeType() case []NullTime: if v != nil { pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] }) if err != nil { return nil, nil, err } } pt = listType(timeType()) case civil.Date: pb.Kind = stringKind(v.String()) pt = dateType() case []civil.Date: if v != nil { pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] }) if err != nil { return nil, nil, err } } pt = listType(dateType()) case NullDate: if v.Valid { return encodeValue(v.Date) } pt = dateType() case []NullDate: if v != nil { pb, err = encodeArray(len(v), func(i int) interface{} { return v[i] }) if err != nil { return nil, nil, err } } pt = listType(dateType()) case GenericColumnValue: // Deep clone to ensure subsequent changes to v before // transmission don't affect our encoded value. pb = proto.Clone(v.Value).(*proto3.Value) pt = proto.Clone(v.Type).(*sppb.Type) case []GenericColumnValue: return nil, nil, errEncoderUnsupportedType(v) default: if !isStructOrArrayOfStructValue(v) { return nil, nil, errEncoderUnsupportedType(v) } typ := reflect.TypeOf(v) // Value is a Go struct value/ptr. if (typ.Kind() == reflect.Struct) || (typ.Kind() == reflect.Ptr && typ.Elem().Kind() == reflect.Struct) { return encodeStruct(v) } // Value is a slice of Go struct values/ptrs. if typ.Kind() == reflect.Slice { return encodeStructArray(v) } } return pb, pt, nil } // Encodes a Go struct value/ptr in v to the spanner Value and Type protos. v // itself must be non-nil. func encodeStruct(v interface{}) (*proto3.Value, *sppb.Type, error) { typ := reflect.TypeOf(v) val := reflect.ValueOf(v) // Pointer to struct. if typ.Kind() == reflect.Ptr && typ.Elem().Kind() == reflect.Struct { typ = typ.Elem() if val.IsNil() { // nil pointer to struct, representing a NULL STRUCT value. Use a // dummy value to get the type. _, st, err := encodeStruct(reflect.Zero(typ).Interface()) if err != nil { return nil, nil, err } return nullProto(), st, nil } val = val.Elem() } if typ.Kind() != reflect.Struct { return nil, nil, errEncoderUnsupportedType(v) } stf := make([]*sppb.StructType_Field, 0, typ.NumField()) stv := make([]*proto3.Value, 0, typ.NumField()) for i := 0; i < typ.NumField(); i++ { // If the field has a 'spanner' tag, use the value of that tag as the field name. // This is used to build STRUCT types with unnamed/duplicate fields. sf := typ.Field(i) fval := val.Field(i) // Embedded fields are not allowed. if sf.Anonymous { return nil, nil, errUnsupportedEmbeddedStructFields(sf.Name) } // Unexported fields are ignored. if !fval.CanInterface() { continue } fname, ok := sf.Tag.Lookup("spanner") if !ok { fname = sf.Name } eval, etype, err := encodeValue(fval.Interface()) if err != nil { return nil, nil, err } stf = append(stf, mkField(fname, etype)) stv = append(stv, eval) } return listProto(stv...), structType(stf...), nil } // Encodes a slice of Go struct values/ptrs in v to the spanner Value and Type // protos. v itself must be non-nil. func encodeStructArray(v interface{}) (*proto3.Value, *sppb.Type, error) { etyp := reflect.TypeOf(v).Elem() sliceval := reflect.ValueOf(v) // Slice of pointers to structs. if etyp.Kind() == reflect.Ptr { etyp = etyp.Elem() } // Use a dummy struct value to get the element type. _, elemTyp, err := encodeStruct(reflect.Zero(etyp).Interface()) if err != nil { return nil, nil, err } // nil slice represents a NULL array-of-struct. if sliceval.IsNil() { return nullProto(), listType(elemTyp), nil } values := make([]*proto3.Value, 0, sliceval.Len()) for i := 0; i < sliceval.Len(); i++ { ev, _, err := encodeStruct(sliceval.Index(i).Interface()) if err != nil { return nil, nil, err } values = append(values, ev) } return listProto(values...), listType(elemTyp), nil } func isStructOrArrayOfStructValue(v interface{}) bool { typ := reflect.TypeOf(v) if typ.Kind() == reflect.Slice { typ = typ.Elem() } if typ.Kind() == reflect.Ptr { typ = typ.Elem() } return typ.Kind() == reflect.Struct } func isSupportedMutationType(v interface{}) bool { switch v.(type) { case nil, string, NullString, []string, []NullString, []byte, [][]byte, int, []int, int64, []int64, NullInt64, []NullInt64, bool, []bool, NullBool, []NullBool, float64, []float64, NullFloat64, []NullFloat64, time.Time, []time.Time, NullTime, []NullTime, civil.Date, []civil.Date, NullDate, []NullDate, GenericColumnValue: return true default: return false } } // encodeValueArray encodes a Value array into a proto3.ListValue. func encodeValueArray(vs []interface{}) (*proto3.ListValue, error) { lv := &proto3.ListValue{} lv.Values = make([]*proto3.Value, 0, len(vs)) for _, v := range vs { if !isSupportedMutationType(v) { return nil, errEncoderUnsupportedType(v) } pb, _, err := encodeValue(v) if err != nil { return nil, err } lv.Values = append(lv.Values, pb) } return lv, nil } // encodeArray assumes that all values of the array element type encode without // error. func encodeArray(len int, at func(int) interface{}) (*proto3.Value, error) { vs := make([]*proto3.Value, len) var err error for i := 0; i < len; i++ { vs[i], _, err = encodeValue(at(i)) if err != nil { return nil, err } } return listProto(vs...), nil } func spannerTagParser(t reflect.StructTag) (name string, keep bool, other interface{}, err error) { if s := t.Get("spanner"); s != "" { if s == "-" { return "", false, nil, nil } return s, true, nil, nil } return "", true, nil, nil } var fieldCache = fields.NewCache(spannerTagParser, nil, nil) google-cloud-go-0.49.0/spanner/value_benchmarks_test.go000066400000000000000000000124571356504100700231460ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package spanner import ( "reflect" "strconv" "testing" "cloud.google.com/go/civil" proto3 "github.com/golang/protobuf/ptypes/struct" sppb "google.golang.org/genproto/googleapis/spanner/v1" ) func BenchmarkEncodeIntArray(b *testing.B) { for _, s := range []struct { name string f func(a []int) (*proto3.Value, *sppb.Type, error) }{ {"Orig", encodeIntArrayOrig}, {"Func", encodeIntArrayFunc}, {"Reflect", encodeIntArrayReflect}, } { b.Run(s.name, func(b *testing.B) { for _, size := range []int{1, 10, 100, 1000} { a := make([]int, size) b.Run(strconv.Itoa(size), func(b *testing.B) { for i := 0; i < b.N; i++ { s.f(a) } }) } }) } } func encodeIntArrayOrig(a []int) (*proto3.Value, *sppb.Type, error) { vs := make([]*proto3.Value, len(a)) var err error for i := range a { vs[i], _, err = encodeValue(a[i]) if err != nil { return nil, nil, err } } return listProto(vs...), listType(intType()), nil } func encodeIntArrayFunc(a []int) (*proto3.Value, *sppb.Type, error) { v, err := encodeArray(len(a), func(i int) interface{} { return a[i] }) if err != nil { return nil, nil, err } return v, listType(intType()), nil } func encodeIntArrayReflect(a []int) (*proto3.Value, *sppb.Type, error) { v, err := encodeArrayReflect(a) if err != nil { return nil, nil, err } return v, listType(intType()), nil } func encodeArrayReflect(a interface{}) (*proto3.Value, error) { va := reflect.ValueOf(a) len := va.Len() vs := make([]*proto3.Value, len) var err error for i := 0; i < len; i++ { vs[i], _, err = encodeValue(va.Index(i).Interface()) if err != nil { return nil, err } } return listProto(vs...), nil } func BenchmarkDecodeGeneric(b *testing.B) { v := stringProto("test") t := stringType() var g GenericColumnValue b.ResetTimer() for i := 0; i < b.N; i++ { decodeValue(v, t, &g) } } func BenchmarkDecodeArray(b *testing.B) { for _, size := range []int{1, 10, 100, 1000} { vals := make([]*proto3.Value, size) for i := 0; i < size; i++ { vals[i] = dateProto(d1) } lv := &proto3.ListValue{Values: vals} b.Run(strconv.Itoa(size), func(b *testing.B) { for _, s := range []struct { name string decode func(*proto3.ListValue) }{ {"DateDirect", decodeArrayDateDirect}, {"DateFunc", decodeArrayDateFunc}, {"DateReflect", decodeArrayDateReflect}, {"StringDecodeStringArray", decodeStringArrayWrap}, {"StringDirect", decodeArrayStringDirect}, {"StringFunc", decodeArrayStringFunc}, {"StringReflect", decodeArrayStringReflect}, } { b.Run(s.name, func(b *testing.B) { for i := 0; i < b.N; i++ { s.decode(lv) } }) } }) } } func decodeArrayDateDirect(pb *proto3.ListValue) { a := make([]civil.Date, len(pb.Values)) t := dateType() for i, v := range pb.Values { if err := decodeValue(v, t, &a[i]); err != nil { panic(err) } } } func decodeArrayDateFunc(pb *proto3.ListValue) { a := make([]civil.Date, len(pb.Values)) if err := decodeArrayFunc(pb, "DATE", dateType(), func(i int) interface{} { return &a[i] }); err != nil { panic(err) } } func decodeArrayDateReflect(pb *proto3.ListValue) { var a []civil.Date if err := decodeArrayReflect(pb, "DATE", dateType(), &a); err != nil { panic(err) } } func decodeStringArrayWrap(pb *proto3.ListValue) { if _, err := decodeStringArray(pb); err != nil { panic(err) } } func decodeArrayStringDirect(pb *proto3.ListValue) { a := make([]string, len(pb.Values)) t := stringType() for i, v := range pb.Values { if err := decodeValue(v, t, &a[i]); err != nil { panic(err) } } } func decodeArrayStringFunc(pb *proto3.ListValue) { a := make([]string, len(pb.Values)) if err := decodeArrayFunc(pb, "STRING", stringType(), func(i int) interface{} { return &a[i] }); err != nil { panic(err) } } func decodeArrayStringReflect(pb *proto3.ListValue) { var a []string if err := decodeArrayReflect(pb, "STRING", stringType(), &a); err != nil { panic(err) } } func decodeArrayFunc(pb *proto3.ListValue, name string, typ *sppb.Type, elptr func(int) interface{}) error { if pb == nil { return errNilListValue(name) } for i, v := range pb.Values { if err := decodeValue(v, typ, elptr(i)); err != nil { return errDecodeArrayElement(i, v, name, err) } } return nil } func decodeArrayReflect(pb *proto3.ListValue, name string, typ *sppb.Type, aptr interface{}) error { if pb == nil { return errNilListValue(name) } av := reflect.ValueOf(aptr).Elem() av.Set(reflect.MakeSlice(av.Type(), len(pb.Values), len(pb.Values))) for i, v := range pb.Values { if err := decodeValue(v, typ, av.Index(i).Addr().Interface()); err != nil { av.Set(reflect.Zero(av.Type())) // reset slice to nil return errDecodeArrayElement(i, v, name, err) } } return nil } google-cloud-go-0.49.0/spanner/value_test.go000066400000000000000000001123321356504100700207420ustar00rootroot00000000000000/* Copyright 2017 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package spanner import ( "math" "reflect" "testing" "time" "cloud.google.com/go/civil" "github.com/golang/protobuf/proto" proto3 "github.com/golang/protobuf/ptypes/struct" sppb "google.golang.org/genproto/googleapis/spanner/v1" ) var ( t1 = mustParseTime("2016-11-15T15:04:05.999999999Z") // Boundaries t2 = mustParseTime("0000-01-01T00:00:00.000000000Z") t3 = mustParseTime("9999-12-31T23:59:59.999999999Z") // Local timezone t4 = time.Now() d1 = mustParseDate("2016-11-15") d2 = mustParseDate("1678-01-01") ) func mustParseTime(s string) time.Time { t, err := time.Parse(time.RFC3339Nano, s) if err != nil { panic(err) } return t } func mustParseDate(s string) civil.Date { d, err := civil.ParseDate(s) if err != nil { panic(err) } return d } // Test encoding Values. func TestEncodeValue(t *testing.T) { var ( tString = stringType() tInt = intType() tBool = boolType() tFloat = floatType() tBytes = bytesType() tTime = timeType() tDate = dateType() ) for i, test := range []struct { in interface{} want *proto3.Value wantType *sppb.Type }{ // STRING / STRING ARRAY {"abc", stringProto("abc"), tString}, {NullString{"abc", true}, stringProto("abc"), tString}, {NullString{"abc", false}, nullProto(), tString}, {[]string(nil), nullProto(), listType(tString)}, {[]string{"abc", "bcd"}, listProto(stringProto("abc"), stringProto("bcd")), listType(tString)}, {[]NullString{{"abcd", true}, {"xyz", false}}, listProto(stringProto("abcd"), nullProto()), listType(tString)}, // BYTES / BYTES ARRAY {[]byte("foo"), bytesProto([]byte("foo")), tBytes}, {[]byte(nil), nullProto(), tBytes}, {[][]byte{nil, []byte("ab")}, listProto(nullProto(), bytesProto([]byte("ab"))), listType(tBytes)}, {[][]byte(nil), nullProto(), listType(tBytes)}, // INT64 / INT64 ARRAY {7, intProto(7), tInt}, {[]int(nil), nullProto(), listType(tInt)}, {[]int{31, 127}, listProto(intProto(31), intProto(127)), listType(tInt)}, {int64(81), intProto(81), tInt}, {[]int64(nil), nullProto(), listType(tInt)}, {[]int64{33, 129}, listProto(intProto(33), intProto(129)), listType(tInt)}, {NullInt64{11, true}, intProto(11), tInt}, {NullInt64{11, false}, nullProto(), tInt}, {[]NullInt64{{35, true}, {131, false}}, listProto(intProto(35), nullProto()), listType(tInt)}, // BOOL / BOOL ARRAY {true, boolProto(true), tBool}, {NullBool{true, true}, boolProto(true), tBool}, {NullBool{true, false}, nullProto(), tBool}, {[]bool{true, false}, listProto(boolProto(true), boolProto(false)), listType(tBool)}, {[]NullBool{{true, true}, {true, false}}, listProto(boolProto(true), nullProto()), listType(tBool)}, // FLOAT64 / FLOAT64 ARRAY {3.14, floatProto(3.14), tFloat}, {NullFloat64{3.1415, true}, floatProto(3.1415), tFloat}, {NullFloat64{math.Inf(1), true}, floatProto(math.Inf(1)), tFloat}, {NullFloat64{3.14159, false}, nullProto(), tFloat}, {[]float64(nil), nullProto(), listType(tFloat)}, {[]float64{3.141, 0.618, math.Inf(-1)}, listProto(floatProto(3.141), floatProto(0.618), floatProto(math.Inf(-1))), listType(tFloat)}, {[]NullFloat64{{3.141, true}, {0.618, false}}, listProto(floatProto(3.141), nullProto()), listType(tFloat)}, // TIMESTAMP / TIMESTAMP ARRAY {t1, timeProto(t1), tTime}, {NullTime{t1, true}, timeProto(t1), tTime}, {NullTime{t1, false}, nullProto(), tTime}, {[]time.Time(nil), nullProto(), listType(tTime)}, {[]time.Time{t1, t2, t3, t4}, listProto(timeProto(t1), timeProto(t2), timeProto(t3), timeProto(t4)), listType(tTime)}, {[]NullTime{{t1, true}, {t1, false}}, listProto(timeProto(t1), nullProto()), listType(tTime)}, // DATE / DATE ARRAY {d1, dateProto(d1), tDate}, {NullDate{d1, true}, dateProto(d1), tDate}, {NullDate{civil.Date{}, false}, nullProto(), tDate}, {[]civil.Date(nil), nullProto(), listType(tDate)}, {[]civil.Date{d1, d2}, listProto(dateProto(d1), dateProto(d2)), listType(tDate)}, {[]NullDate{{d1, true}, {civil.Date{}, false}}, listProto(dateProto(d1), nullProto()), listType(tDate)}, // GenericColumnValue {GenericColumnValue{tString, stringProto("abc")}, stringProto("abc"), tString}, {GenericColumnValue{tString, nullProto()}, nullProto(), tString}, // not actually valid (stringProto inside int list), but demonstrates pass-through. { GenericColumnValue{ Type: listType(tInt), Value: listProto(intProto(5), nullProto(), stringProto("bcd")), }, listProto(intProto(5), nullProto(), stringProto("bcd")), listType(tInt), }, // placeholder {CommitTimestamp, stringProto(commitTimestampPlaceholderString), tTime}, } { got, gotType, err := encodeValue(test.in) if err != nil { t.Fatalf("#%d: got error during encoding: %v, want nil", i, err) } if !testEqual(got, test.want) { t.Errorf("#%d: got encode result: %v, want %v", i, got, test.want) } if !testEqual(gotType, test.wantType) { t.Errorf("#%d: got encode type: %v, want %v", i, gotType, test.wantType) } } } type encodeTest struct { desc string in interface{} want *proto3.Value wantType *sppb.Type } func checkStructEncoding(desc string, got *proto3.Value, gotType *sppb.Type, want *proto3.Value, wantType *sppb.Type, t *testing.T) { if !testEqual(got, want) { t.Errorf("Test %s: got encode result: %v, want %v", desc, got, want) } if !testEqual(gotType, wantType) { t.Errorf("Test %s: got encode type: %v, want %v", desc, gotType, wantType) } } // Testcase code func encodeStructValue(test encodeTest, t *testing.T) { got, gotType, err := encodeValue(test.in) if err != nil { t.Fatalf("Test %s: got error during encoding: %v, want nil", test.desc, err) } checkStructEncoding(test.desc, got, gotType, test.want, test.wantType, t) } func TestEncodeStructValuePointers(t *testing.T) { type structf struct { F int `spanner:"ff2"` } nestedStructProto := structType(mkField("ff2", intType())) type testType struct { Stringf string Structf *structf ArrStructf []*structf } testTypeProto := structType( mkField("Stringf", stringType()), mkField("Structf", nestedStructProto), mkField("ArrStructf", listType(nestedStructProto))) for _, test := range []encodeTest{ { "Pointer to Go struct with pointers-to-(array)-struct fields.", &testType{"hello", &structf{50}, []*structf{{30}, {40}}}, listProto( stringProto("hello"), listProto(intProto(50)), listProto( listProto(intProto(30)), listProto(intProto(40)))), testTypeProto, }, { "Nil pointer to Go struct representing a NULL struct value.", (*testType)(nil), nullProto(), testTypeProto, }, { "Slice of pointers to Go structs with NULL and non-NULL elements.", []*testType{ (*testType)(nil), {"hello", nil, []*structf{nil, {40}}}, {"world", &structf{70}, nil}, }, listProto( nullProto(), listProto( stringProto("hello"), nullProto(), listProto(nullProto(), listProto(intProto(40)))), listProto( stringProto("world"), listProto(intProto(70)), nullProto())), listType(testTypeProto), }, { "Nil slice of pointers to structs representing a NULL array of structs.", []*testType(nil), nullProto(), listType(testTypeProto), }, { "Empty slice of pointers to structs representing an empty array of structs.", []*testType{}, listProto(), listType(testTypeProto), }, } { encodeStructValue(test, t) } } func TestEncodeStructValueErrors(t *testing.T) { type Embedded struct { A int } type embedded struct { B bool } x := 0 for _, test := range []struct { desc string in interface{} wantErr error }{ { "Unsupported embedded fields.", struct{ Embedded }{Embedded{10}}, errUnsupportedEmbeddedStructFields("Embedded"), }, { "Unsupported pointer to embedded fields.", struct{ *Embedded }{&Embedded{10}}, errUnsupportedEmbeddedStructFields("Embedded"), }, { "Unsupported embedded + unexported fields.", struct { int *bool embedded }{10, nil, embedded{false}}, errUnsupportedEmbeddedStructFields("int"), }, { "Unsupported type.", (**struct{})(nil), errEncoderUnsupportedType((**struct{})(nil)), }, { "Unsupported type.", 3, errEncoderUnsupportedType(3), }, { "Unsupported type.", &x, errEncoderUnsupportedType(&x), }, } { _, _, got := encodeStruct(test.in) if got == nil || !testEqual(test.wantErr, got) { t.Errorf("Test: %s, expected error %v during decoding, got %v", test.desc, test.wantErr, got) } } } func TestEncodeStructValueArrayStructFields(t *testing.T) { type structf struct { Intff int } structfType := structType(mkField("Intff", intType())) for _, test := range []encodeTest{ { "Unnamed array-of-struct-typed field.", struct { Intf int ArrStructf []structf `spanner:""` }{10, []structf{{1}, {2}}}, listProto( intProto(10), listProto( listProto(intProto(1)), listProto(intProto(2)))), structType( mkField("Intf", intType()), mkField("", listType(structfType))), }, { "Null array-of-struct-typed field.", struct { Intf int ArrStructf []structf }{10, []structf(nil)}, listProto(intProto(10), nullProto()), structType( mkField("Intf", intType()), mkField("ArrStructf", listType(structfType))), }, { "Array-of-struct-typed field representing empty array.", struct { Intf int ArrStructf []structf }{10, []structf{}}, listProto(intProto(10), listProto([]*proto3.Value{}...)), structType( mkField("Intf", intType()), mkField("ArrStructf", listType(structfType))), }, { "Array-of-struct-typed field with nullable struct elements.", struct { Intf int ArrStructf []*structf }{ 10, []*structf{(*structf)(nil), {1}}, }, listProto( intProto(10), listProto( nullProto(), listProto(intProto(1)))), structType( mkField("Intf", intType()), mkField("ArrStructf", listType(structfType))), }, } { encodeStructValue(test, t) } } func TestEncodeStructValueStructFields(t *testing.T) { type structf struct { Intff int } structfType := structType(mkField("Intff", intType())) for _, test := range []encodeTest{ { "Named struct-type field.", struct { Intf int Structf structf }{10, structf{10}}, listProto(intProto(10), listProto(intProto(10))), structType( mkField("Intf", intType()), mkField("Structf", structfType)), }, { "Unnamed struct-type field.", struct { Intf int Structf structf `spanner:""` }{10, structf{10}}, listProto(intProto(10), listProto(intProto(10))), structType( mkField("Intf", intType()), mkField("", structfType)), }, { "Duplicate struct-typed field.", struct { Structf1 structf `spanner:""` Structf2 structf `spanner:""` }{structf{10}, structf{20}}, listProto(listProto(intProto(10)), listProto(intProto(20))), structType( mkField("", structfType), mkField("", structfType)), }, { "Null struct-typed field.", struct { Intf int Structf *structf }{10, nil}, listProto(intProto(10), nullProto()), structType( mkField("Intf", intType()), mkField("Structf", structfType)), }, { "Empty struct-typed field.", struct { Intf int Structf struct{} }{10, struct{}{}}, listProto(intProto(10), listProto([]*proto3.Value{}...)), structType( mkField("Intf", intType()), mkField("Structf", structType([]*sppb.StructType_Field{}...))), }, } { encodeStructValue(test, t) } } func TestEncodeStructValueFieldNames(t *testing.T) { type embedded struct { B bool } for _, test := range []encodeTest{ { "Duplicate fields.", struct { Field1 int `spanner:"field"` DupField1 int `spanner:"field"` }{10, 20}, listProto(intProto(10), intProto(20)), structType( mkField("field", intType()), mkField("field", intType())), }, { "Duplicate Fields (different types).", struct { IntField int `spanner:"field"` StringField string `spanner:"field"` }{10, "abc"}, listProto(intProto(10), stringProto("abc")), structType( mkField("field", intType()), mkField("field", stringType())), }, { "Duplicate unnamed fields.", struct { Dup int `spanner:""` Dup1 int `spanner:""` }{10, 20}, listProto(intProto(10), intProto(20)), structType( mkField("", intType()), mkField("", intType())), }, { "Named and unnamed fields.", struct { Field string Field1 int `spanner:""` Field2 string `spanner:"field"` }{"abc", 10, "def"}, listProto(stringProto("abc"), intProto(10), stringProto("def")), structType( mkField("Field", stringType()), mkField("", intType()), mkField("field", stringType())), }, { "Ignored unexported fields.", struct { Field int field bool Field1 string `spanner:"field"` }{10, false, "abc"}, listProto(intProto(10), stringProto("abc")), structType( mkField("Field", intType()), mkField("field", stringType())), }, { "Ignored unexported struct/slice fields.", struct { a []*embedded b []embedded c embedded d *embedded Field1 string `spanner:"field"` }{nil, nil, embedded{}, nil, "def"}, listProto(stringProto("def")), structType( mkField("field", stringType())), }, } { encodeStructValue(test, t) } } func TestEncodeStructValueBasicFields(t *testing.T) { StructTypeProto := structType( mkField("Stringf", stringType()), mkField("Intf", intType()), mkField("Boolf", boolType()), mkField("Floatf", floatType()), mkField("Bytef", bytesType()), mkField("Timef", timeType()), mkField("Datef", dateType())) for _, test := range []encodeTest{ { "Basic types.", struct { Stringf string Intf int Boolf bool Floatf float64 Bytef []byte Timef time.Time Datef civil.Date }{"abc", 300, false, 3.45, []byte("foo"), t1, d1}, listProto( stringProto("abc"), intProto(300), boolProto(false), floatProto(3.45), bytesProto([]byte("foo")), timeProto(t1), dateProto(d1)), StructTypeProto, }, { "Basic types null values.", struct { Stringf NullString Intf NullInt64 Boolf NullBool Floatf NullFloat64 Bytef []byte Timef NullTime Datef NullDate }{ NullString{"abc", false}, NullInt64{4, false}, NullBool{false, false}, NullFloat64{5.6, false}, nil, NullTime{t1, false}, NullDate{d1, false}, }, listProto( nullProto(), nullProto(), nullProto(), nullProto(), nullProto(), nullProto(), nullProto()), StructTypeProto, }, } { encodeStructValue(test, t) } } func TestEncodeStructValueArrayFields(t *testing.T) { StructTypeProto := structType( mkField("Stringf", listType(stringType())), mkField("Intf", listType(intType())), mkField("Int64f", listType(intType())), mkField("Boolf", listType(boolType())), mkField("Floatf", listType(floatType())), mkField("Bytef", listType(bytesType())), mkField("Timef", listType(timeType())), mkField("Datef", listType(dateType()))) for _, test := range []encodeTest{ { "Arrays of basic types with non-nullable elements", struct { Stringf []string Intf []int Int64f []int64 Boolf []bool Floatf []float64 Bytef [][]byte Timef []time.Time Datef []civil.Date }{ []string{"abc", "def"}, []int{4, 67}, []int64{5, 68}, []bool{false, true}, []float64{3.45, 0.93}, [][]byte{[]byte("foo"), nil}, []time.Time{t1, t2}, []civil.Date{d1, d2}, }, listProto( listProto(stringProto("abc"), stringProto("def")), listProto(intProto(4), intProto(67)), listProto(intProto(5), intProto(68)), listProto(boolProto(false), boolProto(true)), listProto(floatProto(3.45), floatProto(0.93)), listProto(bytesProto([]byte("foo")), nullProto()), listProto(timeProto(t1), timeProto(t2)), listProto(dateProto(d1), dateProto(d2))), StructTypeProto, }, { "Arrays of basic types with nullable elements.", struct { Stringf []NullString Intf []NullInt64 Int64f []NullInt64 Boolf []NullBool Floatf []NullFloat64 Bytef [][]byte Timef []NullTime Datef []NullDate }{ []NullString{{"abc", false}, {"def", true}}, []NullInt64{{4, false}, {67, true}}, []NullInt64{{5, false}, {68, true}}, []NullBool{{true, false}, {false, true}}, []NullFloat64{{3.45, false}, {0.93, true}}, [][]byte{[]byte("foo"), nil}, []NullTime{{t1, false}, {t2, true}}, []NullDate{{d1, false}, {d2, true}}, }, listProto( listProto(nullProto(), stringProto("def")), listProto(nullProto(), intProto(67)), listProto(nullProto(), intProto(68)), listProto(nullProto(), boolProto(false)), listProto(nullProto(), floatProto(0.93)), listProto(bytesProto([]byte("foo")), nullProto()), listProto(nullProto(), timeProto(t2)), listProto(nullProto(), dateProto(d2))), StructTypeProto, }, { "Null arrays of basic types.", struct { Stringf []NullString Intf []NullInt64 Int64f []NullInt64 Boolf []NullBool Floatf []NullFloat64 Bytef [][]byte Timef []NullTime Datef []NullDate }{ nil, nil, nil, nil, nil, nil, nil, nil, }, listProto( nullProto(), nullProto(), nullProto(), nullProto(), nullProto(), nullProto(), nullProto(), nullProto()), StructTypeProto, }, } { encodeStructValue(test, t) } } // Test decoding Values. func TestDecodeValue(t *testing.T) { for i, test := range []struct { in *proto3.Value t *sppb.Type want interface{} fail bool }{ // STRING {stringProto("abc"), stringType(), "abc", false}, {nullProto(), stringType(), "abc", true}, {stringProto("abc"), stringType(), NullString{"abc", true}, false}, {nullProto(), stringType(), NullString{}, false}, // STRING ARRAY with []NullString { listProto(stringProto("abc"), nullProto(), stringProto("bcd")), listType(stringType()), []NullString{{"abc", true}, {}, {"bcd", true}}, false, }, {nullProto(), listType(stringType()), []NullString(nil), false}, // STRING ARRAY with []string { listProto(stringProto("abc"), stringProto("bcd")), listType(stringType()), []string{"abc", "bcd"}, false, }, // BYTES {bytesProto([]byte("ab")), bytesType(), []byte("ab"), false}, {nullProto(), bytesType(), []byte(nil), false}, // BYTES ARRAY {listProto(bytesProto([]byte("ab")), nullProto()), listType(bytesType()), [][]byte{[]byte("ab"), nil}, false}, {nullProto(), listType(bytesType()), [][]byte(nil), false}, //INT64 {intProto(15), intType(), int64(15), false}, {nullProto(), intType(), int64(0), true}, {intProto(15), intType(), NullInt64{15, true}, false}, {nullProto(), intType(), NullInt64{}, false}, // INT64 ARRAY with []NullInt64 {listProto(intProto(91), nullProto(), intProto(87)), listType(intType()), []NullInt64{{91, true}, {}, {87, true}}, false}, {nullProto(), listType(intType()), []NullInt64(nil), false}, // INT64 ARRAY with []int64 {listProto(intProto(91), intProto(87)), listType(intType()), []int64{91, 87}, false}, // BOOL {boolProto(true), boolType(), true, false}, {nullProto(), boolType(), true, true}, {boolProto(true), boolType(), NullBool{true, true}, false}, {nullProto(), boolType(), NullBool{}, false}, // BOOL ARRAY with []NullBool {listProto(boolProto(true), boolProto(false), nullProto()), listType(boolType()), []NullBool{{true, true}, {false, true}, {}}, false}, {nullProto(), listType(boolType()), []NullBool(nil), false}, // BOOL ARRAY with []bool {listProto(boolProto(true), boolProto(false)), listType(boolType()), []bool{true, false}, false}, // FLOAT64 {floatProto(3.14), floatType(), 3.14, false}, {nullProto(), floatType(), 0.00, true}, {floatProto(3.14), floatType(), NullFloat64{3.14, true}, false}, {nullProto(), floatType(), NullFloat64{}, false}, // FLOAT64 ARRAY with []NullFloat64 { listProto(floatProto(math.Inf(1)), floatProto(math.Inf(-1)), nullProto(), floatProto(3.1)), listType(floatType()), []NullFloat64{{math.Inf(1), true}, {math.Inf(-1), true}, {}, {3.1, true}}, false, }, {nullProto(), listType(floatType()), []NullFloat64(nil), false}, // FLOAT64 ARRAY with []float64 { listProto(floatProto(math.Inf(1)), floatProto(math.Inf(-1)), floatProto(3.1)), listType(floatType()), []float64{math.Inf(1), math.Inf(-1), 3.1}, false, }, // TIMESTAMP {timeProto(t1), timeType(), t1, false}, {timeProto(t1), timeType(), NullTime{t1, true}, false}, {nullProto(), timeType(), NullTime{}, false}, {intProto(7), timeType(), time.Time{}, true}, // TIMESTAMP ARRAY with []NullTime {listProto(timeProto(t1), timeProto(t2), timeProto(t3), nullProto()), listType(timeType()), []NullTime{{t1, true}, {t2, true}, {t3, true}, {}}, false}, {nullProto(), listType(timeType()), []NullTime(nil), false}, // TIMESTAMP ARRAY with []time.Time {listProto(timeProto(t1), timeProto(t2), timeProto(t3)), listType(timeType()), []time.Time{t1, t2, t3}, false}, // DATE {dateProto(d1), dateType(), d1, false}, {dateProto(d1), dateType(), NullDate{d1, true}, false}, {nullProto(), dateType(), NullDate{}, false}, // DATE ARRAY with []NullDate {listProto(dateProto(d1), dateProto(d2), nullProto()), listType(dateType()), []NullDate{{d1, true}, {d2, true}, {}}, false}, {nullProto(), listType(dateType()), []NullDate(nil), false}, // DATE ARRAY with []civil.Date {listProto(dateProto(d1), dateProto(d2)), listType(dateType()), []civil.Date{d1, d2}, false}, // STRUCT ARRAY // STRUCT schema is equal to the following Go struct: // type s struct { // Col1 NullInt64 // Col2 []struct { // SubCol1 float64 // SubCol2 string // } // } { in: listProto( listProto( intProto(3), listProto( listProto(floatProto(3.14), stringProto("this")), listProto(floatProto(0.57), stringProto("siht")), ), ), listProto( nullProto(), nullProto(), ), nullProto(), ), t: listType( structType( mkField("Col1", intType()), mkField( "Col2", listType( structType( mkField("SubCol1", floatType()), mkField("SubCol2", stringType()), ), ), ), ), ), want: []NullRow{ { Row: Row{ fields: []*sppb.StructType_Field{ mkField("Col1", intType()), mkField( "Col2", listType( structType( mkField("SubCol1", floatType()), mkField("SubCol2", stringType()), ), ), ), }, vals: []*proto3.Value{ intProto(3), listProto( listProto(floatProto(3.14), stringProto("this")), listProto(floatProto(0.57), stringProto("siht")), ), }, }, Valid: true, }, { Row: Row{ fields: []*sppb.StructType_Field{ mkField("Col1", intType()), mkField( "Col2", listType( structType( mkField("SubCol1", floatType()), mkField("SubCol2", stringType()), ), ), ), }, vals: []*proto3.Value{ nullProto(), nullProto(), }, }, Valid: true, }, {}, }, fail: false, }, { in: listProto( listProto( intProto(3), listProto( listProto(floatProto(3.14), stringProto("this")), listProto(floatProto(0.57), stringProto("siht")), ), ), listProto( nullProto(), nullProto(), ), nullProto(), ), t: listType( structType( mkField("Col1", intType()), mkField( "Col2", listType( structType( mkField("SubCol1", floatType()), mkField("SubCol2", stringType()), ), ), ), ), ), want: []*struct { Col1 NullInt64 StructCol []*struct { SubCol1 NullFloat64 SubCol2 string } `spanner:"Col2"` }{ { Col1: NullInt64{3, true}, StructCol: []*struct { SubCol1 NullFloat64 SubCol2 string }{ { SubCol1: NullFloat64{3.14, true}, SubCol2: "this", }, { SubCol1: NullFloat64{0.57, true}, SubCol2: "siht", }, }, }, { Col1: NullInt64{}, StructCol: []*struct { SubCol1 NullFloat64 SubCol2 string }(nil), }, nil, }, fail: false, }, // GenericColumnValue {stringProto("abc"), stringType(), GenericColumnValue{stringType(), stringProto("abc")}, false}, {nullProto(), stringType(), GenericColumnValue{stringType(), nullProto()}, false}, // not actually valid (stringProto inside int list), but demonstrates pass-through. { in: listProto(intProto(5), nullProto(), stringProto("bcd")), t: listType(intType()), want: GenericColumnValue{ Type: listType(intType()), Value: listProto(intProto(5), nullProto(), stringProto("bcd")), }, fail: false, }, } { gotp := reflect.New(reflect.TypeOf(test.want)) if err := decodeValue(test.in, test.t, gotp.Interface()); err != nil { if !test.fail { t.Errorf("%d: cannot decode %v(%v): %v", i, test.in, test.t, err) } continue } if test.fail { t.Errorf("%d: decoding %v(%v) succeeds unexpectedly, want error", i, test.in, test.t) continue } got := reflect.Indirect(gotp).Interface() if !testEqual(got, test.want) { t.Errorf("%d: unexpected decoding result - got %v, want %v", i, got, test.want) continue } } } // Test error cases for decodeValue. func TestDecodeValueErrors(t *testing.T) { var s string for i, test := range []struct { in *proto3.Value t *sppb.Type v interface{} }{ {nullProto(), stringType(), nil}, {nullProto(), stringType(), 1}, {timeProto(t1), timeType(), &s}, } { err := decodeValue(test.in, test.t, test.v) if err == nil { t.Errorf("#%d: want error, got nil", i) } } } // Test NaN encoding/decoding. func TestNaN(t *testing.T) { // Decode NaN value. f := 0.0 nf := NullFloat64{} // To float64 if err := decodeValue(floatProto(math.NaN()), floatType(), &f); err != nil { t.Errorf("decodeValue returns %q for %v, want nil", err, floatProto(math.NaN())) } if !math.IsNaN(f) { t.Errorf("f = %v, want %v", f, math.NaN()) } // To NullFloat64 if err := decodeValue(floatProto(math.NaN()), floatType(), &nf); err != nil { t.Errorf("decodeValue returns %q for %v, want nil", err, floatProto(math.NaN())) } if !math.IsNaN(nf.Float64) || !nf.Valid { t.Errorf("f = %v, want %v", f, NullFloat64{math.NaN(), true}) } // Encode NaN value // From float64 v, _, err := encodeValue(math.NaN()) if err != nil { t.Errorf("encodeValue returns %q for NaN, want nil", err) } x, ok := v.GetKind().(*proto3.Value_NumberValue) if !ok { t.Errorf("incorrect type for v.GetKind(): %T, want *proto3.Value_NumberValue", v.GetKind()) } if !math.IsNaN(x.NumberValue) { t.Errorf("x.NumberValue = %v, want %v", x.NumberValue, math.NaN()) } // From NullFloat64 v, _, err = encodeValue(NullFloat64{math.NaN(), true}) if err != nil { t.Errorf("encodeValue returns %q for NaN, want nil", err) } x, ok = v.GetKind().(*proto3.Value_NumberValue) if !ok { t.Errorf("incorrect type for v.GetKind(): %T, want *proto3.Value_NumberValue", v.GetKind()) } if !math.IsNaN(x.NumberValue) { t.Errorf("x.NumberValue = %v, want %v", x.NumberValue, math.NaN()) } } func TestGenericColumnValue(t *testing.T) { for _, test := range []struct { in GenericColumnValue want interface{} fail bool }{ {GenericColumnValue{stringType(), stringProto("abc")}, "abc", false}, {GenericColumnValue{stringType(), stringProto("abc")}, 5, true}, {GenericColumnValue{listType(intType()), listProto(intProto(91), nullProto(), intProto(87))}, []NullInt64{{91, true}, {}, {87, true}}, false}, {GenericColumnValue{intType(), intProto(42)}, GenericColumnValue{intType(), intProto(42)}, false}, // trippy! :-) } { gotp := reflect.New(reflect.TypeOf(test.want)) if err := test.in.Decode(gotp.Interface()); err != nil { if !test.fail { t.Errorf("cannot decode %v to %v: %v", test.in, test.want, err) } continue } if test.fail { t.Errorf("decoding %v to %v succeeds unexpectedly", test.in, test.want) } // Test we can go backwards as well. v, err := newGenericColumnValue(test.want) if err != nil { t.Errorf("NewGenericColumnValue failed: %v", err) continue } if !testEqual(*v, test.in) { t.Errorf("unexpected encode result - got %v, want %v", v, test.in) } } } func TestDecodeStruct(t *testing.T) { stype := &sppb.StructType{Fields: []*sppb.StructType_Field{ {Name: "Id", Type: stringType()}, {Name: "Time", Type: timeType()}, }} lv := listValueProto(stringProto("id"), timeProto(t1)) type ( S1 struct { ID string Time time.Time } S2 struct { ID string Time string } ) var ( s1 S1 s2 S2 ) for i, test := range []struct { ptr interface{} want interface{} fail bool }{ { ptr: &s1, want: &S1{ID: "id", Time: t1}, }, { ptr: &s2, fail: true, }, } { err := decodeStruct(stype, lv, test.ptr) if (err != nil) != test.fail { t.Errorf("#%d: got error %v, wanted fail: %v", i, err, test.fail) } if err == nil && !testEqual(test.ptr, test.want) { t.Errorf("#%d: got %+v, want %+v", i, test.ptr, test.want) } } } func TestEncodeStructValueDynamicStructs(t *testing.T) { dynStructType := reflect.StructOf([]reflect.StructField{ {Name: "A", Type: reflect.TypeOf(0), Tag: `spanner:"a"`}, {Name: "B", Type: reflect.TypeOf(""), Tag: `spanner:"b"`}, }) dynNullableStructType := reflect.PtrTo(dynStructType) dynStructArrType := reflect.SliceOf(dynStructType) dynNullableStructArrType := reflect.SliceOf(dynNullableStructType) dynStructValue := reflect.New(dynStructType) dynStructValue.Elem().Field(0).SetInt(10) dynStructValue.Elem().Field(1).SetString("abc") dynStructArrValue := reflect.MakeSlice(dynNullableStructArrType, 2, 2) dynStructArrValue.Index(0).Set(reflect.Zero(dynNullableStructType)) dynStructArrValue.Index(1).Set(dynStructValue) structProtoType := structType( mkField("a", intType()), mkField("b", stringType())) arrProtoType := listType(structProtoType) for _, test := range []encodeTest{ { "Dynanic non-NULL struct value.", dynStructValue.Elem().Interface(), listProto(intProto(10), stringProto("abc")), structProtoType, }, { "Dynanic NULL struct value.", reflect.Zero(dynNullableStructType).Interface(), nullProto(), structProtoType, }, { "Empty array of dynamic structs.", reflect.MakeSlice(dynStructArrType, 0, 0).Interface(), listProto([]*proto3.Value{}...), arrProtoType, }, { "NULL array of non-NULL-able dynamic structs.", reflect.Zero(dynStructArrType).Interface(), nullProto(), arrProtoType, }, { "NULL array of NULL-able(nil) dynamic structs.", reflect.Zero(dynNullableStructArrType).Interface(), nullProto(), arrProtoType, }, { "Array containing NULL(nil) dynamic-typed struct elements.", dynStructArrValue.Interface(), listProto( nullProto(), listProto(intProto(10), stringProto("abc"))), arrProtoType, }, } { encodeStructValue(test, t) } } func TestEncodeStructValueEmptyStruct(t *testing.T) { emptyListValue := listProto([]*proto3.Value{}...) emptyStructType := structType([]*sppb.StructType_Field{}...) emptyStruct := struct{}{} nullEmptyStruct := (*struct{})(nil) dynamicEmptyStructType := reflect.StructOf(make([]reflect.StructField, 0, 0)) dynamicStructArrType := reflect.SliceOf(reflect.PtrTo((dynamicEmptyStructType))) dynamicEmptyStruct := reflect.New(dynamicEmptyStructType) dynamicNullEmptyStruct := reflect.Zero(reflect.PtrTo(dynamicEmptyStructType)) dynamicStructArrValue := reflect.MakeSlice(dynamicStructArrType, 2, 2) dynamicStructArrValue.Index(0).Set(dynamicNullEmptyStruct) dynamicStructArrValue.Index(1).Set(dynamicEmptyStruct) for _, test := range []encodeTest{ { "Go empty struct.", emptyStruct, emptyListValue, emptyStructType, }, { "Dynamic empty struct.", dynamicEmptyStruct.Interface(), emptyListValue, emptyStructType, }, { "Go NULL empty struct.", nullEmptyStruct, nullProto(), emptyStructType, }, { "Dynamic NULL empty struct.", dynamicNullEmptyStruct.Interface(), nullProto(), emptyStructType, }, { "Non-empty array of dynamic NULL and non-NULL empty structs.", dynamicStructArrValue.Interface(), listProto(nullProto(), emptyListValue), listType(emptyStructType), }, { "Non-empty array of nullable empty structs.", []*struct{}{nullEmptyStruct, &emptyStruct}, listProto(nullProto(), emptyListValue), listType(emptyStructType), }, { "Empty array of empty struct.", []struct{}{}, emptyListValue, listType(emptyStructType), }, { "Null array of empty structs.", []struct{}(nil), nullProto(), listType(emptyStructType), }, } { encodeStructValue(test, t) } } func TestEncodeStructValueMixedStructTypes(t *testing.T) { type staticStruct struct { F int `spanner:"fStatic"` } s1 := staticStruct{10} s2 := (*staticStruct)(nil) var f float64 dynStructType := reflect.StructOf([]reflect.StructField{ {Name: "A", Type: reflect.TypeOf(f), Tag: `spanner:"fDynamic"`}, }) s3 := reflect.New(dynStructType) s3.Elem().Field(0).SetFloat(3.14) for _, test := range []encodeTest{ { "'struct' with static and dynamic *struct, []*struct, []struct fields", struct { A []staticStruct B []*staticStruct C interface{} }{ []staticStruct{s1, s1}, []*staticStruct{&s1, s2}, s3.Interface(), }, listProto( listProto(listProto(intProto(10)), listProto(intProto(10))), listProto(listProto(intProto(10)), nullProto()), listProto(floatProto(3.14))), structType( mkField("A", listType(structType(mkField("fStatic", intType())))), mkField("B", listType(structType(mkField("fStatic", intType())))), mkField("C", structType(mkField("fDynamic", floatType())))), }, } { encodeStructValue(test, t) } } func TestBindParamsDynamic(t *testing.T) { // Verify Statement.bindParams generates correct values and types. st := Statement{ SQL: "SELECT id from t_foo WHERE col = @var", Params: map[string]interface{}{"var": nil}, } want := &sppb.ExecuteSqlRequest{ Params: &proto3.Struct{ Fields: map[string]*proto3.Value{"var": nil}, }, ParamTypes: map[string]*sppb.Type{"var": nil}, } var ( t1, _ = time.Parse(time.RFC3339Nano, "2016-11-15T15:04:05.999999999Z") // Boundaries t2, _ = time.Parse(time.RFC3339Nano, "0001-01-01T00:00:00.000000000Z") ) dynamicStructType := reflect.StructOf([]reflect.StructField{ {Name: "A", Type: reflect.TypeOf(t1), Tag: `spanner:"field"`}, {Name: "B", Type: reflect.TypeOf(3.14), Tag: `spanner:""`}, }) dynamicStructArrType := reflect.SliceOf(reflect.PtrTo(dynamicStructType)) dynamicEmptyStructType := reflect.StructOf(make([]reflect.StructField, 0, 0)) dynamicStructTypeProto := structType( mkField("field", timeType()), mkField("", floatType())) s3 := reflect.New(dynamicStructType) s3.Elem().Field(0).Set(reflect.ValueOf(t1)) s3.Elem().Field(1).SetFloat(1.4) s4 := reflect.New(dynamicStructType) s4.Elem().Field(0).Set(reflect.ValueOf(t2)) s4.Elem().Field(1).SetFloat(-13.3) dynamicStructArrayVal := reflect.MakeSlice(dynamicStructArrType, 2, 2) dynamicStructArrayVal.Index(0).Set(s3) dynamicStructArrayVal.Index(1).Set(s4) for _, test := range []struct { val interface{} wantField *proto3.Value wantType *sppb.Type }{ { s3.Interface(), listProto(timeProto(t1), floatProto(1.4)), structType( mkField("field", timeType()), mkField("", floatType())), }, { reflect.Zero(reflect.PtrTo(dynamicEmptyStructType)).Interface(), nullProto(), structType([]*sppb.StructType_Field{}...), }, { dynamicStructArrayVal.Interface(), listProto( listProto(timeProto(t1), floatProto(1.4)), listProto(timeProto(t2), floatProto(-13.3))), listType(dynamicStructTypeProto), }, { []*struct { F1 time.Time `spanner:"field"` F2 float64 `spanner:""` }{ nil, {t1, 1.4}, }, listProto( nullProto(), listProto(timeProto(t1), floatProto(1.4))), listType(dynamicStructTypeProto), }, } { st.Params["var"] = test.val want.Params.Fields["var"] = test.wantField want.ParamTypes["var"] = test.wantType gotParams, gotParamTypes, gotErr := st.convertParams() if gotErr != nil { t.Error(gotErr) continue } gotParamField := gotParams.Fields["var"] if !proto.Equal(gotParamField, test.wantField) { // handle NaN if test.wantType.Code == floatType().Code && proto.MarshalTextString(gotParamField) == proto.MarshalTextString(test.wantField) { continue } t.Errorf("%#v: got %v, want %v\n", test.val, gotParamField, test.wantField) } gotParamType := gotParamTypes["var"] if !proto.Equal(gotParamType, test.wantType) { t.Errorf("%#v: got %v, want %v\n", test.val, gotParamType, test.wantField) } } } google-cloud-go-0.49.0/speech/000077500000000000000000000000001356504100700160375ustar00rootroot00000000000000google-cloud-go-0.49.0/speech/apiv1/000077500000000000000000000000001356504100700170575ustar00rootroot00000000000000google-cloud-go-0.49.0/speech/apiv1/.repo-metadata.json000066400000000000000000000006411356504100700225540ustar00rootroot00000000000000{ "name": "speech", "name_pretty": "Cloud Speech-to-Text", "product_documentation": "https://cloud.google.com/speech-to-text", "client_documentation": "https://godoc.org/cloud.google.com/go/speech/apiv1", "release_level": "ga", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go/speech", "api_id": "speech.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/speech/apiv1/Recognize_smoke_test.go000066400000000000000000000037431356504100700235770ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package speech import ( "context" "fmt" "strconv" "testing" "time" "cloud.google.com/go/internal/testutil" "google.golang.org/api/iterator" "google.golang.org/api/option" speechpb "google.golang.org/genproto/googleapis/cloud/speech/v1" ) var _ = fmt.Sprintf var _ = iterator.Done var _ = strconv.FormatUint var _ = time.Now func TestSpeechSmoke(t *testing.T) { if testing.Short() { t.Skip("skipping smoke test in short mode") } ctx := context.Background() ts := testutil.TokenSource(ctx, DefaultAuthScopes()...) if ts == nil { t.Skip("Integration tests skipped. See CONTRIBUTING.md for details") } projectId := testutil.ProjID() _ = projectId c, err := NewClient(ctx, option.WithTokenSource(ts)) if err != nil { t.Fatal(err) } var languageCode string = "en-US" var sampleRateHertz int32 = 44100 var encoding speechpb.RecognitionConfig_AudioEncoding = speechpb.RecognitionConfig_FLAC var config = &speechpb.RecognitionConfig{ LanguageCode: languageCode, SampleRateHertz: sampleRateHertz, Encoding: encoding, } var uri string = "gs://gapic-toolkit/hello.flac" var audio = &speechpb.RecognitionAudio{ AudioSource: &speechpb.RecognitionAudio_Uri{ Uri: uri, }, } var request = &speechpb.RecognizeRequest{ Config: config, Audio: audio, } if _, err := c.Recognize(ctx, request); err != nil { t.Error(err) } } google-cloud-go-0.49.0/speech/apiv1/doc.go000066400000000000000000000052161356504100700201570ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go_gapic. DO NOT EDIT. // Package speech is an auto-generated package for the // Cloud Speech-to-Text API. // // Converts audio to text by applying powerful neural network models. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package speech // import "cloud.google.com/go/speech/apiv1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) const versionClient = "20191115" func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return !strings.ContainsRune("0123456789.", r) } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } google-cloud-go-0.49.0/speech/apiv1/mock_test.go000066400000000000000000000247061356504100700214070ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package speech import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" "google.golang.org/api/option" speechpb "google.golang.org/genproto/googleapis/cloud/speech/v1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockSpeechServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. speechpb.SpeechServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockSpeechServer) Recognize(ctx context.Context, req *speechpb.RecognizeRequest) (*speechpb.RecognizeResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*speechpb.RecognizeResponse), nil } func (s *mockSpeechServer) LongRunningRecognize(ctx context.Context, req *speechpb.LongRunningRecognizeRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockSpeechServer) StreamingRecognize(stream speechpb.Speech_StreamingRecognizeServer) error { md, _ := metadata.FromIncomingContext(stream.Context()) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } for { if req, err := stream.Recv(); err == io.EOF { break } else if err != nil { return err } else { s.reqs = append(s.reqs, req) } } if s.err != nil { return s.err } for _, v := range s.resps { if err := stream.Send(v.(*speechpb.StreamingRecognizeResponse)); err != nil { return err } } return nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockSpeech mockSpeechServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() speechpb.RegisterSpeechServer(serv, &mockSpeech) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestSpeechRecognize(t *testing.T) { var expectedResponse *speechpb.RecognizeResponse = &speechpb.RecognizeResponse{} mockSpeech.err = nil mockSpeech.reqs = nil mockSpeech.resps = append(mockSpeech.resps[:0], expectedResponse) var encoding speechpb.RecognitionConfig_AudioEncoding = speechpb.RecognitionConfig_FLAC var sampleRateHertz int32 = 44100 var languageCode string = "en-US" var config = &speechpb.RecognitionConfig{ Encoding: encoding, SampleRateHertz: sampleRateHertz, LanguageCode: languageCode, } var uri string = "gs://bucket_name/file_name.flac" var audio = &speechpb.RecognitionAudio{ AudioSource: &speechpb.RecognitionAudio_Uri{ Uri: uri, }, } var request = &speechpb.RecognizeRequest{ Config: config, Audio: audio, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Recognize(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSpeech.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSpeechRecognizeError(t *testing.T) { errCode := codes.PermissionDenied mockSpeech.err = gstatus.Error(errCode, "test error") var encoding speechpb.RecognitionConfig_AudioEncoding = speechpb.RecognitionConfig_FLAC var sampleRateHertz int32 = 44100 var languageCode string = "en-US" var config = &speechpb.RecognitionConfig{ Encoding: encoding, SampleRateHertz: sampleRateHertz, LanguageCode: languageCode, } var uri string = "gs://bucket_name/file_name.flac" var audio = &speechpb.RecognitionAudio{ AudioSource: &speechpb.RecognitionAudio_Uri{ Uri: uri, }, } var request = &speechpb.RecognizeRequest{ Config: config, Audio: audio, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Recognize(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSpeechLongRunningRecognize(t *testing.T) { var expectedResponse *speechpb.LongRunningRecognizeResponse = &speechpb.LongRunningRecognizeResponse{} mockSpeech.err = nil mockSpeech.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockSpeech.resps = append(mockSpeech.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var encoding speechpb.RecognitionConfig_AudioEncoding = speechpb.RecognitionConfig_FLAC var sampleRateHertz int32 = 44100 var languageCode string = "en-US" var config = &speechpb.RecognitionConfig{ Encoding: encoding, SampleRateHertz: sampleRateHertz, LanguageCode: languageCode, } var uri string = "gs://bucket_name/file_name.flac" var audio = &speechpb.RecognitionAudio{ AudioSource: &speechpb.RecognitionAudio_Uri{ Uri: uri, }, } var request = &speechpb.LongRunningRecognizeRequest{ Config: config, Audio: audio, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.LongRunningRecognize(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockSpeech.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSpeechLongRunningRecognizeError(t *testing.T) { errCode := codes.PermissionDenied mockSpeech.err = nil mockSpeech.resps = append(mockSpeech.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var encoding speechpb.RecognitionConfig_AudioEncoding = speechpb.RecognitionConfig_FLAC var sampleRateHertz int32 = 44100 var languageCode string = "en-US" var config = &speechpb.RecognitionConfig{ Encoding: encoding, SampleRateHertz: sampleRateHertz, LanguageCode: languageCode, } var uri string = "gs://bucket_name/file_name.flac" var audio = &speechpb.RecognitionAudio{ AudioSource: &speechpb.RecognitionAudio_Uri{ Uri: uri, }, } var request = &speechpb.LongRunningRecognizeRequest{ Config: config, Audio: audio, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.LongRunningRecognize(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSpeechStreamingRecognize(t *testing.T) { var expectedResponse *speechpb.StreamingRecognizeResponse = &speechpb.StreamingRecognizeResponse{} mockSpeech.err = nil mockSpeech.reqs = nil mockSpeech.resps = append(mockSpeech.resps[:0], expectedResponse) var request *speechpb.StreamingRecognizeRequest = &speechpb.StreamingRecognizeRequest{} c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } stream, err := c.StreamingRecognize(context.Background()) if err != nil { t.Fatal(err) } if err := stream.Send(request); err != nil { t.Fatal(err) } if err := stream.CloseSend(); err != nil { t.Fatal(err) } resp, err := stream.Recv() if err != nil { t.Fatal(err) } if want, got := request, mockSpeech.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSpeechStreamingRecognizeError(t *testing.T) { errCode := codes.PermissionDenied mockSpeech.err = gstatus.Error(errCode, "test error") var request *speechpb.StreamingRecognizeRequest = &speechpb.StreamingRecognizeRequest{} c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } stream, err := c.StreamingRecognize(context.Background()) if err != nil { t.Fatal(err) } if err := stream.Send(request); err != nil { t.Fatal(err) } if err := stream.CloseSend(); err != nil { t.Fatal(err) } resp, err := stream.Recv() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/speech/apiv1/speech_client.go000066400000000000000000000243241356504100700222200ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go_gapic. DO NOT EDIT. package speech import ( "context" "math" "time" "cloud.google.com/go/longrunning" lroauto "cloud.google.com/go/longrunning/autogen" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" "google.golang.org/api/transport" speechpb "google.golang.org/genproto/googleapis/cloud/speech/v1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // CallOptions contains the retry settings for each method of Client. type CallOptions struct { Recognize []gax.CallOption LongRunningRecognize []gax.CallOption StreamingRecognize []gax.CallOption } func defaultClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("speech.googleapis.com:443"), option.WithGRPCDialOption(grpc.WithDisableServiceConfig()), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultCallOptions() *CallOptions { return &CallOptions{ Recognize: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, codes.DeadlineExceeded, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, LongRunningRecognize: []gax.CallOption{}, StreamingRecognize: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, codes.DeadlineExceeded, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, } } // Client is a client for interacting with Cloud Speech-to-Text API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. client speechpb.SpeechClient // LROClient is used internally to handle longrunning operations. // It is exposed so that its CallOptions can be modified if required. // Users should not Close this client. LROClient *lroauto.OperationsClient // The call options for this service. CallOptions *CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewClient creates a new speech client. // // Service that implements Google Cloud Speech API. func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultClientOptions(), opts...)...) if err != nil { return nil, err } c := &Client{ conn: conn, CallOptions: defaultCallOptions(), client: speechpb.NewSpeechClient(conn), } c.setGoogleClientInfo() c.LROClient, err = lroauto.NewOperationsClient(ctx, option.WithGRPCConn(conn)) if err != nil { // This error "should not happen", since we are just reusing old connection // and never actually need to dial. // If this does happen, we could leak conn. However, we cannot close conn: // If the user invoked the function with option.WithGRPCConn, // we would close a connection that's still in use. // TODO(pongad): investigate error conditions. return nil, err } return c, nil } // Connection returns the client's connection to the API service. func (c *Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *Client) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *Client) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // Recognize performs synchronous speech recognition: receive results after all audio // has been sent and processed. func (c *Client) Recognize(ctx context.Context, req *speechpb.RecognizeRequest, opts ...gax.CallOption) (*speechpb.RecognizeResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.Recognize[0:len(c.CallOptions.Recognize):len(c.CallOptions.Recognize)], opts...) var resp *speechpb.RecognizeResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.Recognize(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // LongRunningRecognize performs asynchronous speech recognition: receive results via the // google.longrunning.Operations interface. Returns either an // Operation.error or an Operation.response which contains // a LongRunningRecognizeResponse message. // For more information on asynchronous speech recognition, see the // how-to (at https://cloud.google.com/speech-to-text/docs/async-recognize). func (c *Client) LongRunningRecognize(ctx context.Context, req *speechpb.LongRunningRecognizeRequest, opts ...gax.CallOption) (*LongRunningRecognizeOperation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.LongRunningRecognize[0:len(c.CallOptions.LongRunningRecognize):len(c.CallOptions.LongRunningRecognize)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.LongRunningRecognize(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &LongRunningRecognizeOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // StreamingRecognize performs bidirectional streaming speech recognition: receive results while // sending audio. This method is only available via the gRPC API (not REST). func (c *Client) StreamingRecognize(ctx context.Context, opts ...gax.CallOption) (speechpb.Speech_StreamingRecognizeClient, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.StreamingRecognize[0:len(c.CallOptions.StreamingRecognize):len(c.CallOptions.StreamingRecognize)], opts...) var resp speechpb.Speech_StreamingRecognizeClient err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.StreamingRecognize(ctx, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // LongRunningRecognizeOperation manages a long-running operation from LongRunningRecognize. type LongRunningRecognizeOperation struct { lro *longrunning.Operation } // LongRunningRecognizeOperation returns a new LongRunningRecognizeOperation from a given name. // The name must be that of a previously created LongRunningRecognizeOperation, possibly from a different process. func (c *Client) LongRunningRecognizeOperation(name string) *LongRunningRecognizeOperation { return &LongRunningRecognizeOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *LongRunningRecognizeOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*speechpb.LongRunningRecognizeResponse, error) { var resp speechpb.LongRunningRecognizeResponse if err := op.lro.WaitWithInterval(ctx, &resp, time.Minute, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *LongRunningRecognizeOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*speechpb.LongRunningRecognizeResponse, error) { var resp speechpb.LongRunningRecognizeResponse if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *LongRunningRecognizeOperation) Metadata() (*speechpb.LongRunningRecognizeMetadata, error) { var meta speechpb.LongRunningRecognizeMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *LongRunningRecognizeOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *LongRunningRecognizeOperation) Name() string { return op.lro.Name() } google-cloud-go-0.49.0/speech/apiv1/speech_client_example_test.go000066400000000000000000000050401356504100700247640ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go_gapic. DO NOT EDIT. package speech_test import ( "context" "io" speech "cloud.google.com/go/speech/apiv1" speechpb "google.golang.org/genproto/googleapis/cloud/speech/v1" ) func ExampleNewClient() { ctx := context.Background() c, err := speech.NewClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleClient_Recognize() { // import speechpb "google.golang.org/genproto/googleapis/cloud/speech/v1" ctx := context.Background() c, err := speech.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &speechpb.RecognizeRequest{ // TODO: Fill request struct fields. } resp, err := c.Recognize(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_LongRunningRecognize() { // import speechpb "google.golang.org/genproto/googleapis/cloud/speech/v1" ctx := context.Background() c, err := speech.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &speechpb.LongRunningRecognizeRequest{ // TODO: Fill request struct fields. } op, err := c.LongRunningRecognize(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_StreamingRecognize() { // import speechpb "google.golang.org/genproto/googleapis/cloud/speech/v1" ctx := context.Background() c, err := speech.NewClient(ctx) if err != nil { // TODO: Handle error. } stream, err := c.StreamingRecognize(ctx) if err != nil { // TODO: Handle error. } go func() { reqs := []*speechpb.StreamingRecognizeRequest{ // TODO: Create requests. } for _, req := range reqs { if err := stream.Send(req); err != nil { // TODO: Handle error. } } stream.CloseSend() }() for { resp, err := stream.Recv() if err == io.EOF { break } if err != nil { // TODO: handle error. } // TODO: Use resp. _ = resp } } google-cloud-go-0.49.0/speech/apiv1p1beta1/000077500000000000000000000000001356504100700202355ustar00rootroot00000000000000google-cloud-go-0.49.0/speech/apiv1p1beta1/.repo-metadata.json000066400000000000000000000006431356504100700237340ustar00rootroot00000000000000{ "name": "speech", "name_pretty": "Cloud Speech-to-Text", "product_documentation": "https://cloud.google.com/speech-to-text", "client_documentation": "https://godoc.org/cloud.google.com/go/speech/apiv1p1beta1", "release_level": "beta", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "speech.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/speech/apiv1p1beta1/Recognize_smoke_test.go000066400000000000000000000037521356504100700247550ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package speech import ( "context" "fmt" "strconv" "testing" "time" "cloud.google.com/go/internal/testutil" "google.golang.org/api/iterator" "google.golang.org/api/option" speechpb "google.golang.org/genproto/googleapis/cloud/speech/v1p1beta1" ) var _ = fmt.Sprintf var _ = iterator.Done var _ = strconv.FormatUint var _ = time.Now func TestSpeechSmoke(t *testing.T) { if testing.Short() { t.Skip("skipping smoke test in short mode") } ctx := context.Background() ts := testutil.TokenSource(ctx, DefaultAuthScopes()...) if ts == nil { t.Skip("Integration tests skipped. See CONTRIBUTING.md for details") } projectId := testutil.ProjID() _ = projectId c, err := NewClient(ctx, option.WithTokenSource(ts)) if err != nil { t.Fatal(err) } var languageCode string = "en-US" var sampleRateHertz int32 = 44100 var encoding speechpb.RecognitionConfig_AudioEncoding = speechpb.RecognitionConfig_FLAC var config = &speechpb.RecognitionConfig{ LanguageCode: languageCode, SampleRateHertz: sampleRateHertz, Encoding: encoding, } var uri string = "gs://gapic-toolkit/hello.flac" var audio = &speechpb.RecognitionAudio{ AudioSource: &speechpb.RecognitionAudio_Uri{ Uri: uri, }, } var request = &speechpb.RecognizeRequest{ Config: config, Audio: audio, } if _, err := c.Recognize(ctx, request); err != nil { t.Error(err) } } google-cloud-go-0.49.0/speech/apiv1p1beta1/doc.go000066400000000000000000000053551356504100700213410ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go_gapic. DO NOT EDIT. // Package speech is an auto-generated package for the // Cloud Speech-to-Text API. // // Converts audio to text by applying powerful neural network models. // // NOTE: This package is in beta. It is not stable, and may be subject to changes. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package speech // import "cloud.google.com/go/speech/apiv1p1beta1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) const versionClient = "20191115" func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return !strings.ContainsRune("0123456789.", r) } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } google-cloud-go-0.49.0/speech/apiv1p1beta1/mock_test.go000066400000000000000000000247151356504100700225650ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package speech import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" "google.golang.org/api/option" speechpb "google.golang.org/genproto/googleapis/cloud/speech/v1p1beta1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockSpeechServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. speechpb.SpeechServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockSpeechServer) Recognize(ctx context.Context, req *speechpb.RecognizeRequest) (*speechpb.RecognizeResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*speechpb.RecognizeResponse), nil } func (s *mockSpeechServer) LongRunningRecognize(ctx context.Context, req *speechpb.LongRunningRecognizeRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockSpeechServer) StreamingRecognize(stream speechpb.Speech_StreamingRecognizeServer) error { md, _ := metadata.FromIncomingContext(stream.Context()) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } for { if req, err := stream.Recv(); err == io.EOF { break } else if err != nil { return err } else { s.reqs = append(s.reqs, req) } } if s.err != nil { return s.err } for _, v := range s.resps { if err := stream.Send(v.(*speechpb.StreamingRecognizeResponse)); err != nil { return err } } return nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockSpeech mockSpeechServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() speechpb.RegisterSpeechServer(serv, &mockSpeech) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestSpeechRecognize(t *testing.T) { var expectedResponse *speechpb.RecognizeResponse = &speechpb.RecognizeResponse{} mockSpeech.err = nil mockSpeech.reqs = nil mockSpeech.resps = append(mockSpeech.resps[:0], expectedResponse) var encoding speechpb.RecognitionConfig_AudioEncoding = speechpb.RecognitionConfig_FLAC var sampleRateHertz int32 = 44100 var languageCode string = "en-US" var config = &speechpb.RecognitionConfig{ Encoding: encoding, SampleRateHertz: sampleRateHertz, LanguageCode: languageCode, } var uri string = "gs://bucket_name/file_name.flac" var audio = &speechpb.RecognitionAudio{ AudioSource: &speechpb.RecognitionAudio_Uri{ Uri: uri, }, } var request = &speechpb.RecognizeRequest{ Config: config, Audio: audio, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Recognize(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockSpeech.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSpeechRecognizeError(t *testing.T) { errCode := codes.PermissionDenied mockSpeech.err = gstatus.Error(errCode, "test error") var encoding speechpb.RecognitionConfig_AudioEncoding = speechpb.RecognitionConfig_FLAC var sampleRateHertz int32 = 44100 var languageCode string = "en-US" var config = &speechpb.RecognitionConfig{ Encoding: encoding, SampleRateHertz: sampleRateHertz, LanguageCode: languageCode, } var uri string = "gs://bucket_name/file_name.flac" var audio = &speechpb.RecognitionAudio{ AudioSource: &speechpb.RecognitionAudio_Uri{ Uri: uri, }, } var request = &speechpb.RecognizeRequest{ Config: config, Audio: audio, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.Recognize(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSpeechLongRunningRecognize(t *testing.T) { var expectedResponse *speechpb.LongRunningRecognizeResponse = &speechpb.LongRunningRecognizeResponse{} mockSpeech.err = nil mockSpeech.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockSpeech.resps = append(mockSpeech.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var encoding speechpb.RecognitionConfig_AudioEncoding = speechpb.RecognitionConfig_FLAC var sampleRateHertz int32 = 44100 var languageCode string = "en-US" var config = &speechpb.RecognitionConfig{ Encoding: encoding, SampleRateHertz: sampleRateHertz, LanguageCode: languageCode, } var uri string = "gs://bucket_name/file_name.flac" var audio = &speechpb.RecognitionAudio{ AudioSource: &speechpb.RecognitionAudio_Uri{ Uri: uri, }, } var request = &speechpb.LongRunningRecognizeRequest{ Config: config, Audio: audio, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.LongRunningRecognize(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockSpeech.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSpeechLongRunningRecognizeError(t *testing.T) { errCode := codes.PermissionDenied mockSpeech.err = nil mockSpeech.resps = append(mockSpeech.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var encoding speechpb.RecognitionConfig_AudioEncoding = speechpb.RecognitionConfig_FLAC var sampleRateHertz int32 = 44100 var languageCode string = "en-US" var config = &speechpb.RecognitionConfig{ Encoding: encoding, SampleRateHertz: sampleRateHertz, LanguageCode: languageCode, } var uri string = "gs://bucket_name/file_name.flac" var audio = &speechpb.RecognitionAudio{ AudioSource: &speechpb.RecognitionAudio_Uri{ Uri: uri, }, } var request = &speechpb.LongRunningRecognizeRequest{ Config: config, Audio: audio, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.LongRunningRecognize(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestSpeechStreamingRecognize(t *testing.T) { var expectedResponse *speechpb.StreamingRecognizeResponse = &speechpb.StreamingRecognizeResponse{} mockSpeech.err = nil mockSpeech.reqs = nil mockSpeech.resps = append(mockSpeech.resps[:0], expectedResponse) var request *speechpb.StreamingRecognizeRequest = &speechpb.StreamingRecognizeRequest{} c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } stream, err := c.StreamingRecognize(context.Background()) if err != nil { t.Fatal(err) } if err := stream.Send(request); err != nil { t.Fatal(err) } if err := stream.CloseSend(); err != nil { t.Fatal(err) } resp, err := stream.Recv() if err != nil { t.Fatal(err) } if want, got := request, mockSpeech.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestSpeechStreamingRecognizeError(t *testing.T) { errCode := codes.PermissionDenied mockSpeech.err = gstatus.Error(errCode, "test error") var request *speechpb.StreamingRecognizeRequest = &speechpb.StreamingRecognizeRequest{} c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } stream, err := c.StreamingRecognize(context.Background()) if err != nil { t.Fatal(err) } if err := stream.Send(request); err != nil { t.Fatal(err) } if err := stream.CloseSend(); err != nil { t.Fatal(err) } resp, err := stream.Recv() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/speech/apiv1p1beta1/speech_client.go000066400000000000000000000243331356504100700233760ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go_gapic. DO NOT EDIT. package speech import ( "context" "math" "time" "cloud.google.com/go/longrunning" lroauto "cloud.google.com/go/longrunning/autogen" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" "google.golang.org/api/transport" speechpb "google.golang.org/genproto/googleapis/cloud/speech/v1p1beta1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // CallOptions contains the retry settings for each method of Client. type CallOptions struct { Recognize []gax.CallOption LongRunningRecognize []gax.CallOption StreamingRecognize []gax.CallOption } func defaultClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("speech.googleapis.com:443"), option.WithGRPCDialOption(grpc.WithDisableServiceConfig()), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultCallOptions() *CallOptions { return &CallOptions{ Recognize: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, LongRunningRecognize: []gax.CallOption{}, StreamingRecognize: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, } } // Client is a client for interacting with Cloud Speech-to-Text API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. client speechpb.SpeechClient // LROClient is used internally to handle longrunning operations. // It is exposed so that its CallOptions can be modified if required. // Users should not Close this client. LROClient *lroauto.OperationsClient // The call options for this service. CallOptions *CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewClient creates a new speech client. // // Service that implements Google Cloud Speech API. func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultClientOptions(), opts...)...) if err != nil { return nil, err } c := &Client{ conn: conn, CallOptions: defaultCallOptions(), client: speechpb.NewSpeechClient(conn), } c.setGoogleClientInfo() c.LROClient, err = lroauto.NewOperationsClient(ctx, option.WithGRPCConn(conn)) if err != nil { // This error "should not happen", since we are just reusing old connection // and never actually need to dial. // If this does happen, we could leak conn. However, we cannot close conn: // If the user invoked the function with option.WithGRPCConn, // we would close a connection that's still in use. // TODO(pongad): investigate error conditions. return nil, err } return c, nil } // Connection returns the client's connection to the API service. func (c *Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *Client) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *Client) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // Recognize performs synchronous speech recognition: receive results after all audio // has been sent and processed. func (c *Client) Recognize(ctx context.Context, req *speechpb.RecognizeRequest, opts ...gax.CallOption) (*speechpb.RecognizeResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.Recognize[0:len(c.CallOptions.Recognize):len(c.CallOptions.Recognize)], opts...) var resp *speechpb.RecognizeResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.Recognize(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // LongRunningRecognize performs asynchronous speech recognition: receive results via the // google.longrunning.Operations interface. Returns either an // Operation.error or an Operation.response which contains // a LongRunningRecognizeResponse message. // For more information on asynchronous speech recognition, see the // how-to (at https://cloud.google.com/speech-to-text/docs/async-recognize). func (c *Client) LongRunningRecognize(ctx context.Context, req *speechpb.LongRunningRecognizeRequest, opts ...gax.CallOption) (*LongRunningRecognizeOperation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.LongRunningRecognize[0:len(c.CallOptions.LongRunningRecognize):len(c.CallOptions.LongRunningRecognize)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.LongRunningRecognize(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &LongRunningRecognizeOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // StreamingRecognize performs bidirectional streaming speech recognition: receive results while // sending audio. This method is only available via the gRPC API (not REST). func (c *Client) StreamingRecognize(ctx context.Context, opts ...gax.CallOption) (speechpb.Speech_StreamingRecognizeClient, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.StreamingRecognize[0:len(c.CallOptions.StreamingRecognize):len(c.CallOptions.StreamingRecognize)], opts...) var resp speechpb.Speech_StreamingRecognizeClient err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.StreamingRecognize(ctx, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // LongRunningRecognizeOperation manages a long-running operation from LongRunningRecognize. type LongRunningRecognizeOperation struct { lro *longrunning.Operation } // LongRunningRecognizeOperation returns a new LongRunningRecognizeOperation from a given name. // The name must be that of a previously created LongRunningRecognizeOperation, possibly from a different process. func (c *Client) LongRunningRecognizeOperation(name string) *LongRunningRecognizeOperation { return &LongRunningRecognizeOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *LongRunningRecognizeOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*speechpb.LongRunningRecognizeResponse, error) { var resp speechpb.LongRunningRecognizeResponse if err := op.lro.WaitWithInterval(ctx, &resp, time.Minute, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *LongRunningRecognizeOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*speechpb.LongRunningRecognizeResponse, error) { var resp speechpb.LongRunningRecognizeResponse if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *LongRunningRecognizeOperation) Metadata() (*speechpb.LongRunningRecognizeMetadata, error) { var meta speechpb.LongRunningRecognizeMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *LongRunningRecognizeOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *LongRunningRecognizeOperation) Name() string { return op.lro.Name() } google-cloud-go-0.49.0/speech/apiv1p1beta1/speech_client_example_test.go000066400000000000000000000051031356504100700261420ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go_gapic. DO NOT EDIT. package speech_test import ( "context" "io" speech "cloud.google.com/go/speech/apiv1p1beta1" speechpb "google.golang.org/genproto/googleapis/cloud/speech/v1p1beta1" ) func ExampleNewClient() { ctx := context.Background() c, err := speech.NewClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleClient_Recognize() { // import speechpb "google.golang.org/genproto/googleapis/cloud/speech/v1p1beta1" ctx := context.Background() c, err := speech.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &speechpb.RecognizeRequest{ // TODO: Fill request struct fields. } resp, err := c.Recognize(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_LongRunningRecognize() { // import speechpb "google.golang.org/genproto/googleapis/cloud/speech/v1p1beta1" ctx := context.Background() c, err := speech.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &speechpb.LongRunningRecognizeRequest{ // TODO: Fill request struct fields. } op, err := c.LongRunningRecognize(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_StreamingRecognize() { // import speechpb "google.golang.org/genproto/googleapis/cloud/speech/v1p1beta1" ctx := context.Background() c, err := speech.NewClient(ctx) if err != nil { // TODO: Handle error. } stream, err := c.StreamingRecognize(ctx) if err != nil { // TODO: Handle error. } go func() { reqs := []*speechpb.StreamingRecognizeRequest{ // TODO: Create requests. } for _, req := range reqs { if err := stream.Send(req); err != nil { // TODO: Handle error. } } stream.CloseSend() }() for { resp, err := stream.Recv() if err == io.EOF { break } if err != nil { // TODO: handle error. } // TODO: Use resp. _ = resp } } google-cloud-go-0.49.0/storage/000077500000000000000000000000001356504100700162345ustar00rootroot00000000000000google-cloud-go-0.49.0/storage/.repo-metadata.json000066400000000000000000000005771356504100700217410ustar00rootroot00000000000000{ "name": "storage", "name_pretty": "storage", "product_documentation": "https://cloud.google.com/storage", "client_documentation": "https://godoc.org/cloud.google.com/go/storage", "release_level": "ga", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go/storage", "api_id": "storage:v2", "requires_billing": true } google-cloud-go-0.49.0/storage/CHANGES.md000066400000000000000000000023101356504100700176220ustar00rootroot00000000000000# Changes ## v1.4.0 - When listing objects in a bucket, allow callers to specify which attributes are queried. This allows for performance optimization. ## v1.3.0 - Use `storage.googleapis.com/storage/v1` by default for GCS requests instead of `www.googleapis.com/storage/v1`. ## v1.2.1 - Fixed a bug where UniformBucketLevelAccess and BucketPolicyOnly were not being sent in all cases. ## v1.2.0 - Add support for UniformBucketLevelAccess. This configures access checks to use only bucket-level IAM policies. See: https://godoc.org/cloud.google.com/go/storage#UniformBucketLevelAccess. - Fix userAgent to use correct version. ## v1.1.2 - Fix memory leak in BucketIterator and ObjectIterator. ## v1.1.1 - Send BucketPolicyOnly even when it's disabled. ## v1.1.0 - Performance improvements for ObjectIterator and BucketIterator. - Fix Bucket.ObjectIterator size calculation checks. - Added HMACKeyOptions to all the methods which allows for options such as UserProject to be set per invocation and optionally be used. ## v1.0.0 This is the first tag to carve out storage as its own module. See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository.google-cloud-go-0.49.0/storage/README.md000066400000000000000000000015521356504100700175160ustar00rootroot00000000000000## Cloud Storage [![GoDoc](https://godoc.org/cloud.google.com/go/storage?status.svg)](https://godoc.org/cloud.google.com/go/storage) - [About Cloud Storage](https://cloud.google.com/storage/) - [API documentation](https://cloud.google.com/storage/docs) - [Go client documentation](https://godoc.org/cloud.google.com/go/storage) - [Complete sample programs](https://github.com/GoogleCloudPlatform/golang-samples/tree/master/storage) ### Example Usage First create a `storage.Client` to use throughout your application: [snip]:# (storage-1) ```go client, err := storage.NewClient(ctx) if err != nil { log.Fatal(err) } ``` [snip]:# (storage-2) ```go // Read the object1 from bucket. rc, err := client.Bucket("bucket").Object("object1").NewReader(ctx) if err != nil { log.Fatal(err) } defer rc.Close() body, err := ioutil.ReadAll(rc) if err != nil { log.Fatal(err) } ```google-cloud-go-0.49.0/storage/acl.go000066400000000000000000000213751356504100700173320ustar00rootroot00000000000000// Copyright 2014 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package storage import ( "context" "net/http" "reflect" "cloud.google.com/go/internal/trace" "google.golang.org/api/googleapi" raw "google.golang.org/api/storage/v1" ) // ACLRole is the level of access to grant. type ACLRole string const ( RoleOwner ACLRole = "OWNER" RoleReader ACLRole = "READER" RoleWriter ACLRole = "WRITER" ) // ACLEntity refers to a user or group. // They are sometimes referred to as grantees. // // It could be in the form of: // "user-", "user-", "group-", "group-", // "domain-" and "project-team-". // // Or one of the predefined constants: AllUsers, AllAuthenticatedUsers. type ACLEntity string const ( AllUsers ACLEntity = "allUsers" AllAuthenticatedUsers ACLEntity = "allAuthenticatedUsers" ) // ACLRule represents a grant for a role to an entity (user, group or team) for a // Google Cloud Storage object or bucket. type ACLRule struct { Entity ACLEntity EntityID string Role ACLRole Domain string Email string ProjectTeam *ProjectTeam } // ProjectTeam is the project team associated with the entity, if any. type ProjectTeam struct { ProjectNumber string Team string } // ACLHandle provides operations on an access control list for a Google Cloud Storage bucket or object. type ACLHandle struct { c *Client bucket string object string isDefault bool userProject string // for requester-pays buckets } // Delete permanently deletes the ACL entry for the given entity. func (a *ACLHandle) Delete(ctx context.Context, entity ACLEntity) (err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.ACL.Delete") defer func() { trace.EndSpan(ctx, err) }() if a.object != "" { return a.objectDelete(ctx, entity) } if a.isDefault { return a.bucketDefaultDelete(ctx, entity) } return a.bucketDelete(ctx, entity) } // Set sets the role for the given entity. func (a *ACLHandle) Set(ctx context.Context, entity ACLEntity, role ACLRole) (err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.ACL.Set") defer func() { trace.EndSpan(ctx, err) }() if a.object != "" { return a.objectSet(ctx, entity, role, false) } if a.isDefault { return a.objectSet(ctx, entity, role, true) } return a.bucketSet(ctx, entity, role) } // List retrieves ACL entries. func (a *ACLHandle) List(ctx context.Context) (rules []ACLRule, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.ACL.List") defer func() { trace.EndSpan(ctx, err) }() if a.object != "" { return a.objectList(ctx) } if a.isDefault { return a.bucketDefaultList(ctx) } return a.bucketList(ctx) } func (a *ACLHandle) bucketDefaultList(ctx context.Context) ([]ACLRule, error) { var acls *raw.ObjectAccessControls var err error err = runWithRetry(ctx, func() error { req := a.c.raw.DefaultObjectAccessControls.List(a.bucket) a.configureCall(ctx, req) acls, err = req.Do() return err }) if err != nil { return nil, err } return toObjectACLRules(acls.Items), nil } func (a *ACLHandle) bucketDefaultDelete(ctx context.Context, entity ACLEntity) error { return runWithRetry(ctx, func() error { req := a.c.raw.DefaultObjectAccessControls.Delete(a.bucket, string(entity)) a.configureCall(ctx, req) return req.Do() }) } func (a *ACLHandle) bucketList(ctx context.Context) ([]ACLRule, error) { var acls *raw.BucketAccessControls var err error err = runWithRetry(ctx, func() error { req := a.c.raw.BucketAccessControls.List(a.bucket) a.configureCall(ctx, req) acls, err = req.Do() return err }) if err != nil { return nil, err } return toBucketACLRules(acls.Items), nil } func (a *ACLHandle) bucketSet(ctx context.Context, entity ACLEntity, role ACLRole) error { acl := &raw.BucketAccessControl{ Bucket: a.bucket, Entity: string(entity), Role: string(role), } err := runWithRetry(ctx, func() error { req := a.c.raw.BucketAccessControls.Update(a.bucket, string(entity), acl) a.configureCall(ctx, req) _, err := req.Do() return err }) if err != nil { return err } return nil } func (a *ACLHandle) bucketDelete(ctx context.Context, entity ACLEntity) error { return runWithRetry(ctx, func() error { req := a.c.raw.BucketAccessControls.Delete(a.bucket, string(entity)) a.configureCall(ctx, req) return req.Do() }) } func (a *ACLHandle) objectList(ctx context.Context) ([]ACLRule, error) { var acls *raw.ObjectAccessControls var err error err = runWithRetry(ctx, func() error { req := a.c.raw.ObjectAccessControls.List(a.bucket, a.object) a.configureCall(ctx, req) acls, err = req.Do() return err }) if err != nil { return nil, err } return toObjectACLRules(acls.Items), nil } func (a *ACLHandle) objectSet(ctx context.Context, entity ACLEntity, role ACLRole, isBucketDefault bool) error { type setRequest interface { Do(opts ...googleapi.CallOption) (*raw.ObjectAccessControl, error) Header() http.Header } acl := &raw.ObjectAccessControl{ Bucket: a.bucket, Entity: string(entity), Role: string(role), } var req setRequest if isBucketDefault { req = a.c.raw.DefaultObjectAccessControls.Update(a.bucket, string(entity), acl) } else { req = a.c.raw.ObjectAccessControls.Update(a.bucket, a.object, string(entity), acl) } a.configureCall(ctx, req) return runWithRetry(ctx, func() error { _, err := req.Do() return err }) } func (a *ACLHandle) objectDelete(ctx context.Context, entity ACLEntity) error { return runWithRetry(ctx, func() error { req := a.c.raw.ObjectAccessControls.Delete(a.bucket, a.object, string(entity)) a.configureCall(ctx, req) return req.Do() }) } func (a *ACLHandle) configureCall(ctx context.Context, call interface{ Header() http.Header }) { vc := reflect.ValueOf(call) vc.MethodByName("Context").Call([]reflect.Value{reflect.ValueOf(ctx)}) if a.userProject != "" { vc.MethodByName("UserProject").Call([]reflect.Value{reflect.ValueOf(a.userProject)}) } setClientHeader(call.Header()) } func toObjectACLRules(items []*raw.ObjectAccessControl) []ACLRule { var rs []ACLRule for _, item := range items { rs = append(rs, toObjectACLRule(item)) } return rs } func toBucketACLRules(items []*raw.BucketAccessControl) []ACLRule { var rs []ACLRule for _, item := range items { rs = append(rs, toBucketACLRule(item)) } return rs } func toObjectACLRule(a *raw.ObjectAccessControl) ACLRule { return ACLRule{ Entity: ACLEntity(a.Entity), EntityID: a.EntityId, Role: ACLRole(a.Role), Domain: a.Domain, Email: a.Email, ProjectTeam: toObjectProjectTeam(a.ProjectTeam), } } func toBucketACLRule(a *raw.BucketAccessControl) ACLRule { return ACLRule{ Entity: ACLEntity(a.Entity), EntityID: a.EntityId, Role: ACLRole(a.Role), Domain: a.Domain, Email: a.Email, ProjectTeam: toBucketProjectTeam(a.ProjectTeam), } } func toRawObjectACL(rules []ACLRule) []*raw.ObjectAccessControl { if len(rules) == 0 { return nil } r := make([]*raw.ObjectAccessControl, 0, len(rules)) for _, rule := range rules { r = append(r, rule.toRawObjectAccessControl("")) // bucket name unnecessary } return r } func toRawBucketACL(rules []ACLRule) []*raw.BucketAccessControl { if len(rules) == 0 { return nil } r := make([]*raw.BucketAccessControl, 0, len(rules)) for _, rule := range rules { r = append(r, rule.toRawBucketAccessControl("")) // bucket name unnecessary } return r } func (r ACLRule) toRawBucketAccessControl(bucket string) *raw.BucketAccessControl { return &raw.BucketAccessControl{ Bucket: bucket, Entity: string(r.Entity), Role: string(r.Role), // The other fields are not settable. } } func (r ACLRule) toRawObjectAccessControl(bucket string) *raw.ObjectAccessControl { return &raw.ObjectAccessControl{ Bucket: bucket, Entity: string(r.Entity), Role: string(r.Role), // The other fields are not settable. } } func toBucketProjectTeam(p *raw.BucketAccessControlProjectTeam) *ProjectTeam { if p == nil { return nil } return &ProjectTeam{ ProjectNumber: p.ProjectNumber, Team: p.Team, } } func toObjectProjectTeam(p *raw.ObjectAccessControlProjectTeam) *ProjectTeam { if p == nil { return nil } return &ProjectTeam{ ProjectNumber: p.ProjectNumber, Team: p.Team, } } google-cloud-go-0.49.0/storage/acl_test.go000066400000000000000000000032301356504100700203570ustar00rootroot00000000000000// Copyright 2014 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package storage import ( "context" "net/http" "testing" "cloud.google.com/go/internal/testutil" ) func TestSetACL(t *testing.T) { ctx := context.Background() mt := &mockTransport{} client := mockClient(t, mt) bh := &ACLHandle{c: client, bucket: "B"} oh := &ACLHandle{c: client, bucket: "B", object: "O"} for _, test := range []struct { desc string f func() error want map[string]interface{} }{ { desc: "bucket Set", f: func() error { return bh.Set(ctx, AllUsers, RoleReader) }, want: map[string]interface{}{ "bucket": "B", "entity": "allUsers", "role": "READER", }, }, { desc: "object Set", f: func() error { return oh.Set(ctx, ACLEntity("e"), RoleWriter) }, want: map[string]interface{}{ "bucket": "B", "entity": "e", "role": "WRITER", }, }} { mt.addResult(&http.Response{StatusCode: 200, Body: bodyReader("{}")}, nil) if err := test.f(); err != nil { t.Fatal(err) } got := mt.gotJSONBody() if diff := testutil.Diff(got, test.want); diff != "" { t.Errorf("%s: %s", test.desc, diff) } } } google-cloud-go-0.49.0/storage/bucket.go000066400000000000000000001174101356504100700200440ustar00rootroot00000000000000// Copyright 2014 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package storage import ( "context" "fmt" "net/http" "reflect" "time" "cloud.google.com/go/internal/optional" "cloud.google.com/go/internal/trace" "google.golang.org/api/googleapi" "google.golang.org/api/iterator" raw "google.golang.org/api/storage/v1" ) // BucketHandle provides operations on a Google Cloud Storage bucket. // Use Client.Bucket to get a handle. type BucketHandle struct { c *Client name string acl ACLHandle defaultObjectACL ACLHandle conds *BucketConditions userProject string // project for Requester Pays buckets } // Bucket returns a BucketHandle, which provides operations on the named bucket. // This call does not perform any network operations. // // The supplied name must contain only lowercase letters, numbers, dashes, // underscores, and dots. The full specification for valid bucket names can be // found at: // https://cloud.google.com/storage/docs/bucket-naming func (c *Client) Bucket(name string) *BucketHandle { return &BucketHandle{ c: c, name: name, acl: ACLHandle{ c: c, bucket: name, }, defaultObjectACL: ACLHandle{ c: c, bucket: name, isDefault: true, }, } } // Create creates the Bucket in the project. // If attrs is nil the API defaults will be used. func (b *BucketHandle) Create(ctx context.Context, projectID string, attrs *BucketAttrs) (err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Bucket.Create") defer func() { trace.EndSpan(ctx, err) }() var bkt *raw.Bucket if attrs != nil { bkt = attrs.toRawBucket() } else { bkt = &raw.Bucket{} } bkt.Name = b.name // If there is lifecycle information but no location, explicitly set // the location. This is a GCS quirk/bug. if bkt.Location == "" && bkt.Lifecycle != nil { bkt.Location = "US" } req := b.c.raw.Buckets.Insert(projectID, bkt) setClientHeader(req.Header()) if attrs != nil && attrs.PredefinedACL != "" { req.PredefinedAcl(attrs.PredefinedACL) } if attrs != nil && attrs.PredefinedDefaultObjectACL != "" { req.PredefinedDefaultObjectAcl(attrs.PredefinedDefaultObjectACL) } return runWithRetry(ctx, func() error { _, err := req.Context(ctx).Do(); return err }) } // Delete deletes the Bucket. func (b *BucketHandle) Delete(ctx context.Context) (err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Bucket.Delete") defer func() { trace.EndSpan(ctx, err) }() req, err := b.newDeleteCall() if err != nil { return err } return runWithRetry(ctx, func() error { return req.Context(ctx).Do() }) } func (b *BucketHandle) newDeleteCall() (*raw.BucketsDeleteCall, error) { req := b.c.raw.Buckets.Delete(b.name) setClientHeader(req.Header()) if err := applyBucketConds("BucketHandle.Delete", b.conds, req); err != nil { return nil, err } if b.userProject != "" { req.UserProject(b.userProject) } return req, nil } // ACL returns an ACLHandle, which provides access to the bucket's access control list. // This controls who can list, create or overwrite the objects in a bucket. // This call does not perform any network operations. func (b *BucketHandle) ACL() *ACLHandle { return &b.acl } // DefaultObjectACL returns an ACLHandle, which provides access to the bucket's default object ACLs. // These ACLs are applied to newly created objects in this bucket that do not have a defined ACL. // This call does not perform any network operations. func (b *BucketHandle) DefaultObjectACL() *ACLHandle { return &b.defaultObjectACL } // Object returns an ObjectHandle, which provides operations on the named object. // This call does not perform any network operations. // // name must consist entirely of valid UTF-8-encoded runes. The full specification // for valid object names can be found at: // https://cloud.google.com/storage/docs/bucket-naming func (b *BucketHandle) Object(name string) *ObjectHandle { return &ObjectHandle{ c: b.c, bucket: b.name, object: name, acl: ACLHandle{ c: b.c, bucket: b.name, object: name, userProject: b.userProject, }, gen: -1, userProject: b.userProject, } } // Attrs returns the metadata for the bucket. func (b *BucketHandle) Attrs(ctx context.Context) (attrs *BucketAttrs, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Bucket.Attrs") defer func() { trace.EndSpan(ctx, err) }() req, err := b.newGetCall() if err != nil { return nil, err } var resp *raw.Bucket err = runWithRetry(ctx, func() error { resp, err = req.Context(ctx).Do() return err }) if e, ok := err.(*googleapi.Error); ok && e.Code == http.StatusNotFound { return nil, ErrBucketNotExist } if err != nil { return nil, err } return newBucket(resp) } func (b *BucketHandle) newGetCall() (*raw.BucketsGetCall, error) { req := b.c.raw.Buckets.Get(b.name).Projection("full") setClientHeader(req.Header()) if err := applyBucketConds("BucketHandle.Attrs", b.conds, req); err != nil { return nil, err } if b.userProject != "" { req.UserProject(b.userProject) } return req, nil } // Update updates a bucket's attributes. func (b *BucketHandle) Update(ctx context.Context, uattrs BucketAttrsToUpdate) (attrs *BucketAttrs, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Bucket.Create") defer func() { trace.EndSpan(ctx, err) }() req, err := b.newPatchCall(&uattrs) if err != nil { return nil, err } if uattrs.PredefinedACL != "" { req.PredefinedAcl(uattrs.PredefinedACL) } if uattrs.PredefinedDefaultObjectACL != "" { req.PredefinedDefaultObjectAcl(uattrs.PredefinedDefaultObjectACL) } // TODO(jba): retry iff metagen is set? rb, err := req.Context(ctx).Do() if err != nil { return nil, err } return newBucket(rb) } func (b *BucketHandle) newPatchCall(uattrs *BucketAttrsToUpdate) (*raw.BucketsPatchCall, error) { rb := uattrs.toRawBucket() req := b.c.raw.Buckets.Patch(b.name, rb).Projection("full") setClientHeader(req.Header()) if err := applyBucketConds("BucketHandle.Update", b.conds, req); err != nil { return nil, err } if b.userProject != "" { req.UserProject(b.userProject) } return req, nil } // BucketAttrs represents the metadata for a Google Cloud Storage bucket. // Read-only fields are ignored by BucketHandle.Create. type BucketAttrs struct { // Name is the name of the bucket. // This field is read-only. Name string // ACL is the list of access control rules on the bucket. ACL []ACLRule // BucketPolicyOnly is an alias for UniformBucketLevelAccess. Use of // UniformBucketLevelAccess is recommended above the use of this field. // Setting BucketPolicyOnly.Enabled OR UniformBucketLevelAccess.Enabled to // true, will enable UniformBucketLevelAccess. BucketPolicyOnly BucketPolicyOnly // UniformBucketLevelAccess configures access checks to use only bucket-level IAM // policies and ignore any ACL rules for the bucket. // See https://cloud.google.com/storage/docs/uniform-bucket-level-access // for more information. UniformBucketLevelAccess UniformBucketLevelAccess // DefaultObjectACL is the list of access controls to // apply to new objects when no object ACL is provided. DefaultObjectACL []ACLRule // DefaultEventBasedHold is the default value for event-based hold on // newly created objects in this bucket. It defaults to false. DefaultEventBasedHold bool // If not empty, applies a predefined set of access controls. It should be set // only when creating a bucket. // It is always empty for BucketAttrs returned from the service. // See https://cloud.google.com/storage/docs/json_api/v1/buckets/insert // for valid values. PredefinedACL string // If not empty, applies a predefined set of default object access controls. // It should be set only when creating a bucket. // It is always empty for BucketAttrs returned from the service. // See https://cloud.google.com/storage/docs/json_api/v1/buckets/insert // for valid values. PredefinedDefaultObjectACL string // Location is the location of the bucket. It defaults to "US". Location string // MetaGeneration is the metadata generation of the bucket. // This field is read-only. MetaGeneration int64 // StorageClass is the default storage class of the bucket. This defines // how objects in the bucket are stored and determines the SLA // and the cost of storage. Typical values are "NEARLINE", "COLDLINE" and // "STANDARD". Defaults to "STANDARD". StorageClass string // Created is the creation time of the bucket. // This field is read-only. Created time.Time // VersioningEnabled reports whether this bucket has versioning enabled. VersioningEnabled bool // Labels are the bucket's labels. Labels map[string]string // RequesterPays reports whether the bucket is a Requester Pays bucket. // Clients performing operations on Requester Pays buckets must provide // a user project (see BucketHandle.UserProject), which will be billed // for the operations. RequesterPays bool // Lifecycle is the lifecycle configuration for objects in the bucket. Lifecycle Lifecycle // Retention policy enforces a minimum retention time for all objects // contained in the bucket. A RetentionPolicy of nil implies the bucket // has no minimum data retention. // // This feature is in private alpha release. It is not currently available to // most customers. It might be changed in backwards-incompatible ways and is not // subject to any SLA or deprecation policy. RetentionPolicy *RetentionPolicy // The bucket's Cross-Origin Resource Sharing (CORS) configuration. CORS []CORS // The encryption configuration used by default for newly inserted objects. Encryption *BucketEncryption // The logging configuration. Logging *BucketLogging // The website configuration. Website *BucketWebsite // Etag is the HTTP/1.1 Entity tag for the bucket. // This field is read-only. Etag string // LocationType describes how data is stored and replicated. // Typical values are "multi-region", "region" and "dual-region". // This field is read-only. LocationType string } // BucketPolicyOnly is an alias for UniformBucketLevelAccess. // Use of UniformBucketLevelAccess is preferred above BucketPolicyOnly. type BucketPolicyOnly struct { // Enabled specifies whether access checks use only bucket-level IAM // policies. Enabled may be disabled until the locked time. Enabled bool // LockedTime specifies the deadline for changing Enabled from true to // false. LockedTime time.Time } // UniformBucketLevelAccess configures access checks to use only bucket-level IAM // policies. type UniformBucketLevelAccess struct { // Enabled specifies whether access checks use only bucket-level IAM // policies. Enabled may be disabled until the locked time. Enabled bool // LockedTime specifies the deadline for changing Enabled from true to // false. LockedTime time.Time } // Lifecycle is the lifecycle configuration for objects in the bucket. type Lifecycle struct { Rules []LifecycleRule } // RetentionPolicy enforces a minimum retention time for all objects // contained in the bucket. // // Any attempt to overwrite or delete objects younger than the retention // period will result in an error. An unlocked retention policy can be // modified or removed from the bucket via the Update method. A // locked retention policy cannot be removed or shortened in duration // for the lifetime of the bucket. // // This feature is in private alpha release. It is not currently available to // most customers. It might be changed in backwards-incompatible ways and is not // subject to any SLA or deprecation policy. type RetentionPolicy struct { // RetentionPeriod specifies the duration that objects need to be // retained. Retention duration must be greater than zero and less than // 100 years. Note that enforcement of retention periods less than a day // is not guaranteed. Such periods should only be used for testing // purposes. RetentionPeriod time.Duration // EffectiveTime is the time from which the policy was enforced and // effective. This field is read-only. EffectiveTime time.Time // IsLocked describes whether the bucket is locked. Once locked, an // object retention policy cannot be modified. // This field is read-only. IsLocked bool } const ( // RFC3339 date with only the date segment, used for CreatedBefore in LifecycleRule. rfc3339Date = "2006-01-02" // DeleteAction is a lifecycle action that deletes a live and/or archived // objects. Takes precedence over SetStorageClass actions. DeleteAction = "Delete" // SetStorageClassAction changes the storage class of live and/or archived // objects. SetStorageClassAction = "SetStorageClass" ) // LifecycleRule is a lifecycle configuration rule. // // When all the configured conditions are met by an object in the bucket, the // configured action will automatically be taken on that object. type LifecycleRule struct { // Action is the action to take when all of the associated conditions are // met. Action LifecycleAction // Condition is the set of conditions that must be met for the associated // action to be taken. Condition LifecycleCondition } // LifecycleAction is a lifecycle configuration action. type LifecycleAction struct { // Type is the type of action to take on matching objects. // // Acceptable values are "Delete" to delete matching objects and // "SetStorageClass" to set the storage class defined in StorageClass on // matching objects. Type string // StorageClass is the storage class to set on matching objects if the Action // is "SetStorageClass". StorageClass string } // Liveness specifies whether the object is live or not. type Liveness int const ( // LiveAndArchived includes both live and archived objects. LiveAndArchived Liveness = iota // Live specifies that the object is still live. Live // Archived specifies that the object is archived. Archived ) // LifecycleCondition is a set of conditions used to match objects and take an // action automatically. // // All configured conditions must be met for the associated action to be taken. type LifecycleCondition struct { // AgeInDays is the age of the object in days. AgeInDays int64 // CreatedBefore is the time the object was created. // // This condition is satisfied when an object is created before midnight of // the specified date in UTC. CreatedBefore time.Time // Liveness specifies the object's liveness. Relevant only for versioned objects Liveness Liveness // MatchesStorageClasses is the condition matching the object's storage // class. // // Values include "NEARLINE", "COLDLINE" and "STANDARD". MatchesStorageClasses []string // NumNewerVersions is the condition matching objects with a number of newer versions. // // If the value is N, this condition is satisfied when there are at least N // versions (including the live version) newer than this version of the // object. NumNewerVersions int64 } // BucketLogging holds the bucket's logging configuration, which defines the // destination bucket and optional name prefix for the current bucket's // logs. type BucketLogging struct { // The destination bucket where the current bucket's logs // should be placed. LogBucket string // A prefix for log object names. LogObjectPrefix string } // BucketWebsite holds the bucket's website configuration, controlling how the // service behaves when accessing bucket contents as a web site. See // https://cloud.google.com/storage/docs/static-website for more information. type BucketWebsite struct { // If the requested object path is missing, the service will ensure the path has // a trailing '/', append this suffix, and attempt to retrieve the resulting // object. This allows the creation of index.html objects to represent directory // pages. MainPageSuffix string // If the requested object path is missing, and any mainPageSuffix object is // missing, if applicable, the service will return the named object from this // bucket as the content for a 404 Not Found result. NotFoundPage string } func newBucket(b *raw.Bucket) (*BucketAttrs, error) { if b == nil { return nil, nil } rp, err := toRetentionPolicy(b.RetentionPolicy) if err != nil { return nil, err } return &BucketAttrs{ Name: b.Name, Location: b.Location, MetaGeneration: b.Metageneration, DefaultEventBasedHold: b.DefaultEventBasedHold, StorageClass: b.StorageClass, Created: convertTime(b.TimeCreated), VersioningEnabled: b.Versioning != nil && b.Versioning.Enabled, ACL: toBucketACLRules(b.Acl), DefaultObjectACL: toObjectACLRules(b.DefaultObjectAcl), Labels: b.Labels, RequesterPays: b.Billing != nil && b.Billing.RequesterPays, Lifecycle: toLifecycle(b.Lifecycle), RetentionPolicy: rp, CORS: toCORS(b.Cors), Encryption: toBucketEncryption(b.Encryption), Logging: toBucketLogging(b.Logging), Website: toBucketWebsite(b.Website), BucketPolicyOnly: toBucketPolicyOnly(b.IamConfiguration), UniformBucketLevelAccess: toUniformBucketLevelAccess(b.IamConfiguration), Etag: b.Etag, LocationType: b.LocationType, }, nil } // toRawBucket copies the editable attribute from b to the raw library's Bucket type. func (b *BucketAttrs) toRawBucket() *raw.Bucket { // Copy label map. var labels map[string]string if len(b.Labels) > 0 { labels = make(map[string]string, len(b.Labels)) for k, v := range b.Labels { labels[k] = v } } // Ignore VersioningEnabled if it is false. This is OK because // we only call this method when creating a bucket, and by default // new buckets have versioning off. var v *raw.BucketVersioning if b.VersioningEnabled { v = &raw.BucketVersioning{Enabled: true} } var bb *raw.BucketBilling if b.RequesterPays { bb = &raw.BucketBilling{RequesterPays: true} } var bktIAM *raw.BucketIamConfiguration if b.UniformBucketLevelAccess.Enabled || b.BucketPolicyOnly.Enabled { bktIAM = &raw.BucketIamConfiguration{ UniformBucketLevelAccess: &raw.BucketIamConfigurationUniformBucketLevelAccess{ Enabled: true, }, } } return &raw.Bucket{ Name: b.Name, Location: b.Location, StorageClass: b.StorageClass, Acl: toRawBucketACL(b.ACL), DefaultObjectAcl: toRawObjectACL(b.DefaultObjectACL), Versioning: v, Labels: labels, Billing: bb, Lifecycle: toRawLifecycle(b.Lifecycle), RetentionPolicy: b.RetentionPolicy.toRawRetentionPolicy(), Cors: toRawCORS(b.CORS), Encryption: b.Encryption.toRawBucketEncryption(), Logging: b.Logging.toRawBucketLogging(), Website: b.Website.toRawBucketWebsite(), IamConfiguration: bktIAM, } } // CORS is the bucket's Cross-Origin Resource Sharing (CORS) configuration. type CORS struct { // MaxAge is the value to return in the Access-Control-Max-Age // header used in preflight responses. MaxAge time.Duration // Methods is the list of HTTP methods on which to include CORS response // headers, (GET, OPTIONS, POST, etc) Note: "*" is permitted in the list // of methods, and means "any method". Methods []string // Origins is the list of Origins eligible to receive CORS response // headers. Note: "*" is permitted in the list of origins, and means // "any Origin". Origins []string // ResponseHeaders is the list of HTTP headers other than the simple // response headers to give permission for the user-agent to share // across domains. ResponseHeaders []string } // BucketEncryption is a bucket's encryption configuration. type BucketEncryption struct { // A Cloud KMS key name, in the form // projects/P/locations/L/keyRings/R/cryptoKeys/K, that will be used to encrypt // objects inserted into this bucket, if no encryption method is specified. // The key's location must be the same as the bucket's. DefaultKMSKeyName string } // BucketAttrsToUpdate define the attributes to update during an Update call. type BucketAttrsToUpdate struct { // If set, updates whether the bucket uses versioning. VersioningEnabled optional.Bool // If set, updates whether the bucket is a Requester Pays bucket. RequesterPays optional.Bool // DefaultEventBasedHold is the default value for event-based hold on // newly created objects in this bucket. DefaultEventBasedHold optional.Bool // BucketPolicyOnly is an alias for UniformBucketLevelAccess. Use of // UniformBucketLevelAccess is recommended above the use of this field. // Setting BucketPolicyOnly.Enabled OR UniformBucketLevelAccess.Enabled to // true, will enable UniformBucketLevelAccess. If both BucketPolicyOnly and // UniformBucketLevelAccess are set, the value of UniformBucketLevelAccess // will take precedence. BucketPolicyOnly *BucketPolicyOnly // UniformBucketLevelAccess configures access checks to use only bucket-level IAM // policies and ignore any ACL rules for the bucket. // See https://cloud.google.com/storage/docs/uniform-bucket-level-access // for more information. UniformBucketLevelAccess *UniformBucketLevelAccess // If set, updates the retention policy of the bucket. Using // RetentionPolicy.RetentionPeriod = 0 will delete the existing policy. // // This feature is in private alpha release. It is not currently available to // most customers. It might be changed in backwards-incompatible ways and is not // subject to any SLA or deprecation policy. RetentionPolicy *RetentionPolicy // If set, replaces the CORS configuration with a new configuration. // An empty (rather than nil) slice causes all CORS policies to be removed. CORS []CORS // If set, replaces the encryption configuration of the bucket. Using // BucketEncryption.DefaultKMSKeyName = "" will delete the existing // configuration. Encryption *BucketEncryption // If set, replaces the lifecycle configuration of the bucket. Lifecycle *Lifecycle // If set, replaces the logging configuration of the bucket. Logging *BucketLogging // If set, replaces the website configuration of the bucket. Website *BucketWebsite // If not empty, applies a predefined set of access controls. // See https://cloud.google.com/storage/docs/json_api/v1/buckets/patch. PredefinedACL string // If not empty, applies a predefined set of default object access controls. // See https://cloud.google.com/storage/docs/json_api/v1/buckets/patch. PredefinedDefaultObjectACL string setLabels map[string]string deleteLabels map[string]bool } // SetLabel causes a label to be added or modified when ua is used // in a call to Bucket.Update. func (ua *BucketAttrsToUpdate) SetLabel(name, value string) { if ua.setLabels == nil { ua.setLabels = map[string]string{} } ua.setLabels[name] = value } // DeleteLabel causes a label to be deleted when ua is used in a // call to Bucket.Update. func (ua *BucketAttrsToUpdate) DeleteLabel(name string) { if ua.deleteLabels == nil { ua.deleteLabels = map[string]bool{} } ua.deleteLabels[name] = true } func (ua *BucketAttrsToUpdate) toRawBucket() *raw.Bucket { rb := &raw.Bucket{} if ua.CORS != nil { rb.Cors = toRawCORS(ua.CORS) rb.ForceSendFields = append(rb.ForceSendFields, "Cors") } if ua.DefaultEventBasedHold != nil { rb.DefaultEventBasedHold = optional.ToBool(ua.DefaultEventBasedHold) rb.ForceSendFields = append(rb.ForceSendFields, "DefaultEventBasedHold") } if ua.RetentionPolicy != nil { if ua.RetentionPolicy.RetentionPeriod == 0 { rb.NullFields = append(rb.NullFields, "RetentionPolicy") rb.RetentionPolicy = nil } else { rb.RetentionPolicy = ua.RetentionPolicy.toRawRetentionPolicy() } } if ua.VersioningEnabled != nil { rb.Versioning = &raw.BucketVersioning{ Enabled: optional.ToBool(ua.VersioningEnabled), ForceSendFields: []string{"Enabled"}, } } if ua.RequesterPays != nil { rb.Billing = &raw.BucketBilling{ RequesterPays: optional.ToBool(ua.RequesterPays), ForceSendFields: []string{"RequesterPays"}, } } if ua.BucketPolicyOnly != nil { rb.IamConfiguration = &raw.BucketIamConfiguration{ UniformBucketLevelAccess: &raw.BucketIamConfigurationUniformBucketLevelAccess{ Enabled: ua.BucketPolicyOnly.Enabled, ForceSendFields: []string{"Enabled"}, }, } } if ua.UniformBucketLevelAccess != nil { rb.IamConfiguration = &raw.BucketIamConfiguration{ UniformBucketLevelAccess: &raw.BucketIamConfigurationUniformBucketLevelAccess{ Enabled: ua.UniformBucketLevelAccess.Enabled, ForceSendFields: []string{"Enabled"}, }, } } if ua.Encryption != nil { if ua.Encryption.DefaultKMSKeyName == "" { rb.NullFields = append(rb.NullFields, "Encryption") rb.Encryption = nil } else { rb.Encryption = ua.Encryption.toRawBucketEncryption() } } if ua.Lifecycle != nil { rb.Lifecycle = toRawLifecycle(*ua.Lifecycle) } if ua.Logging != nil { if *ua.Logging == (BucketLogging{}) { rb.NullFields = append(rb.NullFields, "Logging") rb.Logging = nil } else { rb.Logging = ua.Logging.toRawBucketLogging() } } if ua.Website != nil { if *ua.Website == (BucketWebsite{}) { rb.NullFields = append(rb.NullFields, "Website") rb.Website = nil } else { rb.Website = ua.Website.toRawBucketWebsite() } } if ua.PredefinedACL != "" { // Clear ACL or the call will fail. rb.Acl = nil rb.ForceSendFields = append(rb.ForceSendFields, "Acl") } if ua.PredefinedDefaultObjectACL != "" { // Clear ACLs or the call will fail. rb.DefaultObjectAcl = nil rb.ForceSendFields = append(rb.ForceSendFields, "DefaultObjectAcl") } if ua.setLabels != nil || ua.deleteLabels != nil { rb.Labels = map[string]string{} for k, v := range ua.setLabels { rb.Labels[k] = v } if len(rb.Labels) == 0 && len(ua.deleteLabels) > 0 { rb.ForceSendFields = append(rb.ForceSendFields, "Labels") } for l := range ua.deleteLabels { rb.NullFields = append(rb.NullFields, "Labels."+l) } } return rb } // If returns a new BucketHandle that applies a set of preconditions. // Preconditions already set on the BucketHandle are ignored. // Operations on the new handle will return an error if the preconditions are not // satisfied. The only valid preconditions for buckets are MetagenerationMatch // and MetagenerationNotMatch. func (b *BucketHandle) If(conds BucketConditions) *BucketHandle { b2 := *b b2.conds = &conds return &b2 } // BucketConditions constrain bucket methods to act on specific metagenerations. // // The zero value is an empty set of constraints. type BucketConditions struct { // MetagenerationMatch specifies that the bucket must have the given // metageneration for the operation to occur. // If MetagenerationMatch is zero, it has no effect. MetagenerationMatch int64 // MetagenerationNotMatch specifies that the bucket must not have the given // metageneration for the operation to occur. // If MetagenerationNotMatch is zero, it has no effect. MetagenerationNotMatch int64 } func (c *BucketConditions) validate(method string) error { if *c == (BucketConditions{}) { return fmt.Errorf("storage: %s: empty conditions", method) } if c.MetagenerationMatch != 0 && c.MetagenerationNotMatch != 0 { return fmt.Errorf("storage: %s: multiple conditions specified for metageneration", method) } return nil } // UserProject returns a new BucketHandle that passes the project ID as the user // project for all subsequent calls. Calls with a user project will be billed to that // project rather than to the bucket's owning project. // // A user project is required for all operations on Requester Pays buckets. func (b *BucketHandle) UserProject(projectID string) *BucketHandle { b2 := *b b2.userProject = projectID b2.acl.userProject = projectID b2.defaultObjectACL.userProject = projectID return &b2 } // LockRetentionPolicy locks a bucket's retention policy until a previously-configured // RetentionPeriod past the EffectiveTime. Note that if RetentionPeriod is set to less // than a day, the retention policy is treated as a development configuration and locking // will have no effect. The BucketHandle must have a metageneration condition that // matches the bucket's metageneration. See BucketHandle.If. // // This feature is in private alpha release. It is not currently available to // most customers. It might be changed in backwards-incompatible ways and is not // subject to any SLA or deprecation policy. func (b *BucketHandle) LockRetentionPolicy(ctx context.Context) error { var metageneration int64 if b.conds != nil { metageneration = b.conds.MetagenerationMatch } req := b.c.raw.Buckets.LockRetentionPolicy(b.name, metageneration) _, err := req.Context(ctx).Do() return err } // applyBucketConds modifies the provided call using the conditions in conds. // call is something that quacks like a *raw.WhateverCall. func applyBucketConds(method string, conds *BucketConditions, call interface{}) error { if conds == nil { return nil } if err := conds.validate(method); err != nil { return err } cval := reflect.ValueOf(call) switch { case conds.MetagenerationMatch != 0: if !setConditionField(cval, "IfMetagenerationMatch", conds.MetagenerationMatch) { return fmt.Errorf("storage: %s: ifMetagenerationMatch not supported", method) } case conds.MetagenerationNotMatch != 0: if !setConditionField(cval, "IfMetagenerationNotMatch", conds.MetagenerationNotMatch) { return fmt.Errorf("storage: %s: ifMetagenerationNotMatch not supported", method) } } return nil } func (rp *RetentionPolicy) toRawRetentionPolicy() *raw.BucketRetentionPolicy { if rp == nil { return nil } return &raw.BucketRetentionPolicy{ RetentionPeriod: int64(rp.RetentionPeriod / time.Second), } } func toRetentionPolicy(rp *raw.BucketRetentionPolicy) (*RetentionPolicy, error) { if rp == nil { return nil, nil } t, err := time.Parse(time.RFC3339, rp.EffectiveTime) if err != nil { return nil, err } return &RetentionPolicy{ RetentionPeriod: time.Duration(rp.RetentionPeriod) * time.Second, EffectiveTime: t, IsLocked: rp.IsLocked, }, nil } func toRawCORS(c []CORS) []*raw.BucketCors { var out []*raw.BucketCors for _, v := range c { out = append(out, &raw.BucketCors{ MaxAgeSeconds: int64(v.MaxAge / time.Second), Method: v.Methods, Origin: v.Origins, ResponseHeader: v.ResponseHeaders, }) } return out } func toCORS(rc []*raw.BucketCors) []CORS { var out []CORS for _, v := range rc { out = append(out, CORS{ MaxAge: time.Duration(v.MaxAgeSeconds) * time.Second, Methods: v.Method, Origins: v.Origin, ResponseHeaders: v.ResponseHeader, }) } return out } func toRawLifecycle(l Lifecycle) *raw.BucketLifecycle { var rl raw.BucketLifecycle if len(l.Rules) == 0 { return nil } for _, r := range l.Rules { rr := &raw.BucketLifecycleRule{ Action: &raw.BucketLifecycleRuleAction{ Type: r.Action.Type, StorageClass: r.Action.StorageClass, }, Condition: &raw.BucketLifecycleRuleCondition{ Age: r.Condition.AgeInDays, MatchesStorageClass: r.Condition.MatchesStorageClasses, NumNewerVersions: r.Condition.NumNewerVersions, }, } switch r.Condition.Liveness { case LiveAndArchived: rr.Condition.IsLive = nil case Live: rr.Condition.IsLive = googleapi.Bool(true) case Archived: rr.Condition.IsLive = googleapi.Bool(false) } if !r.Condition.CreatedBefore.IsZero() { rr.Condition.CreatedBefore = r.Condition.CreatedBefore.Format(rfc3339Date) } rl.Rule = append(rl.Rule, rr) } return &rl } func toLifecycle(rl *raw.BucketLifecycle) Lifecycle { var l Lifecycle if rl == nil { return l } for _, rr := range rl.Rule { r := LifecycleRule{ Action: LifecycleAction{ Type: rr.Action.Type, StorageClass: rr.Action.StorageClass, }, Condition: LifecycleCondition{ AgeInDays: rr.Condition.Age, MatchesStorageClasses: rr.Condition.MatchesStorageClass, NumNewerVersions: rr.Condition.NumNewerVersions, }, } switch { case rr.Condition.IsLive == nil: r.Condition.Liveness = LiveAndArchived case *rr.Condition.IsLive == true: r.Condition.Liveness = Live case *rr.Condition.IsLive == false: r.Condition.Liveness = Archived } if rr.Condition.CreatedBefore != "" { r.Condition.CreatedBefore, _ = time.Parse(rfc3339Date, rr.Condition.CreatedBefore) } l.Rules = append(l.Rules, r) } return l } func (e *BucketEncryption) toRawBucketEncryption() *raw.BucketEncryption { if e == nil { return nil } return &raw.BucketEncryption{ DefaultKmsKeyName: e.DefaultKMSKeyName, } } func toBucketEncryption(e *raw.BucketEncryption) *BucketEncryption { if e == nil { return nil } return &BucketEncryption{DefaultKMSKeyName: e.DefaultKmsKeyName} } func (b *BucketLogging) toRawBucketLogging() *raw.BucketLogging { if b == nil { return nil } return &raw.BucketLogging{ LogBucket: b.LogBucket, LogObjectPrefix: b.LogObjectPrefix, } } func toBucketLogging(b *raw.BucketLogging) *BucketLogging { if b == nil { return nil } return &BucketLogging{ LogBucket: b.LogBucket, LogObjectPrefix: b.LogObjectPrefix, } } func (w *BucketWebsite) toRawBucketWebsite() *raw.BucketWebsite { if w == nil { return nil } return &raw.BucketWebsite{ MainPageSuffix: w.MainPageSuffix, NotFoundPage: w.NotFoundPage, } } func toBucketWebsite(w *raw.BucketWebsite) *BucketWebsite { if w == nil { return nil } return &BucketWebsite{ MainPageSuffix: w.MainPageSuffix, NotFoundPage: w.NotFoundPage, } } func toBucketPolicyOnly(b *raw.BucketIamConfiguration) BucketPolicyOnly { if b == nil || b.BucketPolicyOnly == nil || !b.BucketPolicyOnly.Enabled { return BucketPolicyOnly{} } lt, err := time.Parse(time.RFC3339, b.BucketPolicyOnly.LockedTime) if err != nil { return BucketPolicyOnly{ Enabled: true, } } return BucketPolicyOnly{ Enabled: true, LockedTime: lt, } } func toUniformBucketLevelAccess(b *raw.BucketIamConfiguration) UniformBucketLevelAccess { if b == nil || b.UniformBucketLevelAccess == nil || !b.UniformBucketLevelAccess.Enabled { return UniformBucketLevelAccess{} } lt, err := time.Parse(time.RFC3339, b.UniformBucketLevelAccess.LockedTime) if err != nil { return UniformBucketLevelAccess{ Enabled: true, } } return UniformBucketLevelAccess{ Enabled: true, LockedTime: lt, } } // Objects returns an iterator over the objects in the bucket that match the Query q. // If q is nil, no filtering is done. // // Note: The returned iterator is not safe for concurrent operations without explicit synchronization. func (b *BucketHandle) Objects(ctx context.Context, q *Query) *ObjectIterator { it := &ObjectIterator{ ctx: ctx, bucket: b, } it.pageInfo, it.nextFunc = iterator.NewPageInfo( it.fetch, func() int { return len(it.items) }, func() interface{} { b := it.items; it.items = nil; return b }) if q != nil { it.query = *q } return it } // An ObjectIterator is an iterator over ObjectAttrs. // // Note: This iterator is not safe for concurrent operations without explicit synchronization. type ObjectIterator struct { ctx context.Context bucket *BucketHandle query Query pageInfo *iterator.PageInfo nextFunc func() error items []*ObjectAttrs } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. // // Note: This method is not safe for concurrent operations without explicit synchronization. func (it *ObjectIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if // there are no more results. Once Next returns iterator.Done, all subsequent // calls will return iterator.Done. // // If Query.Delimiter is non-empty, some of the ObjectAttrs returned by Next will // have a non-empty Prefix field, and a zero value for all other fields. These // represent prefixes. // // Note: This method is not safe for concurrent operations without explicit synchronization. func (it *ObjectIterator) Next() (*ObjectAttrs, error) { if err := it.nextFunc(); err != nil { return nil, err } item := it.items[0] it.items = it.items[1:] return item, nil } func (it *ObjectIterator) fetch(pageSize int, pageToken string) (string, error) { req := it.bucket.c.raw.Objects.List(it.bucket.name) setClientHeader(req.Header()) req.Projection("full") req.Delimiter(it.query.Delimiter) req.Prefix(it.query.Prefix) req.Versions(it.query.Versions) if len(it.query.fieldSelection) > 0 { req.Fields("nextPageToken", googleapi.Field(it.query.fieldSelection)) } req.PageToken(pageToken) if it.bucket.userProject != "" { req.UserProject(it.bucket.userProject) } if pageSize > 0 { req.MaxResults(int64(pageSize)) } var resp *raw.Objects var err error err = runWithRetry(it.ctx, func() error { resp, err = req.Context(it.ctx).Do() return err }) if err != nil { if e, ok := err.(*googleapi.Error); ok && e.Code == http.StatusNotFound { err = ErrBucketNotExist } return "", err } for _, item := range resp.Items { it.items = append(it.items, newObject(item)) } for _, prefix := range resp.Prefixes { it.items = append(it.items, &ObjectAttrs{Prefix: prefix}) } return resp.NextPageToken, nil } // Buckets returns an iterator over the buckets in the project. You may // optionally set the iterator's Prefix field to restrict the list to buckets // whose names begin with the prefix. By default, all buckets in the project // are returned. // // Note: The returned iterator is not safe for concurrent operations without explicit synchronization. func (c *Client) Buckets(ctx context.Context, projectID string) *BucketIterator { it := &BucketIterator{ ctx: ctx, client: c, projectID: projectID, } it.pageInfo, it.nextFunc = iterator.NewPageInfo( it.fetch, func() int { return len(it.buckets) }, func() interface{} { b := it.buckets; it.buckets = nil; return b }) return it } // A BucketIterator is an iterator over BucketAttrs. // // Note: This iterator is not safe for concurrent operations without explicit synchronization. type BucketIterator struct { // Prefix restricts the iterator to buckets whose names begin with it. Prefix string ctx context.Context client *Client projectID string buckets []*BucketAttrs pageInfo *iterator.PageInfo nextFunc func() error } // Next returns the next result. Its second return value is iterator.Done if // there are no more results. Once Next returns iterator.Done, all subsequent // calls will return iterator.Done. // // Note: This method is not safe for concurrent operations without explicit synchronization. func (it *BucketIterator) Next() (*BucketAttrs, error) { if err := it.nextFunc(); err != nil { return nil, err } b := it.buckets[0] it.buckets = it.buckets[1:] return b, nil } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. // // Note: This method is not safe for concurrent operations without explicit synchronization. func (it *BucketIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } func (it *BucketIterator) fetch(pageSize int, pageToken string) (token string, err error) { req := it.client.raw.Buckets.List(it.projectID) setClientHeader(req.Header()) req.Projection("full") req.Prefix(it.Prefix) req.PageToken(pageToken) if pageSize > 0 { req.MaxResults(int64(pageSize)) } var resp *raw.Buckets err = runWithRetry(it.ctx, func() error { resp, err = req.Context(it.ctx).Do() return err }) if err != nil { return "", err } for _, item := range resp.Items { b, err := newBucket(item) if err != nil { return "", err } it.buckets = append(it.buckets, b) } return resp.NextPageToken, nil } google-cloud-go-0.49.0/storage/bucket_test.go000066400000000000000000000462451356504100700211120ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package storage import ( "net/http" "reflect" "testing" "time" "cloud.google.com/go/internal/testutil" "github.com/google/go-cmp/cmp" "google.golang.org/api/googleapi" raw "google.golang.org/api/storage/v1" ) func TestBucketAttrsToRawBucket(t *testing.T) { t.Parallel() attrs := &BucketAttrs{ Name: "name", ACL: []ACLRule{{Entity: "bob@example.com", Role: RoleOwner, Domain: "d", Email: "e"}}, DefaultObjectACL: []ACLRule{{Entity: AllUsers, Role: RoleReader, EntityID: "eid", ProjectTeam: &ProjectTeam{ProjectNumber: "17", Team: "t"}}}, Etag: "Zkyw9ACJZUvcYmlFaKGChzhmtnE/dt1zHSfweiWpwzdGsqXwuJZqiD0", Location: "loc", StorageClass: "class", RetentionPolicy: &RetentionPolicy{ RetentionPeriod: 3 * time.Second, }, BucketPolicyOnly: BucketPolicyOnly{Enabled: true}, UniformBucketLevelAccess: UniformBucketLevelAccess{Enabled: true}, VersioningEnabled: false, // should be ignored: MetaGeneration: 39, Created: time.Now(), Labels: map[string]string{"label": "value"}, CORS: []CORS{ { MaxAge: time.Hour, Methods: []string{"GET", "POST"}, Origins: []string{"*"}, ResponseHeaders: []string{"FOO"}, }, }, Encryption: &BucketEncryption{DefaultKMSKeyName: "key"}, Logging: &BucketLogging{LogBucket: "lb", LogObjectPrefix: "p"}, Website: &BucketWebsite{MainPageSuffix: "mps", NotFoundPage: "404"}, Lifecycle: Lifecycle{ Rules: []LifecycleRule{{ Action: LifecycleAction{ Type: SetStorageClassAction, StorageClass: "NEARLINE", }, Condition: LifecycleCondition{ AgeInDays: 10, Liveness: Live, CreatedBefore: time.Date(2017, 1, 2, 3, 4, 5, 6, time.UTC), MatchesStorageClasses: []string{"STANDARD"}, NumNewerVersions: 3, }, }, { Action: LifecycleAction{ Type: DeleteAction, }, Condition: LifecycleCondition{ AgeInDays: 30, Liveness: Live, CreatedBefore: time.Date(2017, 1, 2, 3, 4, 5, 6, time.UTC), MatchesStorageClasses: []string{"NEARLINE"}, NumNewerVersions: 10, }, }, { Action: LifecycleAction{ Type: DeleteAction, }, Condition: LifecycleCondition{ Liveness: Archived, }, }}, }, } got := attrs.toRawBucket() want := &raw.Bucket{ Name: "name", Acl: []*raw.BucketAccessControl{ {Entity: "bob@example.com", Role: "OWNER"}, // other fields ignored on create/update }, DefaultObjectAcl: []*raw.ObjectAccessControl{ {Entity: "allUsers", Role: "READER"}, // other fields ignored on create/update }, Location: "loc", StorageClass: "class", RetentionPolicy: &raw.BucketRetentionPolicy{ RetentionPeriod: 3, }, IamConfiguration: &raw.BucketIamConfiguration{ UniformBucketLevelAccess: &raw.BucketIamConfigurationUniformBucketLevelAccess{ Enabled: true, }, }, Versioning: nil, // ignore VersioningEnabled if false Labels: map[string]string{"label": "value"}, Cors: []*raw.BucketCors{ { MaxAgeSeconds: 3600, Method: []string{"GET", "POST"}, Origin: []string{"*"}, ResponseHeader: []string{"FOO"}, }, }, Encryption: &raw.BucketEncryption{DefaultKmsKeyName: "key"}, Logging: &raw.BucketLogging{LogBucket: "lb", LogObjectPrefix: "p"}, Website: &raw.BucketWebsite{MainPageSuffix: "mps", NotFoundPage: "404"}, Lifecycle: &raw.BucketLifecycle{ Rule: []*raw.BucketLifecycleRule{{ Action: &raw.BucketLifecycleRuleAction{ Type: SetStorageClassAction, StorageClass: "NEARLINE", }, Condition: &raw.BucketLifecycleRuleCondition{ Age: 10, IsLive: googleapi.Bool(true), CreatedBefore: "2017-01-02", MatchesStorageClass: []string{"STANDARD"}, NumNewerVersions: 3, }, }, { Action: &raw.BucketLifecycleRuleAction{ Type: DeleteAction, }, Condition: &raw.BucketLifecycleRuleCondition{ Age: 30, IsLive: googleapi.Bool(true), CreatedBefore: "2017-01-02", MatchesStorageClass: []string{"NEARLINE"}, NumNewerVersions: 10, }, }, { Action: &raw.BucketLifecycleRuleAction{ Type: DeleteAction, }, Condition: &raw.BucketLifecycleRuleCondition{ IsLive: googleapi.Bool(false), }, }}, }, } if msg := testutil.Diff(got, want); msg != "" { t.Error(msg) } attrs.VersioningEnabled = true attrs.RequesterPays = true got = attrs.toRawBucket() want.Versioning = &raw.BucketVersioning{Enabled: true} want.Billing = &raw.BucketBilling{RequesterPays: true} if msg := testutil.Diff(got, want); msg != "" { t.Error(msg) } // Test that setting either of BucketPolicyOnly or UniformBucketLevelAccess // will enable UniformBucketLevelAccess. // Set UBLA.Enabled = true --> UBLA should be set to enabled in the proto. attrs.BucketPolicyOnly = BucketPolicyOnly{} attrs.UniformBucketLevelAccess = UniformBucketLevelAccess{Enabled: true} got = attrs.toRawBucket() want.IamConfiguration = &raw.BucketIamConfiguration{ UniformBucketLevelAccess: &raw.BucketIamConfigurationUniformBucketLevelAccess{ Enabled: true, }, } if msg := testutil.Diff(got, want); msg != "" { t.Errorf(msg) } // Set BucketPolicyOnly.Enabled = true --> UBLA should be set to enabled in // the proto. attrs.BucketPolicyOnly = BucketPolicyOnly{Enabled: true} attrs.UniformBucketLevelAccess = UniformBucketLevelAccess{} got = attrs.toRawBucket() want.IamConfiguration = &raw.BucketIamConfiguration{ UniformBucketLevelAccess: &raw.BucketIamConfigurationUniformBucketLevelAccess{ Enabled: true, }, } if msg := testutil.Diff(got, want); msg != "" { t.Errorf(msg) } // Set both BucketPolicyOnly.Enabled = true and // UniformBucketLevelAccess.Enabled=true --> UBLA should be set to enabled // in the proto. attrs.BucketPolicyOnly = BucketPolicyOnly{Enabled: true} attrs.UniformBucketLevelAccess = UniformBucketLevelAccess{Enabled: true} got = attrs.toRawBucket() want.IamConfiguration = &raw.BucketIamConfiguration{ UniformBucketLevelAccess: &raw.BucketIamConfigurationUniformBucketLevelAccess{ Enabled: true, }, } if msg := testutil.Diff(got, want); msg != "" { t.Errorf(msg) } // Set UBLA.Enabled=false and BucketPolicyOnly.Enabled=false --> UBLA // should be disabled in the proto. attrs.BucketPolicyOnly = BucketPolicyOnly{} attrs.UniformBucketLevelAccess = UniformBucketLevelAccess{} got = attrs.toRawBucket() want.IamConfiguration = nil if msg := testutil.Diff(got, want); msg != "" { t.Errorf(msg) } } func TestBucketAttrsToUpdateToRawBucket(t *testing.T) { t.Parallel() au := &BucketAttrsToUpdate{ VersioningEnabled: false, RequesterPays: false, BucketPolicyOnly: &BucketPolicyOnly{Enabled: false}, UniformBucketLevelAccess: &UniformBucketLevelAccess{Enabled: false}, DefaultEventBasedHold: false, RetentionPolicy: &RetentionPolicy{RetentionPeriod: time.Hour}, Encryption: &BucketEncryption{DefaultKMSKeyName: "key2"}, Lifecycle: &Lifecycle{ Rules: []LifecycleRule{ { Action: LifecycleAction{Type: "Delete"}, Condition: LifecycleCondition{AgeInDays: 30}, }, }, }, Logging: &BucketLogging{LogBucket: "lb", LogObjectPrefix: "p"}, Website: &BucketWebsite{MainPageSuffix: "mps", NotFoundPage: "404"}, } au.SetLabel("a", "foo") au.DeleteLabel("b") au.SetLabel("c", "") got := au.toRawBucket() want := &raw.Bucket{ Versioning: &raw.BucketVersioning{ Enabled: false, ForceSendFields: []string{"Enabled"}, }, Labels: map[string]string{ "a": "foo", "c": "", }, Billing: &raw.BucketBilling{ RequesterPays: false, ForceSendFields: []string{"RequesterPays"}, }, DefaultEventBasedHold: false, RetentionPolicy: &raw.BucketRetentionPolicy{RetentionPeriod: 3600}, IamConfiguration: &raw.BucketIamConfiguration{ UniformBucketLevelAccess: &raw.BucketIamConfigurationUniformBucketLevelAccess{ Enabled: false, ForceSendFields: []string{"Enabled"}, }, }, Encryption: &raw.BucketEncryption{DefaultKmsKeyName: "key2"}, NullFields: []string{"Labels.b"}, Lifecycle: &raw.BucketLifecycle{ Rule: []*raw.BucketLifecycleRule{ { Action: &raw.BucketLifecycleRuleAction{Type: "Delete"}, Condition: &raw.BucketLifecycleRuleCondition{Age: 30}, }, }, }, Logging: &raw.BucketLogging{LogBucket: "lb", LogObjectPrefix: "p"}, Website: &raw.BucketWebsite{MainPageSuffix: "mps", NotFoundPage: "404"}, ForceSendFields: []string{"DefaultEventBasedHold"}, } if msg := testutil.Diff(got, want); msg != "" { t.Error(msg) } var au2 BucketAttrsToUpdate au2.DeleteLabel("b") got = au2.toRawBucket() want = &raw.Bucket{ Labels: map[string]string{}, ForceSendFields: []string{"Labels"}, NullFields: []string{"Labels.b"}, } if msg := testutil.Diff(got, want); msg != "" { t.Error(msg) } // Test nulls. au3 := &BucketAttrsToUpdate{ RetentionPolicy: &RetentionPolicy{}, Encryption: &BucketEncryption{}, Logging: &BucketLogging{}, Website: &BucketWebsite{}, } got = au3.toRawBucket() want = &raw.Bucket{ NullFields: []string{"RetentionPolicy", "Encryption", "Logging", "Website"}, } if msg := testutil.Diff(got, want); msg != "" { t.Error(msg) } // Test that setting either of BucketPolicyOnly or UniformBucketLevelAccess // will enable UniformBucketLevelAccess. // Set UBLA.Enabled = true --> UBLA should be set to enabled in the proto. au4 := &BucketAttrsToUpdate{ UniformBucketLevelAccess: &UniformBucketLevelAccess{Enabled: true}, } got = au4.toRawBucket() want = &raw.Bucket{ IamConfiguration: &raw.BucketIamConfiguration{ UniformBucketLevelAccess: &raw.BucketIamConfigurationUniformBucketLevelAccess{ Enabled: true, ForceSendFields: []string{"Enabled"}, }, }, } if msg := testutil.Diff(got, want); msg != "" { t.Errorf(msg) } // Set BucketPolicyOnly.Enabled = true --> UBLA should be set to enabled in // the proto. au5 := &BucketAttrsToUpdate{ BucketPolicyOnly: &BucketPolicyOnly{Enabled: true}, } got = au5.toRawBucket() want = &raw.Bucket{ IamConfiguration: &raw.BucketIamConfiguration{ UniformBucketLevelAccess: &raw.BucketIamConfigurationUniformBucketLevelAccess{ Enabled: true, ForceSendFields: []string{"Enabled"}, }, }, } if msg := testutil.Diff(got, want); msg != "" { t.Errorf(msg) } // Set both BucketPolicyOnly.Enabled = true and // UniformBucketLevelAccess.Enabled=true --> UBLA should be set to enabled // in the proto. au6 := &BucketAttrsToUpdate{ BucketPolicyOnly: &BucketPolicyOnly{Enabled: true}, UniformBucketLevelAccess: &UniformBucketLevelAccess{Enabled: true}, } got = au6.toRawBucket() want = &raw.Bucket{ IamConfiguration: &raw.BucketIamConfiguration{ UniformBucketLevelAccess: &raw.BucketIamConfigurationUniformBucketLevelAccess{ Enabled: true, ForceSendFields: []string{"Enabled"}, }, }, } if msg := testutil.Diff(got, want); msg != "" { t.Errorf(msg) } // Set UBLA.Enabled=false and BucketPolicyOnly.Enabled=false --> UBLA // should be disabled in the proto. au7 := &BucketAttrsToUpdate{ BucketPolicyOnly: &BucketPolicyOnly{Enabled: false}, UniformBucketLevelAccess: &UniformBucketLevelAccess{Enabled: false}, } got = au7.toRawBucket() want = &raw.Bucket{ IamConfiguration: &raw.BucketIamConfiguration{ UniformBucketLevelAccess: &raw.BucketIamConfigurationUniformBucketLevelAccess{ Enabled: false, ForceSendFields: []string{"Enabled"}, }, }, } if msg := testutil.Diff(got, want); msg != "" { t.Errorf(msg) } // UBLA.Enabled will have precedence above BucketPolicyOnly.Enabled if both // are set with different values. au8 := &BucketAttrsToUpdate{ BucketPolicyOnly: &BucketPolicyOnly{Enabled: true}, UniformBucketLevelAccess: &UniformBucketLevelAccess{Enabled: false}, } got = au8.toRawBucket() want = &raw.Bucket{ IamConfiguration: &raw.BucketIamConfiguration{ UniformBucketLevelAccess: &raw.BucketIamConfigurationUniformBucketLevelAccess{ Enabled: false, ForceSendFields: []string{"Enabled"}, }, }, } if msg := testutil.Diff(got, want); msg != "" { t.Errorf(msg) } } func TestCallBuilders(t *testing.T) { rc, err := raw.New(&http.Client{}) if err != nil { t.Fatal(err) } c := &Client{raw: rc} const metagen = 17 b := c.Bucket("name") bm := b.If(BucketConditions{MetagenerationMatch: metagen}).UserProject("p") equal := func(x, y interface{}) bool { return testutil.Equal(x, y, cmp.AllowUnexported( raw.BucketsGetCall{}, raw.BucketsDeleteCall{}, raw.BucketsPatchCall{}, ), cmp.FilterPath(func(p cmp.Path) bool { return p[len(p)-1].Type() == reflect.TypeOf(&raw.Service{}) }, cmp.Ignore()), ) } for i, test := range []struct { callFunc func(*BucketHandle) (interface{}, error) want interface { Header() http.Header } metagenFunc func(interface{}) }{ { func(b *BucketHandle) (interface{}, error) { return b.newGetCall() }, rc.Buckets.Get("name").Projection("full"), func(req interface{}) { req.(*raw.BucketsGetCall).IfMetagenerationMatch(metagen).UserProject("p") }, }, { func(b *BucketHandle) (interface{}, error) { return b.newDeleteCall() }, rc.Buckets.Delete("name"), func(req interface{}) { req.(*raw.BucketsDeleteCall).IfMetagenerationMatch(metagen).UserProject("p") }, }, { func(b *BucketHandle) (interface{}, error) { return b.newPatchCall(&BucketAttrsToUpdate{ VersioningEnabled: false, RequesterPays: false, }) }, rc.Buckets.Patch("name", &raw.Bucket{ Versioning: &raw.BucketVersioning{ Enabled: false, ForceSendFields: []string{"Enabled"}, }, Billing: &raw.BucketBilling{ RequesterPays: false, ForceSendFields: []string{"RequesterPays"}, }, }).Projection("full"), func(req interface{}) { req.(*raw.BucketsPatchCall).IfMetagenerationMatch(metagen).UserProject("p") }, }, } { got, err := test.callFunc(b) if err != nil { t.Fatal(err) } setClientHeader(test.want.Header()) if !equal(got, test.want) { t.Errorf("#%d: got %#v, want %#v", i, got, test.want) } got, err = test.callFunc(bm) if err != nil { t.Fatal(err) } test.metagenFunc(test.want) if !equal(got, test.want) { t.Errorf("#%d:\ngot %#v\nwant %#v", i, got, test.want) } } // Error. bm = b.If(BucketConditions{MetagenerationMatch: 1, MetagenerationNotMatch: 2}) if _, err := bm.newGetCall(); err == nil { t.Errorf("got nil, want error") } if _, err := bm.newDeleteCall(); err == nil { t.Errorf("got nil, want error") } if _, err := bm.newPatchCall(&BucketAttrsToUpdate{}); err == nil { t.Errorf("got nil, want error") } } func TestNewBucket(t *testing.T) { labels := map[string]string{"a": "b"} matchClasses := []string{"STANDARD"} aTime := time.Date(2017, 1, 2, 0, 0, 0, 0, time.UTC) rb := &raw.Bucket{ Name: "name", Location: "loc", DefaultEventBasedHold: true, Metageneration: 3, StorageClass: "sc", TimeCreated: "2017-10-23T04:05:06Z", Versioning: &raw.BucketVersioning{Enabled: true}, Labels: labels, Billing: &raw.BucketBilling{RequesterPays: true}, Etag: "Zkyw9ACJZUvcYmlFaKGChzhmtnE/dt1zHSfweiWpwzdGsqXwuJZqiD0", Lifecycle: &raw.BucketLifecycle{ Rule: []*raw.BucketLifecycleRule{{ Action: &raw.BucketLifecycleRuleAction{ Type: "SetStorageClass", StorageClass: "NEARLINE", }, Condition: &raw.BucketLifecycleRuleCondition{ Age: 10, IsLive: googleapi.Bool(true), CreatedBefore: "2017-01-02", MatchesStorageClass: matchClasses, NumNewerVersions: 3, }, }}, }, RetentionPolicy: &raw.BucketRetentionPolicy{ RetentionPeriod: 3, EffectiveTime: aTime.Format(time.RFC3339), }, IamConfiguration: &raw.BucketIamConfiguration{ BucketPolicyOnly: &raw.BucketIamConfigurationBucketPolicyOnly{ Enabled: true, LockedTime: aTime.Format(time.RFC3339), }, UniformBucketLevelAccess: &raw.BucketIamConfigurationUniformBucketLevelAccess{ Enabled: true, LockedTime: aTime.Format(time.RFC3339), }, }, Cors: []*raw.BucketCors{ { MaxAgeSeconds: 3600, Method: []string{"GET", "POST"}, Origin: []string{"*"}, ResponseHeader: []string{"FOO"}, }, }, Acl: []*raw.BucketAccessControl{ {Bucket: "name", Role: "READER", Email: "joe@example.com", Entity: "allUsers"}, }, LocationType: "dual-region", Encryption: &raw.BucketEncryption{DefaultKmsKeyName: "key"}, Logging: &raw.BucketLogging{LogBucket: "lb", LogObjectPrefix: "p"}, Website: &raw.BucketWebsite{MainPageSuffix: "mps", NotFoundPage: "404"}, } want := &BucketAttrs{ Name: "name", Location: "loc", DefaultEventBasedHold: true, MetaGeneration: 3, StorageClass: "sc", Created: time.Date(2017, 10, 23, 4, 5, 6, 0, time.UTC), VersioningEnabled: true, Labels: labels, Etag: "Zkyw9ACJZUvcYmlFaKGChzhmtnE/dt1zHSfweiWpwzdGsqXwuJZqiD0", RequesterPays: true, Lifecycle: Lifecycle{ Rules: []LifecycleRule{ { Action: LifecycleAction{ Type: SetStorageClassAction, StorageClass: "NEARLINE", }, Condition: LifecycleCondition{ AgeInDays: 10, Liveness: Live, CreatedBefore: time.Date(2017, 1, 2, 0, 0, 0, 0, time.UTC), MatchesStorageClasses: matchClasses, NumNewerVersions: 3, }, }, }, }, RetentionPolicy: &RetentionPolicy{ EffectiveTime: aTime, RetentionPeriod: 3 * time.Second, }, BucketPolicyOnly: BucketPolicyOnly{Enabled: true, LockedTime: aTime}, UniformBucketLevelAccess: UniformBucketLevelAccess{Enabled: true, LockedTime: aTime}, CORS: []CORS{ { MaxAge: time.Hour, Methods: []string{"GET", "POST"}, Origins: []string{"*"}, ResponseHeaders: []string{"FOO"}, }, }, Encryption: &BucketEncryption{DefaultKMSKeyName: "key"}, Logging: &BucketLogging{LogBucket: "lb", LogObjectPrefix: "p"}, Website: &BucketWebsite{MainPageSuffix: "mps", NotFoundPage: "404"}, ACL: []ACLRule{{Entity: "allUsers", Role: RoleReader, Email: "joe@example.com"}}, DefaultObjectACL: nil, LocationType: "dual-region", } got, err := newBucket(rb) if err != nil { t.Fatal(err) } if diff := testutil.Diff(got, want); diff != "" { t.Errorf("got=-, want=+:\n%s", diff) } } google-cloud-go-0.49.0/storage/conformance_test.go000066400000000000000000000052741356504100700221240ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package storage import ( "bytes" "encoding/json" "fmt" "io/ioutil" "net/url" "strings" "testing" "time" storage_v1_tests "cloud.google.com/go/storage/internal/test/conformance" "github.com/golang/protobuf/jsonpb" ) func TestSigningV4Conformance(t *testing.T) { oldUTCNow := utcNow defer func() { utcNow = oldUTCNow }() dir := "internal/test/conformance" inBytes, err := ioutil.ReadFile(dir + "/service-account") if err != nil { t.Fatal(err) } serviceAccount := map[string]string{} if err := json.Unmarshal(inBytes, &serviceAccount); err != nil { t.Fatal(err) } googleAccessID := serviceAccount["client_email"] privateKey := serviceAccount["private_key"] files, err := ioutil.ReadDir(dir) if err != nil { t.Fatal(err) } for _, f := range files { if !strings.Contains(f.Name(), ".json") { continue } inBytes, err := ioutil.ReadFile(dir + "/" + f.Name()) if err != nil { t.Fatalf("%s: %v", f.Name(), err) } var testfile storage_v1_tests.TestFile if err := jsonpb.Unmarshal(bytes.NewReader(inBytes), &testfile); err != nil { t.Fatalf("unmarshalling %s: %v", f.Name(), err) } for _, tc := range testfile.SigningV4Tests { t.Run(tc.Description, func(t *testing.T) { utcNow = func() time.Time { return time.Unix(tc.Timestamp.Seconds, 0).UTC() } gotURL, err := SignedURL(tc.Bucket, tc.Object, &SignedURLOptions{ GoogleAccessID: googleAccessID, PrivateKey: []byte(privateKey), Method: tc.Method, Expires: utcNow().Add(time.Duration(tc.Expiration) * time.Second), Scheme: SigningSchemeV4, Headers: headersAsSlice(tc.Headers), }) if err != nil { t.Fatal(err) } wantURL, err := url.Parse(tc.ExpectedUrl) if err != nil { t.Fatal(err) } // Sort the headers. wantURL.RawQuery = wantURL.Query().Encode() if gotURL != wantURL.String() { t.Fatalf("\nwant:\t%s\ngot:\t%s", wantURL.String(), gotURL) } }) } } } func headersAsSlice(m map[string]string) []string { var s []string for k, v := range m { s = append(s, fmt.Sprintf("%s:%s", k, v)) } return s } google-cloud-go-0.49.0/storage/copy.go000066400000000000000000000175761356504100700175550ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package storage import ( "context" "errors" "fmt" "cloud.google.com/go/internal/trace" raw "google.golang.org/api/storage/v1" ) // CopierFrom creates a Copier that can copy src to dst. // You can immediately call Run on the returned Copier, or // you can configure it first. // // For Requester Pays buckets, the user project of dst is billed, unless it is empty, // in which case the user project of src is billed. func (dst *ObjectHandle) CopierFrom(src *ObjectHandle) *Copier { return &Copier{dst: dst, src: src} } // A Copier copies a source object to a destination. type Copier struct { // ObjectAttrs are optional attributes to set on the destination object. // Any attributes must be initialized before any calls on the Copier. Nil // or zero-valued attributes are ignored. ObjectAttrs // RewriteToken can be set before calling Run to resume a copy // operation. After Run returns a non-nil error, RewriteToken will // have been updated to contain the value needed to resume the copy. RewriteToken string // ProgressFunc can be used to monitor the progress of a multi-RPC copy // operation. If ProgressFunc is not nil and copying requires multiple // calls to the underlying service (see // https://cloud.google.com/storage/docs/json_api/v1/objects/rewrite), then // ProgressFunc will be invoked after each call with the number of bytes of // content copied so far and the total size in bytes of the source object. // // ProgressFunc is intended to make upload progress available to the // application. For example, the implementation of ProgressFunc may update // a progress bar in the application's UI, or log the result of // float64(copiedBytes)/float64(totalBytes). // // ProgressFunc should return quickly without blocking. ProgressFunc func(copiedBytes, totalBytes uint64) // The Cloud KMS key, in the form projects/P/locations/L/keyRings/R/cryptoKeys/K, // that will be used to encrypt the object. Overrides the object's KMSKeyName, if // any. // // Providing both a DestinationKMSKeyName and a customer-supplied encryption key // (via ObjectHandle.Key) on the destination object will result in an error when // Run is called. DestinationKMSKeyName string dst, src *ObjectHandle } // Run performs the copy. func (c *Copier) Run(ctx context.Context) (attrs *ObjectAttrs, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Copier.Run") defer func() { trace.EndSpan(ctx, err) }() if err := c.src.validate(); err != nil { return nil, err } if err := c.dst.validate(); err != nil { return nil, err } if c.DestinationKMSKeyName != "" && c.dst.encryptionKey != nil { return nil, errors.New("storage: cannot use DestinationKMSKeyName with a customer-supplied encryption key") } // Convert destination attributes to raw form, omitting the bucket. // If the bucket is included but name or content-type aren't, the service // returns a 400 with "Required" as the only message. Omitting the bucket // does not cause any problems. rawObject := c.ObjectAttrs.toRawObject("") for { res, err := c.callRewrite(ctx, rawObject) if err != nil { return nil, err } if c.ProgressFunc != nil { c.ProgressFunc(uint64(res.TotalBytesRewritten), uint64(res.ObjectSize)) } if res.Done { // Finished successfully. return newObject(res.Resource), nil } } } func (c *Copier) callRewrite(ctx context.Context, rawObj *raw.Object) (*raw.RewriteResponse, error) { call := c.dst.c.raw.Objects.Rewrite(c.src.bucket, c.src.object, c.dst.bucket, c.dst.object, rawObj) call.Context(ctx).Projection("full") if c.RewriteToken != "" { call.RewriteToken(c.RewriteToken) } if c.DestinationKMSKeyName != "" { call.DestinationKmsKeyName(c.DestinationKMSKeyName) } if c.PredefinedACL != "" { call.DestinationPredefinedAcl(c.PredefinedACL) } if err := applyConds("Copy destination", c.dst.gen, c.dst.conds, call); err != nil { return nil, err } if c.dst.userProject != "" { call.UserProject(c.dst.userProject) } else if c.src.userProject != "" { call.UserProject(c.src.userProject) } if err := applySourceConds(c.src.gen, c.src.conds, call); err != nil { return nil, err } if err := setEncryptionHeaders(call.Header(), c.dst.encryptionKey, false); err != nil { return nil, err } if err := setEncryptionHeaders(call.Header(), c.src.encryptionKey, true); err != nil { return nil, err } var res *raw.RewriteResponse var err error setClientHeader(call.Header()) err = runWithRetry(ctx, func() error { res, err = call.Do(); return err }) if err != nil { return nil, err } c.RewriteToken = res.RewriteToken return res, nil } // ComposerFrom creates a Composer that can compose srcs into dst. // You can immediately call Run on the returned Composer, or you can // configure it first. // // The encryption key for the destination object will be used to decrypt all // source objects and encrypt the destination object. It is an error // to specify an encryption key for any of the source objects. func (dst *ObjectHandle) ComposerFrom(srcs ...*ObjectHandle) *Composer { return &Composer{dst: dst, srcs: srcs} } // A Composer composes source objects into a destination object. // // For Requester Pays buckets, the user project of dst is billed. type Composer struct { // ObjectAttrs are optional attributes to set on the destination object. // Any attributes must be initialized before any calls on the Composer. Nil // or zero-valued attributes are ignored. ObjectAttrs dst *ObjectHandle srcs []*ObjectHandle } // Run performs the compose operation. func (c *Composer) Run(ctx context.Context) (attrs *ObjectAttrs, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Composer.Run") defer func() { trace.EndSpan(ctx, err) }() if err := c.dst.validate(); err != nil { return nil, err } if len(c.srcs) == 0 { return nil, errors.New("storage: at least one source object must be specified") } req := &raw.ComposeRequest{} // Compose requires a non-empty Destination, so we always set it, // even if the caller-provided ObjectAttrs is the zero value. req.Destination = c.ObjectAttrs.toRawObject(c.dst.bucket) for _, src := range c.srcs { if err := src.validate(); err != nil { return nil, err } if src.bucket != c.dst.bucket { return nil, fmt.Errorf("storage: all source objects must be in bucket %q, found %q", c.dst.bucket, src.bucket) } if src.encryptionKey != nil { return nil, fmt.Errorf("storage: compose source %s.%s must not have encryption key", src.bucket, src.object) } srcObj := &raw.ComposeRequestSourceObjects{ Name: src.object, } if err := applyConds("ComposeFrom source", src.gen, src.conds, composeSourceObj{srcObj}); err != nil { return nil, err } req.SourceObjects = append(req.SourceObjects, srcObj) } call := c.dst.c.raw.Objects.Compose(c.dst.bucket, c.dst.object, req).Context(ctx) if err := applyConds("ComposeFrom destination", c.dst.gen, c.dst.conds, call); err != nil { return nil, err } if c.dst.userProject != "" { call.UserProject(c.dst.userProject) } if c.PredefinedACL != "" { call.DestinationPredefinedAcl(c.PredefinedACL) } if err := setEncryptionHeaders(call.Header(), c.dst.encryptionKey, false); err != nil { return nil, err } var obj *raw.Object setClientHeader(call.Header()) err = runWithRetry(ctx, func() error { obj, err = call.Do(); return err }) if err != nil { return nil, err } return newObject(obj), nil } google-cloud-go-0.49.0/storage/copy_test.go000066400000000000000000000040731356504100700206000ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package storage import ( "context" "strings" "testing" ) func TestCopyMissingFields(t *testing.T) { // Verify that copying checks for missing fields.a t.Parallel() var tests = []struct { srcBucket, srcName, destBucket, destName string errMsg string }{ { "mybucket", "", "mybucket", "destname", "name is empty", }, { "mybucket", "srcname", "mybucket", "", "name is empty", }, { "", "srcfile", "mybucket", "destname", "name is empty", }, { "mybucket", "srcfile", "", "destname", "name is empty", }, } ctx := context.Background() client := mockClient(t, &mockTransport{}) for i, test := range tests { src := client.Bucket(test.srcBucket).Object(test.srcName) dst := client.Bucket(test.destBucket).Object(test.destName) _, err := dst.CopierFrom(src).Run(ctx) if !strings.Contains(err.Error(), test.errMsg) { t.Errorf("CopyTo test #%v:\ngot err %q\nwant err %q", i, err, test.errMsg) } } } func TestCopyBothEncryptionKeys(t *testing.T) { // Test that using both a customer-supplied key and a KMS key is an error. ctx := context.Background() client := mockClient(t, &mockTransport{}) dest := client.Bucket("b").Object("d").Key(testEncryptionKey) c := dest.CopierFrom(client.Bucket("b").Object("s")) c.DestinationKMSKeyName = "key" if _, err := c.Run(ctx); err == nil { t.Error("got nil, want error") } else if !strings.Contains(err.Error(), "KMS") { t.Errorf(`got %q, want it to contain "KMS"`, err) } } google-cloud-go-0.49.0/storage/doc.go000066400000000000000000000152461356504100700173400ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. /* Package storage provides an easy way to work with Google Cloud Storage. Google Cloud Storage stores data in named objects, which are grouped into buckets. More information about Google Cloud Storage is available at https://cloud.google.com/storage/docs. See https://godoc.org/cloud.google.com/go for authentication, timeouts, connection pooling and similar aspects of this package. All of the methods of this package use exponential backoff to retry calls that fail with certain errors, as described in https://cloud.google.com/storage/docs/exponential-backoff. Retrying continues indefinitely unless the controlling context is canceled or the client is closed. See context.WithTimeout and context.WithCancel. Creating a Client To start working with this package, create a client: ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: Handle error. } The client will use your default application credentials. If you only wish to access public data, you can create an unauthenticated client with client, err := storage.NewClient(ctx, option.WithoutAuthentication()) Buckets A Google Cloud Storage bucket is a collection of objects. To work with a bucket, make a bucket handle: bkt := client.Bucket(bucketName) A handle is a reference to a bucket. You can have a handle even if the bucket doesn't exist yet. To create a bucket in Google Cloud Storage, call Create on the handle: if err := bkt.Create(ctx, projectID, nil); err != nil { // TODO: Handle error. } Note that although buckets are associated with projects, bucket names are global across all projects. Each bucket has associated metadata, represented in this package by BucketAttrs. The third argument to BucketHandle.Create allows you to set the initial BucketAttrs of a bucket. To retrieve a bucket's attributes, use Attrs: attrs, err := bkt.Attrs(ctx) if err != nil { // TODO: Handle error. } fmt.Printf("bucket %s, created at %s, is located in %s with storage class %s\n", attrs.Name, attrs.Created, attrs.Location, attrs.StorageClass) Objects An object holds arbitrary data as a sequence of bytes, like a file. You refer to objects using a handle, just as with buckets, but unlike buckets you don't explicitly create an object. Instead, the first time you write to an object it will be created. You can use the standard Go io.Reader and io.Writer interfaces to read and write object data: obj := bkt.Object("data") // Write something to obj. // w implements io.Writer. w := obj.NewWriter(ctx) // Write some text to obj. This will either create the object or overwrite whatever is there already. if _, err := fmt.Fprintf(w, "This object contains text.\n"); err != nil { // TODO: Handle error. } // Close, just like writing a file. if err := w.Close(); err != nil { // TODO: Handle error. } // Read it back. r, err := obj.NewReader(ctx) if err != nil { // TODO: Handle error. } defer r.Close() if _, err := io.Copy(os.Stdout, r); err != nil { // TODO: Handle error. } // Prints "This object contains text." Objects also have attributes, which you can fetch with Attrs: objAttrs, err := obj.Attrs(ctx) if err != nil { // TODO: Handle error. } fmt.Printf("object %s has size %d and can be read using %s\n", objAttrs.Name, objAttrs.Size, objAttrs.MediaLink) Listing objects Listing objects in a bucket is done with the Bucket.Objects method: query := &storage.Query{Prefix: ""} var names []string it := bkt.Objects(ctx, query) for { attrs, err := it.Next() if err == iterator.Done { break } if err != nil { log.Fatal(err) } names = append(names, attrs.Name) } If only a subset of object attributes is needed when listing, specifying this subset using Query.SetAttrSelection may speed up the listing process: query := &storage.Query{Prefix: ""} query.SetAttrSelection([]string{"Name"}) // ... as before ACLs Both objects and buckets have ACLs (Access Control Lists). An ACL is a list of ACLRules, each of which specifies the role of a user, group or project. ACLs are suitable for fine-grained control, but you may prefer using IAM to control access at the project level (see https://cloud.google.com/storage/docs/access-control/iam). To list the ACLs of a bucket or object, obtain an ACLHandle and call its List method: acls, err := obj.ACL().List(ctx) if err != nil { // TODO: Handle error. } for _, rule := range acls { fmt.Printf("%s has role %s\n", rule.Entity, rule.Role) } You can also set and delete ACLs. Conditions Every object has a generation and a metageneration. The generation changes whenever the content changes, and the metageneration changes whenever the metadata changes. Conditions let you check these values before an operation; the operation only executes if the conditions match. You can use conditions to prevent race conditions in read-modify-write operations. For example, say you've read an object's metadata into objAttrs. Now you want to write to that object, but only if its contents haven't changed since you read it. Here is how to express that: w = obj.If(storage.Conditions{GenerationMatch: objAttrs.Generation}).NewWriter(ctx) // Proceed with writing as above. Signed URLs You can obtain a URL that lets anyone read or write an object for a limited time. You don't need to create a client to do this. See the documentation of SignedURL for details. url, err := storage.SignedURL(bucketName, "shared-object", opts) if err != nil { // TODO: Handle error. } fmt.Println(url) Errors Errors returned by this client are often of the type [`googleapi.Error`](https://godoc.org/google.golang.org/api/googleapi#Error). These errors can be introspected for more information by type asserting to the richer `googleapi.Error` type. For example: if e, ok := err.(*googleapi.Error); ok { if e.Code == 409 { ... } } */ package storage // import "cloud.google.com/go/storage" google-cloud-go-0.49.0/storage/example_test.go000066400000000000000000000511361356504100700212630ustar00rootroot00000000000000// Copyright 2014 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package storage_test import ( "context" "fmt" "hash/crc32" "io" "io/ioutil" "log" "os" "time" "cloud.google.com/go/storage" "google.golang.org/api/iterator" "google.golang.org/api/option" ) func ExampleNewClient() { ctx := context.Background() // Use Google Application Default Credentials to authorize and authenticate the client. // More information about Application Default Credentials and how to enable is at // https://developers.google.com/identity/protocols/application-default-credentials. client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } // Use the client. // Close the client when finished. if err := client.Close(); err != nil { // TODO: handle error. } } // This example shows how to create an unauthenticated client, which // can be used to access public data. func ExampleNewClient_unauthenticated() { ctx := context.Background() client, err := storage.NewClient(ctx, option.WithoutAuthentication()) if err != nil { // TODO: handle error. } // Use the client. // Close the client when finished. if err := client.Close(); err != nil { // TODO: handle error. } } func ExampleBucketHandle_Create() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } if err := client.Bucket("my-bucket").Create(ctx, "my-project", nil); err != nil { // TODO: handle error. } } func ExampleBucketHandle_Delete() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } if err := client.Bucket("my-bucket").Delete(ctx); err != nil { // TODO: handle error. } } func ExampleBucketHandle_Attrs() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } attrs, err := client.Bucket("my-bucket").Attrs(ctx) if err != nil { // TODO: handle error. } fmt.Println(attrs) } func ExampleBucketHandle_Update() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } // Enable versioning in the bucket, regardless of its previous value. attrs, err := client.Bucket("my-bucket").Update(ctx, storage.BucketAttrsToUpdate{VersioningEnabled: true}) if err != nil { // TODO: handle error. } fmt.Println(attrs) } // If your update is based on the bucket's previous attributes, match the // metageneration number to make sure the bucket hasn't changed since you read it. func ExampleBucketHandle_Update_readModifyWrite() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } b := client.Bucket("my-bucket") attrs, err := b.Attrs(ctx) if err != nil { // TODO: handle error. } var au storage.BucketAttrsToUpdate au.SetLabel("lab", attrs.Labels["lab"]+"-more") if attrs.Labels["delete-me"] == "yes" { au.DeleteLabel("delete-me") } attrs, err = b. If(storage.BucketConditions{MetagenerationMatch: attrs.MetaGeneration}). Update(ctx, au) if err != nil { // TODO: handle error. } fmt.Println(attrs) } func ExampleClient_Buckets() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } it := client.Buckets(ctx, "my-bucket") _ = it // TODO: iterate using Next or iterator.Pager. } func ExampleBucketIterator_Next() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } it := client.Buckets(ctx, "my-project") for { bucketAttrs, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } fmt.Println(bucketAttrs) } } func ExampleBucketHandle_Objects() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } it := client.Bucket("my-bucket").Objects(ctx, nil) _ = it // TODO: iterate using Next or iterator.Pager. } func ExampleBucketHandle_AddNotification() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } b := client.Bucket("my-bucket") n, err := b.AddNotification(ctx, &storage.Notification{ TopicProjectID: "my-project", TopicID: "my-topic", PayloadFormat: storage.JSONPayload, }) if err != nil { // TODO: handle error. } fmt.Println(n.ID) } func ExampleBucketHandle_LockRetentionPolicy() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } b := client.Bucket("my-bucket") attrs, err := b.Attrs(ctx) if err != nil { // TODO: handle error. } // Note that locking the bucket without first attaching a RetentionPolicy // that's at least 1 day is a no-op err = b.If(storage.BucketConditions{MetagenerationMatch: attrs.MetaGeneration}).LockRetentionPolicy(ctx) if err != nil { // TODO: handle err } } func ExampleBucketHandle_Notifications() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } b := client.Bucket("my-bucket") ns, err := b.Notifications(ctx) if err != nil { // TODO: handle error. } for id, n := range ns { fmt.Printf("%s: %+v\n", id, n) } } var notificationID string func ExampleBucketHandle_DeleteNotification() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } b := client.Bucket("my-bucket") // TODO: Obtain notificationID from BucketHandle.AddNotification // or BucketHandle.Notifications. err = b.DeleteNotification(ctx, notificationID) if err != nil { // TODO: handle error. } } func ExampleObjectIterator_Next() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } it := client.Bucket("my-bucket").Objects(ctx, nil) for { objAttrs, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } fmt.Println(objAttrs) } } func ExampleSignedURL() { pkey, err := ioutil.ReadFile("my-private-key.pem") if err != nil { // TODO: handle error. } url, err := storage.SignedURL("my-bucket", "my-object", &storage.SignedURLOptions{ GoogleAccessID: "xxx@developer.gserviceaccount.com", PrivateKey: pkey, Method: "GET", Expires: time.Now().Add(48 * time.Hour), }) if err != nil { // TODO: handle error. } fmt.Println(url) } func ExampleObjectHandle_Attrs() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } objAttrs, err := client.Bucket("my-bucket").Object("my-object").Attrs(ctx) if err != nil { // TODO: handle error. } fmt.Println(objAttrs) } func ExampleObjectHandle_Attrs_withConditions() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } obj := client.Bucket("my-bucket").Object("my-object") // Read the object. objAttrs1, err := obj.Attrs(ctx) if err != nil { // TODO: handle error. } // Do something else for a while. time.Sleep(5 * time.Minute) // Now read the same contents, even if the object has been written since the last read. objAttrs2, err := obj.Generation(objAttrs1.Generation).Attrs(ctx) if err != nil { // TODO: handle error. } fmt.Println(objAttrs1, objAttrs2) } func ExampleObjectHandle_Update() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } // Change only the content type of the object. objAttrs, err := client.Bucket("my-bucket").Object("my-object").Update(ctx, storage.ObjectAttrsToUpdate{ ContentType: "text/html", ContentDisposition: "", // delete ContentDisposition }) if err != nil { // TODO: handle error. } fmt.Println(objAttrs) } func ExampleObjectHandle_NewReader() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } rc, err := client.Bucket("my-bucket").Object("my-object").NewReader(ctx) if err != nil { // TODO: handle error. } slurp, err := ioutil.ReadAll(rc) rc.Close() if err != nil { // TODO: handle error. } fmt.Println("file contents:", slurp) } func ExampleObjectHandle_NewRangeReader() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } // Read only the first 64K. rc, err := client.Bucket("bucketname").Object("filename1").NewRangeReader(ctx, 0, 64*1024) if err != nil { // TODO: handle error. } defer rc.Close() slurp, err := ioutil.ReadAll(rc) if err != nil { // TODO: handle error. } fmt.Printf("first 64K of file contents:\n%s\n", slurp) } func ExampleObjectHandle_NewRangeReader_lastNBytes() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } // Read only the last 10 bytes until the end of the file. rc, err := client.Bucket("bucketname").Object("filename1").NewRangeReader(ctx, -10, -1) if err != nil { // TODO: handle error. } defer rc.Close() slurp, err := ioutil.ReadAll(rc) if err != nil { // TODO: handle error. } fmt.Printf("Last 10 bytes from the end of the file:\n%s\n", slurp) } func ExampleObjectHandle_NewRangeReader_untilEnd() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } // Read from the 101st byte until the end of the file. rc, err := client.Bucket("bucketname").Object("filename1").NewRangeReader(ctx, 100, -1) if err != nil { // TODO: handle error. } defer rc.Close() slurp, err := ioutil.ReadAll(rc) if err != nil { // TODO: handle error. } fmt.Printf("From 101st byte until the end:\n%s\n", slurp) } func ExampleObjectHandle_NewWriter() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } wc := client.Bucket("bucketname").Object("filename1").NewWriter(ctx) _ = wc // TODO: Use the Writer. } func ExampleWriter_Write() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } wc := client.Bucket("bucketname").Object("filename1").NewWriter(ctx) wc.ContentType = "text/plain" wc.ACL = []storage.ACLRule{{Entity: storage.AllUsers, Role: storage.RoleReader}} if _, err := wc.Write([]byte("hello world")); err != nil { // TODO: handle error. // Note that Write may return nil in some error situations, // so always check the error from Close. } if err := wc.Close(); err != nil { // TODO: handle error. } fmt.Println("updated object:", wc.Attrs()) } // To limit the time to write an object (or do anything else // that takes a context), use context.WithTimeout. func ExampleWriter_Write_timeout() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } tctx, cancel := context.WithTimeout(ctx, 30*time.Second) defer cancel() // Cancel when done, whether we time out or not. wc := client.Bucket("bucketname").Object("filename1").NewWriter(tctx) wc.ContentType = "text/plain" wc.ACL = []storage.ACLRule{{Entity: storage.AllUsers, Role: storage.RoleReader}} if _, err := wc.Write([]byte("hello world")); err != nil { // TODO: handle error. // Note that Write may return nil in some error situations, // so always check the error from Close. } if err := wc.Close(); err != nil { // TODO: handle error. } fmt.Println("updated object:", wc.Attrs()) } // To make sure the data you write is uncorrupted, use an MD5 or CRC32c // checksum. This example illustrates CRC32c. func ExampleWriter_Write_checksum() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } data := []byte("verify me") wc := client.Bucket("bucketname").Object("filename1").NewWriter(ctx) wc.CRC32C = crc32.Checksum(data, crc32.MakeTable(crc32.Castagnoli)) wc.SendCRC32C = true if _, err := wc.Write([]byte("hello world")); err != nil { // TODO: handle error. // Note that Write may return nil in some error situations, // so always check the error from Close. } if err := wc.Close(); err != nil { // TODO: handle error. } fmt.Println("updated object:", wc.Attrs()) } func ExampleObjectHandle_Delete() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } // To delete multiple objects in a bucket, list them with an // ObjectIterator, then Delete them. // If you are using this package on the App Engine Flex runtime, // you can init a bucket client with your app's default bucket name. // See http://godoc.org/google.golang.org/appengine/file#DefaultBucketName. bucket := client.Bucket("my-bucket") it := bucket.Objects(ctx, nil) for { objAttrs, err := it.Next() if err != nil && err != iterator.Done { // TODO: Handle error. } if err == iterator.Done { break } if err := bucket.Object(objAttrs.Name).Delete(ctx); err != nil { // TODO: Handle error. } } fmt.Println("deleted all object items in the bucket specified.") } func ExampleACLHandle_Delete() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } // No longer grant access to the bucket to everyone on the Internet. if err := client.Bucket("my-bucket").ACL().Delete(ctx, storage.AllUsers); err != nil { // TODO: handle error. } } func ExampleACLHandle_Set() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } // Let any authenticated user read my-bucket/my-object. obj := client.Bucket("my-bucket").Object("my-object") if err := obj.ACL().Set(ctx, storage.AllAuthenticatedUsers, storage.RoleReader); err != nil { // TODO: handle error. } } func ExampleACLHandle_List() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } // List the default object ACLs for my-bucket. aclRules, err := client.Bucket("my-bucket").DefaultObjectACL().List(ctx) if err != nil { // TODO: handle error. } fmt.Println(aclRules) } func ExampleCopier_Run() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } src := client.Bucket("bucketname").Object("file1") dst := client.Bucket("another-bucketname").Object("file2") // Copy content and modify metadata. copier := dst.CopierFrom(src) copier.ContentType = "text/plain" attrs, err := copier.Run(ctx) if err != nil { // TODO: Handle error, possibly resuming with copier.RewriteToken. } fmt.Println(attrs) // Just copy content. attrs, err = dst.CopierFrom(src).Run(ctx) if err != nil { // TODO: Handle error. No way to resume. } fmt.Println(attrs) } func ExampleCopier_Run_progress() { // Display progress across multiple rewrite RPCs. ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } src := client.Bucket("bucketname").Object("file1") dst := client.Bucket("another-bucketname").Object("file2") copier := dst.CopierFrom(src) copier.ProgressFunc = func(copiedBytes, totalBytes uint64) { log.Printf("copy %.1f%% done", float64(copiedBytes)/float64(totalBytes)*100) } if _, err := copier.Run(ctx); err != nil { // TODO: handle error. } } var key1, key2 []byte func ExampleObjectHandle_CopierFrom_rotateEncryptionKeys() { // To rotate the encryption key on an object, copy it onto itself. ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } obj := client.Bucket("bucketname").Object("obj") // Assume obj is encrypted with key1, and we want to change to key2. _, err = obj.Key(key2).CopierFrom(obj.Key(key1)).Run(ctx) if err != nil { // TODO: handle error. } } func ExampleComposer_Run() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } bkt := client.Bucket("bucketname") src1 := bkt.Object("o1") src2 := bkt.Object("o2") dst := bkt.Object("o3") // Compose and modify metadata. c := dst.ComposerFrom(src1, src2) c.ContentType = "text/plain" attrs, err := c.Run(ctx) if err != nil { // TODO: Handle error. } fmt.Println(attrs) // Just compose. attrs, err = dst.ComposerFrom(src1, src2).Run(ctx) if err != nil { // TODO: Handle error. } fmt.Println(attrs) } var gen int64 func ExampleObjectHandle_Generation() { // Read an object's contents from generation gen, regardless of the // current generation of the object. ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } obj := client.Bucket("my-bucket").Object("my-object") rc, err := obj.Generation(gen).NewReader(ctx) if err != nil { // TODO: handle error. } defer rc.Close() if _, err := io.Copy(os.Stdout, rc); err != nil { // TODO: handle error. } } func ExampleObjectHandle_If() { // Read from an object only if the current generation is gen. ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } obj := client.Bucket("my-bucket").Object("my-object") rc, err := obj.If(storage.Conditions{GenerationMatch: gen}).NewReader(ctx) if err != nil { // TODO: handle error. } defer rc.Close() if _, err := io.Copy(os.Stdout, rc); err != nil { // TODO: handle error. } } var secretKey []byte func ExampleObjectHandle_Key() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } obj := client.Bucket("my-bucket").Object("my-object") // Encrypt the object's contents. w := obj.Key(secretKey).NewWriter(ctx) if _, err := w.Write([]byte("top secret")); err != nil { // TODO: handle error. } if err := w.Close(); err != nil { // TODO: handle error. } } func ExampleClient_CreateHMACKey() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } hkey, err := client.CreateHMACKey(ctx, "project-id", "service-account-email") if err != nil { // TODO: handle error. } _ = hkey // TODO: Use the HMAC Key. } func ExampleHMACKeyHandle_Delete() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } hkh := client.HMACKeyHandle("project-id", "access-key-id") // Make sure that the HMACKey being deleted has a status of inactive. if err := hkh.Delete(ctx); err != nil { // TODO: handle error. } } func ExampleHMACKeyHandle_Get() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } hkh := client.HMACKeyHandle("project-id", "access-key-id") hkey, err := hkh.Get(ctx) if err != nil { // TODO: handle error. } _ = hkey // TODO: Use the HMAC Key. } func ExampleHMACKeyHandle_Update() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } hkh := client.HMACKeyHandle("project-id", "access-key-id") ukey, err := hkh.Update(ctx, storage.HMACKeyAttrsToUpdate{ State: storage.Inactive, }) if err != nil { // TODO: handle error. } _ = ukey // TODO: Use the HMAC Key. } func ExampleClient_ListHMACKeys() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } iter := client.ListHMACKeys(ctx, "project-id") for { key, err := iter.Next() if err == iterator.Done { break } if err != nil { // TODO: handle error. } _ = key // TODO: Use the key. } } func ExampleClient_ListHMACKeys_showDeletedKeys() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } iter := client.ListHMACKeys(ctx, "project-id", storage.ShowDeletedHMACKeys()) for { key, err := iter.Next() if err == iterator.Done { break } if err != nil { // TODO: handle error. } _ = key // TODO: Use the key. } } func ExampleClient_ListHMACKeys_forServiceAccountEmail() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { // TODO: handle error. } iter := client.ListHMACKeys(ctx, "project-id", storage.ForHMACKeyServiceAccountEmail("service@account.email")) for { key, err := iter.Next() if err == iterator.Done { break } if err != nil { // TODO: handle error. } _ = key // TODO: Use the key. } } google-cloud-go-0.49.0/storage/go.mod000066400000000000000000000010761356504100700173460ustar00rootroot00000000000000module cloud.google.com/go/storage go 1.11 require ( cloud.google.com/go v0.46.3 github.com/golang/protobuf v1.3.2 github.com/google/go-cmp v0.3.0 github.com/googleapis/gax-go/v2 v2.0.5 golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136 // indirect golang.org/x/lint v0.0.0-20190930215403-16217165b5de // indirect golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2 // indirect google.golang.org/api v0.14.0 google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9 google.golang.org/grpc v1.21.1 ) google-cloud-go-0.49.0/storage/go.sum000066400000000000000000000406221356504100700173730ustar00rootroot00000000000000cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3 h1:AVXDdKsrtX33oR9fbCMu/+c1o8Ofjq6Ku/MInaLVg5Y= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go/bigquery v1.0.1 h1:hL+ycaJpVE9M7nLoiXb/Pn10ENE2u+oddxbD8uu0ZVU= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/datastore v1.0.0 h1:Kt+gOPPp2LEPWp8CSfxhsM8ik9CcyE/gYu+0r+RnZvM= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/pubsub v1.0.1 h1:W9tAK3E57P75u0XLLR82LZyw8VpAnhmyTOxW9qzmyj8= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024 h1:rBMNdlhTLzJjJSDIjNEXX1Pz3Hmwmz91v+zycvx9PJc= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979 h1:Agxu5KLo8o7Bb634SVDnhIfpTvxmzUwhbYAzBvXt6h4= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136 h1:A1gGSx58LAGVHUUsOf7IiR0u8Xb6W51gRwfDBhkdcaw= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac h1:8R1esu+8QioDxo4E4mX6bFztO+dMTM49DNAaWfO5OeY= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0 h1:HyfiK1WMnHj5FXFXatD+Qs1A/xC2Run6RzeW1SyHxpc= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff h1:On1qIo75ByTwFJ4/W2bIqHcwJ9XAqtSWUs8GwRrIhtc= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2 h1:EtTFh6h4SAKemS+CURDMTDIANuduG5zKEXShyy18bGA= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0 h1:jbyannxz0XFD3zdjgrSUsaJbgpH4eTrkdhRChkHPfO8= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.14.0 h1:uMf5uLi4eQMRrMKhCplNik4U4H8Z6C1br3zOtAa/aDE= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51 h1:Ex1mq5jaJof+kRnYi3SlYJ8KKa9Ao3NHyIT5XJ1gF6U= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9 h1:6XzpBoANz1NqMNfDXzc2QmHmbb1vyMsvRfoP5rM+K1I= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1 h1:j6XxA85m/6txkUCHvzlV5f+HBNl/1r5cZ2A/3IEFOO8= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= google-cloud-go-0.49.0/storage/go110.go000066400000000000000000000017531356504100700174200ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // +build go1.10 package storage import "google.golang.org/api/googleapi" func shouldRetry(err error) bool { switch e := err.(type) { case *googleapi.Error: // Retry on 429 and 5xx, according to // https://cloud.google.com/storage/docs/exponential-backoff. return e.Code == 429 || (e.Code >= 500 && e.Code < 600) case interface{ Temporary() bool }: return e.Temporary() default: return false } } google-cloud-go-0.49.0/storage/go_mod_tidy_hack.go000066400000000000000000000016261356504100700220530ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // This file, and the cloud.google.com/go import, won't actually become part of // the resultant binary. // +build modhack package storage // Necessary for safely adding multi-module repo. See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository import _ "cloud.google.com/go" google-cloud-go-0.49.0/storage/hmac.go000066400000000000000000000310271356504100700174760ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package storage import ( "context" "errors" "fmt" "time" "google.golang.org/api/iterator" raw "google.golang.org/api/storage/v1" ) // HMACState is the state of the HMAC key. // // This type is EXPERIMENTAL and subject to change or removal without notice. type HMACState string const ( // Active is the status for an active key that can be used to sign // requests. Active HMACState = "ACTIVE" // Inactive is the status for an inactive key thus requests signed by // this key will be denied. Inactive HMACState = "INACTIVE" // Deleted is the status for a key that is deleted. // Once in this state the key cannot key cannot be recovered // and does not count towards key limits. Deleted keys will be cleaned // up later. Deleted HMACState = "DELETED" ) // HMACKey is the representation of a Google Cloud Storage HMAC key. // // HMAC keys are used to authenticate signed access to objects. To enable HMAC key // authentication, please visit https://cloud.google.com/storage/docs/migrating. // // This type is EXPERIMENTAL and subject to change or removal without notice. type HMACKey struct { // The HMAC's secret key. Secret string // AccessID is the ID of the HMAC key. AccessID string // Etag is the HTTP/1.1 Entity tag. Etag string // ID is the ID of the HMAC key, including the ProjectID and AccessID. ID string // ProjectID is the ID of the project that owns the // service account to which the key authenticates. ProjectID string // ServiceAccountEmail is the email address // of the key's associated service account. ServiceAccountEmail string // CreatedTime is the creation time of the HMAC key. CreatedTime time.Time // UpdatedTime is the last modification time of the HMAC key metadata. UpdatedTime time.Time // State is the state of the HMAC key. // It can be one of StateActive, StateInactive or StateDeleted. State HMACState } // HMACKeyHandle helps provide access and management for HMAC keys. // // This type is EXPERIMENTAL and subject to change or removal without notice. type HMACKeyHandle struct { projectID string accessID string raw *raw.ProjectsHmacKeysService } // HMACKeyHandle creates a handle that will be used for HMACKey operations. // // This method is EXPERIMENTAL and subject to change or removal without notice. func (c *Client) HMACKeyHandle(projectID, accessID string) *HMACKeyHandle { return &HMACKeyHandle{ projectID: projectID, accessID: accessID, raw: raw.NewProjectsHmacKeysService(c.raw), } } // Get invokes an RPC to retrieve the HMAC key referenced by the // HMACKeyHandle's accessID. // // Options such as UserProjectForHMACKeys can be used to set the // userProject to be billed against for operations. // // This method is EXPERIMENTAL and subject to change or removal without notice. func (hkh *HMACKeyHandle) Get(ctx context.Context, opts ...HMACKeyOption) (*HMACKey, error) { call := hkh.raw.Get(hkh.projectID, hkh.accessID) desc := new(hmacKeyDesc) for _, opt := range opts { opt.withHMACKeyDesc(desc) } if desc.userProjectID != "" { call = call.UserProject(desc.userProjectID) } setClientHeader(call.Header()) var metadata *raw.HmacKeyMetadata var err error err = runWithRetry(ctx, func() error { metadata, err = call.Context(ctx).Do() return err }) if err != nil { return nil, err } hkPb := &raw.HmacKey{ Metadata: metadata, } return pbHmacKeyToHMACKey(hkPb, false) } // Delete invokes an RPC to delete the key referenced by accessID, on Google Cloud Storage. // Only inactive HMAC keys can be deleted. // After deletion, a key cannot be used to authenticate requests. // // This method is EXPERIMENTAL and subject to change or removal without notice. func (hkh *HMACKeyHandle) Delete(ctx context.Context, opts ...HMACKeyOption) error { delCall := hkh.raw.Delete(hkh.projectID, hkh.accessID) desc := new(hmacKeyDesc) for _, opt := range opts { opt.withHMACKeyDesc(desc) } if desc.userProjectID != "" { delCall = delCall.UserProject(desc.userProjectID) } setClientHeader(delCall.Header()) return runWithRetry(ctx, func() error { return delCall.Context(ctx).Do() }) } func pbHmacKeyToHMACKey(pb *raw.HmacKey, updatedTimeCanBeNil bool) (*HMACKey, error) { pbmd := pb.Metadata if pbmd == nil { return nil, errors.New("field Metadata cannot be nil") } createdTime, err := time.Parse(time.RFC3339, pbmd.TimeCreated) if err != nil { return nil, fmt.Errorf("field CreatedTime: %v", err) } updatedTime, err := time.Parse(time.RFC3339, pbmd.Updated) if err != nil && !updatedTimeCanBeNil { return nil, fmt.Errorf("field UpdatedTime: %v", err) } hmk := &HMACKey{ AccessID: pbmd.AccessId, Secret: pb.Secret, Etag: pbmd.Etag, ID: pbmd.Id, State: HMACState(pbmd.State), ProjectID: pbmd.ProjectId, CreatedTime: createdTime, UpdatedTime: updatedTime, ServiceAccountEmail: pbmd.ServiceAccountEmail, } return hmk, nil } // CreateHMACKey invokes an RPC for Google Cloud Storage to create a new HMACKey. // // This method is EXPERIMENTAL and subject to change or removal without notice. func (c *Client) CreateHMACKey(ctx context.Context, projectID, serviceAccountEmail string, opts ...HMACKeyOption) (*HMACKey, error) { if projectID == "" { return nil, errors.New("storage: expecting a non-blank projectID") } if serviceAccountEmail == "" { return nil, errors.New("storage: expecting a non-blank service account email") } svc := raw.NewProjectsHmacKeysService(c.raw) call := svc.Create(projectID, serviceAccountEmail) desc := new(hmacKeyDesc) for _, opt := range opts { opt.withHMACKeyDesc(desc) } if desc.userProjectID != "" { call = call.UserProject(desc.userProjectID) } setClientHeader(call.Header()) var hkPb *raw.HmacKey var err error err = runWithRetry(ctx, func() error { hkPb, err = call.Context(ctx).Do() return err }) if err != nil { return nil, err } return pbHmacKeyToHMACKey(hkPb, true) } // HMACKeyAttrsToUpdate defines the attributes of an HMACKey that will be updated. // // This type is EXPERIMENTAL and subject to change or removal without notice. type HMACKeyAttrsToUpdate struct { // State is required and must be either StateActive or StateInactive. State HMACState // Etag is an optional field and it is the HTTP/1.1 Entity tag. Etag string } // Update mutates the HMACKey referred to by accessID. // // This method is EXPERIMENTAL and subject to change or removal without notice. func (h *HMACKeyHandle) Update(ctx context.Context, au HMACKeyAttrsToUpdate, opts ...HMACKeyOption) (*HMACKey, error) { if au.State != Active && au.State != Inactive { return nil, fmt.Errorf("storage: invalid state %q for update, must be either %q or %q", au.State, Active, Inactive) } call := h.raw.Update(h.projectID, h.accessID, &raw.HmacKeyMetadata{ Etag: au.Etag, State: string(au.State), }) desc := new(hmacKeyDesc) for _, opt := range opts { opt.withHMACKeyDesc(desc) } if desc.userProjectID != "" { call = call.UserProject(desc.userProjectID) } setClientHeader(call.Header()) var metadata *raw.HmacKeyMetadata var err error err = runWithRetry(ctx, func() error { metadata, err = call.Context(ctx).Do() return err }) if err != nil { return nil, err } hkPb := &raw.HmacKey{ Metadata: metadata, } return pbHmacKeyToHMACKey(hkPb, false) } // An HMACKeysIterator is an iterator over HMACKeys. // // Note: This iterator is not safe for concurrent operations without explicit synchronization. // // This type is EXPERIMENTAL and subject to change or removal without notice. type HMACKeysIterator struct { ctx context.Context raw *raw.ProjectsHmacKeysService projectID string hmacKeys []*HMACKey pageInfo *iterator.PageInfo nextFunc func() error index int desc hmacKeyDesc } // ListHMACKeys returns an iterator for listing HMACKeys. // // Note: This iterator is not safe for concurrent operations without explicit synchronization. // // This method is EXPERIMENTAL and subject to change or removal without notice. func (c *Client) ListHMACKeys(ctx context.Context, projectID string, opts ...HMACKeyOption) *HMACKeysIterator { it := &HMACKeysIterator{ ctx: ctx, raw: raw.NewProjectsHmacKeysService(c.raw), projectID: projectID, } for _, opt := range opts { opt.withHMACKeyDesc(&it.desc) } it.pageInfo, it.nextFunc = iterator.NewPageInfo( it.fetch, func() int { return len(it.hmacKeys) - it.index }, func() interface{} { prev := it.hmacKeys it.hmacKeys = it.hmacKeys[:0] it.index = 0 return prev }) return it } // Next returns the next result. Its second return value is iterator.Done if // there are no more results. Once Next returns iterator.Done, all subsequent // calls will return iterator.Done. // // Note: This iterator is not safe for concurrent operations without explicit synchronization. // // This method is EXPERIMENTAL and subject to change or removal without notice. func (it *HMACKeysIterator) Next() (*HMACKey, error) { if err := it.nextFunc(); err != nil { return nil, err } key := it.hmacKeys[it.index] it.index++ return key, nil } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. // // Note: This iterator is not safe for concurrent operations without explicit synchronization. // // This method is EXPERIMENTAL and subject to change or removal without notice. func (it *HMACKeysIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } func (it *HMACKeysIterator) fetch(pageSize int, pageToken string) (token string, err error) { call := it.raw.List(it.projectID) setClientHeader(call.Header()) if pageToken != "" { call = call.PageToken(pageToken) } if it.desc.showDeletedKeys { call = call.ShowDeletedKeys(true) } if it.desc.userProjectID != "" { call = call.UserProject(it.desc.userProjectID) } if it.desc.forServiceAccountEmail != "" { call = call.ServiceAccountEmail(it.desc.forServiceAccountEmail) } if pageSize > 0 { call = call.MaxResults(int64(pageSize)) } ctx := it.ctx var resp *raw.HmacKeysMetadata err = runWithRetry(it.ctx, func() error { resp, err = call.Context(ctx).Do() return err }) if err != nil { return "", err } for _, metadata := range resp.Items { hkPb := &raw.HmacKey{ Metadata: metadata, } hkey, err := pbHmacKeyToHMACKey(hkPb, true) if err != nil { return "", err } it.hmacKeys = append(it.hmacKeys, hkey) } return resp.NextPageToken, nil } type hmacKeyDesc struct { forServiceAccountEmail string showDeletedKeys bool userProjectID string } // HMACKeyOption configures the behavior of HMACKey related methods and actions. // // This interface is EXPERIMENTAL and subject to change or removal without notice. type HMACKeyOption interface { withHMACKeyDesc(*hmacKeyDesc) } type hmacKeyDescFunc func(*hmacKeyDesc) func (hkdf hmacKeyDescFunc) withHMACKeyDesc(hkd *hmacKeyDesc) { hkdf(hkd) } // ForHMACKeyServiceAccountEmail returns HMAC Keys that are // associated with the email address of a service account in the project. // // Only one service account email can be used as a filter, so if multiple // of these options are applied, the last email to be set will be used. // // This option is EXPERIMENTAL and subject to change or removal without notice. func ForHMACKeyServiceAccountEmail(serviceAccountEmail string) HMACKeyOption { return hmacKeyDescFunc(func(hkd *hmacKeyDesc) { hkd.forServiceAccountEmail = serviceAccountEmail }) } // ShowDeletedHMACKeys will also list keys whose state is "DELETED". // // This option is EXPERIMENTAL and subject to change or removal without notice. func ShowDeletedHMACKeys() HMACKeyOption { return hmacKeyDescFunc(func(hkd *hmacKeyDesc) { hkd.showDeletedKeys = true }) } // UserProjectForHMACKeys will bill the request against userProjectID // if userProjectID is non-empty. // // Note: This is a noop right now and only provided for API compatibility. // // This option is EXPERIMENTAL and subject to change or removal without notice. func UserProjectForHMACKeys(userProjectID string) HMACKeyOption { return hmacKeyDescFunc(func(hkd *hmacKeyDesc) { hkd.userProjectID = userProjectID }) } google-cloud-go-0.49.0/storage/hmac_test.go000066400000000000000000000375131356504100700205430ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package storage import ( "context" "fmt" "net/http" "net/url" "strings" "testing" "time" "cloud.google.com/go/internal/testutil" "google.golang.org/api/googleapi" "google.golang.org/api/iterator" ) func TestHMACKeyHandle_GetParsing(t *testing.T) { mt := &mockTransport{} client := mockClient(t, mt) projectID := "hmackey-project-id" ctx := context.Background() tests := []struct { res string want *HMACKey wantErr string }{ { res: fmt.Sprintf(` { "kind": "storage#hmacKeyMetadata", "projectId":%q,"state":"ACTIVE", "timeCreated": "2019-07-06T11:21:58+00:00", "updated": "2019-07-06T11:22:18+00:00" }`, projectID), want: &HMACKey{ State: Active, ProjectID: projectID, UpdatedTime: time.Date(2019, 07, 06, 11, 22, 18, 0, time.UTC), CreatedTime: time.Date(2019, 07, 06, 11, 21, 58, 0, time.UTC), }, }, { res: fmt.Sprintf(` { "kind": "storage#hmacKeyMetadata", "projectId":%q,"state":"ACTIVE", "timeCreated": "2019-07-06T11:21:58+00:00", "updated": "2019-07-06T11:22:18+00:00" }`, projectID), want: &HMACKey{ State: Active, ProjectID: projectID, UpdatedTime: time.Date(2019, 07, 06, 11, 22, 18, 0, time.UTC), CreatedTime: time.Date(2019, 07, 06, 11, 21, 58, 0, time.UTC), }, }, { res: `{}`, // CreatedTime must be formatted in RFC 3339. wantErr: `CreatedTime: parsing time "" as "2006-01-02T15:04:05Z07:00"`, }, { res: `{"timeCreated": "2019-07-foo"}`, // CreatedTime must be formatted in RFC 3339. wantErr: `CreatedTime: parsing time "2019-07-foo" as "2006-01-02T15:04:05Z07:00"`, }, { res: `{ "kind": "storage#hmacKeyMetadata", "state":"INACTIVE", "timeCreated": "2019-07-06T11:21:58+00:00" }`, // UpdatedTime must be formatted in RFC 3339. wantErr: `UpdatedTime: parsing time "" as "2006-01-02T15:04:05Z07:00"`, }, } for i, tt := range tests { mt.addResult(&http.Response{ ProtoMajor: 1, ProtoMinor: 1, ContentLength: int64(len(tt.res)), Status: "OK", StatusCode: 200, Body: bodyReader(tt.res), }, nil) hkh := client.HMACKeyHandle(projectID, "some-access-key-id") got, err := hkh.Get(ctx) if tt.wantErr != "" { if err == nil || !strings.Contains(err.Error(), tt.wantErr) { t.Errorf("#%d: failed to match errors:\ngot: %q\nwant: %q", i, err, tt.wantErr) } if got != nil { t.Errorf("#%d: unexpectedly got a non-nil result: %#v\n", i, got) } continue } if err != nil { t.Errorf("#%d: got an unexpected error: %v", i, err) continue } if diff := testutil.Diff(got, tt.want); diff != "" { t.Errorf("#%d: got - want +\n\n%s", i, diff) } } } func TestHMACKeyHandle_Get_NotFound(t *testing.T) { mt := &mockTransport{} client := mockClient(t, mt) ctx := context.Background() mt.addResult(&http.Response{ ProtoMajor: 2, ProtoMinor: 0, Status: "OK", StatusCode: http.StatusNotFound, Body: bodyReader("Access ID not found in project"), }, nil) hkh := client.HMACKeyHandle("project-id", "some-access-key-id") _, gotErr := hkh.Get(ctx) wantErr := &googleapi.Error{ Body: "Access ID not found in project", Code: http.StatusNotFound, Message: "", } if diff := testutil.Diff(gotErr, wantErr); diff != "" { t.Fatalf("Error mismatch, got - want +\n%s", diff) } } func TestHMACKeyHandle_Delete(t *testing.T) { mt := &mockTransport{} client := mockClient(t, mt) ctx := context.Background() tests := []struct { statusCode int msg string wantErr error }{ { statusCode: http.StatusBadRequest, msg: "Cannot delete keys in 'ACTIVE' state", wantErr: &googleapi.Error{ Code: http.StatusBadRequest, Message: "Cannot delete keys in 'ACTIVE' state", Body: `{"error":{"message":"Cannot delete keys in 'ACTIVE' state"}}`, }, }, { statusCode: http.StatusNotFound, msg: "random message", wantErr: &googleapi.Error{ Code: http.StatusNotFound, Message: "random message", Body: `{"error":{"message":"random message"}}`, }, }, { statusCode: http.StatusNotFound, msg: "Access ID not found in project", wantErr: &googleapi.Error{ Code: http.StatusNotFound, Message: "Access ID not found in project", Body: `{"error":{"message":"Access ID not found in project"}}`, }, }, } for i, tt := range tests { mt.addResult(&http.Response{ ProtoMajor: 2, ProtoMinor: 0, Status: tt.msg, StatusCode: tt.statusCode, Body: bodyReader(fmt.Sprintf(`{"error":{"message":%q}}`, tt.msg)), }, nil) hkh := client.HMACKeyHandle("project", "access-key-id") err := hkh.Delete(ctx) if diff := testutil.Diff(err, tt.wantErr); diff != "" { t.Errorf("#%d: error mismatch got - want +\n%s", i, diff) } } } func TestHMACKeyHandle_Create(t *testing.T) { mt := &mockTransport{} client := mockClient(t, mt) projectID := "hmackey-project-id" serviceAccountEmail := "service-account-email-1" ctx := context.Background() tests := []struct { res string want *HMACKey wantErr string }{ { res: ` { "kind": "storage#hmackey", "secret":"bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ", "metadata": { "projectId":"project-id","state":"ACTIVE", "timeCreated": "2019-07-06T11:21:58+00:00", "updated": "2019-07-06T11:22:18+00:00" } }`, want: &HMACKey{ Secret: "bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ", State: Active, ProjectID: "project-id", UpdatedTime: time.Date(2019, 07, 06, 11, 22, 18, 0, time.UTC), CreatedTime: time.Date(2019, 07, 06, 11, 21, 58, 0, time.UTC), }, }, { res: `{}`, wantErr: "Metadata cannot be nil", }, { res: `{"metadata":{}}`, // CreatedTime must be non-empty and it must formatted in RFC 3339. wantErr: `CreatedTime: parsing time "" as "2006-01-02T15:04:05Z07:00"`, }, { res: `{"metadata":{"timeCreated": "2019-07-foo"}}`, // CreatedTime must be formatted in RFC 3339. wantErr: `CreatedTime: parsing time "2019-07-foo" as "2006-01-02T15:04:05Z07:00"`, }, { res: `{ "kind": "storage#hmackey", "secret":"bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ", "metadata":{ "kind": "storage#hmacKeyMetadata", "state":"ACTIVE", "timeCreated": "2019-07-06T12:11:33+00:00", "projectId": "project-id", "updated": "" } }`, // ONLY during creation is it okay for UpdatedTime to not be set. want: &HMACKey{ Secret: "bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ", State: Active, ProjectID: "project-id", CreatedTime: time.Date(2019, 07, 06, 12, 11, 33, 0, time.UTC), }, }, } for i, tt := range tests { mt.addResult(&http.Response{ ProtoMajor: 1, ProtoMinor: 1, ContentLength: int64(len(tt.res)), Status: "OK", StatusCode: 200, Body: bodyReader(tt.res), }, nil) got, err := client.CreateHMACKey(ctx, projectID, serviceAccountEmail) if tt.wantErr != "" { if err == nil || !strings.Contains(err.Error(), tt.wantErr) { t.Errorf("#%d: failed to match errors:\ngot: %q\nwant: %q", i, err, tt.wantErr) } if got != nil { t.Errorf("#%d: unexpectedly got a non-nil result: %#v\n", i, got) } continue } if err != nil { t.Errorf("#%d: got an unexpected error: %v", i, err) continue } if diff := testutil.Diff(got, tt.want); diff != "" { t.Errorf("#%d: got - want +\n\n%s", i, diff) } } // Lastly ensure that a blank service account will return an error. mt.addResult(&http.Response{ ProtoMajor: 1, ProtoMinor: 1, Status: "OK", StatusCode: 200, Body: bodyReader("{}"), }, nil) hk, err := client.CreateHMACKey(ctx, projectID, "") if err == nil { t.Fatal("Unexpectedly succeeded in creating a key using a blank service account email") } if !strings.Contains(err.Error(), "non-blank service account email") { t.Fatalf("Expected an error about a non-blank service account email: %v", err) } if hk != nil { t.Fatalf("Unexpectedly got back a created HMACKey: %#v", hk) } } func TestHMACKey_UpdateState(t *testing.T) { // This test ensures that updating the state can only // happen with either of Active or Inactive. mt := &mockTransport{} client := mockClient(t, mt) projectID := "hmackey-project-id" ctx := context.Background() hkh := client.HMACKeyHandle(projectID, "some-access-id") // 1. Ensure that invalid states are NOT accepted for an Update. invalidStates := []HMACState{"", Deleted, "active", "inactive", "foo_bar"} for _, invalidState := range invalidStates { t.Run("invalid-"+string(invalidState), func(t *testing.T) { _, err := hkh.Update(ctx, HMACKeyAttrsToUpdate{ State: invalidState, }) if err == nil { t.Fatal("Unexpectedly succeeded") } invalidStateMsg := fmt.Sprintf(`storage: invalid state %q for update, must be either "ACTIVE" or "INACTIVE"`, invalidState) if err.Error() != invalidStateMsg { t.Fatalf("Mismatched error: got: %q\nwant: %q", err, invalidStateMsg) } }) } // 2. Ensure that valid states for Update are accepted. validStates := []HMACState{Active, Inactive} for _, validState := range validStates { t.Run("valid-"+string(validState), func(t *testing.T) { resBody := fmt.Sprintf(`{ "kind": "storage#hmacKeyMetadata", "state":%q, "timeCreated": "2019-07-11T12:11:33+00:00", "projectId": "project-id", "updated": "2019-07-11T12:13:33+00:00" }`, validState) mt.addResult(&http.Response{ ProtoMajor: 1, ProtoMinor: 1, ContentLength: int64(len(resBody)), Status: "OK", StatusCode: 200, Body: bodyReader(resBody), }, nil) hu, err := hkh.Update(ctx, HMACKeyAttrsToUpdate{ State: validState, }) if err != nil { t.Fatalf("Unexpected failure: %v", err) } if hu.State != validState { t.Fatalf("Unexpected updated state %q, expected %q", hu.State, validState) } }) } } func TestHMACKey_ListFull(t *testing.T) { mt := &mockTransport{} client := mockClient(t, mt) projectID := "hmackey-project-id" ctx := context.Background() maxPages := 2 page := 0 mockResponse := func() { defer func() { page++ }() var body string if page >= maxPages { body = `{"kind":"storage#hmacKeysMetadata","items":[]}` } else { offset := page * 2 body = fmt.Sprintf(` { "kind": "storage#hmacKeysMetadata", "items": [{ "accessId": "accessid-%d", "timeCreated": "2019-08-05T12:11:10+00:00", "state": "ACTIVE" }, { "accessId": "accessid-%d", "timeCreated": "2019-08-05T13:12:11+00:00", "state": "INACTIVE" }], "nextPageToken": "pageToken" }`, offset+1, offset+2) } mt.addResult(&http.Response{ ProtoMajor: 2, ProtoMinor: 0, Status: "OK", StatusCode: 200, Body: bodyReader(body), }, nil) } iter := client.ListHMACKeys(ctx, projectID) var gotKeys []*HMACKey for { mockResponse() key, err := iter.Next() if err == iterator.Done { break } if err != nil { t.Fatalf("Unexpected error: %v", err) } gotKeys = append(gotKeys, key) } wantKeys := []*HMACKey{ { AccessID: "accessid-1", CreatedTime: time.Date(2019, time.August, 5, 12, 11, 10, 0, time.UTC), State: Active, }, { AccessID: "accessid-2", CreatedTime: time.Date(2019, time.August, 5, 13, 12, 11, 0, time.UTC), State: Inactive, }, { AccessID: "accessid-3", CreatedTime: time.Date(2019, time.August, 5, 12, 11, 10, 0, time.UTC), State: Active, }, { AccessID: "accessid-4", CreatedTime: time.Date(2019, time.August, 5, 13, 12, 11, 0, time.UTC), State: Inactive, }, } if diff := testutil.Diff(gotKeys, wantKeys); diff != "" { t.Fatalf("Response mismatch: got - want +\n%s", diff) } } func TestHMACKey_List_Options(t *testing.T) { mt := &mockTransport{} client := mockClient(t, mt) projectID := "hmackey-project-id" // Our goal is just to examine the issued HTTP request's URL's // Path and Query to ensure that we have the appropriate paramters. tests := []struct { name string opts []HMACKeyOption wantQuery url.Values }{ { name: "defaults", wantQuery: url.Values{ "alt": {"json"}, "prettyPrint": {"false"}, }, }, { name: "show deleted keys", opts: []HMACKeyOption{ShowDeletedHMACKeys()}, wantQuery: url.Values{"alt": {"json"}, "prettyPrint": {"false"}, "showDeletedKeys": {"true"}}, }, { name: "for service account", opts: []HMACKeyOption{ForHMACKeyServiceAccountEmail("foo@example.org")}, wantQuery: url.Values{ "alt": {"json"}, "prettyPrint": {"false"}, "serviceAccountEmail": {"foo@example.org"}, }, }, { name: "for userProjectID", opts: []HMACKeyOption{UserProjectForHMACKeys("project-x")}, wantQuery: url.Values{ "alt": {"json"}, "prettyPrint": {"false"}, "userProject": {"project-x"}, }, }, { name: "all options", opts: []HMACKeyOption{ ForHMACKeyServiceAccountEmail("foo@example.org"), UserProjectForHMACKeys("project-x"), ShowDeletedHMACKeys(), }, wantQuery: url.Values{ "alt": {"json"}, "prettyPrint": {"false"}, "serviceAccountEmail": {"foo@example.org"}, "showDeletedKeys": {"true"}, "userProject": {"project-x"}, }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { body := `{"kind":"storage#hmacKeysMetadata","items":[]}` mt.addResult(&http.Response{ ProtoMajor: 2, ProtoMinor: 0, ContentLength: int64(len(body)), Status: "OK", StatusCode: 200, Body: bodyReader(body), }, nil) ctx, cancel := context.WithCancel(context.Background()) iter := client.ListHMACKeys(ctx, projectID, tt.opts...) _, _ = iter.Next() cancel() gotQuery := mt.gotReq.URL.Query() if diff := testutil.Diff(gotQuery, tt.wantQuery); diff != "" { t.Errorf("Query mismatch: got - want +\n%s", diff) } }) } } google-cloud-go-0.49.0/storage/iam.go000066400000000000000000000067021356504100700173360ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package storage import ( "context" "cloud.google.com/go/iam" "cloud.google.com/go/internal/trace" raw "google.golang.org/api/storage/v1" iampb "google.golang.org/genproto/googleapis/iam/v1" ) // IAM provides access to IAM access control for the bucket. func (b *BucketHandle) IAM() *iam.Handle { return iam.InternalNewHandleClient(&iamClient{ raw: b.c.raw, userProject: b.userProject, }, b.name) } // iamClient implements the iam.client interface. type iamClient struct { raw *raw.Service userProject string } func (c *iamClient) Get(ctx context.Context, resource string) (p *iampb.Policy, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.IAM.Get") defer func() { trace.EndSpan(ctx, err) }() call := c.raw.Buckets.GetIamPolicy(resource) setClientHeader(call.Header()) if c.userProject != "" { call.UserProject(c.userProject) } var rp *raw.Policy err = runWithRetry(ctx, func() error { rp, err = call.Context(ctx).Do() return err }) if err != nil { return nil, err } return iamFromStoragePolicy(rp), nil } func (c *iamClient) Set(ctx context.Context, resource string, p *iampb.Policy) (err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.IAM.Set") defer func() { trace.EndSpan(ctx, err) }() rp := iamToStoragePolicy(p) call := c.raw.Buckets.SetIamPolicy(resource, rp) setClientHeader(call.Header()) if c.userProject != "" { call.UserProject(c.userProject) } return runWithRetry(ctx, func() error { _, err := call.Context(ctx).Do() return err }) } func (c *iamClient) Test(ctx context.Context, resource string, perms []string) (permissions []string, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.IAM.Test") defer func() { trace.EndSpan(ctx, err) }() call := c.raw.Buckets.TestIamPermissions(resource, perms) setClientHeader(call.Header()) if c.userProject != "" { call.UserProject(c.userProject) } var res *raw.TestIamPermissionsResponse err = runWithRetry(ctx, func() error { res, err = call.Context(ctx).Do() return err }) if err != nil { return nil, err } return res.Permissions, nil } func iamToStoragePolicy(ip *iampb.Policy) *raw.Policy { return &raw.Policy{ Bindings: iamToStorageBindings(ip.Bindings), Etag: string(ip.Etag), } } func iamToStorageBindings(ibs []*iampb.Binding) []*raw.PolicyBindings { var rbs []*raw.PolicyBindings for _, ib := range ibs { rbs = append(rbs, &raw.PolicyBindings{ Role: ib.Role, Members: ib.Members, }) } return rbs } func iamFromStoragePolicy(rp *raw.Policy) *iampb.Policy { return &iampb.Policy{ Bindings: iamFromStorageBindings(rp.Bindings), Etag: []byte(rp.Etag), } } func iamFromStorageBindings(rbs []*raw.PolicyBindings) []*iampb.Binding { var ibs []*iampb.Binding for _, rb := range rbs { ibs = append(ibs, &iampb.Binding{ Role: rb.Role, Members: rb.Members, }) } return ibs } google-cloud-go-0.49.0/storage/integration_test.go000066400000000000000000003003371356504100700221530ustar00rootroot00000000000000// Copyright 2014 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package storage import ( "bytes" "compress/gzip" "context" "crypto/md5" "crypto/sha256" "encoding/base64" "encoding/json" "flag" "fmt" "hash/crc32" "io" "io/ioutil" "log" "math/rand" "net/http" "os" "path/filepath" "runtime" "sort" "strconv" "strings" "testing" "time" "cloud.google.com/go/httpreplay" "cloud.google.com/go/iam" "cloud.google.com/go/internal/testutil" "cloud.google.com/go/internal/uid" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "golang.org/x/oauth2/google" "google.golang.org/api/googleapi" "google.golang.org/api/iterator" itesting "google.golang.org/api/iterator/testing" "google.golang.org/api/option" ) const ( testPrefix = "go-integration-test" replayFilename = "storage.replay" ) var ( record = flag.Bool("record", false, "record RPCs") uidSpace *uid.Space bucketName string // Use our own random number generator to isolate the sequence of random numbers from // other packages. This makes it possible to use HTTP replay and draw the same sequence // of numbers as during recording. rng *rand.Rand newTestClient func(ctx context.Context, opts ...option.ClientOption) (*Client, error) replaying bool testTime time.Time ) func TestMain(m *testing.M) { cleanup := initIntegrationTest() exit := m.Run() if err := cleanup(); err != nil { // Don't fail the test if cleanup fails. log.Printf("Post-test cleanup failed: %v", err) } os.Exit(exit) } // If integration tests will be run, create a unique bucket for them. // Also, set newTestClient to handle record/replay. // Return a cleanup function. func initIntegrationTest() func() error { flag.Parse() // needed for testing.Short() switch { case testing.Short() && *record: log.Fatal("cannot combine -short and -record") return nil case testing.Short() && httpreplay.Supported() && testutil.CanReplay(replayFilename) && testutil.ProjID() != "": // go test -short with a replay file will replay the integration tests, if // the appropriate environment variables have been set. replaying = true httpreplay.DebugHeaders() replayer, err := httpreplay.NewReplayer(replayFilename) if err != nil { log.Fatal(err) } var t time.Time if err := json.Unmarshal(replayer.Initial(), &t); err != nil { log.Fatal(err) } initUIDsAndRand(t) newTestClient = func(ctx context.Context, _ ...option.ClientOption) (*Client, error) { hc, err := replayer.Client(ctx) // no creds needed if err != nil { return nil, err } return NewClient(ctx, option.WithHTTPClient(hc)) } log.Printf("replaying from %s", replayFilename) return func() error { return replayer.Close() } case testing.Short(): // go test -short without a replay file skips the integration tests. if testutil.CanReplay(replayFilename) && testutil.ProjID() != "" { log.Print("replay not supported for Go versions before 1.8") } newTestClient = nil return func() error { return nil } default: // Run integration tests against a real backend. now := time.Now().UTC() initUIDsAndRand(now) var cleanup func() error if *record && httpreplay.Supported() { // Remember the time for replay. nowBytes, err := json.Marshal(now) if err != nil { log.Fatal(err) } recorder, err := httpreplay.NewRecorder(replayFilename, nowBytes) if err != nil { log.Fatalf("could not record: %v", err) } newTestClient = func(ctx context.Context, opts ...option.ClientOption) (*Client, error) { hc, err := recorder.Client(ctx, opts...) if err != nil { return nil, err } return NewClient(ctx, option.WithHTTPClient(hc)) } cleanup = func() error { err1 := cleanupBuckets() err2 := recorder.Close() if err1 != nil { return err1 } return err2 } log.Printf("recording to %s", replayFilename) } else { if *record { log.Print("record not supported for Go versions before 1.8") } newTestClient = NewClient cleanup = cleanupBuckets } ctx := context.Background() client := config(ctx) if client == nil { return func() error { return nil } } defer client.Close() if err := client.Bucket(bucketName).Create(ctx, testutil.ProjID(), nil); err != nil { log.Fatalf("creating bucket %q: %v", bucketName, err) } return cleanup } } func initUIDsAndRand(t time.Time) { uidSpace = uid.NewSpace(testPrefix, &uid.Options{Time: t}) bucketName = uidSpace.New() // Use our own random source, to avoid other parts of the program taking // random numbers from the global source and putting record and replay // out of sync. rng = testutil.NewRand(t) testTime = t } // testConfig returns the Client used to access GCS. testConfig skips // the current test if credentials are not available or when being run // in Short mode. func testConfig(ctx context.Context, t *testing.T) *Client { if testing.Short() && !replaying { t.Skip("Integration tests skipped in short mode") } client := config(ctx) if client == nil { t.Skip("Integration tests skipped. See CONTRIBUTING.md for details") } return client } // config is like testConfig, but it doesn't need a *testing.T. func config(ctx context.Context) *Client { ts := testutil.TokenSource(ctx, ScopeFullControl) if ts == nil { return nil } client, err := newTestClient(ctx, option.WithTokenSource(ts)) if err != nil { log.Fatalf("NewClient: %v", err) } return client } func TestIntegration_BucketMethods(t *testing.T) { ctx := context.Background() client := testConfig(ctx, t) defer client.Close() h := testHelper{t} projectID := testutil.ProjID() newBucketName := uidSpace.New() b := client.Bucket(newBucketName) // Test Create and Delete. h.mustCreate(b, projectID, nil) attrs := h.mustBucketAttrs(b) if got, want := attrs.MetaGeneration, int64(1); got != want { t.Errorf("got metagen %d, want %d", got, want) } if got, want := attrs.StorageClass, "STANDARD"; got != want { t.Errorf("got storage class %q, want %q", got, want) } if attrs.VersioningEnabled { t.Error("got versioning enabled, wanted it disabled") } if attrs.LocationType == "" { t.Error("got an empty LocationType") } h.mustDeleteBucket(b) // Test Create and Delete with attributes. labels := map[string]string{ "l1": "v1", "empty": "", } attrs = &BucketAttrs{ StorageClass: "NEARLINE", VersioningEnabled: true, Labels: labels, Lifecycle: Lifecycle{ Rules: []LifecycleRule{{ Action: LifecycleAction{ Type: SetStorageClassAction, StorageClass: "NEARLINE", }, Condition: LifecycleCondition{ AgeInDays: 10, Liveness: Archived, CreatedBefore: time.Date(2017, 1, 1, 0, 0, 0, 0, time.UTC), MatchesStorageClasses: []string{"STANDARD"}, NumNewerVersions: 3, }, }, { Action: LifecycleAction{ Type: DeleteAction, }, Condition: LifecycleCondition{ AgeInDays: 30, Liveness: Live, CreatedBefore: time.Date(2017, 1, 1, 0, 0, 0, 0, time.UTC), MatchesStorageClasses: []string{"NEARLINE"}, NumNewerVersions: 10, }, }}, }, } h.mustCreate(b, projectID, attrs) attrs = h.mustBucketAttrs(b) if got, want := attrs.MetaGeneration, int64(1); got != want { t.Errorf("got metagen %d, want %d", got, want) } if got, want := attrs.StorageClass, "NEARLINE"; got != want { t.Errorf("got storage class %q, want %q", got, want) } if !attrs.VersioningEnabled { t.Error("got versioning disabled, wanted it enabled") } if got, want := attrs.Labels, labels; !testutil.Equal(got, want) { t.Errorf("labels: got %v, want %v", got, want) } if attrs.LocationType == "" { t.Error("got an empty LocationType") } h.mustDeleteBucket(b) } func TestIntegration_BucketUpdate(t *testing.T) { ctx := context.Background() client := testConfig(ctx, t) defer client.Close() h := testHelper{t} b := client.Bucket(uidSpace.New()) h.mustCreate(b, testutil.ProjID(), nil) defer h.mustDeleteBucket(b) attrs := h.mustBucketAttrs(b) if attrs.VersioningEnabled { t.Fatal("bucket should not have versioning by default") } if len(attrs.Labels) > 0 { t.Fatal("bucket should not have labels initially") } // Using empty BucketAttrsToUpdate should be a no-nop. attrs = h.mustUpdateBucket(b, BucketAttrsToUpdate{}) if attrs.VersioningEnabled { t.Fatal("should not have versioning") } if len(attrs.Labels) > 0 { t.Fatal("should not have labels") } // Turn on versioning, add some labels. ua := BucketAttrsToUpdate{VersioningEnabled: true} ua.SetLabel("l1", "v1") ua.SetLabel("empty", "") attrs = h.mustUpdateBucket(b, ua) if !attrs.VersioningEnabled { t.Fatal("should have versioning now") } wantLabels := map[string]string{ "l1": "v1", "empty": "", } if !testutil.Equal(attrs.Labels, wantLabels) { t.Fatalf("got %v, want %v", attrs.Labels, wantLabels) } // Turn off versioning again; add and remove some more labels. ua = BucketAttrsToUpdate{VersioningEnabled: false} ua.SetLabel("l1", "v2") // update ua.SetLabel("new", "new") // create ua.DeleteLabel("empty") // delete ua.DeleteLabel("absent") // delete non-existent attrs = h.mustUpdateBucket(b, ua) if attrs.VersioningEnabled { t.Fatal("should have versioning off") } wantLabels = map[string]string{ "l1": "v2", "new": "new", } if !testutil.Equal(attrs.Labels, wantLabels) { t.Fatalf("got %v, want %v", attrs.Labels, wantLabels) } // Configure a lifecycle wantLifecycle := Lifecycle{ Rules: []LifecycleRule{ { Action: LifecycleAction{Type: "Delete"}, Condition: LifecycleCondition{AgeInDays: 30}, }, }, } ua = BucketAttrsToUpdate{Lifecycle: &wantLifecycle} attrs = h.mustUpdateBucket(b, ua) if !testutil.Equal(attrs.Lifecycle, wantLifecycle) { t.Fatalf("got %v, want %v", attrs.Lifecycle, wantLifecycle) } } func TestIntegration_BucketPolicyOnly(t *testing.T) { ctx := context.Background() client := testConfig(ctx, t) defer client.Close() h := testHelper{t} bkt := client.Bucket(bucketName) // Insert an object with custom ACL. o := bkt.Object("bucketPolicyOnly") defer func() { if err := o.Delete(ctx); err != nil { log.Printf("failed to delete test object: %v", err) } }() wc := o.NewWriter(ctx) wc.ContentType = "text/plain" h.mustWrite(wc, []byte("test")) a := o.ACL() aclEntity := ACLEntity("user-test@example.com") err := a.Set(ctx, aclEntity, RoleReader) if err != nil { t.Fatalf("set ACL failed: %v", err) } // Enable BucketPolicyOnly. ua := BucketAttrsToUpdate{BucketPolicyOnly: &BucketPolicyOnly{Enabled: true}} attrs := h.mustUpdateBucket(bkt, ua) if got, want := attrs.BucketPolicyOnly.Enabled, true; got != want { t.Fatalf("got %v, want %v", got, want) } if got := attrs.BucketPolicyOnly.LockedTime; got.IsZero() { t.Fatal("got a zero time value, want a populated value") } // Confirm BucketAccessControl returns error. _, err = bkt.ACL().List(ctx) if err == nil { t.Fatal("expected Bucket ACL list to fail") } // Confirm ObjectAccessControl returns error. _, err = o.ACL().List(ctx) if err == nil { t.Fatal("expected Object ACL list to fail") } // Disable BucketPolicyOnly. ua = BucketAttrsToUpdate{BucketPolicyOnly: &BucketPolicyOnly{Enabled: false}} attrs = h.mustUpdateBucket(bkt, ua) if got, want := attrs.BucketPolicyOnly.Enabled, false; got != want { t.Fatalf("got %v, want %v", got, want) } // Check that the object ACLs are the same. // The update to BucketPolicyOnly may be delayed in propagation, so retry // for up to 11 seconds before failing. timeout := time.After(11 * time.Second) var acls []ACLRule for { select { case <-timeout: t.Fatalf("object ACL list failed: %v", err) default: } acls, err = o.ACL().List(ctx) if err == nil { // Check that ACL rules contain custom ACL from above. if !containsACL(acls, aclEntity, RoleReader) { t.Fatalf("expected ACLs %v to include custom ACL entity %v", acls, aclEntity) } break } time.Sleep(200 * time.Millisecond) } } func TestIntegration_UniformBucketLevelAccess(t *testing.T) { t.Skip("https://github.com/googleapis/google-cloud-go/issues/1652") ctx := context.Background() client := testConfig(ctx, t) defer client.Close() h := testHelper{t} bkt := client.Bucket(uidSpace.New()) h.mustCreate(bkt, testutil.ProjID(), nil) defer h.mustDeleteBucket(bkt) // Insert an object with custom ACL. o := bkt.Object("uniformBucketLevelAccess") defer func() { if err := o.Delete(ctx); err != nil { log.Printf("failed to delete test object: %v", err) } }() wc := o.NewWriter(ctx) wc.ContentType = "text/plain" h.mustWrite(wc, []byte("test")) a := o.ACL() aclEntity := ACLEntity("user-test@example.com") err := a.Set(ctx, aclEntity, RoleReader) if err != nil { t.Fatalf("set ACL failed: %v", err) } // Enable UniformBucketLevelAccess. ua := BucketAttrsToUpdate{UniformBucketLevelAccess: &UniformBucketLevelAccess{Enabled: true}} attrs := h.mustUpdateBucket(bkt, ua) if got, want := attrs.UniformBucketLevelAccess.Enabled, true; got != want { t.Fatalf("got %v, want %v", got, want) } if got := attrs.UniformBucketLevelAccess.LockedTime; got.IsZero() { t.Fatal("got a zero time value, want a populated value") } // Confirm BucketAccessControl returns error. _, err = bkt.ACL().List(ctx) if err == nil { t.Fatal("expected Bucket ACL list to fail") } // Confirm ObjectAccessControl returns error. _, err = o.ACL().List(ctx) if err == nil { t.Fatal("expected Object ACL list to fail") } // Disable UniformBucketLevelAccess. ua = BucketAttrsToUpdate{UniformBucketLevelAccess: &UniformBucketLevelAccess{Enabled: false}} attrs = h.mustUpdateBucket(bkt, ua) if got, want := attrs.UniformBucketLevelAccess.Enabled, false; got != want { t.Fatalf("got %v, want %v", got, want) } // Check that the object ACLs are the same. acls, err := o.ACL().List(ctx) if err != nil { t.Fatalf("object ACL list failed: %v", err) } // Check that ACL rules contain custom ACL from above. if !containsACL(acls, aclEntity, RoleReader) { t.Fatalf("expected ACLs %v to include custom ACL entity %v", acls, aclEntity) } } func containsACL(acls []ACLRule, e ACLEntity, r ACLRole) bool { for _, a := range acls { if a.Entity == e && a.Role == r { return true } } return false } func TestIntegration_ConditionalDelete(t *testing.T) { ctx := context.Background() client := testConfig(ctx, t) defer client.Close() h := testHelper{t} o := client.Bucket(bucketName).Object("conddel") wc := o.NewWriter(ctx) wc.ContentType = "text/plain" h.mustWrite(wc, []byte("foo")) gen := wc.Attrs().Generation metaGen := wc.Attrs().Metageneration if err := o.Generation(gen - 1).Delete(ctx); err == nil { t.Fatalf("Unexpected successful delete with Generation") } if err := o.If(Conditions{MetagenerationMatch: metaGen + 1}).Delete(ctx); err == nil { t.Fatalf("Unexpected successful delete with IfMetaGenerationMatch") } if err := o.If(Conditions{MetagenerationNotMatch: metaGen}).Delete(ctx); err == nil { t.Fatalf("Unexpected successful delete with IfMetaGenerationNotMatch") } if err := o.Generation(gen).Delete(ctx); err != nil { t.Fatalf("final delete failed: %v", err) } } func TestIntegration_ObjectsRangeReader(t *testing.T) { ctx := context.Background() client := testConfig(ctx, t) defer client.Close() bkt := client.Bucket(bucketName) objName := uidSpace.New() obj := bkt.Object(objName) w := obj.NewWriter(ctx) contents := []byte("Hello, world this is a range request") if _, err := w.Write(contents); err != nil { t.Fatalf("Failed to write contents: %v", err) } if err := w.Close(); err != nil { t.Fatalf("Failed to close writer: %v", err) } last5s := []struct { name string start int64 length int64 }{ {name: "negative offset", start: -5, length: -1}, {name: "offset with specified length", start: int64(len(contents)) - 5, length: 5}, {name: "offset and read till end", start: int64(len(contents)) - 5, length: -1}, } for _, last5 := range last5s { t.Run(last5.name, func(t *testing.T) { r, err := obj.NewRangeReader(ctx, last5.start, last5.length) if err != nil { t.Fatalf("Failed to make range read: %v", err) } defer r.Close() if got, want := r.Attrs.StartOffset, int64(len(contents))-5; got != want { t.Fatalf("StartOffset mismatch, got %d want %d", got, want) } nr, _ := io.Copy(ioutil.Discard, r) if got, want := nr, int64(5); got != want { t.Fatalf("Body length mismatch, got %d want %d", got, want) } }) } } func TestIntegration_Objects(t *testing.T) { // TODO(jba): Use subtests (Go 1.7). ctx := context.Background() client := testConfig(ctx, t) defer client.Close() // Reset testTime, 'cause object last modification time should be within 5 min // from test (test iteration if -count passed) start time. testTime = time.Now().UTC() newBucketName := uidSpace.New() h := testHelper{t} bkt := client.Bucket(newBucketName) h.mustCreate(bkt, testutil.ProjID(), nil) defer func() { if err := killBucket(ctx, client, newBucketName); err != nil { log.Printf("deleting %q: %v", newBucketName, err) } }() const defaultType = "text/plain" // Populate object names and make a map for their contents. objects := []string{ "obj1", "obj2", "obj/with/slashes", } contents := make(map[string][]byte) // Test Writer. for _, obj := range objects { c := randomContents() if err := writeObject(ctx, bkt.Object(obj), defaultType, c); err != nil { t.Errorf("Write for %v failed with %v", obj, err) } contents[obj] = c } testObjectIterator(t, bkt, objects) testObjectsIterateSelectedAttrs(t, bkt, objects) // Test Reader. for _, obj := range objects { rc, err := bkt.Object(obj).NewReader(ctx) if err != nil { t.Errorf("Can't create a reader for %v, errored with %v", obj, err) continue } if !rc.checkCRC { t.Errorf("%v: not checking CRC", obj) } slurp, err := ioutil.ReadAll(rc) if err != nil { t.Errorf("Can't ReadAll object %v, errored with %v", obj, err) } if got, want := slurp, contents[obj]; !bytes.Equal(got, want) { t.Errorf("Contents (%q) = %q; want %q", obj, got, want) } if got, want := rc.Size(), len(contents[obj]); got != int64(want) { t.Errorf("Size (%q) = %d; want %d", obj, got, want) } if got, want := rc.ContentType(), "text/plain"; got != want { t.Errorf("ContentType (%q) = %q; want %q", obj, got, want) } if got, want := rc.CacheControl(), "public, max-age=60"; got != want { t.Errorf("CacheControl (%q) = %q; want %q", obj, got, want) } // We just wrote these objects, so they should have a recent last-modified time. lm, err := rc.LastModified() // Accept a time within +/- of the test time, to account for natural // variation and the fact that testTime is set at the start of the test run. expectedVariance := 5 * time.Minute if err != nil { t.Errorf("LastModified (%q): got error %v", obj, err) } else if lm.Before(testTime.Add(-expectedVariance)) || lm.After(testTime.Add(expectedVariance)) { t.Errorf("LastModified (%q): got %s, which not the %v from now (%v)", obj, lm, expectedVariance, testTime) } rc.Close() // Check early close. buf := make([]byte, 1) rc, err = bkt.Object(obj).NewReader(ctx) if err != nil { t.Fatalf("%v: %v", obj, err) } _, err = rc.Read(buf) if err != nil { t.Fatalf("%v: %v", obj, err) } if got, want := buf, contents[obj][:1]; !bytes.Equal(got, want) { t.Errorf("Contents[0] (%q) = %q; want %q", obj, got, want) } if err := rc.Close(); err != nil { t.Errorf("%v Close: %v", obj, err) } } obj := objects[0] objlen := int64(len(contents[obj])) // Test Range Reader. for i, r := range []struct { offset, length, want int64 }{ {0, objlen, objlen}, {0, objlen / 2, objlen / 2}, {objlen / 2, objlen, objlen / 2}, {0, 0, 0}, {objlen / 2, 0, 0}, {objlen / 2, -1, objlen / 2}, {0, objlen * 2, objlen}, {-2, -1, 2}, {-objlen, -1, objlen}, {-(objlen / 2), -1, objlen / 2}, } { rc, err := bkt.Object(obj).NewRangeReader(ctx, r.offset, r.length) if err != nil { t.Errorf("%+v: Can't create a range reader for %v, errored with %v", i, obj, err) continue } if rc.Size() != objlen { t.Errorf("%+v: Reader has a content-size of %d, want %d", i, rc.Size(), objlen) } if rc.Remain() != r.want { t.Errorf("%+v: Reader's available bytes reported as %d, want %d", i, rc.Remain(), r.want) } slurp, err := ioutil.ReadAll(rc) if err != nil { t.Errorf("%+v: can't ReadAll object %v, errored with %v", r, obj, err) continue } if len(slurp) != int(r.want) { t.Errorf("%+v: RangeReader (%d, %d): Read %d bytes, wanted %d bytes", i, r.offset, r.length, len(slurp), r.want) continue } switch { case r.offset < 0: // The case of reading the last N bytes. start := objlen + r.offset if got, want := slurp, contents[obj][start:]; !bytes.Equal(got, want) { t.Errorf("RangeReader (%d, %d) = %q; want %q", r.offset, r.length, got, want) } default: if got, want := slurp, contents[obj][r.offset:r.offset+r.want]; !bytes.Equal(got, want) { t.Errorf("RangeReader (%d, %d) = %q; want %q", r.offset, r.length, got, want) } } rc.Close() } objName := objects[0] // Test NewReader googleapi.Error. // Since a 429 or 5xx is hard to cause, we trigger a 416. realLen := len(contents[objName]) _, err := bkt.Object(objName).NewRangeReader(ctx, int64(realLen*2), 10) if err, ok := err.(*googleapi.Error); !ok { t.Error("NewRangeReader did not return a googleapi.Error") } else { if err.Code != 416 { t.Errorf("Code = %d; want %d", err.Code, 416) } if len(err.Header) == 0 { t.Error("Missing googleapi.Error.Header") } if len(err.Body) == 0 { t.Error("Missing googleapi.Error.Body") } } // Test StatObject. o := h.mustObjectAttrs(bkt.Object(objName)) if got, want := o.Name, objName; got != want { t.Errorf("Name (%v) = %q; want %q", objName, got, want) } if got, want := o.ContentType, defaultType; got != want { t.Errorf("ContentType (%v) = %q; want %q", objName, got, want) } created := o.Created // Check that the object is newer than its containing bucket. bAttrs := h.mustBucketAttrs(bkt) if o.Created.Before(bAttrs.Created) { t.Errorf("Object %v is older than its containing bucket, %v", o, bAttrs) } // Test object copy. copyName := "copy-" + objName copyObj, err := bkt.Object(copyName).CopierFrom(bkt.Object(objName)).Run(ctx) if err != nil { t.Errorf("Copier.Run failed with %v", err) } else if !namesEqual(copyObj, newBucketName, copyName) { t.Errorf("Copy object bucket, name: got %q.%q, want %q.%q", copyObj.Bucket, copyObj.Name, newBucketName, copyName) } // Copying with attributes. const contentEncoding = "identity" copier := bkt.Object(copyName).CopierFrom(bkt.Object(objName)) copier.ContentEncoding = contentEncoding copyObj, err = copier.Run(ctx) if err != nil { t.Errorf("Copier.Run failed with %v", err) } else { if !namesEqual(copyObj, newBucketName, copyName) { t.Errorf("Copy object bucket, name: got %q.%q, want %q.%q", copyObj.Bucket, copyObj.Name, newBucketName, copyName) } if copyObj.ContentEncoding != contentEncoding { t.Errorf("Copy ContentEncoding: got %q, want %q", copyObj.ContentEncoding, contentEncoding) } } // Test UpdateAttrs. metadata := map[string]string{"key": "value"} updated := h.mustUpdateObject(bkt.Object(objName), ObjectAttrsToUpdate{ ContentType: "text/html", ContentLanguage: "en", Metadata: metadata, ACL: []ACLRule{{Entity: "domain-google.com", Role: RoleReader}}, }) if got, want := updated.ContentType, "text/html"; got != want { t.Errorf("updated.ContentType == %q; want %q", got, want) } if got, want := updated.ContentLanguage, "en"; got != want { t.Errorf("updated.ContentLanguage == %q; want %q", updated.ContentLanguage, want) } if got, want := updated.Metadata, metadata; !testutil.Equal(got, want) { t.Errorf("updated.Metadata == %+v; want %+v", updated.Metadata, want) } if got, want := updated.Created, created; got != want { t.Errorf("updated.Created == %q; want %q", got, want) } if !updated.Created.Before(updated.Updated) { t.Errorf("updated.Updated should be newer than update.Created") } // Delete ContentType and ContentLanguage. updated = h.mustUpdateObject(bkt.Object(objName), ObjectAttrsToUpdate{ ContentType: "", ContentLanguage: "", Metadata: map[string]string{}, }) if got, want := updated.ContentType, ""; got != want { t.Errorf("updated.ContentType == %q; want %q", got, want) } if got, want := updated.ContentLanguage, ""; got != want { t.Errorf("updated.ContentLanguage == %q; want %q", updated.ContentLanguage, want) } if updated.Metadata != nil { t.Errorf("updated.Metadata == %+v; want nil", updated.Metadata) } if got, want := updated.Created, created; got != want { t.Errorf("updated.Created == %q; want %q", got, want) } if !updated.Created.Before(updated.Updated) { t.Errorf("updated.Updated should be newer than update.Created") } // Test checksums. checksumCases := []struct { name string contents [][]byte size int64 md5 string crc32c uint32 }{ { name: "checksum-object", contents: [][]byte{[]byte("hello"), []byte("world")}, size: 10, md5: "fc5e038d38a57032085441e7fe7010b0", crc32c: 1456190592, }, { name: "zero-object", contents: [][]byte{}, size: 0, md5: "d41d8cd98f00b204e9800998ecf8427e", crc32c: 0, }, } for _, c := range checksumCases { wc := bkt.Object(c.name).NewWriter(ctx) for _, data := range c.contents { if _, err := wc.Write(data); err != nil { t.Errorf("Write(%q) failed with %q", data, err) } } if err = wc.Close(); err != nil { t.Errorf("%q: close failed with %q", c.name, err) } obj := wc.Attrs() if got, want := obj.Size, c.size; got != want { t.Errorf("Object (%q) Size = %v; want %v", c.name, got, want) } if got, want := fmt.Sprintf("%x", obj.MD5), c.md5; got != want { t.Errorf("Object (%q) MD5 = %q; want %q", c.name, got, want) } if got, want := obj.CRC32C, c.crc32c; got != want { t.Errorf("Object (%q) CRC32C = %v; want %v", c.name, got, want) } } // Test public ACL. publicObj := objects[0] if err = bkt.Object(publicObj).ACL().Set(ctx, AllUsers, RoleReader); err != nil { t.Errorf("PutACLEntry failed with %v", err) } publicClient, err := newTestClient(ctx, option.WithoutAuthentication()) if err != nil { t.Fatal(err) } slurp := h.mustRead(publicClient.Bucket(newBucketName).Object(publicObj)) if !bytes.Equal(slurp, contents[publicObj]) { t.Errorf("Public object's content: got %q, want %q", slurp, contents[publicObj]) } // Test writer error handling. wc := publicClient.Bucket(newBucketName).Object(publicObj).NewWriter(ctx) if _, err := wc.Write([]byte("hello")); err != nil { t.Errorf("Write unexpectedly failed with %v", err) } if err = wc.Close(); err == nil { t.Error("Close expected an error, found none") } // Test deleting the copy object. h.mustDeleteObject(bkt.Object(copyName)) // Deleting it a second time should return ErrObjectNotExist. if err := bkt.Object(copyName).Delete(ctx); err != ErrObjectNotExist { t.Errorf("second deletion of %v = %v; want ErrObjectNotExist", copyName, err) } _, err = bkt.Object(copyName).Attrs(ctx) if err != ErrObjectNotExist { t.Errorf("Copy is expected to be deleted, stat errored with %v", err) } // Test object composition. var compSrcs []*ObjectHandle var wantContents []byte for _, obj := range objects { compSrcs = append(compSrcs, bkt.Object(obj)) wantContents = append(wantContents, contents[obj]...) } checkCompose := func(obj *ObjectHandle, wantContentType string) { rc := h.mustNewReader(obj) slurp, err = ioutil.ReadAll(rc) if err != nil { t.Fatalf("ioutil.ReadAll: %v", err) } defer rc.Close() if !bytes.Equal(slurp, wantContents) { t.Errorf("Composed object contents\ngot: %q\nwant: %q", slurp, wantContents) } if got := rc.ContentType(); got != wantContentType { t.Errorf("Composed object content-type = %q, want %q", got, wantContentType) } } // Compose should work even if the user sets no destination attributes. compDst := bkt.Object("composed1") c := compDst.ComposerFrom(compSrcs...) if _, err := c.Run(ctx); err != nil { t.Fatalf("ComposeFrom error: %v", err) } checkCompose(compDst, "application/octet-stream") // It should also work if we do. compDst = bkt.Object("composed2") c = compDst.ComposerFrom(compSrcs...) c.ContentType = "text/json" if _, err := c.Run(ctx); err != nil { t.Fatalf("ComposeFrom error: %v", err) } checkCompose(compDst, "text/json") } func TestIntegration_Encoding(t *testing.T) { ctx := context.Background() client := testConfig(ctx, t) defer client.Close() bkt := client.Bucket(bucketName) // Test content encoding const zeroCount = 20 << 1 // TODO: should be 20 << 20 obj := bkt.Object("gzip-test") w := obj.NewWriter(ctx) w.ContentEncoding = "gzip" gw := gzip.NewWriter(w) if _, err := io.Copy(gw, io.LimitReader(zeros{}, zeroCount)); err != nil { t.Fatalf("io.Copy, upload: %v", err) } if err := gw.Close(); err != nil { t.Errorf("gzip.Close(): %v", err) } if err := w.Close(); err != nil { t.Errorf("w.Close(): %v", err) } r, err := obj.NewReader(ctx) if err != nil { t.Fatalf("NewReader(gzip-test): %v", err) } n, err := io.Copy(ioutil.Discard, r) if err != nil { t.Errorf("io.Copy, download: %v", err) } if n != zeroCount { t.Errorf("downloaded bad data: got %d bytes, want %d", n, zeroCount) } // Test NotFound. _, err = bkt.Object("obj-not-exists").NewReader(ctx) if err != ErrObjectNotExist { t.Errorf("Object should not exist, err found to be %v", err) } } func namesEqual(obj *ObjectAttrs, bucketName, objectName string) bool { return obj.Bucket == bucketName && obj.Name == objectName } func testObjectIterator(t *testing.T, bkt *BucketHandle, objects []string) { ctx := context.Background() h := testHelper{t} // Collect the list of items we expect: ObjectAttrs in lexical order by name. names := make([]string, len(objects)) copy(names, objects) sort.Strings(names) var attrs []*ObjectAttrs for _, name := range names { attrs = append(attrs, h.mustObjectAttrs(bkt.Object(name))) } msg, ok := itesting.TestIterator(attrs, func() interface{} { return bkt.Objects(ctx, &Query{Prefix: "obj"}) }, func(it interface{}) (interface{}, error) { return it.(*ObjectIterator).Next() }) if !ok { t.Errorf("ObjectIterator.Next: %s", msg) } // TODO(jba): test query.Delimiter != "" } func testObjectsIterateSelectedAttrs(t *testing.T, bkt *BucketHandle, objects []string) { // Create a query that will only select the "Name" attr of objects, and // invoke object listing. query := &Query{Prefix: ""} query.SetAttrSelection([]string{"Name"}) var gotNames []string it := bkt.Objects(context.Background(), query) for { attrs, err := it.Next() if err == iterator.Done { break } if err != nil { log.Fatal(err) } gotNames = append(gotNames, attrs.Name) if len(attrs.Bucket) > 0 { t.Errorf("Bucket field not selected, want empty, got = %v", attrs.Bucket) } } sortedNames := make([]string, len(objects)) copy(sortedNames, objects) sort.Strings(sortedNames) sort.Strings(gotNames) if !cmp.Equal(sortedNames, gotNames) { t.Errorf("names = %v, want %v", gotNames, sortedNames) } } func TestIntegration_SignedURL(t *testing.T) { if testing.Short() { // do not test during replay t.Skip("Integration tests skipped in short mode") } // To test SignedURL, we need a real user email and private key. Extract them // from the JSON key file. jwtConf, err := testutil.JWTConfig() if err != nil { t.Fatal(err) } if jwtConf == nil { t.Skip("JSON key file is not present") } ctx := context.Background() client := testConfig(ctx, t) defer client.Close() bkt := client.Bucket(bucketName) obj := "signedURL" contents := []byte("This is a test of SignedURL.\n") md5 := "Jyxvgwm9n2MsrGTMPbMeYA==" // base64-encoded MD5 of contents if err := writeObject(ctx, bkt.Object(obj), "text/plain", contents); err != nil { t.Fatalf("writing: %v", err) } for _, test := range []struct { desc string opts SignedURLOptions headers map[string][]string fail bool }{ { desc: "basic v2", }, { desc: "basic v4", opts: SignedURLOptions{Scheme: SigningSchemeV4}, }, { desc: "MD5 sent and matches", opts: SignedURLOptions{MD5: md5}, headers: map[string][]string{"Content-MD5": {md5}}, }, { desc: "MD5 not sent", opts: SignedURLOptions{MD5: md5}, fail: true, }, { desc: "Content-Type sent and matches", opts: SignedURLOptions{ContentType: "text/plain"}, headers: map[string][]string{"Content-Type": {"text/plain"}}, }, { desc: "Content-Type sent but does not match", opts: SignedURLOptions{ContentType: "text/plain"}, headers: map[string][]string{"Content-Type": {"application/json"}}, fail: true, }, { desc: "Canonical headers sent and match", opts: SignedURLOptions{Headers: []string{ " X-Goog-Foo: Bar baz ", "X-Goog-Novalue", // ignored: no value "X-Google-Foo", // ignored: wrong prefix }}, headers: map[string][]string{"X-Goog-foo": {"Bar baz "}}, }, { desc: "Canonical headers sent but don't match", opts: SignedURLOptions{Headers: []string{" X-Goog-Foo: Bar baz"}}, headers: map[string][]string{"X-Goog-Foo": {"bar baz"}}, fail: true, }, } { opts := test.opts opts.GoogleAccessID = jwtConf.Email opts.PrivateKey = jwtConf.PrivateKey opts.Method = "GET" opts.Expires = time.Now().Add(time.Hour) u, err := SignedURL(bucketName, obj, &opts) if err != nil { t.Errorf("%s: SignedURL: %v", test.desc, err) continue } got, err := getURL(u, test.headers) if err != nil && !test.fail { t.Errorf("%s: getURL %q: %v", test.desc, u, err) } else if err == nil && !bytes.Equal(got, contents) { t.Errorf("%s: got %q, want %q", test.desc, got, contents) } } } func TestIntegration_SignedURL_WithEncryptionKeys(t *testing.T) { t.Skip("Internal bug 128647687") if testing.Short() { // do not test during replay t.Skip("Integration tests skipped in short mode") } // To test SignedURL, we need a real user email and private key. Extract // them from the JSON key file. jwtConf, err := testutil.JWTConfig() if err != nil { t.Fatal(err) } if jwtConf == nil { t.Skip("JSON key file is not present") } ctx := context.Background() client := testConfig(ctx, t) defer client.Close() // TODO(deklerk): document how these were generated and their significance encryptionKey := "AAryxNglNkXQY0Wa+h9+7BLSFMhCzPo22MtXUWjOBbI=" encryptionKeySha256 := "QlCdVONb17U1aCTAjrFvMbnxW/Oul8VAvnG1875WJ3k=" headers := map[string][]string{ "x-goog-encryption-algorithm": {"AES256"}, "x-goog-encryption-key": {encryptionKey}, "x-goog-encryption-key-sha256": {encryptionKeySha256}, } contents := []byte(`{"message":"encryption with csek works"}`) tests := []struct { desc string opts *SignedURLOptions }{ { desc: "v4 URL with customer supplied encryption keys for PUT", opts: &SignedURLOptions{ Method: "PUT", Headers: []string{ "x-goog-encryption-algorithm:AES256", "x-goog-encryption-key:AAryxNglNkXQY0Wa+h9+7BLSFMhCzPo22MtXUWjOBbI=", "x-goog-encryption-key-sha256:QlCdVONb17U1aCTAjrFvMbnxW/Oul8VAvnG1875WJ3k=", }, Scheme: SigningSchemeV4, }, }, { desc: "v4 URL with customer supplied encryption keys for GET", opts: &SignedURLOptions{ Method: "GET", Headers: []string{ "x-goog-encryption-algorithm:AES256", fmt.Sprintf("x-goog-encryption-key:%s", encryptionKey), fmt.Sprintf("x-goog-encryption-key-sha256:%s", encryptionKeySha256), }, Scheme: SigningSchemeV4, }, }, } defer func() { // Delete encrypted object. bkt := client.Bucket(bucketName) err := bkt.Object("csek.json").Delete(ctx) if err != nil { log.Printf("failed to deleted encrypted file: %v", err) } }() for _, test := range tests { opts := test.opts opts.GoogleAccessID = jwtConf.Email opts.PrivateKey = jwtConf.PrivateKey opts.Expires = time.Now().Add(time.Hour) u, err := SignedURL(bucketName, "csek.json", test.opts) if err != nil { t.Fatalf("%s: %v", test.desc, err) } if test.opts.Method == "PUT" { if _, err := putURL(u, headers, bytes.NewReader(contents)); err != nil { t.Fatalf("%s: %v", test.desc, err) } } if test.opts.Method == "GET" { got, err := getURL(u, headers) if err != nil { t.Fatalf("%s: %v", test.desc, err) } if !bytes.Equal(got, contents) { t.Fatalf("%s: got %q, want %q", test.desc, got, contents) } } } } func TestIntegration_SignedURL_EmptyStringObjectName(t *testing.T) { if testing.Short() { // do not test during replay t.Skip("Integration tests skipped in short mode") } // To test SignedURL, we need a real user email and private key. Extract them // from the JSON key file. jwtConf, err := testutil.JWTConfig() if err != nil { t.Fatal(err) } if jwtConf == nil { t.Skip("JSON key file is not present") } ctx := context.Background() client := testConfig(ctx, t) defer client.Close() opts := &SignedURLOptions{ Scheme: SigningSchemeV4, Method: "GET", GoogleAccessID: jwtConf.Email, PrivateKey: jwtConf.PrivateKey, Expires: time.Now().Add(time.Hour), } u, err := SignedURL(bucketName, "", opts) if err != nil { t.Fatal(err) } // Should be some ListBucketResult response. _, err = getURL(u, nil) if err != nil { t.Fatal(err) } } // Make a GET request to a URL using an unauthenticated client, and return its contents. func getURL(url string, headers map[string][]string) ([]byte, error) { req, err := http.NewRequest("GET", url, nil) if err != nil { return nil, err } req.Header = headers res, err := http.DefaultClient.Do(req) if err != nil { return nil, err } defer res.Body.Close() bytes, err := ioutil.ReadAll(res.Body) if err != nil { return nil, err } if res.StatusCode != 200 { return nil, fmt.Errorf("code=%d, body=%s", res.StatusCode, string(bytes)) } return bytes, nil } // Make a PUT request to a URL using an unauthenticated client, and return its contents. func putURL(url string, headers map[string][]string, payload io.Reader) ([]byte, error) { req, err := http.NewRequest("PUT", url, payload) if err != nil { return nil, err } req.Header = headers res, err := http.DefaultClient.Do(req) if err != nil { return nil, err } defer res.Body.Close() bytes, err := ioutil.ReadAll(res.Body) if err != nil { return nil, err } if res.StatusCode != 200 { return nil, fmt.Errorf("code=%d, body=%s", res.StatusCode, string(bytes)) } return bytes, nil } func TestIntegration_ACL(t *testing.T) { t.Skip("https://github.com/googleapis/google-cloud-go/issues/1652") ctx := context.Background() client := testConfig(ctx, t) defer client.Close() bkt := client.Bucket(bucketName) entity := ACLEntity("domain-google.com") rule := ACLRule{Entity: entity, Role: RoleReader, Domain: "google.com"} if err := bkt.DefaultObjectACL().Set(ctx, entity, RoleReader); err != nil { t.Errorf("Can't put default ACL rule for the bucket, errored with %v", err) } acl, err := bkt.DefaultObjectACL().List(ctx) if err != nil { t.Errorf("DefaultObjectACL.List for bucket %q: %v", bucketName, err) } else if !hasRule(acl, rule) { t.Errorf("default ACL missing %#v", rule) } aclObjects := []string{"acl1", "acl2"} for _, obj := range aclObjects { c := randomContents() if err := writeObject(ctx, bkt.Object(obj), "", c); err != nil { t.Errorf("Write for %v failed with %v", obj, err) } } name := aclObjects[0] o := bkt.Object(name) acl, err = o.ACL().List(ctx) if err != nil { t.Errorf("Can't retrieve ACL of %v", name) } else if !hasRule(acl, rule) { t.Errorf("object ACL missing %+v", rule) } if err := o.ACL().Delete(ctx, entity); err != nil { t.Errorf("object ACL: could not delete entity %s", entity) } // Delete the default ACL rule. We can't move this code earlier in the // test, because the test depends on the fact that the object ACL inherits // it. if err := bkt.DefaultObjectACL().Delete(ctx, entity); err != nil { t.Errorf("default ACL: could not delete entity %s", entity) } entity2 := ACLEntity("user-jbd@google.com") rule2 := ACLRule{Entity: entity2, Role: RoleReader, Email: "jbd@google.com"} if err := bkt.ACL().Set(ctx, entity2, RoleReader); err != nil { t.Errorf("Error while putting bucket ACL rule: %v", err) } bACL, err := bkt.ACL().List(ctx) if err != nil { t.Errorf("Error while getting the ACL of the bucket: %v", err) } else if !hasRule(bACL, rule2) { t.Errorf("bucket ACL missing %+v", rule2) } if err := bkt.ACL().Delete(ctx, entity2); err != nil { t.Errorf("Error while deleting bucket ACL rule: %v", err) } } func hasRule(acl []ACLRule, rule ACLRule) bool { for _, r := range acl { if cmp.Equal(r, rule) { return true } } return false } func TestIntegration_ValidObjectNames(t *testing.T) { ctx := context.Background() client := testConfig(ctx, t) defer client.Close() bkt := client.Bucket(bucketName) validNames := []string{ "gopher", "Гоферови", "a", strings.Repeat("a", 1024), } for _, name := range validNames { if err := writeObject(ctx, bkt.Object(name), "", []byte("data")); err != nil { t.Errorf("Object %q write failed: %v. Want success", name, err) continue } defer bkt.Object(name).Delete(ctx) } invalidNames := []string{ "", // Too short. strings.Repeat("a", 1025), // Too long. "new\nlines", "bad\xffunicode", } for _, name := range invalidNames { // Invalid object names will either cause failure during Write or Close. if err := writeObject(ctx, bkt.Object(name), "", []byte("data")); err != nil { continue } defer bkt.Object(name).Delete(ctx) t.Errorf("%q should have failed. Didn't", name) } } func TestIntegration_WriterContentType(t *testing.T) { ctx := context.Background() client := testConfig(ctx, t) defer client.Close() obj := client.Bucket(bucketName).Object("content") testCases := []struct { content string setType, wantType string }{ { content: "It was the best of times, it was the worst of times.", wantType: "text/plain; charset=utf-8", }, { content: "My first page", wantType: "text/html; charset=utf-8", }, { content: "My first page", setType: "text/html", wantType: "text/html", }, { content: "My first page", setType: "image/jpeg", wantType: "image/jpeg", }, } for i, tt := range testCases { if err := writeObject(ctx, obj, tt.setType, []byte(tt.content)); err != nil { t.Errorf("writing #%d: %v", i, err) } attrs, err := obj.Attrs(ctx) if err != nil { t.Errorf("obj.Attrs: %v", err) continue } if got := attrs.ContentType; got != tt.wantType { t.Errorf("Content-Type = %q; want %q\nContent: %q\nSet Content-Type: %q", got, tt.wantType, tt.content, tt.setType) } } } func TestIntegration_ZeroSizedObject(t *testing.T) { t.Parallel() ctx := context.Background() client := testConfig(ctx, t) defer client.Close() h := testHelper{t} obj := client.Bucket(bucketName).Object("zero") // Check writing it works as expected. w := obj.NewWriter(ctx) if err := w.Close(); err != nil { t.Fatalf("Writer.Close: %v", err) } defer obj.Delete(ctx) // Check we can read it too. body := h.mustRead(obj) if len(body) != 0 { t.Errorf("Body is %v, want empty []byte{}", body) } } func TestIntegration_Encryption(t *testing.T) { // This function tests customer-supplied encryption keys for all operations // involving objects. Bucket and ACL operations aren't tested because they // aren't affected by customer encryption. Neither is deletion. ctx := context.Background() client := testConfig(ctx, t) defer client.Close() h := testHelper{t} obj := client.Bucket(bucketName).Object("customer-encryption") key := []byte("my-secret-AES-256-encryption-key") keyHash := sha256.Sum256(key) keyHashB64 := base64.StdEncoding.EncodeToString(keyHash[:]) key2 := []byte("My-Secret-AES-256-Encryption-Key") contents := "top secret." checkMetadataCall := func(msg string, f func(o *ObjectHandle) (*ObjectAttrs, error)) { // Performing a metadata operation without the key should succeed. attrs, err := f(obj) if err != nil { t.Fatalf("%s: %v", msg, err) } // The key hash should match... if got, want := attrs.CustomerKeySHA256, keyHashB64; got != want { t.Errorf("%s: key hash: got %q, want %q", msg, got, want) } // ...but CRC and MD5 should not be present. if attrs.CRC32C != 0 { t.Errorf("%s: CRC: got %v, want 0", msg, attrs.CRC32C) } if len(attrs.MD5) > 0 { t.Errorf("%s: MD5: got %v, want len == 0", msg, attrs.MD5) } // Performing a metadata operation with the key should succeed. attrs, err = f(obj.Key(key)) if err != nil { t.Fatalf("%s: %v", msg, err) } // Check the key and content hashes. if got, want := attrs.CustomerKeySHA256, keyHashB64; got != want { t.Errorf("%s: key hash: got %q, want %q", msg, got, want) } if attrs.CRC32C == 0 { t.Errorf("%s: CRC: got 0, want non-zero", msg) } if len(attrs.MD5) == 0 { t.Errorf("%s: MD5: got len == 0, want len > 0", msg) } } checkRead := func(msg string, o *ObjectHandle, k []byte, wantContents string) { // Reading the object without the key should fail. if _, err := readObject(ctx, o); err == nil { t.Errorf("%s: reading without key: want error, got nil", msg) } // Reading the object with the key should succeed. got := h.mustRead(o.Key(k)) gotContents := string(got) // And the contents should match what we wrote. if gotContents != wantContents { t.Errorf("%s: contents: got %q, want %q", msg, gotContents, wantContents) } } checkReadUnencrypted := func(msg string, obj *ObjectHandle, wantContents string) { got := h.mustRead(obj) gotContents := string(got) if gotContents != wantContents { t.Errorf("%s: got %q, want %q", msg, gotContents, wantContents) } } // Write to obj using our own encryption key, which is a valid 32-byte // AES-256 key. h.mustWrite(obj.Key(key).NewWriter(ctx), []byte(contents)) checkMetadataCall("Attrs", func(o *ObjectHandle) (*ObjectAttrs, error) { return o.Attrs(ctx) }) checkMetadataCall("Update", func(o *ObjectHandle) (*ObjectAttrs, error) { return o.Update(ctx, ObjectAttrsToUpdate{ContentLanguage: "en"}) }) checkRead("first object", obj, key, contents) obj2 := client.Bucket(bucketName).Object("customer-encryption-2") // Copying an object without the key should fail. if _, err := obj2.CopierFrom(obj).Run(ctx); err == nil { t.Fatal("want error, got nil") } // Copying an object with the key should succeed. if _, err := obj2.CopierFrom(obj.Key(key)).Run(ctx); err != nil { t.Fatal(err) } // The destination object is not encrypted; we can read it without a key. checkReadUnencrypted("copy dest", obj2, contents) // Providing a key on the destination but not the source should fail, // since the source is encrypted. if _, err := obj2.Key(key2).CopierFrom(obj).Run(ctx); err == nil { t.Fatal("want error, got nil") } // But copying with keys for both source and destination should succeed. if _, err := obj2.Key(key2).CopierFrom(obj.Key(key)).Run(ctx); err != nil { t.Fatal(err) } // And the destination should be encrypted, meaning we can only read it // with a key. checkRead("copy destination", obj2, key2, contents) // Change obj2's key to prepare for compose, where all objects must have // the same key. Also illustrates key rotation: copy an object to itself // with a different key. if _, err := obj2.Key(key).CopierFrom(obj2.Key(key2)).Run(ctx); err != nil { t.Fatal(err) } obj3 := client.Bucket(bucketName).Object("customer-encryption-3") // Composing without keys should fail. if _, err := obj3.ComposerFrom(obj, obj2).Run(ctx); err == nil { t.Fatal("want error, got nil") } // Keys on the source objects result in an error. if _, err := obj3.ComposerFrom(obj.Key(key), obj2).Run(ctx); err == nil { t.Fatal("want error, got nil") } // A key on the destination object both decrypts the source objects // and encrypts the destination. if _, err := obj3.Key(key).ComposerFrom(obj, obj2).Run(ctx); err != nil { t.Fatalf("got %v, want nil", err) } // Check that the destination in encrypted. checkRead("compose destination", obj3, key, contents+contents) // You can't compose one or more unencrypted source objects into an // encrypted destination object. _, err := obj2.CopierFrom(obj2.Key(key)).Run(ctx) // unencrypt obj2 if err != nil { t.Fatal(err) } if _, err := obj3.Key(key).ComposerFrom(obj2).Run(ctx); err == nil { t.Fatal("got nil, want error") } } func TestIntegration_NonexistentBucket(t *testing.T) { t.Parallel() ctx := context.Background() client := testConfig(ctx, t) defer client.Close() bkt := client.Bucket(uidSpace.New()) if _, err := bkt.Attrs(ctx); err != ErrBucketNotExist { t.Errorf("Attrs: got %v, want ErrBucketNotExist", err) } it := bkt.Objects(ctx, nil) if _, err := it.Next(); err != ErrBucketNotExist { t.Errorf("Objects: got %v, want ErrBucketNotExist", err) } } func TestIntegration_PerObjectStorageClass(t *testing.T) { const ( defaultStorageClass = "STANDARD" newStorageClass = "NEARLINE" ) ctx := context.Background() client := testConfig(ctx, t) defer client.Close() h := testHelper{t} bkt := client.Bucket(bucketName) // The bucket should have the default storage class. battrs := h.mustBucketAttrs(bkt) if battrs.StorageClass != defaultStorageClass { t.Fatalf("bucket storage class: got %q, want %q", battrs.StorageClass, defaultStorageClass) } // Write an object; it should start with the bucket's storage class. obj := bkt.Object("posc") h.mustWrite(obj.NewWriter(ctx), []byte("foo")) oattrs, err := obj.Attrs(ctx) if err != nil { t.Fatal(err) } if oattrs.StorageClass != defaultStorageClass { t.Fatalf("object storage class: got %q, want %q", oattrs.StorageClass, defaultStorageClass) } // Now use Copy to change the storage class. copier := obj.CopierFrom(obj) copier.StorageClass = newStorageClass oattrs2, err := copier.Run(ctx) if err != nil { log.Fatal(err) } if oattrs2.StorageClass != newStorageClass { t.Fatalf("new object storage class: got %q, want %q", oattrs2.StorageClass, newStorageClass) } // We can also write a new object using a non-default storage class. obj2 := bkt.Object("posc2") w := obj2.NewWriter(ctx) w.StorageClass = newStorageClass h.mustWrite(w, []byte("xxx")) if w.Attrs().StorageClass != newStorageClass { t.Fatalf("new object storage class: got %q, want %q", w.Attrs().StorageClass, newStorageClass) } } func TestIntegration_BucketInCopyAttrs(t *testing.T) { // Confirm that if bucket is included in the object attributes of a rewrite // call, but object name and content-type aren't, then we get an error. See // the comment in Copier.Run. ctx := context.Background() client := testConfig(ctx, t) defer client.Close() h := testHelper{t} bkt := client.Bucket(bucketName) obj := bkt.Object("bucketInCopyAttrs") h.mustWrite(obj.NewWriter(ctx), []byte("foo")) copier := obj.CopierFrom(obj) rawObject := copier.ObjectAttrs.toRawObject(bucketName) _, err := copier.callRewrite(ctx, rawObject) if err == nil { t.Errorf("got nil, want error") } } func TestIntegration_NoUnicodeNormalization(t *testing.T) { t.Parallel() ctx := context.Background() client := testConfig(ctx, t) defer client.Close() bkt := client.Bucket("storage-library-test-bucket") h := testHelper{t} for _, tst := range []struct { nameQuoted, content string }{ {`"Caf\u00e9"`, "Normalization Form C"}, {`"Cafe\u0301"`, "Normalization Form D"}, } { name, err := strconv.Unquote(tst.nameQuoted) if err != nil { t.Fatalf("invalid name: %s: %v", tst.nameQuoted, err) } if got := string(h.mustRead(bkt.Object(name))); got != tst.content { t.Errorf("content of %s is %q, want %q", tst.nameQuoted, got, tst.content) } } } func TestIntegration_HashesOnUpload(t *testing.T) { // Check that the user can provide hashes on upload, and that these are checked. ctx := context.Background() client := testConfig(ctx, t) defer client.Close() obj := client.Bucket(bucketName).Object("hashesOnUpload-1") data := []byte("I can't wait to be verified") write := func(w *Writer) error { if _, err := w.Write(data); err != nil { _ = w.Close() return err } return w.Close() } crc32c := crc32.Checksum(data, crc32cTable) // The correct CRC should succeed. w := obj.NewWriter(ctx) w.CRC32C = crc32c w.SendCRC32C = true if err := write(w); err != nil { t.Fatal(err) } // If we change the CRC, validation should fail. w = obj.NewWriter(ctx) w.CRC32C = crc32c + 1 w.SendCRC32C = true if err := write(w); err == nil { t.Fatal("write with bad CRC32c: want error, got nil") } // If we have the wrong CRC but forget to send it, we succeed. w = obj.NewWriter(ctx) w.CRC32C = crc32c + 1 if err := write(w); err != nil { t.Fatal(err) } // MD5 md5 := md5.Sum(data) // The correct MD5 should succeed. w = obj.NewWriter(ctx) w.MD5 = md5[:] if err := write(w); err != nil { t.Fatal(err) } // If we change the MD5, validation should fail. w = obj.NewWriter(ctx) w.MD5 = append([]byte(nil), md5[:]...) w.MD5[0]++ if err := write(w); err == nil { t.Fatal("write with bad MD5: want error, got nil") } } func TestIntegration_BucketIAM(t *testing.T) { ctx := context.Background() client := testConfig(ctx, t) defer client.Close() h := testHelper{t} bkt := client.Bucket(uidSpace.New()) h.mustCreate(bkt, testutil.ProjID(), nil) defer h.mustDeleteBucket(bkt) // This bucket is unique to this test run. So we don't have // to worry about other runs interfering with our IAM policy // changes. member := "projectViewer:" + testutil.ProjID() role := iam.RoleName("roles/storage.objectViewer") // Get the bucket's IAM policy. policy, err := bkt.IAM().Policy(ctx) if err != nil { t.Fatalf("Getting policy: %v", err) } // The member should not have the role. if policy.HasRole(member, role) { t.Errorf("member %q has role %q", member, role) } // Change the policy. policy.Add(member, role) if err := bkt.IAM().SetPolicy(ctx, policy); err != nil { t.Fatalf("SetPolicy: %v", err) } // Confirm that the binding was added. policy, err = bkt.IAM().Policy(ctx) if err != nil { t.Fatalf("Getting policy: %v", err) } if !policy.HasRole(member, role) { t.Errorf("member %q does not have role %q", member, role) } // Check TestPermissions. // This client should have all these permissions (and more). perms := []string{"storage.buckets.get", "storage.buckets.delete"} got, err := bkt.IAM().TestPermissions(ctx, perms) if err != nil { t.Fatalf("TestPermissions: %v", err) } sort.Strings(perms) sort.Strings(got) if !testutil.Equal(got, perms) { t.Errorf("got %v, want %v", got, perms) } } func TestIntegration_RequesterPays(t *testing.T) { // This test needs a second project and user (token source) to test // all possibilities. Since we need these things for Firestore already, // we use them here. // // There are up to three entities involved in a requester-pays call: // // 1. The user making the request. Here, we use // a. The account used to create the token source used for all our // integration tests (see testutil.TokenSource). // b. The account used for the Firestore tests. // 2. The project that owns the requester-pays bucket. Here, that // is the test project ID (see testutil.ProjID). // 3. The project provided as the userProject parameter of the request; // the project to be billed. This test uses: // a. The project that owns the requester-pays bucket (same as (2)) // b. Another project (the Firestore project). // // The following must hold for this test to work: // - (1a) must have resourcemanager.projects.createBillingAssignment permission // (Owner role) on (2) (the project, not the bucket). // - (1b) must NOT have that permission on (2). // - (1b) must have serviceusage.services.use permission (Editor role) on (3b). // - (1b) must NOT have that permission on (3a). // - (1a) must NOT have that permission on (3b). const wantErrorCode = 400 ctx := context.Background() client := testConfig(ctx, t) defer client.Close() h := testHelper{t} bucketName2 := uidSpace.New() b1 := client.Bucket(bucketName2) projID := testutil.ProjID() // Use Firestore project as a project that does not contain the bucket. otherProjID := os.Getenv(envFirestoreProjID) if otherProjID == "" { t.Fatalf("need a second project (env var %s)", envFirestoreProjID) } ts := testutil.TokenSourceEnv(ctx, envFirestorePrivateKey, ScopeFullControl) if ts == nil { t.Fatalf("need a second account (env var %s)", envFirestorePrivateKey) } otherClient, err := newTestClient(ctx, option.WithTokenSource(ts)) if err != nil { t.Fatal(err) } defer otherClient.Close() b2 := otherClient.Bucket(bucketName2) user, err := keyFileEmail(os.Getenv("GCLOUD_TESTS_GOLANG_KEY")) if err != nil { t.Fatal(err) } otherUser, err := keyFileEmail(os.Getenv(envFirestorePrivateKey)) if err != nil { t.Fatal(err) } // Create a requester-pays bucket. The bucket is contained in the project projID. h.mustCreate(b1, projID, &BucketAttrs{RequesterPays: true}) if err := b1.ACL().Set(ctx, ACLEntity("user-"+otherUser), RoleOwner); err != nil { t.Fatal(err) } // Extract the error code from err if it's a googleapi.Error. errCode := func(err error) int { if err == nil { return 0 } if err, ok := err.(*googleapi.Error); ok { return err.Code } return -1 } // Call f under various conditions. // Here b and ob refer to the same bucket, but b is bound to client, // while ob is bound to otherClient. The clients differ in their credentials, // i.e. the identity of the user making the RPC: b's user is an Owner on the // bucket's containing project, ob's is not. call := func(msg string, f func(*BucketHandle) error) { // user: an Owner on the containing project // userProject: absent // result: success, by the rule permitting access by owners of the containing bucket. if err := f(b1); err != nil { t.Errorf("%s: %v, want nil\n"+ "confirm that %s is an Owner on %s", msg, err, user, projID) } // user: an Owner on the containing project // userProject: containing project // result: success, by the same rule as above; userProject is unnecessary but allowed. if err := f(b1.UserProject(projID)); err != nil { t.Errorf("%s: got %v, want nil", msg, err) } // user: not an Owner on the containing project // userProject: absent // result: failure, by the standard requester-pays rule err := f(b2) if got, want := errCode(err), wantErrorCode; got != want { t.Errorf("%s: got error %v with code %d, want code %d\n"+ "confirm that %s is NOT an Owner on %s", msg, err, got, want, otherUser, projID) } // user: not an Owner on the containing project // userProject: not the containing one, but user has Editor role on it // result: success, by the standard requester-pays rule if err := f(b2.UserProject(otherProjID)); err != nil { t.Errorf("%s: got %v, want nil\n"+ "confirm that %s is an Editor on %s and that that project has billing enabled", msg, err, otherUser, otherProjID) } // user: not an Owner on the containing project // userProject: the containing one, on which the user does NOT have Editor permission. // result: failure err = f(b2.UserProject("veener-jba")) if got, want := errCode(err), 403; got != want { t.Errorf("%s: got error %v, want code %d\n"+ "confirm that %s is NOT an Editor on %s", msg, err, want, otherUser, "veener-jba") } } // Getting its attributes requires a user project. var attrs *BucketAttrs call("Bucket attrs", func(b *BucketHandle) error { a, err := b.Attrs(ctx) if a != nil { attrs = a } return err }) if attrs != nil { if got, want := attrs.RequesterPays, true; got != want { t.Fatalf("attr.RequesterPays = %t, want %t", got, want) } } // Object operations. call("write object", func(b *BucketHandle) error { return writeObject(ctx, b.Object("foo"), "text/plain", []byte("hello")) }) call("read object", func(b *BucketHandle) error { _, err := readObject(ctx, b.Object("foo")) return err }) call("object attrs", func(b *BucketHandle) error { _, err := b.Object("foo").Attrs(ctx) return err }) call("update object", func(b *BucketHandle) error { _, err := b.Object("foo").Update(ctx, ObjectAttrsToUpdate{ContentLanguage: "en"}) return err }) // ACL operations. entity := ACLEntity("domain-google.com") call("bucket acl set", func(b *BucketHandle) error { return b.ACL().Set(ctx, entity, RoleReader) }) call("bucket acl list", func(b *BucketHandle) error { _, err := b.ACL().List(ctx) return err }) call("bucket acl delete", func(b *BucketHandle) error { err := b.ACL().Delete(ctx, entity) if errCode(err) == 404 { // Since we call the function multiple times, it will // fail with NotFound for all but the first. return nil } return err }) call("default object acl set", func(b *BucketHandle) error { return b.DefaultObjectACL().Set(ctx, entity, RoleReader) }) call("default object acl list", func(b *BucketHandle) error { _, err := b.DefaultObjectACL().List(ctx) return err }) call("default object acl delete", func(b *BucketHandle) error { err := b.DefaultObjectACL().Delete(ctx, entity) if errCode(err) == 404 { return nil } return err }) call("object acl set", func(b *BucketHandle) error { return b.Object("foo").ACL().Set(ctx, entity, RoleReader) }) call("object acl list", func(b *BucketHandle) error { _, err := b.Object("foo").ACL().List(ctx) return err }) call("object acl delete", func(b *BucketHandle) error { err := b.Object("foo").ACL().Delete(ctx, entity) if errCode(err) == 404 { return nil } return err }) // Copy and compose. call("copy", func(b *BucketHandle) error { _, err := b.Object("copy").CopierFrom(b.Object("foo")).Run(ctx) return err }) call("compose", func(b *BucketHandle) error { _, err := b.Object("compose").ComposerFrom(b.Object("foo"), b.Object("copy")).Run(ctx) return err }) call("delete object", func(b *BucketHandle) error { // Make sure the object exists, so we don't get confused by ErrObjectNotExist. // The storage service may perform validation in any order (perhaps in parallel), // so if we delete an object that doesn't exist and for which we lack permission, // we could see either of those two errors. (See Google-internal bug 78341001.) h.mustWrite(b1.Object("foo").NewWriter(ctx), []byte("hello")) // note: b1, not b. return b.Object("foo").Delete(ctx) }) b1.Object("foo").Delete(ctx) // Make sure object is deleted. for _, obj := range []string{"copy", "compose"} { if err := b1.UserProject(projID).Object(obj).Delete(ctx); err != nil { t.Fatalf("could not delete %q: %v", obj, err) } } h.mustDeleteBucket(b1) } // TODO(jba): move to testutil, factor out from firestore/integration_test.go. const ( envFirestoreProjID = "GCLOUD_TESTS_GOLANG_FIRESTORE_PROJECT_ID" envFirestorePrivateKey = "GCLOUD_TESTS_GOLANG_FIRESTORE_KEY" ) func keyFileEmail(filename string) (string, error) { bytes, err := ioutil.ReadFile(filename) if err != nil { return "", err } var v struct { ClientEmail string `json:"client_email"` } if err := json.Unmarshal(bytes, &v); err != nil { return "", err } return v.ClientEmail, nil } func TestIntegration_Notifications(t *testing.T) { ctx := context.Background() client := testConfig(ctx, t) defer client.Close() bkt := client.Bucket(bucketName) checkNotifications := func(msg string, want map[string]*Notification) { got, err := bkt.Notifications(ctx) if err != nil { t.Fatal(err) } if diff := testutil.Diff(got, want); diff != "" { t.Errorf("%s: got=-, want=+:\n%s", msg, diff) } } checkNotifications("initial", map[string]*Notification{}) nArg := &Notification{ TopicProjectID: testutil.ProjID(), TopicID: "go-storage-notification-test", PayloadFormat: NoPayload, } n, err := bkt.AddNotification(ctx, nArg) if err != nil { t.Fatal(err) } nArg.ID = n.ID if !testutil.Equal(n, nArg) { t.Errorf("got %+v, want %+v", n, nArg) } checkNotifications("after add", map[string]*Notification{n.ID: n}) if err := bkt.DeleteNotification(ctx, n.ID); err != nil { t.Fatal(err) } checkNotifications("after delete", map[string]*Notification{}) } func TestIntegration_PublicBucket(t *testing.T) { // Confirm that an unauthenticated client can access a public bucket. // See https://cloud.google.com/storage/docs/public-datasets/landsat if testing.Short() && !replaying { t.Skip("Integration tests skipped in short mode") } const landsatBucket = "gcp-public-data-landsat" const landsatPrefix = "LC08/PRE/044/034/LC80440342016259LGN00/" const landsatObject = landsatPrefix + "LC80440342016259LGN00_MTL.txt" // Create an unauthenticated client. ctx := context.Background() client, err := newTestClient(ctx, option.WithoutAuthentication()) if err != nil { t.Fatal(err) } defer client.Close() h := testHelper{t} bkt := client.Bucket(landsatBucket) obj := bkt.Object(landsatObject) // Read a public object. bytes := h.mustRead(obj) if got, want := len(bytes), 7903; got != want { t.Errorf("len(bytes) = %d, want %d", got, want) } // List objects in a public bucket. iter := bkt.Objects(ctx, &Query{Prefix: landsatPrefix}) gotCount := 0 for { _, err := iter.Next() if err == iterator.Done { break } if err != nil { t.Fatal(err) } gotCount++ } if wantCount := 13; gotCount != wantCount { t.Errorf("object count: got %d, want %d", gotCount, wantCount) } errCode := func(err error) int { err2, ok := err.(*googleapi.Error) if !ok { return -1 } return err2.Code } // Reading from or writing to a non-public bucket fails. c := testConfig(ctx, t) defer c.Close() nonPublicObj := client.Bucket(bucketName).Object("noauth") // Oddly, reading returns 403 but writing returns 401. _, err = readObject(ctx, nonPublicObj) if got, want := errCode(err), 403; got != want { t.Errorf("got code %d; want %d\nerror: %v", got, want, err) } err = writeObject(ctx, nonPublicObj, "text/plain", []byte("b")) if got, want := errCode(err), 401; got != want { t.Errorf("got code %d; want %d\nerror: %v", got, want, err) } } func TestIntegration_ReadCRC(t *testing.T) { // Test that the checksum is handled correctly when reading files. // For gzipped files, see https://github.com/GoogleCloudPlatform/google-cloud-dotnet/issues/1641. if testing.Short() && !replaying { t.Skip("Integration tests skipped in short mode") } const ( // This is an uncompressed file. // See https://cloud.google.com/storage/docs/public-datasets/landsat uncompressedBucket = "gcp-public-data-landsat" uncompressedObject = "LC08/PRE/044/034/LC80440342016259LGN00/LC80440342016259LGN00_MTL.txt" gzippedBucket = "storage-library-test-bucket" gzippedObject = "gzipped-text.txt" ) ctx := context.Background() client, err := newTestClient(ctx, option.WithoutAuthentication()) if err != nil { t.Fatal(err) } defer client.Close() for _, test := range []struct { desc string obj *ObjectHandle offset, length int64 readCompressed bool // don't decompress a gzipped file wantErr bool wantCheck bool // Should Reader try to check the CRC? }{ { desc: "uncompressed, entire file", obj: client.Bucket(uncompressedBucket).Object(uncompressedObject), offset: 0, length: -1, readCompressed: false, wantCheck: true, }, { desc: "uncompressed, entire file, don't decompress", obj: client.Bucket(uncompressedBucket).Object(uncompressedObject), offset: 0, length: -1, readCompressed: true, wantCheck: true, }, { desc: "uncompressed, suffix", obj: client.Bucket(uncompressedBucket).Object(uncompressedObject), offset: 1, length: -1, readCompressed: false, wantCheck: false, }, { desc: "uncompressed, prefix", obj: client.Bucket(uncompressedBucket).Object(uncompressedObject), offset: 0, length: 18, readCompressed: false, wantCheck: false, }, { // When a gzipped file is unzipped on read, we can't verify the checksum // because it was computed against the zipped contents. We can detect // this case using http.Response.Uncompressed. desc: "compressed, entire file, unzipped", obj: client.Bucket(gzippedBucket).Object(gzippedObject), offset: 0, length: -1, readCompressed: false, wantCheck: false, }, { // When we read a gzipped file uncompressed, it's like reading a regular file: // the served content and the CRC match. desc: "compressed, entire file, read compressed", obj: client.Bucket(gzippedBucket).Object(gzippedObject), offset: 0, length: -1, readCompressed: true, wantCheck: true, }, { desc: "compressed, partial, server unzips", obj: client.Bucket(gzippedBucket).Object(gzippedObject), offset: 1, length: 8, readCompressed: false, wantErr: true, // GCS can't serve part of a gzipped object wantCheck: false, }, { desc: "compressed, partial, read compressed", obj: client.Bucket(gzippedBucket).Object(gzippedObject), offset: 1, length: 8, readCompressed: true, wantCheck: false, }, } { obj := test.obj.ReadCompressed(test.readCompressed) r, err := obj.NewRangeReader(ctx, test.offset, test.length) if err != nil { if test.wantErr { continue } t.Fatalf("%s: %v", test.desc, err) } if got, want := r.checkCRC, test.wantCheck; got != want { t.Errorf("%s, checkCRC: got %t, want %t", test.desc, got, want) } _, err = ioutil.ReadAll(r) _ = r.Close() if err != nil { t.Fatalf("%s: %v", test.desc, err) } } } func TestIntegration_CancelWrite(t *testing.T) { // Verify that canceling the writer's context immediately stops uploading an object. ctx := context.Background() client := testConfig(ctx, t) defer client.Close() bkt := client.Bucket(bucketName) cctx, cancel := context.WithCancel(ctx) defer cancel() obj := bkt.Object("cancel-write") w := obj.NewWriter(cctx) w.ChunkSize = googleapi.MinUploadChunkSize buf := make([]byte, w.ChunkSize) // Write the first chunk. This is read in its entirety before sending the request // (see google.golang.org/api/gensupport.PrepareUpload), so we expect it to return // without error. _, err := w.Write(buf) if err != nil { t.Fatal(err) } // Now cancel the context. cancel() // The next Write should return context.Canceled. _, err = w.Write(buf) if err != context.Canceled { t.Fatalf("got %v, wanted context.Canceled", err) } // The Close should too. err = w.Close() if err != context.Canceled { t.Fatalf("got %v, wanted context.Canceled", err) } } func TestIntegration_UpdateCORS(t *testing.T) { ctx := context.Background() client := testConfig(ctx, t) defer client.Close() h := testHelper{t} initialSettings := []CORS{ { MaxAge: time.Hour, Methods: []string{"POST"}, Origins: []string{"some-origin.com"}, ResponseHeaders: []string{"foo-bar"}, }, } for _, test := range []struct { input []CORS want []CORS }{ { input: []CORS{ { MaxAge: time.Hour, Methods: []string{"GET"}, Origins: []string{"*"}, ResponseHeaders: []string{"some-header"}, }, }, want: []CORS{ { MaxAge: time.Hour, Methods: []string{"GET"}, Origins: []string{"*"}, ResponseHeaders: []string{"some-header"}, }, }, }, { input: []CORS{}, want: nil, }, { input: nil, want: []CORS{ { MaxAge: time.Hour, Methods: []string{"POST"}, Origins: []string{"some-origin.com"}, ResponseHeaders: []string{"foo-bar"}, }, }, }, } { bkt := client.Bucket(uidSpace.New()) h.mustCreate(bkt, testutil.ProjID(), &BucketAttrs{CORS: initialSettings}) defer h.mustDeleteBucket(bkt) h.mustUpdateBucket(bkt, BucketAttrsToUpdate{CORS: test.input}) attrs := h.mustBucketAttrs(bkt) if diff := testutil.Diff(attrs.CORS, test.want); diff != "" { t.Errorf("input: %v\ngot=-, want=+:\n%s", test.input, diff) } } } func TestIntegration_UpdateDefaultEventBasedHold(t *testing.T) { ctx := context.Background() client := testConfig(ctx, t) defer client.Close() h := testHelper{t} bkt := client.Bucket(uidSpace.New()) h.mustCreate(bkt, testutil.ProjID(), &BucketAttrs{}) defer h.mustDeleteBucket(bkt) attrs := h.mustBucketAttrs(bkt) if attrs.DefaultEventBasedHold != false { t.Errorf("got=%v, want=%v", attrs.DefaultEventBasedHold, false) } h.mustUpdateBucket(bkt, BucketAttrsToUpdate{DefaultEventBasedHold: true}) attrs = h.mustBucketAttrs(bkt) if attrs.DefaultEventBasedHold != true { t.Errorf("got=%v, want=%v", attrs.DefaultEventBasedHold, true) } // Omitting it should leave the value unchanged. h.mustUpdateBucket(bkt, BucketAttrsToUpdate{RequesterPays: true}) attrs = h.mustBucketAttrs(bkt) if attrs.DefaultEventBasedHold != true { t.Errorf("got=%v, want=%v", attrs.DefaultEventBasedHold, true) } } func TestIntegration_UpdateEventBasedHold(t *testing.T) { ctx := context.Background() client := testConfig(ctx, t) defer client.Close() h := testHelper{t} bkt := client.Bucket(uidSpace.New()) h.mustCreate(bkt, testutil.ProjID(), &BucketAttrs{}) obj := bkt.Object("some-obj") h.mustWrite(obj.NewWriter(ctx), randomContents()) defer func() { h.mustUpdateObject(obj, ObjectAttrsToUpdate{EventBasedHold: false}) h.mustDeleteObject(obj) h.mustDeleteBucket(bkt) }() attrs := h.mustObjectAttrs(obj) if attrs.EventBasedHold != false { t.Fatalf("got=%v, want=%v", attrs.EventBasedHold, false) } h.mustUpdateObject(obj, ObjectAttrsToUpdate{EventBasedHold: true}) attrs = h.mustObjectAttrs(obj) if attrs.EventBasedHold != true { t.Fatalf("got=%v, want=%v", attrs.EventBasedHold, true) } // Omitting it should leave the value unchanged. h.mustUpdateObject(obj, ObjectAttrsToUpdate{ContentType: "foo"}) attrs = h.mustObjectAttrs(obj) if attrs.EventBasedHold != true { t.Fatalf("got=%v, want=%v", attrs.EventBasedHold, true) } } func TestIntegration_UpdateTemporaryHold(t *testing.T) { ctx := context.Background() client := testConfig(ctx, t) defer client.Close() h := testHelper{t} bkt := client.Bucket(uidSpace.New()) h.mustCreate(bkt, testutil.ProjID(), &BucketAttrs{}) obj := bkt.Object("some-obj") h.mustWrite(obj.NewWriter(ctx), randomContents()) defer func() { h.mustUpdateObject(obj, ObjectAttrsToUpdate{TemporaryHold: false}) h.mustDeleteObject(obj) h.mustDeleteBucket(bkt) }() attrs := h.mustObjectAttrs(obj) if attrs.TemporaryHold != false { t.Fatalf("got=%v, want=%v", attrs.TemporaryHold, false) } h.mustUpdateObject(obj, ObjectAttrsToUpdate{TemporaryHold: true}) attrs = h.mustObjectAttrs(obj) if attrs.TemporaryHold != true { t.Fatalf("got=%v, want=%v", attrs.TemporaryHold, true) } // Omitting it should leave the value unchanged. h.mustUpdateObject(obj, ObjectAttrsToUpdate{ContentType: "foo"}) attrs = h.mustObjectAttrs(obj) if attrs.TemporaryHold != true { t.Fatalf("got=%v, want=%v", attrs.TemporaryHold, true) } } func TestIntegration_UpdateRetentionExpirationTime(t *testing.T) { ctx := context.Background() client := testConfig(ctx, t) defer client.Close() h := testHelper{t} bkt := client.Bucket(uidSpace.New()) h.mustCreate(bkt, testutil.ProjID(), &BucketAttrs{RetentionPolicy: &RetentionPolicy{RetentionPeriod: time.Hour}}) obj := bkt.Object("some-obj") h.mustWrite(obj.NewWriter(ctx), randomContents()) defer func() { h.mustUpdateBucket(bkt, BucketAttrsToUpdate{RetentionPolicy: &RetentionPolicy{RetentionPeriod: 0}}) // RetentionPeriod of less than a day is explicitly called out // as best effort and not guaranteed, so let's log problems deleting // objects instead of failing. if err := obj.Delete(context.Background()); err != nil { t.Logf("%s: object delete: %v", loc(), err) } if err := bkt.Delete(context.Background()); err != nil { t.Logf("%s: bucket delete: %v", loc(), err) } }() attrs := h.mustObjectAttrs(obj) if attrs.RetentionExpirationTime == (time.Time{}) { t.Fatalf("got=%v, wanted a non-zero value", attrs.RetentionExpirationTime) } } func TestIntegration_UpdateRetentionPolicy(t *testing.T) { t.Skip("https://github.com/googleapis/google-cloud-go/issues/1632") ctx := context.Background() client := testConfig(ctx, t) defer client.Close() h := testHelper{t} initial := &RetentionPolicy{RetentionPeriod: time.Minute} for _, test := range []struct { input *RetentionPolicy want *RetentionPolicy }{ { // Update input: &RetentionPolicy{RetentionPeriod: time.Hour}, want: &RetentionPolicy{RetentionPeriod: time.Hour}, }, { // Update even with timestamp (EffectiveTime should be ignored) input: &RetentionPolicy{RetentionPeriod: time.Hour, EffectiveTime: time.Now()}, want: &RetentionPolicy{RetentionPeriod: time.Hour}, }, { // Remove input: &RetentionPolicy{}, want: nil, }, { // Remove even with timestamp (EffectiveTime should be ignored) input: &RetentionPolicy{EffectiveTime: time.Now()}, want: nil, }, { // Ignore input: nil, want: initial, }, } { bkt := client.Bucket(uidSpace.New()) h.mustCreate(bkt, testutil.ProjID(), &BucketAttrs{RetentionPolicy: initial}) defer h.mustDeleteBucket(bkt) h.mustUpdateBucket(bkt, BucketAttrsToUpdate{RetentionPolicy: test.input}) attrs := h.mustBucketAttrs(bkt) if attrs.RetentionPolicy != nil && attrs.RetentionPolicy.EffectiveTime.Unix() == 0 { // Should be set by the server and parsed by the client t.Fatal("EffectiveTime should be set, but it was not") } if diff := testutil.Diff(attrs.RetentionPolicy, test.want, cmpopts.IgnoreTypes(time.Time{})); diff != "" { t.Errorf("input: %v\ngot=-, want=+:\n%s", test.input, diff) } } } func TestIntegration_DeleteObjectInBucketWithRetentionPolicy(t *testing.T) { t.Skip("https://github.com/googleapis/google-cloud-go/issues/1565") ctx := context.Background() client := testConfig(ctx, t) defer client.Close() h := testHelper{t} bkt := client.Bucket(uidSpace.New()) h.mustCreate(bkt, testutil.ProjID(), &BucketAttrs{RetentionPolicy: &RetentionPolicy{RetentionPeriod: 25 * time.Hour}}) oh := bkt.Object("some-object") if err := writeObject(ctx, oh, "text/plain", []byte("hello world")); err != nil { t.Fatal(err) } if err := oh.Delete(ctx); err == nil { t.Fatal("expected to err deleting an object in a bucket with retention period, but got nil") } // Remove the retention period h.mustUpdateBucket(bkt, BucketAttrsToUpdate{RetentionPolicy: &RetentionPolicy{RetentionPeriod: 0}}) h.mustDeleteObject(oh) h.mustDeleteBucket(bkt) } func TestIntegration_LockBucket(t *testing.T) { ctx := context.Background() client := testConfig(ctx, t) defer client.Close() h := testHelper{t} bkt := client.Bucket(uidSpace.New()) h.mustCreate(bkt, testutil.ProjID(), &BucketAttrs{RetentionPolicy: &RetentionPolicy{RetentionPeriod: time.Hour * 25}}) attrs := h.mustBucketAttrs(bkt) if attrs.RetentionPolicy.IsLocked { t.Fatal("Expected bucket to begin unlocked, but it was not") } err := bkt.If(BucketConditions{MetagenerationMatch: attrs.MetaGeneration}).LockRetentionPolicy(ctx) if err != nil { t.Fatal("could not lock", err) } attrs = h.mustBucketAttrs(bkt) if !attrs.RetentionPolicy.IsLocked { t.Fatal("Expected bucket to be locked, but it was not") } _, err = bkt.Update(ctx, BucketAttrsToUpdate{RetentionPolicy: &RetentionPolicy{RetentionPeriod: time.Hour}}) if err == nil { t.Fatal("Expected error updating locked bucket, got nil") } } func TestIntegration_LockBucket_MetagenerationRequired(t *testing.T) { ctx := context.Background() client := testConfig(ctx, t) defer client.Close() h := testHelper{t} bkt := client.Bucket(uidSpace.New()) h.mustCreate(bkt, testutil.ProjID(), &BucketAttrs{ RetentionPolicy: &RetentionPolicy{RetentionPeriod: time.Hour * 25}, }) err := bkt.LockRetentionPolicy(ctx) if err == nil { t.Fatal("expected error locking bucket without metageneration condition, got nil") } } func TestIntegration_KMS(t *testing.T) { ctx := context.Background() client := testConfig(ctx, t) defer client.Close() h := testHelper{t} keyRingName := os.Getenv("GCLOUD_TESTS_GOLANG_KEYRING") if keyRingName == "" { t.Fatal("GCLOUD_TESTS_GOLANG_KEYRING must be set. See CONTRIBUTING.md for details") } keyName1 := keyRingName + "/cryptoKeys/key1" keyName2 := keyRingName + "/cryptoKeys/key2" contents := []byte("my secret") write := func(obj *ObjectHandle, setKey bool) { w := obj.NewWriter(ctx) if setKey { w.KMSKeyName = keyName1 } h.mustWrite(w, contents) } checkRead := func(obj *ObjectHandle) { got := h.mustRead(obj) if !bytes.Equal(got, contents) { t.Errorf("got %v, want %v", got, contents) } attrs := h.mustObjectAttrs(obj) if len(attrs.KMSKeyName) < len(keyName1) || attrs.KMSKeyName[:len(keyName1)] != keyName1 { t.Errorf("got %q, want %q", attrs.KMSKeyName, keyName1) } } // Write an object with a key, then read it to verify its contents and the presence of the key name. bkt := client.Bucket(bucketName) obj := bkt.Object("kms") write(obj, true) checkRead(obj) h.mustDeleteObject(obj) // Encrypt an object with a CSEK, then copy it using a CMEK. src := bkt.Object("csek").Key(testEncryptionKey) if err := writeObject(ctx, src, "text/plain", contents); err != nil { t.Fatal(err) } dest := bkt.Object("cmek") c := dest.CopierFrom(src) c.DestinationKMSKeyName = keyName1 if _, err := c.Run(ctx); err != nil { t.Fatal(err) } checkRead(dest) src.Delete(ctx) dest.Delete(ctx) // Create a bucket with a default key, then write and read an object. bkt = client.Bucket(uidSpace.New()) h.mustCreate(bkt, testutil.ProjID(), &BucketAttrs{ Location: "US", Encryption: &BucketEncryption{DefaultKMSKeyName: keyName1}, }) defer h.mustDeleteBucket(bkt) attrs := h.mustBucketAttrs(bkt) if got, want := attrs.Encryption.DefaultKMSKeyName, keyName1; got != want { t.Fatalf("got %q, want %q", got, want) } obj = bkt.Object("kms") write(obj, false) checkRead(obj) h.mustDeleteObject(obj) // Update the bucket's default key to a different name. // (This key doesn't have to exist.) attrs = h.mustUpdateBucket(bkt, BucketAttrsToUpdate{Encryption: &BucketEncryption{DefaultKMSKeyName: keyName2}}) if got, want := attrs.Encryption.DefaultKMSKeyName, keyName2; got != want { t.Fatalf("got %q, want %q", got, want) } attrs = h.mustBucketAttrs(bkt) if got, want := attrs.Encryption.DefaultKMSKeyName, keyName2; got != want { t.Fatalf("got %q, want %q", got, want) } // Remove the default KMS key. attrs = h.mustUpdateBucket(bkt, BucketAttrsToUpdate{Encryption: &BucketEncryption{DefaultKMSKeyName: ""}}) if attrs.Encryption != nil { t.Fatalf("got %#v, want nil", attrs.Encryption) } } func TestIntegration_PredefinedACLs(t *testing.T) { check := func(msg string, rs []ACLRule, i int, wantEntity ACLEntity, wantRole ACLRole) { if i >= len(rs) { t.Errorf("%s: no rule at index %d", msg, i) return } got := rs[i] if got.Entity != wantEntity || got.Role != wantRole { t.Errorf("%s[%d]: got %+v, want Entity %s and Role %s", msg, i, got, wantEntity, wantRole) } } checkPrefix := func(msg string, rs []ACLRule, i int, wantPrefix string, wantRole ACLRole) { if i >= len(rs) { t.Errorf("%s: no rule at index %d", msg, i) return } got := rs[i] if !strings.HasPrefix(string(got.Entity), wantPrefix) || got.Role != wantRole { t.Errorf("%s[%d]: got %+v, want Entity %s... and Role %s", msg, i, got, wantPrefix, wantRole) } } ctx := context.Background() client := testConfig(ctx, t) defer client.Close() h := testHelper{t} bkt := client.Bucket(uidSpace.New()) h.mustCreate(bkt, testutil.ProjID(), &BucketAttrs{ PredefinedACL: "authenticatedRead", PredefinedDefaultObjectACL: "publicRead", }) defer h.mustDeleteBucket(bkt) attrs := h.mustBucketAttrs(bkt) checkPrefix("Bucket.ACL", attrs.ACL, 0, "project-owners", RoleOwner) check("Bucket.ACL", attrs.ACL, 1, AllAuthenticatedUsers, RoleReader) check("DefaultObjectACL", attrs.DefaultObjectACL, 0, AllUsers, RoleReader) // Bucket update attrs = h.mustUpdateBucket(bkt, BucketAttrsToUpdate{ PredefinedACL: "private", PredefinedDefaultObjectACL: "authenticatedRead", }) checkPrefix("Bucket.ACL update", attrs.ACL, 0, "project-owners", RoleOwner) check("DefaultObjectACL update", attrs.DefaultObjectACL, 0, AllAuthenticatedUsers, RoleReader) // Object creation obj := bkt.Object("private") w := obj.NewWriter(ctx) w.PredefinedACL = "authenticatedRead" h.mustWrite(w, []byte("hello")) defer h.mustDeleteObject(obj) checkPrefix("Object.ACL", w.Attrs().ACL, 0, "user", RoleOwner) check("Object.ACL", w.Attrs().ACL, 1, AllAuthenticatedUsers, RoleReader) // Object update oattrs := h.mustUpdateObject(obj, ObjectAttrsToUpdate{PredefinedACL: "private"}) checkPrefix("Object.ACL update", oattrs.ACL, 0, "user", RoleOwner) if got := len(oattrs.ACL); got != 1 { t.Errorf("got %d ACLs, want 1", got) } // Copy dst := bkt.Object("dst") copier := dst.CopierFrom(obj) copier.PredefinedACL = "publicRead" oattrs, err := copier.Run(ctx) if err != nil { t.Fatal(err) } defer h.mustDeleteObject(dst) // The copied object still retains the "private" ACL of the source object. checkPrefix("Copy dest", oattrs.ACL, 0, "user", RoleOwner) check("Copy dest", oattrs.ACL, 1, AllUsers, RoleReader) // Compose comp := bkt.Object("comp") composer := comp.ComposerFrom(obj, dst) composer.PredefinedACL = "authenticatedRead" oattrs, err = composer.Run(ctx) if err != nil { t.Fatal(err) } defer h.mustDeleteObject(comp) // The composed object still retains the "private" ACL. checkPrefix("Copy dest", oattrs.ACL, 0, "user", RoleOwner) check("Copy dest", oattrs.ACL, 1, AllAuthenticatedUsers, RoleReader) } func TestIntegration_ServiceAccount(t *testing.T) { ctx := context.Background() client := testConfig(ctx, t) defer client.Close() s, err := client.ServiceAccount(ctx, testutil.ProjID()) if err != nil { t.Fatal(err) } want := "@gs-project-accounts.iam.gserviceaccount.com" if !strings.Contains(s, want) { t.Fatalf("got %v, want to contain %v", s, want) } } func TestIntegration_ReaderAttrs(t *testing.T) { ctx := context.Background() client := testConfig(ctx, t) defer client.Close() bkt := client.Bucket(bucketName) const defaultType = "text/plain" obj := "some-object" c := randomContents() if err := writeObject(ctx, bkt.Object(obj), defaultType, c); err != nil { t.Errorf("Write for %v failed with %v", obj, err) } oh := bkt.Object(obj) rc, err := oh.NewReader(ctx) if err != nil { t.Fatal(err) } attrs, err := oh.Attrs(ctx) if err != nil { t.Fatal(err) } got := rc.Attrs want := ReaderObjectAttrs{ Size: attrs.Size, ContentType: attrs.ContentType, ContentEncoding: attrs.ContentEncoding, CacheControl: attrs.CacheControl, LastModified: got.LastModified, // ignored, tested separately Generation: attrs.Generation, Metageneration: attrs.Metageneration, } if got != want { t.Fatalf("got %v, wanted %v", got, want) } if got.LastModified.IsZero() { t.Fatal("LastModified is 0, should be >0") } } func TestIntegration_HMACKey(t *testing.T) { ctx := context.Background() client := testConfig(ctx, t) defer client.Close() projectID := testutil.ProjID() // Use the service account email from the user's credentials. Requires that the // credentials are set via a JSON credentials file. // Note that a service account may only have up to 5 active HMAC keys at once; if // we see flakes because of this, we should consider switching to using a project // pool. credentials := testutil.CredentialsEnv(ctx, "GCLOUD_TESTS_GOLANG_KEY") if credentials == nil { t.Fatal("credentials could not be determined, is GCLOUD_TESTS_GOLANG_KEY set correctly?") } if credentials.JSON == nil { t.Fatal("could not read the JSON key file, is GCLOUD_TESTS_GOLANG_KEY set correctly?") } conf, err := google.JWTConfigFromJSON(credentials.JSON) if err != nil { t.Fatal(err) } serviceAccountEmail := conf.Email hmacKey, err := client.CreateHMACKey(ctx, projectID, serviceAccountEmail) if err != nil { t.Fatalf("Failed to create HMACKey: %v", err) } if hmacKey == nil { t.Fatal("Unexpectedly got back a nil HMAC key") } if hmacKey.State != Active { t.Fatalf("Unexpected state %q, expected %q", hmacKey.State, Active) } hkh := client.HMACKeyHandle(projectID, hmacKey.AccessID) // 1. Ensure that we CANNOT delete an ACTIVE key. if err := hkh.Delete(ctx); err == nil { t.Fatal("Unexpectedly deleted key whose state is ACTIVE: No error from Delete.") } invalidStates := []HMACState{"", Deleted, "active", "inactive", "foo_bar"} for _, invalidState := range invalidStates { t.Run("invalid-"+string(invalidState), func(t *testing.T) { _, err := hkh.Update(ctx, HMACKeyAttrsToUpdate{ State: invalidState, }) if err == nil { t.Fatal("Unexpectedly succeeded") } invalidStateMsg := fmt.Sprintf(`storage: invalid state %q for update, must be either "ACTIVE" or "INACTIVE"`, invalidState) if err.Error() != invalidStateMsg { t.Fatalf("Mismatched error: got: %q\nwant: %q", err, invalidStateMsg) } }) } // 2.1. Setting the State to Inactive should succeed. hu, err := hkh.Update(ctx, HMACKeyAttrsToUpdate{ State: Inactive, }) if err != nil { t.Fatalf("Unexpected Update failure: %v", err) } if got, want := hu.State, Inactive; got != want { t.Fatalf("Unexpected updated state %q, expected %q", got, want) } // 2.2. Setting the State back to Active should succeed. hu, err = hkh.Update(ctx, HMACKeyAttrsToUpdate{ State: Active, }) if err != nil { t.Fatalf("Unexpected Update failure: %v", err) } if got, want := hu.State, Active; got != want { t.Fatalf("Unexpected updated state %q, expected %q", got, want) } // 3. Verify that keys are listed as expected. iter := client.ListHMACKeys(ctx, projectID) count := 0 for ; ; count++ { _, err := iter.Next() if err == iterator.Done { break } if err != nil { t.Fatalf("Failed to ListHMACKeys: %v", err) } } if count == 0 { t.Fatal("Failed to list any HMACKeys") } // 4. Finally set it to back to Inactive and // then retry the deletion which should now succeed. _, _ = hkh.Update(ctx, HMACKeyAttrsToUpdate{ State: Inactive, }) if err := hkh.Delete(ctx); err != nil { t.Fatalf("Unexpected deletion failure: %v", err) } hk, err := hkh.Get(ctx) switch { case err == nil: // If the err == nil, then the returned HMACKey's state MUST be Deleted. if hk == nil || hk.State != Deleted { t.Fatalf("After deletion\nGot %#v\nWanted state %q", hk, Deleted) } case err.Error() != "foo": t.Fatalf("Unexpected error: %v", err) } } type testHelper struct { t *testing.T } func (h testHelper) mustCreate(b *BucketHandle, projID string, attrs *BucketAttrs) { if err := b.Create(context.Background(), projID, attrs); err != nil { h.t.Fatalf("%s: bucket create: %v", loc(), err) } } func (h testHelper) mustDeleteBucket(b *BucketHandle) { if err := b.Delete(context.Background()); err != nil { h.t.Fatalf("%s: bucket delete: %v", loc(), err) } } func (h testHelper) mustBucketAttrs(b *BucketHandle) *BucketAttrs { attrs, err := b.Attrs(context.Background()) if err != nil { h.t.Fatalf("%s: bucket attrs: %v", loc(), err) } return attrs } func (h testHelper) mustUpdateBucket(b *BucketHandle, ua BucketAttrsToUpdate) *BucketAttrs { attrs, err := b.Update(context.Background(), ua) if err != nil { h.t.Fatalf("%s: update: %v", loc(), err) } return attrs } func (h testHelper) mustObjectAttrs(o *ObjectHandle) *ObjectAttrs { attrs, err := o.Attrs(context.Background()) if err != nil { h.t.Fatalf("%s: object attrs: %v", loc(), err) } return attrs } func (h testHelper) mustDeleteObject(o *ObjectHandle) { if err := o.Delete(context.Background()); err != nil { h.t.Fatalf("%s: object delete: %v", loc(), err) } } func (h testHelper) mustUpdateObject(o *ObjectHandle, ua ObjectAttrsToUpdate) *ObjectAttrs { attrs, err := o.Update(context.Background(), ua) if err != nil { h.t.Fatalf("%s: update: %v", loc(), err) } return attrs } func (h testHelper) mustWrite(w *Writer, data []byte) { if _, err := w.Write(data); err != nil { w.Close() h.t.Fatalf("%s: write: %v", loc(), err) } if err := w.Close(); err != nil { h.t.Fatalf("%s: close write: %v", loc(), err) } } func (h testHelper) mustRead(obj *ObjectHandle) []byte { data, err := readObject(context.Background(), obj) if err != nil { h.t.Fatalf("%s: read: %v", loc(), err) } return data } func (h testHelper) mustNewReader(obj *ObjectHandle) *Reader { r, err := obj.NewReader(context.Background()) if err != nil { h.t.Fatalf("%s: new reader: %v", loc(), err) } return r } func writeObject(ctx context.Context, obj *ObjectHandle, contentType string, contents []byte) error { w := obj.NewWriter(ctx) w.ContentType = contentType w.CacheControl = "public, max-age=60" if contents != nil { if _, err := w.Write(contents); err != nil { _ = w.Close() return err } } return w.Close() } // loc returns a string describing the file and line of its caller's call site. In // other words, if a test function calls a helper, and the helper calls loc, then the // string will refer to the line on which the test function called the helper. // TODO(jba): use t.Helper once we drop go 1.6. func loc() string { _, file, line, ok := runtime.Caller(2) if !ok { return "???" } return fmt.Sprintf("%s:%d", filepath.Base(file), line) } func readObject(ctx context.Context, obj *ObjectHandle) ([]byte, error) { r, err := obj.NewReader(ctx) if err != nil { return nil, err } defer r.Close() return ioutil.ReadAll(r) } // cleanupBuckets deletes the bucket used for testing, as well as old // testing buckets that weren't cleaned previously. func cleanupBuckets() error { if testing.Short() { return nil // Don't clean up in short mode. } ctx := context.Background() client := config(ctx) if client == nil { return nil // Don't cleanup if we're not configured correctly. } defer client.Close() if err := killBucket(ctx, client, bucketName); err != nil { return err } // Delete buckets whose name begins with our test prefix, and which were // created a while ago. (Unfortunately GCS doesn't provide last-modified // time, which would be a better way to check for staleness.) const expireAge = 24 * time.Hour projectID := testutil.ProjID() it := client.Buckets(ctx, projectID) it.Prefix = testPrefix for { bktAttrs, err := it.Next() if err == iterator.Done { break } if err != nil { return err } if time.Since(bktAttrs.Created) > expireAge { log.Printf("deleting bucket %q, which is more than %s old", bktAttrs.Name, expireAge) if err := killBucket(ctx, client, bktAttrs.Name); err != nil { return err } } } return nil } // killBucket deletes a bucket and all its objects. func killBucket(ctx context.Context, client *Client, bucketName string) error { bkt := client.Bucket(bucketName) // Bucket must be empty to delete. it := bkt.Objects(ctx, nil) for { objAttrs, err := it.Next() if err == iterator.Done { break } if err != nil { return err } // Objects with a hold must have the hold released. if objAttrs.EventBasedHold || objAttrs.TemporaryHold { obj := bkt.Object(objAttrs.Name) if _, err := obj.Update(ctx, ObjectAttrsToUpdate{EventBasedHold: false, TemporaryHold: false}); err != nil { fmt.Errorf("removing hold from %q: %v", bucketName+"/"+objAttrs.Name, err) } } if err := bkt.Object(objAttrs.Name).Delete(ctx); err != nil { return fmt.Errorf("deleting %q: %v", bucketName+"/"+objAttrs.Name, err) } } // GCS is eventually consistent, so this delete may fail because the // replica still sees an object in the bucket. We log the error and expect // a later test run to delete the bucket. if err := bkt.Delete(ctx); err != nil { log.Printf("deleting %q: %v", bucketName, err) } return nil } func randomContents() []byte { h := md5.New() io.WriteString(h, fmt.Sprintf("hello world%d", rng.Intn(100000))) return h.Sum(nil) } type zeros struct{} func (zeros) Read(p []byte) (int, error) { return len(p), nil } google-cloud-go-0.49.0/storage/internal/000077500000000000000000000000001356504100700200505ustar00rootroot00000000000000google-cloud-go-0.49.0/storage/internal/benchwrapper/000077500000000000000000000000001356504100700225305ustar00rootroot00000000000000google-cloud-go-0.49.0/storage/internal/benchwrapper/README.md000066400000000000000000000004141356504100700240060ustar00rootroot00000000000000# Benchwrapper A small gRPC wrapper around the storage client library. This allows the benchmarking code to prod at storage without speaking Go. ## Running ``` cd storage/internal/benchwrapper export STORAGE_EMULATOR_HOST=localhost:8080 go run *.go --port=8081 ``` google-cloud-go-0.49.0/storage/internal/benchwrapper/main.go000066400000000000000000000052471356504100700240130ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package main wraps the client library in a gRPC interface that a benchmarker can communicate through. package main import ( "context" "flag" "fmt" "io" "io/ioutil" "log" "net" "os" "cloud.google.com/go/storage" pb "cloud.google.com/go/storage/internal/benchwrapper/proto" "google.golang.org/grpc" ) var port = flag.String("port", "", "specify a port to run on") // minRead respresents the number of bytes to read at a time. const minRead = 1024 * 1024 func main() { flag.Parse() if *port == "" { log.Fatalf("usage: %s --port=8081", os.Args[0]) } if os.Getenv("STORAGE_EMULATOR_HOST") == "" { log.Fatal("This benchmarking server only works when connected to an emulator. Please set STORAGE_EMULATOR_HOST.") } ctx := context.Background() c, err := storage.NewClient(ctx) if err != nil { log.Fatal(err) } lis, err := net.Listen("tcp", fmt.Sprintf(":%s", *port)) if err != nil { log.Fatal(err) } s := grpc.NewServer() pb.RegisterStorageBenchWrapperServer(s, &server{ c: c, }) log.Printf("Running on localhost:%s\n", *port) log.Fatal(s.Serve(lis)) } type server struct { c *storage.Client } func (s *server) Read(ctx context.Context, in *pb.ObjectRead) (*pb.EmptyResponse, error) { b := s.c.Bucket(in.GetBucketName()) o := b.Object(in.GetObjectName()) r, err := o.NewReader(ctx) if err != nil { return nil, err } defer r.Close() for int(r.Remain()) > 0 { ba := make([]byte, minRead) _, err := r.Read(ba) if err == io.EOF { return &pb.EmptyResponse{}, nil } if err != nil { return nil, err } } return &pb.EmptyResponse{}, nil } func (s *server) Write(ctx context.Context, in *pb.ObjectWrite) (*pb.EmptyResponse, error) { b := s.c.Bucket(in.GetBucketName()) o := b.Object(in.GetObjectName()) w := o.NewWriter(ctx) content, err := ioutil.ReadFile(in.GetDestination()) if err != nil { return nil, err } w.ContentType = "text/plain" if _, err := w.Write([]byte(content)); err != nil { return nil, err } if err := w.Close(); err != nil { if err == io.EOF { return &pb.EmptyResponse{}, nil } return nil, err } return &pb.EmptyResponse{}, nil } google-cloud-go-0.49.0/storage/internal/benchwrapper/proto/000077500000000000000000000000001356504100700236735ustar00rootroot00000000000000google-cloud-go-0.49.0/storage/internal/benchwrapper/proto/README.md000066400000000000000000000001541356504100700251520ustar00rootroot00000000000000# Regenerating protos ``` cd storage/internal/benchwrapper/proto protoc --go_out=plugins=grpc:. *.proto ```google-cloud-go-0.49.0/storage/internal/benchwrapper/proto/storage.pb.go000066400000000000000000000243371356504100700262770ustar00rootroot00000000000000// Code generated by protoc-gen-go. DO NOT EDIT. // source: storage.proto package storage_bench import ( context "context" fmt "fmt" math "math" proto "github.com/golang/protobuf/proto" grpc "google.golang.org/grpc" ) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal var _ = fmt.Errorf var _ = math.Inf // This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package type ObjectRead struct { // The bucket string identifier. BucketName string `protobuf:"bytes,1,opt,name=bucketName,proto3" json:"bucketName,omitempty"` // The object/blob string identifier. ObjectName string `protobuf:"bytes,2,opt,name=objectName,proto3" json:"objectName,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *ObjectRead) Reset() { *m = ObjectRead{} } func (m *ObjectRead) String() string { return proto.CompactTextString(m) } func (*ObjectRead) ProtoMessage() {} func (*ObjectRead) Descriptor() ([]byte, []int) { return fileDescriptor_0d2c4ccf1453ffdb, []int{0} } func (m *ObjectRead) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ObjectRead.Unmarshal(m, b) } func (m *ObjectRead) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ObjectRead.Marshal(b, m, deterministic) } func (m *ObjectRead) XXX_Merge(src proto.Message) { xxx_messageInfo_ObjectRead.Merge(m, src) } func (m *ObjectRead) XXX_Size() int { return xxx_messageInfo_ObjectRead.Size(m) } func (m *ObjectRead) XXX_DiscardUnknown() { xxx_messageInfo_ObjectRead.DiscardUnknown(m) } var xxx_messageInfo_ObjectRead proto.InternalMessageInfo func (m *ObjectRead) GetBucketName() string { if m != nil { return m.BucketName } return "" } func (m *ObjectRead) GetObjectName() string { if m != nil { return m.ObjectName } return "" } type ObjectWrite struct { // The bucket string identifier. BucketName string `protobuf:"bytes,1,opt,name=bucketName,proto3" json:"bucketName,omitempty"` // The object/blob string identifiers. ObjectName string `protobuf:"bytes,2,opt,name=objectName,proto3" json:"objectName,omitempty"` // The string containing the destination path. Destination string `protobuf:"bytes,3,opt,name=destination,proto3" json:"destination,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *ObjectWrite) Reset() { *m = ObjectWrite{} } func (m *ObjectWrite) String() string { return proto.CompactTextString(m) } func (*ObjectWrite) ProtoMessage() {} func (*ObjectWrite) Descriptor() ([]byte, []int) { return fileDescriptor_0d2c4ccf1453ffdb, []int{1} } func (m *ObjectWrite) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ObjectWrite.Unmarshal(m, b) } func (m *ObjectWrite) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ObjectWrite.Marshal(b, m, deterministic) } func (m *ObjectWrite) XXX_Merge(src proto.Message) { xxx_messageInfo_ObjectWrite.Merge(m, src) } func (m *ObjectWrite) XXX_Size() int { return xxx_messageInfo_ObjectWrite.Size(m) } func (m *ObjectWrite) XXX_DiscardUnknown() { xxx_messageInfo_ObjectWrite.DiscardUnknown(m) } var xxx_messageInfo_ObjectWrite proto.InternalMessageInfo func (m *ObjectWrite) GetBucketName() string { if m != nil { return m.BucketName } return "" } func (m *ObjectWrite) GetObjectName() string { if m != nil { return m.ObjectName } return "" } func (m *ObjectWrite) GetDestination() string { if m != nil { return m.Destination } return "" } type EmptyResponse struct { XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *EmptyResponse) Reset() { *m = EmptyResponse{} } func (m *EmptyResponse) String() string { return proto.CompactTextString(m) } func (*EmptyResponse) ProtoMessage() {} func (*EmptyResponse) Descriptor() ([]byte, []int) { return fileDescriptor_0d2c4ccf1453ffdb, []int{2} } func (m *EmptyResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_EmptyResponse.Unmarshal(m, b) } func (m *EmptyResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_EmptyResponse.Marshal(b, m, deterministic) } func (m *EmptyResponse) XXX_Merge(src proto.Message) { xxx_messageInfo_EmptyResponse.Merge(m, src) } func (m *EmptyResponse) XXX_Size() int { return xxx_messageInfo_EmptyResponse.Size(m) } func (m *EmptyResponse) XXX_DiscardUnknown() { xxx_messageInfo_EmptyResponse.DiscardUnknown(m) } var xxx_messageInfo_EmptyResponse proto.InternalMessageInfo func init() { proto.RegisterType((*ObjectRead)(nil), "storage_bench.ObjectRead") proto.RegisterType((*ObjectWrite)(nil), "storage_bench.ObjectWrite") proto.RegisterType((*EmptyResponse)(nil), "storage_bench.EmptyResponse") } func init() { proto.RegisterFile("storage.proto", fileDescriptor_0d2c4ccf1453ffdb) } var fileDescriptor_0d2c4ccf1453ffdb = []byte{ // 208 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x2d, 0x2e, 0xc9, 0x2f, 0x4a, 0x4c, 0x4f, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x82, 0x71, 0xe3, 0x93, 0x52, 0xf3, 0x92, 0x33, 0x94, 0x7c, 0xb8, 0xb8, 0xfc, 0x93, 0xb2, 0x52, 0x93, 0x4b, 0x82, 0x52, 0x13, 0x53, 0x84, 0xe4, 0xb8, 0xb8, 0x92, 0x4a, 0x93, 0xb3, 0x53, 0x4b, 0xfc, 0x12, 0x73, 0x53, 0x25, 0x18, 0x15, 0x18, 0x35, 0x38, 0x83, 0x90, 0x44, 0x40, 0xf2, 0xf9, 0x60, 0xd5, 0x60, 0x79, 0x26, 0x88, 0x3c, 0x42, 0x44, 0x29, 0x9f, 0x8b, 0x1b, 0x62, 0x5a, 0x78, 0x51, 0x66, 0x49, 0x2a, 0xa5, 0xc6, 0x09, 0x29, 0x70, 0x71, 0xa7, 0xa4, 0x16, 0x97, 0x64, 0xe6, 0x25, 0x96, 0x64, 0xe6, 0xe7, 0x49, 0x30, 0x83, 0x15, 0x20, 0x0b, 0x29, 0xf1, 0x73, 0xf1, 0xba, 0xe6, 0x16, 0x94, 0x54, 0x06, 0xa5, 0x16, 0x17, 0xe4, 0xe7, 0x15, 0xa7, 0x1a, 0xcd, 0x65, 0xe4, 0x12, 0x0e, 0x86, 0xf8, 0xd0, 0x09, 0xe4, 0xc1, 0xf0, 0xa2, 0xc4, 0x82, 0x82, 0xd4, 0x22, 0x21, 0x67, 0x2e, 0x56, 0x88, 0x9b, 0xa4, 0xf4, 0x50, 0x02, 0x40, 0x0f, 0xc9, 0xbd, 0x52, 0x32, 0x68, 0x72, 0x28, 0x46, 0x2b, 0x31, 0x08, 0x39, 0x72, 0xb1, 0x80, 0x83, 0x49, 0x12, 0xab, 0x19, 0x20, 0x29, 0x42, 0x46, 0x24, 0xb1, 0x81, 0x63, 0xc1, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0xb3, 0xe8, 0x1e, 0xa7, 0x96, 0x01, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. var _ context.Context var _ grpc.ClientConn // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. const _ = grpc.SupportPackageIsVersion4 // StorageBenchWrapperClient is the client API for StorageBenchWrapper service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type StorageBenchWrapperClient interface { // Performs an upload from a specific object. Write(ctx context.Context, in *ObjectWrite, opts ...grpc.CallOption) (*EmptyResponse, error) // Read a specific object. Read(ctx context.Context, in *ObjectRead, opts ...grpc.CallOption) (*EmptyResponse, error) } type storageBenchWrapperClient struct { cc *grpc.ClientConn } func NewStorageBenchWrapperClient(cc *grpc.ClientConn) StorageBenchWrapperClient { return &storageBenchWrapperClient{cc} } func (c *storageBenchWrapperClient) Write(ctx context.Context, in *ObjectWrite, opts ...grpc.CallOption) (*EmptyResponse, error) { out := new(EmptyResponse) err := c.cc.Invoke(ctx, "/storage_bench.StorageBenchWrapper/Write", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *storageBenchWrapperClient) Read(ctx context.Context, in *ObjectRead, opts ...grpc.CallOption) (*EmptyResponse, error) { out := new(EmptyResponse) err := c.cc.Invoke(ctx, "/storage_bench.StorageBenchWrapper/Read", in, out, opts...) if err != nil { return nil, err } return out, nil } // StorageBenchWrapperServer is the server API for StorageBenchWrapper service. type StorageBenchWrapperServer interface { // Performs an upload from a specific object. Write(context.Context, *ObjectWrite) (*EmptyResponse, error) // Read a specific object. Read(context.Context, *ObjectRead) (*EmptyResponse, error) } func RegisterStorageBenchWrapperServer(s *grpc.Server, srv StorageBenchWrapperServer) { s.RegisterService(&_StorageBenchWrapper_serviceDesc, srv) } func _StorageBenchWrapper_Write_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ObjectWrite) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(StorageBenchWrapperServer).Write(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/storage_bench.StorageBenchWrapper/Write", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(StorageBenchWrapperServer).Write(ctx, req.(*ObjectWrite)) } return interceptor(ctx, in, info, handler) } func _StorageBenchWrapper_Read_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ObjectRead) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(StorageBenchWrapperServer).Read(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/storage_bench.StorageBenchWrapper/Read", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(StorageBenchWrapperServer).Read(ctx, req.(*ObjectRead)) } return interceptor(ctx, in, info, handler) } var _StorageBenchWrapper_serviceDesc = grpc.ServiceDesc{ ServiceName: "storage_bench.StorageBenchWrapper", HandlerType: (*StorageBenchWrapperServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "Write", Handler: _StorageBenchWrapper_Write_Handler, }, { MethodName: "Read", Handler: _StorageBenchWrapper_Read_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "storage.proto", } google-cloud-go-0.49.0/storage/internal/benchwrapper/proto/storage.proto000066400000000000000000000023321356504100700264240ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. syntax = "proto3"; package storage_bench; message ObjectRead{ // The bucket string identifier. string bucketName = 1; // The object/blob string identifier. string objectName = 2; } message ObjectWrite{ // The bucket string identifier. string bucketName = 1; // The object/blob string identifiers. string objectName = 2; // The string containing the upload file path. string destination = 3; } message EmptyResponse{ } service StorageBenchWrapper{ // Performs an upload from a specific object. rpc Write(ObjectWrite) returns (EmptyResponse) {} // Read a specific object. rpc Read(ObjectRead) returns (EmptyResponse){} } google-cloud-go-0.49.0/storage/internal/test/000077500000000000000000000000001356504100700210275ustar00rootroot00000000000000google-cloud-go-0.49.0/storage/internal/test/conformance/000077500000000000000000000000001356504100700233215ustar00rootroot00000000000000google-cloud-go-0.49.0/storage/internal/test/conformance/README.md000066400000000000000000000003561356504100700246040ustar00rootroot00000000000000# Conformance tests These conformance tests are developed in https://github.com/googleapis/conformance-tests/ and then copied here when prompted that new tests are available. ### Generating test.pb.go ``` protoc --go_out=. *.proto ``` google-cloud-go-0.49.0/storage/internal/test/conformance/service-account000066400000000000000000000046501356504100700263430ustar00rootroot00000000000000{ "comment": "This is a dummy service account JSON file that is inactive. It's fine for it to be public.", "type": "service_account", "project_id": "dummy-project-id", "private_key_id": "ffffffffffffffffffffffffffffffffffffffff", "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCsPzMirIottfQ2\nryjQmPWocSEeGo7f7Q4/tMQXHlXFzo93AGgU2t+clEj9L5loNhLVq+vk+qmnyDz5\nQ04y8jVWyMYzzGNNrGRW/yaYqnqlKZCy1O3bmnNjV7EDbC/jE1ZLBY0U3HaSHfn6\nS9ND8MXdgD0/ulRTWwq6vU8/w6i5tYsU7n2LLlQTl1fQ7/emO9nYcCFJezHZVa0H\nmeWsdHwWsok0skwQYQNIzP3JF9BpR5gJT2gNge6KopDesJeLoLzaX7cUnDn+CAnn\nLuLDwwSsIVKyVxhBFsFXPplgpaQRwmGzwEbf/Xpt9qo26w2UMgn30jsOaKlSeAX8\ncS6ViF+tAgMBAAECggEACKRuJCP8leEOhQziUx8Nmls8wmYqO4WJJLyk5xUMUC22\nSI4CauN1e0V8aQmxnIc0CDkFT7qc9xBmsMoF+yvobbeKrFApvlyzNyM7tEa/exh8\nDGD/IzjbZ8VfWhDcUTwn5QE9DCoon9m1sG+MBNlokB3OVOt8LieAAREdEBG43kJu\nyQTOkY9BGR2AY1FnAl2VZ/jhNDyrme3tp1sW1BJrawzR7Ujo8DzlVcS2geKA9at7\n55ua5GbHz3hfzFgjVXDfnkWzId6aHypUyqHrSn1SqGEbyXTaleKTc6Pgv0PgkJjG\nhZazWWdSuf1T5Xbs0OhAK9qraoAzT6cXXvMEvvPt6QKBgQDXcZKqJAOnGEU4b9+v\nOdoh+nssdrIOBNMu1m8mYbUVYS1aakc1iDGIIWNM3qAwbG+yNEIi2xi80a2RMw2T\n9RyCNB7yqCXXVKLBiwg9FbKMai6Vpk2bWIrzahM9on7AhCax/X2AeOp+UyYhFEy6\nUFG4aHb8THscL7b515ukSuKb5QKBgQDMq+9PuaB0eHsrmL6q4vHNi3MLgijGg/zu\nAXaPygSYAwYW8KglcuLZPvWrL6OG0+CrfmaWTLsyIZO4Uhdj7MLvX6yK7IMnagvk\nL3xjgxSklEHJAwi5wFeJ8ai/1MIuCn8p2re3CbwISKpvf7Sgs/W4196P4vKvTiAz\njcTiSYFIKQKBgCjMpkS4O0TakMlGTmsFnqyOneLmu4NyIHgfPb9cA4n/9DHKLKAT\noaWxBPgatOVWs7RgtyGYsk+XubHkpC6f3X0+15mGhFwJ+CSE6tN+l2iF9zp52vqP\nQwkjzm7+pdhZbmaIpcq9m1K+9lqPWJRz/3XXuqi+5xWIZ7NaxGvRjqaNAoGAdK2b\nutZ2y48XoI3uPFsuP+A8kJX+CtWZrlE1NtmS7tnicdd19AtfmTuUL6fz0FwfW4Su\nlQZfPT/5B339CaEiq/Xd1kDor+J7rvUHM2+5p+1A54gMRGCLRv92FQ4EON0RC1o9\nm2I4SHysdO3XmjmdXmfp4BsgAKJIJzutvtbqlakCgYB+Cb10z37NJJ+WgjDt+yT2\nyUNH17EAYgWXryfRgTyi2POHuJitd64Xzuy6oBVs3wVveYFM6PIKXlj8/DahYX5I\nR2WIzoCNLL3bEZ+nC6Jofpb4kspoAeRporj29SgesK6QBYWHWX2H645RkRGYGpDo\n51gjy9m/hSNqBbH2zmh04A==\n-----END PRIVATE KEY-----\n", "client_email": "test-iam-credentials@dummy-project-id.iam.gserviceaccount.com", "client_id": "000000000000000000000", "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token", "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/test-iam-credentials%40dummy-project-id.iam.gserviceaccount.com" } google-cloud-go-0.49.0/storage/internal/test/conformance/test.pb.go000066400000000000000000000166721356504100700252430ustar00rootroot00000000000000// Code generated by protoc-gen-go. DO NOT EDIT. // source: test.proto package storage_v1_tests import ( fmt "fmt" proto "github.com/golang/protobuf/proto" math "math" timestamp "github.com/golang/protobuf/ptypes/timestamp" ) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal var _ = fmt.Errorf var _ = math.Inf // This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package type TestFile struct { SigningV4Tests []*SigningV4Test `protobuf:"bytes,1,rep,name=signing_v4_tests,json=signingV4Tests,proto3" json:"signing_v4_tests,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *TestFile) Reset() { *m = TestFile{} } func (m *TestFile) String() string { return proto.CompactTextString(m) } func (*TestFile) ProtoMessage() {} func (*TestFile) Descriptor() ([]byte, []int) { return fileDescriptor_test_7c0b908fadc4a1ba, []int{0} } func (m *TestFile) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_TestFile.Unmarshal(m, b) } func (m *TestFile) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_TestFile.Marshal(b, m, deterministic) } func (dst *TestFile) XXX_Merge(src proto.Message) { xxx_messageInfo_TestFile.Merge(dst, src) } func (m *TestFile) XXX_Size() int { return xxx_messageInfo_TestFile.Size(m) } func (m *TestFile) XXX_DiscardUnknown() { xxx_messageInfo_TestFile.DiscardUnknown(m) } var xxx_messageInfo_TestFile proto.InternalMessageInfo func (m *TestFile) GetSigningV4Tests() []*SigningV4Test { if m != nil { return m.SigningV4Tests } return nil } type SigningV4Test struct { FileName string `protobuf:"bytes,1,opt,name=fileName,proto3" json:"fileName,omitempty"` Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` Bucket string `protobuf:"bytes,3,opt,name=bucket,proto3" json:"bucket,omitempty"` Object string `protobuf:"bytes,4,opt,name=object,proto3" json:"object,omitempty"` Method string `protobuf:"bytes,5,opt,name=method,proto3" json:"method,omitempty"` Expiration int64 `protobuf:"varint,6,opt,name=expiration,proto3" json:"expiration,omitempty"` Timestamp *timestamp.Timestamp `protobuf:"bytes,7,opt,name=timestamp,proto3" json:"timestamp,omitempty"` ExpectedUrl string `protobuf:"bytes,8,opt,name=expectedUrl,proto3" json:"expectedUrl,omitempty"` Headers map[string]string `protobuf:"bytes,9,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } func (m *SigningV4Test) Reset() { *m = SigningV4Test{} } func (m *SigningV4Test) String() string { return proto.CompactTextString(m) } func (*SigningV4Test) ProtoMessage() {} func (*SigningV4Test) Descriptor() ([]byte, []int) { return fileDescriptor_test_7c0b908fadc4a1ba, []int{1} } func (m *SigningV4Test) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SigningV4Test.Unmarshal(m, b) } func (m *SigningV4Test) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SigningV4Test.Marshal(b, m, deterministic) } func (dst *SigningV4Test) XXX_Merge(src proto.Message) { xxx_messageInfo_SigningV4Test.Merge(dst, src) } func (m *SigningV4Test) XXX_Size() int { return xxx_messageInfo_SigningV4Test.Size(m) } func (m *SigningV4Test) XXX_DiscardUnknown() { xxx_messageInfo_SigningV4Test.DiscardUnknown(m) } var xxx_messageInfo_SigningV4Test proto.InternalMessageInfo func (m *SigningV4Test) GetFileName() string { if m != nil { return m.FileName } return "" } func (m *SigningV4Test) GetDescription() string { if m != nil { return m.Description } return "" } func (m *SigningV4Test) GetBucket() string { if m != nil { return m.Bucket } return "" } func (m *SigningV4Test) GetObject() string { if m != nil { return m.Object } return "" } func (m *SigningV4Test) GetMethod() string { if m != nil { return m.Method } return "" } func (m *SigningV4Test) GetExpiration() int64 { if m != nil { return m.Expiration } return 0 } func (m *SigningV4Test) GetTimestamp() *timestamp.Timestamp { if m != nil { return m.Timestamp } return nil } func (m *SigningV4Test) GetExpectedUrl() string { if m != nil { return m.ExpectedUrl } return "" } func (m *SigningV4Test) GetHeaders() map[string]string { if m != nil { return m.Headers } return nil } func init() { proto.RegisterType((*TestFile)(nil), "storage.v1.tests.TestFile") proto.RegisterType((*SigningV4Test)(nil), "storage.v1.tests.SigningV4Test") proto.RegisterMapType((map[string]string)(nil), "storage.v1.tests.SigningV4Test.HeadersEntry") } func init() { proto.RegisterFile("test.proto", fileDescriptor_test_7c0b908fadc4a1ba) } var fileDescriptor_test_7c0b908fadc4a1ba = []byte{ // 337 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x90, 0x4d, 0x4f, 0xf2, 0x40, 0x14, 0x85, 0x53, 0xfa, 0xf2, 0x75, 0x79, 0x35, 0x64, 0x62, 0xcc, 0xa4, 0x0b, 0x69, 0x58, 0x75, 0x61, 0x86, 0x88, 0x2c, 0x08, 0x7b, 0x89, 0x6e, 0x5c, 0x54, 0x70, 0x4b, 0xfa, 0x71, 0x29, 0x23, 0x6d, 0xa7, 0xe9, 0x0c, 0x04, 0x7e, 0x88, 0xff, 0xd7, 0x74, 0x06, 0xb0, 0xba, 0x71, 0x37, 0xe7, 0x39, 0xe7, 0xde, 0xc9, 0x3d, 0x00, 0x0a, 0xa5, 0x62, 0x45, 0x29, 0x94, 0x20, 0x7d, 0xa9, 0x44, 0x19, 0x24, 0xc8, 0xf6, 0x0f, 0xac, 0xc2, 0xd2, 0x19, 0x24, 0x42, 0x24, 0x29, 0x8e, 0xb4, 0x1f, 0xee, 0xd6, 0x23, 0xc5, 0x33, 0x94, 0x2a, 0xc8, 0x0a, 0x33, 0x32, 0x5c, 0x42, 0x67, 0x81, 0x52, 0xcd, 0x79, 0x8a, 0xe4, 0x05, 0xfa, 0x92, 0x27, 0x39, 0xcf, 0x93, 0xd5, 0x7e, 0xb2, 0xd2, 0x0b, 0xa8, 0xe5, 0xda, 0x5e, 0x6f, 0x3c, 0x60, 0xbf, 0x37, 0xb3, 0x37, 0x93, 0x7c, 0x9f, 0x54, 0xe3, 0xfe, 0xb5, 0xac, 0x4b, 0x39, 0xfc, 0xb4, 0xe1, 0xea, 0x47, 0x82, 0x38, 0xd0, 0x59, 0xf3, 0x14, 0x5f, 0x83, 0x0c, 0xa9, 0xe5, 0x5a, 0x5e, 0xd7, 0xbf, 0x68, 0xe2, 0x42, 0x2f, 0x46, 0x19, 0x95, 0xbc, 0x50, 0x5c, 0xe4, 0xb4, 0xa1, 0xed, 0x3a, 0x22, 0xb7, 0xd0, 0x0a, 0x77, 0xd1, 0x16, 0x15, 0xb5, 0xb5, 0x79, 0x52, 0x15, 0x17, 0xe1, 0x07, 0x46, 0x8a, 0xfe, 0x33, 0xdc, 0xa8, 0x8a, 0x67, 0xa8, 0x36, 0x22, 0xa6, 0x4d, 0xc3, 0x8d, 0x22, 0x77, 0x00, 0x78, 0x28, 0x78, 0x19, 0xe8, 0x8f, 0x5a, 0xae, 0xe5, 0xd9, 0x7e, 0x8d, 0x90, 0x29, 0x74, 0x2f, 0x0d, 0xd1, 0xb6, 0x6b, 0x79, 0xbd, 0xb1, 0xc3, 0x4c, 0x87, 0xec, 0xdc, 0x21, 0x5b, 0x9c, 0x13, 0xfe, 0x77, 0xb8, 0xba, 0x01, 0x0f, 0x05, 0x46, 0x0a, 0xe3, 0x65, 0x99, 0xd2, 0x8e, 0xb9, 0xa1, 0x86, 0xc8, 0x1c, 0xda, 0x1b, 0x0c, 0x62, 0x2c, 0x25, 0xed, 0xea, 0x56, 0xef, 0xff, 0x68, 0x95, 0x3d, 0x9b, 0xf8, 0x53, 0xae, 0xca, 0xa3, 0x7f, 0x1e, 0x76, 0x66, 0xf0, 0xbf, 0x6e, 0x90, 0x3e, 0xd8, 0x5b, 0x3c, 0x9e, 0x4a, 0xad, 0x9e, 0xe4, 0x06, 0x9a, 0xfb, 0x20, 0xdd, 0xe1, 0xa9, 0x49, 0x23, 0x66, 0x8d, 0xa9, 0x15, 0xb6, 0xf4, 0x11, 0x8f, 0x5f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x36, 0x21, 0xc6, 0x48, 0x36, 0x02, 0x00, 0x00, } google-cloud-go-0.49.0/storage/internal/test/conformance/test.proto000066400000000000000000000020131356504100700253610ustar00rootroot00000000000000// Copyright 2019, Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. syntax = "proto3"; package storage.v1.tests; import "google/protobuf/timestamp.proto"; message TestFile { repeated SigningV4Test signing_v4_tests = 1; } message SigningV4Test { string fileName = 1; string description = 2; string bucket = 3; string object = 4; string method = 5; int64 expiration = 6; google.protobuf.Timestamp timestamp = 7; string expectedUrl = 8; map headers = 9; } google-cloud-go-0.49.0/storage/internal/test/conformance/v4_signatures.json000066400000000000000000000262231356504100700270160ustar00rootroot00000000000000{ "signingV4Tests": [ { "description": "Simple GET", "bucket": "test-bucket", "object": "test-object", "method": "GET", "expiration": "10", "timestamp": "2019-02-01T09:00:00Z", "expectedUrl": "https://storage.googleapis.com/test-bucket/test-object?X-Goog-Algorithm=GOOG4-RSA-SHA256\u0026X-Goog-Credential=test-iam-credentials%40dummy-project-id.iam.gserviceaccount.com%2F20190201%2Fauto%2Fstorage%2Fgoog4_request\u0026X-Goog-Date=20190201T090000Z\u0026X-Goog-Expires=10\u0026X-Goog-SignedHeaders=host\u0026X-Goog-Signature=95e6a13d43a1d1962e667f17397f2b80ac9bdd1669210d5e08e0135df9dff4e56113485dbe429ca2266487b9d1796ebdee2d7cf682a6ef3bb9fbb4c351686fba90d7b621cf1c4eb1fdf126460dd25fa0837dfdde0a9fd98662ce60844c458448fb2b352c203d9969cb74efa4bdb742287744a4f2308afa4af0e0773f55e32e92973619249214b97283b2daa14195244444e33f938138d1e5f561088ce8011f4986dda33a556412594db7c12fc40e1ff3f1bedeb7a42f5bcda0b9567f17f65855f65071fabb88ea12371877f3f77f10e1466fff6ff6973b74a933322ff0949ce357e20abe96c3dd5cfab42c9c83e740a4d32b9e11e146f0eb3404d2e975896f74" }, { "description": "Simple PUT", "bucket": "test-bucket", "object": "test-object", "method": "PUT", "expiration": "10", "timestamp": "2019-02-01T09:00:00Z", "expectedUrl": "https://storage.googleapis.com/test-bucket/test-object?X-Goog-Algorithm=GOOG4-RSA-SHA256\u0026X-Goog-Credential=test-iam-credentials%40dummy-project-id.iam.gserviceaccount.com%2F20190201%2Fauto%2Fstorage%2Fgoog4_request\u0026X-Goog-Date=20190201T090000Z\u0026X-Goog-Expires=10\u0026X-Goog-SignedHeaders=host\u0026X-Goog-Signature=8adff1d4285739e31aa68e73767a46bc5511fde377497dbe08481bf5ceb34e29cc9a59921748d8ec3dd4085b7e9b7772a952afedfcdaecb3ae8352275b8b7c867f204e3db85076220a3127a8a9589302fc1181eae13b9b7fe41109ec8cdc93c1e8bac2d7a0cc32a109ca02d06957211326563ab3d3e678a0ba296e298b5fc5e14593c99d444c94724cc4be97015dbff1dca377b508fa0cb7169195de98d0e4ac96c42b918d28c8d92d33e1bd125ce0fb3cd7ad2c45dae65c22628378f6584971b8bf3945b26f2611eb651e9b6a8648970c1ecf386bb71327b082e7296c4e1ee2fc0bdd8983da80af375c817fb1ad491d0bc22c0f51dba0d66e2cffbc90803e47" }, { "description": "POST for resumable uploads", "bucket": "test-bucket", "object": "test-object", "method": "POST", "expiration": "10", "timestamp": "2019-02-01T09:00:00Z", "expectedUrl": "https://storage.googleapis.com/test-bucket/test-object?X-Goog-Algorithm=GOOG4-RSA-SHA256\u0026X-Goog-Credential=test-iam-credentials%40dummy-project-id.iam.gserviceaccount.com%2F20190201%2Fauto%2Fstorage%2Fgoog4_request\u0026X-Goog-Date=20190201T090000Z\u0026X-Goog-Expires=10\u0026X-Goog-SignedHeaders=host%3Bx-goog-resumable\u0026X-Goog-Signature=4a6d39b23343cedf4c30782aed4b384001828c79ffa3a080a481ea01a640dea0a0ceb58d67a12cef3b243c3f036bb3799c6ee88e8db3eaf7d0bdd4b70a228d0736e07eaa1ee076aff5c6ce09dff1f1f03a0d8ead0d2893408dd3604fdabff553aa6d7af2da67cdba6790006a70240f96717b98f1a6ccb24f00940749599be7ef72aaa5358db63ddd54b2de9e2d6d6a586eac4fe25f36d86fc6ab150418e9c6fa01b732cded226c6d62fc95b72473a4cc55a8257482583fe66d9ab6ede909eb41516a8690946c3e87b0f2052eb0e97e012a14b2f721c42e6e19b8a1cd5658ea36264f10b9b1ada66b8ed5bf7ed7d1708377ac6e5fe608ae361fb594d2e5b24c54", "headers": { "X-goog-resumable": "start" } }, { "description": "Vary expiration and timestamp", "bucket": "test-bucket", "object": "test-object", "method": "GET", "expiration": "20", "timestamp": "2019-03-01T09:00:00Z", "expectedUrl": "https://storage.googleapis.com/test-bucket/test-object?X-Goog-Algorithm=GOOG4-RSA-SHA256\u0026X-Goog-Credential=test-iam-credentials%40dummy-project-id.iam.gserviceaccount.com%2F20190301%2Fauto%2Fstorage%2Fgoog4_request\u0026X-Goog-Date=20190301T090000Z\u0026X-Goog-Expires=20\u0026X-Goog-SignedHeaders=host\u0026X-Goog-Signature=9669ed5b10664dc594c758296580662912cf4bcc5a4ba0b6bf055bcbf6f34eed7bdad664f534962174a924741a0c273a4f67bc1847cef20192a6beab44223bd9d4fbbd749c407b79997598c30f82ddc269ff47ec09fa3afe74e00616d438df0d96a7d8ad0adacfad1dc3286f864d924fe919fb0dce45d3d975c5afe8e13af2db9cc37ba77835f92f7669b61e94c6d562196c1274529e76cfff1564cc2cad7d5387dc8e12f7a5dfd925685fe92c30b43709eee29fa2f66067472cee5423d1a3a4182fe8cea75c9329d181dc6acad7c393cd04f8bf5bc0515127d8ebd65d80c08e19ad03316053ea60033fd1b1fd85a69c576415da3bf0a3718d9ea6d03e0d66f0" }, { "description": "Vary bucket and object", "bucket": "test-bucket2", "object": "test-object2", "method": "GET", "expiration": "10", "timestamp": "2019-02-01T09:00:00Z", "expectedUrl": "https://storage.googleapis.com/test-bucket2/test-object2?X-Goog-Algorithm=GOOG4-RSA-SHA256\u0026X-Goog-Credential=test-iam-credentials%40dummy-project-id.iam.gserviceaccount.com%2F20190201%2Fauto%2Fstorage%2Fgoog4_request\u0026X-Goog-Date=20190201T090000Z\u0026X-Goog-Expires=10\u0026X-Goog-SignedHeaders=host\u0026X-Goog-Signature=36e3d58dfd3ec1d2dd2f24b5ee372a71e811ffaa2162a2b871d26728d0354270bc116face87127532969c4a3967ed05b7309af741e19c7202f3167aa8c2ac420b61417d6451442bb91d7c822cd17be8783f01e05372769c88913561d27e6660dd8259f0081a71f831be6c50283626cbf04494ac10c394b29bb3bce74ab91548f58a37118a452693cf0483d77561fc9cac8f1765d2c724994cca46a83517a10157ee0347a233a2aaeae6e6ab5e204ff8fc5f54f90a3efdb8301d9fff5475d58cd05b181affd657f48203f4fb133c3a3d355b8eefbd10d5a0a5fd70d06e9515460ad74e22334b2cba4b29cae4f6f285cdb92d8f3126d7a1479ca3bdb69c207d860" }, { "description": "Simple headers", "bucket": "test-bucket", "object": "test-object", "method": "GET", "expiration": "10", "timestamp": "2019-02-01T09:00:00Z", "expectedUrl": "https://storage.googleapis.com/test-bucket/test-object?X-Goog-Algorithm=GOOG4-RSA-SHA256\u0026X-Goog-Credential=test-iam-credentials%40dummy-project-id.iam.gserviceaccount.com%2F20190201%2Fauto%2Fstorage%2Fgoog4_request\u0026X-Goog-Date=20190201T090000Z\u0026X-Goog-Expires=10\u0026X-Goog-SignedHeaders=bar%3Bfoo%3Bhost\u0026X-Goog-Signature=68ecd3b008328ed30d91e2fe37444ed7b9b03f28ed4424555b5161980531ef87db1c3a5bc0265aad5640af30f96014c94fb2dba7479c41bfe1c020eb90c0c6d387d4dd09d4a5df8b60ea50eb6b01cdd786a1e37020f5f95eb8f9b6cd3f65a1f8a8a65c9fcb61ea662959efd9cd73b683f8d8804ef4d6d9b2852419b013368842731359d7f9e6d1139032ceca75d5e67cee5fd0192ea2125e5f2955d38d3d50cf116f3a52e6a62de77f6207f5b95aaa1d7d0f8a46de89ea72e7ea30f21286318d7eba0142232b0deb3a1dc9e1e812a981c66b5ffda3c6b01a8a9d113155792309fd53a3acfd054ca7776e8eec28c26480cd1e3c812f67f91d14217f39a606669d", "headers": { "BAR": "BAR-value", "foo": "foo-value" } }, { "description": "Headers should be trimmed", "bucket": "test-bucket", "object": "test-object", "method": "GET", "expiration": "10", "timestamp": "2019-02-01T09:00:00Z", "expectedUrl": "https://storage.googleapis.com/test-bucket/test-object?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=test-iam-credentials%40dummy-project-id.iam.gserviceaccount.com%2F20190201%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20190201T090000Z&X-Goog-Expires=10&X-Goog-SignedHeaders=collapsed%3Bhost%3Bleading%3Btabs%3Btrailing&X-Goog-Signature=52fa1d70bcd527ee9c1241f87c56bc481526e8a63d440948595ff776faacb0caa6e8a3060b113546cb27ed29d80c88d402947d83948758d4e5c49e47d9482751d46b2a99c2dae5bc8f7baffab03dec05b28b5d605610686c48e867d6a4239a2a61a785df7d6099d155bba57d0d331d66d667b5df8e165e8277e2675678fc28499abd34053a2bc4e4fa21d032c4278fd29897e8307f142506a3d8d07149cded15f7defa77028fb88ff45132cee5f6232feb8e7f899fe361f1f8ceed0795aff860084f35e27475447dc6e64e4baa09e96a725eee6fa3c408d6bb51c2bd5f649afb8339f46997d9ef22496a79cf0846e52ac941c08dc4b9d63639d0ff2ce8637412", "headers": { "collapsed": "abc def", "leading": " xyz", "trailing": "abc ", "tabs": "\tabc\t\t\t\tdef\t" } }, { "description": "Header value with multiple inline values", "bucket": "test-bucket", "object": "test-object", "method": "GET", "expiration": "10", "timestamp": "2019-02-01T09:00:00Z", "expectedUrl": "https://storage.googleapis.com/test-bucket/test-object?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=test-iam-credentials%40dummy-project-id.iam.gserviceaccount.com%2F20190201%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20190201T090000Z&X-Goog-Expires=10&X-Goog-SignedHeaders=host%3Bmultiple&X-Goog-Signature=5cc113735625341f59c7203f0c2c9febc95ba6af6b9c38814f8e523214712087dc0996e4960d273ae1889f248ac1e58d4d19cb3a69ad7670e9a8ca1b434e878f59339dc7006cf32dfd715337e9f593e0504371839174962a08294586e0c78160a7aa303397888c8350637c6af3b32ac310886cc4590bfda9ca561ee58fb5b8ec56bc606d2ada6e7df31f4276e9dcb96bcaea39dc2cd096f3fad774f9c4b30e317ad43736c05f76831437f44e8726c1e90d3f6c9827dc273f211f32fc85658dfc5d357eb606743a6b00a29e519eef1bebaf9db3e8f4b1f5f9afb648ad06e60bc42fa8b57025056697c874c9ea76f5a73201c9717ea43e54713ff3502ff3fc626b", "headers": { "multiple": " xyz , abc, def , xyz " } }, { "description": "Customer-supplied encryption key", "bucket": "test-bucket", "object": "test-object", "method": "GET", "expiration": "10", "timestamp": "2019-02-01T09:00:00Z", "expectedUrl": "https://storage.googleapis.com/test-bucket/test-object?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=test-iam-credentials%40dummy-project-id.iam.gserviceaccount.com%2F20190201%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20190201T090000Z&X-Goog-Expires=10&X-Goog-SignedHeaders=host%3Bx-goog-encryption-algorithm%3Bx-goog-encryption-key%3Bx-goog-encryption-key-sha256&X-Goog-Signature=278a1c5a3bad248637054a047014760353942433955871031ed08f515b54588654ad033e91f046ab202b68673030e117d1b786c325e870238b035ba75b3feed560a17aff9bab6bddebd4a31a52cb68b214e27d3b0bd886502c6b36b164306fe88b5a07c6063592afe746b2a5d205dbe90dd5386b94f0a78f75d9f53ee884e18f476e8fc2eb1dd910ce0b4ae1f5d7b09876ef9bf983f539c028429e14bad3c75dbd4ed1ae37856f6d6f8a1805eaf8b52a0d6fc993902e4c1ee8de477661f7b67c3663000474cb00e178189789b2a3ed6bd21b4ade684fca8108ac4dd106acb17f5954d045775f7aa5a98ebda5d3075e11a8ea49c64c6ad1481e463e8c9f11f704", "headers": { "X-Goog-Encryption-Algorithm": "AES256", "X-Goog-Encryption-Key": "key", "X-Goog-Encryption-Key-Sha256": "key-hash" } }, { "description": "List Objects", "bucket": "test-bucket", "method": "GET", "expiration": "10", "timestamp": "2019-02-01T09:00:00Z", "expectedUrl": "https://storage.googleapis.com/test-bucket?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=test-iam-credentials%40dummy-project-id.iam.gserviceaccount.com%2F20190201%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20190201T090000Z&X-Goog-Expires=10&X-Goog-SignedHeaders=host&X-Goog-Signature=6dbe94f8e52b2b8a9a476b1c857efa474e09944e2b52b925800316e094a7169d8dbe0df9c0ac08dabb22ac7e827470ceccd65f5a3eadba2a4fb9beebfe37f0d9bb1e552b851fa31a25045bdf019e507f5feb44f061551ef1aeb18dcec0e38ba2e2f77d560a46eaace9c56ed9aa642281301a9d848b0eb30749e34bc7f73a3d596240533466ff9b5f289cd0d4c845c7d96b82a35a5abd0c3aff83e4440ee6873e796087f43545544dc8c01afe1d79c726696b6f555371e491980e7ec145cca0803cf562c38f3fa1d724242f5dea25aac91d74ec9ddd739ff65523627763eaef25cd1f95ad985aaf0079b7c74eb5bcb2870a9b137a7b2c8e41fbe838c95872f75b" } ] } google-cloud-go-0.49.0/storage/internal/test/dummy_pem000066400000000000000000000042251356504100700227510ustar00rootroot00000000000000Bag Attributes friendlyName: privatekey localKeyID: 54 69 6D 65 20 31 34 31 36 38 35 32 30 30 34 37 37 32 Key Attributes: -----BEGIN RSA PRIVATE KEY----- MIICXQIBAAKBgQCtCWMoJ2Bok2QoGFyU7A6IlGprO9QfUTT0jNrLkIbM5OWNIuDx 64+PEaTS5g5m+2Hz/lmd5jJKanAH4dY9LZzsaYAPq1K17Gcmg1hEisYeKsgOcjYY kwRkV+natCTsC+tfWmS0voRh0jA1rI1J4MikceoHtgWdEuoHrrptRVpWKwIDAQAB AoGAKp3uQvx3vSnX+BwP6Um+RpsvHpwMoW3xue1bEdnVqW8SrlERz+NxZw40ZxDs KSbuuBZD4iTI7BUM5JQVnNm4FQY1YrPlWZLyI73Bj8RKTXrPdJheM/0r7xjiIXbQ 7w4cUSM9rVugnI/rxF2kPIQTGYI+EG/6+P+k6VvgPmC0T/ECQQDUPskiS18WaY+i Koalbrb3GakaBoHrC1b4ln4CAv7fq7H4WvFvqi/2rxLhHYq31iwxYy8s7J7Sba1+ 5vwJ2TxZAkEA0LVfs3Q2VWZ+cM3bv0aYTalMXg6wT+LoNvk9HnOb0zQYajF3qm4G ZFdfEqvOkje0zQ4fcihARKyda/VY84UGIwJBAIZa0FvjNmgrnn7bSKzEbxHwrnkJ EYjGfuGR8mY3mzvfpiM+/oLfSslvfhX+62cALq18yco4ZzlxsFgaxAU//NECQDcS NN94YcHlGqYPW9W7/gI4EwOaoqFhwV6II71+SfbP/0U+KlJZV+xwNZEKrqZcdqPI /zkzL8ovNha/laokRrsCQQCyoPHGcBWj+VFbNoyQnX4tghc6rOY7n4pmpgQvU825 TAM9vnYtSkKK/V56kEDNBO5LwiRsir95IUNclqqMKR1C -----END RSA PRIVATE KEY----- Bag Attributes friendlyName: privatekey localKeyID: 54 69 6D 65 20 31 34 31 36 38 35 32 30 30 34 37 37 32 subject=/CN=1079432350659-nvog0vmn9s6pqr3kr4v2avbc7nkhoa11.apps.googleusercontent.com issuer=/CN=1079432350659-nvog0vmn9s6pqr3kr4v2avbc7nkhoa11.apps.googleusercontent.com -----BEGIN CERTIFICATE----- MIICXTCCAcagAwIBAgIIHxTMQUVJRZ0wDQYJKoZIhvcNAQEFBQAwVDFSMFAGA1UE AxNJMTA3OTQzMjM1MDY1OS1udm9nMHZtbjlzNnBxcjNrcjR2MmF2YmM3bmtob2Ex MS5hcHBzLmdvb2dsZXVzZXJjb250ZW50LmNvbTAeFw0xNDExMjQxODAwMDRaFw0y NDExMjExODAwMDRaMFQxUjBQBgNVBAMTSTEwNzk0MzIzNTA2NTktbnZvZzB2bW45 czZwcXIza3I0djJhdmJjN25raG9hMTEuYXBwcy5nb29nbGV1c2VyY29udGVudC5j b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAK0JYygnYGiTZCgYXJTsDoiU ams71B9RNPSM2suQhszk5Y0i4PHrj48RpNLmDmb7YfP+WZ3mMkpqcAfh1j0tnOxp gA+rUrXsZyaDWESKxh4qyA5yNhiTBGRX6dq0JOwL619aZLS+hGHSMDWsjUngyKRx 6ge2BZ0S6geuum1FWlYrAgMBAAGjODA2MAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/ BAQDAgeAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMCMA0GCSqGSIb3DQEBBQUAA4GB ACVvKkZkomHq3uffOQwdZ4VJYuxrvDGnZu/ExW9WngO2teEsjxABL41TNnRYHN5T lMC19poFA2tR/DySDLJ2XNs/hSvyQUL6HHCncVdR4Srpie88j48peY1MZSMP51Jv qagbbP5K5DSEu02/zZaV0kaCvLEN0KAtj/noDuOOnQU2 -----END CERTIFICATE----- google-cloud-go-0.49.0/storage/internal/test/dummy_rsa000066400000000000000000000032171356504100700227550ustar00rootroot00000000000000-----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAx4fm7dngEmOULNmAs1IGZ9Apfzh+BkaQ1dzkmbUgpcoghucE DZRnAGd2aPyB6skGMXUytWQvNYav0WTR00wFtX1ohWTfv68HGXJ8QXCpyoSKSSFY fuP9X36wBSkSX9J5DVgiuzD5VBdzUISSmapjKm+DcbRALjz6OUIPEWi1Tjl6p5RK 1w41qdbmt7E5/kGhKLDuT7+M83g4VWhgIvaAXtnhklDAggilPPa8ZJ1IFe31lNlr k4DRk38nc6sEutdf3RL7QoH7FBusI7uXV03DC6dwN1kP4GE7bjJhcRb/7jYt7CQ9 /E9Exz3c0yAp0yrTg0Fwh+qxfH9dKwN52S7SBwIDAQABAoIBAQCaCs26K07WY5Jt 3a2Cw3y2gPrIgTCqX6hJs7O5ByEhXZ8nBwsWANBUe4vrGaajQHdLj5OKfsIDrOvn 2NI1MqflqeAbu/kR32q3tq8/Rl+PPiwUsW3E6Pcf1orGMSNCXxeducF2iySySzh3 nSIhCG5uwJDWI7a4+9KiieFgK1pt/Iv30q1SQS8IEntTfXYwANQrfKUVMmVF9aIK 6/WZE2yd5+q3wVVIJ6jsmTzoDCX6QQkkJICIYwCkglmVy5AeTckOVwcXL0jqw5Kf 5/soZJQwLEyBoQq7Kbpa26QHq+CJONetPP8Ssy8MJJXBT+u/bSseMb3Zsr5cr43e DJOhwsThAoGBAPY6rPKl2NT/K7XfRCGm1sbWjUQyDShscwuWJ5+kD0yudnT/ZEJ1 M3+KS/iOOAoHDdEDi9crRvMl0UfNa8MAcDKHflzxg2jg/QI+fTBjPP5GOX0lkZ9g z6VePoVoQw2gpPFVNPPTxKfk27tEzbaffvOLGBEih0Kb7HTINkW8rIlzAoGBAM9y 1yr+jvfS1cGFtNU+Gotoihw2eMKtIqR03Yn3n0PK1nVCDKqwdUqCypz4+ml6cxRK J8+Pfdh7D+ZJd4LEG6Y4QRDLuv5OA700tUoSHxMSNn3q9As4+T3MUyYxWKvTeu3U f2NWP9ePU0lV8ttk7YlpVRaPQmc1qwooBA/z/8AdAoGAW9x0HWqmRICWTBnpjyxx QGlW9rQ9mHEtUotIaRSJ6K/F3cxSGUEkX1a3FRnp6kPLcckC6NlqdNgNBd6rb2rA cPl/uSkZP42Als+9YMoFPU/xrrDPbUhu72EDrj3Bllnyb168jKLa4VBOccUvggxr Dm08I1hgYgdN5huzs7y6GeUCgYEAj+AZJSOJ6o1aXS6rfV3mMRve9bQ9yt8jcKXw 5HhOCEmMtaSKfnOF1Ziih34Sxsb7O2428DiX0mV/YHtBnPsAJidL0SdLWIapBzeg KHArByIRkwE6IvJvwpGMdaex1PIGhx5i/3VZL9qiq/ElT05PhIb+UXgoWMabCp84 OgxDK20CgYAeaFo8BdQ7FmVX2+EEejF+8xSge6WVLtkaon8bqcn6P0O8lLypoOhd mJAYH8WU+UAy9pecUnDZj14LAGNVmYcse8HFX71MoshnvCTFEPVo4rZxIAGwMpeJ 5jgQ3slYLpqrGlcbLgUXBUgzEO684Wk/UV9DFPlHALVqCfXQ9dpJPg== -----END RSA PRIVATE KEY----- google-cloud-go-0.49.0/storage/invoke.go000066400000000000000000000020721356504100700200570ustar00rootroot00000000000000// Copyright 2014 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package storage import ( "context" "cloud.google.com/go/internal" gax "github.com/googleapis/gax-go/v2" ) // runWithRetry calls the function until it returns nil or a non-retryable error, or // the context is done. func runWithRetry(ctx context.Context, call func() error) error { return internal.Retry(ctx, gax.Backoff{}, func() (stop bool, err error) { err = call() if err == nil { return true, nil } if shouldRetry(err) { return false, nil } return true, err }) } google-cloud-go-0.49.0/storage/invoke_test.go000066400000000000000000000027701356504100700211230ustar00rootroot00000000000000// Copyright 2014 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package storage import ( "context" "errors" "testing" "google.golang.org/api/googleapi" ) func TestInvoke(t *testing.T) { t.Parallel() ctx := context.Background() // Time-based tests are flaky. We just make sure that invoke eventually // returns with the right error. for _, test := range []struct { count int // number of times to return retryable error retryCode int // error code for retryable error err error // error to return after count returns of retryCode }{ {0, 0, nil}, {0, 0, errors.New("foo")}, {1, 429, nil}, {1, 429, errors.New("bar")}, {2, 518, nil}, {2, 599, &googleapi.Error{Code: 428}}, } { counter := 0 call := func() error { counter++ if counter <= test.count { return &googleapi.Error{Code: test.retryCode} } return test.err } got := runWithRetry(ctx, call) if got != test.err { t.Errorf("%v: got %v, want %v", test, got, test.err) } } } google-cloud-go-0.49.0/storage/mock_test.go000066400000000000000000000035671356504100700205660ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package storage import ( "context" "encoding/json" "fmt" "io" "io/ioutil" "net/http" "strings" "testing" "google.golang.org/api/option" ) type mockTransport struct { gotReq *http.Request gotBody []byte results []transportResult } type transportResult struct { res *http.Response err error } func (t *mockTransport) addResult(res *http.Response, err error) { t.results = append(t.results, transportResult{res, err}) } func (t *mockTransport) RoundTrip(req *http.Request) (*http.Response, error) { t.gotReq = req t.gotBody = nil if req.Body != nil { bytes, err := ioutil.ReadAll(req.Body) if err != nil { return nil, err } t.gotBody = bytes } if len(t.results) == 0 { return nil, fmt.Errorf("error handling request") } result := t.results[0] t.results = t.results[1:] return result.res, result.err } func (t *mockTransport) gotJSONBody() map[string]interface{} { m := map[string]interface{}{} if err := json.Unmarshal(t.gotBody, &m); err != nil { panic(err) } return m } func mockClient(t *testing.T, m *mockTransport) *Client { client, err := NewClient(context.Background(), option.WithHTTPClient(&http.Client{Transport: m})) if err != nil { t.Fatal(err) } return client } func bodyReader(s string) io.ReadCloser { return ioutil.NopCloser(strings.NewReader(s)) } google-cloud-go-0.49.0/storage/not_go110.go000066400000000000000000000023061356504100700202730ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // +build !go1.10 package storage import ( "net/url" "strings" "google.golang.org/api/googleapi" ) func shouldRetry(err error) bool { switch e := err.(type) { case *googleapi.Error: // Retry on 429 and 5xx, according to // https://cloud.google.com/storage/docs/exponential-backoff. return e.Code == 429 || (e.Code >= 500 && e.Code < 600) case *url.Error: // Retry on REFUSED_STREAM. // Unfortunately the error type is unexported, so we resort to string // matching. return strings.Contains(e.Error(), "REFUSED_STREAM") case interface{ Temporary() bool }: return e.Temporary() default: return false } } google-cloud-go-0.49.0/storage/notifications.go000066400000000000000000000135251356504100700214420ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package storage import ( "context" "errors" "fmt" "regexp" "cloud.google.com/go/internal/trace" raw "google.golang.org/api/storage/v1" ) // A Notification describes how to send Cloud PubSub messages when certain // events occur in a bucket. type Notification struct { //The ID of the notification. ID string // The ID of the topic to which this subscription publishes. TopicID string // The ID of the project to which the topic belongs. TopicProjectID string // Only send notifications about listed event types. If empty, send notifications // for all event types. // See https://cloud.google.com/storage/docs/pubsub-notifications#events. EventTypes []string // If present, only apply this notification configuration to object names that // begin with this prefix. ObjectNamePrefix string // An optional list of additional attributes to attach to each Cloud PubSub // message published for this notification subscription. CustomAttributes map[string]string // The contents of the message payload. // See https://cloud.google.com/storage/docs/pubsub-notifications#payload. PayloadFormat string } // Values for Notification.PayloadFormat. const ( // Send no payload with notification messages. NoPayload = "NONE" // Send object metadata as JSON with notification messages. JSONPayload = "JSON_API_V1" ) // Values for Notification.EventTypes. const ( // Event that occurs when an object is successfully created. ObjectFinalizeEvent = "OBJECT_FINALIZE" // Event that occurs when the metadata of an existing object changes. ObjectMetadataUpdateEvent = "OBJECT_METADATA_UPDATE" // Event that occurs when an object is permanently deleted. ObjectDeleteEvent = "OBJECT_DELETE" // Event that occurs when the live version of an object becomes an // archived version. ObjectArchiveEvent = "OBJECT_ARCHIVE" ) func toNotification(rn *raw.Notification) *Notification { n := &Notification{ ID: rn.Id, EventTypes: rn.EventTypes, ObjectNamePrefix: rn.ObjectNamePrefix, CustomAttributes: rn.CustomAttributes, PayloadFormat: rn.PayloadFormat, } n.TopicProjectID, n.TopicID = parseNotificationTopic(rn.Topic) return n } var topicRE = regexp.MustCompile("^//pubsub.googleapis.com/projects/([^/]+)/topics/([^/]+)") // parseNotificationTopic extracts the project and topic IDs from from the full // resource name returned by the service. If the name is malformed, it returns // "?" for both IDs. func parseNotificationTopic(nt string) (projectID, topicID string) { matches := topicRE.FindStringSubmatch(nt) if matches == nil { return "?", "?" } return matches[1], matches[2] } func toRawNotification(n *Notification) *raw.Notification { return &raw.Notification{ Id: n.ID, Topic: fmt.Sprintf("//pubsub.googleapis.com/projects/%s/topics/%s", n.TopicProjectID, n.TopicID), EventTypes: n.EventTypes, ObjectNamePrefix: n.ObjectNamePrefix, CustomAttributes: n.CustomAttributes, PayloadFormat: string(n.PayloadFormat), } } // AddNotification adds a notification to b. You must set n's TopicProjectID, TopicID // and PayloadFormat, and must not set its ID. The other fields are all optional. The // returned Notification's ID can be used to refer to it. func (b *BucketHandle) AddNotification(ctx context.Context, n *Notification) (ret *Notification, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Bucket.AddNotification") defer func() { trace.EndSpan(ctx, err) }() if n.ID != "" { return nil, errors.New("storage: AddNotification: ID must not be set") } if n.TopicProjectID == "" { return nil, errors.New("storage: AddNotification: missing TopicProjectID") } if n.TopicID == "" { return nil, errors.New("storage: AddNotification: missing TopicID") } call := b.c.raw.Notifications.Insert(b.name, toRawNotification(n)) setClientHeader(call.Header()) if b.userProject != "" { call.UserProject(b.userProject) } rn, err := call.Context(ctx).Do() if err != nil { return nil, err } return toNotification(rn), nil } // Notifications returns all the Notifications configured for this bucket, as a map // indexed by notification ID. func (b *BucketHandle) Notifications(ctx context.Context) (n map[string]*Notification, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Bucket.Notifications") defer func() { trace.EndSpan(ctx, err) }() call := b.c.raw.Notifications.List(b.name) setClientHeader(call.Header()) if b.userProject != "" { call.UserProject(b.userProject) } var res *raw.Notifications err = runWithRetry(ctx, func() error { res, err = call.Context(ctx).Do() return err }) if err != nil { return nil, err } return notificationsToMap(res.Items), nil } func notificationsToMap(rns []*raw.Notification) map[string]*Notification { m := map[string]*Notification{} for _, rn := range rns { m[rn.Id] = toNotification(rn) } return m } // DeleteNotification deletes the notification with the given ID. func (b *BucketHandle) DeleteNotification(ctx context.Context, id string) (err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Bucket.DeleteNotification") defer func() { trace.EndSpan(ctx, err) }() call := b.c.raw.Notifications.Delete(b.name, id) setClientHeader(call.Header()) if b.userProject != "" { call.UserProject(b.userProject) } return call.Context(ctx).Do() } google-cloud-go-0.49.0/storage/notifications_test.go000066400000000000000000000057261356504100700225050ustar00rootroot00000000000000// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package storage import ( "context" "testing" "cloud.google.com/go/internal/testutil" raw "google.golang.org/api/storage/v1" ) func TestParseNotificationTopic(t *testing.T) { for _, test := range []struct { in string wantProjectID string wantTopicID string }{ {"", "?", "?"}, {"foobar", "?", "?"}, {"//pubsub.googleapis.com/projects/foo", "?", "?"}, {"//pubsub.googleapis.com/projects/my-project/topics/my-topic", "my-project", "my-topic"}, } { gotProjectID, gotTopicID := parseNotificationTopic(test.in) if gotProjectID != test.wantProjectID || gotTopicID != test.wantTopicID { t.Errorf("%q: got (%q, %q), want (%q, %q)", test.in, gotProjectID, gotTopicID, test.wantProjectID, test.wantTopicID) } } } func TestConvertNotification(t *testing.T) { want := &Notification{ ID: "id", TopicProjectID: "my-project", TopicID: "my-topic", EventTypes: []string{ObjectFinalizeEvent}, ObjectNamePrefix: "prefix", CustomAttributes: map[string]string{"a": "b"}, PayloadFormat: JSONPayload, } got := toNotification(toRawNotification(want)) if diff := testutil.Diff(got, want); diff != "" { t.Errorf("got=-, want=+:\n%s", diff) } } func TestNotificationsToMap(t *testing.T) { got := notificationsToMap(nil) want := map[string]*Notification{} if !testutil.Equal(got, want) { t.Errorf("got %+v, want %+v", got, want) } in := []*raw.Notification{ {Id: "a", Topic: "//pubsub.googleapis.com/projects/P1/topics/T1"}, {Id: "b", Topic: "//pubsub.googleapis.com/projects/P2/topics/T2"}, {Id: "c", Topic: "//pubsub.googleapis.com/projects/P3/topics/T3"}, } got = notificationsToMap(in) want = map[string]*Notification{ "a": {ID: "a", TopicProjectID: "P1", TopicID: "T1"}, "b": {ID: "b", TopicProjectID: "P2", TopicID: "T2"}, "c": {ID: "c", TopicProjectID: "P3", TopicID: "T3"}, } if diff := testutil.Diff(got, want); diff != "" { t.Errorf("got=-, want=+:\n%s", diff) } } func TestAddNotificationsErrors(t *testing.T) { c := &Client{} b := c.Bucket("b") for _, n := range []*Notification{ {ID: "foo", TopicProjectID: "p", TopicID: "t"}, // has ID {TopicProjectID: "p"}, // missing TopicID {TopicID: "t"}, // missing TopicProjectID } { _, err := b.AddNotification(context.Background(), n) if err == nil { t.Errorf("%+v: got nil, want error", n) } } } google-cloud-go-0.49.0/storage/oc_test.go000066400000000000000000000017641356504100700202330ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package storage import ( "context" "testing" "cloud.google.com/go/internal/testutil" ) func TestIntegration_OCTracing(t *testing.T) { ctx := context.Background() client := testConfig(ctx, t) defer client.Close() te := testutil.NewTestExporter() defer te.Unregister() bkt := client.Bucket(bucketName) bkt.Attrs(ctx) if len(te.Spans) == 0 { t.Fatalf("Expected some spans to be created, but got %d", 0) } } google-cloud-go-0.49.0/storage/reader.go000066400000000000000000000273721356504100700200400ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package storage import ( "context" "errors" "fmt" "hash/crc32" "io" "io/ioutil" "net/http" "net/url" "reflect" "strconv" "strings" "time" "cloud.google.com/go/internal/trace" "google.golang.org/api/googleapi" ) var crc32cTable = crc32.MakeTable(crc32.Castagnoli) // ReaderObjectAttrs are attributes about the object being read. These are populated // during the New call. This struct only holds a subset of object attributes: to // get the full set of attributes, use ObjectHandle.Attrs. // // Each field is read-only. type ReaderObjectAttrs struct { // Size is the length of the object's content. Size int64 // StartOffset is the byte offset within the object // from which reading begins. // This value is only non-zero for range requests. StartOffset int64 // ContentType is the MIME type of the object's content. ContentType string // ContentEncoding is the encoding of the object's content. ContentEncoding string // CacheControl specifies whether and for how long browser and Internet // caches are allowed to cache your objects. CacheControl string // LastModified is the time that the object was last modified. LastModified time.Time // Generation is the generation number of the object's content. Generation int64 // Metageneration is the version of the metadata for this object at // this generation. This field is used for preconditions and for // detecting changes in metadata. A metageneration number is only // meaningful in the context of a particular generation of a // particular object. Metageneration int64 } // NewReader creates a new Reader to read the contents of the // object. // ErrObjectNotExist will be returned if the object is not found. // // The caller must call Close on the returned Reader when done reading. func (o *ObjectHandle) NewReader(ctx context.Context) (*Reader, error) { return o.NewRangeReader(ctx, 0, -1) } // NewRangeReader reads part of an object, reading at most length bytes // starting at the given offset. If length is negative, the object is read // until the end. If offset is negative, the object is read abs(offset) bytes // from the end, and length must also be negative to indicate all remaining // bytes will be read. func (o *ObjectHandle) NewRangeReader(ctx context.Context, offset, length int64) (r *Reader, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Object.NewRangeReader") defer func() { trace.EndSpan(ctx, err) }() if err := o.validate(); err != nil { return nil, err } if offset < 0 && length >= 0 { return nil, fmt.Errorf("storage: invalid offset %d < 0 requires negative length", offset) } if o.conds != nil { if err := o.conds.validate("NewRangeReader"); err != nil { return nil, err } } u := &url.URL{ Scheme: o.c.scheme, Host: o.c.readHost, Path: fmt.Sprintf("/%s/%s", o.bucket, o.object), } verb := "GET" if length == 0 { verb = "HEAD" } req, err := http.NewRequest(verb, u.String(), nil) if err != nil { return nil, err } req = req.WithContext(ctx) if o.userProject != "" { req.Header.Set("X-Goog-User-Project", o.userProject) } if o.readCompressed { req.Header.Set("Accept-Encoding", "gzip") } if err := setEncryptionHeaders(req.Header, o.encryptionKey, false); err != nil { return nil, err } gen := o.gen // Define a function that initiates a Read with offset and length, assuming we // have already read seen bytes. reopen := func(seen int64) (*http.Response, error) { start := offset + seen if length < 0 && start < 0 { req.Header.Set("Range", fmt.Sprintf("bytes=%d", start)) } else if length < 0 && start > 0 { req.Header.Set("Range", fmt.Sprintf("bytes=%d-", start)) } else if length > 0 { // The end character isn't affected by how many bytes we've seen. req.Header.Set("Range", fmt.Sprintf("bytes=%d-%d", start, offset+length-1)) } // We wait to assign conditions here because the generation number can change in between reopen() runs. req.URL.RawQuery = conditionsQuery(gen, o.conds) var res *http.Response err = runWithRetry(ctx, func() error { res, err = o.c.hc.Do(req) if err != nil { return err } if res.StatusCode == http.StatusNotFound { res.Body.Close() return ErrObjectNotExist } if res.StatusCode < 200 || res.StatusCode > 299 { body, _ := ioutil.ReadAll(res.Body) res.Body.Close() return &googleapi.Error{ Code: res.StatusCode, Header: res.Header, Body: string(body), } } if start > 0 && length != 0 && res.StatusCode != http.StatusPartialContent { res.Body.Close() return errors.New("storage: partial request not satisfied") } // If a generation hasn't been specified, and this is the first response we get, let's record the // generation. In future requests we'll use this generation as a precondition to avoid data races. if gen < 0 && res.Header.Get("X-Goog-Generation") != "" { gen64, err := strconv.ParseInt(res.Header.Get("X-Goog-Generation"), 10, 64) if err != nil { return err } gen = gen64 } return nil }) if err != nil { return nil, err } return res, nil } res, err := reopen(0) if err != nil { return nil, err } var ( size int64 // total size of object, even if a range was requested. checkCRC bool crc uint32 startOffset int64 // non-zero if range request. ) if res.StatusCode == http.StatusPartialContent { cr := strings.TrimSpace(res.Header.Get("Content-Range")) if !strings.HasPrefix(cr, "bytes ") || !strings.Contains(cr, "/") { return nil, fmt.Errorf("storage: invalid Content-Range %q", cr) } size, err = strconv.ParseInt(cr[strings.LastIndex(cr, "/")+1:], 10, 64) if err != nil { return nil, fmt.Errorf("storage: invalid Content-Range %q", cr) } dashIndex := strings.Index(cr, "-") if dashIndex >= 0 { startOffset, err = strconv.ParseInt(cr[len("bytes="):dashIndex], 10, 64) if err != nil { return nil, fmt.Errorf("storage: invalid Content-Range %q: %v", cr, err) } } } else { size = res.ContentLength // Check the CRC iff all of the following hold: // - We asked for content (length != 0). // - We got all the content (status != PartialContent). // - The server sent a CRC header. // - The Go http stack did not uncompress the file. // - We were not served compressed data that was uncompressed on download. // The problem with the last two cases is that the CRC will not match -- GCS // computes it on the compressed contents, but we compute it on the // uncompressed contents. if length != 0 && !res.Uncompressed && !uncompressedByServer(res) { crc, checkCRC = parseCRC32c(res) } } remain := res.ContentLength body := res.Body if length == 0 { remain = 0 body.Close() body = emptyBody } var metaGen int64 if res.Header.Get("X-Goog-Generation") != "" { metaGen, err = strconv.ParseInt(res.Header.Get("X-Goog-Metageneration"), 10, 64) if err != nil { return nil, err } } var lm time.Time if res.Header.Get("Last-Modified") != "" { lm, err = http.ParseTime(res.Header.Get("Last-Modified")) if err != nil { return nil, err } } attrs := ReaderObjectAttrs{ Size: size, ContentType: res.Header.Get("Content-Type"), ContentEncoding: res.Header.Get("Content-Encoding"), CacheControl: res.Header.Get("Cache-Control"), LastModified: lm, StartOffset: startOffset, Generation: gen, Metageneration: metaGen, } return &Reader{ Attrs: attrs, body: body, size: size, remain: remain, wantCRC: crc, checkCRC: checkCRC, reopen: reopen, }, nil } func uncompressedByServer(res *http.Response) bool { // If the data is stored as gzip but is not encoded as gzip, then it // was uncompressed by the server. return res.Header.Get("X-Goog-Stored-Content-Encoding") == "gzip" && res.Header.Get("Content-Encoding") != "gzip" } func parseCRC32c(res *http.Response) (uint32, bool) { const prefix = "crc32c=" for _, spec := range res.Header["X-Goog-Hash"] { if strings.HasPrefix(spec, prefix) { c, err := decodeUint32(spec[len(prefix):]) if err == nil { return c, true } } } return 0, false } var emptyBody = ioutil.NopCloser(strings.NewReader("")) // Reader reads a Cloud Storage object. // It implements io.Reader. // // Typically, a Reader computes the CRC of the downloaded content and compares it to // the stored CRC, returning an error from Read if there is a mismatch. This integrity check // is skipped if transcoding occurs. See https://cloud.google.com/storage/docs/transcoding. type Reader struct { Attrs ReaderObjectAttrs body io.ReadCloser seen, remain, size int64 checkCRC bool // should we check the CRC? wantCRC uint32 // the CRC32c value the server sent in the header gotCRC uint32 // running crc reopen func(seen int64) (*http.Response, error) } // Close closes the Reader. It must be called when done reading. func (r *Reader) Close() error { return r.body.Close() } func (r *Reader) Read(p []byte) (int, error) { n, err := r.readWithRetry(p) if r.remain != -1 { r.remain -= int64(n) } if r.checkCRC { r.gotCRC = crc32.Update(r.gotCRC, crc32cTable, p[:n]) // Check CRC here. It would be natural to check it in Close, but // everybody defers Close on the assumption that it doesn't return // anything worth looking at. if err == io.EOF { if r.gotCRC != r.wantCRC { return n, fmt.Errorf("storage: bad CRC on read: got %d, want %d", r.gotCRC, r.wantCRC) } } } return n, err } func (r *Reader) readWithRetry(p []byte) (int, error) { n := 0 for len(p[n:]) > 0 { m, err := r.body.Read(p[n:]) n += m r.seen += int64(m) if !shouldRetryRead(err) { return n, err } // Read failed, but we will try again. Send a ranged read request that takes // into account the number of bytes we've already seen. res, err := r.reopen(r.seen) if err != nil { // reopen already retries return n, err } r.body.Close() r.body = res.Body } return n, nil } func shouldRetryRead(err error) bool { if err == nil { return false } return strings.HasSuffix(err.Error(), "INTERNAL_ERROR") && strings.Contains(reflect.TypeOf(err).String(), "http2") } // Size returns the size of the object in bytes. // The returned value is always the same and is not affected by // calls to Read or Close. // // Deprecated: use Reader.Attrs.Size. func (r *Reader) Size() int64 { return r.Attrs.Size } // Remain returns the number of bytes left to read, or -1 if unknown. func (r *Reader) Remain() int64 { return r.remain } // ContentType returns the content type of the object. // // Deprecated: use Reader.Attrs.ContentType. func (r *Reader) ContentType() string { return r.Attrs.ContentType } // ContentEncoding returns the content encoding of the object. // // Deprecated: use Reader.Attrs.ContentEncoding. func (r *Reader) ContentEncoding() string { return r.Attrs.ContentEncoding } // CacheControl returns the cache control of the object. // // Deprecated: use Reader.Attrs.CacheControl. func (r *Reader) CacheControl() string { return r.Attrs.CacheControl } // LastModified returns the value of the Last-Modified header. // // Deprecated: use Reader.Attrs.LastModified. func (r *Reader) LastModified() (time.Time, error) { return r.Attrs.LastModified, nil } google-cloud-go-0.49.0/storage/reader_test.go000066400000000000000000000174621356504100700210760ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package storage import ( "context" "errors" "fmt" "io" "io/ioutil" "net/http" "strconv" "strings" "testing" "google.golang.org/api/option" ) const readData = "0123456789" func TestRangeReader(t *testing.T) { hc, close := newTestServer(handleRangeRead) defer close() ctx := context.Background() c, err := NewClient(ctx, option.WithHTTPClient(hc)) if err != nil { t.Fatal(err) } obj := c.Bucket("b").Object("o") for _, test := range []struct { offset, length int64 want string }{ {0, -1, readData}, {0, 10, readData}, {0, 5, readData[:5]}, {1, 3, readData[1:4]}, {6, -1, readData[6:]}, {4, 20, readData[4:]}, {-20, -1, readData}, {-6, -1, readData[4:]}, } { r, err := obj.NewRangeReader(ctx, test.offset, test.length) if err != nil { t.Errorf("%d/%d: %v", test.offset, test.length, err) continue } gotb, err := ioutil.ReadAll(r) if err != nil { t.Errorf("%d/%d: %v", test.offset, test.length, err) continue } if got := string(gotb); got != test.want { t.Errorf("%d/%d: got %q, want %q", test.offset, test.length, got, test.want) } } } func handleRangeRead(w http.ResponseWriter, r *http.Request) { rh := strings.TrimSpace(r.Header.Get("Range")) data := readData var from, to int if rh == "" { from = 0 to = len(data) } else { // assume "bytes=N-", "bytes=-N" or "bytes=N-M" var err error i := strings.IndexRune(rh, '=') j := strings.IndexRune(rh, '-') hasPositiveStartOffset := i+1 != j if hasPositiveStartOffset { // The case of "bytes=N-" from, err = strconv.Atoi(rh[i+1 : j]) } else { // The case of "bytes=-N" from, err = strconv.Atoi(rh[i+1:]) from += len(data) if from < 0 { from = 0 } } if err != nil { w.WriteHeader(500) return } to = len(data) if hasPositiveStartOffset && j+1 < len(rh) { // The case of "bytes=N-M" to, err = strconv.Atoi(rh[j+1:]) if err != nil { w.WriteHeader(500) return } to++ // Range header is inclusive, Go slice is exclusive } if from >= len(data) && to != from { w.WriteHeader(416) return } if from > len(data) { from = len(data) } if to > len(data) { to = len(data) } } data = data[from:to] if data != readData { w.Header().Set("Content-Range", fmt.Sprintf("bytes %d-%d/%d", from, to-1, len(readData))) w.WriteHeader(http.StatusPartialContent) } if _, err := w.Write([]byte(data)); err != nil { panic(err) } } type http2Error string func (h http2Error) Error() string { return string(h) } func TestRangeReaderRetry(t *testing.T) { retryErr := http2Error("blah blah INTERNAL_ERROR") readBytes := []byte(readData) hc, close := newTestServer(handleRangeRead) defer close() ctx := context.Background() c, err := NewClient(ctx, option.WithHTTPClient(hc)) if err != nil { t.Fatal(err) } obj := c.Bucket("b").Object("o") for i, test := range []struct { offset, length int64 bodies []fakeReadCloser want string }{ { offset: 0, length: -1, bodies: []fakeReadCloser{ {data: readBytes, counts: []int{10}, err: io.EOF}, }, want: readData, }, { offset: 0, length: -1, bodies: []fakeReadCloser{ {data: readBytes, counts: []int{3}, err: retryErr}, {data: readBytes[3:], counts: []int{5, 2}, err: io.EOF}, }, want: readData, }, { offset: 0, length: -1, bodies: []fakeReadCloser{ {data: readBytes, counts: []int{5}, err: retryErr}, {data: readBytes[5:], counts: []int{1, 3}, err: retryErr}, {data: readBytes[9:], counts: []int{1}, err: io.EOF}, }, want: readData, }, { offset: 0, length: 5, bodies: []fakeReadCloser{ {data: readBytes, counts: []int{3}, err: retryErr}, {data: readBytes[3:], counts: []int{2}, err: io.EOF}, }, want: readData[:5], }, { offset: 1, length: 5, bodies: []fakeReadCloser{ {data: readBytes, counts: []int{3}, err: retryErr}, {data: readBytes[3:], counts: []int{2}, err: io.EOF}, }, want: readData[:5], }, { offset: 1, length: 3, bodies: []fakeReadCloser{ {data: readBytes[1:], counts: []int{1}, err: retryErr}, {data: readBytes[2:], counts: []int{2}, err: io.EOF}, }, want: readData[1:4], }, { offset: 4, length: -1, bodies: []fakeReadCloser{ {data: readBytes[4:], counts: []int{1}, err: retryErr}, {data: readBytes[5:], counts: []int{4}, err: retryErr}, {data: readBytes[9:], counts: []int{1}, err: io.EOF}, }, want: readData[4:], }, { offset: -4, length: -1, bodies: []fakeReadCloser{ {data: readBytes[6:], counts: []int{1}, err: retryErr}, {data: readBytes[7:], counts: []int{3}, err: io.EOF}, }, want: readData[6:], }, } { r, err := obj.NewRangeReader(ctx, test.offset, test.length) if err != nil { t.Errorf("#%d: %v", i, err) continue } r.body = &test.bodies[0] b := 0 r.reopen = func(int64) (*http.Response, error) { b++ return &http.Response{Body: &test.bodies[b]}, nil } buf := make([]byte, len(readData)/2) var gotb []byte for { n, err := r.Read(buf) gotb = append(gotb, buf[:n]...) if err == io.EOF { break } if err != nil { t.Fatalf("#%d: %v", i, err) } } if err != nil { t.Errorf("#%d: %v", i, err) continue } if got := string(gotb); got != test.want { t.Errorf("#%d: got %q, want %q", i, got, test.want) } if r.Attrs.Size != int64(len(readData)) { t.Errorf("#%d: got Attrs.Size=%q, want %q", i, r.Attrs.Size, len(readData)) } wantOffset := test.offset if wantOffset < 0 { wantOffset += int64(len(readData)) if wantOffset < 0 { wantOffset = 0 } } if got := r.Attrs.StartOffset; got != wantOffset { t.Errorf("#%d: got Attrs.Offset=%q, want %q", i, got, wantOffset) } } r, err := obj.NewRangeReader(ctx, -100, 10) if err == nil { t.Fatal("Expected a non-nil error with negative offset and positive length") } else if want := "storage: invalid offset"; !strings.HasPrefix(err.Error(), want) { t.Errorf("Error mismatch\nGot: %q\nWant prefix: %q\n", err.Error(), want) } if r != nil { t.Errorf("Expected nil reader") } } type fakeReadCloser struct { data []byte counts []int // how much of data to deliver on each read err error // error to return with last count d int // current position in data c int // current position in counts } func (f *fakeReadCloser) Close() error { return nil } func (f *fakeReadCloser) Read(buf []byte) (int, error) { i := f.c n := 0 if i < len(f.counts) { n = f.counts[i] } var err error if i >= len(f.counts)-1 { err = f.err } copy(buf, f.data[f.d:f.d+n]) if len(buf) < n { n = len(buf) f.counts[i] -= n err = nil } else { f.c++ } f.d += n return n, err } func TestFakeReadCloser(t *testing.T) { e := errors.New("") f := &fakeReadCloser{ data: []byte(readData), counts: []int{1, 2, 3}, err: e, } wants := []string{"0", "12", "345"} buf := make([]byte, 10) for i := 0; i < 3; i++ { n, err := f.Read(buf) if got, want := n, f.counts[i]; got != want { t.Fatalf("i=%d: got %d, want %d", i, got, want) } var wantErr error if i == 2 { wantErr = e } if err != wantErr { t.Fatalf("i=%d: got error %v, want %v", i, err, wantErr) } if got, want := string(buf[:n]), wants[i]; got != want { t.Fatalf("i=%d: got %q, want %q", i, got, want) } } } google-cloud-go-0.49.0/storage/retry_test.go000066400000000000000000000141301356504100700207660ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package storage_test import ( "context" "fmt" "io/ioutil" "net/http" "net/http/httptest" "strings" "sync/atomic" "testing" "time" "golang.org/x/oauth2" "cloud.google.com/go/storage" "google.golang.org/api/googleapi" "google.golang.org/api/option" ) func TestIndefiniteRetries(t *testing.T) { t.Skip("https://github.com/googleapis/google-cloud-go/issues/1641") if testing.Short() { t.Skip("A long running test for retries") } uploadRoute := "/upload" var resumableUploadIDs atomic.Value resumableUploadIDs.Store(make(map[string]time.Time)) lookupUploadID := func(resumableUploadID string) (time.Time, bool) { t, ok := resumableUploadIDs.Load().(map[string]time.Time)[resumableUploadID] return t, ok } memoizeUploadID := func(resumableUploadID string) { resumableUploadIDs.Load().(map[string]time.Time)[resumableUploadID] = time.Now().UTC() } cst := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { resumableUploadID := r.URL.Query().Get("upload_id") path := r.URL.Path switch { case path == "/b": // Bucket creation w.Write([]byte(`{"kind":"storage#bucket","id":"bucket","name":"bucket"}`)) return case strings.HasPrefix(path, "/b/") && strings.HasSuffix(path, "/o"): if resumableUploadID == "" { uploadID := time.Now().Format(time.RFC3339Nano) w.Header().Set("X-GUploader-UploadID", uploadID) // Now for the resumable upload URL. w.Header().Set("Location", fmt.Sprintf("http://%s?upload_id=%s", r.Host+uploadRoute, uploadID)) } else { w.Write([]byte(`{"kind":"storage#object","bucket":"bucket","name":"bucket"}`)) } return case path == uploadRoute: start, _, _, completedUpload, spamThem := parseContentRange(r.Header) if resumableUploadID != "" { _, ok := lookupUploadID(resumableUploadID) if !ok { if start == "0" { // First time that we are encountering this upload // and it is at byte 0, so memoize the uploadID. memoizeUploadID(resumableUploadID) } else { // If the start and end range are non-zero this is the exact // error in https://github.com/googleapis/google-cloud-go/issues/1507 // mismatched_content_start (Invalid request. According to the Content-Range header, // the upload offset is 1082130432 byte(s), which exceeds already uploaded size of 0 byte(s).) errStr := fmt.Sprintf("mismatched_content_start (Invalid request. According to the Content-Range header,"+ "the upload offset is %s byte(s), which exceeds already uploaded size of 0 byte(s).)\n%s", start, r.Header["Content-Range"]) http.Error(w, errStr, http.StatusServiceUnavailable) return } } } if spamThem { // Reproduce https://github.com/googleapis/google-cloud-go/issues/1507 // by sending then a retryable error on the last byte. w.WriteHeader(http.StatusTooManyRequests) return } if completedUpload { // Completed the upload. return } // Consume the body since we can accept this body. _, _ = ioutil.ReadAll(r.Body) w.Header().Set("X-Http-Status-Code-Override", "308") return default: http.Error(w, "Unimplemented", http.StatusNotFound) return } })) defer cst.Close() hc := &http.Client{ Transport: &oauth2.Transport{ Source: new(tokenSupplier), }, } ctx, cancel := context.WithCancel(context.Background()) defer cancel() opts := []option.ClientOption{option.WithHTTPClient(hc), option.WithEndpoint(cst.URL)} sc, err := storage.NewClient(ctx, opts...) if err != nil { t.Fatalf("Failed to create storage client: %v", err) } defer sc.Close() obj := sc.Bucket("issue-1507").Object("object") w := obj.NewWriter(ctx) maxFileSize := 1 << 20 chunkSize := maxFileSize / 4 w.ChunkSize = chunkSize for i := 0; i < maxFileSize; { nowStr := time.Now().Format(time.RFC3339Nano) n, _ := fmt.Fprintf(w, "%s%s", nowStr, strings.Repeat("a", w.ChunkSize)) i += n } closeDone := make(chan error, 1) go func() { // Invoking w.Close() to ensure that this triggers completion of the upload. closeDone <- w.Close() }() // Given that the ExponentialBackoff is 30 seconds from a start of 100ms, // let's wait for a maximum of 5 minutes to account for (2**n) increments // between [100ms, 30s]. maxWait := 5 * time.Minute select { case <-time.After(maxWait): t.Fatalf("Test took longer than %s to return", maxWait) case err := <-closeDone: ge, ok := err.(*googleapi.Error) if !ok { t.Fatalf("Got error (%v) of type %T, expected *googleapi.Error", err, err) } if ge.Code != http.StatusTooManyRequests { t.Fatalf("Got unexpected error: %#v\nWant statusCode of %d", ge, http.StatusTooManyRequests) } } } type tokenSupplier int func (ts *tokenSupplier) Token() (*oauth2.Token, error) { return &oauth2.Token{ AccessToken: "access-token", TokenType: "Bearer", RefreshToken: "refresh-token", Expiry: time.Now().Add(time.Hour), }, nil } func parseContentRange(hdr http.Header) (start, end, max string, completed, spamThem bool) { cRange := strings.TrimPrefix(hdr.Get("Content-Range"), "bytes ") rangeSplits := strings.Split(cRange, "/") prelude := rangeSplits[0] max = rangeSplits[1] if len(prelude) == 0 || prelude == "*" { // Completed the upload. completed = true return } startEndSplit := strings.Split(prelude, "-") start, end = startEndSplit[0], startEndSplit[1] if max != "*" { // They've uploaded the last byte. // Reproduce https://github.com/googleapis/google-cloud-go/issues/1507 // by sending then a retryable error on the last byte. spamThem = true } return } google-cloud-go-0.49.0/storage/storage.go000066400000000000000000001354071356504100700202410ustar00rootroot00000000000000// Copyright 2014 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package storage import ( "bytes" "context" "crypto" "crypto/rand" "crypto/rsa" "crypto/sha256" "crypto/x509" "encoding/base64" "encoding/hex" "encoding/pem" "errors" "fmt" "net/http" "net/url" "os" "reflect" "regexp" "sort" "strconv" "strings" "time" "unicode/utf8" "cloud.google.com/go/internal/optional" "cloud.google.com/go/internal/trace" "cloud.google.com/go/internal/version" "google.golang.org/api/googleapi" "google.golang.org/api/option" raw "google.golang.org/api/storage/v1" htransport "google.golang.org/api/transport/http" ) var ( // ErrBucketNotExist indicates that the bucket does not exist. ErrBucketNotExist = errors.New("storage: bucket doesn't exist") // ErrObjectNotExist indicates that the object does not exist. ErrObjectNotExist = errors.New("storage: object doesn't exist") ) var userAgent = fmt.Sprintf("gcloud-golang-storage/%s", version.Repo) const ( // ScopeFullControl grants permissions to manage your // data and permissions in Google Cloud Storage. ScopeFullControl = raw.DevstorageFullControlScope // ScopeReadOnly grants permissions to // view your data in Google Cloud Storage. ScopeReadOnly = raw.DevstorageReadOnlyScope // ScopeReadWrite grants permissions to manage your // data in Google Cloud Storage. ScopeReadWrite = raw.DevstorageReadWriteScope ) var xGoogHeader = fmt.Sprintf("gl-go/%s gccl/%s", version.Go(), version.Repo) func setClientHeader(headers http.Header) { headers.Set("x-goog-api-client", xGoogHeader) } // Client is a client for interacting with Google Cloud Storage. // // Clients should be reused instead of created as needed. // The methods of Client are safe for concurrent use by multiple goroutines. type Client struct { hc *http.Client raw *raw.Service // Scheme describes the scheme under the current host. scheme string // EnvHost is the host set on the STORAGE_EMULATOR_HOST variable. envHost string // ReadHost is the default host used on the reader. readHost string } // NewClient creates a new Google Cloud Storage client. // The default scope is ScopeFullControl. To use a different scope, like ScopeReadOnly, use option.WithScopes. func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { var host, readHost, scheme string if host = os.Getenv("STORAGE_EMULATOR_HOST"); host == "" { scheme = "https" readHost = "storage.googleapis.com" opts = append(opts, option.WithScopes(ScopeFullControl), option.WithUserAgent(userAgent)) } else { scheme = "http" readHost = host opts = append(opts, option.WithoutAuthentication()) } hc, ep, err := htransport.NewClient(ctx, opts...) if err != nil { return nil, fmt.Errorf("dialing: %v", err) } rawService, err := raw.New(hc) if err != nil { return nil, fmt.Errorf("storage client: %v", err) } if ep == "" { // Override the default value for BasePath from the raw client. // TODO: remove when the raw client uses this endpoint as its default (~end of 2020) rawService.BasePath = "https://storage.googleapis.com/storage/v1/" } else { rawService.BasePath = ep } return &Client{ hc: hc, raw: rawService, scheme: scheme, envHost: host, readHost: readHost, }, nil } // Close closes the Client. // // Close need not be called at program exit. func (c *Client) Close() error { // Set fields to nil so that subsequent uses will panic. c.hc = nil c.raw = nil return nil } // SigningScheme determines the API version to use when signing URLs. type SigningScheme int const ( // SigningSchemeDefault is presently V2 and will change to V4 in the future. SigningSchemeDefault SigningScheme = iota // SigningSchemeV2 uses the V2 scheme to sign URLs. SigningSchemeV2 // SigningSchemeV4 uses the V4 scheme to sign URLs. SigningSchemeV4 ) // SignedURLOptions allows you to restrict the access to the signed URL. type SignedURLOptions struct { // GoogleAccessID represents the authorizer of the signed URL generation. // It is typically the Google service account client email address from // the Google Developers Console in the form of "xxx@developer.gserviceaccount.com". // Required. GoogleAccessID string // PrivateKey is the Google service account private key. It is obtainable // from the Google Developers Console. // At https://console.developers.google.com/project//apiui/credential, // create a service account client ID or reuse one of your existing service account // credentials. Click on the "Generate new P12 key" to generate and download // a new private key. Once you download the P12 file, use the following command // to convert it into a PEM file. // // $ openssl pkcs12 -in key.p12 -passin pass:notasecret -out key.pem -nodes // // Provide the contents of the PEM file as a byte slice. // Exactly one of PrivateKey or SignBytes must be non-nil. PrivateKey []byte // SignBytes is a function for implementing custom signing. For example, if // your application is running on Google App Engine, you can use // appengine's internal signing function: // ctx := appengine.NewContext(request) // acc, _ := appengine.ServiceAccount(ctx) // url, err := SignedURL("bucket", "object", &SignedURLOptions{ // GoogleAccessID: acc, // SignBytes: func(b []byte) ([]byte, error) { // _, signedBytes, err := appengine.SignBytes(ctx, b) // return signedBytes, err // }, // // etc. // }) // // Exactly one of PrivateKey or SignBytes must be non-nil. SignBytes func([]byte) ([]byte, error) // Method is the HTTP method to be used with the signed URL. // Signed URLs can be used with GET, HEAD, PUT, and DELETE requests. // Required. Method string // Expires is the expiration time on the signed URL. It must be // a datetime in the future. For SigningSchemeV4, the expiration may be no // more than seven days in the future. // Required. Expires time.Time // ContentType is the content type header the client must provide // to use the generated signed URL. // Optional. ContentType string // Headers is a list of extension headers the client must provide // in order to use the generated signed URL. // Optional. Headers []string // MD5 is the base64 encoded MD5 checksum of the file. // If provided, the client should provide the exact value on the request // header in order to use the signed URL. // Optional. MD5 string // Scheme determines the version of URL signing to use. Default is // SigningSchemeV2. Scheme SigningScheme } var ( tabRegex = regexp.MustCompile(`[\t]+`) // I was tempted to call this spacex. :) spaceRegex = regexp.MustCompile(` +`) canonicalHeaderRegexp = regexp.MustCompile(`(?i)^(x-goog-[^:]+):(.*)?$`) excludedCanonicalHeaders = map[string]bool{ "x-goog-encryption-key": true, "x-goog-encryption-key-sha256": true, } ) // v2SanitizeHeaders applies the specifications for canonical extension headers at // https://cloud.google.com/storage/docs/access-control/signed-urls#about-canonical-extension-headers. func v2SanitizeHeaders(hdrs []string) []string { headerMap := map[string][]string{} for _, hdr := range hdrs { // No leading or trailing whitespaces. sanitizedHeader := strings.TrimSpace(hdr) var header, value string // Only keep canonical headers, discard any others. headerMatches := canonicalHeaderRegexp.FindStringSubmatch(sanitizedHeader) if len(headerMatches) == 0 { continue } header = headerMatches[1] value = headerMatches[2] header = strings.ToLower(strings.TrimSpace(header)) value = strings.TrimSpace(value) if excludedCanonicalHeaders[header] { // Do not keep any deliberately excluded canonical headers when signing. continue } if len(value) > 0 { // Remove duplicate headers by appending the values of duplicates // in their order of appearance. headerMap[header] = append(headerMap[header], value) } } var sanitizedHeaders []string for header, values := range headerMap { // There should be no spaces around the colon separating the header name // from the header value or around the values themselves. The values // should be separated by commas. // // NOTE: The semantics for headers without a value are not clear. // However from specifications these should be edge-cases anyway and we // should assume that there will be no canonical headers using empty // values. Any such headers are discarded at the regexp stage above. sanitizedHeaders = append(sanitizedHeaders, fmt.Sprintf("%s:%s", header, strings.Join(values, ","))) } sort.Strings(sanitizedHeaders) return sanitizedHeaders } // v4SanitizeHeaders applies the specifications for canonical extension headers // at https://cloud.google.com/storage/docs/access-control/signed-urls#about-canonical-extension-headers. // // V4 does a couple things differently from V2: // - Headers get sorted by key, instead of by key:value. We do this in // signedURLV4. // - There's no canonical regexp: we simply split headers on :. // - We don't exclude canonical headers. // - We replace leading and trailing spaces in header values, like v2, but also // all intermediate space duplicates get stripped. That is, there's only ever // a single consecutive space. func v4SanitizeHeaders(hdrs []string) []string { headerMap := map[string][]string{} for _, hdr := range hdrs { // No leading or trailing whitespaces. sanitizedHeader := strings.TrimSpace(hdr) var key, value string headerMatches := strings.Split(sanitizedHeader, ":") if len(headerMatches) < 2 { continue } key = headerMatches[0] value = headerMatches[1] key = strings.ToLower(strings.TrimSpace(key)) value = strings.TrimSpace(value) value = string(spaceRegex.ReplaceAll([]byte(value), []byte(" "))) value = string(tabRegex.ReplaceAll([]byte(value), []byte("\t"))) if len(value) > 0 { // Remove duplicate headers by appending the values of duplicates // in their order of appearance. headerMap[key] = append(headerMap[key], value) } } var sanitizedHeaders []string for header, values := range headerMap { // There should be no spaces around the colon separating the header name // from the header value or around the values themselves. The values // should be separated by commas. // // NOTE: The semantics for headers without a value are not clear. // However from specifications these should be edge-cases anyway and we // should assume that there will be no canonical headers using empty // values. Any such headers are discarded at the regexp stage above. sanitizedHeaders = append(sanitizedHeaders, fmt.Sprintf("%s:%s", header, strings.Join(values, ","))) } return sanitizedHeaders } // SignedURL returns a URL for the specified object. Signed URLs allow // the users access to a restricted resource for a limited time without having a // Google account or signing in. For more information about the signed // URLs, see https://cloud.google.com/storage/docs/accesscontrol#Signed-URLs. func SignedURL(bucket, name string, opts *SignedURLOptions) (string, error) { now := utcNow() if err := validateOptions(opts, now); err != nil { return "", err } switch opts.Scheme { case SigningSchemeV2: opts.Headers = v2SanitizeHeaders(opts.Headers) return signedURLV2(bucket, name, opts) case SigningSchemeV4: opts.Headers = v4SanitizeHeaders(opts.Headers) return signedURLV4(bucket, name, opts, now) default: // SigningSchemeDefault opts.Headers = v2SanitizeHeaders(opts.Headers) return signedURLV2(bucket, name, opts) } } func validateOptions(opts *SignedURLOptions, now time.Time) error { if opts == nil { return errors.New("storage: missing required SignedURLOptions") } if opts.GoogleAccessID == "" { return errors.New("storage: missing required GoogleAccessID") } if (opts.PrivateKey == nil) == (opts.SignBytes == nil) { return errors.New("storage: exactly one of PrivateKey or SignedBytes must be set") } if opts.Method == "" { return errors.New("storage: missing required method option") } if opts.Expires.IsZero() { return errors.New("storage: missing required expires option") } if opts.MD5 != "" { md5, err := base64.StdEncoding.DecodeString(opts.MD5) if err != nil || len(md5) != 16 { return errors.New("storage: invalid MD5 checksum") } } if opts.Scheme == SigningSchemeV4 { cutoff := now.Add(604801 * time.Second) // 7 days + 1 second if !opts.Expires.Before(cutoff) { return errors.New("storage: expires must be within seven days from now") } } return nil } const ( iso8601 = "20060102T150405Z" yearMonthDay = "20060102" ) // utcNow returns the current time in UTC and is a variable to allow for // reassignment in tests to provide deterministic signed URL values. var utcNow = func() time.Time { return time.Now().UTC() } // extractHeaderNames takes in a series of key:value headers and returns the // header names only. func extractHeaderNames(kvs []string) []string { var res []string for _, header := range kvs { nameValue := strings.Split(header, ":") res = append(res, nameValue[0]) } return res } // signedURLV4 creates a signed URL using the sigV4 algorithm. func signedURLV4(bucket, name string, opts *SignedURLOptions, now time.Time) (string, error) { buf := &bytes.Buffer{} fmt.Fprintf(buf, "%s\n", opts.Method) u := &url.URL{Path: bucket} if name != "" { u.Path += "/" + name } // Note: we have to add a / here because GCS does so auto-magically, despite // Go's EscapedPath not doing so (and we have to exactly match their // canonical query). fmt.Fprintf(buf, "/%s\n", u.EscapedPath()) headerNames := append(extractHeaderNames(opts.Headers), "host") if opts.ContentType != "" { headerNames = append(headerNames, "content-type") } if opts.MD5 != "" { headerNames = append(headerNames, "content-md5") } sort.Strings(headerNames) signedHeaders := strings.Join(headerNames, ";") timestamp := now.Format(iso8601) credentialScope := fmt.Sprintf("%s/auto/storage/goog4_request", now.Format(yearMonthDay)) canonicalQueryString := url.Values{ "X-Goog-Algorithm": {"GOOG4-RSA-SHA256"}, "X-Goog-Credential": {fmt.Sprintf("%s/%s", opts.GoogleAccessID, credentialScope)}, "X-Goog-Date": {timestamp}, "X-Goog-Expires": {fmt.Sprintf("%d", int(opts.Expires.Sub(now).Seconds()))}, "X-Goog-SignedHeaders": {signedHeaders}, } fmt.Fprintf(buf, "%s\n", canonicalQueryString.Encode()) u.Host = "storage.googleapis.com" var headersWithValue []string headersWithValue = append(headersWithValue, "host:"+u.Host) headersWithValue = append(headersWithValue, opts.Headers...) if opts.ContentType != "" { headersWithValue = append(headersWithValue, "content-type:"+strings.TrimSpace(opts.ContentType)) } if opts.MD5 != "" { headersWithValue = append(headersWithValue, "content-md5:"+strings.TrimSpace(opts.MD5)) } canonicalHeaders := strings.Join(sortHeadersByKey(headersWithValue), "\n") fmt.Fprintf(buf, "%s\n\n", canonicalHeaders) fmt.Fprintf(buf, "%s\n", signedHeaders) fmt.Fprint(buf, "UNSIGNED-PAYLOAD") sum := sha256.Sum256(buf.Bytes()) hexDigest := hex.EncodeToString(sum[:]) signBuf := &bytes.Buffer{} fmt.Fprint(signBuf, "GOOG4-RSA-SHA256\n") fmt.Fprintf(signBuf, "%s\n", timestamp) fmt.Fprintf(signBuf, "%s\n", credentialScope) fmt.Fprintf(signBuf, "%s", hexDigest) signBytes := opts.SignBytes if opts.PrivateKey != nil { key, err := parseKey(opts.PrivateKey) if err != nil { return "", err } signBytes = func(b []byte) ([]byte, error) { sum := sha256.Sum256(b) return rsa.SignPKCS1v15( rand.Reader, key, crypto.SHA256, sum[:], ) } } b, err := signBytes(signBuf.Bytes()) if err != nil { return "", err } signature := hex.EncodeToString(b) canonicalQueryString.Set("X-Goog-Signature", string(signature)) u.Scheme = "https" u.RawQuery = canonicalQueryString.Encode() return u.String(), nil } // takes a list of headerKey:headervalue1,headervalue2,etc and sorts by header // key. func sortHeadersByKey(hdrs []string) []string { headersMap := map[string]string{} var headersKeys []string for _, h := range hdrs { parts := strings.Split(h, ":") k := parts[0] v := parts[1] headersMap[k] = v headersKeys = append(headersKeys, k) } sort.Strings(headersKeys) var sorted []string for _, k := range headersKeys { v := headersMap[k] sorted = append(sorted, fmt.Sprintf("%s:%s", k, v)) } return sorted } func signedURLV2(bucket, name string, opts *SignedURLOptions) (string, error) { signBytes := opts.SignBytes if opts.PrivateKey != nil { key, err := parseKey(opts.PrivateKey) if err != nil { return "", err } signBytes = func(b []byte) ([]byte, error) { sum := sha256.Sum256(b) return rsa.SignPKCS1v15( rand.Reader, key, crypto.SHA256, sum[:], ) } } u := &url.URL{ Path: fmt.Sprintf("/%s/%s", bucket, name), } buf := &bytes.Buffer{} fmt.Fprintf(buf, "%s\n", opts.Method) fmt.Fprintf(buf, "%s\n", opts.MD5) fmt.Fprintf(buf, "%s\n", opts.ContentType) fmt.Fprintf(buf, "%d\n", opts.Expires.Unix()) if len(opts.Headers) > 0 { fmt.Fprintf(buf, "%s\n", strings.Join(opts.Headers, "\n")) } fmt.Fprintf(buf, "%s", u.String()) b, err := signBytes(buf.Bytes()) if err != nil { return "", err } encoded := base64.StdEncoding.EncodeToString(b) u.Scheme = "https" u.Host = "storage.googleapis.com" q := u.Query() q.Set("GoogleAccessId", opts.GoogleAccessID) q.Set("Expires", fmt.Sprintf("%d", opts.Expires.Unix())) q.Set("Signature", string(encoded)) u.RawQuery = q.Encode() return u.String(), nil } // ObjectHandle provides operations on an object in a Google Cloud Storage bucket. // Use BucketHandle.Object to get a handle. type ObjectHandle struct { c *Client bucket string object string acl ACLHandle gen int64 // a negative value indicates latest conds *Conditions encryptionKey []byte // AES-256 key userProject string // for requester-pays buckets readCompressed bool // Accept-Encoding: gzip } // ACL provides access to the object's access control list. // This controls who can read and write this object. // This call does not perform any network operations. func (o *ObjectHandle) ACL() *ACLHandle { return &o.acl } // Generation returns a new ObjectHandle that operates on a specific generation // of the object. // By default, the handle operates on the latest generation. Not // all operations work when given a specific generation; check the API // endpoints at https://cloud.google.com/storage/docs/json_api/ for details. func (o *ObjectHandle) Generation(gen int64) *ObjectHandle { o2 := *o o2.gen = gen return &o2 } // If returns a new ObjectHandle that applies a set of preconditions. // Preconditions already set on the ObjectHandle are ignored. // Operations on the new handle will return an error if the preconditions are not // satisfied. See https://cloud.google.com/storage/docs/generations-preconditions // for more details. func (o *ObjectHandle) If(conds Conditions) *ObjectHandle { o2 := *o o2.conds = &conds return &o2 } // Key returns a new ObjectHandle that uses the supplied encryption // key to encrypt and decrypt the object's contents. // // Encryption key must be a 32-byte AES-256 key. // See https://cloud.google.com/storage/docs/encryption for details. func (o *ObjectHandle) Key(encryptionKey []byte) *ObjectHandle { o2 := *o o2.encryptionKey = encryptionKey return &o2 } // Attrs returns meta information about the object. // ErrObjectNotExist will be returned if the object is not found. func (o *ObjectHandle) Attrs(ctx context.Context) (attrs *ObjectAttrs, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Object.Attrs") defer func() { trace.EndSpan(ctx, err) }() if err := o.validate(); err != nil { return nil, err } call := o.c.raw.Objects.Get(o.bucket, o.object).Projection("full").Context(ctx) if err := applyConds("Attrs", o.gen, o.conds, call); err != nil { return nil, err } if o.userProject != "" { call.UserProject(o.userProject) } if err := setEncryptionHeaders(call.Header(), o.encryptionKey, false); err != nil { return nil, err } var obj *raw.Object setClientHeader(call.Header()) err = runWithRetry(ctx, func() error { obj, err = call.Do(); return err }) if e, ok := err.(*googleapi.Error); ok && e.Code == http.StatusNotFound { return nil, ErrObjectNotExist } if err != nil { return nil, err } return newObject(obj), nil } // Update updates an object with the provided attributes. // All zero-value attributes are ignored. // ErrObjectNotExist will be returned if the object is not found. func (o *ObjectHandle) Update(ctx context.Context, uattrs ObjectAttrsToUpdate) (oa *ObjectAttrs, err error) { ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Object.Update") defer func() { trace.EndSpan(ctx, err) }() if err := o.validate(); err != nil { return nil, err } var attrs ObjectAttrs // Lists of fields to send, and set to null, in the JSON. var forceSendFields, nullFields []string if uattrs.ContentType != nil { attrs.ContentType = optional.ToString(uattrs.ContentType) // For ContentType, sending the empty string is a no-op. // Instead we send a null. if attrs.ContentType == "" { nullFields = append(nullFields, "ContentType") } else { forceSendFields = append(forceSendFields, "ContentType") } } if uattrs.ContentLanguage != nil { attrs.ContentLanguage = optional.ToString(uattrs.ContentLanguage) // For ContentLanguage it's an error to send the empty string. // Instead we send a null. if attrs.ContentLanguage == "" { nullFields = append(nullFields, "ContentLanguage") } else { forceSendFields = append(forceSendFields, "ContentLanguage") } } if uattrs.ContentEncoding != nil { attrs.ContentEncoding = optional.ToString(uattrs.ContentEncoding) forceSendFields = append(forceSendFields, "ContentEncoding") } if uattrs.ContentDisposition != nil { attrs.ContentDisposition = optional.ToString(uattrs.ContentDisposition) forceSendFields = append(forceSendFields, "ContentDisposition") } if uattrs.CacheControl != nil { attrs.CacheControl = optional.ToString(uattrs.CacheControl) forceSendFields = append(forceSendFields, "CacheControl") } if uattrs.EventBasedHold != nil { attrs.EventBasedHold = optional.ToBool(uattrs.EventBasedHold) forceSendFields = append(forceSendFields, "EventBasedHold") } if uattrs.TemporaryHold != nil { attrs.TemporaryHold = optional.ToBool(uattrs.TemporaryHold) forceSendFields = append(forceSendFields, "TemporaryHold") } if uattrs.Metadata != nil { attrs.Metadata = uattrs.Metadata if len(attrs.Metadata) == 0 { // Sending the empty map is a no-op. We send null instead. nullFields = append(nullFields, "Metadata") } else { forceSendFields = append(forceSendFields, "Metadata") } } if uattrs.ACL != nil { attrs.ACL = uattrs.ACL // It's an error to attempt to delete the ACL, so // we don't append to nullFields here. forceSendFields = append(forceSendFields, "Acl") } rawObj := attrs.toRawObject(o.bucket) rawObj.ForceSendFields = forceSendFields rawObj.NullFields = nullFields call := o.c.raw.Objects.Patch(o.bucket, o.object, rawObj).Projection("full").Context(ctx) if err := applyConds("Update", o.gen, o.conds, call); err != nil { return nil, err } if o.userProject != "" { call.UserProject(o.userProject) } if uattrs.PredefinedACL != "" { call.PredefinedAcl(uattrs.PredefinedACL) } if err := setEncryptionHeaders(call.Header(), o.encryptionKey, false); err != nil { return nil, err } var obj *raw.Object setClientHeader(call.Header()) err = runWithRetry(ctx, func() error { obj, err = call.Do(); return err }) if e, ok := err.(*googleapi.Error); ok && e.Code == http.StatusNotFound { return nil, ErrObjectNotExist } if err != nil { return nil, err } return newObject(obj), nil } // BucketName returns the name of the bucket. func (o *ObjectHandle) BucketName() string { return o.bucket } // ObjectName returns the name of the object. func (o *ObjectHandle) ObjectName() string { return o.object } // ObjectAttrsToUpdate is used to update the attributes of an object. // Only fields set to non-nil values will be updated. // Set a field to its zero value to delete it. // // For example, to change ContentType and delete ContentEncoding and // Metadata, use // ObjectAttrsToUpdate{ // ContentType: "text/html", // ContentEncoding: "", // Metadata: map[string]string{}, // } type ObjectAttrsToUpdate struct { EventBasedHold optional.Bool TemporaryHold optional.Bool ContentType optional.String ContentLanguage optional.String ContentEncoding optional.String ContentDisposition optional.String CacheControl optional.String Metadata map[string]string // set to map[string]string{} to delete ACL []ACLRule // If not empty, applies a predefined set of access controls. ACL must be nil. // See https://cloud.google.com/storage/docs/json_api/v1/objects/patch. PredefinedACL string } // Delete deletes the single specified object. func (o *ObjectHandle) Delete(ctx context.Context) error { if err := o.validate(); err != nil { return err } call := o.c.raw.Objects.Delete(o.bucket, o.object).Context(ctx) if err := applyConds("Delete", o.gen, o.conds, call); err != nil { return err } if o.userProject != "" { call.UserProject(o.userProject) } // Encryption doesn't apply to Delete. setClientHeader(call.Header()) err := runWithRetry(ctx, func() error { return call.Do() }) switch e := err.(type) { case nil: return nil case *googleapi.Error: if e.Code == http.StatusNotFound { return ErrObjectNotExist } } return err } // ReadCompressed when true causes the read to happen without decompressing. func (o *ObjectHandle) ReadCompressed(compressed bool) *ObjectHandle { o2 := *o o2.readCompressed = compressed return &o2 } // NewWriter returns a storage Writer that writes to the GCS object // associated with this ObjectHandle. // // A new object will be created unless an object with this name already exists. // Otherwise any previous object with the same name will be replaced. // The object will not be available (and any previous object will remain) // until Close has been called. // // Attributes can be set on the object by modifying the returned Writer's // ObjectAttrs field before the first call to Write. If no ContentType // attribute is specified, the content type will be automatically sniffed // using net/http.DetectContentType. // // It is the caller's responsibility to call Close when writing is done. To // stop writing without saving the data, cancel the context. func (o *ObjectHandle) NewWriter(ctx context.Context) *Writer { return &Writer{ ctx: ctx, o: o, donec: make(chan struct{}), ObjectAttrs: ObjectAttrs{Name: o.object}, ChunkSize: googleapi.DefaultUploadChunkSize, } } func (o *ObjectHandle) validate() error { if o.bucket == "" { return errors.New("storage: bucket name is empty") } if o.object == "" { return errors.New("storage: object name is empty") } if !utf8.ValidString(o.object) { return fmt.Errorf("storage: object name %q is not valid UTF-8", o.object) } return nil } // parseKey converts the binary contents of a private key file to an // *rsa.PrivateKey. It detects whether the private key is in a PEM container or // not. If so, it extracts the private key from PEM container before // conversion. It only supports PEM containers with no passphrase. func parseKey(key []byte) (*rsa.PrivateKey, error) { if block, _ := pem.Decode(key); block != nil { key = block.Bytes } parsedKey, err := x509.ParsePKCS8PrivateKey(key) if err != nil { parsedKey, err = x509.ParsePKCS1PrivateKey(key) if err != nil { return nil, err } } parsed, ok := parsedKey.(*rsa.PrivateKey) if !ok { return nil, errors.New("oauth2: private key is invalid") } return parsed, nil } // toRawObject copies the editable attributes from o to the raw library's Object type. func (o *ObjectAttrs) toRawObject(bucket string) *raw.Object { var ret string if !o.RetentionExpirationTime.IsZero() { ret = o.RetentionExpirationTime.Format(time.RFC3339) } return &raw.Object{ Bucket: bucket, Name: o.Name, EventBasedHold: o.EventBasedHold, TemporaryHold: o.TemporaryHold, RetentionExpirationTime: ret, ContentType: o.ContentType, ContentEncoding: o.ContentEncoding, ContentLanguage: o.ContentLanguage, CacheControl: o.CacheControl, ContentDisposition: o.ContentDisposition, StorageClass: o.StorageClass, Acl: toRawObjectACL(o.ACL), Metadata: o.Metadata, } } // ObjectAttrs represents the metadata for a Google Cloud Storage (GCS) object. type ObjectAttrs struct { // Bucket is the name of the bucket containing this GCS object. // This field is read-only. Bucket string // Name is the name of the object within the bucket. // This field is read-only. Name string // ContentType is the MIME type of the object's content. ContentType string // ContentLanguage is the content language of the object's content. ContentLanguage string // CacheControl is the Cache-Control header to be sent in the response // headers when serving the object data. CacheControl string // EventBasedHold specifies whether an object is under event-based hold. New // objects created in a bucket whose DefaultEventBasedHold is set will // default to that value. EventBasedHold bool // TemporaryHold specifies whether an object is under temporary hold. While // this flag is set to true, the object is protected against deletion and // overwrites. TemporaryHold bool // RetentionExpirationTime is a server-determined value that specifies the // earliest time that the object's retention period expires. // This is a read-only field. RetentionExpirationTime time.Time // ACL is the list of access control rules for the object. ACL []ACLRule // If not empty, applies a predefined set of access controls. It should be set // only when writing, copying or composing an object. When copying or composing, // it acts as the destinationPredefinedAcl parameter. // PredefinedACL is always empty for ObjectAttrs returned from the service. // See https://cloud.google.com/storage/docs/json_api/v1/objects/insert // for valid values. PredefinedACL string // Owner is the owner of the object. This field is read-only. // // If non-zero, it is in the form of "user-". Owner string // Size is the length of the object's content. This field is read-only. Size int64 // ContentEncoding is the encoding of the object's content. ContentEncoding string // ContentDisposition is the optional Content-Disposition header of the object // sent in the response headers. ContentDisposition string // MD5 is the MD5 hash of the object's content. This field is read-only, // except when used from a Writer. If set on a Writer, the uploaded // data is rejected if its MD5 hash does not match this field. MD5 []byte // CRC32C is the CRC32 checksum of the object's content using // the Castagnoli93 polynomial. This field is read-only, except when // used from a Writer. If set on a Writer and Writer.SendCRC32C // is true, the uploaded data is rejected if its CRC32c hash does not // match this field. CRC32C uint32 // MediaLink is an URL to the object's content. This field is read-only. MediaLink string // Metadata represents user-provided metadata, in key/value pairs. // It can be nil if no metadata is provided. Metadata map[string]string // Generation is the generation number of the object's content. // This field is read-only. Generation int64 // Metageneration is the version of the metadata for this // object at this generation. This field is used for preconditions // and for detecting changes in metadata. A metageneration number // is only meaningful in the context of a particular generation // of a particular object. This field is read-only. Metageneration int64 // StorageClass is the storage class of the object. // This value defines how objects in the bucket are stored and // determines the SLA and the cost of storage. Typical values are // "NEARLINE", "COLDLINE" and "STANDARD". // It defaults to "STANDARD". StorageClass string // Created is the time the object was created. This field is read-only. Created time.Time // Deleted is the time the object was deleted. // If not deleted, it is the zero value. This field is read-only. Deleted time.Time // Updated is the creation or modification time of the object. // For buckets with versioning enabled, changing an object's // metadata does not change this property. This field is read-only. Updated time.Time // CustomerKeySHA256 is the base64-encoded SHA-256 hash of the // customer-supplied encryption key for the object. It is empty if there is // no customer-supplied encryption key. // See // https://cloud.google.com/storage/docs/encryption for more about // encryption in Google Cloud Storage. CustomerKeySHA256 string // Cloud KMS key name, in the form // projects/P/locations/L/keyRings/R/cryptoKeys/K, used to encrypt this object, // if the object is encrypted by such a key. // // Providing both a KMSKeyName and a customer-supplied encryption key (via // ObjectHandle.Key) will result in an error when writing an object. KMSKeyName string // Prefix is set only for ObjectAttrs which represent synthetic "directory // entries" when iterating over buckets using Query.Delimiter. See // ObjectIterator.Next. When set, no other fields in ObjectAttrs will be // populated. Prefix string // Etag is the HTTP/1.1 Entity tag for the object. // This field is read-only. Etag string } // convertTime converts a time in RFC3339 format to time.Time. // If any error occurs in parsing, the zero-value time.Time is silently returned. func convertTime(t string) time.Time { var r time.Time if t != "" { r, _ = time.Parse(time.RFC3339, t) } return r } func newObject(o *raw.Object) *ObjectAttrs { if o == nil { return nil } owner := "" if o.Owner != nil { owner = o.Owner.Entity } md5, _ := base64.StdEncoding.DecodeString(o.Md5Hash) crc32c, _ := decodeUint32(o.Crc32c) var sha256 string if o.CustomerEncryption != nil { sha256 = o.CustomerEncryption.KeySha256 } return &ObjectAttrs{ Bucket: o.Bucket, Name: o.Name, ContentType: o.ContentType, ContentLanguage: o.ContentLanguage, CacheControl: o.CacheControl, EventBasedHold: o.EventBasedHold, TemporaryHold: o.TemporaryHold, RetentionExpirationTime: convertTime(o.RetentionExpirationTime), ACL: toObjectACLRules(o.Acl), Owner: owner, ContentEncoding: o.ContentEncoding, ContentDisposition: o.ContentDisposition, Size: int64(o.Size), MD5: md5, CRC32C: crc32c, MediaLink: o.MediaLink, Metadata: o.Metadata, Generation: o.Generation, Metageneration: o.Metageneration, StorageClass: o.StorageClass, CustomerKeySHA256: sha256, KMSKeyName: o.KmsKeyName, Created: convertTime(o.TimeCreated), Deleted: convertTime(o.TimeDeleted), Updated: convertTime(o.Updated), Etag: o.Etag, } } // Decode a uint32 encoded in Base64 in big-endian byte order. func decodeUint32(b64 string) (uint32, error) { d, err := base64.StdEncoding.DecodeString(b64) if err != nil { return 0, err } if len(d) != 4 { return 0, fmt.Errorf("storage: %q does not encode a 32-bit value", d) } return uint32(d[0])<<24 + uint32(d[1])<<16 + uint32(d[2])<<8 + uint32(d[3]), nil } // Encode a uint32 as Base64 in big-endian byte order. func encodeUint32(u uint32) string { b := []byte{byte(u >> 24), byte(u >> 16), byte(u >> 8), byte(u)} return base64.StdEncoding.EncodeToString(b) } // Query represents a query to filter objects from a bucket. type Query struct { // Delimiter returns results in a directory-like fashion. // Results will contain only objects whose names, aside from the // prefix, do not contain delimiter. Objects whose names, // aside from the prefix, contain delimiter will have their name, // truncated after the delimiter, returned in prefixes. // Duplicate prefixes are omitted. // Optional. Delimiter string // Prefix is the prefix filter to query objects // whose names begin with this prefix. // Optional. Prefix string // Versions indicates whether multiple versions of the same // object will be included in the results. Versions bool // fieldSelection is used to select only specific fields to be returned by // the query. It's used internally and is populated for the user by // calling Query.SetAttrSelection fieldSelection string } // attrToFieldMap maps the field names of ObjectAttrs to the underlying field // names in the API call. Only the ObjectAttrs field names are visible to users // because they are already part of the public API of the package. var attrToFieldMap = map[string]string{ "Bucket": "bucket", "Name": "name", "ContentType": "contentType", "ContentLanguage": "contentLanguage", "CacheControl": "cacheControl", "EventBasedHold": "eventBasedHold", "TemporaryHold": "temporaryHold", "RetentionExpirationTime": "retentionExpirationTime", "ACL": "acl", "Owner": "owner", "ContentEncoding": "contentEncoding", "ContentDisposition": "contentDisposition", "Size": "size", "MD5": "md5hash", "CRC32C": "crc32c", "MediaLink": "mediaLink", "Metadata": "metadata", "Generation": "generation", "Metageneration": "metageneration", "StorageClass": "storageClass", "CustomerKeySHA256": "customerEncryption", "KMSKeyName": "kmsKeyName", "Created": "timeCreated", "Deleted": "timeDeleted", "Updated": "timeUpdated", "Etag": "etag", } // SetAttrSelection makes the query populate only specific attributes of // objects. When iterating over objects, if you only need each object's name // and size, pass []string{"Name", "Size"} to this method. Only these fields // will be fetched for each object across the network; the other fields of // ObjectAttr will remain at their default values. This is a performance // optimization; for more information, see // https://cloud.google.com/storage/docs/json_api/v1/how-tos/performance func (q *Query) SetAttrSelection(attrs []string) error { fieldSet := make(map[string]bool) for _, attr := range attrs { field, ok := attrToFieldMap[attr] if !ok { return fmt.Errorf("storage: attr %v is not valid", attr) } fieldSet[field] = true } if len(fieldSet) > 0 { var b strings.Builder b.WriteString("items(") first := true for field := range fieldSet { if !first { b.WriteString(",") } first = false b.WriteString(field) } b.WriteString(")") q.fieldSelection = b.String() } return nil } // Conditions constrain methods to act on specific generations of // objects. // // The zero value is an empty set of constraints. Not all conditions or // combinations of conditions are applicable to all methods. // See https://cloud.google.com/storage/docs/generations-preconditions // for details on how these operate. type Conditions struct { // Generation constraints. // At most one of the following can be set to a non-zero value. // GenerationMatch specifies that the object must have the given generation // for the operation to occur. // If GenerationMatch is zero, it has no effect. // Use DoesNotExist to specify that the object does not exist in the bucket. GenerationMatch int64 // GenerationNotMatch specifies that the object must not have the given // generation for the operation to occur. // If GenerationNotMatch is zero, it has no effect. GenerationNotMatch int64 // DoesNotExist specifies that the object must not exist in the bucket for // the operation to occur. // If DoesNotExist is false, it has no effect. DoesNotExist bool // Metadata generation constraints. // At most one of the following can be set to a non-zero value. // MetagenerationMatch specifies that the object must have the given // metageneration for the operation to occur. // If MetagenerationMatch is zero, it has no effect. MetagenerationMatch int64 // MetagenerationNotMatch specifies that the object must not have the given // metageneration for the operation to occur. // If MetagenerationNotMatch is zero, it has no effect. MetagenerationNotMatch int64 } func (c *Conditions) validate(method string) error { if *c == (Conditions{}) { return fmt.Errorf("storage: %s: empty conditions", method) } if !c.isGenerationValid() { return fmt.Errorf("storage: %s: multiple conditions specified for generation", method) } if !c.isMetagenerationValid() { return fmt.Errorf("storage: %s: multiple conditions specified for metageneration", method) } return nil } func (c *Conditions) isGenerationValid() bool { n := 0 if c.GenerationMatch != 0 { n++ } if c.GenerationNotMatch != 0 { n++ } if c.DoesNotExist { n++ } return n <= 1 } func (c *Conditions) isMetagenerationValid() bool { return c.MetagenerationMatch == 0 || c.MetagenerationNotMatch == 0 } // applyConds modifies the provided call using the conditions in conds. // call is something that quacks like a *raw.WhateverCall. func applyConds(method string, gen int64, conds *Conditions, call interface{}) error { cval := reflect.ValueOf(call) if gen >= 0 { if !setConditionField(cval, "Generation", gen) { return fmt.Errorf("storage: %s: generation not supported", method) } } if conds == nil { return nil } if err := conds.validate(method); err != nil { return err } switch { case conds.GenerationMatch != 0: if !setConditionField(cval, "IfGenerationMatch", conds.GenerationMatch) { return fmt.Errorf("storage: %s: ifGenerationMatch not supported", method) } case conds.GenerationNotMatch != 0: if !setConditionField(cval, "IfGenerationNotMatch", conds.GenerationNotMatch) { return fmt.Errorf("storage: %s: ifGenerationNotMatch not supported", method) } case conds.DoesNotExist: if !setConditionField(cval, "IfGenerationMatch", int64(0)) { return fmt.Errorf("storage: %s: DoesNotExist not supported", method) } } switch { case conds.MetagenerationMatch != 0: if !setConditionField(cval, "IfMetagenerationMatch", conds.MetagenerationMatch) { return fmt.Errorf("storage: %s: ifMetagenerationMatch not supported", method) } case conds.MetagenerationNotMatch != 0: if !setConditionField(cval, "IfMetagenerationNotMatch", conds.MetagenerationNotMatch) { return fmt.Errorf("storage: %s: ifMetagenerationNotMatch not supported", method) } } return nil } func applySourceConds(gen int64, conds *Conditions, call *raw.ObjectsRewriteCall) error { if gen >= 0 { call.SourceGeneration(gen) } if conds == nil { return nil } if err := conds.validate("CopyTo source"); err != nil { return err } switch { case conds.GenerationMatch != 0: call.IfSourceGenerationMatch(conds.GenerationMatch) case conds.GenerationNotMatch != 0: call.IfSourceGenerationNotMatch(conds.GenerationNotMatch) case conds.DoesNotExist: call.IfSourceGenerationMatch(0) } switch { case conds.MetagenerationMatch != 0: call.IfSourceMetagenerationMatch(conds.MetagenerationMatch) case conds.MetagenerationNotMatch != 0: call.IfSourceMetagenerationNotMatch(conds.MetagenerationNotMatch) } return nil } // setConditionField sets a field on a *raw.WhateverCall. // We can't use anonymous interfaces because the return type is // different, since the field setters are builders. func setConditionField(call reflect.Value, name string, value interface{}) bool { m := call.MethodByName(name) if !m.IsValid() { return false } m.Call([]reflect.Value{reflect.ValueOf(value)}) return true } // conditionsQuery returns the generation and conditions as a URL query // string suitable for URL.RawQuery. It assumes that the conditions // have been validated. func conditionsQuery(gen int64, conds *Conditions) string { // URL escapes are elided because integer strings are URL-safe. var buf []byte appendParam := func(s string, n int64) { if len(buf) > 0 { buf = append(buf, '&') } buf = append(buf, s...) buf = strconv.AppendInt(buf, n, 10) } if gen >= 0 { appendParam("generation=", gen) } if conds == nil { return string(buf) } switch { case conds.GenerationMatch != 0: appendParam("ifGenerationMatch=", conds.GenerationMatch) case conds.GenerationNotMatch != 0: appendParam("ifGenerationNotMatch=", conds.GenerationNotMatch) case conds.DoesNotExist: appendParam("ifGenerationMatch=", 0) } switch { case conds.MetagenerationMatch != 0: appendParam("ifMetagenerationMatch=", conds.MetagenerationMatch) case conds.MetagenerationNotMatch != 0: appendParam("ifMetagenerationNotMatch=", conds.MetagenerationNotMatch) } return string(buf) } // composeSourceObj wraps a *raw.ComposeRequestSourceObjects, but adds the methods // that modifyCall searches for by name. type composeSourceObj struct { src *raw.ComposeRequestSourceObjects } func (c composeSourceObj) Generation(gen int64) { c.src.Generation = gen } func (c composeSourceObj) IfGenerationMatch(gen int64) { // It's safe to overwrite ObjectPreconditions, since its only field is // IfGenerationMatch. c.src.ObjectPreconditions = &raw.ComposeRequestSourceObjectsObjectPreconditions{ IfGenerationMatch: gen, } } func setEncryptionHeaders(headers http.Header, key []byte, copySource bool) error { if key == nil { return nil } // TODO(jbd): Ask the API team to return a more user-friendly error // and avoid doing this check at the client level. if len(key) != 32 { return errors.New("storage: not a 32-byte AES-256 key") } var cs string if copySource { cs = "copy-source-" } headers.Set("x-goog-"+cs+"encryption-algorithm", "AES256") headers.Set("x-goog-"+cs+"encryption-key", base64.StdEncoding.EncodeToString(key)) keyHash := sha256.Sum256(key) headers.Set("x-goog-"+cs+"encryption-key-sha256", base64.StdEncoding.EncodeToString(keyHash[:])) return nil } // ServiceAccount fetches the email address of the given project's Google Cloud Storage service account. func (c *Client) ServiceAccount(ctx context.Context, projectID string) (string, error) { r := c.raw.Projects.ServiceAccount.Get(projectID) res, err := r.Context(ctx).Do() if err != nil { return "", err } return res.EmailAddress, nil } google-cloud-go-0.49.0/storage/storage.replay000066400000000000000000131221121356504100700211210ustar00rootroot00000000000000{ "Initial": "IjIwMTktMDUtMDJUMjI6MjM6NTMuNDAzNDMyMDEzWiI=", "Version": "0.2", "Converter": { "ClearHeaders": [ "^X-Goog-.*Encryption-Key$" ], "RemoveRequestHeaders": [ "^Authorization$", "^Proxy-Authorization$", "^Connection$", "^Content-Type$", "^Date$", "^Host$", "^Transfer-Encoding$", "^Via$", "^X-Forwarded-.*$", "^X-Cloud-Trace-Context$", "^X-Goog-Api-Client$", "^X-Google-.*$", "^X-Gfe-.*$" ], "RemoveResponseHeaders": [ "^X-Google-.*$", "^X-Gfe-.*$" ], "ClearParams": null, "RemoveParams": null }, "Entries": [ { "ID": "f5f231bed6e14b7f", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b?alt=json\u0026prettyPrint=false\u0026project=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "60" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIn0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "485" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:23:54 GMT" ], "Etag": [ "CAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrZvgYBWgsCwPaGI9bo1ccC0WCBc8kJgydTwioDtXR9xps4HiDoKXI-vjYUl876SMqF0JhmhaEBgvxrIL9Y989YCFrH65xGys_r1JbPdi9M9N0kS3M" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjIzOjU0LjYxMFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyMzo1NC42MTBaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiaWFtQ29uZmlndXJhdGlvbiI6eyJidWNrZXRQb2xpY3lPbmx5Ijp7ImVuYWJsZWQiOmZhbHNlfX0sImxvY2F0aW9uIjoiVVMiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsImV0YWciOiJDQUU9In0=" } }, { "ID": "9a9914424ef59619", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b?alt=json\u0026prettyPrint=false\u0026project=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "60" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAyIn0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "485" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:23:55 GMT" ], "Etag": [ "CAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqFvRYrCleVqpn0QshSvzW5I1-8o7N6vGYh8o5G1f-AHnsX2N_x-NKJrvlxnXqm9auw5gMoWFaJTSTtKL5y85WlQ_eAjmmlrkD4tbHYBZJ386xgaZw" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMiIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMiIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAyIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjIzOjU1LjEwOVoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyMzo1NS4xMDlaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiaWFtQ29uZmlndXJhdGlvbiI6eyJidWNrZXRQb2xpY3lPbmx5Ijp7ImVuYWJsZWQiOmZhbHNlfX0sImxvY2F0aW9uIjoiVVMiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsImV0YWciOiJDQUU9In0=" } }, { "ID": "17f2abbdd781a33b", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0002?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "2431" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:23:55 GMT" ], "Etag": [ "CAE=" ], "Expires": [ "Thu, 02 May 2019 22:23:55 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoYoTmTG5mxpFGPvmECUTlGMlQwhfmqGsZtBtZ9xV89Pw3q-p5BBeX_3imdofr_7EBT7nBm4v5alpg45Zi8a8ET28qBH2xfNe4n15HR-1fhGou2wQU" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMiIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMiIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAyIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjIzOjU1LjEwOVoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyMzo1NS4xMDlaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDIvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAyL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDIiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAyL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDIvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDIiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDIvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMi9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMiIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUU9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBRT0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwiZXRhZyI6IkNBRT0ifQ==" } }, { "ID": "6752f5a9a036af11", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0002?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:23:56 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Ur4bFsk4ylv96GsTkuDKG--hVaCR_UEhZ_fAzMGt5Eu5ZKncHOLjU_f2PcNP9saFGW-UkH9jXwt_nuR0G2zXOBjMJmLdd7Ml61bGMMrJeVa0OtcGpM" ] }, "Body": "" } }, { "ID": "9c25646df7aacad9", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b?alt=json\u0026prettyPrint=false\u0026project=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "543" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJsYWJlbHMiOnsiZW1wdHkiOiIiLCJsMSI6InYxIn0sImxpZmVjeWNsZSI6eyJydWxlIjpbeyJhY3Rpb24iOnsic3RvcmFnZUNsYXNzIjoiTkVBUkxJTkUiLCJ0eXBlIjoiU2V0U3RvcmFnZUNsYXNzIn0sImNvbmRpdGlvbiI6eyJhZ2UiOjEwLCJjcmVhdGVkQmVmb3JlIjoiMjAxNy0wMS0wMSIsImlzTGl2ZSI6ZmFsc2UsIm1hdGNoZXNTdG9yYWdlQ2xhc3MiOlsiTVVMVElfUkVHSU9OQUwiLCJTVEFOREFSRCJdLCJudW1OZXdlclZlcnNpb25zIjozfX0seyJhY3Rpb24iOnsidHlwZSI6IkRlbGV0ZSJ9LCJjb25kaXRpb24iOnsiYWdlIjozMCwiY3JlYXRlZEJlZm9yZSI6IjIwMTctMDEtMDEiLCJpc0xpdmUiOnRydWUsIm1hdGNoZXNTdG9yYWdlQ2xhc3MiOlsiTkVBUkxJTkUiXSwibnVtTmV3ZXJWZXJzaW9ucyI6MTB9fV19LCJsb2NhdGlvbiI6IlVTIiwibmFtZSI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMiIsInN0b3JhZ2VDbGFzcyI6Ik5FQVJMSU5FIiwidmVyc2lvbmluZyI6eyJlbmFibGVkIjp0cnVlfX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "926" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:23:56 GMT" ], "Etag": [ "CAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uq6CjN9PjjzT3LmHxW_tU_ciQ1rahetoQGbX_gX8EC5il7tPJi2yxi5VZxnDNrp1h14b7Ix8tnvtkHufAyO1-lMRutdHK5GSzonff78Nm6KPAKN5fU" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMiIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMiIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAyIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjIzOjU2LjQwOVoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyMzo1Ni40MDlaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiaWFtQ29uZmlndXJhdGlvbiI6eyJidWNrZXRQb2xpY3lPbmx5Ijp7ImVuYWJsZWQiOmZhbHNlfX0sImxvY2F0aW9uIjoiVVMiLCJ2ZXJzaW9uaW5nIjp7ImVuYWJsZWQiOnRydWV9LCJsaWZlY3ljbGUiOnsicnVsZSI6W3siYWN0aW9uIjp7InR5cGUiOiJTZXRTdG9yYWdlQ2xhc3MiLCJzdG9yYWdlQ2xhc3MiOiJORUFSTElORSJ9LCJjb25kaXRpb24iOnsiYWdlIjoxMCwiY3JlYXRlZEJlZm9yZSI6IjIwMTctMDEtMDEiLCJpc0xpdmUiOmZhbHNlLCJtYXRjaGVzU3RvcmFnZUNsYXNzIjpbIk1VTFRJX1JFR0lPTkFMIiwiU1RBTkRBUkQiXSwibnVtTmV3ZXJWZXJzaW9ucyI6M319LHsiYWN0aW9uIjp7InR5cGUiOiJEZWxldGUifSwiY29uZGl0aW9uIjp7ImFnZSI6MzAsImNyZWF0ZWRCZWZvcmUiOiIyMDE3LTAxLTAxIiwiaXNMaXZlIjp0cnVlLCJtYXRjaGVzU3RvcmFnZUNsYXNzIjpbIk5FQVJMSU5FIl0sIm51bU5ld2VyVmVyc2lvbnMiOjEwfX1dfSwibGFiZWxzIjp7ImwxIjoidjEiLCJlbXB0eSI6IiJ9LCJzdG9yYWdlQ2xhc3MiOiJORUFSTElORSIsImV0YWciOiJDQUU9In0=" } }, { "ID": "f795b9adcb1b546e", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0002?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "2872" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:23:56 GMT" ], "Etag": [ "CAE=" ], "Expires": [ "Thu, 02 May 2019 22:23:56 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Up2-mWQyRDbFSpF6U96vQpaBYr74NgiUWh3-KZnLWaFYnhQti1tgKWNtL15YgK8blaRSnzGeACPA6jNuM34yhr7bxztrdN2tobEQAzD5RVgzpqx14w" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMiIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMiIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAyIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjIzOjU2LjQwOVoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyMzo1Ni40MDlaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDIvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAyL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDIiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAyL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDIvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDIiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDIvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMi9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMiIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUU9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBRT0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsInZlcnNpb25pbmciOnsiZW5hYmxlZCI6dHJ1ZX0sImxpZmVjeWNsZSI6eyJydWxlIjpbeyJhY3Rpb24iOnsidHlwZSI6IlNldFN0b3JhZ2VDbGFzcyIsInN0b3JhZ2VDbGFzcyI6Ik5FQVJMSU5FIn0sImNvbmRpdGlvbiI6eyJhZ2UiOjEwLCJjcmVhdGVkQmVmb3JlIjoiMjAxNy0wMS0wMSIsImlzTGl2ZSI6ZmFsc2UsIm1hdGNoZXNTdG9yYWdlQ2xhc3MiOlsiTVVMVElfUkVHSU9OQUwiLCJTVEFOREFSRCJdLCJudW1OZXdlclZlcnNpb25zIjozfX0seyJhY3Rpb24iOnsidHlwZSI6IkRlbGV0ZSJ9LCJjb25kaXRpb24iOnsiYWdlIjozMCwiY3JlYXRlZEJlZm9yZSI6IjIwMTctMDEtMDEiLCJpc0xpdmUiOnRydWUsIm1hdGNoZXNTdG9yYWdlQ2xhc3MiOlsiTkVBUkxJTkUiXSwibnVtTmV3ZXJWZXJzaW9ucyI6MTB9fV19LCJsYWJlbHMiOnsibDEiOiJ2MSIsImVtcHR5IjoiIn0sInN0b3JhZ2VDbGFzcyI6Ik5FQVJMSU5FIiwiZXRhZyI6IkNBRT0ifQ==" } }, { "ID": "2ee3f84c4e4045fb", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0002?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:23:57 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UplJEr-Hxa3hDFT5ozLEHYhHfaxlYFpc9Vwm8AL831-w_7BBgxHjjEsU8Br_uLnLes0h9hz37iuE9V8uVZ2liHY7ZD4piNH31oyapjCtwyXrukIP94" ] }, "Body": "" } }, { "ID": "16f19dbf8e206756", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "2431" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:23:57 GMT" ], "Etag": [ "CAE=" ], "Expires": [ "Thu, 02 May 2019 22:23:57 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uqvp5XjvB8nhNuz-bTeN9OklTfiBGldYKkcY13JF6oUfpV0z_jwoEQD3B3Ss3wWpaSmZfePjo7fkkr-hP3jbrUazNHaqQliiHqOBSNmSoPmwJpzfOI" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjIzOjU0LjYxMFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyMzo1NC42MTBaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUU9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBRT0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwiZXRhZyI6IkNBRT0ifQ==" } }, { "ID": "949f5ce411d6f672", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "3" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "e30K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "2431" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:23:58 GMT" ], "Etag": [ "CAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpVeVcmmuUyOt3Hbja89_Ewi6GRsJtRduqK93OT4Ys1aK5GqDWeGxyDbczUyRLeUYvZgtJzYLwVOOUszqAF4ipSXgZ1L_byd9cJ7ttVfQ_ceQBXxY4" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjIzOjU0LjYxMFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyMzo1NC42MTBaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUU9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBRT0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwiZXRhZyI6IkNBRT0ifQ==" } }, { "ID": "b75303fbdafb66d0", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "64" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJsYWJlbHMiOnsiZW1wdHkiOiIiLCJsMSI6InYxIn0sInZlcnNpb25pbmciOnsiZW5hYmxlZCI6dHJ1ZX19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "2493" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:23:58 GMT" ], "Etag": [ "CAI=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqDnNlC3m95GplHjE79aqzhtwgfJCWQjHaCFG4i7qmTFliz2gdE4OiOnKAPIoNqxEngE35065YXNYA65aMSSeEluDKmQ__rJXcS_DpRdoYP4rZIyPo" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjIzOjU0LjYxMFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyMzo1OC40MzZaIiwibWV0YWdlbmVyYXRpb24iOiIyIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FJPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUk9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBST0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBST0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsInZlcnNpb25pbmciOnsiZW5hYmxlZCI6dHJ1ZX0sImxhYmVscyI6eyJlbXB0eSI6IiIsImwxIjoidjEifSwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJldGFnIjoiQ0FJPSJ9" } }, { "ID": "831805b62d969707", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "93" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJsYWJlbHMiOnsiYWJzZW50IjpudWxsLCJlbXB0eSI6bnVsbCwibDEiOiJ2MiIsIm5ldyI6Im5ldyJ9LCJ2ZXJzaW9uaW5nIjp7ImVuYWJsZWQiOmZhbHNlfX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "2495" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:23:59 GMT" ], "Etag": [ "CAM=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uq8yNb3V9Kq8zPa_pdVrJIYv83v4fu6xAHwktfTz_Cy4K1rpi8xrDzYmw5wICaazfMcAiYPhM8r4Y6WkeOyeCRInvkJ6ndduhNN_dgu1U59uI5F3Qc" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjIzOjU0LjYxMFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyMzo1OS4wMzJaIiwibWV0YWdlbmVyYXRpb24iOiIzIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FNPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQU09In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQU09In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBTT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQU09In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBTT0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsInZlcnNpb25pbmciOnsiZW5hYmxlZCI6ZmFsc2V9LCJsYWJlbHMiOnsibDEiOiJ2MiIsIm5ldyI6Im5ldyJ9LCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsImV0YWciOiJDQU09In0=" } }, { "ID": "8a816d061fe9e7e0", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "77" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJsaWZlY3ljbGUiOnsicnVsZSI6W3siYWN0aW9uIjp7InR5cGUiOiJEZWxldGUifSwiY29uZGl0aW9uIjp7ImFnZSI6MzB9fV19fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "2570" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:23:59 GMT" ], "Etag": [ "CAQ=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrbjywEmDPkqxln7-Nx_8ngRxoWvncfCx1fGVpPZGEjjmg8OJgv0uaczxapjlNeEcvMnqWI_RVzG6_588QaO8nCnPVnE2kkIek3D_t6UNL9CCPYLRc" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjIzOjU0LjYxMFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyMzo1OS41MzBaIiwibWV0YWdlbmVyYXRpb24iOiI0IiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FRPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQVE9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQVE9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBUT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQVE9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBUT0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsInZlcnNpb25pbmciOnsiZW5hYmxlZCI6ZmFsc2V9LCJsaWZlY3ljbGUiOnsicnVsZSI6W3siYWN0aW9uIjp7InR5cGUiOiJEZWxldGUifSwiY29uZGl0aW9uIjp7ImFnZSI6MzB9fV19LCJsYWJlbHMiOnsibDEiOiJ2MiIsIm5ldyI6Im5ldyJ9LCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsImV0YWciOiJDQVE9In0=" } }, { "ID": "6a60397ebae323e7", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW4iLCJuYW1lIjoiYnVja2V0UG9saWN5T25seSJ9Cg==", "dGVzdA==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3305" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:00 GMT" ], "Etag": [ "CPmu4bnx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UokOvJnDKKHAQOa8mJLrxFpWWvQ2U_BC_3uI0Z4x870Q068evHio_t_YudbSq614h77-ofhBsyHpoknWnm_YrnXxkHzopreKoMBykFIcbsSB8TDKEE" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9idWNrZXRQb2xpY3lPbmx5LzE1NTY4MzU4NDAwNTUxNjEiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9idWNrZXRQb2xpY3lPbmx5IiwibmFtZSI6ImJ1Y2tldFBvbGljeU9ubHkiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0MDA1NTE2MSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowMC4wNTRaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDAuMDU0WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjAwLjA1NFoiLCJzaXplIjoiNCIsIm1kNUhhc2giOiJDWTlyelVZaDAzUEszazZESmllMDlnPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vYnVja2V0UG9saWN5T25seT9nZW5lcmF0aW9uPTE1NTY4MzU4NDAwNTUxNjEmYWx0PW1lZGlhIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYnVja2V0UG9saWN5T25seS8xNTU2ODM1ODQwMDU1MTYxL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2J1Y2tldFBvbGljeU9ubHkvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImJ1Y2tldFBvbGljeU9ubHkiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0MDA1NTE2MSIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDUG11NGJueC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYnVja2V0UG9saWN5T25seS8xNTU2ODM1ODQwMDU1MTYxL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9idWNrZXRQb2xpY3lPbmx5L2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiYnVja2V0UG9saWN5T25seSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQwMDU1MTYxIiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ1BtdTRibngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2J1Y2tldFBvbGljeU9ubHkvMTU1NjgzNTg0MDA1NTE2MS9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vYnVja2V0UG9saWN5T25seS9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImJ1Y2tldFBvbGljeU9ubHkiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0MDA1NTE2MSIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDUG11NGJueC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYnVja2V0UG9saWN5T25seS8xNTU2ODM1ODQwMDU1MTYxL3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9idWNrZXRQb2xpY3lPbmx5L2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiYnVja2V0UG9saWN5T25seSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQwMDU1MTYxIiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ1BtdTRibngvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJocUJ5d0E9PSIsImV0YWciOiJDUG11NGJueC9lRUNFQUU9In0=" } }, { "ID": "32d392d1da32f27b", "Request": { "Method": "PUT", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/bucketPolicyOnly/acl/user-test%40example.com?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "111" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJlbnRpdHkiOiJ1c2VyLXRlc3RAZXhhbXBsZS5jb20iLCJyb2xlIjoiUkVBREVSIn0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "519" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:00 GMT" ], "Etag": [ "CPmu4bnx/eECEAI=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uoau0xgFp6ib5wM0bBWjRlklvDRPOu0VZ-LFCeENUWXutmkXSfgUbtr2Nuefb7Pm_yLvCNqtB9B6k_N1V7AlvkN4_JEz67ZSXQ_sAD5L1teQIpGiqA" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYnVja2V0UG9saWN5T25seS8xNTU2ODM1ODQwMDU1MTYxL3VzZXItdGVzdEBleGFtcGxlLmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2J1Y2tldFBvbGljeU9ubHkvYWNsL3VzZXItdGVzdEBleGFtcGxlLmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImJ1Y2tldFBvbGljeU9ubHkiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0MDA1NTE2MSIsImVudGl0eSI6InVzZXItdGVzdEBleGFtcGxlLmNvbSIsInJvbGUiOiJSRUFERVIiLCJlbWFpbCI6InRlc3RAZXhhbXBsZS5jb20iLCJldGFnIjoiQ1BtdTRibngvZUVDRUFJPSJ9" } }, { "ID": "6e3d0eda38a3ab6e", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "59" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJpYW1Db25maWd1cmF0aW9uIjp7ImJ1Y2tldFBvbGljeU9ubHkiOnsiZW5hYmxlZCI6dHJ1ZX19fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "663" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:01 GMT" ], "Etag": [ "CAU=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpSPFJHLzusxOr_OvhStJlWEpOs2EuthMO0Ys6pS9bsQeP0fthp_VUZfa8_sN8TX6PJYpxIdFlxB2QUaIujot1cUrssoU74XFrAwoqhlmiE5y9Aw-w" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjIzOjU0LjYxMFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowMS4yNDJaIiwibWV0YWdlbmVyYXRpb24iOiI1IiwiaWFtQ29uZmlndXJhdGlvbiI6eyJidWNrZXRQb2xpY3lPbmx5Ijp7ImVuYWJsZWQiOnRydWUsImxvY2tlZFRpbWUiOiIyMDE5LTA3LTMxVDIyOjI0OjAxLjIzMFoifX0sImxvY2F0aW9uIjoiVVMiLCJ2ZXJzaW9uaW5nIjp7ImVuYWJsZWQiOmZhbHNlfSwibGlmZWN5Y2xlIjp7InJ1bGUiOlt7ImFjdGlvbiI6eyJ0eXBlIjoiRGVsZXRlIn0sImNvbmRpdGlvbiI6eyJhZ2UiOjMwfX1dfSwibGFiZWxzIjp7ImwxIjoidjIiLCJuZXciOiJuZXcifSwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJldGFnIjoiQ0FVPSJ9" } }, { "ID": "8f8dbb687dc49edb", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/acl?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "13230" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:01 GMT" ], "Expires": [ "Thu, 02 May 2019 22:24:01 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UpGpW2zLlN7nAgV5IVkKU3kx4QWHCkzAgMa-QPC1PyCol8CP9W605bMUmFMeerbR4enzmeNMvtb4a2HzBPUZ296YfGdtkt_6Guq82E226xzC5TPq4w" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6ImludmFsaWQiLCJtZXNzYWdlIjoiQ2Fubm90IGdldCBsZWdhY3kgQUNMcyBmb3IgYSBidWNrZXQgdGhhdCBoYXMgZW5hYmxlZCBCdWNrZXQgUG9saWN5IE9ubHkuIFJlYWQgbW9yZSBhdCBodHRwczovL2Nsb3VkLmdvb2dsZS5jb20vc3RvcmFnZS9kb2NzL2J1Y2tldC1wb2xpY3ktb25seS4iLCJkZWJ1Z0luZm8iOiJjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6SU5WQUxJRF9SRVFVRVNUX0ZPUl9CVUNLRVRfUE9MSUNZX09OTFlfUkVTT1VSQ0U6IENhbm5vdCBnZXQgbGVnYWN5IEFDTHMgZm9yIGEgYnVja2V0IHRoYXQgaGFzIGVuYWJsZWQgQnVja2V0IFBvbGljeSBPbmx5LiBSZWFkIG1vcmUgYXQgaHR0cHM6Ly9jbG91ZC5nb29nbGUuY29tL3N0b3JhZ2UvZG9jcy9idWNrZXQtcG9saWN5LW9ubHkuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkxpc3RBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChMaXN0QWNscy5qYXZhOjEwMSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkxpc3RBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChMaXN0QWNscy5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci5saXN0KEFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmphdmE6ODkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IENhbm5vdCBnZXQgbGVnYWN5IEFDTHMgZm9yIGEgYnVja2V0IHRoYXQgaGFzIGVuYWJsZWQgQnVja2V0IFBvbGljeSBPbmx5LiBSZWFkIG1vcmUgYXQgaHR0cHM6Ly9jbG91ZC5nb29nbGUuY29tL3N0b3JhZ2UvZG9jcy9idWNrZXQtcG9saWN5LW9ubHkuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPUlOVkFMSURfVkFMVUUsIGNhdGVnb3J5PVVTRVJfRVJST1IsIGNhdXNlPW51bGwsIGRlYnVnSW5mbz1jb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6SU5WQUxJRF9SRVFVRVNUX0ZPUl9CVUNLRVRfUE9MSUNZX09OTFlfUkVTT1VSQ0U6IENhbm5vdCBnZXQgbGVnYWN5IEFDTHMgZm9yIGEgYnVja2V0IHRoYXQgaGFzIGVuYWJsZWQgQnVja2V0IFBvbGljeSBPbmx5LiBSZWFkIG1vcmUgYXQgaHR0cHM6Ly9jbG91ZC5nb29nbGUuY29tL3N0b3JhZ2UvZG9jcy9idWNrZXQtcG9saWN5LW9ubHkuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkxpc3RBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChMaXN0QWNscy5qYXZhOjEwMSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkxpc3RBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChMaXN0QWNscy5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci5saXN0KEFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmphdmE6ODkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IENhbm5vdCBnZXQgbGVnYWN5IEFDTHMgZm9yIGEgYnVja2V0IHRoYXQgaGFzIGVuYWJsZWQgQnVja2V0IFBvbGljeSBPbmx5LiBSZWFkIG1vcmUgYXQgaHR0cHM6Ly9jbG91ZC5nb29nbGUuY29tL3N0b3JhZ2UvZG9jcy9idWNrZXQtcG9saWN5LW9ubHkuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZG9tYWluPWdsb2JhbCwgZXh0ZW5kZWRIZWxwPW51bGwsIGh0dHBIZWFkZXJzPXt9LCBodHRwU3RhdHVzPWJhZFJlcXVlc3QsIGludGVybmFsUmVhc29uPVJlYXNvbnthcmd1bWVudHM9e30sIGNhdXNlPW51bGwsIGNvZGU9Z2RhdGEuQ29yZUVycm9yRG9tYWluLklOVkFMSURfVkFMVUUsIGNyZWF0ZWRCeUJhY2tlbmQ9dHJ1ZSwgZGVidWdNZXNzYWdlPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpJTlZBTElEX1JFUVVFU1RfRk9SX0JVQ0tFVF9QT0xJQ1lfT05MWV9SRVNPVVJDRTogQ2Fubm90IGdldCBsZWdhY3kgQUNMcyBmb3IgYSBidWNrZXQgdGhhdCBoYXMgZW5hYmxlZCBCdWNrZXQgUG9saWN5IE9ubHkuIFJlYWQgbW9yZSBhdCBodHRwczovL2Nsb3VkLmdvb2dsZS5jb20vc3RvcmFnZS9kb2NzL2J1Y2tldC1wb2xpY3ktb25seS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuTGlzdEFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKExpc3RBY2xzLmphdmE6MTAxKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuTGlzdEFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKExpc3RBY2xzLmphdmE6MjUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLkFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmxpc3QoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YTo4OSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogQ2Fubm90IGdldCBsZWdhY3kgQUNMcyBmb3IgYSBidWNrZXQgdGhhdCBoYXMgZW5hYmxlZCBCdWNrZXQgUG9saWN5IE9ubHkuIFJlYWQgbW9yZSBhdCBodHRwczovL2Nsb3VkLmdvb2dsZS5jb20vc3RvcmFnZS9kb2NzL2J1Y2tldC1wb2xpY3ktb25seS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuLCBlcnJvclByb3RvQ29kZT1JTlZBTElEX1ZBTFVFLCBlcnJvclByb3RvRG9tYWluPWdkYXRhLkNvcmVFcnJvckRvbWFpbiwgZmlsdGVyZWRNZXNzYWdlPW51bGwsIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9Q2Fubm90IGdldCBsZWdhY3kgQUNMcyBmb3IgYSBidWNrZXQgdGhhdCBoYXMgZW5hYmxlZCBCdWNrZXQgUG9saWN5IE9ubHkuIFJlYWQgbW9yZSBhdCBodHRwczovL2Nsb3VkLmdvb2dsZS5jb20vc3RvcmFnZS9kb2NzL2J1Y2tldC1wb2xpY3ktb25seS4sIHVubmFtZWRBcmd1bWVudHM9W119LCBsb2NhdGlvbj1udWxsLCBtZXNzYWdlPUNhbm5vdCBnZXQgbGVnYWN5IEFDTHMgZm9yIGEgYnVja2V0IHRoYXQgaGFzIGVuYWJsZWQgQnVja2V0IFBvbGljeSBPbmx5LiBSZWFkIG1vcmUgYXQgaHR0cHM6Ly9jbG91ZC5nb29nbGUuY29tL3N0b3JhZ2UvZG9jcy9idWNrZXQtcG9saWN5LW9ubHkuLCByZWFzb249aW52YWxpZCwgcnBjQ29kZT00MDB9IENhbm5vdCBnZXQgbGVnYWN5IEFDTHMgZm9yIGEgYnVja2V0IHRoYXQgaGFzIGVuYWJsZWQgQnVja2V0IFBvbGljeSBPbmx5LiBSZWFkIG1vcmUgYXQgaHR0cHM6Ly9jbG91ZC5nb29nbGUuY29tL3N0b3JhZ2UvZG9jcy9idWNrZXQtcG9saWN5LW9ubHkuOiBjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6SU5WQUxJRF9SRVFVRVNUX0ZPUl9CVUNLRVRfUE9MSUNZX09OTFlfUkVTT1VSQ0U6IENhbm5vdCBnZXQgbGVnYWN5IEFDTHMgZm9yIGEgYnVja2V0IHRoYXQgaGFzIGVuYWJsZWQgQnVja2V0IFBvbGljeSBPbmx5LiBSZWFkIG1vcmUgYXQgaHR0cHM6Ly9jbG91ZC5nb29nbGUuY29tL3N0b3JhZ2UvZG9jcy9idWNrZXQtcG9saWN5LW9ubHkuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkxpc3RBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChMaXN0QWNscy5qYXZhOjEwMSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkxpc3RBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChMaXN0QWNscy5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci5saXN0KEFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmphdmE6ODkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IENhbm5vdCBnZXQgbGVnYWN5IEFDTHMgZm9yIGEgYnVja2V0IHRoYXQgaGFzIGVuYWJsZWQgQnVja2V0IFBvbGljeSBPbmx5LiBSZWFkIG1vcmUgYXQgaHR0cHM6Ly9jbG91ZC5nb29nbGUuY29tL3N0b3JhZ2UvZG9jcy9idWNrZXQtcG9saWN5LW9ubHkuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS5FcnJvckNvbGxlY3Rvci50b0ZhdWx0KEVycm9yQ29sbGVjdG9yLmphdmE6NTQpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5RXJyb3JDb252ZXJ0ZXIudG9GYXVsdChSb3N5RXJyb3JDb252ZXJ0ZXIuamF2YTo2Nylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lIYW5kbGVyJDIuY2FsbChSb3N5SGFuZGxlci5qYXZhOjI1OSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lIYW5kbGVyJDIuY2FsbChSb3N5SGFuZGxlci5qYXZhOjIzOSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkRpcmVjdEV4ZWN1dG9yLmV4ZWN1dGUoRGlyZWN0RXhlY3V0b3IuamF2YTozMClcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmV4ZWN1dGVMaXN0ZW5lcihBYnN0cmFjdEZ1dHVyZS5qYXZhOjExNDMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5jb21wbGV0ZShBYnN0cmFjdEZ1dHVyZS5qYXZhOjk2Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLnNldChBYnN0cmFjdEZ1dHVyZS5qYXZhOjczMSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkRpcmVjdEV4ZWN1dG9yLmV4ZWN1dGUoRGlyZWN0RXhlY3V0b3IuamF2YTozMClcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmV4ZWN1dGVMaXN0ZW5lcihBYnN0cmFjdEZ1dHVyZS5qYXZhOjExNDMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5jb21wbGV0ZShBYnN0cmFjdEZ1dHVyZS5qYXZhOjk2Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLnNldChBYnN0cmFjdEZ1dHVyZS5qYXZhOjczMSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnRocmVhZC5UaHJlYWRUcmFja2VycyRUaHJlYWRUcmFja2luZ1J1bm5hYmxlLnJ1bihUaHJlYWRUcmFja2Vycy5qYXZhOjEyNilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoVHJhY2VDb250ZXh0LmphdmE6NDUzKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuc2VydmVyLkNvbW1vbk1vZHVsZSRDb250ZXh0Q2FycnlpbmdFeGVjdXRvclNlcnZpY2UkMS5ydW5JbkNvbnRleHQoQ29tbW9uTW9kdWxlLmphdmE6ODAyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlJDEucnVuKFRyYWNlQ29udGV4dC5qYXZhOjQ2MClcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihUcmFjZUNvbnRleHQuamF2YTozMTkpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkQWJzdHJhY3RUcmFjZUNvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoVHJhY2VDb250ZXh0LmphdmE6MzExKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NTcpXG5cdGF0IGNvbS5nb29nbGUuZ3NlLmludGVybmFsLkRpc3BhdGNoUXVldWVJbXBsJFdvcmtlclRocmVhZC5ydW4oRGlzcGF0Y2hRdWV1ZUltcGwuamF2YTo0MDMpXG4ifV0sImNvZGUiOjQwMCwibWVzc2FnZSI6IkNhbm5vdCBnZXQgbGVnYWN5IEFDTHMgZm9yIGEgYnVja2V0IHRoYXQgaGFzIGVuYWJsZWQgQnVja2V0IFBvbGljeSBPbmx5LiBSZWFkIG1vcmUgYXQgaHR0cHM6Ly9jbG91ZC5nb29nbGUuY29tL3N0b3JhZ2UvZG9jcy9idWNrZXQtcG9saWN5LW9ubHkuIn19" } }, { "ID": "42ce6421b2c9fae4", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/bucketPolicyOnly/acl?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 403, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "13358" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:02 GMT" ], "Expires": [ "Thu, 02 May 2019 22:24:02 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UqJwxja3nYzWYbg_I5gWvOiow2ORuo8tNA-_Vzw7DX_YVhhb6_p1giUk3WjUHWt-lyDA13adhPGi4BDfIXzQyf-ZL3lsHoa2sNm29BIqRznw4mkAdE" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6ImZvcmJpZGRlbiIsIm1lc3NhZ2UiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHN0b3JhZ2Uub2JqZWN0cy5nZXQgYWNjZXNzIHRvIGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9idWNrZXRQb2xpY3lPbmx5LiIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpBQ0NFU1NfREVOSUVEOiBhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHN0b3JhZ2Uub2JqZWN0cy5nZXQgYWNjZXNzIHRvIGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9idWNrZXRQb2xpY3lPbmx5LlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5MaXN0QWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoTGlzdEFjbHMuamF2YToxMDEpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5MaXN0QWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoTGlzdEFjbHMuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IubGlzdChBY2Nlc3NDb250cm9sc0RlbGVnYXRvci5qYXZhOjg5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHN0b3JhZ2Uub2JqZWN0cy5nZXQgYWNjZXNzIHRvIGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9idWNrZXRQb2xpY3lPbmx5LlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cbmNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLkZhdWx0OiBJbW11dGFibGVFcnJvckRlZmluaXRpb257YmFzZT1GT1JCSURERU4sIGNhdGVnb3J5PVVTRVJfRVJST1IsIGNhdXNlPW51bGwsIGRlYnVnSW5mbz1jb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6QUNDRVNTX0RFTklFRDogYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20gZG9lcyBub3QgaGF2ZSBzdG9yYWdlLm9iamVjdHMuZ2V0IGFjY2VzcyB0byBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYnVja2V0UG9saWN5T25seS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuTGlzdEFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKExpc3RBY2xzLmphdmE6MTAxKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuTGlzdEFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKExpc3RBY2xzLmphdmE6MjUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLkFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmxpc3QoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YTo4OSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20gZG9lcyBub3QgaGF2ZSBzdG9yYWdlLm9iamVjdHMuZ2V0IGFjY2VzcyB0byBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYnVja2V0UG9saWN5T25seS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuLCBkb21haW49Z2xvYmFsLCBleHRlbmRlZEhlbHA9bnVsbCwgaHR0cEhlYWRlcnM9e30sIGh0dHBTdGF0dXM9Zm9yYmlkZGVuLCBpbnRlcm5hbFJlYXNvbj1SZWFzb257YXJndW1lbnRzPXt9LCBjYXVzZT1udWxsLCBjb2RlPWdkYXRhLkNvcmVFcnJvckRvbWFpbi5GT1JCSURERU4sIGNyZWF0ZWRCeUJhY2tlbmQ9dHJ1ZSwgZGVidWdNZXNzYWdlPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpBQ0NFU1NfREVOSUVEOiBhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHN0b3JhZ2Uub2JqZWN0cy5nZXQgYWNjZXNzIHRvIGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9idWNrZXRQb2xpY3lPbmx5LlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5MaXN0QWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoTGlzdEFjbHMuamF2YToxMDEpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5MaXN0QWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoTGlzdEFjbHMuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IubGlzdChBY2Nlc3NDb250cm9sc0RlbGVnYXRvci5qYXZhOjg5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHN0b3JhZ2Uub2JqZWN0cy5nZXQgYWNjZXNzIHRvIGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9idWNrZXRQb2xpY3lPbmx5LlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGVycm9yUHJvdG9Db2RlPUZPUkJJRERFTiwgZXJyb3JQcm90b0RvbWFpbj1nZGF0YS5Db3JlRXJyb3JEb21haW4sIGZpbHRlcmVkTWVzc2FnZT1udWxsLCBsb2NhdGlvbj1udWxsLCBtZXNzYWdlPWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc3RvcmFnZS5vYmplY3RzLmdldCBhY2Nlc3MgdG8gZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2J1Y2tldFBvbGljeU9ubHkuLCB1bm5hbWVkQXJndW1lbnRzPVtdfSwgbG9jYXRpb249bnVsbCwgbWVzc2FnZT1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHN0b3JhZ2Uub2JqZWN0cy5nZXQgYWNjZXNzIHRvIGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9idWNrZXRQb2xpY3lPbmx5LiwgcmVhc29uPWZvcmJpZGRlbiwgcnBjQ29kZT00MDN9IGFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc3RvcmFnZS5vYmplY3RzLmdldCBhY2Nlc3MgdG8gZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2J1Y2tldFBvbGljeU9ubHkuOiBjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6QUNDRVNTX0RFTklFRDogYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20gZG9lcyBub3QgaGF2ZSBzdG9yYWdlLm9iamVjdHMuZ2V0IGFjY2VzcyB0byBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYnVja2V0UG9saWN5T25seS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuTGlzdEFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKExpc3RBY2xzLmphdmE6MTAxKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuTGlzdEFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKExpc3RBY2xzLmphdmE6MjUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLkFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmxpc3QoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YTo4OSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20gZG9lcyBub3QgaGF2ZSBzdG9yYWdlLm9iamVjdHMuZ2V0IGFjY2VzcyB0byBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYnVja2V0UG9saWN5T25seS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLkVycm9yQ29sbGVjdG9yLnRvRmF1bHQoRXJyb3JDb2xsZWN0b3IuamF2YTo1NClcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lFcnJvckNvbnZlcnRlci50b0ZhdWx0KFJvc3lFcnJvckNvbnZlcnRlci5qYXZhOjY3KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUhhbmRsZXIkMi5jYWxsKFJvc3lIYW5kbGVyLmphdmE6MjU5KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUhhbmRsZXIkMi5jYWxsKFJvc3lIYW5kbGVyLmphdmE6MjM5KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRGlyZWN0RXhlY3V0b3IuZXhlY3V0ZShEaXJlY3RFeGVjdXRvci5qYXZhOjMwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuZXhlY3V0ZUxpc3RlbmVyKEFic3RyYWN0RnV0dXJlLmphdmE6MTE0Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmNvbXBsZXRlKEFic3RyYWN0RnV0dXJlLmphdmE6OTYzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuc2V0KEFic3RyYWN0RnV0dXJlLmphdmE6NzMxKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRGlyZWN0RXhlY3V0b3IuZXhlY3V0ZShEaXJlY3RFeGVjdXRvci5qYXZhOjMwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuZXhlY3V0ZUxpc3RlbmVyKEFic3RyYWN0RnV0dXJlLmphdmE6MTE0Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmNvbXBsZXRlKEFic3RyYWN0RnV0dXJlLmphdmE6OTYzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuc2V0KEFic3RyYWN0RnV0dXJlLmphdmE6NzMxKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIudGhyZWFkLlRocmVhZFRyYWNrZXJzJFRocmVhZFRyYWNraW5nUnVubmFibGUucnVuKFRocmVhZFRyYWNrZXJzLmphdmE6MTI2KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChUcmFjZUNvbnRleHQuamF2YTo0NTMpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5zZXJ2ZXIuQ29tbW9uTW9kdWxlJENvbnRleHRDYXJyeWluZ0V4ZWN1dG9yU2VydmljZSQxLnJ1bkluQ29udGV4dChDb21tb25Nb2R1bGUuamF2YTo4MDIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUkMS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDYwKVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkQWJzdHJhY3RUcmFjZUNvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKFRyYWNlQ29udGV4dC5qYXZhOjMxOSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChUcmFjZUNvbnRleHQuamF2YTozMTEpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuKFRyYWNlQ29udGV4dC5qYXZhOjQ1Nylcblx0YXQgY29tLmdvb2dsZS5nc2UuaW50ZXJuYWwuRGlzcGF0Y2hRdWV1ZUltcGwkV29ya2VyVGhyZWFkLnJ1bihEaXNwYXRjaFF1ZXVlSW1wbC5qYXZhOjQwMylcbiJ9XSwiY29kZSI6NDAzLCJtZXNzYWdlIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20gZG9lcyBub3QgaGF2ZSBzdG9yYWdlLm9iamVjdHMuZ2V0IGFjY2VzcyB0byBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYnVja2V0UG9saWN5T25seS4ifX0=" } }, { "ID": "0ca0bddf513110f4", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "45" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJpYW1Db25maWd1cmF0aW9uIjp7ImJ1Y2tldFBvbGljeU9ubHkiOnt9fX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "624" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:02 GMT" ], "Etag": [ "CAY=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpdDWPDU9-gPzHEieE0Rqx_40yf8fJLhwAP6fVsdS4F7I7sWj0h-Ti7VoDWciZgI_lgNUB7qyh08wjTAxrTLTsSiIYt2GR6ksxhDRupMoPWni5kXmE" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjIzOjU0LjYxMFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowMi4zNjFaIiwibWV0YWdlbmVyYXRpb24iOiI2IiwiaWFtQ29uZmlndXJhdGlvbiI6eyJidWNrZXRQb2xpY3lPbmx5Ijp7ImVuYWJsZWQiOmZhbHNlfX0sImxvY2F0aW9uIjoiVVMiLCJ2ZXJzaW9uaW5nIjp7ImVuYWJsZWQiOmZhbHNlfSwibGlmZWN5Y2xlIjp7InJ1bGUiOlt7ImFjdGlvbiI6eyJ0eXBlIjoiRGVsZXRlIn0sImNvbmRpdGlvbiI6eyJhZ2UiOjMwfX1dfSwibGFiZWxzIjp7ImwxIjoidjIiLCJuZXciOiJuZXcifSwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJldGFnIjoiQ0FZPSJ9" } }, { "ID": "8a8bee740102593d", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/bucketPolicyOnly/acl?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "2964" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:02 GMT" ], "Etag": [ "CPmu4bnx/eECEAI=" ], "Expires": [ "Thu, 02 May 2019 22:24:02 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uq59Mf8Ea4fgpDnUzupeIP3bGt3VpyI6HjL4KJtDKAD_h-Ua-AJSX3u3x4TCsx2MZcIVhMs9pW9SWsrIcsvsr3kGt2Je9W87LElbN5dlw02EItBcR4" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9scyIsIml0ZW1zIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYnVja2V0UG9saWN5T25seS8xNTU2ODM1ODQwMDU1MTYxL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2J1Y2tldFBvbGljeU9ubHkvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImJ1Y2tldFBvbGljeU9ubHkiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0MDA1NTE2MSIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDUG11NGJueC9lRUNFQUk9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYnVja2V0UG9saWN5T25seS8xNTU2ODM1ODQwMDU1MTYxL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9idWNrZXRQb2xpY3lPbmx5L2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiYnVja2V0UG9saWN5T25seSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQwMDU1MTYxIiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ1BtdTRibngvZUVDRUFJPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2J1Y2tldFBvbGljeU9ubHkvMTU1NjgzNTg0MDA1NTE2MS9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vYnVja2V0UG9saWN5T25seS9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImJ1Y2tldFBvbGljeU9ubHkiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0MDA1NTE2MSIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDUG11NGJueC9lRUNFQUk9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYnVja2V0UG9saWN5T25seS8xNTU2ODM1ODQwMDU1MTYxL3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9idWNrZXRQb2xpY3lPbmx5L2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiYnVja2V0UG9saWN5T25seSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQwMDU1MTYxIiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ1BtdTRibngvZUVDRUFJPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2J1Y2tldFBvbGljeU9ubHkvMTU1NjgzNTg0MDA1NTE2MS91c2VyLXRlc3RAZXhhbXBsZS5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9idWNrZXRQb2xpY3lPbmx5L2FjbC91c2VyLXRlc3RAZXhhbXBsZS5jb20iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJidWNrZXRQb2xpY3lPbmx5IiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDAwNTUxNjEiLCJlbnRpdHkiOiJ1c2VyLXRlc3RAZXhhbXBsZS5jb20iLCJyb2xlIjoiUkVBREVSIiwiZW1haWwiOiJ0ZXN0QGV4YW1wbGUuY29tIiwiZXRhZyI6IkNQbXU0Ym54L2VFQ0VBST0ifV19" } }, { "ID": "91ba2c22c5f5de9a", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/bucketPolicyOnly?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:24:03 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrwotKay181GHzZsWfp6BzJA4FDOIfK2s1WlzB9p8QsIEX42AtvMhkgLWqSIyEhb-MSv9snqx0WRwUs5sDN3_5NVoFTzQeLkDBR9mbsixI-udc8SLI" ] }, "Body": "" } }, { "ID": "43fec6c3a8c8cb63", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW4iLCJuYW1lIjoiY29uZGRlbCJ9Cg==", "Zm9v" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3161" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:03 GMT" ], "Etag": [ "CNHLq7vx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrrYnzZRz4GFV3BsHoF-vv9v2Lc13Wp6-P5iowSZFjqyykVhYZ6CkesIVxA2v2xNCbVeWgCBXCFFt9fje73cis1cECwwqrYLr5QF5bZCy4TsJ-LT8k" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb25kZGVsLzE1NTY4MzU4NDMzNjg0MDEiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jb25kZGVsIiwibmFtZSI6ImNvbmRkZWwiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0MzM2ODQwMSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowMy4zNjhaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDMuMzY4WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjAzLjM2OFoiLCJzaXplIjoiMyIsIm1kNUhhc2giOiJyTDBZMjB6QytGenQ3MlZQek1TazJBPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY29uZGRlbD9nZW5lcmF0aW9uPTE1NTY4MzU4NDMzNjg0MDEmYWx0PW1lZGlhIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY29uZGRlbC8xNTU2ODM1ODQzMzY4NDAxL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2NvbmRkZWwvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImNvbmRkZWwiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0MzM2ODQwMSIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDTkhMcTd2eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY29uZGRlbC8xNTU2ODM1ODQzMzY4NDAxL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jb25kZGVsL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY29uZGRlbCIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQzMzY4NDAxIiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ05ITHE3dngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NvbmRkZWwvMTU1NjgzNTg0MzM2ODQwMS9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY29uZGRlbC9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImNvbmRkZWwiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0MzM2ODQwMSIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDTkhMcTd2eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY29uZGRlbC8xNTU2ODM1ODQzMzY4NDAxL3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jb25kZGVsL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY29uZGRlbCIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQzMzY4NDAxIiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ05ITHE3dngvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJ6OFN1SFE9PSIsImV0YWciOiJDTkhMcTd2eC9lRUNFQUU9In0=" } }, { "ID": "ba03d9efb1402903", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/conddel?alt=json\u0026generation=1556835843368400\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 404, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "12249" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:03 GMT" ], "Expires": [ "Thu, 02 May 2019 22:24:03 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2Ur-mcvaL-eBgBoviwBg_r8LyEEK3JNyFaj0cFy2neOMo1pVkWpkGQ-3gz8vQNtAGoX-Q7_CMYLNv_I0pOoy5iRr-MdYKny5ICdC1s3ji5DwL7sqmn0" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6Im5vdEZvdW5kIiwibWVzc2FnZSI6Ik5vIHN1Y2ggb2JqZWN0OiBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY29uZGRlbCIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpPQkpFQ1RfTk9UX0ZPVU5EOiBObyBzdWNoIG9iamVjdDogZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NvbmRkZWxcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuRGVsZXRlT2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChEZWxldGVPYmplY3QuamF2YTo4OClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkRlbGV0ZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlT2JqZWN0LmphdmE6MjUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLk9iamVjdHNEZWxlZ2F0b3IuZGVsZXRlKE9iamVjdHNEZWxlZ2F0b3IuamF2YToxMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IE5vIHN1Y2ggb2JqZWN0OiBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY29uZGRlbFxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cbmNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLkZhdWx0OiBJbW11dGFibGVFcnJvckRlZmluaXRpb257YmFzZT1OT1RfRk9VTkQsIGNhdGVnb3J5PVVTRVJfRVJST1IsIGNhdXNlPW51bGwsIGRlYnVnSW5mbz1jb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6T0JKRUNUX05PVF9GT1VORDogTm8gc3VjaCBvYmplY3Q6IGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb25kZGVsXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkRlbGV0ZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlT2JqZWN0LmphdmE6ODgpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5EZWxldGVPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZU9iamVjdC5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLmRlbGV0ZShPYmplY3RzRGVsZWdhdG9yLmphdmE6MTEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBObyBzdWNoIG9iamVjdDogZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NvbmRkZWxcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuLCBkb21haW49Z2xvYmFsLCBleHRlbmRlZEhlbHA9bnVsbCwgaHR0cEhlYWRlcnM9e30sIGh0dHBTdGF0dXM9bm90Rm91bmQsIGludGVybmFsUmVhc29uPVJlYXNvbnthcmd1bWVudHM9e30sIGNhdXNlPW51bGwsIGNvZGU9Z2RhdGEuQ29yZUVycm9yRG9tYWluLk5PVF9GT1VORCwgY3JlYXRlZEJ5QmFja2VuZD10cnVlLCBkZWJ1Z01lc3NhZ2U9Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6Ok9CSkVDVF9OT1RfRk9VTkQ6IE5vIHN1Y2ggb2JqZWN0OiBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY29uZGRlbFxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5EZWxldGVPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZU9iamVjdC5qYXZhOjg4KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuRGVsZXRlT2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChEZWxldGVPYmplY3QuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uT2JqZWN0c0RlbGVnYXRvci5kZWxldGUoT2JqZWN0c0RlbGVnYXRvci5qYXZhOjExMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogTm8gc3VjaCBvYmplY3Q6IGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb25kZGVsXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZXJyb3JQcm90b0NvZGU9Tk9UX0ZPVU5ELCBlcnJvclByb3RvRG9tYWluPWdkYXRhLkNvcmVFcnJvckRvbWFpbiwgZmlsdGVyZWRNZXNzYWdlPW51bGwsIGxvY2F0aW9uPWVudGl0eS5yZXNvdXJjZV9pZC5uYW1lLCBtZXNzYWdlPU5vIHN1Y2ggb2JqZWN0OiBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY29uZGRlbCwgdW5uYW1lZEFyZ3VtZW50cz1bXX0sIGxvY2F0aW9uPWVudGl0eS5yZXNvdXJjZV9pZC5uYW1lLCBtZXNzYWdlPU5vIHN1Y2ggb2JqZWN0OiBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY29uZGRlbCwgcmVhc29uPW5vdEZvdW5kLCBycGNDb2RlPTQwNH0gTm8gc3VjaCBvYmplY3Q6IGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb25kZGVsOiBjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6T0JKRUNUX05PVF9GT1VORDogTm8gc3VjaCBvYmplY3Q6IGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb25kZGVsXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkRlbGV0ZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlT2JqZWN0LmphdmE6ODgpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5EZWxldGVPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZU9iamVjdC5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLmRlbGV0ZShPYmplY3RzRGVsZWdhdG9yLmphdmE6MTEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBObyBzdWNoIG9iamVjdDogZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NvbmRkZWxcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLkVycm9yQ29sbGVjdG9yLnRvRmF1bHQoRXJyb3JDb2xsZWN0b3IuamF2YTo1NClcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lFcnJvckNvbnZlcnRlci50b0ZhdWx0KFJvc3lFcnJvckNvbnZlcnRlci5qYXZhOjY3KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUhhbmRsZXIkMi5jYWxsKFJvc3lIYW5kbGVyLmphdmE6MjU5KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUhhbmRsZXIkMi5jYWxsKFJvc3lIYW5kbGVyLmphdmE6MjM5KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRGlyZWN0RXhlY3V0b3IuZXhlY3V0ZShEaXJlY3RFeGVjdXRvci5qYXZhOjMwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuZXhlY3V0ZUxpc3RlbmVyKEFic3RyYWN0RnV0dXJlLmphdmE6MTE0Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmNvbXBsZXRlKEFic3RyYWN0RnV0dXJlLmphdmE6OTYzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuc2V0KEFic3RyYWN0RnV0dXJlLmphdmE6NzMxKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRGlyZWN0RXhlY3V0b3IuZXhlY3V0ZShEaXJlY3RFeGVjdXRvci5qYXZhOjMwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuZXhlY3V0ZUxpc3RlbmVyKEFic3RyYWN0RnV0dXJlLmphdmE6MTE0Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmNvbXBsZXRlKEFic3RyYWN0RnV0dXJlLmphdmE6OTYzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuc2V0KEFic3RyYWN0RnV0dXJlLmphdmE6NzMxKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIudGhyZWFkLlRocmVhZFRyYWNrZXJzJFRocmVhZFRyYWNraW5nUnVubmFibGUucnVuKFRocmVhZFRyYWNrZXJzLmphdmE6MTI2KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChUcmFjZUNvbnRleHQuamF2YTo0NTMpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5zZXJ2ZXIuQ29tbW9uTW9kdWxlJENvbnRleHRDYXJyeWluZ0V4ZWN1dG9yU2VydmljZSQxLnJ1bkluQ29udGV4dChDb21tb25Nb2R1bGUuamF2YTo4MDIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUkMS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDYwKVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkQWJzdHJhY3RUcmFjZUNvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKFRyYWNlQ29udGV4dC5qYXZhOjMxOSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChUcmFjZUNvbnRleHQuamF2YTozMTEpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuKFRyYWNlQ29udGV4dC5qYXZhOjQ1Nylcblx0YXQgY29tLmdvb2dsZS5nc2UuaW50ZXJuYWwuRGlzcGF0Y2hRdWV1ZUltcGwkV29ya2VyVGhyZWFkLnJ1bihEaXNwYXRjaFF1ZXVlSW1wbC5qYXZhOjQwMylcbiJ9XSwiY29kZSI6NDA0LCJtZXNzYWdlIjoiTm8gc3VjaCBvYmplY3Q6IGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb25kZGVsIn19" } }, { "ID": "e26af2cd4673cc7c", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/conddel?alt=json\u0026ifMetagenerationMatch=2\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 412, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "12051" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:03 GMT" ], "Expires": [ "Thu, 02 May 2019 22:24:03 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2Uopfd5TJBzhGauzgyZW0h-TNFtDHz34k0kjbeuTeQPnMGBaiSFz9FdWA2gxp7qKp-V586voh7kqHgnVSW_QI4bWEuC35pj8NbCmmpNL_9pstpCgckw" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6ImNvbmRpdGlvbk5vdE1ldCIsIm1lc3NhZ2UiOiJQcmVjb25kaXRpb24gRmFpbGVkIiwibG9jYXRpb25UeXBlIjoiaGVhZGVyIiwibG9jYXRpb24iOiJJZi1NYXRjaCIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpJTkNPUlJFQ1RfTUVUQV9HRU5FUkFUSU9OX1NQRUNJRklFRDogRXhwZWN0ZWQgbWV0YWRhdGEgZ2VuZXJhdGlvbiB0byBtYXRjaCAyLCBidXQgYWN0dWFsIHZhbHVlIHdhcyAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5EZWxldGVPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZU9iamVjdC5qYXZhOjg4KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuRGVsZXRlT2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChEZWxldGVPYmplY3QuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uT2JqZWN0c0RlbGVnYXRvci5kZWxldGUoT2JqZWN0c0RlbGVnYXRvci5qYXZhOjExMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogRXhwZWN0ZWQgbWV0YWRhdGEgZ2VuZXJhdGlvbiB0byBtYXRjaCAyLCBidXQgYWN0dWFsIHZhbHVlIHdhcyAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cbmNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLkZhdWx0OiBJbW11dGFibGVFcnJvckRlZmluaXRpb257YmFzZT1QUkVDT05ESVRJT05fRkFJTEVELCBjYXRlZ29yeT1VU0VSX0VSUk9SLCBjYXVzZT1udWxsLCBkZWJ1Z0luZm89Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OklOQ09SUkVDVF9NRVRBX0dFTkVSQVRJT05fU1BFQ0lGSUVEOiBFeHBlY3RlZCBtZXRhZGF0YSBnZW5lcmF0aW9uIHRvIG1hdGNoIDIsIGJ1dCBhY3R1YWwgdmFsdWUgd2FzIDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkRlbGV0ZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlT2JqZWN0LmphdmE6ODgpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5EZWxldGVPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZU9iamVjdC5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLmRlbGV0ZShPYmplY3RzRGVsZWdhdG9yLmphdmE6MTEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBFeHBlY3RlZCBtZXRhZGF0YSBnZW5lcmF0aW9uIHRvIG1hdGNoIDIsIGJ1dCBhY3R1YWwgdmFsdWUgd2FzIDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZG9tYWluPWdsb2JhbCwgZXh0ZW5kZWRIZWxwPW51bGwsIGh0dHBIZWFkZXJzPXt9LCBodHRwU3RhdHVzPXByZWNvbmRpdGlvbkZhaWxlZCwgaW50ZXJuYWxSZWFzb249UmVhc29ue2FyZ3VtZW50cz17fSwgY2F1c2U9bnVsbCwgY29kZT1nZGF0YS5Db3JlRXJyb3JEb21haW4uQ09ORElUSU9OX05PVF9NRVQsIGNyZWF0ZWRCeUJhY2tlbmQ9dHJ1ZSwgZGVidWdNZXNzYWdlPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpJTkNPUlJFQ1RfTUVUQV9HRU5FUkFUSU9OX1NQRUNJRklFRDogRXhwZWN0ZWQgbWV0YWRhdGEgZ2VuZXJhdGlvbiB0byBtYXRjaCAyLCBidXQgYWN0dWFsIHZhbHVlIHdhcyAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5EZWxldGVPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZU9iamVjdC5qYXZhOjg4KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuRGVsZXRlT2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChEZWxldGVPYmplY3QuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uT2JqZWN0c0RlbGVnYXRvci5kZWxldGUoT2JqZWN0c0RlbGVnYXRvci5qYXZhOjExMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogRXhwZWN0ZWQgbWV0YWRhdGEgZ2VuZXJhdGlvbiB0byBtYXRjaCAyLCBidXQgYWN0dWFsIHZhbHVlIHdhcyAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGVycm9yUHJvdG9Db2RlPUNPTkRJVElPTl9OT1RfTUVULCBlcnJvclByb3RvRG9tYWluPWdkYXRhLkNvcmVFcnJvckRvbWFpbiwgZmlsdGVyZWRNZXNzYWdlPW51bGwsIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9bnVsbCwgdW5uYW1lZEFyZ3VtZW50cz1bXX0sIGxvY2F0aW9uPWhlYWRlcnMuSWYtTWF0Y2gsIG1lc3NhZ2U9UHJlY29uZGl0aW9uIEZhaWxlZCwgcmVhc29uPWNvbmRpdGlvbk5vdE1ldCwgcnBjQ29kZT00MTJ9IFByZWNvbmRpdGlvbiBGYWlsZWQ6IGNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpJTkNPUlJFQ1RfTUVUQV9HRU5FUkFUSU9OX1NQRUNJRklFRDogRXhwZWN0ZWQgbWV0YWRhdGEgZ2VuZXJhdGlvbiB0byBtYXRjaCAyLCBidXQgYWN0dWFsIHZhbHVlIHdhcyAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5EZWxldGVPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZU9iamVjdC5qYXZhOjg4KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuRGVsZXRlT2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChEZWxldGVPYmplY3QuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uT2JqZWN0c0RlbGVnYXRvci5kZWxldGUoT2JqZWN0c0RlbGVnYXRvci5qYXZhOjExMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogRXhwZWN0ZWQgbWV0YWRhdGEgZ2VuZXJhdGlvbiB0byBtYXRjaCAyLCBidXQgYWN0dWFsIHZhbHVlIHdhcyAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRXJyb3JDb2xsZWN0b3IudG9GYXVsdChFcnJvckNvbGxlY3Rvci5qYXZhOjU0KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUVycm9yQ29udmVydGVyLnRvRmF1bHQoUm9zeUVycm9yQ29udmVydGVyLmphdmE6NjcpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyNTkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyMzkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci50aHJlYWQuVGhyZWFkVHJhY2tlcnMkVGhyZWFkVHJhY2tpbmdSdW5uYWJsZS5ydW4oVGhyZWFkVHJhY2tlcnMuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjQ1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnNlcnZlci5Db21tb25Nb2R1bGUkQ29udGV4dENhcnJ5aW5nRXhlY3V0b3JTZXJ2aWNlJDEucnVuSW5Db250ZXh0KENvbW1vbk1vZHVsZS5qYXZhOjgwMilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZSQxLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NjApXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoVHJhY2VDb250ZXh0LmphdmE6MzE5KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjMxMSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDU3KVxuXHRhdCBjb20uZ29vZ2xlLmdzZS5pbnRlcm5hbC5EaXNwYXRjaFF1ZXVlSW1wbCRXb3JrZXJUaHJlYWQucnVuKERpc3BhdGNoUXVldWVJbXBsLmphdmE6NDAzKVxuIn1dLCJjb2RlIjo0MTIsIm1lc3NhZ2UiOiJQcmVjb25kaXRpb24gRmFpbGVkIn19" } }, { "ID": "857f8a30eb55b023", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/conddel?alt=json\u0026ifMetagenerationNotMatch=1\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 304, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:24:04 GMT" ], "Expires": [ "Thu, 02 May 2019 22:24:04 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uprv3QMjU4zz49ScYI4YaY9FitNwO7wGMQ1KZ8Y99w4D7keznFfA8M80bMdKvSH55jsWsDoLKcQ1VvIqIEUw88NqSfUM7E5SR_y5zfDaCf_uHSlgPM" ] }, "Body": "" } }, { "ID": "4c69a7dc19302935", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/conddel?alt=json\u0026generation=1556835843368401\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:24:04 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpoiZa1zqMV-8ZkeUrvT6Xi0uJul6yGWWth5s3YbFtA2p0-6vc_54sNtEbxbnsASZyMDXLelHaCSixgcVT6JDVELrXHDim9gHcjjlSTF6BsHWu181A" ] }, "Body": "" } }, { "ID": "834f05b1eb2dbc32", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW4iLCJuYW1lIjoib2JqMSJ9Cg==", "TuDshcL7vdCAXh8L42NvEQ==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3150" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:04 GMT" ], "Etag": [ "CLnS+bvx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UozIFQVqWdhJxDLMyV7dfkeraSOw2Mw_AsI_aCWnAUudrz4HjQgZ4kbnvKXJfNF3SMQhxzxZHhk1Otmw7PgPxL7HyDkPDyK1DeHDc8GyfY1B3Q3YfA" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoxLzE1NTY4MzU4NDQ2NDcyMjUiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoxIiwibmFtZSI6Im9iajEiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowNC42NDZaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDQuNjQ2WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA0LjY0NloiLCJzaXplIjoiMTYiLCJtZDVIYXNoIjoiU25hL1VXdjdtY1pJMjNvRTV0VWFiUT09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajE/Z2VuZXJhdGlvbj0xNTU2ODM1ODQ0NjQ3MjI1JmFsdD1tZWRpYSIsImNhY2hlQ29udHJvbCI6InB1YmxpYywgbWF4LWFnZT02MCIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEvMTU1NjgzNTg0NDY0NzIyNS9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoxL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDQ2NDcyMjUiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0xuUytidngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEvMTU1NjgzNTg0NDY0NzIyNS9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMS9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNMblMrYnZ4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoxLzE1NTY4MzU4NDQ2NDcyMjUvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajEvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDQ2NDcyMjUiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0xuUytidngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEvMTU1NjgzNTg0NDY0NzIyNS91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMS9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNMblMrYnZ4L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoiQ1Q2ZFRBPT0iLCJldGFnIjoiQ0xuUytidngvZUVDRUFFPSJ9" } }, { "ID": "34a1730e8bbe1d09", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW4iLCJuYW1lIjoib2JqMiJ9Cg==", "55GZ37DvGFQS3PnkEKv3Jg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3150" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:05 GMT" ], "Etag": [ "CJ2Xkrzx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoVrbP1vUH6TU_zfm_Aaca624z-91MoULnLIBcn9Hg4htv5T5Z6B4XYJMFZUuDjWWeBhR6EpG1UZL4iJe0TJybYQ2CCsB_k63CcOex39xaOIT8UYUA" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoyLzE1NTY4MzU4NDUwNDkyNDUiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoyIiwibmFtZSI6Im9iajIiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTA0OTI0NSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowNS4wNDhaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDUuMDQ4WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA1LjA0OFoiLCJzaXplIjoiMTYiLCJtZDVIYXNoIjoiQ0Mxd2x3ck1PSXEwZHZNa015bFVoZz09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajI/Z2VuZXJhdGlvbj0xNTU2ODM1ODQ1MDQ5MjQ1JmFsdD1tZWRpYSIsImNhY2hlQ29udHJvbCI6InB1YmxpYywgbWF4LWFnZT02MCIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajIvMTU1NjgzNTg0NTA0OTI0NS9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoyL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoyIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDUwNDkyNDUiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0oyWGtyengvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajIvMTU1NjgzNTg0NTA0OTI0NS9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMi9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajIiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTA0OTI0NSIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNKMlhrcnp4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoyLzE1NTY4MzU4NDUwNDkyNDUvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajIvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoyIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDUwNDkyNDUiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0oyWGtyengvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajIvMTU1NjgzNTg0NTA0OTI0NS91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMi9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajIiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTA0OTI0NSIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNKMlhrcnp4L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoialY1QVZRPT0iLCJldGFnIjoiQ0oyWGtyengvZUVDRUFFPSJ9" } }, { "ID": "b7c2c8ec1e65fb6d", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW4iLCJuYW1lIjoib2JqL3dpdGgvc2xhc2hlcyJ9Cg==", "kT7fkMXrRdrhn2P2+EeT5g==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3366" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:05 GMT" ], "Etag": [ "COqurrzx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrEgFAbU2gAqyKMITI9vr9kAgIBfNY3ZGs1l2_X4e-fVtNb01M9N81N-83LdChVzrk8iB09yuKUKdxRc0nMYrgy7S1fqPwbJdsQ6TJfMB05JJj6qr4" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmovd2l0aC9zbGFzaGVzLzE1NTY4MzU4NDU1MTEwMTgiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmolMkZ3aXRoJTJGc2xhc2hlcyIsIm5hbWUiOiJvYmovd2l0aC9zbGFzaGVzIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDU1MTEwMTgiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW4iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDUuNTEwWiIsInVwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA1LjUxMFoiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowNS41MTBaIiwic2l6ZSI6IjE2IiwibWQ1SGFzaCI6InVlei9oSjZ3QXJlRFFuY2NEVWR4Zmc9PSIsIm1lZGlhTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmolMkZ3aXRoJTJGc2xhc2hlcz9nZW5lcmF0aW9uPTE1NTY4MzU4NDU1MTEwMTgmYWx0PW1lZGlhIiwiY2FjaGVDb250cm9sIjoicHVibGljLCBtYXgtYWdlPTYwIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqL3dpdGgvc2xhc2hlcy8xNTU2ODM1ODQ1NTExMDE4L3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iaiUyRndpdGglMkZzbGFzaGVzL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmovd2l0aC9zbGFzaGVzIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDU1MTEwMTgiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ09xdXJyengvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iai93aXRoL3NsYXNoZXMvMTU1NjgzNTg0NTUxMTAxOC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqJTJGd2l0aCUyRnNsYXNoZXMvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmovd2l0aC9zbGFzaGVzIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDU1MTEwMTgiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDT3F1cnJ6eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqL3dpdGgvc2xhc2hlcy8xNTU2ODM1ODQ1NTExMDE4L3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmolMkZ3aXRoJTJGc2xhc2hlcy9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iai93aXRoL3NsYXNoZXMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTUxMTAxOCIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDT3F1cnJ6eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqL3dpdGgvc2xhc2hlcy8xNTU2ODM1ODQ1NTExMDE4L3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmolMkZ3aXRoJTJGc2xhc2hlcy9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iai93aXRoL3NsYXNoZXMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTUxMTAxOCIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNPcXVycnp4L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoib2VvK0ZBPT0iLCJldGFnIjoiQ09xdXJyengvZUVDRUFFPSJ9" } }, { "ID": "0dbae3d4b454f434", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/obj%2Fwith%2Fslashes?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3366" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:05 GMT" ], "Etag": [ "COqurrzx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uqk7CzWGAqaT12X_fTymveyPtsPJIPHD814QaAOIQLA_AJo_4OtnQOOXJM2jJhIZ1Co4NgEmboDUG9su4SN5fDTHObNh9elLts9VpUJ9iSYrIsn-Os" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmovd2l0aC9zbGFzaGVzLzE1NTY4MzU4NDU1MTEwMTgiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmolMkZ3aXRoJTJGc2xhc2hlcyIsIm5hbWUiOiJvYmovd2l0aC9zbGFzaGVzIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDU1MTEwMTgiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW4iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDUuNTEwWiIsInVwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA1LjUxMFoiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowNS41MTBaIiwic2l6ZSI6IjE2IiwibWQ1SGFzaCI6InVlei9oSjZ3QXJlRFFuY2NEVWR4Zmc9PSIsIm1lZGlhTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmolMkZ3aXRoJTJGc2xhc2hlcz9nZW5lcmF0aW9uPTE1NTY4MzU4NDU1MTEwMTgmYWx0PW1lZGlhIiwiY2FjaGVDb250cm9sIjoicHVibGljLCBtYXgtYWdlPTYwIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqL3dpdGgvc2xhc2hlcy8xNTU2ODM1ODQ1NTExMDE4L3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iaiUyRndpdGglMkZzbGFzaGVzL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmovd2l0aC9zbGFzaGVzIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDU1MTEwMTgiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ09xdXJyengvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iai93aXRoL3NsYXNoZXMvMTU1NjgzNTg0NTUxMTAxOC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqJTJGd2l0aCUyRnNsYXNoZXMvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmovd2l0aC9zbGFzaGVzIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDU1MTEwMTgiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDT3F1cnJ6eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqL3dpdGgvc2xhc2hlcy8xNTU2ODM1ODQ1NTExMDE4L3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmolMkZ3aXRoJTJGc2xhc2hlcy9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iai93aXRoL3NsYXNoZXMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTUxMTAxOCIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDT3F1cnJ6eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqL3dpdGgvc2xhc2hlcy8xNTU2ODM1ODQ1NTExMDE4L3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmolMkZ3aXRoJTJGc2xhc2hlcy9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iai93aXRoL3NsYXNoZXMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTUxMTAxOCIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNPcXVycnp4L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoib2VvK0ZBPT0iLCJldGFnIjoiQ09xdXJyengvZUVDRUFFPSJ9" } }, { "ID": "3793882b91d38a07", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/obj1?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3150" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:06 GMT" ], "Etag": [ "CLnS+bvx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpzUH_BRjU20OGbDAW2dy0lx9Gk_1Ko7zks6KG6OEpq0pBPfCIBjkCeIZTxKxtvxnOd1hqlZF7SlbNoyNUqX5UFXpZY5NjP5GTeUkm512vaBR5vnDI" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoxLzE1NTY4MzU4NDQ2NDcyMjUiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoxIiwibmFtZSI6Im9iajEiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowNC42NDZaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDQuNjQ2WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA0LjY0NloiLCJzaXplIjoiMTYiLCJtZDVIYXNoIjoiU25hL1VXdjdtY1pJMjNvRTV0VWFiUT09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajE/Z2VuZXJhdGlvbj0xNTU2ODM1ODQ0NjQ3MjI1JmFsdD1tZWRpYSIsImNhY2hlQ29udHJvbCI6InB1YmxpYywgbWF4LWFnZT02MCIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEvMTU1NjgzNTg0NDY0NzIyNS9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoxL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDQ2NDcyMjUiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0xuUytidngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEvMTU1NjgzNTg0NDY0NzIyNS9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMS9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNMblMrYnZ4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoxLzE1NTY4MzU4NDQ2NDcyMjUvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajEvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDQ2NDcyMjUiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0xuUytidngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEvMTU1NjgzNTg0NDY0NzIyNS91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMS9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNMblMrYnZ4L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoiQ1Q2ZFRBPT0iLCJldGFnIjoiQ0xuUytidngvZUVDRUFFPSJ9" } }, { "ID": "39924c2826bcd33f", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/obj2?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3150" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:06 GMT" ], "Etag": [ "CJ2Xkrzx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrgOr-dpWoY-JJi6vRigJX3Mpi_WQ4zWvWKK382DCP-mzWSnrpbaOzijhTCdNz6pmXskVVs30APwlqZgvb-S6xAwXqKJG5n6832Py4UlTdDR_INTew" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoyLzE1NTY4MzU4NDUwNDkyNDUiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoyIiwibmFtZSI6Im9iajIiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTA0OTI0NSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowNS4wNDhaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDUuMDQ4WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA1LjA0OFoiLCJzaXplIjoiMTYiLCJtZDVIYXNoIjoiQ0Mxd2x3ck1PSXEwZHZNa015bFVoZz09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajI/Z2VuZXJhdGlvbj0xNTU2ODM1ODQ1MDQ5MjQ1JmFsdD1tZWRpYSIsImNhY2hlQ29udHJvbCI6InB1YmxpYywgbWF4LWFnZT02MCIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajIvMTU1NjgzNTg0NTA0OTI0NS9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoyL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoyIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDUwNDkyNDUiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0oyWGtyengvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajIvMTU1NjgzNTg0NTA0OTI0NS9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMi9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajIiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTA0OTI0NSIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNKMlhrcnp4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoyLzE1NTY4MzU4NDUwNDkyNDUvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajIvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoyIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDUwNDkyNDUiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0oyWGtyengvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajIvMTU1NjgzNTg0NTA0OTI0NS91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMi9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajIiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTA0OTI0NSIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNKMlhrcnp4L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoialY1QVZRPT0iLCJldGFnIjoiQ0oyWGtyengvZUVDRUFFPSJ9" } }, { "ID": "89ea9ab5e21a635e", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026delimiter=\u0026pageToken=\u0026prefix=obj\u0026prettyPrint=false\u0026projection=full\u0026versions=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "9705" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:06 GMT" ], "Expires": [ "Thu, 02 May 2019 22:24:06 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uqj9dj5PbUhIU3baBv98vMViDP-BnVPs0APrFYL4jSbKc7fK6eAGoyDfsccGzxK-t0lGvozizW4ltrga8DXo_oxlZ9-k5a85v9i0PWTFIisPC7xuL8" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iai93aXRoL3NsYXNoZXMvMTU1NjgzNTg0NTUxMTAxOCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iaiUyRndpdGglMkZzbGFzaGVzIiwibmFtZSI6Im9iai93aXRoL3NsYXNoZXMiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTUxMTAxOCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowNS41MTBaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDUuNTEwWiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA1LjUxMFoiLCJzaXplIjoiMTYiLCJtZDVIYXNoIjoidWV6L2hKNndBcmVEUW5jY0RVZHhmZz09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iaiUyRndpdGglMkZzbGFzaGVzP2dlbmVyYXRpb249MTU1NjgzNTg0NTUxMTAxOCZhbHQ9bWVkaWEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmovd2l0aC9zbGFzaGVzLzE1NTY4MzU4NDU1MTEwMTgvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqJTJGd2l0aCUyRnNsYXNoZXMvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iai93aXRoL3NsYXNoZXMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTUxMTAxOCIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDT3F1cnJ6eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqL3dpdGgvc2xhc2hlcy8xNTU2ODM1ODQ1NTExMDE4L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmolMkZ3aXRoJTJGc2xhc2hlcy9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iai93aXRoL3NsYXNoZXMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTUxMTAxOCIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNPcXVycnp4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmovd2l0aC9zbGFzaGVzLzE1NTY4MzU4NDU1MTEwMTgvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iaiUyRndpdGglMkZzbGFzaGVzL2FjbC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqL3dpdGgvc2xhc2hlcyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1NTExMDE4IiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNPcXVycnp4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmovd2l0aC9zbGFzaGVzLzE1NTY4MzU4NDU1MTEwMTgvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iaiUyRndpdGglMkZzbGFzaGVzL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqL3dpdGgvc2xhc2hlcyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1NTExMDE4IiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ09xdXJyengvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJvZW8rRkE9PSIsImV0YWciOiJDT3F1cnJ6eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoxLzE1NTY4MzU4NDQ2NDcyMjUiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoxIiwibmFtZSI6Im9iajEiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowNC42NDZaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDQuNjQ2WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA0LjY0NloiLCJzaXplIjoiMTYiLCJtZDVIYXNoIjoiU25hL1VXdjdtY1pJMjNvRTV0VWFiUT09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajE/Z2VuZXJhdGlvbj0xNTU2ODM1ODQ0NjQ3MjI1JmFsdD1tZWRpYSIsImNhY2hlQ29udHJvbCI6InB1YmxpYywgbWF4LWFnZT02MCIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEvMTU1NjgzNTg0NDY0NzIyNS9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoxL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDQ2NDcyMjUiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0xuUytidngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEvMTU1NjgzNTg0NDY0NzIyNS9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMS9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNMblMrYnZ4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoxLzE1NTY4MzU4NDQ2NDcyMjUvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajEvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDQ2NDcyMjUiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0xuUytidngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEvMTU1NjgzNTg0NDY0NzIyNS91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMS9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNMblMrYnZ4L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoiQ1Q2ZFRBPT0iLCJldGFnIjoiQ0xuUytidngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMi8xNTU2ODM1ODQ1MDQ5MjQ1Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMiIsIm5hbWUiOiJvYmoyIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDUwNDkyNDUiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW4iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDUuMDQ4WiIsInVwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA1LjA0OFoiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowNS4wNDhaIiwic2l6ZSI6IjE2IiwibWQ1SGFzaCI6IkNDMXdsd3JNT0lxMGR2TWtNeWxVaGc9PSIsIm1lZGlhTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoyP2dlbmVyYXRpb249MTU1NjgzNTg0NTA0OTI0NSZhbHQ9bWVkaWEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoyLzE1NTY4MzU4NDUwNDkyNDUvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMi9hY2wvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqMiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1MDQ5MjQ1IiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNKMlhrcnp4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoyLzE1NTY4MzU4NDUwNDkyNDUvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajIvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoyIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDUwNDkyNDUiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDSjJYa3J6eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMi8xNTU2ODM1ODQ1MDQ5MjQ1L3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoyL2FjbC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqMiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1MDQ5MjQ1IiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNKMlhrcnp4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoyLzE1NTY4MzU4NDUwNDkyNDUvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajIvYWNsL3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoyIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDUwNDkyNDUiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDSjJYa3J6eC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6ImpWNUFWUT09IiwiZXRhZyI6IkNKMlhrcnp4L2VFQ0VBRT0ifV19" } }, { "ID": "b27c106562362f6b", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026delimiter=\u0026maxResults=1\u0026pageToken=\u0026prefix=obj\u0026prettyPrint=false\u0026projection=full\u0026versions=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "3446" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:06 GMT" ], "Expires": [ "Thu, 02 May 2019 22:24:06 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoIo3JJa2rfg9_o3bXN_5QU6XU_iIrWYfuEuvKTQL0O5tjIHkODIDd4biyHxjbGNFnrQNbkiEUXWEBlo-3fTVgfFTOWuaPpgae-SafTBP8h5X5ddJ4" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwibmV4dFBhZ2VUb2tlbiI6IkNoQnZZbW92ZDJsMGFDOXpiR0Z6YUdWeiIsIml0ZW1zIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmovd2l0aC9zbGFzaGVzLzE1NTY4MzU4NDU1MTEwMTgiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmolMkZ3aXRoJTJGc2xhc2hlcyIsIm5hbWUiOiJvYmovd2l0aC9zbGFzaGVzIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDU1MTEwMTgiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW4iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDUuNTEwWiIsInVwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA1LjUxMFoiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowNS41MTBaIiwic2l6ZSI6IjE2IiwibWQ1SGFzaCI6InVlei9oSjZ3QXJlRFFuY2NEVWR4Zmc9PSIsIm1lZGlhTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmolMkZ3aXRoJTJGc2xhc2hlcz9nZW5lcmF0aW9uPTE1NTY4MzU4NDU1MTEwMTgmYWx0PW1lZGlhIiwiY2FjaGVDb250cm9sIjoicHVibGljLCBtYXgtYWdlPTYwIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqL3dpdGgvc2xhc2hlcy8xNTU2ODM1ODQ1NTExMDE4L3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iaiUyRndpdGglMkZzbGFzaGVzL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmovd2l0aC9zbGFzaGVzIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDU1MTEwMTgiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ09xdXJyengvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iai93aXRoL3NsYXNoZXMvMTU1NjgzNTg0NTUxMTAxOC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqJTJGd2l0aCUyRnNsYXNoZXMvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmovd2l0aC9zbGFzaGVzIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDU1MTEwMTgiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDT3F1cnJ6eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqL3dpdGgvc2xhc2hlcy8xNTU2ODM1ODQ1NTExMDE4L3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmolMkZ3aXRoJTJGc2xhc2hlcy9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iai93aXRoL3NsYXNoZXMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTUxMTAxOCIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDT3F1cnJ6eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqL3dpdGgvc2xhc2hlcy8xNTU2ODM1ODQ1NTExMDE4L3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmolMkZ3aXRoJTJGc2xhc2hlcy9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iai93aXRoL3NsYXNoZXMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTUxMTAxOCIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNPcXVycnp4L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoib2VvK0ZBPT0iLCJldGFnIjoiQ09xdXJyengvZUVDRUFFPSJ9XX0=" } }, { "ID": "ca654b46531c4cb2", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026delimiter=\u0026maxResults=1\u0026pageToken=ChBvYmovd2l0aC9zbGFzaGVz\u0026prefix=obj\u0026prettyPrint=false\u0026projection=full\u0026versions=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "3214" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:07 GMT" ], "Expires": [ "Thu, 02 May 2019 22:24:07 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqINI0Ii418NlxoYErOrjhTKb3-G3n-8h1Ryc_4YT4Tksc7WXA9m4CcJWInyhJahYC-UUrM47O5EK-3FUt3toZOZxWlbwhE6Sfnra0H-CqjmvxWyRs" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwibmV4dFBhZ2VUb2tlbiI6IkNnUnZZbW94IiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEvMTU1NjgzNTg0NDY0NzIyNSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajEiLCJuYW1lIjoib2JqMSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ0NjQ3MjI1IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA0LjY0NloiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowNC42NDZaIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDQuNjQ2WiIsInNpemUiOiIxNiIsIm1kNUhhc2giOiJTbmEvVVd2N21jWkkyM29FNXRVYWJRPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMT9nZW5lcmF0aW9uPTE1NTY4MzU4NDQ2NDcyMjUmYWx0PW1lZGlhIiwiY2FjaGVDb250cm9sIjoicHVibGljLCBtYXgtYWdlPTYwIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMS8xNTU2ODM1ODQ0NjQ3MjI1L3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajEvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDTG5TK2J2eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMS8xNTU2ODM1ODQ0NjQ3MjI1L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoxL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqMSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ0NjQ3MjI1IiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0xuUytidngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEvMTU1NjgzNTg0NDY0NzIyNS9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMS9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDTG5TK2J2eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMS8xNTU2ODM1ODQ0NjQ3MjI1L3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoxL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqMSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ0NjQ3MjI1IiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ0xuUytidngvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJDVDZkVEE9PSIsImV0YWciOiJDTG5TK2J2eC9lRUNFQUU9In1dfQ==" } }, { "ID": "0186889a60e651db", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026delimiter=\u0026maxResults=1\u0026pageToken=CgRvYmox\u0026prefix=obj\u0026prettyPrint=false\u0026projection=full\u0026versions=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "3187" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:07 GMT" ], "Expires": [ "Thu, 02 May 2019 22:24:07 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpFTK3QnFf4m9htpY4s3P9_NHuDiQl8InpJoWPOaQHo0XaYnSoSqkH7CcUbm0-sWamsCZbd4DHoXHLCrea3ff9rLpWlptkL0aMKV_Dleb1Xm-j14fQ" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajIvMTU1NjgzNTg0NTA0OTI0NSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajIiLCJuYW1lIjoib2JqMiIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1MDQ5MjQ1IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA1LjA0OFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowNS4wNDhaIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDUuMDQ4WiIsInNpemUiOiIxNiIsIm1kNUhhc2giOiJDQzF3bHdyTU9JcTBkdk1rTXlsVWhnPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMj9nZW5lcmF0aW9uPTE1NTY4MzU4NDUwNDkyNDUmYWx0PW1lZGlhIiwiY2FjaGVDb250cm9sIjoicHVibGljLCBtYXgtYWdlPTYwIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMi8xNTU2ODM1ODQ1MDQ5MjQ1L3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajIvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajIiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTA0OTI0NSIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDSjJYa3J6eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMi8xNTU2ODM1ODQ1MDQ5MjQ1L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoyL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqMiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1MDQ5MjQ1IiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0oyWGtyengvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajIvMTU1NjgzNTg0NTA0OTI0NS9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMi9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajIiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTA0OTI0NSIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDSjJYa3J6eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMi8xNTU2ODM1ODQ1MDQ5MjQ1L3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoyL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqMiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1MDQ5MjQ1IiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ0oyWGtyengvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJqVjVBVlE9PSIsImV0YWciOiJDSjJYa3J6eC9lRUNFQUU9In1dfQ==" } }, { "ID": "a253776f79c46fe1", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026delimiter=\u0026maxResults=1\u0026pageToken=\u0026prefix=obj\u0026prettyPrint=false\u0026projection=full\u0026versions=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "3446" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:07 GMT" ], "Expires": [ "Thu, 02 May 2019 22:24:07 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uoadifz-4B7kC7DvXOyrNa5omK5-DXUNJBtT_d5I1jciPUvGlRm1L1vkvVMU1Y5n9zFig2CF_qqBLlcdvoYCaUeaNUu706L0fKJhJkA8vV5JUvFq0E" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwibmV4dFBhZ2VUb2tlbiI6IkNoQnZZbW92ZDJsMGFDOXpiR0Z6YUdWeiIsIml0ZW1zIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmovd2l0aC9zbGFzaGVzLzE1NTY4MzU4NDU1MTEwMTgiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmolMkZ3aXRoJTJGc2xhc2hlcyIsIm5hbWUiOiJvYmovd2l0aC9zbGFzaGVzIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDU1MTEwMTgiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW4iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDUuNTEwWiIsInVwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA1LjUxMFoiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowNS41MTBaIiwic2l6ZSI6IjE2IiwibWQ1SGFzaCI6InVlei9oSjZ3QXJlRFFuY2NEVWR4Zmc9PSIsIm1lZGlhTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmolMkZ3aXRoJTJGc2xhc2hlcz9nZW5lcmF0aW9uPTE1NTY4MzU4NDU1MTEwMTgmYWx0PW1lZGlhIiwiY2FjaGVDb250cm9sIjoicHVibGljLCBtYXgtYWdlPTYwIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqL3dpdGgvc2xhc2hlcy8xNTU2ODM1ODQ1NTExMDE4L3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iaiUyRndpdGglMkZzbGFzaGVzL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmovd2l0aC9zbGFzaGVzIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDU1MTEwMTgiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ09xdXJyengvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iai93aXRoL3NsYXNoZXMvMTU1NjgzNTg0NTUxMTAxOC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqJTJGd2l0aCUyRnNsYXNoZXMvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmovd2l0aC9zbGFzaGVzIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDU1MTEwMTgiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDT3F1cnJ6eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqL3dpdGgvc2xhc2hlcy8xNTU2ODM1ODQ1NTExMDE4L3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmolMkZ3aXRoJTJGc2xhc2hlcy9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iai93aXRoL3NsYXNoZXMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTUxMTAxOCIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDT3F1cnJ6eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqL3dpdGgvc2xhc2hlcy8xNTU2ODM1ODQ1NTExMDE4L3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmolMkZ3aXRoJTJGc2xhc2hlcy9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iai93aXRoL3NsYXNoZXMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTUxMTAxOCIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNPcXVycnp4L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoib2VvK0ZBPT0iLCJldGFnIjoiQ09xdXJyengvZUVDRUFFPSJ9XX0=" } }, { "ID": "dc8959751769ee9c", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026delimiter=\u0026maxResults=1\u0026pageToken=ChBvYmovd2l0aC9zbGFzaGVz\u0026prefix=obj\u0026prettyPrint=false\u0026projection=full\u0026versions=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "3214" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:08 GMT" ], "Expires": [ "Thu, 02 May 2019 22:24:08 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqLeV9n2aiAq15pl3CqEWOt3_OYHsxbG0lHFIKr7Emh5btUEXLXl4nZWPi27LinKW7i0LYvp-HZK5b9E742MR_PNFe87treTpz_QgUmchGPKLcdZVM" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwibmV4dFBhZ2VUb2tlbiI6IkNnUnZZbW94IiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEvMTU1NjgzNTg0NDY0NzIyNSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajEiLCJuYW1lIjoib2JqMSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ0NjQ3MjI1IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA0LjY0NloiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowNC42NDZaIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDQuNjQ2WiIsInNpemUiOiIxNiIsIm1kNUhhc2giOiJTbmEvVVd2N21jWkkyM29FNXRVYWJRPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMT9nZW5lcmF0aW9uPTE1NTY4MzU4NDQ2NDcyMjUmYWx0PW1lZGlhIiwiY2FjaGVDb250cm9sIjoicHVibGljLCBtYXgtYWdlPTYwIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMS8xNTU2ODM1ODQ0NjQ3MjI1L3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajEvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDTG5TK2J2eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMS8xNTU2ODM1ODQ0NjQ3MjI1L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoxL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqMSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ0NjQ3MjI1IiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0xuUytidngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEvMTU1NjgzNTg0NDY0NzIyNS9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMS9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDTG5TK2J2eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMS8xNTU2ODM1ODQ0NjQ3MjI1L3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoxL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqMSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ0NjQ3MjI1IiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ0xuUytidngvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJDVDZkVEE9PSIsImV0YWciOiJDTG5TK2J2eC9lRUNFQUU9In1dfQ==" } }, { "ID": "23f7f167269db6b2", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026delimiter=\u0026maxResults=1\u0026pageToken=CgRvYmox\u0026prefix=obj\u0026prettyPrint=false\u0026projection=full\u0026versions=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "3187" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:08 GMT" ], "Expires": [ "Thu, 02 May 2019 22:24:08 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uo4hY4jSbETgB5jf-AU8_b1sRvfTSrlt_Pt6UXiuTte4GtueVBgDwuMEliwE2-nOSiRE6juXOCbR1LQlRrpek1TLeRRf1cCVbz90YcCIGhWV_zFz0o" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajIvMTU1NjgzNTg0NTA0OTI0NSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajIiLCJuYW1lIjoib2JqMiIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1MDQ5MjQ1IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA1LjA0OFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowNS4wNDhaIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDUuMDQ4WiIsInNpemUiOiIxNiIsIm1kNUhhc2giOiJDQzF3bHdyTU9JcTBkdk1rTXlsVWhnPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMj9nZW5lcmF0aW9uPTE1NTY4MzU4NDUwNDkyNDUmYWx0PW1lZGlhIiwiY2FjaGVDb250cm9sIjoicHVibGljLCBtYXgtYWdlPTYwIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMi8xNTU2ODM1ODQ1MDQ5MjQ1L3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajIvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajIiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTA0OTI0NSIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDSjJYa3J6eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMi8xNTU2ODM1ODQ1MDQ5MjQ1L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoyL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqMiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1MDQ5MjQ1IiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0oyWGtyengvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajIvMTU1NjgzNTg0NTA0OTI0NS9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMi9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajIiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTA0OTI0NSIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDSjJYa3J6eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMi8xNTU2ODM1ODQ1MDQ5MjQ1L3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoyL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqMiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1MDQ5MjQ1IiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ0oyWGtyengvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJqVjVBVlE9PSIsImV0YWciOiJDSjJYa3J6eC9lRUNFQUU9In1dfQ==" } }, { "ID": "518c5855f7f2035b", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026delimiter=\u0026maxResults=2\u0026pageToken=\u0026prefix=obj\u0026prettyPrint=false\u0026projection=full\u0026versions=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "6581" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:09 GMT" ], "Expires": [ "Thu, 02 May 2019 22:24:09 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqGaiKkmr1oBduBvG8APGBVoM_Ve7zHw4TBuyV3QYcFr9SYzEnATEwE5P6BH-yBsVXSmaRLej1a55x18Bra_ZAC7nYh2UKvWM66JGE3U1muaDBabyw" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwibmV4dFBhZ2VUb2tlbiI6IkNnUnZZbW94IiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iai93aXRoL3NsYXNoZXMvMTU1NjgzNTg0NTUxMTAxOCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iaiUyRndpdGglMkZzbGFzaGVzIiwibmFtZSI6Im9iai93aXRoL3NsYXNoZXMiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTUxMTAxOCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowNS41MTBaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDUuNTEwWiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA1LjUxMFoiLCJzaXplIjoiMTYiLCJtZDVIYXNoIjoidWV6L2hKNndBcmVEUW5jY0RVZHhmZz09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iaiUyRndpdGglMkZzbGFzaGVzP2dlbmVyYXRpb249MTU1NjgzNTg0NTUxMTAxOCZhbHQ9bWVkaWEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmovd2l0aC9zbGFzaGVzLzE1NTY4MzU4NDU1MTEwMTgvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqJTJGd2l0aCUyRnNsYXNoZXMvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iai93aXRoL3NsYXNoZXMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTUxMTAxOCIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDT3F1cnJ6eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqL3dpdGgvc2xhc2hlcy8xNTU2ODM1ODQ1NTExMDE4L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmolMkZ3aXRoJTJGc2xhc2hlcy9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iai93aXRoL3NsYXNoZXMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTUxMTAxOCIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNPcXVycnp4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmovd2l0aC9zbGFzaGVzLzE1NTY4MzU4NDU1MTEwMTgvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iaiUyRndpdGglMkZzbGFzaGVzL2FjbC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqL3dpdGgvc2xhc2hlcyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1NTExMDE4IiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNPcXVycnp4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmovd2l0aC9zbGFzaGVzLzE1NTY4MzU4NDU1MTEwMTgvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iaiUyRndpdGglMkZzbGFzaGVzL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqL3dpdGgvc2xhc2hlcyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1NTExMDE4IiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ09xdXJyengvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJvZW8rRkE9PSIsImV0YWciOiJDT3F1cnJ6eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoxLzE1NTY4MzU4NDQ2NDcyMjUiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoxIiwibmFtZSI6Im9iajEiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowNC42NDZaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDQuNjQ2WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA0LjY0NloiLCJzaXplIjoiMTYiLCJtZDVIYXNoIjoiU25hL1VXdjdtY1pJMjNvRTV0VWFiUT09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajE/Z2VuZXJhdGlvbj0xNTU2ODM1ODQ0NjQ3MjI1JmFsdD1tZWRpYSIsImNhY2hlQ29udHJvbCI6InB1YmxpYywgbWF4LWFnZT02MCIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEvMTU1NjgzNTg0NDY0NzIyNS9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoxL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDQ2NDcyMjUiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0xuUytidngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEvMTU1NjgzNTg0NDY0NzIyNS9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMS9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNMblMrYnZ4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoxLzE1NTY4MzU4NDQ2NDcyMjUvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajEvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDQ2NDcyMjUiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0xuUytidngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEvMTU1NjgzNTg0NDY0NzIyNS91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMS9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNMblMrYnZ4L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoiQ1Q2ZFRBPT0iLCJldGFnIjoiQ0xuUytidngvZUVDRUFFPSJ9XX0=" } }, { "ID": "5887398d8cd8c906", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026delimiter=\u0026maxResults=2\u0026pageToken=CgRvYmox\u0026prefix=obj\u0026prettyPrint=false\u0026projection=full\u0026versions=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "3187" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:09 GMT" ], "Expires": [ "Thu, 02 May 2019 22:24:09 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqGAvr7ojM3PcmnrTMTX-TXgYKzfo-3gzwYU_l9OaCfpth_ad2lWUJf6w6B8pjEGsAFZJvNueCHYGSJdx6YJ7NAe71oah1xi6lGQvQkWEwAl0fXd7Y" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajIvMTU1NjgzNTg0NTA0OTI0NSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajIiLCJuYW1lIjoib2JqMiIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1MDQ5MjQ1IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA1LjA0OFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowNS4wNDhaIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDUuMDQ4WiIsInNpemUiOiIxNiIsIm1kNUhhc2giOiJDQzF3bHdyTU9JcTBkdk1rTXlsVWhnPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMj9nZW5lcmF0aW9uPTE1NTY4MzU4NDUwNDkyNDUmYWx0PW1lZGlhIiwiY2FjaGVDb250cm9sIjoicHVibGljLCBtYXgtYWdlPTYwIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMi8xNTU2ODM1ODQ1MDQ5MjQ1L3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajIvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajIiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTA0OTI0NSIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDSjJYa3J6eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMi8xNTU2ODM1ODQ1MDQ5MjQ1L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoyL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqMiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1MDQ5MjQ1IiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0oyWGtyengvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajIvMTU1NjgzNTg0NTA0OTI0NS9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMi9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajIiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTA0OTI0NSIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDSjJYa3J6eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMi8xNTU2ODM1ODQ1MDQ5MjQ1L3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoyL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqMiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1MDQ5MjQ1IiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ0oyWGtyengvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJqVjVBVlE9PSIsImV0YWciOiJDSjJYa3J6eC9lRUNFQUU9In1dfQ==" } }, { "ID": "81d53e304c7ed90d", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026delimiter=\u0026maxResults=2\u0026pageToken=\u0026prefix=obj\u0026prettyPrint=false\u0026projection=full\u0026versions=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "6581" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:09 GMT" ], "Expires": [ "Thu, 02 May 2019 22:24:09 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Ur9XEMeCefUS1K7QkIxrxZboQ1zQ5SkrEUZMzrQdNBNAuDQnpDczXzJvF-rZmxFVYSdMySScTTu-FICOdI91b-fQVRomrqAxJwgn60FoObIVVpgkog" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwibmV4dFBhZ2VUb2tlbiI6IkNnUnZZbW94IiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iai93aXRoL3NsYXNoZXMvMTU1NjgzNTg0NTUxMTAxOCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iaiUyRndpdGglMkZzbGFzaGVzIiwibmFtZSI6Im9iai93aXRoL3NsYXNoZXMiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTUxMTAxOCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowNS41MTBaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDUuNTEwWiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA1LjUxMFoiLCJzaXplIjoiMTYiLCJtZDVIYXNoIjoidWV6L2hKNndBcmVEUW5jY0RVZHhmZz09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iaiUyRndpdGglMkZzbGFzaGVzP2dlbmVyYXRpb249MTU1NjgzNTg0NTUxMTAxOCZhbHQ9bWVkaWEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmovd2l0aC9zbGFzaGVzLzE1NTY4MzU4NDU1MTEwMTgvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqJTJGd2l0aCUyRnNsYXNoZXMvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iai93aXRoL3NsYXNoZXMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTUxMTAxOCIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDT3F1cnJ6eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqL3dpdGgvc2xhc2hlcy8xNTU2ODM1ODQ1NTExMDE4L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmolMkZ3aXRoJTJGc2xhc2hlcy9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iai93aXRoL3NsYXNoZXMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTUxMTAxOCIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNPcXVycnp4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmovd2l0aC9zbGFzaGVzLzE1NTY4MzU4NDU1MTEwMTgvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iaiUyRndpdGglMkZzbGFzaGVzL2FjbC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqL3dpdGgvc2xhc2hlcyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1NTExMDE4IiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNPcXVycnp4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmovd2l0aC9zbGFzaGVzLzE1NTY4MzU4NDU1MTEwMTgvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iaiUyRndpdGglMkZzbGFzaGVzL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqL3dpdGgvc2xhc2hlcyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1NTExMDE4IiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ09xdXJyengvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJvZW8rRkE9PSIsImV0YWciOiJDT3F1cnJ6eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoxLzE1NTY4MzU4NDQ2NDcyMjUiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoxIiwibmFtZSI6Im9iajEiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowNC42NDZaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDQuNjQ2WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA0LjY0NloiLCJzaXplIjoiMTYiLCJtZDVIYXNoIjoiU25hL1VXdjdtY1pJMjNvRTV0VWFiUT09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajE/Z2VuZXJhdGlvbj0xNTU2ODM1ODQ0NjQ3MjI1JmFsdD1tZWRpYSIsImNhY2hlQ29udHJvbCI6InB1YmxpYywgbWF4LWFnZT02MCIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEvMTU1NjgzNTg0NDY0NzIyNS9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoxL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDQ2NDcyMjUiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0xuUytidngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEvMTU1NjgzNTg0NDY0NzIyNS9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMS9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNMblMrYnZ4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoxLzE1NTY4MzU4NDQ2NDcyMjUvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajEvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDQ2NDcyMjUiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0xuUytidngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEvMTU1NjgzNTg0NDY0NzIyNS91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMS9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNMblMrYnZ4L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoiQ1Q2ZFRBPT0iLCJldGFnIjoiQ0xuUytidngvZUVDRUFFPSJ9XX0=" } }, { "ID": "0be1bdae5ba86bfd", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026delimiter=\u0026maxResults=2\u0026pageToken=CgRvYmox\u0026prefix=obj\u0026prettyPrint=false\u0026projection=full\u0026versions=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "3187" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:10 GMT" ], "Expires": [ "Thu, 02 May 2019 22:24:10 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UocXesX_BUCirPixQFUhYfAIoR0Os309HMGHarzTGrqH1PkmHuGaaiNSH_pJq8nnWUXEnjk1cvuPGJWCF21t7EJQtCIGBWQoPBNV6OpvALZGdpPXuI" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajIvMTU1NjgzNTg0NTA0OTI0NSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajIiLCJuYW1lIjoib2JqMiIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1MDQ5MjQ1IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA1LjA0OFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowNS4wNDhaIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDUuMDQ4WiIsInNpemUiOiIxNiIsIm1kNUhhc2giOiJDQzF3bHdyTU9JcTBkdk1rTXlsVWhnPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMj9nZW5lcmF0aW9uPTE1NTY4MzU4NDUwNDkyNDUmYWx0PW1lZGlhIiwiY2FjaGVDb250cm9sIjoicHVibGljLCBtYXgtYWdlPTYwIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMi8xNTU2ODM1ODQ1MDQ5MjQ1L3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajIvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajIiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTA0OTI0NSIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDSjJYa3J6eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMi8xNTU2ODM1ODQ1MDQ5MjQ1L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoyL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqMiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1MDQ5MjQ1IiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0oyWGtyengvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajIvMTU1NjgzNTg0NTA0OTI0NS9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMi9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajIiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTA0OTI0NSIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDSjJYa3J6eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMi8xNTU2ODM1ODQ1MDQ5MjQ1L3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoyL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqMiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1MDQ5MjQ1IiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ0oyWGtyengvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJqVjVBVlE9PSIsImV0YWciOiJDSjJYa3J6eC9lRUNFQUU9In1dfQ==" } }, { "ID": "592a3fdf8b5a83e5", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026delimiter=\u0026maxResults=3\u0026pageToken=\u0026prefix=obj\u0026prettyPrint=false\u0026projection=full\u0026versions=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "9705" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:10 GMT" ], "Expires": [ "Thu, 02 May 2019 22:24:10 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoS2FM55Dkg1PRaNQBzsu5KBns-svmRrQ5byrUGRHgnsBQQDdE3ZznljVTrNq3wDAClddQ4zbCMQSLdqxPPNlom-n1tMg1hO8s6kS8_CTWy2SOM6As" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iai93aXRoL3NsYXNoZXMvMTU1NjgzNTg0NTUxMTAxOCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iaiUyRndpdGglMkZzbGFzaGVzIiwibmFtZSI6Im9iai93aXRoL3NsYXNoZXMiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTUxMTAxOCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowNS41MTBaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDUuNTEwWiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA1LjUxMFoiLCJzaXplIjoiMTYiLCJtZDVIYXNoIjoidWV6L2hKNndBcmVEUW5jY0RVZHhmZz09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iaiUyRndpdGglMkZzbGFzaGVzP2dlbmVyYXRpb249MTU1NjgzNTg0NTUxMTAxOCZhbHQ9bWVkaWEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmovd2l0aC9zbGFzaGVzLzE1NTY4MzU4NDU1MTEwMTgvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqJTJGd2l0aCUyRnNsYXNoZXMvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iai93aXRoL3NsYXNoZXMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTUxMTAxOCIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDT3F1cnJ6eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqL3dpdGgvc2xhc2hlcy8xNTU2ODM1ODQ1NTExMDE4L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmolMkZ3aXRoJTJGc2xhc2hlcy9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iai93aXRoL3NsYXNoZXMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTUxMTAxOCIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNPcXVycnp4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmovd2l0aC9zbGFzaGVzLzE1NTY4MzU4NDU1MTEwMTgvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iaiUyRndpdGglMkZzbGFzaGVzL2FjbC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqL3dpdGgvc2xhc2hlcyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1NTExMDE4IiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNPcXVycnp4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmovd2l0aC9zbGFzaGVzLzE1NTY4MzU4NDU1MTEwMTgvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iaiUyRndpdGglMkZzbGFzaGVzL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqL3dpdGgvc2xhc2hlcyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1NTExMDE4IiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ09xdXJyengvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJvZW8rRkE9PSIsImV0YWciOiJDT3F1cnJ6eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoxLzE1NTY4MzU4NDQ2NDcyMjUiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoxIiwibmFtZSI6Im9iajEiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowNC42NDZaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDQuNjQ2WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA0LjY0NloiLCJzaXplIjoiMTYiLCJtZDVIYXNoIjoiU25hL1VXdjdtY1pJMjNvRTV0VWFiUT09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajE/Z2VuZXJhdGlvbj0xNTU2ODM1ODQ0NjQ3MjI1JmFsdD1tZWRpYSIsImNhY2hlQ29udHJvbCI6InB1YmxpYywgbWF4LWFnZT02MCIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEvMTU1NjgzNTg0NDY0NzIyNS9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoxL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDQ2NDcyMjUiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0xuUytidngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEvMTU1NjgzNTg0NDY0NzIyNS9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMS9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNMblMrYnZ4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoxLzE1NTY4MzU4NDQ2NDcyMjUvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajEvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDQ2NDcyMjUiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0xuUytidngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEvMTU1NjgzNTg0NDY0NzIyNS91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMS9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNMblMrYnZ4L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoiQ1Q2ZFRBPT0iLCJldGFnIjoiQ0xuUytidngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMi8xNTU2ODM1ODQ1MDQ5MjQ1Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMiIsIm5hbWUiOiJvYmoyIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDUwNDkyNDUiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW4iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDUuMDQ4WiIsInVwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA1LjA0OFoiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowNS4wNDhaIiwic2l6ZSI6IjE2IiwibWQ1SGFzaCI6IkNDMXdsd3JNT0lxMGR2TWtNeWxVaGc9PSIsIm1lZGlhTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoyP2dlbmVyYXRpb249MTU1NjgzNTg0NTA0OTI0NSZhbHQ9bWVkaWEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoyLzE1NTY4MzU4NDUwNDkyNDUvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMi9hY2wvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqMiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1MDQ5MjQ1IiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNKMlhrcnp4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoyLzE1NTY4MzU4NDUwNDkyNDUvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajIvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoyIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDUwNDkyNDUiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDSjJYa3J6eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMi8xNTU2ODM1ODQ1MDQ5MjQ1L3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoyL2FjbC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqMiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1MDQ5MjQ1IiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNKMlhrcnp4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoyLzE1NTY4MzU4NDUwNDkyNDUvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajIvYWNsL3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoyIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDUwNDkyNDUiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDSjJYa3J6eC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6ImpWNUFWUT09IiwiZXRhZyI6IkNKMlhrcnp4L2VFQ0VBRT0ifV19" } }, { "ID": "b01846866b585241", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026delimiter=\u0026maxResults=3\u0026pageToken=\u0026prefix=obj\u0026prettyPrint=false\u0026projection=full\u0026versions=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "9705" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:10 GMT" ], "Expires": [ "Thu, 02 May 2019 22:24:10 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uo22tWMx8uW6afXbfFrFT8UZzPbsqPItYMdRAPHNEuksgeqWI2US_xblUG6C8WgcHvfEeR_19eVmBTmW6QE7rmosaIm_raZxW9FuCHHiSi8TJnZ1CI" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iai93aXRoL3NsYXNoZXMvMTU1NjgzNTg0NTUxMTAxOCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iaiUyRndpdGglMkZzbGFzaGVzIiwibmFtZSI6Im9iai93aXRoL3NsYXNoZXMiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTUxMTAxOCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowNS41MTBaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDUuNTEwWiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA1LjUxMFoiLCJzaXplIjoiMTYiLCJtZDVIYXNoIjoidWV6L2hKNndBcmVEUW5jY0RVZHhmZz09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iaiUyRndpdGglMkZzbGFzaGVzP2dlbmVyYXRpb249MTU1NjgzNTg0NTUxMTAxOCZhbHQ9bWVkaWEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmovd2l0aC9zbGFzaGVzLzE1NTY4MzU4NDU1MTEwMTgvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqJTJGd2l0aCUyRnNsYXNoZXMvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iai93aXRoL3NsYXNoZXMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTUxMTAxOCIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDT3F1cnJ6eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqL3dpdGgvc2xhc2hlcy8xNTU2ODM1ODQ1NTExMDE4L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmolMkZ3aXRoJTJGc2xhc2hlcy9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iai93aXRoL3NsYXNoZXMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTUxMTAxOCIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNPcXVycnp4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmovd2l0aC9zbGFzaGVzLzE1NTY4MzU4NDU1MTEwMTgvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iaiUyRndpdGglMkZzbGFzaGVzL2FjbC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqL3dpdGgvc2xhc2hlcyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1NTExMDE4IiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNPcXVycnp4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmovd2l0aC9zbGFzaGVzLzE1NTY4MzU4NDU1MTEwMTgvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iaiUyRndpdGglMkZzbGFzaGVzL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqL3dpdGgvc2xhc2hlcyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1NTExMDE4IiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ09xdXJyengvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJvZW8rRkE9PSIsImV0YWciOiJDT3F1cnJ6eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoxLzE1NTY4MzU4NDQ2NDcyMjUiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoxIiwibmFtZSI6Im9iajEiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowNC42NDZaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDQuNjQ2WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA0LjY0NloiLCJzaXplIjoiMTYiLCJtZDVIYXNoIjoiU25hL1VXdjdtY1pJMjNvRTV0VWFiUT09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajE/Z2VuZXJhdGlvbj0xNTU2ODM1ODQ0NjQ3MjI1JmFsdD1tZWRpYSIsImNhY2hlQ29udHJvbCI6InB1YmxpYywgbWF4LWFnZT02MCIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEvMTU1NjgzNTg0NDY0NzIyNS9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoxL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDQ2NDcyMjUiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0xuUytidngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEvMTU1NjgzNTg0NDY0NzIyNS9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMS9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNMblMrYnZ4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoxLzE1NTY4MzU4NDQ2NDcyMjUvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajEvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDQ2NDcyMjUiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0xuUytidngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEvMTU1NjgzNTg0NDY0NzIyNS91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMS9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNMblMrYnZ4L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoiQ1Q2ZFRBPT0iLCJldGFnIjoiQ0xuUytidngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMi8xNTU2ODM1ODQ1MDQ5MjQ1Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMiIsIm5hbWUiOiJvYmoyIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDUwNDkyNDUiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW4iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDUuMDQ4WiIsInVwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA1LjA0OFoiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowNS4wNDhaIiwic2l6ZSI6IjE2IiwibWQ1SGFzaCI6IkNDMXdsd3JNT0lxMGR2TWtNeWxVaGc9PSIsIm1lZGlhTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoyP2dlbmVyYXRpb249MTU1NjgzNTg0NTA0OTI0NSZhbHQ9bWVkaWEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoyLzE1NTY4MzU4NDUwNDkyNDUvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMi9hY2wvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqMiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1MDQ5MjQ1IiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNKMlhrcnp4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoyLzE1NTY4MzU4NDUwNDkyNDUvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajIvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoyIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDUwNDkyNDUiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDSjJYa3J6eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMi8xNTU2ODM1ODQ1MDQ5MjQ1L3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoyL2FjbC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqMiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1MDQ5MjQ1IiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNKMlhrcnp4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoyLzE1NTY4MzU4NDUwNDkyNDUvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajIvYWNsL3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoyIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDUwNDkyNDUiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDSjJYa3J6eC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6ImpWNUFWUT09IiwiZXRhZyI6IkNKMlhrcnp4L2VFQ0VBRT0ifV19" } }, { "ID": "2eeefee032c6e805", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026delimiter=\u0026maxResults=13\u0026pageToken=\u0026prefix=obj\u0026prettyPrint=false\u0026projection=full\u0026versions=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "9705" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:11 GMT" ], "Expires": [ "Thu, 02 May 2019 22:24:11 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uq55nB00t16AHTo1gSxBFUNplz5SJcGYBOeCPsK-MD5OLO_kHKT3YNZq69AAHpozaWVrTU_jDQqiqMFSoPhhmlF2dR1mcq6Ihk_y8uuFY6FM4O_hmI" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iai93aXRoL3NsYXNoZXMvMTU1NjgzNTg0NTUxMTAxOCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iaiUyRndpdGglMkZzbGFzaGVzIiwibmFtZSI6Im9iai93aXRoL3NsYXNoZXMiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTUxMTAxOCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowNS41MTBaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDUuNTEwWiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA1LjUxMFoiLCJzaXplIjoiMTYiLCJtZDVIYXNoIjoidWV6L2hKNndBcmVEUW5jY0RVZHhmZz09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iaiUyRndpdGglMkZzbGFzaGVzP2dlbmVyYXRpb249MTU1NjgzNTg0NTUxMTAxOCZhbHQ9bWVkaWEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmovd2l0aC9zbGFzaGVzLzE1NTY4MzU4NDU1MTEwMTgvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqJTJGd2l0aCUyRnNsYXNoZXMvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iai93aXRoL3NsYXNoZXMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTUxMTAxOCIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDT3F1cnJ6eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqL3dpdGgvc2xhc2hlcy8xNTU2ODM1ODQ1NTExMDE4L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmolMkZ3aXRoJTJGc2xhc2hlcy9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iai93aXRoL3NsYXNoZXMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTUxMTAxOCIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNPcXVycnp4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmovd2l0aC9zbGFzaGVzLzE1NTY4MzU4NDU1MTEwMTgvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iaiUyRndpdGglMkZzbGFzaGVzL2FjbC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqL3dpdGgvc2xhc2hlcyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1NTExMDE4IiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNPcXVycnp4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmovd2l0aC9zbGFzaGVzLzE1NTY4MzU4NDU1MTEwMTgvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iaiUyRndpdGglMkZzbGFzaGVzL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqL3dpdGgvc2xhc2hlcyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1NTExMDE4IiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ09xdXJyengvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJvZW8rRkE9PSIsImV0YWciOiJDT3F1cnJ6eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoxLzE1NTY4MzU4NDQ2NDcyMjUiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoxIiwibmFtZSI6Im9iajEiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowNC42NDZaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDQuNjQ2WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA0LjY0NloiLCJzaXplIjoiMTYiLCJtZDVIYXNoIjoiU25hL1VXdjdtY1pJMjNvRTV0VWFiUT09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajE/Z2VuZXJhdGlvbj0xNTU2ODM1ODQ0NjQ3MjI1JmFsdD1tZWRpYSIsImNhY2hlQ29udHJvbCI6InB1YmxpYywgbWF4LWFnZT02MCIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEvMTU1NjgzNTg0NDY0NzIyNS9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoxL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDQ2NDcyMjUiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0xuUytidngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEvMTU1NjgzNTg0NDY0NzIyNS9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMS9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNMblMrYnZ4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoxLzE1NTY4MzU4NDQ2NDcyMjUvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajEvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDQ2NDcyMjUiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0xuUytidngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEvMTU1NjgzNTg0NDY0NzIyNS91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMS9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNMblMrYnZ4L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoiQ1Q2ZFRBPT0iLCJldGFnIjoiQ0xuUytidngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMi8xNTU2ODM1ODQ1MDQ5MjQ1Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMiIsIm5hbWUiOiJvYmoyIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDUwNDkyNDUiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW4iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDUuMDQ4WiIsInVwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA1LjA0OFoiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowNS4wNDhaIiwic2l6ZSI6IjE2IiwibWQ1SGFzaCI6IkNDMXdsd3JNT0lxMGR2TWtNeWxVaGc9PSIsIm1lZGlhTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoyP2dlbmVyYXRpb249MTU1NjgzNTg0NTA0OTI0NSZhbHQ9bWVkaWEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoyLzE1NTY4MzU4NDUwNDkyNDUvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMi9hY2wvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqMiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1MDQ5MjQ1IiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNKMlhrcnp4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoyLzE1NTY4MzU4NDUwNDkyNDUvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajIvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoyIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDUwNDkyNDUiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDSjJYa3J6eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMi8xNTU2ODM1ODQ1MDQ5MjQ1L3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoyL2FjbC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqMiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1MDQ5MjQ1IiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNKMlhrcnp4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoyLzE1NTY4MzU4NDUwNDkyNDUvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajIvYWNsL3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoyIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDUwNDkyNDUiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDSjJYa3J6eC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6ImpWNUFWUT09IiwiZXRhZyI6IkNKMlhrcnp4L2VFQ0VBRT0ifV19" } }, { "ID": "11bfe17bc978cdfd", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026delimiter=\u0026maxResults=13\u0026pageToken=\u0026prefix=obj\u0026prettyPrint=false\u0026projection=full\u0026versions=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "9705" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:11 GMT" ], "Expires": [ "Thu, 02 May 2019 22:24:11 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UotgN85lDspseXEgwnXhmfSmio9oOxSzhqtyabApVH0KQz_aVg3DbQ7m0Z0L9SzPzzmNEUfU6xhAT5xQAXf-wvY1NHDFxdf9IJ6YoVNhN0aHN-75hY" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iai93aXRoL3NsYXNoZXMvMTU1NjgzNTg0NTUxMTAxOCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iaiUyRndpdGglMkZzbGFzaGVzIiwibmFtZSI6Im9iai93aXRoL3NsYXNoZXMiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTUxMTAxOCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowNS41MTBaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDUuNTEwWiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA1LjUxMFoiLCJzaXplIjoiMTYiLCJtZDVIYXNoIjoidWV6L2hKNndBcmVEUW5jY0RVZHhmZz09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iaiUyRndpdGglMkZzbGFzaGVzP2dlbmVyYXRpb249MTU1NjgzNTg0NTUxMTAxOCZhbHQ9bWVkaWEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmovd2l0aC9zbGFzaGVzLzE1NTY4MzU4NDU1MTEwMTgvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqJTJGd2l0aCUyRnNsYXNoZXMvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iai93aXRoL3NsYXNoZXMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTUxMTAxOCIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDT3F1cnJ6eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqL3dpdGgvc2xhc2hlcy8xNTU2ODM1ODQ1NTExMDE4L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmolMkZ3aXRoJTJGc2xhc2hlcy9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iai93aXRoL3NsYXNoZXMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTUxMTAxOCIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNPcXVycnp4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmovd2l0aC9zbGFzaGVzLzE1NTY4MzU4NDU1MTEwMTgvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iaiUyRndpdGglMkZzbGFzaGVzL2FjbC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqL3dpdGgvc2xhc2hlcyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1NTExMDE4IiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNPcXVycnp4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmovd2l0aC9zbGFzaGVzLzE1NTY4MzU4NDU1MTEwMTgvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iaiUyRndpdGglMkZzbGFzaGVzL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqL3dpdGgvc2xhc2hlcyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1NTExMDE4IiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ09xdXJyengvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJvZW8rRkE9PSIsImV0YWciOiJDT3F1cnJ6eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoxLzE1NTY4MzU4NDQ2NDcyMjUiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoxIiwibmFtZSI6Im9iajEiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowNC42NDZaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDQuNjQ2WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA0LjY0NloiLCJzaXplIjoiMTYiLCJtZDVIYXNoIjoiU25hL1VXdjdtY1pJMjNvRTV0VWFiUT09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajE/Z2VuZXJhdGlvbj0xNTU2ODM1ODQ0NjQ3MjI1JmFsdD1tZWRpYSIsImNhY2hlQ29udHJvbCI6InB1YmxpYywgbWF4LWFnZT02MCIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEvMTU1NjgzNTg0NDY0NzIyNS9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoxL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDQ2NDcyMjUiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0xuUytidngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEvMTU1NjgzNTg0NDY0NzIyNS9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMS9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNMblMrYnZ4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoxLzE1NTY4MzU4NDQ2NDcyMjUvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajEvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDQ2NDcyMjUiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0xuUytidngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEvMTU1NjgzNTg0NDY0NzIyNS91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMS9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNMblMrYnZ4L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoiQ1Q2ZFRBPT0iLCJldGFnIjoiQ0xuUytidngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMi8xNTU2ODM1ODQ1MDQ5MjQ1Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMiIsIm5hbWUiOiJvYmoyIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDUwNDkyNDUiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW4iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDUuMDQ4WiIsInVwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA1LjA0OFoiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowNS4wNDhaIiwic2l6ZSI6IjE2IiwibWQ1SGFzaCI6IkNDMXdsd3JNT0lxMGR2TWtNeWxVaGc9PSIsIm1lZGlhTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoyP2dlbmVyYXRpb249MTU1NjgzNTg0NTA0OTI0NSZhbHQ9bWVkaWEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoyLzE1NTY4MzU4NDUwNDkyNDUvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMi9hY2wvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqMiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1MDQ5MjQ1IiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNKMlhrcnp4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoyLzE1NTY4MzU4NDUwNDkyNDUvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajIvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoyIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDUwNDkyNDUiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDSjJYa3J6eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMi8xNTU2ODM1ODQ1MDQ5MjQ1L3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoyL2FjbC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqMiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1MDQ5MjQ1IiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNKMlhrcnp4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoyLzE1NTY4MzU4NDUwNDkyNDUvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajIvYWNsL3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoyIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDUwNDkyNDUiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDSjJYa3J6eC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6ImpWNUFWUT09IiwiZXRhZyI6IkNKMlhrcnp4L2VFQ0VBRT0ifV19" } }, { "ID": "c05bfa6f1a43381b", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/go-integration-test-20190502-80633403432013-0001/obj1", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "public, max-age=60" ], "Content-Length": [ "16" ], "Content-Type": [ "text/plain" ], "Date": [ "Thu, 02 May 2019 22:24:11 GMT" ], "Etag": [ "\"4a76bf516bfb99c648db7a04e6d51a6d\"" ], "Expires": [ "Thu, 02 May 2019 22:25:11 GMT" ], "Last-Modified": [ "Thu, 02 May 2019 22:24:04 GMT" ], "Server": [ "UploadServer" ], "X-Goog-Expiration": [ "Sat, 01 Jun 2019 22:24:04 GMT" ], "X-Goog-Generation": [ "1556835844647225" ], "X-Goog-Hash": [ "crc32c=CT6dTA==", "md5=Sna/UWv7mcZI23oE5tUabQ==" ], "X-Goog-Metageneration": [ "1" ], "X-Goog-Storage-Class": [ "STANDARD" ], "X-Goog-Stored-Content-Encoding": [ "identity" ], "X-Goog-Stored-Content-Length": [ "16" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrVVjXVa2SMY6cjYeIgdcZOivQwE2Crz6UPZs2VXVBFMwReZs7kKbETuTMwuEMHKKm_LIrk-o6jS07MimubSWVxGMzT1BtCacU1X2Go_RckmyJPZso" ] }, "Body": "TuDshcL7vdCAXh8L42NvEQ==" } }, { "ID": "f2932604385db16e", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/go-integration-test-20190502-80633403432013-0001/obj1", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "public, max-age=60" ], "Content-Length": [ "16" ], "Content-Type": [ "text/plain" ], "Date": [ "Thu, 02 May 2019 22:24:12 GMT" ], "Etag": [ "\"4a76bf516bfb99c648db7a04e6d51a6d\"" ], "Expires": [ "Thu, 02 May 2019 22:25:12 GMT" ], "Last-Modified": [ "Thu, 02 May 2019 22:24:04 GMT" ], "Server": [ "UploadServer" ], "X-Goog-Expiration": [ "Sat, 01 Jun 2019 22:24:04 GMT" ], "X-Goog-Generation": [ "1556835844647225" ], "X-Goog-Hash": [ "crc32c=CT6dTA==", "md5=Sna/UWv7mcZI23oE5tUabQ==" ], "X-Goog-Metageneration": [ "1" ], "X-Goog-Storage-Class": [ "STANDARD" ], "X-Goog-Stored-Content-Encoding": [ "identity" ], "X-Goog-Stored-Content-Length": [ "16" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrADckAOw2vMHdy0qy02f20x-8s_Ue81-NYwSpKeqp6Zx6eCPReLM6qXUyxFz0xHNGob5WJA8J4ctl6ZFzL2fEVwBMNY8xxzpkKOAwSu9n9e0OE63E" ] }, "Body": "TuDshcL7vdCAXh8L42NvEQ==" } }, { "ID": "8581afc6216ad2cb", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/go-integration-test-20190502-80633403432013-0001/obj2", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "public, max-age=60" ], "Content-Length": [ "16" ], "Content-Type": [ "text/plain" ], "Date": [ "Thu, 02 May 2019 22:24:12 GMT" ], "Etag": [ "\"082d70970acc388ab476f32433295486\"" ], "Expires": [ "Thu, 02 May 2019 22:25:12 GMT" ], "Last-Modified": [ "Thu, 02 May 2019 22:24:05 GMT" ], "Server": [ "UploadServer" ], "X-Goog-Expiration": [ "Sat, 01 Jun 2019 22:24:05 GMT" ], "X-Goog-Generation": [ "1556835845049245" ], "X-Goog-Hash": [ "crc32c=jV5AVQ==", "md5=CC1wlwrMOIq0dvMkMylUhg==" ], "X-Goog-Metageneration": [ "1" ], "X-Goog-Storage-Class": [ "STANDARD" ], "X-Goog-Stored-Content-Encoding": [ "identity" ], "X-Goog-Stored-Content-Length": [ "16" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrkoYpGTn57WC5t-sItsEdWimp47AtSuqw8autFOD3TirChrdQThg_Fh-kykfgvnTaOyiw1InKeYs0Z2MISmjUpu4uHUUGDKTX6W0zQEuUks7i2BqQ" ] }, "Body": "55GZ37DvGFQS3PnkEKv3Jg==" } }, { "ID": "ae129e597d5dd3e8", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/go-integration-test-20190502-80633403432013-0001/obj2", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "public, max-age=60" ], "Content-Length": [ "16" ], "Content-Type": [ "text/plain" ], "Date": [ "Thu, 02 May 2019 22:24:12 GMT" ], "Etag": [ "\"082d70970acc388ab476f32433295486\"" ], "Expires": [ "Thu, 02 May 2019 22:25:12 GMT" ], "Last-Modified": [ "Thu, 02 May 2019 22:24:05 GMT" ], "Server": [ "UploadServer" ], "X-Goog-Expiration": [ "Sat, 01 Jun 2019 22:24:05 GMT" ], "X-Goog-Generation": [ "1556835845049245" ], "X-Goog-Hash": [ "crc32c=jV5AVQ==", "md5=CC1wlwrMOIq0dvMkMylUhg==" ], "X-Goog-Metageneration": [ "1" ], "X-Goog-Storage-Class": [ "STANDARD" ], "X-Goog-Stored-Content-Encoding": [ "identity" ], "X-Goog-Stored-Content-Length": [ "16" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoaoET13zBO6-kmfarxy5tCZhmqc2oO38xOd6m6OQ55e-MyyKYM35hNakm5xYdWaoUNsKwVCiklp4HtYE8afVObxcDERuTCgyTw-olewCN6VBwd-H0" ] }, "Body": "55GZ37DvGFQS3PnkEKv3Jg==" } }, { "ID": "11acf26dc7680b3e", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/go-integration-test-20190502-80633403432013-0001/obj/with/slashes", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "public, max-age=60" ], "Content-Length": [ "16" ], "Content-Type": [ "text/plain" ], "Date": [ "Thu, 02 May 2019 22:24:12 GMT" ], "Etag": [ "\"b9ecff849eb002b78342771c0d47717e\"" ], "Expires": [ "Thu, 02 May 2019 22:25:12 GMT" ], "Last-Modified": [ "Thu, 02 May 2019 22:24:05 GMT" ], "Server": [ "UploadServer" ], "X-Goog-Expiration": [ "Sat, 01 Jun 2019 22:24:05 GMT" ], "X-Goog-Generation": [ "1556835845511018" ], "X-Goog-Hash": [ "crc32c=oeo+FA==", "md5=uez/hJ6wAreDQnccDUdxfg==" ], "X-Goog-Metageneration": [ "1" ], "X-Goog-Storage-Class": [ "STANDARD" ], "X-Goog-Stored-Content-Encoding": [ "identity" ], "X-Goog-Stored-Content-Length": [ "16" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Up_XtsS2bu4fnGI-Z85gqz1MECYqweRqin42arAyEfpJpZwmadI1-Op9V7n-q3UaYyRtUWFR7an7zKxWhJ_CB6PXz-C55C1nPoI7EWVEV2oXcS-q8c" ] }, "Body": "kT7fkMXrRdrhn2P2+EeT5g==" } }, { "ID": "ff72204b0c538268", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/go-integration-test-20190502-80633403432013-0001/obj/with/slashes", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "public, max-age=60" ], "Content-Length": [ "16" ], "Content-Type": [ "text/plain" ], "Date": [ "Thu, 02 May 2019 22:24:12 GMT" ], "Etag": [ "\"b9ecff849eb002b78342771c0d47717e\"" ], "Expires": [ "Thu, 02 May 2019 22:25:12 GMT" ], "Last-Modified": [ "Thu, 02 May 2019 22:24:05 GMT" ], "Server": [ "UploadServer" ], "X-Goog-Expiration": [ "Sat, 01 Jun 2019 22:24:05 GMT" ], "X-Goog-Generation": [ "1556835845511018" ], "X-Goog-Hash": [ "crc32c=oeo+FA==", "md5=uez/hJ6wAreDQnccDUdxfg==" ], "X-Goog-Metageneration": [ "1" ], "X-Goog-Storage-Class": [ "STANDARD" ], "X-Goog-Stored-Content-Encoding": [ "identity" ], "X-Goog-Stored-Content-Length": [ "16" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqrjLdnTX47-_XGNBlBZ0rEgsIkYJMzixBaVmhjn8IsK66UpQAUO-njMM-WznI-DBNIbXVTcPQKZBNe2ZHZEskfuRjsFwMjtooyUH_PqTfZnARVv8M" ] }, "Body": "kT7fkMXrRdrhn2P2+EeT5g==" } }, { "ID": "7972502f866e015e", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/go-integration-test-20190502-80633403432013-0001/obj1", "Header": { "Range": [ "bytes=0-15" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "public, max-age=60" ], "Content-Length": [ "16" ], "Content-Type": [ "text/plain" ], "Date": [ "Thu, 02 May 2019 22:24:12 GMT" ], "Etag": [ "\"4a76bf516bfb99c648db7a04e6d51a6d\"" ], "Expires": [ "Thu, 02 May 2019 22:25:12 GMT" ], "Last-Modified": [ "Thu, 02 May 2019 22:24:04 GMT" ], "Server": [ "UploadServer" ], "X-Goog-Expiration": [ "Sat, 01 Jun 2019 22:24:04 GMT" ], "X-Goog-Generation": [ "1556835844647225" ], "X-Goog-Hash": [ "crc32c=CT6dTA==", "md5=Sna/UWv7mcZI23oE5tUabQ==" ], "X-Goog-Metageneration": [ "1" ], "X-Goog-Storage-Class": [ "STANDARD" ], "X-Goog-Stored-Content-Encoding": [ "identity" ], "X-Goog-Stored-Content-Length": [ "16" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoNiJIZYFETpngMkDItRU7PtN7Fv4bDU7Kfvndst1JR2eGmW-tOMTfng8Abx6EWwPvvodLkSk-1TM4Gywxzh3c24gPDN4NsQMuh40Mfp0Jvg1syOls" ] }, "Body": "TuDshcL7vdCAXh8L42NvEQ==" } }, { "ID": "251a62254c59cbd1", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/go-integration-test-20190502-80633403432013-0001/obj1", "Header": { "Range": [ "bytes=0-7" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 206, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "public, max-age=60" ], "Content-Length": [ "8" ], "Content-Range": [ "bytes 0-7/16" ], "Content-Type": [ "text/plain" ], "Date": [ "Thu, 02 May 2019 22:24:12 GMT" ], "Etag": [ "\"4a76bf516bfb99c648db7a04e6d51a6d\"" ], "Expires": [ "Thu, 02 May 2019 22:25:12 GMT" ], "Last-Modified": [ "Thu, 02 May 2019 22:24:04 GMT" ], "Server": [ "UploadServer" ], "X-Goog-Expiration": [ "Sat, 01 Jun 2019 22:24:04 GMT" ], "X-Goog-Generation": [ "1556835844647225" ], "X-Goog-Hash": [ "crc32c=CT6dTA==", "md5=Sna/UWv7mcZI23oE5tUabQ==" ], "X-Goog-Metageneration": [ "1" ], "X-Goog-Storage-Class": [ "STANDARD" ], "X-Goog-Stored-Content-Encoding": [ "identity" ], "X-Goog-Stored-Content-Length": [ "16" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UobLFpkqodTM1bHuzS0GzRCKZypPQkf3nH1hbOexCjgjAcheZhV_zxJRyLhOYZoW8ABEaVMJLULNrzAm1VZs4JrTdtT46fYIcQe7OBeJp0aHI7Lr5s" ] }, "Body": "TuDshcL7vdA=" } }, { "ID": "2482617229166e50", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/go-integration-test-20190502-80633403432013-0001/obj1", "Header": { "Range": [ "bytes=8-23" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 206, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "public, max-age=60" ], "Content-Length": [ "8" ], "Content-Range": [ "bytes 8-15/16" ], "Content-Type": [ "text/plain" ], "Date": [ "Thu, 02 May 2019 22:24:12 GMT" ], "Etag": [ "\"4a76bf516bfb99c648db7a04e6d51a6d\"" ], "Expires": [ "Thu, 02 May 2019 22:25:12 GMT" ], "Last-Modified": [ "Thu, 02 May 2019 22:24:04 GMT" ], "Server": [ "UploadServer" ], "X-Goog-Expiration": [ "Sat, 01 Jun 2019 22:24:04 GMT" ], "X-Goog-Generation": [ "1556835844647225" ], "X-Goog-Hash": [ "crc32c=CT6dTA==", "md5=Sna/UWv7mcZI23oE5tUabQ==" ], "X-Goog-Metageneration": [ "1" ], "X-Goog-Storage-Class": [ "STANDARD" ], "X-Goog-Stored-Content-Encoding": [ "identity" ], "X-Goog-Stored-Content-Length": [ "16" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uon8ZtKgOTqFm36bWHd3hf535jPGQBEX9j2yPrr11_ycAJjfI4A-mFWMTsFRR3nwSo68784B9TUPUjQd0cib0QIrfBjfDcz91p6oPJG3VpV9afywIY" ] }, "Body": "gF4fC+NjbxE=" } }, { "ID": "74ff0c5848c7dba6", "Request": { "Method": "HEAD", "URL": "https://storage.googleapis.com/go-integration-test-20190502-80633403432013-0001/obj1", "Header": { "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "public, max-age=60" ], "Content-Length": [ "16" ], "Content-Type": [ "text/plain" ], "Date": [ "Thu, 02 May 2019 22:24:12 GMT" ], "Etag": [ "\"4a76bf516bfb99c648db7a04e6d51a6d\"" ], "Expires": [ "Thu, 02 May 2019 22:25:12 GMT" ], "Last-Modified": [ "Thu, 02 May 2019 22:24:04 GMT" ], "Server": [ "UploadServer" ], "X-Goog-Expiration": [ "Sat, 01 Jun 2019 22:24:04 GMT" ], "X-Goog-Generation": [ "1556835844647225" ], "X-Goog-Hash": [ "crc32c=CT6dTA==", "md5=Sna/UWv7mcZI23oE5tUabQ==" ], "X-Goog-Metageneration": [ "1" ], "X-Goog-Storage-Class": [ "STANDARD" ], "X-Goog-Stored-Content-Encoding": [ "identity" ], "X-Goog-Stored-Content-Length": [ "16" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqKc-08ZJEWVbyaV84xKlnrHkl2PBuBUQP6xtx6TzZW0fsjyZ-SHshiy-QMGCuP1UF4x1ettHyDvRbAleHIXy4y7wMwoUWST2NKs_0oRA0oVqOoKtQ" ] }, "Body": "" } }, { "ID": "90888164f5d2d40d", "Request": { "Method": "HEAD", "URL": "https://storage.googleapis.com/go-integration-test-20190502-80633403432013-0001/obj1", "Header": { "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "public, max-age=60" ], "Content-Length": [ "16" ], "Content-Type": [ "text/plain" ], "Date": [ "Thu, 02 May 2019 22:24:13 GMT" ], "Etag": [ "\"4a76bf516bfb99c648db7a04e6d51a6d\"" ], "Expires": [ "Thu, 02 May 2019 22:25:13 GMT" ], "Last-Modified": [ "Thu, 02 May 2019 22:24:04 GMT" ], "Server": [ "UploadServer" ], "X-Goog-Expiration": [ "Sat, 01 Jun 2019 22:24:04 GMT" ], "X-Goog-Generation": [ "1556835844647225" ], "X-Goog-Hash": [ "crc32c=CT6dTA==", "md5=Sna/UWv7mcZI23oE5tUabQ==" ], "X-Goog-Metageneration": [ "1" ], "X-Goog-Storage-Class": [ "STANDARD" ], "X-Goog-Stored-Content-Encoding": [ "identity" ], "X-Goog-Stored-Content-Length": [ "16" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoTSlg3r_LSoiqQyJVJDzL-0xNj6jlSNp9zLUmlPtu3xbhCLBDNAxY9CRbyEjw7UudDcsFOe43C3QlsVjoBJln1q179ZspYWXY-fHqjrztAfJkZUpU" ] }, "Body": "" } }, { "ID": "7961f3dc74fa0663", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/go-integration-test-20190502-80633403432013-0001/obj1", "Header": { "Range": [ "bytes=8-" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 206, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "public, max-age=60" ], "Content-Length": [ "8" ], "Content-Range": [ "bytes 8-15/16" ], "Content-Type": [ "text/plain" ], "Date": [ "Thu, 02 May 2019 22:24:13 GMT" ], "Etag": [ "\"4a76bf516bfb99c648db7a04e6d51a6d\"" ], "Expires": [ "Thu, 02 May 2019 22:25:13 GMT" ], "Last-Modified": [ "Thu, 02 May 2019 22:24:04 GMT" ], "Server": [ "UploadServer" ], "X-Goog-Expiration": [ "Sat, 01 Jun 2019 22:24:04 GMT" ], "X-Goog-Generation": [ "1556835844647225" ], "X-Goog-Hash": [ "crc32c=CT6dTA==", "md5=Sna/UWv7mcZI23oE5tUabQ==" ], "X-Goog-Metageneration": [ "1" ], "X-Goog-Storage-Class": [ "STANDARD" ], "X-Goog-Stored-Content-Encoding": [ "identity" ], "X-Goog-Stored-Content-Length": [ "16" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqJjC8HFLb8u_EaJVF0_TUOhNWhbooW0oANE8_LPjoIdLcoU42caZe7LjgbTIjCb0Ss3horP2noxirF3u3FGq0Yoh4rjuHBVhwZcemZHnKLgJUUbQQ" ] }, "Body": "gF4fC+NjbxE=" } }, { "ID": "af8c1fcfa456592a", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/go-integration-test-20190502-80633403432013-0001/obj1", "Header": { "Range": [ "bytes=0-31" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "public, max-age=60" ], "Content-Length": [ "16" ], "Content-Type": [ "text/plain" ], "Date": [ "Thu, 02 May 2019 22:24:13 GMT" ], "Etag": [ "\"4a76bf516bfb99c648db7a04e6d51a6d\"" ], "Expires": [ "Thu, 02 May 2019 22:25:13 GMT" ], "Last-Modified": [ "Thu, 02 May 2019 22:24:04 GMT" ], "Server": [ "UploadServer" ], "X-Goog-Expiration": [ "Sat, 01 Jun 2019 22:24:04 GMT" ], "X-Goog-Generation": [ "1556835844647225" ], "X-Goog-Hash": [ "crc32c=CT6dTA==", "md5=Sna/UWv7mcZI23oE5tUabQ==" ], "X-Goog-Metageneration": [ "1" ], "X-Goog-Storage-Class": [ "STANDARD" ], "X-Goog-Stored-Content-Encoding": [ "identity" ], "X-Goog-Stored-Content-Length": [ "16" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uqq6ro5-i6q8pIDup0yW35uFEynuLK95P8OSFhj7b70DK33tjv3fkOdkobsfwplOAGuNME2bLjQuyy8mhd2xBbNjyjvXt13Nc48PB4M2t_46RoM3Ak" ] }, "Body": "TuDshcL7vdCAXh8L42NvEQ==" } }, { "ID": "d312c241da5bd348", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/go-integration-test-20190502-80633403432013-0001/obj1", "Header": { "Range": [ "bytes=32-41" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 416, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "public, max-age=60" ], "Content-Length": [ "167" ], "Content-Type": [ "application/xml; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:13 GMT" ], "Etag": [ "\"4a76bf516bfb99c648db7a04e6d51a6d\"" ], "Expires": [ "Thu, 02 May 2019 22:25:13 GMT" ], "Last-Modified": [ "Thu, 02 May 2019 22:24:04 GMT" ], "Server": [ "UploadServer" ], "X-Goog-Expiration": [ "Sat, 01 Jun 2019 22:24:04 GMT" ], "X-Goog-Generation": [ "1556835844647225" ], "X-Goog-Hash": [ "crc32c=CT6dTA==", "md5=Sna/UWv7mcZI23oE5tUabQ==" ], "X-Goog-Metageneration": [ "1" ], "X-Goog-Storage-Class": [ "STANDARD" ], "X-Goog-Stored-Content-Encoding": [ "identity" ], "X-Goog-Stored-Content-Length": [ "16" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UpAvzLs-GgdTPEGM2kvABFTxehSb-DhZQ2Y31nQ9ad0RMmfIMtVGRBXvkXo7FwGAy78ZHMSGWRKG-DYMy6JU9PCM4Tpo8PDmm4-rHa_LVpH2dFN-JM" ] }, "Body": "PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48RXJyb3I+PENvZGU+SW52YWxpZFJhbmdlPC9Db2RlPjxNZXNzYWdlPlRoZSByZXF1ZXN0ZWQgcmFuZ2UgY2Fubm90IGJlIHNhdGlzZmllZC48L01lc3NhZ2U+PERldGFpbHM+Ynl0ZXM9MzItNDE8L0RldGFpbHM+PC9FcnJvcj4=" } }, { "ID": "2bbd010d0173c966", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/obj1?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3150" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:13 GMT" ], "Etag": [ "CLnS+bvx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpZDScoUU4zzBoXc21jt6C1vcW1SrU6ELiWodrCID-OoNKVMbecv_DSgHZATQGs4GS-BebkzqdalqTq5C77aKXQMxiks-9A5kyrc8N4aY9L5YndaI8" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoxLzE1NTY4MzU4NDQ2NDcyMjUiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoxIiwibmFtZSI6Im9iajEiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowNC42NDZaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDQuNjQ2WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA0LjY0NloiLCJzaXplIjoiMTYiLCJtZDVIYXNoIjoiU25hL1VXdjdtY1pJMjNvRTV0VWFiUT09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajE/Z2VuZXJhdGlvbj0xNTU2ODM1ODQ0NjQ3MjI1JmFsdD1tZWRpYSIsImNhY2hlQ29udHJvbCI6InB1YmxpYywgbWF4LWFnZT02MCIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEvMTU1NjgzNTg0NDY0NzIyNS9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoxL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDQ2NDcyMjUiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0xuUytidngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEvMTU1NjgzNTg0NDY0NzIyNS9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMS9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNMblMrYnZ4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoxLzE1NTY4MzU4NDQ2NDcyMjUvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajEvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDQ2NDcyMjUiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0xuUytidngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEvMTU1NjgzNTg0NDY0NzIyNS91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMS9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNMblMrYnZ4L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoiQ1Q2ZFRBPT0iLCJldGFnIjoiQ0xuUytidngvZUVDRUFFPSJ9" } }, { "ID": "e3522e1cc7aef940", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "2570" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:13 GMT" ], "Etag": [ "CAY=" ], "Expires": [ "Thu, 02 May 2019 22:24:13 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Ur5x_r1PKMQrnKbsfUWRR6wBwFQTM8U9mGwyq_fK56rrHE_UoLDxLRpiuaFGLVi9L4Hj67UXH76drA6KQQQgOsMVo0YEl1pVS2P7OKQ64WF4NubRCU" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjIzOjU0LjYxMFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowMi4zNjFaIiwibWV0YWdlbmVyYXRpb24iOiI2IiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FZPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQVk9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQVk9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBWT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQVk9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBWT0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsInZlcnNpb25pbmciOnsiZW5hYmxlZCI6ZmFsc2V9LCJsaWZlY3ljbGUiOnsicnVsZSI6W3siYWN0aW9uIjp7InR5cGUiOiJEZWxldGUifSwiY29uZGl0aW9uIjp7ImFnZSI6MzB9fV19LCJsYWJlbHMiOnsibDEiOiJ2MiIsIm5ldyI6Im5ldyJ9LCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsImV0YWciOiJDQVk9In0=" } }, { "ID": "77ed46692038573c", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/obj1/rewriteTo/b/go-integration-test-20190502-80633403432013-0001/o/copy-obj1?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "3" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "e30K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3333" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:14 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpBnZgUt8GyAer5VG-_nEuf3YizRjF2t4MS6vOflI_Vid1-zVpQ99TuphB3pZjPZNI5ZoHJxCmDv3lyLwyhUDvk_p_NO9x8qZTEpjf1EOO5uxRsOxo" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNyZXdyaXRlUmVzcG9uc2UiLCJ0b3RhbEJ5dGVzUmV3cml0dGVuIjoiMTYiLCJvYmplY3RTaXplIjoiMTYiLCJkb25lIjp0cnVlLCJyZXNvdXJjZSI6eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb3B5LW9iajEvMTU1NjgzNTg1NDE0NDc5MiIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2NvcHktb2JqMSIsIm5hbWUiOiJjb3B5LW9iajEiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg1NDE0NDc5MiIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDoxNC4xNDRaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MTQuMTQ0WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjE0LjE0NFoiLCJzaXplIjoiMTYiLCJtZDVIYXNoIjoiU25hL1VXdjdtY1pJMjNvRTV0VWFiUT09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2NvcHktb2JqMT9nZW5lcmF0aW9uPTE1NTY4MzU4NTQxNDQ3OTImYWx0PW1lZGlhIiwiY2FjaGVDb250cm9sIjoicHVibGljLCBtYXgtYWdlPTYwIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY29weS1vYmoxLzE1NTY4MzU4NTQxNDQ3OTIvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY29weS1vYmoxL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJjb3B5LW9iajEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg1NDE0NDc5MiIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDSmlxdmNEeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY29weS1vYmoxLzE1NTY4MzU4NTQxNDQ3OTIvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2NvcHktb2JqMS9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImNvcHktb2JqMSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODU0MTQ0NzkyIiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0ppcXZjRHgvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NvcHktb2JqMS8xNTU2ODM1ODU0MTQ0NzkyL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jb3B5LW9iajEvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJjb3B5LW9iajEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg1NDE0NDc5MiIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDSmlxdmNEeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY29weS1vYmoxLzE1NTY4MzU4NTQxNDQ3OTIvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2NvcHktb2JqMS9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImNvcHktb2JqMSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODU0MTQ0NzkyIiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ0ppcXZjRHgvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJDVDZkVEE9PSIsImV0YWciOiJDSmlxdmNEeC9lRUNFQUU9In19" } }, { "ID": "9187dbb998c64d40", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/obj1/rewriteTo/b/go-integration-test-20190502-80633403432013-0001/o/copy-obj1?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "31" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb250ZW50RW5jb2RpbmciOiJpZGVudGl0eSJ9Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3299" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:14 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpyrF7U9KSc3XcJb-T_KGf3Fg2yhFUjJqTl06wpqqhG5IT6chgLCWKnLTuamfHtVq8XcP7acZy4TGyKIEvZ4L36TGTfSM8Zp_JyF8K4rN5p375VBMc" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNyZXdyaXRlUmVzcG9uc2UiLCJ0b3RhbEJ5dGVzUmV3cml0dGVuIjoiMTYiLCJvYmplY3RTaXplIjoiMTYiLCJkb25lIjp0cnVlLCJyZXNvdXJjZSI6eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb3B5LW9iajEvMTU1NjgzNTg1NDc0NzU0MyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2NvcHktb2JqMSIsIm5hbWUiOiJjb3B5LW9iajEiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg1NDc0NzU0MyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDoxNC43NDdaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MTQuNzQ3WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjE0Ljc0N1oiLCJzaXplIjoiMTYiLCJtZDVIYXNoIjoiU25hL1VXdjdtY1pJMjNvRTV0VWFiUT09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2NvcHktb2JqMT9nZW5lcmF0aW9uPTE1NTY4MzU4NTQ3NDc1NDMmYWx0PW1lZGlhIiwiY29udGVudEVuY29kaW5nIjoiaWRlbnRpdHkiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb3B5LW9iajEvMTU1NjgzNTg1NDc0NzU0My9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jb3B5LW9iajEvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImNvcHktb2JqMSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODU0NzQ3NTQzIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNKZVA0c0R4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb3B5LW9iajEvMTU1NjgzNTg1NDc0NzU0My9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY29weS1vYmoxL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY29weS1vYmoxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NTQ3NDc1NDMiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDSmVQNHNEeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY29weS1vYmoxLzE1NTY4MzU4NTQ3NDc1NDMvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2NvcHktb2JqMS9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImNvcHktb2JqMSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODU0NzQ3NTQzIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNKZVA0c0R4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb3B5LW9iajEvMTU1NjgzNTg1NDc0NzU0My91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY29weS1vYmoxL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY29weS1vYmoxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NTQ3NDc1NDMiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDSmVQNHNEeC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6IkNUNmRUQT09IiwiZXRhZyI6IkNKZVA0c0R4L2VFQ0VBRT0ifX0=" } }, { "ID": "c199412d75fadc45", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/obj1?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "193" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJhY2wiOlt7ImVudGl0eSI6ImRvbWFpbi1nb29nbGUuY29tIiwicm9sZSI6IlJFQURFUiJ9XSwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwiY29udGVudExhbmd1YWdlIjoiZW4iLCJjb250ZW50VHlwZSI6InRleHQvaHRtbCIsIm1ldGFkYXRhIjp7ImtleSI6InZhbHVlIn19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "2046" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:15 GMT" ], "Etag": [ "CLnS+bvx/eECEAI=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqKO5A_yihnTzTSNbXxyLm-I3MkyC58APsD1U6RZ5_xpjjjL3nXVZIyACkeiDKXRZyU_oP1Yt0FeX23ONp6JeNyoy0J0kW8GwGMgPeN1ATdWGzCMXs" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoxLzE1NTY4MzU4NDQ2NDcyMjUiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoxIiwibmFtZSI6Im9iajEiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsIm1ldGFnZW5lcmF0aW9uIjoiMiIsImNvbnRlbnRUeXBlIjoidGV4dC9odG1sIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA0LjY0NloiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDoxNS4yMjBaIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDQuNjQ2WiIsInNpemUiOiIxNiIsIm1kNUhhc2giOiJTbmEvVVd2N21jWkkyM29FNXRVYWJRPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMT9nZW5lcmF0aW9uPTE1NTY4MzU4NDQ2NDcyMjUmYWx0PW1lZGlhIiwiY29udGVudExhbmd1YWdlIjoiZW4iLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJtZXRhZGF0YSI6eyJrZXkiOiJ2YWx1ZSJ9LCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoxLzE1NTY4MzU4NDQ2NDcyMjUvZG9tYWluLWdvb2dsZS5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoxL2FjbC9kb21haW4tZ29vZ2xlLmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsImVudGl0eSI6ImRvbWFpbi1nb29nbGUuY29tIiwicm9sZSI6IlJFQURFUiIsImRvbWFpbiI6Imdvb2dsZS5jb20iLCJldGFnIjoiQ0xuUytidngvZUVDRUFJPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEvMTU1NjgzNTg0NDY0NzIyNS91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMS9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNMblMrYnZ4L2VFQ0VBST0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoiQ1Q2ZFRBPT0iLCJldGFnIjoiQ0xuUytidngvZUVDRUFJPSJ9" } }, { "ID": "c845025158c6b7d0", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/obj1?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "120" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJjb250ZW50TGFuZ3VhZ2UiOm51bGwsImNvbnRlbnRUeXBlIjpudWxsLCJtZXRhZGF0YSI6bnVsbH0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "1970" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:15 GMT" ], "Etag": [ "CLnS+bvx/eECEAM=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UryOVdmGzCqBOS2ZZ0nw1SqbHF7qJ1CeTxgb6a1BJyoA42NTNZ8RdEVQGNF5u2hWdSQW79cBOonxjms_MoogyDJVAtKHl1rys87QHF6-750NNNSoEw" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoxLzE1NTY4MzU4NDQ2NDcyMjUiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoxIiwibmFtZSI6Im9iajEiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NDY0NzIyNSIsIm1ldGFnZW5lcmF0aW9uIjoiMyIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowNC42NDZaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MTUuNTI3WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA0LjY0NloiLCJzaXplIjoiMTYiLCJtZDVIYXNoIjoiU25hL1VXdjdtY1pJMjNvRTV0VWFiUT09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajE/Z2VuZXJhdGlvbj0xNTU2ODM1ODQ0NjQ3MjI1JmFsdD1tZWRpYSIsImNhY2hlQ29udHJvbCI6InB1YmxpYywgbWF4LWFnZT02MCIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEvMTU1NjgzNTg0NDY0NzIyNS9kb21haW4tZ29vZ2xlLmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajEvYWNsL2RvbWFpbi1nb29nbGUuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqMSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ0NjQ3MjI1IiwiZW50aXR5IjoiZG9tYWluLWdvb2dsZS5jb20iLCJyb2xlIjoiUkVBREVSIiwiZG9tYWluIjoiZ29vZ2xlLmNvbSIsImV0YWciOiJDTG5TK2J2eC9lRUNFQU09In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMS8xNTU2ODM1ODQ0NjQ3MjI1L3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoxL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqMSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ0NjQ3MjI1IiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ0xuUytidngvZUVDRUFNPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJDVDZkVEE9PSIsImV0YWciOiJDTG5TK2J2eC9lRUNFQU09In0=" } }, { "ID": "811b0b9d4980b14f", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJuYW1lIjoiY2hlY2tzdW0tb2JqZWN0In0K", "aGVsbG93b3JsZA==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3305" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:16 GMT" ], "Etag": [ "CIGhrMHx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqJTh_P91pby-vQkRF12GexDihy7TZAlUPamDV_REldvXeqvbrWY_kB0Vcp1lYyuIY7EK2_eMBYYSRMMIVEYz5fxxt51-9Br_UmYvnuRgjhfC16AuA" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jaGVja3N1bS1vYmplY3QvMTU1NjgzNTg1NTk2MjI0MSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2NoZWNrc3VtLW9iamVjdCIsIm5hbWUiOiJjaGVja3N1bS1vYmplY3QiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg1NTk2MjI0MSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDoxNS45NjFaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MTUuOTYxWiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjE1Ljk2MVoiLCJzaXplIjoiMTAiLCJtZDVIYXNoIjoiL0Y0RGpUaWxjRElJVkVIbi9uQVFzQT09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2NoZWNrc3VtLW9iamVjdD9nZW5lcmF0aW9uPTE1NTY4MzU4NTU5NjIyNDEmYWx0PW1lZGlhIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY2hlY2tzdW0tb2JqZWN0LzE1NTY4MzU4NTU5NjIyNDEvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY2hlY2tzdW0tb2JqZWN0L2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJjaGVja3N1bS1vYmplY3QiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg1NTk2MjI0MSIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDSUdock1IeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY2hlY2tzdW0tb2JqZWN0LzE1NTY4MzU4NTU5NjIyNDEvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2NoZWNrc3VtLW9iamVjdC9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImNoZWNrc3VtLW9iamVjdCIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODU1OTYyMjQxIiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0lHaHJNSHgvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NoZWNrc3VtLW9iamVjdC8xNTU2ODM1ODU1OTYyMjQxL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jaGVja3N1bS1vYmplY3QvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJjaGVja3N1bS1vYmplY3QiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg1NTk2MjI0MSIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDSUdock1IeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY2hlY2tzdW0tb2JqZWN0LzE1NTY4MzU4NTU5NjIyNDEvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2NoZWNrc3VtLW9iamVjdC9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImNoZWNrc3VtLW9iamVjdCIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODU1OTYyMjQxIiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ0lHaHJNSHgvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJWc3UwZ0E9PSIsImV0YWciOiJDSUdock1IeC9lRUNFQUU9In0=" } }, { "ID": "69c77b8bdd7cc643", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJuYW1lIjoiemVyby1vYmplY3QifQo=", "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3240" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:16 GMT" ], "Etag": [ "CLirz8Hx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Ur2iXVwACD0yFKYjt0WT-lW1Tx6PtpOgDYttPBWBnJZ3CPf4cUK7heI_9SwdzYXoieaRHDj9n3w3M_SExedwQqQ-GTOY9qM9DPmrPy11hEny0WjECc" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS96ZXJvLW9iamVjdC8xNTU2ODM1ODU2NTM3MDE2Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vemVyby1vYmplY3QiLCJuYW1lIjoiemVyby1vYmplY3QiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg1NjUzNzAxNiIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDoxNi41MzZaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MTYuNTM2WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjE2LjUzNloiLCJzaXplIjoiMCIsIm1kNUhhc2giOiIxQjJNMlk4QXNnVHBnQW1ZN1BoQ2ZnPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vemVyby1vYmplY3Q/Z2VuZXJhdGlvbj0xNTU2ODM1ODU2NTM3MDE2JmFsdD1tZWRpYSIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL3plcm8tb2JqZWN0LzE1NTY4MzU4NTY1MzcwMTYvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vemVyby1vYmplY3QvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Inplcm8tb2JqZWN0IiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NTY1MzcwMTYiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0xpcno4SHgvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL3plcm8tb2JqZWN0LzE1NTY4MzU4NTY1MzcwMTYvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL3plcm8tb2JqZWN0L2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiemVyby1vYmplY3QiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg1NjUzNzAxNiIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNMaXJ6OEh4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS96ZXJvLW9iamVjdC8xNTU2ODM1ODU2NTM3MDE2L3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby96ZXJvLW9iamVjdC9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Inplcm8tb2JqZWN0IiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NTY1MzcwMTYiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0xpcno4SHgvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL3plcm8tb2JqZWN0LzE1NTY4MzU4NTY1MzcwMTYvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL3plcm8tb2JqZWN0L2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiemVyby1vYmplY3QiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg1NjUzNzAxNiIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNMaXJ6OEh4L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoiQUFBQUFBPT0iLCJldGFnIjoiQ0xpcno4SHgvZUVDRUFFPSJ9" } }, { "ID": "1017883279ca634a", "Request": { "Method": "PUT", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/obj1/acl/allUsers?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "98" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJlbnRpdHkiOiJhbGxVc2VycyIsInJvbGUiOiJSRUFERVIifQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "417" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:17 GMT" ], "Etag": [ "CLnS+bvx/eECEAQ=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoKqYaaFUj6b4ezS4lnnQgYv4CHVSsqhVSlLP3QqpItNahh25KnLzbTccK_idrfjKV0gExzr17MvFmoRw7oUIWyJJINmpEXEw5EmHScxipsb3KbWZ8" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMS8xNTU2ODM1ODQ0NjQ3MjI1L2FsbFVzZXJzIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMS9hY2wvYWxsVXNlcnMiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDQ2NDcyMjUiLCJlbnRpdHkiOiJhbGxVc2VycyIsInJvbGUiOiJSRUFERVIiLCJldGFnIjoiQ0xuUytidngvZUVDRUFRPSJ9" } }, { "ID": "35f04bf2400be96f", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/go-integration-test-20190502-80633403432013-0001/obj1", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "public, max-age=60" ], "Content-Length": [ "16" ], "Content-Type": [ "application/octet-stream" ], "Date": [ "Thu, 02 May 2019 22:24:17 GMT" ], "Etag": [ "\"4a76bf516bfb99c648db7a04e6d51a6d\"" ], "Expires": [ "Thu, 02 May 2019 22:25:17 GMT" ], "Last-Modified": [ "Thu, 02 May 2019 22:24:04 GMT" ], "Server": [ "UploadServer" ], "X-Goog-Expiration": [ "Sat, 01 Jun 2019 22:24:04 GMT" ], "X-Goog-Generation": [ "1556835844647225" ], "X-Goog-Hash": [ "crc32c=CT6dTA==", "md5=Sna/UWv7mcZI23oE5tUabQ==" ], "X-Goog-Metageneration": [ "4" ], "X-Goog-Storage-Class": [ "STANDARD" ], "X-Goog-Stored-Content-Encoding": [ "identity" ], "X-Goog-Stored-Content-Length": [ "16" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqC9teasrZdeHJo8KLaQQ251d02ORMxXreH3TKcaQp4NWLVbpiAw1GpW9WeSdFgbpWtVDdyzfjE93gAs6uA0kdlDPZsIEfJVK3GFfaZE2aW5aFCn8Y" ] }, "Body": "TuDshcL7vdCAXh8L42NvEQ==" } }, { "ID": "d01040504d2a91c4", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJuYW1lIjoib2JqMSJ9Cg==", "aGVsbG8=" ] }, "Response": { "StatusCode": 401, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Content-Length": [ "30343" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:17 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "Www-Authenticate": [ "Bearer realm=\"https://accounts.google.com/\"" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UqRhLZOcm0K7eNByUzCBgYfgiytuZ6Hj06jPkbkK77LS80OPgO_78AL530-2AcrlLe1fIy0jM0tonLLncLuOszrqKcGgVhqEJuE48-67vqBRACjqmY" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6InJlcXVpcmVkIiwibWVzc2FnZSI6IkFub255bW91cyBjYWxsZXIgZG9lcyBub3QgaGF2ZSBzdG9yYWdlLm9iamVjdHMuY3JlYXRlIGFjY2VzcyB0byBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMS4iLCJsb2NhdGlvblR5cGUiOiJoZWFkZXIiLCJsb2NhdGlvbiI6IkF1dGhvcml6YXRpb24iLCJkZWJ1Z0luZm8iOiJjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6QUNDRVNTX0RFTklFRDogQW5vbnltb3VzIGNhbGxlciBkb2VzIG5vdCBoYXZlIHN0b3JhZ2Uub2JqZWN0cy5jcmVhdGUgYWNjZXNzIHRvIGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5JbnNlcnRPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEluc2VydE9iamVjdC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkluc2VydE9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoSW5zZXJ0T2JqZWN0LmphdmE6NDQpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLk9iamVjdHNEZWxlZ2F0b3IuaW5zZXJ0KE9iamVjdHNEZWxlZ2F0b3IuamF2YTo5NSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogQW5vbnltb3VzIGNhbGxlciBkb2VzIG5vdCBoYXZlIHN0b3JhZ2Uub2JqZWN0cy5jcmVhdGUgYWNjZXNzIHRvIGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cbmNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLkZhdWx0OiBJbW11dGFibGVFcnJvckRlZmluaXRpb257YmFzZT1MT0dJTl9SRVFVSVJFRCwgY2F0ZWdvcnk9VVNFUl9FUlJPUiwgY2F1c2U9Y29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPUxPR0lOX1JFUVVJUkVELCBjYXRlZ29yeT1VU0VSX0VSUk9SLCBjYXVzZT1udWxsLCBkZWJ1Z0luZm89Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OkFDQ0VTU19ERU5JRUQ6IEFub255bW91cyBjYWxsZXIgZG9lcyBub3QgaGF2ZSBzdG9yYWdlLm9iamVjdHMuY3JlYXRlIGFjY2VzcyB0byBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuSW5zZXJ0T2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRPYmplY3QuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5JbnNlcnRPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEluc2VydE9iamVjdC5qYXZhOjQ0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLmluc2VydChPYmplY3RzRGVsZWdhdG9yLmphdmE6OTUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEFub255bW91cyBjYWxsZXIgZG9lcyBub3QgaGF2ZSBzdG9yYWdlLm9iamVjdHMuY3JlYXRlIGFjY2VzcyB0byBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuLCBkb21haW49Z2xvYmFsLCBleHRlbmRlZEhlbHA9bnVsbCwgaHR0cEhlYWRlcnM9e30sIGh0dHBTdGF0dXM9dW5hdXRob3JpemVkLCBpbnRlcm5hbFJlYXNvbj1SZWFzb257YXJndW1lbnRzPXt9LCBjYXVzZT1udWxsLCBjb2RlPWdkYXRhLkNvcmVFcnJvckRvbWFpbi5SRVFVSVJFRCwgY3JlYXRlZEJ5QmFja2VuZD10cnVlLCBkZWJ1Z01lc3NhZ2U9Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OkFDQ0VTU19ERU5JRUQ6IEFub255bW91cyBjYWxsZXIgZG9lcyBub3QgaGF2ZSBzdG9yYWdlLm9iamVjdHMuY3JlYXRlIGFjY2VzcyB0byBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuSW5zZXJ0T2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRPYmplY3QuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5JbnNlcnRPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEluc2VydE9iamVjdC5qYXZhOjQ0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLmluc2VydChPYmplY3RzRGVsZWdhdG9yLmphdmE6OTUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEFub255bW91cyBjYWxsZXIgZG9lcyBub3QgaGF2ZSBzdG9yYWdlLm9iamVjdHMuY3JlYXRlIGFjY2VzcyB0byBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuLCBlcnJvclByb3RvQ29kZT1SRVFVSVJFRCwgZXJyb3JQcm90b0RvbWFpbj1nZGF0YS5Db3JlRXJyb3JEb21haW4sIGZpbHRlcmVkTWVzc2FnZT1udWxsLCBsb2NhdGlvbj1lbnRpdHkuYXV0aGVudGljYXRlZF91c2VyLCBtZXNzYWdlPUFub255bW91cyBjYWxsZXIgZG9lcyBub3QgaGF2ZSBzdG9yYWdlLm9iamVjdHMuY3JlYXRlIGFjY2VzcyB0byBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMS4sIHVubmFtZWRBcmd1bWVudHM9W119LCBsb2NhdGlvbj1oZWFkZXJzLkF1dGhvcml6YXRpb24sIG1lc3NhZ2U9QW5vbnltb3VzIGNhbGxlciBkb2VzIG5vdCBoYXZlIHN0b3JhZ2Uub2JqZWN0cy5jcmVhdGUgYWNjZXNzIHRvIGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoxLiwgcmVhc29uPXJlcXVpcmVkLCBycGNDb2RlPTQwMX0gQW5vbnltb3VzIGNhbGxlciBkb2VzIG5vdCBoYXZlIHN0b3JhZ2Uub2JqZWN0cy5jcmVhdGUgYWNjZXNzIHRvIGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoxLjogY29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OkFDQ0VTU19ERU5JRUQ6IEFub255bW91cyBjYWxsZXIgZG9lcyBub3QgaGF2ZSBzdG9yYWdlLm9iamVjdHMuY3JlYXRlIGFjY2VzcyB0byBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuSW5zZXJ0T2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRPYmplY3QuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5JbnNlcnRPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEluc2VydE9iamVjdC5qYXZhOjQ0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLmluc2VydChPYmplY3RzRGVsZWdhdG9yLmphdmE6OTUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEFub255bW91cyBjYWxsZXIgZG9lcyBub3QgaGF2ZSBzdG9yYWdlLm9iamVjdHMuY3JlYXRlIGFjY2VzcyB0byBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuLCBkZWJ1Z0luZm89Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OkFDQ0VTU19ERU5JRUQ6IEFub255bW91cyBjYWxsZXIgZG9lcyBub3QgaGF2ZSBzdG9yYWdlLm9iamVjdHMuY3JlYXRlIGFjY2VzcyB0byBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuSW5zZXJ0T2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRPYmplY3QuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5JbnNlcnRPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEluc2VydE9iamVjdC5qYXZhOjQ0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLmluc2VydChPYmplY3RzRGVsZWdhdG9yLmphdmE6OTUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEFub255bW91cyBjYWxsZXIgZG9lcyBub3QgaGF2ZSBzdG9yYWdlLm9iamVjdHMuY3JlYXRlIGFjY2VzcyB0byBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuLCBkb21haW49Z2xvYmFsLCBleHRlbmRlZEhlbHA9bnVsbCwgaHR0cEhlYWRlcnM9e1dXVy1BdXRoZW50aWNhdGU9W0JlYXJlciByZWFsbT1cImh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9cIl19LCBodHRwU3RhdHVzPXVuYXV0aG9yaXplZCwgaW50ZXJuYWxSZWFzb249UmVhc29ue2FyZ3VtZW50cz17fSwgY2F1c2U9bnVsbCwgY29kZT1nZGF0YS5Db3JlRXJyb3JEb21haW4uUkVRVUlSRUQsIGNyZWF0ZWRCeUJhY2tlbmQ9dHJ1ZSwgZGVidWdNZXNzYWdlPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpBQ0NFU1NfREVOSUVEOiBBbm9ueW1vdXMgY2FsbGVyIGRvZXMgbm90IGhhdmUgc3RvcmFnZS5vYmplY3RzLmNyZWF0ZSBhY2Nlc3MgdG8gZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkluc2VydE9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoSW5zZXJ0T2JqZWN0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuSW5zZXJ0T2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRPYmplY3QuamF2YTo0NClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uT2JqZWN0c0RlbGVnYXRvci5pbnNlcnQoT2JqZWN0c0RlbGVnYXRvci5qYXZhOjk1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBBbm9ueW1vdXMgY2FsbGVyIGRvZXMgbm90IGhhdmUgc3RvcmFnZS5vYmplY3RzLmNyZWF0ZSBhY2Nlc3MgdG8gZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZXJyb3JQcm90b0NvZGU9UkVRVUlSRUQsIGVycm9yUHJvdG9Eb21haW49Z2RhdGEuQ29yZUVycm9yRG9tYWluLCBmaWx0ZXJlZE1lc3NhZ2U9bnVsbCwgbG9jYXRpb249ZW50aXR5LmF1dGhlbnRpY2F0ZWRfdXNlciwgbWVzc2FnZT1Bbm9ueW1vdXMgY2FsbGVyIGRvZXMgbm90IGhhdmUgc3RvcmFnZS5vYmplY3RzLmNyZWF0ZSBhY2Nlc3MgdG8gZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEuLCB1bm5hbWVkQXJndW1lbnRzPVtdfSwgbG9jYXRpb249aGVhZGVycy5BdXRob3JpemF0aW9uLCBtZXNzYWdlPUFub255bW91cyBjYWxsZXIgZG9lcyBub3QgaGF2ZSBzdG9yYWdlLm9iamVjdHMuY3JlYXRlIGFjY2VzcyB0byBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMS4sIHJlYXNvbj1yZXF1aXJlZCwgcnBjQ29kZT00MDF9IEFub255bW91cyBjYWxsZXIgZG9lcyBub3QgaGF2ZSBzdG9yYWdlLm9iamVjdHMuY3JlYXRlIGFjY2VzcyB0byBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMS46IGNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpBQ0NFU1NfREVOSUVEOiBBbm9ueW1vdXMgY2FsbGVyIGRvZXMgbm90IGhhdmUgc3RvcmFnZS5vYmplY3RzLmNyZWF0ZSBhY2Nlc3MgdG8gZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkluc2VydE9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoSW5zZXJ0T2JqZWN0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuSW5zZXJ0T2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRPYmplY3QuamF2YTo0NClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uT2JqZWN0c0RlbGVnYXRvci5pbnNlcnQoT2JqZWN0c0RlbGVnYXRvci5qYXZhOjk1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBBbm9ueW1vdXMgY2FsbGVyIGRvZXMgbm90IGhhdmUgc3RvcmFnZS5vYmplY3RzLmNyZWF0ZSBhY2Nlc3MgdG8gZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuYXV0aC5BdXRoZW50aWNhdG9ySW50ZXJjZXB0b3IuYWRkQ2hhbGxlbmdlSGVhZGVyKEF1dGhlbnRpY2F0b3JJbnRlcmNlcHRvci5qYXZhOjI2OSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmF1dGguQXV0aGVudGljYXRvckludGVyY2VwdG9yLnByb2Nlc3NFcnJvclJlc3BvbnNlKEF1dGhlbnRpY2F0b3JJbnRlcmNlcHRvci5qYXZhOjIzNilcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmF1dGguR2FpYU1pbnRJbnRlcmNlcHRvci5wcm9jZXNzRXJyb3JSZXNwb25zZShHYWlhTWludEludGVyY2VwdG9yLmphdmE6NzY4KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS5pbnRlcmNlcHQuQXJvdW5kSW50ZXJjZXB0b3JXcmFwcGVyLnByb2Nlc3NFcnJvclJlc3BvbnNlKEFyb3VuZEludGVyY2VwdG9yV3JhcHBlci5qYXZhOjI4KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuc3RhdHMuU3RhdHNCb290c3RyYXAkSW50ZXJjZXB0b3JTdGF0c1JlY29yZGVyLnByb2Nlc3NFcnJvclJlc3BvbnNlKFN0YXRzQm9vdHN0cmFwLmphdmE6MzE1KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS5pbnRlcmNlcHQuSW50ZXJjZXB0aW9ucyRBcm91bmRJbnRlcmNlcHRpb24uaGFuZGxlRXJyb3JSZXNwb25zZShJbnRlcmNlcHRpb25zLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS5pbnRlcmNlcHQuSW50ZXJjZXB0aW9ucyRBcm91bmRJbnRlcmNlcHRpb24uYWNjZXNzJDIwMChJbnRlcmNlcHRpb25zLmphdmE6MTAzKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS5pbnRlcmNlcHQuSW50ZXJjZXB0aW9ucyRBcm91bmRJbnRlcmNlcHRpb24kMS5jYWxsKEludGVyY2VwdGlvbnMuamF2YToxNDQpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLmludGVyY2VwdC5JbnRlcmNlcHRpb25zJEFyb3VuZEludGVyY2VwdGlvbiQxLmNhbGwoSW50ZXJjZXB0aW9ucy5qYXZhOjEzNylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkRpcmVjdEV4ZWN1dG9yLmV4ZWN1dGUoRGlyZWN0RXhlY3V0b3IuamF2YTozMClcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmV4ZWN1dGVMaXN0ZW5lcihBYnN0cmFjdEZ1dHVyZS5qYXZhOjExNDMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5jb21wbGV0ZShBYnN0cmFjdEZ1dHVyZS5qYXZhOjk2Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLnNldEV4Y2VwdGlvbihBYnN0cmFjdEZ1dHVyZS5qYXZhOjc1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2OClcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkRpcmVjdEV4ZWN1dG9yLmV4ZWN1dGUoRGlyZWN0RXhlY3V0b3IuamF2YTozMClcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmV4ZWN1dGVMaXN0ZW5lcihBYnN0cmFjdEZ1dHVyZS5qYXZhOjExNDMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5jb21wbGV0ZShBYnN0cmFjdEZ1dHVyZS5qYXZhOjk2Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLnNldChBYnN0cmFjdEZ1dHVyZS5qYXZhOjczMSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkRpcmVjdEV4ZWN1dG9yLmV4ZWN1dGUoRGlyZWN0RXhlY3V0b3IuamF2YTozMClcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmV4ZWN1dGVMaXN0ZW5lcihBYnN0cmFjdEZ1dHVyZS5qYXZhOjExNDMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5jb21wbGV0ZShBYnN0cmFjdEZ1dHVyZS5qYXZhOjk2Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLnNldChBYnN0cmFjdEZ1dHVyZS5qYXZhOjczMSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnRocmVhZC5UaHJlYWRUcmFja2VycyRUaHJlYWRUcmFja2luZ1J1bm5hYmxlLnJ1bihUaHJlYWRUcmFja2Vycy5qYXZhOjEyNilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoVHJhY2VDb250ZXh0LmphdmE6NDUzKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuc2VydmVyLkNvbW1vbk1vZHVsZSRDb250ZXh0Q2FycnlpbmdFeGVjdXRvclNlcnZpY2UkMS5ydW5JbkNvbnRleHQoQ29tbW9uTW9kdWxlLmphdmE6ODAyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlJDEucnVuKFRyYWNlQ29udGV4dC5qYXZhOjQ2MClcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihUcmFjZUNvbnRleHQuamF2YTozMTkpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkQWJzdHJhY3RUcmFjZUNvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoVHJhY2VDb250ZXh0LmphdmE6MzExKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NTcpXG5cdGF0IGNvbS5nb29nbGUuZ3NlLmludGVybmFsLkRpc3BhdGNoUXVldWVJbXBsJFdvcmtlclRocmVhZC5ydW4oRGlzcGF0Y2hRdWV1ZUltcGwuamF2YTo0MDMpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLkZhdWx0OiBJbW11dGFibGVFcnJvckRlZmluaXRpb257YmFzZT1MT0dJTl9SRVFVSVJFRCwgY2F0ZWdvcnk9VVNFUl9FUlJPUiwgY2F1c2U9bnVsbCwgZGVidWdJbmZvPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpBQ0NFU1NfREVOSUVEOiBBbm9ueW1vdXMgY2FsbGVyIGRvZXMgbm90IGhhdmUgc3RvcmFnZS5vYmplY3RzLmNyZWF0ZSBhY2Nlc3MgdG8gZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkluc2VydE9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoSW5zZXJ0T2JqZWN0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuSW5zZXJ0T2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRPYmplY3QuamF2YTo0NClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uT2JqZWN0c0RlbGVnYXRvci5pbnNlcnQoT2JqZWN0c0RlbGVnYXRvci5qYXZhOjk1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBBbm9ueW1vdXMgY2FsbGVyIGRvZXMgbm90IGhhdmUgc3RvcmFnZS5vYmplY3RzLmNyZWF0ZSBhY2Nlc3MgdG8gZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZG9tYWluPWdsb2JhbCwgZXh0ZW5kZWRIZWxwPW51bGwsIGh0dHBIZWFkZXJzPXt9LCBodHRwU3RhdHVzPXVuYXV0aG9yaXplZCwgaW50ZXJuYWxSZWFzb249UmVhc29ue2FyZ3VtZW50cz17fSwgY2F1c2U9bnVsbCwgY29kZT1nZGF0YS5Db3JlRXJyb3JEb21haW4uUkVRVUlSRUQsIGNyZWF0ZWRCeUJhY2tlbmQ9dHJ1ZSwgZGVidWdNZXNzYWdlPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpBQ0NFU1NfREVOSUVEOiBBbm9ueW1vdXMgY2FsbGVyIGRvZXMgbm90IGhhdmUgc3RvcmFnZS5vYmplY3RzLmNyZWF0ZSBhY2Nlc3MgdG8gZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkluc2VydE9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoSW5zZXJ0T2JqZWN0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuSW5zZXJ0T2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRPYmplY3QuamF2YTo0NClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uT2JqZWN0c0RlbGVnYXRvci5pbnNlcnQoT2JqZWN0c0RlbGVnYXRvci5qYXZhOjk1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBBbm9ueW1vdXMgY2FsbGVyIGRvZXMgbm90IGhhdmUgc3RvcmFnZS5vYmplY3RzLmNyZWF0ZSBhY2Nlc3MgdG8gZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZXJyb3JQcm90b0NvZGU9UkVRVUlSRUQsIGVycm9yUHJvdG9Eb21haW49Z2RhdGEuQ29yZUVycm9yRG9tYWluLCBmaWx0ZXJlZE1lc3NhZ2U9bnVsbCwgbG9jYXRpb249ZW50aXR5LmF1dGhlbnRpY2F0ZWRfdXNlciwgbWVzc2FnZT1Bbm9ueW1vdXMgY2FsbGVyIGRvZXMgbm90IGhhdmUgc3RvcmFnZS5vYmplY3RzLmNyZWF0ZSBhY2Nlc3MgdG8gZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEuLCB1bm5hbWVkQXJndW1lbnRzPVtdfSwgbG9jYXRpb249aGVhZGVycy5BdXRob3JpemF0aW9uLCBtZXNzYWdlPUFub255bW91cyBjYWxsZXIgZG9lcyBub3QgaGF2ZSBzdG9yYWdlLm9iamVjdHMuY3JlYXRlIGFjY2VzcyB0byBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMS4sIHJlYXNvbj1yZXF1aXJlZCwgcnBjQ29kZT00MDF9IEFub255bW91cyBjYWxsZXIgZG9lcyBub3QgaGF2ZSBzdG9yYWdlLm9iamVjdHMuY3JlYXRlIGFjY2VzcyB0byBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMS46IGNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpBQ0NFU1NfREVOSUVEOiBBbm9ueW1vdXMgY2FsbGVyIGRvZXMgbm90IGhhdmUgc3RvcmFnZS5vYmplY3RzLmNyZWF0ZSBhY2Nlc3MgdG8gZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkluc2VydE9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoSW5zZXJ0T2JqZWN0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuSW5zZXJ0T2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRPYmplY3QuamF2YTo0NClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uT2JqZWN0c0RlbGVnYXRvci5pbnNlcnQoT2JqZWN0c0RlbGVnYXRvci5qYXZhOjk1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBBbm9ueW1vdXMgY2FsbGVyIGRvZXMgbm90IGhhdmUgc3RvcmFnZS5vYmplY3RzLmNyZWF0ZSBhY2Nlc3MgdG8gZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS5FcnJvckNvbGxlY3Rvci50b0ZhdWx0KEVycm9yQ29sbGVjdG9yLmphdmE6NTQpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5RXJyb3JDb252ZXJ0ZXIudG9GYXVsdChSb3N5RXJyb3JDb252ZXJ0ZXIuamF2YTo2Nylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lIYW5kbGVyJDIuY2FsbChSb3N5SGFuZGxlci5qYXZhOjI1OSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lIYW5kbGVyJDIuY2FsbChSb3N5SGFuZGxlci5qYXZhOjIzOSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0Li4uIDIwIG1vcmVcbiJ9XSwiY29kZSI6NDAxLCJtZXNzYWdlIjoiQW5vbnltb3VzIGNhbGxlciBkb2VzIG5vdCBoYXZlIHN0b3JhZ2Uub2JqZWN0cy5jcmVhdGUgYWNjZXNzIHRvIGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoxLiJ9fQ==" } }, { "ID": "db327c92dac99584", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/copy-obj1?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:24:18 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uoa0LrEhOIeq-iYERbwsOkXjr0QR1ANe3tDsleUqoFNU7fRIruaqYikdnU1svzhc8iGRwx0A5dAGYQ_mM045LN_oxU1c76ugXtnWS2PW8wBcmst7hk" ] }, "Body": "" } }, { "ID": "e70c028bd3dc9250", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/copy-obj1?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 404, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "12275" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:18 GMT" ], "Expires": [ "Thu, 02 May 2019 22:24:18 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UqrvFq18HewCbAkJcD7BmKgE8_WOFqSNkcwbpbNqCDPIy5jLVf2fIaHdg76_1rHuAHTtFM84Zr6euptOehRZOqA38Zc_BrJUSZKjg686imvazehpBc" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6Im5vdEZvdW5kIiwibWVzc2FnZSI6Ik5vIHN1Y2ggb2JqZWN0OiBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY29weS1vYmoxIiwiZGVidWdJbmZvIjoiY29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6Ok9CSkVDVF9OT1RfRk9VTkQ6IE5vIHN1Y2ggb2JqZWN0OiBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY29weS1vYmoxXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkRlbGV0ZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlT2JqZWN0LmphdmE6ODgpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5EZWxldGVPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZU9iamVjdC5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLmRlbGV0ZShPYmplY3RzRGVsZWdhdG9yLmphdmE6MTEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBObyBzdWNoIG9iamVjdDogZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NvcHktb2JqMVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cbmNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLkZhdWx0OiBJbW11dGFibGVFcnJvckRlZmluaXRpb257YmFzZT1OT1RfRk9VTkQsIGNhdGVnb3J5PVVTRVJfRVJST1IsIGNhdXNlPW51bGwsIGRlYnVnSW5mbz1jb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6T0JKRUNUX05PVF9GT1VORDogTm8gc3VjaCBvYmplY3Q6IGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb3B5LW9iajFcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuRGVsZXRlT2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChEZWxldGVPYmplY3QuamF2YTo4OClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkRlbGV0ZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlT2JqZWN0LmphdmE6MjUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLk9iamVjdHNEZWxlZ2F0b3IuZGVsZXRlKE9iamVjdHNEZWxlZ2F0b3IuamF2YToxMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IE5vIHN1Y2ggb2JqZWN0OiBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY29weS1vYmoxXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZG9tYWluPWdsb2JhbCwgZXh0ZW5kZWRIZWxwPW51bGwsIGh0dHBIZWFkZXJzPXt9LCBodHRwU3RhdHVzPW5vdEZvdW5kLCBpbnRlcm5hbFJlYXNvbj1SZWFzb257YXJndW1lbnRzPXt9LCBjYXVzZT1udWxsLCBjb2RlPWdkYXRhLkNvcmVFcnJvckRvbWFpbi5OT1RfRk9VTkQsIGNyZWF0ZWRCeUJhY2tlbmQ9dHJ1ZSwgZGVidWdNZXNzYWdlPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpPQkpFQ1RfTk9UX0ZPVU5EOiBObyBzdWNoIG9iamVjdDogZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NvcHktb2JqMVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5EZWxldGVPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZU9iamVjdC5qYXZhOjg4KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuRGVsZXRlT2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChEZWxldGVPYmplY3QuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uT2JqZWN0c0RlbGVnYXRvci5kZWxldGUoT2JqZWN0c0RlbGVnYXRvci5qYXZhOjExMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogTm8gc3VjaCBvYmplY3Q6IGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb3B5LW9iajFcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuLCBlcnJvclByb3RvQ29kZT1OT1RfRk9VTkQsIGVycm9yUHJvdG9Eb21haW49Z2RhdGEuQ29yZUVycm9yRG9tYWluLCBmaWx0ZXJlZE1lc3NhZ2U9bnVsbCwgbG9jYXRpb249ZW50aXR5LnJlc291cmNlX2lkLm5hbWUsIG1lc3NhZ2U9Tm8gc3VjaCBvYmplY3Q6IGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb3B5LW9iajEsIHVubmFtZWRBcmd1bWVudHM9W119LCBsb2NhdGlvbj1lbnRpdHkucmVzb3VyY2VfaWQubmFtZSwgbWVzc2FnZT1ObyBzdWNoIG9iamVjdDogZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NvcHktb2JqMSwgcmVhc29uPW5vdEZvdW5kLCBycGNDb2RlPTQwNH0gTm8gc3VjaCBvYmplY3Q6IGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb3B5LW9iajE6IGNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpPQkpFQ1RfTk9UX0ZPVU5EOiBObyBzdWNoIG9iamVjdDogZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NvcHktb2JqMVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5EZWxldGVPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZU9iamVjdC5qYXZhOjg4KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuRGVsZXRlT2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChEZWxldGVPYmplY3QuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uT2JqZWN0c0RlbGVnYXRvci5kZWxldGUoT2JqZWN0c0RlbGVnYXRvci5qYXZhOjExMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogTm8gc3VjaCBvYmplY3Q6IGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb3B5LW9iajFcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLkVycm9yQ29sbGVjdG9yLnRvRmF1bHQoRXJyb3JDb2xsZWN0b3IuamF2YTo1NClcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lFcnJvckNvbnZlcnRlci50b0ZhdWx0KFJvc3lFcnJvckNvbnZlcnRlci5qYXZhOjY3KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUhhbmRsZXIkMi5jYWxsKFJvc3lIYW5kbGVyLmphdmE6MjU5KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUhhbmRsZXIkMi5jYWxsKFJvc3lIYW5kbGVyLmphdmE6MjM5KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRGlyZWN0RXhlY3V0b3IuZXhlY3V0ZShEaXJlY3RFeGVjdXRvci5qYXZhOjMwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuZXhlY3V0ZUxpc3RlbmVyKEFic3RyYWN0RnV0dXJlLmphdmE6MTE0Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmNvbXBsZXRlKEFic3RyYWN0RnV0dXJlLmphdmE6OTYzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuc2V0KEFic3RyYWN0RnV0dXJlLmphdmE6NzMxKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRGlyZWN0RXhlY3V0b3IuZXhlY3V0ZShEaXJlY3RFeGVjdXRvci5qYXZhOjMwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuZXhlY3V0ZUxpc3RlbmVyKEFic3RyYWN0RnV0dXJlLmphdmE6MTE0Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmNvbXBsZXRlKEFic3RyYWN0RnV0dXJlLmphdmE6OTYzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuc2V0KEFic3RyYWN0RnV0dXJlLmphdmE6NzMxKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIudGhyZWFkLlRocmVhZFRyYWNrZXJzJFRocmVhZFRyYWNraW5nUnVubmFibGUucnVuKFRocmVhZFRyYWNrZXJzLmphdmE6MTI2KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChUcmFjZUNvbnRleHQuamF2YTo0NTMpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5zZXJ2ZXIuQ29tbW9uTW9kdWxlJENvbnRleHRDYXJyeWluZ0V4ZWN1dG9yU2VydmljZSQxLnJ1bkluQ29udGV4dChDb21tb25Nb2R1bGUuamF2YTo4MDIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUkMS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDYwKVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkQWJzdHJhY3RUcmFjZUNvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKFRyYWNlQ29udGV4dC5qYXZhOjMxOSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChUcmFjZUNvbnRleHQuamF2YTozMTEpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuKFRyYWNlQ29udGV4dC5qYXZhOjQ1Nylcblx0YXQgY29tLmdvb2dsZS5nc2UuaW50ZXJuYWwuRGlzcGF0Y2hRdWV1ZUltcGwkV29ya2VyVGhyZWFkLnJ1bihEaXNwYXRjaFF1ZXVlSW1wbC5qYXZhOjQwMylcbiJ9XSwiY29kZSI6NDA0LCJtZXNzYWdlIjoiTm8gc3VjaCBvYmplY3Q6IGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb3B5LW9iajEifX0=" } }, { "ID": "4d7120b41e583669", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/copy-obj1?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 404, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "12215" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:18 GMT" ], "Expires": [ "Thu, 02 May 2019 22:24:18 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UoJ1cGOQjoNiRk8qv-igyccVp3Vg_ut7NLSEO3A-yyQwgGnoXR5jPbi3tuomYWrS57GIvd6GpShkcAYSIJ2e94Jx_1SseYkYtlSF8a7qsDU0OVFYgM" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6Im5vdEZvdW5kIiwibWVzc2FnZSI6Ik5vIHN1Y2ggb2JqZWN0OiBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY29weS1vYmoxIiwiZGVidWdJbmZvIjoiY29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6Ok9CSkVDVF9OT1RfRk9VTkQ6IE5vIHN1Y2ggb2JqZWN0OiBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY29weS1vYmoxXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkdldE9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoR2V0T2JqZWN0LmphdmE6MzA5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuR2V0T2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChHZXRPYmplY3QuamF2YTo3MClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uT2JqZWN0c0RlbGVnYXRvci5nZXQoT2JqZWN0c0RlbGVnYXRvci5qYXZhOjgxKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBObyBzdWNoIG9iamVjdDogZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NvcHktb2JqMVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cbmNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLkZhdWx0OiBJbW11dGFibGVFcnJvckRlZmluaXRpb257YmFzZT1OT1RfRk9VTkQsIGNhdGVnb3J5PVVTRVJfRVJST1IsIGNhdXNlPW51bGwsIGRlYnVnSW5mbz1jb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6T0JKRUNUX05PVF9GT1VORDogTm8gc3VjaCBvYmplY3Q6IGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb3B5LW9iajFcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuR2V0T2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChHZXRPYmplY3QuamF2YTozMDkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5HZXRPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEdldE9iamVjdC5qYXZhOjcwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLmdldChPYmplY3RzRGVsZWdhdG9yLmphdmE6ODEpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IE5vIHN1Y2ggb2JqZWN0OiBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY29weS1vYmoxXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZG9tYWluPWdsb2JhbCwgZXh0ZW5kZWRIZWxwPW51bGwsIGh0dHBIZWFkZXJzPXt9LCBodHRwU3RhdHVzPW5vdEZvdW5kLCBpbnRlcm5hbFJlYXNvbj1SZWFzb257YXJndW1lbnRzPXt9LCBjYXVzZT1udWxsLCBjb2RlPWdkYXRhLkNvcmVFcnJvckRvbWFpbi5OT1RfRk9VTkQsIGNyZWF0ZWRCeUJhY2tlbmQ9dHJ1ZSwgZGVidWdNZXNzYWdlPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpPQkpFQ1RfTk9UX0ZPVU5EOiBObyBzdWNoIG9iamVjdDogZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NvcHktb2JqMVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5HZXRPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEdldE9iamVjdC5qYXZhOjMwOSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkdldE9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoR2V0T2JqZWN0LmphdmE6NzApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLk9iamVjdHNEZWxlZ2F0b3IuZ2V0KE9iamVjdHNEZWxlZ2F0b3IuamF2YTo4MSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogTm8gc3VjaCBvYmplY3Q6IGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb3B5LW9iajFcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuLCBlcnJvclByb3RvQ29kZT1OT1RfRk9VTkQsIGVycm9yUHJvdG9Eb21haW49Z2RhdGEuQ29yZUVycm9yRG9tYWluLCBmaWx0ZXJlZE1lc3NhZ2U9bnVsbCwgbG9jYXRpb249ZW50aXR5LnJlc291cmNlX2lkLm5hbWUsIG1lc3NhZ2U9Tm8gc3VjaCBvYmplY3Q6IGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb3B5LW9iajEsIHVubmFtZWRBcmd1bWVudHM9W119LCBsb2NhdGlvbj1lbnRpdHkucmVzb3VyY2VfaWQubmFtZSwgbWVzc2FnZT1ObyBzdWNoIG9iamVjdDogZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NvcHktb2JqMSwgcmVhc29uPW5vdEZvdW5kLCBycGNDb2RlPTQwNH0gTm8gc3VjaCBvYmplY3Q6IGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb3B5LW9iajE6IGNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpPQkpFQ1RfTk9UX0ZPVU5EOiBObyBzdWNoIG9iamVjdDogZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NvcHktb2JqMVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5HZXRPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEdldE9iamVjdC5qYXZhOjMwOSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkdldE9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoR2V0T2JqZWN0LmphdmE6NzApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLk9iamVjdHNEZWxlZ2F0b3IuZ2V0KE9iamVjdHNEZWxlZ2F0b3IuamF2YTo4MSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogTm8gc3VjaCBvYmplY3Q6IGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb3B5LW9iajFcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLkVycm9yQ29sbGVjdG9yLnRvRmF1bHQoRXJyb3JDb2xsZWN0b3IuamF2YTo1NClcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lFcnJvckNvbnZlcnRlci50b0ZhdWx0KFJvc3lFcnJvckNvbnZlcnRlci5qYXZhOjY3KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUhhbmRsZXIkMi5jYWxsKFJvc3lIYW5kbGVyLmphdmE6MjU5KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUhhbmRsZXIkMi5jYWxsKFJvc3lIYW5kbGVyLmphdmE6MjM5KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRGlyZWN0RXhlY3V0b3IuZXhlY3V0ZShEaXJlY3RFeGVjdXRvci5qYXZhOjMwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuZXhlY3V0ZUxpc3RlbmVyKEFic3RyYWN0RnV0dXJlLmphdmE6MTE0Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmNvbXBsZXRlKEFic3RyYWN0RnV0dXJlLmphdmE6OTYzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuc2V0KEFic3RyYWN0RnV0dXJlLmphdmE6NzMxKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRGlyZWN0RXhlY3V0b3IuZXhlY3V0ZShEaXJlY3RFeGVjdXRvci5qYXZhOjMwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuZXhlY3V0ZUxpc3RlbmVyKEFic3RyYWN0RnV0dXJlLmphdmE6MTE0Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmNvbXBsZXRlKEFic3RyYWN0RnV0dXJlLmphdmE6OTYzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuc2V0KEFic3RyYWN0RnV0dXJlLmphdmE6NzMxKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIudGhyZWFkLlRocmVhZFRyYWNrZXJzJFRocmVhZFRyYWNraW5nUnVubmFibGUucnVuKFRocmVhZFRyYWNrZXJzLmphdmE6MTI2KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChUcmFjZUNvbnRleHQuamF2YTo0NTMpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5zZXJ2ZXIuQ29tbW9uTW9kdWxlJENvbnRleHRDYXJyeWluZ0V4ZWN1dG9yU2VydmljZSQxLnJ1bkluQ29udGV4dChDb21tb25Nb2R1bGUuamF2YTo4MDIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUkMS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDYwKVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkQWJzdHJhY3RUcmFjZUNvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKFRyYWNlQ29udGV4dC5qYXZhOjMxOSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChUcmFjZUNvbnRleHQuamF2YTozMTEpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuKFRyYWNlQ29udGV4dC5qYXZhOjQ1Nylcblx0YXQgY29tLmdvb2dsZS5nc2UuaW50ZXJuYWwuRGlzcGF0Y2hRdWV1ZUltcGwkV29ya2VyVGhyZWFkLnJ1bihEaXNwYXRjaFF1ZXVlSW1wbC5qYXZhOjQwMylcbiJ9XSwiY29kZSI6NDA0LCJtZXNzYWdlIjoiTm8gc3VjaCBvYmplY3Q6IGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb3B5LW9iajEifX0=" } }, { "ID": "e7711da9b067a58f", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/composed1/compose?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "156" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJkZXN0aW5hdGlvbiI6eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEifSwic291cmNlT2JqZWN0cyI6W3sibmFtZSI6Im9iajEifSx7Im5hbWUiOiJvYmoyIn0seyJuYW1lIjoib2JqL3dpdGgvc2xhc2hlcyJ9XX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "750" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:19 GMT" ], "Etag": [ "CI2048Lx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoJ5Us6Rp03fUUqSAPFFGPuqW2qR4gCfzJ4w3W1Kx8C0JGfNDxte0QlBoVEi4K7rV5zkUY1IXQvIk6FOU3DxP8ECZdxkVJBW57Jf5iXo8kRyLVu7OA" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb21wb3NlZDEvMTU1NjgzNTg1ODk2Mjk1NyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2NvbXBvc2VkMSIsIm5hbWUiOiJjb21wb3NlZDEiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg1ODk2Mjk1NyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDoxOC45NjJaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MTguOTYyWiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjE4Ljk2MloiLCJzaXplIjoiNDgiLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY29tcG9zZWQxP2dlbmVyYXRpb249MTU1NjgzNTg1ODk2Mjk1NyZhbHQ9bWVkaWEiLCJjcmMzMmMiOiJBYldCeVE9PSIsImNvbXBvbmVudENvdW50IjozLCJldGFnIjoiQ0kyMDQ4THgvZUVDRUFFPSJ9" } }, { "ID": "de5d78de4310ff60", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/go-integration-test-20190502-80633403432013-0001/composed1", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "48" ], "Content-Type": [ "application/octet-stream" ], "Date": [ "Thu, 02 May 2019 22:24:19 GMT" ], "Etag": [ "\"-CI2048Lx/eECEAE=\"" ], "Expires": [ "Thu, 02 May 2019 22:24:19 GMT" ], "Last-Modified": [ "Thu, 02 May 2019 22:24:18 GMT" ], "Server": [ "UploadServer" ], "X-Goog-Component-Count": [ "3" ], "X-Goog-Expiration": [ "Sat, 01 Jun 2019 22:24:18 GMT" ], "X-Goog-Generation": [ "1556835858962957" ], "X-Goog-Hash": [ "crc32c=AbWByQ==" ], "X-Goog-Metageneration": [ "1" ], "X-Goog-Storage-Class": [ "STANDARD" ], "X-Goog-Stored-Content-Encoding": [ "identity" ], "X-Goog-Stored-Content-Length": [ "48" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqprnxhGEtAMeMcwiKn43QTEdsHrB7k_jCjOqnvH984bk5CIjIhSalrDVNwlLb37IU67jIYyIY1Nq8uaSz5HGUROWwpE6SVmGvIGXnuAbTP7x8Ez5w" ] }, "Body": "TuDshcL7vdCAXh8L42NvEeeRmd+w7xhUEtz55BCr9yaRPt+QxetF2uGfY/b4R5Pm" } }, { "ID": "4b7c14a3f35089ce", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/composed2/compose?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "182" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJkZXN0aW5hdGlvbiI6eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJjb250ZW50VHlwZSI6InRleHQvanNvbiJ9LCJzb3VyY2VPYmplY3RzIjpbeyJuYW1lIjoib2JqMSJ9LHsibmFtZSI6Im9iajIifSx7Im5hbWUiOiJvYmovd2l0aC9zbGFzaGVzIn1dfQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "776" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:19 GMT" ], "Etag": [ "CP+RiMPx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrMYc2wH1kAYUthDQQhZ4gGQU6kYXq6KGs1msu9ifujWYQ2dwS5ifqZFWiTYf74Rq2y9VkzALfhjkTK6anDL-SwHxUH3IwMe8j1rrrbaMbv7eLQCR8" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb21wb3NlZDIvMTU1NjgzNTg1OTU2NDc5OSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2NvbXBvc2VkMiIsIm5hbWUiOiJjb21wb3NlZDIiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg1OTU2NDc5OSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9qc29uIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjE5LjU2NFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDoxOS41NjRaIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MTkuNTY0WiIsInNpemUiOiI0OCIsIm1lZGlhTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jb21wb3NlZDI/Z2VuZXJhdGlvbj0xNTU2ODM1ODU5NTY0Nzk5JmFsdD1tZWRpYSIsImNyYzMyYyI6IkFiV0J5UT09IiwiY29tcG9uZW50Q291bnQiOjMsImV0YWciOiJDUCtSaU1QeC9lRUNFQUU9In0=" } }, { "ID": "26a4cb091ed2f1bd", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/go-integration-test-20190502-80633403432013-0001/composed2", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "48" ], "Content-Type": [ "text/json" ], "Date": [ "Thu, 02 May 2019 22:24:19 GMT" ], "Etag": [ "\"-CP+RiMPx/eECEAE=\"" ], "Expires": [ "Thu, 02 May 2019 22:24:19 GMT" ], "Last-Modified": [ "Thu, 02 May 2019 22:24:19 GMT" ], "Server": [ "UploadServer" ], "X-Goog-Component-Count": [ "3" ], "X-Goog-Expiration": [ "Sat, 01 Jun 2019 22:24:19 GMT" ], "X-Goog-Generation": [ "1556835859564799" ], "X-Goog-Hash": [ "crc32c=AbWByQ==" ], "X-Goog-Metageneration": [ "1" ], "X-Goog-Storage-Class": [ "STANDARD" ], "X-Goog-Stored-Content-Encoding": [ "identity" ], "X-Goog-Stored-Content-Length": [ "48" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Ur-t-yqapXjBzjIrFWFhaT080f06JahbskCp0DC_-izUjPK4fYn556m2qyRDgj9HjkkDPtKR6dauzF5afjNZZ61bN_dTvw15d82A206-SdS1Jv_YM4" ] }, "Body": "TuDshcL7vdCAXh8L42NvEeeRmd+w7xhUEtz55BCr9yaRPt+QxetF2uGfY/b4R5Pm" } }, { "ID": "6b59ed7d3d098970", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJjb250ZW50RW5jb2RpbmciOiJnemlwIiwibmFtZSI6Imd6aXAtdGVzdCJ9Cg==", "H4sIAAAAAAAA/2IgEgACAAD//7E97OkoAAAA" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3227" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:20 GMT" ], "Etag": [ "CNuJssPx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoXNmswaWh2Gfcz1pYPy7etwk09Nz_dmuYVq55M2p3ox38A3mC0QgoHf-hL1uCZxQvusJSIHeugTQvmCgZvRdXV-3juD0W8KI669m0EILAHSfnVoJ8" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9nemlwLXRlc3QvMTU1NjgzNTg2MDI1MTg2NyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2d6aXAtdGVzdCIsIm5hbWUiOiJnemlwLXRlc3QiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg2MDI1MTg2NyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoiYXBwbGljYXRpb24veC1nemlwIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjIwLjI1MVoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDoyMC4yNTFaIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MjAuMjUxWiIsInNpemUiOiIyNyIsIm1kNUhhc2giOiJPdEN3K2FSUklScUtHRkFFT2F4K3F3PT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vZ3ppcC10ZXN0P2dlbmVyYXRpb249MTU1NjgzNTg2MDI1MTg2NyZhbHQ9bWVkaWEiLCJjb250ZW50RW5jb2RpbmciOiJnemlwIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvZ3ppcC10ZXN0LzE1NTY4MzU4NjAyNTE4NjcvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vZ3ppcC10ZXN0L2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJnemlwLXRlc3QiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg2MDI1MTg2NyIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDTnVKc3NQeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvZ3ppcC10ZXN0LzE1NTY4MzU4NjAyNTE4NjcvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2d6aXAtdGVzdC9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Imd6aXAtdGVzdCIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODYwMjUxODY3IiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ051SnNzUHgvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2d6aXAtdGVzdC8xNTU2ODM1ODYwMjUxODY3L3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9nemlwLXRlc3QvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJnemlwLXRlc3QiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg2MDI1MTg2NyIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDTnVKc3NQeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvZ3ppcC10ZXN0LzE1NTY4MzU4NjAyNTE4NjcvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2d6aXAtdGVzdC9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Imd6aXAtdGVzdCIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODYwMjUxODY3IiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ051SnNzUHgvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiI5RGh3QkE9PSIsImV0YWciOiJDTnVKc3NQeC9lRUNFQUU9In0=" } }, { "ID": "070a9af78f7967bf", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/go-integration-test-20190502-80633403432013-0001/gzip-test", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "none" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Type": [ "application/x-gzip" ], "Date": [ "Thu, 02 May 2019 22:24:20 GMT" ], "Expires": [ "Thu, 02 May 2019 22:24:20 GMT" ], "Last-Modified": [ "Thu, 02 May 2019 22:24:20 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Accept-Encoding" ], "X-Goog-Expiration": [ "Sat, 01 Jun 2019 22:24:20 GMT" ], "X-Goog-Generation": [ "1556835860251867" ], "X-Goog-Hash": [ "crc32c=9DhwBA==", "md5=OtCw+aRRIRqKGFAEOax+qw==" ], "X-Goog-Metageneration": [ "1" ], "X-Goog-Storage-Class": [ "STANDARD" ], "X-Goog-Stored-Content-Encoding": [ "gzip" ], "X-Goog-Stored-Content-Length": [ "27" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UosPALnXk-3j5nBlDDWX7hBP4xBNcCe7lGNkEU-sHHTWsRexFWLoB-1gn8RfnlqS6Q5ZTrR86NBxpP1T0bFxgHnlYUYGh-G3mThRCgGIAWjXggOeOU" ] }, "Body": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==" } }, { "ID": "3ece6665583d65fb", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/go-integration-test-20190502-80633403432013-0001/obj-not-exists", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 404, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "225" ], "Content-Type": [ "application/xml; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:20 GMT" ], "Expires": [ "Thu, 02 May 2019 22:24:20 GMT" ], "Server": [ "UploadServer" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2Uph0zmuYk7ZmOWzbNkj24Iai85wz2vKj0mMnMkIHIoDUlDAUCA0e_CgFT5fV_XAvgUx06I9FspomkB_ImflSVCvj55GK6zEoY5iV1hN96nh4AmPBN0" ] }, "Body": "PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48RXJyb3I+PENvZGU+Tm9TdWNoS2V5PC9Db2RlPjxNZXNzYWdlPlRoZSBzcGVjaWZpZWQga2V5IGRvZXMgbm90IGV4aXN0LjwvTWVzc2FnZT48RGV0YWlscz5ObyBzdWNoIG9iamVjdDogZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iai1ub3QtZXhpc3RzPC9EZXRhaWxzPjwvRXJyb3I+" } }, { "ID": "602f4fdfff4e490c", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW4iLCJuYW1lIjoic2lnbmVkVVJMIn0K", "VGhpcyBpcyBhIHRlc3Qgb2YgU2lnbmVkVVJMLgo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3230" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:21 GMT" ], "Etag": [ "CNat6MPx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoWSi2VcVAHJJzhGSPjVT17kZYaCh3uZvWXBU0R4hVmPZJ10gvbv_Ucrfd2kwrBvRYoZaQcYkY5Q3M-oywiCNtLm6SM9InWHz2Omc-0pWJJjfQWPCM" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9zaWduZWRVUkwvMTU1NjgzNTg2MTE0MTIwNiIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL3NpZ25lZFVSTCIsIm5hbWUiOiJzaWduZWRVUkwiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg2MTE0MTIwNiIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDoyMS4xNDBaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MjEuMTQwWiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjIxLjE0MFoiLCJzaXplIjoiMjkiLCJtZDVIYXNoIjoiSnl4dmd3bTluMk1zckdUTVBiTWVZQT09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL3NpZ25lZFVSTD9nZW5lcmF0aW9uPTE1NTY4MzU4NjExNDEyMDYmYWx0PW1lZGlhIiwiY2FjaGVDb250cm9sIjoicHVibGljLCBtYXgtYWdlPTYwIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvc2lnbmVkVVJMLzE1NTY4MzU4NjExNDEyMDYvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vc2lnbmVkVVJML2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJzaWduZWRVUkwiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg2MTE0MTIwNiIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDTmF0Nk1QeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvc2lnbmVkVVJMLzE1NTY4MzU4NjExNDEyMDYvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL3NpZ25lZFVSTC9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6InNpZ25lZFVSTCIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODYxMTQxMjA2IiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ05hdDZNUHgvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL3NpZ25lZFVSTC8xNTU2ODM1ODYxMTQxMjA2L3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9zaWduZWRVUkwvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJzaWduZWRVUkwiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg2MTE0MTIwNiIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDTmF0Nk1QeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvc2lnbmVkVVJMLzE1NTY4MzU4NjExNDEyMDYvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL3NpZ25lZFVSTC9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6InNpZ25lZFVSTCIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODYxMTQxMjA2IiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ05hdDZNUHgvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJaVHFBTHc9PSIsImV0YWciOiJDTmF0Nk1QeC9lRUNFQUU9In0=" } }, { "ID": "4a1c9dc802f4427c", "Request": { "Method": "PUT", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/defaultObjectAcl/domain-google.com?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "107" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJlbnRpdHkiOiJkb21haW4tZ29vZ2xlLmNvbSIsInJvbGUiOiJSRUFERVIifQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "119" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:23 GMT" ], "Etag": [ "CAc=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrbFZENfdiDkKpD_H_zm44x7h5bTZ3VD6MEoiiXuMwxHHK-zCSSoPRA2ALNUXoR3EcS1c-huuyZBIiw7ULKii7BNqKz0RMu4lWRxrDRQBOjGwKDDgE" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoiZG9tYWluLWdvb2dsZS5jb20iLCJyb2xlIjoiUkVBREVSIiwiZG9tYWluIjoiZ29vZ2xlLmNvbSIsImV0YWciOiJDQWM9In0=" } }, { "ID": "e12cb7360f4fd8dd", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/defaultObjectAcl?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "684" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:23 GMT" ], "Etag": [ "CAc=" ], "Expires": [ "Thu, 02 May 2019 22:24:23 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrVJI9g41JQEDEgaIAOXKSCe2B8xklFKSoIciM7uC0uod7t7NzXfxsIrI6mQeZGkWa2B12xdKpSJBndrNbBvygZ6aXxpBBvL8d80NJ42u8KQC7AaFE" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9scyIsIml0ZW1zIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBYz0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQWM9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBYz0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJkb21haW4tZ29vZ2xlLmNvbSIsInJvbGUiOiJSRUFERVIiLCJkb21haW4iOiJnb29nbGUuY29tIiwiZXRhZyI6IkNBYz0ifV19" } }, { "ID": "d25b1dc2d7247768", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJuYW1lIjoiYWNsMSJ9Cg==", "/pXmp0sD+azbBKjod9MhwQ==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3631" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:24 GMT" ], "Etag": [ "COr+pcXx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UosBTMUgCzCYlGDKqRCN7Kexl832zyi4FxoRqfYtmTr8yv63z4BAQBeCTLajyZqMbRyzjje7TtPPYomUSv_8zrQ8bFdXlNzbTSeKK8kXi2Ys82jus4" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9hY2wxLzE1NTY4MzU4NjQyNDgxNzAiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9hY2wxIiwibmFtZSI6ImFjbDEiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg2NDI0ODE3MCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjI0LjI0N1oiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDoyNC4yNDdaIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MjQuMjQ3WiIsInNpemUiOiIxNiIsIm1kNUhhc2giOiIwRTl0Rk5wWmowL1dLT0o2ZlY5cGF3PT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vYWNsMT9nZW5lcmF0aW9uPTE1NTY4MzU4NjQyNDgxNzAmYWx0PW1lZGlhIiwiY2FjaGVDb250cm9sIjoicHVibGljLCBtYXgtYWdlPTYwIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYWNsMS8xNTU2ODM1ODY0MjQ4MTcwL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2FjbDEvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImFjbDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg2NDI0ODE3MCIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDT3IrcGNYeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYWNsMS8xNTU2ODM1ODY0MjQ4MTcwL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9hY2wxL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiYWNsMSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODY0MjQ4MTcwIiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ09yK3BjWHgvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2FjbDEvMTU1NjgzNTg2NDI0ODE3MC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vYWNsMS9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImFjbDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg2NDI0ODE3MCIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDT3IrcGNYeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYWNsMS8xNTU2ODM1ODY0MjQ4MTcwL2RvbWFpbi1nb29nbGUuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vYWNsMS9hY2wvZG9tYWluLWdvb2dsZS5jb20iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJhY2wxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NjQyNDgxNzAiLCJlbnRpdHkiOiJkb21haW4tZ29vZ2xlLmNvbSIsInJvbGUiOiJSRUFERVIiLCJkb21haW4iOiJnb29nbGUuY29tIiwiZXRhZyI6IkNPcitwY1h4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9hY2wxLzE1NTY4MzU4NjQyNDgxNzAvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2FjbDEvYWNsL3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJhY2wxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NjQyNDgxNzAiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDT3IrcGNYeC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6IkZpRG1WZz09IiwiZXRhZyI6IkNPcitwY1h4L2VFQ0VBRT0ifQ==" } }, { "ID": "1d3df0d90130f5fe", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJuYW1lIjoiYWNsMiJ9Cg==", "HSHw5Wsm5u7iJL/jjKkPVQ==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3631" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:24 GMT" ], "Etag": [ "CJrxw8Xx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpMl0_NB41LujALQWmul06CCiuw7okuKlhYG_qilsoXlld2qoYgc2-ABYogriA37QOJMK5ZlJ5sYzP2Mp7CTSzK9uccFLi10TdrGFMUjUpD0OvcXrE" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9hY2wyLzE1NTY4MzU4NjQ3Mzc5NDYiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9hY2wyIiwibmFtZSI6ImFjbDIiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg2NDczNzk0NiIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjI0LjczN1oiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDoyNC43MzdaIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MjQuNzM3WiIsInNpemUiOiIxNiIsIm1kNUhhc2giOiJjOStPL3JnMjRIVEZCYytldFdqZWZnPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vYWNsMj9nZW5lcmF0aW9uPTE1NTY4MzU4NjQ3Mzc5NDYmYWx0PW1lZGlhIiwiY2FjaGVDb250cm9sIjoicHVibGljLCBtYXgtYWdlPTYwIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYWNsMi8xNTU2ODM1ODY0NzM3OTQ2L3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2FjbDIvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImFjbDIiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg2NDczNzk0NiIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDSnJ4dzhYeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYWNsMi8xNTU2ODM1ODY0NzM3OTQ2L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9hY2wyL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiYWNsMiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODY0NzM3OTQ2IiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0pyeHc4WHgvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2FjbDIvMTU1NjgzNTg2NDczNzk0Ni9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vYWNsMi9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImFjbDIiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg2NDczNzk0NiIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDSnJ4dzhYeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYWNsMi8xNTU2ODM1ODY0NzM3OTQ2L2RvbWFpbi1nb29nbGUuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vYWNsMi9hY2wvZG9tYWluLWdvb2dsZS5jb20iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJhY2wyIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NjQ3Mzc5NDYiLCJlbnRpdHkiOiJkb21haW4tZ29vZ2xlLmNvbSIsInJvbGUiOiJSRUFERVIiLCJkb21haW4iOiJnb29nbGUuY29tIiwiZXRhZyI6IkNKcnh3OFh4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9hY2wyLzE1NTY4MzU4NjQ3Mzc5NDYvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2FjbDIvYWNsL3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJhY2wyIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NjQ3Mzc5NDYiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDSnJ4dzhYeC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6IkF0TlJ0QT09IiwiZXRhZyI6IkNKcnh3OFh4L2VFQ0VBRT0ifQ==" } }, { "ID": "a270daf4f72d9d3d", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/acl1/acl?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "2767" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:25 GMT" ], "Etag": [ "COr+pcXx/eECEAE=" ], "Expires": [ "Thu, 02 May 2019 22:24:25 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UranlihhkPcnPzTT2UYs4r6Hritk60lULu-pzO6YX-EWIlMlFiXzKmxaZVgOcPfnCgfJsRktKsL_TbFun1PfupraBREfYklCvRXKvJ_526gW-Jf9zs" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9scyIsIml0ZW1zIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYWNsMS8xNTU2ODM1ODY0MjQ4MTcwL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2FjbDEvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImFjbDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg2NDI0ODE3MCIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDT3IrcGNYeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYWNsMS8xNTU2ODM1ODY0MjQ4MTcwL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9hY2wxL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiYWNsMSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODY0MjQ4MTcwIiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ09yK3BjWHgvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2FjbDEvMTU1NjgzNTg2NDI0ODE3MC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vYWNsMS9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImFjbDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg2NDI0ODE3MCIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDT3IrcGNYeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYWNsMS8xNTU2ODM1ODY0MjQ4MTcwL2RvbWFpbi1nb29nbGUuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vYWNsMS9hY2wvZG9tYWluLWdvb2dsZS5jb20iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJhY2wxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NjQyNDgxNzAiLCJlbnRpdHkiOiJkb21haW4tZ29vZ2xlLmNvbSIsInJvbGUiOiJSRUFERVIiLCJkb21haW4iOiJnb29nbGUuY29tIiwiZXRhZyI6IkNPcitwY1h4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9hY2wxLzE1NTY4MzU4NjQyNDgxNzAvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2FjbDEvYWNsL3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJhY2wxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NjQyNDgxNzAiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDT3IrcGNYeC9lRUNFQUU9In1dfQ==" } }, { "ID": "328125b2bc991e95", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/acl1/acl/domain-google.com?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:24:25 GMT" ], "Etag": [ "COr+pcXx/eECEAI=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UosP78wuW4e1mPLJgcCbCxBC4Je5LWjKugd0fVK51u-P3qeXbQXj4_Amo25ZHyut2LZvoipvmK95xEvebSyVyzVydKyU2VSbHLDkwnRpR-nr9UGIf0" ] }, "Body": "" } }, { "ID": "1c7595376917851f", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/defaultObjectAcl/domain-google.com?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:24:26 GMT" ], "Etag": [ "CAg=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqnZXiLrdCFoctnkKUqdvXLdSp9xumFk20gsRJc4xB1CTZ14aLZYwbDJmi90E28Q2_E4klaJBOaB1OCcpbDBoF1N9E9Bk3VEaNYYrHKMoECuO7RMPs" ] }, "Body": "" } }, { "ID": "4183198b151a3557", "Request": { "Method": "PUT", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/acl/user-jbd%40google.com?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "109" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJlbnRpdHkiOiJ1c2VyLWpiZEBnb29nbGUuY29tIiwicm9sZSI6IlJFQURFUiJ9Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "386" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:27 GMT" ], "Etag": [ "CAk=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uo361-YkcyyOvd5CL4q3LgTM1Bk4RdkPY3cn-qOm6Dn0vghTnmIE9VKkzGiOnjRNnD7SWXGMqpxaCGvCt6P44D55PqOwAtVTF8PNwmEK9HWCoVXABo" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvdXNlci1qYmRAZ29vZ2xlLmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9hY2wvdXNlci1qYmRAZ29vZ2xlLmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsImVudGl0eSI6InVzZXItamJkQGdvb2dsZS5jb20iLCJyb2xlIjoiUkVBREVSIiwiZW1haWwiOiJqYmRAZ29vZ2xlLmNvbSIsImV0YWciOiJDQWs9In0=" } }, { "ID": "e98f53a71d8839c9", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/acl?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "1789" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:28 GMT" ], "Etag": [ "CAk=" ], "Expires": [ "Thu, 02 May 2019 22:24:28 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrqACfvLjoBUrCN_6ksyMdPlv7yPWQGo1D9u1UiCCgFDRlEwr6NOp18BSxaeTuMIabf2ciNj7_Ba1W6YCz64HlcYyQOoEXNfGYGKcAqGTubXsGHPVk" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9scyIsIml0ZW1zIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FrPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQWs9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQWs9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvdXNlci1qYmRAZ29vZ2xlLmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9hY2wvdXNlci1qYmRAZ29vZ2xlLmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsImVudGl0eSI6InVzZXItamJkQGdvb2dsZS5jb20iLCJyb2xlIjoiUkVBREVSIiwiZW1haWwiOiJqYmRAZ29vZ2xlLmNvbSIsImV0YWciOiJDQWs9In1dfQ==" } }, { "ID": "28b9a29086758e65", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/acl/user-jbd%40google.com?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:24:28 GMT" ], "Etag": [ "CAo=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UozsFdtI43Ltv91E18-CrdRZ4pQDVZXReJOVhpWDu3mxNA7rrWU7hNGl4kPMd0FgcVWDigZA5JBNsYbFV113Ew6Cp2uTsuk0uI1io_mhA6-Lmd2h18" ] }, "Body": "" } }, { "ID": "8ef9f7b6caefd750", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJuYW1lIjoiZ29waGVyIn0K", "ZGF0YQ==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3196" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:29 GMT" ], "Etag": [ "CIXH3cfx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uo97hrh9l4pmrJQqaH8Qu3axsdbEPH2Y8GSEso8-ExKuf4ot8o2uS79ROJcgCtql4vLQJ_4L8q0Z7E9E2WYbbl6vKUYKdQiCI0POisS9o_ViNh9-Yk" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9nb3BoZXIvMTU1NjgzNTg2OTM1MjgzNyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2dvcGhlciIsIm5hbWUiOiJnb3BoZXIiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg2OTM1MjgzNyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDoyOS4zNTJaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MjkuMzUyWiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjI5LjM1MloiLCJzaXplIjoiNCIsIm1kNUhhc2giOiJqWGQvT0YwOS9zaUJYU0QzU1dBbTNBPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vZ29waGVyP2dlbmVyYXRpb249MTU1NjgzNTg2OTM1MjgzNyZhbHQ9bWVkaWEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9nb3BoZXIvMTU1NjgzNTg2OTM1MjgzNy9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9nb3BoZXIvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImdvcGhlciIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODY5MzUyODM3IiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNJWEgzY2Z4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9nb3BoZXIvMTU1NjgzNTg2OTM1MjgzNy9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vZ29waGVyL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiZ29waGVyIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NjkzNTI4MzciLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDSVhIM2NmeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvZ29waGVyLzE1NTY4MzU4NjkzNTI4MzcvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2dvcGhlci9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImdvcGhlciIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODY5MzUyODM3IiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNJWEgzY2Z4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9nb3BoZXIvMTU1NjgzNTg2OTM1MjgzNy91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vZ29waGVyL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiZ29waGVyIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NjkzNTI4MzciLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDSVhIM2NmeC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6InJ0aDkwUT09IiwiZXRhZyI6IkNJWEgzY2Z4L2VFQ0VBRT0ifQ==" } }, { "ID": "ae3a5920bc8a9c3c", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJuYW1lIjoi0JPQvtGE0LXRgNC+0LLQuCJ9Cg==", "ZGF0YQ==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3548" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:29 GMT" ], "Etag": [ "CPzK+8fx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrPLZGQqU8j04JqxMmfsqas3HGTlrdx5NM99YR5nCedJYGMSaZ1ynvd2UbUcdwps_gfRo__0XapzHuD3hM_bshff65qlnw_i2cOwp97N2EhfUsZ1X4" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS/Qk9C+0YTQtdGA0L7QstC4LzE1NTY4MzU4Njk4NDQ4NjAiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby8lRDAlOTMlRDAlQkUlRDElODQlRDAlQjUlRDElODAlRDAlQkUlRDAlQjIlRDAlQjgiLCJuYW1lIjoi0JPQvtGE0LXRgNC+0LLQuCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODY5ODQ0ODYwIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjI5Ljg0NFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDoyOS44NDRaIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MjkuODQ0WiIsInNpemUiOiI0IiwibWQ1SGFzaCI6ImpYZC9PRjA5L3NpQlhTRDNTV0FtM0E9PSIsIm1lZGlhTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby8lRDAlOTMlRDAlQkUlRDElODQlRDAlQjUlRDElODAlRDAlQkUlRDAlQjIlRDAlQjg/Z2VuZXJhdGlvbj0xNTU2ODM1ODY5ODQ0ODYwJmFsdD1tZWRpYSIsImNhY2hlQ29udHJvbCI6InB1YmxpYywgbWF4LWFnZT02MCIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL9CT0L7RhNC10YDQvtCy0LgvMTU1NjgzNTg2OTg0NDg2MC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby8lRDAlOTMlRDAlQkUlRDElODQlRDAlQjUlRDElODAlRDAlQkUlRDAlQjIlRDAlQjgvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ItCT0L7RhNC10YDQvtCy0LgiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg2OTg0NDg2MCIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDUHpLKzhmeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEv0JPQvtGE0LXRgNC+0LLQuC8xNTU2ODM1ODY5ODQ0ODYwL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby8lRDAlOTMlRDAlQkUlRDElODQlRDAlQjUlRDElODAlRDAlQkUlRDAlQjIlRDAlQjgvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiLQk9C+0YTQtdGA0L7QstC4IiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4Njk4NDQ4NjAiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDUHpLKzhmeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEv0JPQvtGE0LXRgNC+0LLQuC8xNTU2ODM1ODY5ODQ0ODYwL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby8lRDAlOTMlRDAlQkUlRDElODQlRDAlQjUlRDElODAlRDAlQkUlRDAlQjIlRDAlQjgvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiLQk9C+0YTQtdGA0L7QstC4IiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4Njk4NDQ4NjAiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ1B6Sys4ZngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL9CT0L7RhNC10YDQvtCy0LgvMTU1NjgzNTg2OTg0NDg2MC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vJUQwJTkzJUQwJUJFJUQxJTg0JUQwJUI1JUQxJTgwJUQwJUJFJUQwJUIyJUQwJUI4L2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoi0JPQvtGE0LXRgNC+0LLQuCIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODY5ODQ0ODYwIiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ1B6Sys4ZngvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJydGg5MFE9PSIsImV0YWciOiJDUHpLKzhmeC9lRUNFQUU9In0=" } }, { "ID": "0104a746dbe20580", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJuYW1lIjoiYSJ9Cg==", "ZGF0YQ==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3116" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:30 GMT" ], "Etag": [ "COKVlMjx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqY12miALkWDvx8PHEyL23oxWZlw8Jq7Cn6kS8E8_Tn1tTWWoTuS_pWb5pi9qevCIvqK6aTK56MzwrMuy9axIjpw5yyMZ42MaWK_YFkBr95OnK5IbM" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9hLzE1NTY4MzU4NzAyNDc2NTAiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9hIiwibmFtZSI6ImEiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3MDI0NzY1MCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDozMC4yNDdaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MzAuMjQ3WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjMwLjI0N1oiLCJzaXplIjoiNCIsIm1kNUhhc2giOiJqWGQvT0YwOS9zaUJYU0QzU1dBbTNBPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vYT9nZW5lcmF0aW9uPTE1NTY4MzU4NzAyNDc2NTAmYWx0PW1lZGlhIiwiY2FjaGVDb250cm9sIjoicHVibGljLCBtYXgtYWdlPTYwIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYS8xNTU2ODM1ODcwMjQ3NjUwL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2EvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3MDI0NzY1MCIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDT0tWbE1qeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYS8xNTU2ODM1ODcwMjQ3NjUwL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9hL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiYSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODcwMjQ3NjUwIiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ09LVmxNangvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2EvMTU1NjgzNTg3MDI0NzY1MC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vYS9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3MDI0NzY1MCIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDT0tWbE1qeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYS8xNTU2ODM1ODcwMjQ3NjUwL3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9hL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiYSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODcwMjQ3NjUwIiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ09LVmxNangvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJydGg5MFE9PSIsImV0YWciOiJDT0tWbE1qeC9lRUNFQUU9In0=" } }, { "ID": "da19af085be0fb47", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJuYW1lIjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9Cg==", "ZGF0YQ==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "19484" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:30 GMT" ], "Etag": [ "CLmmusjx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrAJr55dqTDkY_jBKB0vAWyE0owtzB_kEoH91_FKTr9C3bHd8fWUiTrsruL5mgwXg2l8gbPiOXad-A9HIJ3Zt_AeXq_p0m-Q8LrHQqJ6sAKsbzV4Zw" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9hYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhLzE1NTY4MzU4NzA4NzIzNzciLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9hYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwibmFtZSI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3MDg3MjM3NyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDozMC44NzJaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MzAuODcyWiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjMwLjg3MloiLCJzaXplIjoiNCIsIm1kNUhhc2giOiJqWGQvT0YwOS9zaUJYU0QzU1dBbTNBPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYT9nZW5lcmF0aW9uPTE1NTY4MzU4NzA4NzIzNzcmYWx0PW1lZGlhIiwiY2FjaGVDb250cm9sIjoicHVibGljLCBtYXgtYWdlPTYwIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYS8xNTU2ODM1ODcwODcyMzc3L3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2FhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3MDg3MjM3NyIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDTG1tdXNqeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYS8xNTU2ODM1ODcwODcyMzc3L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9hYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODcwODcyMzc3IiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0xtbXVzangvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2FhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEvMTU1NjgzNTg3MDg3MjM3Ny9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYS9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3MDg3MjM3NyIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDTG1tdXNqeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYS8xNTU2ODM1ODcwODcyMzc3L3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9hYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODcwODcyMzc3IiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ0xtbXVzangvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJydGg5MFE9PSIsImV0YWciOiJDTG1tdXNqeC9lRUNFQUU9In0=" } }, { "ID": "96f915707a76c50c", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAifQo=", "ZGF0YQ==" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Content-Length": [ "2948" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:31 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UrQIwi81TFCNpDIZUjs_5tSUFqURLnaBF7g2l1sGMuHCTWZeLyr45VWkcc8fUDYnF-P84QixYQbTzJGuJzOOx7mw1qluYDqoORFGPICfvKmNxrZM3A" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6InJlcXVpcmVkIiwibWVzc2FnZSI6IlJlcXVpcmVkIiwiZGVidWdJbmZvIjoiY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPVJFUVVJUkVELCBjYXRlZ29yeT1VU0VSX0VSUk9SLCBjYXVzZT1udWxsLCBkZWJ1Z0luZm89bnVsbCwgZG9tYWluPWdsb2JhbCwgZXh0ZW5kZWRIZWxwPW51bGwsIGh0dHBIZWFkZXJzPXt9LCBodHRwU3RhdHVzPWJhZFJlcXVlc3QsIGludGVybmFsUmVhc29uPVJlYXNvbnthcmd1bWVudHM9e30sIGNhdXNlPW51bGwsIGNvZGU9Z2RhdGEuQ29yZUVycm9yRG9tYWluLlJFUVVJUkVELCBjcmVhdGVkQnlCYWNrZW5kPXRydWUsIGRlYnVnTWVzc2FnZT1udWxsLCBlcnJvclByb3RvQ29kZT1SRVFVSVJFRCwgZXJyb3JQcm90b0RvbWFpbj1nZGF0YS5Db3JlRXJyb3JEb21haW4sIGZpbHRlcmVkTWVzc2FnZT1udWxsLCBsb2NhdGlvbj1lbnRpdHkucmVzb3VyY2UuaWQubmFtZSwgbWVzc2FnZT1udWxsLCB1bm5hbWVkQXJndW1lbnRzPVtdfSwgbG9jYXRpb249ZW50aXR5LnJlc291cmNlLmlkLm5hbWUsIG1lc3NhZ2U9UmVxdWlyZWQsIHJlYXNvbj1yZXF1aXJlZCwgcnBjQ29kZT00MDB9IFJlcXVpcmVkXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLkVycm9yQ29sbGVjdG9yLnRvRmF1bHQoRXJyb3JDb2xsZWN0b3IuamF2YTo1NClcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lFcnJvckNvbnZlcnRlci50b0ZhdWx0KFJvc3lFcnJvckNvbnZlcnRlci5qYXZhOjY3KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUhhbmRsZXIkMi5jYWxsKFJvc3lIYW5kbGVyLmphdmE6MjU5KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUhhbmRsZXIkMi5jYWxsKFJvc3lIYW5kbGVyLmphdmE6MjM5KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRGlyZWN0RXhlY3V0b3IuZXhlY3V0ZShEaXJlY3RFeGVjdXRvci5qYXZhOjMwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuZXhlY3V0ZUxpc3RlbmVyKEFic3RyYWN0RnV0dXJlLmphdmE6MTE0Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmNvbXBsZXRlKEFic3RyYWN0RnV0dXJlLmphdmE6OTYzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuc2V0KEFic3RyYWN0RnV0dXJlLmphdmE6NzMxKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRGlyZWN0RXhlY3V0b3IuZXhlY3V0ZShEaXJlY3RFeGVjdXRvci5qYXZhOjMwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuZXhlY3V0ZUxpc3RlbmVyKEFic3RyYWN0RnV0dXJlLmphdmE6MTE0Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmNvbXBsZXRlKEFic3RyYWN0RnV0dXJlLmphdmE6OTYzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuc2V0KEFic3RyYWN0RnV0dXJlLmphdmE6NzMxKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIudGhyZWFkLlRocmVhZFRyYWNrZXJzJFRocmVhZFRyYWNraW5nUnVubmFibGUucnVuKFRocmVhZFRyYWNrZXJzLmphdmE6MTI2KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChUcmFjZUNvbnRleHQuamF2YTo0NTMpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5zZXJ2ZXIuQ29tbW9uTW9kdWxlJENvbnRleHRDYXJyeWluZ0V4ZWN1dG9yU2VydmljZSQxLnJ1bkluQ29udGV4dChDb21tb25Nb2R1bGUuamF2YTo4MDIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUkMS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDYwKVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkQWJzdHJhY3RUcmFjZUNvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKFRyYWNlQ29udGV4dC5qYXZhOjMxOSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChUcmFjZUNvbnRleHQuamF2YTozMTEpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuKFRyYWNlQ29udGV4dC5qYXZhOjQ1Nylcblx0YXQgY29tLmdvb2dsZS5nc2UuaW50ZXJuYWwuRGlzcGF0Y2hRdWV1ZUltcGwkV29ya2VyVGhyZWFkLnJ1bihEaXNwYXRjaFF1ZXVlSW1wbC5qYXZhOjQwMylcbiJ9XSwiY29kZSI6NDAwLCJtZXNzYWdlIjoiUmVxdWlyZWQifX0=" } }, { "ID": "7a562d6e65ef8a7a", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJuYW1lIjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifQo=", "ZGF0YQ==" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Content-Length": [ "4785" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:31 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2Ups-3Re4_9njFMmkYwND6BuK5cgxs5tKVRwQ2CGkcks-K0aALbethXTYaEb6fLos6w_FSnM8YkPGM3TETCAoyYpVbQPlotXR9CH3DXngjQNv0yv_ZQ" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6ImludmFsaWQiLCJtZXNzYWdlIjoiVGhlIG1heGltdW0gb2JqZWN0IGxlbmd0aCBpcyAxMDI0IGNoYXJhY3RlcnMsIGJ1dCBnb3QgYSBuYW1lIHdpdGggMTAyNSBjaGFyYWN0ZXJzOiAnJ2FhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhLi4uJyciLCJkZWJ1Z0luZm8iOiJjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS5GYXVsdDogSW1tdXRhYmxlRXJyb3JEZWZpbml0aW9ue2Jhc2U9SU5WQUxJRF9WQUxVRSwgY2F0ZWdvcnk9VVNFUl9FUlJPUiwgY2F1c2U9bnVsbCwgZGVidWdJbmZvPW51bGwsIGRvbWFpbj1nbG9iYWwsIGV4dGVuZGVkSGVscD1udWxsLCBodHRwSGVhZGVycz17fSwgaHR0cFN0YXR1cz1iYWRSZXF1ZXN0LCBpbnRlcm5hbFJlYXNvbj1SZWFzb257YXJndW1lbnRzPXt9LCBjYXVzZT1udWxsLCBjb2RlPWdkYXRhLkNvcmVFcnJvckRvbWFpbi5JTlZBTElEX1ZBTFVFLCBjcmVhdGVkQnlCYWNrZW5kPXRydWUsIGRlYnVnTWVzc2FnZT1udWxsLCBlcnJvclByb3RvQ29kZT1JTlZBTElEX1ZBTFVFLCBlcnJvclByb3RvRG9tYWluPWdkYXRhLkNvcmVFcnJvckRvbWFpbiwgZmlsdGVyZWRNZXNzYWdlPW51bGwsIGxvY2F0aW9uPWVudGl0eS5yZXNvdXJjZS5pZC5uYW1lLCBtZXNzYWdlPVRoZSBtYXhpbXVtIG9iamVjdCBsZW5ndGggaXMgMTAyNCBjaGFyYWN0ZXJzLCBidXQgZ290IGEgbmFtZSB3aXRoIDEwMjUgY2hhcmFjdGVyczogJydhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYS4uLicnLCB1bm5hbWVkQXJndW1lbnRzPVthYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYV19LCBsb2NhdGlvbj1lbnRpdHkucmVzb3VyY2UuaWQubmFtZSwgbWVzc2FnZT1UaGUgbWF4aW11bSBvYmplY3QgbGVuZ3RoIGlzIDEwMjQgY2hhcmFjdGVycywgYnV0IGdvdCBhIG5hbWUgd2l0aCAxMDI1IGNoYXJhY3RlcnM6ICcnYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEuLi4nJywgcmVhc29uPWludmFsaWQsIHJwY0NvZGU9NDAwfSBUaGUgbWF4aW11bSBvYmplY3QgbGVuZ3RoIGlzIDEwMjQgY2hhcmFjdGVycywgYnV0IGdvdCBhIG5hbWUgd2l0aCAxMDI1IGNoYXJhY3RlcnM6ICcnYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEuLi4nJ1xuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS5FcnJvckNvbGxlY3Rvci50b0ZhdWx0KEVycm9yQ29sbGVjdG9yLmphdmE6NTQpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5RXJyb3JDb252ZXJ0ZXIudG9GYXVsdChSb3N5RXJyb3JDb252ZXJ0ZXIuamF2YTo2Nylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lIYW5kbGVyJDIuY2FsbChSb3N5SGFuZGxlci5qYXZhOjI1OSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lIYW5kbGVyJDIuY2FsbChSb3N5SGFuZGxlci5qYXZhOjIzOSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkRpcmVjdEV4ZWN1dG9yLmV4ZWN1dGUoRGlyZWN0RXhlY3V0b3IuamF2YTozMClcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmV4ZWN1dGVMaXN0ZW5lcihBYnN0cmFjdEZ1dHVyZS5qYXZhOjExNDMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5jb21wbGV0ZShBYnN0cmFjdEZ1dHVyZS5qYXZhOjk2Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLnNldChBYnN0cmFjdEZ1dHVyZS5qYXZhOjczMSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkRpcmVjdEV4ZWN1dG9yLmV4ZWN1dGUoRGlyZWN0RXhlY3V0b3IuamF2YTozMClcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmV4ZWN1dGVMaXN0ZW5lcihBYnN0cmFjdEZ1dHVyZS5qYXZhOjExNDMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5jb21wbGV0ZShBYnN0cmFjdEZ1dHVyZS5qYXZhOjk2Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLnNldChBYnN0cmFjdEZ1dHVyZS5qYXZhOjczMSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnRocmVhZC5UaHJlYWRUcmFja2VycyRUaHJlYWRUcmFja2luZ1J1bm5hYmxlLnJ1bihUaHJlYWRUcmFja2Vycy5qYXZhOjEyNilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoVHJhY2VDb250ZXh0LmphdmE6NDUzKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuc2VydmVyLkNvbW1vbk1vZHVsZSRDb250ZXh0Q2FycnlpbmdFeGVjdXRvclNlcnZpY2UkMS5ydW5JbkNvbnRleHQoQ29tbW9uTW9kdWxlLmphdmE6ODAyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlJDEucnVuKFRyYWNlQ29udGV4dC5qYXZhOjQ2MClcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihUcmFjZUNvbnRleHQuamF2YTozMTkpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkQWJzdHJhY3RUcmFjZUNvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoVHJhY2VDb250ZXh0LmphdmE6MzExKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NTcpXG5cdGF0IGNvbS5nb29nbGUuZ3NlLmludGVybmFsLkRpc3BhdGNoUXVldWVJbXBsJFdvcmtlclRocmVhZC5ydW4oRGlzcGF0Y2hRdWV1ZUltcGwuamF2YTo0MDMpXG4ifV0sImNvZGUiOjQwMCwibWVzc2FnZSI6IlRoZSBtYXhpbXVtIG9iamVjdCBsZW5ndGggaXMgMTAyNCBjaGFyYWN0ZXJzLCBidXQgZ290IGEgbmFtZSB3aXRoIDEwMjUgY2hhcmFjdGVyczogJydhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYS4uLicnIn19" } }, { "ID": "239b642e1919a84a", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJuYW1lIjoibmV3XG5saW5lcyJ9Cg==", "ZGF0YQ==" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Content-Length": [ "3270" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:31 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2Urk-XOPoshQkyIHYZp241R2W5lOuLwqPMx606rubzPOaGggM2z_sZO93dYCJHffXuPDOjy64lIxrBXIYW4QT04eM932jPtzPdVd-PFWssV9RYk83JE" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6ImludmFsaWQiLCJtZXNzYWdlIjoiRGlzYWxsb3dlZCB1bmljb2RlIGNoYXJhY3RlcnMgcHJlc2VudCBpbiBvYmplY3QgbmFtZSAnJ25ld1xubGluZXMnJyIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLkZhdWx0OiBJbW11dGFibGVFcnJvckRlZmluaXRpb257YmFzZT1JTlZBTElEX1ZBTFVFLCBjYXRlZ29yeT1VU0VSX0VSUk9SLCBjYXVzZT1udWxsLCBkZWJ1Z0luZm89bnVsbCwgZG9tYWluPWdsb2JhbCwgZXh0ZW5kZWRIZWxwPW51bGwsIGh0dHBIZWFkZXJzPXt9LCBodHRwU3RhdHVzPWJhZFJlcXVlc3QsIGludGVybmFsUmVhc29uPVJlYXNvbnthcmd1bWVudHM9e30sIGNhdXNlPW51bGwsIGNvZGU9Z2RhdGEuQ29yZUVycm9yRG9tYWluLklOVkFMSURfVkFMVUUsIGNyZWF0ZWRCeUJhY2tlbmQ9dHJ1ZSwgZGVidWdNZXNzYWdlPW51bGwsIGVycm9yUHJvdG9Db2RlPUlOVkFMSURfVkFMVUUsIGVycm9yUHJvdG9Eb21haW49Z2RhdGEuQ29yZUVycm9yRG9tYWluLCBmaWx0ZXJlZE1lc3NhZ2U9bnVsbCwgbG9jYXRpb249ZW50aXR5LnJlc291cmNlLmlkLm5hbWUsIG1lc3NhZ2U9RGlzYWxsb3dlZCB1bmljb2RlIGNoYXJhY3RlcnMgcHJlc2VudCBpbiBvYmplY3QgbmFtZSAnJ25ld1xubGluZXMnJywgdW5uYW1lZEFyZ3VtZW50cz1bbmV3XG5saW5lc119LCBsb2NhdGlvbj1lbnRpdHkucmVzb3VyY2UuaWQubmFtZSwgbWVzc2FnZT1EaXNhbGxvd2VkIHVuaWNvZGUgY2hhcmFjdGVycyBwcmVzZW50IGluIG9iamVjdCBuYW1lICcnbmV3XG5saW5lcycnLCByZWFzb249aW52YWxpZCwgcnBjQ29kZT00MDB9IERpc2FsbG93ZWQgdW5pY29kZSBjaGFyYWN0ZXJzIHByZXNlbnQgaW4gb2JqZWN0IG5hbWUgJyduZXdcbmxpbmVzJydcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRXJyb3JDb2xsZWN0b3IudG9GYXVsdChFcnJvckNvbGxlY3Rvci5qYXZhOjU0KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUVycm9yQ29udmVydGVyLnRvRmF1bHQoUm9zeUVycm9yQ29udmVydGVyLmphdmE6NjcpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyNTkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyMzkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci50aHJlYWQuVGhyZWFkVHJhY2tlcnMkVGhyZWFkVHJhY2tpbmdSdW5uYWJsZS5ydW4oVGhyZWFkVHJhY2tlcnMuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjQ1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnNlcnZlci5Db21tb25Nb2R1bGUkQ29udGV4dENhcnJ5aW5nRXhlY3V0b3JTZXJ2aWNlJDEucnVuSW5Db250ZXh0KENvbW1vbk1vZHVsZS5qYXZhOjgwMilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZSQxLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NjApXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoVHJhY2VDb250ZXh0LmphdmE6MzE5KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjMxMSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDU3KVxuXHRhdCBjb20uZ29vZ2xlLmdzZS5pbnRlcm5hbC5EaXNwYXRjaFF1ZXVlSW1wbCRXb3JrZXJUaHJlYWQucnVuKERpc3BhdGNoUXVldWVJbXBsLmphdmE6NDAzKVxuIn1dLCJjb2RlIjo0MDAsIm1lc3NhZ2UiOiJEaXNhbGxvd2VkIHVuaWNvZGUgY2hhcmFjdGVycyBwcmVzZW50IGluIG9iamVjdCBuYW1lICcnbmV3XG5saW5lcycnIn19" } }, { "ID": "3cd795cb0b675f98", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:24:31 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpOXjD9T_c_FRByyyA-CjE753kXZefEzIwQdrNG6OewoHOvKC3Bb9LleziQ6-ymVDg-F1S1eeQeFNJH7nJxDsdA_VmxOjeBzTDB_F3--_1NtwMF6Do" ] }, "Body": "" } }, { "ID": "361d4541e2cb460a", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/a?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:24:31 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpomJFlpfOIJoFvdCmQgD2dRXSREzV1ToI2ntcHi8I9tSyzMCUk0ZrytllkwR_nU8WFZ0YuXVl0Kwsq1EhJL85RlBgCkBNc1P-yVMyNbdt5YrooKok" ] }, "Body": "" } }, { "ID": "a4e929446e49411d", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/%D0%93%D0%BE%D1%84%D0%B5%D1%80%D0%BE%D0%B2%D0%B8?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:24:31 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqmdInqhuXhUxVjtfRvXvHd6Rmo1ODUbeNFFTBW4diuT7HDjzmYnvd4TU6oJPqbck52yFAR99fMx4Tks1TllSUCB4GsMVbBNENfZU6te-hXIB8XyJs" ] }, "Body": "" } }, { "ID": "89b2ef62a071f7b9", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/gopher?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:24:32 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrRgapcSgK1GOswXS37Vynb9BRj0go8bNPOBtrFZ3TDr-nzIdlvKBQuwHtXl4Tlb-mLl-A65zL5Iw3unCEuy6lwtWl5-V7REtcIVHkrWLK5AoLoHqA" ] }, "Body": "" } }, { "ID": "ca91b2e4ee4555cb", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJuYW1lIjoiY29udGVudCJ9Cg==", "SXQgd2FzIHRoZSBiZXN0IG9mIHRpbWVzLCBpdCB3YXMgdGhlIHdvcnN0IG9mIHRpbWVzLg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3213" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:32 GMT" ], "Etag": [ "CLGNmsnx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UovWW5HSrWbcvQoWGU3c_n64wwcau06tjEM-fzdADFSbmmylG3VLjae6MRNIM4B9gDitCKfjo1_xPQNAZEmMYzRplVmdI4cIrBC8ursFSUywoCSJeU" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb250ZW50LzE1NTY4MzU4NzI0NDIwMzMiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jb250ZW50IiwibmFtZSI6ImNvbnRlbnQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3MjQ0MjAzMyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDozMi40NDFaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MzIuNDQxWiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjMyLjQ0MVoiLCJzaXplIjoiNTIiLCJtZDVIYXNoIjoiSzI4NUF3S1dXZlZSZEJjQ1VYaHpOZz09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2NvbnRlbnQ/Z2VuZXJhdGlvbj0xNTU2ODM1ODcyNDQyMDMzJmFsdD1tZWRpYSIsImNhY2hlQ29udHJvbCI6InB1YmxpYywgbWF4LWFnZT02MCIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NvbnRlbnQvMTU1NjgzNTg3MjQ0MjAzMy9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jb250ZW50L2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJjb250ZW50IiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NzI0NDIwMzMiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0xHTm1zbngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NvbnRlbnQvMTU1NjgzNTg3MjQ0MjAzMy9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY29udGVudC9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImNvbnRlbnQiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3MjQ0MjAzMyIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNMR05tc254L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb250ZW50LzE1NTY4MzU4NzI0NDIwMzMvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2NvbnRlbnQvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJjb250ZW50IiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NzI0NDIwMzMiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0xHTm1zbngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NvbnRlbnQvMTU1NjgzNTg3MjQ0MjAzMy91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY29udGVudC9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImNvbnRlbnQiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3MjQ0MjAzMyIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNMR05tc254L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoiRmNYTThRPT0iLCJldGFnIjoiQ0xHTm1zbngvZUVDRUFFPSJ9" } }, { "ID": "eb678345630fe080", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/content?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3213" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:32 GMT" ], "Etag": [ "CLGNmsnx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrtPOErXGrnlQtXCV1PhgO5nz80m75Fzs7DoR-y8Ava3jvL9NDJ4L-i8SIV_tktR8VqCvv9uh-X1ltJCj3isa_oY8TlV-OsZeIiESuDrRTYueQWQP0" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb250ZW50LzE1NTY4MzU4NzI0NDIwMzMiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jb250ZW50IiwibmFtZSI6ImNvbnRlbnQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3MjQ0MjAzMyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDozMi40NDFaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MzIuNDQxWiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjMyLjQ0MVoiLCJzaXplIjoiNTIiLCJtZDVIYXNoIjoiSzI4NUF3S1dXZlZSZEJjQ1VYaHpOZz09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2NvbnRlbnQ/Z2VuZXJhdGlvbj0xNTU2ODM1ODcyNDQyMDMzJmFsdD1tZWRpYSIsImNhY2hlQ29udHJvbCI6InB1YmxpYywgbWF4LWFnZT02MCIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NvbnRlbnQvMTU1NjgzNTg3MjQ0MjAzMy9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jb250ZW50L2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJjb250ZW50IiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NzI0NDIwMzMiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0xHTm1zbngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NvbnRlbnQvMTU1NjgzNTg3MjQ0MjAzMy9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY29udGVudC9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImNvbnRlbnQiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3MjQ0MjAzMyIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNMR05tc254L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb250ZW50LzE1NTY4MzU4NzI0NDIwMzMvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2NvbnRlbnQvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJjb250ZW50IiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NzI0NDIwMzMiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0xHTm1zbngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NvbnRlbnQvMTU1NjgzNTg3MjQ0MjAzMy91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY29udGVudC9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImNvbnRlbnQiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3MjQ0MjAzMyIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNMR05tc254L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoiRmNYTThRPT0iLCJldGFnIjoiQ0xHTm1zbngvZUVDRUFFPSJ9" } }, { "ID": "d76ba152a62e7dc1", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJuYW1lIjoiY29udGVudCJ9Cg==", "PGh0bWw+PGhlYWQ+PHRpdGxlPk15IGZpcnN0IHBhZ2U8L3RpdGxlPjwvaGVhZD48L2h0bWw+" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3212" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:33 GMT" ], "Etag": [ "CLPJv8nx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uqk5XoKCyt74JBpeU8oREfzh3e0LLtXupBjcWtsFfHNZDEn4DjcmzWo6resyQ1gEisBp_STlU4hVaU3MbTyX3LM443_Gsu4ouZGdf3ZTvTzsLD_zNw" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb250ZW50LzE1NTY4MzU4NzMwNTU5MjMiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jb250ZW50IiwibmFtZSI6ImNvbnRlbnQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3MzA1NTkyMyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9odG1sOyBjaGFyc2V0PXV0Zi04IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjMzLjA1NVoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDozMy4wNTVaIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MzMuMDU1WiIsInNpemUiOiI1NCIsIm1kNUhhc2giOiJOOHA4L3M5RndkQUFubHZyL2xFQWpRPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY29udGVudD9nZW5lcmF0aW9uPTE1NTY4MzU4NzMwNTU5MjMmYWx0PW1lZGlhIiwiY2FjaGVDb250cm9sIjoicHVibGljLCBtYXgtYWdlPTYwIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY29udGVudC8xNTU2ODM1ODczMDU1OTIzL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2NvbnRlbnQvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImNvbnRlbnQiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3MzA1NTkyMyIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDTFBKdjhueC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY29udGVudC8xNTU2ODM1ODczMDU1OTIzL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jb250ZW50L2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY29udGVudCIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODczMDU1OTIzIiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0xQSnY4bngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NvbnRlbnQvMTU1NjgzNTg3MzA1NTkyMy9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY29udGVudC9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImNvbnRlbnQiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3MzA1NTkyMyIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDTFBKdjhueC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY29udGVudC8xNTU2ODM1ODczMDU1OTIzL3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jb250ZW50L2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY29udGVudCIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODczMDU1OTIzIiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ0xQSnY4bngvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJHb1Vic1E9PSIsImV0YWciOiJDTFBKdjhueC9lRUNFQUU9In0=" } }, { "ID": "f785ed7f0490bb6d", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/content?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3212" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:33 GMT" ], "Etag": [ "CLPJv8nx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrCqpaad9mhxk7VZgTc8xIunote5-AHPp3vYkUbSU8uiVcq65rcnrbtIuCqJ63JTuVJvKw7pFwnLjyn5fL37JzfXLhmLAowAV67_Qqtxxhiy4WQars" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb250ZW50LzE1NTY4MzU4NzMwNTU5MjMiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jb250ZW50IiwibmFtZSI6ImNvbnRlbnQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3MzA1NTkyMyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9odG1sOyBjaGFyc2V0PXV0Zi04IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjMzLjA1NVoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDozMy4wNTVaIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MzMuMDU1WiIsInNpemUiOiI1NCIsIm1kNUhhc2giOiJOOHA4L3M5RndkQUFubHZyL2xFQWpRPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY29udGVudD9nZW5lcmF0aW9uPTE1NTY4MzU4NzMwNTU5MjMmYWx0PW1lZGlhIiwiY2FjaGVDb250cm9sIjoicHVibGljLCBtYXgtYWdlPTYwIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY29udGVudC8xNTU2ODM1ODczMDU1OTIzL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2NvbnRlbnQvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImNvbnRlbnQiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3MzA1NTkyMyIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDTFBKdjhueC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY29udGVudC8xNTU2ODM1ODczMDU1OTIzL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jb250ZW50L2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY29udGVudCIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODczMDU1OTIzIiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0xQSnY4bngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NvbnRlbnQvMTU1NjgzNTg3MzA1NTkyMy9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY29udGVudC9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImNvbnRlbnQiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3MzA1NTkyMyIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDTFBKdjhueC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY29udGVudC8xNTU2ODM1ODczMDU1OTIzL3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jb250ZW50L2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY29udGVudCIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODczMDU1OTIzIiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ0xQSnY4bngvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJHb1Vic1E9PSIsImV0YWciOiJDTFBKdjhueC9lRUNFQUU9In0=" } }, { "ID": "096d156b863922d6", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJjb250ZW50VHlwZSI6InRleHQvaHRtbCIsIm5hbWUiOiJjb250ZW50In0K", "PGh0bWw+PGhlYWQ+PHRpdGxlPk15IGZpcnN0IHBhZ2U8L3RpdGxlPjwvaGVhZD48L2h0bWw+" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3197" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:33 GMT" ], "Etag": [ "CPW+6cnx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoivaSzjVdOm2KP4nXCF8VQDNHXmlNjm9rZwTaWzjvBmH3oK01QYTnHqZ5DhYRewu_1H0KoQgFpUIC-M4OKZoOhRHrq0-H8HLT__SqD1D5cmezrqHo" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb250ZW50LzE1NTY4MzU4NzM3NDI3MDkiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jb250ZW50IiwibmFtZSI6ImNvbnRlbnQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3Mzc0MjcwOSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9odG1sIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjMzLjc0MloiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDozMy43NDJaIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MzMuNzQyWiIsInNpemUiOiI1NCIsIm1kNUhhc2giOiJOOHA4L3M5RndkQUFubHZyL2xFQWpRPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY29udGVudD9nZW5lcmF0aW9uPTE1NTY4MzU4NzM3NDI3MDkmYWx0PW1lZGlhIiwiY2FjaGVDb250cm9sIjoicHVibGljLCBtYXgtYWdlPTYwIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY29udGVudC8xNTU2ODM1ODczNzQyNzA5L3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2NvbnRlbnQvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImNvbnRlbnQiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3Mzc0MjcwOSIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDUFcrNmNueC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY29udGVudC8xNTU2ODM1ODczNzQyNzA5L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jb250ZW50L2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY29udGVudCIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODczNzQyNzA5IiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ1BXKzZjbngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NvbnRlbnQvMTU1NjgzNTg3Mzc0MjcwOS9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY29udGVudC9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImNvbnRlbnQiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3Mzc0MjcwOSIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDUFcrNmNueC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY29udGVudC8xNTU2ODM1ODczNzQyNzA5L3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jb250ZW50L2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY29udGVudCIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODczNzQyNzA5IiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ1BXKzZjbngvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJHb1Vic1E9PSIsImV0YWciOiJDUFcrNmNueC9lRUNFQUU9In0=" } }, { "ID": "0e96d304e9558094", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/content?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3197" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:34 GMT" ], "Etag": [ "CPW+6cnx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uoc-8JwtQprLtec5Ft6q3z4p0ooDaCCLmO9oVgrOXvBpoFhApztj8anfFwEcHdzpB6FBlUFqou0viF_HLHJvHolsxeCCoDOhqyIggOOlWjnSRg8XzY" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb250ZW50LzE1NTY4MzU4NzM3NDI3MDkiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jb250ZW50IiwibmFtZSI6ImNvbnRlbnQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3Mzc0MjcwOSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9odG1sIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjMzLjc0MloiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDozMy43NDJaIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MzMuNzQyWiIsInNpemUiOiI1NCIsIm1kNUhhc2giOiJOOHA4L3M5RndkQUFubHZyL2xFQWpRPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY29udGVudD9nZW5lcmF0aW9uPTE1NTY4MzU4NzM3NDI3MDkmYWx0PW1lZGlhIiwiY2FjaGVDb250cm9sIjoicHVibGljLCBtYXgtYWdlPTYwIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY29udGVudC8xNTU2ODM1ODczNzQyNzA5L3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2NvbnRlbnQvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImNvbnRlbnQiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3Mzc0MjcwOSIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDUFcrNmNueC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY29udGVudC8xNTU2ODM1ODczNzQyNzA5L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jb250ZW50L2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY29udGVudCIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODczNzQyNzA5IiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ1BXKzZjbngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NvbnRlbnQvMTU1NjgzNTg3Mzc0MjcwOS9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY29udGVudC9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImNvbnRlbnQiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3Mzc0MjcwOSIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDUFcrNmNueC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY29udGVudC8xNTU2ODM1ODczNzQyNzA5L3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jb250ZW50L2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY29udGVudCIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODczNzQyNzA5IiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ1BXKzZjbngvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJHb1Vic1E9PSIsImV0YWciOiJDUFcrNmNueC9lRUNFQUU9In0=" } }, { "ID": "b4c8dedc10a69e07", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJjb250ZW50VHlwZSI6ImltYWdlL2pwZWciLCJuYW1lIjoiY29udGVudCJ9Cg==", "PGh0bWw+PGhlYWQ+PHRpdGxlPk15IGZpcnN0IHBhZ2U8L3RpdGxlPjwvaGVhZD48L2h0bWw+" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3198" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:34 GMT" ], "Etag": [ "CM/Yjsrx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpC3UBVkNENjfRoaL2M1fPRh-iTDTwCsgF8O3TOX_iBuXcDxMjOoTmrIhD4cE5g1s7PObP66TZB1lecFypnLz8hL-aowsOxUMuL0KXJvrgoGxKHUFg" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb250ZW50LzE1NTY4MzU4NzQzNTIyMDciLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jb250ZW50IiwibmFtZSI6ImNvbnRlbnQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3NDM1MjIwNyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoiaW1hZ2UvanBlZyIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDozNC4zNTFaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MzQuMzUxWiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjM0LjM1MVoiLCJzaXplIjoiNTQiLCJtZDVIYXNoIjoiTjhwOC9zOUZ3ZEFBbmx2ci9sRUFqUT09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2NvbnRlbnQ/Z2VuZXJhdGlvbj0xNTU2ODM1ODc0MzUyMjA3JmFsdD1tZWRpYSIsImNhY2hlQ29udHJvbCI6InB1YmxpYywgbWF4LWFnZT02MCIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NvbnRlbnQvMTU1NjgzNTg3NDM1MjIwNy9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jb250ZW50L2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJjb250ZW50IiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NzQzNTIyMDciLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ00vWWpzcngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NvbnRlbnQvMTU1NjgzNTg3NDM1MjIwNy9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY29udGVudC9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImNvbnRlbnQiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3NDM1MjIwNyIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNNL1lqc3J4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb250ZW50LzE1NTY4MzU4NzQzNTIyMDcvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2NvbnRlbnQvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJjb250ZW50IiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NzQzNTIyMDciLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ00vWWpzcngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NvbnRlbnQvMTU1NjgzNTg3NDM1MjIwNy91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY29udGVudC9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImNvbnRlbnQiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3NDM1MjIwNyIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNNL1lqc3J4L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoiR29VYnNRPT0iLCJldGFnIjoiQ00vWWpzcngvZUVDRUFFPSJ9" } }, { "ID": "c45640ec17230f64", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/content?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3198" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:34 GMT" ], "Etag": [ "CM/Yjsrx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrvqLsOaMe2H6Xh3MyDCOuHmLzU1fn_Zh6kHLkpTpn4EWj3nFkeROu1g-cABD151cTh8YmY798iEku-Q3TnZIMZ5mexmHiCJKdUhAolbSd9b_apMK8" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb250ZW50LzE1NTY4MzU4NzQzNTIyMDciLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jb250ZW50IiwibmFtZSI6ImNvbnRlbnQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3NDM1MjIwNyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoiaW1hZ2UvanBlZyIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDozNC4zNTFaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MzQuMzUxWiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjM0LjM1MVoiLCJzaXplIjoiNTQiLCJtZDVIYXNoIjoiTjhwOC9zOUZ3ZEFBbmx2ci9sRUFqUT09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2NvbnRlbnQ/Z2VuZXJhdGlvbj0xNTU2ODM1ODc0MzUyMjA3JmFsdD1tZWRpYSIsImNhY2hlQ29udHJvbCI6InB1YmxpYywgbWF4LWFnZT02MCIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NvbnRlbnQvMTU1NjgzNTg3NDM1MjIwNy9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jb250ZW50L2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJjb250ZW50IiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NzQzNTIyMDciLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ00vWWpzcngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NvbnRlbnQvMTU1NjgzNTg3NDM1MjIwNy9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY29udGVudC9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImNvbnRlbnQiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3NDM1MjIwNyIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNNL1lqc3J4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb250ZW50LzE1NTY4MzU4NzQzNTIyMDcvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2NvbnRlbnQvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJjb250ZW50IiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NzQzNTIyMDciLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ00vWWpzcngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NvbnRlbnQvMTU1NjgzNTg3NDM1MjIwNy91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY29udGVudC9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImNvbnRlbnQiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3NDM1MjIwNyIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNNL1lqc3J4L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoiR29VYnNRPT0iLCJldGFnIjoiQ00vWWpzcngvZUVDRUFFPSJ9" } }, { "ID": "752ab630b062d61e", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ], "X-Goog-Encryption-Algorithm": [ "AES256" ], "X-Goog-Encryption-Key": [ "CLEARED" ], "X-Goog-Encryption-Key-Sha256": [ "H+LmnXhRoeI6TMW5bsV6HyUk6pyGc2IMbqYbAXBcps0=" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJuYW1lIjoiY3VzdG9tZXItZW5jcnlwdGlvbiJ9Cg==", "dG9wIHNlY3JldC4=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3482" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:35 GMT" ], "Etag": [ "CPjnucrx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpaWw6jJMKNOoCNMXwJNVVsxqzPhGfMo-5g3krJ7A8_PSGTx4W2OakfmtDvzOpg1hexLJcsWunNHfyWVXsjBpM58dtQlM6VucQW4Uxndlb9RIp0UhM" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLzE1NTY4MzU4NzUwNTg2ODAiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jdXN0b21lci1lbmNyeXB0aW9uIiwibmFtZSI6ImN1c3RvbWVyLWVuY3J5cHRpb24iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3NTA1ODY4MCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDozNS4wNThaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MzUuMDU4WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjM1LjA1OFoiLCJzaXplIjoiMTEiLCJtZDVIYXNoIjoieHdXTkZhMFZkWFBtbEF3cmxjQUpjZz09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2N1c3RvbWVyLWVuY3J5cHRpb24/Z2VuZXJhdGlvbj0xNTU2ODM1ODc1MDU4NjgwJmFsdD1tZWRpYSIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2N1c3RvbWVyLWVuY3J5cHRpb24vMTU1NjgzNTg3NTA1ODY4MC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jdXN0b21lci1lbmNyeXB0aW9uL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJjdXN0b21lci1lbmNyeXB0aW9uIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NzUwNTg2ODAiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ1BqbnVjcngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2N1c3RvbWVyLWVuY3J5cHRpb24vMTU1NjgzNTg3NTA1ODY4MC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY3VzdG9tZXItZW5jcnlwdGlvbi9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImN1c3RvbWVyLWVuY3J5cHRpb24iLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3NTA1ODY4MCIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNQam51Y3J4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLzE1NTY4MzU4NzUwNTg2ODAvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2N1c3RvbWVyLWVuY3J5cHRpb24vYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJjdXN0b21lci1lbmNyeXB0aW9uIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NzUwNTg2ODAiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ1BqbnVjcngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2N1c3RvbWVyLWVuY3J5cHRpb24vMTU1NjgzNTg3NTA1ODY4MC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY3VzdG9tZXItZW5jcnlwdGlvbi9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImN1c3RvbWVyLWVuY3J5cHRpb24iLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3NTA1ODY4MCIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNQam51Y3J4L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoicjBOR3JnPT0iLCJldGFnIjoiQ1BqbnVjcngvZUVDRUFFPSIsImN1c3RvbWVyRW5jcnlwdGlvbiI6eyJlbmNyeXB0aW9uQWxnb3JpdGhtIjoiQUVTMjU2Iiwia2V5U2hhMjU2IjoiSCtMbW5YaFJvZUk2VE1XNWJzVjZIeVVrNnB5R2MySU1icVliQVhCY3BzMD0ifX0=" } }, { "ID": "3f4d8fd0e94ca6de", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/customer-encryption?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3425" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:35 GMT" ], "Etag": [ "CPjnucrx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoO-NbHUptMgzQPx9zApWGCeqMgfkk2mt6PJl1iWbq8ocUYq_0ud8gPuj9bcBTBOBdqewKzSouddziC-BFLoOdQJ6ElkN136q5y39ZRDN4zq6UWLUs" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLzE1NTY4MzU4NzUwNTg2ODAiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jdXN0b21lci1lbmNyeXB0aW9uIiwibmFtZSI6ImN1c3RvbWVyLWVuY3J5cHRpb24iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3NTA1ODY4MCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDozNS4wNThaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MzUuMDU4WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjM1LjA1OFoiLCJzaXplIjoiMTEiLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY3VzdG9tZXItZW5jcnlwdGlvbj9nZW5lcmF0aW9uPTE1NTY4MzU4NzUwNTg2ODAmYWx0PW1lZGlhIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY3VzdG9tZXItZW5jcnlwdGlvbi8xNTU2ODM1ODc1MDU4NjgwL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2N1c3RvbWVyLWVuY3J5cHRpb24vYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImN1c3RvbWVyLWVuY3J5cHRpb24iLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3NTA1ODY4MCIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDUGpudWNyeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY3VzdG9tZXItZW5jcnlwdGlvbi8xNTU2ODM1ODc1MDU4NjgwL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jdXN0b21lci1lbmNyeXB0aW9uL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY3VzdG9tZXItZW5jcnlwdGlvbiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODc1MDU4NjgwIiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ1BqbnVjcngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2N1c3RvbWVyLWVuY3J5cHRpb24vMTU1NjgzNTg3NTA1ODY4MC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY3VzdG9tZXItZW5jcnlwdGlvbi9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImN1c3RvbWVyLWVuY3J5cHRpb24iLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3NTA1ODY4MCIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDUGpudWNyeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY3VzdG9tZXItZW5jcnlwdGlvbi8xNTU2ODM1ODc1MDU4NjgwL3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jdXN0b21lci1lbmNyeXB0aW9uL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY3VzdG9tZXItZW5jcnlwdGlvbiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODc1MDU4NjgwIiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ1BqbnVjcngvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJldGFnIjoiQ1BqbnVjcngvZUVDRUFFPSIsImN1c3RvbWVyRW5jcnlwdGlvbiI6eyJlbmNyeXB0aW9uQWxnb3JpdGhtIjoiQUVTMjU2Iiwia2V5U2hhMjU2IjoiSCtMbW5YaFJvZUk2VE1XNWJzVjZIeVVrNnB5R2MySU1icVliQVhCY3BzMD0ifX0=" } }, { "ID": "0355971107342253", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/customer-encryption?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ], "X-Goog-Encryption-Algorithm": [ "AES256" ], "X-Goog-Encryption-Key": [ "CLEARED" ], "X-Goog-Encryption-Key-Sha256": [ "H+LmnXhRoeI6TMW5bsV6HyUk6pyGc2IMbqYbAXBcps0=" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3482" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:35 GMT" ], "Etag": [ "CPjnucrx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UryZM2k28xNlFIDnXCH6SJ8RA2lDVNIx-5_eYRExB4-D1-dg_3fWvU3AREwoow4DvlYN4eyzA1AthWs5y0tYZEzvamBoZufkrXPmD64aT8kzAatns8" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLzE1NTY4MzU4NzUwNTg2ODAiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jdXN0b21lci1lbmNyeXB0aW9uIiwibmFtZSI6ImN1c3RvbWVyLWVuY3J5cHRpb24iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3NTA1ODY4MCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDozNS4wNThaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MzUuMDU4WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjM1LjA1OFoiLCJzaXplIjoiMTEiLCJtZDVIYXNoIjoieHdXTkZhMFZkWFBtbEF3cmxjQUpjZz09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2N1c3RvbWVyLWVuY3J5cHRpb24/Z2VuZXJhdGlvbj0xNTU2ODM1ODc1MDU4NjgwJmFsdD1tZWRpYSIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2N1c3RvbWVyLWVuY3J5cHRpb24vMTU1NjgzNTg3NTA1ODY4MC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jdXN0b21lci1lbmNyeXB0aW9uL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJjdXN0b21lci1lbmNyeXB0aW9uIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NzUwNTg2ODAiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ1BqbnVjcngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2N1c3RvbWVyLWVuY3J5cHRpb24vMTU1NjgzNTg3NTA1ODY4MC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY3VzdG9tZXItZW5jcnlwdGlvbi9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImN1c3RvbWVyLWVuY3J5cHRpb24iLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3NTA1ODY4MCIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNQam51Y3J4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLzE1NTY4MzU4NzUwNTg2ODAvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2N1c3RvbWVyLWVuY3J5cHRpb24vYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJjdXN0b21lci1lbmNyeXB0aW9uIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NzUwNTg2ODAiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ1BqbnVjcngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2N1c3RvbWVyLWVuY3J5cHRpb24vMTU1NjgzNTg3NTA1ODY4MC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY3VzdG9tZXItZW5jcnlwdGlvbi9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImN1c3RvbWVyLWVuY3J5cHRpb24iLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3NTA1ODY4MCIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNQam51Y3J4L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoicjBOR3JnPT0iLCJldGFnIjoiQ1BqbnVjcngvZUVDRUFFPSIsImN1c3RvbWVyRW5jcnlwdGlvbiI6eyJlbmNyeXB0aW9uQWxnb3JpdGhtIjoiQUVTMjU2Iiwia2V5U2hhMjU2IjoiSCtMbW5YaFJvZUk2VE1XNWJzVjZIeVVrNnB5R2MySU1icVliQVhCY3BzMD0ifX0=" } }, { "ID": "8f8c7cba5307c918", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/customer-encryption?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "85" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJjb250ZW50TGFuZ3VhZ2UiOiJlbiJ9Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3448" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:36 GMT" ], "Etag": [ "CPjnucrx/eECEAI=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Upnljw7UWMuKFeJUJp_gu-lyfzDRVTwgInddze_9zF5waX4glKKpcRrGpe50cvS8dV_xbbKLQa-CqAMVxlEp7qIHsmTdUR1amjrq0w9U_qrn4gYwSw" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLzE1NTY4MzU4NzUwNTg2ODAiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jdXN0b21lci1lbmNyeXB0aW9uIiwibmFtZSI6ImN1c3RvbWVyLWVuY3J5cHRpb24iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3NTA1ODY4MCIsIm1ldGFnZW5lcmF0aW9uIjoiMiIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDozNS4wNThaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MzUuOTIwWiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjM1LjA1OFoiLCJzaXplIjoiMTEiLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY3VzdG9tZXItZW5jcnlwdGlvbj9nZW5lcmF0aW9uPTE1NTY4MzU4NzUwNTg2ODAmYWx0PW1lZGlhIiwiY29udGVudExhbmd1YWdlIjoiZW4iLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLzE1NTY4MzU4NzUwNTg2ODAvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY3VzdG9tZXItZW5jcnlwdGlvbi9hY2wvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY3VzdG9tZXItZW5jcnlwdGlvbiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODc1MDU4NjgwIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNQam51Y3J4L2VFQ0VBST0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLzE1NTY4MzU4NzUwNTg2ODAvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2N1c3RvbWVyLWVuY3J5cHRpb24vYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJjdXN0b21lci1lbmNyeXB0aW9uIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NzUwNTg2ODAiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDUGpudWNyeC9lRUNFQUk9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY3VzdG9tZXItZW5jcnlwdGlvbi8xNTU2ODM1ODc1MDU4NjgwL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jdXN0b21lci1lbmNyeXB0aW9uL2FjbC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY3VzdG9tZXItZW5jcnlwdGlvbiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODc1MDU4NjgwIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNQam51Y3J4L2VFQ0VBST0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLzE1NTY4MzU4NzUwNTg2ODAvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2N1c3RvbWVyLWVuY3J5cHRpb24vYWNsL3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJjdXN0b21lci1lbmNyeXB0aW9uIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NzUwNTg2ODAiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDUGpudWNyeC9lRUNFQUk9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImV0YWciOiJDUGpudWNyeC9lRUNFQUk9IiwiY3VzdG9tZXJFbmNyeXB0aW9uIjp7ImVuY3J5cHRpb25BbGdvcml0aG0iOiJBRVMyNTYiLCJrZXlTaGEyNTYiOiJIK0xtblhoUm9lSTZUTVc1YnNWNkh5VWs2cHlHYzJJTWJxWWJBWEJjcHMwPSJ9fQ==" } }, { "ID": "fc766ddbbfcd9d8a", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/customer-encryption?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "85" ], "User-Agent": [ "google-api-go-client/0.5" ], "X-Goog-Encryption-Algorithm": [ "AES256" ], "X-Goog-Encryption-Key": [ "CLEARED" ], "X-Goog-Encryption-Key-Sha256": [ "H+LmnXhRoeI6TMW5bsV6HyUk6pyGc2IMbqYbAXBcps0=" ] }, "MediaType": "application/json", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJjb250ZW50TGFuZ3VhZ2UiOiJlbiJ9Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3505" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:36 GMT" ], "Etag": [ "CPjnucrx/eECEAM=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqlTuEeQHkdcuHKu_aWtuYjopXaORKyG9TF597i1ybzIPgJHE_oiKH-xYwG_D2txhF_Sv6Jzfy44Dfga1bINCpPLseDEeD_Ez4rvxx8baTX1uJ7lJo" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLzE1NTY4MzU4NzUwNTg2ODAiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jdXN0b21lci1lbmNyeXB0aW9uIiwibmFtZSI6ImN1c3RvbWVyLWVuY3J5cHRpb24iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3NTA1ODY4MCIsIm1ldGFnZW5lcmF0aW9uIjoiMyIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDozNS4wNThaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MzYuMjI1WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjM1LjA1OFoiLCJzaXplIjoiMTEiLCJtZDVIYXNoIjoieHdXTkZhMFZkWFBtbEF3cmxjQUpjZz09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2N1c3RvbWVyLWVuY3J5cHRpb24/Z2VuZXJhdGlvbj0xNTU2ODM1ODc1MDU4NjgwJmFsdD1tZWRpYSIsImNvbnRlbnRMYW5ndWFnZSI6ImVuIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY3VzdG9tZXItZW5jcnlwdGlvbi8xNTU2ODM1ODc1MDU4NjgwL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2N1c3RvbWVyLWVuY3J5cHRpb24vYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImN1c3RvbWVyLWVuY3J5cHRpb24iLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3NTA1ODY4MCIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDUGpudWNyeC9lRUNFQU09In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY3VzdG9tZXItZW5jcnlwdGlvbi8xNTU2ODM1ODc1MDU4NjgwL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jdXN0b21lci1lbmNyeXB0aW9uL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY3VzdG9tZXItZW5jcnlwdGlvbiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODc1MDU4NjgwIiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ1BqbnVjcngvZUVDRUFNPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2N1c3RvbWVyLWVuY3J5cHRpb24vMTU1NjgzNTg3NTA1ODY4MC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY3VzdG9tZXItZW5jcnlwdGlvbi9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImN1c3RvbWVyLWVuY3J5cHRpb24iLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3NTA1ODY4MCIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDUGpudWNyeC9lRUNFQU09In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY3VzdG9tZXItZW5jcnlwdGlvbi8xNTU2ODM1ODc1MDU4NjgwL3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jdXN0b21lci1lbmNyeXB0aW9uL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY3VzdG9tZXItZW5jcnlwdGlvbiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODc1MDU4NjgwIiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ1BqbnVjcngvZUVDRUFNPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJyME5Hcmc9PSIsImV0YWciOiJDUGpudWNyeC9lRUNFQU09IiwiY3VzdG9tZXJFbmNyeXB0aW9uIjp7ImVuY3J5cHRpb25BbGdvcml0aG0iOiJBRVMyNTYiLCJrZXlTaGEyNTYiOiJIK0xtblhoUm9lSTZUTVc1YnNWNkh5VWs2cHlHYzJJTWJxWWJBWEJjcHMwPSJ9fQ==" } }, { "ID": "fb1e502029272329", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/go-integration-test-20190502-80633403432013-0001/customer-encryption", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "277" ], "Content-Type": [ "application/xml; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:36 GMT" ], "Expires": [ "Thu, 02 May 2019 22:24:36 GMT" ], "Server": [ "UploadServer" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2Urm5pF1ghApp-RiVg_TAipd-LdTbF-hcDPcVRYbmj7KUIQxnsMUF5WOcrMA1t7ZltdvPZhyfsELISuH6DGJlUUedaCNH-B5j580GjBYLUKCwmAADeM" ] }, "Body": "PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48RXJyb3I+PENvZGU+UmVzb3VyY2VJc0VuY3J5cHRlZFdpdGhDdXN0b21lckVuY3J5cHRpb25LZXk8L0NvZGU+PE1lc3NhZ2U+VGhlIHJlc291cmNlIGlzIGVuY3J5cHRlZCB3aXRoIGEgY3VzdG9tZXIgZW5jcnlwdGlvbiBrZXkuPC9NZXNzYWdlPjxEZXRhaWxzPlRoZSByZXF1ZXN0ZWQgb2JqZWN0IGlzIGVuY3J5cHRlZCBieSBhIGN1c3RvbWVyLXN1cHBsaWVkIGVuY3J5cHRpb24ga2V5LjwvRGV0YWlscz48L0Vycm9yPg==" } }, { "ID": "c151ba4fab0c6499", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/go-integration-test-20190502-80633403432013-0001/customer-encryption", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "Go-http-client/1.1" ], "X-Goog-Encryption-Algorithm": [ "AES256" ], "X-Goog-Encryption-Key": [ "CLEARED" ], "X-Goog-Encryption-Key-Sha256": [ "H+LmnXhRoeI6TMW5bsV6HyUk6pyGc2IMbqYbAXBcps0=" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Language": [ "en" ], "Content-Length": [ "11" ], "Content-Type": [ "text/plain; charset=utf-8" ], "Date": [ "Thu, 02 May 2019 22:24:36 GMT" ], "Etag": [ "\"-CPjnucrx/eECEAM=\"" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Last-Modified": [ "Thu, 02 May 2019 22:24:35 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "X-Goog-Encryption-Algorithm": [ "AES256" ], "X-Goog-Encryption-Key-Sha256": [ "H+LmnXhRoeI6TMW5bsV6HyUk6pyGc2IMbqYbAXBcps0=" ], "X-Goog-Expiration": [ "Sat, 01 Jun 2019 22:24:35 GMT" ], "X-Goog-Generation": [ "1556835875058680" ], "X-Goog-Hash": [ "crc32c=r0NGrg==", "md5=xwWNFa0VdXPmlAwrlcAJcg==" ], "X-Goog-Metageneration": [ "3" ], "X-Goog-Storage-Class": [ "STANDARD" ], "X-Goog-Stored-Content-Encoding": [ "identity" ], "X-Goog-Stored-Content-Length": [ "11" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Ur68mIGQ8VAtTRZs4F6ixZZYKcqe1oTqWHWqmp7gNF-81XKf2xX6eS4PcegbKx7bYnb4i6dzTCoLlbaJRNHwwLVzNbYMkGNy_bTHbWYTgtlBSKVtWs" ] }, "Body": "dG9wIHNlY3JldC4=" } }, { "ID": "e09c6326cc60ad82", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/customer-encryption/rewriteTo/b/go-integration-test-20190502-80633403432013-0001/o/customer-encryption-2?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "3" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "e30K" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Content-Length": [ "12563" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:36 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UqldLQvGKuu2fihIdwh7CvU7W0yE3vUXu8jqefTPSMhlGgvR1EfeYFqjk_Zxj7fEpv7AjugvHnn1DmkJxJWhrZyM8b5gS4uJID92D_018h2YHH1r30" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6InJlc291cmNlSXNFbmNyeXB0ZWRXaXRoQ3VzdG9tZXJFbmNyeXB0aW9uS2V5IiwibWVzc2FnZSI6IlRoZSB0YXJnZXQgb2JqZWN0IGlzIGVuY3J5cHRlZCBieSBhIGN1c3RvbWVyLXN1cHBsaWVkIGVuY3J5cHRpb24ga2V5LiIsImV4dGVuZGVkSGVscCI6Imh0dHBzOi8vY2xvdWQuZ29vZ2xlLmNvbS9zdG9yYWdlL2RvY3MvZW5jcnlwdGlvbiNjdXN0b21lci1zdXBwbGllZF9lbmNyeXB0aW9uX2tleXMiLCJkZWJ1Z0luZm8iOiJjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6UkVTT1VSQ0VfSVNfRU5DUllQVEVEX1dJVEhfQ1VTVE9NRVJfRU5DUllQVElPTl9LRVlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuUmV3cml0ZU9iamVjdC5yZXdyaXRlKFJld3JpdGVPYmplY3QuamF2YToyMDApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5SZXdyaXRlT2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXdyaXRlT2JqZWN0LmphdmE6MTkzKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuUmV3cml0ZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmV3cml0ZU9iamVjdC5qYXZhOjQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLnJld3JpdGUoT2JqZWN0c0RlbGVnYXRvci5qYXZhOjEyMSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE4IG1vcmVcblxuY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPUlOVkFMSURfVkFMVUUsIGNhdGVnb3J5PVVTRVJfRVJST1IsIGNhdXNlPW51bGwsIGRlYnVnSW5mbz1jb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6UkVTT1VSQ0VfSVNfRU5DUllQVEVEX1dJVEhfQ1VTVE9NRVJfRU5DUllQVElPTl9LRVlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuUmV3cml0ZU9iamVjdC5yZXdyaXRlKFJld3JpdGVPYmplY3QuamF2YToyMDApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5SZXdyaXRlT2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXdyaXRlT2JqZWN0LmphdmE6MTkzKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuUmV3cml0ZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmV3cml0ZU9iamVjdC5qYXZhOjQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLnJld3JpdGUoT2JqZWN0c0RlbGVnYXRvci5qYXZhOjEyMSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE4IG1vcmVcbiwgZG9tYWluPWdsb2JhbCwgZXh0ZW5kZWRIZWxwPWh0dHBzOi8vY2xvdWQuZ29vZ2xlLmNvbS9zdG9yYWdlL2RvY3MvZW5jcnlwdGlvbiNjdXN0b21lci1zdXBwbGllZF9lbmNyeXB0aW9uX2tleXMsIGh0dHBIZWFkZXJzPXt9LCBodHRwU3RhdHVzPWJhZFJlcXVlc3QsIGludGVybmFsUmVhc29uPVJlYXNvbnthcmd1bWVudHM9e30sIGNhdXNlPW51bGwsIGNvZGU9Y2xvdWQuYmlnc3RvcmUuYXBpLkJpZ3N0b3JlRXJyb3JEb21haW4uUkVTT1VSQ0VfSVNfRU5DUllQVEVEX1dJVEhfQ1VTVE9NRVJfRU5DUllQVElPTl9LRVksIGNyZWF0ZWRCeUJhY2tlbmQ9dHJ1ZSwgZGVidWdNZXNzYWdlPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpSRVNPVVJDRV9JU19FTkNSWVBURURfV0lUSF9DVVNUT01FUl9FTkNSWVBUSU9OX0tFWVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5SZXdyaXRlT2JqZWN0LnJld3JpdGUoUmV3cml0ZU9iamVjdC5qYXZhOjIwMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLlJld3JpdGVPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJld3JpdGVPYmplY3QuamF2YToxOTMpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5SZXdyaXRlT2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXdyaXRlT2JqZWN0LmphdmE6NDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLk9iamVjdHNEZWxlZ2F0b3IucmV3cml0ZShPYmplY3RzRGVsZWdhdG9yLmphdmE6MTIxKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTggbW9yZVxuLCBlcnJvclByb3RvQ29kZT1SRVNPVVJDRV9JU19FTkNSWVBURURfV0lUSF9DVVNUT01FUl9FTkNSWVBUSU9OX0tFWSwgZXJyb3JQcm90b0RvbWFpbj1jbG91ZC5iaWdzdG9yZS5hcGkuQmlnc3RvcmVFcnJvckRvbWFpbiwgZmlsdGVyZWRNZXNzYWdlPW51bGwsIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9VGhlIHJlcXVlc3RlZCBvYmplY3QgaXMgZW5jcnlwdGVkIGJ5IGEgY3VzdG9tZXItc3VwcGxpZWQgZW5jcnlwdGlvbiBrZXkuLCB1bm5hbWVkQXJndW1lbnRzPVtdfSwgbG9jYXRpb249bnVsbCwgbWVzc2FnZT1UaGUgdGFyZ2V0IG9iamVjdCBpcyBlbmNyeXB0ZWQgYnkgYSBjdXN0b21lci1zdXBwbGllZCBlbmNyeXB0aW9uIGtleS4sIHJlYXNvbj1yZXNvdXJjZUlzRW5jcnlwdGVkV2l0aEN1c3RvbWVyRW5jcnlwdGlvbktleSwgcnBjQ29kZT00MDB9IFRoZSB0YXJnZXQgb2JqZWN0IGlzIGVuY3J5cHRlZCBieSBhIGN1c3RvbWVyLXN1cHBsaWVkIGVuY3J5cHRpb24ga2V5LjogY29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlJFU09VUkNFX0lTX0VOQ1JZUFRFRF9XSVRIX0NVU1RPTUVSX0VOQ1JZUFRJT05fS0VZXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLlJld3JpdGVPYmplY3QucmV3cml0ZShSZXdyaXRlT2JqZWN0LmphdmE6MjAwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuUmV3cml0ZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmV3cml0ZU9iamVjdC5qYXZhOjE5Mylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLlJld3JpdGVPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJld3JpdGVPYmplY3QuamF2YTo0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uT2JqZWN0c0RlbGVnYXRvci5yZXdyaXRlKE9iamVjdHNEZWxlZ2F0b3IuamF2YToxMjEpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IFxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxOCBtb3JlXG5cblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRXJyb3JDb2xsZWN0b3IudG9GYXVsdChFcnJvckNvbGxlY3Rvci5qYXZhOjU0KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUVycm9yQ29udmVydGVyLnRvRmF1bHQoUm9zeUVycm9yQ29udmVydGVyLmphdmE6NjcpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyNTkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyMzkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci50aHJlYWQuVGhyZWFkVHJhY2tlcnMkVGhyZWFkVHJhY2tpbmdSdW5uYWJsZS5ydW4oVGhyZWFkVHJhY2tlcnMuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjQ1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnNlcnZlci5Db21tb25Nb2R1bGUkQ29udGV4dENhcnJ5aW5nRXhlY3V0b3JTZXJ2aWNlJDEucnVuSW5Db250ZXh0KENvbW1vbk1vZHVsZS5qYXZhOjgwMilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZSQxLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NjApXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoVHJhY2VDb250ZXh0LmphdmE6MzE5KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjMxMSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDU3KVxuXHRhdCBjb20uZ29vZ2xlLmdzZS5pbnRlcm5hbC5EaXNwYXRjaFF1ZXVlSW1wbCRXb3JrZXJUaHJlYWQucnVuKERpc3BhdGNoUXVldWVJbXBsLmphdmE6NDAzKVxuIn1dLCJjb2RlIjo0MDAsIm1lc3NhZ2UiOiJUaGUgdGFyZ2V0IG9iamVjdCBpcyBlbmNyeXB0ZWQgYnkgYSBjdXN0b21lci1zdXBwbGllZCBlbmNyeXB0aW9uIGtleS4ifX0=" } }, { "ID": "6c83b36cc6fc482c", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/customer-encryption/rewriteTo/b/go-integration-test-20190502-80633403432013-0001/o/customer-encryption-2?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "3" ], "User-Agent": [ "google-api-go-client/0.5" ], "X-Goog-Copy-Source-Encryption-Algorithm": [ "AES256" ], "X-Goog-Copy-Source-Encryption-Key": [ "CLEARED" ], "X-Goog-Copy-Source-Encryption-Key-Sha256": [ "H+LmnXhRoeI6TMW5bsV6HyUk6pyGc2IMbqYbAXBcps0=" ] }, "MediaType": "application/json", "BodyParts": [ "e30K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3527" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:37 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqGOUzu40Jq-_GztkQxoFN64MHcSoZjph7ivV8tqrp6ENxFIB0c82xqEdKKfcpqbJ2YXtXQgwflZgX-uiVOgGY_1c8SLoV7geQMfErTz1Q0NDM4YDM" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNyZXdyaXRlUmVzcG9uc2UiLCJ0b3RhbEJ5dGVzUmV3cml0dGVuIjoiMTEiLCJvYmplY3RTaXplIjoiMTEiLCJkb25lIjp0cnVlLCJyZXNvdXJjZSI6eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLTIvMTU1NjgzNTg3NzEwODYxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2N1c3RvbWVyLWVuY3J5cHRpb24tMiIsIm5hbWUiOiJjdXN0b21lci1lbmNyeXB0aW9uLTIiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3NzEwODYxNCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDozNy4xMDhaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MzcuMTA4WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjM3LjEwOFoiLCJzaXplIjoiMTEiLCJtZDVIYXNoIjoieHdXTkZhMFZkWFBtbEF3cmxjQUpjZz09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2N1c3RvbWVyLWVuY3J5cHRpb24tMj9nZW5lcmF0aW9uPTE1NTY4MzU4NzcxMDg2MTQmYWx0PW1lZGlhIiwiY29udGVudExhbmd1YWdlIjoiZW4iLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLTIvMTU1NjgzNTg3NzEwODYxNC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jdXN0b21lci1lbmNyeXB0aW9uLTIvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImN1c3RvbWVyLWVuY3J5cHRpb24tMiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODc3MTA4NjE0IiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNJYjN0c3Z4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLTIvMTU1NjgzNTg3NzEwODYxNC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY3VzdG9tZXItZW5jcnlwdGlvbi0yL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY3VzdG9tZXItZW5jcnlwdGlvbi0yIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NzcxMDg2MTQiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDSWIzdHN2eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY3VzdG9tZXItZW5jcnlwdGlvbi0yLzE1NTY4MzU4NzcxMDg2MTQvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2N1c3RvbWVyLWVuY3J5cHRpb24tMi9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImN1c3RvbWVyLWVuY3J5cHRpb24tMiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODc3MTA4NjE0IiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNJYjN0c3Z4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLTIvMTU1NjgzNTg3NzEwODYxNC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY3VzdG9tZXItZW5jcnlwdGlvbi0yL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY3VzdG9tZXItZW5jcnlwdGlvbi0yIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NzcxMDg2MTQiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDSWIzdHN2eC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6InIwTkdyZz09IiwiZXRhZyI6IkNJYjN0c3Z4L2VFQ0VBRT0ifX0=" } }, { "ID": "e499f3b7077fb222", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/go-integration-test-20190502-80633403432013-0001/customer-encryption-2", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Language": [ "en" ], "Content-Length": [ "11" ], "Content-Type": [ "text/plain; charset=utf-8" ], "Date": [ "Thu, 02 May 2019 22:24:37 GMT" ], "Etag": [ "\"c7058d15ad157573e6940c2b95c00972\"" ], "Expires": [ "Thu, 02 May 2019 22:24:37 GMT" ], "Last-Modified": [ "Thu, 02 May 2019 22:24:37 GMT" ], "Server": [ "UploadServer" ], "X-Goog-Expiration": [ "Sat, 01 Jun 2019 22:24:37 GMT" ], "X-Goog-Generation": [ "1556835877108614" ], "X-Goog-Hash": [ "crc32c=r0NGrg==", "md5=xwWNFa0VdXPmlAwrlcAJcg==" ], "X-Goog-Metageneration": [ "1" ], "X-Goog-Storage-Class": [ "STANDARD" ], "X-Goog-Stored-Content-Encoding": [ "identity" ], "X-Goog-Stored-Content-Length": [ "11" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpfEf1WUM8E5dSmOe1sOfgheagnlrcFUolvMMBiP6jDvPqoS7Sx0IwklM-DwnuAbBJPQ_EHhX-42njQu9vUjXqamH1U6np0Vmi0BngqFYOTc9MVP3M" ] }, "Body": "dG9wIHNlY3JldC4=" } }, { "ID": "9e67dfa901c4e619", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/customer-encryption/rewriteTo/b/go-integration-test-20190502-80633403432013-0001/o/customer-encryption-2?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "3" ], "User-Agent": [ "google-api-go-client/0.5" ], "X-Goog-Encryption-Algorithm": [ "AES256" ], "X-Goog-Encryption-Key": [ "CLEARED" ], "X-Goog-Encryption-Key-Sha256": [ "FnBvfQ1dDsyS8kHD+aB6HHIglDoQ5Im7WYDm3XYTGrQ=" ] }, "MediaType": "application/json", "BodyParts": [ "e30K" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Content-Length": [ "12563" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:37 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UoYPZ-j39Sr1Whn6F3PYeVaxqIIjS_fBgSNkBO7f7B8RMWih6iCCLf1cPDXB3Br-0XBkdm6i9N9fGeK84_laVYWuJc0uJwSCXydk0bSWezw0qec5yE" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6InJlc291cmNlSXNFbmNyeXB0ZWRXaXRoQ3VzdG9tZXJFbmNyeXB0aW9uS2V5IiwibWVzc2FnZSI6IlRoZSB0YXJnZXQgb2JqZWN0IGlzIGVuY3J5cHRlZCBieSBhIGN1c3RvbWVyLXN1cHBsaWVkIGVuY3J5cHRpb24ga2V5LiIsImV4dGVuZGVkSGVscCI6Imh0dHBzOi8vY2xvdWQuZ29vZ2xlLmNvbS9zdG9yYWdlL2RvY3MvZW5jcnlwdGlvbiNjdXN0b21lci1zdXBwbGllZF9lbmNyeXB0aW9uX2tleXMiLCJkZWJ1Z0luZm8iOiJjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6UkVTT1VSQ0VfSVNfRU5DUllQVEVEX1dJVEhfQ1VTVE9NRVJfRU5DUllQVElPTl9LRVlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuUmV3cml0ZU9iamVjdC5yZXdyaXRlKFJld3JpdGVPYmplY3QuamF2YToyMDApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5SZXdyaXRlT2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXdyaXRlT2JqZWN0LmphdmE6MTkzKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuUmV3cml0ZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmV3cml0ZU9iamVjdC5qYXZhOjQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLnJld3JpdGUoT2JqZWN0c0RlbGVnYXRvci5qYXZhOjEyMSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE4IG1vcmVcblxuY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPUlOVkFMSURfVkFMVUUsIGNhdGVnb3J5PVVTRVJfRVJST1IsIGNhdXNlPW51bGwsIGRlYnVnSW5mbz1jb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6UkVTT1VSQ0VfSVNfRU5DUllQVEVEX1dJVEhfQ1VTVE9NRVJfRU5DUllQVElPTl9LRVlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuUmV3cml0ZU9iamVjdC5yZXdyaXRlKFJld3JpdGVPYmplY3QuamF2YToyMDApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5SZXdyaXRlT2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXdyaXRlT2JqZWN0LmphdmE6MTkzKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuUmV3cml0ZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmV3cml0ZU9iamVjdC5qYXZhOjQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLnJld3JpdGUoT2JqZWN0c0RlbGVnYXRvci5qYXZhOjEyMSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE4IG1vcmVcbiwgZG9tYWluPWdsb2JhbCwgZXh0ZW5kZWRIZWxwPWh0dHBzOi8vY2xvdWQuZ29vZ2xlLmNvbS9zdG9yYWdlL2RvY3MvZW5jcnlwdGlvbiNjdXN0b21lci1zdXBwbGllZF9lbmNyeXB0aW9uX2tleXMsIGh0dHBIZWFkZXJzPXt9LCBodHRwU3RhdHVzPWJhZFJlcXVlc3QsIGludGVybmFsUmVhc29uPVJlYXNvbnthcmd1bWVudHM9e30sIGNhdXNlPW51bGwsIGNvZGU9Y2xvdWQuYmlnc3RvcmUuYXBpLkJpZ3N0b3JlRXJyb3JEb21haW4uUkVTT1VSQ0VfSVNfRU5DUllQVEVEX1dJVEhfQ1VTVE9NRVJfRU5DUllQVElPTl9LRVksIGNyZWF0ZWRCeUJhY2tlbmQ9dHJ1ZSwgZGVidWdNZXNzYWdlPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpSRVNPVVJDRV9JU19FTkNSWVBURURfV0lUSF9DVVNUT01FUl9FTkNSWVBUSU9OX0tFWVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5SZXdyaXRlT2JqZWN0LnJld3JpdGUoUmV3cml0ZU9iamVjdC5qYXZhOjIwMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLlJld3JpdGVPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJld3JpdGVPYmplY3QuamF2YToxOTMpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5SZXdyaXRlT2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXdyaXRlT2JqZWN0LmphdmE6NDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLk9iamVjdHNEZWxlZ2F0b3IucmV3cml0ZShPYmplY3RzRGVsZWdhdG9yLmphdmE6MTIxKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTggbW9yZVxuLCBlcnJvclByb3RvQ29kZT1SRVNPVVJDRV9JU19FTkNSWVBURURfV0lUSF9DVVNUT01FUl9FTkNSWVBUSU9OX0tFWSwgZXJyb3JQcm90b0RvbWFpbj1jbG91ZC5iaWdzdG9yZS5hcGkuQmlnc3RvcmVFcnJvckRvbWFpbiwgZmlsdGVyZWRNZXNzYWdlPW51bGwsIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9VGhlIHJlcXVlc3RlZCBvYmplY3QgaXMgZW5jcnlwdGVkIGJ5IGEgY3VzdG9tZXItc3VwcGxpZWQgZW5jcnlwdGlvbiBrZXkuLCB1bm5hbWVkQXJndW1lbnRzPVtdfSwgbG9jYXRpb249bnVsbCwgbWVzc2FnZT1UaGUgdGFyZ2V0IG9iamVjdCBpcyBlbmNyeXB0ZWQgYnkgYSBjdXN0b21lci1zdXBwbGllZCBlbmNyeXB0aW9uIGtleS4sIHJlYXNvbj1yZXNvdXJjZUlzRW5jcnlwdGVkV2l0aEN1c3RvbWVyRW5jcnlwdGlvbktleSwgcnBjQ29kZT00MDB9IFRoZSB0YXJnZXQgb2JqZWN0IGlzIGVuY3J5cHRlZCBieSBhIGN1c3RvbWVyLXN1cHBsaWVkIGVuY3J5cHRpb24ga2V5LjogY29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlJFU09VUkNFX0lTX0VOQ1JZUFRFRF9XSVRIX0NVU1RPTUVSX0VOQ1JZUFRJT05fS0VZXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLlJld3JpdGVPYmplY3QucmV3cml0ZShSZXdyaXRlT2JqZWN0LmphdmE6MjAwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuUmV3cml0ZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmV3cml0ZU9iamVjdC5qYXZhOjE5Mylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLlJld3JpdGVPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJld3JpdGVPYmplY3QuamF2YTo0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uT2JqZWN0c0RlbGVnYXRvci5yZXdyaXRlKE9iamVjdHNEZWxlZ2F0b3IuamF2YToxMjEpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IFxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxOCBtb3JlXG5cblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRXJyb3JDb2xsZWN0b3IudG9GYXVsdChFcnJvckNvbGxlY3Rvci5qYXZhOjU0KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUVycm9yQ29udmVydGVyLnRvRmF1bHQoUm9zeUVycm9yQ29udmVydGVyLmphdmE6NjcpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyNTkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyMzkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci50aHJlYWQuVGhyZWFkVHJhY2tlcnMkVGhyZWFkVHJhY2tpbmdSdW5uYWJsZS5ydW4oVGhyZWFkVHJhY2tlcnMuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjQ1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnNlcnZlci5Db21tb25Nb2R1bGUkQ29udGV4dENhcnJ5aW5nRXhlY3V0b3JTZXJ2aWNlJDEucnVuSW5Db250ZXh0KENvbW1vbk1vZHVsZS5qYXZhOjgwMilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZSQxLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NjApXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoVHJhY2VDb250ZXh0LmphdmE6MzE5KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjMxMSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDU3KVxuXHRhdCBjb20uZ29vZ2xlLmdzZS5pbnRlcm5hbC5EaXNwYXRjaFF1ZXVlSW1wbCRXb3JrZXJUaHJlYWQucnVuKERpc3BhdGNoUXVldWVJbXBsLmphdmE6NDAzKVxuIn1dLCJjb2RlIjo0MDAsIm1lc3NhZ2UiOiJUaGUgdGFyZ2V0IG9iamVjdCBpcyBlbmNyeXB0ZWQgYnkgYSBjdXN0b21lci1zdXBwbGllZCBlbmNyeXB0aW9uIGtleS4ifX0=" } }, { "ID": "670f74ac2a0b734e", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/customer-encryption/rewriteTo/b/go-integration-test-20190502-80633403432013-0001/o/customer-encryption-2?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "3" ], "User-Agent": [ "google-api-go-client/0.5" ], "X-Goog-Copy-Source-Encryption-Algorithm": [ "AES256" ], "X-Goog-Copy-Source-Encryption-Key": [ "CLEARED" ], "X-Goog-Copy-Source-Encryption-Key-Sha256": [ "H+LmnXhRoeI6TMW5bsV6HyUk6pyGc2IMbqYbAXBcps0=" ], "X-Goog-Encryption-Algorithm": [ "AES256" ], "X-Goog-Encryption-Key": [ "CLEARED" ], "X-Goog-Encryption-Key-Sha256": [ "FnBvfQ1dDsyS8kHD+aB6HHIglDoQ5Im7WYDm3XYTGrQ=" ] }, "MediaType": "application/json", "BodyParts": [ "e30K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3640" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:38 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoWwxnT2DHS1ymBhZJmnwxQiajAVYbOH62dyhX86syLNW_TlPnzYaM_7kACpN8ar5EeAHQ9fsMSHP4CqMcb6ZWg5KY3OkbPvfitdLalAA9MXxMFqoo" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNyZXdyaXRlUmVzcG9uc2UiLCJ0b3RhbEJ5dGVzUmV3cml0dGVuIjoiMTEiLCJvYmplY3RTaXplIjoiMTEiLCJkb25lIjp0cnVlLCJyZXNvdXJjZSI6eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLTIvMTU1NjgzNTg3ODE4MzI1MSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2N1c3RvbWVyLWVuY3J5cHRpb24tMiIsIm5hbWUiOiJjdXN0b21lci1lbmNyeXB0aW9uLTIiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3ODE4MzI1MSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDozOC4xODJaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MzguMTgyWiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjM4LjE4MloiLCJzaXplIjoiMTEiLCJtZDVIYXNoIjoieHdXTkZhMFZkWFBtbEF3cmxjQUpjZz09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2N1c3RvbWVyLWVuY3J5cHRpb24tMj9nZW5lcmF0aW9uPTE1NTY4MzU4NzgxODMyNTEmYWx0PW1lZGlhIiwiY29udGVudExhbmd1YWdlIjoiZW4iLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLTIvMTU1NjgzNTg3ODE4MzI1MS9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jdXN0b21lci1lbmNyeXB0aW9uLTIvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImN1c3RvbWVyLWVuY3J5cHRpb24tMiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODc4MTgzMjUxIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNOUEMrTXZ4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLTIvMTU1NjgzNTg3ODE4MzI1MS9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY3VzdG9tZXItZW5jcnlwdGlvbi0yL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY3VzdG9tZXItZW5jcnlwdGlvbi0yIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NzgxODMyNTEiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDTlBDK012eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY3VzdG9tZXItZW5jcnlwdGlvbi0yLzE1NTY4MzU4NzgxODMyNTEvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2N1c3RvbWVyLWVuY3J5cHRpb24tMi9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImN1c3RvbWVyLWVuY3J5cHRpb24tMiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODc4MTgzMjUxIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNOUEMrTXZ4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLTIvMTU1NjgzNTg3ODE4MzI1MS91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY3VzdG9tZXItZW5jcnlwdGlvbi0yL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY3VzdG9tZXItZW5jcnlwdGlvbi0yIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NzgxODMyNTEiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDTlBDK012eC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6InIwTkdyZz09IiwiZXRhZyI6IkNOUEMrTXZ4L2VFQ0VBRT0iLCJjdXN0b21lckVuY3J5cHRpb24iOnsiZW5jcnlwdGlvbkFsZ29yaXRobSI6IkFFUzI1NiIsImtleVNoYTI1NiI6IkZuQnZmUTFkRHN5UzhrSEQrYUI2SEhJZ2xEb1E1SW03V1lEbTNYWVRHclE9In19fQ==" } }, { "ID": "9c6e7ad2d8e2c68a", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/go-integration-test-20190502-80633403432013-0001/customer-encryption-2", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "277" ], "Content-Type": [ "application/xml; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:38 GMT" ], "Expires": [ "Thu, 02 May 2019 22:24:38 GMT" ], "Server": [ "UploadServer" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UoSrQtDkljyQ-aUJoC8m6nY20wZiHLTwh4znEZ5hyKxLQUrZIi7PnU416twfTwfPXWvd4cPGZC3NVdpJWg332KnUKSEdFPY2BQwLJ-_9S5eVdwMrf8" ] }, "Body": "PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48RXJyb3I+PENvZGU+UmVzb3VyY2VJc0VuY3J5cHRlZFdpdGhDdXN0b21lckVuY3J5cHRpb25LZXk8L0NvZGU+PE1lc3NhZ2U+VGhlIHJlc291cmNlIGlzIGVuY3J5cHRlZCB3aXRoIGEgY3VzdG9tZXIgZW5jcnlwdGlvbiBrZXkuPC9NZXNzYWdlPjxEZXRhaWxzPlRoZSByZXF1ZXN0ZWQgb2JqZWN0IGlzIGVuY3J5cHRlZCBieSBhIGN1c3RvbWVyLXN1cHBsaWVkIGVuY3J5cHRpb24ga2V5LjwvRGV0YWlscz48L0Vycm9yPg==" } }, { "ID": "b5fbec9f26148f95", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/go-integration-test-20190502-80633403432013-0001/customer-encryption-2", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "Go-http-client/1.1" ], "X-Goog-Encryption-Algorithm": [ "AES256" ], "X-Goog-Encryption-Key": [ "CLEARED" ], "X-Goog-Encryption-Key-Sha256": [ "FnBvfQ1dDsyS8kHD+aB6HHIglDoQ5Im7WYDm3XYTGrQ=" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Language": [ "en" ], "Content-Length": [ "11" ], "Content-Type": [ "text/plain; charset=utf-8" ], "Date": [ "Thu, 02 May 2019 22:24:38 GMT" ], "Etag": [ "\"-CNPC+Mvx/eECEAE=\"" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Last-Modified": [ "Thu, 02 May 2019 22:24:38 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "X-Goog-Encryption-Algorithm": [ "AES256" ], "X-Goog-Encryption-Key-Sha256": [ "FnBvfQ1dDsyS8kHD+aB6HHIglDoQ5Im7WYDm3XYTGrQ=" ], "X-Goog-Expiration": [ "Sat, 01 Jun 2019 22:24:38 GMT" ], "X-Goog-Generation": [ "1556835878183251" ], "X-Goog-Hash": [ "crc32c=r0NGrg==", "md5=xwWNFa0VdXPmlAwrlcAJcg==" ], "X-Goog-Metageneration": [ "1" ], "X-Goog-Storage-Class": [ "STANDARD" ], "X-Goog-Stored-Content-Encoding": [ "identity" ], "X-Goog-Stored-Content-Length": [ "11" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpTr8Qws5nL-el_ied6M7FYtryiLpFfhGNN-TxakIl1FCAOBJwMeq6_KBQ0l4UmT8VePQQ9h_S8r55NolBB1Ex12-iKvooCkTsNmvQ4rE4hOqQGbLc" ] }, "Body": "dG9wIHNlY3JldC4=" } }, { "ID": "616de25561ebbffa", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/customer-encryption-2/rewriteTo/b/go-integration-test-20190502-80633403432013-0001/o/customer-encryption-2?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "3" ], "User-Agent": [ "google-api-go-client/0.5" ], "X-Goog-Copy-Source-Encryption-Algorithm": [ "AES256" ], "X-Goog-Copy-Source-Encryption-Key": [ "CLEARED" ], "X-Goog-Copy-Source-Encryption-Key-Sha256": [ "FnBvfQ1dDsyS8kHD+aB6HHIglDoQ5Im7WYDm3XYTGrQ=" ], "X-Goog-Encryption-Algorithm": [ "AES256" ], "X-Goog-Encryption-Key": [ "CLEARED" ], "X-Goog-Encryption-Key-Sha256": [ "H+LmnXhRoeI6TMW5bsV6HyUk6pyGc2IMbqYbAXBcps0=" ] }, "MediaType": "application/json", "BodyParts": [ "e30K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3640" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:39 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqyD8XYw6tgOBbcxdUIVAw_vXrrryw0bgh-L-jRW0hyJt0lCHU9K26isn6tykgml7UgX52dgw65xD_ht4yxbHkY_VFl6MkEY6H-mWRx0_52xj49RW8" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNyZXdyaXRlUmVzcG9uc2UiLCJ0b3RhbEJ5dGVzUmV3cml0dGVuIjoiMTEiLCJvYmplY3RTaXplIjoiMTEiLCJkb25lIjp0cnVlLCJyZXNvdXJjZSI6eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLTIvMTU1NjgzNTg3ODk5ODUxMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2N1c3RvbWVyLWVuY3J5cHRpb24tMiIsIm5hbWUiOiJjdXN0b21lci1lbmNyeXB0aW9uLTIiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3ODk5ODUxMSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDozOC45OThaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MzguOTk4WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjM4Ljk5OFoiLCJzaXplIjoiMTEiLCJtZDVIYXNoIjoieHdXTkZhMFZkWFBtbEF3cmxjQUpjZz09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2N1c3RvbWVyLWVuY3J5cHRpb24tMj9nZW5lcmF0aW9uPTE1NTY4MzU4Nzg5OTg1MTEmYWx0PW1lZGlhIiwiY29udGVudExhbmd1YWdlIjoiZW4iLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLTIvMTU1NjgzNTg3ODk5ODUxMS9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jdXN0b21lci1lbmNyeXB0aW9uLTIvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImN1c3RvbWVyLWVuY3J5cHRpb24tMiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODc4OTk4NTExIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNPK2pxc3p4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLTIvMTU1NjgzNTg3ODk5ODUxMS9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY3VzdG9tZXItZW5jcnlwdGlvbi0yL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY3VzdG9tZXItZW5jcnlwdGlvbi0yIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4Nzg5OTg1MTEiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDTytqcXN6eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY3VzdG9tZXItZW5jcnlwdGlvbi0yLzE1NTY4MzU4Nzg5OTg1MTEvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2N1c3RvbWVyLWVuY3J5cHRpb24tMi9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImN1c3RvbWVyLWVuY3J5cHRpb24tMiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODc4OTk4NTExIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNPK2pxc3p4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLTIvMTU1NjgzNTg3ODk5ODUxMS91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY3VzdG9tZXItZW5jcnlwdGlvbi0yL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY3VzdG9tZXItZW5jcnlwdGlvbi0yIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4Nzg5OTg1MTEiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDTytqcXN6eC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6InIwTkdyZz09IiwiZXRhZyI6IkNPK2pxc3p4L2VFQ0VBRT0iLCJjdXN0b21lckVuY3J5cHRpb24iOnsiZW5jcnlwdGlvbkFsZ29yaXRobSI6IkFFUzI1NiIsImtleVNoYTI1NiI6IkgrTG1uWGhSb2VJNlRNVzVic1Y2SHlVazZweUdjMklNYnFZYkFYQmNwczA9In19fQ==" } }, { "ID": "2ddf1402c6efc3a8", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/customer-encryption-3/compose?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "160" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJkZXN0aW5hdGlvbiI6eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEifSwic291cmNlT2JqZWN0cyI6W3sibmFtZSI6ImN1c3RvbWVyLWVuY3J5cHRpb24ifSx7Im5hbWUiOiJjdXN0b21lci1lbmNyeXB0aW9uLTIifV19Cg==" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Content-Length": [ "13334" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:39 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UrFitgTFIY6yt8kk3zprPGtWncWc7Ad6oUFVXVdE0O3QqK0qlYGB7RSw-dwN1AvMk4Sndi8gR22cF8qs88ZlmdAxB-1zYdUNqwArmpP2xni66xX-L4" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6InJlc291cmNlSXNFbmNyeXB0ZWRXaXRoQ3VzdG9tZXJFbmNyeXB0aW9uS2V5IiwibWVzc2FnZSI6IlRoZSB0YXJnZXQgb2JqZWN0IGlzIGVuY3J5cHRlZCBieSBhIGN1c3RvbWVyLXN1cHBsaWVkIGVuY3J5cHRpb24ga2V5LiIsImV4dGVuZGVkSGVscCI6Imh0dHBzOi8vY2xvdWQuZ29vZ2xlLmNvbS9zdG9yYWdlL2RvY3MvZW5jcnlwdGlvbiNjdXN0b21lci1zdXBwbGllZF9lbmNyeXB0aW9uX2tleXMiLCJkZWJ1Z0luZm8iOiJjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6UkVTT1VSQ0VfSVNfRU5DUllQVEVEX1dJVEhfQ1VTVE9NRVJfRU5DUllQVElPTl9LRVk6IENvbXBvbmVudCBvYmplY3QgKGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uKSBpcyBlbmNyeXB0ZWQgYnkgYSBjdXN0b21lci1zdXBwbGllZCBlbmNyeXB0aW9uIGtleS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuQ29tcG9zZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoQ29tcG9zZU9iamVjdC5qYXZhOjE5OSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkNvbXBvc2VPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKENvbXBvc2VPYmplY3QuamF2YTo0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uT2JqZWN0c0RlbGVnYXRvci5jb21wb3NlKE9iamVjdHNEZWxlZ2F0b3IuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IENvbXBvbmVudCBvYmplY3QgKGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uKSBpcyBlbmNyeXB0ZWQgYnkgYSBjdXN0b21lci1zdXBwbGllZCBlbmNyeXB0aW9uIGtleS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuXG5jb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS5GYXVsdDogSW1tdXRhYmxlRXJyb3JEZWZpbml0aW9ue2Jhc2U9SU5WQUxJRF9WQUxVRSwgY2F0ZWdvcnk9VVNFUl9FUlJPUiwgY2F1c2U9bnVsbCwgZGVidWdJbmZvPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpSRVNPVVJDRV9JU19FTkNSWVBURURfV0lUSF9DVVNUT01FUl9FTkNSWVBUSU9OX0tFWTogQ29tcG9uZW50IG9iamVjdCAoZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2N1c3RvbWVyLWVuY3J5cHRpb24pIGlzIGVuY3J5cHRlZCBieSBhIGN1c3RvbWVyLXN1cHBsaWVkIGVuY3J5cHRpb24ga2V5LlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5Db21wb3NlT2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChDb21wb3NlT2JqZWN0LmphdmE6MTk5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuQ29tcG9zZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoQ29tcG9zZU9iamVjdC5qYXZhOjQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLmNvbXBvc2UoT2JqZWN0c0RlbGVnYXRvci5qYXZhOjEyNilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogQ29tcG9uZW50IG9iamVjdCAoZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2N1c3RvbWVyLWVuY3J5cHRpb24pIGlzIGVuY3J5cHRlZCBieSBhIGN1c3RvbWVyLXN1cHBsaWVkIGVuY3J5cHRpb24ga2V5LlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGRvbWFpbj1nbG9iYWwsIGV4dGVuZGVkSGVscD1odHRwczovL2Nsb3VkLmdvb2dsZS5jb20vc3RvcmFnZS9kb2NzL2VuY3J5cHRpb24jY3VzdG9tZXItc3VwcGxpZWRfZW5jcnlwdGlvbl9rZXlzLCBodHRwSGVhZGVycz17fSwgaHR0cFN0YXR1cz1iYWRSZXF1ZXN0LCBpbnRlcm5hbFJlYXNvbj1SZWFzb257YXJndW1lbnRzPXt9LCBjYXVzZT1udWxsLCBjb2RlPWNsb3VkLmJpZ3N0b3JlLmFwaS5CaWdzdG9yZUVycm9yRG9tYWluLlJFU09VUkNFX0lTX0VOQ1JZUFRFRF9XSVRIX0NVU1RPTUVSX0VOQ1JZUFRJT05fS0VZLCBjcmVhdGVkQnlCYWNrZW5kPXRydWUsIGRlYnVnTWVzc2FnZT1jb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6UkVTT1VSQ0VfSVNfRU5DUllQVEVEX1dJVEhfQ1VTVE9NRVJfRU5DUllQVElPTl9LRVk6IENvbXBvbmVudCBvYmplY3QgKGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uKSBpcyBlbmNyeXB0ZWQgYnkgYSBjdXN0b21lci1zdXBwbGllZCBlbmNyeXB0aW9uIGtleS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuQ29tcG9zZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoQ29tcG9zZU9iamVjdC5qYXZhOjE5OSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkNvbXBvc2VPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKENvbXBvc2VPYmplY3QuamF2YTo0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uT2JqZWN0c0RlbGVnYXRvci5jb21wb3NlKE9iamVjdHNEZWxlZ2F0b3IuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IENvbXBvbmVudCBvYmplY3QgKGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uKSBpcyBlbmNyeXB0ZWQgYnkgYSBjdXN0b21lci1zdXBwbGllZCBlbmNyeXB0aW9uIGtleS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuLCBlcnJvclByb3RvQ29kZT1SRVNPVVJDRV9JU19FTkNSWVBURURfV0lUSF9DVVNUT01FUl9FTkNSWVBUSU9OX0tFWSwgZXJyb3JQcm90b0RvbWFpbj1jbG91ZC5iaWdzdG9yZS5hcGkuQmlnc3RvcmVFcnJvckRvbWFpbiwgZmlsdGVyZWRNZXNzYWdlPW51bGwsIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9Q29tcG9uZW50IG9iamVjdCAoZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2N1c3RvbWVyLWVuY3J5cHRpb24pIGlzIGVuY3J5cHRlZCBieSBhIGN1c3RvbWVyLXN1cHBsaWVkIGVuY3J5cHRpb24ga2V5LiwgdW5uYW1lZEFyZ3VtZW50cz1bXX0sIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9VGhlIHRhcmdldCBvYmplY3QgaXMgZW5jcnlwdGVkIGJ5IGEgY3VzdG9tZXItc3VwcGxpZWQgZW5jcnlwdGlvbiBrZXkuLCByZWFzb249cmVzb3VyY2VJc0VuY3J5cHRlZFdpdGhDdXN0b21lckVuY3J5cHRpb25LZXksIHJwY0NvZGU9NDAwfSBUaGUgdGFyZ2V0IG9iamVjdCBpcyBlbmNyeXB0ZWQgYnkgYSBjdXN0b21lci1zdXBwbGllZCBlbmNyeXB0aW9uIGtleS46IGNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpSRVNPVVJDRV9JU19FTkNSWVBURURfV0lUSF9DVVNUT01FUl9FTkNSWVBUSU9OX0tFWTogQ29tcG9uZW50IG9iamVjdCAoZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2N1c3RvbWVyLWVuY3J5cHRpb24pIGlzIGVuY3J5cHRlZCBieSBhIGN1c3RvbWVyLXN1cHBsaWVkIGVuY3J5cHRpb24ga2V5LlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5Db21wb3NlT2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChDb21wb3NlT2JqZWN0LmphdmE6MTk5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuQ29tcG9zZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoQ29tcG9zZU9iamVjdC5qYXZhOjQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLmNvbXBvc2UoT2JqZWN0c0RlbGVnYXRvci5qYXZhOjEyNilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogQ29tcG9uZW50IG9iamVjdCAoZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2N1c3RvbWVyLWVuY3J5cHRpb24pIGlzIGVuY3J5cHRlZCBieSBhIGN1c3RvbWVyLXN1cHBsaWVkIGVuY3J5cHRpb24ga2V5LlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRXJyb3JDb2xsZWN0b3IudG9GYXVsdChFcnJvckNvbGxlY3Rvci5qYXZhOjU0KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUVycm9yQ29udmVydGVyLnRvRmF1bHQoUm9zeUVycm9yQ29udmVydGVyLmphdmE6NjcpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyNTkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyMzkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci50aHJlYWQuVGhyZWFkVHJhY2tlcnMkVGhyZWFkVHJhY2tpbmdSdW5uYWJsZS5ydW4oVGhyZWFkVHJhY2tlcnMuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjQ1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnNlcnZlci5Db21tb25Nb2R1bGUkQ29udGV4dENhcnJ5aW5nRXhlY3V0b3JTZXJ2aWNlJDEucnVuSW5Db250ZXh0KENvbW1vbk1vZHVsZS5qYXZhOjgwMilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZSQxLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NjApXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoVHJhY2VDb250ZXh0LmphdmE6MzE5KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjMxMSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDU3KVxuXHRhdCBjb20uZ29vZ2xlLmdzZS5pbnRlcm5hbC5EaXNwYXRjaFF1ZXVlSW1wbCRXb3JrZXJUaHJlYWQucnVuKERpc3BhdGNoUXVldWVJbXBsLmphdmE6NDAzKVxuIn1dLCJjb2RlIjo0MDAsIm1lc3NhZ2UiOiJUaGUgdGFyZ2V0IG9iamVjdCBpcyBlbmNyeXB0ZWQgYnkgYSBjdXN0b21lci1zdXBwbGllZCBlbmNyeXB0aW9uIGtleS4ifX0=" } }, { "ID": "eea75f5f6c3c7e89", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/customer-encryption-3/compose?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "160" ], "User-Agent": [ "google-api-go-client/0.5" ], "X-Goog-Encryption-Algorithm": [ "AES256" ], "X-Goog-Encryption-Key": [ "CLEARED" ], "X-Goog-Encryption-Key-Sha256": [ "H+LmnXhRoeI6TMW5bsV6HyUk6pyGc2IMbqYbAXBcps0=" ] }, "MediaType": "application/json", "BodyParts": [ "eyJkZXN0aW5hdGlvbiI6eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEifSwic291cmNlT2JqZWN0cyI6W3sibmFtZSI6ImN1c3RvbWVyLWVuY3J5cHRpb24ifSx7Im5hbWUiOiJjdXN0b21lci1lbmNyeXB0aW9uLTIifV19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "911" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:39 GMT" ], "Etag": [ "CPDp3szx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uotyvz71ZfU1J_hl3NsDz9ldw92nWlIp9muxpBUsdv0nTyfJEqz-yQFyEwE2UM11wv7tkpLQfffGlKhlx7CVK0S1UYJnS2XQu2P0Uiz5bbamHxE520" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLTMvMTU1NjgzNTg3OTg1OTQ0MCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2N1c3RvbWVyLWVuY3J5cHRpb24tMyIsIm5hbWUiOiJjdXN0b21lci1lbmNyeXB0aW9uLTMiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3OTg1OTQ0MCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDozOS44NTlaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MzkuODU5WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjM5Ljg1OVoiLCJzaXplIjoiMjIiLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY3VzdG9tZXItZW5jcnlwdGlvbi0zP2dlbmVyYXRpb249MTU1NjgzNTg3OTg1OTQ0MCZhbHQ9bWVkaWEiLCJjcmMzMmMiOiI1ajF5cGc9PSIsImNvbXBvbmVudENvdW50IjoyLCJldGFnIjoiQ1BEcDNzengvZUVDRUFFPSIsImN1c3RvbWVyRW5jcnlwdGlvbiI6eyJlbmNyeXB0aW9uQWxnb3JpdGhtIjoiQUVTMjU2Iiwia2V5U2hhMjU2IjoiSCtMbW5YaFJvZUk2VE1XNWJzVjZIeVVrNnB5R2MySU1icVliQVhCY3BzMD0ifX0=" } }, { "ID": "b19fb82ecf450b51", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/go-integration-test-20190502-80633403432013-0001/customer-encryption-3", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "277" ], "Content-Type": [ "application/xml; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:40 GMT" ], "Expires": [ "Thu, 02 May 2019 22:24:40 GMT" ], "Server": [ "UploadServer" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2Urcj3TJ6B5h4Q0DT7G_ioI_Icu9iv65m57OlRH6h9mKD9zZZl320H3QD6A7fNd1UPBSGGDZ9I0TG4_lSFa8JgkJQEVRGVRvVQv36b7ArCuGmg0loV0" ] }, "Body": "PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48RXJyb3I+PENvZGU+UmVzb3VyY2VJc0VuY3J5cHRlZFdpdGhDdXN0b21lckVuY3J5cHRpb25LZXk8L0NvZGU+PE1lc3NhZ2U+VGhlIHJlc291cmNlIGlzIGVuY3J5cHRlZCB3aXRoIGEgY3VzdG9tZXIgZW5jcnlwdGlvbiBrZXkuPC9NZXNzYWdlPjxEZXRhaWxzPlRoZSByZXF1ZXN0ZWQgb2JqZWN0IGlzIGVuY3J5cHRlZCBieSBhIGN1c3RvbWVyLXN1cHBsaWVkIGVuY3J5cHRpb24ga2V5LjwvRGV0YWlscz48L0Vycm9yPg==" } }, { "ID": "1f0a12bd00a88965", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/go-integration-test-20190502-80633403432013-0001/customer-encryption-3", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "Go-http-client/1.1" ], "X-Goog-Encryption-Algorithm": [ "AES256" ], "X-Goog-Encryption-Key": [ "CLEARED" ], "X-Goog-Encryption-Key-Sha256": [ "H+LmnXhRoeI6TMW5bsV6HyUk6pyGc2IMbqYbAXBcps0=" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "22" ], "Content-Type": [ "application/octet-stream" ], "Date": [ "Thu, 02 May 2019 22:24:40 GMT" ], "Etag": [ "\"-CPDp3szx/eECEAE=\"" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Last-Modified": [ "Thu, 02 May 2019 22:24:39 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "X-Goog-Component-Count": [ "2" ], "X-Goog-Encryption-Algorithm": [ "AES256" ], "X-Goog-Encryption-Key-Sha256": [ "H+LmnXhRoeI6TMW5bsV6HyUk6pyGc2IMbqYbAXBcps0=" ], "X-Goog-Expiration": [ "Sat, 01 Jun 2019 22:24:39 GMT" ], "X-Goog-Generation": [ "1556835879859440" ], "X-Goog-Hash": [ "crc32c=5j1ypg==" ], "X-Goog-Metageneration": [ "1" ], "X-Goog-Storage-Class": [ "STANDARD" ], "X-Goog-Stored-Content-Encoding": [ "identity" ], "X-Goog-Stored-Content-Length": [ "22" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Ur7DoEkjdrkGGrYpsCDbd2Y6c_Mu8sEA7cN_k06l4WjY25UJsijDFWSlSIA9SCi-ouLuI3if4Rh33a5n5vKcN3oSYjzK92eSPVCczEpQdILKFWyQh4" ] }, "Body": "dG9wIHNlY3JldC50b3Agc2VjcmV0Lg==" } }, { "ID": "f649a81672a92823", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/customer-encryption-2/rewriteTo/b/go-integration-test-20190502-80633403432013-0001/o/customer-encryption-2?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "3" ], "User-Agent": [ "google-api-go-client/0.5" ], "X-Goog-Copy-Source-Encryption-Algorithm": [ "AES256" ], "X-Goog-Copy-Source-Encryption-Key": [ "CLEARED" ], "X-Goog-Copy-Source-Encryption-Key-Sha256": [ "H+LmnXhRoeI6TMW5bsV6HyUk6pyGc2IMbqYbAXBcps0=" ] }, "MediaType": "application/json", "BodyParts": [ "e30K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3527" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:40 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrfhqrYGhW8ew5dxbfg_DcMhaJh6k2oY_JqMwPRSDtS3Ef5kljeo8oTONrxRIAP8I0ScqxFCy7okNejkqOeO4Vr1TBZ2mc4MDjwiJA52ERSgZMUyvM" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNyZXdyaXRlUmVzcG9uc2UiLCJ0b3RhbEJ5dGVzUmV3cml0dGVuIjoiMTEiLCJvYmplY3RTaXplIjoiMTEiLCJkb25lIjp0cnVlLCJyZXNvdXJjZSI6eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLTIvMTU1NjgzNTg4MDcxNzUwNiIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2N1c3RvbWVyLWVuY3J5cHRpb24tMiIsIm5hbWUiOiJjdXN0b21lci1lbmNyeXB0aW9uLTIiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg4MDcxNzUwNiIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDo0MC43MTdaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6NDAuNzE3WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjQwLjcxN1oiLCJzaXplIjoiMTEiLCJtZDVIYXNoIjoieHdXTkZhMFZkWFBtbEF3cmxjQUpjZz09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2N1c3RvbWVyLWVuY3J5cHRpb24tMj9nZW5lcmF0aW9uPTE1NTY4MzU4ODA3MTc1MDYmYWx0PW1lZGlhIiwiY29udGVudExhbmd1YWdlIjoiZW4iLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLTIvMTU1NjgzNTg4MDcxNzUwNi9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jdXN0b21lci1lbmNyeXB0aW9uLTIvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImN1c3RvbWVyLWVuY3J5cHRpb24tMiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODgwNzE3NTA2IiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNNS1prODN4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLTIvMTU1NjgzNTg4MDcxNzUwNi9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY3VzdG9tZXItZW5jcnlwdGlvbi0yL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY3VzdG9tZXItZW5jcnlwdGlvbi0yIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4ODA3MTc1MDYiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDTUtaazgzeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY3VzdG9tZXItZW5jcnlwdGlvbi0yLzE1NTY4MzU4ODA3MTc1MDYvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2N1c3RvbWVyLWVuY3J5cHRpb24tMi9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImN1c3RvbWVyLWVuY3J5cHRpb24tMiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODgwNzE3NTA2IiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNNS1prODN4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLTIvMTU1NjgzNTg4MDcxNzUwNi91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY3VzdG9tZXItZW5jcnlwdGlvbi0yL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY3VzdG9tZXItZW5jcnlwdGlvbi0yIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4ODA3MTc1MDYiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDTUtaazgzeC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6InIwTkdyZz09IiwiZXRhZyI6IkNNS1prODN4L2VFQ0VBRT0ifX0=" } }, { "ID": "61763fd57e906039", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/customer-encryption-3/compose?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "129" ], "User-Agent": [ "google-api-go-client/0.5" ], "X-Goog-Encryption-Algorithm": [ "AES256" ], "X-Goog-Encryption-Key": [ "CLEARED" ], "X-Goog-Encryption-Key-Sha256": [ "H+LmnXhRoeI6TMW5bsV6HyUk6pyGc2IMbqYbAXBcps0=" ] }, "MediaType": "application/json", "BodyParts": [ "eyJkZXN0aW5hdGlvbiI6eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEifSwic291cmNlT2JqZWN0cyI6W3sibmFtZSI6ImN1c3RvbWVyLWVuY3J5cHRpb24tMiJ9XX0K" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Content-Length": [ "13444" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:41 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2Ur7TRBQyfrSgWnsPL0CVfQCd5s_QJN9pRUHB1YttIoObh1YkzCEtuRxrwyKYtccpyodUCMmTVRyD6d0oDy-c2_Q7GK-_6OC5h_EF_1e9-t6E8VZCQ8" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6InJlc291cmNlTm90RW5jcnlwdGVkV2l0aEN1c3RvbWVyRW5jcnlwdGlvbktleSIsIm1lc3NhZ2UiOiJUaGUgdGFyZ2V0IG9iamVjdCBpcyBub3QgZW5jcnlwdGVkIGJ5IGEgY3VzdG9tZXItc3VwcGxpZWQgZW5jcnlwdGlvbiBrZXkuIiwiZXh0ZW5kZWRIZWxwIjoiaHR0cHM6Ly9jbG91ZC5nb29nbGUuY29tL3N0b3JhZ2UvZG9jcy9lbmNyeXB0aW9uI2N1c3RvbWVyLXN1cHBsaWVkX2VuY3J5cHRpb25fa2V5cyIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpSRVNPVVJDRV9OT1RfRU5DUllQVEVEX1dJVEhfQ1VTVE9NRVJfRU5DUllQVElPTl9LRVk6IENvbXBvbmVudCBvYmplY3QgKGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLTIpIHVzIG5vdCBlbmNyeXB0ZWQgYnkgYSBjdXN0b21lci1zdXBwbGllZCBlbmNyeXB0aW9uIGtleS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuQ29tcG9zZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoQ29tcG9zZU9iamVjdC5qYXZhOjE5OSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkNvbXBvc2VPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKENvbXBvc2VPYmplY3QuamF2YTo0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uT2JqZWN0c0RlbGVnYXRvci5jb21wb3NlKE9iamVjdHNEZWxlZ2F0b3IuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IENvbXBvbmVudCBvYmplY3QgKGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLTIpIHVzIG5vdCBlbmNyeXB0ZWQgYnkgYSBjdXN0b21lci1zdXBwbGllZCBlbmNyeXB0aW9uIGtleS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuXG5jb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS5GYXVsdDogSW1tdXRhYmxlRXJyb3JEZWZpbml0aW9ue2Jhc2U9SU5WQUxJRF9WQUxVRSwgY2F0ZWdvcnk9VVNFUl9FUlJPUiwgY2F1c2U9bnVsbCwgZGVidWdJbmZvPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpSRVNPVVJDRV9OT1RfRU5DUllQVEVEX1dJVEhfQ1VTVE9NRVJfRU5DUllQVElPTl9LRVk6IENvbXBvbmVudCBvYmplY3QgKGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLTIpIHVzIG5vdCBlbmNyeXB0ZWQgYnkgYSBjdXN0b21lci1zdXBwbGllZCBlbmNyeXB0aW9uIGtleS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuQ29tcG9zZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoQ29tcG9zZU9iamVjdC5qYXZhOjE5OSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkNvbXBvc2VPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKENvbXBvc2VPYmplY3QuamF2YTo0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uT2JqZWN0c0RlbGVnYXRvci5jb21wb3NlKE9iamVjdHNEZWxlZ2F0b3IuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IENvbXBvbmVudCBvYmplY3QgKGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLTIpIHVzIG5vdCBlbmNyeXB0ZWQgYnkgYSBjdXN0b21lci1zdXBwbGllZCBlbmNyeXB0aW9uIGtleS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuLCBkb21haW49Z2xvYmFsLCBleHRlbmRlZEhlbHA9aHR0cHM6Ly9jbG91ZC5nb29nbGUuY29tL3N0b3JhZ2UvZG9jcy9lbmNyeXB0aW9uI2N1c3RvbWVyLXN1cHBsaWVkX2VuY3J5cHRpb25fa2V5cywgaHR0cEhlYWRlcnM9e30sIGh0dHBTdGF0dXM9YmFkUmVxdWVzdCwgaW50ZXJuYWxSZWFzb249UmVhc29ue2FyZ3VtZW50cz17fSwgY2F1c2U9bnVsbCwgY29kZT1jbG91ZC5iaWdzdG9yZS5hcGkuQmlnc3RvcmVFcnJvckRvbWFpbi5SRVNPVVJDRV9OT1RfRU5DUllQVEVEX1dJVEhfQ1VTVE9NRVJfRU5DUllQVElPTl9LRVksIGNyZWF0ZWRCeUJhY2tlbmQ9dHJ1ZSwgZGVidWdNZXNzYWdlPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpSRVNPVVJDRV9OT1RfRU5DUllQVEVEX1dJVEhfQ1VTVE9NRVJfRU5DUllQVElPTl9LRVk6IENvbXBvbmVudCBvYmplY3QgKGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLTIpIHVzIG5vdCBlbmNyeXB0ZWQgYnkgYSBjdXN0b21lci1zdXBwbGllZCBlbmNyeXB0aW9uIGtleS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuQ29tcG9zZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoQ29tcG9zZU9iamVjdC5qYXZhOjE5OSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkNvbXBvc2VPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKENvbXBvc2VPYmplY3QuamF2YTo0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uT2JqZWN0c0RlbGVnYXRvci5jb21wb3NlKE9iamVjdHNEZWxlZ2F0b3IuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IENvbXBvbmVudCBvYmplY3QgKGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLTIpIHVzIG5vdCBlbmNyeXB0ZWQgYnkgYSBjdXN0b21lci1zdXBwbGllZCBlbmNyeXB0aW9uIGtleS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuLCBlcnJvclByb3RvQ29kZT1SRVNPVVJDRV9OT1RfRU5DUllQVEVEX1dJVEhfQ1VTVE9NRVJfRU5DUllQVElPTl9LRVksIGVycm9yUHJvdG9Eb21haW49Y2xvdWQuYmlnc3RvcmUuYXBpLkJpZ3N0b3JlRXJyb3JEb21haW4sIGZpbHRlcmVkTWVzc2FnZT1udWxsLCBsb2NhdGlvbj1lbnRpdHkuZW5jcnlwdGlvbktleSwgbWVzc2FnZT1Db21wb25lbnQgb2JqZWN0IChnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY3VzdG9tZXItZW5jcnlwdGlvbi0yKSB1cyBub3QgZW5jcnlwdGVkIGJ5IGEgY3VzdG9tZXItc3VwcGxpZWQgZW5jcnlwdGlvbiBrZXkuLCB1bm5hbWVkQXJndW1lbnRzPVtdfSwgbG9jYXRpb249ZW50aXR5LmVuY3J5cHRpb25LZXksIG1lc3NhZ2U9VGhlIHRhcmdldCBvYmplY3QgaXMgbm90IGVuY3J5cHRlZCBieSBhIGN1c3RvbWVyLXN1cHBsaWVkIGVuY3J5cHRpb24ga2V5LiwgcmVhc29uPXJlc291cmNlTm90RW5jcnlwdGVkV2l0aEN1c3RvbWVyRW5jcnlwdGlvbktleSwgcnBjQ29kZT00MDB9IFRoZSB0YXJnZXQgb2JqZWN0IGlzIG5vdCBlbmNyeXB0ZWQgYnkgYSBjdXN0b21lci1zdXBwbGllZCBlbmNyeXB0aW9uIGtleS46IGNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpSRVNPVVJDRV9OT1RfRU5DUllQVEVEX1dJVEhfQ1VTVE9NRVJfRU5DUllQVElPTl9LRVk6IENvbXBvbmVudCBvYmplY3QgKGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLTIpIHVzIG5vdCBlbmNyeXB0ZWQgYnkgYSBjdXN0b21lci1zdXBwbGllZCBlbmNyeXB0aW9uIGtleS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuQ29tcG9zZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoQ29tcG9zZU9iamVjdC5qYXZhOjE5OSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkNvbXBvc2VPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKENvbXBvc2VPYmplY3QuamF2YTo0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uT2JqZWN0c0RlbGVnYXRvci5jb21wb3NlKE9iamVjdHNEZWxlZ2F0b3IuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IENvbXBvbmVudCBvYmplY3QgKGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLTIpIHVzIG5vdCBlbmNyeXB0ZWQgYnkgYSBjdXN0b21lci1zdXBwbGllZCBlbmNyeXB0aW9uIGtleS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLkVycm9yQ29sbGVjdG9yLnRvRmF1bHQoRXJyb3JDb2xsZWN0b3IuamF2YTo1NClcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lFcnJvckNvbnZlcnRlci50b0ZhdWx0KFJvc3lFcnJvckNvbnZlcnRlci5qYXZhOjY3KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUhhbmRsZXIkMi5jYWxsKFJvc3lIYW5kbGVyLmphdmE6MjU5KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUhhbmRsZXIkMi5jYWxsKFJvc3lIYW5kbGVyLmphdmE6MjM5KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRGlyZWN0RXhlY3V0b3IuZXhlY3V0ZShEaXJlY3RFeGVjdXRvci5qYXZhOjMwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuZXhlY3V0ZUxpc3RlbmVyKEFic3RyYWN0RnV0dXJlLmphdmE6MTE0Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmNvbXBsZXRlKEFic3RyYWN0RnV0dXJlLmphdmE6OTYzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuc2V0KEFic3RyYWN0RnV0dXJlLmphdmE6NzMxKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRGlyZWN0RXhlY3V0b3IuZXhlY3V0ZShEaXJlY3RFeGVjdXRvci5qYXZhOjMwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuZXhlY3V0ZUxpc3RlbmVyKEFic3RyYWN0RnV0dXJlLmphdmE6MTE0Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmNvbXBsZXRlKEFic3RyYWN0RnV0dXJlLmphdmE6OTYzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuc2V0KEFic3RyYWN0RnV0dXJlLmphdmE6NzMxKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIudGhyZWFkLlRocmVhZFRyYWNrZXJzJFRocmVhZFRyYWNraW5nUnVubmFibGUucnVuKFRocmVhZFRyYWNrZXJzLmphdmE6MTI2KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChUcmFjZUNvbnRleHQuamF2YTo0NTMpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5zZXJ2ZXIuQ29tbW9uTW9kdWxlJENvbnRleHRDYXJyeWluZ0V4ZWN1dG9yU2VydmljZSQxLnJ1bkluQ29udGV4dChDb21tb25Nb2R1bGUuamF2YTo4MDIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUkMS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDYwKVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkQWJzdHJhY3RUcmFjZUNvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKFRyYWNlQ29udGV4dC5qYXZhOjMxOSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChUcmFjZUNvbnRleHQuamF2YTozMTEpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuKFRyYWNlQ29udGV4dC5qYXZhOjQ1Nylcblx0YXQgY29tLmdvb2dsZS5nc2UuaW50ZXJuYWwuRGlzcGF0Y2hRdWV1ZUltcGwkV29ya2VyVGhyZWFkLnJ1bihEaXNwYXRjaFF1ZXVlSW1wbC5qYXZhOjQwMylcbiJ9XSwiY29kZSI6NDAwLCJtZXNzYWdlIjoiVGhlIHRhcmdldCBvYmplY3QgaXMgbm90IGVuY3J5cHRlZCBieSBhIGN1c3RvbWVyLXN1cHBsaWVkIGVuY3J5cHRpb24ga2V5LiJ9fQ==" } }, { "ID": "b45cb452c78d7b50", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "2571" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:41 GMT" ], "Etag": [ "CAo=" ], "Expires": [ "Thu, 02 May 2019 22:24:41 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uq2YnotZtU1JMnJw10vtgVDeukiWK_4DXx0QFWA91CaCYLPXLDKzCzY8xqb6EGkVxvw731As27REu_hYOqZTwSfJJ6SeHemliLV9JgQYjfngxL0HFA" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjIzOjU0LjYxMFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDoyOC44ODJaIiwibWV0YWdlbmVyYXRpb24iOiIxMCIsImFjbCI6W3sia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9hY2wvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBbz0ifSx7ImtpbmQiOiJzdG9yYWdlI2J1Y2tldEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0FvPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0FvPSJ9XSwiZGVmYXVsdE9iamVjdEFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDQW89In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0FvPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQW89In1dLCJpYW1Db25maWd1cmF0aW9uIjp7ImJ1Y2tldFBvbGljeU9ubHkiOnsiZW5hYmxlZCI6ZmFsc2V9fSwib3duZXIiOnsiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0In0sImxvY2F0aW9uIjoiVVMiLCJ2ZXJzaW9uaW5nIjp7ImVuYWJsZWQiOmZhbHNlfSwibGlmZWN5Y2xlIjp7InJ1bGUiOlt7ImFjdGlvbiI6eyJ0eXBlIjoiRGVsZXRlIn0sImNvbmRpdGlvbiI6eyJhZ2UiOjMwfX1dfSwibGFiZWxzIjp7Im5ldyI6Im5ldyIsImwxIjoidjIifSwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJldGFnIjoiQ0FvPSJ9" } }, { "ID": "6831287fd0edbcd4", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJuYW1lIjoicG9zYyJ9Cg==", "Zm9v" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3128" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:42 GMT" ], "Etag": [ "CJek2c3x/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrXGhYaqbrodjXeCKtZGAt0hM0GrM8GBcZBkGkLJ7550-Iqaxp681SkhDDDOp0V3-xMmoq3rjWOC8A4XvJfAzgxGsO2VekCUJgUBMalL8hEAur49q8" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9wb3NjLzE1NTY4MzU4ODE4NjU3NTEiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9wb3NjIiwibmFtZSI6InBvc2MiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg4MTg2NTc1MSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDo0MS44NjVaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6NDEuODY1WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjQxLjg2NVoiLCJzaXplIjoiMyIsIm1kNUhhc2giOiJyTDBZMjB6QytGenQ3MlZQek1TazJBPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vcG9zYz9nZW5lcmF0aW9uPTE1NTY4MzU4ODE4NjU3NTEmYWx0PW1lZGlhIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvcG9zYy8xNTU2ODM1ODgxODY1NzUxL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL3Bvc2MvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6InBvc2MiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg4MTg2NTc1MSIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDSmVrMmMzeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvcG9zYy8xNTU2ODM1ODgxODY1NzUxL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9wb3NjL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoicG9zYyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODgxODY1NzUxIiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0plazJjM3gvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL3Bvc2MvMTU1NjgzNTg4MTg2NTc1MS9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vcG9zYy9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6InBvc2MiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg4MTg2NTc1MSIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDSmVrMmMzeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvcG9zYy8xNTU2ODM1ODgxODY1NzUxL3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9wb3NjL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoicG9zYyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODgxODY1NzUxIiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ0plazJjM3gvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJ6OFN1SFE9PSIsImV0YWciOiJDSmVrMmMzeC9lRUNFQUU9In0=" } }, { "ID": "7588cdc84e3976f4", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/posc?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3128" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:42 GMT" ], "Etag": [ "CJek2c3x/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpGBHQWnSHLUYlW5nck2w_3QN4x5uYmOM-GIatNzD1tqhzK0JOf7rBe1BKILpdyEUPlSmrLwrukcqJwHgfezE50OQL7ha9n6_fc6qUMoVwkEGawOgA" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9wb3NjLzE1NTY4MzU4ODE4NjU3NTEiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9wb3NjIiwibmFtZSI6InBvc2MiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg4MTg2NTc1MSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDo0MS44NjVaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6NDEuODY1WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjQxLjg2NVoiLCJzaXplIjoiMyIsIm1kNUhhc2giOiJyTDBZMjB6QytGenQ3MlZQek1TazJBPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vcG9zYz9nZW5lcmF0aW9uPTE1NTY4MzU4ODE4NjU3NTEmYWx0PW1lZGlhIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvcG9zYy8xNTU2ODM1ODgxODY1NzUxL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL3Bvc2MvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6InBvc2MiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg4MTg2NTc1MSIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDSmVrMmMzeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvcG9zYy8xNTU2ODM1ODgxODY1NzUxL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9wb3NjL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoicG9zYyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODgxODY1NzUxIiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0plazJjM3gvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL3Bvc2MvMTU1NjgzNTg4MTg2NTc1MS9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vcG9zYy9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6InBvc2MiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg4MTg2NTc1MSIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDSmVrMmMzeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvcG9zYy8xNTU2ODM1ODgxODY1NzUxL3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9wb3NjL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoicG9zYyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODgxODY1NzUxIiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ0plazJjM3gvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJ6OFN1SFE9PSIsImV0YWciOiJDSmVrMmMzeC9lRUNFQUU9In0=" } }, { "ID": "974ed1b42608e806", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/posc/rewriteTo/b/go-integration-test-20190502-80633403432013-0001/o/posc?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "34" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJzdG9yYWdlQ2xhc3MiOiJNVUxUSV9SRUdJT05BTCJ9Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3193" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:42 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrKCtuc_GsAj6sf3zXpqT2_KZrdL0SEwsunv07k0DaaEHMj8gkX4kRCcm5r8AUrD9RNYjoKeceiCyY4pDN8nrHljshmEIXF2P29Oyd0KSuqDjsNeps" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNyZXdyaXRlUmVzcG9uc2UiLCJ0b3RhbEJ5dGVzUmV3cml0dGVuIjoiMyIsIm9iamVjdFNpemUiOiIzIiwiZG9uZSI6dHJ1ZSwicmVzb3VyY2UiOnsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvcG9zYy8xNTU2ODM1ODgyNzYwNjA3Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vcG9zYyIsIm5hbWUiOiJwb3NjIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4ODI3NjA2MDciLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6NDIuNzYwWiIsInVwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjQyLjc2MFoiLCJzdG9yYWdlQ2xhc3MiOiJNVUxUSV9SRUdJT05BTCIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDo0Mi43NjBaIiwic2l6ZSI6IjMiLCJtZDVIYXNoIjoickwwWTIwekMrRnp0NzJWUHpNU2syQT09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL3Bvc2M/Z2VuZXJhdGlvbj0xNTU2ODM1ODgyNzYwNjA3JmFsdD1tZWRpYSIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL3Bvc2MvMTU1NjgzNTg4Mjc2MDYwNy9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9wb3NjL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJwb3NjIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4ODI3NjA2MDciLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0ovemo4N3gvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL3Bvc2MvMTU1NjgzNTg4Mjc2MDYwNy9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vcG9zYy9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6InBvc2MiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg4Mjc2MDYwNyIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNKL3pqODd4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9wb3NjLzE1NTY4MzU4ODI3NjA2MDcvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL3Bvc2MvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJwb3NjIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4ODI3NjA2MDciLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0ovemo4N3gvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL3Bvc2MvMTU1NjgzNTg4Mjc2MDYwNy91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vcG9zYy9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6InBvc2MiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg4Mjc2MDYwNyIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNKL3pqODd4L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoiejhTdUhRPT0iLCJldGFnIjoiQ0ovemo4N3gvZUVDRUFFPSJ9fQ==" } }, { "ID": "a2be30bf1e3cb539", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJuYW1lIjoicG9zYzIiLCJzdG9yYWdlQ2xhc3MiOiJNVUxUSV9SRUdJT05BTCJ9Cg==", "eHh4" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3150" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:43 GMT" ], "Etag": [ "CILrp87x/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqziYHpTkcbyMFRtHko_e04Rze8FHLbALw476U2bB9k_SqPwILBzxKRLzFvRN4q3RLt4xR1mpR2lgJ1Zq0BNYCefLOZsOeq4JbzJYLxGL5V799xkQ8" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9wb3NjMi8xNTU2ODM1ODgzMTUyNzcwIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vcG9zYzIiLCJuYW1lIjoicG9zYzIiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg4MzE1Mjc3MCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDo0My4xNTJaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6NDMuMTUyWiIsInN0b3JhZ2VDbGFzcyI6Ik1VTFRJX1JFR0lPTkFMIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjQzLjE1MloiLCJzaXplIjoiMyIsIm1kNUhhc2giOiI5V0dxOXU4TDhVMUNDTHRHcE15enJRPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vcG9zYzI/Z2VuZXJhdGlvbj0xNTU2ODM1ODgzMTUyNzcwJmFsdD1tZWRpYSIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL3Bvc2MyLzE1NTY4MzU4ODMxNTI3NzAvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vcG9zYzIvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6InBvc2MyIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4ODMxNTI3NzAiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0lMcnA4N3gvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL3Bvc2MyLzE1NTY4MzU4ODMxNTI3NzAvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL3Bvc2MyL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoicG9zYzIiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg4MzE1Mjc3MCIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNJTHJwODd4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9wb3NjMi8xNTU2ODM1ODgzMTUyNzcwL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9wb3NjMi9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6InBvc2MyIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4ODMxNTI3NzAiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0lMcnA4N3gvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL3Bvc2MyLzE1NTY4MzU4ODMxNTI3NzAvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL3Bvc2MyL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoicG9zYzIiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg4MzE1Mjc3MCIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNJTHJwODd4L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoiMTdxQUJRPT0iLCJldGFnIjoiQ0lMcnA4N3gvZUVDRUFFPSJ9" } }, { "ID": "d570e13411ade628", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJuYW1lIjoiYnVja2V0SW5Db3B5QXR0cnMifQo=", "Zm9v" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3336" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:43 GMT" ], "Etag": [ "CPCDx87x/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrltsLp6xgl5GQBA_ZoqyMKcRlP-MvWyo0epRXUAbOAkOUUpAOgezp4fFQRP5wEM1fq771AWUgtYvQ3HLXCnwxmDaCqJxEhICiYhxDp8RpvCnn3xuI" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9idWNrZXRJbkNvcHlBdHRycy8xNTU2ODM1ODgzNjYzODU2Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vYnVja2V0SW5Db3B5QXR0cnMiLCJuYW1lIjoiYnVja2V0SW5Db3B5QXR0cnMiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg4MzY2Mzg1NiIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDo0My42NjNaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6NDMuNjYzWiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjQzLjY2M1oiLCJzaXplIjoiMyIsIm1kNUhhc2giOiJyTDBZMjB6QytGenQ3MlZQek1TazJBPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vYnVja2V0SW5Db3B5QXR0cnM/Z2VuZXJhdGlvbj0xNTU2ODM1ODgzNjYzODU2JmFsdD1tZWRpYSIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2J1Y2tldEluQ29weUF0dHJzLzE1NTY4MzU4ODM2NjM4NTYvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vYnVja2V0SW5Db3B5QXR0cnMvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImJ1Y2tldEluQ29weUF0dHJzIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4ODM2NjM4NTYiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ1BDRHg4N3gvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2J1Y2tldEluQ29weUF0dHJzLzE1NTY4MzU4ODM2NjM4NTYvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2J1Y2tldEluQ29weUF0dHJzL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiYnVja2V0SW5Db3B5QXR0cnMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg4MzY2Mzg1NiIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNQQ0R4ODd4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9idWNrZXRJbkNvcHlBdHRycy8xNTU2ODM1ODgzNjYzODU2L3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9idWNrZXRJbkNvcHlBdHRycy9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImJ1Y2tldEluQ29weUF0dHJzIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4ODM2NjM4NTYiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ1BDRHg4N3gvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2J1Y2tldEluQ29weUF0dHJzLzE1NTY4MzU4ODM2NjM4NTYvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2J1Y2tldEluQ29weUF0dHJzL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiYnVja2V0SW5Db3B5QXR0cnMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg4MzY2Mzg1NiIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNQQ0R4ODd4L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoiejhTdUhRPT0iLCJldGFnIjoiQ1BDRHg4N3gvZUVDRUFFPSJ9" } }, { "ID": "284a06aa5d3f4c0f", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/bucketInCopyAttrs/rewriteTo/b/go-integration-test-20190502-80633403432013-0001/o/bucketInCopyAttrs?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "62" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEifQo=" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Content-Length": [ "2972" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:43 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UqEuzT5vUHzBcQTT84B5lbxQRZ8Wazbvf7pARGdim0OKOWWM6MdR9KrH11f9w9bxrybc2YHzoveHnAwpEgFzwUcXlLN8xDttCt9pwOnPMX3My8utXg" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6InJlcXVpcmVkIiwibWVzc2FnZSI6IlJlcXVpcmVkIiwiZGVidWdJbmZvIjoiY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPVJFUVVJUkVELCBjYXRlZ29yeT1VU0VSX0VSUk9SLCBjYXVzZT1udWxsLCBkZWJ1Z0luZm89bnVsbCwgZG9tYWluPWdsb2JhbCwgZXh0ZW5kZWRIZWxwPW51bGwsIGh0dHBIZWFkZXJzPXt9LCBodHRwU3RhdHVzPWJhZFJlcXVlc3QsIGludGVybmFsUmVhc29uPVJlYXNvbnthcmd1bWVudHM9e30sIGNhdXNlPW51bGwsIGNvZGU9Z2RhdGEuQ29yZUVycm9yRG9tYWluLlJFUVVJUkVELCBjcmVhdGVkQnlCYWNrZW5kPXRydWUsIGRlYnVnTWVzc2FnZT1udWxsLCBlcnJvclByb3RvQ29kZT1SRVFVSVJFRCwgZXJyb3JQcm90b0RvbWFpbj1nZGF0YS5Db3JlRXJyb3JEb21haW4sIGZpbHRlcmVkTWVzc2FnZT1udWxsLCBsb2NhdGlvbj1lbnRpdHkuZGVzdGluYXRpb25fcmVzb3VyY2UuaWQubmFtZSwgbWVzc2FnZT1udWxsLCB1bm5hbWVkQXJndW1lbnRzPVtdfSwgbG9jYXRpb249ZW50aXR5LmRlc3RpbmF0aW9uX3Jlc291cmNlLmlkLm5hbWUsIG1lc3NhZ2U9UmVxdWlyZWQsIHJlYXNvbj1yZXF1aXJlZCwgcnBjQ29kZT00MDB9IFJlcXVpcmVkXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLkVycm9yQ29sbGVjdG9yLnRvRmF1bHQoRXJyb3JDb2xsZWN0b3IuamF2YTo1NClcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lFcnJvckNvbnZlcnRlci50b0ZhdWx0KFJvc3lFcnJvckNvbnZlcnRlci5qYXZhOjY3KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUhhbmRsZXIkMi5jYWxsKFJvc3lIYW5kbGVyLmphdmE6MjU5KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUhhbmRsZXIkMi5jYWxsKFJvc3lIYW5kbGVyLmphdmE6MjM5KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRGlyZWN0RXhlY3V0b3IuZXhlY3V0ZShEaXJlY3RFeGVjdXRvci5qYXZhOjMwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuZXhlY3V0ZUxpc3RlbmVyKEFic3RyYWN0RnV0dXJlLmphdmE6MTE0Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmNvbXBsZXRlKEFic3RyYWN0RnV0dXJlLmphdmE6OTYzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuc2V0KEFic3RyYWN0RnV0dXJlLmphdmE6NzMxKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRGlyZWN0RXhlY3V0b3IuZXhlY3V0ZShEaXJlY3RFeGVjdXRvci5qYXZhOjMwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuZXhlY3V0ZUxpc3RlbmVyKEFic3RyYWN0RnV0dXJlLmphdmE6MTE0Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmNvbXBsZXRlKEFic3RyYWN0RnV0dXJlLmphdmE6OTYzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuc2V0KEFic3RyYWN0RnV0dXJlLmphdmE6NzMxKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIudGhyZWFkLlRocmVhZFRyYWNrZXJzJFRocmVhZFRyYWNraW5nUnVubmFibGUucnVuKFRocmVhZFRyYWNrZXJzLmphdmE6MTI2KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChUcmFjZUNvbnRleHQuamF2YTo0NTMpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5zZXJ2ZXIuQ29tbW9uTW9kdWxlJENvbnRleHRDYXJyeWluZ0V4ZWN1dG9yU2VydmljZSQxLnJ1bkluQ29udGV4dChDb21tb25Nb2R1bGUuamF2YTo4MDIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUkMS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDYwKVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkQWJzdHJhY3RUcmFjZUNvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKFRyYWNlQ29udGV4dC5qYXZhOjMxOSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChUcmFjZUNvbnRleHQuamF2YTozMTEpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuKFRyYWNlQ29udGV4dC5qYXZhOjQ1Nylcblx0YXQgY29tLmdvb2dsZS5nc2UuaW50ZXJuYWwuRGlzcGF0Y2hRdWV1ZUltcGwkV29ya2VyVGhyZWFkLnJ1bihEaXNwYXRjaFF1ZXVlSW1wbC5qYXZhOjQwMylcbiJ9XSwiY29kZSI6NDAwLCJtZXNzYWdlIjoiUmVxdWlyZWQifX0=" } }, { "ID": "631a4dc25c1479df", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJjcmMzMmMiOiJjSCtBK3c9PSIsIm5hbWUiOiJoYXNoZXNPblVwbG9hZC0xIn0K", "SSBjYW4ndCB3YWl0IHRvIGJlIHZlcmlmaWVk" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3321" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:44 GMT" ], "Etag": [ "CIes587x/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Up5pzFgsk-trM6xfNGHCutAafrBhKStla4toQDjvEsTPe4TTesYnwc0KLg9WK95RXOKqdm_KUngd4hv6Tucfns_MALlJyx1s6A2cZR3vco6jKPTW00" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9oYXNoZXNPblVwbG9hZC0xLzE1NTY4MzU4ODQxOTMyODciLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9oYXNoZXNPblVwbG9hZC0xIiwibmFtZSI6Imhhc2hlc09uVXBsb2FkLTEiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg4NDE5MzI4NyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDo0NC4xOTJaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6NDQuMTkyWiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjQ0LjE5MloiLCJzaXplIjoiMjciLCJtZDVIYXNoIjoib2ZaakdsY1hQSmlHT0FmS0ZiSmwxUT09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2hhc2hlc09uVXBsb2FkLTE/Z2VuZXJhdGlvbj0xNTU2ODM1ODg0MTkzMjg3JmFsdD1tZWRpYSIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2hhc2hlc09uVXBsb2FkLTEvMTU1NjgzNTg4NDE5MzI4Ny9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9oYXNoZXNPblVwbG9hZC0xL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJoYXNoZXNPblVwbG9hZC0xIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4ODQxOTMyODciLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0llczU4N3gvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2hhc2hlc09uVXBsb2FkLTEvMTU1NjgzNTg4NDE5MzI4Ny9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vaGFzaGVzT25VcGxvYWQtMS9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Imhhc2hlc09uVXBsb2FkLTEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg4NDE5MzI4NyIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNJZXM1ODd4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9oYXNoZXNPblVwbG9hZC0xLzE1NTY4MzU4ODQxOTMyODcvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2hhc2hlc09uVXBsb2FkLTEvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJoYXNoZXNPblVwbG9hZC0xIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4ODQxOTMyODciLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0llczU4N3gvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2hhc2hlc09uVXBsb2FkLTEvMTU1NjgzNTg4NDE5MzI4Ny91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vaGFzaGVzT25VcGxvYWQtMS9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Imhhc2hlc09uVXBsb2FkLTEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg4NDE5MzI4NyIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNJZXM1ODd4L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoiY0grQSt3PT0iLCJldGFnIjoiQ0llczU4N3gvZUVDRUFFPSJ9" } }, { "ID": "e60d42eeeafea205", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJjcmMzMmMiOiJjSCtBL0E9PSIsIm5hbWUiOiJoYXNoZXNPblVwbG9hZC0xIn0K", "SSBjYW4ndCB3YWl0IHRvIGJlIHZlcmlmaWVk" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Content-Length": [ "3301" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:44 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UpZ9QOOcNdGntWr097PRNnaDFbt2xarczbyHRwkwxSiwRZIhV26iZGbh5vHIpvl3Z5Dxc7hjtWuutHTMn8jpCTEowLJNAre2A6mZxVNtV52Vh6XDX4" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6ImludmFsaWQiLCJtZXNzYWdlIjoiUHJvdmlkZWQgQ1JDMzJDIFwiY0grQS9BPT1cIiBkb2Vzbid0IG1hdGNoIGNhbGN1bGF0ZWQgQ1JDMzJDIFwiY0grQSt3PT1cIi4iLCJkZWJ1Z0luZm8iOiJjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS5GYXVsdDogSW1tdXRhYmxlRXJyb3JEZWZpbml0aW9ue2Jhc2U9SU5WQUxJRF9WQUxVRSwgY2F0ZWdvcnk9VVNFUl9FUlJPUiwgY2F1c2U9bnVsbCwgZGVidWdJbmZvPW51bGwsIGRvbWFpbj1nbG9iYWwsIGV4dGVuZGVkSGVscD1udWxsLCBodHRwSGVhZGVycz17fSwgaHR0cFN0YXR1cz1iYWRSZXF1ZXN0LCBpbnRlcm5hbFJlYXNvbj1SZWFzb257YXJndW1lbnRzPXt9LCBjYXVzZT1udWxsLCBjb2RlPWdkYXRhLkNvcmVFcnJvckRvbWFpbi5JTlZBTElEX1ZBTFVFLCBjcmVhdGVkQnlCYWNrZW5kPXRydWUsIGRlYnVnTWVzc2FnZT1udWxsLCBlcnJvclByb3RvQ29kZT1JTlZBTElEX1ZBTFVFLCBlcnJvclByb3RvRG9tYWluPWdkYXRhLkNvcmVFcnJvckRvbWFpbiwgZmlsdGVyZWRNZXNzYWdlPW51bGwsIGxvY2F0aW9uPWVudGl0eS5yZXNvdXJjZS5jcmMzMmMsIG1lc3NhZ2U9UHJvdmlkZWQgQ1JDMzJDIFwiY0grQS9BPT1cIiBkb2Vzbid0IG1hdGNoIGNhbGN1bGF0ZWQgQ1JDMzJDIFwiY0grQSt3PT1cIi4sIHVubmFtZWRBcmd1bWVudHM9W2NIK0EvQT09XX0sIGxvY2F0aW9uPWVudGl0eS5yZXNvdXJjZS5jcmMzMmMsIG1lc3NhZ2U9UHJvdmlkZWQgQ1JDMzJDIFwiY0grQS9BPT1cIiBkb2Vzbid0IG1hdGNoIGNhbGN1bGF0ZWQgQ1JDMzJDIFwiY0grQSt3PT1cIi4sIHJlYXNvbj1pbnZhbGlkLCBycGNDb2RlPTQwMH0gUHJvdmlkZWQgQ1JDMzJDIFwiY0grQS9BPT1cIiBkb2Vzbid0IG1hdGNoIGNhbGN1bGF0ZWQgQ1JDMzJDIFwiY0grQSt3PT1cIi5cblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRXJyb3JDb2xsZWN0b3IudG9GYXVsdChFcnJvckNvbGxlY3Rvci5qYXZhOjU0KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUVycm9yQ29udmVydGVyLnRvRmF1bHQoUm9zeUVycm9yQ29udmVydGVyLmphdmE6NjcpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyNTkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyMzkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci50aHJlYWQuVGhyZWFkVHJhY2tlcnMkVGhyZWFkVHJhY2tpbmdSdW5uYWJsZS5ydW4oVGhyZWFkVHJhY2tlcnMuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjQ1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnNlcnZlci5Db21tb25Nb2R1bGUkQ29udGV4dENhcnJ5aW5nRXhlY3V0b3JTZXJ2aWNlJDEucnVuSW5Db250ZXh0KENvbW1vbk1vZHVsZS5qYXZhOjgwMilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZSQxLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NjApXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoVHJhY2VDb250ZXh0LmphdmE6MzE5KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjMxMSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDU3KVxuXHRhdCBjb20uZ29vZ2xlLmdzZS5pbnRlcm5hbC5EaXNwYXRjaFF1ZXVlSW1wbCRXb3JrZXJUaHJlYWQucnVuKERpc3BhdGNoUXVldWVJbXBsLmphdmE6NDAzKVxuIn1dLCJjb2RlIjo0MDAsIm1lc3NhZ2UiOiJQcm92aWRlZCBDUkMzMkMgXCJjSCtBL0E9PVwiIGRvZXNuJ3QgbWF0Y2ggY2FsY3VsYXRlZCBDUkMzMkMgXCJjSCtBK3c9PVwiLiJ9fQ==" } }, { "ID": "5a293e6162b30ef3", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJuYW1lIjoiaGFzaGVzT25VcGxvYWQtMSJ9Cg==", "SSBjYW4ndCB3YWl0IHRvIGJlIHZlcmlmaWVk" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3321" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:44 GMT" ], "Etag": [ "CJuDg8/x/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqgpXYBQOYHYXTQAVb7IGna0BRqHaB7oBdZ19frcgAVGErLbEHe3bESKZ7zKSO6r0AtvqwfCEuJty95EeD5MkwqIsXbr88YcTG0j7M-g4yTKkejukI" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9oYXNoZXNPblVwbG9hZC0xLzE1NTY4MzU4ODQ2NDY4MTEiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9oYXNoZXNPblVwbG9hZC0xIiwibmFtZSI6Imhhc2hlc09uVXBsb2FkLTEiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg4NDY0NjgxMSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDo0NC42NDZaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6NDQuNjQ2WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjQ0LjY0NloiLCJzaXplIjoiMjciLCJtZDVIYXNoIjoib2ZaakdsY1hQSmlHT0FmS0ZiSmwxUT09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2hhc2hlc09uVXBsb2FkLTE/Z2VuZXJhdGlvbj0xNTU2ODM1ODg0NjQ2ODExJmFsdD1tZWRpYSIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2hhc2hlc09uVXBsb2FkLTEvMTU1NjgzNTg4NDY0NjgxMS9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9oYXNoZXNPblVwbG9hZC0xL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJoYXNoZXNPblVwbG9hZC0xIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4ODQ2NDY4MTEiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0p1RGc4L3gvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2hhc2hlc09uVXBsb2FkLTEvMTU1NjgzNTg4NDY0NjgxMS9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vaGFzaGVzT25VcGxvYWQtMS9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Imhhc2hlc09uVXBsb2FkLTEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg4NDY0NjgxMSIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNKdURnOC94L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9oYXNoZXNPblVwbG9hZC0xLzE1NTY4MzU4ODQ2NDY4MTEvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2hhc2hlc09uVXBsb2FkLTEvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJoYXNoZXNPblVwbG9hZC0xIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4ODQ2NDY4MTEiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0p1RGc4L3gvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2hhc2hlc09uVXBsb2FkLTEvMTU1NjgzNTg4NDY0NjgxMS91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vaGFzaGVzT25VcGxvYWQtMS9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Imhhc2hlc09uVXBsb2FkLTEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg4NDY0NjgxMSIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNKdURnOC94L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoiY0grQSt3PT0iLCJldGFnIjoiQ0p1RGc4L3gvZUVDRUFFPSJ9" } }, { "ID": "19f19648f1196c10", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJtZDVIYXNoIjoib2ZaakdsY1hQSmlHT0FmS0ZiSmwxUT09IiwibmFtZSI6Imhhc2hlc09uVXBsb2FkLTEifQo=", "SSBjYW4ndCB3YWl0IHRvIGJlIHZlcmlmaWVk" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3321" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:45 GMT" ], "Etag": [ "CKDem8/x/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqAmKuvPxUsjTHDB5nMuNG92dU0gql0Yol2zlvPDWEDuXHQRLhOJzYBAH207Ot-_IB22pH5QSfTaTayqEWBUfkobCR9YGVa79W0LG4fv9fnAjxk5Cs" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9oYXNoZXNPblVwbG9hZC0xLzE1NTY4MzU4ODUwNTE2ODAiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9oYXNoZXNPblVwbG9hZC0xIiwibmFtZSI6Imhhc2hlc09uVXBsb2FkLTEiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg4NTA1MTY4MCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDo0NS4wNTFaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6NDUuMDUxWiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjQ1LjA1MVoiLCJzaXplIjoiMjciLCJtZDVIYXNoIjoib2ZaakdsY1hQSmlHT0FmS0ZiSmwxUT09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2hhc2hlc09uVXBsb2FkLTE/Z2VuZXJhdGlvbj0xNTU2ODM1ODg1MDUxNjgwJmFsdD1tZWRpYSIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2hhc2hlc09uVXBsb2FkLTEvMTU1NjgzNTg4NTA1MTY4MC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9oYXNoZXNPblVwbG9hZC0xL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJoYXNoZXNPblVwbG9hZC0xIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4ODUwNTE2ODAiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0tEZW04L3gvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2hhc2hlc09uVXBsb2FkLTEvMTU1NjgzNTg4NTA1MTY4MC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vaGFzaGVzT25VcGxvYWQtMS9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Imhhc2hlc09uVXBsb2FkLTEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg4NTA1MTY4MCIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNLRGVtOC94L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9oYXNoZXNPblVwbG9hZC0xLzE1NTY4MzU4ODUwNTE2ODAvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2hhc2hlc09uVXBsb2FkLTEvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJoYXNoZXNPblVwbG9hZC0xIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4ODUwNTE2ODAiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0tEZW04L3gvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2hhc2hlc09uVXBsb2FkLTEvMTU1NjgzNTg4NTA1MTY4MC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vaGFzaGVzT25VcGxvYWQtMS9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Imhhc2hlc09uVXBsb2FkLTEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg4NTA1MTY4MCIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNLRGVtOC94L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoiY0grQSt3PT0iLCJldGFnIjoiQ0tEZW04L3gvZUVDRUFFPSJ9" } }, { "ID": "880416f9891fc25f", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJtZDVIYXNoIjoib3ZaakdsY1hQSmlHT0FmS0ZiSmwxUT09IiwibmFtZSI6Imhhc2hlc09uVXBsb2FkLTEifQo=", "SSBjYW4ndCB3YWl0IHRvIGJlIHZlcmlmaWVk" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Content-Length": [ "3515" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:45 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UoFC5_DRlr9xktR_eWpfuFqiZRbenVOATtUEg3tfJC8JbCqagKQzn0_sYLvxvG52ordbl2Nwo0L6Y0AbwuenLAo1uoX4uzHnro-JiY8MkdQEsO3uSA" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6ImludmFsaWQiLCJtZXNzYWdlIjoiUHJvdmlkZWQgTUQ1IGhhc2ggXCJvdlpqR2xjWFBKaUdPQWZLRmJKbDFRPT1cIiBkb2Vzbid0IG1hdGNoIGNhbGN1bGF0ZWQgTUQ1IGhhc2ggXCJvZlpqR2xjWFBKaUdPQWZLRmJKbDFRPT1cIi4iLCJkZWJ1Z0luZm8iOiJjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS5GYXVsdDogSW1tdXRhYmxlRXJyb3JEZWZpbml0aW9ue2Jhc2U9SU5WQUxJRF9WQUxVRSwgY2F0ZWdvcnk9VVNFUl9FUlJPUiwgY2F1c2U9bnVsbCwgZGVidWdJbmZvPW51bGwsIGRvbWFpbj1nbG9iYWwsIGV4dGVuZGVkSGVscD1udWxsLCBodHRwSGVhZGVycz17fSwgaHR0cFN0YXR1cz1iYWRSZXF1ZXN0LCBpbnRlcm5hbFJlYXNvbj1SZWFzb257YXJndW1lbnRzPXt9LCBjYXVzZT1udWxsLCBjb2RlPWdkYXRhLkNvcmVFcnJvckRvbWFpbi5JTlZBTElEX1ZBTFVFLCBjcmVhdGVkQnlCYWNrZW5kPXRydWUsIGRlYnVnTWVzc2FnZT1udWxsLCBlcnJvclByb3RvQ29kZT1JTlZBTElEX1ZBTFVFLCBlcnJvclByb3RvRG9tYWluPWdkYXRhLkNvcmVFcnJvckRvbWFpbiwgZmlsdGVyZWRNZXNzYWdlPW51bGwsIGxvY2F0aW9uPWVudGl0eS5yZXNvdXJjZS5tZDVfaGFzaF9iYXNlNjQsIG1lc3NhZ2U9UHJvdmlkZWQgTUQ1IGhhc2ggXCJvdlpqR2xjWFBKaUdPQWZLRmJKbDFRPT1cIiBkb2Vzbid0IG1hdGNoIGNhbGN1bGF0ZWQgTUQ1IGhhc2ggXCJvZlpqR2xjWFBKaUdPQWZLRmJKbDFRPT1cIi4sIHVubmFtZWRBcmd1bWVudHM9W292WmpHbGNYUEppR09BZktGYkpsMVE9PV19LCBsb2NhdGlvbj1lbnRpdHkucmVzb3VyY2UubWQ1X2hhc2hfYmFzZTY0LCBtZXNzYWdlPVByb3ZpZGVkIE1ENSBoYXNoIFwib3ZaakdsY1hQSmlHT0FmS0ZiSmwxUT09XCIgZG9lc24ndCBtYXRjaCBjYWxjdWxhdGVkIE1ENSBoYXNoIFwib2ZaakdsY1hQSmlHT0FmS0ZiSmwxUT09XCIuLCByZWFzb249aW52YWxpZCwgcnBjQ29kZT00MDB9IFByb3ZpZGVkIE1ENSBoYXNoIFwib3ZaakdsY1hQSmlHT0FmS0ZiSmwxUT09XCIgZG9lc24ndCBtYXRjaCBjYWxjdWxhdGVkIE1ENSBoYXNoIFwib2ZaakdsY1hQSmlHT0FmS0ZiSmwxUT09XCIuXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLkVycm9yQ29sbGVjdG9yLnRvRmF1bHQoRXJyb3JDb2xsZWN0b3IuamF2YTo1NClcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lFcnJvckNvbnZlcnRlci50b0ZhdWx0KFJvc3lFcnJvckNvbnZlcnRlci5qYXZhOjY3KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUhhbmRsZXIkMi5jYWxsKFJvc3lIYW5kbGVyLmphdmE6MjU5KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUhhbmRsZXIkMi5jYWxsKFJvc3lIYW5kbGVyLmphdmE6MjM5KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRGlyZWN0RXhlY3V0b3IuZXhlY3V0ZShEaXJlY3RFeGVjdXRvci5qYXZhOjMwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuZXhlY3V0ZUxpc3RlbmVyKEFic3RyYWN0RnV0dXJlLmphdmE6MTE0Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmNvbXBsZXRlKEFic3RyYWN0RnV0dXJlLmphdmE6OTYzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuc2V0KEFic3RyYWN0RnV0dXJlLmphdmE6NzMxKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRGlyZWN0RXhlY3V0b3IuZXhlY3V0ZShEaXJlY3RFeGVjdXRvci5qYXZhOjMwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuZXhlY3V0ZUxpc3RlbmVyKEFic3RyYWN0RnV0dXJlLmphdmE6MTE0Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmNvbXBsZXRlKEFic3RyYWN0RnV0dXJlLmphdmE6OTYzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuc2V0KEFic3RyYWN0RnV0dXJlLmphdmE6NzMxKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIudGhyZWFkLlRocmVhZFRyYWNrZXJzJFRocmVhZFRyYWNraW5nUnVubmFibGUucnVuKFRocmVhZFRyYWNrZXJzLmphdmE6MTI2KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChUcmFjZUNvbnRleHQuamF2YTo0NTMpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5zZXJ2ZXIuQ29tbW9uTW9kdWxlJENvbnRleHRDYXJyeWluZ0V4ZWN1dG9yU2VydmljZSQxLnJ1bkluQ29udGV4dChDb21tb25Nb2R1bGUuamF2YTo4MDIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUkMS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDYwKVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkQWJzdHJhY3RUcmFjZUNvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKFRyYWNlQ29udGV4dC5qYXZhOjMxOSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChUcmFjZUNvbnRleHQuamF2YTozMTEpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuKFRyYWNlQ29udGV4dC5qYXZhOjQ1Nylcblx0YXQgY29tLmdvb2dsZS5nc2UuaW50ZXJuYWwuRGlzcGF0Y2hRdWV1ZUltcGwkV29ya2VyVGhyZWFkLnJ1bihEaXNwYXRjaFF1ZXVlSW1wbC5qYXZhOjQwMylcbiJ9XSwiY29kZSI6NDAwLCJtZXNzYWdlIjoiUHJvdmlkZWQgTUQ1IGhhc2ggXCJvdlpqR2xjWFBKaUdPQWZLRmJKbDFRPT1cIiBkb2Vzbid0IG1hdGNoIGNhbGN1bGF0ZWQgTUQ1IGhhc2ggXCJvZlpqR2xjWFBKaUdPQWZLRmJKbDFRPT1cIi4ifX0=" } }, { "ID": "e1a7bef7c2f0f7b9", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/iam?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "341" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:45 GMT" ], "Etag": [ "CAo=" ], "Expires": [ "Thu, 02 May 2019 22:24:45 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrDioJ0fktjtyI_mABE4-oH9KqDlurM5mWiYDhoDp_LRJYSPvDxjuoaYzNhjoTHdHPALySTzCxScTstm27R-praR27EAm4Gx9k3wHAAwKJUptqRnFE" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNwb2xpY3kiLCJyZXNvdXJjZUlkIjoicHJvamVjdHMvXy9idWNrZXRzL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsImJpbmRpbmdzIjpbeyJyb2xlIjoicm9sZXMvc3RvcmFnZS5sZWdhY3lCdWNrZXRPd25lciIsIm1lbWJlcnMiOlsicHJvamVjdEVkaXRvcjpkZWtsZXJrLXNhbmRib3giLCJwcm9qZWN0T3duZXI6ZGVrbGVyay1zYW5kYm94Il19LHsicm9sZSI6InJvbGVzL3N0b3JhZ2UubGVnYWN5QnVja2V0UmVhZGVyIiwibWVtYmVycyI6WyJwcm9qZWN0Vmlld2VyOmRla2xlcmstc2FuZGJveCJdfV0sImV0YWciOiJDQW89In0=" } }, { "ID": "df5371a2b0cd8c3b", "Request": { "Method": "PUT", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/iam?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "317" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJiaW5kaW5ncyI6W3sibWVtYmVycyI6WyJwcm9qZWN0RWRpdG9yOmRla2xlcmstc2FuZGJveCIsInByb2plY3RPd25lcjpkZWtsZXJrLXNhbmRib3giXSwicm9sZSI6InJvbGVzL3N0b3JhZ2UubGVnYWN5QnVja2V0T3duZXIifSx7Im1lbWJlcnMiOlsicHJvamVjdFZpZXdlcjpkZWtsZXJrLXNhbmRib3giXSwicm9sZSI6InJvbGVzL3N0b3JhZ2UubGVnYWN5QnVja2V0UmVhZGVyIn0seyJtZW1iZXJzIjpbInByb2plY3RWaWV3ZXI6ZGVrbGVyay1zYW5kYm94Il0sInJvbGUiOiJyb2xlcy9zdG9yYWdlLm9iamVjdFZpZXdlciJ9XSwiZXRhZyI6IkNBbz0ifQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "423" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:46 GMT" ], "Etag": [ "CAs=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrAVgetrpv1xjtKv2B7KFBdnbg20V-btiRn3sD4kQF7shWIQ1-FqJMRsbYfcYJyTMQHv_BhW_eVzvcc56z0LOcYfE-wbCRZpqYjen6c-bVcMzPet2A" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNwb2xpY3kiLCJyZXNvdXJjZUlkIjoicHJvamVjdHMvXy9idWNrZXRzL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsImJpbmRpbmdzIjpbeyJyb2xlIjoicm9sZXMvc3RvcmFnZS5sZWdhY3lCdWNrZXRPd25lciIsIm1lbWJlcnMiOlsicHJvamVjdEVkaXRvcjpkZWtsZXJrLXNhbmRib3giLCJwcm9qZWN0T3duZXI6ZGVrbGVyay1zYW5kYm94Il19LHsicm9sZSI6InJvbGVzL3N0b3JhZ2UubGVnYWN5QnVja2V0UmVhZGVyIiwibWVtYmVycyI6WyJwcm9qZWN0Vmlld2VyOmRla2xlcmstc2FuZGJveCJdfSx7InJvbGUiOiJyb2xlcy9zdG9yYWdlLm9iamVjdFZpZXdlciIsIm1lbWJlcnMiOlsicHJvamVjdFZpZXdlcjpkZWtsZXJrLXNhbmRib3giXX1dLCJldGFnIjoiQ0FzPSJ9" } }, { "ID": "feaa4b1a4dda0450", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/iam?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "423" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:46 GMT" ], "Etag": [ "CAs=" ], "Expires": [ "Thu, 02 May 2019 22:24:46 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqwMVZVQQ8s-ZBUJDLKyC-qMMTANncoBhRQWlMCITVUXQrTnFGGxu4GdKyVcuudrSa-DWy5w5iLE-i4a407GopUNma3xIq1eNiyVAziPD7jQ4YluzA" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNwb2xpY3kiLCJyZXNvdXJjZUlkIjoicHJvamVjdHMvXy9idWNrZXRzL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsImJpbmRpbmdzIjpbeyJyb2xlIjoicm9sZXMvc3RvcmFnZS5sZWdhY3lCdWNrZXRPd25lciIsIm1lbWJlcnMiOlsicHJvamVjdEVkaXRvcjpkZWtsZXJrLXNhbmRib3giLCJwcm9qZWN0T3duZXI6ZGVrbGVyay1zYW5kYm94Il19LHsicm9sZSI6InJvbGVzL3N0b3JhZ2UubGVnYWN5QnVja2V0UmVhZGVyIiwibWVtYmVycyI6WyJwcm9qZWN0Vmlld2VyOmRla2xlcmstc2FuZGJveCJdfSx7InJvbGUiOiJyb2xlcy9zdG9yYWdlLm9iamVjdFZpZXdlciIsIm1lbWJlcnMiOlsicHJvamVjdFZpZXdlcjpkZWtsZXJrLXNhbmRib3giXX1dLCJldGFnIjoiQ0FzPSJ9" } }, { "ID": "23d94c8a09c0c334", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/iam/testPermissions?alt=json\u0026permissions=storage.buckets.get\u0026permissions=storage.buckets.delete\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "108" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:46 GMT" ], "Expires": [ "Thu, 02 May 2019 22:24:46 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoR-XKWu9nOWmFZve2-NeDyDvZDo5rYpPD3avVEmZkZ-lODvHCSR0D7zdPeCa61L5EtOIYJBqmC0D9Xc229A1GDS5d91vgAGuzRoxRnNa9DjBw68xM" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSN0ZXN0SWFtUGVybWlzc2lvbnNSZXNwb25zZSIsInBlcm1pc3Npb25zIjpbInN0b3JhZ2UuYnVja2V0cy5nZXQiLCJzdG9yYWdlLmJ1Y2tldHMuZGVsZXRlIl19" } }, { "ID": "3d0a13fe961ed15c", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b?alt=json\u0026prettyPrint=false\u0026project=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "93" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJiaWxsaW5nIjp7InJlcXVlc3RlclBheXMiOnRydWV9LCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIn0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "518" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:47 GMT" ], "Etag": [ "CAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoIRjhruHo5rweyX35Zt-Mzm5UDD5vr4319gSNjtnJHD2RWtVLvQdjuZ0jv-XKT3s1xcJO7CvoU-qAehCknukI5ssvv2LgwazyhnkcuFws3isqM9uo" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjQ2LjgwM1oiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDo0Ni44MDNaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiaWFtQ29uZmlndXJhdGlvbiI6eyJidWNrZXRQb2xpY3lPbmx5Ijp7ImVuYWJsZWQiOmZhbHNlfX0sImxvY2F0aW9uIjoiVVMiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsImJpbGxpbmciOnsicmVxdWVzdGVyUGF5cyI6dHJ1ZX0sImV0YWciOiJDQUU9In0=" } }, { "ID": "c1f385994f4db8e3", "Request": { "Method": "PUT", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/acl/user-integration%40gcloud-golang-firestore-tests.iam.gserviceaccount.com?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "159" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJlbnRpdHkiOiJ1c2VyLWludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIn0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "589" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:48 GMT" ], "Etag": [ "CAI=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UozEPu-BKQnmBUxTwsOWB7mmIPC5lppmUt6lA150OiXgQttSVRetVysUp299p7PbjI08qchUQl2idgMbfBCScDL5SuoHi_u9ani0DXYX2OV9QXAovQ" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvdXNlci1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9hY2wvdXNlci1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsImVudGl0eSI6InVzZXItaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNBST0ifQ==" } }, { "ID": "ccb3141a79c55333", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "3054" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:48 GMT" ], "Etag": [ "CAI=" ], "Expires": [ "Thu, 02 May 2019 22:24:48 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoG9XpooOFPlHtC8fg7llzYYETQUMEm0PvG4TbxBF5KdfCdB_sxNi0Yy9KrAmMDPBVyq0Iuaq7mzQOhQe9lXe5PBOc8-CGTXZiEMkMMJe3OYxjExIM" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjQ2LjgwM1oiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDo0Ny45MTlaIiwibWV0YWdlbmVyYXRpb24iOiIyIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FJPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvdXNlci1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9hY2wvdXNlci1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsImVudGl0eSI6InVzZXItaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNBST0ifV0sImRlZmF1bHRPYmplY3RBY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FJPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNBST0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0FJPSJ9XSwiaWFtQ29uZmlndXJhdGlvbiI6eyJidWNrZXRQb2xpY3lPbmx5Ijp7ImVuYWJsZWQiOmZhbHNlfX0sIm93bmVyIjp7ImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCJ9LCJsb2NhdGlvbiI6IlVTIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJiaWxsaW5nIjp7InJlcXVlc3RlclBheXMiOnRydWV9LCJldGFnIjoiQ0FJPSJ9" } }, { "ID": "2d4244737318f2d5", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003?alt=json\u0026prettyPrint=false\u0026projection=full\u0026userProject=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "3054" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:48 GMT" ], "Etag": [ "CAI=" ], "Expires": [ "Thu, 02 May 2019 22:24:48 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uqn_UdEXhLLXE1QsYjwtyqQlzX3nDvpAO1WNpRkHhyV39RJKkxMBrcd8f6Xo3VZFDps7iKuQHnW49yRqjh42062lkisOH7otDXrdAKAih4Iz9fzERM" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjQ2LjgwM1oiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDo0Ny45MTlaIiwibWV0YWdlbmVyYXRpb24iOiIyIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FJPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvdXNlci1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9hY2wvdXNlci1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsImVudGl0eSI6InVzZXItaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNBST0ifV0sImRlZmF1bHRPYmplY3RBY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FJPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNBST0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0FJPSJ9XSwiaWFtQ29uZmlndXJhdGlvbiI6eyJidWNrZXRQb2xpY3lPbmx5Ijp7ImVuYWJsZWQiOmZhbHNlfX0sIm93bmVyIjp7ImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCJ9LCJsb2NhdGlvbiI6IlVTIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJiaWxsaW5nIjp7InJlcXVlc3RlclBheXMiOnRydWV9LCJldGFnIjoiQ0FJPSJ9" } }, { "ID": "b63c3951975a766e", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "12183" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:49 GMT" ], "Expires": [ "Thu, 02 May 2019 22:24:49 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2Uq-LP6kQLHNpjT5jYVkPzNXyfr838sGr4jGMVPq-FOq01ayCWvyWVAsvUbxp0NSdOYJcW-z0i2NkQLuSKGQYrX_3z8LW1Vb4uL2jxfC8kSiuz28hkA" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6InJlcXVpcmVkIiwibWVzc2FnZSI6IkJ1Y2tldCBpcyByZXF1ZXN0ZXIgcGF5cyBidWNrZXQgYnV0IG5vIHVzZXIgcHJvamVjdCBwcm92aWRlZC4iLCJkZWJ1Z0luZm8iOiJjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX01JU1NJTkc6IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYnVja2V0cy5HZXRCdWNrZXQuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEdldEJ1Y2tldC5qYXZhOjEwNClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5idWNrZXRzLkdldEJ1Y2tldC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoR2V0QnVja2V0LmphdmE6MzMpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLkJ1Y2tldHNEZWxlZ2F0b3IuZ2V0KEJ1Y2tldHNEZWxlZ2F0b3IuamF2YTo4Mylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogQnVja2V0IGlzIFJlcXVlc3RlciBQYXlzIGJ1Y2tldCBidXQgbm8gYmlsbGluZyBwcm9qZWN0IGlkIHByb3ZpZGVkIGZvciBub24tb3duZXIuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPVJFUVVJUkVELCBjYXRlZ29yeT1VU0VSX0VSUk9SLCBjYXVzZT1udWxsLCBkZWJ1Z0luZm89Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuR2V0QnVja2V0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChHZXRCdWNrZXQuamF2YToxMDQpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYnVja2V0cy5HZXRCdWNrZXQuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEdldEJ1Y2tldC5qYXZhOjMzKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5CdWNrZXRzRGVsZWdhdG9yLmdldChCdWNrZXRzRGVsZWdhdG9yLmphdmE6ODMpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGRvbWFpbj1nbG9iYWwsIGV4dGVuZGVkSGVscD1udWxsLCBodHRwSGVhZGVycz17fSwgaHR0cFN0YXR1cz1iYWRSZXF1ZXN0LCBpbnRlcm5hbFJlYXNvbj1SZWFzb257YXJndW1lbnRzPXt9LCBjYXVzZT1udWxsLCBjb2RlPWdkYXRhLkNvcmVFcnJvckRvbWFpbi5SRVFVSVJFRCwgY3JlYXRlZEJ5QmFja2VuZD10cnVlLCBkZWJ1Z01lc3NhZ2U9Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuR2V0QnVja2V0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChHZXRCdWNrZXQuamF2YToxMDQpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYnVja2V0cy5HZXRCdWNrZXQuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEdldEJ1Y2tldC5qYXZhOjMzKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5CdWNrZXRzRGVsZWdhdG9yLmdldChCdWNrZXRzRGVsZWdhdG9yLmphdmE6ODMpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGVycm9yUHJvdG9Db2RlPVJFUVVJUkVELCBlcnJvclByb3RvRG9tYWluPWdkYXRhLkNvcmVFcnJvckRvbWFpbiwgZmlsdGVyZWRNZXNzYWdlPW51bGwsIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9QnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLiwgdW5uYW1lZEFyZ3VtZW50cz1bXX0sIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9QnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLiwgcmVhc29uPXJlcXVpcmVkLCBycGNDb2RlPTQwMH0gQnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLjogY29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuR2V0QnVja2V0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChHZXRCdWNrZXQuamF2YToxMDQpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYnVja2V0cy5HZXRCdWNrZXQuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEdldEJ1Y2tldC5qYXZhOjMzKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5CdWNrZXRzRGVsZWdhdG9yLmdldChCdWNrZXRzRGVsZWdhdG9yLmphdmE6ODMpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRXJyb3JDb2xsZWN0b3IudG9GYXVsdChFcnJvckNvbGxlY3Rvci5qYXZhOjU0KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUVycm9yQ29udmVydGVyLnRvRmF1bHQoUm9zeUVycm9yQ29udmVydGVyLmphdmE6NjcpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyNTkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyMzkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci50aHJlYWQuVGhyZWFkVHJhY2tlcnMkVGhyZWFkVHJhY2tpbmdSdW5uYWJsZS5ydW4oVGhyZWFkVHJhY2tlcnMuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjQ1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnNlcnZlci5Db21tb25Nb2R1bGUkQ29udGV4dENhcnJ5aW5nRXhlY3V0b3JTZXJ2aWNlJDEucnVuSW5Db250ZXh0KENvbW1vbk1vZHVsZS5qYXZhOjgwMilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZSQxLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NjApXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoVHJhY2VDb250ZXh0LmphdmE6MzE5KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjMxMSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDU3KVxuXHRhdCBjb20uZ29vZ2xlLmdzZS5pbnRlcm5hbC5EaXNwYXRjaFF1ZXVlSW1wbCRXb3JrZXJUaHJlYWQucnVuKERpc3BhdGNoUXVldWVJbXBsLmphdmE6NDAzKVxuIn1dLCJjb2RlIjo0MDAsIm1lc3NhZ2UiOiJCdWNrZXQgaXMgcmVxdWVzdGVyIHBheXMgYnVja2V0IGJ1dCBubyB1c2VyIHByb2plY3QgcHJvdmlkZWQuIn19" } }, { "ID": "0764f2598b67c664", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003?alt=json\u0026prettyPrint=false\u0026projection=full\u0026userProject=gcloud-golang-firestore-tests", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "3054" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:49 GMT" ], "Etag": [ "CAI=" ], "Expires": [ "Thu, 02 May 2019 22:24:49 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrGddSv5GSaZB7qBmb0PigbMbJmWs91JB0W99oOTcbMeUk9QeBf-7QF7W_BpAn3wNxqVD5cBDPgGuKrZCfYv77SgCGxcPW-jrXsUY5h50q8eFL0_3o" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjQ2LjgwM1oiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDo0Ny45MTlaIiwibWV0YWdlbmVyYXRpb24iOiIyIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FJPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvdXNlci1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9hY2wvdXNlci1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsImVudGl0eSI6InVzZXItaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNBST0ifV0sImRlZmF1bHRPYmplY3RBY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FJPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNBST0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0FJPSJ9XSwiaWFtQ29uZmlndXJhdGlvbiI6eyJidWNrZXRQb2xpY3lPbmx5Ijp7ImVuYWJsZWQiOmZhbHNlfX0sIm93bmVyIjp7ImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCJ9LCJsb2NhdGlvbiI6IlVTIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJiaWxsaW5nIjp7InJlcXVlc3RlclBheXMiOnRydWV9LCJldGFnIjoiQ0FJPSJ9" } }, { "ID": "bdb0ff507e4df251", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003?alt=json\u0026prettyPrint=false\u0026projection=full\u0026userProject=veener-jba", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 403, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "13039" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:49 GMT" ], "Expires": [ "Thu, 02 May 2019 22:24:49 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2Up8t6bOWiJucB8KpVlIp8WjWLSUKssQaynZNguVy_oBM2ggBePUFnoteMcbw_L9aSHoD4hwi91dMaBC4aVc6VuaMSBSVuCe0L_0IymxhBIx3SRj_As" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6ImZvcmJpZGRlbiIsIm1lc3NhZ2UiOiJpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpVU0VSX1BST0pFQ1RfQUNDRVNTX0RFTklFRDogaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20gZG9lcyBub3QgaGF2ZSBzZXJ2aWNldXNhZ2Uuc2VydmljZXMudXNlIGFjY2VzcyB0byBwcm9qZWN0IDY0MjA4MDkxODEwMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuR2V0QnVja2V0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChHZXRCdWNrZXQuamF2YToxMDQpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYnVja2V0cy5HZXRCdWNrZXQuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEdldEJ1Y2tldC5qYXZhOjMzKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5CdWNrZXRzRGVsZWdhdG9yLmdldChCdWNrZXRzRGVsZWdhdG9yLmphdmE6ODMpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPUZPUkJJRERFTiwgY2F0ZWdvcnk9VVNFUl9FUlJPUiwgY2F1c2U9bnVsbCwgZGVidWdJbmZvPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpVU0VSX1BST0pFQ1RfQUNDRVNTX0RFTklFRDogaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20gZG9lcyBub3QgaGF2ZSBzZXJ2aWNldXNhZ2Uuc2VydmljZXMudXNlIGFjY2VzcyB0byBwcm9qZWN0IDY0MjA4MDkxODEwMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuR2V0QnVja2V0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChHZXRCdWNrZXQuamF2YToxMDQpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYnVja2V0cy5HZXRCdWNrZXQuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEdldEJ1Y2tldC5qYXZhOjMzKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5CdWNrZXRzRGVsZWdhdG9yLmdldChCdWNrZXRzRGVsZWdhdG9yLmphdmE6ODMpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZG9tYWluPWdsb2JhbCwgZXh0ZW5kZWRIZWxwPW51bGwsIGh0dHBIZWFkZXJzPXt9LCBodHRwU3RhdHVzPWZvcmJpZGRlbiwgaW50ZXJuYWxSZWFzb249UmVhc29ue2FyZ3VtZW50cz17fSwgY2F1c2U9bnVsbCwgY29kZT1nZGF0YS5Db3JlRXJyb3JEb21haW4uRk9SQklEREVOLCBjcmVhdGVkQnlCYWNrZW5kPXRydWUsIGRlYnVnTWVzc2FnZT1jb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX0FDQ0VTU19ERU5JRUQ6IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5idWNrZXRzLkdldEJ1Y2tldC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoR2V0QnVja2V0LmphdmE6MTA0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuR2V0QnVja2V0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChHZXRCdWNrZXQuamF2YTozMylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQnVja2V0c0RlbGVnYXRvci5nZXQoQnVja2V0c0RlbGVnYXRvci5qYXZhOjgzKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGVycm9yUHJvdG9Db2RlPUZPUkJJRERFTiwgZXJyb3JQcm90b0RvbWFpbj1nZGF0YS5Db3JlRXJyb3JEb21haW4sIGZpbHRlcmVkTWVzc2FnZT1udWxsLCBsb2NhdGlvbj1udWxsLCBtZXNzYWdlPWludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuLCB1bm5hbWVkQXJndW1lbnRzPVtdfSwgbG9jYXRpb249bnVsbCwgbWVzc2FnZT1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiwgcmVhc29uPWZvcmJpZGRlbiwgcnBjQ29kZT00MDN9IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuOiBjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX0FDQ0VTU19ERU5JRUQ6IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5idWNrZXRzLkdldEJ1Y2tldC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoR2V0QnVja2V0LmphdmE6MTA0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuR2V0QnVja2V0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChHZXRCdWNrZXQuamF2YTozMylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQnVja2V0c0RlbGVnYXRvci5nZXQoQnVja2V0c0RlbGVnYXRvci5qYXZhOjgzKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRXJyb3JDb2xsZWN0b3IudG9GYXVsdChFcnJvckNvbGxlY3Rvci5qYXZhOjU0KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUVycm9yQ29udmVydGVyLnRvRmF1bHQoUm9zeUVycm9yQ29udmVydGVyLmphdmE6NjcpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyNTkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyMzkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci50aHJlYWQuVGhyZWFkVHJhY2tlcnMkVGhyZWFkVHJhY2tpbmdSdW5uYWJsZS5ydW4oVGhyZWFkVHJhY2tlcnMuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjQ1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnNlcnZlci5Db21tb25Nb2R1bGUkQ29udGV4dENhcnJ5aW5nRXhlY3V0b3JTZXJ2aWNlJDEucnVuSW5Db250ZXh0KENvbW1vbk1vZHVsZS5qYXZhOjgwMilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZSQxLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NjApXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoVHJhY2VDb250ZXh0LmphdmE6MzE5KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjMxMSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDU3KVxuXHRhdCBjb20uZ29vZ2xlLmdzZS5pbnRlcm5hbC5EaXNwYXRjaFF1ZXVlSW1wbCRXb3JrZXJUaHJlYWQucnVuKERpc3BhdGNoUXVldWVJbXBsLmphdmE6NDAzKVxuIn1dLCJjb2RlIjo0MDMsIm1lc3NhZ2UiOiJpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiJ9fQ==" } }, { "ID": "d2e66ae2cc0d11bc", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW4iLCJuYW1lIjoiZm9vIn0K", "aGVsbG8=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3133" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:50 GMT" ], "Etag": [ "COq52NHx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqQ_qlqWPPh6t8-gwPlD5zRB96zsmFgzyez4LG3XN4uErivnyHcCeeHje_i95VLJcWYXn7_-knEn0faPBCCAIStf4fXGs_Lz_VzHK6CLBZjU-oBxcU" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTg5MDI0MDc0NiIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2ZvbyIsIm5hbWUiOiJmb28iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg5MDI0MDc0NiIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDo1MC4yNDBaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6NTAuMjQwWiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjUwLjI0MFoiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vP2dlbmVyYXRpb249MTU1NjgzNTg5MDI0MDc0NiZhbHQ9bWVkaWEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTg5MDI0MDc0Ni9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvby9mb28vYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsIm9iamVjdCI6ImZvbyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODkwMjQwNzQ2IiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNPcTUyTkh4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTg5MDI0MDc0Ni9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwib2JqZWN0IjoiZm9vIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4OTAyNDA3NDYiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDT3E1Mk5IeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvZm9vLzE1NTY4MzU4OTAyNDA3NDYvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2Zvby9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsIm9iamVjdCI6ImZvbyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODkwMjQwNzQ2IiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNPcTUyTkh4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTg5MDI0MDc0Ni91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwib2JqZWN0IjoiZm9vIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4OTAyNDA3NDYiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDT3E1Mk5IeC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNPcTUyTkh4L2VFQ0VBRT0ifQ==" } }, { "ID": "89b2bc9232a865a4", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart\u0026userProject=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW4iLCJuYW1lIjoiZm9vIn0K", "aGVsbG8=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3133" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:50 GMT" ], "Etag": [ "CJTz9tHx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrymnpCwS6vZ0kM33ZD4nBupWs9hAuaOGpwiNcS4GJctgaLPe9CQ0Ada06yQV1aEfh9FtX6lgYh9jHwbsT6qdgOYOYe9yGDdAF9f91aE4y4VUHQHts" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTg5MDczOTYwNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2ZvbyIsIm5hbWUiOiJmb28iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg5MDczOTYwNCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDo1MC43MzlaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6NTAuNzM5WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjUwLjczOVoiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vP2dlbmVyYXRpb249MTU1NjgzNTg5MDczOTYwNCZhbHQ9bWVkaWEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTg5MDczOTYwNC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvby9mb28vYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsIm9iamVjdCI6ImZvbyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODkwNzM5NjA0IiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNKVHo5dEh4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTg5MDczOTYwNC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwib2JqZWN0IjoiZm9vIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4OTA3Mzk2MDQiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDSlR6OXRIeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvZm9vLzE1NTY4MzU4OTA3Mzk2MDQvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2Zvby9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsIm9iamVjdCI6ImZvbyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODkwNzM5NjA0IiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNKVHo5dEh4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTg5MDczOTYwNC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwib2JqZWN0IjoiZm9vIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4OTA3Mzk2MDQiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDSlR6OXRIeC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNKVHo5dEh4L2VFQ0VBRT0ifQ==" } }, { "ID": "a70634faba29225b", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW4iLCJuYW1lIjoiZm9vIn0K", "aGVsbG8=" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Content-Length": [ "12243" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:51 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UqsIKUUc6WyIHUlDvAIDlXVeOofVG4sVV3Rus8ktfPMTUTI7e4PH4657AoDnNOKKy9TOgt8yUtUvCNvDFQC1xwVApFofRhWT3kcjsEYRgZPCDDsUqM" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6InJlcXVpcmVkIiwibWVzc2FnZSI6IkJ1Y2tldCBpcyByZXF1ZXN0ZXIgcGF5cyBidWNrZXQgYnV0IG5vIHVzZXIgcHJvamVjdCBwcm92aWRlZC4iLCJkZWJ1Z0luZm8iOiJjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX01JU1NJTkc6IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5JbnNlcnRPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEluc2VydE9iamVjdC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkluc2VydE9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoSW5zZXJ0T2JqZWN0LmphdmE6NDQpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLk9iamVjdHNEZWxlZ2F0b3IuaW5zZXJ0KE9iamVjdHNEZWxlZ2F0b3IuamF2YTo5NSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogQnVja2V0IGlzIFJlcXVlc3RlciBQYXlzIGJ1Y2tldCBidXQgbm8gYmlsbGluZyBwcm9qZWN0IGlkIHByb3ZpZGVkIGZvciBub24tb3duZXIuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPVJFUVVJUkVELCBjYXRlZ29yeT1VU0VSX0VSUk9SLCBjYXVzZT1udWxsLCBkZWJ1Z0luZm89Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuSW5zZXJ0T2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRPYmplY3QuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5JbnNlcnRPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEluc2VydE9iamVjdC5qYXZhOjQ0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLmluc2VydChPYmplY3RzRGVsZWdhdG9yLmphdmE6OTUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGRvbWFpbj1nbG9iYWwsIGV4dGVuZGVkSGVscD1udWxsLCBodHRwSGVhZGVycz17fSwgaHR0cFN0YXR1cz1iYWRSZXF1ZXN0LCBpbnRlcm5hbFJlYXNvbj1SZWFzb257YXJndW1lbnRzPXt9LCBjYXVzZT1udWxsLCBjb2RlPWdkYXRhLkNvcmVFcnJvckRvbWFpbi5SRVFVSVJFRCwgY3JlYXRlZEJ5QmFja2VuZD10cnVlLCBkZWJ1Z01lc3NhZ2U9Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuSW5zZXJ0T2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRPYmplY3QuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5JbnNlcnRPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEluc2VydE9iamVjdC5qYXZhOjQ0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLmluc2VydChPYmplY3RzRGVsZWdhdG9yLmphdmE6OTUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGVycm9yUHJvdG9Db2RlPVJFUVVJUkVELCBlcnJvclByb3RvRG9tYWluPWdkYXRhLkNvcmVFcnJvckRvbWFpbiwgZmlsdGVyZWRNZXNzYWdlPW51bGwsIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9QnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLiwgdW5uYW1lZEFyZ3VtZW50cz1bXX0sIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9QnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLiwgcmVhc29uPXJlcXVpcmVkLCBycGNDb2RlPTQwMH0gQnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLjogY29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuSW5zZXJ0T2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRPYmplY3QuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5JbnNlcnRPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEluc2VydE9iamVjdC5qYXZhOjQ0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLmluc2VydChPYmplY3RzRGVsZWdhdG9yLmphdmE6OTUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRXJyb3JDb2xsZWN0b3IudG9GYXVsdChFcnJvckNvbGxlY3Rvci5qYXZhOjU0KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUVycm9yQ29udmVydGVyLnRvRmF1bHQoUm9zeUVycm9yQ29udmVydGVyLmphdmE6NjcpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyNTkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyMzkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci50aHJlYWQuVGhyZWFkVHJhY2tlcnMkVGhyZWFkVHJhY2tpbmdSdW5uYWJsZS5ydW4oVGhyZWFkVHJhY2tlcnMuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjQ1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnNlcnZlci5Db21tb25Nb2R1bGUkQ29udGV4dENhcnJ5aW5nRXhlY3V0b3JTZXJ2aWNlJDEucnVuSW5Db250ZXh0KENvbW1vbk1vZHVsZS5qYXZhOjgwMilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZSQxLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NjApXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoVHJhY2VDb250ZXh0LmphdmE6MzE5KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjMxMSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDU3KVxuXHRhdCBjb20uZ29vZ2xlLmdzZS5pbnRlcm5hbC5EaXNwYXRjaFF1ZXVlSW1wbCRXb3JrZXJUaHJlYWQucnVuKERpc3BhdGNoUXVldWVJbXBsLmphdmE6NDAzKVxuIn1dLCJjb2RlIjo0MDAsIm1lc3NhZ2UiOiJCdWNrZXQgaXMgcmVxdWVzdGVyIHBheXMgYnVja2V0IGJ1dCBubyB1c2VyIHByb2plY3QgcHJvdmlkZWQuIn19" } }, { "ID": "5539336327f2e0ba", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart\u0026userProject=gcloud-golang-firestore-tests", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW4iLCJuYW1lIjoiZm9vIn0K", "aGVsbG8=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3193" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:51 GMT" ], "Etag": [ "COGeqNLx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrH7pn9r8O1Zu1Nc2aNUO_CO75MyvOJyONGw27TUkfWRSSmFIWJUZ6F3e3OprVF5jKtAkQ73puZbyNCK6mozyHrmPRRa0mtyuBPhkYg4DzPGkXJOSU" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTg5MTU0ODAwMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2ZvbyIsIm5hbWUiOiJmb28iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg5MTU0ODAwMSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDo1MS41NDdaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6NTEuNTQ3WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjUxLjU0N1oiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vP2dlbmVyYXRpb249MTU1NjgzNTg5MTU0ODAwMSZhbHQ9bWVkaWEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTg5MTU0ODAwMS9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvby9mb28vYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsIm9iamVjdCI6ImZvbyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODkxNTQ4MDAxIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNPR2VxTkx4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTg5MTU0ODAwMS9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwib2JqZWN0IjoiZm9vIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4OTE1NDgwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDT0dlcU5MeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvZm9vLzE1NTY4MzU4OTE1NDgwMDEvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2Zvby9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsIm9iamVjdCI6ImZvbyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODkxNTQ4MDAxIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNPR2VxTkx4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTg5MTU0ODAwMS91c2VyLWludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vL2FjbC91c2VyLWludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwib2JqZWN0IjoiZm9vIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4OTE1NDgwMDEiLCJlbnRpdHkiOiJ1c2VyLWludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDT0dlcU5MeC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNPR2VxTkx4L2VFQ0VBRT0ifQ==" } }, { "ID": "029ec3d54709e7ce", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart\u0026userProject=veener-jba", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW4iLCJuYW1lIjoiZm9vIn0K", "aGVsbG8=" ] }, "Response": { "StatusCode": 403, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Content-Length": [ "13099" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:52 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UqcpItVCw5LaIWvDckOjfoChIifJGtuURBAmgtpzzna_iVOfDSaQOhxiMDVfYkV3mKG7__z0WTNRdVpa2Zs2IPcIAKwqwSeIMaLtz--MluSCHv9kc8" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6ImZvcmJpZGRlbiIsIm1lc3NhZ2UiOiJpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpVU0VSX1BST0pFQ1RfQUNDRVNTX0RFTklFRDogaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20gZG9lcyBub3QgaGF2ZSBzZXJ2aWNldXNhZ2Uuc2VydmljZXMudXNlIGFjY2VzcyB0byBwcm9qZWN0IDY0MjA4MDkxODEwMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuSW5zZXJ0T2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRPYmplY3QuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5JbnNlcnRPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEluc2VydE9iamVjdC5qYXZhOjQ0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLmluc2VydChPYmplY3RzRGVsZWdhdG9yLmphdmE6OTUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPUZPUkJJRERFTiwgY2F0ZWdvcnk9VVNFUl9FUlJPUiwgY2F1c2U9bnVsbCwgZGVidWdJbmZvPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpVU0VSX1BST0pFQ1RfQUNDRVNTX0RFTklFRDogaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20gZG9lcyBub3QgaGF2ZSBzZXJ2aWNldXNhZ2Uuc2VydmljZXMudXNlIGFjY2VzcyB0byBwcm9qZWN0IDY0MjA4MDkxODEwMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuSW5zZXJ0T2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRPYmplY3QuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5JbnNlcnRPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEluc2VydE9iamVjdC5qYXZhOjQ0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLmluc2VydChPYmplY3RzRGVsZWdhdG9yLmphdmE6OTUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZG9tYWluPWdsb2JhbCwgZXh0ZW5kZWRIZWxwPW51bGwsIGh0dHBIZWFkZXJzPXt9LCBodHRwU3RhdHVzPWZvcmJpZGRlbiwgaW50ZXJuYWxSZWFzb249UmVhc29ue2FyZ3VtZW50cz17fSwgY2F1c2U9bnVsbCwgY29kZT1nZGF0YS5Db3JlRXJyb3JEb21haW4uRk9SQklEREVOLCBjcmVhdGVkQnlCYWNrZW5kPXRydWUsIGRlYnVnTWVzc2FnZT1jb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX0FDQ0VTU19ERU5JRUQ6IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkluc2VydE9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoSW5zZXJ0T2JqZWN0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuSW5zZXJ0T2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRPYmplY3QuamF2YTo0NClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uT2JqZWN0c0RlbGVnYXRvci5pbnNlcnQoT2JqZWN0c0RlbGVnYXRvci5qYXZhOjk1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGVycm9yUHJvdG9Db2RlPUZPUkJJRERFTiwgZXJyb3JQcm90b0RvbWFpbj1nZGF0YS5Db3JlRXJyb3JEb21haW4sIGZpbHRlcmVkTWVzc2FnZT1udWxsLCBsb2NhdGlvbj1udWxsLCBtZXNzYWdlPWludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuLCB1bm5hbWVkQXJndW1lbnRzPVtdfSwgbG9jYXRpb249bnVsbCwgbWVzc2FnZT1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiwgcmVhc29uPWZvcmJpZGRlbiwgcnBjQ29kZT00MDN9IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuOiBjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX0FDQ0VTU19ERU5JRUQ6IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkluc2VydE9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoSW5zZXJ0T2JqZWN0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuSW5zZXJ0T2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRPYmplY3QuamF2YTo0NClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uT2JqZWN0c0RlbGVnYXRvci5pbnNlcnQoT2JqZWN0c0RlbGVnYXRvci5qYXZhOjk1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRXJyb3JDb2xsZWN0b3IudG9GYXVsdChFcnJvckNvbGxlY3Rvci5qYXZhOjU0KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUVycm9yQ29udmVydGVyLnRvRmF1bHQoUm9zeUVycm9yQ29udmVydGVyLmphdmE6NjcpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyNTkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyMzkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci50aHJlYWQuVGhyZWFkVHJhY2tlcnMkVGhyZWFkVHJhY2tpbmdSdW5uYWJsZS5ydW4oVGhyZWFkVHJhY2tlcnMuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjQ1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnNlcnZlci5Db21tb25Nb2R1bGUkQ29udGV4dENhcnJ5aW5nRXhlY3V0b3JTZXJ2aWNlJDEucnVuSW5Db250ZXh0KENvbW1vbk1vZHVsZS5qYXZhOjgwMilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZSQxLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NjApXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoVHJhY2VDb250ZXh0LmphdmE6MzE5KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjMxMSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDU3KVxuXHRhdCBjb20uZ29vZ2xlLmdzZS5pbnRlcm5hbC5EaXNwYXRjaFF1ZXVlSW1wbCRXb3JrZXJUaHJlYWQucnVuKERpc3BhdGNoUXVldWVJbXBsLmphdmE6NDAzKVxuIn1dLCJjb2RlIjo0MDMsIm1lc3NhZ2UiOiJpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiJ9fQ==" } }, { "ID": "bc0d0ed808bc8e68", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/go-integration-test-20190502-80633403432013-0003/foo", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "5" ], "Content-Type": [ "text/plain" ], "Date": [ "Thu, 02 May 2019 22:24:52 GMT" ], "Etag": [ "\"5d41402abc4b2a76b9719d911017c592\"" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Last-Modified": [ "Thu, 02 May 2019 22:24:51 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "X-Goog-Generation": [ "1556835891548001" ], "X-Goog-Hash": [ "crc32c=mnG7TA==", "md5=XUFAKrxLKna5cZ2REBfFkg==" ], "X-Goog-Metageneration": [ "1" ], "X-Goog-Storage-Class": [ "STANDARD" ], "X-Goog-Stored-Content-Encoding": [ "identity" ], "X-Goog-Stored-Content-Length": [ "5" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpljfpVGJewuMZUyJZ8DU7j2k6JmfPqXXgkeeu8vGdK5j-C_DUgpubS4nFEp1z8EsN-fUdceCxfiy-FGIJiFpME38hWnztW_WIn6zeSh6LCbwIK9oM" ] }, "Body": "aGVsbG8=" } }, { "ID": "b695481e00d2d6d9", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/go-integration-test-20190502-80633403432013-0003/foo", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "Go-http-client/1.1" ], "X-Goog-User-Project": [ "deklerk-sandbox" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "5" ], "Content-Type": [ "text/plain" ], "Date": [ "Thu, 02 May 2019 22:24:52 GMT" ], "Etag": [ "\"5d41402abc4b2a76b9719d911017c592\"" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Last-Modified": [ "Thu, 02 May 2019 22:24:51 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "X-Goog-Generation": [ "1556835891548001" ], "X-Goog-Hash": [ "crc32c=mnG7TA==", "md5=XUFAKrxLKna5cZ2REBfFkg==" ], "X-Goog-Metageneration": [ "1" ], "X-Goog-Storage-Class": [ "STANDARD" ], "X-Goog-Stored-Content-Encoding": [ "identity" ], "X-Goog-Stored-Content-Length": [ "5" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrmYf7b7ig2ase_O8qHEsgSAXifAlxVdDy_Zh5Qaqx1IlL1wkTvy1BSblI6ZDz3M2X-Y6KrdJp1IaP6nDU1F_Yhyt84Y7dOG80r2g-x4E7NAyyjV0o" ] }, "Body": "aGVsbG8=" } }, { "ID": "2fe3b6cc96ffa451", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/go-integration-test-20190502-80633403432013-0003/foo", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "266" ], "Content-Type": [ "application/xml; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:52 GMT" ], "Expires": [ "Thu, 02 May 2019 22:24:52 GMT" ], "Server": [ "UploadServer" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2Ur-S2G_BUo7MzXUj-7vUDuVFWfBIA5GJYfTdaeruyelzRGFimnhov8wRB_ozWC2cGPQ-a2xQk8bw_cVV_D2Q7c7rdR1ujaTM3oIjr8vjsJBZXa1VeA" ] }, "Body": "PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48RXJyb3I+PENvZGU+VXNlclByb2plY3RNaXNzaW5nPC9Db2RlPjxNZXNzYWdlPkJ1Y2tldCBpcyBhIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLjwvTWVzc2FnZT48RGV0YWlscz5CdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci48L0RldGFpbHM+PC9FcnJvcj4=" } }, { "ID": "59bdcad91d723d0e", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/go-integration-test-20190502-80633403432013-0003/foo", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "Go-http-client/1.1" ], "X-Goog-User-Project": [ "gcloud-golang-firestore-tests" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "5" ], "Content-Type": [ "text/plain" ], "Date": [ "Thu, 02 May 2019 22:24:52 GMT" ], "Etag": [ "\"5d41402abc4b2a76b9719d911017c592\"" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Last-Modified": [ "Thu, 02 May 2019 22:24:51 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "X-Goog-Generation": [ "1556835891548001" ], "X-Goog-Hash": [ "crc32c=mnG7TA==", "md5=XUFAKrxLKna5cZ2REBfFkg==" ], "X-Goog-Metageneration": [ "1" ], "X-Goog-Storage-Class": [ "STANDARD" ], "X-Goog-Stored-Content-Encoding": [ "identity" ], "X-Goog-Stored-Content-Length": [ "5" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Up3lrNfk5bvup2RRbcsT6CeDACQitaiF3BTMyQ7B23ACtTqwWweq9ooOfZn3CX7tsbzljhlY_009nsTXXQwm7V_xNNd8FZwT44CzSpul-SZIRODC2w" ] }, "Body": "aGVsbG8=" } }, { "ID": "7b7b6a79cd2a53e3", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/go-integration-test-20190502-80633403432013-0003/foo", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "Go-http-client/1.1" ], "X-Goog-User-Project": [ "veener-jba" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 403, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "342" ], "Content-Type": [ "application/xml; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:52 GMT" ], "Expires": [ "Thu, 02 May 2019 22:24:52 GMT" ], "Server": [ "UploadServer" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UpT7Ge_QpcDrqajg6a4kZrmoA55ZSma9IM3pyz0Ow1bu5nLURc0V7cAThbvikg47_O-ox0uMdF6zBbtVtKL7olyMUGd9wqCQ9ubELVoJXiNMDehvXY" ] }, "Body": "PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48RXJyb3I+PENvZGU+VXNlclByb2plY3RBY2Nlc3NEZW5pZWQ8L0NvZGU+PE1lc3NhZ2U+UmVxdWVzdGVyIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBwZXJtaXNzaW9ucyBvbiB1c2VyIHByb2plY3QuPC9NZXNzYWdlPjxEZXRhaWxzPmludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuPC9EZXRhaWxzPjwvRXJyb3I+" } }, { "ID": "914bca19df35cbed", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/foo?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3193" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:53 GMT" ], "Etag": [ "COGeqNLx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpM7lBsoxgNb-rh81Lfe0tWFGTkXQYfEB12ofkKZ8SK8kK5bPRUsQMVhm3aYB2N9e5_QSBZA25my-t5LpgR8TVW1lNTGd97OoD7bdBhP_CGo3xMbos" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTg5MTU0ODAwMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2ZvbyIsIm5hbWUiOiJmb28iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg5MTU0ODAwMSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDo1MS41NDdaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6NTEuNTQ3WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjUxLjU0N1oiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vP2dlbmVyYXRpb249MTU1NjgzNTg5MTU0ODAwMSZhbHQ9bWVkaWEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTg5MTU0ODAwMS9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvby9mb28vYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsIm9iamVjdCI6ImZvbyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODkxNTQ4MDAxIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNPR2VxTkx4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTg5MTU0ODAwMS9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwib2JqZWN0IjoiZm9vIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4OTE1NDgwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDT0dlcU5MeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvZm9vLzE1NTY4MzU4OTE1NDgwMDEvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2Zvby9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsIm9iamVjdCI6ImZvbyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODkxNTQ4MDAxIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNPR2VxTkx4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTg5MTU0ODAwMS91c2VyLWludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vL2FjbC91c2VyLWludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwib2JqZWN0IjoiZm9vIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4OTE1NDgwMDEiLCJlbnRpdHkiOiJ1c2VyLWludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDT0dlcU5MeC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNPR2VxTkx4L2VFQ0VBRT0ifQ==" } }, { "ID": "164b4ffce0c7e233", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/foo?alt=json\u0026prettyPrint=false\u0026projection=full\u0026userProject=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3193" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:53 GMT" ], "Etag": [ "COGeqNLx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqbRkPvid4Zo9mQsbMXlTlOQ1womp_CnHUJcNWRamG_lp4ABhgVPVOdL8lE11J3tmvVkYhzcEPpIJuA_RTvuAbssXFsNo9Fu14cQ44HwhSRYk7r_dU" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTg5MTU0ODAwMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2ZvbyIsIm5hbWUiOiJmb28iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg5MTU0ODAwMSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDo1MS41NDdaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6NTEuNTQ3WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjUxLjU0N1oiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vP2dlbmVyYXRpb249MTU1NjgzNTg5MTU0ODAwMSZhbHQ9bWVkaWEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTg5MTU0ODAwMS9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvby9mb28vYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsIm9iamVjdCI6ImZvbyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODkxNTQ4MDAxIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNPR2VxTkx4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTg5MTU0ODAwMS9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwib2JqZWN0IjoiZm9vIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4OTE1NDgwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDT0dlcU5MeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvZm9vLzE1NTY4MzU4OTE1NDgwMDEvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2Zvby9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsIm9iamVjdCI6ImZvbyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODkxNTQ4MDAxIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNPR2VxTkx4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTg5MTU0ODAwMS91c2VyLWludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vL2FjbC91c2VyLWludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwib2JqZWN0IjoiZm9vIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4OTE1NDgwMDEiLCJlbnRpdHkiOiJ1c2VyLWludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDT0dlcU5MeC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNPR2VxTkx4L2VFQ0VBRT0ifQ==" } }, { "ID": "d04d3cb2ac9d6376", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/foo?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "12183" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:53 GMT" ], "Expires": [ "Thu, 02 May 2019 22:24:53 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UrcH6PdfDpm0th9SnZgYwMYIiYGYz2VvNs-Nb0VYFbZdA4QXfOJiRFg-xKqmDq09HRt7j8OwTDO7UMm2EiqwjPz7j_JPIvfcCzfCnVVoF3XiZFomuQ" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6InJlcXVpcmVkIiwibWVzc2FnZSI6IkJ1Y2tldCBpcyByZXF1ZXN0ZXIgcGF5cyBidWNrZXQgYnV0IG5vIHVzZXIgcHJvamVjdCBwcm92aWRlZC4iLCJkZWJ1Z0luZm8iOiJjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX01JU1NJTkc6IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5HZXRPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEdldE9iamVjdC5qYXZhOjMwOSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkdldE9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoR2V0T2JqZWN0LmphdmE6NzApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLk9iamVjdHNEZWxlZ2F0b3IuZ2V0KE9iamVjdHNEZWxlZ2F0b3IuamF2YTo4MSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogQnVja2V0IGlzIFJlcXVlc3RlciBQYXlzIGJ1Y2tldCBidXQgbm8gYmlsbGluZyBwcm9qZWN0IGlkIHByb3ZpZGVkIGZvciBub24tb3duZXIuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPVJFUVVJUkVELCBjYXRlZ29yeT1VU0VSX0VSUk9SLCBjYXVzZT1udWxsLCBkZWJ1Z0luZm89Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuR2V0T2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChHZXRPYmplY3QuamF2YTozMDkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5HZXRPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEdldE9iamVjdC5qYXZhOjcwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLmdldChPYmplY3RzRGVsZWdhdG9yLmphdmE6ODEpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGRvbWFpbj1nbG9iYWwsIGV4dGVuZGVkSGVscD1udWxsLCBodHRwSGVhZGVycz17fSwgaHR0cFN0YXR1cz1iYWRSZXF1ZXN0LCBpbnRlcm5hbFJlYXNvbj1SZWFzb257YXJndW1lbnRzPXt9LCBjYXVzZT1udWxsLCBjb2RlPWdkYXRhLkNvcmVFcnJvckRvbWFpbi5SRVFVSVJFRCwgY3JlYXRlZEJ5QmFja2VuZD10cnVlLCBkZWJ1Z01lc3NhZ2U9Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuR2V0T2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChHZXRPYmplY3QuamF2YTozMDkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5HZXRPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEdldE9iamVjdC5qYXZhOjcwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLmdldChPYmplY3RzRGVsZWdhdG9yLmphdmE6ODEpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGVycm9yUHJvdG9Db2RlPVJFUVVJUkVELCBlcnJvclByb3RvRG9tYWluPWdkYXRhLkNvcmVFcnJvckRvbWFpbiwgZmlsdGVyZWRNZXNzYWdlPW51bGwsIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9QnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLiwgdW5uYW1lZEFyZ3VtZW50cz1bXX0sIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9QnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLiwgcmVhc29uPXJlcXVpcmVkLCBycGNDb2RlPTQwMH0gQnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLjogY29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuR2V0T2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChHZXRPYmplY3QuamF2YTozMDkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5HZXRPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEdldE9iamVjdC5qYXZhOjcwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLmdldChPYmplY3RzRGVsZWdhdG9yLmphdmE6ODEpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRXJyb3JDb2xsZWN0b3IudG9GYXVsdChFcnJvckNvbGxlY3Rvci5qYXZhOjU0KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUVycm9yQ29udmVydGVyLnRvRmF1bHQoUm9zeUVycm9yQ29udmVydGVyLmphdmE6NjcpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyNTkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyMzkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci50aHJlYWQuVGhyZWFkVHJhY2tlcnMkVGhyZWFkVHJhY2tpbmdSdW5uYWJsZS5ydW4oVGhyZWFkVHJhY2tlcnMuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjQ1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnNlcnZlci5Db21tb25Nb2R1bGUkQ29udGV4dENhcnJ5aW5nRXhlY3V0b3JTZXJ2aWNlJDEucnVuSW5Db250ZXh0KENvbW1vbk1vZHVsZS5qYXZhOjgwMilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZSQxLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NjApXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoVHJhY2VDb250ZXh0LmphdmE6MzE5KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjMxMSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDU3KVxuXHRhdCBjb20uZ29vZ2xlLmdzZS5pbnRlcm5hbC5EaXNwYXRjaFF1ZXVlSW1wbCRXb3JrZXJUaHJlYWQucnVuKERpc3BhdGNoUXVldWVJbXBsLmphdmE6NDAzKVxuIn1dLCJjb2RlIjo0MDAsIm1lc3NhZ2UiOiJCdWNrZXQgaXMgcmVxdWVzdGVyIHBheXMgYnVja2V0IGJ1dCBubyB1c2VyIHByb2plY3QgcHJvdmlkZWQuIn19" } }, { "ID": "8b3aeb1f423d76c5", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/foo?alt=json\u0026prettyPrint=false\u0026projection=full\u0026userProject=gcloud-golang-firestore-tests", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3193" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:54 GMT" ], "Etag": [ "COGeqNLx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoX_zzYo9AYFb44YmIz49k5z8v8ITzEQsDrSxEE50-7AC-ndg18Yo5DFAZ9ZFCDtT5P7kch3c0-YlkhX-5oYCUIm-mmPmoTg0CKWVI0TJ9la9z9-vE" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTg5MTU0ODAwMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2ZvbyIsIm5hbWUiOiJmb28iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg5MTU0ODAwMSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDo1MS41NDdaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6NTEuNTQ3WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjUxLjU0N1oiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vP2dlbmVyYXRpb249MTU1NjgzNTg5MTU0ODAwMSZhbHQ9bWVkaWEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTg5MTU0ODAwMS9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvby9mb28vYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsIm9iamVjdCI6ImZvbyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODkxNTQ4MDAxIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNPR2VxTkx4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTg5MTU0ODAwMS9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwib2JqZWN0IjoiZm9vIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4OTE1NDgwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDT0dlcU5MeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvZm9vLzE1NTY4MzU4OTE1NDgwMDEvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2Zvby9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsIm9iamVjdCI6ImZvbyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODkxNTQ4MDAxIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNPR2VxTkx4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTg5MTU0ODAwMS91c2VyLWludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vL2FjbC91c2VyLWludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwib2JqZWN0IjoiZm9vIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4OTE1NDgwMDEiLCJlbnRpdHkiOiJ1c2VyLWludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDT0dlcU5MeC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNPR2VxTkx4L2VFQ0VBRT0ifQ==" } }, { "ID": "f32edc9a9263c0a1", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/foo?alt=json\u0026prettyPrint=false\u0026projection=full\u0026userProject=veener-jba", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 403, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "13039" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:54 GMT" ], "Expires": [ "Thu, 02 May 2019 22:24:54 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2Uok5lyOpE3YUZDwRz_bsA-E-xzWeqaApyadumOOFoA_YmOi_xnvFaJr6gfp9Gaktbpud9mv8qDCIvq1Yu7CyAVY0ScanSfNCke3naR_G7kPKYgrywY" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6ImZvcmJpZGRlbiIsIm1lc3NhZ2UiOiJpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpVU0VSX1BST0pFQ1RfQUNDRVNTX0RFTklFRDogaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20gZG9lcyBub3QgaGF2ZSBzZXJ2aWNldXNhZ2Uuc2VydmljZXMudXNlIGFjY2VzcyB0byBwcm9qZWN0IDY0MjA4MDkxODEwMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuR2V0T2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChHZXRPYmplY3QuamF2YTozMDkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5HZXRPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEdldE9iamVjdC5qYXZhOjcwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLmdldChPYmplY3RzRGVsZWdhdG9yLmphdmE6ODEpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPUZPUkJJRERFTiwgY2F0ZWdvcnk9VVNFUl9FUlJPUiwgY2F1c2U9bnVsbCwgZGVidWdJbmZvPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpVU0VSX1BST0pFQ1RfQUNDRVNTX0RFTklFRDogaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20gZG9lcyBub3QgaGF2ZSBzZXJ2aWNldXNhZ2Uuc2VydmljZXMudXNlIGFjY2VzcyB0byBwcm9qZWN0IDY0MjA4MDkxODEwMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuR2V0T2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChHZXRPYmplY3QuamF2YTozMDkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5HZXRPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEdldE9iamVjdC5qYXZhOjcwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLmdldChPYmplY3RzRGVsZWdhdG9yLmphdmE6ODEpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZG9tYWluPWdsb2JhbCwgZXh0ZW5kZWRIZWxwPW51bGwsIGh0dHBIZWFkZXJzPXt9LCBodHRwU3RhdHVzPWZvcmJpZGRlbiwgaW50ZXJuYWxSZWFzb249UmVhc29ue2FyZ3VtZW50cz17fSwgY2F1c2U9bnVsbCwgY29kZT1nZGF0YS5Db3JlRXJyb3JEb21haW4uRk9SQklEREVOLCBjcmVhdGVkQnlCYWNrZW5kPXRydWUsIGRlYnVnTWVzc2FnZT1jb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX0FDQ0VTU19ERU5JRUQ6IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkdldE9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoR2V0T2JqZWN0LmphdmE6MzA5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuR2V0T2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChHZXRPYmplY3QuamF2YTo3MClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uT2JqZWN0c0RlbGVnYXRvci5nZXQoT2JqZWN0c0RlbGVnYXRvci5qYXZhOjgxKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGVycm9yUHJvdG9Db2RlPUZPUkJJRERFTiwgZXJyb3JQcm90b0RvbWFpbj1nZGF0YS5Db3JlRXJyb3JEb21haW4sIGZpbHRlcmVkTWVzc2FnZT1udWxsLCBsb2NhdGlvbj1udWxsLCBtZXNzYWdlPWludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuLCB1bm5hbWVkQXJndW1lbnRzPVtdfSwgbG9jYXRpb249bnVsbCwgbWVzc2FnZT1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiwgcmVhc29uPWZvcmJpZGRlbiwgcnBjQ29kZT00MDN9IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuOiBjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX0FDQ0VTU19ERU5JRUQ6IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkdldE9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoR2V0T2JqZWN0LmphdmE6MzA5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuR2V0T2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChHZXRPYmplY3QuamF2YTo3MClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uT2JqZWN0c0RlbGVnYXRvci5nZXQoT2JqZWN0c0RlbGVnYXRvci5qYXZhOjgxKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRXJyb3JDb2xsZWN0b3IudG9GYXVsdChFcnJvckNvbGxlY3Rvci5qYXZhOjU0KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUVycm9yQ29udmVydGVyLnRvRmF1bHQoUm9zeUVycm9yQ29udmVydGVyLmphdmE6NjcpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyNTkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyMzkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci50aHJlYWQuVGhyZWFkVHJhY2tlcnMkVGhyZWFkVHJhY2tpbmdSdW5uYWJsZS5ydW4oVGhyZWFkVHJhY2tlcnMuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjQ1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnNlcnZlci5Db21tb25Nb2R1bGUkQ29udGV4dENhcnJ5aW5nRXhlY3V0b3JTZXJ2aWNlJDEucnVuSW5Db250ZXh0KENvbW1vbk1vZHVsZS5qYXZhOjgwMilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZSQxLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NjApXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoVHJhY2VDb250ZXh0LmphdmE6MzE5KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjMxMSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDU3KVxuXHRhdCBjb20uZ29vZ2xlLmdzZS5pbnRlcm5hbC5EaXNwYXRjaFF1ZXVlSW1wbCRXb3JrZXJUaHJlYWQucnVuKERpc3BhdGNoUXVldWVJbXBsLmphdmE6NDAzKVxuIn1dLCJjb2RlIjo0MDMsIm1lc3NhZ2UiOiJpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiJ9fQ==" } }, { "ID": "da73739950dbfa82", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/foo?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "85" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJjb250ZW50TGFuZ3VhZ2UiOiJlbiJ9Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3216" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:54 GMT" ], "Etag": [ "COGeqNLx/eECEAI=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrdpofRnchjkCQz5LLoghzg-RHoGATH3xbgJVW0LKGBkH025w5EB5RlGmHHnmXuPtK_5Ffyl1bxjmoc_h7_vGvjcxWbHv9-NKe9fLO_oNYRmw-ffvU" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTg5MTU0ODAwMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2ZvbyIsIm5hbWUiOiJmb28iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg5MTU0ODAwMSIsIm1ldGFnZW5lcmF0aW9uIjoiMiIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDo1MS41NDdaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6NTQuNzM4WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjUxLjU0N1oiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vP2dlbmVyYXRpb249MTU1NjgzNTg5MTU0ODAwMSZhbHQ9bWVkaWEiLCJjb250ZW50TGFuZ3VhZ2UiOiJlbiIsImNhY2hlQ29udHJvbCI6InB1YmxpYywgbWF4LWFnZT02MCIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL2Zvby8xNTU2ODM1ODkxNTQ4MDAxL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2Zvby9hY2wvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwib2JqZWN0IjoiZm9vIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4OTE1NDgwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ09HZXFOTHgvZUVDRUFJPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL2Zvby8xNTU2ODM1ODkxNTQ4MDAxL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvby9mb28vYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJvYmplY3QiOiJmb28iLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg5MTU0ODAwMSIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNPR2VxTkx4L2VFQ0VBST0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTg5MTU0ODAwMS9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vL2FjbC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwib2JqZWN0IjoiZm9vIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4OTE1NDgwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ09HZXFOTHgvZUVDRUFJPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL2Zvby8xNTU2ODM1ODkxNTQ4MDAxL3VzZXItaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvby9mb28vYWNsL3VzZXItaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJvYmplY3QiOiJmb28iLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg5MTU0ODAwMSIsImVudGl0eSI6InVzZXItaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNPR2VxTkx4L2VFQ0VBST0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ09HZXFOTHgvZUVDRUFJPSJ9" } }, { "ID": "94e697431c9323b9", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/foo?alt=json\u0026prettyPrint=false\u0026projection=full\u0026userProject=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "85" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJjb250ZW50TGFuZ3VhZ2UiOiJlbiJ9Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3216" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:55 GMT" ], "Etag": [ "COGeqNLx/eECEAM=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uqhr0guIL00afW_qpaRvxEGRSJEWTtfrZP2Tv8Vqt2xas1ivvvMHVbSpT12ltU7FjytFhno9SFXTS8pW1S0S8qJdFctUCa83tkcQRXgN1uPUwhX1ws" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTg5MTU0ODAwMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2ZvbyIsIm5hbWUiOiJmb28iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg5MTU0ODAwMSIsIm1ldGFnZW5lcmF0aW9uIjoiMyIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDo1MS41NDdaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6NTUuMTMwWiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjUxLjU0N1oiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vP2dlbmVyYXRpb249MTU1NjgzNTg5MTU0ODAwMSZhbHQ9bWVkaWEiLCJjb250ZW50TGFuZ3VhZ2UiOiJlbiIsImNhY2hlQ29udHJvbCI6InB1YmxpYywgbWF4LWFnZT02MCIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL2Zvby8xNTU2ODM1ODkxNTQ4MDAxL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2Zvby9hY2wvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwib2JqZWN0IjoiZm9vIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4OTE1NDgwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ09HZXFOTHgvZUVDRUFNPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL2Zvby8xNTU2ODM1ODkxNTQ4MDAxL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvby9mb28vYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJvYmplY3QiOiJmb28iLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg5MTU0ODAwMSIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNPR2VxTkx4L2VFQ0VBTT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTg5MTU0ODAwMS9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vL2FjbC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwib2JqZWN0IjoiZm9vIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4OTE1NDgwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ09HZXFOTHgvZUVDRUFNPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL2Zvby8xNTU2ODM1ODkxNTQ4MDAxL3VzZXItaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvby9mb28vYWNsL3VzZXItaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJvYmplY3QiOiJmb28iLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg5MTU0ODAwMSIsImVudGl0eSI6InVzZXItaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNPR2VxTkx4L2VFQ0VBTT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ09HZXFOTHgvZUVDRUFNPSJ9" } }, { "ID": "3c5d694690a75054", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/foo?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "85" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJjb250ZW50TGFuZ3VhZ2UiOiJlbiJ9Cg==" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Content-Length": [ "12375" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:55 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UogsU3nh3dfRYWq9YqTmJc7CfCX1U0b-IrWpDCM7M4YwfuUWgzzzcydWdHLrF0UPqRxNFQj3eMHBbDuHYcF0xuUNah4g5J_nt26feHRp-moh7uFXNw" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6InJlcXVpcmVkIiwibWVzc2FnZSI6IkJ1Y2tldCBpcyByZXF1ZXN0ZXIgcGF5cyBidWNrZXQgYnV0IG5vIHVzZXIgcHJvamVjdCBwcm92aWRlZC4iLCJkZWJ1Z0luZm8iOiJjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX01JU1NJTkc6IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5VcGRhdGVBbmRQYXRjaE9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoVXBkYXRlQW5kUGF0Y2hPYmplY3QuamF2YTo0MjgpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5VcGRhdGVBbmRQYXRjaE9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoVXBkYXRlQW5kUGF0Y2hPYmplY3QuamF2YTo1OClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uT2JqZWN0c0RlbGVnYXRvci51cGRhdGUoT2JqZWN0c0RlbGVnYXRvci5qYXZhOjEwMylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogQnVja2V0IGlzIFJlcXVlc3RlciBQYXlzIGJ1Y2tldCBidXQgbm8gYmlsbGluZyBwcm9qZWN0IGlkIHByb3ZpZGVkIGZvciBub24tb3duZXIuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPVJFUVVJUkVELCBjYXRlZ29yeT1VU0VSX0VSUk9SLCBjYXVzZT1udWxsLCBkZWJ1Z0luZm89Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuVXBkYXRlQW5kUGF0Y2hPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFVwZGF0ZUFuZFBhdGNoT2JqZWN0LmphdmE6NDI4KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuVXBkYXRlQW5kUGF0Y2hPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFVwZGF0ZUFuZFBhdGNoT2JqZWN0LmphdmE6NTgpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLk9iamVjdHNEZWxlZ2F0b3IudXBkYXRlKE9iamVjdHNEZWxlZ2F0b3IuamF2YToxMDMpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGRvbWFpbj1nbG9iYWwsIGV4dGVuZGVkSGVscD1udWxsLCBodHRwSGVhZGVycz17fSwgaHR0cFN0YXR1cz1iYWRSZXF1ZXN0LCBpbnRlcm5hbFJlYXNvbj1SZWFzb257YXJndW1lbnRzPXt9LCBjYXVzZT1udWxsLCBjb2RlPWdkYXRhLkNvcmVFcnJvckRvbWFpbi5SRVFVSVJFRCwgY3JlYXRlZEJ5QmFja2VuZD10cnVlLCBkZWJ1Z01lc3NhZ2U9Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuVXBkYXRlQW5kUGF0Y2hPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFVwZGF0ZUFuZFBhdGNoT2JqZWN0LmphdmE6NDI4KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuVXBkYXRlQW5kUGF0Y2hPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFVwZGF0ZUFuZFBhdGNoT2JqZWN0LmphdmE6NTgpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLk9iamVjdHNEZWxlZ2F0b3IudXBkYXRlKE9iamVjdHNEZWxlZ2F0b3IuamF2YToxMDMpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGVycm9yUHJvdG9Db2RlPVJFUVVJUkVELCBlcnJvclByb3RvRG9tYWluPWdkYXRhLkNvcmVFcnJvckRvbWFpbiwgZmlsdGVyZWRNZXNzYWdlPW51bGwsIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9QnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLiwgdW5uYW1lZEFyZ3VtZW50cz1bXX0sIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9QnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLiwgcmVhc29uPXJlcXVpcmVkLCBycGNDb2RlPTQwMH0gQnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLjogY29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuVXBkYXRlQW5kUGF0Y2hPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFVwZGF0ZUFuZFBhdGNoT2JqZWN0LmphdmE6NDI4KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuVXBkYXRlQW5kUGF0Y2hPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFVwZGF0ZUFuZFBhdGNoT2JqZWN0LmphdmE6NTgpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLk9iamVjdHNEZWxlZ2F0b3IudXBkYXRlKE9iamVjdHNEZWxlZ2F0b3IuamF2YToxMDMpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRXJyb3JDb2xsZWN0b3IudG9GYXVsdChFcnJvckNvbGxlY3Rvci5qYXZhOjU0KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUVycm9yQ29udmVydGVyLnRvRmF1bHQoUm9zeUVycm9yQ29udmVydGVyLmphdmE6NjcpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyNTkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyMzkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci50aHJlYWQuVGhyZWFkVHJhY2tlcnMkVGhyZWFkVHJhY2tpbmdSdW5uYWJsZS5ydW4oVGhyZWFkVHJhY2tlcnMuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjQ1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnNlcnZlci5Db21tb25Nb2R1bGUkQ29udGV4dENhcnJ5aW5nRXhlY3V0b3JTZXJ2aWNlJDEucnVuSW5Db250ZXh0KENvbW1vbk1vZHVsZS5qYXZhOjgwMilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZSQxLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NjApXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoVHJhY2VDb250ZXh0LmphdmE6MzE5KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjMxMSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDU3KVxuXHRhdCBjb20uZ29vZ2xlLmdzZS5pbnRlcm5hbC5EaXNwYXRjaFF1ZXVlSW1wbCRXb3JrZXJUaHJlYWQucnVuKERpc3BhdGNoUXVldWVJbXBsLmphdmE6NDAzKVxuIn1dLCJjb2RlIjo0MDAsIm1lc3NhZ2UiOiJCdWNrZXQgaXMgcmVxdWVzdGVyIHBheXMgYnVja2V0IGJ1dCBubyB1c2VyIHByb2plY3QgcHJvdmlkZWQuIn19" } }, { "ID": "e050063f79f64820", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/foo?alt=json\u0026prettyPrint=false\u0026projection=full\u0026userProject=gcloud-golang-firestore-tests", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "85" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJjb250ZW50TGFuZ3VhZ2UiOiJlbiJ9Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3216" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:55 GMT" ], "Etag": [ "COGeqNLx/eECEAQ=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uq4hs_SY8_2HHPHu8NfVIkOdwmZz7h6XH0nWRSTQJSqzQZQGvv1p83Z6W209h3bXsbN9_ESiU3OIyLRwmEldfBP94hRhN5t1JnagcKPcMEOv8FtvHs" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTg5MTU0ODAwMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2ZvbyIsIm5hbWUiOiJmb28iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg5MTU0ODAwMSIsIm1ldGFnZW5lcmF0aW9uIjoiNCIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDo1MS41NDdaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6NTUuODI0WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjUxLjU0N1oiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vP2dlbmVyYXRpb249MTU1NjgzNTg5MTU0ODAwMSZhbHQ9bWVkaWEiLCJjb250ZW50TGFuZ3VhZ2UiOiJlbiIsImNhY2hlQ29udHJvbCI6InB1YmxpYywgbWF4LWFnZT02MCIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL2Zvby8xNTU2ODM1ODkxNTQ4MDAxL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2Zvby9hY2wvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwib2JqZWN0IjoiZm9vIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4OTE1NDgwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ09HZXFOTHgvZUVDRUFRPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL2Zvby8xNTU2ODM1ODkxNTQ4MDAxL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvby9mb28vYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJvYmplY3QiOiJmb28iLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg5MTU0ODAwMSIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNPR2VxTkx4L2VFQ0VBUT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTg5MTU0ODAwMS9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vL2FjbC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwib2JqZWN0IjoiZm9vIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4OTE1NDgwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ09HZXFOTHgvZUVDRUFRPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL2Zvby8xNTU2ODM1ODkxNTQ4MDAxL3VzZXItaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvby9mb28vYWNsL3VzZXItaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJvYmplY3QiOiJmb28iLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg5MTU0ODAwMSIsImVudGl0eSI6InVzZXItaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNPR2VxTkx4L2VFQ0VBUT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ09HZXFOTHgvZUVDRUFRPSJ9" } }, { "ID": "f7edef926cdb7d75", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/foo?alt=json\u0026prettyPrint=false\u0026projection=full\u0026userProject=veener-jba", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "85" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJjb250ZW50TGFuZ3VhZ2UiOiJlbiJ9Cg==" ] }, "Response": { "StatusCode": 403, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Content-Length": [ "13231" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:56 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UqyQ9DLrBDGkx7uOkrIKrzMMYA4YygdFsd1si16n2Lr4I5Rfp1lxwadC3jThiJbE-cDyuZATHtvM2bzpsRDPJzbmKgtxYydHykiB-oCsSFqfwy50gw" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6ImZvcmJpZGRlbiIsIm1lc3NhZ2UiOiJpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpVU0VSX1BST0pFQ1RfQUNDRVNTX0RFTklFRDogaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20gZG9lcyBub3QgaGF2ZSBzZXJ2aWNldXNhZ2Uuc2VydmljZXMudXNlIGFjY2VzcyB0byBwcm9qZWN0IDY0MjA4MDkxODEwMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuVXBkYXRlQW5kUGF0Y2hPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFVwZGF0ZUFuZFBhdGNoT2JqZWN0LmphdmE6NDI4KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuVXBkYXRlQW5kUGF0Y2hPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFVwZGF0ZUFuZFBhdGNoT2JqZWN0LmphdmE6NTgpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLk9iamVjdHNEZWxlZ2F0b3IudXBkYXRlKE9iamVjdHNEZWxlZ2F0b3IuamF2YToxMDMpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPUZPUkJJRERFTiwgY2F0ZWdvcnk9VVNFUl9FUlJPUiwgY2F1c2U9bnVsbCwgZGVidWdJbmZvPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpVU0VSX1BST0pFQ1RfQUNDRVNTX0RFTklFRDogaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20gZG9lcyBub3QgaGF2ZSBzZXJ2aWNldXNhZ2Uuc2VydmljZXMudXNlIGFjY2VzcyB0byBwcm9qZWN0IDY0MjA4MDkxODEwMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuVXBkYXRlQW5kUGF0Y2hPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFVwZGF0ZUFuZFBhdGNoT2JqZWN0LmphdmE6NDI4KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuVXBkYXRlQW5kUGF0Y2hPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFVwZGF0ZUFuZFBhdGNoT2JqZWN0LmphdmE6NTgpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLk9iamVjdHNEZWxlZ2F0b3IudXBkYXRlKE9iamVjdHNEZWxlZ2F0b3IuamF2YToxMDMpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZG9tYWluPWdsb2JhbCwgZXh0ZW5kZWRIZWxwPW51bGwsIGh0dHBIZWFkZXJzPXt9LCBodHRwU3RhdHVzPWZvcmJpZGRlbiwgaW50ZXJuYWxSZWFzb249UmVhc29ue2FyZ3VtZW50cz17fSwgY2F1c2U9bnVsbCwgY29kZT1nZGF0YS5Db3JlRXJyb3JEb21haW4uRk9SQklEREVOLCBjcmVhdGVkQnlCYWNrZW5kPXRydWUsIGRlYnVnTWVzc2FnZT1jb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX0FDQ0VTU19ERU5JRUQ6IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLlVwZGF0ZUFuZFBhdGNoT2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChVcGRhdGVBbmRQYXRjaE9iamVjdC5qYXZhOjQyOClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLlVwZGF0ZUFuZFBhdGNoT2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChVcGRhdGVBbmRQYXRjaE9iamVjdC5qYXZhOjU4KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLnVwZGF0ZShPYmplY3RzRGVsZWdhdG9yLmphdmE6MTAzKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGVycm9yUHJvdG9Db2RlPUZPUkJJRERFTiwgZXJyb3JQcm90b0RvbWFpbj1nZGF0YS5Db3JlRXJyb3JEb21haW4sIGZpbHRlcmVkTWVzc2FnZT1udWxsLCBsb2NhdGlvbj1udWxsLCBtZXNzYWdlPWludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuLCB1bm5hbWVkQXJndW1lbnRzPVtdfSwgbG9jYXRpb249bnVsbCwgbWVzc2FnZT1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiwgcmVhc29uPWZvcmJpZGRlbiwgcnBjQ29kZT00MDN9IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuOiBjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX0FDQ0VTU19ERU5JRUQ6IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLlVwZGF0ZUFuZFBhdGNoT2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChVcGRhdGVBbmRQYXRjaE9iamVjdC5qYXZhOjQyOClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLlVwZGF0ZUFuZFBhdGNoT2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChVcGRhdGVBbmRQYXRjaE9iamVjdC5qYXZhOjU4KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLnVwZGF0ZShPYmplY3RzRGVsZWdhdG9yLmphdmE6MTAzKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRXJyb3JDb2xsZWN0b3IudG9GYXVsdChFcnJvckNvbGxlY3Rvci5qYXZhOjU0KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUVycm9yQ29udmVydGVyLnRvRmF1bHQoUm9zeUVycm9yQ29udmVydGVyLmphdmE6NjcpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyNTkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyMzkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci50aHJlYWQuVGhyZWFkVHJhY2tlcnMkVGhyZWFkVHJhY2tpbmdSdW5uYWJsZS5ydW4oVGhyZWFkVHJhY2tlcnMuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjQ1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnNlcnZlci5Db21tb25Nb2R1bGUkQ29udGV4dENhcnJ5aW5nRXhlY3V0b3JTZXJ2aWNlJDEucnVuSW5Db250ZXh0KENvbW1vbk1vZHVsZS5qYXZhOjgwMilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZSQxLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NjApXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoVHJhY2VDb250ZXh0LmphdmE6MzE5KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjMxMSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDU3KVxuXHRhdCBjb20uZ29vZ2xlLmdzZS5pbnRlcm5hbC5EaXNwYXRjaFF1ZXVlSW1wbCRXb3JrZXJUaHJlYWQucnVuKERpc3BhdGNoUXVldWVJbXBsLmphdmE6NDAzKVxuIn1dLCJjb2RlIjo0MDMsIm1lc3NhZ2UiOiJpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiJ9fQ==" } }, { "ID": "2745d195a40b86f1", "Request": { "Method": "PUT", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/acl/domain-google.com?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "107" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJlbnRpdHkiOiJkb21haW4tZ29vZ2xlLmNvbSIsInJvbGUiOiJSRUFERVIifQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "377" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:57 GMT" ], "Etag": [ "CAM=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpGeWJRYTNsu57knuRFhwHuoeUMIJhUtuQj4PLhGDoFcITB2Y--7JgaOCVhepJ6a5RRKvU9d3UrAyrtbGNOVHyW2WAbN_KpfkiFhYq8l7HPERpLDjg" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvZG9tYWluLWdvb2dsZS5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvYWNsL2RvbWFpbi1nb29nbGUuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwiZW50aXR5IjoiZG9tYWluLWdvb2dsZS5jb20iLCJyb2xlIjoiUkVBREVSIiwiZG9tYWluIjoiZ29vZ2xlLmNvbSIsImV0YWciOiJDQU09In0=" } }, { "ID": "5258a70437064146", "Request": { "Method": "PUT", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/acl/domain-google.com?alt=json\u0026prettyPrint=false\u0026userProject=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "107" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJlbnRpdHkiOiJkb21haW4tZ29vZ2xlLmNvbSIsInJvbGUiOiJSRUFERVIifQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "377" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:57 GMT" ], "Etag": [ "CAM=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqImoOCe_iDYCV8XHpaaEXPn-jeAf0M1MyixGju1tNCSTBIMEKDzh_wxVxapMmXWPnOes7YX0T0Fr663x7eJCl85B0EGXggUgp8bqeDV3cJ-mqeDrY" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvZG9tYWluLWdvb2dsZS5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvYWNsL2RvbWFpbi1nb29nbGUuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwiZW50aXR5IjoiZG9tYWluLWdvb2dsZS5jb20iLCJyb2xlIjoiUkVBREVSIiwiZG9tYWluIjoiZ29vZ2xlLmNvbSIsImV0YWciOiJDQU09In0=" } }, { "ID": "5cef2c464b7356c8", "Request": { "Method": "PUT", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/acl/domain-google.com?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "107" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJlbnRpdHkiOiJkb21haW4tZ29vZ2xlLmNvbSIsInJvbGUiOiJSRUFERVIifQo=" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Content-Length": [ "12243" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:58 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UpH5br-AVWN2g1nkkM_FJWZIjgOgh2NGLuiyYUS7QD2DSs6B-c0IQHgC2NUyy0eZq4McQhwxBGhUJ05-WeD_bX35i7skN7Jn_q3ELAaDwpi6_x3Z8c" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6InJlcXVpcmVkIiwibWVzc2FnZSI6IkJ1Y2tldCBpcyByZXF1ZXN0ZXIgcGF5cyBidWNrZXQgYnV0IG5vIHVzZXIgcHJvamVjdCBwcm92aWRlZC4iLCJkZWJ1Z0luZm8iOiJjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX01JU1NJTkc6IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5VcGRhdGVBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChVcGRhdGVBY2xzLmphdmE6OTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5VcGRhdGVBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChVcGRhdGVBY2xzLmphdmE6MjcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLkFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLnVwZGF0ZShBY2Nlc3NDb250cm9sc0RlbGVnYXRvci5qYXZhOjEwMylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogQnVja2V0IGlzIFJlcXVlc3RlciBQYXlzIGJ1Y2tldCBidXQgbm8gYmlsbGluZyBwcm9qZWN0IGlkIHByb3ZpZGVkIGZvciBub24tb3duZXIuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPVJFUVVJUkVELCBjYXRlZ29yeT1VU0VSX0VSUk9SLCBjYXVzZT1udWxsLCBkZWJ1Z0luZm89Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuVXBkYXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoVXBkYXRlQWNscy5qYXZhOjkwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuVXBkYXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoVXBkYXRlQWNscy5qYXZhOjI3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci51cGRhdGUoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YToxMDMpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGRvbWFpbj1nbG9iYWwsIGV4dGVuZGVkSGVscD1udWxsLCBodHRwSGVhZGVycz17fSwgaHR0cFN0YXR1cz1iYWRSZXF1ZXN0LCBpbnRlcm5hbFJlYXNvbj1SZWFzb257YXJndW1lbnRzPXt9LCBjYXVzZT1udWxsLCBjb2RlPWdkYXRhLkNvcmVFcnJvckRvbWFpbi5SRVFVSVJFRCwgY3JlYXRlZEJ5QmFja2VuZD10cnVlLCBkZWJ1Z01lc3NhZ2U9Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuVXBkYXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoVXBkYXRlQWNscy5qYXZhOjkwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuVXBkYXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoVXBkYXRlQWNscy5qYXZhOjI3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci51cGRhdGUoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YToxMDMpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGVycm9yUHJvdG9Db2RlPVJFUVVJUkVELCBlcnJvclByb3RvRG9tYWluPWdkYXRhLkNvcmVFcnJvckRvbWFpbiwgZmlsdGVyZWRNZXNzYWdlPW51bGwsIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9QnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLiwgdW5uYW1lZEFyZ3VtZW50cz1bXX0sIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9QnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLiwgcmVhc29uPXJlcXVpcmVkLCBycGNDb2RlPTQwMH0gQnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLjogY29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuVXBkYXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoVXBkYXRlQWNscy5qYXZhOjkwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuVXBkYXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoVXBkYXRlQWNscy5qYXZhOjI3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci51cGRhdGUoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YToxMDMpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRXJyb3JDb2xsZWN0b3IudG9GYXVsdChFcnJvckNvbGxlY3Rvci5qYXZhOjU0KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUVycm9yQ29udmVydGVyLnRvRmF1bHQoUm9zeUVycm9yQ29udmVydGVyLmphdmE6NjcpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyNTkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyMzkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci50aHJlYWQuVGhyZWFkVHJhY2tlcnMkVGhyZWFkVHJhY2tpbmdSdW5uYWJsZS5ydW4oVGhyZWFkVHJhY2tlcnMuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjQ1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnNlcnZlci5Db21tb25Nb2R1bGUkQ29udGV4dENhcnJ5aW5nRXhlY3V0b3JTZXJ2aWNlJDEucnVuSW5Db250ZXh0KENvbW1vbk1vZHVsZS5qYXZhOjgwMilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZSQxLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NjApXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoVHJhY2VDb250ZXh0LmphdmE6MzE5KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjMxMSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDU3KVxuXHRhdCBjb20uZ29vZ2xlLmdzZS5pbnRlcm5hbC5EaXNwYXRjaFF1ZXVlSW1wbCRXb3JrZXJUaHJlYWQucnVuKERpc3BhdGNoUXVldWVJbXBsLmphdmE6NDAzKVxuIn1dLCJjb2RlIjo0MDAsIm1lc3NhZ2UiOiJCdWNrZXQgaXMgcmVxdWVzdGVyIHBheXMgYnVja2V0IGJ1dCBubyB1c2VyIHByb2plY3QgcHJvdmlkZWQuIn19" } }, { "ID": "11cd5140a264e423", "Request": { "Method": "PUT", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/acl/domain-google.com?alt=json\u0026prettyPrint=false\u0026userProject=gcloud-golang-firestore-tests", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "107" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJlbnRpdHkiOiJkb21haW4tZ29vZ2xlLmNvbSIsInJvbGUiOiJSRUFERVIifQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "377" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:58 GMT" ], "Etag": [ "CAM=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uo2_tsxxuZC3Ni-A0zL0E9w8OVne0sWfLi61Cv48eTWj2R4F6G0AmXZU7J8L-WnDJf4s-6GpZV0SyQqrjBA_Mp75pJfWb6cl9_7oimTy8HPnxAtMwc" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvZG9tYWluLWdvb2dsZS5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvYWNsL2RvbWFpbi1nb29nbGUuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwiZW50aXR5IjoiZG9tYWluLWdvb2dsZS5jb20iLCJyb2xlIjoiUkVBREVSIiwiZG9tYWluIjoiZ29vZ2xlLmNvbSIsImV0YWciOiJDQU09In0=" } }, { "ID": "dac6629e58d45469", "Request": { "Method": "PUT", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/acl/domain-google.com?alt=json\u0026prettyPrint=false\u0026userProject=veener-jba", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "107" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJlbnRpdHkiOiJkb21haW4tZ29vZ2xlLmNvbSIsInJvbGUiOiJSRUFERVIifQo=" ] }, "Response": { "StatusCode": 403, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Content-Length": [ "13099" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:58 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UrTXUzCa6WOvWD6NqoHhkdwRtG0Z4h0QurHOuKU1gyAWzXOt8lc1NVsLqe-6m8siE76k7l8g0EY3Le273_4GFB81gHMhM4qBOOgbwSBgLl4zKHZspU" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6ImZvcmJpZGRlbiIsIm1lc3NhZ2UiOiJpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpVU0VSX1BST0pFQ1RfQUNDRVNTX0RFTklFRDogaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20gZG9lcyBub3QgaGF2ZSBzZXJ2aWNldXNhZ2Uuc2VydmljZXMudXNlIGFjY2VzcyB0byBwcm9qZWN0IDY0MjA4MDkxODEwMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuVXBkYXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoVXBkYXRlQWNscy5qYXZhOjkwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuVXBkYXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoVXBkYXRlQWNscy5qYXZhOjI3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci51cGRhdGUoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YToxMDMpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPUZPUkJJRERFTiwgY2F0ZWdvcnk9VVNFUl9FUlJPUiwgY2F1c2U9bnVsbCwgZGVidWdJbmZvPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpVU0VSX1BST0pFQ1RfQUNDRVNTX0RFTklFRDogaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20gZG9lcyBub3QgaGF2ZSBzZXJ2aWNldXNhZ2Uuc2VydmljZXMudXNlIGFjY2VzcyB0byBwcm9qZWN0IDY0MjA4MDkxODEwMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuVXBkYXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoVXBkYXRlQWNscy5qYXZhOjkwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuVXBkYXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoVXBkYXRlQWNscy5qYXZhOjI3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci51cGRhdGUoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YToxMDMpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZG9tYWluPWdsb2JhbCwgZXh0ZW5kZWRIZWxwPW51bGwsIGh0dHBIZWFkZXJzPXt9LCBodHRwU3RhdHVzPWZvcmJpZGRlbiwgaW50ZXJuYWxSZWFzb249UmVhc29ue2FyZ3VtZW50cz17fSwgY2F1c2U9bnVsbCwgY29kZT1nZGF0YS5Db3JlRXJyb3JEb21haW4uRk9SQklEREVOLCBjcmVhdGVkQnlCYWNrZW5kPXRydWUsIGRlYnVnTWVzc2FnZT1jb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX0FDQ0VTU19ERU5JRUQ6IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLlVwZGF0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFVwZGF0ZUFjbHMuamF2YTo5MClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLlVwZGF0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFVwZGF0ZUFjbHMuamF2YToyNylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IudXBkYXRlKEFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmphdmE6MTAzKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGVycm9yUHJvdG9Db2RlPUZPUkJJRERFTiwgZXJyb3JQcm90b0RvbWFpbj1nZGF0YS5Db3JlRXJyb3JEb21haW4sIGZpbHRlcmVkTWVzc2FnZT1udWxsLCBsb2NhdGlvbj1udWxsLCBtZXNzYWdlPWludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuLCB1bm5hbWVkQXJndW1lbnRzPVtdfSwgbG9jYXRpb249bnVsbCwgbWVzc2FnZT1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiwgcmVhc29uPWZvcmJpZGRlbiwgcnBjQ29kZT00MDN9IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuOiBjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX0FDQ0VTU19ERU5JRUQ6IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLlVwZGF0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFVwZGF0ZUFjbHMuamF2YTo5MClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLlVwZGF0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFVwZGF0ZUFjbHMuamF2YToyNylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IudXBkYXRlKEFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmphdmE6MTAzKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRXJyb3JDb2xsZWN0b3IudG9GYXVsdChFcnJvckNvbGxlY3Rvci5qYXZhOjU0KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUVycm9yQ29udmVydGVyLnRvRmF1bHQoUm9zeUVycm9yQ29udmVydGVyLmphdmE6NjcpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyNTkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyMzkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci50aHJlYWQuVGhyZWFkVHJhY2tlcnMkVGhyZWFkVHJhY2tpbmdSdW5uYWJsZS5ydW4oVGhyZWFkVHJhY2tlcnMuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjQ1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnNlcnZlci5Db21tb25Nb2R1bGUkQ29udGV4dENhcnJ5aW5nRXhlY3V0b3JTZXJ2aWNlJDEucnVuSW5Db250ZXh0KENvbW1vbk1vZHVsZS5qYXZhOjgwMilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZSQxLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NjApXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoVHJhY2VDb250ZXh0LmphdmE6MzE5KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjMxMSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDU3KVxuXHRhdCBjb20uZ29vZ2xlLmdzZS5pbnRlcm5hbC5EaXNwYXRjaFF1ZXVlSW1wbCRXb3JrZXJUaHJlYWQucnVuKERpc3BhdGNoUXVldWVJbXBsLmphdmE6NDAzKVxuIn1dLCJjb2RlIjo0MDMsIm1lc3NhZ2UiOiJpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiJ9fQ==" } }, { "ID": "1c8663192ed534e8", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/acl?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "2370" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:59 GMT" ], "Etag": [ "CAM=" ], "Expires": [ "Thu, 02 May 2019 22:24:59 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uqfc2TzyVBAwGuVpWWQt7OYr3IQEmVj5R7LIr5LSRAhwFernkoD6TFVnJno_ria4LL8P9tSQgzCF7uJpStJTpYgTOiW5FqTxQ-AgbOjFmAMjah3o6U" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9scyIsIml0ZW1zIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FNPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQU09In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQU09In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvdXNlci1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9hY2wvdXNlci1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsImVudGl0eSI6InVzZXItaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNBTT0ifSx7ImtpbmQiOiJzdG9yYWdlI2J1Y2tldEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9kb21haW4tZ29vZ2xlLmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9hY2wvZG9tYWluLWdvb2dsZS5jb20iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJlbnRpdHkiOiJkb21haW4tZ29vZ2xlLmNvbSIsInJvbGUiOiJSRUFERVIiLCJkb21haW4iOiJnb29nbGUuY29tIiwiZXRhZyI6IkNBTT0ifV19" } }, { "ID": "51858ae7ea77845a", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/acl?alt=json\u0026prettyPrint=false\u0026userProject=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "2370" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:59 GMT" ], "Etag": [ "CAM=" ], "Expires": [ "Thu, 02 May 2019 22:24:59 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uqc5V7vaPL-d4aMLJi5QXyxZYWWtGBx0QuvfeB8rFlhwPGPFLQUABxm_XXkR0AOeIqdZ-intSu7I5srWdFKX85aY8r-z4oRTuB-CjGUe5uMiXQzXU4" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9scyIsIml0ZW1zIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FNPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQU09In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQU09In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvdXNlci1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9hY2wvdXNlci1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsImVudGl0eSI6InVzZXItaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNBTT0ifSx7ImtpbmQiOiJzdG9yYWdlI2J1Y2tldEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9kb21haW4tZ29vZ2xlLmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9hY2wvZG9tYWluLWdvb2dsZS5jb20iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJlbnRpdHkiOiJkb21haW4tZ29vZ2xlLmNvbSIsInJvbGUiOiJSRUFERVIiLCJkb21haW4iOiJnb29nbGUuY29tIiwiZXRhZyI6IkNBTT0ifV19" } }, { "ID": "8248d1314da9a068", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/acl?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "12203" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:24:59 GMT" ], "Expires": [ "Thu, 02 May 2019 22:24:59 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2Uqrg4CYWnZtCkMXT5KHCcQXY-aSGc6JuuEoVkTtKgObB9qr-dE-5sMKCrbTfpFudhid3ulDpkNuOUmRmBy4k7QQoRxqgues_a8dB85cOybZKZTM864" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6InJlcXVpcmVkIiwibWVzc2FnZSI6IkJ1Y2tldCBpcyByZXF1ZXN0ZXIgcGF5cyBidWNrZXQgYnV0IG5vIHVzZXIgcHJvamVjdCBwcm92aWRlZC4iLCJkZWJ1Z0luZm8iOiJjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX01JU1NJTkc6IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5MaXN0QWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoTGlzdEFjbHMuamF2YToxMDEpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5MaXN0QWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoTGlzdEFjbHMuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IubGlzdChBY2Nlc3NDb250cm9sc0RlbGVnYXRvci5qYXZhOjg5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuXG5jb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS5GYXVsdDogSW1tdXRhYmxlRXJyb3JEZWZpbml0aW9ue2Jhc2U9UkVRVUlSRUQsIGNhdGVnb3J5PVVTRVJfRVJST1IsIGNhdXNlPW51bGwsIGRlYnVnSW5mbz1jb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX01JU1NJTkc6IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5MaXN0QWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoTGlzdEFjbHMuamF2YToxMDEpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5MaXN0QWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoTGlzdEFjbHMuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IubGlzdChBY2Nlc3NDb250cm9sc0RlbGVnYXRvci5qYXZhOjg5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuLCBkb21haW49Z2xvYmFsLCBleHRlbmRlZEhlbHA9bnVsbCwgaHR0cEhlYWRlcnM9e30sIGh0dHBTdGF0dXM9YmFkUmVxdWVzdCwgaW50ZXJuYWxSZWFzb249UmVhc29ue2FyZ3VtZW50cz17fSwgY2F1c2U9bnVsbCwgY29kZT1nZGF0YS5Db3JlRXJyb3JEb21haW4uUkVRVUlSRUQsIGNyZWF0ZWRCeUJhY2tlbmQ9dHJ1ZSwgZGVidWdNZXNzYWdlPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpVU0VSX1BST0pFQ1RfTUlTU0lORzogQnVja2V0IGlzIFJlcXVlc3RlciBQYXlzIGJ1Y2tldCBidXQgbm8gYmlsbGluZyBwcm9qZWN0IGlkIHByb3ZpZGVkIGZvciBub24tb3duZXIuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkxpc3RBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChMaXN0QWNscy5qYXZhOjEwMSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkxpc3RBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChMaXN0QWNscy5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci5saXN0KEFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmphdmE6ODkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGVycm9yUHJvdG9Db2RlPVJFUVVJUkVELCBlcnJvclByb3RvRG9tYWluPWdkYXRhLkNvcmVFcnJvckRvbWFpbiwgZmlsdGVyZWRNZXNzYWdlPW51bGwsIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9QnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLiwgdW5uYW1lZEFyZ3VtZW50cz1bXX0sIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9QnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLiwgcmVhc29uPXJlcXVpcmVkLCBycGNDb2RlPTQwMH0gQnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLjogY29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuTGlzdEFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKExpc3RBY2xzLmphdmE6MTAxKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuTGlzdEFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKExpc3RBY2xzLmphdmE6MjUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLkFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmxpc3QoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YTo4OSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogQnVja2V0IGlzIFJlcXVlc3RlciBQYXlzIGJ1Y2tldCBidXQgbm8gYmlsbGluZyBwcm9qZWN0IGlkIHByb3ZpZGVkIGZvciBub24tb3duZXIuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS5FcnJvckNvbGxlY3Rvci50b0ZhdWx0KEVycm9yQ29sbGVjdG9yLmphdmE6NTQpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5RXJyb3JDb252ZXJ0ZXIudG9GYXVsdChSb3N5RXJyb3JDb252ZXJ0ZXIuamF2YTo2Nylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lIYW5kbGVyJDIuY2FsbChSb3N5SGFuZGxlci5qYXZhOjI1OSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lIYW5kbGVyJDIuY2FsbChSb3N5SGFuZGxlci5qYXZhOjIzOSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkRpcmVjdEV4ZWN1dG9yLmV4ZWN1dGUoRGlyZWN0RXhlY3V0b3IuamF2YTozMClcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmV4ZWN1dGVMaXN0ZW5lcihBYnN0cmFjdEZ1dHVyZS5qYXZhOjExNDMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5jb21wbGV0ZShBYnN0cmFjdEZ1dHVyZS5qYXZhOjk2Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLnNldChBYnN0cmFjdEZ1dHVyZS5qYXZhOjczMSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkRpcmVjdEV4ZWN1dG9yLmV4ZWN1dGUoRGlyZWN0RXhlY3V0b3IuamF2YTozMClcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmV4ZWN1dGVMaXN0ZW5lcihBYnN0cmFjdEZ1dHVyZS5qYXZhOjExNDMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5jb21wbGV0ZShBYnN0cmFjdEZ1dHVyZS5qYXZhOjk2Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLnNldChBYnN0cmFjdEZ1dHVyZS5qYXZhOjczMSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnRocmVhZC5UaHJlYWRUcmFja2VycyRUaHJlYWRUcmFja2luZ1J1bm5hYmxlLnJ1bihUaHJlYWRUcmFja2Vycy5qYXZhOjEyNilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoVHJhY2VDb250ZXh0LmphdmE6NDUzKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuc2VydmVyLkNvbW1vbk1vZHVsZSRDb250ZXh0Q2FycnlpbmdFeGVjdXRvclNlcnZpY2UkMS5ydW5JbkNvbnRleHQoQ29tbW9uTW9kdWxlLmphdmE6ODAyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlJDEucnVuKFRyYWNlQ29udGV4dC5qYXZhOjQ2MClcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihUcmFjZUNvbnRleHQuamF2YTozMTkpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkQWJzdHJhY3RUcmFjZUNvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoVHJhY2VDb250ZXh0LmphdmE6MzExKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NTcpXG5cdGF0IGNvbS5nb29nbGUuZ3NlLmludGVybmFsLkRpc3BhdGNoUXVldWVJbXBsJFdvcmtlclRocmVhZC5ydW4oRGlzcGF0Y2hRdWV1ZUltcGwuamF2YTo0MDMpXG4ifV0sImNvZGUiOjQwMCwibWVzc2FnZSI6IkJ1Y2tldCBpcyByZXF1ZXN0ZXIgcGF5cyBidWNrZXQgYnV0IG5vIHVzZXIgcHJvamVjdCBwcm92aWRlZC4ifX0=" } }, { "ID": "8c1628782bcf7eaf", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/acl?alt=json\u0026prettyPrint=false\u0026userProject=gcloud-golang-firestore-tests", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "2370" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:00 GMT" ], "Etag": [ "CAM=" ], "Expires": [ "Thu, 02 May 2019 22:25:00 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uqmer5wTHG4zziRJUR_QqUbX_xgytHZkMg2KFntbVz8pn55RFN7idAyYcqz3AhqthLD-bHH2Lggdg4MuIdjHVk_kKHxvDdqI0p814avmZPYAhJdvsE" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9scyIsIml0ZW1zIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FNPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQU09In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQU09In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvdXNlci1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9hY2wvdXNlci1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsImVudGl0eSI6InVzZXItaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNBTT0ifSx7ImtpbmQiOiJzdG9yYWdlI2J1Y2tldEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9kb21haW4tZ29vZ2xlLmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9hY2wvZG9tYWluLWdvb2dsZS5jb20iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJlbnRpdHkiOiJkb21haW4tZ29vZ2xlLmNvbSIsInJvbGUiOiJSRUFERVIiLCJkb21haW4iOiJnb29nbGUuY29tIiwiZXRhZyI6IkNBTT0ifV19" } }, { "ID": "6813d64060667ba0", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/acl?alt=json\u0026prettyPrint=false\u0026userProject=veener-jba", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 403, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "13059" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:00 GMT" ], "Expires": [ "Thu, 02 May 2019 22:25:00 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UpsvYC9PE_CO5H9MncFfA0uYzQqFBOqu0_zdexcxDTJ22CO_vv1LiRY6ZSC49_FMeUZBA3KdMfOnS7DsSxBpqrLC9ZM6GAs2sFolmZKhp0RWJjvOzs" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6ImZvcmJpZGRlbiIsIm1lc3NhZ2UiOiJpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpVU0VSX1BST0pFQ1RfQUNDRVNTX0RFTklFRDogaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20gZG9lcyBub3QgaGF2ZSBzZXJ2aWNldXNhZ2Uuc2VydmljZXMudXNlIGFjY2VzcyB0byBwcm9qZWN0IDY0MjA4MDkxODEwMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuTGlzdEFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKExpc3RBY2xzLmphdmE6MTAxKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuTGlzdEFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKExpc3RBY2xzLmphdmE6MjUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLkFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmxpc3QoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YTo4OSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20gZG9lcyBub3QgaGF2ZSBzZXJ2aWNldXNhZ2Uuc2VydmljZXMudXNlIGFjY2VzcyB0byBwcm9qZWN0IDY0MjA4MDkxODEwMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuXG5jb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS5GYXVsdDogSW1tdXRhYmxlRXJyb3JEZWZpbml0aW9ue2Jhc2U9Rk9SQklEREVOLCBjYXRlZ29yeT1VU0VSX0VSUk9SLCBjYXVzZT1udWxsLCBkZWJ1Z0luZm89Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9BQ0NFU1NfREVOSUVEOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5MaXN0QWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoTGlzdEFjbHMuamF2YToxMDEpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5MaXN0QWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoTGlzdEFjbHMuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IubGlzdChBY2Nlc3NDb250cm9sc0RlbGVnYXRvci5qYXZhOjg5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGRvbWFpbj1nbG9iYWwsIGV4dGVuZGVkSGVscD1udWxsLCBodHRwSGVhZGVycz17fSwgaHR0cFN0YXR1cz1mb3JiaWRkZW4sIGludGVybmFsUmVhc29uPVJlYXNvbnthcmd1bWVudHM9e30sIGNhdXNlPW51bGwsIGNvZGU9Z2RhdGEuQ29yZUVycm9yRG9tYWluLkZPUkJJRERFTiwgY3JlYXRlZEJ5QmFja2VuZD10cnVlLCBkZWJ1Z01lc3NhZ2U9Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9BQ0NFU1NfREVOSUVEOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5MaXN0QWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoTGlzdEFjbHMuamF2YToxMDEpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5MaXN0QWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoTGlzdEFjbHMuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IubGlzdChBY2Nlc3NDb250cm9sc0RlbGVnYXRvci5qYXZhOjg5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGVycm9yUHJvdG9Db2RlPUZPUkJJRERFTiwgZXJyb3JQcm90b0RvbWFpbj1nZGF0YS5Db3JlRXJyb3JEb21haW4sIGZpbHRlcmVkTWVzc2FnZT1udWxsLCBsb2NhdGlvbj1udWxsLCBtZXNzYWdlPWludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuLCB1bm5hbWVkQXJndW1lbnRzPVtdfSwgbG9jYXRpb249bnVsbCwgbWVzc2FnZT1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiwgcmVhc29uPWZvcmJpZGRlbiwgcnBjQ29kZT00MDN9IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuOiBjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX0FDQ0VTU19ERU5JRUQ6IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkxpc3RBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChMaXN0QWNscy5qYXZhOjEwMSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkxpc3RBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChMaXN0QWNscy5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci5saXN0KEFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmphdmE6ODkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS5FcnJvckNvbGxlY3Rvci50b0ZhdWx0KEVycm9yQ29sbGVjdG9yLmphdmE6NTQpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5RXJyb3JDb252ZXJ0ZXIudG9GYXVsdChSb3N5RXJyb3JDb252ZXJ0ZXIuamF2YTo2Nylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lIYW5kbGVyJDIuY2FsbChSb3N5SGFuZGxlci5qYXZhOjI1OSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lIYW5kbGVyJDIuY2FsbChSb3N5SGFuZGxlci5qYXZhOjIzOSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkRpcmVjdEV4ZWN1dG9yLmV4ZWN1dGUoRGlyZWN0RXhlY3V0b3IuamF2YTozMClcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmV4ZWN1dGVMaXN0ZW5lcihBYnN0cmFjdEZ1dHVyZS5qYXZhOjExNDMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5jb21wbGV0ZShBYnN0cmFjdEZ1dHVyZS5qYXZhOjk2Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLnNldChBYnN0cmFjdEZ1dHVyZS5qYXZhOjczMSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkRpcmVjdEV4ZWN1dG9yLmV4ZWN1dGUoRGlyZWN0RXhlY3V0b3IuamF2YTozMClcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmV4ZWN1dGVMaXN0ZW5lcihBYnN0cmFjdEZ1dHVyZS5qYXZhOjExNDMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5jb21wbGV0ZShBYnN0cmFjdEZ1dHVyZS5qYXZhOjk2Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLnNldChBYnN0cmFjdEZ1dHVyZS5qYXZhOjczMSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnRocmVhZC5UaHJlYWRUcmFja2VycyRUaHJlYWRUcmFja2luZ1J1bm5hYmxlLnJ1bihUaHJlYWRUcmFja2Vycy5qYXZhOjEyNilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoVHJhY2VDb250ZXh0LmphdmE6NDUzKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuc2VydmVyLkNvbW1vbk1vZHVsZSRDb250ZXh0Q2FycnlpbmdFeGVjdXRvclNlcnZpY2UkMS5ydW5JbkNvbnRleHQoQ29tbW9uTW9kdWxlLmphdmE6ODAyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlJDEucnVuKFRyYWNlQ29udGV4dC5qYXZhOjQ2MClcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihUcmFjZUNvbnRleHQuamF2YTozMTkpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkQWJzdHJhY3RUcmFjZUNvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoVHJhY2VDb250ZXh0LmphdmE6MzExKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NTcpXG5cdGF0IGNvbS5nb29nbGUuZ3NlLmludGVybmFsLkRpc3BhdGNoUXVldWVJbXBsJFdvcmtlclRocmVhZC5ydW4oRGlzcGF0Y2hRdWV1ZUltcGwuamF2YTo0MDMpXG4ifV0sImNvZGUiOjQwMywibWVzc2FnZSI6ImludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuIn19" } }, { "ID": "76ac0290041d5a26", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/acl/domain-google.com?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:25:01 GMT" ], "Etag": [ "CAQ=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Ur-ejQ-G_PN4CMllngdiEh1SqHQNy8TXBA-htpazVSOadp1oThRsYsQuflX2kwkDQHFpeo1UgDPXqi5BRq8qZUBsM2koJIMOp-APWnB8T_qsTHlY30" ] }, "Body": "" } }, { "ID": "0de0d173f3f5c2cc", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/acl/domain-google.com?alt=json\u0026prettyPrint=false\u0026userProject=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 404, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "11631" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:01 GMT" ], "Expires": [ "Thu, 02 May 2019 22:25:01 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UqLOtWcLW6yZk8n72e3qkdl4ft2-s7FJFYyRv_5REkk9Q6d7qk6Pcpcy_HMCJFgKTV5RZzzIU3k5hceknIV1XNGVWK7gOCFimyeb8sFjNZC7y7rypI" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6Im5vdEZvdW5kIiwibWVzc2FnZSI6Ik5vdCBGb3VuZCIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpBQ0xfU0NPUEVfTk9UX0ZPVU5EOiBTcGVjaWZpZWQgQUNMIHNjb3BlIHdhcyBub3QgZm91bmRcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjg2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci5kZWxldGUoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YToxMDkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IFNwZWNpZmllZCBBQ0wgc2NvcGUgd2FzIG5vdCBmb3VuZFxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cbmNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLkZhdWx0OiBJbW11dGFibGVFcnJvckRlZmluaXRpb257YmFzZT1OT1RfRk9VTkQsIGNhdGVnb3J5PVVTRVJfRVJST1IsIGNhdXNlPW51bGwsIGRlYnVnSW5mbz1jb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6QUNMX1NDT1BFX05PVF9GT1VORDogU3BlY2lmaWVkIEFDTCBzY29wZSB3YXMgbm90IGZvdW5kXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkRlbGV0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZUFjbHMuamF2YTo4Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkRlbGV0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZUFjbHMuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuZGVsZXRlKEFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmphdmE6MTA5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBTcGVjaWZpZWQgQUNMIHNjb3BlIHdhcyBub3QgZm91bmRcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuLCBkb21haW49Z2xvYmFsLCBleHRlbmRlZEhlbHA9bnVsbCwgaHR0cEhlYWRlcnM9e30sIGh0dHBTdGF0dXM9bm90Rm91bmQsIGludGVybmFsUmVhc29uPVJlYXNvbnthcmd1bWVudHM9e30sIGNhdXNlPW51bGwsIGNvZGU9Z2RhdGEuQ29yZUVycm9yRG9tYWluLk5PVF9GT1VORCwgY3JlYXRlZEJ5QmFja2VuZD10cnVlLCBkZWJ1Z01lc3NhZ2U9Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OkFDTF9TQ09QRV9OT1RfRk9VTkQ6IFNwZWNpZmllZCBBQ0wgc2NvcGUgd2FzIG5vdCBmb3VuZFxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5EZWxldGVBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChEZWxldGVBY2xzLmphdmE6ODYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5EZWxldGVBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChEZWxldGVBY2xzLmphdmE6MjUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLkFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmRlbGV0ZShBY2Nlc3NDb250cm9sc0RlbGVnYXRvci5qYXZhOjEwOSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogU3BlY2lmaWVkIEFDTCBzY29wZSB3YXMgbm90IGZvdW5kXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZXJyb3JQcm90b0NvZGU9Tk9UX0ZPVU5ELCBlcnJvclByb3RvRG9tYWluPWdkYXRhLkNvcmVFcnJvckRvbWFpbiwgZmlsdGVyZWRNZXNzYWdlPW51bGwsIGxvY2F0aW9uPWVudGl0eS5yZXNvdXJjZV9pZC5zY29wZSwgbWVzc2FnZT1udWxsLCB1bm5hbWVkQXJndW1lbnRzPVtdfSwgbG9jYXRpb249ZW50aXR5LnJlc291cmNlX2lkLnNjb3BlLCBtZXNzYWdlPU5vdCBGb3VuZCwgcmVhc29uPW5vdEZvdW5kLCBycGNDb2RlPTQwNH0gTm90IEZvdW5kOiBjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6QUNMX1NDT1BFX05PVF9GT1VORDogU3BlY2lmaWVkIEFDTCBzY29wZSB3YXMgbm90IGZvdW5kXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkRlbGV0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZUFjbHMuamF2YTo4Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkRlbGV0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZUFjbHMuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuZGVsZXRlKEFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmphdmE6MTA5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBTcGVjaWZpZWQgQUNMIHNjb3BlIHdhcyBub3QgZm91bmRcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLkVycm9yQ29sbGVjdG9yLnRvRmF1bHQoRXJyb3JDb2xsZWN0b3IuamF2YTo1NClcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lFcnJvckNvbnZlcnRlci50b0ZhdWx0KFJvc3lFcnJvckNvbnZlcnRlci5qYXZhOjY3KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUhhbmRsZXIkMi5jYWxsKFJvc3lIYW5kbGVyLmphdmE6MjU5KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUhhbmRsZXIkMi5jYWxsKFJvc3lIYW5kbGVyLmphdmE6MjM5KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRGlyZWN0RXhlY3V0b3IuZXhlY3V0ZShEaXJlY3RFeGVjdXRvci5qYXZhOjMwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuZXhlY3V0ZUxpc3RlbmVyKEFic3RyYWN0RnV0dXJlLmphdmE6MTE0Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmNvbXBsZXRlKEFic3RyYWN0RnV0dXJlLmphdmE6OTYzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuc2V0KEFic3RyYWN0RnV0dXJlLmphdmE6NzMxKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRGlyZWN0RXhlY3V0b3IuZXhlY3V0ZShEaXJlY3RFeGVjdXRvci5qYXZhOjMwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuZXhlY3V0ZUxpc3RlbmVyKEFic3RyYWN0RnV0dXJlLmphdmE6MTE0Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmNvbXBsZXRlKEFic3RyYWN0RnV0dXJlLmphdmE6OTYzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuc2V0KEFic3RyYWN0RnV0dXJlLmphdmE6NzMxKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIudGhyZWFkLlRocmVhZFRyYWNrZXJzJFRocmVhZFRyYWNraW5nUnVubmFibGUucnVuKFRocmVhZFRyYWNrZXJzLmphdmE6MTI2KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChUcmFjZUNvbnRleHQuamF2YTo0NTMpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5zZXJ2ZXIuQ29tbW9uTW9kdWxlJENvbnRleHRDYXJyeWluZ0V4ZWN1dG9yU2VydmljZSQxLnJ1bkluQ29udGV4dChDb21tb25Nb2R1bGUuamF2YTo4MDIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUkMS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDYwKVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkQWJzdHJhY3RUcmFjZUNvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKFRyYWNlQ29udGV4dC5qYXZhOjMxOSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChUcmFjZUNvbnRleHQuamF2YTozMTEpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuKFRyYWNlQ29udGV4dC5qYXZhOjQ1Nylcblx0YXQgY29tLmdvb2dsZS5nc2UuaW50ZXJuYWwuRGlzcGF0Y2hRdWV1ZUltcGwkV29ya2VyVGhyZWFkLnJ1bihEaXNwYXRjaFF1ZXVlSW1wbC5qYXZhOjQwMylcbiJ9XSwiY29kZSI6NDA0LCJtZXNzYWdlIjoiTm90IEZvdW5kIn19" } }, { "ID": "eb2af5bce5b9e1df", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/acl/domain-google.com?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "12243" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:02 GMT" ], "Expires": [ "Thu, 02 May 2019 22:25:02 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2Uqgaldc1OJvgmfZxcZs4i5d6EXMyFK93ZUJLzSK8Vo-qPYKRwhvPzK8GFv3gqrdyjBbvdc2Uz57nCwy10LhC5AD2pscln8VbaQIOAHqxvkwsqV27Rw" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6InJlcXVpcmVkIiwibWVzc2FnZSI6IkJ1Y2tldCBpcyByZXF1ZXN0ZXIgcGF5cyBidWNrZXQgYnV0IG5vIHVzZXIgcHJvamVjdCBwcm92aWRlZC4iLCJkZWJ1Z0luZm8iOiJjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX01JU1NJTkc6IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5EZWxldGVBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChEZWxldGVBY2xzLmphdmE6ODYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5EZWxldGVBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChEZWxldGVBY2xzLmphdmE6MjUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLkFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmRlbGV0ZShBY2Nlc3NDb250cm9sc0RlbGVnYXRvci5qYXZhOjEwOSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogQnVja2V0IGlzIFJlcXVlc3RlciBQYXlzIGJ1Y2tldCBidXQgbm8gYmlsbGluZyBwcm9qZWN0IGlkIHByb3ZpZGVkIGZvciBub24tb3duZXIuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPVJFUVVJUkVELCBjYXRlZ29yeT1VU0VSX0VSUk9SLCBjYXVzZT1udWxsLCBkZWJ1Z0luZm89Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjg2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci5kZWxldGUoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YToxMDkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGRvbWFpbj1nbG9iYWwsIGV4dGVuZGVkSGVscD1udWxsLCBodHRwSGVhZGVycz17fSwgaHR0cFN0YXR1cz1iYWRSZXF1ZXN0LCBpbnRlcm5hbFJlYXNvbj1SZWFzb257YXJndW1lbnRzPXt9LCBjYXVzZT1udWxsLCBjb2RlPWdkYXRhLkNvcmVFcnJvckRvbWFpbi5SRVFVSVJFRCwgY3JlYXRlZEJ5QmFja2VuZD10cnVlLCBkZWJ1Z01lc3NhZ2U9Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjg2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci5kZWxldGUoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YToxMDkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGVycm9yUHJvdG9Db2RlPVJFUVVJUkVELCBlcnJvclByb3RvRG9tYWluPWdkYXRhLkNvcmVFcnJvckRvbWFpbiwgZmlsdGVyZWRNZXNzYWdlPW51bGwsIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9QnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLiwgdW5uYW1lZEFyZ3VtZW50cz1bXX0sIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9QnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLiwgcmVhc29uPXJlcXVpcmVkLCBycGNDb2RlPTQwMH0gQnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLjogY29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjg2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci5kZWxldGUoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YToxMDkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRXJyb3JDb2xsZWN0b3IudG9GYXVsdChFcnJvckNvbGxlY3Rvci5qYXZhOjU0KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUVycm9yQ29udmVydGVyLnRvRmF1bHQoUm9zeUVycm9yQ29udmVydGVyLmphdmE6NjcpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyNTkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyMzkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci50aHJlYWQuVGhyZWFkVHJhY2tlcnMkVGhyZWFkVHJhY2tpbmdSdW5uYWJsZS5ydW4oVGhyZWFkVHJhY2tlcnMuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjQ1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnNlcnZlci5Db21tb25Nb2R1bGUkQ29udGV4dENhcnJ5aW5nRXhlY3V0b3JTZXJ2aWNlJDEucnVuSW5Db250ZXh0KENvbW1vbk1vZHVsZS5qYXZhOjgwMilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZSQxLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NjApXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoVHJhY2VDb250ZXh0LmphdmE6MzE5KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjMxMSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDU3KVxuXHRhdCBjb20uZ29vZ2xlLmdzZS5pbnRlcm5hbC5EaXNwYXRjaFF1ZXVlSW1wbCRXb3JrZXJUaHJlYWQucnVuKERpc3BhdGNoUXVldWVJbXBsLmphdmE6NDAzKVxuIn1dLCJjb2RlIjo0MDAsIm1lc3NhZ2UiOiJCdWNrZXQgaXMgcmVxdWVzdGVyIHBheXMgYnVja2V0IGJ1dCBubyB1c2VyIHByb2plY3QgcHJvdmlkZWQuIn19" } }, { "ID": "ad55ad01147a8c62", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/acl/domain-google.com?alt=json\u0026prettyPrint=false\u0026userProject=gcloud-golang-firestore-tests", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 404, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "11631" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:02 GMT" ], "Expires": [ "Thu, 02 May 2019 22:25:02 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UoQpkkPNbb1CGY8lAzUfymkmZ7PNlRK6hK3deBeoMip13ARTb212DIgf4lgUDM8PVQsAqcnKwzNulbZICoGzHwrsBZfyi7p5TGX2yJHLXSAGEY0MBE" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6Im5vdEZvdW5kIiwibWVzc2FnZSI6Ik5vdCBGb3VuZCIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpBQ0xfU0NPUEVfTk9UX0ZPVU5EOiBTcGVjaWZpZWQgQUNMIHNjb3BlIHdhcyBub3QgZm91bmRcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjg2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci5kZWxldGUoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YToxMDkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IFNwZWNpZmllZCBBQ0wgc2NvcGUgd2FzIG5vdCBmb3VuZFxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cbmNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLkZhdWx0OiBJbW11dGFibGVFcnJvckRlZmluaXRpb257YmFzZT1OT1RfRk9VTkQsIGNhdGVnb3J5PVVTRVJfRVJST1IsIGNhdXNlPW51bGwsIGRlYnVnSW5mbz1jb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6QUNMX1NDT1BFX05PVF9GT1VORDogU3BlY2lmaWVkIEFDTCBzY29wZSB3YXMgbm90IGZvdW5kXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkRlbGV0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZUFjbHMuamF2YTo4Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkRlbGV0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZUFjbHMuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuZGVsZXRlKEFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmphdmE6MTA5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBTcGVjaWZpZWQgQUNMIHNjb3BlIHdhcyBub3QgZm91bmRcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuLCBkb21haW49Z2xvYmFsLCBleHRlbmRlZEhlbHA9bnVsbCwgaHR0cEhlYWRlcnM9e30sIGh0dHBTdGF0dXM9bm90Rm91bmQsIGludGVybmFsUmVhc29uPVJlYXNvbnthcmd1bWVudHM9e30sIGNhdXNlPW51bGwsIGNvZGU9Z2RhdGEuQ29yZUVycm9yRG9tYWluLk5PVF9GT1VORCwgY3JlYXRlZEJ5QmFja2VuZD10cnVlLCBkZWJ1Z01lc3NhZ2U9Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OkFDTF9TQ09QRV9OT1RfRk9VTkQ6IFNwZWNpZmllZCBBQ0wgc2NvcGUgd2FzIG5vdCBmb3VuZFxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5EZWxldGVBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChEZWxldGVBY2xzLmphdmE6ODYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5EZWxldGVBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChEZWxldGVBY2xzLmphdmE6MjUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLkFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmRlbGV0ZShBY2Nlc3NDb250cm9sc0RlbGVnYXRvci5qYXZhOjEwOSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogU3BlY2lmaWVkIEFDTCBzY29wZSB3YXMgbm90IGZvdW5kXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZXJyb3JQcm90b0NvZGU9Tk9UX0ZPVU5ELCBlcnJvclByb3RvRG9tYWluPWdkYXRhLkNvcmVFcnJvckRvbWFpbiwgZmlsdGVyZWRNZXNzYWdlPW51bGwsIGxvY2F0aW9uPWVudGl0eS5yZXNvdXJjZV9pZC5zY29wZSwgbWVzc2FnZT1udWxsLCB1bm5hbWVkQXJndW1lbnRzPVtdfSwgbG9jYXRpb249ZW50aXR5LnJlc291cmNlX2lkLnNjb3BlLCBtZXNzYWdlPU5vdCBGb3VuZCwgcmVhc29uPW5vdEZvdW5kLCBycGNDb2RlPTQwNH0gTm90IEZvdW5kOiBjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6QUNMX1NDT1BFX05PVF9GT1VORDogU3BlY2lmaWVkIEFDTCBzY29wZSB3YXMgbm90IGZvdW5kXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkRlbGV0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZUFjbHMuamF2YTo4Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkRlbGV0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZUFjbHMuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuZGVsZXRlKEFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmphdmE6MTA5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBTcGVjaWZpZWQgQUNMIHNjb3BlIHdhcyBub3QgZm91bmRcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLkVycm9yQ29sbGVjdG9yLnRvRmF1bHQoRXJyb3JDb2xsZWN0b3IuamF2YTo1NClcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lFcnJvckNvbnZlcnRlci50b0ZhdWx0KFJvc3lFcnJvckNvbnZlcnRlci5qYXZhOjY3KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUhhbmRsZXIkMi5jYWxsKFJvc3lIYW5kbGVyLmphdmE6MjU5KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUhhbmRsZXIkMi5jYWxsKFJvc3lIYW5kbGVyLmphdmE6MjM5KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRGlyZWN0RXhlY3V0b3IuZXhlY3V0ZShEaXJlY3RFeGVjdXRvci5qYXZhOjMwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuZXhlY3V0ZUxpc3RlbmVyKEFic3RyYWN0RnV0dXJlLmphdmE6MTE0Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmNvbXBsZXRlKEFic3RyYWN0RnV0dXJlLmphdmE6OTYzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuc2V0KEFic3RyYWN0RnV0dXJlLmphdmE6NzMxKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRGlyZWN0RXhlY3V0b3IuZXhlY3V0ZShEaXJlY3RFeGVjdXRvci5qYXZhOjMwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuZXhlY3V0ZUxpc3RlbmVyKEFic3RyYWN0RnV0dXJlLmphdmE6MTE0Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmNvbXBsZXRlKEFic3RyYWN0RnV0dXJlLmphdmE6OTYzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuc2V0KEFic3RyYWN0RnV0dXJlLmphdmE6NzMxKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIudGhyZWFkLlRocmVhZFRyYWNrZXJzJFRocmVhZFRyYWNraW5nUnVubmFibGUucnVuKFRocmVhZFRyYWNrZXJzLmphdmE6MTI2KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChUcmFjZUNvbnRleHQuamF2YTo0NTMpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5zZXJ2ZXIuQ29tbW9uTW9kdWxlJENvbnRleHRDYXJyeWluZ0V4ZWN1dG9yU2VydmljZSQxLnJ1bkluQ29udGV4dChDb21tb25Nb2R1bGUuamF2YTo4MDIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUkMS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDYwKVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkQWJzdHJhY3RUcmFjZUNvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKFRyYWNlQ29udGV4dC5qYXZhOjMxOSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChUcmFjZUNvbnRleHQuamF2YTozMTEpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuKFRyYWNlQ29udGV4dC5qYXZhOjQ1Nylcblx0YXQgY29tLmdvb2dsZS5nc2UuaW50ZXJuYWwuRGlzcGF0Y2hRdWV1ZUltcGwkV29ya2VyVGhyZWFkLnJ1bihEaXNwYXRjaFF1ZXVlSW1wbC5qYXZhOjQwMylcbiJ9XSwiY29kZSI6NDA0LCJtZXNzYWdlIjoiTm90IEZvdW5kIn19" } }, { "ID": "1ef9ea9b9bc398a6", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/acl/domain-google.com?alt=json\u0026prettyPrint=false\u0026userProject=veener-jba", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 403, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "13099" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:03 GMT" ], "Expires": [ "Thu, 02 May 2019 22:25:03 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2Ur5WrZwygTHM0dDH6L1kypZzaAQtCwxt9wA7VXvgnjwrfwdRnTw0D7K3VLYLRTPDcf8mRFn5CetkcimFxfqUDoWLMF7bH1TLiBr38K6aBU74aRWUd4" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6ImZvcmJpZGRlbiIsIm1lc3NhZ2UiOiJpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpVU0VSX1BST0pFQ1RfQUNDRVNTX0RFTklFRDogaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20gZG9lcyBub3QgaGF2ZSBzZXJ2aWNldXNhZ2Uuc2VydmljZXMudXNlIGFjY2VzcyB0byBwcm9qZWN0IDY0MjA4MDkxODEwMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjg2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci5kZWxldGUoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YToxMDkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPUZPUkJJRERFTiwgY2F0ZWdvcnk9VVNFUl9FUlJPUiwgY2F1c2U9bnVsbCwgZGVidWdJbmZvPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpVU0VSX1BST0pFQ1RfQUNDRVNTX0RFTklFRDogaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20gZG9lcyBub3QgaGF2ZSBzZXJ2aWNldXNhZ2Uuc2VydmljZXMudXNlIGFjY2VzcyB0byBwcm9qZWN0IDY0MjA4MDkxODEwMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjg2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci5kZWxldGUoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YToxMDkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZG9tYWluPWdsb2JhbCwgZXh0ZW5kZWRIZWxwPW51bGwsIGh0dHBIZWFkZXJzPXt9LCBodHRwU3RhdHVzPWZvcmJpZGRlbiwgaW50ZXJuYWxSZWFzb249UmVhc29ue2FyZ3VtZW50cz17fSwgY2F1c2U9bnVsbCwgY29kZT1nZGF0YS5Db3JlRXJyb3JEb21haW4uRk9SQklEREVOLCBjcmVhdGVkQnlCYWNrZW5kPXRydWUsIGRlYnVnTWVzc2FnZT1jb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX0FDQ0VTU19ERU5JRUQ6IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkRlbGV0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZUFjbHMuamF2YTo4Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkRlbGV0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZUFjbHMuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuZGVsZXRlKEFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmphdmE6MTA5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGVycm9yUHJvdG9Db2RlPUZPUkJJRERFTiwgZXJyb3JQcm90b0RvbWFpbj1nZGF0YS5Db3JlRXJyb3JEb21haW4sIGZpbHRlcmVkTWVzc2FnZT1udWxsLCBsb2NhdGlvbj1udWxsLCBtZXNzYWdlPWludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuLCB1bm5hbWVkQXJndW1lbnRzPVtdfSwgbG9jYXRpb249bnVsbCwgbWVzc2FnZT1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiwgcmVhc29uPWZvcmJpZGRlbiwgcnBjQ29kZT00MDN9IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuOiBjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX0FDQ0VTU19ERU5JRUQ6IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkRlbGV0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZUFjbHMuamF2YTo4Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkRlbGV0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZUFjbHMuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuZGVsZXRlKEFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmphdmE6MTA5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRXJyb3JDb2xsZWN0b3IudG9GYXVsdChFcnJvckNvbGxlY3Rvci5qYXZhOjU0KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUVycm9yQ29udmVydGVyLnRvRmF1bHQoUm9zeUVycm9yQ29udmVydGVyLmphdmE6NjcpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyNTkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyMzkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci50aHJlYWQuVGhyZWFkVHJhY2tlcnMkVGhyZWFkVHJhY2tpbmdSdW5uYWJsZS5ydW4oVGhyZWFkVHJhY2tlcnMuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjQ1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnNlcnZlci5Db21tb25Nb2R1bGUkQ29udGV4dENhcnJ5aW5nRXhlY3V0b3JTZXJ2aWNlJDEucnVuSW5Db250ZXh0KENvbW1vbk1vZHVsZS5qYXZhOjgwMilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZSQxLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NjApXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoVHJhY2VDb250ZXh0LmphdmE6MzE5KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjMxMSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDU3KVxuXHRhdCBjb20uZ29vZ2xlLmdzZS5pbnRlcm5hbC5EaXNwYXRjaFF1ZXVlSW1wbCRXb3JrZXJUaHJlYWQucnVuKERpc3BhdGNoUXVldWVJbXBsLmphdmE6NDAzKVxuIn1dLCJjb2RlIjo0MDMsIm1lc3NhZ2UiOiJpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiJ9fQ==" } }, { "ID": "5c1cadcffc6c95e0", "Request": { "Method": "PUT", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/defaultObjectAcl/domain-google.com?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "107" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJlbnRpdHkiOiJkb21haW4tZ29vZ2xlLmNvbSIsInJvbGUiOiJSRUFERVIifQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "119" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:04 GMT" ], "Etag": [ "CAU=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uo_n__u-lZKgZqveqge9YBw7wQMldCd4t0io7l_L_nlcF4DSPBPvZd9jGPCstE1EYuQS9L-Z3Y53Q15FlqM1IcmRDv6bYEJQWqkpuzCRRa_TLh9P7A" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoiZG9tYWluLWdvb2dsZS5jb20iLCJyb2xlIjoiUkVBREVSIiwiZG9tYWluIjoiZ29vZ2xlLmNvbSIsImV0YWciOiJDQVU9In0=" } }, { "ID": "4a615256ab8c55b4", "Request": { "Method": "PUT", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/defaultObjectAcl/domain-google.com?alt=json\u0026prettyPrint=false\u0026userProject=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "107" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJlbnRpdHkiOiJkb21haW4tZ29vZ2xlLmNvbSIsInJvbGUiOiJSRUFERVIifQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "119" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:04 GMT" ], "Etag": [ "CAU=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpwGIlBhvugAIHxiObS0RPpJ40OY_R3exJfPh5IHLLB3SrdYtGMpD01QLdxc3E0IPGkBiTrwM-Z2X1gMcxuOqJWJUrhV4xTFe_n5G8bBxzievz39F4" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoiZG9tYWluLWdvb2dsZS5jb20iLCJyb2xlIjoiUkVBREVSIiwiZG9tYWluIjoiZ29vZ2xlLmNvbSIsImV0YWciOiJDQVU9In0=" } }, { "ID": "63c0acd95aa571a1", "Request": { "Method": "PUT", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/defaultObjectAcl/domain-google.com?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "107" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJlbnRpdHkiOiJkb21haW4tZ29vZ2xlLmNvbSIsInJvbGUiOiJSRUFERVIifQo=" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Content-Length": [ "12243" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:04 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UqNu5DFt-lpr-_4YX8LRIhoi3KVRYVgFAlG7WOPsY7IGJ2NLZSF3SQhmkvfL_IKZ0FWIwx1nGT6HBBe9t2RYXNE1kXis-9KgEaAWhrEByTud5QGx5c" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6InJlcXVpcmVkIiwibWVzc2FnZSI6IkJ1Y2tldCBpcyByZXF1ZXN0ZXIgcGF5cyBidWNrZXQgYnV0IG5vIHVzZXIgcHJvamVjdCBwcm92aWRlZC4iLCJkZWJ1Z0luZm8iOiJjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX01JU1NJTkc6IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5VcGRhdGVBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChVcGRhdGVBY2xzLmphdmE6OTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5VcGRhdGVBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChVcGRhdGVBY2xzLmphdmE6MjcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLkFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLnVwZGF0ZShBY2Nlc3NDb250cm9sc0RlbGVnYXRvci5qYXZhOjEwMylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogQnVja2V0IGlzIFJlcXVlc3RlciBQYXlzIGJ1Y2tldCBidXQgbm8gYmlsbGluZyBwcm9qZWN0IGlkIHByb3ZpZGVkIGZvciBub24tb3duZXIuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPVJFUVVJUkVELCBjYXRlZ29yeT1VU0VSX0VSUk9SLCBjYXVzZT1udWxsLCBkZWJ1Z0luZm89Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuVXBkYXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoVXBkYXRlQWNscy5qYXZhOjkwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuVXBkYXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoVXBkYXRlQWNscy5qYXZhOjI3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci51cGRhdGUoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YToxMDMpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGRvbWFpbj1nbG9iYWwsIGV4dGVuZGVkSGVscD1udWxsLCBodHRwSGVhZGVycz17fSwgaHR0cFN0YXR1cz1iYWRSZXF1ZXN0LCBpbnRlcm5hbFJlYXNvbj1SZWFzb257YXJndW1lbnRzPXt9LCBjYXVzZT1udWxsLCBjb2RlPWdkYXRhLkNvcmVFcnJvckRvbWFpbi5SRVFVSVJFRCwgY3JlYXRlZEJ5QmFja2VuZD10cnVlLCBkZWJ1Z01lc3NhZ2U9Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuVXBkYXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoVXBkYXRlQWNscy5qYXZhOjkwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuVXBkYXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoVXBkYXRlQWNscy5qYXZhOjI3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci51cGRhdGUoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YToxMDMpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGVycm9yUHJvdG9Db2RlPVJFUVVJUkVELCBlcnJvclByb3RvRG9tYWluPWdkYXRhLkNvcmVFcnJvckRvbWFpbiwgZmlsdGVyZWRNZXNzYWdlPW51bGwsIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9QnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLiwgdW5uYW1lZEFyZ3VtZW50cz1bXX0sIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9QnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLiwgcmVhc29uPXJlcXVpcmVkLCBycGNDb2RlPTQwMH0gQnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLjogY29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuVXBkYXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoVXBkYXRlQWNscy5qYXZhOjkwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuVXBkYXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoVXBkYXRlQWNscy5qYXZhOjI3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci51cGRhdGUoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YToxMDMpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRXJyb3JDb2xsZWN0b3IudG9GYXVsdChFcnJvckNvbGxlY3Rvci5qYXZhOjU0KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUVycm9yQ29udmVydGVyLnRvRmF1bHQoUm9zeUVycm9yQ29udmVydGVyLmphdmE6NjcpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyNTkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyMzkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci50aHJlYWQuVGhyZWFkVHJhY2tlcnMkVGhyZWFkVHJhY2tpbmdSdW5uYWJsZS5ydW4oVGhyZWFkVHJhY2tlcnMuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjQ1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnNlcnZlci5Db21tb25Nb2R1bGUkQ29udGV4dENhcnJ5aW5nRXhlY3V0b3JTZXJ2aWNlJDEucnVuSW5Db250ZXh0KENvbW1vbk1vZHVsZS5qYXZhOjgwMilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZSQxLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NjApXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoVHJhY2VDb250ZXh0LmphdmE6MzE5KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjMxMSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDU3KVxuXHRhdCBjb20uZ29vZ2xlLmdzZS5pbnRlcm5hbC5EaXNwYXRjaFF1ZXVlSW1wbCRXb3JrZXJUaHJlYWQucnVuKERpc3BhdGNoUXVldWVJbXBsLmphdmE6NDAzKVxuIn1dLCJjb2RlIjo0MDAsIm1lc3NhZ2UiOiJCdWNrZXQgaXMgcmVxdWVzdGVyIHBheXMgYnVja2V0IGJ1dCBubyB1c2VyIHByb2plY3QgcHJvdmlkZWQuIn19" } }, { "ID": "3c6b1be88134f9d9", "Request": { "Method": "PUT", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/defaultObjectAcl/domain-google.com?alt=json\u0026prettyPrint=false\u0026userProject=gcloud-golang-firestore-tests", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "107" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJlbnRpdHkiOiJkb21haW4tZ29vZ2xlLmNvbSIsInJvbGUiOiJSRUFERVIifQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "119" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:05 GMT" ], "Etag": [ "CAU=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqzTVWCTbjlM7VCFWFbOojrtt8ZMY9bRy0eXj0Uxj3gaYalvwqR0WBrtbX0iGQ-aN5pv3-Acc7EWIoHBa37YbMpx9fuoJUpTswmdpiCOH3wbMN7tIk" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoiZG9tYWluLWdvb2dsZS5jb20iLCJyb2xlIjoiUkVBREVSIiwiZG9tYWluIjoiZ29vZ2xlLmNvbSIsImV0YWciOiJDQVU9In0=" } }, { "ID": "60cde48b740e9a63", "Request": { "Method": "PUT", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/defaultObjectAcl/domain-google.com?alt=json\u0026prettyPrint=false\u0026userProject=veener-jba", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "107" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJlbnRpdHkiOiJkb21haW4tZ29vZ2xlLmNvbSIsInJvbGUiOiJSRUFERVIifQo=" ] }, "Response": { "StatusCode": 403, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Content-Length": [ "13099" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:05 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UrLyiKgPsp1RDgH3Q2SGlQAwTvGJwVDvb9U9FfvTysIFo6sO-5AoXrGPQfZpr80aMOEKojmPksURjhsteWSV9gdPsOlPIJMorxvQMHeomMCh-Bgmuo" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6ImZvcmJpZGRlbiIsIm1lc3NhZ2UiOiJpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpVU0VSX1BST0pFQ1RfQUNDRVNTX0RFTklFRDogaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20gZG9lcyBub3QgaGF2ZSBzZXJ2aWNldXNhZ2Uuc2VydmljZXMudXNlIGFjY2VzcyB0byBwcm9qZWN0IDY0MjA4MDkxODEwMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuVXBkYXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoVXBkYXRlQWNscy5qYXZhOjkwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuVXBkYXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoVXBkYXRlQWNscy5qYXZhOjI3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci51cGRhdGUoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YToxMDMpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPUZPUkJJRERFTiwgY2F0ZWdvcnk9VVNFUl9FUlJPUiwgY2F1c2U9bnVsbCwgZGVidWdJbmZvPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpVU0VSX1BST0pFQ1RfQUNDRVNTX0RFTklFRDogaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20gZG9lcyBub3QgaGF2ZSBzZXJ2aWNldXNhZ2Uuc2VydmljZXMudXNlIGFjY2VzcyB0byBwcm9qZWN0IDY0MjA4MDkxODEwMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuVXBkYXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoVXBkYXRlQWNscy5qYXZhOjkwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuVXBkYXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoVXBkYXRlQWNscy5qYXZhOjI3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci51cGRhdGUoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YToxMDMpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZG9tYWluPWdsb2JhbCwgZXh0ZW5kZWRIZWxwPW51bGwsIGh0dHBIZWFkZXJzPXt9LCBodHRwU3RhdHVzPWZvcmJpZGRlbiwgaW50ZXJuYWxSZWFzb249UmVhc29ue2FyZ3VtZW50cz17fSwgY2F1c2U9bnVsbCwgY29kZT1nZGF0YS5Db3JlRXJyb3JEb21haW4uRk9SQklEREVOLCBjcmVhdGVkQnlCYWNrZW5kPXRydWUsIGRlYnVnTWVzc2FnZT1jb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX0FDQ0VTU19ERU5JRUQ6IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLlVwZGF0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFVwZGF0ZUFjbHMuamF2YTo5MClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLlVwZGF0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFVwZGF0ZUFjbHMuamF2YToyNylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IudXBkYXRlKEFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmphdmE6MTAzKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGVycm9yUHJvdG9Db2RlPUZPUkJJRERFTiwgZXJyb3JQcm90b0RvbWFpbj1nZGF0YS5Db3JlRXJyb3JEb21haW4sIGZpbHRlcmVkTWVzc2FnZT1udWxsLCBsb2NhdGlvbj1udWxsLCBtZXNzYWdlPWludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuLCB1bm5hbWVkQXJndW1lbnRzPVtdfSwgbG9jYXRpb249bnVsbCwgbWVzc2FnZT1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiwgcmVhc29uPWZvcmJpZGRlbiwgcnBjQ29kZT00MDN9IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuOiBjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX0FDQ0VTU19ERU5JRUQ6IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLlVwZGF0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFVwZGF0ZUFjbHMuamF2YTo5MClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLlVwZGF0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFVwZGF0ZUFjbHMuamF2YToyNylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IudXBkYXRlKEFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmphdmE6MTAzKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRXJyb3JDb2xsZWN0b3IudG9GYXVsdChFcnJvckNvbGxlY3Rvci5qYXZhOjU0KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUVycm9yQ29udmVydGVyLnRvRmF1bHQoUm9zeUVycm9yQ29udmVydGVyLmphdmE6NjcpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyNTkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyMzkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci50aHJlYWQuVGhyZWFkVHJhY2tlcnMkVGhyZWFkVHJhY2tpbmdSdW5uYWJsZS5ydW4oVGhyZWFkVHJhY2tlcnMuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjQ1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnNlcnZlci5Db21tb25Nb2R1bGUkQ29udGV4dENhcnJ5aW5nRXhlY3V0b3JTZXJ2aWNlJDEucnVuSW5Db250ZXh0KENvbW1vbk1vZHVsZS5qYXZhOjgwMilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZSQxLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NjApXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoVHJhY2VDb250ZXh0LmphdmE6MzE5KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjMxMSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDU3KVxuXHRhdCBjb20uZ29vZ2xlLmdzZS5pbnRlcm5hbC5EaXNwYXRjaFF1ZXVlSW1wbCRXb3JrZXJUaHJlYWQucnVuKERpc3BhdGNoUXVldWVJbXBsLmphdmE6NDAzKVxuIn1dLCJjb2RlIjo0MDMsIm1lc3NhZ2UiOiJpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiJ9fQ==" } }, { "ID": "95b915570e7c2375", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/defaultObjectAcl?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "684" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:05 GMT" ], "Etag": [ "CAU=" ], "Expires": [ "Thu, 02 May 2019 22:25:05 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrOZjNI5VbLPTLuBwhSAdcgxvqgcFpH-ED4XyEgIbnndmtC_zJ0lkLfudymSRpdRE4NBxn1Vp-AmZnb1ONsP2I1GBnLYfpYRbzFQpmihPrgBkDnaB4" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9scyIsIml0ZW1zIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBVT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQVU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBVT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJkb21haW4tZ29vZ2xlLmNvbSIsInJvbGUiOiJSRUFERVIiLCJkb21haW4iOiJnb29nbGUuY29tIiwiZXRhZyI6IkNBVT0ifV19" } }, { "ID": "e4170c637b705043", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/defaultObjectAcl?alt=json\u0026prettyPrint=false\u0026userProject=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "684" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:05 GMT" ], "Etag": [ "CAU=" ], "Expires": [ "Thu, 02 May 2019 22:25:05 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqXQonYrNQZxcXoDllGz19Ruu-Eq1_3FVjMndISB0h1O1ojodwFr2Xor2nZHBZgv3NN_YOSrunnT_KYTfBFNdqtVvqVC2L19Qhwk-cxse_FqrMVbIM" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9scyIsIml0ZW1zIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBVT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQVU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBVT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJkb21haW4tZ29vZ2xlLmNvbSIsInJvbGUiOiJSRUFERVIiLCJkb21haW4iOiJnb29nbGUuY29tIiwiZXRhZyI6IkNBVT0ifV19" } }, { "ID": "a3918deffd2f8f0f", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/defaultObjectAcl?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "12203" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:06 GMT" ], "Expires": [ "Thu, 02 May 2019 22:25:06 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UpCCE2tr_4iWFlwmQkFVvzfskSWvZdvohQYV52oXF-tWUfie6Brp5TYrvUYx7jH8zsTg9qqk_kv0th8pOA1WsHahBUbDYuaqAmW0EpSJI6_xjBPdZ8" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6InJlcXVpcmVkIiwibWVzc2FnZSI6IkJ1Y2tldCBpcyByZXF1ZXN0ZXIgcGF5cyBidWNrZXQgYnV0IG5vIHVzZXIgcHJvamVjdCBwcm92aWRlZC4iLCJkZWJ1Z0luZm8iOiJjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX01JU1NJTkc6IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5MaXN0QWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoTGlzdEFjbHMuamF2YToxMDEpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5MaXN0QWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoTGlzdEFjbHMuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IubGlzdChBY2Nlc3NDb250cm9sc0RlbGVnYXRvci5qYXZhOjg5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuXG5jb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS5GYXVsdDogSW1tdXRhYmxlRXJyb3JEZWZpbml0aW9ue2Jhc2U9UkVRVUlSRUQsIGNhdGVnb3J5PVVTRVJfRVJST1IsIGNhdXNlPW51bGwsIGRlYnVnSW5mbz1jb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX01JU1NJTkc6IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5MaXN0QWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoTGlzdEFjbHMuamF2YToxMDEpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5MaXN0QWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoTGlzdEFjbHMuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IubGlzdChBY2Nlc3NDb250cm9sc0RlbGVnYXRvci5qYXZhOjg5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuLCBkb21haW49Z2xvYmFsLCBleHRlbmRlZEhlbHA9bnVsbCwgaHR0cEhlYWRlcnM9e30sIGh0dHBTdGF0dXM9YmFkUmVxdWVzdCwgaW50ZXJuYWxSZWFzb249UmVhc29ue2FyZ3VtZW50cz17fSwgY2F1c2U9bnVsbCwgY29kZT1nZGF0YS5Db3JlRXJyb3JEb21haW4uUkVRVUlSRUQsIGNyZWF0ZWRCeUJhY2tlbmQ9dHJ1ZSwgZGVidWdNZXNzYWdlPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpVU0VSX1BST0pFQ1RfTUlTU0lORzogQnVja2V0IGlzIFJlcXVlc3RlciBQYXlzIGJ1Y2tldCBidXQgbm8gYmlsbGluZyBwcm9qZWN0IGlkIHByb3ZpZGVkIGZvciBub24tb3duZXIuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkxpc3RBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChMaXN0QWNscy5qYXZhOjEwMSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkxpc3RBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChMaXN0QWNscy5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci5saXN0KEFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmphdmE6ODkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGVycm9yUHJvdG9Db2RlPVJFUVVJUkVELCBlcnJvclByb3RvRG9tYWluPWdkYXRhLkNvcmVFcnJvckRvbWFpbiwgZmlsdGVyZWRNZXNzYWdlPW51bGwsIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9QnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLiwgdW5uYW1lZEFyZ3VtZW50cz1bXX0sIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9QnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLiwgcmVhc29uPXJlcXVpcmVkLCBycGNDb2RlPTQwMH0gQnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLjogY29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuTGlzdEFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKExpc3RBY2xzLmphdmE6MTAxKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuTGlzdEFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKExpc3RBY2xzLmphdmE6MjUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLkFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmxpc3QoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YTo4OSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogQnVja2V0IGlzIFJlcXVlc3RlciBQYXlzIGJ1Y2tldCBidXQgbm8gYmlsbGluZyBwcm9qZWN0IGlkIHByb3ZpZGVkIGZvciBub24tb3duZXIuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS5FcnJvckNvbGxlY3Rvci50b0ZhdWx0KEVycm9yQ29sbGVjdG9yLmphdmE6NTQpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5RXJyb3JDb252ZXJ0ZXIudG9GYXVsdChSb3N5RXJyb3JDb252ZXJ0ZXIuamF2YTo2Nylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lIYW5kbGVyJDIuY2FsbChSb3N5SGFuZGxlci5qYXZhOjI1OSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lIYW5kbGVyJDIuY2FsbChSb3N5SGFuZGxlci5qYXZhOjIzOSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkRpcmVjdEV4ZWN1dG9yLmV4ZWN1dGUoRGlyZWN0RXhlY3V0b3IuamF2YTozMClcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmV4ZWN1dGVMaXN0ZW5lcihBYnN0cmFjdEZ1dHVyZS5qYXZhOjExNDMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5jb21wbGV0ZShBYnN0cmFjdEZ1dHVyZS5qYXZhOjk2Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLnNldChBYnN0cmFjdEZ1dHVyZS5qYXZhOjczMSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkRpcmVjdEV4ZWN1dG9yLmV4ZWN1dGUoRGlyZWN0RXhlY3V0b3IuamF2YTozMClcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmV4ZWN1dGVMaXN0ZW5lcihBYnN0cmFjdEZ1dHVyZS5qYXZhOjExNDMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5jb21wbGV0ZShBYnN0cmFjdEZ1dHVyZS5qYXZhOjk2Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLnNldChBYnN0cmFjdEZ1dHVyZS5qYXZhOjczMSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnRocmVhZC5UaHJlYWRUcmFja2VycyRUaHJlYWRUcmFja2luZ1J1bm5hYmxlLnJ1bihUaHJlYWRUcmFja2Vycy5qYXZhOjEyNilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoVHJhY2VDb250ZXh0LmphdmE6NDUzKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuc2VydmVyLkNvbW1vbk1vZHVsZSRDb250ZXh0Q2FycnlpbmdFeGVjdXRvclNlcnZpY2UkMS5ydW5JbkNvbnRleHQoQ29tbW9uTW9kdWxlLmphdmE6ODAyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlJDEucnVuKFRyYWNlQ29udGV4dC5qYXZhOjQ2MClcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihUcmFjZUNvbnRleHQuamF2YTozMTkpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkQWJzdHJhY3RUcmFjZUNvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoVHJhY2VDb250ZXh0LmphdmE6MzExKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NTcpXG5cdGF0IGNvbS5nb29nbGUuZ3NlLmludGVybmFsLkRpc3BhdGNoUXVldWVJbXBsJFdvcmtlclRocmVhZC5ydW4oRGlzcGF0Y2hRdWV1ZUltcGwuamF2YTo0MDMpXG4ifV0sImNvZGUiOjQwMCwibWVzc2FnZSI6IkJ1Y2tldCBpcyByZXF1ZXN0ZXIgcGF5cyBidWNrZXQgYnV0IG5vIHVzZXIgcHJvamVjdCBwcm92aWRlZC4ifX0=" } }, { "ID": "42a941620757dac5", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/defaultObjectAcl?alt=json\u0026prettyPrint=false\u0026userProject=gcloud-golang-firestore-tests", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "684" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:06 GMT" ], "Etag": [ "CAU=" ], "Expires": [ "Thu, 02 May 2019 22:25:06 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uoqov2civPKG8oSKmpVgUSoOD4W3rev4av_O6jgxkc5tSpPMgtxZeG3NznVRuFJLgClao2zPH8BvZIxTAAPUi_R-H0zgPz6ou8k9SMzLrcgW_HW100" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9scyIsIml0ZW1zIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBVT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQVU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBVT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJkb21haW4tZ29vZ2xlLmNvbSIsInJvbGUiOiJSRUFERVIiLCJkb21haW4iOiJnb29nbGUuY29tIiwiZXRhZyI6IkNBVT0ifV19" } }, { "ID": "ae79f2e22d58681a", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/defaultObjectAcl?alt=json\u0026prettyPrint=false\u0026userProject=veener-jba", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 403, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "13059" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:06 GMT" ], "Expires": [ "Thu, 02 May 2019 22:25:06 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UqP_EhJin_8uqVkiSwAv0jBAI8A0o7nSwNAQ-Z_EdAnq2PItIGJZl5NOE_xcDTFce_ncHfsf6LvV4NMvuxiOsl32BOddZj_6x5dC36QqrKvhXKaQJ0" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6ImZvcmJpZGRlbiIsIm1lc3NhZ2UiOiJpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpVU0VSX1BST0pFQ1RfQUNDRVNTX0RFTklFRDogaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20gZG9lcyBub3QgaGF2ZSBzZXJ2aWNldXNhZ2Uuc2VydmljZXMudXNlIGFjY2VzcyB0byBwcm9qZWN0IDY0MjA4MDkxODEwMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuTGlzdEFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKExpc3RBY2xzLmphdmE6MTAxKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuTGlzdEFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKExpc3RBY2xzLmphdmE6MjUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLkFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmxpc3QoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YTo4OSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20gZG9lcyBub3QgaGF2ZSBzZXJ2aWNldXNhZ2Uuc2VydmljZXMudXNlIGFjY2VzcyB0byBwcm9qZWN0IDY0MjA4MDkxODEwMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuXG5jb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS5GYXVsdDogSW1tdXRhYmxlRXJyb3JEZWZpbml0aW9ue2Jhc2U9Rk9SQklEREVOLCBjYXRlZ29yeT1VU0VSX0VSUk9SLCBjYXVzZT1udWxsLCBkZWJ1Z0luZm89Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9BQ0NFU1NfREVOSUVEOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5MaXN0QWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoTGlzdEFjbHMuamF2YToxMDEpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5MaXN0QWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoTGlzdEFjbHMuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IubGlzdChBY2Nlc3NDb250cm9sc0RlbGVnYXRvci5qYXZhOjg5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGRvbWFpbj1nbG9iYWwsIGV4dGVuZGVkSGVscD1udWxsLCBodHRwSGVhZGVycz17fSwgaHR0cFN0YXR1cz1mb3JiaWRkZW4sIGludGVybmFsUmVhc29uPVJlYXNvbnthcmd1bWVudHM9e30sIGNhdXNlPW51bGwsIGNvZGU9Z2RhdGEuQ29yZUVycm9yRG9tYWluLkZPUkJJRERFTiwgY3JlYXRlZEJ5QmFja2VuZD10cnVlLCBkZWJ1Z01lc3NhZ2U9Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9BQ0NFU1NfREVOSUVEOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5MaXN0QWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoTGlzdEFjbHMuamF2YToxMDEpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5MaXN0QWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoTGlzdEFjbHMuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IubGlzdChBY2Nlc3NDb250cm9sc0RlbGVnYXRvci5qYXZhOjg5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGVycm9yUHJvdG9Db2RlPUZPUkJJRERFTiwgZXJyb3JQcm90b0RvbWFpbj1nZGF0YS5Db3JlRXJyb3JEb21haW4sIGZpbHRlcmVkTWVzc2FnZT1udWxsLCBsb2NhdGlvbj1udWxsLCBtZXNzYWdlPWludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuLCB1bm5hbWVkQXJndW1lbnRzPVtdfSwgbG9jYXRpb249bnVsbCwgbWVzc2FnZT1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiwgcmVhc29uPWZvcmJpZGRlbiwgcnBjQ29kZT00MDN9IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuOiBjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX0FDQ0VTU19ERU5JRUQ6IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkxpc3RBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChMaXN0QWNscy5qYXZhOjEwMSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkxpc3RBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChMaXN0QWNscy5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci5saXN0KEFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmphdmE6ODkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS5FcnJvckNvbGxlY3Rvci50b0ZhdWx0KEVycm9yQ29sbGVjdG9yLmphdmE6NTQpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5RXJyb3JDb252ZXJ0ZXIudG9GYXVsdChSb3N5RXJyb3JDb252ZXJ0ZXIuamF2YTo2Nylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lIYW5kbGVyJDIuY2FsbChSb3N5SGFuZGxlci5qYXZhOjI1OSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lIYW5kbGVyJDIuY2FsbChSb3N5SGFuZGxlci5qYXZhOjIzOSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkRpcmVjdEV4ZWN1dG9yLmV4ZWN1dGUoRGlyZWN0RXhlY3V0b3IuamF2YTozMClcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmV4ZWN1dGVMaXN0ZW5lcihBYnN0cmFjdEZ1dHVyZS5qYXZhOjExNDMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5jb21wbGV0ZShBYnN0cmFjdEZ1dHVyZS5qYXZhOjk2Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLnNldChBYnN0cmFjdEZ1dHVyZS5qYXZhOjczMSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkRpcmVjdEV4ZWN1dG9yLmV4ZWN1dGUoRGlyZWN0RXhlY3V0b3IuamF2YTozMClcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmV4ZWN1dGVMaXN0ZW5lcihBYnN0cmFjdEZ1dHVyZS5qYXZhOjExNDMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5jb21wbGV0ZShBYnN0cmFjdEZ1dHVyZS5qYXZhOjk2Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLnNldChBYnN0cmFjdEZ1dHVyZS5qYXZhOjczMSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnRocmVhZC5UaHJlYWRUcmFja2VycyRUaHJlYWRUcmFja2luZ1J1bm5hYmxlLnJ1bihUaHJlYWRUcmFja2Vycy5qYXZhOjEyNilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoVHJhY2VDb250ZXh0LmphdmE6NDUzKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuc2VydmVyLkNvbW1vbk1vZHVsZSRDb250ZXh0Q2FycnlpbmdFeGVjdXRvclNlcnZpY2UkMS5ydW5JbkNvbnRleHQoQ29tbW9uTW9kdWxlLmphdmE6ODAyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlJDEucnVuKFRyYWNlQ29udGV4dC5qYXZhOjQ2MClcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihUcmFjZUNvbnRleHQuamF2YTozMTkpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkQWJzdHJhY3RUcmFjZUNvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoVHJhY2VDb250ZXh0LmphdmE6MzExKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NTcpXG5cdGF0IGNvbS5nb29nbGUuZ3NlLmludGVybmFsLkRpc3BhdGNoUXVldWVJbXBsJFdvcmtlclRocmVhZC5ydW4oRGlzcGF0Y2hRdWV1ZUltcGwuamF2YTo0MDMpXG4ifV0sImNvZGUiOjQwMywibWVzc2FnZSI6ImludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuIn19" } }, { "ID": "99becaf4890b3c21", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/defaultObjectAcl/domain-google.com?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:25:08 GMT" ], "Etag": [ "CAY=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpWMu40YNkuE3QcNByTmrKw_cnq4a8DVtcknBJ7gTnLdH1BC6CqoFOStPpa6y4PMmdpLpquozlOzvI4NWjgZYp1d9F_wBEyaq-wquTQAWGXNy3qktY" ] }, "Body": "" } }, { "ID": "586ccc26d5a22712", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/defaultObjectAcl/domain-google.com?alt=json\u0026prettyPrint=false\u0026userProject=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 404, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "11631" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:08 GMT" ], "Expires": [ "Thu, 02 May 2019 22:25:08 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UpsRO9GedosQ-kg2lCQpx2S6C0-HH592CdB3SU9yGMwEEGKX9md7KGeSDhecrm_6Ug6tyYtEMlsMq08YBAKGprXfcN9130mRolu_HVey3CcrXK1nZ0" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6Im5vdEZvdW5kIiwibWVzc2FnZSI6Ik5vdCBGb3VuZCIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpBQ0xfU0NPUEVfTk9UX0ZPVU5EOiBTcGVjaWZpZWQgQUNMIHNjb3BlIHdhcyBub3QgZm91bmRcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjg2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci5kZWxldGUoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YToxMDkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IFNwZWNpZmllZCBBQ0wgc2NvcGUgd2FzIG5vdCBmb3VuZFxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cbmNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLkZhdWx0OiBJbW11dGFibGVFcnJvckRlZmluaXRpb257YmFzZT1OT1RfRk9VTkQsIGNhdGVnb3J5PVVTRVJfRVJST1IsIGNhdXNlPW51bGwsIGRlYnVnSW5mbz1jb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6QUNMX1NDT1BFX05PVF9GT1VORDogU3BlY2lmaWVkIEFDTCBzY29wZSB3YXMgbm90IGZvdW5kXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkRlbGV0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZUFjbHMuamF2YTo4Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkRlbGV0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZUFjbHMuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuZGVsZXRlKEFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmphdmE6MTA5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBTcGVjaWZpZWQgQUNMIHNjb3BlIHdhcyBub3QgZm91bmRcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuLCBkb21haW49Z2xvYmFsLCBleHRlbmRlZEhlbHA9bnVsbCwgaHR0cEhlYWRlcnM9e30sIGh0dHBTdGF0dXM9bm90Rm91bmQsIGludGVybmFsUmVhc29uPVJlYXNvbnthcmd1bWVudHM9e30sIGNhdXNlPW51bGwsIGNvZGU9Z2RhdGEuQ29yZUVycm9yRG9tYWluLk5PVF9GT1VORCwgY3JlYXRlZEJ5QmFja2VuZD10cnVlLCBkZWJ1Z01lc3NhZ2U9Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OkFDTF9TQ09QRV9OT1RfRk9VTkQ6IFNwZWNpZmllZCBBQ0wgc2NvcGUgd2FzIG5vdCBmb3VuZFxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5EZWxldGVBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChEZWxldGVBY2xzLmphdmE6ODYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5EZWxldGVBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChEZWxldGVBY2xzLmphdmE6MjUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLkFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmRlbGV0ZShBY2Nlc3NDb250cm9sc0RlbGVnYXRvci5qYXZhOjEwOSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogU3BlY2lmaWVkIEFDTCBzY29wZSB3YXMgbm90IGZvdW5kXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZXJyb3JQcm90b0NvZGU9Tk9UX0ZPVU5ELCBlcnJvclByb3RvRG9tYWluPWdkYXRhLkNvcmVFcnJvckRvbWFpbiwgZmlsdGVyZWRNZXNzYWdlPW51bGwsIGxvY2F0aW9uPWVudGl0eS5yZXNvdXJjZV9pZC5zY29wZSwgbWVzc2FnZT1udWxsLCB1bm5hbWVkQXJndW1lbnRzPVtdfSwgbG9jYXRpb249ZW50aXR5LnJlc291cmNlX2lkLnNjb3BlLCBtZXNzYWdlPU5vdCBGb3VuZCwgcmVhc29uPW5vdEZvdW5kLCBycGNDb2RlPTQwNH0gTm90IEZvdW5kOiBjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6QUNMX1NDT1BFX05PVF9GT1VORDogU3BlY2lmaWVkIEFDTCBzY29wZSB3YXMgbm90IGZvdW5kXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkRlbGV0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZUFjbHMuamF2YTo4Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkRlbGV0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZUFjbHMuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuZGVsZXRlKEFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmphdmE6MTA5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBTcGVjaWZpZWQgQUNMIHNjb3BlIHdhcyBub3QgZm91bmRcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLkVycm9yQ29sbGVjdG9yLnRvRmF1bHQoRXJyb3JDb2xsZWN0b3IuamF2YTo1NClcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lFcnJvckNvbnZlcnRlci50b0ZhdWx0KFJvc3lFcnJvckNvbnZlcnRlci5qYXZhOjY3KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUhhbmRsZXIkMi5jYWxsKFJvc3lIYW5kbGVyLmphdmE6MjU5KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUhhbmRsZXIkMi5jYWxsKFJvc3lIYW5kbGVyLmphdmE6MjM5KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRGlyZWN0RXhlY3V0b3IuZXhlY3V0ZShEaXJlY3RFeGVjdXRvci5qYXZhOjMwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuZXhlY3V0ZUxpc3RlbmVyKEFic3RyYWN0RnV0dXJlLmphdmE6MTE0Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmNvbXBsZXRlKEFic3RyYWN0RnV0dXJlLmphdmE6OTYzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuc2V0KEFic3RyYWN0RnV0dXJlLmphdmE6NzMxKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRGlyZWN0RXhlY3V0b3IuZXhlY3V0ZShEaXJlY3RFeGVjdXRvci5qYXZhOjMwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuZXhlY3V0ZUxpc3RlbmVyKEFic3RyYWN0RnV0dXJlLmphdmE6MTE0Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmNvbXBsZXRlKEFic3RyYWN0RnV0dXJlLmphdmE6OTYzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuc2V0KEFic3RyYWN0RnV0dXJlLmphdmE6NzMxKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIudGhyZWFkLlRocmVhZFRyYWNrZXJzJFRocmVhZFRyYWNraW5nUnVubmFibGUucnVuKFRocmVhZFRyYWNrZXJzLmphdmE6MTI2KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChUcmFjZUNvbnRleHQuamF2YTo0NTMpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5zZXJ2ZXIuQ29tbW9uTW9kdWxlJENvbnRleHRDYXJyeWluZ0V4ZWN1dG9yU2VydmljZSQxLnJ1bkluQ29udGV4dChDb21tb25Nb2R1bGUuamF2YTo4MDIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUkMS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDYwKVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkQWJzdHJhY3RUcmFjZUNvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKFRyYWNlQ29udGV4dC5qYXZhOjMxOSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChUcmFjZUNvbnRleHQuamF2YTozMTEpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuKFRyYWNlQ29udGV4dC5qYXZhOjQ1Nylcblx0YXQgY29tLmdvb2dsZS5nc2UuaW50ZXJuYWwuRGlzcGF0Y2hRdWV1ZUltcGwkV29ya2VyVGhyZWFkLnJ1bihEaXNwYXRjaFF1ZXVlSW1wbC5qYXZhOjQwMylcbiJ9XSwiY29kZSI6NDA0LCJtZXNzYWdlIjoiTm90IEZvdW5kIn19" } }, { "ID": "fad4bdab588e0f3a", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/defaultObjectAcl/domain-google.com?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "12243" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:08 GMT" ], "Expires": [ "Thu, 02 May 2019 22:25:08 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UoUefKoF0asUvxzmAtX5z5m_5FRy9UfliKkjQN8cYyrHAotGwiQA72QN0lYfA0HXbe7gFRokwBAY8R5OpHcEdRq5K9sw8AwHuNtruFtBMxjN0D3hR4" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6InJlcXVpcmVkIiwibWVzc2FnZSI6IkJ1Y2tldCBpcyByZXF1ZXN0ZXIgcGF5cyBidWNrZXQgYnV0IG5vIHVzZXIgcHJvamVjdCBwcm92aWRlZC4iLCJkZWJ1Z0luZm8iOiJjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX01JU1NJTkc6IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5EZWxldGVBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChEZWxldGVBY2xzLmphdmE6ODYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5EZWxldGVBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChEZWxldGVBY2xzLmphdmE6MjUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLkFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmRlbGV0ZShBY2Nlc3NDb250cm9sc0RlbGVnYXRvci5qYXZhOjEwOSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogQnVja2V0IGlzIFJlcXVlc3RlciBQYXlzIGJ1Y2tldCBidXQgbm8gYmlsbGluZyBwcm9qZWN0IGlkIHByb3ZpZGVkIGZvciBub24tb3duZXIuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPVJFUVVJUkVELCBjYXRlZ29yeT1VU0VSX0VSUk9SLCBjYXVzZT1udWxsLCBkZWJ1Z0luZm89Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjg2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci5kZWxldGUoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YToxMDkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGRvbWFpbj1nbG9iYWwsIGV4dGVuZGVkSGVscD1udWxsLCBodHRwSGVhZGVycz17fSwgaHR0cFN0YXR1cz1iYWRSZXF1ZXN0LCBpbnRlcm5hbFJlYXNvbj1SZWFzb257YXJndW1lbnRzPXt9LCBjYXVzZT1udWxsLCBjb2RlPWdkYXRhLkNvcmVFcnJvckRvbWFpbi5SRVFVSVJFRCwgY3JlYXRlZEJ5QmFja2VuZD10cnVlLCBkZWJ1Z01lc3NhZ2U9Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjg2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci5kZWxldGUoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YToxMDkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGVycm9yUHJvdG9Db2RlPVJFUVVJUkVELCBlcnJvclByb3RvRG9tYWluPWdkYXRhLkNvcmVFcnJvckRvbWFpbiwgZmlsdGVyZWRNZXNzYWdlPW51bGwsIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9QnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLiwgdW5uYW1lZEFyZ3VtZW50cz1bXX0sIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9QnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLiwgcmVhc29uPXJlcXVpcmVkLCBycGNDb2RlPTQwMH0gQnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLjogY29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjg2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci5kZWxldGUoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YToxMDkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRXJyb3JDb2xsZWN0b3IudG9GYXVsdChFcnJvckNvbGxlY3Rvci5qYXZhOjU0KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUVycm9yQ29udmVydGVyLnRvRmF1bHQoUm9zeUVycm9yQ29udmVydGVyLmphdmE6NjcpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyNTkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyMzkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci50aHJlYWQuVGhyZWFkVHJhY2tlcnMkVGhyZWFkVHJhY2tpbmdSdW5uYWJsZS5ydW4oVGhyZWFkVHJhY2tlcnMuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjQ1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnNlcnZlci5Db21tb25Nb2R1bGUkQ29udGV4dENhcnJ5aW5nRXhlY3V0b3JTZXJ2aWNlJDEucnVuSW5Db250ZXh0KENvbW1vbk1vZHVsZS5qYXZhOjgwMilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZSQxLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NjApXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoVHJhY2VDb250ZXh0LmphdmE6MzE5KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjMxMSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDU3KVxuXHRhdCBjb20uZ29vZ2xlLmdzZS5pbnRlcm5hbC5EaXNwYXRjaFF1ZXVlSW1wbCRXb3JrZXJUaHJlYWQucnVuKERpc3BhdGNoUXVldWVJbXBsLmphdmE6NDAzKVxuIn1dLCJjb2RlIjo0MDAsIm1lc3NhZ2UiOiJCdWNrZXQgaXMgcmVxdWVzdGVyIHBheXMgYnVja2V0IGJ1dCBubyB1c2VyIHByb2plY3QgcHJvdmlkZWQuIn19" } }, { "ID": "23bb9ce53da2f525", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/defaultObjectAcl/domain-google.com?alt=json\u0026prettyPrint=false\u0026userProject=gcloud-golang-firestore-tests", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 404, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "11631" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:09 GMT" ], "Expires": [ "Thu, 02 May 2019 22:25:09 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2Upa2KE5JJOXq2FOn7RHasJpOeeHqWU2kk3BC4cQcGQ9jGzh6XIksN6Z6u1NVoCbxW7-3zGiZMdAop-oa_EuyPAauD__JgzNPdngeNeXO7lsGaVI6i8" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6Im5vdEZvdW5kIiwibWVzc2FnZSI6Ik5vdCBGb3VuZCIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpBQ0xfU0NPUEVfTk9UX0ZPVU5EOiBTcGVjaWZpZWQgQUNMIHNjb3BlIHdhcyBub3QgZm91bmRcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjg2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci5kZWxldGUoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YToxMDkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IFNwZWNpZmllZCBBQ0wgc2NvcGUgd2FzIG5vdCBmb3VuZFxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cbmNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLkZhdWx0OiBJbW11dGFibGVFcnJvckRlZmluaXRpb257YmFzZT1OT1RfRk9VTkQsIGNhdGVnb3J5PVVTRVJfRVJST1IsIGNhdXNlPW51bGwsIGRlYnVnSW5mbz1jb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6QUNMX1NDT1BFX05PVF9GT1VORDogU3BlY2lmaWVkIEFDTCBzY29wZSB3YXMgbm90IGZvdW5kXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkRlbGV0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZUFjbHMuamF2YTo4Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkRlbGV0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZUFjbHMuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuZGVsZXRlKEFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmphdmE6MTA5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBTcGVjaWZpZWQgQUNMIHNjb3BlIHdhcyBub3QgZm91bmRcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuLCBkb21haW49Z2xvYmFsLCBleHRlbmRlZEhlbHA9bnVsbCwgaHR0cEhlYWRlcnM9e30sIGh0dHBTdGF0dXM9bm90Rm91bmQsIGludGVybmFsUmVhc29uPVJlYXNvbnthcmd1bWVudHM9e30sIGNhdXNlPW51bGwsIGNvZGU9Z2RhdGEuQ29yZUVycm9yRG9tYWluLk5PVF9GT1VORCwgY3JlYXRlZEJ5QmFja2VuZD10cnVlLCBkZWJ1Z01lc3NhZ2U9Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OkFDTF9TQ09QRV9OT1RfRk9VTkQ6IFNwZWNpZmllZCBBQ0wgc2NvcGUgd2FzIG5vdCBmb3VuZFxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5EZWxldGVBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChEZWxldGVBY2xzLmphdmE6ODYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5EZWxldGVBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChEZWxldGVBY2xzLmphdmE6MjUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLkFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmRlbGV0ZShBY2Nlc3NDb250cm9sc0RlbGVnYXRvci5qYXZhOjEwOSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogU3BlY2lmaWVkIEFDTCBzY29wZSB3YXMgbm90IGZvdW5kXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZXJyb3JQcm90b0NvZGU9Tk9UX0ZPVU5ELCBlcnJvclByb3RvRG9tYWluPWdkYXRhLkNvcmVFcnJvckRvbWFpbiwgZmlsdGVyZWRNZXNzYWdlPW51bGwsIGxvY2F0aW9uPWVudGl0eS5yZXNvdXJjZV9pZC5zY29wZSwgbWVzc2FnZT1udWxsLCB1bm5hbWVkQXJndW1lbnRzPVtdfSwgbG9jYXRpb249ZW50aXR5LnJlc291cmNlX2lkLnNjb3BlLCBtZXNzYWdlPU5vdCBGb3VuZCwgcmVhc29uPW5vdEZvdW5kLCBycGNDb2RlPTQwNH0gTm90IEZvdW5kOiBjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6QUNMX1NDT1BFX05PVF9GT1VORDogU3BlY2lmaWVkIEFDTCBzY29wZSB3YXMgbm90IGZvdW5kXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkRlbGV0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZUFjbHMuamF2YTo4Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkRlbGV0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZUFjbHMuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuZGVsZXRlKEFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmphdmE6MTA5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBTcGVjaWZpZWQgQUNMIHNjb3BlIHdhcyBub3QgZm91bmRcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLkVycm9yQ29sbGVjdG9yLnRvRmF1bHQoRXJyb3JDb2xsZWN0b3IuamF2YTo1NClcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lFcnJvckNvbnZlcnRlci50b0ZhdWx0KFJvc3lFcnJvckNvbnZlcnRlci5qYXZhOjY3KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUhhbmRsZXIkMi5jYWxsKFJvc3lIYW5kbGVyLmphdmE6MjU5KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUhhbmRsZXIkMi5jYWxsKFJvc3lIYW5kbGVyLmphdmE6MjM5KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRGlyZWN0RXhlY3V0b3IuZXhlY3V0ZShEaXJlY3RFeGVjdXRvci5qYXZhOjMwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuZXhlY3V0ZUxpc3RlbmVyKEFic3RyYWN0RnV0dXJlLmphdmE6MTE0Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmNvbXBsZXRlKEFic3RyYWN0RnV0dXJlLmphdmE6OTYzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuc2V0KEFic3RyYWN0RnV0dXJlLmphdmE6NzMxKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRGlyZWN0RXhlY3V0b3IuZXhlY3V0ZShEaXJlY3RFeGVjdXRvci5qYXZhOjMwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuZXhlY3V0ZUxpc3RlbmVyKEFic3RyYWN0RnV0dXJlLmphdmE6MTE0Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmNvbXBsZXRlKEFic3RyYWN0RnV0dXJlLmphdmE6OTYzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuc2V0KEFic3RyYWN0RnV0dXJlLmphdmE6NzMxKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIudGhyZWFkLlRocmVhZFRyYWNrZXJzJFRocmVhZFRyYWNraW5nUnVubmFibGUucnVuKFRocmVhZFRyYWNrZXJzLmphdmE6MTI2KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChUcmFjZUNvbnRleHQuamF2YTo0NTMpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5zZXJ2ZXIuQ29tbW9uTW9kdWxlJENvbnRleHRDYXJyeWluZ0V4ZWN1dG9yU2VydmljZSQxLnJ1bkluQ29udGV4dChDb21tb25Nb2R1bGUuamF2YTo4MDIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUkMS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDYwKVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkQWJzdHJhY3RUcmFjZUNvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKFRyYWNlQ29udGV4dC5qYXZhOjMxOSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChUcmFjZUNvbnRleHQuamF2YTozMTEpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuKFRyYWNlQ29udGV4dC5qYXZhOjQ1Nylcblx0YXQgY29tLmdvb2dsZS5nc2UuaW50ZXJuYWwuRGlzcGF0Y2hRdWV1ZUltcGwkV29ya2VyVGhyZWFkLnJ1bihEaXNwYXRjaFF1ZXVlSW1wbC5qYXZhOjQwMylcbiJ9XSwiY29kZSI6NDA0LCJtZXNzYWdlIjoiTm90IEZvdW5kIn19" } }, { "ID": "46482e47e655836d", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/defaultObjectAcl/domain-google.com?alt=json\u0026prettyPrint=false\u0026userProject=veener-jba", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 403, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "13099" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:09 GMT" ], "Expires": [ "Thu, 02 May 2019 22:25:09 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2Urze42blCAS2Dskbf5jkbCkdo5IhfOjcTlcufV1ooZd5x_QD0zK1gRoXLXfvLjKHEKaJ7cuDeSRmNjuqgEoxJFMmXUoPOIetWLYbH0G-lJcM6tydew" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6ImZvcmJpZGRlbiIsIm1lc3NhZ2UiOiJpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpVU0VSX1BST0pFQ1RfQUNDRVNTX0RFTklFRDogaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20gZG9lcyBub3QgaGF2ZSBzZXJ2aWNldXNhZ2Uuc2VydmljZXMudXNlIGFjY2VzcyB0byBwcm9qZWN0IDY0MjA4MDkxODEwMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjg2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci5kZWxldGUoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YToxMDkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPUZPUkJJRERFTiwgY2F0ZWdvcnk9VVNFUl9FUlJPUiwgY2F1c2U9bnVsbCwgZGVidWdJbmZvPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpVU0VSX1BST0pFQ1RfQUNDRVNTX0RFTklFRDogaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20gZG9lcyBub3QgaGF2ZSBzZXJ2aWNldXNhZ2Uuc2VydmljZXMudXNlIGFjY2VzcyB0byBwcm9qZWN0IDY0MjA4MDkxODEwMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjg2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci5kZWxldGUoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YToxMDkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZG9tYWluPWdsb2JhbCwgZXh0ZW5kZWRIZWxwPW51bGwsIGh0dHBIZWFkZXJzPXt9LCBodHRwU3RhdHVzPWZvcmJpZGRlbiwgaW50ZXJuYWxSZWFzb249UmVhc29ue2FyZ3VtZW50cz17fSwgY2F1c2U9bnVsbCwgY29kZT1nZGF0YS5Db3JlRXJyb3JEb21haW4uRk9SQklEREVOLCBjcmVhdGVkQnlCYWNrZW5kPXRydWUsIGRlYnVnTWVzc2FnZT1jb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX0FDQ0VTU19ERU5JRUQ6IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkRlbGV0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZUFjbHMuamF2YTo4Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkRlbGV0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZUFjbHMuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuZGVsZXRlKEFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmphdmE6MTA5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGVycm9yUHJvdG9Db2RlPUZPUkJJRERFTiwgZXJyb3JQcm90b0RvbWFpbj1nZGF0YS5Db3JlRXJyb3JEb21haW4sIGZpbHRlcmVkTWVzc2FnZT1udWxsLCBsb2NhdGlvbj1udWxsLCBtZXNzYWdlPWludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuLCB1bm5hbWVkQXJndW1lbnRzPVtdfSwgbG9jYXRpb249bnVsbCwgbWVzc2FnZT1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiwgcmVhc29uPWZvcmJpZGRlbiwgcnBjQ29kZT00MDN9IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuOiBjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX0FDQ0VTU19ERU5JRUQ6IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkRlbGV0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZUFjbHMuamF2YTo4Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkRlbGV0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZUFjbHMuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuZGVsZXRlKEFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmphdmE6MTA5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRXJyb3JDb2xsZWN0b3IudG9GYXVsdChFcnJvckNvbGxlY3Rvci5qYXZhOjU0KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUVycm9yQ29udmVydGVyLnRvRmF1bHQoUm9zeUVycm9yQ29udmVydGVyLmphdmE6NjcpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyNTkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyMzkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci50aHJlYWQuVGhyZWFkVHJhY2tlcnMkVGhyZWFkVHJhY2tpbmdSdW5uYWJsZS5ydW4oVGhyZWFkVHJhY2tlcnMuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjQ1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnNlcnZlci5Db21tb25Nb2R1bGUkQ29udGV4dENhcnJ5aW5nRXhlY3V0b3JTZXJ2aWNlJDEucnVuSW5Db250ZXh0KENvbW1vbk1vZHVsZS5qYXZhOjgwMilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZSQxLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NjApXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoVHJhY2VDb250ZXh0LmphdmE6MzE5KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjMxMSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDU3KVxuXHRhdCBjb20uZ29vZ2xlLmdzZS5pbnRlcm5hbC5EaXNwYXRjaFF1ZXVlSW1wbCRXb3JrZXJUaHJlYWQucnVuKERpc3BhdGNoUXVldWVJbXBsLmphdmE6NDAzKVxuIn1dLCJjb2RlIjo0MDMsIm1lc3NhZ2UiOiJpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiJ9fQ==" } }, { "ID": "856a1fb5ffdb000f", "Request": { "Method": "PUT", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/foo/acl/domain-google.com?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "107" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJlbnRpdHkiOiJkb21haW4tZ29vZ2xlLmNvbSIsInJvbGUiOiJSRUFERVIifQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "463" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:09 GMT" ], "Etag": [ "COGeqNLx/eECEAU=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoFSnYuPlv_JejZ0nEjoWRXeLwj0MS-ddTlIaSOjaK5BudyIcIOeVDEeyFYWsF-GCZzMC0F7v-UEw0_lbsYBXCMZcLp6WZu_s3OPDREhpz2s3Txw-s" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvZm9vLzE1NTY4MzU4OTE1NDgwMDEvZG9tYWluLWdvb2dsZS5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvby9mb28vYWNsL2RvbWFpbi1nb29nbGUuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwib2JqZWN0IjoiZm9vIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4OTE1NDgwMDEiLCJlbnRpdHkiOiJkb21haW4tZ29vZ2xlLmNvbSIsInJvbGUiOiJSRUFERVIiLCJkb21haW4iOiJnb29nbGUuY29tIiwiZXRhZyI6IkNPR2VxTkx4L2VFQ0VBVT0ifQ==" } }, { "ID": "a74c3e1b541a9ffc", "Request": { "Method": "PUT", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/foo/acl/domain-google.com?alt=json\u0026prettyPrint=false\u0026userProject=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "107" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJlbnRpdHkiOiJkb21haW4tZ29vZ2xlLmNvbSIsInJvbGUiOiJSRUFERVIifQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "463" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:10 GMT" ], "Etag": [ "COGeqNLx/eECEAU=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Ury3MiMZho3xaSHmFgwHNvKIHTa0_gZzfKvX8FW6iVGNkdSbXvmVypIUuIoKXDjd4rOXpFghdoJlES9A_iXUvZyfWAZLvWqR1w6sDRymrIARVd0dPE" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvZm9vLzE1NTY4MzU4OTE1NDgwMDEvZG9tYWluLWdvb2dsZS5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvby9mb28vYWNsL2RvbWFpbi1nb29nbGUuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwib2JqZWN0IjoiZm9vIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4OTE1NDgwMDEiLCJlbnRpdHkiOiJkb21haW4tZ29vZ2xlLmNvbSIsInJvbGUiOiJSRUFERVIiLCJkb21haW4iOiJnb29nbGUuY29tIiwiZXRhZyI6IkNPR2VxTkx4L2VFQ0VBVT0ifQ==" } }, { "ID": "913da4fa24ea5f1f", "Request": { "Method": "PUT", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/foo/acl/domain-google.com?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "107" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJlbnRpdHkiOiJkb21haW4tZ29vZ2xlLmNvbSIsInJvbGUiOiJSRUFERVIifQo=" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Content-Length": [ "12243" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:10 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UoKAxObyNBS_Mew44t3k1u80cLBGQW_I2ohrF96rIjZRxFscjGFrvsOHfLxw78rTRnpHmfA0uXnNz8T2FPc_Op16Lnn1YkfyOezSEhDBx11qZbinEE" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6InJlcXVpcmVkIiwibWVzc2FnZSI6IkJ1Y2tldCBpcyByZXF1ZXN0ZXIgcGF5cyBidWNrZXQgYnV0IG5vIHVzZXIgcHJvamVjdCBwcm92aWRlZC4iLCJkZWJ1Z0luZm8iOiJjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX01JU1NJTkc6IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5VcGRhdGVBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChVcGRhdGVBY2xzLmphdmE6OTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5VcGRhdGVBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChVcGRhdGVBY2xzLmphdmE6MjcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLkFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLnVwZGF0ZShBY2Nlc3NDb250cm9sc0RlbGVnYXRvci5qYXZhOjEwMylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogQnVja2V0IGlzIFJlcXVlc3RlciBQYXlzIGJ1Y2tldCBidXQgbm8gYmlsbGluZyBwcm9qZWN0IGlkIHByb3ZpZGVkIGZvciBub24tb3duZXIuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPVJFUVVJUkVELCBjYXRlZ29yeT1VU0VSX0VSUk9SLCBjYXVzZT1udWxsLCBkZWJ1Z0luZm89Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuVXBkYXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoVXBkYXRlQWNscy5qYXZhOjkwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuVXBkYXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoVXBkYXRlQWNscy5qYXZhOjI3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci51cGRhdGUoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YToxMDMpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGRvbWFpbj1nbG9iYWwsIGV4dGVuZGVkSGVscD1udWxsLCBodHRwSGVhZGVycz17fSwgaHR0cFN0YXR1cz1iYWRSZXF1ZXN0LCBpbnRlcm5hbFJlYXNvbj1SZWFzb257YXJndW1lbnRzPXt9LCBjYXVzZT1udWxsLCBjb2RlPWdkYXRhLkNvcmVFcnJvckRvbWFpbi5SRVFVSVJFRCwgY3JlYXRlZEJ5QmFja2VuZD10cnVlLCBkZWJ1Z01lc3NhZ2U9Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuVXBkYXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoVXBkYXRlQWNscy5qYXZhOjkwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuVXBkYXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoVXBkYXRlQWNscy5qYXZhOjI3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci51cGRhdGUoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YToxMDMpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGVycm9yUHJvdG9Db2RlPVJFUVVJUkVELCBlcnJvclByb3RvRG9tYWluPWdkYXRhLkNvcmVFcnJvckRvbWFpbiwgZmlsdGVyZWRNZXNzYWdlPW51bGwsIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9QnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLiwgdW5uYW1lZEFyZ3VtZW50cz1bXX0sIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9QnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLiwgcmVhc29uPXJlcXVpcmVkLCBycGNDb2RlPTQwMH0gQnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLjogY29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuVXBkYXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoVXBkYXRlQWNscy5qYXZhOjkwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuVXBkYXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoVXBkYXRlQWNscy5qYXZhOjI3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci51cGRhdGUoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YToxMDMpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRXJyb3JDb2xsZWN0b3IudG9GYXVsdChFcnJvckNvbGxlY3Rvci5qYXZhOjU0KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUVycm9yQ29udmVydGVyLnRvRmF1bHQoUm9zeUVycm9yQ29udmVydGVyLmphdmE6NjcpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyNTkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyMzkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci50aHJlYWQuVGhyZWFkVHJhY2tlcnMkVGhyZWFkVHJhY2tpbmdSdW5uYWJsZS5ydW4oVGhyZWFkVHJhY2tlcnMuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjQ1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnNlcnZlci5Db21tb25Nb2R1bGUkQ29udGV4dENhcnJ5aW5nRXhlY3V0b3JTZXJ2aWNlJDEucnVuSW5Db250ZXh0KENvbW1vbk1vZHVsZS5qYXZhOjgwMilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZSQxLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NjApXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoVHJhY2VDb250ZXh0LmphdmE6MzE5KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjMxMSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDU3KVxuXHRhdCBjb20uZ29vZ2xlLmdzZS5pbnRlcm5hbC5EaXNwYXRjaFF1ZXVlSW1wbCRXb3JrZXJUaHJlYWQucnVuKERpc3BhdGNoUXVldWVJbXBsLmphdmE6NDAzKVxuIn1dLCJjb2RlIjo0MDAsIm1lc3NhZ2UiOiJCdWNrZXQgaXMgcmVxdWVzdGVyIHBheXMgYnVja2V0IGJ1dCBubyB1c2VyIHByb2plY3QgcHJvdmlkZWQuIn19" } }, { "ID": "5dbdf24cae75e565", "Request": { "Method": "PUT", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/foo/acl/domain-google.com?alt=json\u0026prettyPrint=false\u0026userProject=gcloud-golang-firestore-tests", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "107" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJlbnRpdHkiOiJkb21haW4tZ29vZ2xlLmNvbSIsInJvbGUiOiJSRUFERVIifQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "463" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:10 GMT" ], "Etag": [ "COGeqNLx/eECEAU=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpoJgRZ665WjiUif7SnQ-Vg4B0kJl-UQ_kIk5XgmcQIL5zmCBp3NCxjksybkvNKpGcQnIJSLevfyWd2fugRv5y5vxmEBgqFffIy8ibTIyBDH4b7R74" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvZm9vLzE1NTY4MzU4OTE1NDgwMDEvZG9tYWluLWdvb2dsZS5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvby9mb28vYWNsL2RvbWFpbi1nb29nbGUuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwib2JqZWN0IjoiZm9vIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4OTE1NDgwMDEiLCJlbnRpdHkiOiJkb21haW4tZ29vZ2xlLmNvbSIsInJvbGUiOiJSRUFERVIiLCJkb21haW4iOiJnb29nbGUuY29tIiwiZXRhZyI6IkNPR2VxTkx4L2VFQ0VBVT0ifQ==" } }, { "ID": "f41892a142fe6d2b", "Request": { "Method": "PUT", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/foo/acl/domain-google.com?alt=json\u0026prettyPrint=false\u0026userProject=veener-jba", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "107" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJlbnRpdHkiOiJkb21haW4tZ29vZ2xlLmNvbSIsInJvbGUiOiJSRUFERVIifQo=" ] }, "Response": { "StatusCode": 403, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Content-Length": [ "13099" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:11 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UpThInLTHhtepE7J4k-Rg6OoLRyOqnjPz4sZmfIH6wp5TSIyLrZQhExKAP52XbwUwMYp7x-xypSMY5kfR66I-dmpRWaFkfs0Lhy-Z6kqb5JUXSppqk" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6ImZvcmJpZGRlbiIsIm1lc3NhZ2UiOiJpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpVU0VSX1BST0pFQ1RfQUNDRVNTX0RFTklFRDogaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20gZG9lcyBub3QgaGF2ZSBzZXJ2aWNldXNhZ2Uuc2VydmljZXMudXNlIGFjY2VzcyB0byBwcm9qZWN0IDY0MjA4MDkxODEwMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuVXBkYXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoVXBkYXRlQWNscy5qYXZhOjkwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuVXBkYXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoVXBkYXRlQWNscy5qYXZhOjI3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci51cGRhdGUoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YToxMDMpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPUZPUkJJRERFTiwgY2F0ZWdvcnk9VVNFUl9FUlJPUiwgY2F1c2U9bnVsbCwgZGVidWdJbmZvPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpVU0VSX1BST0pFQ1RfQUNDRVNTX0RFTklFRDogaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20gZG9lcyBub3QgaGF2ZSBzZXJ2aWNldXNhZ2Uuc2VydmljZXMudXNlIGFjY2VzcyB0byBwcm9qZWN0IDY0MjA4MDkxODEwMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuVXBkYXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoVXBkYXRlQWNscy5qYXZhOjkwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuVXBkYXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoVXBkYXRlQWNscy5qYXZhOjI3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci51cGRhdGUoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YToxMDMpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZG9tYWluPWdsb2JhbCwgZXh0ZW5kZWRIZWxwPW51bGwsIGh0dHBIZWFkZXJzPXt9LCBodHRwU3RhdHVzPWZvcmJpZGRlbiwgaW50ZXJuYWxSZWFzb249UmVhc29ue2FyZ3VtZW50cz17fSwgY2F1c2U9bnVsbCwgY29kZT1nZGF0YS5Db3JlRXJyb3JEb21haW4uRk9SQklEREVOLCBjcmVhdGVkQnlCYWNrZW5kPXRydWUsIGRlYnVnTWVzc2FnZT1jb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX0FDQ0VTU19ERU5JRUQ6IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLlVwZGF0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFVwZGF0ZUFjbHMuamF2YTo5MClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLlVwZGF0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFVwZGF0ZUFjbHMuamF2YToyNylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IudXBkYXRlKEFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmphdmE6MTAzKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGVycm9yUHJvdG9Db2RlPUZPUkJJRERFTiwgZXJyb3JQcm90b0RvbWFpbj1nZGF0YS5Db3JlRXJyb3JEb21haW4sIGZpbHRlcmVkTWVzc2FnZT1udWxsLCBsb2NhdGlvbj1udWxsLCBtZXNzYWdlPWludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuLCB1bm5hbWVkQXJndW1lbnRzPVtdfSwgbG9jYXRpb249bnVsbCwgbWVzc2FnZT1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiwgcmVhc29uPWZvcmJpZGRlbiwgcnBjQ29kZT00MDN9IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuOiBjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX0FDQ0VTU19ERU5JRUQ6IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLlVwZGF0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFVwZGF0ZUFjbHMuamF2YTo5MClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLlVwZGF0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFVwZGF0ZUFjbHMuamF2YToyNylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IudXBkYXRlKEFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmphdmE6MTAzKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRXJyb3JDb2xsZWN0b3IudG9GYXVsdChFcnJvckNvbGxlY3Rvci5qYXZhOjU0KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUVycm9yQ29udmVydGVyLnRvRmF1bHQoUm9zeUVycm9yQ29udmVydGVyLmphdmE6NjcpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyNTkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyMzkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci50aHJlYWQuVGhyZWFkVHJhY2tlcnMkVGhyZWFkVHJhY2tpbmdSdW5uYWJsZS5ydW4oVGhyZWFkVHJhY2tlcnMuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjQ1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnNlcnZlci5Db21tb25Nb2R1bGUkQ29udGV4dENhcnJ5aW5nRXhlY3V0b3JTZXJ2aWNlJDEucnVuSW5Db250ZXh0KENvbW1vbk1vZHVsZS5qYXZhOjgwMilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZSQxLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NjApXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoVHJhY2VDb250ZXh0LmphdmE6MzE5KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjMxMSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDU3KVxuXHRhdCBjb20uZ29vZ2xlLmdzZS5pbnRlcm5hbC5EaXNwYXRjaFF1ZXVlSW1wbCRXb3JrZXJUaHJlYWQucnVuKERpc3BhdGNoUXVldWVJbXBsLmphdmE6NDAzKVxuIn1dLCJjb2RlIjo0MDMsIm1lc3NhZ2UiOiJpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiJ9fQ==" } }, { "ID": "5eb0710be2571dab", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/foo/acl?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "2800" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:11 GMT" ], "Etag": [ "COGeqNLx/eECEAU=" ], "Expires": [ "Thu, 02 May 2019 22:25:11 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpbetUCGwYg4rhIR-DP3ntPqbkFwSqutNltVR55I4qedP-rZ5hC7ospMy6hZ4aQaNOhNv0frmst8MQZ0j6Mp8BcTC6qy7mU8bhEAiMGLycR5XxUWfI" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9scyIsIml0ZW1zIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvZm9vLzE1NTY4MzU4OTE1NDgwMDEvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJvYmplY3QiOiJmb28iLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg5MTU0ODAwMSIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDT0dlcU5MeC9lRUNFQVU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvZm9vLzE1NTY4MzU4OTE1NDgwMDEvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2Zvby9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsIm9iamVjdCI6ImZvbyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODkxNTQ4MDAxIiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ09HZXFOTHgvZUVDRUFVPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL2Zvby8xNTU2ODM1ODkxNTQ4MDAxL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvby9mb28vYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJvYmplY3QiOiJmb28iLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg5MTU0ODAwMSIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDT0dlcU5MeC9lRUNFQVU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvZm9vLzE1NTY4MzU4OTE1NDgwMDEvdXNlci1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2Zvby9hY2wvdXNlci1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsIm9iamVjdCI6ImZvbyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODkxNTQ4MDAxIiwiZW50aXR5IjoidXNlci1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ09HZXFOTHgvZUVDRUFVPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL2Zvby8xNTU2ODM1ODkxNTQ4MDAxL2RvbWFpbi1nb29nbGUuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vL2FjbC9kb21haW4tZ29vZ2xlLmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsIm9iamVjdCI6ImZvbyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODkxNTQ4MDAxIiwiZW50aXR5IjoiZG9tYWluLWdvb2dsZS5jb20iLCJyb2xlIjoiUkVBREVSIiwiZG9tYWluIjoiZ29vZ2xlLmNvbSIsImV0YWciOiJDT0dlcU5MeC9lRUNFQVU9In1dfQ==" } }, { "ID": "56aaafb0a24b0644", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/foo/acl?alt=json\u0026prettyPrint=false\u0026userProject=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "2800" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:11 GMT" ], "Etag": [ "COGeqNLx/eECEAU=" ], "Expires": [ "Thu, 02 May 2019 22:25:11 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrqQczDm-dzjgTlLFcJ2lXQrMTpQ_8UP-1hNbGj7eZEgZcbxWA-oyXqEe4tJXq3gYdZ3mEIcAzaDtNeBHWidpIev7kdXWank04_JSWbQtU2UomJqeU" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9scyIsIml0ZW1zIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvZm9vLzE1NTY4MzU4OTE1NDgwMDEvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJvYmplY3QiOiJmb28iLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg5MTU0ODAwMSIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDT0dlcU5MeC9lRUNFQVU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvZm9vLzE1NTY4MzU4OTE1NDgwMDEvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2Zvby9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsIm9iamVjdCI6ImZvbyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODkxNTQ4MDAxIiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ09HZXFOTHgvZUVDRUFVPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL2Zvby8xNTU2ODM1ODkxNTQ4MDAxL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvby9mb28vYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJvYmplY3QiOiJmb28iLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg5MTU0ODAwMSIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDT0dlcU5MeC9lRUNFQVU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvZm9vLzE1NTY4MzU4OTE1NDgwMDEvdXNlci1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2Zvby9hY2wvdXNlci1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsIm9iamVjdCI6ImZvbyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODkxNTQ4MDAxIiwiZW50aXR5IjoidXNlci1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ09HZXFOTHgvZUVDRUFVPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL2Zvby8xNTU2ODM1ODkxNTQ4MDAxL2RvbWFpbi1nb29nbGUuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vL2FjbC9kb21haW4tZ29vZ2xlLmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsIm9iamVjdCI6ImZvbyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODkxNTQ4MDAxIiwiZW50aXR5IjoiZG9tYWluLWdvb2dsZS5jb20iLCJyb2xlIjoiUkVBREVSIiwiZG9tYWluIjoiZ29vZ2xlLmNvbSIsImV0YWciOiJDT0dlcU5MeC9lRUNFQVU9In1dfQ==" } }, { "ID": "3bbc40d778939612", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/foo/acl?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "12203" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:12 GMT" ], "Expires": [ "Thu, 02 May 2019 22:25:12 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2Ur5kJWpLwxz76BKPll75-nOsLv_uoh7X-TW0SbNHCYEzkGq8VZ-W8a5tKGUF6rKea4ejr4MhcqJVr1Zu7O-zNAfQWJMsHC9CTkOrPa5Iu1s0KBJDdY" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6InJlcXVpcmVkIiwibWVzc2FnZSI6IkJ1Y2tldCBpcyByZXF1ZXN0ZXIgcGF5cyBidWNrZXQgYnV0IG5vIHVzZXIgcHJvamVjdCBwcm92aWRlZC4iLCJkZWJ1Z0luZm8iOiJjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX01JU1NJTkc6IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5MaXN0QWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoTGlzdEFjbHMuamF2YToxMDEpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5MaXN0QWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoTGlzdEFjbHMuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IubGlzdChBY2Nlc3NDb250cm9sc0RlbGVnYXRvci5qYXZhOjg5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuXG5jb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS5GYXVsdDogSW1tdXRhYmxlRXJyb3JEZWZpbml0aW9ue2Jhc2U9UkVRVUlSRUQsIGNhdGVnb3J5PVVTRVJfRVJST1IsIGNhdXNlPW51bGwsIGRlYnVnSW5mbz1jb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX01JU1NJTkc6IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5MaXN0QWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoTGlzdEFjbHMuamF2YToxMDEpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5MaXN0QWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoTGlzdEFjbHMuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IubGlzdChBY2Nlc3NDb250cm9sc0RlbGVnYXRvci5qYXZhOjg5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuLCBkb21haW49Z2xvYmFsLCBleHRlbmRlZEhlbHA9bnVsbCwgaHR0cEhlYWRlcnM9e30sIGh0dHBTdGF0dXM9YmFkUmVxdWVzdCwgaW50ZXJuYWxSZWFzb249UmVhc29ue2FyZ3VtZW50cz17fSwgY2F1c2U9bnVsbCwgY29kZT1nZGF0YS5Db3JlRXJyb3JEb21haW4uUkVRVUlSRUQsIGNyZWF0ZWRCeUJhY2tlbmQ9dHJ1ZSwgZGVidWdNZXNzYWdlPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpVU0VSX1BST0pFQ1RfTUlTU0lORzogQnVja2V0IGlzIFJlcXVlc3RlciBQYXlzIGJ1Y2tldCBidXQgbm8gYmlsbGluZyBwcm9qZWN0IGlkIHByb3ZpZGVkIGZvciBub24tb3duZXIuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkxpc3RBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChMaXN0QWNscy5qYXZhOjEwMSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkxpc3RBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChMaXN0QWNscy5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci5saXN0KEFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmphdmE6ODkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGVycm9yUHJvdG9Db2RlPVJFUVVJUkVELCBlcnJvclByb3RvRG9tYWluPWdkYXRhLkNvcmVFcnJvckRvbWFpbiwgZmlsdGVyZWRNZXNzYWdlPW51bGwsIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9QnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLiwgdW5uYW1lZEFyZ3VtZW50cz1bXX0sIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9QnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLiwgcmVhc29uPXJlcXVpcmVkLCBycGNDb2RlPTQwMH0gQnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLjogY29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuTGlzdEFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKExpc3RBY2xzLmphdmE6MTAxKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuTGlzdEFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKExpc3RBY2xzLmphdmE6MjUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLkFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmxpc3QoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YTo4OSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogQnVja2V0IGlzIFJlcXVlc3RlciBQYXlzIGJ1Y2tldCBidXQgbm8gYmlsbGluZyBwcm9qZWN0IGlkIHByb3ZpZGVkIGZvciBub24tb3duZXIuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS5FcnJvckNvbGxlY3Rvci50b0ZhdWx0KEVycm9yQ29sbGVjdG9yLmphdmE6NTQpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5RXJyb3JDb252ZXJ0ZXIudG9GYXVsdChSb3N5RXJyb3JDb252ZXJ0ZXIuamF2YTo2Nylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lIYW5kbGVyJDIuY2FsbChSb3N5SGFuZGxlci5qYXZhOjI1OSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lIYW5kbGVyJDIuY2FsbChSb3N5SGFuZGxlci5qYXZhOjIzOSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkRpcmVjdEV4ZWN1dG9yLmV4ZWN1dGUoRGlyZWN0RXhlY3V0b3IuamF2YTozMClcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmV4ZWN1dGVMaXN0ZW5lcihBYnN0cmFjdEZ1dHVyZS5qYXZhOjExNDMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5jb21wbGV0ZShBYnN0cmFjdEZ1dHVyZS5qYXZhOjk2Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLnNldChBYnN0cmFjdEZ1dHVyZS5qYXZhOjczMSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkRpcmVjdEV4ZWN1dG9yLmV4ZWN1dGUoRGlyZWN0RXhlY3V0b3IuamF2YTozMClcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmV4ZWN1dGVMaXN0ZW5lcihBYnN0cmFjdEZ1dHVyZS5qYXZhOjExNDMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5jb21wbGV0ZShBYnN0cmFjdEZ1dHVyZS5qYXZhOjk2Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLnNldChBYnN0cmFjdEZ1dHVyZS5qYXZhOjczMSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnRocmVhZC5UaHJlYWRUcmFja2VycyRUaHJlYWRUcmFja2luZ1J1bm5hYmxlLnJ1bihUaHJlYWRUcmFja2Vycy5qYXZhOjEyNilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoVHJhY2VDb250ZXh0LmphdmE6NDUzKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuc2VydmVyLkNvbW1vbk1vZHVsZSRDb250ZXh0Q2FycnlpbmdFeGVjdXRvclNlcnZpY2UkMS5ydW5JbkNvbnRleHQoQ29tbW9uTW9kdWxlLmphdmE6ODAyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlJDEucnVuKFRyYWNlQ29udGV4dC5qYXZhOjQ2MClcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihUcmFjZUNvbnRleHQuamF2YTozMTkpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkQWJzdHJhY3RUcmFjZUNvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoVHJhY2VDb250ZXh0LmphdmE6MzExKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NTcpXG5cdGF0IGNvbS5nb29nbGUuZ3NlLmludGVybmFsLkRpc3BhdGNoUXVldWVJbXBsJFdvcmtlclRocmVhZC5ydW4oRGlzcGF0Y2hRdWV1ZUltcGwuamF2YTo0MDMpXG4ifV0sImNvZGUiOjQwMCwibWVzc2FnZSI6IkJ1Y2tldCBpcyByZXF1ZXN0ZXIgcGF5cyBidWNrZXQgYnV0IG5vIHVzZXIgcHJvamVjdCBwcm92aWRlZC4ifX0=" } }, { "ID": "a2868e9e376e356b", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/foo/acl?alt=json\u0026prettyPrint=false\u0026userProject=gcloud-golang-firestore-tests", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "2800" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:12 GMT" ], "Etag": [ "COGeqNLx/eECEAU=" ], "Expires": [ "Thu, 02 May 2019 22:25:12 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoyZfAJB3TroGxzYv0gy7dHUwpU0jtIeU_EyQSFQKzHlHbyRa33r_a-B1aHw5tHaoawuDvv7skisdx10yhmm9ZRrPw0ibwpMkX5Cwhf0OK85DF84jM" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9scyIsIml0ZW1zIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvZm9vLzE1NTY4MzU4OTE1NDgwMDEvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJvYmplY3QiOiJmb28iLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg5MTU0ODAwMSIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDT0dlcU5MeC9lRUNFQVU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvZm9vLzE1NTY4MzU4OTE1NDgwMDEvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2Zvby9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsIm9iamVjdCI6ImZvbyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODkxNTQ4MDAxIiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ09HZXFOTHgvZUVDRUFVPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL2Zvby8xNTU2ODM1ODkxNTQ4MDAxL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvby9mb28vYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJvYmplY3QiOiJmb28iLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg5MTU0ODAwMSIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDT0dlcU5MeC9lRUNFQVU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvZm9vLzE1NTY4MzU4OTE1NDgwMDEvdXNlci1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2Zvby9hY2wvdXNlci1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsIm9iamVjdCI6ImZvbyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODkxNTQ4MDAxIiwiZW50aXR5IjoidXNlci1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ09HZXFOTHgvZUVDRUFVPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL2Zvby8xNTU2ODM1ODkxNTQ4MDAxL2RvbWFpbi1nb29nbGUuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vL2FjbC9kb21haW4tZ29vZ2xlLmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsIm9iamVjdCI6ImZvbyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODkxNTQ4MDAxIiwiZW50aXR5IjoiZG9tYWluLWdvb2dsZS5jb20iLCJyb2xlIjoiUkVBREVSIiwiZG9tYWluIjoiZ29vZ2xlLmNvbSIsImV0YWciOiJDT0dlcU5MeC9lRUNFQVU9In1dfQ==" } }, { "ID": "ffb216dc74ccc27e", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/foo/acl?alt=json\u0026prettyPrint=false\u0026userProject=veener-jba", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 403, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "13059" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:12 GMT" ], "Expires": [ "Thu, 02 May 2019 22:25:12 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UqBumxgw_FTJlt7J3xLsBDxljAcEyC2G5aQqhEibawMttB-ogPabqDfz8ZN65WtOikIggZQ8OqW8zigV4Q5vfQkog7NMasAuivcMjhAsgqv_6qWv_E" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6ImZvcmJpZGRlbiIsIm1lc3NhZ2UiOiJpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpVU0VSX1BST0pFQ1RfQUNDRVNTX0RFTklFRDogaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20gZG9lcyBub3QgaGF2ZSBzZXJ2aWNldXNhZ2Uuc2VydmljZXMudXNlIGFjY2VzcyB0byBwcm9qZWN0IDY0MjA4MDkxODEwMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuTGlzdEFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKExpc3RBY2xzLmphdmE6MTAxKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuTGlzdEFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKExpc3RBY2xzLmphdmE6MjUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLkFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmxpc3QoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YTo4OSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20gZG9lcyBub3QgaGF2ZSBzZXJ2aWNldXNhZ2Uuc2VydmljZXMudXNlIGFjY2VzcyB0byBwcm9qZWN0IDY0MjA4MDkxODEwMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuXG5jb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS5GYXVsdDogSW1tdXRhYmxlRXJyb3JEZWZpbml0aW9ue2Jhc2U9Rk9SQklEREVOLCBjYXRlZ29yeT1VU0VSX0VSUk9SLCBjYXVzZT1udWxsLCBkZWJ1Z0luZm89Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9BQ0NFU1NfREVOSUVEOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5MaXN0QWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoTGlzdEFjbHMuamF2YToxMDEpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5MaXN0QWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoTGlzdEFjbHMuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IubGlzdChBY2Nlc3NDb250cm9sc0RlbGVnYXRvci5qYXZhOjg5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGRvbWFpbj1nbG9iYWwsIGV4dGVuZGVkSGVscD1udWxsLCBodHRwSGVhZGVycz17fSwgaHR0cFN0YXR1cz1mb3JiaWRkZW4sIGludGVybmFsUmVhc29uPVJlYXNvbnthcmd1bWVudHM9e30sIGNhdXNlPW51bGwsIGNvZGU9Z2RhdGEuQ29yZUVycm9yRG9tYWluLkZPUkJJRERFTiwgY3JlYXRlZEJ5QmFja2VuZD10cnVlLCBkZWJ1Z01lc3NhZ2U9Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9BQ0NFU1NfREVOSUVEOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5MaXN0QWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoTGlzdEFjbHMuamF2YToxMDEpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5MaXN0QWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoTGlzdEFjbHMuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IubGlzdChBY2Nlc3NDb250cm9sc0RlbGVnYXRvci5qYXZhOjg5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGVycm9yUHJvdG9Db2RlPUZPUkJJRERFTiwgZXJyb3JQcm90b0RvbWFpbj1nZGF0YS5Db3JlRXJyb3JEb21haW4sIGZpbHRlcmVkTWVzc2FnZT1udWxsLCBsb2NhdGlvbj1udWxsLCBtZXNzYWdlPWludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuLCB1bm5hbWVkQXJndW1lbnRzPVtdfSwgbG9jYXRpb249bnVsbCwgbWVzc2FnZT1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiwgcmVhc29uPWZvcmJpZGRlbiwgcnBjQ29kZT00MDN9IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuOiBjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX0FDQ0VTU19ERU5JRUQ6IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkxpc3RBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChMaXN0QWNscy5qYXZhOjEwMSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkxpc3RBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChMaXN0QWNscy5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci5saXN0KEFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmphdmE6ODkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS5FcnJvckNvbGxlY3Rvci50b0ZhdWx0KEVycm9yQ29sbGVjdG9yLmphdmE6NTQpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5RXJyb3JDb252ZXJ0ZXIudG9GYXVsdChSb3N5RXJyb3JDb252ZXJ0ZXIuamF2YTo2Nylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lIYW5kbGVyJDIuY2FsbChSb3N5SGFuZGxlci5qYXZhOjI1OSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lIYW5kbGVyJDIuY2FsbChSb3N5SGFuZGxlci5qYXZhOjIzOSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkRpcmVjdEV4ZWN1dG9yLmV4ZWN1dGUoRGlyZWN0RXhlY3V0b3IuamF2YTozMClcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmV4ZWN1dGVMaXN0ZW5lcihBYnN0cmFjdEZ1dHVyZS5qYXZhOjExNDMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5jb21wbGV0ZShBYnN0cmFjdEZ1dHVyZS5qYXZhOjk2Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLnNldChBYnN0cmFjdEZ1dHVyZS5qYXZhOjczMSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkRpcmVjdEV4ZWN1dG9yLmV4ZWN1dGUoRGlyZWN0RXhlY3V0b3IuamF2YTozMClcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmV4ZWN1dGVMaXN0ZW5lcihBYnN0cmFjdEZ1dHVyZS5qYXZhOjExNDMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5jb21wbGV0ZShBYnN0cmFjdEZ1dHVyZS5qYXZhOjk2Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLnNldChBYnN0cmFjdEZ1dHVyZS5qYXZhOjczMSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnRocmVhZC5UaHJlYWRUcmFja2VycyRUaHJlYWRUcmFja2luZ1J1bm5hYmxlLnJ1bihUaHJlYWRUcmFja2Vycy5qYXZhOjEyNilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoVHJhY2VDb250ZXh0LmphdmE6NDUzKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuc2VydmVyLkNvbW1vbk1vZHVsZSRDb250ZXh0Q2FycnlpbmdFeGVjdXRvclNlcnZpY2UkMS5ydW5JbkNvbnRleHQoQ29tbW9uTW9kdWxlLmphdmE6ODAyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlJDEucnVuKFRyYWNlQ29udGV4dC5qYXZhOjQ2MClcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihUcmFjZUNvbnRleHQuamF2YTozMTkpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkQWJzdHJhY3RUcmFjZUNvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoVHJhY2VDb250ZXh0LmphdmE6MzExKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NTcpXG5cdGF0IGNvbS5nb29nbGUuZ3NlLmludGVybmFsLkRpc3BhdGNoUXVldWVJbXBsJFdvcmtlclRocmVhZC5ydW4oRGlzcGF0Y2hRdWV1ZUltcGwuamF2YTo0MDMpXG4ifV0sImNvZGUiOjQwMywibWVzc2FnZSI6ImludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuIn19" } }, { "ID": "183157f40c6c1bcd", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/foo/acl/domain-google.com?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:25:13 GMT" ], "Etag": [ "COGeqNLx/eECEAY=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrC6xxVQeIIjitNwDv5PhDUIBQbtGdHJDi_AmLs8vTbGzkby-5hguMIwI_UeHlCuGF1u5jBoVwCOgSqJBiJJ5fxh8oCzBn-nHGcGAdIOeQt7gTL0RQ" ] }, "Body": "" } }, { "ID": "4b6b925053570053", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/foo/acl/domain-google.com?alt=json\u0026prettyPrint=false\u0026userProject=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 404, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "11631" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:13 GMT" ], "Expires": [ "Thu, 02 May 2019 22:25:13 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UpiIBwh04pJH1-X9d1oJluF_2ZCJEFLzF4E7SI-easf2noIolxavCbpH7NP9GMmNXnVK_ZJm4kW8coV5ArXDr-Rwodjnd9Bn2hFiJ_puNeWWldJ6mA" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6Im5vdEZvdW5kIiwibWVzc2FnZSI6Ik5vdCBGb3VuZCIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpBQ0xfU0NPUEVfTk9UX0ZPVU5EOiBTcGVjaWZpZWQgQUNMIHNjb3BlIHdhcyBub3QgZm91bmRcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjg2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci5kZWxldGUoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YToxMDkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IFNwZWNpZmllZCBBQ0wgc2NvcGUgd2FzIG5vdCBmb3VuZFxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cbmNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLkZhdWx0OiBJbW11dGFibGVFcnJvckRlZmluaXRpb257YmFzZT1OT1RfRk9VTkQsIGNhdGVnb3J5PVVTRVJfRVJST1IsIGNhdXNlPW51bGwsIGRlYnVnSW5mbz1jb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6QUNMX1NDT1BFX05PVF9GT1VORDogU3BlY2lmaWVkIEFDTCBzY29wZSB3YXMgbm90IGZvdW5kXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkRlbGV0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZUFjbHMuamF2YTo4Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkRlbGV0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZUFjbHMuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuZGVsZXRlKEFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmphdmE6MTA5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBTcGVjaWZpZWQgQUNMIHNjb3BlIHdhcyBub3QgZm91bmRcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuLCBkb21haW49Z2xvYmFsLCBleHRlbmRlZEhlbHA9bnVsbCwgaHR0cEhlYWRlcnM9e30sIGh0dHBTdGF0dXM9bm90Rm91bmQsIGludGVybmFsUmVhc29uPVJlYXNvbnthcmd1bWVudHM9e30sIGNhdXNlPW51bGwsIGNvZGU9Z2RhdGEuQ29yZUVycm9yRG9tYWluLk5PVF9GT1VORCwgY3JlYXRlZEJ5QmFja2VuZD10cnVlLCBkZWJ1Z01lc3NhZ2U9Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OkFDTF9TQ09QRV9OT1RfRk9VTkQ6IFNwZWNpZmllZCBBQ0wgc2NvcGUgd2FzIG5vdCBmb3VuZFxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5EZWxldGVBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChEZWxldGVBY2xzLmphdmE6ODYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5EZWxldGVBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChEZWxldGVBY2xzLmphdmE6MjUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLkFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmRlbGV0ZShBY2Nlc3NDb250cm9sc0RlbGVnYXRvci5qYXZhOjEwOSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogU3BlY2lmaWVkIEFDTCBzY29wZSB3YXMgbm90IGZvdW5kXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZXJyb3JQcm90b0NvZGU9Tk9UX0ZPVU5ELCBlcnJvclByb3RvRG9tYWluPWdkYXRhLkNvcmVFcnJvckRvbWFpbiwgZmlsdGVyZWRNZXNzYWdlPW51bGwsIGxvY2F0aW9uPWVudGl0eS5yZXNvdXJjZV9pZC5zY29wZSwgbWVzc2FnZT1udWxsLCB1bm5hbWVkQXJndW1lbnRzPVtdfSwgbG9jYXRpb249ZW50aXR5LnJlc291cmNlX2lkLnNjb3BlLCBtZXNzYWdlPU5vdCBGb3VuZCwgcmVhc29uPW5vdEZvdW5kLCBycGNDb2RlPTQwNH0gTm90IEZvdW5kOiBjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6QUNMX1NDT1BFX05PVF9GT1VORDogU3BlY2lmaWVkIEFDTCBzY29wZSB3YXMgbm90IGZvdW5kXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkRlbGV0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZUFjbHMuamF2YTo4Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkRlbGV0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZUFjbHMuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuZGVsZXRlKEFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmphdmE6MTA5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBTcGVjaWZpZWQgQUNMIHNjb3BlIHdhcyBub3QgZm91bmRcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLkVycm9yQ29sbGVjdG9yLnRvRmF1bHQoRXJyb3JDb2xsZWN0b3IuamF2YTo1NClcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lFcnJvckNvbnZlcnRlci50b0ZhdWx0KFJvc3lFcnJvckNvbnZlcnRlci5qYXZhOjY3KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUhhbmRsZXIkMi5jYWxsKFJvc3lIYW5kbGVyLmphdmE6MjU5KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUhhbmRsZXIkMi5jYWxsKFJvc3lIYW5kbGVyLmphdmE6MjM5KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRGlyZWN0RXhlY3V0b3IuZXhlY3V0ZShEaXJlY3RFeGVjdXRvci5qYXZhOjMwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuZXhlY3V0ZUxpc3RlbmVyKEFic3RyYWN0RnV0dXJlLmphdmE6MTE0Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmNvbXBsZXRlKEFic3RyYWN0RnV0dXJlLmphdmE6OTYzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuc2V0KEFic3RyYWN0RnV0dXJlLmphdmE6NzMxKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRGlyZWN0RXhlY3V0b3IuZXhlY3V0ZShEaXJlY3RFeGVjdXRvci5qYXZhOjMwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuZXhlY3V0ZUxpc3RlbmVyKEFic3RyYWN0RnV0dXJlLmphdmE6MTE0Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmNvbXBsZXRlKEFic3RyYWN0RnV0dXJlLmphdmE6OTYzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuc2V0KEFic3RyYWN0RnV0dXJlLmphdmE6NzMxKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIudGhyZWFkLlRocmVhZFRyYWNrZXJzJFRocmVhZFRyYWNraW5nUnVubmFibGUucnVuKFRocmVhZFRyYWNrZXJzLmphdmE6MTI2KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChUcmFjZUNvbnRleHQuamF2YTo0NTMpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5zZXJ2ZXIuQ29tbW9uTW9kdWxlJENvbnRleHRDYXJyeWluZ0V4ZWN1dG9yU2VydmljZSQxLnJ1bkluQ29udGV4dChDb21tb25Nb2R1bGUuamF2YTo4MDIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUkMS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDYwKVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkQWJzdHJhY3RUcmFjZUNvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKFRyYWNlQ29udGV4dC5qYXZhOjMxOSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChUcmFjZUNvbnRleHQuamF2YTozMTEpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuKFRyYWNlQ29udGV4dC5qYXZhOjQ1Nylcblx0YXQgY29tLmdvb2dsZS5nc2UuaW50ZXJuYWwuRGlzcGF0Y2hRdWV1ZUltcGwkV29ya2VyVGhyZWFkLnJ1bihEaXNwYXRjaFF1ZXVlSW1wbC5qYXZhOjQwMylcbiJ9XSwiY29kZSI6NDA0LCJtZXNzYWdlIjoiTm90IEZvdW5kIn19" } }, { "ID": "9b4f9c448170e89d", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/foo/acl/domain-google.com?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "12243" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:14 GMT" ], "Expires": [ "Thu, 02 May 2019 22:25:14 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UqHc1VVBdvXFq9aDPAprpXNP5xPt-ZtPdYXwCQPHX_s4gkCMom31AtHeDocV_hker5qryWoYnRD8PPu5c7JqDNQ75v7GgE1vO5xAt7AqWPoLU5MO5A" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6InJlcXVpcmVkIiwibWVzc2FnZSI6IkJ1Y2tldCBpcyByZXF1ZXN0ZXIgcGF5cyBidWNrZXQgYnV0IG5vIHVzZXIgcHJvamVjdCBwcm92aWRlZC4iLCJkZWJ1Z0luZm8iOiJjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX01JU1NJTkc6IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5EZWxldGVBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChEZWxldGVBY2xzLmphdmE6ODYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5EZWxldGVBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChEZWxldGVBY2xzLmphdmE6MjUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLkFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmRlbGV0ZShBY2Nlc3NDb250cm9sc0RlbGVnYXRvci5qYXZhOjEwOSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogQnVja2V0IGlzIFJlcXVlc3RlciBQYXlzIGJ1Y2tldCBidXQgbm8gYmlsbGluZyBwcm9qZWN0IGlkIHByb3ZpZGVkIGZvciBub24tb3duZXIuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPVJFUVVJUkVELCBjYXRlZ29yeT1VU0VSX0VSUk9SLCBjYXVzZT1udWxsLCBkZWJ1Z0luZm89Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjg2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci5kZWxldGUoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YToxMDkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGRvbWFpbj1nbG9iYWwsIGV4dGVuZGVkSGVscD1udWxsLCBodHRwSGVhZGVycz17fSwgaHR0cFN0YXR1cz1iYWRSZXF1ZXN0LCBpbnRlcm5hbFJlYXNvbj1SZWFzb257YXJndW1lbnRzPXt9LCBjYXVzZT1udWxsLCBjb2RlPWdkYXRhLkNvcmVFcnJvckRvbWFpbi5SRVFVSVJFRCwgY3JlYXRlZEJ5QmFja2VuZD10cnVlLCBkZWJ1Z01lc3NhZ2U9Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjg2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci5kZWxldGUoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YToxMDkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGVycm9yUHJvdG9Db2RlPVJFUVVJUkVELCBlcnJvclByb3RvRG9tYWluPWdkYXRhLkNvcmVFcnJvckRvbWFpbiwgZmlsdGVyZWRNZXNzYWdlPW51bGwsIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9QnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLiwgdW5uYW1lZEFyZ3VtZW50cz1bXX0sIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9QnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLiwgcmVhc29uPXJlcXVpcmVkLCBycGNDb2RlPTQwMH0gQnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLjogY29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjg2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci5kZWxldGUoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YToxMDkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRXJyb3JDb2xsZWN0b3IudG9GYXVsdChFcnJvckNvbGxlY3Rvci5qYXZhOjU0KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUVycm9yQ29udmVydGVyLnRvRmF1bHQoUm9zeUVycm9yQ29udmVydGVyLmphdmE6NjcpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyNTkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyMzkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci50aHJlYWQuVGhyZWFkVHJhY2tlcnMkVGhyZWFkVHJhY2tpbmdSdW5uYWJsZS5ydW4oVGhyZWFkVHJhY2tlcnMuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjQ1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnNlcnZlci5Db21tb25Nb2R1bGUkQ29udGV4dENhcnJ5aW5nRXhlY3V0b3JTZXJ2aWNlJDEucnVuSW5Db250ZXh0KENvbW1vbk1vZHVsZS5qYXZhOjgwMilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZSQxLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NjApXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoVHJhY2VDb250ZXh0LmphdmE6MzE5KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjMxMSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDU3KVxuXHRhdCBjb20uZ29vZ2xlLmdzZS5pbnRlcm5hbC5EaXNwYXRjaFF1ZXVlSW1wbCRXb3JrZXJUaHJlYWQucnVuKERpc3BhdGNoUXVldWVJbXBsLmphdmE6NDAzKVxuIn1dLCJjb2RlIjo0MDAsIm1lc3NhZ2UiOiJCdWNrZXQgaXMgcmVxdWVzdGVyIHBheXMgYnVja2V0IGJ1dCBubyB1c2VyIHByb2plY3QgcHJvdmlkZWQuIn19" } }, { "ID": "692d41cf9ea91eb2", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/foo/acl/domain-google.com?alt=json\u0026prettyPrint=false\u0026userProject=gcloud-golang-firestore-tests", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 404, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "11631" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:14 GMT" ], "Expires": [ "Thu, 02 May 2019 22:25:14 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UpuFB_mdJg9Fd7Sj06Xdcrj7Up2xXVc_P-SgISEEtiv4v9doPXzNbzBz92Q2UfEchYWSQnikHhS34dUAOefj9J4vaBYqjc9RjFmrn8YcPNyS8aWKgI" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6Im5vdEZvdW5kIiwibWVzc2FnZSI6Ik5vdCBGb3VuZCIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpBQ0xfU0NPUEVfTk9UX0ZPVU5EOiBTcGVjaWZpZWQgQUNMIHNjb3BlIHdhcyBub3QgZm91bmRcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjg2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci5kZWxldGUoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YToxMDkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IFNwZWNpZmllZCBBQ0wgc2NvcGUgd2FzIG5vdCBmb3VuZFxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cbmNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLkZhdWx0OiBJbW11dGFibGVFcnJvckRlZmluaXRpb257YmFzZT1OT1RfRk9VTkQsIGNhdGVnb3J5PVVTRVJfRVJST1IsIGNhdXNlPW51bGwsIGRlYnVnSW5mbz1jb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6QUNMX1NDT1BFX05PVF9GT1VORDogU3BlY2lmaWVkIEFDTCBzY29wZSB3YXMgbm90IGZvdW5kXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkRlbGV0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZUFjbHMuamF2YTo4Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkRlbGV0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZUFjbHMuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuZGVsZXRlKEFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmphdmE6MTA5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBTcGVjaWZpZWQgQUNMIHNjb3BlIHdhcyBub3QgZm91bmRcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuLCBkb21haW49Z2xvYmFsLCBleHRlbmRlZEhlbHA9bnVsbCwgaHR0cEhlYWRlcnM9e30sIGh0dHBTdGF0dXM9bm90Rm91bmQsIGludGVybmFsUmVhc29uPVJlYXNvbnthcmd1bWVudHM9e30sIGNhdXNlPW51bGwsIGNvZGU9Z2RhdGEuQ29yZUVycm9yRG9tYWluLk5PVF9GT1VORCwgY3JlYXRlZEJ5QmFja2VuZD10cnVlLCBkZWJ1Z01lc3NhZ2U9Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OkFDTF9TQ09QRV9OT1RfRk9VTkQ6IFNwZWNpZmllZCBBQ0wgc2NvcGUgd2FzIG5vdCBmb3VuZFxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5EZWxldGVBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChEZWxldGVBY2xzLmphdmE6ODYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYWNscy5EZWxldGVBY2xzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChEZWxldGVBY2xzLmphdmE6MjUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLkFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmRlbGV0ZShBY2Nlc3NDb250cm9sc0RlbGVnYXRvci5qYXZhOjEwOSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogU3BlY2lmaWVkIEFDTCBzY29wZSB3YXMgbm90IGZvdW5kXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZXJyb3JQcm90b0NvZGU9Tk9UX0ZPVU5ELCBlcnJvclByb3RvRG9tYWluPWdkYXRhLkNvcmVFcnJvckRvbWFpbiwgZmlsdGVyZWRNZXNzYWdlPW51bGwsIGxvY2F0aW9uPWVudGl0eS5yZXNvdXJjZV9pZC5zY29wZSwgbWVzc2FnZT1udWxsLCB1bm5hbWVkQXJndW1lbnRzPVtdfSwgbG9jYXRpb249ZW50aXR5LnJlc291cmNlX2lkLnNjb3BlLCBtZXNzYWdlPU5vdCBGb3VuZCwgcmVhc29uPW5vdEZvdW5kLCBycGNDb2RlPTQwNH0gTm90IEZvdW5kOiBjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6QUNMX1NDT1BFX05PVF9GT1VORDogU3BlY2lmaWVkIEFDTCBzY29wZSB3YXMgbm90IGZvdW5kXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkRlbGV0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZUFjbHMuamF2YTo4Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkRlbGV0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZUFjbHMuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuZGVsZXRlKEFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmphdmE6MTA5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBTcGVjaWZpZWQgQUNMIHNjb3BlIHdhcyBub3QgZm91bmRcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLkVycm9yQ29sbGVjdG9yLnRvRmF1bHQoRXJyb3JDb2xsZWN0b3IuamF2YTo1NClcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lFcnJvckNvbnZlcnRlci50b0ZhdWx0KFJvc3lFcnJvckNvbnZlcnRlci5qYXZhOjY3KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUhhbmRsZXIkMi5jYWxsKFJvc3lIYW5kbGVyLmphdmE6MjU5KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUhhbmRsZXIkMi5jYWxsKFJvc3lIYW5kbGVyLmphdmE6MjM5KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRGlyZWN0RXhlY3V0b3IuZXhlY3V0ZShEaXJlY3RFeGVjdXRvci5qYXZhOjMwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuZXhlY3V0ZUxpc3RlbmVyKEFic3RyYWN0RnV0dXJlLmphdmE6MTE0Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmNvbXBsZXRlKEFic3RyYWN0RnV0dXJlLmphdmE6OTYzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuc2V0KEFic3RyYWN0RnV0dXJlLmphdmE6NzMxKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRGlyZWN0RXhlY3V0b3IuZXhlY3V0ZShEaXJlY3RFeGVjdXRvci5qYXZhOjMwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuZXhlY3V0ZUxpc3RlbmVyKEFic3RyYWN0RnV0dXJlLmphdmE6MTE0Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmNvbXBsZXRlKEFic3RyYWN0RnV0dXJlLmphdmE6OTYzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuc2V0KEFic3RyYWN0RnV0dXJlLmphdmE6NzMxKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIudGhyZWFkLlRocmVhZFRyYWNrZXJzJFRocmVhZFRyYWNraW5nUnVubmFibGUucnVuKFRocmVhZFRyYWNrZXJzLmphdmE6MTI2KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChUcmFjZUNvbnRleHQuamF2YTo0NTMpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5zZXJ2ZXIuQ29tbW9uTW9kdWxlJENvbnRleHRDYXJyeWluZ0V4ZWN1dG9yU2VydmljZSQxLnJ1bkluQ29udGV4dChDb21tb25Nb2R1bGUuamF2YTo4MDIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUkMS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDYwKVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkQWJzdHJhY3RUcmFjZUNvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKFRyYWNlQ29udGV4dC5qYXZhOjMxOSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChUcmFjZUNvbnRleHQuamF2YTozMTEpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuKFRyYWNlQ29udGV4dC5qYXZhOjQ1Nylcblx0YXQgY29tLmdvb2dsZS5nc2UuaW50ZXJuYWwuRGlzcGF0Y2hRdWV1ZUltcGwkV29ya2VyVGhyZWFkLnJ1bihEaXNwYXRjaFF1ZXVlSW1wbC5qYXZhOjQwMylcbiJ9XSwiY29kZSI6NDA0LCJtZXNzYWdlIjoiTm90IEZvdW5kIn19" } }, { "ID": "db035a3cc51de007", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/foo/acl/domain-google.com?alt=json\u0026prettyPrint=false\u0026userProject=veener-jba", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 403, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "13099" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:14 GMT" ], "Expires": [ "Thu, 02 May 2019 22:25:14 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UrGb7BqO44vNpZjBnLrSI6_jVCVRFevSqm5eux2DIE2zmUY3sH0T0st7OOsLPcBjvLSbDfijMcdJwsgpM1fQGcerB9bS8Ffd4Qgzdjth0I8FreV4Vs" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6ImZvcmJpZGRlbiIsIm1lc3NhZ2UiOiJpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpVU0VSX1BST0pFQ1RfQUNDRVNTX0RFTklFRDogaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20gZG9lcyBub3QgaGF2ZSBzZXJ2aWNldXNhZ2Uuc2VydmljZXMudXNlIGFjY2VzcyB0byBwcm9qZWN0IDY0MjA4MDkxODEwMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjg2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci5kZWxldGUoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YToxMDkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPUZPUkJJRERFTiwgY2F0ZWdvcnk9VVNFUl9FUlJPUiwgY2F1c2U9bnVsbCwgZGVidWdJbmZvPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpVU0VSX1BST0pFQ1RfQUNDRVNTX0RFTklFRDogaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20gZG9lcyBub3QgaGF2ZSBzZXJ2aWNldXNhZ2Uuc2VydmljZXMudXNlIGFjY2VzcyB0byBwcm9qZWN0IDY0MjA4MDkxODEwMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjg2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmFjbHMuRGVsZXRlQWNscy5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlQWNscy5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5BY2Nlc3NDb250cm9sc0RlbGVnYXRvci5kZWxldGUoQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuamF2YToxMDkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZG9tYWluPWdsb2JhbCwgZXh0ZW5kZWRIZWxwPW51bGwsIGh0dHBIZWFkZXJzPXt9LCBodHRwU3RhdHVzPWZvcmJpZGRlbiwgaW50ZXJuYWxSZWFzb249UmVhc29ue2FyZ3VtZW50cz17fSwgY2F1c2U9bnVsbCwgY29kZT1nZGF0YS5Db3JlRXJyb3JEb21haW4uRk9SQklEREVOLCBjcmVhdGVkQnlCYWNrZW5kPXRydWUsIGRlYnVnTWVzc2FnZT1jb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX0FDQ0VTU19ERU5JRUQ6IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkRlbGV0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZUFjbHMuamF2YTo4Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkRlbGV0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZUFjbHMuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuZGVsZXRlKEFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmphdmE6MTA5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGVycm9yUHJvdG9Db2RlPUZPUkJJRERFTiwgZXJyb3JQcm90b0RvbWFpbj1nZGF0YS5Db3JlRXJyb3JEb21haW4sIGZpbHRlcmVkTWVzc2FnZT1udWxsLCBsb2NhdGlvbj1udWxsLCBtZXNzYWdlPWludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuLCB1bm5hbWVkQXJndW1lbnRzPVtdfSwgbG9jYXRpb249bnVsbCwgbWVzc2FnZT1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiwgcmVhc29uPWZvcmJpZGRlbiwgcnBjQ29kZT00MDN9IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuOiBjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX0FDQ0VTU19ERU5JRUQ6IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkRlbGV0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZUFjbHMuamF2YTo4Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5hY2xzLkRlbGV0ZUFjbHMuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZUFjbHMuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQWNjZXNzQ29udHJvbHNEZWxlZ2F0b3IuZGVsZXRlKEFjY2Vzc0NvbnRyb2xzRGVsZWdhdG9yLmphdmE6MTA5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRXJyb3JDb2xsZWN0b3IudG9GYXVsdChFcnJvckNvbGxlY3Rvci5qYXZhOjU0KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUVycm9yQ29udmVydGVyLnRvRmF1bHQoUm9zeUVycm9yQ29udmVydGVyLmphdmE6NjcpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyNTkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyMzkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci50aHJlYWQuVGhyZWFkVHJhY2tlcnMkVGhyZWFkVHJhY2tpbmdSdW5uYWJsZS5ydW4oVGhyZWFkVHJhY2tlcnMuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjQ1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnNlcnZlci5Db21tb25Nb2R1bGUkQ29udGV4dENhcnJ5aW5nRXhlY3V0b3JTZXJ2aWNlJDEucnVuSW5Db250ZXh0KENvbW1vbk1vZHVsZS5qYXZhOjgwMilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZSQxLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NjApXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoVHJhY2VDb250ZXh0LmphdmE6MzE5KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjMxMSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDU3KVxuXHRhdCBjb20uZ29vZ2xlLmdzZS5pbnRlcm5hbC5EaXNwYXRjaFF1ZXVlSW1wbCRXb3JrZXJUaHJlYWQucnVuKERpc3BhdGNoUXVldWVJbXBsLmphdmE6NDAzKVxuIn1dLCJjb2RlIjo0MDMsIm1lc3NhZ2UiOiJpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiJ9fQ==" } }, { "ID": "e1d95794cb6be989", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/foo/rewriteTo/b/go-integration-test-20190502-80633403432013-0003/o/copy?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "3" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "e30K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3273" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:15 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoVcH2L0r9wGab--fnRuKptLRoUoHCUHfRegh3rKNQExHVsYLnt1NFwOKFa_6hRbeYXO1aY8-F-KiD6IY3sWykIKXr5iqelEJHTWEMQ8wHuzIcWLO8" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNyZXdyaXRlUmVzcG9uc2UiLCJ0b3RhbEJ5dGVzUmV3cml0dGVuIjoiNSIsIm9iamVjdFNpemUiOiI1IiwiZG9uZSI6dHJ1ZSwicmVzb3VyY2UiOnsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvY29weS8xNTU2ODM1OTE1MjY2MjE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vY29weSIsIm5hbWUiOiJjb3B5IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5MTUyNjYyMTQiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW4iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDUtMDJUMjI6MjU6MTUuMjY1WiIsInVwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjE1LjI2NVoiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNToxNS4yNjVaIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2NvcHk/Z2VuZXJhdGlvbj0xNTU2ODM1OTE1MjY2MjE0JmFsdD1tZWRpYSIsImNvbnRlbnRMYW5ndWFnZSI6ImVuIiwiY2FjaGVDb250cm9sIjoicHVibGljLCBtYXgtYWdlPTYwIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvY29weS8xNTU2ODM1OTE1MjY2MjE0L3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2NvcHkvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsIm9iamVjdCI6ImNvcHkiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTkxNTI2NjIxNCIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDS2J4ejkzeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvY29weS8xNTU2ODM1OTE1MjY2MjE0L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvby9jb3B5L2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwib2JqZWN0IjoiY29weSIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTE1MjY2MjE0IiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0tieHo5M3gvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL2NvcHkvMTU1NjgzNTkxNTI2NjIxNC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vY29weS9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsIm9iamVjdCI6ImNvcHkiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTkxNTI2NjIxNCIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDS2J4ejkzeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvY29weS8xNTU2ODM1OTE1MjY2MjE0L3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvby9jb3B5L2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwib2JqZWN0IjoiY29weSIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTE1MjY2MjE0IiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ0tieHo5M3gvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDS2J4ejkzeC9lRUNFQUU9In19" } }, { "ID": "297f13e741cceb04", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/foo/rewriteTo/b/go-integration-test-20190502-80633403432013-0003/o/copy?alt=json\u0026prettyPrint=false\u0026projection=full\u0026userProject=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "3" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "e30K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3273" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:15 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UroLXQs6945-UOUyN7qOhICUNnGSzCVrNCv5DD9uMyvgD08zpuufBZj8WM8Fxe0DuOuQowqbPEn1UdJdbFTW7puyeY4zX8fM6UgT7SZIVB0Xi-B0OM" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNyZXdyaXRlUmVzcG9uc2UiLCJ0b3RhbEJ5dGVzUmV3cml0dGVuIjoiNSIsIm9iamVjdFNpemUiOiI1IiwiZG9uZSI6dHJ1ZSwicmVzb3VyY2UiOnsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvY29weS8xNTU2ODM1OTE1ODQxOTk3Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vY29weSIsIm5hbWUiOiJjb3B5IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5MTU4NDE5OTciLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW4iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDUtMDJUMjI6MjU6MTUuODQxWiIsInVwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjE1Ljg0MVoiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNToxNS44NDFaIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2NvcHk/Z2VuZXJhdGlvbj0xNTU2ODM1OTE1ODQxOTk3JmFsdD1tZWRpYSIsImNvbnRlbnRMYW5ndWFnZSI6ImVuIiwiY2FjaGVDb250cm9sIjoicHVibGljLCBtYXgtYWdlPTYwIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvY29weS8xNTU2ODM1OTE1ODQxOTk3L3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2NvcHkvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsIm9iamVjdCI6ImNvcHkiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTkxNTg0MTk5NyIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDTTJEODkzeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvY29weS8xNTU2ODM1OTE1ODQxOTk3L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvby9jb3B5L2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwib2JqZWN0IjoiY29weSIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTE1ODQxOTk3IiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ00yRDg5M3gvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL2NvcHkvMTU1NjgzNTkxNTg0MTk5Ny9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vY29weS9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsIm9iamVjdCI6ImNvcHkiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTkxNTg0MTk5NyIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDTTJEODkzeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvY29weS8xNTU2ODM1OTE1ODQxOTk3L3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvby9jb3B5L2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwib2JqZWN0IjoiY29weSIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTE1ODQxOTk3IiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ00yRDg5M3gvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTTJEODkzeC9lRUNFQUU9In19" } }, { "ID": "9617f04d2dc95a7c", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/foo/rewriteTo/b/go-integration-test-20190502-80633403432013-0003/o/copy?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "3" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "e30K" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Content-Length": [ "12683" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:16 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UqeJiJeDLLZgn9vlRyNk1plY-7dcPXaz47gPNAhMqmSx5ZMvg6pqWj18PVUR65UGuWE7Amtua_zqsv0dVyDZE2FFceMeIQcQ2n6noklvRS9kxPXcEU" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6InJlcXVpcmVkIiwibWVzc2FnZSI6IkJ1Y2tldCBpcyByZXF1ZXN0ZXIgcGF5cyBidWNrZXQgYnV0IG5vIHVzZXIgcHJvamVjdCBwcm92aWRlZC4iLCJkZWJ1Z0luZm8iOiJjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX01JU1NJTkc6IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5SZXdyaXRlT2JqZWN0LnJld3JpdGUoUmV3cml0ZU9iamVjdC5qYXZhOjIwMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLlJld3JpdGVPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJld3JpdGVPYmplY3QuamF2YToxOTMpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5SZXdyaXRlT2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXdyaXRlT2JqZWN0LmphdmE6NDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLk9iamVjdHNEZWxlZ2F0b3IucmV3cml0ZShPYmplY3RzRGVsZWdhdG9yLmphdmE6MTIxKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTggbW9yZVxuXG5jb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS5GYXVsdDogSW1tdXRhYmxlRXJyb3JEZWZpbml0aW9ue2Jhc2U9UkVRVUlSRUQsIGNhdGVnb3J5PVVTRVJfRVJST1IsIGNhdXNlPW51bGwsIGRlYnVnSW5mbz1jb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX01JU1NJTkc6IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5SZXdyaXRlT2JqZWN0LnJld3JpdGUoUmV3cml0ZU9iamVjdC5qYXZhOjIwMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLlJld3JpdGVPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJld3JpdGVPYmplY3QuamF2YToxOTMpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5SZXdyaXRlT2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXdyaXRlT2JqZWN0LmphdmE6NDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLk9iamVjdHNEZWxlZ2F0b3IucmV3cml0ZShPYmplY3RzRGVsZWdhdG9yLmphdmE6MTIxKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTggbW9yZVxuLCBkb21haW49Z2xvYmFsLCBleHRlbmRlZEhlbHA9bnVsbCwgaHR0cEhlYWRlcnM9e30sIGh0dHBTdGF0dXM9YmFkUmVxdWVzdCwgaW50ZXJuYWxSZWFzb249UmVhc29ue2FyZ3VtZW50cz17fSwgY2F1c2U9bnVsbCwgY29kZT1nZGF0YS5Db3JlRXJyb3JEb21haW4uUkVRVUlSRUQsIGNyZWF0ZWRCeUJhY2tlbmQ9dHJ1ZSwgZGVidWdNZXNzYWdlPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpVU0VSX1BST0pFQ1RfTUlTU0lORzogQnVja2V0IGlzIFJlcXVlc3RlciBQYXlzIGJ1Y2tldCBidXQgbm8gYmlsbGluZyBwcm9qZWN0IGlkIHByb3ZpZGVkIGZvciBub24tb3duZXIuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLlJld3JpdGVPYmplY3QucmV3cml0ZShSZXdyaXRlT2JqZWN0LmphdmE6MjAwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuUmV3cml0ZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmV3cml0ZU9iamVjdC5qYXZhOjE5Mylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLlJld3JpdGVPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJld3JpdGVPYmplY3QuamF2YTo0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uT2JqZWN0c0RlbGVnYXRvci5yZXdyaXRlKE9iamVjdHNEZWxlZ2F0b3IuamF2YToxMjEpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxOCBtb3JlXG4sIGVycm9yUHJvdG9Db2RlPVJFUVVJUkVELCBlcnJvclByb3RvRG9tYWluPWdkYXRhLkNvcmVFcnJvckRvbWFpbiwgZmlsdGVyZWRNZXNzYWdlPW51bGwsIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9QnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLiwgdW5uYW1lZEFyZ3VtZW50cz1bXX0sIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9QnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLiwgcmVhc29uPXJlcXVpcmVkLCBycGNDb2RlPTQwMH0gQnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLjogY29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuUmV3cml0ZU9iamVjdC5yZXdyaXRlKFJld3JpdGVPYmplY3QuamF2YToyMDApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5SZXdyaXRlT2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXdyaXRlT2JqZWN0LmphdmE6MTkzKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuUmV3cml0ZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmV3cml0ZU9iamVjdC5qYXZhOjQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLnJld3JpdGUoT2JqZWN0c0RlbGVnYXRvci5qYXZhOjEyMSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogQnVja2V0IGlzIFJlcXVlc3RlciBQYXlzIGJ1Y2tldCBidXQgbm8gYmlsbGluZyBwcm9qZWN0IGlkIHByb3ZpZGVkIGZvciBub24tb3duZXIuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE4IG1vcmVcblxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS5FcnJvckNvbGxlY3Rvci50b0ZhdWx0KEVycm9yQ29sbGVjdG9yLmphdmE6NTQpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5RXJyb3JDb252ZXJ0ZXIudG9GYXVsdChSb3N5RXJyb3JDb252ZXJ0ZXIuamF2YTo2Nylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lIYW5kbGVyJDIuY2FsbChSb3N5SGFuZGxlci5qYXZhOjI1OSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lIYW5kbGVyJDIuY2FsbChSb3N5SGFuZGxlci5qYXZhOjIzOSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkRpcmVjdEV4ZWN1dG9yLmV4ZWN1dGUoRGlyZWN0RXhlY3V0b3IuamF2YTozMClcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmV4ZWN1dGVMaXN0ZW5lcihBYnN0cmFjdEZ1dHVyZS5qYXZhOjExNDMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5jb21wbGV0ZShBYnN0cmFjdEZ1dHVyZS5qYXZhOjk2Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLnNldChBYnN0cmFjdEZ1dHVyZS5qYXZhOjczMSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkRpcmVjdEV4ZWN1dG9yLmV4ZWN1dGUoRGlyZWN0RXhlY3V0b3IuamF2YTozMClcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmV4ZWN1dGVMaXN0ZW5lcihBYnN0cmFjdEZ1dHVyZS5qYXZhOjExNDMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5jb21wbGV0ZShBYnN0cmFjdEZ1dHVyZS5qYXZhOjk2Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLnNldChBYnN0cmFjdEZ1dHVyZS5qYXZhOjczMSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnRocmVhZC5UaHJlYWRUcmFja2VycyRUaHJlYWRUcmFja2luZ1J1bm5hYmxlLnJ1bihUaHJlYWRUcmFja2Vycy5qYXZhOjEyNilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoVHJhY2VDb250ZXh0LmphdmE6NDUzKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuc2VydmVyLkNvbW1vbk1vZHVsZSRDb250ZXh0Q2FycnlpbmdFeGVjdXRvclNlcnZpY2UkMS5ydW5JbkNvbnRleHQoQ29tbW9uTW9kdWxlLmphdmE6ODAyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlJDEucnVuKFRyYWNlQ29udGV4dC5qYXZhOjQ2MClcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihUcmFjZUNvbnRleHQuamF2YTozMTkpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkQWJzdHJhY3RUcmFjZUNvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoVHJhY2VDb250ZXh0LmphdmE6MzExKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NTcpXG5cdGF0IGNvbS5nb29nbGUuZ3NlLmludGVybmFsLkRpc3BhdGNoUXVldWVJbXBsJFdvcmtlclRocmVhZC5ydW4oRGlzcGF0Y2hRdWV1ZUltcGwuamF2YTo0MDMpXG4ifV0sImNvZGUiOjQwMCwibWVzc2FnZSI6IkJ1Y2tldCBpcyByZXF1ZXN0ZXIgcGF5cyBidWNrZXQgYnV0IG5vIHVzZXIgcHJvamVjdCBwcm92aWRlZC4ifX0=" } }, { "ID": "2309e069a65c894f", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/foo/rewriteTo/b/go-integration-test-20190502-80633403432013-0003/o/copy?alt=json\u0026prettyPrint=false\u0026projection=full\u0026userProject=gcloud-golang-firestore-tests", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "3" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "e30K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3333" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:16 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpxhvVZmlJMvR93BoI0JsL0TYbDN-kmlYHQOOlRfb-Nnqpc8iUImRtJT8Qvx0XWrOsALmLv4Oub_aeCCWkHPvqaF28oAazlhqRZYoxrPlaQlW0N1Qs" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNyZXdyaXRlUmVzcG9uc2UiLCJ0b3RhbEJ5dGVzUmV3cml0dGVuIjoiNSIsIm9iamVjdFNpemUiOiI1IiwiZG9uZSI6dHJ1ZSwicmVzb3VyY2UiOnsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvY29weS8xNTU2ODM1OTE2NjM3MTY1Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vY29weSIsIm5hbWUiOiJjb3B5IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5MTY2MzcxNjUiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW4iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDUtMDJUMjI6MjU6MTYuNjM2WiIsInVwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjE2LjYzNloiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNToxNi42MzZaIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2NvcHk/Z2VuZXJhdGlvbj0xNTU2ODM1OTE2NjM3MTY1JmFsdD1tZWRpYSIsImNvbnRlbnRMYW5ndWFnZSI6ImVuIiwiY2FjaGVDb250cm9sIjoicHVibGljLCBtYXgtYWdlPTYwIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvY29weS8xNTU2ODM1OTE2NjM3MTY1L3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2NvcHkvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsIm9iamVjdCI6ImNvcHkiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTkxNjYzNzE2NSIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDTzNIbzk3eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvY29weS8xNTU2ODM1OTE2NjM3MTY1L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvby9jb3B5L2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwib2JqZWN0IjoiY29weSIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTE2NjM3MTY1IiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ08zSG85N3gvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL2NvcHkvMTU1NjgzNTkxNjYzNzE2NS9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vY29weS9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsIm9iamVjdCI6ImNvcHkiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTkxNjYzNzE2NSIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDTzNIbzk3eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvY29weS8xNTU2ODM1OTE2NjM3MTY1L3VzZXItaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvby9jb3B5L2FjbC91c2VyLWludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwib2JqZWN0IjoiY29weSIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTE2NjM3MTY1IiwiZW50aXR5IjoidXNlci1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ08zSG85N3gvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTzNIbzk3eC9lRUNFQUU9In19" } }, { "ID": "d2fe101ea1da654d", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/foo/rewriteTo/b/go-integration-test-20190502-80633403432013-0003/o/copy?alt=json\u0026prettyPrint=false\u0026projection=full\u0026userProject=veener-jba", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "3" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "e30K" ] }, "Response": { "StatusCode": 403, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Content-Length": [ "13539" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:16 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UqjFigs6aYtqXW_7VucOIgJY2MQZwuLv9B12s2ffhWgWDxtJyjLinG4A8U9gKBCpiTt9jUvdHKtaG20qZfyfN9Q1eVAkUQh_zv7ESbqnWhsiheI7zw" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6ImZvcmJpZGRlbiIsIm1lc3NhZ2UiOiJpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpVU0VSX1BST0pFQ1RfQUNDRVNTX0RFTklFRDogaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20gZG9lcyBub3QgaGF2ZSBzZXJ2aWNldXNhZ2Uuc2VydmljZXMudXNlIGFjY2VzcyB0byBwcm9qZWN0IDY0MjA4MDkxODEwMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuUmV3cml0ZU9iamVjdC5yZXdyaXRlKFJld3JpdGVPYmplY3QuamF2YToyMDApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5SZXdyaXRlT2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXdyaXRlT2JqZWN0LmphdmE6MTkzKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuUmV3cml0ZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmV3cml0ZU9iamVjdC5qYXZhOjQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLnJld3JpdGUoT2JqZWN0c0RlbGVnYXRvci5qYXZhOjEyMSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20gZG9lcyBub3QgaGF2ZSBzZXJ2aWNldXNhZ2Uuc2VydmljZXMudXNlIGFjY2VzcyB0byBwcm9qZWN0IDY0MjA4MDkxODEwMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTggbW9yZVxuXG5jb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS5GYXVsdDogSW1tdXRhYmxlRXJyb3JEZWZpbml0aW9ue2Jhc2U9Rk9SQklEREVOLCBjYXRlZ29yeT1VU0VSX0VSUk9SLCBjYXVzZT1udWxsLCBkZWJ1Z0luZm89Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9BQ0NFU1NfREVOSUVEOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5SZXdyaXRlT2JqZWN0LnJld3JpdGUoUmV3cml0ZU9iamVjdC5qYXZhOjIwMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLlJld3JpdGVPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJld3JpdGVPYmplY3QuamF2YToxOTMpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5SZXdyaXRlT2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXdyaXRlT2JqZWN0LmphdmE6NDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLk9iamVjdHNEZWxlZ2F0b3IucmV3cml0ZShPYmplY3RzRGVsZWdhdG9yLmphdmE6MTIxKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxOCBtb3JlXG4sIGRvbWFpbj1nbG9iYWwsIGV4dGVuZGVkSGVscD1udWxsLCBodHRwSGVhZGVycz17fSwgaHR0cFN0YXR1cz1mb3JiaWRkZW4sIGludGVybmFsUmVhc29uPVJlYXNvbnthcmd1bWVudHM9e30sIGNhdXNlPW51bGwsIGNvZGU9Z2RhdGEuQ29yZUVycm9yRG9tYWluLkZPUkJJRERFTiwgY3JlYXRlZEJ5QmFja2VuZD10cnVlLCBkZWJ1Z01lc3NhZ2U9Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9BQ0NFU1NfREVOSUVEOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5SZXdyaXRlT2JqZWN0LnJld3JpdGUoUmV3cml0ZU9iamVjdC5qYXZhOjIwMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLlJld3JpdGVPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJld3JpdGVPYmplY3QuamF2YToxOTMpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5SZXdyaXRlT2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXdyaXRlT2JqZWN0LmphdmE6NDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLk9iamVjdHNEZWxlZ2F0b3IucmV3cml0ZShPYmplY3RzRGVsZWdhdG9yLmphdmE6MTIxKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxOCBtb3JlXG4sIGVycm9yUHJvdG9Db2RlPUZPUkJJRERFTiwgZXJyb3JQcm90b0RvbWFpbj1nZGF0YS5Db3JlRXJyb3JEb21haW4sIGZpbHRlcmVkTWVzc2FnZT1udWxsLCBsb2NhdGlvbj1udWxsLCBtZXNzYWdlPWludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuLCB1bm5hbWVkQXJndW1lbnRzPVtdfSwgbG9jYXRpb249bnVsbCwgbWVzc2FnZT1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiwgcmVhc29uPWZvcmJpZGRlbiwgcnBjQ29kZT00MDN9IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuOiBjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX0FDQ0VTU19ERU5JRUQ6IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLlJld3JpdGVPYmplY3QucmV3cml0ZShSZXdyaXRlT2JqZWN0LmphdmE6MjAwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuUmV3cml0ZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmV3cml0ZU9iamVjdC5qYXZhOjE5Mylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLlJld3JpdGVPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJld3JpdGVPYmplY3QuamF2YTo0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uT2JqZWN0c0RlbGVnYXRvci5yZXdyaXRlKE9iamVjdHNEZWxlZ2F0b3IuamF2YToxMjEpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE4IG1vcmVcblxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS5FcnJvckNvbGxlY3Rvci50b0ZhdWx0KEVycm9yQ29sbGVjdG9yLmphdmE6NTQpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5RXJyb3JDb252ZXJ0ZXIudG9GYXVsdChSb3N5RXJyb3JDb252ZXJ0ZXIuamF2YTo2Nylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lIYW5kbGVyJDIuY2FsbChSb3N5SGFuZGxlci5qYXZhOjI1OSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lIYW5kbGVyJDIuY2FsbChSb3N5SGFuZGxlci5qYXZhOjIzOSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkRpcmVjdEV4ZWN1dG9yLmV4ZWN1dGUoRGlyZWN0RXhlY3V0b3IuamF2YTozMClcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmV4ZWN1dGVMaXN0ZW5lcihBYnN0cmFjdEZ1dHVyZS5qYXZhOjExNDMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5jb21wbGV0ZShBYnN0cmFjdEZ1dHVyZS5qYXZhOjk2Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLnNldChBYnN0cmFjdEZ1dHVyZS5qYXZhOjczMSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkRpcmVjdEV4ZWN1dG9yLmV4ZWN1dGUoRGlyZWN0RXhlY3V0b3IuamF2YTozMClcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmV4ZWN1dGVMaXN0ZW5lcihBYnN0cmFjdEZ1dHVyZS5qYXZhOjExNDMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5jb21wbGV0ZShBYnN0cmFjdEZ1dHVyZS5qYXZhOjk2Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLnNldChBYnN0cmFjdEZ1dHVyZS5qYXZhOjczMSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnRocmVhZC5UaHJlYWRUcmFja2VycyRUaHJlYWRUcmFja2luZ1J1bm5hYmxlLnJ1bihUaHJlYWRUcmFja2Vycy5qYXZhOjEyNilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoVHJhY2VDb250ZXh0LmphdmE6NDUzKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuc2VydmVyLkNvbW1vbk1vZHVsZSRDb250ZXh0Q2FycnlpbmdFeGVjdXRvclNlcnZpY2UkMS5ydW5JbkNvbnRleHQoQ29tbW9uTW9kdWxlLmphdmE6ODAyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlJDEucnVuKFRyYWNlQ29udGV4dC5qYXZhOjQ2MClcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihUcmFjZUNvbnRleHQuamF2YTozMTkpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkQWJzdHJhY3RUcmFjZUNvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoVHJhY2VDb250ZXh0LmphdmE6MzExKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NTcpXG5cdGF0IGNvbS5nb29nbGUuZ3NlLmludGVybmFsLkRpc3BhdGNoUXVldWVJbXBsJFdvcmtlclRocmVhZC5ydW4oRGlzcGF0Y2hRdWV1ZUltcGwuamF2YTo0MDMpXG4ifV0sImNvZGUiOjQwMywibWVzc2FnZSI6ImludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuIn19" } }, { "ID": "6620f07aff04b6fd", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/compose/compose?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "127" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJkZXN0aW5hdGlvbiI6eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMifSwic291cmNlT2JqZWN0cyI6W3sibmFtZSI6ImZvbyJ9LHsibmFtZSI6ImNvcHkifV19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "742" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:17 GMT" ], "Etag": [ "CP/B0t7x/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpyWMaddvNz0IWnQ6KIl-tv6fJZCvrqTlGuaoHvKqXhxb3O1EKUIEirKSVcaedFZyxtjLhPD7Nj6qf1CRGWG1VnVigo5Wf3sYFDuuLvctxVpoHT0rY" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9jb21wb3NlLzE1NTY4MzU5MTc0MDY0NjMiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvby9jb21wb3NlIiwibmFtZSI6ImNvbXBvc2UiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTkxNzQwNjQ2MyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNToxNy40MDZaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjU6MTcuNDA2WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjE3LjQwNloiLCJzaXplIjoiMTAiLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vY29tcG9zZT9nZW5lcmF0aW9uPTE1NTY4MzU5MTc0MDY0NjMmYWx0PW1lZGlhIiwiY3JjMzJjIjoiL1JDT2dnPT0iLCJjb21wb25lbnRDb3VudCI6MiwiZXRhZyI6IkNQL0IwdDd4L2VFQ0VBRT0ifQ==" } }, { "ID": "7f88847ad9c49799", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/compose/compose?alt=json\u0026prettyPrint=false\u0026userProject=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "127" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJkZXN0aW5hdGlvbiI6eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMifSwic291cmNlT2JqZWN0cyI6W3sibmFtZSI6ImZvbyJ9LHsibmFtZSI6ImNvcHkifV19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "742" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:18 GMT" ], "Etag": [ "CKav+N7x/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Urtn69BB0ytbCZpuCbus4w__tiLeBpqeNzD2gKl5KN2LgP9ZJOIjudGKpDOJRhyW_WQjVOCJBC1CSB_AgE0MdPzVDAKWt13VfQ8aKe3pMWh4y1kOlI" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9jb21wb3NlLzE1NTY4MzU5MTgwMjY2NjIiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvby9jb21wb3NlIiwibmFtZSI6ImNvbXBvc2UiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTkxODAyNjY2MiIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNToxOC4wMjZaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjU6MTguMDI2WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjE4LjAyNloiLCJzaXplIjoiMTAiLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vY29tcG9zZT9nZW5lcmF0aW9uPTE1NTY4MzU5MTgwMjY2NjImYWx0PW1lZGlhIiwiY3JjMzJjIjoiL1JDT2dnPT0iLCJjb21wb25lbnRDb3VudCI6MiwiZXRhZyI6IkNLYXYrTjd4L2VFQ0VBRT0ifQ==" } }, { "ID": "a21f3ddca57ed424", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/compose/compose?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "127" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJkZXN0aW5hdGlvbiI6eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMifSwic291cmNlT2JqZWN0cyI6W3sibmFtZSI6ImZvbyJ9LHsibmFtZSI6ImNvcHkifV19Cg==" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Content-Length": [ "12267" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:18 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UrE9jrLJ0W1PUHWT3ldYhVsL9nNhAeFPU2K8g2rCMimty07QlN95esxj7dBAySQ-nzvK17L3WA7vjmxjCpeQADa2bztj6ke8NZjb8fuWkQHsnnzKXA" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6InJlcXVpcmVkIiwibWVzc2FnZSI6IkJ1Y2tldCBpcyByZXF1ZXN0ZXIgcGF5cyBidWNrZXQgYnV0IG5vIHVzZXIgcHJvamVjdCBwcm92aWRlZC4iLCJkZWJ1Z0luZm8iOiJjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX01JU1NJTkc6IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5Db21wb3NlT2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChDb21wb3NlT2JqZWN0LmphdmE6MTk5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuQ29tcG9zZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoQ29tcG9zZU9iamVjdC5qYXZhOjQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLmNvbXBvc2UoT2JqZWN0c0RlbGVnYXRvci5qYXZhOjEyNilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogQnVja2V0IGlzIFJlcXVlc3RlciBQYXlzIGJ1Y2tldCBidXQgbm8gYmlsbGluZyBwcm9qZWN0IGlkIHByb3ZpZGVkIGZvciBub24tb3duZXIuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPVJFUVVJUkVELCBjYXRlZ29yeT1VU0VSX0VSUk9SLCBjYXVzZT1udWxsLCBkZWJ1Z0luZm89Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuQ29tcG9zZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoQ29tcG9zZU9iamVjdC5qYXZhOjE5OSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkNvbXBvc2VPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKENvbXBvc2VPYmplY3QuamF2YTo0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uT2JqZWN0c0RlbGVnYXRvci5jb21wb3NlKE9iamVjdHNEZWxlZ2F0b3IuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGRvbWFpbj1nbG9iYWwsIGV4dGVuZGVkSGVscD1udWxsLCBodHRwSGVhZGVycz17fSwgaHR0cFN0YXR1cz1iYWRSZXF1ZXN0LCBpbnRlcm5hbFJlYXNvbj1SZWFzb257YXJndW1lbnRzPXt9LCBjYXVzZT1udWxsLCBjb2RlPWdkYXRhLkNvcmVFcnJvckRvbWFpbi5SRVFVSVJFRCwgY3JlYXRlZEJ5QmFja2VuZD10cnVlLCBkZWJ1Z01lc3NhZ2U9Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuQ29tcG9zZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoQ29tcG9zZU9iamVjdC5qYXZhOjE5OSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkNvbXBvc2VPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKENvbXBvc2VPYmplY3QuamF2YTo0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uT2JqZWN0c0RlbGVnYXRvci5jb21wb3NlKE9iamVjdHNEZWxlZ2F0b3IuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGVycm9yUHJvdG9Db2RlPVJFUVVJUkVELCBlcnJvclByb3RvRG9tYWluPWdkYXRhLkNvcmVFcnJvckRvbWFpbiwgZmlsdGVyZWRNZXNzYWdlPW51bGwsIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9QnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLiwgdW5uYW1lZEFyZ3VtZW50cz1bXX0sIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9QnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLiwgcmVhc29uPXJlcXVpcmVkLCBycGNDb2RlPTQwMH0gQnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLjogY29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuQ29tcG9zZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoQ29tcG9zZU9iamVjdC5qYXZhOjE5OSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkNvbXBvc2VPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKENvbXBvc2VPYmplY3QuamF2YTo0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uT2JqZWN0c0RlbGVnYXRvci5jb21wb3NlKE9iamVjdHNEZWxlZ2F0b3IuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRXJyb3JDb2xsZWN0b3IudG9GYXVsdChFcnJvckNvbGxlY3Rvci5qYXZhOjU0KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUVycm9yQ29udmVydGVyLnRvRmF1bHQoUm9zeUVycm9yQ29udmVydGVyLmphdmE6NjcpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyNTkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyMzkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci50aHJlYWQuVGhyZWFkVHJhY2tlcnMkVGhyZWFkVHJhY2tpbmdSdW5uYWJsZS5ydW4oVGhyZWFkVHJhY2tlcnMuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjQ1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnNlcnZlci5Db21tb25Nb2R1bGUkQ29udGV4dENhcnJ5aW5nRXhlY3V0b3JTZXJ2aWNlJDEucnVuSW5Db250ZXh0KENvbW1vbk1vZHVsZS5qYXZhOjgwMilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZSQxLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NjApXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoVHJhY2VDb250ZXh0LmphdmE6MzE5KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjMxMSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDU3KVxuXHRhdCBjb20uZ29vZ2xlLmdzZS5pbnRlcm5hbC5EaXNwYXRjaFF1ZXVlSW1wbCRXb3JrZXJUaHJlYWQucnVuKERpc3BhdGNoUXVldWVJbXBsLmphdmE6NDAzKVxuIn1dLCJjb2RlIjo0MDAsIm1lc3NhZ2UiOiJCdWNrZXQgaXMgcmVxdWVzdGVyIHBheXMgYnVja2V0IGJ1dCBubyB1c2VyIHByb2plY3QgcHJvdmlkZWQuIn19" } }, { "ID": "08fda3fa173e6e11", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/compose/compose?alt=json\u0026prettyPrint=false\u0026userProject=gcloud-golang-firestore-tests", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "127" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJkZXN0aW5hdGlvbiI6eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMifSwic291cmNlT2JqZWN0cyI6W3sibmFtZSI6ImZvbyJ9LHsibmFtZSI6ImNvcHkifV19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "742" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:19 GMT" ], "Etag": [ "CKy2sd/x/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqfGXVJ2-MQaZWJ-JS6runpSycA3GDKIXYHDGf3VBOXnADbUzL2YhZVmlQcW_95jXY0eMkK4Z5tSRk3cxGP_84T_1t3YDYQS2p37ZouBk7GfX-4xxw" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9jb21wb3NlLzE1NTY4MzU5MTg5NjE0NTIiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvby9jb21wb3NlIiwibmFtZSI6ImNvbXBvc2UiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTkxODk2MTQ1MiIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNToxOC45NjFaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjU6MTguOTYxWiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjE4Ljk2MVoiLCJzaXplIjoiMTAiLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vY29tcG9zZT9nZW5lcmF0aW9uPTE1NTY4MzU5MTg5NjE0NTImYWx0PW1lZGlhIiwiY3JjMzJjIjoiL1JDT2dnPT0iLCJjb21wb25lbnRDb3VudCI6MiwiZXRhZyI6IkNLeTJzZC94L2VFQ0VBRT0ifQ==" } }, { "ID": "0c9e19bd4ec37de2", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/compose/compose?alt=json\u0026prettyPrint=false\u0026userProject=veener-jba", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "127" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJkZXN0aW5hdGlvbiI6eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMifSwic291cmNlT2JqZWN0cyI6W3sibmFtZSI6ImZvbyJ9LHsibmFtZSI6ImNvcHkifV19Cg==" ] }, "Response": { "StatusCode": 403, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Content-Length": [ "13123" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:19 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UqGREJ2AZDcrZiJzPX5ltwlB28vRYhZ_xv4LMIO3La2IgFWk4wd5IVrqBs3z2epgtg7wkPpZm4qPH9zTzSIsXNxdLLHcNMMYr2azidefxtJVgXqgDY" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6ImZvcmJpZGRlbiIsIm1lc3NhZ2UiOiJpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpVU0VSX1BST0pFQ1RfQUNDRVNTX0RFTklFRDogaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20gZG9lcyBub3QgaGF2ZSBzZXJ2aWNldXNhZ2Uuc2VydmljZXMudXNlIGFjY2VzcyB0byBwcm9qZWN0IDY0MjA4MDkxODEwMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuQ29tcG9zZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoQ29tcG9zZU9iamVjdC5qYXZhOjE5OSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkNvbXBvc2VPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKENvbXBvc2VPYmplY3QuamF2YTo0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uT2JqZWN0c0RlbGVnYXRvci5jb21wb3NlKE9iamVjdHNEZWxlZ2F0b3IuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPUZPUkJJRERFTiwgY2F0ZWdvcnk9VVNFUl9FUlJPUiwgY2F1c2U9bnVsbCwgZGVidWdJbmZvPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpVU0VSX1BST0pFQ1RfQUNDRVNTX0RFTklFRDogaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20gZG9lcyBub3QgaGF2ZSBzZXJ2aWNldXNhZ2Uuc2VydmljZXMudXNlIGFjY2VzcyB0byBwcm9qZWN0IDY0MjA4MDkxODEwMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuQ29tcG9zZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoQ29tcG9zZU9iamVjdC5qYXZhOjE5OSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkNvbXBvc2VPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKENvbXBvc2VPYmplY3QuamF2YTo0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uT2JqZWN0c0RlbGVnYXRvci5jb21wb3NlKE9iamVjdHNEZWxlZ2F0b3IuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZG9tYWluPWdsb2JhbCwgZXh0ZW5kZWRIZWxwPW51bGwsIGh0dHBIZWFkZXJzPXt9LCBodHRwU3RhdHVzPWZvcmJpZGRlbiwgaW50ZXJuYWxSZWFzb249UmVhc29ue2FyZ3VtZW50cz17fSwgY2F1c2U9bnVsbCwgY29kZT1nZGF0YS5Db3JlRXJyb3JEb21haW4uRk9SQklEREVOLCBjcmVhdGVkQnlCYWNrZW5kPXRydWUsIGRlYnVnTWVzc2FnZT1jb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX0FDQ0VTU19ERU5JRUQ6IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkNvbXBvc2VPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKENvbXBvc2VPYmplY3QuamF2YToxOTkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5Db21wb3NlT2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChDb21wb3NlT2JqZWN0LmphdmE6NDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLk9iamVjdHNEZWxlZ2F0b3IuY29tcG9zZShPYmplY3RzRGVsZWdhdG9yLmphdmE6MTI2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGVycm9yUHJvdG9Db2RlPUZPUkJJRERFTiwgZXJyb3JQcm90b0RvbWFpbj1nZGF0YS5Db3JlRXJyb3JEb21haW4sIGZpbHRlcmVkTWVzc2FnZT1udWxsLCBsb2NhdGlvbj1udWxsLCBtZXNzYWdlPWludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuLCB1bm5hbWVkQXJndW1lbnRzPVtdfSwgbG9jYXRpb249bnVsbCwgbWVzc2FnZT1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiwgcmVhc29uPWZvcmJpZGRlbiwgcnBjQ29kZT00MDN9IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuOiBjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX0FDQ0VTU19ERU5JRUQ6IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkNvbXBvc2VPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKENvbXBvc2VPYmplY3QuamF2YToxOTkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5Db21wb3NlT2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChDb21wb3NlT2JqZWN0LmphdmE6NDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLk9iamVjdHNEZWxlZ2F0b3IuY29tcG9zZShPYmplY3RzRGVsZWdhdG9yLmphdmE6MTI2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRXJyb3JDb2xsZWN0b3IudG9GYXVsdChFcnJvckNvbGxlY3Rvci5qYXZhOjU0KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUVycm9yQ29udmVydGVyLnRvRmF1bHQoUm9zeUVycm9yQ29udmVydGVyLmphdmE6NjcpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyNTkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyMzkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci50aHJlYWQuVGhyZWFkVHJhY2tlcnMkVGhyZWFkVHJhY2tpbmdSdW5uYWJsZS5ydW4oVGhyZWFkVHJhY2tlcnMuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjQ1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnNlcnZlci5Db21tb25Nb2R1bGUkQ29udGV4dENhcnJ5aW5nRXhlY3V0b3JTZXJ2aWNlJDEucnVuSW5Db250ZXh0KENvbW1vbk1vZHVsZS5qYXZhOjgwMilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZSQxLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NjApXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoVHJhY2VDb250ZXh0LmphdmE6MzE5KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjMxMSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDU3KVxuXHRhdCBjb20uZ29vZ2xlLmdzZS5pbnRlcm5hbC5EaXNwYXRjaFF1ZXVlSW1wbCRXb3JrZXJUaHJlYWQucnVuKERpc3BhdGNoUXVldWVJbXBsLmphdmE6NDAzKVxuIn1dLCJjb2RlIjo0MDMsIm1lc3NhZ2UiOiJpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiJ9fQ==" } }, { "ID": "84daee26f7d989ce", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJuYW1lIjoiZm9vIn0K", "aGVsbG8=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3112" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:19 GMT" ], "Etag": [ "CLmF4d/x/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoLuw-z5wwTKy-X92_i7pyTrimolUNRUGrElhep6rUH_mmpgu_Vxp-1ncr8x8XNXHLs8NFRW5S7WVUsaDRRTrC5KBPea4EoFLANK8MFY0FpTkXr7_g" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTkxOTc0MTYyNSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2ZvbyIsIm5hbWUiOiJmb28iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTkxOTc0MTYyNSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNToxOS43NDFaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjU6MTkuNzQxWiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjE5Ljc0MVoiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vP2dlbmVyYXRpb249MTU1NjgzNTkxOTc0MTYyNSZhbHQ9bWVkaWEiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTkxOTc0MTYyNS9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvby9mb28vYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsIm9iamVjdCI6ImZvbyIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTE5NzQxNjI1IiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNMbUY0ZC94L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTkxOTc0MTYyNS9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwib2JqZWN0IjoiZm9vIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5MTk3NDE2MjUiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDTG1GNGQveC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvZm9vLzE1NTY4MzU5MTk3NDE2MjUvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2Zvby9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsIm9iamVjdCI6ImZvbyIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTE5NzQxNjI1IiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNMbUY0ZC94L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTkxOTc0MTYyNS91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwib2JqZWN0IjoiZm9vIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5MTk3NDE2MjUiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDTG1GNGQveC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNMbUY0ZC94L2VFQ0VBRT0ifQ==" } }, { "ID": "8457a5701f4ced08", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/foo?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:25:20 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpKF1M6PpAT354ON3809wMCor-B9KITRuEV34MQczP3OD4Co0sJYtNSub2FUzA8qanTDrtANRK0RuxPTz314o3HQro2HLOoyKZBow5CZ4sfsunKHv0" ] }, "Body": "" } }, { "ID": "1c2ba8a7670e2218", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJuYW1lIjoiZm9vIn0K", "aGVsbG8=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3112" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:20 GMT" ], "Etag": [ "CP+SgODx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uoq9hgjjwBbSH1zXN2UlNtWO31Qf5uk4ijjGCQlETB9_5H_CouvU3q4tyHAKEbIBlaW1_mNk3Fsp6LgXqsPPKvFzs3-WHeADAgc2-GpD-0inoYUHMs" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTkyMDI1MTI2MyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2ZvbyIsIm5hbWUiOiJmb28iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTkyMDI1MTI2MyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNToyMC4yNTBaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjU6MjAuMjUwWiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjIwLjI1MFoiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vP2dlbmVyYXRpb249MTU1NjgzNTkyMDI1MTI2MyZhbHQ9bWVkaWEiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTkyMDI1MTI2My9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvby9mb28vYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsIm9iamVjdCI6ImZvbyIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTIwMjUxMjYzIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNQK1NnT0R4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTkyMDI1MTI2My9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwib2JqZWN0IjoiZm9vIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5MjAyNTEyNjMiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDUCtTZ09EeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvZm9vLzE1NTY4MzU5MjAyNTEyNjMvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2Zvby9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsIm9iamVjdCI6ImZvbyIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTIwMjUxMjYzIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNQK1NnT0R4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTkyMDI1MTI2My91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwib2JqZWN0IjoiZm9vIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5MjAyNTEyNjMiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDUCtTZ09EeC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNQK1NnT0R4L2VFQ0VBRT0ifQ==" } }, { "ID": "7e6d2f97bd881584", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/foo?alt=json\u0026prettyPrint=false\u0026userProject=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:25:20 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UohQH2nTuRg_FtGhlfr9zC26C6lKFA-aZTf4GbiV5kWZCJ9E4YLHfIUKLpCLIgEfX9TAvi4oPNWfEBpbY-orlescLxrxYcB1U5fLmzzHQR2R0teR-s" ] }, "Body": "" } }, { "ID": "48e189abff98ea93", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJuYW1lIjoiZm9vIn0K", "aGVsbG8=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3112" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:21 GMT" ], "Etag": [ "CM3Aq+Dx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uq_NscG9s3iq-8NZq8vQhzdc9FJMaAfq_0GborrX84b8gG2zpbUNtEVnrjFjLyOXqBeJwthPgPUPcsGbIcD597LaPlxt-VNaetM2BLtMtYry8pPeQ8" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTkyMDk2MTYxMyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2ZvbyIsIm5hbWUiOiJmb28iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTkyMDk2MTYxMyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNToyMC45NjFaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjU6MjAuOTYxWiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjIwLjk2MVoiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vP2dlbmVyYXRpb249MTU1NjgzNTkyMDk2MTYxMyZhbHQ9bWVkaWEiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTkyMDk2MTYxMy9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvby9mb28vYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsIm9iamVjdCI6ImZvbyIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTIwOTYxNjEzIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNNM0FxK0R4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTkyMDk2MTYxMy9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwib2JqZWN0IjoiZm9vIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5MjA5NjE2MTMiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDTTNBcStEeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvZm9vLzE1NTY4MzU5MjA5NjE2MTMvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2Zvby9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsIm9iamVjdCI6ImZvbyIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTIwOTYxNjEzIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNNM0FxK0R4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTkyMDk2MTYxMy91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwib2JqZWN0IjoiZm9vIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5MjA5NjE2MTMiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDTTNBcStEeC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNNM0FxK0R4L2VFQ0VBRT0ifQ==" } }, { "ID": "02d6922c26c06cbd", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/foo?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 400, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "12243" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:21 GMT" ], "Expires": [ "Thu, 02 May 2019 22:25:21 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UrmjSJHhErkbzi8feJ_-8XOMqsIzGrEe6frQzWXQ7dPl0D8MW1mMHClKdwb2zBOTvpx7mXQWy2STZYSqx2o7O1Tr2DB1RZfwCZ3xp1jgw3NCICi7Xw" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6InJlcXVpcmVkIiwibWVzc2FnZSI6IkJ1Y2tldCBpcyByZXF1ZXN0ZXIgcGF5cyBidWNrZXQgYnV0IG5vIHVzZXIgcHJvamVjdCBwcm92aWRlZC4iLCJkZWJ1Z0luZm8iOiJjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX01JU1NJTkc6IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5EZWxldGVPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZU9iamVjdC5qYXZhOjg4KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuRGVsZXRlT2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChEZWxldGVPYmplY3QuamF2YToyNSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uT2JqZWN0c0RlbGVnYXRvci5kZWxldGUoT2JqZWN0c0RlbGVnYXRvci5qYXZhOjExMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogQnVja2V0IGlzIFJlcXVlc3RlciBQYXlzIGJ1Y2tldCBidXQgbm8gYmlsbGluZyBwcm9qZWN0IGlkIHByb3ZpZGVkIGZvciBub24tb3duZXIuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPVJFUVVJUkVELCBjYXRlZ29yeT1VU0VSX0VSUk9SLCBjYXVzZT1udWxsLCBkZWJ1Z0luZm89Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuRGVsZXRlT2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChEZWxldGVPYmplY3QuamF2YTo4OClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkRlbGV0ZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlT2JqZWN0LmphdmE6MjUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLk9iamVjdHNEZWxlZ2F0b3IuZGVsZXRlKE9iamVjdHNEZWxlZ2F0b3IuamF2YToxMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGRvbWFpbj1nbG9iYWwsIGV4dGVuZGVkSGVscD1udWxsLCBodHRwSGVhZGVycz17fSwgaHR0cFN0YXR1cz1iYWRSZXF1ZXN0LCBpbnRlcm5hbFJlYXNvbj1SZWFzb257YXJndW1lbnRzPXt9LCBjYXVzZT1udWxsLCBjb2RlPWdkYXRhLkNvcmVFcnJvckRvbWFpbi5SRVFVSVJFRCwgY3JlYXRlZEJ5QmFja2VuZD10cnVlLCBkZWJ1Z01lc3NhZ2U9Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuRGVsZXRlT2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChEZWxldGVPYmplY3QuamF2YTo4OClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkRlbGV0ZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlT2JqZWN0LmphdmE6MjUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLk9iamVjdHNEZWxlZ2F0b3IuZGVsZXRlKE9iamVjdHNEZWxlZ2F0b3IuamF2YToxMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGVycm9yUHJvdG9Db2RlPVJFUVVJUkVELCBlcnJvclByb3RvRG9tYWluPWdkYXRhLkNvcmVFcnJvckRvbWFpbiwgZmlsdGVyZWRNZXNzYWdlPW51bGwsIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9QnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLiwgdW5uYW1lZEFyZ3VtZW50cz1bXX0sIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9QnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLiwgcmVhc29uPXJlcXVpcmVkLCBycGNDb2RlPTQwMH0gQnVja2V0IGlzIHJlcXVlc3RlciBwYXlzIGJ1Y2tldCBidXQgbm8gdXNlciBwcm9qZWN0IHByb3ZpZGVkLjogY29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlVTRVJfUFJPSkVDVF9NSVNTSU5HOiBCdWNrZXQgaXMgUmVxdWVzdGVyIFBheXMgYnVja2V0IGJ1dCBubyBiaWxsaW5nIHByb2plY3QgaWQgcHJvdmlkZWQgZm9yIG5vbi1vd25lci5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuRGVsZXRlT2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChEZWxldGVPYmplY3QuamF2YTo4OClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkRlbGV0ZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlT2JqZWN0LmphdmE6MjUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLk9iamVjdHNEZWxlZ2F0b3IuZGVsZXRlKE9iamVjdHNEZWxlZ2F0b3IuamF2YToxMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEJ1Y2tldCBpcyBSZXF1ZXN0ZXIgUGF5cyBidWNrZXQgYnV0IG5vIGJpbGxpbmcgcHJvamVjdCBpZCBwcm92aWRlZCBmb3Igbm9uLW93bmVyLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRXJyb3JDb2xsZWN0b3IudG9GYXVsdChFcnJvckNvbGxlY3Rvci5qYXZhOjU0KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUVycm9yQ29udmVydGVyLnRvRmF1bHQoUm9zeUVycm9yQ29udmVydGVyLmphdmE6NjcpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyNTkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyMzkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci50aHJlYWQuVGhyZWFkVHJhY2tlcnMkVGhyZWFkVHJhY2tpbmdSdW5uYWJsZS5ydW4oVGhyZWFkVHJhY2tlcnMuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjQ1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnNlcnZlci5Db21tb25Nb2R1bGUkQ29udGV4dENhcnJ5aW5nRXhlY3V0b3JTZXJ2aWNlJDEucnVuSW5Db250ZXh0KENvbW1vbk1vZHVsZS5qYXZhOjgwMilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZSQxLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NjApXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoVHJhY2VDb250ZXh0LmphdmE6MzE5KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjMxMSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDU3KVxuXHRhdCBjb20uZ29vZ2xlLmdzZS5pbnRlcm5hbC5EaXNwYXRjaFF1ZXVlSW1wbCRXb3JrZXJUaHJlYWQucnVuKERpc3BhdGNoUXVldWVJbXBsLmphdmE6NDAzKVxuIn1dLCJjb2RlIjo0MDAsIm1lc3NhZ2UiOiJCdWNrZXQgaXMgcmVxdWVzdGVyIHBheXMgYnVja2V0IGJ1dCBubyB1c2VyIHByb2plY3QgcHJvdmlkZWQuIn19" } }, { "ID": "3fee93fca0ef933c", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJuYW1lIjoiZm9vIn0K", "aGVsbG8=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3112" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:21 GMT" ], "Etag": [ "CLfH1eDx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqLO91a0iSaTsK7EA2iN621UX-atvJ-8m8BeqeR8_o_CQLB8Pco5FMXznwQY7DZ8u0GPd1BvLE98s5S7T1Z6yL66OKL0CFFUntLBqNAKlji2Dcme6g" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTkyMTY1MDYxNSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2ZvbyIsIm5hbWUiOiJmb28iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTkyMTY1MDYxNSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNToyMS42NTBaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjU6MjEuNjUwWiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjIxLjY1MFoiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vP2dlbmVyYXRpb249MTU1NjgzNTkyMTY1MDYxNSZhbHQ9bWVkaWEiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTkyMTY1MDYxNS9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvby9mb28vYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsIm9iamVjdCI6ImZvbyIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTIxNjUwNjE1IiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNMZkgxZUR4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTkyMTY1MDYxNS9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwib2JqZWN0IjoiZm9vIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5MjE2NTA2MTUiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDTGZIMWVEeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvZm9vLzE1NTY4MzU5MjE2NTA2MTUvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2Zvby9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsIm9iamVjdCI6ImZvbyIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTIxNjUwNjE1IiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNMZkgxZUR4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTkyMTY1MDYxNS91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwib2JqZWN0IjoiZm9vIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5MjE2NTA2MTUiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDTGZIMWVEeC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNMZkgxZUR4L2VFQ0VBRT0ifQ==" } }, { "ID": "5c26cf93373a296a", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/foo?alt=json\u0026prettyPrint=false\u0026userProject=gcloud-golang-firestore-tests", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:25:22 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Urx3fvI3sQc5JiIazK1OQw5W12poVdjRyBKxIBM6N98jEJli9F0O33KVHHcHaP-QybHub31QmLNngZpzcVKJq33DSaVMW2Vpi5BUaVAAUL2jMoyOxs" ] }, "Body": "" } }, { "ID": "f8b5020ef71e4047", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJuYW1lIjoiZm9vIn0K", "aGVsbG8=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3112" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:22 GMT" ], "Etag": [ "CIungeHx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uq8QEz45d-uPa7qZ6Nl_SMqw2iepQXoM4aAkTx4YCqArXnSKI1UO3ZhJ5-_PDg3Uq6PPa2JDBTbxckiZCRMQvf0Cv6E_8Cwk3jKXGkneWFJYSeMAts" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTkyMjM2NzM3MSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2ZvbyIsIm5hbWUiOiJmb28iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTkyMjM2NzM3MSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNToyMi4zNjZaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjU6MjIuMzY2WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjIyLjM2NloiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vP2dlbmVyYXRpb249MTU1NjgzNTkyMjM2NzM3MSZhbHQ9bWVkaWEiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTkyMjM2NzM3MS9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvby9mb28vYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsIm9iamVjdCI6ImZvbyIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTIyMzY3MzcxIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNJdW5nZUh4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTkyMjM2NzM3MS9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwib2JqZWN0IjoiZm9vIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5MjIzNjczNzEiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDSXVuZ2VIeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDMvZm9vLzE1NTY4MzU5MjIzNjczNzEvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9vL2Zvby9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMyIsIm9iamVjdCI6ImZvbyIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTIyMzY3MzcxIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNJdW5nZUh4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMy9mb28vMTU1NjgzNTkyMjM2NzM3MS91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzL28vZm9vL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAzIiwib2JqZWN0IjoiZm9vIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5MjIzNjczNzEiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDSXVuZ2VIeC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNJdW5nZUh4L2VFQ0VBRT0ifQ==" } }, { "ID": "7cfadd8c1e7c0bd8", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/foo?alt=json\u0026prettyPrint=false\u0026userProject=veener-jba", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 403, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "13099" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:22 GMT" ], "Expires": [ "Thu, 02 May 2019 22:25:22 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UpjVnPaklKmbO8qV2lapwEIAwPjvf4HSJs3kNHHO_xZH4bV65pVPLKCb2qjMPCYSwEKRZzH6NpYjm6WlxsBdJnfBvpyRpIR017q9iJDyBcVPNUoDn8" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6ImZvcmJpZGRlbiIsIm1lc3NhZ2UiOiJpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpVU0VSX1BST0pFQ1RfQUNDRVNTX0RFTklFRDogaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20gZG9lcyBub3QgaGF2ZSBzZXJ2aWNldXNhZ2Uuc2VydmljZXMudXNlIGFjY2VzcyB0byBwcm9qZWN0IDY0MjA4MDkxODEwMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuRGVsZXRlT2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChEZWxldGVPYmplY3QuamF2YTo4OClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkRlbGV0ZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlT2JqZWN0LmphdmE6MjUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLk9iamVjdHNEZWxlZ2F0b3IuZGVsZXRlKE9iamVjdHNEZWxlZ2F0b3IuamF2YToxMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPUZPUkJJRERFTiwgY2F0ZWdvcnk9VVNFUl9FUlJPUiwgY2F1c2U9bnVsbCwgZGVidWdJbmZvPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpVU0VSX1BST0pFQ1RfQUNDRVNTX0RFTklFRDogaW50ZWdyYXRpb25AZ2Nsb3VkLWdvbGFuZy1maXJlc3RvcmUtdGVzdHMuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20gZG9lcyBub3QgaGF2ZSBzZXJ2aWNldXNhZ2Uuc2VydmljZXMudXNlIGFjY2VzcyB0byBwcm9qZWN0IDY0MjA4MDkxODEwMS5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuRGVsZXRlT2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChEZWxldGVPYmplY3QuamF2YTo4OClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkRlbGV0ZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlT2JqZWN0LmphdmE6MjUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLk9iamVjdHNEZWxlZ2F0b3IuZGVsZXRlKE9iamVjdHNEZWxlZ2F0b3IuamF2YToxMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZG9tYWluPWdsb2JhbCwgZXh0ZW5kZWRIZWxwPW51bGwsIGh0dHBIZWFkZXJzPXt9LCBodHRwU3RhdHVzPWZvcmJpZGRlbiwgaW50ZXJuYWxSZWFzb249UmVhc29ue2FyZ3VtZW50cz17fSwgY2F1c2U9bnVsbCwgY29kZT1nZGF0YS5Db3JlRXJyb3JEb21haW4uRk9SQklEREVOLCBjcmVhdGVkQnlCYWNrZW5kPXRydWUsIGRlYnVnTWVzc2FnZT1jb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX0FDQ0VTU19ERU5JRUQ6IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkRlbGV0ZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlT2JqZWN0LmphdmE6ODgpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5EZWxldGVPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZU9iamVjdC5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLmRlbGV0ZShPYmplY3RzRGVsZWdhdG9yLmphdmE6MTEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGVycm9yUHJvdG9Db2RlPUZPUkJJRERFTiwgZXJyb3JQcm90b0RvbWFpbj1nZGF0YS5Db3JlRXJyb3JEb21haW4sIGZpbHRlcmVkTWVzc2FnZT1udWxsLCBsb2NhdGlvbj1udWxsLCBtZXNzYWdlPWludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuLCB1bm5hbWVkQXJndW1lbnRzPVtdfSwgbG9jYXRpb249bnVsbCwgbWVzc2FnZT1pbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiwgcmVhc29uPWZvcmJpZGRlbiwgcnBjQ29kZT00MDN9IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuOiBjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6VVNFUl9QUk9KRUNUX0FDQ0VTU19ERU5JRUQ6IGludGVncmF0aW9uQGdjbG91ZC1nb2xhbmctZmlyZXN0b3JlLXRlc3RzLmlhbS5nc2VydmljZWFjY291bnQuY29tIGRvZXMgbm90IGhhdmUgc2VydmljZXVzYWdlLnNlcnZpY2VzLnVzZSBhY2Nlc3MgdG8gcHJvamVjdCA2NDIwODA5MTgxMDEuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkRlbGV0ZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlT2JqZWN0LmphdmE6ODgpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5EZWxldGVPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZU9iamVjdC5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLmRlbGV0ZShPYmplY3RzRGVsZWdhdG9yLmphdmE6MTEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRXJyb3JDb2xsZWN0b3IudG9GYXVsdChFcnJvckNvbGxlY3Rvci5qYXZhOjU0KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUVycm9yQ29udmVydGVyLnRvRmF1bHQoUm9zeUVycm9yQ29udmVydGVyLmphdmE6NjcpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyNTkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyMzkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci50aHJlYWQuVGhyZWFkVHJhY2tlcnMkVGhyZWFkVHJhY2tpbmdSdW5uYWJsZS5ydW4oVGhyZWFkVHJhY2tlcnMuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjQ1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnNlcnZlci5Db21tb25Nb2R1bGUkQ29udGV4dENhcnJ5aW5nRXhlY3V0b3JTZXJ2aWNlJDEucnVuSW5Db250ZXh0KENvbW1vbk1vZHVsZS5qYXZhOjgwMilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZSQxLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NjApXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoVHJhY2VDb250ZXh0LmphdmE6MzE5KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjMxMSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDU3KVxuXHRhdCBjb20uZ29vZ2xlLmdzZS5pbnRlcm5hbC5EaXNwYXRjaFF1ZXVlSW1wbCRXb3JrZXJUaHJlYWQucnVuKERpc3BhdGNoUXVldWVJbXBsLmphdmE6NDAzKVxuIn1dLCJjb2RlIjo0MDMsIm1lc3NhZ2UiOiJpbnRlZ3JhdGlvbkBnY2xvdWQtZ29sYW5nLWZpcmVzdG9yZS10ZXN0cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSBkb2VzIG5vdCBoYXZlIHNlcnZpY2V1c2FnZS5zZXJ2aWNlcy51c2UgYWNjZXNzIHRvIHByb2plY3QgNjQyMDgwOTE4MTAxLiJ9fQ==" } }, { "ID": "b1381b9995cf35f5", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/foo?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:25:23 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrD1hmfKK3yAwFXKqIwvCsEVMb_e7MWysJc7zbyVjZ_sbD9P41lzc0gYSef9yl8CRa6B0RtPq14V5MBSdy6C0i_cAkgANDN1da3O5QKELvACU11moU" ] }, "Body": "" } }, { "ID": "5e06ccad06bbd110", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/copy?alt=json\u0026prettyPrint=false\u0026userProject=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:25:23 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Ur2FRcf4QGZH2KhkP3kATb9eOy4S9lgrA3NQXYqhc1KBZDbcZN5NHF4MB6WiTxOraNE0HhkW3SOg8sp1gS4kAcWRZ2G0EGWmLgL6RUcwr3a2O-WY10" ] }, "Body": "" } }, { "ID": "b637ccaa36faa55b", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003/o/compose?alt=json\u0026prettyPrint=false\u0026userProject=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:25:23 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqGzSAdUK8pPs53JjaSJVQJObMJRsfQ5FIpSL0D4tNfft68cfE8Xb5fjSsAQG_PfmKZyX1Ind-s6dW6FgwREeHzu_OnEeOwCOaT8EZi2N4vNeWLvac" ] }, "Body": "" } }, { "ID": "15055c361faad5c1", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0003?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:25:24 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqwmXVRTmXX3P5iId4-EjuA1oviIQD-Vbdr7M5rgd7d5IxNvmPVkZz_zFyMBNoHd_DzXnPMN5R7grAe1yDdOzbyafIBwRcFsLh4r0a7ghp4LkNSLZk" ] }, "Body": "" } }, { "ID": "307f8a44d4ce6e9f", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/notificationConfigs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "32" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:24 GMT" ], "Expires": [ "Thu, 02 May 2019 22:25:24 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpaHmcEJBKGI7CtW9fK8-j5Z-oRk_dTwMS40wVaoNH1PN7k6x6d_9aD3w3ce6WGZJF5OYxkdoifp6L2vVz5lIGjzcmmIZ4Wxp1vktBOv8hLa417Mp4" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNub3RpZmljYXRpb25zIn0=" } }, { "ID": "f8df88961018be68", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/notificationConfigs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "121" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJwYXlsb2FkX2Zvcm1hdCI6Ik5PTkUiLCJ0b3BpYyI6Ii8vcHVic3ViLmdvb2dsZWFwaXMuY29tL3Byb2plY3RzL2Rla2xlcmstc2FuZGJveC90b3BpY3MvZ28tc3RvcmFnZS1ub3RpZmljYXRpb24tdGVzdCJ9Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "297" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:24 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqWiAA6LvnU4rExe2rVTwwFd51SI93o_d2tOj9OY1jk_qe1Yd1eiTXIa2eNecJQsmgwuFr4BUQoWy8ndutrCqGucmVIRL0jA6-i-vaGGVRF8uEe0AM" ] }, "Body": "eyJpZCI6IjExIiwidG9waWMiOiIvL3B1YnN1Yi5nb29nbGVhcGlzLmNvbS9wcm9qZWN0cy9kZWtsZXJrLXNhbmRib3gvdG9waWNzL2dvLXN0b3JhZ2Utbm90aWZpY2F0aW9uLXRlc3QiLCJwYXlsb2FkX2Zvcm1hdCI6Ik5PTkUiLCJldGFnIjoiMTEiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvbm90aWZpY2F0aW9uQ29uZmlncy8xMSIsImtpbmQiOiJzdG9yYWdlI25vdGlmaWNhdGlvbiJ9" } }, { "ID": "45f44fa6c3668273", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/notificationConfigs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "340" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:25 GMT" ], "Expires": [ "Thu, 02 May 2019 22:25:25 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoFWgB9V-ilyDIBP7KEF3SY7uTg-rikYE1ooEgWYkiXb2cW6oOwwtH1W7oe24WU2A9oyJIGOSskz3_icHqmMn7CfPoZQ-Lu5QdtZzv_5062_-UzAt0" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNub3RpZmljYXRpb25zIiwiaXRlbXMiOlt7ImlkIjoiMTEiLCJ0b3BpYyI6Ii8vcHVic3ViLmdvb2dsZWFwaXMuY29tL3Byb2plY3RzL2Rla2xlcmstc2FuZGJveC90b3BpY3MvZ28tc3RvcmFnZS1ub3RpZmljYXRpb24tdGVzdCIsInBheWxvYWRfZm9ybWF0IjoiTk9ORSIsImV0YWciOiIxMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9ub3RpZmljYXRpb25Db25maWdzLzExIiwia2luZCI6InN0b3JhZ2Ujbm90aWZpY2F0aW9uIn1dfQ==" } }, { "ID": "08c2546e2c262ee7", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/notificationConfigs/11?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:25:25 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoTmXr5TZZPRnABz_XbbZpjwU3iPz2e802RkcmNFr3sLzUx205tdmAb6vVWMNlYMUGZ5tGoddlqQ_oPnz0Xdvpz8CiD2eDLMDyrMbxVFjc3BinwBo0" ] }, "Body": "" } }, { "ID": "efc8b67f9c2f4b40", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/notificationConfigs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "32" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:25 GMT" ], "Expires": [ "Thu, 02 May 2019 22:25:25 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UraMBYT56qFvKLe_OPJfpJRhTy2qSpQyRjP6CScOnnijgaQ88eQtVahktX_Vsvy-G7J11d7GNT64FnpqZrewu1sUmuNNLiEtmkqVFILdNcWed6i1w4" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNub3RpZmljYXRpb25zIn0=" } }, { "ID": "6dd92f9ce3b15a57", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/gcp-public-data-landsat/LC08/PRE/044/034/LC80440342016259LGN00/LC80440342016259LGN00_MTL.txt", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "public, max-age=3600" ], "Content-Length": [ "7903" ], "Content-Type": [ "application/octet-stream" ], "Date": [ "Thu, 02 May 2019 22:25:25 GMT" ], "Etag": [ "\"7a5fd4743bd647485f88496fadb05c51\"" ], "Expires": [ "Thu, 02 May 2019 23:25:25 GMT" ], "Last-Modified": [ "Tue, 04 Oct 2016 16:42:07 GMT" ], "Server": [ "UploadServer" ], "X-Goog-Generation": [ "1475599327662000" ], "X-Goog-Hash": [ "crc32c=PWBt8g==", "md5=el/UdDvWR0hfiElvrbBcUQ==" ], "X-Goog-Metageneration": [ "1" ], "X-Goog-Storage-Class": [ "STANDARD" ], "X-Goog-Stored-Content-Encoding": [ "identity" ], "X-Goog-Stored-Content-Length": [ "7903" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpedRCcxIOhXCWdipyV2E0R3z00CUlOK6rPlof1gpKuQbLeJmvMoPFn28o8zqmmeVJ5rbX41bB6Hp116-_ISgEXl4Htmc1VS0Aq41lJQiN_mIvozbY" ] }, "Body": "R1JPVVAgPSBMMV9NRVRBREFUQV9GSUxFCiAgR1JPVVAgPSBNRVRBREFUQV9GSUxFX0lORk8KICAgIE9SSUdJTiA9ICJJbWFnZSBjb3VydGVzeSBvZiB0aGUgVS5TLiBHZW9sb2dpY2FsIFN1cnZleSIKICAgIFJFUVVFU1RfSUQgPSAiMDcwMTYwOTE5MTA1MV8wMDAwNCIKICAgIExBTkRTQVRfU0NFTkVfSUQgPSAiTEM4MDQ0MDM0MjAxNjI1OUxHTjAwIgogICAgRklMRV9EQVRFID0gMjAxNi0wOS0yMFQwMzoxMzowMloKICAgIFNUQVRJT05fSUQgPSAiTEdOIgogICAgUFJPQ0VTU0lOR19TT0ZUV0FSRV9WRVJTSU9OID0gIkxQR1NfMi42LjIiCiAgRU5EX0dST1VQID0gTUVUQURBVEFfRklMRV9JTkZPCiAgR1JPVVAgPSBQUk9EVUNUX01FVEFEQVRBCiAgICBEQVRBX1RZUEUgPSAiTDFUIgogICAgRUxFVkFUSU9OX1NPVVJDRSA9ICJHTFMyMDAwIgogICAgT1VUUFVUX0ZPUk1BVCA9ICJHRU9USUZGIgogICAgU1BBQ0VDUkFGVF9JRCA9ICJMQU5EU0FUXzgiCiAgICBTRU5TT1JfSUQgPSAiT0xJX1RJUlMiCiAgICBXUlNfUEFUSCA9IDQ0CiAgICBXUlNfUk9XID0gMzQKICAgIE5BRElSX09GRk5BRElSID0gIk5BRElSIgogICAgVEFSR0VUX1dSU19QQVRIID0gNDQKICAgIFRBUkdFVF9XUlNfUk9XID0gMzQKICAgIERBVEVfQUNRVUlSRUQgPSAyMDE2LTA5LTE1CiAgICBTQ0VORV9DRU5URVJfVElNRSA9ICIxODo0NjoxOC42ODY3MzgwWiIKICAgIENPUk5FUl9VTF9MQVRfUFJPRFVDVCA9IDM4LjUyODE5CiAgICBDT1JORVJfVUxfTE9OX1BST0RVQ1QgPSAtMTIzLjQwODQzCiAgICBDT1JORVJfVVJfTEFUX1BST0RVQ1QgPSAzOC41MDc2NQogICAgQ09STkVSX1VSX0xPTl9QUk9EVUNUID0gLTEyMC43NjkzMwogICAgQ09STkVSX0xMX0xBVF9QUk9EVUNUID0gMzYuNDE2MzMKICAgIENPUk5FUl9MTF9MT05fUFJPRFVDVCA9IC0xMjMuMzk3MDkKICAgIENPUk5FUl9MUl9MQVRfUFJPRFVDVCA9IDM2LjM5NzI5CiAgICBDT1JORVJfTFJfTE9OX1BST0RVQ1QgPSAtMTIwLjgzMTE3CiAgICBDT1JORVJfVUxfUFJPSkVDVElPTl9YX1BST0RVQ1QgPSA0NjQ0MDAuMDAwCiAgICBDT1JORVJfVUxfUFJPSkVDVElPTl9ZX1BST0RVQ1QgPSA0MjY0NTAwLjAwMAogICAgQ09STkVSX1VSX1BST0pFQ1RJT05fWF9QUk9EVUNUID0gNjk0NTAwLjAwMAogICAgQ09STkVSX1VSX1BST0pFQ1RJT05fWV9QUk9EVUNUID0gNDI2NDUwMC4wMDAKICAgIENPUk5FUl9MTF9QUk9KRUNUSU9OX1hfUFJPRFVDVCA9IDQ2NDQwMC4wMDAKICAgIENPUk5FUl9MTF9QUk9KRUNUSU9OX1lfUFJPRFVDVCA9IDQwMzAyMDAuMDAwCiAgICBDT1JORVJfTFJfUFJPSkVDVElPTl9YX1BST0RVQ1QgPSA2OTQ1MDAuMDAwCiAgICBDT1JORVJfTFJfUFJPSkVDVElPTl9ZX1BST0RVQ1QgPSA0MDMwMjAwLjAwMAogICAgUEFOQ0hST01BVElDX0xJTkVTID0gMTU2MjEKICAgIFBBTkNIUk9NQVRJQ19TQU1QTEVTID0gMTUzNDEKICAgIFJFRkxFQ1RJVkVfTElORVMgPSA3ODExCiAgICBSRUZMRUNUSVZFX1NBTVBMRVMgPSA3NjcxCiAgICBUSEVSTUFMX0xJTkVTID0gNzgxMQogICAgVEhFUk1BTF9TQU1QTEVTID0gNzY3MQogICAgRklMRV9OQU1FX0JBTkRfMSA9ICJMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjEuVElGIgogICAgRklMRV9OQU1FX0JBTkRfMiA9ICJMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjIuVElGIgogICAgRklMRV9OQU1FX0JBTkRfMyA9ICJMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjMuVElGIgogICAgRklMRV9OQU1FX0JBTkRfNCA9ICJMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjQuVElGIgogICAgRklMRV9OQU1FX0JBTkRfNSA9ICJMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjUuVElGIgogICAgRklMRV9OQU1FX0JBTkRfNiA9ICJMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjYuVElGIgogICAgRklMRV9OQU1FX0JBTkRfNyA9ICJMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjcuVElGIgogICAgRklMRV9OQU1FX0JBTkRfOCA9ICJMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjguVElGIgogICAgRklMRV9OQU1FX0JBTkRfOSA9ICJMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjkuVElGIgogICAgRklMRV9OQU1FX0JBTkRfMTAgPSAiTEM4MDQ0MDM0MjAxNjI1OUxHTjAwX0IxMC5USUYiCiAgICBGSUxFX05BTUVfQkFORF8xMSA9ICJMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjExLlRJRiIKICAgIEZJTEVfTkFNRV9CQU5EX1FVQUxJVFkgPSAiTEM4MDQ0MDM0MjAxNjI1OUxHTjAwX0JRQS5USUYiCiAgICBNRVRBREFUQV9GSUxFX05BTUUgPSAiTEM4MDQ0MDM0MjAxNjI1OUxHTjAwX01UTC50eHQiCiAgICBCUEZfTkFNRV9PTEkgPSAiTE84QlBGMjAxNjA5MTUxODMwNTdfMjAxNjA5MTUyMDA5NTAuMDEiCiAgICBCUEZfTkFNRV9USVJTID0gIkxUOEJQRjIwMTYwOTAyMDg0MTIyXzIwMTYwOTE3MDc0MDI3LjAyIgogICAgQ1BGX05BTUUgPSAiTDhDUEYyMDE2MDcwMV8yMDE2MDkzMC4wMiIKICAgIFJMVVRfRklMRV9OQU1FID0gIkw4UkxVVDIwMTUwMzAzXzIwNDMxMjMxdjExLmg1IgogIEVORF9HUk9VUCA9IFBST0RVQ1RfTUVUQURBVEEKICBHUk9VUCA9IElNQUdFX0FUVFJJQlVURVMKICAgIENMT1VEX0NPVkVSID0gMjkuNTYKICAgIENMT1VEX0NPVkVSX0xBTkQgPSAzLjMzCiAgICBJTUFHRV9RVUFMSVRZX09MSSA9IDkKICAgIElNQUdFX1FVQUxJVFlfVElSUyA9IDkKICAgIFRJUlNfU1NNX01PREVMID0gIkZJTkFMIgogICAgVElSU19TU01fUE9TSVRJT05fU1RBVFVTID0gIkVTVElNQVRFRCIKICAgIFJPTExfQU5HTEUgPSAtMC4wMDEKICAgIFNVTl9BWklNVVRIID0gMTQ4LjQ4MDQ5Mzk2CiAgICBTVU5fRUxFVkFUSU9OID0gNTAuOTM3NjgzOTkKICAgIEVBUlRIX1NVTl9ESVNUQU5DRSA9IDEuMDA1Mzc1MgogICAgR1JPVU5EX0NPTlRST0xfUE9JTlRTX1ZFUlNJT04gPSA0CiAgICBHUk9VTkRfQ09OVFJPTF9QT0lOVFNfTU9ERUwgPSA1NDgKICAgIEdFT01FVFJJQ19STVNFX01PREVMID0gNS44NTcKICAgIEdFT01FVFJJQ19STVNFX01PREVMX1kgPSAzLjg0MQogICAgR0VPTUVUUklDX1JNU0VfTU9ERUxfWCA9IDQuNDIyCiAgICBHUk9VTkRfQ09OVFJPTF9QT0lOVFNfVkVSSUZZID0gMjI4CiAgICBHRU9NRVRSSUNfUk1TRV9WRVJJRlkgPSAzLjM4MgogIEVORF9HUk9VUCA9IElNQUdFX0FUVFJJQlVURVMKICBHUk9VUCA9IE1JTl9NQVhfUkFESUFOQ0UKICAgIFJBRElBTkNFX01BWElNVU1fQkFORF8xID0gNzUxLjk1NzA5CiAgICBSQURJQU5DRV9NSU5JTVVNX0JBTkRfMSA9IC02Mi4wOTY4NgogICAgUkFESUFOQ0VfTUFYSU1VTV9CQU5EXzIgPSA3NzAuMDEzMTgKICAgIFJBRElBTkNFX01JTklNVU1fQkFORF8yID0gLTYzLjU4Nzk0CiAgICBSQURJQU5DRV9NQVhJTVVNX0JBTkRfMyA9IDcwOS41NjA2MQogICAgUkFESUFOQ0VfTUlOSU1VTV9CQU5EXzMgPSAtNTguNTk1NzUKICAgIFJBRElBTkNFX01BWElNVU1fQkFORF80ID0gNTk4LjM0MTQ5CiAgICBSQURJQU5DRV9NSU5JTVVNX0JBTkRfNCA9IC00OS40MTEyMwogICAgUkFESUFOQ0VfTUFYSU1VTV9CQU5EXzUgPSAzNjYuMTU1MTUKICAgIFJBRElBTkNFX01JTklNVU1fQkFORF81ID0gLTMwLjIzNzIxCiAgICBSQURJQU5DRV9NQVhJTVVNX0JBTkRfNiA9IDkxLjA1OTQ2CiAgICBSQURJQU5DRV9NSU5JTVVNX0JBTkRfNiA9IC03LjUxOTcyCiAgICBSQURJQU5DRV9NQVhJTVVNX0JBTkRfNyA9IDMwLjY5MTkxCiAgICBSQURJQU5DRV9NSU5JTVVNX0JBTkRfNyA9IC0yLjUzNDU1CiAgICBSQURJQU5DRV9NQVhJTVVNX0JBTkRfOCA9IDY3Ny4xNTc4NAogICAgUkFESUFOQ0VfTUlOSU1VTV9CQU5EXzggPSAtNTUuOTE5OTIKICAgIFJBRElBTkNFX01BWElNVU1fQkFORF85ID0gMTQzLjEwMTczCiAgICBSQURJQU5DRV9NSU5JTVVNX0JBTkRfOSA9IC0xMS44MTczOQogICAgUkFESUFOQ0VfTUFYSU1VTV9CQU5EXzEwID0gMjIuMDAxODAKICAgIFJBRElBTkNFX01JTklNVU1fQkFORF8xMCA9IDAuMTAwMzMKICAgIFJBRElBTkNFX01BWElNVU1fQkFORF8xMSA9IDIyLjAwMTgwCiAgICBSQURJQU5DRV9NSU5JTVVNX0JBTkRfMTEgPSAwLjEwMDMzCiAgRU5EX0dST1VQID0gTUlOX01BWF9SQURJQU5DRQogIEdST1VQID0gTUlOX01BWF9SRUZMRUNUQU5DRQogICAgUkVGTEVDVEFOQ0VfTUFYSU1VTV9CQU5EXzEgPSAxLjIxMDcwMAogICAgUkVGTEVDVEFOQ0VfTUlOSU1VTV9CQU5EXzEgPSAtMC4wOTk5ODAKICAgIFJFRkxFQ1RBTkNFX01BWElNVU1fQkFORF8yID0gMS4yMTA3MDAKICAgIFJFRkxFQ1RBTkNFX01JTklNVU1fQkFORF8yID0gLTAuMDk5OTgwCiAgICBSRUZMRUNUQU5DRV9NQVhJTVVNX0JBTkRfMyA9IDEuMjEwNzAwCiAgICBSRUZMRUNUQU5DRV9NSU5JTVVNX0JBTkRfMyA9IC0wLjA5OTk4MAogICAgUkVGTEVDVEFOQ0VfTUFYSU1VTV9CQU5EXzQgPSAxLjIxMDcwMAogICAgUkVGTEVDVEFOQ0VfTUlOSU1VTV9CQU5EXzQgPSAtMC4wOTk5ODAKICAgIFJFRkxFQ1RBTkNFX01BWElNVU1fQkFORF81ID0gMS4yMTA3MDAKICAgIFJFRkxFQ1RBTkNFX01JTklNVU1fQkFORF81ID0gLTAuMDk5OTgwCiAgICBSRUZMRUNUQU5DRV9NQVhJTVVNX0JBTkRfNiA9IDEuMjEwNzAwCiAgICBSRUZMRUNUQU5DRV9NSU5JTVVNX0JBTkRfNiA9IC0wLjA5OTk4MAogICAgUkVGTEVDVEFOQ0VfTUFYSU1VTV9CQU5EXzcgPSAxLjIxMDcwMAogICAgUkVGTEVDVEFOQ0VfTUlOSU1VTV9CQU5EXzcgPSAtMC4wOTk5ODAKICAgIFJFRkxFQ1RBTkNFX01BWElNVU1fQkFORF84ID0gMS4yMTA3MDAKICAgIFJFRkxFQ1RBTkNFX01JTklNVU1fQkFORF84ID0gLTAuMDk5OTgwCiAgICBSRUZMRUNUQU5DRV9NQVhJTVVNX0JBTkRfOSA9IDEuMjEwNzAwCiAgICBSRUZMRUNUQU5DRV9NSU5JTVVNX0JBTkRfOSA9IC0wLjA5OTk4MAogIEVORF9HUk9VUCA9IE1JTl9NQVhfUkVGTEVDVEFOQ0UKICBHUk9VUCA9IE1JTl9NQVhfUElYRUxfVkFMVUUKICAgIFFVQU5USVpFX0NBTF9NQVhfQkFORF8xID0gNjU1MzUKICAgIFFVQU5USVpFX0NBTF9NSU5fQkFORF8xID0gMQogICAgUVVBTlRJWkVfQ0FMX01BWF9CQU5EXzIgPSA2NTUzNQogICAgUVVBTlRJWkVfQ0FMX01JTl9CQU5EXzIgPSAxCiAgICBRVUFOVElaRV9DQUxfTUFYX0JBTkRfMyA9IDY1NTM1CiAgICBRVUFOVElaRV9DQUxfTUlOX0JBTkRfMyA9IDEKICAgIFFVQU5USVpFX0NBTF9NQVhfQkFORF80ID0gNjU1MzUKICAgIFFVQU5USVpFX0NBTF9NSU5fQkFORF80ID0gMQogICAgUVVBTlRJWkVfQ0FMX01BWF9CQU5EXzUgPSA2NTUzNQogICAgUVVBTlRJWkVfQ0FMX01JTl9CQU5EXzUgPSAxCiAgICBRVUFOVElaRV9DQUxfTUFYX0JBTkRfNiA9IDY1NTM1CiAgICBRVUFOVElaRV9DQUxfTUlOX0JBTkRfNiA9IDEKICAgIFFVQU5USVpFX0NBTF9NQVhfQkFORF83ID0gNjU1MzUKICAgIFFVQU5USVpFX0NBTF9NSU5fQkFORF83ID0gMQogICAgUVVBTlRJWkVfQ0FMX01BWF9CQU5EXzggPSA2NTUzNQogICAgUVVBTlRJWkVfQ0FMX01JTl9CQU5EXzggPSAxCiAgICBRVUFOVElaRV9DQUxfTUFYX0JBTkRfOSA9IDY1NTM1CiAgICBRVUFOVElaRV9DQUxfTUlOX0JBTkRfOSA9IDEKICAgIFFVQU5USVpFX0NBTF9NQVhfQkFORF8xMCA9IDY1NTM1CiAgICBRVUFOVElaRV9DQUxfTUlOX0JBTkRfMTAgPSAxCiAgICBRVUFOVElaRV9DQUxfTUFYX0JBTkRfMTEgPSA2NTUzNQogICAgUVVBTlRJWkVfQ0FMX01JTl9CQU5EXzExID0gMQogIEVORF9HUk9VUCA9IE1JTl9NQVhfUElYRUxfVkFMVUUKICBHUk9VUCA9IFJBRElPTUVUUklDX1JFU0NBTElORwogICAgUkFESUFOQ0VfTVVMVF9CQU5EXzEgPSAxLjI0MjJFLTAyCiAgICBSQURJQU5DRV9NVUxUX0JBTkRfMiA9IDEuMjcyMEUtMDIKICAgIFJBRElBTkNFX01VTFRfQkFORF8zID0gMS4xNzIxRS0wMgogICAgUkFESUFOQ0VfTVVMVF9CQU5EXzQgPSA5Ljg4NDJFLTAzCiAgICBSQURJQU5DRV9NVUxUX0JBTkRfNSA9IDYuMDQ4N0UtMDMKICAgIFJBRElBTkNFX01VTFRfQkFORF82ID0gMS41MDQyRS0wMwogICAgUkFESUFOQ0VfTVVMVF9CQU5EXzcgPSA1LjA3MDFFLTA0CiAgICBSQURJQU5DRV9NVUxUX0JBTkRfOCA9IDEuMTE4NkUtMDIKICAgIFJBRElBTkNFX01VTFRfQkFORF85ID0gMi4zNjQwRS0wMwogICAgUkFESUFOQ0VfTVVMVF9CQU5EXzEwID0gMy4zNDIwRS0wNAogICAgUkFESUFOQ0VfTVVMVF9CQU5EXzExID0gMy4zNDIwRS0wNAogICAgUkFESUFOQ0VfQUREX0JBTkRfMSA9IC02Mi4xMDkyOAogICAgUkFESUFOQ0VfQUREX0JBTkRfMiA9IC02My42MDA2NgogICAgUkFESUFOQ0VfQUREX0JBTkRfMyA9IC01OC42MDc0NwogICAgUkFESUFOQ0VfQUREX0JBTkRfNCA9IC00OS40MjExMgogICAgUkFESUFOQ0VfQUREX0JBTkRfNSA9IC0zMC4yNDMyNgogICAgUkFESUFOQ0VfQUREX0JBTkRfNiA9IC03LjUyMTIyCiAgICBSQURJQU5DRV9BRERfQkFORF83ID0gLTIuNTM1MDUKICAgIFJBRElBTkNFX0FERF9CQU5EXzggPSAtNTUuOTMxMTAKICAgIFJBRElBTkNFX0FERF9CQU5EXzkgPSAtMTEuODE5NzUKICAgIFJBRElBTkNFX0FERF9CQU5EXzEwID0gMC4xMDAwMAogICAgUkFESUFOQ0VfQUREX0JBTkRfMTEgPSAwLjEwMDAwCiAgICBSRUZMRUNUQU5DRV9NVUxUX0JBTkRfMSA9IDIuMDAwMEUtMDUKICAgIFJFRkxFQ1RBTkNFX01VTFRfQkFORF8yID0gMi4wMDAwRS0wNQogICAgUkVGTEVDVEFOQ0VfTVVMVF9CQU5EXzMgPSAyLjAwMDBFLTA1CiAgICBSRUZMRUNUQU5DRV9NVUxUX0JBTkRfNCA9IDIuMDAwMEUtMDUKICAgIFJFRkxFQ1RBTkNFX01VTFRfQkFORF81ID0gMi4wMDAwRS0wNQogICAgUkVGTEVDVEFOQ0VfTVVMVF9CQU5EXzYgPSAyLjAwMDBFLTA1CiAgICBSRUZMRUNUQU5DRV9NVUxUX0JBTkRfNyA9IDIuMDAwMEUtMDUKICAgIFJFRkxFQ1RBTkNFX01VTFRfQkFORF84ID0gMi4wMDAwRS0wNQogICAgUkVGTEVDVEFOQ0VfTVVMVF9CQU5EXzkgPSAyLjAwMDBFLTA1CiAgICBSRUZMRUNUQU5DRV9BRERfQkFORF8xID0gLTAuMTAwMDAwCiAgICBSRUZMRUNUQU5DRV9BRERfQkFORF8yID0gLTAuMTAwMDAwCiAgICBSRUZMRUNUQU5DRV9BRERfQkFORF8zID0gLTAuMTAwMDAwCiAgICBSRUZMRUNUQU5DRV9BRERfQkFORF80ID0gLTAuMTAwMDAwCiAgICBSRUZMRUNUQU5DRV9BRERfQkFORF81ID0gLTAuMTAwMDAwCiAgICBSRUZMRUNUQU5DRV9BRERfQkFORF82ID0gLTAuMTAwMDAwCiAgICBSRUZMRUNUQU5DRV9BRERfQkFORF83ID0gLTAuMTAwMDAwCiAgICBSRUZMRUNUQU5DRV9BRERfQkFORF84ID0gLTAuMTAwMDAwCiAgICBSRUZMRUNUQU5DRV9BRERfQkFORF85ID0gLTAuMTAwMDAwCiAgRU5EX0dST1VQID0gUkFESU9NRVRSSUNfUkVTQ0FMSU5HCiAgR1JPVVAgPSBUSVJTX1RIRVJNQUxfQ09OU1RBTlRTCiAgICBLMV9DT05TVEFOVF9CQU5EXzEwID0gNzc0Ljg4NTMKICAgIEsxX0NPTlNUQU5UX0JBTkRfMTEgPSA0ODAuODg4MwogICAgSzJfQ09OU1RBTlRfQkFORF8xMCA9IDEzMjEuMDc4OQogICAgSzJfQ09OU1RBTlRfQkFORF8xMSA9IDEyMDEuMTQ0MgogIEVORF9HUk9VUCA9IFRJUlNfVEhFUk1BTF9DT05TVEFOVFMKICBHUk9VUCA9IFBST0pFQ1RJT05fUEFSQU1FVEVSUwogICAgTUFQX1BST0pFQ1RJT04gPSAiVVRNIgogICAgREFUVU0gPSAiV0dTODQiCiAgICBFTExJUFNPSUQgPSAiV0dTODQiCiAgICBVVE1fWk9ORSA9IDEwCiAgICBHUklEX0NFTExfU0laRV9QQU5DSFJPTUFUSUMgPSAxNS4wMAogICAgR1JJRF9DRUxMX1NJWkVfUkVGTEVDVElWRSA9IDMwLjAwCiAgICBHUklEX0NFTExfU0laRV9USEVSTUFMID0gMzAuMDAKICAgIE9SSUVOVEFUSU9OID0gIk5PUlRIX1VQIgogICAgUkVTQU1QTElOR19PUFRJT04gPSAiQ1VCSUNfQ09OVk9MVVRJT04iCiAgRU5EX0dST1VQID0gUFJPSkVDVElPTl9QQVJBTUVURVJTCkVORF9HUk9VUCA9IEwxX01FVEFEQVRBX0ZJTEUKRU5ECg==" } }, { "ID": "914cb60452456134", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/gcp-public-data-landsat/o?alt=json\u0026delimiter=\u0026pageToken=\u0026prefix=LC08%2FPRE%2F044%2F034%2FLC80440342016259LGN00%2F\u0026prettyPrint=false\u0026projection=full\u0026versions=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "12632" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:26 GMT" ], "Expires": [ "Thu, 02 May 2019 22:25:26 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpLE4EijIrGqoHRLrCqmprZtxBU2JtHLLsZ-nIakblnuZX8s6FZA1SEaczyybdjB32loN1-gVCf83PFM4x06S24ATKp9-xRgQ9QNC9fwVH_ec4e9JQ" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ2NwLXB1YmxpYy1kYXRhLWxhbmRzYXQvTEMwOC9QUkUvMDQ0LzAzNC9MQzgwNDQwMzQyMDE2MjU5TEdOMDAvTEM4MDQ0MDM0MjAxNjI1OUxHTjAwX0IxLlRJRi8xNDc1NTk5MTQ0NTc5MDAwIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ2NwLXB1YmxpYy1kYXRhLWxhbmRzYXQvby9MQzA4JTJGUFJFJTJGMDQ0JTJGMDM0JTJGTEM4MDQ0MDM0MjAxNjI1OUxHTjAwJTJGTEM4MDQ0MDM0MjAxNjI1OUxHTjAwX0IxLlRJRiIsIm5hbWUiOiJMQzA4L1BSRS8wNDQvMDM0L0xDODA0NDAzNDIwMTYyNTlMR04wMC9MQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjEuVElGIiwiYnVja2V0IjoiZ2NwLXB1YmxpYy1kYXRhLWxhbmRzYXQiLCJnZW5lcmF0aW9uIjoiMTQ3NTU5OTE0NDU3OTAwMCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIiwidGltZUNyZWF0ZWQiOiIyMDE2LTEwLTA0VDE2OjM5OjA0LjU0NVoiLCJ1cGRhdGVkIjoiMjAxNi0xMC0wNFQxNjozOTowNC41NDVaIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTYtMTAtMDRUMTY6Mzk6MDQuNTQ1WiIsInNpemUiOiI3NDcyMTczNiIsIm1kNUhhc2giOiI4MzVMNkI1ZnJCMHpDQjZzMjJyMlN3PT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ2NwLXB1YmxpYy1kYXRhLWxhbmRzYXQvby9MQzA4JTJGUFJFJTJGMDQ0JTJGMDM0JTJGTEM4MDQ0MDM0MjAxNjI1OUxHTjAwJTJGTEM4MDQ0MDM0MjAxNjI1OUxHTjAwX0IxLlRJRj9nZW5lcmF0aW9uPTE0NzU1OTkxNDQ1NzkwMDAmYWx0PW1lZGlhIiwiY3JjMzJjIjoiOTM0QnJnPT0iLCJldGFnIjoiQ0xqZjM1Ykx3YzhDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnY3AtcHVibGljLWRhdGEtbGFuZHNhdC9MQzA4L1BSRS8wNDQvMDM0L0xDODA0NDAzNDIwMTYyNTlMR04wMC9MQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjEwLlRJRi8xNDc1NTk5MzEwMDQyMDAwIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ2NwLXB1YmxpYy1kYXRhLWxhbmRzYXQvby9MQzA4JTJGUFJFJTJGMDQ0JTJGMDM0JTJGTEM4MDQ0MDM0MjAxNjI1OUxHTjAwJTJGTEM4MDQ0MDM0MjAxNjI1OUxHTjAwX0IxMC5USUYiLCJuYW1lIjoiTEMwOC9QUkUvMDQ0LzAzNC9MQzgwNDQwMzQyMDE2MjU5TEdOMDAvTEM4MDQ0MDM0MjAxNjI1OUxHTjAwX0IxMC5USUYiLCJidWNrZXQiOiJnY3AtcHVibGljLWRhdGEtbGFuZHNhdCIsImdlbmVyYXRpb24iOiIxNDc1NTk5MzEwMDQyMDAwIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTYtMTAtMDRUMTY6NDE6NTAuMDAyWiIsInVwZGF0ZWQiOiIyMDE2LTEwLTA0VDE2OjQxOjUwLjAwMloiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxNi0xMC0wNFQxNjo0MTo1MC4wMDJaIiwic2l6ZSI6IjU4NjgxMjI4IiwibWQ1SGFzaCI6IkJXNjIzeEhnMTVJaFYyNG1ickwrQXc9PSIsIm1lZGlhTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nY3AtcHVibGljLWRhdGEtbGFuZHNhdC9vL0xDMDglMkZQUkUlMkYwNDQlMkYwMzQlMkZMQzgwNDQwMzQyMDE2MjU5TEdOMDAlMkZMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjEwLlRJRj9nZW5lcmF0aW9uPTE0NzU1OTkzMTAwNDIwMDAmYWx0PW1lZGlhIiwiY3JjMzJjIjoieHpWMmZnPT0iLCJldGFnIjoiQ0pEbjB1WEx3YzhDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnY3AtcHVibGljLWRhdGEtbGFuZHNhdC9MQzA4L1BSRS8wNDQvMDM0L0xDODA0NDAzNDIwMTYyNTlMR04wMC9MQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjExLlRJRi8xNDc1NTk5MzE5MTg4MDAwIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ2NwLXB1YmxpYy1kYXRhLWxhbmRzYXQvby9MQzA4JTJGUFJFJTJGMDQ0JTJGMDM0JTJGTEM4MDQ0MDM0MjAxNjI1OUxHTjAwJTJGTEM4MDQ0MDM0MjAxNjI1OUxHTjAwX0IxMS5USUYiLCJuYW1lIjoiTEMwOC9QUkUvMDQ0LzAzNC9MQzgwNDQwMzQyMDE2MjU5TEdOMDAvTEM4MDQ0MDM0MjAxNjI1OUxHTjAwX0IxMS5USUYiLCJidWNrZXQiOiJnY3AtcHVibGljLWRhdGEtbGFuZHNhdCIsImdlbmVyYXRpb24iOiIxNDc1NTk5MzE5MTg4MDAwIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTYtMTAtMDRUMTY6NDE6NTkuMTQ5WiIsInVwZGF0ZWQiOiIyMDE2LTEwLTA0VDE2OjQxOjU5LjE0OVoiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxNi0xMC0wNFQxNjo0MTo1OS4xNDlaIiwic2l6ZSI6IjU2Nzk2NDM5IiwibWQ1SGFzaCI6IkZPeGl5eEpYcUFmbFJUOGxGblNkT2c9PSIsIm1lZGlhTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nY3AtcHVibGljLWRhdGEtbGFuZHNhdC9vL0xDMDglMkZQUkUlMkYwNDQlMkYwMzQlMkZMQzgwNDQwMzQyMDE2MjU5TEdOMDAlMkZMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjExLlRJRj9nZW5lcmF0aW9uPTE0NzU1OTkzMTkxODgwMDAmYWx0PW1lZGlhIiwiY3JjMzJjIjoicC9IRlZ3PT0iLCJldGFnIjoiQ0tDRWdlckx3YzhDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnY3AtcHVibGljLWRhdGEtbGFuZHNhdC9MQzA4L1BSRS8wNDQvMDM0L0xDODA0NDAzNDIwMTYyNTlMR04wMC9MQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjIuVElGLzE0NzU1OTkxNjEyMjQwMDAiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nY3AtcHVibGljLWRhdGEtbGFuZHNhdC9vL0xDMDglMkZQUkUlMkYwNDQlMkYwMzQlMkZMQzgwNDQwMzQyMDE2MjU5TEdOMDAlMkZMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjIuVElGIiwibmFtZSI6IkxDMDgvUFJFLzA0NC8wMzQvTEM4MDQ0MDM0MjAxNjI1OUxHTjAwL0xDODA0NDAzNDIwMTYyNTlMR04wMF9CMi5USUYiLCJidWNrZXQiOiJnY3AtcHVibGljLWRhdGEtbGFuZHNhdCIsImdlbmVyYXRpb24iOiIxNDc1NTk5MTYxMjI0MDAwIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTYtMTAtMDRUMTY6Mzk6MjEuMTYwWiIsInVwZGF0ZWQiOiIyMDE2LTEwLTA0VDE2OjM5OjIxLjE2MFoiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxNi0xMC0wNFQxNjozOToyMS4xNjBaIiwic2l6ZSI6Ijc3MTQ5NzcxIiwibWQ1SGFzaCI6Ik1QMjJ6ak9vMk5zMGlZNE1UUEpSd0E9PSIsIm1lZGlhTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nY3AtcHVibGljLWRhdGEtbGFuZHNhdC9vL0xDMDglMkZQUkUlMkYwNDQlMkYwMzQlMkZMQzgwNDQwMzQyMDE2MjU5TEdOMDAlMkZMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjIuVElGP2dlbmVyYXRpb249MTQ3NTU5OTE2MTIyNDAwMCZhbHQ9bWVkaWEiLCJjcmMzMmMiOiJySThZUmc9PSIsImV0YWciOiJDTURXMTU3THdjOENFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdjcC1wdWJsaWMtZGF0YS1sYW5kc2F0L0xDMDgvUFJFLzA0NC8wMzQvTEM4MDQ0MDM0MjAxNjI1OUxHTjAwL0xDODA0NDAzNDIwMTYyNTlMR04wMF9CMy5USUYvMTQ3NTU5OTE3ODQzNTAwMCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2djcC1wdWJsaWMtZGF0YS1sYW5kc2F0L28vTEMwOCUyRlBSRSUyRjA0NCUyRjAzNCUyRkxDODA0NDAzNDIwMTYyNTlMR04wMCUyRkxDODA0NDAzNDIwMTYyNTlMR04wMF9CMy5USUYiLCJuYW1lIjoiTEMwOC9QUkUvMDQ0LzAzNC9MQzgwNDQwMzQyMDE2MjU5TEdOMDAvTEM4MDQ0MDM0MjAxNjI1OUxHTjAwX0IzLlRJRiIsImJ1Y2tldCI6ImdjcC1wdWJsaWMtZGF0YS1sYW5kc2F0IiwiZ2VuZXJhdGlvbiI6IjE0NzU1OTkxNzg0MzUwMDAiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6ImFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSIsInRpbWVDcmVhdGVkIjoiMjAxNi0xMC0wNFQxNjozOTozOC4zNzZaIiwidXBkYXRlZCI6IjIwMTYtMTAtMDRUMTY6Mzk6MzguMzc2WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE2LTEwLTA0VDE2OjM5OjM4LjM3NloiLCJzaXplIjoiODAyOTM2ODciLCJtZDVIYXNoIjoidlFNaUdlRHVCZzZjcjNYc2ZJRWpvUT09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2djcC1wdWJsaWMtZGF0YS1sYW5kc2F0L28vTEMwOCUyRlBSRSUyRjA0NCUyRjAzNCUyRkxDODA0NDAzNDIwMTYyNTlMR04wMCUyRkxDODA0NDAzNDIwMTYyNTlMR04wMF9CMy5USUY/Z2VuZXJhdGlvbj0xNDc1NTk5MTc4NDM1MDAwJmFsdD1tZWRpYSIsImNyYzMyYyI6InVaQnJuQT09IiwiZXRhZyI6IkNMaVQ4cWJMd2M4Q0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ2NwLXB1YmxpYy1kYXRhLWxhbmRzYXQvTEMwOC9QUkUvMDQ0LzAzNC9MQzgwNDQwMzQyMDE2MjU5TEdOMDAvTEM4MDQ0MDM0MjAxNjI1OUxHTjAwX0I0LlRJRi8xNDc1NTk5MTk0MjY4MDAwIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ2NwLXB1YmxpYy1kYXRhLWxhbmRzYXQvby9MQzA4JTJGUFJFJTJGMDQ0JTJGMDM0JTJGTEM4MDQ0MDM0MjAxNjI1OUxHTjAwJTJGTEM4MDQ0MDM0MjAxNjI1OUxHTjAwX0I0LlRJRiIsIm5hbWUiOiJMQzA4L1BSRS8wNDQvMDM0L0xDODA0NDAzNDIwMTYyNTlMR04wMC9MQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjQuVElGIiwiYnVja2V0IjoiZ2NwLXB1YmxpYy1kYXRhLWxhbmRzYXQiLCJnZW5lcmF0aW9uIjoiMTQ3NTU5OTE5NDI2ODAwMCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIiwidGltZUNyZWF0ZWQiOiIyMDE2LTEwLTA0VDE2OjM5OjU0LjIxMVoiLCJ1cGRhdGVkIjoiMjAxNi0xMC0wNFQxNjozOTo1NC4yMTFaIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTYtMTAtMDRUMTY6Mzk6NTQuMjExWiIsInNpemUiOiI4NDQ5NDM3NSIsIm1kNUhhc2giOiJGV2VWQTAxWk8wK21BK0VSRmN6dWhBPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ2NwLXB1YmxpYy1kYXRhLWxhbmRzYXQvby9MQzA4JTJGUFJFJTJGMDQ0JTJGMDM0JTJGTEM4MDQ0MDM0MjAxNjI1OUxHTjAwJTJGTEM4MDQ0MDM0MjAxNjI1OUxHTjAwX0I0LlRJRj9nZW5lcmF0aW9uPTE0NzU1OTkxOTQyNjgwMDAmYWx0PW1lZGlhIiwiY3JjMzJjIjoiV2VzNW9RPT0iLCJldGFnIjoiQ09EQ3VLN0x3YzhDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnY3AtcHVibGljLWRhdGEtbGFuZHNhdC9MQzA4L1BSRS8wNDQvMDM0L0xDODA0NDAzNDIwMTYyNTlMR04wMC9MQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjUuVElGLzE0NzU1OTkyMDI5NzkwMDAiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nY3AtcHVibGljLWRhdGEtbGFuZHNhdC9vL0xDMDglMkZQUkUlMkYwNDQlMkYwMzQlMkZMQzgwNDQwMzQyMDE2MjU5TEdOMDAlMkZMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjUuVElGIiwibmFtZSI6IkxDMDgvUFJFLzA0NC8wMzQvTEM4MDQ0MDM0MjAxNjI1OUxHTjAwL0xDODA0NDAzNDIwMTYyNTlMR04wMF9CNS5USUYiLCJidWNrZXQiOiJnY3AtcHVibGljLWRhdGEtbGFuZHNhdCIsImdlbmVyYXRpb24iOiIxNDc1NTk5MjAyOTc5MDAwIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTYtMTAtMDRUMTY6NDA6MDIuOTM3WiIsInVwZGF0ZWQiOiIyMDE2LTEwLTA0VDE2OjQwOjAyLjkzN1oiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxNi0xMC0wNFQxNjo0MDowMi45MzdaIiwic2l6ZSI6Ijg5MzE4NDY3IiwibWQ1SGFzaCI6InA0b3lLSEFHbzVLeTNLZzFUSzFaUXc9PSIsIm1lZGlhTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nY3AtcHVibGljLWRhdGEtbGFuZHNhdC9vL0xDMDglMkZQUkUlMkYwNDQlMkYwMzQlMkZMQzgwNDQwMzQyMDE2MjU5TEdOMDAlMkZMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjUuVElGP2dlbmVyYXRpb249MTQ3NTU5OTIwMjk3OTAwMCZhbHQ9bWVkaWEiLCJjcmMzMmMiOiJwVFl1dXc9PSIsImV0YWciOiJDTGlaekxMTHdjOENFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdjcC1wdWJsaWMtZGF0YS1sYW5kc2F0L0xDMDgvUFJFLzA0NC8wMzQvTEM4MDQ0MDM0MjAxNjI1OUxHTjAwL0xDODA0NDAzNDIwMTYyNTlMR04wMF9CNi5USUYvMTQ3NTU5OTIzMzQ4MTAwMCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2djcC1wdWJsaWMtZGF0YS1sYW5kc2F0L28vTEMwOCUyRlBSRSUyRjA0NCUyRjAzNCUyRkxDODA0NDAzNDIwMTYyNTlMR04wMCUyRkxDODA0NDAzNDIwMTYyNTlMR04wMF9CNi5USUYiLCJuYW1lIjoiTEMwOC9QUkUvMDQ0LzAzNC9MQzgwNDQwMzQyMDE2MjU5TEdOMDAvTEM4MDQ0MDM0MjAxNjI1OUxHTjAwX0I2LlRJRiIsImJ1Y2tldCI6ImdjcC1wdWJsaWMtZGF0YS1sYW5kc2F0IiwiZ2VuZXJhdGlvbiI6IjE0NzU1OTkyMzM0ODEwMDAiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6ImFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSIsInRpbWVDcmVhdGVkIjoiMjAxNi0xMC0wNFQxNjo0MDozMy4zNDlaIiwidXBkYXRlZCI6IjIwMTYtMTAtMDRUMTY6NDA6MzMuMzQ5WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE2LTEwLTA0VDE2OjQwOjMzLjM0OVoiLCJzaXplIjoiODk0NjU3NjciLCJtZDVIYXNoIjoiMlo3MkdVT0t0bGd6VDlWUlNHWVhqQT09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2djcC1wdWJsaWMtZGF0YS1sYW5kc2F0L28vTEMwOCUyRlBSRSUyRjA0NCUyRjAzNCUyRkxDODA0NDAzNDIwMTYyNTlMR04wMCUyRkxDODA0NDAzNDIwMTYyNTlMR04wMF9CNi5USUY/Z2VuZXJhdGlvbj0xNDc1NTk5MjMzNDgxMDAwJmFsdD1tZWRpYSIsImNyYzMyYyI6IklOWEhiUT09IiwiZXRhZyI6IkNLanlrY0hMd2M4Q0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ2NwLXB1YmxpYy1kYXRhLWxhbmRzYXQvTEMwOC9QUkUvMDQ0LzAzNC9MQzgwNDQwMzQyMDE2MjU5TEdOMDAvTEM4MDQ0MDM0MjAxNjI1OUxHTjAwX0I3LlRJRi8xNDc1NTk5MjQxMDU1MDAwIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ2NwLXB1YmxpYy1kYXRhLWxhbmRzYXQvby9MQzA4JTJGUFJFJTJGMDQ0JTJGMDM0JTJGTEM4MDQ0MDM0MjAxNjI1OUxHTjAwJTJGTEM4MDQ0MDM0MjAxNjI1OUxHTjAwX0I3LlRJRiIsIm5hbWUiOiJMQzA4L1BSRS8wNDQvMDM0L0xDODA0NDAzNDIwMTYyNTlMR04wMC9MQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjcuVElGIiwiYnVja2V0IjoiZ2NwLXB1YmxpYy1kYXRhLWxhbmRzYXQiLCJnZW5lcmF0aW9uIjoiMTQ3NTU5OTI0MTA1NTAwMCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIiwidGltZUNyZWF0ZWQiOiIyMDE2LTEwLTA0VDE2OjQwOjQxLjAyMVoiLCJ1cGRhdGVkIjoiMjAxNi0xMC0wNFQxNjo0MDo0MS4wMjFaIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTYtMTAtMDRUMTY6NDA6NDEuMDIxWiIsInNpemUiOiI4NjQ2MjYxNCIsIm1kNUhhc2giOiI4Z1BOUTdRWm9GMkNOWlo5RW1ybG9nPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ2NwLXB1YmxpYy1kYXRhLWxhbmRzYXQvby9MQzA4JTJGUFJFJTJGMDQ0JTJGMDM0JTJGTEM4MDQ0MDM0MjAxNjI1OUxHTjAwJTJGTEM4MDQ0MDM0MjAxNjI1OUxHTjAwX0I3LlRJRj9nZW5lcmF0aW9uPTE0NzU1OTkyNDEwNTUwMDAmYWx0PW1lZGlhIiwiY3JjMzJjIjoidXdDRCtBPT0iLCJldGFnIjoiQ0ppVzRNVEx3YzhDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnY3AtcHVibGljLWRhdGEtbGFuZHNhdC9MQzA4L1BSRS8wNDQvMDM0L0xDODA0NDAzNDIwMTYyNTlMR04wMC9MQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjguVElGLzE0NzU1OTkyODEzMzgwMDAiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nY3AtcHVibGljLWRhdGEtbGFuZHNhdC9vL0xDMDglMkZQUkUlMkYwNDQlMkYwMzQlMkZMQzgwNDQwMzQyMDE2MjU5TEdOMDAlMkZMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjguVElGIiwibmFtZSI6IkxDMDgvUFJFLzA0NC8wMzQvTEM4MDQ0MDM0MjAxNjI1OUxHTjAwL0xDODA0NDAzNDIwMTYyNTlMR04wMF9COC5USUYiLCJidWNrZXQiOiJnY3AtcHVibGljLWRhdGEtbGFuZHNhdCIsImdlbmVyYXRpb24iOiIxNDc1NTk5MjgxMzM4MDAwIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTYtMTAtMDRUMTY6NDE6MjEuMzAwWiIsInVwZGF0ZWQiOiIyMDE2LTEwLTA0VDE2OjQxOjIxLjMwMFoiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxNi0xMC0wNFQxNjo0MToyMS4zMDBaIiwic2l6ZSI6IjMxODg4Nzc3NCIsIm1kNUhhc2giOiJ5Nzk1THJVekJ3azJ0TDZQTTAxY0VBPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ2NwLXB1YmxpYy1kYXRhLWxhbmRzYXQvby9MQzA4JTJGUFJFJTJGMDQ0JTJGMDM0JTJGTEM4MDQ0MDM0MjAxNjI1OUxHTjAwJTJGTEM4MDQ0MDM0MjAxNjI1OUxHTjAwX0I4LlRJRj9nZW5lcmF0aW9uPTE0NzU1OTkyODEzMzgwMDAmYWx0PW1lZGlhIiwiY3JjMzJjIjoiWjMrWmhRPT0iLCJldGFnIjoiQ0pEdCt0Zkx3YzhDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnY3AtcHVibGljLWRhdGEtbGFuZHNhdC9MQzA4L1BSRS8wNDQvMDM0L0xDODA0NDAzNDIwMTYyNTlMR04wMC9MQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjkuVElGLzE0NzU1OTkyOTE0MjUwMDAiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nY3AtcHVibGljLWRhdGEtbGFuZHNhdC9vL0xDMDglMkZQUkUlMkYwNDQlMkYwMzQlMkZMQzgwNDQwMzQyMDE2MjU5TEdOMDAlMkZMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjkuVElGIiwibmFtZSI6IkxDMDgvUFJFLzA0NC8wMzQvTEM4MDQ0MDM0MjAxNjI1OUxHTjAwL0xDODA0NDAzNDIwMTYyNTlMR04wMF9COS5USUYiLCJidWNrZXQiOiJnY3AtcHVibGljLWRhdGEtbGFuZHNhdCIsImdlbmVyYXRpb24iOiIxNDc1NTk5MjkxNDI1MDAwIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTYtMTAtMDRUMTY6NDE6MzEuMzYxWiIsInVwZGF0ZWQiOiIyMDE2LTEwLTA0VDE2OjQxOjMxLjM2MVoiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxNi0xMC0wNFQxNjo0MTozMS4zNjFaIiwic2l6ZSI6IjQ0MzA4MjA1IiwibWQ1SGFzaCI6IjVCNDFFMkRCYlk1MnBZUFVHVmg5NWc9PSIsIm1lZGlhTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nY3AtcHVibGljLWRhdGEtbGFuZHNhdC9vL0xDMDglMkZQUkUlMkYwNDQlMkYwMzQlMkZMQzgwNDQwMzQyMDE2MjU5TEdOMDAlMkZMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjkuVElGP2dlbmVyYXRpb249MTQ3NTU5OTI5MTQyNTAwMCZhbHQ9bWVkaWEiLCJjcmMzMmMiOiJhME9EUXc9PSIsImV0YWciOiJDT2pCNHR6THdjOENFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdjcC1wdWJsaWMtZGF0YS1sYW5kc2F0L0xDMDgvUFJFLzA0NC8wMzQvTEM4MDQ0MDM0MjAxNjI1OUxHTjAwL0xDODA0NDAzNDIwMTYyNTlMR04wMF9CUUEuVElGLzE0NzU1OTkzMjcyMjIwMDAiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nY3AtcHVibGljLWRhdGEtbGFuZHNhdC9vL0xDMDglMkZQUkUlMkYwNDQlMkYwMzQlMkZMQzgwNDQwMzQyMDE2MjU5TEdOMDAlMkZMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQlFBLlRJRiIsIm5hbWUiOiJMQzA4L1BSRS8wNDQvMDM0L0xDODA0NDAzNDIwMTYyNTlMR04wMC9MQzgwNDQwMzQyMDE2MjU5TEdOMDBfQlFBLlRJRiIsImJ1Y2tldCI6ImdjcC1wdWJsaWMtZGF0YS1sYW5kc2F0IiwiZ2VuZXJhdGlvbiI6IjE0NzU1OTkzMjcyMjIwMDAiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6ImFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSIsInRpbWVDcmVhdGVkIjoiMjAxNi0xMC0wNFQxNjo0MjowNy4xNTlaIiwidXBkYXRlZCI6IjIwMTYtMTAtMDRUMTY6NDI6MDcuMTU5WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE2LTEwLTA0VDE2OjQyOjA3LjE1OVoiLCJzaXplIjoiMzM1NDcxOSIsIm1kNUhhc2giOiJ6cWlndmw1RW52bWkvR0xjOHlINTFBPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ2NwLXB1YmxpYy1kYXRhLWxhbmRzYXQvby9MQzA4JTJGUFJFJTJGMDQ0JTJGMDM0JTJGTEM4MDQ0MDM0MjAxNjI1OUxHTjAwJTJGTEM4MDQ0MDM0MjAxNjI1OUxHTjAwX0JRQS5USUY/Z2VuZXJhdGlvbj0xNDc1NTk5MzI3MjIyMDAwJmFsdD1tZWRpYSIsImNyYzMyYyI6IldPQmdLQT09IiwiZXRhZyI6IkNQQ3g2KzNMd2M4Q0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ2NwLXB1YmxpYy1kYXRhLWxhbmRzYXQvTEMwOC9QUkUvMDQ0LzAzNC9MQzgwNDQwMzQyMDE2MjU5TEdOMDAvTEM4MDQ0MDM0MjAxNjI1OUxHTjAwX01UTC50eHQvMTQ3NTU5OTMyNzY2MjAwMCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2djcC1wdWJsaWMtZGF0YS1sYW5kc2F0L28vTEMwOCUyRlBSRSUyRjA0NCUyRjAzNCUyRkxDODA0NDAzNDIwMTYyNTlMR04wMCUyRkxDODA0NDAzNDIwMTYyNTlMR04wMF9NVEwudHh0IiwibmFtZSI6IkxDMDgvUFJFLzA0NC8wMzQvTEM4MDQ0MDM0MjAxNjI1OUxHTjAwL0xDODA0NDAzNDIwMTYyNTlMR04wMF9NVEwudHh0IiwiYnVja2V0IjoiZ2NwLXB1YmxpYy1kYXRhLWxhbmRzYXQiLCJnZW5lcmF0aW9uIjoiMTQ3NTU5OTMyNzY2MjAwMCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIiwidGltZUNyZWF0ZWQiOiIyMDE2LTEwLTA0VDE2OjQyOjA3LjYxOFoiLCJ1cGRhdGVkIjoiMjAxNi0xMC0wNFQxNjo0MjowNy42MThaIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTYtMTAtMDRUMTY6NDI6MDcuNjE4WiIsInNpemUiOiI3OTAzIiwibWQ1SGFzaCI6ImVsL1VkRHZXUjBoZmlFbHZyYkJjVVE9PSIsIm1lZGlhTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nY3AtcHVibGljLWRhdGEtbGFuZHNhdC9vL0xDMDglMkZQUkUlMkYwNDQlMkYwMzQlMkZMQzgwNDQwMzQyMDE2MjU5TEdOMDAlMkZMQzgwNDQwMzQyMDE2MjU5TEdOMDBfTVRMLnR4dD9nZW5lcmF0aW9uPTE0NzU1OTkzMjc2NjIwMDAmYWx0PW1lZGlhIiwiY3JjMzJjIjoiUFdCdDhnPT0iLCJldGFnIjoiQ0xDZmh1N0x3YzhDRUFFPSJ9XX0=" } }, { "ID": "3f3f45cd2b718e17", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/go-integration-test-20190502-80633403432013-0001/noauth", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 403, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "247" ], "Content-Type": [ "application/xml; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:26 GMT" ], "Expires": [ "Thu, 02 May 2019 22:25:26 GMT" ], "Server": [ "UploadServer" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UqsZlmkTyf2_fqITeaIiM8s2MLUvz5qFiP_rzA4Mf6Q9LMxsiQeP-GBRwHON_XvnG2qef3XL1EzgTLA_GxtLKZRjdzOBndJPf9XbJa9KjJCIPlducQ" ] }, "Body": "PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48RXJyb3I+PENvZGU+QWNjZXNzRGVuaWVkPC9Db2RlPjxNZXNzYWdlPkFjY2VzcyBkZW5pZWQuPC9NZXNzYWdlPjxEZXRhaWxzPkFub255bW91cyBjYWxsZXIgZG9lcyBub3QgaGF2ZSBzdG9yYWdlLm9iamVjdHMuZ2V0IGFjY2VzcyB0byBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvbm9hdXRoLjwvRGV0YWlscz48L0Vycm9yPg==" } }, { "ID": "110cdd2daefc6162", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW4iLCJuYW1lIjoibm9hdXRoIn0K", "Yg==" ] }, "Response": { "StatusCode": 401, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Content-Length": [ "30405" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:26 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "Www-Authenticate": [ "Bearer realm=\"https://accounts.google.com/\"" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UrGgfg36ZmqdKbc0NqBivwXULVnF2NuBAD31rJqzC5Rj9xgHFbRnwxJCbdxCuUdlAhGW_-H88mBadNGmqch0fmAyAd80HPANBkUmIgkolsL4HK7XAU" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6InJlcXVpcmVkIiwibWVzc2FnZSI6IkFub255bW91cyBjYWxsZXIgZG9lcyBub3QgaGF2ZSBzdG9yYWdlLm9iamVjdHMuY3JlYXRlIGFjY2VzcyB0byBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvbm9hdXRoLiIsImxvY2F0aW9uVHlwZSI6ImhlYWRlciIsImxvY2F0aW9uIjoiQXV0aG9yaXphdGlvbiIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpBQ0NFU1NfREVOSUVEOiBBbm9ueW1vdXMgY2FsbGVyIGRvZXMgbm90IGhhdmUgc3RvcmFnZS5vYmplY3RzLmNyZWF0ZSBhY2Nlc3MgdG8gZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL25vYXV0aC5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuSW5zZXJ0T2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRPYmplY3QuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5JbnNlcnRPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEluc2VydE9iamVjdC5qYXZhOjQ0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLmluc2VydChPYmplY3RzRGVsZWdhdG9yLmphdmE6OTUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEFub255bW91cyBjYWxsZXIgZG9lcyBub3QgaGF2ZSBzdG9yYWdlLm9iamVjdHMuY3JlYXRlIGFjY2VzcyB0byBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvbm9hdXRoLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cbmNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLkZhdWx0OiBJbW11dGFibGVFcnJvckRlZmluaXRpb257YmFzZT1MT0dJTl9SRVFVSVJFRCwgY2F0ZWdvcnk9VVNFUl9FUlJPUiwgY2F1c2U9Y29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPUxPR0lOX1JFUVVJUkVELCBjYXRlZ29yeT1VU0VSX0VSUk9SLCBjYXVzZT1udWxsLCBkZWJ1Z0luZm89Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OkFDQ0VTU19ERU5JRUQ6IEFub255bW91cyBjYWxsZXIgZG9lcyBub3QgaGF2ZSBzdG9yYWdlLm9iamVjdHMuY3JlYXRlIGFjY2VzcyB0byBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvbm9hdXRoLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5JbnNlcnRPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEluc2VydE9iamVjdC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkluc2VydE9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoSW5zZXJ0T2JqZWN0LmphdmE6NDQpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLk9iamVjdHNEZWxlZ2F0b3IuaW5zZXJ0KE9iamVjdHNEZWxlZ2F0b3IuamF2YTo5NSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogQW5vbnltb3VzIGNhbGxlciBkb2VzIG5vdCBoYXZlIHN0b3JhZ2Uub2JqZWN0cy5jcmVhdGUgYWNjZXNzIHRvIGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9ub2F1dGguXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZG9tYWluPWdsb2JhbCwgZXh0ZW5kZWRIZWxwPW51bGwsIGh0dHBIZWFkZXJzPXt9LCBodHRwU3RhdHVzPXVuYXV0aG9yaXplZCwgaW50ZXJuYWxSZWFzb249UmVhc29ue2FyZ3VtZW50cz17fSwgY2F1c2U9bnVsbCwgY29kZT1nZGF0YS5Db3JlRXJyb3JEb21haW4uUkVRVUlSRUQsIGNyZWF0ZWRCeUJhY2tlbmQ9dHJ1ZSwgZGVidWdNZXNzYWdlPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpBQ0NFU1NfREVOSUVEOiBBbm9ueW1vdXMgY2FsbGVyIGRvZXMgbm90IGhhdmUgc3RvcmFnZS5vYmplY3RzLmNyZWF0ZSBhY2Nlc3MgdG8gZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL25vYXV0aC5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuSW5zZXJ0T2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRPYmplY3QuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5JbnNlcnRPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEluc2VydE9iamVjdC5qYXZhOjQ0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLmluc2VydChPYmplY3RzRGVsZWdhdG9yLmphdmE6OTUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEFub255bW91cyBjYWxsZXIgZG9lcyBub3QgaGF2ZSBzdG9yYWdlLm9iamVjdHMuY3JlYXRlIGFjY2VzcyB0byBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvbm9hdXRoLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGVycm9yUHJvdG9Db2RlPVJFUVVJUkVELCBlcnJvclByb3RvRG9tYWluPWdkYXRhLkNvcmVFcnJvckRvbWFpbiwgZmlsdGVyZWRNZXNzYWdlPW51bGwsIGxvY2F0aW9uPWVudGl0eS5hdXRoZW50aWNhdGVkX3VzZXIsIG1lc3NhZ2U9QW5vbnltb3VzIGNhbGxlciBkb2VzIG5vdCBoYXZlIHN0b3JhZ2Uub2JqZWN0cy5jcmVhdGUgYWNjZXNzIHRvIGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9ub2F1dGguLCB1bm5hbWVkQXJndW1lbnRzPVtdfSwgbG9jYXRpb249aGVhZGVycy5BdXRob3JpemF0aW9uLCBtZXNzYWdlPUFub255bW91cyBjYWxsZXIgZG9lcyBub3QgaGF2ZSBzdG9yYWdlLm9iamVjdHMuY3JlYXRlIGFjY2VzcyB0byBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvbm9hdXRoLiwgcmVhc29uPXJlcXVpcmVkLCBycGNDb2RlPTQwMX0gQW5vbnltb3VzIGNhbGxlciBkb2VzIG5vdCBoYXZlIHN0b3JhZ2Uub2JqZWN0cy5jcmVhdGUgYWNjZXNzIHRvIGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9ub2F1dGguOiBjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6QUNDRVNTX0RFTklFRDogQW5vbnltb3VzIGNhbGxlciBkb2VzIG5vdCBoYXZlIHN0b3JhZ2Uub2JqZWN0cy5jcmVhdGUgYWNjZXNzIHRvIGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9ub2F1dGguXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkluc2VydE9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoSW5zZXJ0T2JqZWN0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuSW5zZXJ0T2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRPYmplY3QuamF2YTo0NClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uT2JqZWN0c0RlbGVnYXRvci5pbnNlcnQoT2JqZWN0c0RlbGVnYXRvci5qYXZhOjk1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBBbm9ueW1vdXMgY2FsbGVyIGRvZXMgbm90IGhhdmUgc3RvcmFnZS5vYmplY3RzLmNyZWF0ZSBhY2Nlc3MgdG8gZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL25vYXV0aC5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuLCBkZWJ1Z0luZm89Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OkFDQ0VTU19ERU5JRUQ6IEFub255bW91cyBjYWxsZXIgZG9lcyBub3QgaGF2ZSBzdG9yYWdlLm9iamVjdHMuY3JlYXRlIGFjY2VzcyB0byBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvbm9hdXRoLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5JbnNlcnRPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEluc2VydE9iamVjdC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkluc2VydE9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoSW5zZXJ0T2JqZWN0LmphdmE6NDQpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLk9iamVjdHNEZWxlZ2F0b3IuaW5zZXJ0KE9iamVjdHNEZWxlZ2F0b3IuamF2YTo5NSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogQW5vbnltb3VzIGNhbGxlciBkb2VzIG5vdCBoYXZlIHN0b3JhZ2Uub2JqZWN0cy5jcmVhdGUgYWNjZXNzIHRvIGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9ub2F1dGguXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZG9tYWluPWdsb2JhbCwgZXh0ZW5kZWRIZWxwPW51bGwsIGh0dHBIZWFkZXJzPXtXV1ctQXV0aGVudGljYXRlPVtCZWFyZXIgcmVhbG09XCJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20vXCJdfSwgaHR0cFN0YXR1cz11bmF1dGhvcml6ZWQsIGludGVybmFsUmVhc29uPVJlYXNvbnthcmd1bWVudHM9e30sIGNhdXNlPW51bGwsIGNvZGU9Z2RhdGEuQ29yZUVycm9yRG9tYWluLlJFUVVJUkVELCBjcmVhdGVkQnlCYWNrZW5kPXRydWUsIGRlYnVnTWVzc2FnZT1jb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6QUNDRVNTX0RFTklFRDogQW5vbnltb3VzIGNhbGxlciBkb2VzIG5vdCBoYXZlIHN0b3JhZ2Uub2JqZWN0cy5jcmVhdGUgYWNjZXNzIHRvIGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9ub2F1dGguXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkluc2VydE9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoSW5zZXJ0T2JqZWN0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuSW5zZXJ0T2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRPYmplY3QuamF2YTo0NClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uT2JqZWN0c0RlbGVnYXRvci5pbnNlcnQoT2JqZWN0c0RlbGVnYXRvci5qYXZhOjk1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBBbm9ueW1vdXMgY2FsbGVyIGRvZXMgbm90IGhhdmUgc3RvcmFnZS5vYmplY3RzLmNyZWF0ZSBhY2Nlc3MgdG8gZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL25vYXV0aC5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuLCBlcnJvclByb3RvQ29kZT1SRVFVSVJFRCwgZXJyb3JQcm90b0RvbWFpbj1nZGF0YS5Db3JlRXJyb3JEb21haW4sIGZpbHRlcmVkTWVzc2FnZT1udWxsLCBsb2NhdGlvbj1lbnRpdHkuYXV0aGVudGljYXRlZF91c2VyLCBtZXNzYWdlPUFub255bW91cyBjYWxsZXIgZG9lcyBub3QgaGF2ZSBzdG9yYWdlLm9iamVjdHMuY3JlYXRlIGFjY2VzcyB0byBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvbm9hdXRoLiwgdW5uYW1lZEFyZ3VtZW50cz1bXX0sIGxvY2F0aW9uPWhlYWRlcnMuQXV0aG9yaXphdGlvbiwgbWVzc2FnZT1Bbm9ueW1vdXMgY2FsbGVyIGRvZXMgbm90IGhhdmUgc3RvcmFnZS5vYmplY3RzLmNyZWF0ZSBhY2Nlc3MgdG8gZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL25vYXV0aC4sIHJlYXNvbj1yZXF1aXJlZCwgcnBjQ29kZT00MDF9IEFub255bW91cyBjYWxsZXIgZG9lcyBub3QgaGF2ZSBzdG9yYWdlLm9iamVjdHMuY3JlYXRlIGFjY2VzcyB0byBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvbm9hdXRoLjogY29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OkFDQ0VTU19ERU5JRUQ6IEFub255bW91cyBjYWxsZXIgZG9lcyBub3QgaGF2ZSBzdG9yYWdlLm9iamVjdHMuY3JlYXRlIGFjY2VzcyB0byBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvbm9hdXRoLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5JbnNlcnRPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEluc2VydE9iamVjdC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkluc2VydE9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoSW5zZXJ0T2JqZWN0LmphdmE6NDQpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLk9iamVjdHNEZWxlZ2F0b3IuaW5zZXJ0KE9iamVjdHNEZWxlZ2F0b3IuamF2YTo5NSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogQW5vbnltb3VzIGNhbGxlciBkb2VzIG5vdCBoYXZlIHN0b3JhZ2Uub2JqZWN0cy5jcmVhdGUgYWNjZXNzIHRvIGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9ub2F1dGguXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuYXV0aC5BdXRoZW50aWNhdG9ySW50ZXJjZXB0b3IuYWRkQ2hhbGxlbmdlSGVhZGVyKEF1dGhlbnRpY2F0b3JJbnRlcmNlcHRvci5qYXZhOjI2OSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmF1dGguQXV0aGVudGljYXRvckludGVyY2VwdG9yLnByb2Nlc3NFcnJvclJlc3BvbnNlKEF1dGhlbnRpY2F0b3JJbnRlcmNlcHRvci5qYXZhOjIzNilcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmF1dGguR2FpYU1pbnRJbnRlcmNlcHRvci5wcm9jZXNzRXJyb3JSZXNwb25zZShHYWlhTWludEludGVyY2VwdG9yLmphdmE6NzY4KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS5pbnRlcmNlcHQuQXJvdW5kSW50ZXJjZXB0b3JXcmFwcGVyLnByb2Nlc3NFcnJvclJlc3BvbnNlKEFyb3VuZEludGVyY2VwdG9yV3JhcHBlci5qYXZhOjI4KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuc3RhdHMuU3RhdHNCb290c3RyYXAkSW50ZXJjZXB0b3JTdGF0c1JlY29yZGVyLnByb2Nlc3NFcnJvclJlc3BvbnNlKFN0YXRzQm9vdHN0cmFwLmphdmE6MzE1KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS5pbnRlcmNlcHQuSW50ZXJjZXB0aW9ucyRBcm91bmRJbnRlcmNlcHRpb24uaGFuZGxlRXJyb3JSZXNwb25zZShJbnRlcmNlcHRpb25zLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS5pbnRlcmNlcHQuSW50ZXJjZXB0aW9ucyRBcm91bmRJbnRlcmNlcHRpb24uYWNjZXNzJDIwMChJbnRlcmNlcHRpb25zLmphdmE6MTAzKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS5pbnRlcmNlcHQuSW50ZXJjZXB0aW9ucyRBcm91bmRJbnRlcmNlcHRpb24kMS5jYWxsKEludGVyY2VwdGlvbnMuamF2YToxNDQpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLmludGVyY2VwdC5JbnRlcmNlcHRpb25zJEFyb3VuZEludGVyY2VwdGlvbiQxLmNhbGwoSW50ZXJjZXB0aW9ucy5qYXZhOjEzNylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkRpcmVjdEV4ZWN1dG9yLmV4ZWN1dGUoRGlyZWN0RXhlY3V0b3IuamF2YTozMClcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmV4ZWN1dGVMaXN0ZW5lcihBYnN0cmFjdEZ1dHVyZS5qYXZhOjExNDMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5jb21wbGV0ZShBYnN0cmFjdEZ1dHVyZS5qYXZhOjk2Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLnNldEV4Y2VwdGlvbihBYnN0cmFjdEZ1dHVyZS5qYXZhOjc1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2OClcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkRpcmVjdEV4ZWN1dG9yLmV4ZWN1dGUoRGlyZWN0RXhlY3V0b3IuamF2YTozMClcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmV4ZWN1dGVMaXN0ZW5lcihBYnN0cmFjdEZ1dHVyZS5qYXZhOjExNDMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5jb21wbGV0ZShBYnN0cmFjdEZ1dHVyZS5qYXZhOjk2Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLnNldChBYnN0cmFjdEZ1dHVyZS5qYXZhOjczMSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkRpcmVjdEV4ZWN1dG9yLmV4ZWN1dGUoRGlyZWN0RXhlY3V0b3IuamF2YTozMClcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmV4ZWN1dGVMaXN0ZW5lcihBYnN0cmFjdEZ1dHVyZS5qYXZhOjExNDMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5jb21wbGV0ZShBYnN0cmFjdEZ1dHVyZS5qYXZhOjk2Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLnNldChBYnN0cmFjdEZ1dHVyZS5qYXZhOjczMSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnRocmVhZC5UaHJlYWRUcmFja2VycyRUaHJlYWRUcmFja2luZ1J1bm5hYmxlLnJ1bihUaHJlYWRUcmFja2Vycy5qYXZhOjEyNilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoVHJhY2VDb250ZXh0LmphdmE6NDUzKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuc2VydmVyLkNvbW1vbk1vZHVsZSRDb250ZXh0Q2FycnlpbmdFeGVjdXRvclNlcnZpY2UkMS5ydW5JbkNvbnRleHQoQ29tbW9uTW9kdWxlLmphdmE6ODAyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlJDEucnVuKFRyYWNlQ29udGV4dC5qYXZhOjQ2MClcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihUcmFjZUNvbnRleHQuamF2YTozMTkpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkQWJzdHJhY3RUcmFjZUNvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoVHJhY2VDb250ZXh0LmphdmE6MzExKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NTcpXG5cdGF0IGNvbS5nb29nbGUuZ3NlLmludGVybmFsLkRpc3BhdGNoUXVldWVJbXBsJFdvcmtlclRocmVhZC5ydW4oRGlzcGF0Y2hRdWV1ZUltcGwuamF2YTo0MDMpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLkZhdWx0OiBJbW11dGFibGVFcnJvckRlZmluaXRpb257YmFzZT1MT0dJTl9SRVFVSVJFRCwgY2F0ZWdvcnk9VVNFUl9FUlJPUiwgY2F1c2U9bnVsbCwgZGVidWdJbmZvPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpBQ0NFU1NfREVOSUVEOiBBbm9ueW1vdXMgY2FsbGVyIGRvZXMgbm90IGhhdmUgc3RvcmFnZS5vYmplY3RzLmNyZWF0ZSBhY2Nlc3MgdG8gZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL25vYXV0aC5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuSW5zZXJ0T2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRPYmplY3QuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5JbnNlcnRPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEluc2VydE9iamVjdC5qYXZhOjQ0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLmluc2VydChPYmplY3RzRGVsZWdhdG9yLmphdmE6OTUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IEFub255bW91cyBjYWxsZXIgZG9lcyBub3QgaGF2ZSBzdG9yYWdlLm9iamVjdHMuY3JlYXRlIGFjY2VzcyB0byBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvbm9hdXRoLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGRvbWFpbj1nbG9iYWwsIGV4dGVuZGVkSGVscD1udWxsLCBodHRwSGVhZGVycz17fSwgaHR0cFN0YXR1cz11bmF1dGhvcml6ZWQsIGludGVybmFsUmVhc29uPVJlYXNvbnthcmd1bWVudHM9e30sIGNhdXNlPW51bGwsIGNvZGU9Z2RhdGEuQ29yZUVycm9yRG9tYWluLlJFUVVJUkVELCBjcmVhdGVkQnlCYWNrZW5kPXRydWUsIGRlYnVnTWVzc2FnZT1jb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6QUNDRVNTX0RFTklFRDogQW5vbnltb3VzIGNhbGxlciBkb2VzIG5vdCBoYXZlIHN0b3JhZ2Uub2JqZWN0cy5jcmVhdGUgYWNjZXNzIHRvIGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9ub2F1dGguXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkluc2VydE9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoSW5zZXJ0T2JqZWN0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuSW5zZXJ0T2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRPYmplY3QuamF2YTo0NClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uT2JqZWN0c0RlbGVnYXRvci5pbnNlcnQoT2JqZWN0c0RlbGVnYXRvci5qYXZhOjk1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBBbm9ueW1vdXMgY2FsbGVyIGRvZXMgbm90IGhhdmUgc3RvcmFnZS5vYmplY3RzLmNyZWF0ZSBhY2Nlc3MgdG8gZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL25vYXV0aC5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuLCBlcnJvclByb3RvQ29kZT1SRVFVSVJFRCwgZXJyb3JQcm90b0RvbWFpbj1nZGF0YS5Db3JlRXJyb3JEb21haW4sIGZpbHRlcmVkTWVzc2FnZT1udWxsLCBsb2NhdGlvbj1lbnRpdHkuYXV0aGVudGljYXRlZF91c2VyLCBtZXNzYWdlPUFub255bW91cyBjYWxsZXIgZG9lcyBub3QgaGF2ZSBzdG9yYWdlLm9iamVjdHMuY3JlYXRlIGFjY2VzcyB0byBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvbm9hdXRoLiwgdW5uYW1lZEFyZ3VtZW50cz1bXX0sIGxvY2F0aW9uPWhlYWRlcnMuQXV0aG9yaXphdGlvbiwgbWVzc2FnZT1Bbm9ueW1vdXMgY2FsbGVyIGRvZXMgbm90IGhhdmUgc3RvcmFnZS5vYmplY3RzLmNyZWF0ZSBhY2Nlc3MgdG8gZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL25vYXV0aC4sIHJlYXNvbj1yZXF1aXJlZCwgcnBjQ29kZT00MDF9IEFub255bW91cyBjYWxsZXIgZG9lcyBub3QgaGF2ZSBzdG9yYWdlLm9iamVjdHMuY3JlYXRlIGFjY2VzcyB0byBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvbm9hdXRoLjogY29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OkFDQ0VTU19ERU5JRUQ6IEFub255bW91cyBjYWxsZXIgZG9lcyBub3QgaGF2ZSBzdG9yYWdlLm9iamVjdHMuY3JlYXRlIGFjY2VzcyB0byBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvbm9hdXRoLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5JbnNlcnRPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEluc2VydE9iamVjdC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkluc2VydE9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoSW5zZXJ0T2JqZWN0LmphdmE6NDQpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLk9iamVjdHNEZWxlZ2F0b3IuaW5zZXJ0KE9iamVjdHNEZWxlZ2F0b3IuamF2YTo5NSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogQW5vbnltb3VzIGNhbGxlciBkb2VzIG5vdCBoYXZlIHN0b3JhZ2Uub2JqZWN0cy5jcmVhdGUgYWNjZXNzIHRvIGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9ub2F1dGguXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS5FcnJvckNvbGxlY3Rvci50b0ZhdWx0KEVycm9yQ29sbGVjdG9yLmphdmE6NTQpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5RXJyb3JDb252ZXJ0ZXIudG9GYXVsdChSb3N5RXJyb3JDb252ZXJ0ZXIuamF2YTo2Nylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lIYW5kbGVyJDIuY2FsbChSb3N5SGFuZGxlci5qYXZhOjI1OSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lIYW5kbGVyJDIuY2FsbChSb3N5SGFuZGxlci5qYXZhOjIzOSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0Li4uIDIwIG1vcmVcbiJ9XSwiY29kZSI6NDAxLCJtZXNzYWdlIjoiQW5vbnltb3VzIGNhbGxlciBkb2VzIG5vdCBoYXZlIHN0b3JhZ2Uub2JqZWN0cy5jcmVhdGUgYWNjZXNzIHRvIGdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9ub2F1dGguIn19" } }, { "ID": "848c7013eb1665b1", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/gcp-public-data-landsat/LC08/PRE/044/034/LC80440342016259LGN00/LC80440342016259LGN00_MTL.txt", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "public, max-age=3600" ], "Content-Length": [ "7903" ], "Content-Type": [ "application/octet-stream" ], "Date": [ "Thu, 02 May 2019 22:25:27 GMT" ], "Etag": [ "\"7a5fd4743bd647485f88496fadb05c51\"" ], "Expires": [ "Thu, 02 May 2019 23:25:27 GMT" ], "Last-Modified": [ "Tue, 04 Oct 2016 16:42:07 GMT" ], "Server": [ "UploadServer" ], "X-Goog-Generation": [ "1475599327662000" ], "X-Goog-Hash": [ "crc32c=PWBt8g==", "md5=el/UdDvWR0hfiElvrbBcUQ==" ], "X-Goog-Metageneration": [ "1" ], "X-Goog-Storage-Class": [ "STANDARD" ], "X-Goog-Stored-Content-Encoding": [ "identity" ], "X-Goog-Stored-Content-Length": [ "7903" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uqbrgn51bDFbwZ1c2_BxCHhog7If9w6ooKAtb2YCerQcObpiFJZqT3-Jn7zTXEEPVuysmxKw4PmvEOmkbCAJVkmbEVZm6z877JKFhrXTrkWqWYooq8" ] }, "Body": "R1JPVVAgPSBMMV9NRVRBREFUQV9GSUxFCiAgR1JPVVAgPSBNRVRBREFUQV9GSUxFX0lORk8KICAgIE9SSUdJTiA9ICJJbWFnZSBjb3VydGVzeSBvZiB0aGUgVS5TLiBHZW9sb2dpY2FsIFN1cnZleSIKICAgIFJFUVVFU1RfSUQgPSAiMDcwMTYwOTE5MTA1MV8wMDAwNCIKICAgIExBTkRTQVRfU0NFTkVfSUQgPSAiTEM4MDQ0MDM0MjAxNjI1OUxHTjAwIgogICAgRklMRV9EQVRFID0gMjAxNi0wOS0yMFQwMzoxMzowMloKICAgIFNUQVRJT05fSUQgPSAiTEdOIgogICAgUFJPQ0VTU0lOR19TT0ZUV0FSRV9WRVJTSU9OID0gIkxQR1NfMi42LjIiCiAgRU5EX0dST1VQID0gTUVUQURBVEFfRklMRV9JTkZPCiAgR1JPVVAgPSBQUk9EVUNUX01FVEFEQVRBCiAgICBEQVRBX1RZUEUgPSAiTDFUIgogICAgRUxFVkFUSU9OX1NPVVJDRSA9ICJHTFMyMDAwIgogICAgT1VUUFVUX0ZPUk1BVCA9ICJHRU9USUZGIgogICAgU1BBQ0VDUkFGVF9JRCA9ICJMQU5EU0FUXzgiCiAgICBTRU5TT1JfSUQgPSAiT0xJX1RJUlMiCiAgICBXUlNfUEFUSCA9IDQ0CiAgICBXUlNfUk9XID0gMzQKICAgIE5BRElSX09GRk5BRElSID0gIk5BRElSIgogICAgVEFSR0VUX1dSU19QQVRIID0gNDQKICAgIFRBUkdFVF9XUlNfUk9XID0gMzQKICAgIERBVEVfQUNRVUlSRUQgPSAyMDE2LTA5LTE1CiAgICBTQ0VORV9DRU5URVJfVElNRSA9ICIxODo0NjoxOC42ODY3MzgwWiIKICAgIENPUk5FUl9VTF9MQVRfUFJPRFVDVCA9IDM4LjUyODE5CiAgICBDT1JORVJfVUxfTE9OX1BST0RVQ1QgPSAtMTIzLjQwODQzCiAgICBDT1JORVJfVVJfTEFUX1BST0RVQ1QgPSAzOC41MDc2NQogICAgQ09STkVSX1VSX0xPTl9QUk9EVUNUID0gLTEyMC43NjkzMwogICAgQ09STkVSX0xMX0xBVF9QUk9EVUNUID0gMzYuNDE2MzMKICAgIENPUk5FUl9MTF9MT05fUFJPRFVDVCA9IC0xMjMuMzk3MDkKICAgIENPUk5FUl9MUl9MQVRfUFJPRFVDVCA9IDM2LjM5NzI5CiAgICBDT1JORVJfTFJfTE9OX1BST0RVQ1QgPSAtMTIwLjgzMTE3CiAgICBDT1JORVJfVUxfUFJPSkVDVElPTl9YX1BST0RVQ1QgPSA0NjQ0MDAuMDAwCiAgICBDT1JORVJfVUxfUFJPSkVDVElPTl9ZX1BST0RVQ1QgPSA0MjY0NTAwLjAwMAogICAgQ09STkVSX1VSX1BST0pFQ1RJT05fWF9QUk9EVUNUID0gNjk0NTAwLjAwMAogICAgQ09STkVSX1VSX1BST0pFQ1RJT05fWV9QUk9EVUNUID0gNDI2NDUwMC4wMDAKICAgIENPUk5FUl9MTF9QUk9KRUNUSU9OX1hfUFJPRFVDVCA9IDQ2NDQwMC4wMDAKICAgIENPUk5FUl9MTF9QUk9KRUNUSU9OX1lfUFJPRFVDVCA9IDQwMzAyMDAuMDAwCiAgICBDT1JORVJfTFJfUFJPSkVDVElPTl9YX1BST0RVQ1QgPSA2OTQ1MDAuMDAwCiAgICBDT1JORVJfTFJfUFJPSkVDVElPTl9ZX1BST0RVQ1QgPSA0MDMwMjAwLjAwMAogICAgUEFOQ0hST01BVElDX0xJTkVTID0gMTU2MjEKICAgIFBBTkNIUk9NQVRJQ19TQU1QTEVTID0gMTUzNDEKICAgIFJFRkxFQ1RJVkVfTElORVMgPSA3ODExCiAgICBSRUZMRUNUSVZFX1NBTVBMRVMgPSA3NjcxCiAgICBUSEVSTUFMX0xJTkVTID0gNzgxMQogICAgVEhFUk1BTF9TQU1QTEVTID0gNzY3MQogICAgRklMRV9OQU1FX0JBTkRfMSA9ICJMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjEuVElGIgogICAgRklMRV9OQU1FX0JBTkRfMiA9ICJMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjIuVElGIgogICAgRklMRV9OQU1FX0JBTkRfMyA9ICJMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjMuVElGIgogICAgRklMRV9OQU1FX0JBTkRfNCA9ICJMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjQuVElGIgogICAgRklMRV9OQU1FX0JBTkRfNSA9ICJMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjUuVElGIgogICAgRklMRV9OQU1FX0JBTkRfNiA9ICJMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjYuVElGIgogICAgRklMRV9OQU1FX0JBTkRfNyA9ICJMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjcuVElGIgogICAgRklMRV9OQU1FX0JBTkRfOCA9ICJMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjguVElGIgogICAgRklMRV9OQU1FX0JBTkRfOSA9ICJMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjkuVElGIgogICAgRklMRV9OQU1FX0JBTkRfMTAgPSAiTEM4MDQ0MDM0MjAxNjI1OUxHTjAwX0IxMC5USUYiCiAgICBGSUxFX05BTUVfQkFORF8xMSA9ICJMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjExLlRJRiIKICAgIEZJTEVfTkFNRV9CQU5EX1FVQUxJVFkgPSAiTEM4MDQ0MDM0MjAxNjI1OUxHTjAwX0JRQS5USUYiCiAgICBNRVRBREFUQV9GSUxFX05BTUUgPSAiTEM4MDQ0MDM0MjAxNjI1OUxHTjAwX01UTC50eHQiCiAgICBCUEZfTkFNRV9PTEkgPSAiTE84QlBGMjAxNjA5MTUxODMwNTdfMjAxNjA5MTUyMDA5NTAuMDEiCiAgICBCUEZfTkFNRV9USVJTID0gIkxUOEJQRjIwMTYwOTAyMDg0MTIyXzIwMTYwOTE3MDc0MDI3LjAyIgogICAgQ1BGX05BTUUgPSAiTDhDUEYyMDE2MDcwMV8yMDE2MDkzMC4wMiIKICAgIFJMVVRfRklMRV9OQU1FID0gIkw4UkxVVDIwMTUwMzAzXzIwNDMxMjMxdjExLmg1IgogIEVORF9HUk9VUCA9IFBST0RVQ1RfTUVUQURBVEEKICBHUk9VUCA9IElNQUdFX0FUVFJJQlVURVMKICAgIENMT1VEX0NPVkVSID0gMjkuNTYKICAgIENMT1VEX0NPVkVSX0xBTkQgPSAzLjMzCiAgICBJTUFHRV9RVUFMSVRZX09MSSA9IDkKICAgIElNQUdFX1FVQUxJVFlfVElSUyA9IDkKICAgIFRJUlNfU1NNX01PREVMID0gIkZJTkFMIgogICAgVElSU19TU01fUE9TSVRJT05fU1RBVFVTID0gIkVTVElNQVRFRCIKICAgIFJPTExfQU5HTEUgPSAtMC4wMDEKICAgIFNVTl9BWklNVVRIID0gMTQ4LjQ4MDQ5Mzk2CiAgICBTVU5fRUxFVkFUSU9OID0gNTAuOTM3NjgzOTkKICAgIEVBUlRIX1NVTl9ESVNUQU5DRSA9IDEuMDA1Mzc1MgogICAgR1JPVU5EX0NPTlRST0xfUE9JTlRTX1ZFUlNJT04gPSA0CiAgICBHUk9VTkRfQ09OVFJPTF9QT0lOVFNfTU9ERUwgPSA1NDgKICAgIEdFT01FVFJJQ19STVNFX01PREVMID0gNS44NTcKICAgIEdFT01FVFJJQ19STVNFX01PREVMX1kgPSAzLjg0MQogICAgR0VPTUVUUklDX1JNU0VfTU9ERUxfWCA9IDQuNDIyCiAgICBHUk9VTkRfQ09OVFJPTF9QT0lOVFNfVkVSSUZZID0gMjI4CiAgICBHRU9NRVRSSUNfUk1TRV9WRVJJRlkgPSAzLjM4MgogIEVORF9HUk9VUCA9IElNQUdFX0FUVFJJQlVURVMKICBHUk9VUCA9IE1JTl9NQVhfUkFESUFOQ0UKICAgIFJBRElBTkNFX01BWElNVU1fQkFORF8xID0gNzUxLjk1NzA5CiAgICBSQURJQU5DRV9NSU5JTVVNX0JBTkRfMSA9IC02Mi4wOTY4NgogICAgUkFESUFOQ0VfTUFYSU1VTV9CQU5EXzIgPSA3NzAuMDEzMTgKICAgIFJBRElBTkNFX01JTklNVU1fQkFORF8yID0gLTYzLjU4Nzk0CiAgICBSQURJQU5DRV9NQVhJTVVNX0JBTkRfMyA9IDcwOS41NjA2MQogICAgUkFESUFOQ0VfTUlOSU1VTV9CQU5EXzMgPSAtNTguNTk1NzUKICAgIFJBRElBTkNFX01BWElNVU1fQkFORF80ID0gNTk4LjM0MTQ5CiAgICBSQURJQU5DRV9NSU5JTVVNX0JBTkRfNCA9IC00OS40MTEyMwogICAgUkFESUFOQ0VfTUFYSU1VTV9CQU5EXzUgPSAzNjYuMTU1MTUKICAgIFJBRElBTkNFX01JTklNVU1fQkFORF81ID0gLTMwLjIzNzIxCiAgICBSQURJQU5DRV9NQVhJTVVNX0JBTkRfNiA9IDkxLjA1OTQ2CiAgICBSQURJQU5DRV9NSU5JTVVNX0JBTkRfNiA9IC03LjUxOTcyCiAgICBSQURJQU5DRV9NQVhJTVVNX0JBTkRfNyA9IDMwLjY5MTkxCiAgICBSQURJQU5DRV9NSU5JTVVNX0JBTkRfNyA9IC0yLjUzNDU1CiAgICBSQURJQU5DRV9NQVhJTVVNX0JBTkRfOCA9IDY3Ny4xNTc4NAogICAgUkFESUFOQ0VfTUlOSU1VTV9CQU5EXzggPSAtNTUuOTE5OTIKICAgIFJBRElBTkNFX01BWElNVU1fQkFORF85ID0gMTQzLjEwMTczCiAgICBSQURJQU5DRV9NSU5JTVVNX0JBTkRfOSA9IC0xMS44MTczOQogICAgUkFESUFOQ0VfTUFYSU1VTV9CQU5EXzEwID0gMjIuMDAxODAKICAgIFJBRElBTkNFX01JTklNVU1fQkFORF8xMCA9IDAuMTAwMzMKICAgIFJBRElBTkNFX01BWElNVU1fQkFORF8xMSA9IDIyLjAwMTgwCiAgICBSQURJQU5DRV9NSU5JTVVNX0JBTkRfMTEgPSAwLjEwMDMzCiAgRU5EX0dST1VQID0gTUlOX01BWF9SQURJQU5DRQogIEdST1VQID0gTUlOX01BWF9SRUZMRUNUQU5DRQogICAgUkVGTEVDVEFOQ0VfTUFYSU1VTV9CQU5EXzEgPSAxLjIxMDcwMAogICAgUkVGTEVDVEFOQ0VfTUlOSU1VTV9CQU5EXzEgPSAtMC4wOTk5ODAKICAgIFJFRkxFQ1RBTkNFX01BWElNVU1fQkFORF8yID0gMS4yMTA3MDAKICAgIFJFRkxFQ1RBTkNFX01JTklNVU1fQkFORF8yID0gLTAuMDk5OTgwCiAgICBSRUZMRUNUQU5DRV9NQVhJTVVNX0JBTkRfMyA9IDEuMjEwNzAwCiAgICBSRUZMRUNUQU5DRV9NSU5JTVVNX0JBTkRfMyA9IC0wLjA5OTk4MAogICAgUkVGTEVDVEFOQ0VfTUFYSU1VTV9CQU5EXzQgPSAxLjIxMDcwMAogICAgUkVGTEVDVEFOQ0VfTUlOSU1VTV9CQU5EXzQgPSAtMC4wOTk5ODAKICAgIFJFRkxFQ1RBTkNFX01BWElNVU1fQkFORF81ID0gMS4yMTA3MDAKICAgIFJFRkxFQ1RBTkNFX01JTklNVU1fQkFORF81ID0gLTAuMDk5OTgwCiAgICBSRUZMRUNUQU5DRV9NQVhJTVVNX0JBTkRfNiA9IDEuMjEwNzAwCiAgICBSRUZMRUNUQU5DRV9NSU5JTVVNX0JBTkRfNiA9IC0wLjA5OTk4MAogICAgUkVGTEVDVEFOQ0VfTUFYSU1VTV9CQU5EXzcgPSAxLjIxMDcwMAogICAgUkVGTEVDVEFOQ0VfTUlOSU1VTV9CQU5EXzcgPSAtMC4wOTk5ODAKICAgIFJFRkxFQ1RBTkNFX01BWElNVU1fQkFORF84ID0gMS4yMTA3MDAKICAgIFJFRkxFQ1RBTkNFX01JTklNVU1fQkFORF84ID0gLTAuMDk5OTgwCiAgICBSRUZMRUNUQU5DRV9NQVhJTVVNX0JBTkRfOSA9IDEuMjEwNzAwCiAgICBSRUZMRUNUQU5DRV9NSU5JTVVNX0JBTkRfOSA9IC0wLjA5OTk4MAogIEVORF9HUk9VUCA9IE1JTl9NQVhfUkVGTEVDVEFOQ0UKICBHUk9VUCA9IE1JTl9NQVhfUElYRUxfVkFMVUUKICAgIFFVQU5USVpFX0NBTF9NQVhfQkFORF8xID0gNjU1MzUKICAgIFFVQU5USVpFX0NBTF9NSU5fQkFORF8xID0gMQogICAgUVVBTlRJWkVfQ0FMX01BWF9CQU5EXzIgPSA2NTUzNQogICAgUVVBTlRJWkVfQ0FMX01JTl9CQU5EXzIgPSAxCiAgICBRVUFOVElaRV9DQUxfTUFYX0JBTkRfMyA9IDY1NTM1CiAgICBRVUFOVElaRV9DQUxfTUlOX0JBTkRfMyA9IDEKICAgIFFVQU5USVpFX0NBTF9NQVhfQkFORF80ID0gNjU1MzUKICAgIFFVQU5USVpFX0NBTF9NSU5fQkFORF80ID0gMQogICAgUVVBTlRJWkVfQ0FMX01BWF9CQU5EXzUgPSA2NTUzNQogICAgUVVBTlRJWkVfQ0FMX01JTl9CQU5EXzUgPSAxCiAgICBRVUFOVElaRV9DQUxfTUFYX0JBTkRfNiA9IDY1NTM1CiAgICBRVUFOVElaRV9DQUxfTUlOX0JBTkRfNiA9IDEKICAgIFFVQU5USVpFX0NBTF9NQVhfQkFORF83ID0gNjU1MzUKICAgIFFVQU5USVpFX0NBTF9NSU5fQkFORF83ID0gMQogICAgUVVBTlRJWkVfQ0FMX01BWF9CQU5EXzggPSA2NTUzNQogICAgUVVBTlRJWkVfQ0FMX01JTl9CQU5EXzggPSAxCiAgICBRVUFOVElaRV9DQUxfTUFYX0JBTkRfOSA9IDY1NTM1CiAgICBRVUFOVElaRV9DQUxfTUlOX0JBTkRfOSA9IDEKICAgIFFVQU5USVpFX0NBTF9NQVhfQkFORF8xMCA9IDY1NTM1CiAgICBRVUFOVElaRV9DQUxfTUlOX0JBTkRfMTAgPSAxCiAgICBRVUFOVElaRV9DQUxfTUFYX0JBTkRfMTEgPSA2NTUzNQogICAgUVVBTlRJWkVfQ0FMX01JTl9CQU5EXzExID0gMQogIEVORF9HUk9VUCA9IE1JTl9NQVhfUElYRUxfVkFMVUUKICBHUk9VUCA9IFJBRElPTUVUUklDX1JFU0NBTElORwogICAgUkFESUFOQ0VfTVVMVF9CQU5EXzEgPSAxLjI0MjJFLTAyCiAgICBSQURJQU5DRV9NVUxUX0JBTkRfMiA9IDEuMjcyMEUtMDIKICAgIFJBRElBTkNFX01VTFRfQkFORF8zID0gMS4xNzIxRS0wMgogICAgUkFESUFOQ0VfTVVMVF9CQU5EXzQgPSA5Ljg4NDJFLTAzCiAgICBSQURJQU5DRV9NVUxUX0JBTkRfNSA9IDYuMDQ4N0UtMDMKICAgIFJBRElBTkNFX01VTFRfQkFORF82ID0gMS41MDQyRS0wMwogICAgUkFESUFOQ0VfTVVMVF9CQU5EXzcgPSA1LjA3MDFFLTA0CiAgICBSQURJQU5DRV9NVUxUX0JBTkRfOCA9IDEuMTE4NkUtMDIKICAgIFJBRElBTkNFX01VTFRfQkFORF85ID0gMi4zNjQwRS0wMwogICAgUkFESUFOQ0VfTVVMVF9CQU5EXzEwID0gMy4zNDIwRS0wNAogICAgUkFESUFOQ0VfTVVMVF9CQU5EXzExID0gMy4zNDIwRS0wNAogICAgUkFESUFOQ0VfQUREX0JBTkRfMSA9IC02Mi4xMDkyOAogICAgUkFESUFOQ0VfQUREX0JBTkRfMiA9IC02My42MDA2NgogICAgUkFESUFOQ0VfQUREX0JBTkRfMyA9IC01OC42MDc0NwogICAgUkFESUFOQ0VfQUREX0JBTkRfNCA9IC00OS40MjExMgogICAgUkFESUFOQ0VfQUREX0JBTkRfNSA9IC0zMC4yNDMyNgogICAgUkFESUFOQ0VfQUREX0JBTkRfNiA9IC03LjUyMTIyCiAgICBSQURJQU5DRV9BRERfQkFORF83ID0gLTIuNTM1MDUKICAgIFJBRElBTkNFX0FERF9CQU5EXzggPSAtNTUuOTMxMTAKICAgIFJBRElBTkNFX0FERF9CQU5EXzkgPSAtMTEuODE5NzUKICAgIFJBRElBTkNFX0FERF9CQU5EXzEwID0gMC4xMDAwMAogICAgUkFESUFOQ0VfQUREX0JBTkRfMTEgPSAwLjEwMDAwCiAgICBSRUZMRUNUQU5DRV9NVUxUX0JBTkRfMSA9IDIuMDAwMEUtMDUKICAgIFJFRkxFQ1RBTkNFX01VTFRfQkFORF8yID0gMi4wMDAwRS0wNQogICAgUkVGTEVDVEFOQ0VfTVVMVF9CQU5EXzMgPSAyLjAwMDBFLTA1CiAgICBSRUZMRUNUQU5DRV9NVUxUX0JBTkRfNCA9IDIuMDAwMEUtMDUKICAgIFJFRkxFQ1RBTkNFX01VTFRfQkFORF81ID0gMi4wMDAwRS0wNQogICAgUkVGTEVDVEFOQ0VfTVVMVF9CQU5EXzYgPSAyLjAwMDBFLTA1CiAgICBSRUZMRUNUQU5DRV9NVUxUX0JBTkRfNyA9IDIuMDAwMEUtMDUKICAgIFJFRkxFQ1RBTkNFX01VTFRfQkFORF84ID0gMi4wMDAwRS0wNQogICAgUkVGTEVDVEFOQ0VfTVVMVF9CQU5EXzkgPSAyLjAwMDBFLTA1CiAgICBSRUZMRUNUQU5DRV9BRERfQkFORF8xID0gLTAuMTAwMDAwCiAgICBSRUZMRUNUQU5DRV9BRERfQkFORF8yID0gLTAuMTAwMDAwCiAgICBSRUZMRUNUQU5DRV9BRERfQkFORF8zID0gLTAuMTAwMDAwCiAgICBSRUZMRUNUQU5DRV9BRERfQkFORF80ID0gLTAuMTAwMDAwCiAgICBSRUZMRUNUQU5DRV9BRERfQkFORF81ID0gLTAuMTAwMDAwCiAgICBSRUZMRUNUQU5DRV9BRERfQkFORF82ID0gLTAuMTAwMDAwCiAgICBSRUZMRUNUQU5DRV9BRERfQkFORF83ID0gLTAuMTAwMDAwCiAgICBSRUZMRUNUQU5DRV9BRERfQkFORF84ID0gLTAuMTAwMDAwCiAgICBSRUZMRUNUQU5DRV9BRERfQkFORF85ID0gLTAuMTAwMDAwCiAgRU5EX0dST1VQID0gUkFESU9NRVRSSUNfUkVTQ0FMSU5HCiAgR1JPVVAgPSBUSVJTX1RIRVJNQUxfQ09OU1RBTlRTCiAgICBLMV9DT05TVEFOVF9CQU5EXzEwID0gNzc0Ljg4NTMKICAgIEsxX0NPTlNUQU5UX0JBTkRfMTEgPSA0ODAuODg4MwogICAgSzJfQ09OU1RBTlRfQkFORF8xMCA9IDEzMjEuMDc4OQogICAgSzJfQ09OU1RBTlRfQkFORF8xMSA9IDEyMDEuMTQ0MgogIEVORF9HUk9VUCA9IFRJUlNfVEhFUk1BTF9DT05TVEFOVFMKICBHUk9VUCA9IFBST0pFQ1RJT05fUEFSQU1FVEVSUwogICAgTUFQX1BST0pFQ1RJT04gPSAiVVRNIgogICAgREFUVU0gPSAiV0dTODQiCiAgICBFTExJUFNPSUQgPSAiV0dTODQiCiAgICBVVE1fWk9ORSA9IDEwCiAgICBHUklEX0NFTExfU0laRV9QQU5DSFJPTUFUSUMgPSAxNS4wMAogICAgR1JJRF9DRUxMX1NJWkVfUkVGTEVDVElWRSA9IDMwLjAwCiAgICBHUklEX0NFTExfU0laRV9USEVSTUFMID0gMzAuMDAKICAgIE9SSUVOVEFUSU9OID0gIk5PUlRIX1VQIgogICAgUkVTQU1QTElOR19PUFRJT04gPSAiQ1VCSUNfQ09OVk9MVVRJT04iCiAgRU5EX0dST1VQID0gUFJPSkVDVElPTl9QQVJBTUVURVJTCkVORF9HUk9VUCA9IEwxX01FVEFEQVRBX0ZJTEUKRU5ECg==" } }, { "ID": "a5f818071a0f22da", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/gcp-public-data-landsat/LC08/PRE/044/034/LC80440342016259LGN00/LC80440342016259LGN00_MTL.txt", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "public, max-age=3600" ], "Content-Length": [ "7903" ], "Content-Type": [ "application/octet-stream" ], "Date": [ "Thu, 02 May 2019 22:25:27 GMT" ], "Etag": [ "\"7a5fd4743bd647485f88496fadb05c51\"" ], "Expires": [ "Thu, 02 May 2019 23:25:27 GMT" ], "Last-Modified": [ "Tue, 04 Oct 2016 16:42:07 GMT" ], "Server": [ "UploadServer" ], "X-Goog-Generation": [ "1475599327662000" ], "X-Goog-Hash": [ "crc32c=PWBt8g==", "md5=el/UdDvWR0hfiElvrbBcUQ==" ], "X-Goog-Metageneration": [ "1" ], "X-Goog-Storage-Class": [ "STANDARD" ], "X-Goog-Stored-Content-Encoding": [ "identity" ], "X-Goog-Stored-Content-Length": [ "7903" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrozB-0-kEtkjITLFZA2uQpw77J_Zc6GErrYrIyxkPTWeUHJNBRLw4JXhyIEFG8szc7bhqblQVKoKYiZ4myOcfL5zIM9KYGIbCyAP9e4sEEdx2pBe0" ] }, "Body": "R1JPVVAgPSBMMV9NRVRBREFUQV9GSUxFCiAgR1JPVVAgPSBNRVRBREFUQV9GSUxFX0lORk8KICAgIE9SSUdJTiA9ICJJbWFnZSBjb3VydGVzeSBvZiB0aGUgVS5TLiBHZW9sb2dpY2FsIFN1cnZleSIKICAgIFJFUVVFU1RfSUQgPSAiMDcwMTYwOTE5MTA1MV8wMDAwNCIKICAgIExBTkRTQVRfU0NFTkVfSUQgPSAiTEM4MDQ0MDM0MjAxNjI1OUxHTjAwIgogICAgRklMRV9EQVRFID0gMjAxNi0wOS0yMFQwMzoxMzowMloKICAgIFNUQVRJT05fSUQgPSAiTEdOIgogICAgUFJPQ0VTU0lOR19TT0ZUV0FSRV9WRVJTSU9OID0gIkxQR1NfMi42LjIiCiAgRU5EX0dST1VQID0gTUVUQURBVEFfRklMRV9JTkZPCiAgR1JPVVAgPSBQUk9EVUNUX01FVEFEQVRBCiAgICBEQVRBX1RZUEUgPSAiTDFUIgogICAgRUxFVkFUSU9OX1NPVVJDRSA9ICJHTFMyMDAwIgogICAgT1VUUFVUX0ZPUk1BVCA9ICJHRU9USUZGIgogICAgU1BBQ0VDUkFGVF9JRCA9ICJMQU5EU0FUXzgiCiAgICBTRU5TT1JfSUQgPSAiT0xJX1RJUlMiCiAgICBXUlNfUEFUSCA9IDQ0CiAgICBXUlNfUk9XID0gMzQKICAgIE5BRElSX09GRk5BRElSID0gIk5BRElSIgogICAgVEFSR0VUX1dSU19QQVRIID0gNDQKICAgIFRBUkdFVF9XUlNfUk9XID0gMzQKICAgIERBVEVfQUNRVUlSRUQgPSAyMDE2LTA5LTE1CiAgICBTQ0VORV9DRU5URVJfVElNRSA9ICIxODo0NjoxOC42ODY3MzgwWiIKICAgIENPUk5FUl9VTF9MQVRfUFJPRFVDVCA9IDM4LjUyODE5CiAgICBDT1JORVJfVUxfTE9OX1BST0RVQ1QgPSAtMTIzLjQwODQzCiAgICBDT1JORVJfVVJfTEFUX1BST0RVQ1QgPSAzOC41MDc2NQogICAgQ09STkVSX1VSX0xPTl9QUk9EVUNUID0gLTEyMC43NjkzMwogICAgQ09STkVSX0xMX0xBVF9QUk9EVUNUID0gMzYuNDE2MzMKICAgIENPUk5FUl9MTF9MT05fUFJPRFVDVCA9IC0xMjMuMzk3MDkKICAgIENPUk5FUl9MUl9MQVRfUFJPRFVDVCA9IDM2LjM5NzI5CiAgICBDT1JORVJfTFJfTE9OX1BST0RVQ1QgPSAtMTIwLjgzMTE3CiAgICBDT1JORVJfVUxfUFJPSkVDVElPTl9YX1BST0RVQ1QgPSA0NjQ0MDAuMDAwCiAgICBDT1JORVJfVUxfUFJPSkVDVElPTl9ZX1BST0RVQ1QgPSA0MjY0NTAwLjAwMAogICAgQ09STkVSX1VSX1BST0pFQ1RJT05fWF9QUk9EVUNUID0gNjk0NTAwLjAwMAogICAgQ09STkVSX1VSX1BST0pFQ1RJT05fWV9QUk9EVUNUID0gNDI2NDUwMC4wMDAKICAgIENPUk5FUl9MTF9QUk9KRUNUSU9OX1hfUFJPRFVDVCA9IDQ2NDQwMC4wMDAKICAgIENPUk5FUl9MTF9QUk9KRUNUSU9OX1lfUFJPRFVDVCA9IDQwMzAyMDAuMDAwCiAgICBDT1JORVJfTFJfUFJPSkVDVElPTl9YX1BST0RVQ1QgPSA2OTQ1MDAuMDAwCiAgICBDT1JORVJfTFJfUFJPSkVDVElPTl9ZX1BST0RVQ1QgPSA0MDMwMjAwLjAwMAogICAgUEFOQ0hST01BVElDX0xJTkVTID0gMTU2MjEKICAgIFBBTkNIUk9NQVRJQ19TQU1QTEVTID0gMTUzNDEKICAgIFJFRkxFQ1RJVkVfTElORVMgPSA3ODExCiAgICBSRUZMRUNUSVZFX1NBTVBMRVMgPSA3NjcxCiAgICBUSEVSTUFMX0xJTkVTID0gNzgxMQogICAgVEhFUk1BTF9TQU1QTEVTID0gNzY3MQogICAgRklMRV9OQU1FX0JBTkRfMSA9ICJMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjEuVElGIgogICAgRklMRV9OQU1FX0JBTkRfMiA9ICJMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjIuVElGIgogICAgRklMRV9OQU1FX0JBTkRfMyA9ICJMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjMuVElGIgogICAgRklMRV9OQU1FX0JBTkRfNCA9ICJMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjQuVElGIgogICAgRklMRV9OQU1FX0JBTkRfNSA9ICJMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjUuVElGIgogICAgRklMRV9OQU1FX0JBTkRfNiA9ICJMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjYuVElGIgogICAgRklMRV9OQU1FX0JBTkRfNyA9ICJMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjcuVElGIgogICAgRklMRV9OQU1FX0JBTkRfOCA9ICJMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjguVElGIgogICAgRklMRV9OQU1FX0JBTkRfOSA9ICJMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjkuVElGIgogICAgRklMRV9OQU1FX0JBTkRfMTAgPSAiTEM4MDQ0MDM0MjAxNjI1OUxHTjAwX0IxMC5USUYiCiAgICBGSUxFX05BTUVfQkFORF8xMSA9ICJMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjExLlRJRiIKICAgIEZJTEVfTkFNRV9CQU5EX1FVQUxJVFkgPSAiTEM4MDQ0MDM0MjAxNjI1OUxHTjAwX0JRQS5USUYiCiAgICBNRVRBREFUQV9GSUxFX05BTUUgPSAiTEM4MDQ0MDM0MjAxNjI1OUxHTjAwX01UTC50eHQiCiAgICBCUEZfTkFNRV9PTEkgPSAiTE84QlBGMjAxNjA5MTUxODMwNTdfMjAxNjA5MTUyMDA5NTAuMDEiCiAgICBCUEZfTkFNRV9USVJTID0gIkxUOEJQRjIwMTYwOTAyMDg0MTIyXzIwMTYwOTE3MDc0MDI3LjAyIgogICAgQ1BGX05BTUUgPSAiTDhDUEYyMDE2MDcwMV8yMDE2MDkzMC4wMiIKICAgIFJMVVRfRklMRV9OQU1FID0gIkw4UkxVVDIwMTUwMzAzXzIwNDMxMjMxdjExLmg1IgogIEVORF9HUk9VUCA9IFBST0RVQ1RfTUVUQURBVEEKICBHUk9VUCA9IElNQUdFX0FUVFJJQlVURVMKICAgIENMT1VEX0NPVkVSID0gMjkuNTYKICAgIENMT1VEX0NPVkVSX0xBTkQgPSAzLjMzCiAgICBJTUFHRV9RVUFMSVRZX09MSSA9IDkKICAgIElNQUdFX1FVQUxJVFlfVElSUyA9IDkKICAgIFRJUlNfU1NNX01PREVMID0gIkZJTkFMIgogICAgVElSU19TU01fUE9TSVRJT05fU1RBVFVTID0gIkVTVElNQVRFRCIKICAgIFJPTExfQU5HTEUgPSAtMC4wMDEKICAgIFNVTl9BWklNVVRIID0gMTQ4LjQ4MDQ5Mzk2CiAgICBTVU5fRUxFVkFUSU9OID0gNTAuOTM3NjgzOTkKICAgIEVBUlRIX1NVTl9ESVNUQU5DRSA9IDEuMDA1Mzc1MgogICAgR1JPVU5EX0NPTlRST0xfUE9JTlRTX1ZFUlNJT04gPSA0CiAgICBHUk9VTkRfQ09OVFJPTF9QT0lOVFNfTU9ERUwgPSA1NDgKICAgIEdFT01FVFJJQ19STVNFX01PREVMID0gNS44NTcKICAgIEdFT01FVFJJQ19STVNFX01PREVMX1kgPSAzLjg0MQogICAgR0VPTUVUUklDX1JNU0VfTU9ERUxfWCA9IDQuNDIyCiAgICBHUk9VTkRfQ09OVFJPTF9QT0lOVFNfVkVSSUZZID0gMjI4CiAgICBHRU9NRVRSSUNfUk1TRV9WRVJJRlkgPSAzLjM4MgogIEVORF9HUk9VUCA9IElNQUdFX0FUVFJJQlVURVMKICBHUk9VUCA9IE1JTl9NQVhfUkFESUFOQ0UKICAgIFJBRElBTkNFX01BWElNVU1fQkFORF8xID0gNzUxLjk1NzA5CiAgICBSQURJQU5DRV9NSU5JTVVNX0JBTkRfMSA9IC02Mi4wOTY4NgogICAgUkFESUFOQ0VfTUFYSU1VTV9CQU5EXzIgPSA3NzAuMDEzMTgKICAgIFJBRElBTkNFX01JTklNVU1fQkFORF8yID0gLTYzLjU4Nzk0CiAgICBSQURJQU5DRV9NQVhJTVVNX0JBTkRfMyA9IDcwOS41NjA2MQogICAgUkFESUFOQ0VfTUlOSU1VTV9CQU5EXzMgPSAtNTguNTk1NzUKICAgIFJBRElBTkNFX01BWElNVU1fQkFORF80ID0gNTk4LjM0MTQ5CiAgICBSQURJQU5DRV9NSU5JTVVNX0JBTkRfNCA9IC00OS40MTEyMwogICAgUkFESUFOQ0VfTUFYSU1VTV9CQU5EXzUgPSAzNjYuMTU1MTUKICAgIFJBRElBTkNFX01JTklNVU1fQkFORF81ID0gLTMwLjIzNzIxCiAgICBSQURJQU5DRV9NQVhJTVVNX0JBTkRfNiA9IDkxLjA1OTQ2CiAgICBSQURJQU5DRV9NSU5JTVVNX0JBTkRfNiA9IC03LjUxOTcyCiAgICBSQURJQU5DRV9NQVhJTVVNX0JBTkRfNyA9IDMwLjY5MTkxCiAgICBSQURJQU5DRV9NSU5JTVVNX0JBTkRfNyA9IC0yLjUzNDU1CiAgICBSQURJQU5DRV9NQVhJTVVNX0JBTkRfOCA9IDY3Ny4xNTc4NAogICAgUkFESUFOQ0VfTUlOSU1VTV9CQU5EXzggPSAtNTUuOTE5OTIKICAgIFJBRElBTkNFX01BWElNVU1fQkFORF85ID0gMTQzLjEwMTczCiAgICBSQURJQU5DRV9NSU5JTVVNX0JBTkRfOSA9IC0xMS44MTczOQogICAgUkFESUFOQ0VfTUFYSU1VTV9CQU5EXzEwID0gMjIuMDAxODAKICAgIFJBRElBTkNFX01JTklNVU1fQkFORF8xMCA9IDAuMTAwMzMKICAgIFJBRElBTkNFX01BWElNVU1fQkFORF8xMSA9IDIyLjAwMTgwCiAgICBSQURJQU5DRV9NSU5JTVVNX0JBTkRfMTEgPSAwLjEwMDMzCiAgRU5EX0dST1VQID0gTUlOX01BWF9SQURJQU5DRQogIEdST1VQID0gTUlOX01BWF9SRUZMRUNUQU5DRQogICAgUkVGTEVDVEFOQ0VfTUFYSU1VTV9CQU5EXzEgPSAxLjIxMDcwMAogICAgUkVGTEVDVEFOQ0VfTUlOSU1VTV9CQU5EXzEgPSAtMC4wOTk5ODAKICAgIFJFRkxFQ1RBTkNFX01BWElNVU1fQkFORF8yID0gMS4yMTA3MDAKICAgIFJFRkxFQ1RBTkNFX01JTklNVU1fQkFORF8yID0gLTAuMDk5OTgwCiAgICBSRUZMRUNUQU5DRV9NQVhJTVVNX0JBTkRfMyA9IDEuMjEwNzAwCiAgICBSRUZMRUNUQU5DRV9NSU5JTVVNX0JBTkRfMyA9IC0wLjA5OTk4MAogICAgUkVGTEVDVEFOQ0VfTUFYSU1VTV9CQU5EXzQgPSAxLjIxMDcwMAogICAgUkVGTEVDVEFOQ0VfTUlOSU1VTV9CQU5EXzQgPSAtMC4wOTk5ODAKICAgIFJFRkxFQ1RBTkNFX01BWElNVU1fQkFORF81ID0gMS4yMTA3MDAKICAgIFJFRkxFQ1RBTkNFX01JTklNVU1fQkFORF81ID0gLTAuMDk5OTgwCiAgICBSRUZMRUNUQU5DRV9NQVhJTVVNX0JBTkRfNiA9IDEuMjEwNzAwCiAgICBSRUZMRUNUQU5DRV9NSU5JTVVNX0JBTkRfNiA9IC0wLjA5OTk4MAogICAgUkVGTEVDVEFOQ0VfTUFYSU1VTV9CQU5EXzcgPSAxLjIxMDcwMAogICAgUkVGTEVDVEFOQ0VfTUlOSU1VTV9CQU5EXzcgPSAtMC4wOTk5ODAKICAgIFJFRkxFQ1RBTkNFX01BWElNVU1fQkFORF84ID0gMS4yMTA3MDAKICAgIFJFRkxFQ1RBTkNFX01JTklNVU1fQkFORF84ID0gLTAuMDk5OTgwCiAgICBSRUZMRUNUQU5DRV9NQVhJTVVNX0JBTkRfOSA9IDEuMjEwNzAwCiAgICBSRUZMRUNUQU5DRV9NSU5JTVVNX0JBTkRfOSA9IC0wLjA5OTk4MAogIEVORF9HUk9VUCA9IE1JTl9NQVhfUkVGTEVDVEFOQ0UKICBHUk9VUCA9IE1JTl9NQVhfUElYRUxfVkFMVUUKICAgIFFVQU5USVpFX0NBTF9NQVhfQkFORF8xID0gNjU1MzUKICAgIFFVQU5USVpFX0NBTF9NSU5fQkFORF8xID0gMQogICAgUVVBTlRJWkVfQ0FMX01BWF9CQU5EXzIgPSA2NTUzNQogICAgUVVBTlRJWkVfQ0FMX01JTl9CQU5EXzIgPSAxCiAgICBRVUFOVElaRV9DQUxfTUFYX0JBTkRfMyA9IDY1NTM1CiAgICBRVUFOVElaRV9DQUxfTUlOX0JBTkRfMyA9IDEKICAgIFFVQU5USVpFX0NBTF9NQVhfQkFORF80ID0gNjU1MzUKICAgIFFVQU5USVpFX0NBTF9NSU5fQkFORF80ID0gMQogICAgUVVBTlRJWkVfQ0FMX01BWF9CQU5EXzUgPSA2NTUzNQogICAgUVVBTlRJWkVfQ0FMX01JTl9CQU5EXzUgPSAxCiAgICBRVUFOVElaRV9DQUxfTUFYX0JBTkRfNiA9IDY1NTM1CiAgICBRVUFOVElaRV9DQUxfTUlOX0JBTkRfNiA9IDEKICAgIFFVQU5USVpFX0NBTF9NQVhfQkFORF83ID0gNjU1MzUKICAgIFFVQU5USVpFX0NBTF9NSU5fQkFORF83ID0gMQogICAgUVVBTlRJWkVfQ0FMX01BWF9CQU5EXzggPSA2NTUzNQogICAgUVVBTlRJWkVfQ0FMX01JTl9CQU5EXzggPSAxCiAgICBRVUFOVElaRV9DQUxfTUFYX0JBTkRfOSA9IDY1NTM1CiAgICBRVUFOVElaRV9DQUxfTUlOX0JBTkRfOSA9IDEKICAgIFFVQU5USVpFX0NBTF9NQVhfQkFORF8xMCA9IDY1NTM1CiAgICBRVUFOVElaRV9DQUxfTUlOX0JBTkRfMTAgPSAxCiAgICBRVUFOVElaRV9DQUxfTUFYX0JBTkRfMTEgPSA2NTUzNQogICAgUVVBTlRJWkVfQ0FMX01JTl9CQU5EXzExID0gMQogIEVORF9HUk9VUCA9IE1JTl9NQVhfUElYRUxfVkFMVUUKICBHUk9VUCA9IFJBRElPTUVUUklDX1JFU0NBTElORwogICAgUkFESUFOQ0VfTVVMVF9CQU5EXzEgPSAxLjI0MjJFLTAyCiAgICBSQURJQU5DRV9NVUxUX0JBTkRfMiA9IDEuMjcyMEUtMDIKICAgIFJBRElBTkNFX01VTFRfQkFORF8zID0gMS4xNzIxRS0wMgogICAgUkFESUFOQ0VfTVVMVF9CQU5EXzQgPSA5Ljg4NDJFLTAzCiAgICBSQURJQU5DRV9NVUxUX0JBTkRfNSA9IDYuMDQ4N0UtMDMKICAgIFJBRElBTkNFX01VTFRfQkFORF82ID0gMS41MDQyRS0wMwogICAgUkFESUFOQ0VfTVVMVF9CQU5EXzcgPSA1LjA3MDFFLTA0CiAgICBSQURJQU5DRV9NVUxUX0JBTkRfOCA9IDEuMTE4NkUtMDIKICAgIFJBRElBTkNFX01VTFRfQkFORF85ID0gMi4zNjQwRS0wMwogICAgUkFESUFOQ0VfTVVMVF9CQU5EXzEwID0gMy4zNDIwRS0wNAogICAgUkFESUFOQ0VfTVVMVF9CQU5EXzExID0gMy4zNDIwRS0wNAogICAgUkFESUFOQ0VfQUREX0JBTkRfMSA9IC02Mi4xMDkyOAogICAgUkFESUFOQ0VfQUREX0JBTkRfMiA9IC02My42MDA2NgogICAgUkFESUFOQ0VfQUREX0JBTkRfMyA9IC01OC42MDc0NwogICAgUkFESUFOQ0VfQUREX0JBTkRfNCA9IC00OS40MjExMgogICAgUkFESUFOQ0VfQUREX0JBTkRfNSA9IC0zMC4yNDMyNgogICAgUkFESUFOQ0VfQUREX0JBTkRfNiA9IC03LjUyMTIyCiAgICBSQURJQU5DRV9BRERfQkFORF83ID0gLTIuNTM1MDUKICAgIFJBRElBTkNFX0FERF9CQU5EXzggPSAtNTUuOTMxMTAKICAgIFJBRElBTkNFX0FERF9CQU5EXzkgPSAtMTEuODE5NzUKICAgIFJBRElBTkNFX0FERF9CQU5EXzEwID0gMC4xMDAwMAogICAgUkFESUFOQ0VfQUREX0JBTkRfMTEgPSAwLjEwMDAwCiAgICBSRUZMRUNUQU5DRV9NVUxUX0JBTkRfMSA9IDIuMDAwMEUtMDUKICAgIFJFRkxFQ1RBTkNFX01VTFRfQkFORF8yID0gMi4wMDAwRS0wNQogICAgUkVGTEVDVEFOQ0VfTVVMVF9CQU5EXzMgPSAyLjAwMDBFLTA1CiAgICBSRUZMRUNUQU5DRV9NVUxUX0JBTkRfNCA9IDIuMDAwMEUtMDUKICAgIFJFRkxFQ1RBTkNFX01VTFRfQkFORF81ID0gMi4wMDAwRS0wNQogICAgUkVGTEVDVEFOQ0VfTVVMVF9CQU5EXzYgPSAyLjAwMDBFLTA1CiAgICBSRUZMRUNUQU5DRV9NVUxUX0JBTkRfNyA9IDIuMDAwMEUtMDUKICAgIFJFRkxFQ1RBTkNFX01VTFRfQkFORF84ID0gMi4wMDAwRS0wNQogICAgUkVGTEVDVEFOQ0VfTVVMVF9CQU5EXzkgPSAyLjAwMDBFLTA1CiAgICBSRUZMRUNUQU5DRV9BRERfQkFORF8xID0gLTAuMTAwMDAwCiAgICBSRUZMRUNUQU5DRV9BRERfQkFORF8yID0gLTAuMTAwMDAwCiAgICBSRUZMRUNUQU5DRV9BRERfQkFORF8zID0gLTAuMTAwMDAwCiAgICBSRUZMRUNUQU5DRV9BRERfQkFORF80ID0gLTAuMTAwMDAwCiAgICBSRUZMRUNUQU5DRV9BRERfQkFORF81ID0gLTAuMTAwMDAwCiAgICBSRUZMRUNUQU5DRV9BRERfQkFORF82ID0gLTAuMTAwMDAwCiAgICBSRUZMRUNUQU5DRV9BRERfQkFORF83ID0gLTAuMTAwMDAwCiAgICBSRUZMRUNUQU5DRV9BRERfQkFORF84ID0gLTAuMTAwMDAwCiAgICBSRUZMRUNUQU5DRV9BRERfQkFORF85ID0gLTAuMTAwMDAwCiAgRU5EX0dST1VQID0gUkFESU9NRVRSSUNfUkVTQ0FMSU5HCiAgR1JPVVAgPSBUSVJTX1RIRVJNQUxfQ09OU1RBTlRTCiAgICBLMV9DT05TVEFOVF9CQU5EXzEwID0gNzc0Ljg4NTMKICAgIEsxX0NPTlNUQU5UX0JBTkRfMTEgPSA0ODAuODg4MwogICAgSzJfQ09OU1RBTlRfQkFORF8xMCA9IDEzMjEuMDc4OQogICAgSzJfQ09OU1RBTlRfQkFORF8xMSA9IDEyMDEuMTQ0MgogIEVORF9HUk9VUCA9IFRJUlNfVEhFUk1BTF9DT05TVEFOVFMKICBHUk9VUCA9IFBST0pFQ1RJT05fUEFSQU1FVEVSUwogICAgTUFQX1BST0pFQ1RJT04gPSAiVVRNIgogICAgREFUVU0gPSAiV0dTODQiCiAgICBFTExJUFNPSUQgPSAiV0dTODQiCiAgICBVVE1fWk9ORSA9IDEwCiAgICBHUklEX0NFTExfU0laRV9QQU5DSFJPTUFUSUMgPSAxNS4wMAogICAgR1JJRF9DRUxMX1NJWkVfUkVGTEVDVElWRSA9IDMwLjAwCiAgICBHUklEX0NFTExfU0laRV9USEVSTUFMID0gMzAuMDAKICAgIE9SSUVOVEFUSU9OID0gIk5PUlRIX1VQIgogICAgUkVTQU1QTElOR19PUFRJT04gPSAiQ1VCSUNfQ09OVk9MVVRJT04iCiAgRU5EX0dST1VQID0gUFJPSkVDVElPTl9QQVJBTUVURVJTCkVORF9HUk9VUCA9IEwxX01FVEFEQVRBX0ZJTEUKRU5ECg==" } }, { "ID": "55eeb942e5603431", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/gcp-public-data-landsat/LC08/PRE/044/034/LC80440342016259LGN00/LC80440342016259LGN00_MTL.txt", "Header": { "Range": [ "bytes=1-" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 206, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "public, max-age=3600" ], "Content-Length": [ "7902" ], "Content-Range": [ "bytes 1-7902/7903" ], "Content-Type": [ "application/octet-stream" ], "Date": [ "Thu, 02 May 2019 22:25:27 GMT" ], "Etag": [ "\"7a5fd4743bd647485f88496fadb05c51\"" ], "Expires": [ "Thu, 02 May 2019 23:25:27 GMT" ], "Last-Modified": [ "Tue, 04 Oct 2016 16:42:07 GMT" ], "Server": [ "UploadServer" ], "X-Goog-Generation": [ "1475599327662000" ], "X-Goog-Hash": [ "crc32c=PWBt8g==", "md5=el/UdDvWR0hfiElvrbBcUQ==" ], "X-Goog-Metageneration": [ "1" ], "X-Goog-Storage-Class": [ "STANDARD" ], "X-Goog-Stored-Content-Encoding": [ "identity" ], "X-Goog-Stored-Content-Length": [ "7903" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqlAytrsQn43Os8JxSOx4C8v9ApqqtqwEE7kZ-voKAcmcYe32lG7ANHxzNrwkqN8bbLLohoAHd88brZDVaC3U6Q01dhBBoeDFnlkCzHKUJjA8ZWrgM" ] }, "Body": "Uk9VUCA9IEwxX01FVEFEQVRBX0ZJTEUKICBHUk9VUCA9IE1FVEFEQVRBX0ZJTEVfSU5GTwogICAgT1JJR0lOID0gIkltYWdlIGNvdXJ0ZXN5IG9mIHRoZSBVLlMuIEdlb2xvZ2ljYWwgU3VydmV5IgogICAgUkVRVUVTVF9JRCA9ICIwNzAxNjA5MTkxMDUxXzAwMDA0IgogICAgTEFORFNBVF9TQ0VORV9JRCA9ICJMQzgwNDQwMzQyMDE2MjU5TEdOMDAiCiAgICBGSUxFX0RBVEUgPSAyMDE2LTA5LTIwVDAzOjEzOjAyWgogICAgU1RBVElPTl9JRCA9ICJMR04iCiAgICBQUk9DRVNTSU5HX1NPRlRXQVJFX1ZFUlNJT04gPSAiTFBHU18yLjYuMiIKICBFTkRfR1JPVVAgPSBNRVRBREFUQV9GSUxFX0lORk8KICBHUk9VUCA9IFBST0RVQ1RfTUVUQURBVEEKICAgIERBVEFfVFlQRSA9ICJMMVQiCiAgICBFTEVWQVRJT05fU09VUkNFID0gIkdMUzIwMDAiCiAgICBPVVRQVVRfRk9STUFUID0gIkdFT1RJRkYiCiAgICBTUEFDRUNSQUZUX0lEID0gIkxBTkRTQVRfOCIKICAgIFNFTlNPUl9JRCA9ICJPTElfVElSUyIKICAgIFdSU19QQVRIID0gNDQKICAgIFdSU19ST1cgPSAzNAogICAgTkFESVJfT0ZGTkFESVIgPSAiTkFESVIiCiAgICBUQVJHRVRfV1JTX1BBVEggPSA0NAogICAgVEFSR0VUX1dSU19ST1cgPSAzNAogICAgREFURV9BQ1FVSVJFRCA9IDIwMTYtMDktMTUKICAgIFNDRU5FX0NFTlRFUl9USU1FID0gIjE4OjQ2OjE4LjY4NjczODBaIgogICAgQ09STkVSX1VMX0xBVF9QUk9EVUNUID0gMzguNTI4MTkKICAgIENPUk5FUl9VTF9MT05fUFJPRFVDVCA9IC0xMjMuNDA4NDMKICAgIENPUk5FUl9VUl9MQVRfUFJPRFVDVCA9IDM4LjUwNzY1CiAgICBDT1JORVJfVVJfTE9OX1BST0RVQ1QgPSAtMTIwLjc2OTMzCiAgICBDT1JORVJfTExfTEFUX1BST0RVQ1QgPSAzNi40MTYzMwogICAgQ09STkVSX0xMX0xPTl9QUk9EVUNUID0gLTEyMy4zOTcwOQogICAgQ09STkVSX0xSX0xBVF9QUk9EVUNUID0gMzYuMzk3MjkKICAgIENPUk5FUl9MUl9MT05fUFJPRFVDVCA9IC0xMjAuODMxMTcKICAgIENPUk5FUl9VTF9QUk9KRUNUSU9OX1hfUFJPRFVDVCA9IDQ2NDQwMC4wMDAKICAgIENPUk5FUl9VTF9QUk9KRUNUSU9OX1lfUFJPRFVDVCA9IDQyNjQ1MDAuMDAwCiAgICBDT1JORVJfVVJfUFJPSkVDVElPTl9YX1BST0RVQ1QgPSA2OTQ1MDAuMDAwCiAgICBDT1JORVJfVVJfUFJPSkVDVElPTl9ZX1BST0RVQ1QgPSA0MjY0NTAwLjAwMAogICAgQ09STkVSX0xMX1BST0pFQ1RJT05fWF9QUk9EVUNUID0gNDY0NDAwLjAwMAogICAgQ09STkVSX0xMX1BST0pFQ1RJT05fWV9QUk9EVUNUID0gNDAzMDIwMC4wMDAKICAgIENPUk5FUl9MUl9QUk9KRUNUSU9OX1hfUFJPRFVDVCA9IDY5NDUwMC4wMDAKICAgIENPUk5FUl9MUl9QUk9KRUNUSU9OX1lfUFJPRFVDVCA9IDQwMzAyMDAuMDAwCiAgICBQQU5DSFJPTUFUSUNfTElORVMgPSAxNTYyMQogICAgUEFOQ0hST01BVElDX1NBTVBMRVMgPSAxNTM0MQogICAgUkVGTEVDVElWRV9MSU5FUyA9IDc4MTEKICAgIFJFRkxFQ1RJVkVfU0FNUExFUyA9IDc2NzEKICAgIFRIRVJNQUxfTElORVMgPSA3ODExCiAgICBUSEVSTUFMX1NBTVBMRVMgPSA3NjcxCiAgICBGSUxFX05BTUVfQkFORF8xID0gIkxDODA0NDAzNDIwMTYyNTlMR04wMF9CMS5USUYiCiAgICBGSUxFX05BTUVfQkFORF8yID0gIkxDODA0NDAzNDIwMTYyNTlMR04wMF9CMi5USUYiCiAgICBGSUxFX05BTUVfQkFORF8zID0gIkxDODA0NDAzNDIwMTYyNTlMR04wMF9CMy5USUYiCiAgICBGSUxFX05BTUVfQkFORF80ID0gIkxDODA0NDAzNDIwMTYyNTlMR04wMF9CNC5USUYiCiAgICBGSUxFX05BTUVfQkFORF81ID0gIkxDODA0NDAzNDIwMTYyNTlMR04wMF9CNS5USUYiCiAgICBGSUxFX05BTUVfQkFORF82ID0gIkxDODA0NDAzNDIwMTYyNTlMR04wMF9CNi5USUYiCiAgICBGSUxFX05BTUVfQkFORF83ID0gIkxDODA0NDAzNDIwMTYyNTlMR04wMF9CNy5USUYiCiAgICBGSUxFX05BTUVfQkFORF84ID0gIkxDODA0NDAzNDIwMTYyNTlMR04wMF9COC5USUYiCiAgICBGSUxFX05BTUVfQkFORF85ID0gIkxDODA0NDAzNDIwMTYyNTlMR04wMF9COS5USUYiCiAgICBGSUxFX05BTUVfQkFORF8xMCA9ICJMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQjEwLlRJRiIKICAgIEZJTEVfTkFNRV9CQU5EXzExID0gIkxDODA0NDAzNDIwMTYyNTlMR04wMF9CMTEuVElGIgogICAgRklMRV9OQU1FX0JBTkRfUVVBTElUWSA9ICJMQzgwNDQwMzQyMDE2MjU5TEdOMDBfQlFBLlRJRiIKICAgIE1FVEFEQVRBX0ZJTEVfTkFNRSA9ICJMQzgwNDQwMzQyMDE2MjU5TEdOMDBfTVRMLnR4dCIKICAgIEJQRl9OQU1FX09MSSA9ICJMTzhCUEYyMDE2MDkxNTE4MzA1N18yMDE2MDkxNTIwMDk1MC4wMSIKICAgIEJQRl9OQU1FX1RJUlMgPSAiTFQ4QlBGMjAxNjA5MDIwODQxMjJfMjAxNjA5MTcwNzQwMjcuMDIiCiAgICBDUEZfTkFNRSA9ICJMOENQRjIwMTYwNzAxXzIwMTYwOTMwLjAyIgogICAgUkxVVF9GSUxFX05BTUUgPSAiTDhSTFVUMjAxNTAzMDNfMjA0MzEyMzF2MTEuaDUiCiAgRU5EX0dST1VQID0gUFJPRFVDVF9NRVRBREFUQQogIEdST1VQID0gSU1BR0VfQVRUUklCVVRFUwogICAgQ0xPVURfQ09WRVIgPSAyOS41NgogICAgQ0xPVURfQ09WRVJfTEFORCA9IDMuMzMKICAgIElNQUdFX1FVQUxJVFlfT0xJID0gOQogICAgSU1BR0VfUVVBTElUWV9USVJTID0gOQogICAgVElSU19TU01fTU9ERUwgPSAiRklOQUwiCiAgICBUSVJTX1NTTV9QT1NJVElPTl9TVEFUVVMgPSAiRVNUSU1BVEVEIgogICAgUk9MTF9BTkdMRSA9IC0wLjAwMQogICAgU1VOX0FaSU1VVEggPSAxNDguNDgwNDkzOTYKICAgIFNVTl9FTEVWQVRJT04gPSA1MC45Mzc2ODM5OQogICAgRUFSVEhfU1VOX0RJU1RBTkNFID0gMS4wMDUzNzUyCiAgICBHUk9VTkRfQ09OVFJPTF9QT0lOVFNfVkVSU0lPTiA9IDQKICAgIEdST1VORF9DT05UUk9MX1BPSU5UU19NT0RFTCA9IDU0OAogICAgR0VPTUVUUklDX1JNU0VfTU9ERUwgPSA1Ljg1NwogICAgR0VPTUVUUklDX1JNU0VfTU9ERUxfWSA9IDMuODQxCiAgICBHRU9NRVRSSUNfUk1TRV9NT0RFTF9YID0gNC40MjIKICAgIEdST1VORF9DT05UUk9MX1BPSU5UU19WRVJJRlkgPSAyMjgKICAgIEdFT01FVFJJQ19STVNFX1ZFUklGWSA9IDMuMzgyCiAgRU5EX0dST1VQID0gSU1BR0VfQVRUUklCVVRFUwogIEdST1VQID0gTUlOX01BWF9SQURJQU5DRQogICAgUkFESUFOQ0VfTUFYSU1VTV9CQU5EXzEgPSA3NTEuOTU3MDkKICAgIFJBRElBTkNFX01JTklNVU1fQkFORF8xID0gLTYyLjA5Njg2CiAgICBSQURJQU5DRV9NQVhJTVVNX0JBTkRfMiA9IDc3MC4wMTMxOAogICAgUkFESUFOQ0VfTUlOSU1VTV9CQU5EXzIgPSAtNjMuNTg3OTQKICAgIFJBRElBTkNFX01BWElNVU1fQkFORF8zID0gNzA5LjU2MDYxCiAgICBSQURJQU5DRV9NSU5JTVVNX0JBTkRfMyA9IC01OC41OTU3NQogICAgUkFESUFOQ0VfTUFYSU1VTV9CQU5EXzQgPSA1OTguMzQxNDkKICAgIFJBRElBTkNFX01JTklNVU1fQkFORF80ID0gLTQ5LjQxMTIzCiAgICBSQURJQU5DRV9NQVhJTVVNX0JBTkRfNSA9IDM2Ni4xNTUxNQogICAgUkFESUFOQ0VfTUlOSU1VTV9CQU5EXzUgPSAtMzAuMjM3MjEKICAgIFJBRElBTkNFX01BWElNVU1fQkFORF82ID0gOTEuMDU5NDYKICAgIFJBRElBTkNFX01JTklNVU1fQkFORF82ID0gLTcuNTE5NzIKICAgIFJBRElBTkNFX01BWElNVU1fQkFORF83ID0gMzAuNjkxOTEKICAgIFJBRElBTkNFX01JTklNVU1fQkFORF83ID0gLTIuNTM0NTUKICAgIFJBRElBTkNFX01BWElNVU1fQkFORF84ID0gNjc3LjE1Nzg0CiAgICBSQURJQU5DRV9NSU5JTVVNX0JBTkRfOCA9IC01NS45MTk5MgogICAgUkFESUFOQ0VfTUFYSU1VTV9CQU5EXzkgPSAxNDMuMTAxNzMKICAgIFJBRElBTkNFX01JTklNVU1fQkFORF85ID0gLTExLjgxNzM5CiAgICBSQURJQU5DRV9NQVhJTVVNX0JBTkRfMTAgPSAyMi4wMDE4MAogICAgUkFESUFOQ0VfTUlOSU1VTV9CQU5EXzEwID0gMC4xMDAzMwogICAgUkFESUFOQ0VfTUFYSU1VTV9CQU5EXzExID0gMjIuMDAxODAKICAgIFJBRElBTkNFX01JTklNVU1fQkFORF8xMSA9IDAuMTAwMzMKICBFTkRfR1JPVVAgPSBNSU5fTUFYX1JBRElBTkNFCiAgR1JPVVAgPSBNSU5fTUFYX1JFRkxFQ1RBTkNFCiAgICBSRUZMRUNUQU5DRV9NQVhJTVVNX0JBTkRfMSA9IDEuMjEwNzAwCiAgICBSRUZMRUNUQU5DRV9NSU5JTVVNX0JBTkRfMSA9IC0wLjA5OTk4MAogICAgUkVGTEVDVEFOQ0VfTUFYSU1VTV9CQU5EXzIgPSAxLjIxMDcwMAogICAgUkVGTEVDVEFOQ0VfTUlOSU1VTV9CQU5EXzIgPSAtMC4wOTk5ODAKICAgIFJFRkxFQ1RBTkNFX01BWElNVU1fQkFORF8zID0gMS4yMTA3MDAKICAgIFJFRkxFQ1RBTkNFX01JTklNVU1fQkFORF8zID0gLTAuMDk5OTgwCiAgICBSRUZMRUNUQU5DRV9NQVhJTVVNX0JBTkRfNCA9IDEuMjEwNzAwCiAgICBSRUZMRUNUQU5DRV9NSU5JTVVNX0JBTkRfNCA9IC0wLjA5OTk4MAogICAgUkVGTEVDVEFOQ0VfTUFYSU1VTV9CQU5EXzUgPSAxLjIxMDcwMAogICAgUkVGTEVDVEFOQ0VfTUlOSU1VTV9CQU5EXzUgPSAtMC4wOTk5ODAKICAgIFJFRkxFQ1RBTkNFX01BWElNVU1fQkFORF82ID0gMS4yMTA3MDAKICAgIFJFRkxFQ1RBTkNFX01JTklNVU1fQkFORF82ID0gLTAuMDk5OTgwCiAgICBSRUZMRUNUQU5DRV9NQVhJTVVNX0JBTkRfNyA9IDEuMjEwNzAwCiAgICBSRUZMRUNUQU5DRV9NSU5JTVVNX0JBTkRfNyA9IC0wLjA5OTk4MAogICAgUkVGTEVDVEFOQ0VfTUFYSU1VTV9CQU5EXzggPSAxLjIxMDcwMAogICAgUkVGTEVDVEFOQ0VfTUlOSU1VTV9CQU5EXzggPSAtMC4wOTk5ODAKICAgIFJFRkxFQ1RBTkNFX01BWElNVU1fQkFORF85ID0gMS4yMTA3MDAKICAgIFJFRkxFQ1RBTkNFX01JTklNVU1fQkFORF85ID0gLTAuMDk5OTgwCiAgRU5EX0dST1VQID0gTUlOX01BWF9SRUZMRUNUQU5DRQogIEdST1VQID0gTUlOX01BWF9QSVhFTF9WQUxVRQogICAgUVVBTlRJWkVfQ0FMX01BWF9CQU5EXzEgPSA2NTUzNQogICAgUVVBTlRJWkVfQ0FMX01JTl9CQU5EXzEgPSAxCiAgICBRVUFOVElaRV9DQUxfTUFYX0JBTkRfMiA9IDY1NTM1CiAgICBRVUFOVElaRV9DQUxfTUlOX0JBTkRfMiA9IDEKICAgIFFVQU5USVpFX0NBTF9NQVhfQkFORF8zID0gNjU1MzUKICAgIFFVQU5USVpFX0NBTF9NSU5fQkFORF8zID0gMQogICAgUVVBTlRJWkVfQ0FMX01BWF9CQU5EXzQgPSA2NTUzNQogICAgUVVBTlRJWkVfQ0FMX01JTl9CQU5EXzQgPSAxCiAgICBRVUFOVElaRV9DQUxfTUFYX0JBTkRfNSA9IDY1NTM1CiAgICBRVUFOVElaRV9DQUxfTUlOX0JBTkRfNSA9IDEKICAgIFFVQU5USVpFX0NBTF9NQVhfQkFORF82ID0gNjU1MzUKICAgIFFVQU5USVpFX0NBTF9NSU5fQkFORF82ID0gMQogICAgUVVBTlRJWkVfQ0FMX01BWF9CQU5EXzcgPSA2NTUzNQogICAgUVVBTlRJWkVfQ0FMX01JTl9CQU5EXzcgPSAxCiAgICBRVUFOVElaRV9DQUxfTUFYX0JBTkRfOCA9IDY1NTM1CiAgICBRVUFOVElaRV9DQUxfTUlOX0JBTkRfOCA9IDEKICAgIFFVQU5USVpFX0NBTF9NQVhfQkFORF85ID0gNjU1MzUKICAgIFFVQU5USVpFX0NBTF9NSU5fQkFORF85ID0gMQogICAgUVVBTlRJWkVfQ0FMX01BWF9CQU5EXzEwID0gNjU1MzUKICAgIFFVQU5USVpFX0NBTF9NSU5fQkFORF8xMCA9IDEKICAgIFFVQU5USVpFX0NBTF9NQVhfQkFORF8xMSA9IDY1NTM1CiAgICBRVUFOVElaRV9DQUxfTUlOX0JBTkRfMTEgPSAxCiAgRU5EX0dST1VQID0gTUlOX01BWF9QSVhFTF9WQUxVRQogIEdST1VQID0gUkFESU9NRVRSSUNfUkVTQ0FMSU5HCiAgICBSQURJQU5DRV9NVUxUX0JBTkRfMSA9IDEuMjQyMkUtMDIKICAgIFJBRElBTkNFX01VTFRfQkFORF8yID0gMS4yNzIwRS0wMgogICAgUkFESUFOQ0VfTVVMVF9CQU5EXzMgPSAxLjE3MjFFLTAyCiAgICBSQURJQU5DRV9NVUxUX0JBTkRfNCA9IDkuODg0MkUtMDMKICAgIFJBRElBTkNFX01VTFRfQkFORF81ID0gNi4wNDg3RS0wMwogICAgUkFESUFOQ0VfTVVMVF9CQU5EXzYgPSAxLjUwNDJFLTAzCiAgICBSQURJQU5DRV9NVUxUX0JBTkRfNyA9IDUuMDcwMUUtMDQKICAgIFJBRElBTkNFX01VTFRfQkFORF84ID0gMS4xMTg2RS0wMgogICAgUkFESUFOQ0VfTVVMVF9CQU5EXzkgPSAyLjM2NDBFLTAzCiAgICBSQURJQU5DRV9NVUxUX0JBTkRfMTAgPSAzLjM0MjBFLTA0CiAgICBSQURJQU5DRV9NVUxUX0JBTkRfMTEgPSAzLjM0MjBFLTA0CiAgICBSQURJQU5DRV9BRERfQkFORF8xID0gLTYyLjEwOTI4CiAgICBSQURJQU5DRV9BRERfQkFORF8yID0gLTYzLjYwMDY2CiAgICBSQURJQU5DRV9BRERfQkFORF8zID0gLTU4LjYwNzQ3CiAgICBSQURJQU5DRV9BRERfQkFORF80ID0gLTQ5LjQyMTEyCiAgICBSQURJQU5DRV9BRERfQkFORF81ID0gLTMwLjI0MzI2CiAgICBSQURJQU5DRV9BRERfQkFORF82ID0gLTcuNTIxMjIKICAgIFJBRElBTkNFX0FERF9CQU5EXzcgPSAtMi41MzUwNQogICAgUkFESUFOQ0VfQUREX0JBTkRfOCA9IC01NS45MzExMAogICAgUkFESUFOQ0VfQUREX0JBTkRfOSA9IC0xMS44MTk3NQogICAgUkFESUFOQ0VfQUREX0JBTkRfMTAgPSAwLjEwMDAwCiAgICBSQURJQU5DRV9BRERfQkFORF8xMSA9IDAuMTAwMDAKICAgIFJFRkxFQ1RBTkNFX01VTFRfQkFORF8xID0gMi4wMDAwRS0wNQogICAgUkVGTEVDVEFOQ0VfTVVMVF9CQU5EXzIgPSAyLjAwMDBFLTA1CiAgICBSRUZMRUNUQU5DRV9NVUxUX0JBTkRfMyA9IDIuMDAwMEUtMDUKICAgIFJFRkxFQ1RBTkNFX01VTFRfQkFORF80ID0gMi4wMDAwRS0wNQogICAgUkVGTEVDVEFOQ0VfTVVMVF9CQU5EXzUgPSAyLjAwMDBFLTA1CiAgICBSRUZMRUNUQU5DRV9NVUxUX0JBTkRfNiA9IDIuMDAwMEUtMDUKICAgIFJFRkxFQ1RBTkNFX01VTFRfQkFORF83ID0gMi4wMDAwRS0wNQogICAgUkVGTEVDVEFOQ0VfTVVMVF9CQU5EXzggPSAyLjAwMDBFLTA1CiAgICBSRUZMRUNUQU5DRV9NVUxUX0JBTkRfOSA9IDIuMDAwMEUtMDUKICAgIFJFRkxFQ1RBTkNFX0FERF9CQU5EXzEgPSAtMC4xMDAwMDAKICAgIFJFRkxFQ1RBTkNFX0FERF9CQU5EXzIgPSAtMC4xMDAwMDAKICAgIFJFRkxFQ1RBTkNFX0FERF9CQU5EXzMgPSAtMC4xMDAwMDAKICAgIFJFRkxFQ1RBTkNFX0FERF9CQU5EXzQgPSAtMC4xMDAwMDAKICAgIFJFRkxFQ1RBTkNFX0FERF9CQU5EXzUgPSAtMC4xMDAwMDAKICAgIFJFRkxFQ1RBTkNFX0FERF9CQU5EXzYgPSAtMC4xMDAwMDAKICAgIFJFRkxFQ1RBTkNFX0FERF9CQU5EXzcgPSAtMC4xMDAwMDAKICAgIFJFRkxFQ1RBTkNFX0FERF9CQU5EXzggPSAtMC4xMDAwMDAKICAgIFJFRkxFQ1RBTkNFX0FERF9CQU5EXzkgPSAtMC4xMDAwMDAKICBFTkRfR1JPVVAgPSBSQURJT01FVFJJQ19SRVNDQUxJTkcKICBHUk9VUCA9IFRJUlNfVEhFUk1BTF9DT05TVEFOVFMKICAgIEsxX0NPTlNUQU5UX0JBTkRfMTAgPSA3NzQuODg1MwogICAgSzFfQ09OU1RBTlRfQkFORF8xMSA9IDQ4MC44ODgzCiAgICBLMl9DT05TVEFOVF9CQU5EXzEwID0gMTMyMS4wNzg5CiAgICBLMl9DT05TVEFOVF9CQU5EXzExID0gMTIwMS4xNDQyCiAgRU5EX0dST1VQID0gVElSU19USEVSTUFMX0NPTlNUQU5UUwogIEdST1VQID0gUFJPSkVDVElPTl9QQVJBTUVURVJTCiAgICBNQVBfUFJPSkVDVElPTiA9ICJVVE0iCiAgICBEQVRVTSA9ICJXR1M4NCIKICAgIEVMTElQU09JRCA9ICJXR1M4NCIKICAgIFVUTV9aT05FID0gMTAKICAgIEdSSURfQ0VMTF9TSVpFX1BBTkNIUk9NQVRJQyA9IDE1LjAwCiAgICBHUklEX0NFTExfU0laRV9SRUZMRUNUSVZFID0gMzAuMDAKICAgIEdSSURfQ0VMTF9TSVpFX1RIRVJNQUwgPSAzMC4wMAogICAgT1JJRU5UQVRJT04gPSAiTk9SVEhfVVAiCiAgICBSRVNBTVBMSU5HX09QVElPTiA9ICJDVUJJQ19DT05WT0xVVElPTiIKICBFTkRfR1JPVVAgPSBQUk9KRUNUSU9OX1BBUkFNRVRFUlMKRU5EX0dST1VQID0gTDFfTUVUQURBVEFfRklMRQpFTkQK" } }, { "ID": "320dc27adc377057", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/gcp-public-data-landsat/LC08/PRE/044/034/LC80440342016259LGN00/LC80440342016259LGN00_MTL.txt", "Header": { "Range": [ "bytes=0-17" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 206, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "public, max-age=3600" ], "Content-Length": [ "18" ], "Content-Range": [ "bytes 0-17/7903" ], "Content-Type": [ "application/octet-stream" ], "Date": [ "Thu, 02 May 2019 22:25:27 GMT" ], "Etag": [ "\"7a5fd4743bd647485f88496fadb05c51\"" ], "Expires": [ "Thu, 02 May 2019 23:25:27 GMT" ], "Last-Modified": [ "Tue, 04 Oct 2016 16:42:07 GMT" ], "Server": [ "UploadServer" ], "X-Goog-Generation": [ "1475599327662000" ], "X-Goog-Hash": [ "crc32c=PWBt8g==", "md5=el/UdDvWR0hfiElvrbBcUQ==" ], "X-Goog-Metageneration": [ "1" ], "X-Goog-Storage-Class": [ "STANDARD" ], "X-Goog-Stored-Content-Encoding": [ "identity" ], "X-Goog-Stored-Content-Length": [ "7903" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UovperPufphUvaf55r54Wd-USAbL2ZQVTseICyulStqI633iJcFBLryyqecsHQcoU2cXp4MsKgB8uQu979IXcnv-aGNm6viDydIrqmPqA7SmPElPGI" ] }, "Body": "R1JPVVAgPSBMMV9NRVRBREFU" } }, { "ID": "a20a4e3b35dfd271", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/storage-library-test-bucket/gzipped-text.txt", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "public, max-age=3600" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "text/plain" ], "Date": [ "Thu, 02 May 2019 22:25:27 GMT" ], "Etag": [ "\"c6117833aa4d1510d09ef69144d56790\"" ], "Expires": [ "Thu, 02 May 2019 23:25:27 GMT" ], "Last-Modified": [ "Tue, 14 Nov 2017 13:07:32 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Accept-Encoding" ], "X-Goog-Generation": [ "1510664852486988" ], "X-Goog-Hash": [ "crc32c=T1s5RQ==", "md5=xhF4M6pNFRDQnvaRRNVnkA==" ], "X-Goog-Metageneration": [ "2" ], "X-Goog-Storage-Class": [ "MULTI_REGIONAL" ], "X-Goog-Stored-Content-Encoding": [ "gzip" ], "X-Goog-Stored-Content-Length": [ "31" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uq7491k1eCc7fe_JApsP1zDcSyo759KmHvh-9YHm9ekpOGaG8v1bZNPjaMEkikJSDYt_LkVMHrb9HTDx9vvDGy3Zm1kPrlxS4933Sw-Wdh35lDomi4" ] }, "Body": "H4sIAAAAAAAAC8tIzcnJVyjPL8pJAQCFEUoNCwAAAA==" } }, { "ID": "d1941f2e08f3bc52", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/storage-library-test-bucket/gzipped-text.txt", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "public, max-age=3600" ], "Content-Encoding": [ "gzip" ], "Content-Type": [ "text/plain" ], "Date": [ "Thu, 02 May 2019 22:25:27 GMT" ], "Etag": [ "\"c6117833aa4d1510d09ef69144d56790\"" ], "Expires": [ "Thu, 02 May 2019 23:25:27 GMT" ], "Last-Modified": [ "Tue, 14 Nov 2017 13:07:32 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Accept-Encoding" ], "X-Goog-Generation": [ "1510664852486988" ], "X-Goog-Hash": [ "crc32c=T1s5RQ==", "md5=xhF4M6pNFRDQnvaRRNVnkA==" ], "X-Goog-Metageneration": [ "2" ], "X-Goog-Storage-Class": [ "MULTI_REGIONAL" ], "X-Goog-Stored-Content-Encoding": [ "gzip" ], "X-Goog-Stored-Content-Length": [ "31" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoYIJ-m0VbRdjw7ZGI_0TiIfj6fcuhJkomWPdQGApFxH2_LnekHIdv7igEpJAM3a-zrTOzR20bzvc-JBunTe_-f_Hsyxz_VPxJNrQY7PSrQ3OMfEhQ" ] }, "Body": "H4sIAAAAAAAAC8tIzcnJVyjPL8pJAQCFEUoNCwAAAA==" } }, { "ID": "2451a87df39e1241", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/storage-library-test-bucket/gzipped-text.txt", "Header": { "Range": [ "bytes=1-8" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "public, max-age=3600" ], "Content-Type": [ "text/plain" ], "Date": [ "Thu, 02 May 2019 22:25:27 GMT" ], "Etag": [ "W/\"c6117833aa4d1510d09ef69144d56790\"" ], "Expires": [ "Thu, 02 May 2019 23:25:27 GMT" ], "Last-Modified": [ "Tue, 14 Nov 2017 13:07:32 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Accept-Encoding" ], "Warning": [ "214 UploadServer gunzipped" ], "X-Goog-Generation": [ "1510664852486988" ], "X-Goog-Hash": [ "crc32c=T1s5RQ==", "md5=xhF4M6pNFRDQnvaRRNVnkA==" ], "X-Goog-Metageneration": [ "2" ], "X-Goog-Storage-Class": [ "MULTI_REGIONAL" ], "X-Goog-Stored-Content-Encoding": [ "gzip" ], "X-Goog-Stored-Content-Length": [ "31" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Response-Body-Transformations": [ "gunzipped" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoNfvi75DBdUL5KpenQbqbsYr5A8YSQp2lGAPIhe4FlijJP95WctTUrdrLIyq3riprP50HzntCuw7zh5ycZfqbJBkFbibeIwEp5bVDj7yVpJbqctiI" ] }, "Body": "aGVsbG8gd29ybGQ=" } }, { "ID": "f0e47a86731e8924", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/storage-library-test-bucket/gzipped-text.txt", "Header": { "Accept-Encoding": [ "gzip" ], "Range": [ "bytes=1-8" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 206, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "public, max-age=3600" ], "Content-Encoding": [ "gzip" ], "Content-Range": [ "bytes 1-8/31" ], "Content-Type": [ "text/plain" ], "Date": [ "Thu, 02 May 2019 22:25:27 GMT" ], "Etag": [ "\"c6117833aa4d1510d09ef69144d56790\"" ], "Expires": [ "Thu, 02 May 2019 23:25:27 GMT" ], "Last-Modified": [ "Tue, 14 Nov 2017 13:07:32 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Accept-Encoding" ], "X-Goog-Generation": [ "1510664852486988" ], "X-Goog-Hash": [ "crc32c=T1s5RQ==", "md5=xhF4M6pNFRDQnvaRRNVnkA==" ], "X-Goog-Metageneration": [ "2" ], "X-Goog-Storage-Class": [ "MULTI_REGIONAL" ], "X-Goog-Stored-Content-Encoding": [ "gzip" ], "X-Goog-Stored-Content-Length": [ "31" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Upzmwe6UNntf6SxdYLZTz0aZiFJ7UANU6y7I2YKJbADGSVoCRe63OoxcC4uh-9n2JEnkvQgq0dwCHCbQ3qmYG4cWFEovG_fIMKFx6O11iPQUhLmeFw" ] }, "Body": "iwgAAAAAAAA=" } }, { "ID": "2a14c414736e344d", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b?alt=json\u0026prettyPrint=false\u0026project=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "168" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb3JzIjpbeyJtYXhBZ2VTZWNvbmRzIjozNjAwLCJtZXRob2QiOlsiUE9TVCJdLCJvcmlnaW4iOlsic29tZS1vcmlnaW4uY29tIl0sInJlc3BvbnNlSGVhZGVyIjpbImZvby1iYXIiXX1dLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA0In0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "593" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:28 GMT" ], "Etag": [ "CAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrgiftU7BDllYqI1jhKj6RbZME3LoakRb653ThaSSD_kzX1O5odabBcDFfG-oswR6YOcDZTW174qxbUaa2G1EvajUt_wJAD3ViGgoMwT_YjoTvObkc" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNCIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA0IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjI4LjAwOVoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNToyOC4wMDlaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiaWFtQ29uZmlndXJhdGlvbiI6eyJidWNrZXRQb2xpY3lPbmx5Ijp7ImVuYWJsZWQiOmZhbHNlfX0sImxvY2F0aW9uIjoiVVMiLCJjb3JzIjpbeyJvcmlnaW4iOlsic29tZS1vcmlnaW4uY29tIl0sIm1ldGhvZCI6WyJQT1NUIl0sInJlc3BvbnNlSGVhZGVyIjpbImZvby1iYXIiXSwibWF4QWdlU2Vjb25kcyI6MzYwMH1dLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsImV0YWciOiJDQUU9In0=" } }, { "ID": "b03cb69547c1a6de", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0004?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "99" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb3JzIjpbeyJtYXhBZ2VTZWNvbmRzIjozNjAwLCJtZXRob2QiOlsiR0VUIl0sIm9yaWdpbiI6WyIqIl0sInJlc3BvbnNlSGVhZGVyIjpbInNvbWUtaGVhZGVyIl19XX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "2528" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:28 GMT" ], "Etag": [ "CAI=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Urw36CL-_RvF58GoVX1bJlTZ1YUUdWXJKQDIac7eTOYj5s65KYFsk2ndonwA5ro_9nGPfo4qRIYyt7J1Xxb01TiJUQPRXzH-z9T_S5UQE6fxOssN0g" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNCIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA0IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjI4LjAwOVoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNToyOC43MjRaIiwibWV0YWdlbmVyYXRpb24iOiIyIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDQvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA0L2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDQiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FJPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA0L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDQvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDQiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDQvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNC9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNCIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUk9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBST0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBST0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsImNvcnMiOlt7Im9yaWdpbiI6WyIqIl0sIm1ldGhvZCI6WyJHRVQiXSwicmVzcG9uc2VIZWFkZXIiOlsic29tZS1oZWFkZXIiXSwibWF4QWdlU2Vjb25kcyI6MzYwMH1dLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsImV0YWciOiJDQUk9In0=" } }, { "ID": "735da673f622341d", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0004?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "2528" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:29 GMT" ], "Etag": [ "CAI=" ], "Expires": [ "Thu, 02 May 2019 22:25:29 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Urb-FeCpjdYOEj6HdkFXRMfVXffmMB8xjLqLwPvjgs3FghXs7r94UrXEpX0rW_CgEpjG6v6iHCWCkwxib31kFkLPMZMMZxHTy66dPT2AdBDsIE8Y8k" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNCIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA0IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjI4LjAwOVoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNToyOC43MjRaIiwibWV0YWdlbmVyYXRpb24iOiIyIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDQvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA0L2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDQiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FJPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA0L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDQvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDQiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDQvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNC9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNCIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUk9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBST0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBST0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsImNvcnMiOlt7Im9yaWdpbiI6WyIqIl0sIm1ldGhvZCI6WyJHRVQiXSwicmVzcG9uc2VIZWFkZXIiOlsic29tZS1oZWFkZXIiXSwibWF4QWdlU2Vjb25kcyI6MzYwMH1dLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsImV0YWciOiJDQUk9In0=" } }, { "ID": "97ce23a7211781ed", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b?alt=json\u0026prettyPrint=false\u0026project=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "168" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb3JzIjpbeyJtYXhBZ2VTZWNvbmRzIjozNjAwLCJtZXRob2QiOlsiUE9TVCJdLCJvcmlnaW4iOlsic29tZS1vcmlnaW4uY29tIl0sInJlc3BvbnNlSGVhZGVyIjpbImZvby1iYXIiXX1dLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA1In0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "593" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:30 GMT" ], "Etag": [ "CAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrqrjU-mu7dGgY6-CuNd9AwgGuKtQ_O589el9eyWSAb54cDYnQN74dl8HxRVzIUayStgIinEuuux2afAlvkUGm9lhrefX8nugBXNL2lGluNcfQKfRo" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNSIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA1IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjI5LjcyNFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNToyOS43MjRaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiaWFtQ29uZmlndXJhdGlvbiI6eyJidWNrZXRQb2xpY3lPbmx5Ijp7ImVuYWJsZWQiOmZhbHNlfX0sImxvY2F0aW9uIjoiVVMiLCJjb3JzIjpbeyJvcmlnaW4iOlsic29tZS1vcmlnaW4uY29tIl0sIm1ldGhvZCI6WyJQT1NUIl0sInJlc3BvbnNlSGVhZGVyIjpbImZvby1iYXIiXSwibWF4QWdlU2Vjb25kcyI6MzYwMH1dLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsImV0YWciOiJDQUU9In0=" } }, { "ID": "a8f5b1c42d7a3c5f", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0005?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "12" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb3JzIjpbXX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "2431" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:30 GMT" ], "Etag": [ "CAI=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpZ4q-BeojZ4WgF5ZHNzJG7sIvdOxmprH5GqoQ3DM-QllSzHWOwAfhVdJZH7WmVK5Dfs1TQH-pKgneNLb_9uYM-rDFb_5Hh9vs89o4pOPT9ob9ezTE" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNSIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA1IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjI5LjcyNFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTozMC42MjhaIiwibWV0YWdlbmVyYXRpb24iOiIyIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDUvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA1L2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDUiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FJPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA1L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDUvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDUiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDUvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNS9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNSIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUk9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBST0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBST0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwiZXRhZyI6IkNBST0ifQ==" } }, { "ID": "cab9472f01ed4bd5", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0005?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "2431" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:31 GMT" ], "Etag": [ "CAI=" ], "Expires": [ "Thu, 02 May 2019 22:25:31 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uo0__TFFuzUsEi6Eck0G1lblGy_1abmyPHERWBavjN2GHncyWWnKQ6yYaFDpDVQ-kfBS15M6H9NoxXUDS0hZ9VX8S9hK4rUGAAFWXznHjOntSK5ldY" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNSIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA1IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjI5LjcyNFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTozMC42MjhaIiwibWV0YWdlbmVyYXRpb24iOiIyIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDUvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA1L2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDUiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FJPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA1L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDUvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDUiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDUvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNS9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNSIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUk9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBST0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBST0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwiZXRhZyI6IkNBST0ifQ==" } }, { "ID": "7a196e6b35872d48", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b?alt=json\u0026prettyPrint=false\u0026project=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "168" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJjb3JzIjpbeyJtYXhBZ2VTZWNvbmRzIjozNjAwLCJtZXRob2QiOlsiUE9TVCJdLCJvcmlnaW4iOlsic29tZS1vcmlnaW4uY29tIl0sInJlc3BvbnNlSGVhZGVyIjpbImZvby1iYXIiXX1dLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA2In0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "593" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:31 GMT" ], "Etag": [ "CAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpJhdZl7X4YXxzKdcr7SJ3C6Xadtlo0ixoS8DNO1jaDHs5MeGKu9nx2pHWPpnUWd13HZ8inxG0pMh3un84TucDfyLu4Z-5Gp7Ka3HBfPnt_w_VTiuE" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNiIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNiIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA2IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjMxLjQwN1oiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTozMS40MDdaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiaWFtQ29uZmlndXJhdGlvbiI6eyJidWNrZXRQb2xpY3lPbmx5Ijp7ImVuYWJsZWQiOmZhbHNlfX0sImxvY2F0aW9uIjoiVVMiLCJjb3JzIjpbeyJvcmlnaW4iOlsic29tZS1vcmlnaW4uY29tIl0sIm1ldGhvZCI6WyJQT1NUIl0sInJlc3BvbnNlSGVhZGVyIjpbImZvby1iYXIiXSwibWF4QWdlU2Vjb25kcyI6MzYwMH1dLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsImV0YWciOiJDQUU9In0=" } }, { "ID": "24b6a3b712ccab17", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0006?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "3" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "e30K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "2539" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:31 GMT" ], "Etag": [ "CAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uqe_Q9NPVf3WTO_It8-A42wh0FD3KyF4kopi6posCEX6l28cnowG8O7WSYwETklwvpp0Uk1fCXiVmgwqLlWCSc3ez-nYllKp5m_UVtxup1E1UNadGg" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNiIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNiIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA2IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjMxLjQwN1oiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTozMS40MDdaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDYvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA2L2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDYiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA2L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDYvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDYiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDYvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNi9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNiIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUU9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBRT0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsImNvcnMiOlt7Im9yaWdpbiI6WyJzb21lLW9yaWdpbi5jb20iXSwibWV0aG9kIjpbIlBPU1QiXSwicmVzcG9uc2VIZWFkZXIiOlsiZm9vLWJhciJdLCJtYXhBZ2VTZWNvbmRzIjozNjAwfV0sInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwiZXRhZyI6IkNBRT0ifQ==" } }, { "ID": "ebed90fad884e1cd", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0006?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "2539" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:32 GMT" ], "Etag": [ "CAE=" ], "Expires": [ "Thu, 02 May 2019 22:25:32 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrjLjhrtR5T2TdsRM6X3HPy_6vnZjhUfpjytCivwknDLKhiMkND-f1qeZ4te6AnGrv_qtnGI4OGajQJaydHJvQZGWpnBQN9VOXHqYjSBTCxnNbcbC4" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNiIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNiIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA2IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjMxLjQwN1oiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTozMS40MDdaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDYvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA2L2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDYiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA2L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDYvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDYiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDYvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNi9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNiIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUU9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBRT0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsImNvcnMiOlt7Im9yaWdpbiI6WyJzb21lLW9yaWdpbi5jb20iXSwibWV0aG9kIjpbIlBPU1QiXSwicmVzcG9uc2VIZWFkZXIiOlsiZm9vLWJhciJdLCJtYXhBZ2VTZWNvbmRzIjozNjAwfV0sInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwiZXRhZyI6IkNBRT0ifQ==" } }, { "ID": "31ee7f558375c66a", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0006?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:25:32 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Up70C3kZ6tTqgyRHbTyjXA5pLWMohouKPHCPhexU8UuWw0cAmLxjHcwaa2xBT-Soq-CLyVxoWeEkxFMhRqqK87xaM38Q2hSjGkeXEhmhoZ3iy5s6D8" ] }, "Body": "" } }, { "ID": "72458186a1839a5a", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0005?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:25:32 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpsiYUGF50kaeS-bMsAR51mlDVCwH9HwmqU1hCFSwzrMDgCmGF46ZuQGfqWx4SJprlBWIxaNwT_EQMKQrTQARvFyee5ZOJq21xZUsVEc1iBW0KkiVk" ] }, "Body": "" } }, { "ID": "20fcdf5cb9502a64", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0004?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:25:33 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Up8ALydoTkq1rLUaKiwrh6YEhczTwI3VX8iKuCNoqr6N2BSBvtxD2Qc9De99Svk_4EX82rynlWctsS2F9Ffr4WuDby30_W1Fl7TMWFZGWfo5Wc_nfI" ] }, "Body": "" } }, { "ID": "ace99589753f3389", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b?alt=json\u0026prettyPrint=false\u0026project=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "60" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA3In0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "485" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:33 GMT" ], "Etag": [ "CAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UotVHCMZG4hcbTx20gUPBV1LsUxIAVuDym9d21c2In0VVLzBxOM_DAULuLEd9LTMmpNg6A7yW4yqEsnRlHhAaMbpe7MwAWbadF2gJJ2M7uGdA-rcLQ" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNyIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA3IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjMzLjcwNVoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTozMy43MDVaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiaWFtQ29uZmlndXJhdGlvbiI6eyJidWNrZXRQb2xpY3lPbmx5Ijp7ImVuYWJsZWQiOmZhbHNlfX0sImxvY2F0aW9uIjoiVVMiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsImV0YWciOiJDQUU9In0=" } }, { "ID": "466aeae01d2d2933", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0007?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "2431" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:34 GMT" ], "Etag": [ "CAE=" ], "Expires": [ "Thu, 02 May 2019 22:25:34 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoVuGt1j5ranQuT0nS5bzOIcVM5M42RwIHcF2mKK_H1ctJEqC_djWDMm00OBFXY4yxsTFdQ1ZYjWVnFq8GhUAWUsvsj4_B9Ur8MzJQcbAzG9vHgIjs" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNyIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA3IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjMzLjcwNVoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTozMy43MDVaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDcvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA3L2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDciLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA3L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDcvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDciLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDcvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNy9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNyIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUU9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBRT0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwiZXRhZyI6IkNBRT0ifQ==" } }, { "ID": "34d8505e483be050", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0007?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "31" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJkZWZhdWx0RXZlbnRCYXNlZEhvbGQiOnRydWV9Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "2460" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:34 GMT" ], "Etag": [ "CAI=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uo5A5V7O5JcpElASqEqUZ_UiEjPa-39PCu3SwJk8EE9cHfyeVL5DWQkAss8k9iRx7YjD4ZC7WnzE_ENz95PuKdccjgzeC2GLFAUzA-sR2iEf-lNil4" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNyIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA3IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjMzLjcwNVoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTozNC42MzJaIiwibWV0YWdlbmVyYXRpb24iOiIyIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDcvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA3L2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDciLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FJPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA3L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDcvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDciLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDcvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNy9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNyIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUk9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBST0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBST0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsImRlZmF1bHRFdmVudEJhc2VkSG9sZCI6dHJ1ZSwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJldGFnIjoiQ0FJPSJ9" } }, { "ID": "728568d994e275c7", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0007?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "2460" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:34 GMT" ], "Etag": [ "CAI=" ], "Expires": [ "Thu, 02 May 2019 22:25:34 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrOVH8W8OREkTrF0UKlK3dOp_AAbRF7Rsx16Zbjdl5caBObFjXETVORm7o-d-YYcPIjcrx1mKcQwxHCIXpdE5P6baH6WeY3Wc3JVF7UcQnKna-a_U4" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNyIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA3IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjMzLjcwNVoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTozNC42MzJaIiwibWV0YWdlbmVyYXRpb24iOiIyIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDcvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA3L2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDciLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FJPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA3L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDcvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDciLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDcvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNy9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNyIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUk9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBST0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBST0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsImRlZmF1bHRFdmVudEJhc2VkSG9sZCI6dHJ1ZSwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJldGFnIjoiQ0FJPSJ9" } }, { "ID": "b7230d8a6b23fd8b", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0007?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "35" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJiaWxsaW5nIjp7InJlcXVlc3RlclBheXMiOnRydWV9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "2493" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:35 GMT" ], "Etag": [ "CAM=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uouwpmid1Y6D0uXWBb_WrmlZVHKYnw0RGbreddchrmPzQUE1H_DeclZnbl6Yb2346L4YNt44ZeZWEM2u46h7Zx45lw9rUFxZDQIvlXRn4vT6fW4WQQ" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNyIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA3IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjMzLjcwNVoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTozNS4zMzNaIiwibWV0YWdlbmVyYXRpb24iOiIzIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDcvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA3L2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDciLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FNPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA3L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDcvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDciLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQU09In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDcvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNy9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNyIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQU09In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBTT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQU09In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBTT0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsImRlZmF1bHRFdmVudEJhc2VkSG9sZCI6dHJ1ZSwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJiaWxsaW5nIjp7InJlcXVlc3RlclBheXMiOnRydWV9LCJldGFnIjoiQ0FNPSJ9" } }, { "ID": "ec9da9e78b750503", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0007?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "2493" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:35 GMT" ], "Etag": [ "CAM=" ], "Expires": [ "Thu, 02 May 2019 22:25:35 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uq25oUSnJMHsIEARHohSGtkz5vw7RCXuQupRBliEjCXMeivgUIK0y9C3U4yWEJ-_182SvGUQLvo5rXxymcoyahwAEhfe21FJU_M2IijdiWsSv83eow" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNyIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA3IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjMzLjcwNVoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTozNS4zMzNaIiwibWV0YWdlbmVyYXRpb24iOiIzIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDcvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA3L2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDciLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FNPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA3L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDcvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDciLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQU09In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDcvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNy9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwNyIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQU09In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBTT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQU09In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBTT0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsImRlZmF1bHRFdmVudEJhc2VkSG9sZCI6dHJ1ZSwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJiaWxsaW5nIjp7InJlcXVlc3RlclBheXMiOnRydWV9LCJldGFnIjoiQ0FNPSJ9" } }, { "ID": "ad49d37f07d631a5", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0007?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:25:36 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uq02fbr_iko_zBCbJljbMwyW7mOaz1cqR6AWHm2ac3m9BcqrUXNkmRqxk0R2rZW6SAUC_KzbOze-1wUGY2E0g6wbYLUqcb8IOdqN2-ROvYO49uxzjE" ] }, "Body": "" } }, { "ID": "7b04c14c4e323488", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b?alt=json\u0026prettyPrint=false\u0026project=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "60" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA4In0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "485" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:36 GMT" ], "Etag": [ "CAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrJrrmhbKyKRTvA3_mNqzRsaaMOAAlvn8UMwBiOR77-6X6m5InqoXMb4qoollPzgpcFOmchQ54jFNic0xJf-tiGu0tlrzSdbjh5Hzw8Rl3RnJy_jPw" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOCIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA4IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjM2LjUwMVoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTozNi41MDFaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiaWFtQ29uZmlndXJhdGlvbiI6eyJidWNrZXRQb2xpY3lPbmx5Ijp7ImVuYWJsZWQiOmZhbHNlfX0sImxvY2F0aW9uIjoiVVMiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsImV0YWciOiJDQUU9In0=" } }, { "ID": "ae3e9c648aaff158", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0008/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDgiLCJuYW1lIjoic29tZS1vYmoifQo=", "X7Xb+/Xtxt2fLTn7y+yBvw==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3193" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:37 GMT" ], "Etag": [ "CJbmhujx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrJv7oOcHCzf9atnIPo70j3xSldrZtXTb5CmV1iuM4mMPU4hiBgpDqCAdUDI3i9hlR2qRie9qT30AJNshzO5CSsuzoTQ88W255VO8VVumaCSZ0KXZs" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOC9zb21lLW9iai8xNTU2ODM1OTM3MTM3NDMwIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA4L28vc29tZS1vYmoiLCJuYW1lIjoic29tZS1vYmoiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDgiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTkzNzEzNzQzMCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTozNy4xMzdaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjU6MzcuMTM3WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjM3LjEzN1oiLCJzaXplIjoiMTYiLCJtZDVIYXNoIjoiZExyZG9WZ2p4bEFBR05hWVgxQm1idz09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOC9vL3NvbWUtb2JqP2dlbmVyYXRpb249MTU1NjgzNTkzNzEzNzQzMCZhbHQ9bWVkaWEiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOC9zb21lLW9iai8xNTU2ODM1OTM3MTM3NDMwL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOC9vL3NvbWUtb2JqL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDgiLCJvYmplY3QiOiJzb21lLW9iaiIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTM3MTM3NDMwIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNKYm1odWp4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOC9zb21lLW9iai8xNTU2ODM1OTM3MTM3NDMwL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDgvby9zb21lLW9iai9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOCIsIm9iamVjdCI6InNvbWUtb2JqIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5MzcxMzc0MzAiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDSmJtaHVqeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDgvc29tZS1vYmovMTU1NjgzNTkzNzEzNzQzMC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA4L28vc29tZS1vYmovYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDgiLCJvYmplY3QiOiJzb21lLW9iaiIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTM3MTM3NDMwIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNKYm1odWp4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOC9zb21lLW9iai8xNTU2ODM1OTM3MTM3NDMwL3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDgvby9zb21lLW9iai9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOCIsIm9iamVjdCI6InNvbWUtb2JqIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5MzcxMzc0MzAiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDSmJtaHVqeC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6Ik01ZUcvQT09IiwiZXRhZyI6IkNKYm1odWp4L2VFQ0VBRT0ifQ==" } }, { "ID": "e7a12fdbeb636933", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0008/o/some-obj?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3193" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:37 GMT" ], "Etag": [ "CJbmhujx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uo-mQ6Bnw1qbAyHbMdumiv5YlTBrFQbHo-9tXn02VufGPTp3_Q8nXXp9VIcdRmzH2CJbhaVLu5fUFYZ6VKgcitBwcE-dCwxWrzaljgyT6zmM7x01ls" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOC9zb21lLW9iai8xNTU2ODM1OTM3MTM3NDMwIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA4L28vc29tZS1vYmoiLCJuYW1lIjoic29tZS1vYmoiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDgiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTkzNzEzNzQzMCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTozNy4xMzdaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjU6MzcuMTM3WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjM3LjEzN1oiLCJzaXplIjoiMTYiLCJtZDVIYXNoIjoiZExyZG9WZ2p4bEFBR05hWVgxQm1idz09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOC9vL3NvbWUtb2JqP2dlbmVyYXRpb249MTU1NjgzNTkzNzEzNzQzMCZhbHQ9bWVkaWEiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOC9zb21lLW9iai8xNTU2ODM1OTM3MTM3NDMwL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOC9vL3NvbWUtb2JqL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDgiLCJvYmplY3QiOiJzb21lLW9iaiIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTM3MTM3NDMwIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNKYm1odWp4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOC9zb21lLW9iai8xNTU2ODM1OTM3MTM3NDMwL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDgvby9zb21lLW9iai9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOCIsIm9iamVjdCI6InNvbWUtb2JqIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5MzcxMzc0MzAiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDSmJtaHVqeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDgvc29tZS1vYmovMTU1NjgzNTkzNzEzNzQzMC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA4L28vc29tZS1vYmovYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDgiLCJvYmplY3QiOiJzb21lLW9iaiIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTM3MTM3NDMwIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNKYm1odWp4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOC9zb21lLW9iai8xNTU2ODM1OTM3MTM3NDMwL3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDgvby9zb21lLW9iai9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOCIsIm9iamVjdCI6InNvbWUtb2JqIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5MzcxMzc0MzAiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDSmJtaHVqeC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6Ik01ZUcvQT09IiwiZXRhZyI6IkNKYm1odWp4L2VFQ0VBRT0ifQ==" } }, { "ID": "142eb6c42bc6f90e", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0008/o/some-obj?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "84" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDgiLCJldmVudEJhc2VkSG9sZCI6dHJ1ZX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3215" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:37 GMT" ], "Etag": [ "CJbmhujx/eECEAI=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrBTG1gAXfMDmjm_clsDlv04E6VRtZUsUKnaVr4bC3AIRXILH2f0UebFf1_SmXPSf6Go8sw7TXti9yO112PAG5QNin3LwaSjRuFDSH_unnMZJwRceM" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOC9zb21lLW9iai8xNTU2ODM1OTM3MTM3NDMwIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA4L28vc29tZS1vYmoiLCJuYW1lIjoic29tZS1vYmoiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDgiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTkzNzEzNzQzMCIsIm1ldGFnZW5lcmF0aW9uIjoiMiIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTozNy4xMzdaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjU6MzcuODI1WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjM3LjEzN1oiLCJzaXplIjoiMTYiLCJtZDVIYXNoIjoiZExyZG9WZ2p4bEFBR05hWVgxQm1idz09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOC9vL3NvbWUtb2JqP2dlbmVyYXRpb249MTU1NjgzNTkzNzEzNzQzMCZhbHQ9bWVkaWEiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOC9zb21lLW9iai8xNTU2ODM1OTM3MTM3NDMwL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOC9vL3NvbWUtb2JqL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDgiLCJvYmplY3QiOiJzb21lLW9iaiIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTM3MTM3NDMwIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNKYm1odWp4L2VFQ0VBST0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOC9zb21lLW9iai8xNTU2ODM1OTM3MTM3NDMwL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDgvby9zb21lLW9iai9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOCIsIm9iamVjdCI6InNvbWUtb2JqIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5MzcxMzc0MzAiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDSmJtaHVqeC9lRUNFQUk9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDgvc29tZS1vYmovMTU1NjgzNTkzNzEzNzQzMC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA4L28vc29tZS1vYmovYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDgiLCJvYmplY3QiOiJzb21lLW9iaiIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTM3MTM3NDMwIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNKYm1odWp4L2VFQ0VBST0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOC9zb21lLW9iai8xNTU2ODM1OTM3MTM3NDMwL3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDgvby9zb21lLW9iai9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOCIsIm9iamVjdCI6InNvbWUtb2JqIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5MzcxMzc0MzAiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDSmJtaHVqeC9lRUNFQUk9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6Ik01ZUcvQT09IiwiZXRhZyI6IkNKYm1odWp4L2VFQ0VBST0iLCJldmVudEJhc2VkSG9sZCI6dHJ1ZX0=" } }, { "ID": "12487e4f20538041", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0008/o/some-obj?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3215" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:38 GMT" ], "Etag": [ "CJbmhujx/eECEAI=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqxyG_OCKjwh7TR9zL9nbOGPP1ttxni9cP68b18nTZ7wZ8WqVE0MAGh1XFphNYZEYr-2kdgNgmqQrOvFiNbg6hJi-RfjCWYg0KHPLKfzyWc-gejszc" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOC9zb21lLW9iai8xNTU2ODM1OTM3MTM3NDMwIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA4L28vc29tZS1vYmoiLCJuYW1lIjoic29tZS1vYmoiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDgiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTkzNzEzNzQzMCIsIm1ldGFnZW5lcmF0aW9uIjoiMiIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTozNy4xMzdaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjU6MzcuODI1WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjM3LjEzN1oiLCJzaXplIjoiMTYiLCJtZDVIYXNoIjoiZExyZG9WZ2p4bEFBR05hWVgxQm1idz09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOC9vL3NvbWUtb2JqP2dlbmVyYXRpb249MTU1NjgzNTkzNzEzNzQzMCZhbHQ9bWVkaWEiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOC9zb21lLW9iai8xNTU2ODM1OTM3MTM3NDMwL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOC9vL3NvbWUtb2JqL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDgiLCJvYmplY3QiOiJzb21lLW9iaiIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTM3MTM3NDMwIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNKYm1odWp4L2VFQ0VBST0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOC9zb21lLW9iai8xNTU2ODM1OTM3MTM3NDMwL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDgvby9zb21lLW9iai9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOCIsIm9iamVjdCI6InNvbWUtb2JqIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5MzcxMzc0MzAiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDSmJtaHVqeC9lRUNFQUk9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDgvc29tZS1vYmovMTU1NjgzNTkzNzEzNzQzMC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA4L28vc29tZS1vYmovYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDgiLCJvYmplY3QiOiJzb21lLW9iaiIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTM3MTM3NDMwIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNKYm1odWp4L2VFQ0VBST0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOC9zb21lLW9iai8xNTU2ODM1OTM3MTM3NDMwL3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDgvby9zb21lLW9iai9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOCIsIm9iamVjdCI6InNvbWUtb2JqIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5MzcxMzc0MzAiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDSmJtaHVqeC9lRUNFQUk9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6Ik01ZUcvQT09IiwiZXRhZyI6IkNKYm1odWp4L2VFQ0VBST0iLCJldmVudEJhc2VkSG9sZCI6dHJ1ZX0=" } }, { "ID": "e3a625bb7418cea9", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0008/o/some-obj?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "82" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDgiLCJjb250ZW50VHlwZSI6ImZvbyJ9Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3193" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:38 GMT" ], "Etag": [ "CJbmhujx/eECEAM=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoVf0XeyD5sC9KvHEILX2e7x7VyJ9d9xoyrP3NqGFlsMgvK3zgeOEOXDvSpftUSy4opndA74-LNRkmAi8Q_6wc91iC8OWV7X3VR8kENWwclNK30V_U" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOC9zb21lLW9iai8xNTU2ODM1OTM3MTM3NDMwIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA4L28vc29tZS1vYmoiLCJuYW1lIjoic29tZS1vYmoiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDgiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTkzNzEzNzQzMCIsIm1ldGFnZW5lcmF0aW9uIjoiMyIsImNvbnRlbnRUeXBlIjoiZm9vIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjM3LjEzN1oiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTozOC40MjBaIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjU6MzcuMTM3WiIsInNpemUiOiIxNiIsIm1kNUhhc2giOiJkTHJkb1ZnanhsQUFHTmFZWDFCbWJ3PT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA4L28vc29tZS1vYmo/Z2VuZXJhdGlvbj0xNTU2ODM1OTM3MTM3NDMwJmFsdD1tZWRpYSIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA4L3NvbWUtb2JqLzE1NTY4MzU5MzcxMzc0MzAvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA4L28vc29tZS1vYmovYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOCIsIm9iamVjdCI6InNvbWUtb2JqIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5MzcxMzc0MzAiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0pibWh1angvZUVDRUFNPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA4L3NvbWUtb2JqLzE1NTY4MzU5MzcxMzc0MzAvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOC9vL3NvbWUtb2JqL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA4Iiwib2JqZWN0Ijoic29tZS1vYmoiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTkzNzEzNzQzMCIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNKYm1odWp4L2VFQ0VBTT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOC9zb21lLW9iai8xNTU2ODM1OTM3MTM3NDMwL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDgvby9zb21lLW9iai9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOCIsIm9iamVjdCI6InNvbWUtb2JqIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5MzcxMzc0MzAiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0pibWh1angvZUVDRUFNPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA4L3NvbWUtb2JqLzE1NTY4MzU5MzcxMzc0MzAvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOC9vL3NvbWUtb2JqL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA4Iiwib2JqZWN0Ijoic29tZS1vYmoiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTkzNzEzNzQzMCIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNKYm1odWp4L2VFQ0VBTT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoiTTVlRy9BPT0iLCJldGFnIjoiQ0pibWh1angvZUVDRUFNPSIsImV2ZW50QmFzZWRIb2xkIjp0cnVlfQ==" } }, { "ID": "2290ac6bb34b705b", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0008/o/some-obj?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3193" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:38 GMT" ], "Etag": [ "CJbmhujx/eECEAM=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoKagfJuJDLVLgIcrGtlV_UXlXLSqfEFj2-knllMBWWLktTv22ZfKoeSo8lY6gSfE1LKlvn87WiyJv75QWpcWdXzvablAMBOAZ_XMe-1D8dKZ5ipHs" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOC9zb21lLW9iai8xNTU2ODM1OTM3MTM3NDMwIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA4L28vc29tZS1vYmoiLCJuYW1lIjoic29tZS1vYmoiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDgiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTkzNzEzNzQzMCIsIm1ldGFnZW5lcmF0aW9uIjoiMyIsImNvbnRlbnRUeXBlIjoiZm9vIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjM3LjEzN1oiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTozOC40MjBaIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjU6MzcuMTM3WiIsInNpemUiOiIxNiIsIm1kNUhhc2giOiJkTHJkb1ZnanhsQUFHTmFZWDFCbWJ3PT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA4L28vc29tZS1vYmo/Z2VuZXJhdGlvbj0xNTU2ODM1OTM3MTM3NDMwJmFsdD1tZWRpYSIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA4L3NvbWUtb2JqLzE1NTY4MzU5MzcxMzc0MzAvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA4L28vc29tZS1vYmovYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOCIsIm9iamVjdCI6InNvbWUtb2JqIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5MzcxMzc0MzAiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0pibWh1angvZUVDRUFNPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA4L3NvbWUtb2JqLzE1NTY4MzU5MzcxMzc0MzAvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOC9vL3NvbWUtb2JqL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA4Iiwib2JqZWN0Ijoic29tZS1vYmoiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTkzNzEzNzQzMCIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNKYm1odWp4L2VFQ0VBTT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOC9zb21lLW9iai8xNTU2ODM1OTM3MTM3NDMwL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDgvby9zb21lLW9iai9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOCIsIm9iamVjdCI6InNvbWUtb2JqIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5MzcxMzc0MzAiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0pibWh1angvZUVDRUFNPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA4L3NvbWUtb2JqLzE1NTY4MzU5MzcxMzc0MzAvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOC9vL3NvbWUtb2JqL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA4Iiwib2JqZWN0Ijoic29tZS1vYmoiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTkzNzEzNzQzMCIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNKYm1odWp4L2VFQ0VBTT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoiTTVlRy9BPT0iLCJldGFnIjoiQ0pibWh1angvZUVDRUFNPSIsImV2ZW50QmFzZWRIb2xkIjp0cnVlfQ==" } }, { "ID": "572d50dc9b5ce8a4", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0008/o/some-obj?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "85" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDgiLCJldmVudEJhc2VkSG9sZCI6ZmFsc2V9Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3194" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:39 GMT" ], "Etag": [ "CJbmhujx/eECEAQ=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrWVb2L8OGfosYWTjk_F-zmyNwltYI93f2tqyP4EkOx7hIRpsSG2iGDFXB7SP7DKn-teczhb9tiBKRM7rYG5vcJ5jVinideFoX44khld5BhtRaQsUc" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOC9zb21lLW9iai8xNTU2ODM1OTM3MTM3NDMwIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA4L28vc29tZS1vYmoiLCJuYW1lIjoic29tZS1vYmoiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDgiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTkzNzEzNzQzMCIsIm1ldGFnZW5lcmF0aW9uIjoiNCIsImNvbnRlbnRUeXBlIjoiZm9vIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjM3LjEzN1oiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTozOC45MTlaIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjU6MzcuMTM3WiIsInNpemUiOiIxNiIsIm1kNUhhc2giOiJkTHJkb1ZnanhsQUFHTmFZWDFCbWJ3PT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA4L28vc29tZS1vYmo/Z2VuZXJhdGlvbj0xNTU2ODM1OTM3MTM3NDMwJmFsdD1tZWRpYSIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA4L3NvbWUtb2JqLzE1NTY4MzU5MzcxMzc0MzAvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA4L28vc29tZS1vYmovYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOCIsIm9iamVjdCI6InNvbWUtb2JqIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5MzcxMzc0MzAiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0pibWh1angvZUVDRUFRPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA4L3NvbWUtb2JqLzE1NTY4MzU5MzcxMzc0MzAvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOC9vL3NvbWUtb2JqL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA4Iiwib2JqZWN0Ijoic29tZS1vYmoiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTkzNzEzNzQzMCIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNKYm1odWp4L2VFQ0VBUT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOC9zb21lLW9iai8xNTU2ODM1OTM3MTM3NDMwL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDgvby9zb21lLW9iai9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOCIsIm9iamVjdCI6InNvbWUtb2JqIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5MzcxMzc0MzAiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0pibWh1angvZUVDRUFRPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA4L3NvbWUtb2JqLzE1NTY4MzU5MzcxMzc0MzAvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOC9vL3NvbWUtb2JqL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA4Iiwib2JqZWN0Ijoic29tZS1vYmoiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTkzNzEzNzQzMCIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNKYm1odWp4L2VFQ0VBUT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoiTTVlRy9BPT0iLCJldGFnIjoiQ0pibWh1angvZUVDRUFRPSIsImV2ZW50QmFzZWRIb2xkIjpmYWxzZX0=" } }, { "ID": "bda340f0117c1fb4", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0008/o/some-obj?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:25:39 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UotG32AgmOwDD_bLLd_W64JCOZQ2-UgeY_cOZwomlkWb6Vx5JSE54tdsuCPvawuyJ8eNuCf8EM0qXlIjtAyg6QQiuN9t72vHrQLsrSs6WtJBDGZziU" ] }, "Body": "" } }, { "ID": "9a0b7379af024a3a", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0008?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:25:39 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Ur7S22mcdvPtDq_Z9iUbo4v0ApOQXNFgXFNZuacd8yZUq2FhZKco01Z2T4vJSv8s1yZkGXzoUrAuUKnCBx0vZuE-MDGnmTF_YxhQoXobyvAyktswdE" ] }, "Body": "" } }, { "ID": "affb380cf86f173c", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b?alt=json\u0026prettyPrint=false\u0026project=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "60" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA5In0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "485" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:40 GMT" ], "Etag": [ "CAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrF4q2mbuFoVeV9q22libc-FjfB1eDXSMYhNGZNU6sbaMWEKdc-8eXu1gtMLC7Ia9bSRU0oxgpIRR9516KZRcg7o_VGdrU1lliVPuSY9rYa4OsJymE" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOSIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA5IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjQwLjA4MVoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTo0MC4wODFaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiaWFtQ29uZmlndXJhdGlvbiI6eyJidWNrZXRQb2xpY3lPbmx5Ijp7ImVuYWJsZWQiOmZhbHNlfX0sImxvY2F0aW9uIjoiVVMiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsImV0YWciOiJDQUU9In0=" } }, { "ID": "88123486ecd710ed", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0009/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDkiLCJuYW1lIjoic29tZS1vYmoifQo=", "cGCusp668ZMwY59j94Srfg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3193" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:41 GMT" ], "Etag": [ "CNC/3Onx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrixhGvSHn6UzWmshHjh8Ny2NE4LW-gcPPW4dCm9dZTDfBwtENYMJra88jZlphQFcyabnQwTegZW9_6bL8KYNOsyYQYgdtEDvFFMQeJ9B_IXQbrsgI" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOS9zb21lLW9iai8xNTU2ODM1OTQwNjM4NjcyIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA5L28vc29tZS1vYmoiLCJuYW1lIjoic29tZS1vYmoiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDkiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk0MDYzODY3MiIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTo0MC42MzhaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjU6NDAuNjM4WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjQwLjYzOFoiLCJzaXplIjoiMTYiLCJtZDVIYXNoIjoiUjhVSExIMG84ZjFlTVhVRHRyMTZLZz09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOS9vL3NvbWUtb2JqP2dlbmVyYXRpb249MTU1NjgzNTk0MDYzODY3MiZhbHQ9bWVkaWEiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOS9zb21lLW9iai8xNTU2ODM1OTQwNjM4NjcyL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOS9vL3NvbWUtb2JqL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDkiLCJvYmplY3QiOiJzb21lLW9iaiIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTQwNjM4NjcyIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNOQy8zT254L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOS9zb21lLW9iai8xNTU2ODM1OTQwNjM4NjcyL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDkvby9zb21lLW9iai9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOSIsIm9iamVjdCI6InNvbWUtb2JqIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5NDA2Mzg2NzIiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDTkMvM09ueC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDkvc29tZS1vYmovMTU1NjgzNTk0MDYzODY3Mi9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA5L28vc29tZS1vYmovYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDkiLCJvYmplY3QiOiJzb21lLW9iaiIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTQwNjM4NjcyIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNOQy8zT254L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOS9zb21lLW9iai8xNTU2ODM1OTQwNjM4NjcyL3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDkvby9zb21lLW9iai9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOSIsIm9iamVjdCI6InNvbWUtb2JqIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5NDA2Mzg2NzIiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDTkMvM09ueC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6IjB6R3NGUT09IiwiZXRhZyI6IkNOQy8zT254L2VFQ0VBRT0ifQ==" } }, { "ID": "042e51e8b073dc93", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0009/o/some-obj?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3193" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:41 GMT" ], "Etag": [ "CNC/3Onx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqTH44ERv_v2A5OmhnLVBFOkQ_bPdeDI-MNir5xjrZt1ybrczlk9GwseHZ-kt566XrMnuYGTaCkr4ImF__dpbt98CqMpmYkiJaR1vKcI1DC7o3Dbl8" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOS9zb21lLW9iai8xNTU2ODM1OTQwNjM4NjcyIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA5L28vc29tZS1vYmoiLCJuYW1lIjoic29tZS1vYmoiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDkiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk0MDYzODY3MiIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTo0MC42MzhaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjU6NDAuNjM4WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjQwLjYzOFoiLCJzaXplIjoiMTYiLCJtZDVIYXNoIjoiUjhVSExIMG84ZjFlTVhVRHRyMTZLZz09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOS9vL3NvbWUtb2JqP2dlbmVyYXRpb249MTU1NjgzNTk0MDYzODY3MiZhbHQ9bWVkaWEiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOS9zb21lLW9iai8xNTU2ODM1OTQwNjM4NjcyL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOS9vL3NvbWUtb2JqL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDkiLCJvYmplY3QiOiJzb21lLW9iaiIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTQwNjM4NjcyIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNOQy8zT254L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOS9zb21lLW9iai8xNTU2ODM1OTQwNjM4NjcyL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDkvby9zb21lLW9iai9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOSIsIm9iamVjdCI6InNvbWUtb2JqIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5NDA2Mzg2NzIiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDTkMvM09ueC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDkvc29tZS1vYmovMTU1NjgzNTk0MDYzODY3Mi9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA5L28vc29tZS1vYmovYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDkiLCJvYmplY3QiOiJzb21lLW9iaiIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTQwNjM4NjcyIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNOQy8zT254L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOS9zb21lLW9iai8xNTU2ODM1OTQwNjM4NjcyL3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDkvby9zb21lLW9iai9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOSIsIm9iamVjdCI6InNvbWUtb2JqIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5NDA2Mzg2NzIiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDTkMvM09ueC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6IjB6R3NGUT09IiwiZXRhZyI6IkNOQy8zT254L2VFQ0VBRT0ifQ==" } }, { "ID": "ed898d656784527a", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0009/o/some-obj?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "83" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDkiLCJ0ZW1wb3JhcnlIb2xkIjp0cnVlfQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3214" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:41 GMT" ], "Etag": [ "CNC/3Onx/eECEAI=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Urh-jh9w3q8AC6TmG1NF_6JgV-Js74mV6EkB4ccrlZ1ZCQ9TlA4AhJ-J6rkqtJ9fKiy4YjT_l-TN6dQhnCwZvTUqoaJC-W-z6QQZywuQ1uX9a90PhU" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOS9zb21lLW9iai8xNTU2ODM1OTQwNjM4NjcyIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA5L28vc29tZS1vYmoiLCJuYW1lIjoic29tZS1vYmoiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDkiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk0MDYzODY3MiIsIm1ldGFnZW5lcmF0aW9uIjoiMiIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTo0MC42MzhaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjU6NDEuNTE5WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjQwLjYzOFoiLCJzaXplIjoiMTYiLCJtZDVIYXNoIjoiUjhVSExIMG84ZjFlTVhVRHRyMTZLZz09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOS9vL3NvbWUtb2JqP2dlbmVyYXRpb249MTU1NjgzNTk0MDYzODY3MiZhbHQ9bWVkaWEiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOS9zb21lLW9iai8xNTU2ODM1OTQwNjM4NjcyL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOS9vL3NvbWUtb2JqL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDkiLCJvYmplY3QiOiJzb21lLW9iaiIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTQwNjM4NjcyIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNOQy8zT254L2VFQ0VBST0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOS9zb21lLW9iai8xNTU2ODM1OTQwNjM4NjcyL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDkvby9zb21lLW9iai9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOSIsIm9iamVjdCI6InNvbWUtb2JqIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5NDA2Mzg2NzIiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDTkMvM09ueC9lRUNFQUk9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDkvc29tZS1vYmovMTU1NjgzNTk0MDYzODY3Mi9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA5L28vc29tZS1vYmovYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDkiLCJvYmplY3QiOiJzb21lLW9iaiIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTQwNjM4NjcyIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNOQy8zT254L2VFQ0VBST0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOS9zb21lLW9iai8xNTU2ODM1OTQwNjM4NjcyL3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDkvby9zb21lLW9iai9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOSIsIm9iamVjdCI6InNvbWUtb2JqIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5NDA2Mzg2NzIiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDTkMvM09ueC9lRUNFQUk9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6IjB6R3NGUT09IiwiZXRhZyI6IkNOQy8zT254L2VFQ0VBST0iLCJ0ZW1wb3JhcnlIb2xkIjp0cnVlfQ==" } }, { "ID": "9ddea19a0c44c449", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0009/o/some-obj?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3214" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:41 GMT" ], "Etag": [ "CNC/3Onx/eECEAI=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoZVnUhVRVPu1unMjxNHQzZrlqTsVtPMZHc_YPTkvy18AAD3d_TOg9qTNAEv5NXUC5n0XF1sPedifaWR19a5w7dCMltRYfuJUfGxaMzyrvpqKbGjx4" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOS9zb21lLW9iai8xNTU2ODM1OTQwNjM4NjcyIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA5L28vc29tZS1vYmoiLCJuYW1lIjoic29tZS1vYmoiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDkiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk0MDYzODY3MiIsIm1ldGFnZW5lcmF0aW9uIjoiMiIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTo0MC42MzhaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjU6NDEuNTE5WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjQwLjYzOFoiLCJzaXplIjoiMTYiLCJtZDVIYXNoIjoiUjhVSExIMG84ZjFlTVhVRHRyMTZLZz09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOS9vL3NvbWUtb2JqP2dlbmVyYXRpb249MTU1NjgzNTk0MDYzODY3MiZhbHQ9bWVkaWEiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOS9zb21lLW9iai8xNTU2ODM1OTQwNjM4NjcyL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOS9vL3NvbWUtb2JqL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDkiLCJvYmplY3QiOiJzb21lLW9iaiIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTQwNjM4NjcyIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNOQy8zT254L2VFQ0VBST0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOS9zb21lLW9iai8xNTU2ODM1OTQwNjM4NjcyL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDkvby9zb21lLW9iai9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOSIsIm9iamVjdCI6InNvbWUtb2JqIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5NDA2Mzg2NzIiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDTkMvM09ueC9lRUNFQUk9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDkvc29tZS1vYmovMTU1NjgzNTk0MDYzODY3Mi9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA5L28vc29tZS1vYmovYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDkiLCJvYmplY3QiOiJzb21lLW9iaiIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTQwNjM4NjcyIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNOQy8zT254L2VFQ0VBST0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOS9zb21lLW9iai8xNTU2ODM1OTQwNjM4NjcyL3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDkvby9zb21lLW9iai9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOSIsIm9iamVjdCI6InNvbWUtb2JqIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5NDA2Mzg2NzIiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDTkMvM09ueC9lRUNFQUk9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6IjB6R3NGUT09IiwiZXRhZyI6IkNOQy8zT254L2VFQ0VBST0iLCJ0ZW1wb3JhcnlIb2xkIjp0cnVlfQ==" } }, { "ID": "9b6c4955472bdb51", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0009/o/some-obj?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "82" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDkiLCJjb250ZW50VHlwZSI6ImZvbyJ9Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3192" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:42 GMT" ], "Etag": [ "CNC/3Onx/eECEAM=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoybPBMseeVzkBPlzTObhT-eKnJ9TbsC15btCmXKMDvqgD5Uz4JclrgL9lBqMq09UjP8GL2_3zCDkfA0gJ8SHCDZbHEi1XYcuAUT7hmXazBL3IIMqc" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOS9zb21lLW9iai8xNTU2ODM1OTQwNjM4NjcyIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA5L28vc29tZS1vYmoiLCJuYW1lIjoic29tZS1vYmoiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDkiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk0MDYzODY3MiIsIm1ldGFnZW5lcmF0aW9uIjoiMyIsImNvbnRlbnRUeXBlIjoiZm9vIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjQwLjYzOFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTo0Mi4xMjNaIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjU6NDAuNjM4WiIsInNpemUiOiIxNiIsIm1kNUhhc2giOiJSOFVITEgwbzhmMWVNWFVEdHIxNktnPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA5L28vc29tZS1vYmo/Z2VuZXJhdGlvbj0xNTU2ODM1OTQwNjM4NjcyJmFsdD1tZWRpYSIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA5L3NvbWUtb2JqLzE1NTY4MzU5NDA2Mzg2NzIvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA5L28vc29tZS1vYmovYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOSIsIm9iamVjdCI6InNvbWUtb2JqIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5NDA2Mzg2NzIiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ05DLzNPbngvZUVDRUFNPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA5L3NvbWUtb2JqLzE1NTY4MzU5NDA2Mzg2NzIvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOS9vL3NvbWUtb2JqL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA5Iiwib2JqZWN0Ijoic29tZS1vYmoiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk0MDYzODY3MiIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNOQy8zT254L2VFQ0VBTT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOS9zb21lLW9iai8xNTU2ODM1OTQwNjM4NjcyL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDkvby9zb21lLW9iai9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOSIsIm9iamVjdCI6InNvbWUtb2JqIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5NDA2Mzg2NzIiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ05DLzNPbngvZUVDRUFNPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA5L3NvbWUtb2JqLzE1NTY4MzU5NDA2Mzg2NzIvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOS9vL3NvbWUtb2JqL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA5Iiwib2JqZWN0Ijoic29tZS1vYmoiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk0MDYzODY3MiIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNOQy8zT254L2VFQ0VBTT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoiMHpHc0ZRPT0iLCJldGFnIjoiQ05DLzNPbngvZUVDRUFNPSIsInRlbXBvcmFyeUhvbGQiOnRydWV9" } }, { "ID": "0227238a512229dc", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0009/o/some-obj?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3192" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:42 GMT" ], "Etag": [ "CNC/3Onx/eECEAM=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Up6PS1r6NaUKQ9158DD3cKWHqyParXLdcW8k7sToMskeTU6BjpajWENp3qNHqLMFvX9NrK78TIw31h_ANYkltj3vAQoYq2RG5C6ZB2LCvUIch96SMo" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOS9zb21lLW9iai8xNTU2ODM1OTQwNjM4NjcyIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA5L28vc29tZS1vYmoiLCJuYW1lIjoic29tZS1vYmoiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDkiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk0MDYzODY3MiIsIm1ldGFnZW5lcmF0aW9uIjoiMyIsImNvbnRlbnRUeXBlIjoiZm9vIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjQwLjYzOFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTo0Mi4xMjNaIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjU6NDAuNjM4WiIsInNpemUiOiIxNiIsIm1kNUhhc2giOiJSOFVITEgwbzhmMWVNWFVEdHIxNktnPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA5L28vc29tZS1vYmo/Z2VuZXJhdGlvbj0xNTU2ODM1OTQwNjM4NjcyJmFsdD1tZWRpYSIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA5L3NvbWUtb2JqLzE1NTY4MzU5NDA2Mzg2NzIvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA5L28vc29tZS1vYmovYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOSIsIm9iamVjdCI6InNvbWUtb2JqIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5NDA2Mzg2NzIiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ05DLzNPbngvZUVDRUFNPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA5L3NvbWUtb2JqLzE1NTY4MzU5NDA2Mzg2NzIvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOS9vL3NvbWUtb2JqL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA5Iiwib2JqZWN0Ijoic29tZS1vYmoiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk0MDYzODY3MiIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNOQy8zT254L2VFQ0VBTT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOS9zb21lLW9iai8xNTU2ODM1OTQwNjM4NjcyL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDkvby9zb21lLW9iai9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOSIsIm9iamVjdCI6InNvbWUtb2JqIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5NDA2Mzg2NzIiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ05DLzNPbngvZUVDRUFNPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA5L3NvbWUtb2JqLzE1NTY4MzU5NDA2Mzg2NzIvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOS9vL3NvbWUtb2JqL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA5Iiwib2JqZWN0Ijoic29tZS1vYmoiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk0MDYzODY3MiIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNOQy8zT254L2VFQ0VBTT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoiMHpHc0ZRPT0iLCJldGFnIjoiQ05DLzNPbngvZUVDRUFNPSIsInRlbXBvcmFyeUhvbGQiOnRydWV9" } }, { "ID": "7a81946424736215", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0009/o/some-obj?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "84" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDkiLCJ0ZW1wb3JhcnlIb2xkIjpmYWxzZX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3193" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:42 GMT" ], "Etag": [ "CNC/3Onx/eECEAQ=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uo1klBHpEl6qb-hfnVYr2KJLmo_3_1fgqlMYMBpBt23b-U9pF7bPcNEiJaMtrGEhZPQb9-QnqHiU8qPfmpNpSdy9KR41FwZm-89gyu3EtE5gq3J9-0" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOS9zb21lLW9iai8xNTU2ODM1OTQwNjM4NjcyIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA5L28vc29tZS1vYmoiLCJuYW1lIjoic29tZS1vYmoiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDkiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk0MDYzODY3MiIsIm1ldGFnZW5lcmF0aW9uIjoiNCIsImNvbnRlbnRUeXBlIjoiZm9vIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjQwLjYzOFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTo0Mi43MjFaIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjU6NDAuNjM4WiIsInNpemUiOiIxNiIsIm1kNUhhc2giOiJSOFVITEgwbzhmMWVNWFVEdHIxNktnPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA5L28vc29tZS1vYmo/Z2VuZXJhdGlvbj0xNTU2ODM1OTQwNjM4NjcyJmFsdD1tZWRpYSIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA5L3NvbWUtb2JqLzE1NTY4MzU5NDA2Mzg2NzIvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA5L28vc29tZS1vYmovYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOSIsIm9iamVjdCI6InNvbWUtb2JqIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5NDA2Mzg2NzIiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ05DLzNPbngvZUVDRUFRPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA5L3NvbWUtb2JqLzE1NTY4MzU5NDA2Mzg2NzIvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOS9vL3NvbWUtb2JqL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA5Iiwib2JqZWN0Ijoic29tZS1vYmoiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk0MDYzODY3MiIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNOQy8zT254L2VFQ0VBUT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOS9zb21lLW9iai8xNTU2ODM1OTQwNjM4NjcyL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDkvby9zb21lLW9iai9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOSIsIm9iamVjdCI6InNvbWUtb2JqIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5NDA2Mzg2NzIiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ05DLzNPbngvZUVDRUFRPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA5L3NvbWUtb2JqLzE1NTY4MzU5NDA2Mzg2NzIvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwOS9vL3NvbWUtb2JqL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDA5Iiwib2JqZWN0Ijoic29tZS1vYmoiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk0MDYzODY3MiIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNOQy8zT254L2VFQ0VBUT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoiMHpHc0ZRPT0iLCJldGFnIjoiQ05DLzNPbngvZUVDRUFRPSIsInRlbXBvcmFyeUhvbGQiOmZhbHNlfQ==" } }, { "ID": "7865e37b40b9ec66", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0009/o/some-obj?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:25:43 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uo2nfd81k4cBaY8ZFRGIu8G6DHyGUVAdIJCB65E8ZqqO9ADJIV4K22sQaOA8fqGL3jyi3tIszjBVsXHOFrCgca1vLXSpA1-3s2cn-MVhTKpzZ5tzY4" ] }, "Body": "" } }, { "ID": "fd9104ab049c0173", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0009?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:25:43 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqMqIYvjYuUxhnSLyoY-p5BYUiuZIX7cs418asOvABObfrQc8eXZpo-V4LSZVWWgt4CNoviMvFwcdC9sCTKCZU1H-9Ifcuf8lptTMZpiWMJjZfD-DY" ] }, "Body": "" } }, { "ID": "e735515a80a67931", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b?alt=json\u0026prettyPrint=false\u0026project=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "105" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDEwIiwicmV0ZW50aW9uUG9saWN5Ijp7InJldGVudGlvblBlcmlvZCI6IjM2MDAifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "573" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:44 GMT" ], "Etag": [ "CAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uqxx-CzGd9qn-QCqeE_iYOkeO93A0IpWx1voocTxhTrdkkBJonYBIWXeaEq3g-LNThw7j85IKVotWyBNZlHzqYSgBchb0DeXXetMqS8WBkY603Sa60" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMCIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDEwIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjQzLjgwNFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTo0My44MDRaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiaWFtQ29uZmlndXJhdGlvbiI6eyJidWNrZXRQb2xpY3lPbmx5Ijp7ImVuYWJsZWQiOmZhbHNlfX0sImxvY2F0aW9uIjoiVVMiLCJyZXRlbnRpb25Qb2xpY3kiOnsicmV0ZW50aW9uUGVyaW9kIjoiMzYwMCIsImVmZmVjdGl2ZVRpbWUiOiIyMDE5LTA1LTAyVDIyOjI1OjQzLjgwNFoifSwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJldGFnIjoiQ0FFPSJ9" } }, { "ID": "94bfaea89e1f47c2", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0010/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTAiLCJuYW1lIjoic29tZS1vYmoifQo=", "29UJUEl2/QvM9FnDBFnPRA==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3245" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:44 GMT" ], "Etag": [ "CPXIv+vx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqLSIzBtq8Qn_3f51_hlfoIkcpamafGwB3U8er3K_mzANwxXyscBHWZhaxb2-3M2wOT6GZER6-zLAtdeeSNtSlUMHkHX77gocrZGYj103HA-AGjVSM" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMC9zb21lLW9iai8xNTU2ODM1OTQ0MzU5MDI5Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDEwL28vc29tZS1vYmoiLCJuYW1lIjoic29tZS1vYmoiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTAiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk0NDM1OTAyOSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjQ0LjM1OFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTo0NC4zNThaIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjU6NDQuMzU4WiIsInNpemUiOiIxNiIsIm1kNUhhc2giOiJQYzFTWFEyUUk3MGxNNlZIN1F0NUFnPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDEwL28vc29tZS1vYmo/Z2VuZXJhdGlvbj0xNTU2ODM1OTQ0MzU5MDI5JmFsdD1tZWRpYSIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDEwL3NvbWUtb2JqLzE1NTY4MzU5NDQzNTkwMjkvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDEwL28vc29tZS1vYmovYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMCIsIm9iamVjdCI6InNvbWUtb2JqIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5NDQzNTkwMjkiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ1BYSXYrdngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDEwL3NvbWUtb2JqLzE1NTY4MzU5NDQzNTkwMjkvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMC9vL3NvbWUtb2JqL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDEwIiwib2JqZWN0Ijoic29tZS1vYmoiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk0NDM1OTAyOSIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNQWEl2K3Z4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMC9zb21lLW9iai8xNTU2ODM1OTQ0MzU5MDI5L3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTAvby9zb21lLW9iai9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMCIsIm9iamVjdCI6InNvbWUtb2JqIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5NDQzNTkwMjkiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ1BYSXYrdngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDEwL3NvbWUtb2JqLzE1NTY4MzU5NDQzNTkwMjkvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMC9vL3NvbWUtb2JqL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDEwIiwib2JqZWN0Ijoic29tZS1vYmoiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk0NDM1OTAyOSIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNQWEl2K3Z4L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoidUpwZFdRPT0iLCJldGFnIjoiQ1BYSXYrdngvZUVDRUFFPSIsInJldGVudGlvbkV4cGlyYXRpb25UaW1lIjoiMjAxOS0wNS0wMlQyMzoyNTo0NC4zNThaIn0=" } }, { "ID": "7db6d4640ce21307", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0010/o/some-obj?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3245" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:44 GMT" ], "Etag": [ "CPXIv+vx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoUK3qzYL0xUcMKfWD6mmDZqRfnd8q7O14gBrKng7OYalNXZR3ZegpD1VyqjzW6bgQqFvLrtFjWXwPoJ4E78_nThYByR2n3Hm33ms2fvCdaRSOy1Qc" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMC9zb21lLW9iai8xNTU2ODM1OTQ0MzU5MDI5Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDEwL28vc29tZS1vYmoiLCJuYW1lIjoic29tZS1vYmoiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTAiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk0NDM1OTAyOSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjQ0LjM1OFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTo0NC4zNThaIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjU6NDQuMzU4WiIsInNpemUiOiIxNiIsIm1kNUhhc2giOiJQYzFTWFEyUUk3MGxNNlZIN1F0NUFnPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDEwL28vc29tZS1vYmo/Z2VuZXJhdGlvbj0xNTU2ODM1OTQ0MzU5MDI5JmFsdD1tZWRpYSIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDEwL3NvbWUtb2JqLzE1NTY4MzU5NDQzNTkwMjkvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDEwL28vc29tZS1vYmovYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMCIsIm9iamVjdCI6InNvbWUtb2JqIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5NDQzNTkwMjkiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ1BYSXYrdngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDEwL3NvbWUtb2JqLzE1NTY4MzU5NDQzNTkwMjkvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMC9vL3NvbWUtb2JqL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDEwIiwib2JqZWN0Ijoic29tZS1vYmoiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk0NDM1OTAyOSIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNQWEl2K3Z4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMC9zb21lLW9iai8xNTU2ODM1OTQ0MzU5MDI5L3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTAvby9zb21lLW9iai9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMCIsIm9iamVjdCI6InNvbWUtb2JqIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5NDQzNTkwMjkiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ1BYSXYrdngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDEwL3NvbWUtb2JqLzE1NTY4MzU5NDQzNTkwMjkvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMC9vL3NvbWUtb2JqL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDEwIiwib2JqZWN0Ijoic29tZS1vYmoiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk0NDM1OTAyOSIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNQWEl2K3Z4L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoidUpwZFdRPT0iLCJldGFnIjoiQ1BYSXYrdngvZUVDRUFFPSIsInJldGVudGlvbkV4cGlyYXRpb25UaW1lIjoiMjAxOS0wNS0wMlQyMzoyNTo0NC4zNThaIn0=" } }, { "ID": "cec800ec28205dab", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0010?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "25" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJyZXRlbnRpb25Qb2xpY3kiOm51bGx9Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "2431" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:45 GMT" ], "Etag": [ "CAI=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqAm9jtf7nMSv2Bbn_pFGaLCmlq2CtqUdGeEOyYrkllqiADBk9_xsJS3BufmzfGIdARRHN7jVwbeHKev2CHMyzWoGA8UxNGNIldPCC4oZ1dMPARKHk" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMCIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDEwIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjQzLjgwNFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTo0NS4yMjZaIiwibWV0YWdlbmVyYXRpb24iOiIyIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTAvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDEwL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTAiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FJPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDEwL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTAvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTAiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTAvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMC9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMCIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUk9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBST0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBST0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwiZXRhZyI6IkNBST0ifQ==" } }, { "ID": "c787f6d5b23123a3", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0010/o/some-obj?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:25:45 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrgP5ghUeBxvXks4XlillwzLwfwyRGxt5y-FImGHSwZ-Meht6M0-keE0YTUG2Qy5hH5i1gpWPyGHXweFDyrk8a3QbDPnG5shDEoxzNOlMEsX6V8-4I" ] }, "Body": "" } }, { "ID": "144726e64e401a23", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0010?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:25:45 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpxuxvNJ3APW11H4y-qweAzn3ChIZ0eRjSetoSHkGwVvO7nMR17h5Hbj8I8zgOGjR7HPA201lDCw47ejD6kj1wCz3ZTIrUz-r-qjdm0vGGszQYFidQ" ] }, "Body": "" } }, { "ID": "eebfbd37f51a5cc6", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b?alt=json\u0026prettyPrint=false\u0026project=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "103" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDExIiwicmV0ZW50aW9uUG9saWN5Ijp7InJldGVudGlvblBlcmlvZCI6IjYwIn19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "571" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:46 GMT" ], "Etag": [ "CAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uox0foiLUu9KuEF-KVU8lIN_yUKAJsYEuwVqgSXvzFRGmzJtSZvFeNvMDS8W0aQ7c8YoI89qS_MxU8zBSBqcljYpIZe1NPIvkEFEG5K22RJkAuwmh8" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMSIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDExIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjQ2LjE3M1oiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTo0Ni4xNzNaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiaWFtQ29uZmlndXJhdGlvbiI6eyJidWNrZXRQb2xpY3lPbmx5Ijp7ImVuYWJsZWQiOmZhbHNlfX0sImxvY2F0aW9uIjoiVVMiLCJyZXRlbnRpb25Qb2xpY3kiOnsicmV0ZW50aW9uUGVyaW9kIjoiNjAiLCJlZmZlY3RpdmVUaW1lIjoiMjAxOS0wNS0wMlQyMjoyNTo0Ni4xNzNaIn0sInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwiZXRhZyI6IkNBRT0ifQ==" } }, { "ID": "c7ddc04b5d29113a", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0011?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "47" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJyZXRlbnRpb25Qb2xpY3kiOnsicmV0ZW50aW9uUGVyaW9kIjoiMzYwMCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "2519" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:46 GMT" ], "Etag": [ "CAI=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpD4zsQLTflaR7g-z0FszOHvw5oXvxqdiyjlAnMwMcBcUEjidrpIGgpvmrz1EWi2AyWkdDCSY0l8ItQxYnWwSZt24jOxXBlzq-gCNrCCE6j0fJVGKw" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMSIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDExIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjQ2LjE3M1oiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTo0Ni44NjNaIiwibWV0YWdlbmVyYXRpb24iOiIyIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTEvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDExL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTEiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FJPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDExL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTEvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTEiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTEvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMS9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMSIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUk9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBST0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBST0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsInJldGVudGlvblBvbGljeSI6eyJyZXRlbnRpb25QZXJpb2QiOiIzNjAwIiwiZWZmZWN0aXZlVGltZSI6IjIwMTktMDUtMDJUMjI6MjU6NDYuMTczWiJ9LCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsImV0YWciOiJDQUk9In0=" } }, { "ID": "e08a38dca4dda51f", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0011?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "2519" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:47 GMT" ], "Etag": [ "CAI=" ], "Expires": [ "Thu, 02 May 2019 22:25:47 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrsphQdkHT0ctCFLyPV1JRkq7cyQ7w1tvYmAWv-6tYsuThaMN-vkUJoTNz2gPKGy6jV0yqdbXaAlRlD_5n6GiQa-ULOyKLi-C0q8y25lfk7L6zROE4" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMSIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDExIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjQ2LjE3M1oiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTo0Ni44NjNaIiwibWV0YWdlbmVyYXRpb24iOiIyIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTEvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDExL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTEiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FJPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDExL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTEvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTEiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTEvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMS9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMSIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUk9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBST0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBST0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsInJldGVudGlvblBvbGljeSI6eyJyZXRlbnRpb25QZXJpb2QiOiIzNjAwIiwiZWZmZWN0aXZlVGltZSI6IjIwMTktMDUtMDJUMjI6MjU6NDYuMTczWiJ9LCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsImV0YWciOiJDQUk9In0=" } }, { "ID": "fe586a68284be237", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b?alt=json\u0026prettyPrint=false\u0026project=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "103" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDEyIiwicmV0ZW50aW9uUG9saWN5Ijp7InJldGVudGlvblBlcmlvZCI6IjYwIn19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "571" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:47 GMT" ], "Etag": [ "CAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpAjkPxULicnoY5wPnfrg-D7yzTbTzTZcUShEN8JSsqVMN758lI4DlkvFibNK9URhYVBH0xclTheAOO_CEDoVb5egvcF-WJqJ3SDisU2YPaZsohRro" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMiIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMiIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDEyIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjQ3LjU2NVoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTo0Ny41NjVaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiaWFtQ29uZmlndXJhdGlvbiI6eyJidWNrZXRQb2xpY3lPbmx5Ijp7ImVuYWJsZWQiOmZhbHNlfX0sImxvY2F0aW9uIjoiVVMiLCJyZXRlbnRpb25Qb2xpY3kiOnsicmV0ZW50aW9uUGVyaW9kIjoiNjAiLCJlZmZlY3RpdmVUaW1lIjoiMjAxOS0wNS0wMlQyMjoyNTo0Ny41NjVaIn0sInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwiZXRhZyI6IkNBRT0ifQ==" } }, { "ID": "732c3421adfb99d8", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0012?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "47" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJyZXRlbnRpb25Qb2xpY3kiOnsicmV0ZW50aW9uUGVyaW9kIjoiMzYwMCJ9fQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "2519" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:48 GMT" ], "Etag": [ "CAI=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UohfaTh8JFEjT7TTMwV7NkrcAsgkdpDyovvbjHJLNbXalzOWX3_HwhowBimaqZXhkuvBx1D38zsUZ5dEzigoyoXRJtgHfy7ClUrshBL_yMfPkZ4JE4" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMiIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMiIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDEyIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjQ3LjU2NVoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTo0OC4yNzBaIiwibWV0YWdlbmVyYXRpb24iOiIyIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTIvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDEyL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTIiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FJPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDEyL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTIvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTIiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTIvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMi9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMiIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUk9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBST0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBST0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsInJldGVudGlvblBvbGljeSI6eyJyZXRlbnRpb25QZXJpb2QiOiIzNjAwIiwiZWZmZWN0aXZlVGltZSI6IjIwMTktMDUtMDJUMjI6MjU6NDcuNTY1WiJ9LCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsImV0YWciOiJDQUk9In0=" } }, { "ID": "aebe46d0a31a6e95", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0012?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "2519" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:48 GMT" ], "Etag": [ "CAI=" ], "Expires": [ "Thu, 02 May 2019 22:25:48 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uop7c4AxllIcwFmLfqhIIaGP3Q9uHfmQoAm9LttwjQIvzHiJvu4fg_Q3UfNP8YbDuP97jLsG78JbCK68eSQv8ZHPp8kpzfdJcvOER0cs75wQ9gC7NA" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMiIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMiIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDEyIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjQ3LjU2NVoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTo0OC4yNzBaIiwibWV0YWdlbmVyYXRpb24iOiIyIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTIvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDEyL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTIiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FJPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDEyL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTIvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTIiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTIvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMi9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMiIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUk9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBST0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBST0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsInJldGVudGlvblBvbGljeSI6eyJyZXRlbnRpb25QZXJpb2QiOiIzNjAwIiwiZWZmZWN0aXZlVGltZSI6IjIwMTktMDUtMDJUMjI6MjU6NDcuNTY1WiJ9LCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsImV0YWciOiJDQUk9In0=" } }, { "ID": "bea48b3667650bdd", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b?alt=json\u0026prettyPrint=false\u0026project=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "103" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDEzIiwicmV0ZW50aW9uUG9saWN5Ijp7InJldGVudGlvblBlcmlvZCI6IjYwIn19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "571" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:49 GMT" ], "Etag": [ "CAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uo1p1nEuvoUAqYHYa8wuU6qF64gN2JPCxLqqFEUiKXLgo9rwPH_btm63155v5hbuS6sow8cYEvsXVJthsJ1Zn8qfb05USodp1EvTTrt_m1rpJnIxdo" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMyIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDEzIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjQ5LjAxNFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTo0OS4wMTRaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiaWFtQ29uZmlndXJhdGlvbiI6eyJidWNrZXRQb2xpY3lPbmx5Ijp7ImVuYWJsZWQiOmZhbHNlfX0sImxvY2F0aW9uIjoiVVMiLCJyZXRlbnRpb25Qb2xpY3kiOnsicmV0ZW50aW9uUGVyaW9kIjoiNjAiLCJlZmZlY3RpdmVUaW1lIjoiMjAxOS0wNS0wMlQyMjoyNTo0OS4wMTRaIn0sInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwiZXRhZyI6IkNBRT0ifQ==" } }, { "ID": "a951cae4048b1267", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0013?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "25" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJyZXRlbnRpb25Qb2xpY3kiOm51bGx9Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "2431" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:49 GMT" ], "Etag": [ "CAI=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpZAHhwxqSSY5MYFK1fdLLirRH41rc7W2YWSnn4CQZkbdR_98fRYjddtqZVfpEizqsZ1BNa5A7ENxQz7BwQSamASc8XAC5gyZp_pwi-Yu8l0XLSCpU" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMyIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDEzIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjQ5LjAxNFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTo0OS42MjdaIiwibWV0YWdlbmVyYXRpb24iOiIyIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTMvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDEzL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTMiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FJPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDEzL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTMvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTMiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTMvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMy9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMyIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUk9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBST0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBST0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwiZXRhZyI6IkNBST0ifQ==" } }, { "ID": "e7f0506408261db3", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0013?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "2431" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:49 GMT" ], "Etag": [ "CAI=" ], "Expires": [ "Thu, 02 May 2019 22:25:49 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UotOOFJlGACBcheGxpS8qxLlGsDT0xOhT_Cg1M_6DxUI16IiOu-YHaPvwzxilOKOrTvL8kRzcVUiNuFeS6rQExTmdK70I1IOH2d2BLOrMm1L5Int1g" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMyIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDEzIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjQ5LjAxNFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTo0OS42MjdaIiwibWV0YWdlbmVyYXRpb24iOiIyIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTMvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDEzL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTMiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FJPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDEzL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTMvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTMiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTMvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMy9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxMyIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUk9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBST0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBST0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwiZXRhZyI6IkNBST0ifQ==" } }, { "ID": "b2c4589e9b9b5ad2", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b?alt=json\u0026prettyPrint=false\u0026project=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "103" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE0IiwicmV0ZW50aW9uUG9saWN5Ijp7InJldGVudGlvblBlcmlvZCI6IjYwIn19Cg==" ] }, "Response": { "StatusCode": 429, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Content-Length": [ "12201" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:50 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UoFdLKiYfqS-J3PXjvHGxpXtJwVnUB7Li8XrR-DTYkmyed-ZlUmUcmZFgGyIayuACtUWVYBcRbhYOKvgkfl8srE0OdJbc15OHWBttYqenraJ0MdXj8" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6InVzYWdlTGltaXRzIiwicmVhc29uIjoicmF0ZUxpbWl0RXhjZWVkZWQiLCJtZXNzYWdlIjoiVGhlIHByb2plY3QgZXhjZWVkZWQgdGhlIHJhdGUgbGltaXQgZm9yIGNyZWF0aW5nIGFuZCBkZWxldGluZyBidWNrZXRzLiIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpQUk9KRUNUX0JVQ0tFVF9PUF9SQVRFX1RPT19ISUdIOiBDcmVhdGluZyBidWNrZXRzIHRvbyBxdWlja2x5LCBwbGVhc2Ugc2xvdyBkb3duXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5idWNrZXRzLkluc2VydEJ1Y2tldC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoSW5zZXJ0QnVja2V0LmphdmE6MTg0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuSW5zZXJ0QnVja2V0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRCdWNrZXQuamF2YTo0Milcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQnVja2V0c0RlbGVnYXRvci5pbnNlcnQoQnVja2V0c0RlbGVnYXRvci5qYXZhOjk1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBDcmVhdGluZyBidWNrZXRzIHRvbyBxdWlja2x5LCBwbGVhc2Ugc2xvdyBkb3duXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPVRPT19NQU5ZX1JFUVVFU1RTLCBjYXRlZ29yeT1RVU9UQV9FUlJPUiwgY2F1c2U9bnVsbCwgZGVidWdJbmZvPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpQUk9KRUNUX0JVQ0tFVF9PUF9SQVRFX1RPT19ISUdIOiBDcmVhdGluZyBidWNrZXRzIHRvbyBxdWlja2x5LCBwbGVhc2Ugc2xvdyBkb3duXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5idWNrZXRzLkluc2VydEJ1Y2tldC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoSW5zZXJ0QnVja2V0LmphdmE6MTg0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuSW5zZXJ0QnVja2V0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRCdWNrZXQuamF2YTo0Milcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQnVja2V0c0RlbGVnYXRvci5pbnNlcnQoQnVja2V0c0RlbGVnYXRvci5qYXZhOjk1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBDcmVhdGluZyBidWNrZXRzIHRvbyBxdWlja2x5LCBwbGVhc2Ugc2xvdyBkb3duXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZG9tYWluPXVzYWdlTGltaXRzLCBleHRlbmRlZEhlbHA9bnVsbCwgaHR0cEhlYWRlcnM9e30sIGh0dHBTdGF0dXM9dG9vTWFueVJlcXVlc3RzLCBpbnRlcm5hbFJlYXNvbj1SZWFzb257YXJndW1lbnRzPXt9LCBjYXVzZT1udWxsLCBjb2RlPWNsb3VkLmJpZ3N0b3JlLmFwaS5CaWdzdG9yZUVycm9yRG9tYWluLkNMSUVOVF9RVU9UQV9FWENFRURFRCwgY3JlYXRlZEJ5QmFja2VuZD10cnVlLCBkZWJ1Z01lc3NhZ2U9Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlBST0pFQ1RfQlVDS0VUX09QX1JBVEVfVE9PX0hJR0g6IENyZWF0aW5nIGJ1Y2tldHMgdG9vIHF1aWNrbHksIHBsZWFzZSBzbG93IGRvd25cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuSW5zZXJ0QnVja2V0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRCdWNrZXQuamF2YToxODQpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYnVja2V0cy5JbnNlcnRCdWNrZXQuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEluc2VydEJ1Y2tldC5qYXZhOjQyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5CdWNrZXRzRGVsZWdhdG9yLmluc2VydChCdWNrZXRzRGVsZWdhdG9yLmphdmE6OTUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IENyZWF0aW5nIGJ1Y2tldHMgdG9vIHF1aWNrbHksIHBsZWFzZSBzbG93IGRvd25cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuLCBlcnJvclByb3RvQ29kZT1DTElFTlRfUVVPVEFfRVhDRUVERUQsIGVycm9yUHJvdG9Eb21haW49Y2xvdWQuYmlnc3RvcmUuYXBpLkJpZ3N0b3JlRXJyb3JEb21haW4sIGZpbHRlcmVkTWVzc2FnZT1udWxsLCBsb2NhdGlvbj1lbnRpdHkucmVzb3VyY2UuYnVja2V0Lm5hbWUsIG1lc3NhZ2U9VGhlIHByb2plY3QgZXhjZWVkZWQgdGhlIHJhdGUgbGltaXQgZm9yIGNyZWF0aW5nIGFuZCBkZWxldGluZyBidWNrZXRzLiwgdW5uYW1lZEFyZ3VtZW50cz1bXX0sIGxvY2F0aW9uPWVudGl0eS5yZXNvdXJjZS5idWNrZXQubmFtZSwgbWVzc2FnZT1UaGUgcHJvamVjdCBleGNlZWRlZCB0aGUgcmF0ZSBsaW1pdCBmb3IgY3JlYXRpbmcgYW5kIGRlbGV0aW5nIGJ1Y2tldHMuLCByZWFzb249cmF0ZUxpbWl0RXhjZWVkZWQsIHJwY0NvZGU9NDI5fSBUaGUgcHJvamVjdCBleGNlZWRlZCB0aGUgcmF0ZSBsaW1pdCBmb3IgY3JlYXRpbmcgYW5kIGRlbGV0aW5nIGJ1Y2tldHMuOiBjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6UFJPSkVDVF9CVUNLRVRfT1BfUkFURV9UT09fSElHSDogQ3JlYXRpbmcgYnVja2V0cyB0b28gcXVpY2tseSwgcGxlYXNlIHNsb3cgZG93blxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYnVja2V0cy5JbnNlcnRCdWNrZXQuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEluc2VydEJ1Y2tldC5qYXZhOjE4NClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5idWNrZXRzLkluc2VydEJ1Y2tldC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoSW5zZXJ0QnVja2V0LmphdmE6NDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLkJ1Y2tldHNEZWxlZ2F0b3IuaW5zZXJ0KEJ1Y2tldHNEZWxlZ2F0b3IuamF2YTo5NSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogQ3JlYXRpbmcgYnVja2V0cyB0b28gcXVpY2tseSwgcGxlYXNlIHNsb3cgZG93blxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRXJyb3JDb2xsZWN0b3IudG9GYXVsdChFcnJvckNvbGxlY3Rvci5qYXZhOjU0KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUVycm9yQ29udmVydGVyLnRvRmF1bHQoUm9zeUVycm9yQ29udmVydGVyLmphdmE6NjcpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyNTkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyMzkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci50aHJlYWQuVGhyZWFkVHJhY2tlcnMkVGhyZWFkVHJhY2tpbmdSdW5uYWJsZS5ydW4oVGhyZWFkVHJhY2tlcnMuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjQ1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnNlcnZlci5Db21tb25Nb2R1bGUkQ29udGV4dENhcnJ5aW5nRXhlY3V0b3JTZXJ2aWNlJDEucnVuSW5Db250ZXh0KENvbW1vbk1vZHVsZS5qYXZhOjgwMilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZSQxLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NjApXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoVHJhY2VDb250ZXh0LmphdmE6MzE5KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjMxMSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDU3KVxuXHRhdCBjb20uZ29vZ2xlLmdzZS5pbnRlcm5hbC5EaXNwYXRjaFF1ZXVlSW1wbCRXb3JrZXJUaHJlYWQucnVuKERpc3BhdGNoUXVldWVJbXBsLmphdmE6NDAzKVxuIn1dLCJjb2RlIjo0MjksIm1lc3NhZ2UiOiJUaGUgcHJvamVjdCBleGNlZWRlZCB0aGUgcmF0ZSBsaW1pdCBmb3IgY3JlYXRpbmcgYW5kIGRlbGV0aW5nIGJ1Y2tldHMuIn19" } }, { "ID": "836baafb4e98da80", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b?alt=json\u0026prettyPrint=false\u0026project=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "103" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE0IiwicmV0ZW50aW9uUG9saWN5Ijp7InJldGVudGlvblBlcmlvZCI6IjYwIn19Cg==" ] }, "Response": { "StatusCode": 429, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Content-Length": [ "12201" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:51 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UpNuySlLo4SanUdFJK3SGoCidNgWEW4mUuFDGMLLSzY-UUA3TJtN5_FLoLq7et7d1YSUDlOoGZY4a_GdewGQtsUwGdbHLz-bopObpzPy160Wm3UMpg" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6InVzYWdlTGltaXRzIiwicmVhc29uIjoicmF0ZUxpbWl0RXhjZWVkZWQiLCJtZXNzYWdlIjoiVGhlIHByb2plY3QgZXhjZWVkZWQgdGhlIHJhdGUgbGltaXQgZm9yIGNyZWF0aW5nIGFuZCBkZWxldGluZyBidWNrZXRzLiIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpQUk9KRUNUX0JVQ0tFVF9PUF9SQVRFX1RPT19ISUdIOiBDcmVhdGluZyBidWNrZXRzIHRvbyBxdWlja2x5LCBwbGVhc2Ugc2xvdyBkb3duXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5idWNrZXRzLkluc2VydEJ1Y2tldC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoSW5zZXJ0QnVja2V0LmphdmE6MTg0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuSW5zZXJ0QnVja2V0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRCdWNrZXQuamF2YTo0Milcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQnVja2V0c0RlbGVnYXRvci5pbnNlcnQoQnVja2V0c0RlbGVnYXRvci5qYXZhOjk1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBDcmVhdGluZyBidWNrZXRzIHRvbyBxdWlja2x5LCBwbGVhc2Ugc2xvdyBkb3duXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPVRPT19NQU5ZX1JFUVVFU1RTLCBjYXRlZ29yeT1RVU9UQV9FUlJPUiwgY2F1c2U9bnVsbCwgZGVidWdJbmZvPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpQUk9KRUNUX0JVQ0tFVF9PUF9SQVRFX1RPT19ISUdIOiBDcmVhdGluZyBidWNrZXRzIHRvbyBxdWlja2x5LCBwbGVhc2Ugc2xvdyBkb3duXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5idWNrZXRzLkluc2VydEJ1Y2tldC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoSW5zZXJ0QnVja2V0LmphdmE6MTg0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuSW5zZXJ0QnVja2V0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRCdWNrZXQuamF2YTo0Milcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQnVja2V0c0RlbGVnYXRvci5pbnNlcnQoQnVja2V0c0RlbGVnYXRvci5qYXZhOjk1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBDcmVhdGluZyBidWNrZXRzIHRvbyBxdWlja2x5LCBwbGVhc2Ugc2xvdyBkb3duXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZG9tYWluPXVzYWdlTGltaXRzLCBleHRlbmRlZEhlbHA9bnVsbCwgaHR0cEhlYWRlcnM9e30sIGh0dHBTdGF0dXM9dG9vTWFueVJlcXVlc3RzLCBpbnRlcm5hbFJlYXNvbj1SZWFzb257YXJndW1lbnRzPXt9LCBjYXVzZT1udWxsLCBjb2RlPWNsb3VkLmJpZ3N0b3JlLmFwaS5CaWdzdG9yZUVycm9yRG9tYWluLkNMSUVOVF9RVU9UQV9FWENFRURFRCwgY3JlYXRlZEJ5QmFja2VuZD10cnVlLCBkZWJ1Z01lc3NhZ2U9Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlBST0pFQ1RfQlVDS0VUX09QX1JBVEVfVE9PX0hJR0g6IENyZWF0aW5nIGJ1Y2tldHMgdG9vIHF1aWNrbHksIHBsZWFzZSBzbG93IGRvd25cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuSW5zZXJ0QnVja2V0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRCdWNrZXQuamF2YToxODQpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYnVja2V0cy5JbnNlcnRCdWNrZXQuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEluc2VydEJ1Y2tldC5qYXZhOjQyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5CdWNrZXRzRGVsZWdhdG9yLmluc2VydChCdWNrZXRzRGVsZWdhdG9yLmphdmE6OTUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IENyZWF0aW5nIGJ1Y2tldHMgdG9vIHF1aWNrbHksIHBsZWFzZSBzbG93IGRvd25cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuLCBlcnJvclByb3RvQ29kZT1DTElFTlRfUVVPVEFfRVhDRUVERUQsIGVycm9yUHJvdG9Eb21haW49Y2xvdWQuYmlnc3RvcmUuYXBpLkJpZ3N0b3JlRXJyb3JEb21haW4sIGZpbHRlcmVkTWVzc2FnZT1udWxsLCBsb2NhdGlvbj1lbnRpdHkucmVzb3VyY2UuYnVja2V0Lm5hbWUsIG1lc3NhZ2U9VGhlIHByb2plY3QgZXhjZWVkZWQgdGhlIHJhdGUgbGltaXQgZm9yIGNyZWF0aW5nIGFuZCBkZWxldGluZyBidWNrZXRzLiwgdW5uYW1lZEFyZ3VtZW50cz1bXX0sIGxvY2F0aW9uPWVudGl0eS5yZXNvdXJjZS5idWNrZXQubmFtZSwgbWVzc2FnZT1UaGUgcHJvamVjdCBleGNlZWRlZCB0aGUgcmF0ZSBsaW1pdCBmb3IgY3JlYXRpbmcgYW5kIGRlbGV0aW5nIGJ1Y2tldHMuLCByZWFzb249cmF0ZUxpbWl0RXhjZWVkZWQsIHJwY0NvZGU9NDI5fSBUaGUgcHJvamVjdCBleGNlZWRlZCB0aGUgcmF0ZSBsaW1pdCBmb3IgY3JlYXRpbmcgYW5kIGRlbGV0aW5nIGJ1Y2tldHMuOiBjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6UFJPSkVDVF9CVUNLRVRfT1BfUkFURV9UT09fSElHSDogQ3JlYXRpbmcgYnVja2V0cyB0b28gcXVpY2tseSwgcGxlYXNlIHNsb3cgZG93blxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYnVja2V0cy5JbnNlcnRCdWNrZXQuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEluc2VydEJ1Y2tldC5qYXZhOjE4NClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5idWNrZXRzLkluc2VydEJ1Y2tldC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoSW5zZXJ0QnVja2V0LmphdmE6NDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLkJ1Y2tldHNEZWxlZ2F0b3IuaW5zZXJ0KEJ1Y2tldHNEZWxlZ2F0b3IuamF2YTo5NSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogQ3JlYXRpbmcgYnVja2V0cyB0b28gcXVpY2tseSwgcGxlYXNlIHNsb3cgZG93blxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRXJyb3JDb2xsZWN0b3IudG9GYXVsdChFcnJvckNvbGxlY3Rvci5qYXZhOjU0KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUVycm9yQ29udmVydGVyLnRvRmF1bHQoUm9zeUVycm9yQ29udmVydGVyLmphdmE6NjcpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyNTkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyMzkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci50aHJlYWQuVGhyZWFkVHJhY2tlcnMkVGhyZWFkVHJhY2tpbmdSdW5uYWJsZS5ydW4oVGhyZWFkVHJhY2tlcnMuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjQ1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnNlcnZlci5Db21tb25Nb2R1bGUkQ29udGV4dENhcnJ5aW5nRXhlY3V0b3JTZXJ2aWNlJDEucnVuSW5Db250ZXh0KENvbW1vbk1vZHVsZS5qYXZhOjgwMilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZSQxLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NjApXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoVHJhY2VDb250ZXh0LmphdmE6MzE5KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjMxMSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDU3KVxuXHRhdCBjb20uZ29vZ2xlLmdzZS5pbnRlcm5hbC5EaXNwYXRjaFF1ZXVlSW1wbCRXb3JrZXJUaHJlYWQucnVuKERpc3BhdGNoUXVldWVJbXBsLmphdmE6NDAzKVxuIn1dLCJjb2RlIjo0MjksIm1lc3NhZ2UiOiJUaGUgcHJvamVjdCBleGNlZWRlZCB0aGUgcmF0ZSBsaW1pdCBmb3IgY3JlYXRpbmcgYW5kIGRlbGV0aW5nIGJ1Y2tldHMuIn19" } }, { "ID": "281ffb73e66efd1f", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b?alt=json\u0026prettyPrint=false\u0026project=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "103" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE0IiwicmV0ZW50aW9uUG9saWN5Ijp7InJldGVudGlvblBlcmlvZCI6IjYwIn19Cg==" ] }, "Response": { "StatusCode": 429, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Content-Length": [ "12201" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:52 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2Uo8PK9JysFiApLjDSbbo9GloKqKjLO8vr85RWGkeC_Q0iEQf7zu2mwQVeiuJ81pfdJCUja0HrhNG13sczI2XoflqlsWNFvdxHGjCBrvDObr-s6Y32U" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6InVzYWdlTGltaXRzIiwicmVhc29uIjoicmF0ZUxpbWl0RXhjZWVkZWQiLCJtZXNzYWdlIjoiVGhlIHByb2plY3QgZXhjZWVkZWQgdGhlIHJhdGUgbGltaXQgZm9yIGNyZWF0aW5nIGFuZCBkZWxldGluZyBidWNrZXRzLiIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpQUk9KRUNUX0JVQ0tFVF9PUF9SQVRFX1RPT19ISUdIOiBDcmVhdGluZyBidWNrZXRzIHRvbyBxdWlja2x5LCBwbGVhc2Ugc2xvdyBkb3duXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5idWNrZXRzLkluc2VydEJ1Y2tldC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoSW5zZXJ0QnVja2V0LmphdmE6MTg0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuSW5zZXJ0QnVja2V0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRCdWNrZXQuamF2YTo0Milcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQnVja2V0c0RlbGVnYXRvci5pbnNlcnQoQnVja2V0c0RlbGVnYXRvci5qYXZhOjk1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBDcmVhdGluZyBidWNrZXRzIHRvbyBxdWlja2x5LCBwbGVhc2Ugc2xvdyBkb3duXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPVRPT19NQU5ZX1JFUVVFU1RTLCBjYXRlZ29yeT1RVU9UQV9FUlJPUiwgY2F1c2U9bnVsbCwgZGVidWdJbmZvPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpQUk9KRUNUX0JVQ0tFVF9PUF9SQVRFX1RPT19ISUdIOiBDcmVhdGluZyBidWNrZXRzIHRvbyBxdWlja2x5LCBwbGVhc2Ugc2xvdyBkb3duXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5idWNrZXRzLkluc2VydEJ1Y2tldC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoSW5zZXJ0QnVja2V0LmphdmE6MTg0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuSW5zZXJ0QnVja2V0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRCdWNrZXQuamF2YTo0Milcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQnVja2V0c0RlbGVnYXRvci5pbnNlcnQoQnVja2V0c0RlbGVnYXRvci5qYXZhOjk1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBDcmVhdGluZyBidWNrZXRzIHRvbyBxdWlja2x5LCBwbGVhc2Ugc2xvdyBkb3duXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZG9tYWluPXVzYWdlTGltaXRzLCBleHRlbmRlZEhlbHA9bnVsbCwgaHR0cEhlYWRlcnM9e30sIGh0dHBTdGF0dXM9dG9vTWFueVJlcXVlc3RzLCBpbnRlcm5hbFJlYXNvbj1SZWFzb257YXJndW1lbnRzPXt9LCBjYXVzZT1udWxsLCBjb2RlPWNsb3VkLmJpZ3N0b3JlLmFwaS5CaWdzdG9yZUVycm9yRG9tYWluLkNMSUVOVF9RVU9UQV9FWENFRURFRCwgY3JlYXRlZEJ5QmFja2VuZD10cnVlLCBkZWJ1Z01lc3NhZ2U9Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlBST0pFQ1RfQlVDS0VUX09QX1JBVEVfVE9PX0hJR0g6IENyZWF0aW5nIGJ1Y2tldHMgdG9vIHF1aWNrbHksIHBsZWFzZSBzbG93IGRvd25cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuSW5zZXJ0QnVja2V0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRCdWNrZXQuamF2YToxODQpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYnVja2V0cy5JbnNlcnRCdWNrZXQuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEluc2VydEJ1Y2tldC5qYXZhOjQyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5CdWNrZXRzRGVsZWdhdG9yLmluc2VydChCdWNrZXRzRGVsZWdhdG9yLmphdmE6OTUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IENyZWF0aW5nIGJ1Y2tldHMgdG9vIHF1aWNrbHksIHBsZWFzZSBzbG93IGRvd25cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuLCBlcnJvclByb3RvQ29kZT1DTElFTlRfUVVPVEFfRVhDRUVERUQsIGVycm9yUHJvdG9Eb21haW49Y2xvdWQuYmlnc3RvcmUuYXBpLkJpZ3N0b3JlRXJyb3JEb21haW4sIGZpbHRlcmVkTWVzc2FnZT1udWxsLCBsb2NhdGlvbj1lbnRpdHkucmVzb3VyY2UuYnVja2V0Lm5hbWUsIG1lc3NhZ2U9VGhlIHByb2plY3QgZXhjZWVkZWQgdGhlIHJhdGUgbGltaXQgZm9yIGNyZWF0aW5nIGFuZCBkZWxldGluZyBidWNrZXRzLiwgdW5uYW1lZEFyZ3VtZW50cz1bXX0sIGxvY2F0aW9uPWVudGl0eS5yZXNvdXJjZS5idWNrZXQubmFtZSwgbWVzc2FnZT1UaGUgcHJvamVjdCBleGNlZWRlZCB0aGUgcmF0ZSBsaW1pdCBmb3IgY3JlYXRpbmcgYW5kIGRlbGV0aW5nIGJ1Y2tldHMuLCByZWFzb249cmF0ZUxpbWl0RXhjZWVkZWQsIHJwY0NvZGU9NDI5fSBUaGUgcHJvamVjdCBleGNlZWRlZCB0aGUgcmF0ZSBsaW1pdCBmb3IgY3JlYXRpbmcgYW5kIGRlbGV0aW5nIGJ1Y2tldHMuOiBjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6UFJPSkVDVF9CVUNLRVRfT1BfUkFURV9UT09fSElHSDogQ3JlYXRpbmcgYnVja2V0cyB0b28gcXVpY2tseSwgcGxlYXNlIHNsb3cgZG93blxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYnVja2V0cy5JbnNlcnRCdWNrZXQuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEluc2VydEJ1Y2tldC5qYXZhOjE4NClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5idWNrZXRzLkluc2VydEJ1Y2tldC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoSW5zZXJ0QnVja2V0LmphdmE6NDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLkJ1Y2tldHNEZWxlZ2F0b3IuaW5zZXJ0KEJ1Y2tldHNEZWxlZ2F0b3IuamF2YTo5NSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogQ3JlYXRpbmcgYnVja2V0cyB0b28gcXVpY2tseSwgcGxlYXNlIHNsb3cgZG93blxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRXJyb3JDb2xsZWN0b3IudG9GYXVsdChFcnJvckNvbGxlY3Rvci5qYXZhOjU0KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUVycm9yQ29udmVydGVyLnRvRmF1bHQoUm9zeUVycm9yQ29udmVydGVyLmphdmE6NjcpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyNTkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyMzkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci50aHJlYWQuVGhyZWFkVHJhY2tlcnMkVGhyZWFkVHJhY2tpbmdSdW5uYWJsZS5ydW4oVGhyZWFkVHJhY2tlcnMuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjQ1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnNlcnZlci5Db21tb25Nb2R1bGUkQ29udGV4dENhcnJ5aW5nRXhlY3V0b3JTZXJ2aWNlJDEucnVuSW5Db250ZXh0KENvbW1vbk1vZHVsZS5qYXZhOjgwMilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZSQxLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NjApXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoVHJhY2VDb250ZXh0LmphdmE6MzE5KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjMxMSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDU3KVxuXHRhdCBjb20uZ29vZ2xlLmdzZS5pbnRlcm5hbC5EaXNwYXRjaFF1ZXVlSW1wbCRXb3JrZXJUaHJlYWQucnVuKERpc3BhdGNoUXVldWVJbXBsLmphdmE6NDAzKVxuIn1dLCJjb2RlIjo0MjksIm1lc3NhZ2UiOiJUaGUgcHJvamVjdCBleGNlZWRlZCB0aGUgcmF0ZSBsaW1pdCBmb3IgY3JlYXRpbmcgYW5kIGRlbGV0aW5nIGJ1Y2tldHMuIn19" } }, { "ID": "515ecb8616d48a7f", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b?alt=json\u0026prettyPrint=false\u0026project=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "103" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE0IiwicmV0ZW50aW9uUG9saWN5Ijp7InJldGVudGlvblBlcmlvZCI6IjYwIn19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "571" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:55 GMT" ], "Etag": [ "CAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqF93J_Bpwg-_yefVpKWteSyWBSx9FqNm8MP5eZKqVfvDWpSF6EPZsISss7hNOkKMM5OuV8stlJIW2UAkzsSgkYOHx5fCwOwylbtqAyb8OlYJCHz6Q" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNCIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE0IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjU1LjIwNFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTo1NS4yMDRaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiaWFtQ29uZmlndXJhdGlvbiI6eyJidWNrZXRQb2xpY3lPbmx5Ijp7ImVuYWJsZWQiOmZhbHNlfX0sImxvY2F0aW9uIjoiVVMiLCJyZXRlbnRpb25Qb2xpY3kiOnsicmV0ZW50aW9uUGVyaW9kIjoiNjAiLCJlZmZlY3RpdmVUaW1lIjoiMjAxOS0wNS0wMlQyMjoyNTo1NS4yMDRaIn0sInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwiZXRhZyI6IkNBRT0ifQ==" } }, { "ID": "771e55d617425f26", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0014?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "25" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJyZXRlbnRpb25Qb2xpY3kiOm51bGx9Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "2431" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:55 GMT" ], "Etag": [ "CAI=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Up6Slob_akPo2UWNmzCe-LD4cb-9DVTq_FPlNxA7mKVF6fBFks6gFnZ83BSajEU2qD8g14Y-pX20kbfoKf8XGR9pIW2xXH_oHCxsjspHZ2ARGePTMA" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNCIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE0IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjU1LjIwNFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTo1NS44MjVaIiwibWV0YWdlbmVyYXRpb24iOiIyIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTQvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE0L2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTQiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FJPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE0L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTQvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTQiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTQvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNC9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNCIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUk9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBST0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBST0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwiZXRhZyI6IkNBST0ifQ==" } }, { "ID": "9526aab2be8b214c", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0014?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "2431" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:56 GMT" ], "Etag": [ "CAI=" ], "Expires": [ "Thu, 02 May 2019 22:25:56 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UopNhdzHbHv4sXyk0r1owz7bkkPQwYIGbb3gRingbq7vgESKltWLIr9PDDIUNREfumEvZDfpxMineWYNzZ0qdOaI1QNYqXjnuxO6sCUDjBYEhr76uk" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNCIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE0IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjU1LjIwNFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTo1NS44MjVaIiwibWV0YWdlbmVyYXRpb24iOiIyIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTQvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE0L2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTQiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FJPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE0L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTQvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTQiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTQvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNC9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNCIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUk9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBST0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBST0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwiZXRhZyI6IkNBST0ifQ==" } }, { "ID": "0aabff8aa1cc1e9c", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b?alt=json\u0026prettyPrint=false\u0026project=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "103" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE1IiwicmV0ZW50aW9uUG9saWN5Ijp7InJldGVudGlvblBlcmlvZCI6IjYwIn19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "571" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:56 GMT" ], "Etag": [ "CAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpTj6zYv1NMHDI_ktA1d-p7HKq4YnJMxxI9nXubPfCMyIspOgya8HYibmvOMFwLtCPagnzRHe0HbmTCSqJpYMay0xYZstGSE_IUWRqI9lUhzq0Iqe4" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNSIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE1IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjU2LjM3NFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTo1Ni4zNzRaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiaWFtQ29uZmlndXJhdGlvbiI6eyJidWNrZXRQb2xpY3lPbmx5Ijp7ImVuYWJsZWQiOmZhbHNlfX0sImxvY2F0aW9uIjoiVVMiLCJyZXRlbnRpb25Qb2xpY3kiOnsicmV0ZW50aW9uUGVyaW9kIjoiNjAiLCJlZmZlY3RpdmVUaW1lIjoiMjAxOS0wNS0wMlQyMjoyNTo1Ni4zNzRaIn0sInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwiZXRhZyI6IkNBRT0ifQ==" } }, { "ID": "05147b5b5fdd7882", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0015?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "3" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "e30K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "2517" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:56 GMT" ], "Etag": [ "CAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uoshhz3RuOTlNgZ3gOLis_dSFBsqr7khyJCdWUD8BGk0_j-AHxA5etttVHuHTrUcDksF4LdtfJLhlVrAJe9PrGiYZ-Wy57j6tb7L6vc0qHoTvolIRg" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNSIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE1IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjU2LjM3NFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTo1Ni4zNzRaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTUvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE1L2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTUiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE1L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTUvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTUiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTUvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNS9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNSIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUU9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBRT0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsInJldGVudGlvblBvbGljeSI6eyJyZXRlbnRpb25QZXJpb2QiOiI2MCIsImVmZmVjdGl2ZVRpbWUiOiIyMDE5LTA1LTAyVDIyOjI1OjU2LjM3NFoifSwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJldGFnIjoiQ0FFPSJ9" } }, { "ID": "7de8d497e7e1a76c", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0015?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "2517" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:57 GMT" ], "Etag": [ "CAE=" ], "Expires": [ "Thu, 02 May 2019 22:25:57 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Up3mjbvLxwRDDhjg8GTGBNcJM7EraDydPsmD77oQcyYYGVlQnUqg0NQbezf4KQOoOHoEnC9jMR052e0olW3qi9KdAi4-qJEiKGI1rGivb5hnJnmU5o" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNSIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE1IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjU2LjM3NFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTo1Ni4zNzRaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTUvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE1L2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTUiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE1L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTUvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTUiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTUvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNS9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNSIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUU9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBRT0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsInJldGVudGlvblBvbGljeSI6eyJyZXRlbnRpb25QZXJpb2QiOiI2MCIsImVmZmVjdGl2ZVRpbWUiOiIyMDE5LTA1LTAyVDIyOjI1OjU2LjM3NFoifSwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJldGFnIjoiQ0FFPSJ9" } }, { "ID": "3876040740117531", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0015?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:25:57 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqGdmh-XzrU5d5VwRugwWr452hENxpWf1sEtNCDaGksLJ1taCgnEjL_0oAlELqirqyXLlw-frE8LYo1V37Pk1G3qvWGk9E1iSZV7uECOjsdE3JagK8" ] }, "Body": "" } }, { "ID": "39fb456e528c7081", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0014?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:25:57 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqKcAQsTdqHfiXj71c5kivJTwCNhY6xUQpZtaxywsmr1kNG5_MdJBsOvuLVbDSHKRIsG9tDxk_9Gz-7zaqP_pqke1aqKOFg9NeCU4ZqfjD0SBy0Q5Q" ] }, "Body": "" } }, { "ID": "3fdacef865a6fc39", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0013?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:25:58 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Ur0PIkQTUvOl8-6tC08mwiS3nBPydo1OYUeD6Q46ZrU6VkmpRwxc9MikGqJlsejuGZkyY_aaxUVKYGREjOF363tfkbII3of6pGFuQ8rINOf8uFV5ts" ] }, "Body": "" } }, { "ID": "2da48fa864dd9efe", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0012?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:25:58 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoWkbW_2n8KvRkdk7Lh_5eOVBjW6JvoW0i9LNQUHM-Df2H1QIbUYIwFnUGLt-bPfFa46Ur-v8Q76mU24KpjW7WIC_HVq4Q5H96pRYk7I6ggUsckTs0" ] }, "Body": "" } }, { "ID": "3ef26f9548e0aec4", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0011?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:25:59 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqZfOfnhYy6nk2TxHz3h1eMu_0KlczCaOb-xcAIBRoRgxk7Q67BqsT5fvb-vAky2phYzQWNHLTk-0T8V2tpPY4Hg23Ub9evuo6_YEndEVdiBRhTcFI" ] }, "Body": "" } }, { "ID": "8f3abbeca307cc5a", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b?alt=json\u0026prettyPrint=false\u0026project=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "106" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE2IiwicmV0ZW50aW9uUG9saWN5Ijp7InJldGVudGlvblBlcmlvZCI6IjkwMDAwIn19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "574" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:25:59 GMT" ], "Etag": [ "CAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqdSQK1TuFGAgs143LV6RLNjzfrsAl5vt-Jb_RQ4dcVGDzK8I29sKKrPmcY0rLIJuVIQar3mdRGhNLhqXp2xCKli28TFq4rtsIgiA4DxCtdVbajIhY" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNiIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNiIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE2IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjU5LjM2NFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTo1OS4zNjRaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiaWFtQ29uZmlndXJhdGlvbiI6eyJidWNrZXRQb2xpY3lPbmx5Ijp7ImVuYWJsZWQiOmZhbHNlfX0sImxvY2F0aW9uIjoiVVMiLCJyZXRlbnRpb25Qb2xpY3kiOnsicmV0ZW50aW9uUGVyaW9kIjoiOTAwMDAiLCJlZmZlY3RpdmVUaW1lIjoiMjAxOS0wNS0wMlQyMjoyNTo1OS4zNjRaIn0sInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwiZXRhZyI6IkNBRT0ifQ==" } }, { "ID": "bb92a1c4ecd9e884", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0016/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTYiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW4iLCJuYW1lIjoic29tZS1vYmplY3QifQo=", "aGVsbG8gd29ybGQ=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3315" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:00 GMT" ], "Etag": [ "COup9/Lx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrRoCa6t1nTWVUrdfIXfyxZBI6PKBkzO24svoJRDEYMEsduIrzBpdDiX8mIUWSxcL8-pSRZgcDvy9_iHKpoVbiUNt4QhlG7zosGpa3WOk--YlBxjeM" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNi9zb21lLW9iamVjdC8xNTU2ODM1OTU5OTUyNjE5Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE2L28vc29tZS1vYmplY3QiLCJuYW1lIjoic29tZS1vYmplY3QiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTYiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk1OTk1MjYxOSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNTo1OS45NTJaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjU6NTkuOTUyWiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjU5Ljk1MloiLCJzaXplIjoiMTEiLCJtZDVIYXNoIjoiWHJZN3UrQWU3dENUeXlLN2oxck53dz09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNi9vL3NvbWUtb2JqZWN0P2dlbmVyYXRpb249MTU1NjgzNTk1OTk1MjYxOSZhbHQ9bWVkaWEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNi9zb21lLW9iamVjdC8xNTU2ODM1OTU5OTUyNjE5L3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNi9vL3NvbWUtb2JqZWN0L2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTYiLCJvYmplY3QiOiJzb21lLW9iamVjdCIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTU5OTUyNjE5IiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNPdXA5L0x4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNi9zb21lLW9iamVjdC8xNTU2ODM1OTU5OTUyNjE5L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTYvby9zb21lLW9iamVjdC9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNiIsIm9iamVjdCI6InNvbWUtb2JqZWN0IiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5NTk5NTI2MTkiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDT3VwOS9MeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTYvc29tZS1vYmplY3QvMTU1NjgzNTk1OTk1MjYxOS9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE2L28vc29tZS1vYmplY3QvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTYiLCJvYmplY3QiOiJzb21lLW9iamVjdCIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTU5OTUyNjE5IiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNPdXA5L0x4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNi9zb21lLW9iamVjdC8xNTU2ODM1OTU5OTUyNjE5L3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTYvby9zb21lLW9iamVjdC9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNiIsIm9iamVjdCI6InNvbWUtb2JqZWN0IiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5NTk5NTI2MTkiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDT3VwOS9MeC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6InlaUmxxZz09IiwiZXRhZyI6IkNPdXA5L0x4L2VFQ0VBRT0iLCJyZXRlbnRpb25FeHBpcmF0aW9uVGltZSI6IjIwMTktMDUtMDNUMjM6MjU6NTkuOTUyWiJ9" } }, { "ID": "8f2ac73db961f1d6", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0016/o/some-object?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 403, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "13884" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:00 GMT" ], "Expires": [ "Thu, 02 May 2019 22:26:00 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2Uok63dRFSkGv0Fum7yPhHf_AtYTWceX5_zkck648-jhWkyym1ezg2Og-LqKJ6nnZCW_gPZuU01OkZErKAQbL7mvQroCq8nEtNTEAosMxk9fJRKpYlc" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6ImZvcmJpZGRlbiIsIm1lc3NhZ2UiOiJPYmplY3QgJ2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNi9zb21lLW9iamVjdCcgaXMgc3ViamVjdCB0byBidWNrZXQncyByZXRlbnRpb24gcG9saWN5IGFuZCBjYW5ub3QgYmUgZGVsZXRlZCwgb3ZlcndyaXR0ZW4gb3IgYXJjaGl2ZWQgdW50aWwgMjAxOS0wNS0wM1QxNjoyNTo1OS45NTIyMDg0MjgtMDc6MDAiLCJkZWJ1Z0luZm8iOiJjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6UkVURU5USU9OX1BPTElDWV9OT1RfTUVUOiBPYmplY3QgJ2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNi9zb21lLW9iamVjdCcgaXMgc3ViamVjdCB0byBidWNrZXQncyByZXRlbnRpb24gcG9saWN5IGFuZCBjYW5ub3QgYmUgZGVsZXRlZCwgb3ZlcndyaXR0ZW4gb3IgYXJjaGl2ZWQgdW50aWwgMjAxOS0wNS0wM1QxNjoyNTo1OS45NTIyMDg0MjgtMDc6MDBcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuRGVsZXRlT2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChEZWxldGVPYmplY3QuamF2YTo4OClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkRlbGV0ZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlT2JqZWN0LmphdmE6MjUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLk9iamVjdHNEZWxlZ2F0b3IuZGVsZXRlKE9iamVjdHNEZWxlZ2F0b3IuamF2YToxMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IE9iamVjdCAnZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE2L3NvbWUtb2JqZWN0JyBpcyBzdWJqZWN0IHRvIGJ1Y2tldCdzIHJldGVudGlvbiBwb2xpY3kgYW5kIGNhbm5vdCBiZSBkZWxldGVkLCBvdmVyd3JpdHRlbiBvciBhcmNoaXZlZCB1bnRpbCAyMDE5LTA1LTAzVDE2OjI1OjU5Ljk1MjIwODQyOC0wNzowMFxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cbmNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLkZhdWx0OiBJbW11dGFibGVFcnJvckRlZmluaXRpb257YmFzZT1GT1JCSURERU4sIGNhdGVnb3J5PVVTRVJfRVJST1IsIGNhdXNlPW51bGwsIGRlYnVnSW5mbz1jb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6UkVURU5USU9OX1BPTElDWV9OT1RfTUVUOiBPYmplY3QgJ2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNi9zb21lLW9iamVjdCcgaXMgc3ViamVjdCB0byBidWNrZXQncyByZXRlbnRpb24gcG9saWN5IGFuZCBjYW5ub3QgYmUgZGVsZXRlZCwgb3ZlcndyaXR0ZW4gb3IgYXJjaGl2ZWQgdW50aWwgMjAxOS0wNS0wM1QxNjoyNTo1OS45NTIyMDg0MjgtMDc6MDBcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLm9iamVjdHMuRGVsZXRlT2JqZWN0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChEZWxldGVPYmplY3QuamF2YTo4OClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkRlbGV0ZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlT2JqZWN0LmphdmE6MjUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLk9iamVjdHNEZWxlZ2F0b3IuZGVsZXRlKE9iamVjdHNEZWxlZ2F0b3IuamF2YToxMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IE9iamVjdCAnZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE2L3NvbWUtb2JqZWN0JyBpcyBzdWJqZWN0IHRvIGJ1Y2tldCdzIHJldGVudGlvbiBwb2xpY3kgYW5kIGNhbm5vdCBiZSBkZWxldGVkLCBvdmVyd3JpdHRlbiBvciBhcmNoaXZlZCB1bnRpbCAyMDE5LTA1LTAzVDE2OjI1OjU5Ljk1MjIwODQyOC0wNzowMFxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGRvbWFpbj1nbG9iYWwsIGV4dGVuZGVkSGVscD1udWxsLCBodHRwSGVhZGVycz17fSwgaHR0cFN0YXR1cz1mb3JiaWRkZW4sIGludGVybmFsUmVhc29uPVJlYXNvbnthcmd1bWVudHM9e30sIGNhdXNlPW51bGwsIGNvZGU9Z2RhdGEuQ29yZUVycm9yRG9tYWluLkZPUkJJRERFTiwgY3JlYXRlZEJ5QmFja2VuZD10cnVlLCBkZWJ1Z01lc3NhZ2U9Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlJFVEVOVElPTl9QT0xJQ1lfTk9UX01FVDogT2JqZWN0ICdnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTYvc29tZS1vYmplY3QnIGlzIHN1YmplY3QgdG8gYnVja2V0J3MgcmV0ZW50aW9uIHBvbGljeSBhbmQgY2Fubm90IGJlIGRlbGV0ZWQsIG92ZXJ3cml0dGVuIG9yIGFyY2hpdmVkIHVudGlsIDIwMTktMDUtMDNUMTY6MjU6NTkuOTUyMjA4NDI4LTA3OjAwXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkRlbGV0ZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlT2JqZWN0LmphdmE6ODgpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5EZWxldGVPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZU9iamVjdC5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLmRlbGV0ZShPYmplY3RzRGVsZWdhdG9yLmphdmE6MTEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBPYmplY3QgJ2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNi9zb21lLW9iamVjdCcgaXMgc3ViamVjdCB0byBidWNrZXQncyByZXRlbnRpb24gcG9saWN5IGFuZCBjYW5ub3QgYmUgZGVsZXRlZCwgb3ZlcndyaXR0ZW4gb3IgYXJjaGl2ZWQgdW50aWwgMjAxOS0wNS0wM1QxNjoyNTo1OS45NTIyMDg0MjgtMDc6MDBcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuLCBlcnJvclByb3RvQ29kZT1GT1JCSURERU4sIGVycm9yUHJvdG9Eb21haW49Z2RhdGEuQ29yZUVycm9yRG9tYWluLCBmaWx0ZXJlZE1lc3NhZ2U9bnVsbCwgbG9jYXRpb249bnVsbCwgbWVzc2FnZT1PYmplY3QgJ2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNi9zb21lLW9iamVjdCcgaXMgc3ViamVjdCB0byBidWNrZXQncyByZXRlbnRpb24gcG9saWN5IGFuZCBjYW5ub3QgYmUgZGVsZXRlZCwgb3ZlcndyaXR0ZW4gb3IgYXJjaGl2ZWQgdW50aWwgMjAxOS0wNS0wM1QxNjoyNTo1OS45NTIyMDg0MjgtMDc6MDAsIHVubmFtZWRBcmd1bWVudHM9W119LCBsb2NhdGlvbj1udWxsLCBtZXNzYWdlPU9iamVjdCAnZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE2L3NvbWUtb2JqZWN0JyBpcyBzdWJqZWN0IHRvIGJ1Y2tldCdzIHJldGVudGlvbiBwb2xpY3kgYW5kIGNhbm5vdCBiZSBkZWxldGVkLCBvdmVyd3JpdHRlbiBvciBhcmNoaXZlZCB1bnRpbCAyMDE5LTA1LTAzVDE2OjI1OjU5Ljk1MjIwODQyOC0wNzowMCwgcmVhc29uPWZvcmJpZGRlbiwgcnBjQ29kZT00MDN9IE9iamVjdCAnZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE2L3NvbWUtb2JqZWN0JyBpcyBzdWJqZWN0IHRvIGJ1Y2tldCdzIHJldGVudGlvbiBwb2xpY3kgYW5kIGNhbm5vdCBiZSBkZWxldGVkLCBvdmVyd3JpdHRlbiBvciBhcmNoaXZlZCB1bnRpbCAyMDE5LTA1LTAzVDE2OjI1OjU5Ljk1MjIwODQyOC0wNzowMDogY29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlJFVEVOVElPTl9QT0xJQ1lfTk9UX01FVDogT2JqZWN0ICdnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTYvc29tZS1vYmplY3QnIGlzIHN1YmplY3QgdG8gYnVja2V0J3MgcmV0ZW50aW9uIHBvbGljeSBhbmQgY2Fubm90IGJlIGRlbGV0ZWQsIG92ZXJ3cml0dGVuIG9yIGFyY2hpdmVkIHVudGlsIDIwMTktMDUtMDNUMTY6MjU6NTkuOTUyMjA4NDI4LTA3OjAwXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkRlbGV0ZU9iamVjdC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoRGVsZXRlT2JqZWN0LmphdmE6ODgpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMub2JqZWN0cy5EZWxldGVPYmplY3QuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKERlbGV0ZU9iamVjdC5qYXZhOjI1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLmRlbGV0ZShPYmplY3RzRGVsZWdhdG9yLmphdmE6MTEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBPYmplY3QgJ2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNi9zb21lLW9iamVjdCcgaXMgc3ViamVjdCB0byBidWNrZXQncyByZXRlbnRpb24gcG9saWN5IGFuZCBjYW5ub3QgYmUgZGVsZXRlZCwgb3ZlcndyaXR0ZW4gb3IgYXJjaGl2ZWQgdW50aWwgMjAxOS0wNS0wM1QxNjoyNTo1OS45NTIyMDg0MjgtMDc6MDBcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLkVycm9yQ29sbGVjdG9yLnRvRmF1bHQoRXJyb3JDb2xsZWN0b3IuamF2YTo1NClcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lFcnJvckNvbnZlcnRlci50b0ZhdWx0KFJvc3lFcnJvckNvbnZlcnRlci5qYXZhOjY3KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUhhbmRsZXIkMi5jYWxsKFJvc3lIYW5kbGVyLmphdmE6MjU5KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUhhbmRsZXIkMi5jYWxsKFJvc3lIYW5kbGVyLmphdmE6MjM5KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRGlyZWN0RXhlY3V0b3IuZXhlY3V0ZShEaXJlY3RFeGVjdXRvci5qYXZhOjMwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuZXhlY3V0ZUxpc3RlbmVyKEFic3RyYWN0RnV0dXJlLmphdmE6MTE0Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmNvbXBsZXRlKEFic3RyYWN0RnV0dXJlLmphdmE6OTYzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuc2V0KEFic3RyYWN0RnV0dXJlLmphdmE6NzMxKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRGlyZWN0RXhlY3V0b3IuZXhlY3V0ZShEaXJlY3RFeGVjdXRvci5qYXZhOjMwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuZXhlY3V0ZUxpc3RlbmVyKEFic3RyYWN0RnV0dXJlLmphdmE6MTE0Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmNvbXBsZXRlKEFic3RyYWN0RnV0dXJlLmphdmE6OTYzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuc2V0KEFic3RyYWN0RnV0dXJlLmphdmE6NzMxKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIudGhyZWFkLlRocmVhZFRyYWNrZXJzJFRocmVhZFRyYWNraW5nUnVubmFibGUucnVuKFRocmVhZFRyYWNrZXJzLmphdmE6MTI2KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChUcmFjZUNvbnRleHQuamF2YTo0NTMpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5zZXJ2ZXIuQ29tbW9uTW9kdWxlJENvbnRleHRDYXJyeWluZ0V4ZWN1dG9yU2VydmljZSQxLnJ1bkluQ29udGV4dChDb21tb25Nb2R1bGUuamF2YTo4MDIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUkMS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDYwKVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkQWJzdHJhY3RUcmFjZUNvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKFRyYWNlQ29udGV4dC5qYXZhOjMxOSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChUcmFjZUNvbnRleHQuamF2YTozMTEpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuKFRyYWNlQ29udGV4dC5qYXZhOjQ1Nylcblx0YXQgY29tLmdvb2dsZS5nc2UuaW50ZXJuYWwuRGlzcGF0Y2hRdWV1ZUltcGwkV29ya2VyVGhyZWFkLnJ1bihEaXNwYXRjaFF1ZXVlSW1wbC5qYXZhOjQwMylcbiJ9XSwiY29kZSI6NDAzLCJtZXNzYWdlIjoiT2JqZWN0ICdnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTYvc29tZS1vYmplY3QnIGlzIHN1YmplY3QgdG8gYnVja2V0J3MgcmV0ZW50aW9uIHBvbGljeSBhbmQgY2Fubm90IGJlIGRlbGV0ZWQsIG92ZXJ3cml0dGVuIG9yIGFyY2hpdmVkIHVudGlsIDIwMTktMDUtMDNUMTY6MjU6NTkuOTUyMjA4NDI4LTA3OjAwIn19" } }, { "ID": "5a7a0988789dfb17", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0016?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "25" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJyZXRlbnRpb25Qb2xpY3kiOm51bGx9Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "2431" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:00 GMT" ], "Etag": [ "CAI=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrZIBPbBTYIUYYaBFrcXzNnp7uuC8DoPry45bX57PyfL7aM5a83NLxYnvWsXD62w3LrRVksNhJbrLnSL5e8ZS6b0Cto8ufh-V00gNrGI-CaTc4achc" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNiIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNiIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE2IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI1OjU5LjM2NFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNjowMC43NTZaIiwibWV0YWdlbmVyYXRpb24iOiIyIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTYvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE2L2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTYiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FJPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE2L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTYvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTYiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTYvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNi9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNiIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUk9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBST0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBST0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwiZXRhZyI6IkNBST0ifQ==" } }, { "ID": "8410bda61aa0b6fd", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0016/o/some-object?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:26:01 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uo2MOVFr2ZwvkwYm32qtqndRBhJnBc28nVBEBowKjIIxpOxiYcSef4wtz9sLTJ23PbXr1F8L_TfGwyShv5j1eTsQ-91OXU8Q8JEZtui9VVyK96j2D4" ] }, "Body": "" } }, { "ID": "7b024f33e16d850f", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0016?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:26:01 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpDkcsqcqPLSySgf13o9jWNafbKdVjSRqGNu3ZedvF7TlL9TBswdMMpcl0zQOHtvXWIrhrcZODr7RjRhHuvS8gJdMbnYeQDHrBCbiH6x9WrnaZ5uIQ" ] }, "Body": "" } }, { "ID": "33b0efc1b91cfb42", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b?alt=json\u0026prettyPrint=false\u0026project=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "106" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE3IiwicmV0ZW50aW9uUG9saWN5Ijp7InJldGVudGlvblBlcmlvZCI6IjkwMDAwIn19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "574" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:02 GMT" ], "Etag": [ "CAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpItvsNld0b1FGsjQgaVCDxW22UEra8vRGfkWtbDS7R2kMbHRPr0I6iPjzaQBOaa9-xUJxGO-JV6RhMlWwH2NY-FXY2-0lrkZiAzIL-tdFwkCwlF-Q" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNyIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE3IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI2OjAxLjkwOFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNjowMS45MDhaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiaWFtQ29uZmlndXJhdGlvbiI6eyJidWNrZXRQb2xpY3lPbmx5Ijp7ImVuYWJsZWQiOmZhbHNlfX0sImxvY2F0aW9uIjoiVVMiLCJyZXRlbnRpb25Qb2xpY3kiOnsicmV0ZW50aW9uUGVyaW9kIjoiOTAwMDAiLCJlZmZlY3RpdmVUaW1lIjoiMjAxOS0wNS0wMlQyMjoyNjowMS45MDhaIn0sInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwiZXRhZyI6IkNBRT0ifQ==" } }, { "ID": "632b9a0387d9cff1", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0017?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "2520" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:02 GMT" ], "Etag": [ "CAE=" ], "Expires": [ "Thu, 02 May 2019 22:26:02 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpEVtrO8ed8TEHdpzyw857ZykloGKTT56atylmGnu682Y0VxI_T6SWN0JLFupJ_2Cu80ntiZttFSCBqwqFGfxVrRqsNnf0KBDyzqOH8eI-BaWPBXvE" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNyIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE3IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI2OjAxLjkwOFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNjowMS45MDhaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTcvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE3L2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTciLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE3L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTcvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTciLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTcvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNy9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNyIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUU9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBRT0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsInJldGVudGlvblBvbGljeSI6eyJyZXRlbnRpb25QZXJpb2QiOiI5MDAwMCIsImVmZmVjdGl2ZVRpbWUiOiIyMDE5LTA1LTAyVDIyOjI2OjAxLjkwOFoifSwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJldGFnIjoiQ0FFPSJ9" } }, { "ID": "a32a5924f876577b", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0017/lockRetentionPolicy?alt=json\u0026ifMetagenerationMatch=1\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "0" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "639" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:03 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpsYL8RxAKClLw1KRdSSIORQHYKKf_HMml2vtwDOFrh0kTYDzhGEgX2RJAPQKOP2-70q7ZZ2VfkkGz12tmTiRgSuwB2dM3xxZxZucASROVeoit9Shg" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNyIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE3IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI2OjAxLjkwOFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNjowMy41NDRaIiwibWV0YWdlbmVyYXRpb24iOiIyIiwiaWFtQ29uZmlndXJhdGlvbiI6eyJidWNrZXRQb2xpY3lPbmx5Ijp7ImVuYWJsZWQiOmZhbHNlfX0sIm93bmVyIjp7ImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCJ9LCJsb2NhdGlvbiI6IlVTIiwicmV0ZW50aW9uUG9saWN5Ijp7InJldGVudGlvblBlcmlvZCI6IjkwMDAwIiwiZWZmZWN0aXZlVGltZSI6IjIwMTktMDUtMDJUMjI6MjY6MDEuOTA4WiIsImlzTG9ja2VkIjp0cnVlfSwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJldGFnIjoiQ0FJPSJ9" } }, { "ID": "718775f2f8320cfd", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0017?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "2536" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:03 GMT" ], "Etag": [ "CAI=" ], "Expires": [ "Thu, 02 May 2019 22:26:03 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UprHupyIuGJCYeUCPKigfkARZRkCc2Jz051KFrXK7YS0FbdKxNe3r20jon1ejkooHsAtcXQOi1tDV41Ob9dJ3Zoyj7stDImJ0eQriMO0WLLQ__-V54" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNyIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE3IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI2OjAxLjkwOFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNjowMy41NDRaIiwibWV0YWdlbmVyYXRpb24iOiIyIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTcvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE3L2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTciLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FJPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE3L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTcvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTciLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTcvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNy9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNyIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUk9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBST0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBST0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsInJldGVudGlvblBvbGljeSI6eyJyZXRlbnRpb25QZXJpb2QiOiI5MDAwMCIsImVmZmVjdGl2ZVRpbWUiOiIyMDE5LTA1LTAyVDIyOjI2OjAxLjkwOFoiLCJpc0xvY2tlZCI6dHJ1ZX0sInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwiZXRhZyI6IkNBST0ifQ==" } }, { "ID": "2f4b1104fa94954b", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0017?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "47" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJyZXRlbnRpb25Qb2xpY3kiOnsicmV0ZW50aW9uUGVyaW9kIjoiMzYwMCJ9fQo=" ] }, "Response": { "StatusCode": 403, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Content-Length": [ "13774" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:04 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UrafLpm39Fg6hBYYi9lSEizIWUdMduEDQykOeT9Bch6uf9BNQUO9sOAnWpTklSpNac1yW_kSNj-JR8LMmVLirC2kqG2DcQdE-Hg5dtVBkVZ4Xhjlc8" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6ImZvcmJpZGRlbiIsIm1lc3NhZ2UiOiJDYW5ub3QgcmVkdWNlIHJldGVudGlvbiBkdXJhdGlvbiBvZiBhIGxvY2tlZCBSZXRlbnRpb24gUG9saWN5IGZvciBidWNrZXQgJ2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNycuIiwiZGVidWdJbmZvIjoiY29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OkFDQ0VTU19ERU5JRUQ6IENhbm5vdCByZWR1Y2UgcmV0ZW50aW9uIGR1cmF0aW9uIG9mIGEgbG9ja2VkIFJldGVudGlvbiBQb2xpY3kgZm9yIGJ1Y2tldCAnZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE3Jy5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuVXBkYXRlQW5kUGF0Y2hCdWNrZXQudXBkYXRlQnVja2V0KFVwZGF0ZUFuZFBhdGNoQnVja2V0LmphdmE6MTE5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuUGF0Y2hCdWNrZXQucGF0Y2hCdWNrZXQoUGF0Y2hCdWNrZXQuamF2YToxOTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYnVja2V0cy5QYXRjaEJ1Y2tldC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUGF0Y2hCdWNrZXQuamF2YToxNDEpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYnVja2V0cy5QYXRjaEJ1Y2tldC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUGF0Y2hCdWNrZXQuamF2YTo0Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQnVja2V0c0RlbGVnYXRvci51cGRhdGUoQnVja2V0c0RlbGVnYXRvci5qYXZhOjEwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogQ2Fubm90IHJlZHVjZSByZXRlbnRpb24gZHVyYXRpb24gb2YgYSBsb2NrZWQgUmV0ZW50aW9uIFBvbGljeSBmb3IgYnVja2V0ICdnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTcnLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxOSBtb3JlXG5cbmNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLkZhdWx0OiBJbW11dGFibGVFcnJvckRlZmluaXRpb257YmFzZT1GT1JCSURERU4sIGNhdGVnb3J5PVVTRVJfRVJST1IsIGNhdXNlPW51bGwsIGRlYnVnSW5mbz1jb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6QUNDRVNTX0RFTklFRDogQ2Fubm90IHJlZHVjZSByZXRlbnRpb24gZHVyYXRpb24gb2YgYSBsb2NrZWQgUmV0ZW50aW9uIFBvbGljeSBmb3IgYnVja2V0ICdnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTcnLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYnVja2V0cy5VcGRhdGVBbmRQYXRjaEJ1Y2tldC51cGRhdGVCdWNrZXQoVXBkYXRlQW5kUGF0Y2hCdWNrZXQuamF2YToxMTkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYnVja2V0cy5QYXRjaEJ1Y2tldC5wYXRjaEJ1Y2tldChQYXRjaEJ1Y2tldC5qYXZhOjE5Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5idWNrZXRzLlBhdGNoQnVja2V0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChQYXRjaEJ1Y2tldC5qYXZhOjE0MSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5idWNrZXRzLlBhdGNoQnVja2V0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChQYXRjaEJ1Y2tldC5qYXZhOjQ2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5CdWNrZXRzRGVsZWdhdG9yLnVwZGF0ZShCdWNrZXRzRGVsZWdhdG9yLmphdmE6MTAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBDYW5ub3QgcmVkdWNlIHJldGVudGlvbiBkdXJhdGlvbiBvZiBhIGxvY2tlZCBSZXRlbnRpb24gUG9saWN5IGZvciBidWNrZXQgJ2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNycuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE5IG1vcmVcbiwgZG9tYWluPWdsb2JhbCwgZXh0ZW5kZWRIZWxwPW51bGwsIGh0dHBIZWFkZXJzPXt9LCBodHRwU3RhdHVzPWZvcmJpZGRlbiwgaW50ZXJuYWxSZWFzb249UmVhc29ue2FyZ3VtZW50cz17fSwgY2F1c2U9bnVsbCwgY29kZT1nZGF0YS5Db3JlRXJyb3JEb21haW4uRk9SQklEREVOLCBjcmVhdGVkQnlCYWNrZW5kPXRydWUsIGRlYnVnTWVzc2FnZT1jb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6QUNDRVNTX0RFTklFRDogQ2Fubm90IHJlZHVjZSByZXRlbnRpb24gZHVyYXRpb24gb2YgYSBsb2NrZWQgUmV0ZW50aW9uIFBvbGljeSBmb3IgYnVja2V0ICdnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTcnLlxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYnVja2V0cy5VcGRhdGVBbmRQYXRjaEJ1Y2tldC51cGRhdGVCdWNrZXQoVXBkYXRlQW5kUGF0Y2hCdWNrZXQuamF2YToxMTkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYnVja2V0cy5QYXRjaEJ1Y2tldC5wYXRjaEJ1Y2tldChQYXRjaEJ1Y2tldC5qYXZhOjE5Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5idWNrZXRzLlBhdGNoQnVja2V0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChQYXRjaEJ1Y2tldC5qYXZhOjE0MSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5idWNrZXRzLlBhdGNoQnVja2V0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChQYXRjaEJ1Y2tldC5qYXZhOjQ2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5CdWNrZXRzRGVsZWdhdG9yLnVwZGF0ZShCdWNrZXRzRGVsZWdhdG9yLmphdmE6MTAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBDYW5ub3QgcmVkdWNlIHJldGVudGlvbiBkdXJhdGlvbiBvZiBhIGxvY2tlZCBSZXRlbnRpb24gUG9saWN5IGZvciBidWNrZXQgJ2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNycuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE5IG1vcmVcbiwgZXJyb3JQcm90b0NvZGU9Rk9SQklEREVOLCBlcnJvclByb3RvRG9tYWluPWdkYXRhLkNvcmVFcnJvckRvbWFpbiwgZmlsdGVyZWRNZXNzYWdlPW51bGwsIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9Q2Fubm90IHJlZHVjZSByZXRlbnRpb24gZHVyYXRpb24gb2YgYSBsb2NrZWQgUmV0ZW50aW9uIFBvbGljeSBmb3IgYnVja2V0ICdnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTcnLiwgdW5uYW1lZEFyZ3VtZW50cz1bXX0sIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9Q2Fubm90IHJlZHVjZSByZXRlbnRpb24gZHVyYXRpb24gb2YgYSBsb2NrZWQgUmV0ZW50aW9uIFBvbGljeSBmb3IgYnVja2V0ICdnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTcnLiwgcmVhc29uPWZvcmJpZGRlbiwgcnBjQ29kZT00MDN9IENhbm5vdCByZWR1Y2UgcmV0ZW50aW9uIGR1cmF0aW9uIG9mIGEgbG9ja2VkIFJldGVudGlvbiBQb2xpY3kgZm9yIGJ1Y2tldCAnZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE3Jy46IGNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpBQ0NFU1NfREVOSUVEOiBDYW5ub3QgcmVkdWNlIHJldGVudGlvbiBkdXJhdGlvbiBvZiBhIGxvY2tlZCBSZXRlbnRpb24gUG9saWN5IGZvciBidWNrZXQgJ2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNycuXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5idWNrZXRzLlVwZGF0ZUFuZFBhdGNoQnVja2V0LnVwZGF0ZUJ1Y2tldChVcGRhdGVBbmRQYXRjaEJ1Y2tldC5qYXZhOjExOSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5idWNrZXRzLlBhdGNoQnVja2V0LnBhdGNoQnVja2V0KFBhdGNoQnVja2V0LmphdmE6MTk2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuUGF0Y2hCdWNrZXQuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFBhdGNoQnVja2V0LmphdmE6MTQxKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuUGF0Y2hCdWNrZXQuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFBhdGNoQnVja2V0LmphdmE6NDYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLkJ1Y2tldHNEZWxlZ2F0b3IudXBkYXRlKEJ1Y2tldHNEZWxlZ2F0b3IuamF2YToxMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IENhbm5vdCByZWR1Y2UgcmV0ZW50aW9uIGR1cmF0aW9uIG9mIGEgbG9ja2VkIFJldGVudGlvbiBQb2xpY3kgZm9yIGJ1Y2tldCAnZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE3Jy5cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTkgbW9yZVxuXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLkVycm9yQ29sbGVjdG9yLnRvRmF1bHQoRXJyb3JDb2xsZWN0b3IuamF2YTo1NClcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lFcnJvckNvbnZlcnRlci50b0ZhdWx0KFJvc3lFcnJvckNvbnZlcnRlci5qYXZhOjY3KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUhhbmRsZXIkMi5jYWxsKFJvc3lIYW5kbGVyLmphdmE6MjU5KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUhhbmRsZXIkMi5jYWxsKFJvc3lIYW5kbGVyLmphdmE6MjM5KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRGlyZWN0RXhlY3V0b3IuZXhlY3V0ZShEaXJlY3RFeGVjdXRvci5qYXZhOjMwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuZXhlY3V0ZUxpc3RlbmVyKEFic3RyYWN0RnV0dXJlLmphdmE6MTE0Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmNvbXBsZXRlKEFic3RyYWN0RnV0dXJlLmphdmE6OTYzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuc2V0KEFic3RyYWN0RnV0dXJlLmphdmE6NzMxKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRGlyZWN0RXhlY3V0b3IuZXhlY3V0ZShEaXJlY3RFeGVjdXRvci5qYXZhOjMwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuZXhlY3V0ZUxpc3RlbmVyKEFic3RyYWN0RnV0dXJlLmphdmE6MTE0Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmNvbXBsZXRlKEFic3RyYWN0RnV0dXJlLmphdmE6OTYzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuc2V0KEFic3RyYWN0RnV0dXJlLmphdmE6NzMxKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIudGhyZWFkLlRocmVhZFRyYWNrZXJzJFRocmVhZFRyYWNraW5nUnVubmFibGUucnVuKFRocmVhZFRyYWNrZXJzLmphdmE6MTI2KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChUcmFjZUNvbnRleHQuamF2YTo0NTMpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5zZXJ2ZXIuQ29tbW9uTW9kdWxlJENvbnRleHRDYXJyeWluZ0V4ZWN1dG9yU2VydmljZSQxLnJ1bkluQ29udGV4dChDb21tb25Nb2R1bGUuamF2YTo4MDIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUkMS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDYwKVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkQWJzdHJhY3RUcmFjZUNvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKFRyYWNlQ29udGV4dC5qYXZhOjMxOSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChUcmFjZUNvbnRleHQuamF2YTozMTEpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuKFRyYWNlQ29udGV4dC5qYXZhOjQ1Nylcblx0YXQgY29tLmdvb2dsZS5nc2UuaW50ZXJuYWwuRGlzcGF0Y2hRdWV1ZUltcGwkV29ya2VyVGhyZWFkLnJ1bihEaXNwYXRjaFF1ZXVlSW1wbC5qYXZhOjQwMylcbiJ9XSwiY29kZSI6NDAzLCJtZXNzYWdlIjoiQ2Fubm90IHJlZHVjZSByZXRlbnRpb24gZHVyYXRpb24gb2YgYSBsb2NrZWQgUmV0ZW50aW9uIFBvbGljeSBmb3IgYnVja2V0ICdnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTcnLiJ9fQ==" } }, { "ID": "a8964565736a4805", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b?alt=json\u0026prettyPrint=false\u0026project=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "106" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE4IiwicmV0ZW50aW9uUG9saWN5Ijp7InJldGVudGlvblBlcmlvZCI6IjkwMDAwIn19Cg==" ] }, "Response": { "StatusCode": 429, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Content-Length": [ "12201" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:04 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UrNbiNCNtu8DhS-gNXfoe4R9DFKEVzknZ0g6YoI0JdvwH6P199oVJ2oaJwh9WXMte6frhDr_vJo1_PlxLhezMnUTJzMYZgPlPWdU1QN9imk3hXgawE" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6InVzYWdlTGltaXRzIiwicmVhc29uIjoicmF0ZUxpbWl0RXhjZWVkZWQiLCJtZXNzYWdlIjoiVGhlIHByb2plY3QgZXhjZWVkZWQgdGhlIHJhdGUgbGltaXQgZm9yIGNyZWF0aW5nIGFuZCBkZWxldGluZyBidWNrZXRzLiIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpQUk9KRUNUX0JVQ0tFVF9PUF9SQVRFX1RPT19ISUdIOiBDcmVhdGluZyBidWNrZXRzIHRvbyBxdWlja2x5LCBwbGVhc2Ugc2xvdyBkb3duXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5idWNrZXRzLkluc2VydEJ1Y2tldC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoSW5zZXJ0QnVja2V0LmphdmE6MTg0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuSW5zZXJ0QnVja2V0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRCdWNrZXQuamF2YTo0Milcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQnVja2V0c0RlbGVnYXRvci5pbnNlcnQoQnVja2V0c0RlbGVnYXRvci5qYXZhOjk1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBDcmVhdGluZyBidWNrZXRzIHRvbyBxdWlja2x5LCBwbGVhc2Ugc2xvdyBkb3duXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPVRPT19NQU5ZX1JFUVVFU1RTLCBjYXRlZ29yeT1RVU9UQV9FUlJPUiwgY2F1c2U9bnVsbCwgZGVidWdJbmZvPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpQUk9KRUNUX0JVQ0tFVF9PUF9SQVRFX1RPT19ISUdIOiBDcmVhdGluZyBidWNrZXRzIHRvbyBxdWlja2x5LCBwbGVhc2Ugc2xvdyBkb3duXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5idWNrZXRzLkluc2VydEJ1Y2tldC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoSW5zZXJ0QnVja2V0LmphdmE6MTg0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuSW5zZXJ0QnVja2V0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRCdWNrZXQuamF2YTo0Milcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQnVja2V0c0RlbGVnYXRvci5pbnNlcnQoQnVja2V0c0RlbGVnYXRvci5qYXZhOjk1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBDcmVhdGluZyBidWNrZXRzIHRvbyBxdWlja2x5LCBwbGVhc2Ugc2xvdyBkb3duXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZG9tYWluPXVzYWdlTGltaXRzLCBleHRlbmRlZEhlbHA9bnVsbCwgaHR0cEhlYWRlcnM9e30sIGh0dHBTdGF0dXM9dG9vTWFueVJlcXVlc3RzLCBpbnRlcm5hbFJlYXNvbj1SZWFzb257YXJndW1lbnRzPXt9LCBjYXVzZT1udWxsLCBjb2RlPWNsb3VkLmJpZ3N0b3JlLmFwaS5CaWdzdG9yZUVycm9yRG9tYWluLkNMSUVOVF9RVU9UQV9FWENFRURFRCwgY3JlYXRlZEJ5QmFja2VuZD10cnVlLCBkZWJ1Z01lc3NhZ2U9Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlBST0pFQ1RfQlVDS0VUX09QX1JBVEVfVE9PX0hJR0g6IENyZWF0aW5nIGJ1Y2tldHMgdG9vIHF1aWNrbHksIHBsZWFzZSBzbG93IGRvd25cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuSW5zZXJ0QnVja2V0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRCdWNrZXQuamF2YToxODQpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYnVja2V0cy5JbnNlcnRCdWNrZXQuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEluc2VydEJ1Y2tldC5qYXZhOjQyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5CdWNrZXRzRGVsZWdhdG9yLmluc2VydChCdWNrZXRzRGVsZWdhdG9yLmphdmE6OTUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IENyZWF0aW5nIGJ1Y2tldHMgdG9vIHF1aWNrbHksIHBsZWFzZSBzbG93IGRvd25cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuLCBlcnJvclByb3RvQ29kZT1DTElFTlRfUVVPVEFfRVhDRUVERUQsIGVycm9yUHJvdG9Eb21haW49Y2xvdWQuYmlnc3RvcmUuYXBpLkJpZ3N0b3JlRXJyb3JEb21haW4sIGZpbHRlcmVkTWVzc2FnZT1udWxsLCBsb2NhdGlvbj1lbnRpdHkucmVzb3VyY2UuYnVja2V0Lm5hbWUsIG1lc3NhZ2U9VGhlIHByb2plY3QgZXhjZWVkZWQgdGhlIHJhdGUgbGltaXQgZm9yIGNyZWF0aW5nIGFuZCBkZWxldGluZyBidWNrZXRzLiwgdW5uYW1lZEFyZ3VtZW50cz1bXX0sIGxvY2F0aW9uPWVudGl0eS5yZXNvdXJjZS5idWNrZXQubmFtZSwgbWVzc2FnZT1UaGUgcHJvamVjdCBleGNlZWRlZCB0aGUgcmF0ZSBsaW1pdCBmb3IgY3JlYXRpbmcgYW5kIGRlbGV0aW5nIGJ1Y2tldHMuLCByZWFzb249cmF0ZUxpbWl0RXhjZWVkZWQsIHJwY0NvZGU9NDI5fSBUaGUgcHJvamVjdCBleGNlZWRlZCB0aGUgcmF0ZSBsaW1pdCBmb3IgY3JlYXRpbmcgYW5kIGRlbGV0aW5nIGJ1Y2tldHMuOiBjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6UFJPSkVDVF9CVUNLRVRfT1BfUkFURV9UT09fSElHSDogQ3JlYXRpbmcgYnVja2V0cyB0b28gcXVpY2tseSwgcGxlYXNlIHNsb3cgZG93blxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYnVja2V0cy5JbnNlcnRCdWNrZXQuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEluc2VydEJ1Y2tldC5qYXZhOjE4NClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5idWNrZXRzLkluc2VydEJ1Y2tldC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoSW5zZXJ0QnVja2V0LmphdmE6NDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLkJ1Y2tldHNEZWxlZ2F0b3IuaW5zZXJ0KEJ1Y2tldHNEZWxlZ2F0b3IuamF2YTo5NSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogQ3JlYXRpbmcgYnVja2V0cyB0b28gcXVpY2tseSwgcGxlYXNlIHNsb3cgZG93blxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRXJyb3JDb2xsZWN0b3IudG9GYXVsdChFcnJvckNvbGxlY3Rvci5qYXZhOjU0KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUVycm9yQ29udmVydGVyLnRvRmF1bHQoUm9zeUVycm9yQ29udmVydGVyLmphdmE6NjcpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyNTkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyMzkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci50aHJlYWQuVGhyZWFkVHJhY2tlcnMkVGhyZWFkVHJhY2tpbmdSdW5uYWJsZS5ydW4oVGhyZWFkVHJhY2tlcnMuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjQ1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnNlcnZlci5Db21tb25Nb2R1bGUkQ29udGV4dENhcnJ5aW5nRXhlY3V0b3JTZXJ2aWNlJDEucnVuSW5Db250ZXh0KENvbW1vbk1vZHVsZS5qYXZhOjgwMilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZSQxLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NjApXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoVHJhY2VDb250ZXh0LmphdmE6MzE5KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjMxMSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDU3KVxuXHRhdCBjb20uZ29vZ2xlLmdzZS5pbnRlcm5hbC5EaXNwYXRjaFF1ZXVlSW1wbCRXb3JrZXJUaHJlYWQucnVuKERpc3BhdGNoUXVldWVJbXBsLmphdmE6NDAzKVxuIn1dLCJjb2RlIjo0MjksIm1lc3NhZ2UiOiJUaGUgcHJvamVjdCBleGNlZWRlZCB0aGUgcmF0ZSBsaW1pdCBmb3IgY3JlYXRpbmcgYW5kIGRlbGV0aW5nIGJ1Y2tldHMuIn19" } }, { "ID": "49648eb4e4e2ddda", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b?alt=json\u0026prettyPrint=false\u0026project=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "106" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE4IiwicmV0ZW50aW9uUG9saWN5Ijp7InJldGVudGlvblBlcmlvZCI6IjkwMDAwIn19Cg==" ] }, "Response": { "StatusCode": 429, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Content-Length": [ "12201" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:05 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UplUHmGCg4wOKtpKVz2KH0cn-th8s-KXQR62bOkAF1pV1zIZJvsoI_tURcFttkyHks8g05Hln5fT4Ej_O-Lx6JCTovYYwhhHIK7AAcialHMj5fPHk4" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6InVzYWdlTGltaXRzIiwicmVhc29uIjoicmF0ZUxpbWl0RXhjZWVkZWQiLCJtZXNzYWdlIjoiVGhlIHByb2plY3QgZXhjZWVkZWQgdGhlIHJhdGUgbGltaXQgZm9yIGNyZWF0aW5nIGFuZCBkZWxldGluZyBidWNrZXRzLiIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpQUk9KRUNUX0JVQ0tFVF9PUF9SQVRFX1RPT19ISUdIOiBDcmVhdGluZyBidWNrZXRzIHRvbyBxdWlja2x5LCBwbGVhc2Ugc2xvdyBkb3duXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5idWNrZXRzLkluc2VydEJ1Y2tldC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoSW5zZXJ0QnVja2V0LmphdmE6MTg0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuSW5zZXJ0QnVja2V0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRCdWNrZXQuamF2YTo0Milcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQnVja2V0c0RlbGVnYXRvci5pbnNlcnQoQnVja2V0c0RlbGVnYXRvci5qYXZhOjk1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBDcmVhdGluZyBidWNrZXRzIHRvbyBxdWlja2x5LCBwbGVhc2Ugc2xvdyBkb3duXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPVRPT19NQU5ZX1JFUVVFU1RTLCBjYXRlZ29yeT1RVU9UQV9FUlJPUiwgY2F1c2U9bnVsbCwgZGVidWdJbmZvPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpQUk9KRUNUX0JVQ0tFVF9PUF9SQVRFX1RPT19ISUdIOiBDcmVhdGluZyBidWNrZXRzIHRvbyBxdWlja2x5LCBwbGVhc2Ugc2xvdyBkb3duXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5idWNrZXRzLkluc2VydEJ1Y2tldC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoSW5zZXJ0QnVja2V0LmphdmE6MTg0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuSW5zZXJ0QnVja2V0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRCdWNrZXQuamF2YTo0Milcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQnVja2V0c0RlbGVnYXRvci5pbnNlcnQoQnVja2V0c0RlbGVnYXRvci5qYXZhOjk1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBDcmVhdGluZyBidWNrZXRzIHRvbyBxdWlja2x5LCBwbGVhc2Ugc2xvdyBkb3duXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZG9tYWluPXVzYWdlTGltaXRzLCBleHRlbmRlZEhlbHA9bnVsbCwgaHR0cEhlYWRlcnM9e30sIGh0dHBTdGF0dXM9dG9vTWFueVJlcXVlc3RzLCBpbnRlcm5hbFJlYXNvbj1SZWFzb257YXJndW1lbnRzPXt9LCBjYXVzZT1udWxsLCBjb2RlPWNsb3VkLmJpZ3N0b3JlLmFwaS5CaWdzdG9yZUVycm9yRG9tYWluLkNMSUVOVF9RVU9UQV9FWENFRURFRCwgY3JlYXRlZEJ5QmFja2VuZD10cnVlLCBkZWJ1Z01lc3NhZ2U9Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlBST0pFQ1RfQlVDS0VUX09QX1JBVEVfVE9PX0hJR0g6IENyZWF0aW5nIGJ1Y2tldHMgdG9vIHF1aWNrbHksIHBsZWFzZSBzbG93IGRvd25cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuSW5zZXJ0QnVja2V0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRCdWNrZXQuamF2YToxODQpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYnVja2V0cy5JbnNlcnRCdWNrZXQuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEluc2VydEJ1Y2tldC5qYXZhOjQyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5CdWNrZXRzRGVsZWdhdG9yLmluc2VydChCdWNrZXRzRGVsZWdhdG9yLmphdmE6OTUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IENyZWF0aW5nIGJ1Y2tldHMgdG9vIHF1aWNrbHksIHBsZWFzZSBzbG93IGRvd25cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuLCBlcnJvclByb3RvQ29kZT1DTElFTlRfUVVPVEFfRVhDRUVERUQsIGVycm9yUHJvdG9Eb21haW49Y2xvdWQuYmlnc3RvcmUuYXBpLkJpZ3N0b3JlRXJyb3JEb21haW4sIGZpbHRlcmVkTWVzc2FnZT1udWxsLCBsb2NhdGlvbj1lbnRpdHkucmVzb3VyY2UuYnVja2V0Lm5hbWUsIG1lc3NhZ2U9VGhlIHByb2plY3QgZXhjZWVkZWQgdGhlIHJhdGUgbGltaXQgZm9yIGNyZWF0aW5nIGFuZCBkZWxldGluZyBidWNrZXRzLiwgdW5uYW1lZEFyZ3VtZW50cz1bXX0sIGxvY2F0aW9uPWVudGl0eS5yZXNvdXJjZS5idWNrZXQubmFtZSwgbWVzc2FnZT1UaGUgcHJvamVjdCBleGNlZWRlZCB0aGUgcmF0ZSBsaW1pdCBmb3IgY3JlYXRpbmcgYW5kIGRlbGV0aW5nIGJ1Y2tldHMuLCByZWFzb249cmF0ZUxpbWl0RXhjZWVkZWQsIHJwY0NvZGU9NDI5fSBUaGUgcHJvamVjdCBleGNlZWRlZCB0aGUgcmF0ZSBsaW1pdCBmb3IgY3JlYXRpbmcgYW5kIGRlbGV0aW5nIGJ1Y2tldHMuOiBjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6UFJPSkVDVF9CVUNLRVRfT1BfUkFURV9UT09fSElHSDogQ3JlYXRpbmcgYnVja2V0cyB0b28gcXVpY2tseSwgcGxlYXNlIHNsb3cgZG93blxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYnVja2V0cy5JbnNlcnRCdWNrZXQuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEluc2VydEJ1Y2tldC5qYXZhOjE4NClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5idWNrZXRzLkluc2VydEJ1Y2tldC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoSW5zZXJ0QnVja2V0LmphdmE6NDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLkJ1Y2tldHNEZWxlZ2F0b3IuaW5zZXJ0KEJ1Y2tldHNEZWxlZ2F0b3IuamF2YTo5NSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogQ3JlYXRpbmcgYnVja2V0cyB0b28gcXVpY2tseSwgcGxlYXNlIHNsb3cgZG93blxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRXJyb3JDb2xsZWN0b3IudG9GYXVsdChFcnJvckNvbGxlY3Rvci5qYXZhOjU0KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUVycm9yQ29udmVydGVyLnRvRmF1bHQoUm9zeUVycm9yQ29udmVydGVyLmphdmE6NjcpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyNTkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyMzkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci50aHJlYWQuVGhyZWFkVHJhY2tlcnMkVGhyZWFkVHJhY2tpbmdSdW5uYWJsZS5ydW4oVGhyZWFkVHJhY2tlcnMuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjQ1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnNlcnZlci5Db21tb25Nb2R1bGUkQ29udGV4dENhcnJ5aW5nRXhlY3V0b3JTZXJ2aWNlJDEucnVuSW5Db250ZXh0KENvbW1vbk1vZHVsZS5qYXZhOjgwMilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZSQxLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NjApXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoVHJhY2VDb250ZXh0LmphdmE6MzE5KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjMxMSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDU3KVxuXHRhdCBjb20uZ29vZ2xlLmdzZS5pbnRlcm5hbC5EaXNwYXRjaFF1ZXVlSW1wbCRXb3JrZXJUaHJlYWQucnVuKERpc3BhdGNoUXVldWVJbXBsLmphdmE6NDAzKVxuIn1dLCJjb2RlIjo0MjksIm1lc3NhZ2UiOiJUaGUgcHJvamVjdCBleGNlZWRlZCB0aGUgcmF0ZSBsaW1pdCBmb3IgY3JlYXRpbmcgYW5kIGRlbGV0aW5nIGJ1Y2tldHMuIn19" } }, { "ID": "42cf12714cf13289", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b?alt=json\u0026prettyPrint=false\u0026project=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "106" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE4IiwicmV0ZW50aW9uUG9saWN5Ijp7InJldGVudGlvblBlcmlvZCI6IjkwMDAwIn19Cg==" ] }, "Response": { "StatusCode": 429, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Content-Length": [ "12201" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:07 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UrcjWbo0pc_i_GQTU2WE6YR0XhWYMGRPJutu1MQXo6XbRKJAYhzNK4p2-_gCqZ6BvNGncUP1UZNoTrXsFFGt1RRTRR3DS9XNiws0gt9YQdp_I8dqqM" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6InVzYWdlTGltaXRzIiwicmVhc29uIjoicmF0ZUxpbWl0RXhjZWVkZWQiLCJtZXNzYWdlIjoiVGhlIHByb2plY3QgZXhjZWVkZWQgdGhlIHJhdGUgbGltaXQgZm9yIGNyZWF0aW5nIGFuZCBkZWxldGluZyBidWNrZXRzLiIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpQUk9KRUNUX0JVQ0tFVF9PUF9SQVRFX1RPT19ISUdIOiBDcmVhdGluZyBidWNrZXRzIHRvbyBxdWlja2x5LCBwbGVhc2Ugc2xvdyBkb3duXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5idWNrZXRzLkluc2VydEJ1Y2tldC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoSW5zZXJ0QnVja2V0LmphdmE6MTg0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuSW5zZXJ0QnVja2V0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRCdWNrZXQuamF2YTo0Milcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQnVja2V0c0RlbGVnYXRvci5pbnNlcnQoQnVja2V0c0RlbGVnYXRvci5qYXZhOjk1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBDcmVhdGluZyBidWNrZXRzIHRvbyBxdWlja2x5LCBwbGVhc2Ugc2xvdyBkb3duXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPVRPT19NQU5ZX1JFUVVFU1RTLCBjYXRlZ29yeT1RVU9UQV9FUlJPUiwgY2F1c2U9bnVsbCwgZGVidWdJbmZvPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpQUk9KRUNUX0JVQ0tFVF9PUF9SQVRFX1RPT19ISUdIOiBDcmVhdGluZyBidWNrZXRzIHRvbyBxdWlja2x5LCBwbGVhc2Ugc2xvdyBkb3duXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5idWNrZXRzLkluc2VydEJ1Y2tldC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoSW5zZXJ0QnVja2V0LmphdmE6MTg0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuSW5zZXJ0QnVja2V0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRCdWNrZXQuamF2YTo0Milcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQnVja2V0c0RlbGVnYXRvci5pbnNlcnQoQnVja2V0c0RlbGVnYXRvci5qYXZhOjk1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBDcmVhdGluZyBidWNrZXRzIHRvbyBxdWlja2x5LCBwbGVhc2Ugc2xvdyBkb3duXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZG9tYWluPXVzYWdlTGltaXRzLCBleHRlbmRlZEhlbHA9bnVsbCwgaHR0cEhlYWRlcnM9e30sIGh0dHBTdGF0dXM9dG9vTWFueVJlcXVlc3RzLCBpbnRlcm5hbFJlYXNvbj1SZWFzb257YXJndW1lbnRzPXt9LCBjYXVzZT1udWxsLCBjb2RlPWNsb3VkLmJpZ3N0b3JlLmFwaS5CaWdzdG9yZUVycm9yRG9tYWluLkNMSUVOVF9RVU9UQV9FWENFRURFRCwgY3JlYXRlZEJ5QmFja2VuZD10cnVlLCBkZWJ1Z01lc3NhZ2U9Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlBST0pFQ1RfQlVDS0VUX09QX1JBVEVfVE9PX0hJR0g6IENyZWF0aW5nIGJ1Y2tldHMgdG9vIHF1aWNrbHksIHBsZWFzZSBzbG93IGRvd25cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuSW5zZXJ0QnVja2V0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRCdWNrZXQuamF2YToxODQpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYnVja2V0cy5JbnNlcnRCdWNrZXQuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEluc2VydEJ1Y2tldC5qYXZhOjQyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5CdWNrZXRzRGVsZWdhdG9yLmluc2VydChCdWNrZXRzRGVsZWdhdG9yLmphdmE6OTUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IENyZWF0aW5nIGJ1Y2tldHMgdG9vIHF1aWNrbHksIHBsZWFzZSBzbG93IGRvd25cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuLCBlcnJvclByb3RvQ29kZT1DTElFTlRfUVVPVEFfRVhDRUVERUQsIGVycm9yUHJvdG9Eb21haW49Y2xvdWQuYmlnc3RvcmUuYXBpLkJpZ3N0b3JlRXJyb3JEb21haW4sIGZpbHRlcmVkTWVzc2FnZT1udWxsLCBsb2NhdGlvbj1lbnRpdHkucmVzb3VyY2UuYnVja2V0Lm5hbWUsIG1lc3NhZ2U9VGhlIHByb2plY3QgZXhjZWVkZWQgdGhlIHJhdGUgbGltaXQgZm9yIGNyZWF0aW5nIGFuZCBkZWxldGluZyBidWNrZXRzLiwgdW5uYW1lZEFyZ3VtZW50cz1bXX0sIGxvY2F0aW9uPWVudGl0eS5yZXNvdXJjZS5idWNrZXQubmFtZSwgbWVzc2FnZT1UaGUgcHJvamVjdCBleGNlZWRlZCB0aGUgcmF0ZSBsaW1pdCBmb3IgY3JlYXRpbmcgYW5kIGRlbGV0aW5nIGJ1Y2tldHMuLCByZWFzb249cmF0ZUxpbWl0RXhjZWVkZWQsIHJwY0NvZGU9NDI5fSBUaGUgcHJvamVjdCBleGNlZWRlZCB0aGUgcmF0ZSBsaW1pdCBmb3IgY3JlYXRpbmcgYW5kIGRlbGV0aW5nIGJ1Y2tldHMuOiBjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6UFJPSkVDVF9CVUNLRVRfT1BfUkFURV9UT09fSElHSDogQ3JlYXRpbmcgYnVja2V0cyB0b28gcXVpY2tseSwgcGxlYXNlIHNsb3cgZG93blxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYnVja2V0cy5JbnNlcnRCdWNrZXQuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEluc2VydEJ1Y2tldC5qYXZhOjE4NClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5idWNrZXRzLkluc2VydEJ1Y2tldC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoSW5zZXJ0QnVja2V0LmphdmE6NDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLkJ1Y2tldHNEZWxlZ2F0b3IuaW5zZXJ0KEJ1Y2tldHNEZWxlZ2F0b3IuamF2YTo5NSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogQ3JlYXRpbmcgYnVja2V0cyB0b28gcXVpY2tseSwgcGxlYXNlIHNsb3cgZG93blxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRXJyb3JDb2xsZWN0b3IudG9GYXVsdChFcnJvckNvbGxlY3Rvci5qYXZhOjU0KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUVycm9yQ29udmVydGVyLnRvRmF1bHQoUm9zeUVycm9yQ29udmVydGVyLmphdmE6NjcpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyNTkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyMzkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci50aHJlYWQuVGhyZWFkVHJhY2tlcnMkVGhyZWFkVHJhY2tpbmdSdW5uYWJsZS5ydW4oVGhyZWFkVHJhY2tlcnMuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjQ1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnNlcnZlci5Db21tb25Nb2R1bGUkQ29udGV4dENhcnJ5aW5nRXhlY3V0b3JTZXJ2aWNlJDEucnVuSW5Db250ZXh0KENvbW1vbk1vZHVsZS5qYXZhOjgwMilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZSQxLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NjApXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoVHJhY2VDb250ZXh0LmphdmE6MzE5KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjMxMSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDU3KVxuXHRhdCBjb20uZ29vZ2xlLmdzZS5pbnRlcm5hbC5EaXNwYXRjaFF1ZXVlSW1wbCRXb3JrZXJUaHJlYWQucnVuKERpc3BhdGNoUXVldWVJbXBsLmphdmE6NDAzKVxuIn1dLCJjb2RlIjo0MjksIm1lc3NhZ2UiOiJUaGUgcHJvamVjdCBleGNlZWRlZCB0aGUgcmF0ZSBsaW1pdCBmb3IgY3JlYXRpbmcgYW5kIGRlbGV0aW5nIGJ1Y2tldHMuIn19" } }, { "ID": "4f0fdb3eb607f33b", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b?alt=json\u0026prettyPrint=false\u0026project=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "106" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE4IiwicmV0ZW50aW9uUG9saWN5Ijp7InJldGVudGlvblBlcmlvZCI6IjkwMDAwIn19Cg==" ] }, "Response": { "StatusCode": 429, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Content-Length": [ "12201" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:11 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2Up0EsbUXQesAgz95sFt6OzWRDj5WAXqEpYaqHgGvCClYnBGvjX8eQmor80UQOCIDzT6v9ZAtOPVhFIqkJG6rV0-CDXiLAnr4gwDrPkqgezvm8PQTaY" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6InVzYWdlTGltaXRzIiwicmVhc29uIjoicmF0ZUxpbWl0RXhjZWVkZWQiLCJtZXNzYWdlIjoiVGhlIHByb2plY3QgZXhjZWVkZWQgdGhlIHJhdGUgbGltaXQgZm9yIGNyZWF0aW5nIGFuZCBkZWxldGluZyBidWNrZXRzLiIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpQUk9KRUNUX0JVQ0tFVF9PUF9SQVRFX1RPT19ISUdIOiBDcmVhdGluZyBidWNrZXRzIHRvbyBxdWlja2x5LCBwbGVhc2Ugc2xvdyBkb3duXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5idWNrZXRzLkluc2VydEJ1Y2tldC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoSW5zZXJ0QnVja2V0LmphdmE6MTg0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuSW5zZXJ0QnVja2V0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRCdWNrZXQuamF2YTo0Milcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQnVja2V0c0RlbGVnYXRvci5pbnNlcnQoQnVja2V0c0RlbGVnYXRvci5qYXZhOjk1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBDcmVhdGluZyBidWNrZXRzIHRvbyBxdWlja2x5LCBwbGVhc2Ugc2xvdyBkb3duXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPVRPT19NQU5ZX1JFUVVFU1RTLCBjYXRlZ29yeT1RVU9UQV9FUlJPUiwgY2F1c2U9bnVsbCwgZGVidWdJbmZvPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpQUk9KRUNUX0JVQ0tFVF9PUF9SQVRFX1RPT19ISUdIOiBDcmVhdGluZyBidWNrZXRzIHRvbyBxdWlja2x5LCBwbGVhc2Ugc2xvdyBkb3duXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5idWNrZXRzLkluc2VydEJ1Y2tldC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoSW5zZXJ0QnVja2V0LmphdmE6MTg0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuSW5zZXJ0QnVja2V0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRCdWNrZXQuamF2YTo0Milcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQnVja2V0c0RlbGVnYXRvci5pbnNlcnQoQnVja2V0c0RlbGVnYXRvci5qYXZhOjk1KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBDcmVhdGluZyBidWNrZXRzIHRvbyBxdWlja2x5LCBwbGVhc2Ugc2xvdyBkb3duXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZG9tYWluPXVzYWdlTGltaXRzLCBleHRlbmRlZEhlbHA9bnVsbCwgaHR0cEhlYWRlcnM9e30sIGh0dHBTdGF0dXM9dG9vTWFueVJlcXVlc3RzLCBpbnRlcm5hbFJlYXNvbj1SZWFzb257YXJndW1lbnRzPXt9LCBjYXVzZT1udWxsLCBjb2RlPWNsb3VkLmJpZ3N0b3JlLmFwaS5CaWdzdG9yZUVycm9yRG9tYWluLkNMSUVOVF9RVU9UQV9FWENFRURFRCwgY3JlYXRlZEJ5QmFja2VuZD10cnVlLCBkZWJ1Z01lc3NhZ2U9Y29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OlBST0pFQ1RfQlVDS0VUX09QX1JBVEVfVE9PX0hJR0g6IENyZWF0aW5nIGJ1Y2tldHMgdG9vIHF1aWNrbHksIHBsZWFzZSBzbG93IGRvd25cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuSW5zZXJ0QnVja2V0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChJbnNlcnRCdWNrZXQuamF2YToxODQpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYnVja2V0cy5JbnNlcnRCdWNrZXQuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEluc2VydEJ1Y2tldC5qYXZhOjQyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5CdWNrZXRzRGVsZWdhdG9yLmluc2VydChCdWNrZXRzRGVsZWdhdG9yLmphdmE6OTUpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IENyZWF0aW5nIGJ1Y2tldHMgdG9vIHF1aWNrbHksIHBsZWFzZSBzbG93IGRvd25cblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuLCBlcnJvclByb3RvQ29kZT1DTElFTlRfUVVPVEFfRVhDRUVERUQsIGVycm9yUHJvdG9Eb21haW49Y2xvdWQuYmlnc3RvcmUuYXBpLkJpZ3N0b3JlRXJyb3JEb21haW4sIGZpbHRlcmVkTWVzc2FnZT1udWxsLCBsb2NhdGlvbj1lbnRpdHkucmVzb3VyY2UuYnVja2V0Lm5hbWUsIG1lc3NhZ2U9VGhlIHByb2plY3QgZXhjZWVkZWQgdGhlIHJhdGUgbGltaXQgZm9yIGNyZWF0aW5nIGFuZCBkZWxldGluZyBidWNrZXRzLiwgdW5uYW1lZEFyZ3VtZW50cz1bXX0sIGxvY2F0aW9uPWVudGl0eS5yZXNvdXJjZS5idWNrZXQubmFtZSwgbWVzc2FnZT1UaGUgcHJvamVjdCBleGNlZWRlZCB0aGUgcmF0ZSBsaW1pdCBmb3IgY3JlYXRpbmcgYW5kIGRlbGV0aW5nIGJ1Y2tldHMuLCByZWFzb249cmF0ZUxpbWl0RXhjZWVkZWQsIHJwY0NvZGU9NDI5fSBUaGUgcHJvamVjdCBleGNlZWRlZCB0aGUgcmF0ZSBsaW1pdCBmb3IgY3JlYXRpbmcgYW5kIGRlbGV0aW5nIGJ1Y2tldHMuOiBjb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6UFJPSkVDVF9CVUNLRVRfT1BfUkFURV9UT09fSElHSDogQ3JlYXRpbmcgYnVja2V0cyB0b28gcXVpY2tseSwgcGxlYXNlIHNsb3cgZG93blxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50b1JwYzNFeGNlcHRpb24oQmlnc3RvcmVFeGNlcHRpb24uamF2YToxNDcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYnVja2V0cy5JbnNlcnRCdWNrZXQuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEluc2VydEJ1Y2tldC5qYXZhOjE4NClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5idWNrZXRzLkluc2VydEJ1Y2tldC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoSW5zZXJ0QnVja2V0LmphdmE6NDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLkJ1Y2tldHNEZWxlZ2F0b3IuaW5zZXJ0KEJ1Y2tldHNEZWxlZ2F0b3IuamF2YTo5NSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uUnBjUmVjZWl2ZXIubGFtYmRhJHByb2Nlc3NSZXF1ZXN0QXN5bmMkNChScGNSZWNlaXZlci5qYXZhOjIwMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5pc29sYXRpb24uQXN5bmNFeGVjdXRvci5sYW1iZGEkc3VibWl0JDAoQXN5bmNFeGVjdXRvci5qYXZhOjI1Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KENvbnRleHRSdW5uYWJsZS5qYXZhOjUwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZSQxLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozOSlcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo3Milcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KEdlbmVyaWNDb250ZXh0Q2FsbGJhY2suamF2YTo2NClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM1KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IucnVuV29ya2VyKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjExNDkpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvciRXb3JrZXIucnVuKFRocmVhZFBvb2xFeGVjdXRvci5qYXZhOjYyNClcblx0YXQgamF2YS5sYW5nLlRocmVhZC5ydW4oVGhyZWFkLmphdmE6NzQ4KVxuQ2F1c2VkIGJ5OiBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbjogQ3JlYXRpbmcgYnVja2V0cyB0b28gcXVpY2tseSwgcGxlYXNlIHNsb3cgZG93blxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG5cblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRXJyb3JDb2xsZWN0b3IudG9GYXVsdChFcnJvckNvbGxlY3Rvci5qYXZhOjU0KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUVycm9yQ29udmVydGVyLnRvRmF1bHQoUm9zeUVycm9yQ29udmVydGVyLmphdmE6NjcpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyNTkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5SGFuZGxlciQyLmNhbGwoUm9zeUhhbmRsZXIuamF2YToyMzkpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5EaXJlY3RFeGVjdXRvci5leGVjdXRlKERpcmVjdEV4ZWN1dG9yLmphdmE6MzApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5leGVjdXRlTGlzdGVuZXIoQWJzdHJhY3RGdXR1cmUuamF2YToxMTQzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuY29tcGxldGUoQWJzdHJhY3RGdXR1cmUuamF2YTo5NjMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5zZXQoQWJzdHJhY3RGdXR1cmUuamF2YTo3MzEpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLnV0aWwuQ2FsbGFibGVGdXR1cmUucnVuKENhbGxhYmxlRnV0dXJlLmphdmE6NjIpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci50aHJlYWQuVGhyZWFkVHJhY2tlcnMkVGhyZWFkVHJhY2tpbmdSdW5uYWJsZS5ydW4oVGhyZWFkVHJhY2tlcnMuamF2YToxMjYpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuSW5Db250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjQ1Mylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnNlcnZlci5Db21tb25Nb2R1bGUkQ29udGV4dENhcnJ5aW5nRXhlY3V0b3JTZXJ2aWNlJDEucnVuSW5Db250ZXh0KENvbW1vbk1vZHVsZS5qYXZhOjgwMilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZSQxLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NjApXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoVHJhY2VDb250ZXh0LmphdmE6MzE5KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0KFRyYWNlQ29udGV4dC5qYXZhOjMxMSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDU3KVxuXHRhdCBjb20uZ29vZ2xlLmdzZS5pbnRlcm5hbC5EaXNwYXRjaFF1ZXVlSW1wbCRXb3JrZXJUaHJlYWQucnVuKERpc3BhdGNoUXVldWVJbXBsLmphdmE6NDAzKVxuIn1dLCJjb2RlIjo0MjksIm1lc3NhZ2UiOiJUaGUgcHJvamVjdCBleGNlZWRlZCB0aGUgcmF0ZSBsaW1pdCBmb3IgY3JlYXRpbmcgYW5kIGRlbGV0aW5nIGJ1Y2tldHMuIn19" } }, { "ID": "a5a8b8af13be21cf", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b?alt=json\u0026prettyPrint=false\u0026project=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "106" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE4IiwicmV0ZW50aW9uUG9saWN5Ijp7InJldGVudGlvblBlcmlvZCI6IjkwMDAwIn19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "574" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:15 GMT" ], "Etag": [ "CAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpF7Lqxvm1dNC6q_v81ZB1Ui9c2ZLJ3GXLX6Y6UNZN1nbkF78c0J3NwXavHF1cMFZ5oP8ufCnmCLg9vQHM6tfs2ih8YxQSfE4D3AxGsvBaGNP3VUMo" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOCIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE4IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI2OjE1LjA5N1oiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNjoxNS4wOTdaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiaWFtQ29uZmlndXJhdGlvbiI6eyJidWNrZXRQb2xpY3lPbmx5Ijp7ImVuYWJsZWQiOmZhbHNlfX0sImxvY2F0aW9uIjoiVVMiLCJyZXRlbnRpb25Qb2xpY3kiOnsicmV0ZW50aW9uUGVyaW9kIjoiOTAwMDAiLCJlZmZlY3RpdmVUaW1lIjoiMjAxOS0wNS0wMlQyMjoyNjoxNS4wOTdaIn0sInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwiZXRhZyI6IkNBRT0ifQ==" } }, { "ID": "e1dbaeed8c6d1ffb", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0018/lockRetentionPolicy?alt=json\u0026ifMetagenerationMatch=0\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "0" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 412, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Content-Length": [ "12155" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:16 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2Ur4dRXLSTXYf9VXr3eOCMfuLBwDLvNQMXwIYjwEuSFQO_p-SxZQXQJ7I_VA0T5Hn8gnnEZIqLV3vLCnurXr0cyHDEMpCdxWOiIiqsXlgkbcLKf78to" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6ImNvbmRpdGlvbk5vdE1ldCIsIm1lc3NhZ2UiOiJQcmVjb25kaXRpb24gRmFpbGVkIiwibG9jYXRpb25UeXBlIjoiaGVhZGVyIiwibG9jYXRpb24iOiJJZi1NYXRjaCIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpJTkNPUlJFQ1RfTUVUQV9HRU5FUkFUSU9OX1NQRUNJRklFRDogZXhwZWN0ZWQgQnVja2V0TWV0YWRhdGEubWV0YWRhdGFfZ2VuZXJhdGlvbjogMCBhY3R1YWw6IDFcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuTG9ja1JldGVudGlvblBvbGljeS5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoTG9ja1JldGVudGlvblBvbGljeS5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5idWNrZXRzLkxvY2tSZXRlbnRpb25Qb2xpY3kuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKExvY2tSZXRlbnRpb25Qb2xpY3kuamF2YTo1Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQnVja2V0c0RlbGVnYXRvci5sb2NrUmV0ZW50aW9uUG9saWN5KEJ1Y2tldHNEZWxlZ2F0b3IuamF2YToxMDkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IGV4cGVjdGVkIEJ1Y2tldE1ldGFkYXRhLm1ldGFkYXRhX2dlbmVyYXRpb246IDAgYWN0dWFsOiAxXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPVBSRUNPTkRJVElPTl9GQUlMRUQsIGNhdGVnb3J5PVVTRVJfRVJST1IsIGNhdXNlPW51bGwsIGRlYnVnSW5mbz1jb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6SU5DT1JSRUNUX01FVEFfR0VORVJBVElPTl9TUEVDSUZJRUQ6IGV4cGVjdGVkIEJ1Y2tldE1ldGFkYXRhLm1ldGFkYXRhX2dlbmVyYXRpb246IDAgYWN0dWFsOiAxXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5idWNrZXRzLkxvY2tSZXRlbnRpb25Qb2xpY3kuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKExvY2tSZXRlbnRpb25Qb2xpY3kuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYnVja2V0cy5Mb2NrUmV0ZW50aW9uUG9saWN5LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChMb2NrUmV0ZW50aW9uUG9saWN5LmphdmE6NTcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLkJ1Y2tldHNEZWxlZ2F0b3IubG9ja1JldGVudGlvblBvbGljeShCdWNrZXRzRGVsZWdhdG9yLmphdmE6MTA5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBleHBlY3RlZCBCdWNrZXRNZXRhZGF0YS5tZXRhZGF0YV9nZW5lcmF0aW9uOiAwIGFjdHVhbDogMVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGRvbWFpbj1nbG9iYWwsIGV4dGVuZGVkSGVscD1udWxsLCBodHRwSGVhZGVycz17fSwgaHR0cFN0YXR1cz1wcmVjb25kaXRpb25GYWlsZWQsIGludGVybmFsUmVhc29uPVJlYXNvbnthcmd1bWVudHM9e30sIGNhdXNlPW51bGwsIGNvZGU9Z2RhdGEuQ29yZUVycm9yRG9tYWluLkNPTkRJVElPTl9OT1RfTUVULCBjcmVhdGVkQnlCYWNrZW5kPXRydWUsIGRlYnVnTWVzc2FnZT1jb20uZ29vZ2xlLm5ldC5ycGMzLlJwY0V4Y2VwdGlvbjogY2xvdWQuYmlnc3RvcmUuUmVzcG9uc2VDb2RlLkVycm9yQ29kZTo6SU5DT1JSRUNUX01FVEFfR0VORVJBVElPTl9TUEVDSUZJRUQ6IGV4cGVjdGVkIEJ1Y2tldE1ldGFkYXRhLm1ldGFkYXRhX2dlbmVyYXRpb246IDAgYWN0dWFsOiAxXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5idWNrZXRzLkxvY2tSZXRlbnRpb25Qb2xpY3kuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKExvY2tSZXRlbnRpb25Qb2xpY3kuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYnVja2V0cy5Mb2NrUmV0ZW50aW9uUG9saWN5LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChMb2NrUmV0ZW50aW9uUG9saWN5LmphdmE6NTcpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChSZXF1ZXN0SGFuZGxlci5qYXZhOjMxMClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlKFJlcXVlc3RIYW5kbGVyLmphdmE6MjU2KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLkJ1Y2tldHNEZWxlZ2F0b3IubG9ja1JldGVudGlvblBvbGljeShCdWNrZXRzRGVsZWdhdG9yLmphdmE6MTA5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBleHBlY3RlZCBCdWNrZXRNZXRhZGF0YS5tZXRhZGF0YV9nZW5lcmF0aW9uOiAwIGFjdHVhbDogMVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMTIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93UnBjM09uRXJyb3IoQmlnc3RvcmVFeGNlcHRpb24uamF2YTozMjApXG5cdC4uLiAxNyBtb3JlXG4sIGVycm9yUHJvdG9Db2RlPUNPTkRJVElPTl9OT1RfTUVULCBlcnJvclByb3RvRG9tYWluPWdkYXRhLkNvcmVFcnJvckRvbWFpbiwgZmlsdGVyZWRNZXNzYWdlPW51bGwsIGxvY2F0aW9uPW51bGwsIG1lc3NhZ2U9bnVsbCwgdW5uYW1lZEFyZ3VtZW50cz1bXX0sIGxvY2F0aW9uPWhlYWRlcnMuSWYtTWF0Y2gsIG1lc3NhZ2U9UHJlY29uZGl0aW9uIEZhaWxlZCwgcmVhc29uPWNvbmRpdGlvbk5vdE1ldCwgcnBjQ29kZT00MTJ9IFByZWNvbmRpdGlvbiBGYWlsZWQ6IGNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpJTkNPUlJFQ1RfTUVUQV9HRU5FUkFUSU9OX1NQRUNJRklFRDogZXhwZWN0ZWQgQnVja2V0TWV0YWRhdGEubWV0YWRhdGFfZ2VuZXJhdGlvbjogMCBhY3R1YWw6IDFcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuTG9ja1JldGVudGlvblBvbGljeS5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoTG9ja1JldGVudGlvblBvbGljeS5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5idWNrZXRzLkxvY2tSZXRlbnRpb25Qb2xpY3kuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKExvY2tSZXRlbnRpb25Qb2xpY3kuamF2YTo1Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQnVja2V0c0RlbGVnYXRvci5sb2NrUmV0ZW50aW9uUG9saWN5KEJ1Y2tldHNEZWxlZ2F0b3IuamF2YToxMDkpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IGV4cGVjdGVkIEJ1Y2tldE1ldGFkYXRhLm1ldGFkYXRhX2dlbmVyYXRpb246IDAgYWN0dWFsOiAxXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS5FcnJvckNvbGxlY3Rvci50b0ZhdWx0KEVycm9yQ29sbGVjdG9yLmphdmE6NTQpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5RXJyb3JDb252ZXJ0ZXIudG9GYXVsdChSb3N5RXJyb3JDb252ZXJ0ZXIuamF2YTo2Nylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lIYW5kbGVyJDIuY2FsbChSb3N5SGFuZGxlci5qYXZhOjI1OSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lIYW5kbGVyJDIuY2FsbChSb3N5SGFuZGxlci5qYXZhOjIzOSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkRpcmVjdEV4ZWN1dG9yLmV4ZWN1dGUoRGlyZWN0RXhlY3V0b3IuamF2YTozMClcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmV4ZWN1dGVMaXN0ZW5lcihBYnN0cmFjdEZ1dHVyZS5qYXZhOjExNDMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5jb21wbGV0ZShBYnN0cmFjdEZ1dHVyZS5qYXZhOjk2Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLnNldChBYnN0cmFjdEZ1dHVyZS5qYXZhOjczMSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkRpcmVjdEV4ZWN1dG9yLmV4ZWN1dGUoRGlyZWN0RXhlY3V0b3IuamF2YTozMClcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmV4ZWN1dGVMaXN0ZW5lcihBYnN0cmFjdEZ1dHVyZS5qYXZhOjExNDMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5jb21wbGV0ZShBYnN0cmFjdEZ1dHVyZS5qYXZhOjk2Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLnNldChBYnN0cmFjdEZ1dHVyZS5qYXZhOjczMSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnRocmVhZC5UaHJlYWRUcmFja2VycyRUaHJlYWRUcmFja2luZ1J1bm5hYmxlLnJ1bihUaHJlYWRUcmFja2Vycy5qYXZhOjEyNilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoVHJhY2VDb250ZXh0LmphdmE6NDUzKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuc2VydmVyLkNvbW1vbk1vZHVsZSRDb250ZXh0Q2FycnlpbmdFeGVjdXRvclNlcnZpY2UkMS5ydW5JbkNvbnRleHQoQ29tbW9uTW9kdWxlLmphdmE6ODAyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlJDEucnVuKFRyYWNlQ29udGV4dC5qYXZhOjQ2MClcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihUcmFjZUNvbnRleHQuamF2YTozMTkpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkQWJzdHJhY3RUcmFjZUNvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoVHJhY2VDb250ZXh0LmphdmE6MzExKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NTcpXG5cdGF0IGNvbS5nb29nbGUuZ3NlLmludGVybmFsLkRpc3BhdGNoUXVldWVJbXBsJFdvcmtlclRocmVhZC5ydW4oRGlzcGF0Y2hRdWV1ZUltcGwuamF2YTo0MDMpXG4ifV0sImNvZGUiOjQxMiwibWVzc2FnZSI6IlByZWNvbmRpdGlvbiBGYWlsZWQifX0=" } }, { "ID": "814dffcceacb3bd8", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026kmsKeyName=projects%2Fdeklerk-sandbox%2Flocations%2Fglobal%2FkeyRings%2Fgo-integration-test%2FcryptoKeys%2Fkey1\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJuYW1lIjoia21zIn0K", "bXkgc2VjcmV0" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3234" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:17 GMT" ], "Etag": [ "CMGB+Prx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Upis-8CwJYvr7glFAMnec_3T3YDojfTz3O_uICK5tQQmfJF2_rFtNnbqopcxBL5L3aKyoYe4zOLoqN4_MFFrhYKDm6Tmrl3rytuh0ymlCV15VZKyrQ" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9rbXMvMTU1NjgzNTk3Njc0MTA1NyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2ttcyIsIm5hbWUiOiJrbXMiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk3Njc0MTA1NyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNjoxNi43NDBaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjY6MTYuNzQwWiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI2OjE2Ljc0MFoiLCJzaXplIjoiOSIsIm1kNUhhc2giOiJBQVBRUzQ2VHJuTVlucWlLQWJhZ3RRPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28va21zP2dlbmVyYXRpb249MTU1NjgzNTk3Njc0MTA1NyZhbHQ9bWVkaWEiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9rbXMvMTU1NjgzNTk3Njc0MTA1Ny9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9rbXMvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImttcyIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTc2NzQxMDU3IiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNNR0IrUHJ4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9rbXMvMTU1NjgzNTk3Njc0MTA1Ny9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28va21zL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoia21zIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5NzY3NDEwNTciLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDTUdCK1ByeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEva21zLzE1NTY4MzU5NzY3NDEwNTcvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2ttcy9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImttcyIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTc2NzQxMDU3IiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNNR0IrUHJ4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9rbXMvMTU1NjgzNTk3Njc0MTA1Ny91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28va21zL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoia21zIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5NzY3NDEwNTciLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDTUdCK1ByeC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6IlVJNzg1QT09IiwiZXRhZyI6IkNNR0IrUHJ4L2VFQ0VBRT0iLCJrbXNLZXlOYW1lIjoicHJvamVjdHMvZGVrbGVyay1zYW5kYm94L2xvY2F0aW9ucy9nbG9iYWwva2V5UmluZ3MvZ28taW50ZWdyYXRpb24tdGVzdC9jcnlwdG9LZXlzL2tleTEvY3J5cHRvS2V5VmVyc2lvbnMvMSJ9" } }, { "ID": "9b05110f2b59351b", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/go-integration-test-20190502-80633403432013-0001/kms", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "9" ], "Content-Type": [ "text/plain; charset=utf-8" ], "Date": [ "Thu, 02 May 2019 22:26:17 GMT" ], "Etag": [ "\"-CMGB+Prx/eECEAE=\"" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Last-Modified": [ "Thu, 02 May 2019 22:26:16 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "X-Goog-Encryption-Kms-Key-Name": [ "projects/deklerk-sandbox/locations/global/keyRings/go-integration-test/cryptoKeys/key1/cryptoKeyVersions/1" ], "X-Goog-Expiration": [ "Sat, 01 Jun 2019 22:26:16 GMT" ], "X-Goog-Generation": [ "1556835976741057" ], "X-Goog-Hash": [ "crc32c=UI785A==", "md5=AAPQS46TrnMYnqiKAbagtQ==" ], "X-Goog-Metageneration": [ "1" ], "X-Goog-Storage-Class": [ "STANDARD" ], "X-Goog-Stored-Content-Encoding": [ "identity" ], "X-Goog-Stored-Content-Length": [ "9" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpZ6aSiGPoeZKANPoMPgXhL1QD5nbILvzv8v3sOMId95Y65wOPssqesNA1MXzp86JA4Qa5gAMxxx5cnY4z3-tCUnvsKoIHn3NXOK2U6ZSRLzYNeQeU" ] }, "Body": "bXkgc2VjcmV0" } }, { "ID": "011b81453e7060ac", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/kms?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3234" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:17 GMT" ], "Etag": [ "CMGB+Prx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uq5t8aexqBqqxnLJFK9mWmGdVrFfd3gaCGOKfGJMO1phB3ATnxt67-cLVpELRy1gNnjNOK7-zMzWCR6yV1v5PQcv3lccINA--Q92RoECpvBON-QKtc" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9rbXMvMTU1NjgzNTk3Njc0MTA1NyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2ttcyIsIm5hbWUiOiJrbXMiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk3Njc0MTA1NyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNjoxNi43NDBaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjY6MTYuNzQwWiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI2OjE2Ljc0MFoiLCJzaXplIjoiOSIsIm1kNUhhc2giOiJBQVBRUzQ2VHJuTVlucWlLQWJhZ3RRPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28va21zP2dlbmVyYXRpb249MTU1NjgzNTk3Njc0MTA1NyZhbHQ9bWVkaWEiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9rbXMvMTU1NjgzNTk3Njc0MTA1Ny9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9rbXMvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImttcyIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTc2NzQxMDU3IiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNNR0IrUHJ4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9rbXMvMTU1NjgzNTk3Njc0MTA1Ny9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28va21zL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoia21zIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5NzY3NDEwNTciLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDTUdCK1ByeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEva21zLzE1NTY4MzU5NzY3NDEwNTcvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2ttcy9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImttcyIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTc2NzQxMDU3IiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNNR0IrUHJ4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9rbXMvMTU1NjgzNTk3Njc0MTA1Ny91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28va21zL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoia21zIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5NzY3NDEwNTciLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDTUdCK1ByeC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6IlVJNzg1QT09IiwiZXRhZyI6IkNNR0IrUHJ4L2VFQ0VBRT0iLCJrbXNLZXlOYW1lIjoicHJvamVjdHMvZGVrbGVyay1zYW5kYm94L2xvY2F0aW9ucy9nbG9iYWwva2V5UmluZ3MvZ28taW50ZWdyYXRpb24tdGVzdC9jcnlwdG9LZXlzL2tleTEvY3J5cHRvS2V5VmVyc2lvbnMvMSJ9" } }, { "ID": "0dbd0a37c735be56", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/kms?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:26:17 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Ur_RD6un7NLXQpzwRBFEfZdp982qhfEzyvw8f_P1Lx1wKv8sUid99lQ7Nba5Rs73IJfv3qHXjQfUDHjWclvCAcS91nMboiexn-FwiMrUuKqCQ_d__4" ] }, "Body": "" } }, { "ID": "1b81fc72e201f2a2", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ], "X-Goog-Encryption-Algorithm": [ "AES256" ], "X-Goog-Encryption-Key": [ "CLEARED" ], "X-Goog-Encryption-Key-Sha256": [ "Io4lnOPU+EThO0X0nq7mNEXB1rWxZsBI4L37pBmyfDc=" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW4iLCJuYW1lIjoiY3NlayJ9Cg==", "bXkgc2VjcmV0" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3262" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:17 GMT" ], "Etag": [ "CKCxsfvx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqRTb3RtqG1gIL-ENbVZC8nWKRHapQP78uVzv4yyL2t7N8cA5jEBWa014iJALicWO06KthvAMPLctgZCJ2UvPqo72IO4_LheEfTr13-_h43M-roUyc" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jc2VrLzE1NTY4MzU5Nzc2ODEwNTYiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jc2VrIiwibmFtZSI6ImNzZWsiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk3NzY4MTA1NiIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNjoxNy42ODBaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjY6MTcuNjgwWiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI2OjE3LjY4MFoiLCJzaXplIjoiOSIsIm1kNUhhc2giOiJBQVBRUzQ2VHJuTVlucWlLQWJhZ3RRPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY3Nlaz9nZW5lcmF0aW9uPTE1NTY4MzU5Nzc2ODEwNTYmYWx0PW1lZGlhIiwiY2FjaGVDb250cm9sIjoicHVibGljLCBtYXgtYWdlPTYwIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY3Nlay8xNTU2ODM1OTc3NjgxMDU2L3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2NzZWsvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImNzZWsiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk3NzY4MTA1NiIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDS0N4c2Z2eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY3Nlay8xNTU2ODM1OTc3NjgxMDU2L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jc2VrL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY3NlayIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTc3NjgxMDU2IiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0tDeHNmdngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NzZWsvMTU1NjgzNTk3NzY4MTA1Ni9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY3Nlay9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImNzZWsiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk3NzY4MTA1NiIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDS0N4c2Z2eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY3Nlay8xNTU2ODM1OTc3NjgxMDU2L3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jc2VrL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY3NlayIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTc3NjgxMDU2IiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ0tDeHNmdngvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJVSTc4NUE9PSIsImV0YWciOiJDS0N4c2Z2eC9lRUNFQUU9IiwiY3VzdG9tZXJFbmNyeXB0aW9uIjp7ImVuY3J5cHRpb25BbGdvcml0aG0iOiJBRVMyNTYiLCJrZXlTaGEyNTYiOiJJbzRsbk9QVStFVGhPMFgwbnE3bU5FWEIxcld4WnNCSTRMMzdwQm15ZkRjPSJ9fQ==" } }, { "ID": "6da27052d0dabd22", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/csek/rewriteTo/b/go-integration-test-20190502-80633403432013-0001/o/cmek?alt=json\u0026destinationKmsKeyName=projects%2Fdeklerk-sandbox%2Flocations%2Fglobal%2FkeyRings%2Fgo-integration-test%2FcryptoKeys%2Fkey1\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "3" ], "User-Agent": [ "google-api-go-client/0.5" ], "X-Goog-Copy-Source-Encryption-Algorithm": [ "AES256" ], "X-Goog-Copy-Source-Encryption-Key": [ "CLEARED" ], "X-Goog-Copy-Source-Encryption-Key-Sha256": [ "Io4lnOPU+EThO0X0nq7mNEXB1rWxZsBI4L37pBmyfDc=" ] }, "MediaType": "application/json", "BodyParts": [ "e30K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3372" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:18 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpKmOV156VWN4edUkrNip1urAj8WTpDcgGTS520rVGilFT71KrZLZQxUMKloxtxKx5R6V9pUvIqYym68P8lQ8RSc5rEE_D1KlH-NyPgybiPERbxYZ4" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNyZXdyaXRlUmVzcG9uc2UiLCJ0b3RhbEJ5dGVzUmV3cml0dGVuIjoiOSIsIm9iamVjdFNpemUiOiI5IiwiZG9uZSI6dHJ1ZSwicmVzb3VyY2UiOnsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY21lay8xNTU2ODM1OTc4MTI2NDc3Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY21layIsIm5hbWUiOiJjbWVrIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5NzgxMjY0NzciLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW4iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDUtMDJUMjI6MjY6MTguMTI2WiIsInVwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI2OjE4LjEyNloiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNjoxOC4xMjZaIiwic2l6ZSI6IjkiLCJtZDVIYXNoIjoiQUFQUVM0NlRybk1ZbnFpS0FiYWd0UT09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2NtZWs/Z2VuZXJhdGlvbj0xNTU2ODM1OTc4MTI2NDc3JmFsdD1tZWRpYSIsImNhY2hlQ29udHJvbCI6InB1YmxpYywgbWF4LWFnZT02MCIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NtZWsvMTU1NjgzNTk3ODEyNjQ3Ny9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jbWVrL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJjbWVrIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5NzgxMjY0NzciLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0kzSnpQdngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NtZWsvMTU1NjgzNTk3ODEyNjQ3Ny9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY21lay9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImNtZWsiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk3ODEyNjQ3NyIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNJM0p6UHZ4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jbWVrLzE1NTY4MzU5NzgxMjY0NzcvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2NtZWsvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJjbWVrIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5NzgxMjY0NzciLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0kzSnpQdngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NtZWsvMTU1NjgzNTk3ODEyNjQ3Ny91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY21lay9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImNtZWsiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk3ODEyNjQ3NyIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNJM0p6UHZ4L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoiVUk3ODVBPT0iLCJldGFnIjoiQ0kzSnpQdngvZUVDRUFFPSIsImttc0tleU5hbWUiOiJwcm9qZWN0cy9kZWtsZXJrLXNhbmRib3gvbG9jYXRpb25zL2dsb2JhbC9rZXlSaW5ncy9nby1pbnRlZ3JhdGlvbi10ZXN0L2NyeXB0b0tleXMva2V5MS9jcnlwdG9LZXlWZXJzaW9ucy8xIn19" } }, { "ID": "6ff8a4be1ed6bda3", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/go-integration-test-20190502-80633403432013-0001/cmek", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "9" ], "Content-Type": [ "text/plain" ], "Date": [ "Thu, 02 May 2019 22:26:18 GMT" ], "Etag": [ "\"-CI3JzPvx/eECEAE=\"" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Last-Modified": [ "Thu, 02 May 2019 22:26:18 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "X-Goog-Encryption-Kms-Key-Name": [ "projects/deklerk-sandbox/locations/global/keyRings/go-integration-test/cryptoKeys/key1/cryptoKeyVersions/1" ], "X-Goog-Expiration": [ "Sat, 01 Jun 2019 22:26:18 GMT" ], "X-Goog-Generation": [ "1556835978126477" ], "X-Goog-Hash": [ "crc32c=UI785A==", "md5=AAPQS46TrnMYnqiKAbagtQ==" ], "X-Goog-Metageneration": [ "1" ], "X-Goog-Storage-Class": [ "STANDARD" ], "X-Goog-Stored-Content-Encoding": [ "identity" ], "X-Goog-Stored-Content-Length": [ "9" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqDR7RHLf_CQraIBM5Z3vCUxSJndE0E6FBOLFBqmYvMntnrQyVIfxwuTE6BtHL4b8oQszU6rIycc72JMUjiGRM_XoGdjsk-WhsbBmL_3c3x5H1s4bs" ] }, "Body": "bXkgc2VjcmV0" } }, { "ID": "51f1995364e644ed", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/cmek?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3271" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:18 GMT" ], "Etag": [ "CI3JzPvx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpM1hbkOXC-oSxvoqjP8s2MpxREJEpzVp2TTYj-6B8467MLYSA-yrWs9UoGwRGQUCJTR76e-qAmQnbzGsFGT31Kc3qjevb8SM0MynLHL9GhOMkm72w" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jbWVrLzE1NTY4MzU5NzgxMjY0NzciLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jbWVrIiwibmFtZSI6ImNtZWsiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk3ODEyNjQ3NyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNjoxOC4xMjZaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjY6MTguMTI2WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI2OjE4LjEyNloiLCJzaXplIjoiOSIsIm1kNUhhc2giOiJBQVBRUzQ2VHJuTVlucWlLQWJhZ3RRPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY21laz9nZW5lcmF0aW9uPTE1NTY4MzU5NzgxMjY0NzcmYWx0PW1lZGlhIiwiY2FjaGVDb250cm9sIjoicHVibGljLCBtYXgtYWdlPTYwIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY21lay8xNTU2ODM1OTc4MTI2NDc3L3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2NtZWsvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImNtZWsiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk3ODEyNjQ3NyIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDSTNKelB2eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY21lay8xNTU2ODM1OTc4MTI2NDc3L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jbWVrL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY21layIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTc4MTI2NDc3IiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0kzSnpQdngvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NtZWsvMTU1NjgzNTk3ODEyNjQ3Ny9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY21lay9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImNtZWsiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk3ODEyNjQ3NyIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDSTNKelB2eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY21lay8xNTU2ODM1OTc4MTI2NDc3L3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jbWVrL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY21layIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTc4MTI2NDc3IiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ0kzSnpQdngvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJVSTc4NUE9PSIsImV0YWciOiJDSTNKelB2eC9lRUNFQUU9Iiwia21zS2V5TmFtZSI6InByb2plY3RzL2Rla2xlcmstc2FuZGJveC9sb2NhdGlvbnMvZ2xvYmFsL2tleVJpbmdzL2dvLWludGVncmF0aW9uLXRlc3QvY3J5cHRvS2V5cy9rZXkxL2NyeXB0b0tleVZlcnNpb25zLzEifQ==" } }, { "ID": "8972a840dc3d95a5", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/csek?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:26:18 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoTmNCzrFh_7cFaryet35nLbKqM6dyo7nvsyZApHIj6fLKcMDb9ZA-_TRNjGOLNFjjoD0IZ1YOz9P-ftNchBFkjWDTaFzBjbHmryCc9JInU3wd_DLw" ] }, "Body": "" } }, { "ID": "1e28b278fe3e0a66", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/cmek?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:26:18 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqrX5OILXadm6r5e8fLyuLEhQncM5jrmmDaOesSqraquvQbXXKhTqNJ63RYU3qj90M3FLjwnAOz8oOBTQQDOq2sRqUkbpBbJzYj82Rp3Rd9VLpNns0" ] }, "Body": "" } }, { "ID": "d1ac5d123ee4bae6", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b?alt=json\u0026prettyPrint=false\u0026project=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "200" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJlbmNyeXB0aW9uIjp7ImRlZmF1bHRLbXNLZXlOYW1lIjoicHJvamVjdHMvZGVrbGVyay1zYW5kYm94L2xvY2F0aW9ucy9nbG9iYWwva2V5UmluZ3MvZ28taW50ZWdyYXRpb24tdGVzdC9jcnlwdG9LZXlzL2tleTEifSwibG9jYXRpb24iOiJVUyIsIm5hbWUiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTkifQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "609" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:19 GMT" ], "Etag": [ "CAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpbajYTiCBBelYuwcqOs7_O-SyJbcV6WGwYhC4JCMmeImLlFLb93JyaiYrSp-201iYZTIdQ2VViFR_Emxe2Z7b4jV_G-0o2xzkqnkSnz0-Qcw_q0Wc" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOSIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE5IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI2OjE5LjA2N1oiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNjoxOS4wNjdaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiaWFtQ29uZmlndXJhdGlvbiI6eyJidWNrZXRQb2xpY3lPbmx5Ijp7ImVuYWJsZWQiOmZhbHNlfX0sImVuY3J5cHRpb24iOnsiZGVmYXVsdEttc0tleU5hbWUiOiJwcm9qZWN0cy9kZWtsZXJrLXNhbmRib3gvbG9jYXRpb25zL2dsb2JhbC9rZXlSaW5ncy9nby1pbnRlZ3JhdGlvbi10ZXN0L2NyeXB0b0tleXMva2V5MSJ9LCJsb2NhdGlvbiI6IlVTIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJldGFnIjoiQ0FFPSJ9" } }, { "ID": "d035cdb991d0fabb", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0019?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "2555" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:19 GMT" ], "Etag": [ "CAE=" ], "Expires": [ "Thu, 02 May 2019 22:26:19 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uoi5SKd4TdRXg-INW-U3pKcPA2ioBWIc2zdC5W3J4efS9iZ0EKFNqprjQ-NGEK_3wSDGezk4Al3Dd4JovGxXSnH73rIw22S_R__XRrpTQmYpTiNFGQ" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOSIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE5IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI2OjE5LjA2N1oiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNjoxOS4wNjdaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTkvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE5L2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTkiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE5L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTkvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTkiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTkvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOS9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOSIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUU9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBRT0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJlbmNyeXB0aW9uIjp7ImRlZmF1bHRLbXNLZXlOYW1lIjoicHJvamVjdHMvZGVrbGVyay1zYW5kYm94L2xvY2F0aW9ucy9nbG9iYWwva2V5UmluZ3MvZ28taW50ZWdyYXRpb24tdGVzdC9jcnlwdG9LZXlzL2tleTEifSwib3duZXIiOnsiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0In0sImxvY2F0aW9uIjoiVVMiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsImV0YWciOiJDQUU9In0=" } }, { "ID": "672cb2bcc1ed4ee2", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0019/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTkiLCJuYW1lIjoia21zIn0K", "bXkgc2VjcmV0" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3234" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:20 GMT" ], "Etag": [ "CLHMt/zx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Upyst1aH69iaN9J4055oX7H2yReN5TADIX11Vul8KakNuYZbJ7yXm1GBdvCDVB-IPTvbhzELJWgfurnIHxGpzKJszLO70n58xMnVbSLsHX1J3W02Lw" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOS9rbXMvMTU1NjgzNTk3OTg3OTk4NSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOS9vL2ttcyIsIm5hbWUiOiJrbXMiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTkiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk3OTg3OTk4NSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNjoxOS44NzlaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjY6MTkuODc5WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI2OjE5Ljg3OVoiLCJzaXplIjoiOSIsIm1kNUhhc2giOiJBQVBRUzQ2VHJuTVlucWlLQWJhZ3RRPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE5L28va21zP2dlbmVyYXRpb249MTU1NjgzNTk3OTg3OTk4NSZhbHQ9bWVkaWEiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOS9rbXMvMTU1NjgzNTk3OTg3OTk4NS9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTkvby9rbXMvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOSIsIm9iamVjdCI6ImttcyIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTc5ODc5OTg1IiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNMSE10L3p4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOS9rbXMvMTU1NjgzNTk3OTg3OTk4NS9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE5L28va21zL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE5Iiwib2JqZWN0Ijoia21zIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5Nzk4Nzk5ODUiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDTEhNdC96eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTkva21zLzE1NTY4MzU5Nzk4Nzk5ODUvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOS9vL2ttcy9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOSIsIm9iamVjdCI6ImttcyIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTc5ODc5OTg1IiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNMSE10L3p4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOS9rbXMvMTU1NjgzNTk3OTg3OTk4NS91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE5L28va21zL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE5Iiwib2JqZWN0Ijoia21zIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5Nzk4Nzk5ODUiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDTEhNdC96eC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6IlVJNzg1QT09IiwiZXRhZyI6IkNMSE10L3p4L2VFQ0VBRT0iLCJrbXNLZXlOYW1lIjoicHJvamVjdHMvZGVrbGVyay1zYW5kYm94L2xvY2F0aW9ucy9nbG9iYWwva2V5UmluZ3MvZ28taW50ZWdyYXRpb24tdGVzdC9jcnlwdG9LZXlzL2tleTEvY3J5cHRvS2V5VmVyc2lvbnMvMSJ9" } }, { "ID": "c037ecafa6249395", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/go-integration-test-20190502-80633403432013-0019/kms", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "9" ], "Content-Type": [ "text/plain; charset=utf-8" ], "Date": [ "Thu, 02 May 2019 22:26:20 GMT" ], "Etag": [ "\"-CLHMt/zx/eECEAE=\"" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Last-Modified": [ "Thu, 02 May 2019 22:26:19 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "X-Goog-Encryption-Kms-Key-Name": [ "projects/deklerk-sandbox/locations/global/keyRings/go-integration-test/cryptoKeys/key1/cryptoKeyVersions/1" ], "X-Goog-Generation": [ "1556835979879985" ], "X-Goog-Hash": [ "crc32c=UI785A==", "md5=AAPQS46TrnMYnqiKAbagtQ==" ], "X-Goog-Metageneration": [ "1" ], "X-Goog-Storage-Class": [ "STANDARD" ], "X-Goog-Stored-Content-Encoding": [ "identity" ], "X-Goog-Stored-Content-Length": [ "9" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrrQOFSgCkxAaKVPAQhz0ohMN6irPryraHLjWDEQgV3dNEwc5cxqcDDRChzx6_HR1Z_NPlm3vmjFCJcNK-2rAz-tmvVS8w36Q5U9Lc2wAGUgL_joX4" ] }, "Body": "bXkgc2VjcmV0" } }, { "ID": "fc3eda648104f042", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0019/o/kms?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3234" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:20 GMT" ], "Etag": [ "CLHMt/zx/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqHPSbutJRXX-6i05QnH_4UizrPft0fsGc3_ISDNmXQ4C3RPbEAnNfS1Ren0j3k2z8zxk9AV1WZQCWiKG9D5A8gZAZESFxbSZyjbBH8jkLEsEX54NQ" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOS9rbXMvMTU1NjgzNTk3OTg3OTk4NSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOS9vL2ttcyIsIm5hbWUiOiJrbXMiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTkiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk3OTg3OTk4NSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNjoxOS44NzlaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjY6MTkuODc5WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI2OjE5Ljg3OVoiLCJzaXplIjoiOSIsIm1kNUhhc2giOiJBQVBRUzQ2VHJuTVlucWlLQWJhZ3RRPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE5L28va21zP2dlbmVyYXRpb249MTU1NjgzNTk3OTg3OTk4NSZhbHQ9bWVkaWEiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOS9rbXMvMTU1NjgzNTk3OTg3OTk4NS9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTkvby9rbXMvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOSIsIm9iamVjdCI6ImttcyIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTc5ODc5OTg1IiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNMSE10L3p4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOS9rbXMvMTU1NjgzNTk3OTg3OTk4NS9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE5L28va21zL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE5Iiwib2JqZWN0Ijoia21zIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5Nzk4Nzk5ODUiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDTEhNdC96eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTkva21zLzE1NTY4MzU5Nzk4Nzk5ODUvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOS9vL2ttcy9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOSIsIm9iamVjdCI6ImttcyIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTc5ODc5OTg1IiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNMSE10L3p4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOS9rbXMvMTU1NjgzNTk3OTg3OTk4NS91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE5L28va21zL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE5Iiwib2JqZWN0Ijoia21zIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5Nzk4Nzk5ODUiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDTEhNdC96eC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6IlVJNzg1QT09IiwiZXRhZyI6IkNMSE10L3p4L2VFQ0VBRT0iLCJrbXNLZXlOYW1lIjoicHJvamVjdHMvZGVrbGVyay1zYW5kYm94L2xvY2F0aW9ucy9nbG9iYWwva2V5UmluZ3MvZ28taW50ZWdyYXRpb24tdGVzdC9jcnlwdG9LZXlzL2tleTEvY3J5cHRvS2V5VmVyc2lvbnMvMSJ9" } }, { "ID": "13283bc1ba20f019", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0019/o/kms?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:26:20 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uo2b3OtHWqpsRWxurpcGgrEtM10ZDdsrIa2z0nFsO-P4G3RAGYMTVMR0MCtwLDePrKyhfnsK-d9T5AIcRpeaIe8Z40Qm7gkZP4Fdi9jXd6ceYe5Iwc" ] }, "Body": "" } }, { "ID": "ca2255586aa4aeab", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0019?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "126" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJlbmNyeXB0aW9uIjp7ImRlZmF1bHRLbXNLZXlOYW1lIjoicHJvamVjdHMvZGVrbGVyay1zYW5kYm94L2xvY2F0aW9ucy9nbG9iYWwva2V5UmluZ3MvZ28taW50ZWdyYXRpb24tdGVzdC9jcnlwdG9LZXlzL2tleTIifX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "2555" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:21 GMT" ], "Etag": [ "CAI=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Ur05CMGbsLFprbwWYFSeE3I5dKFdFUzO--ImyAzkLt6ueNGpMDviyX6c1S4F6t1bqXTSnyQXXQzgugu8JoecrL3-1eJOPsqnN-OBMubntJCblkyWqE" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOSIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE5IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI2OjE5LjA2N1oiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNjoyMS4zMzZaIiwibWV0YWdlbmVyYXRpb24iOiIyIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTkvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE5L2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTkiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FJPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE5L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTkvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTkiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTkvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOS9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOSIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUk9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBST0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBST0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJlbmNyeXB0aW9uIjp7ImRlZmF1bHRLbXNLZXlOYW1lIjoicHJvamVjdHMvZGVrbGVyay1zYW5kYm94L2xvY2F0aW9ucy9nbG9iYWwva2V5UmluZ3MvZ28taW50ZWdyYXRpb24tdGVzdC9jcnlwdG9LZXlzL2tleTIifSwib3duZXIiOnsiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0In0sImxvY2F0aW9uIjoiVVMiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsImV0YWciOiJDQUk9In0=" } }, { "ID": "e1c336910a43425f", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0019?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "2555" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:21 GMT" ], "Etag": [ "CAI=" ], "Expires": [ "Thu, 02 May 2019 22:26:21 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Urcwbg5Z9C0rFvSTWYj4FxF27ooV0028Cm-yme-BrfmvK0dWsRkfRQEMWylWwokcmM2kIvLKEiucJlvDLHvnbJPB_HjH3zF2Lm8xCwV_9gPN42QDeo" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOSIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE5IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI2OjE5LjA2N1oiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNjoyMS4zMzZaIiwibWV0YWdlbmVyYXRpb24iOiIyIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTkvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE5L2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTkiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FJPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE5L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTkvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTkiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTkvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOS9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOSIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUk9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBST0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBST0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJlbmNyeXB0aW9uIjp7ImRlZmF1bHRLbXNLZXlOYW1lIjoicHJvamVjdHMvZGVrbGVyay1zYW5kYm94L2xvY2F0aW9ucy9nbG9iYWwva2V5UmluZ3MvZ28taW50ZWdyYXRpb24tdGVzdC9jcnlwdG9LZXlzL2tleTIifSwib3duZXIiOnsiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0In0sImxvY2F0aW9uIjoiVVMiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsImV0YWciOiJDQUk9In0=" } }, { "ID": "581a002b653f595d", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0019?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "20" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJlbmNyeXB0aW9uIjpudWxsfQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "2431" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:22 GMT" ], "Etag": [ "CAM=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Upv2LawTqc_eDVGR_hv2jSCyEA77H33uMkPevVxUUDKj1u4a9IWOH2f1oMXpU52-49Jg17SUSoJUJai1Ueff3ahN58GC9FCxwJt5v5xOHI3SytFjpo" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOSIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE5IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI2OjE5LjA2N1oiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNjoyMi4xMjRaIiwibWV0YWdlbmVyYXRpb24iOiIzIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTkvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE5L2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTkiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FNPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE5L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTkvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTkiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQU09In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTkvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOS9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOSIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQU09In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBTT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQU09In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBTT0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwiZXRhZyI6IkNBTT0ifQ==" } }, { "ID": "a0db97c641f3f17c", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0019?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:26:22 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uo15eoN1OrQFM6eqxJcuNFl7Wfr6x_VvJ0ENBlhhC_Hedf5al2OplGnNslWnRQT9RVs92RVLevZ_F_ohutgnNsUbK1PVsR04UnQ_A6ea3C0ZLy8FkI" ] }, "Body": "" } }, { "ID": "ca84fc3a71a55ea8", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b?alt=json\u0026predefinedAcl=authenticatedRead\u0026predefinedDefaultObjectAcl=publicRead\u0026prettyPrint=false\u0026project=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "60" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIwIn0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "1468" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:23 GMT" ], "Etag": [ "CAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrnCCRKNh19fdBAL3pyCzbtLnG7z20pSwSZKl9uTerD6o6-B5mB79mqZRIbXNcUmcpTdpxTreKjvsHK3Y9EKq_5fkzBPInDj8YkjbGViIpd1ldSots" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAyMCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAyMCIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIwIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI2OjIzLjEwNloiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNjoyMy4xMDZaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjAvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIwL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjAiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIwL2FsbEF1dGhlbnRpY2F0ZWRVc2VycyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAyMC9hY2wvYWxsQXV0aGVudGljYXRlZFVzZXJzIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIwIiwiZW50aXR5IjoiYWxsQXV0aGVudGljYXRlZFVzZXJzIiwicm9sZSI6IlJFQURFUiIsImV0YWciOiJDQUU9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoiYWxsVXNlcnMiLCJyb2xlIjoiUkVBREVSIiwiZXRhZyI6IkNBRT0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwiZXRhZyI6IkNBRT0ifQ==" } }, { "ID": "ed54d82686b4d390", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0020?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "1468" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:23 GMT" ], "Etag": [ "CAE=" ], "Expires": [ "Thu, 02 May 2019 22:26:23 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpXJh1_aAMuDVjYxLZJdwqAt7OwZdmTkc0_5wf_LshhNm_So0q87o7gJ31T58vp1b0_CucSecAyyyOLUbYTDrWDDTZGMkZBpfx1iBArjRtBcud1IgI" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAyMCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAyMCIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIwIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI2OjIzLjEwNloiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNjoyMy4xMDZaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjAvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIwL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjAiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIwL2FsbEF1dGhlbnRpY2F0ZWRVc2VycyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAyMC9hY2wvYWxsQXV0aGVudGljYXRlZFVzZXJzIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIwIiwiZW50aXR5IjoiYWxsQXV0aGVudGljYXRlZFVzZXJzIiwicm9sZSI6IlJFQURFUiIsImV0YWciOiJDQUU9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoiYWxsVXNlcnMiLCJyb2xlIjoiUkVBREVSIiwiZXRhZyI6IkNBRT0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwiZXRhZyI6IkNBRT0ifQ==" } }, { "ID": "224aee5425ffb86e", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0020?alt=json\u0026predefinedAcl=private\u0026predefinedDefaultObjectAcl=authenticatedRead\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "33" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJhY2wiOltdLCJkZWZhdWx0T2JqZWN0QWNsIjpbXX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "1113" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:24 GMT" ], "Etag": [ "CAI=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoknWPZdEFnvKZGCGO_Z26ZaKeXNdBzc6k6qqlbGdQXVEtPvLPR2oYtKCXsqDgFBjMw4wfWVXwDfmcc5u5kBAxshpuzKGgCp8UOxv-i_Rml56mzrOI" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAyMCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAyMCIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIwIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI2OjIzLjEwNloiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNjoyNC40MjVaIiwibWV0YWdlbmVyYXRpb24iOiIyIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjAvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIwL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjAiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FJPSJ9XSwiZGVmYXVsdE9iamVjdEFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImVudGl0eSI6ImFsbEF1dGhlbnRpY2F0ZWRVc2VycyIsInJvbGUiOiJSRUFERVIiLCJldGFnIjoiQ0FJPSJ9XSwiaWFtQ29uZmlndXJhdGlvbiI6eyJidWNrZXRQb2xpY3lPbmx5Ijp7ImVuYWJsZWQiOmZhbHNlfX0sIm93bmVyIjp7ImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCJ9LCJsb2NhdGlvbiI6IlVTIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJldGFnIjoiQ0FJPSJ9" } }, { "ID": "b6a80796e20baf03", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0020/o?alt=json\u0026predefinedAcl=authenticatedRead\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjAiLCJuYW1lIjoicHJpdmF0ZSJ9Cg==", "aGVsbG8=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "1995" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:25 GMT" ], "Etag": [ "CNDq5v7x/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqMfGdFW2xElqOJcP4q5XeDjVehJr4FmjcFPij-Y31f_168_Jgb6zibcWxCOJzrV1aUYYTXZW9DMX-BcvfJi6YXoBCPpN23EhrGQyY7tHSb0SVurGY" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAyMC9wcml2YXRlLzE1NTY4MzU5ODQ4NDgyMDgiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjAvby9wcml2YXRlIiwibmFtZSI6InByaXZhdGUiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjAiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk4NDg0ODIwOCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNjoyNC44NDdaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjY6MjQuODQ3WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI2OjI0Ljg0N1oiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIwL28vcHJpdmF0ZT9nZW5lcmF0aW9uPTE1NTY4MzU5ODQ4NDgyMDgmYWx0PW1lZGlhIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjAvcHJpdmF0ZS8xNTU2ODM1OTg0ODQ4MjA4L3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjAvby9wcml2YXRlL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIwIiwib2JqZWN0IjoicHJpdmF0ZSIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTg0ODQ4MjA4IiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ05EcTV2N3gvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIwL3ByaXZhdGUvMTU1NjgzNTk4NDg0ODIwOC9hbGxBdXRoZW50aWNhdGVkVXNlcnMiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjAvby9wcml2YXRlL2FjbC9hbGxBdXRoZW50aWNhdGVkVXNlcnMiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjAiLCJvYmplY3QiOiJwcml2YXRlIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5ODQ4NDgyMDgiLCJlbnRpdHkiOiJhbGxBdXRoZW50aWNhdGVkVXNlcnMiLCJyb2xlIjoiUkVBREVSIiwiZXRhZyI6IkNORHE1djd4L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ05EcTV2N3gvZUVDRUFFPSJ9" } }, { "ID": "4812f1e0e907256e", "Request": { "Method": "PATCH", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0020/o/private?alt=json\u0026predefinedAcl=private\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "62" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjAifQo=" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "1529" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:25 GMT" ], "Etag": [ "CNDq5v7x/eECEAI=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqTjsMMIlet4CWUmGoB3TuGzhTHXlDwuUe1SAQO8H2vmbTo2QYYV_WozfDO2NyZpsA9LCtgwwthwxeEeEG182WQTTe3xLWnsVjqPZx-iho8JAgI66U" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAyMC9wcml2YXRlLzE1NTY4MzU5ODQ4NDgyMDgiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjAvby9wcml2YXRlIiwibmFtZSI6InByaXZhdGUiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjAiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk4NDg0ODIwOCIsIm1ldGFnZW5lcmF0aW9uIjoiMiIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNjoyNC44NDdaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjY6MjUuNDIzWiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI2OjI0Ljg0N1oiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIwL28vcHJpdmF0ZT9nZW5lcmF0aW9uPTE1NTY4MzU5ODQ4NDgyMDgmYWx0PW1lZGlhIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjAvcHJpdmF0ZS8xNTU2ODM1OTg0ODQ4MjA4L3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjAvby9wcml2YXRlL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIwIiwib2JqZWN0IjoicHJpdmF0ZSIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTg0ODQ4MjA4IiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ05EcTV2N3gvZUVDRUFJPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTkRxNXY3eC9lRUNFQUk9In0=" } }, { "ID": "969763dc18755620", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0020/o/private/rewriteTo/b/go-integration-test-20190502-80633403432013-0020/o/dst?alt=json\u0026destinationPredefinedAcl=publicRead\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "3" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "e30K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "2017" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:25 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoNk9xKdyuh-I4RkIXqQxMF4A82DZ9b2HYZOdVK7ELOsnMYBqOmrqsY5hzZJsLXMZCZ6zOSzCeefQZuTgYHwyd-jAttJ4QoA1lDk0HTwZqigIfpjCc" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNyZXdyaXRlUmVzcG9uc2UiLCJ0b3RhbEJ5dGVzUmV3cml0dGVuIjoiNSIsIm9iamVjdFNpemUiOiI1IiwiZG9uZSI6dHJ1ZSwicmVzb3VyY2UiOnsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjAvZHN0LzE1NTY4MzU5ODU4NTAyNjkiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjAvby9kc3QiLCJuYW1lIjoiZHN0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIwIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5ODU4NTAyNjkiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDUtMDJUMjI6MjY6MjUuODQ5WiIsInVwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI2OjI1Ljg0OVoiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNjoyNS44NDlaIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAyMC9vL2RzdD9nZW5lcmF0aW9uPTE1NTY4MzU5ODU4NTAyNjkmYWx0PW1lZGlhIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjAvZHN0LzE1NTY4MzU5ODU4NTAyNjkvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAyMC9vL2RzdC9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAyMCIsIm9iamVjdCI6ImRzdCIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTg1ODUwMjY5IiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ0ozL28vL3gvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIwL2RzdC8xNTU2ODM1OTg1ODUwMjY5L2FsbFVzZXJzIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIwL28vZHN0L2FjbC9hbGxVc2VycyIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAyMCIsIm9iamVjdCI6ImRzdCIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTg1ODUwMjY5IiwiZW50aXR5IjoiYWxsVXNlcnMiLCJyb2xlIjoiUkVBREVSIiwiZXRhZyI6IkNKMy9vLy94L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ0ozL28vL3gvZUVDRUFFPSJ9fQ==" } }, { "ID": "8db7e2a6b620e794", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0020/o/comp/compose?alt=json\u0026destinationPredefinedAcl=authenticatedRead\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "130" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJkZXN0aW5hdGlvbiI6eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjAifSwic291cmNlT2JqZWN0cyI6W3sibmFtZSI6InByaXZhdGUifSx7Im5hbWUiOiJkc3QifV19Cg==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "1906" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:26 GMT" ], "Etag": [ "CJGwwP/x/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpqjCYxNFNTu3V1H_kV5WJxkbEYE9I3H5fYjfGMPO7n6C9NJstYZGcIh6xVA5RAxMCwP1PdzXITgTI1m2vm5xP5nhzLVRHKhder2qzYFGsAooH-kG0" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAyMC9jb21wLzE1NTY4MzU5ODYzMTUyODEiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjAvby9jb21wIiwibmFtZSI6ImNvbXAiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjAiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk4NjMxNTI4MSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNjoyNi4zMTRaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjY6MjYuMzE0WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI2OjI2LjMxNFoiLCJzaXplIjoiMTAiLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIwL28vY29tcD9nZW5lcmF0aW9uPTE1NTY4MzU5ODYzMTUyODEmYWx0PW1lZGlhIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjAvY29tcC8xNTU2ODM1OTg2MzE1MjgxL3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjAvby9jb21wL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIwIiwib2JqZWN0IjoiY29tcCIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTg2MzE1MjgxIiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ0pHd3dQL3gvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIwL2NvbXAvMTU1NjgzNTk4NjMxNTI4MS9hbGxBdXRoZW50aWNhdGVkVXNlcnMiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjAvby9jb21wL2FjbC9hbGxBdXRoZW50aWNhdGVkVXNlcnMiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjAiLCJvYmplY3QiOiJjb21wIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5ODYzMTUyODEiLCJlbnRpdHkiOiJhbGxBdXRoZW50aWNhdGVkVXNlcnMiLCJyb2xlIjoiUkVBREVSIiwiZXRhZyI6IkNKR3d3UC94L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoiL1JDT2dnPT0iLCJjb21wb25lbnRDb3VudCI6MiwiZXRhZyI6IkNKR3d3UC94L2VFQ0VBRT0ifQ==" } }, { "ID": "72a0ce58c513f6d5", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0020/o/comp?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:26:26 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpWOQtHF0cKNME8sTEm9vbS9KKKLLK9afxka1b6TTVGxDjCQ4qAdnA9zshsfVFVKK5hNS10aABAQog_gjYCZTXbbsF4bQNBM0i4R7bK2r7saocPtFo" ] }, "Body": "" } }, { "ID": "111b5a296b726631", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0020/o/dst?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:26:26 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqPsYXABoYOnGueMXiIvH9AntIPEf4xc6i18Nnr_XEYBxy-3LSK9klIcNyfSB7we4lgbctsiYA2e2WWBJlfqk1GnK6YA2fj-e3IiPbKwBwTSLjr1Jk" ] }, "Body": "" } }, { "ID": "27e4065cd2000d43", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0020/o/private?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:26:27 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpMPK_b_vcRkSIj1t37L47as9idfpbrNWqzirdNBLwoaGDMPlbjatMzjLThnYRNwk9CqTNQ5H8eoKFbunpe5TMktUo_FHyI7rryoUhbCpkbytRrTeM" ] }, "Body": "" } }, { "ID": "cccb109f5fba2a3a", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0020?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:26:27 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoVAiJOaePqfycNhiwbkPOptOqgpe9Tvo0jo1aW2nviozj4-QcjTtnGGyhcdrZ8QTxT-KHPo-saYS9ESC_6osYhChJOCi8b9nXtuqH0BqlvywXs9FE" ] }, "Body": "" } }, { "ID": "cfab6af30981f62b", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/projects/deklerk-sandbox/serviceAccount?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "116" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:28 GMT" ], "Expires": [ "Thu, 02 May 2019 22:26:28 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrDBTBzZwm7GH6Jklv6hzuaZaO3JdgliJk8zLZkVNDqwDO7tYP-c06rzrTj03llkWuV_l1k9w2tbUcGG2Rtv-1MdozY6pktTutDMLfyhyHe1DaEIys" ] }, "Body": "eyJlbWFpbF9hZGRyZXNzIjoic2VydmljZS00OTYxNjk2MDE3MTRAZ3MtcHJvamVjdC1hY2NvdW50cy5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImtpbmQiOiJzdG9yYWdlI3NlcnZpY2VBY2NvdW50In0=" } }, { "ID": "677e783b9aea8c15", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW4iLCJuYW1lIjoic29tZS1vYmplY3QifQo=", "vcVTjdWWssp9XFk0D3Nk5w==" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3262" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:28 GMT" ], "Etag": [ "CPryt4Dy/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrdWRt6oMzDM98VpA0VDmWRuNvox2ZBw6ZpjbyOFDKCFKgJ92jsLkF8v4M4UUxaTUVpmr8iElUTld7Q2g5_MZSbRatDE2zVgaY-769Ppq7Nx6f0HAg" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9zb21lLW9iamVjdC8xNTU2ODM1OTg4MjczNTMwIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vc29tZS1vYmplY3QiLCJuYW1lIjoic29tZS1vYmplY3QiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk4ODI3MzUzMCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNjoyOC4yNzNaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjY6MjguMjczWiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI2OjI4LjI3M1oiLCJzaXplIjoiMTYiLCJtZDVIYXNoIjoidEhhY2ZTS2ZCeUMrLytjbEc3cStqdz09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL3NvbWUtb2JqZWN0P2dlbmVyYXRpb249MTU1NjgzNTk4ODI3MzUzMCZhbHQ9bWVkaWEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9zb21lLW9iamVjdC8xNTU2ODM1OTg4MjczNTMwL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL3NvbWUtb2JqZWN0L2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJzb21lLW9iamVjdCIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTg4MjczNTMwIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNQcnl0NER5L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9zb21lLW9iamVjdC8xNTU2ODM1OTg4MjczNTMwL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9zb21lLW9iamVjdC9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6InNvbWUtb2JqZWN0IiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5ODgyNzM1MzAiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDUHJ5dDREeS9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvc29tZS1vYmplY3QvMTU1NjgzNTk4ODI3MzUzMC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vc29tZS1vYmplY3QvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJzb21lLW9iamVjdCIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTg4MjczNTMwIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNQcnl0NER5L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9zb21lLW9iamVjdC8xNTU2ODM1OTg4MjczNTMwL3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9zb21lLW9iamVjdC9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6InNvbWUtb2JqZWN0IiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5ODgyNzM1MzAiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDUHJ5dDREeS9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6IlNtMWdLdz09IiwiZXRhZyI6IkNQcnl0NER5L2VFQ0VBRT0ifQ==" } }, { "ID": "ff3c05fe02cd38ac", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/go-integration-test-20190502-80633403432013-0001/some-object", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "public, max-age=60" ], "Content-Length": [ "16" ], "Content-Type": [ "text/plain" ], "Date": [ "Thu, 02 May 2019 22:26:28 GMT" ], "Etag": [ "\"b4769c7d229f0720beffe7251bbabe8f\"" ], "Expires": [ "Thu, 02 May 2019 22:27:28 GMT" ], "Last-Modified": [ "Thu, 02 May 2019 22:26:28 GMT" ], "Server": [ "UploadServer" ], "X-Goog-Expiration": [ "Sat, 01 Jun 2019 22:26:28 GMT" ], "X-Goog-Generation": [ "1556835988273530" ], "X-Goog-Hash": [ "crc32c=Sm1gKw==", "md5=tHacfSKfByC+/+clG7q+jw==" ], "X-Goog-Metageneration": [ "1" ], "X-Goog-Storage-Class": [ "STANDARD" ], "X-Goog-Stored-Content-Encoding": [ "identity" ], "X-Goog-Stored-Content-Length": [ "16" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uqn6PsKCJsyZAhI_JtSOcVKs7SWuqYsoprQTUagoZXqu1CHWyBc1TzWfUyF9iv5VBS4iZPP5qz0Lf3b51p8O36Sud2-QS2zDg9FKhtm1uBFKLpcTOs" ] }, "Body": "vcVTjdWWssp9XFk0D3Nk5w==" } }, { "ID": "d1c7cc7c0e1d2829", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/some-object?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3262" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:28 GMT" ], "Etag": [ "CPryt4Dy/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqluzdkA1sUAJQJZodwWmM7SP7tNoX2JJjDiqHTy3XtjEqiVDNpI0whWTFJJH4caozRYjJPjTb6_ywm82dnAiYEo-YCknhlvkWexfTq1BM9MRWwQeg" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9zb21lLW9iamVjdC8xNTU2ODM1OTg4MjczNTMwIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vc29tZS1vYmplY3QiLCJuYW1lIjoic29tZS1vYmplY3QiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk4ODI3MzUzMCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNjoyOC4yNzNaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjY6MjguMjczWiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI2OjI4LjI3M1oiLCJzaXplIjoiMTYiLCJtZDVIYXNoIjoidEhhY2ZTS2ZCeUMrLytjbEc3cStqdz09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL3NvbWUtb2JqZWN0P2dlbmVyYXRpb249MTU1NjgzNTk4ODI3MzUzMCZhbHQ9bWVkaWEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9zb21lLW9iamVjdC8xNTU2ODM1OTg4MjczNTMwL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL3NvbWUtb2JqZWN0L2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJzb21lLW9iamVjdCIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTg4MjczNTMwIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNQcnl0NER5L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9zb21lLW9iamVjdC8xNTU2ODM1OTg4MjczNTMwL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9zb21lLW9iamVjdC9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6InNvbWUtb2JqZWN0IiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5ODgyNzM1MzAiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDUHJ5dDREeS9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvc29tZS1vYmplY3QvMTU1NjgzNTk4ODI3MzUzMC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vc29tZS1vYmplY3QvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJzb21lLW9iamVjdCIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTg4MjczNTMwIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNQcnl0NER5L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9zb21lLW9iamVjdC8xNTU2ODM1OTg4MjczNTMwL3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9zb21lLW9iamVjdC9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6InNvbWUtb2JqZWN0IiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5ODgyNzM1MzAiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDUHJ5dDREeS9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6IlNtMWdLdz09IiwiZXRhZyI6IkNQcnl0NER5L2VFQ0VBRT0ifQ==" } }, { "ID": "951f74cbe6b30b67", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "2571" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:28 GMT" ], "Etag": [ "CA0=" ], "Expires": [ "Thu, 02 May 2019 22:26:28 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoMRpk7F0qXPvUV4uNPdV7VhfUO2Mm-qPBbx3VV92y1wRyElPF1kbRNEGJ1KqbIW5w2XozD7IzjxBx4KevqcPxZr0_E1iU1_NASedJ4lZj4EFoP9UI" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjIzOjU0LjYxMFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNToyNS41MjdaIiwibWV0YWdlbmVyYXRpb24iOiIxMyIsImFjbCI6W3sia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQTA9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0EwPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0EwPSJ9XSwiZGVmYXVsdE9iamVjdEFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDQTA9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0EwPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQTA9In1dLCJpYW1Db25maWd1cmF0aW9uIjp7ImJ1Y2tldFBvbGljeU9ubHkiOnsiZW5hYmxlZCI6ZmFsc2V9fSwib3duZXIiOnsiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0In0sImxvY2F0aW9uIjoiVVMiLCJ2ZXJzaW9uaW5nIjp7ImVuYWJsZWQiOmZhbHNlfSwibGlmZWN5Y2xlIjp7InJ1bGUiOlt7ImFjdGlvbiI6eyJ0eXBlIjoiRGVsZXRlIn0sImNvbmRpdGlvbiI6eyJhZ2UiOjMwfX1dfSwibGFiZWxzIjp7ImwxIjoidjIiLCJuZXciOiJuZXcifSwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJldGFnIjoiQ0EwPSJ9" } }, { "ID": "aadc7916a3fc24ad", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0021?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 404, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "11805" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:29 GMT" ], "Expires": [ "Thu, 02 May 2019 22:26:29 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2UqhoAeZtt8ffiWaPr6J0LEaVR3vjerqtJ7gMM9BObOkz_6MtctDuS_s8-DZRxtTZsGfMDtekIKG2v8p2_sb3MxvTgeLhgO4vqvJNIszTaMjjyQcEdY" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6Im5vdEZvdW5kIiwibWVzc2FnZSI6Ik5vdCBGb3VuZCIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpCVUNLRVRfTk9UX0ZPVU5EOiBObyBzdWNoIGJ1Y2tldDogZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIxXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5idWNrZXRzLkdldEJ1Y2tldC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoR2V0QnVja2V0LmphdmE6MTA0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuR2V0QnVja2V0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChHZXRCdWNrZXQuamF2YTozMylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQnVja2V0c0RlbGVnYXRvci5nZXQoQnVja2V0c0RlbGVnYXRvci5qYXZhOjgzKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBObyBzdWNoIGJ1Y2tldDogZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIxXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPU5PVF9GT1VORCwgY2F0ZWdvcnk9VVNFUl9FUlJPUiwgY2F1c2U9bnVsbCwgZGVidWdJbmZvPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpCVUNLRVRfTk9UX0ZPVU5EOiBObyBzdWNoIGJ1Y2tldDogZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIxXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5idWNrZXRzLkdldEJ1Y2tldC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoR2V0QnVja2V0LmphdmE6MTA0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuR2V0QnVja2V0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChHZXRCdWNrZXQuamF2YTozMylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQnVja2V0c0RlbGVnYXRvci5nZXQoQnVja2V0c0RlbGVnYXRvci5qYXZhOjgzKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBObyBzdWNoIGJ1Y2tldDogZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIxXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZG9tYWluPWdsb2JhbCwgZXh0ZW5kZWRIZWxwPW51bGwsIGh0dHBIZWFkZXJzPXt9LCBodHRwU3RhdHVzPW5vdEZvdW5kLCBpbnRlcm5hbFJlYXNvbj1SZWFzb257YXJndW1lbnRzPXt9LCBjYXVzZT1udWxsLCBjb2RlPWdkYXRhLkNvcmVFcnJvckRvbWFpbi5OT1RfRk9VTkQsIGNyZWF0ZWRCeUJhY2tlbmQ9dHJ1ZSwgZGVidWdNZXNzYWdlPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpCVUNLRVRfTk9UX0ZPVU5EOiBObyBzdWNoIGJ1Y2tldDogZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIxXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5idWNrZXRzLkdldEJ1Y2tldC5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoR2V0QnVja2V0LmphdmE6MTA0KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuR2V0QnVja2V0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChHZXRCdWNrZXQuamF2YTozMylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5mcmFtZXdvcmsuUmVxdWVzdEhhbmRsZXIuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKFJlcXVlc3RIYW5kbGVyLmphdmE6MzEwKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGUoUmVxdWVzdEhhbmRsZXIuamF2YToyNTYpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uQnVja2V0c0RlbGVnYXRvci5nZXQoQnVja2V0c0RlbGVnYXRvci5qYXZhOjgzKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBObyBzdWNoIGJ1Y2tldDogZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIxXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZXJyb3JQcm90b0NvZGU9Tk9UX0ZPVU5ELCBlcnJvclByb3RvRG9tYWluPWdkYXRhLkNvcmVFcnJvckRvbWFpbiwgZmlsdGVyZWRNZXNzYWdlPW51bGwsIGxvY2F0aW9uPWVudGl0eS5yZXNvdXJjZV9pZC5uYW1lLCBtZXNzYWdlPW51bGwsIHVubmFtZWRBcmd1bWVudHM9W119LCBsb2NhdGlvbj1lbnRpdHkucmVzb3VyY2VfaWQubmFtZSwgbWVzc2FnZT1Ob3QgRm91bmQsIHJlYXNvbj1ub3RGb3VuZCwgcnBjQ29kZT00MDR9IE5vdCBGb3VuZDogY29tLmdvb2dsZS5uZXQucnBjMy5ScGNFeGNlcHRpb246IGNsb3VkLmJpZ3N0b3JlLlJlc3BvbnNlQ29kZS5FcnJvckNvZGU6OkJVQ0tFVF9OT1RfRk9VTkQ6IE5vIHN1Y2ggYnVja2V0OiBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjFcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udG9ScGMzRXhjZXB0aW9uKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MTQ3KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmhhbmRsZXJzLmJ1Y2tldHMuR2V0QnVja2V0LmhhbmRsZVJlcXVlc3RSZWNlaXZlZChHZXRCdWNrZXQuamF2YToxMDQpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uaGFuZGxlcnMuYnVja2V0cy5HZXRCdWNrZXQuaGFuZGxlUmVxdWVzdFJlY2VpdmVkKEdldEJ1Y2tldC5qYXZhOjMzKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5CdWNrZXRzRGVsZWdhdG9yLmdldChCdWNrZXRzRGVsZWdhdG9yLmphdmE6ODMpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLlJwY1JlY2VpdmVyLmxhbWJkYSRwcm9jZXNzUmVxdWVzdEFzeW5jJDQoUnBjUmVjZWl2ZXIuamF2YToyMDIpXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuaXNvbGF0aW9uLkFzeW5jRXhlY3V0b3IubGFtYmRhJHN1Ym1pdCQwKEFzeW5jRXhlY3V0b3IuamF2YToyNTMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChDb250ZXh0UnVubmFibGUuamF2YTo1MClcblx0YXQgY29tLmdvb2dsZS5jb21tb24uY29udGV4dC5Db250ZXh0UnVubmFibGUkMS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzkpXG5cdGF0IGlvLmdycGMuQ29udGV4dC5ydW4oQ29udGV4dC5qYXZhOjU2NSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkN1cnJlbnRDb250ZXh0LnJ1bkluQ29udGV4dChDdXJyZW50Q29udGV4dC5qYXZhOjIwNClcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLkdlbmVyaWNDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NzIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChHZW5lcmljQ29udGV4dENhbGxiYWNrLmphdmE6NjQpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlLnJ1bihDb250ZXh0UnVubmFibGUuamF2YTozNSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yLnJ1bldvcmtlcihUaHJlYWRQb29sRXhlY3V0b3IuamF2YToxMTQ5KVxuXHRhdCBqYXZhLnV0aWwuY29uY3VycmVudC5UaHJlYWRQb29sRXhlY3V0b3IkV29ya2VyLnJ1bihUaHJlYWRQb29sRXhlY3V0b3IuamF2YTo2MjQpXG5cdGF0IGphdmEubGFuZy5UaHJlYWQucnVuKFRocmVhZC5qYXZhOjc0OClcbkNhdXNlZCBieTogY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb246IE5vIHN1Y2ggYnVja2V0OiBnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjFcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzEyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmNvbW1vbi5CaWdzdG9yZUV4Y2VwdGlvbi50aHJvd1JwYzNPbkVycm9yKEJpZ3N0b3JlRXhjZXB0aW9uLmphdmE6MzIwKVxuXHQuLi4gMTcgbW9yZVxuXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5jb3JlLkVycm9yQ29sbGVjdG9yLnRvRmF1bHQoRXJyb3JDb2xsZWN0b3IuamF2YTo1NClcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lFcnJvckNvbnZlcnRlci50b0ZhdWx0KFJvc3lFcnJvckNvbnZlcnRlci5qYXZhOjY3KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUhhbmRsZXIkMi5jYWxsKFJvc3lIYW5kbGVyLmphdmE6MjU5KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIucmVzdC5hZGFwdGVyLnJvc3kuUm9zeUhhbmRsZXIkMi5jYWxsKFJvc3lIYW5kbGVyLmphdmE6MjM5KVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRGlyZWN0RXhlY3V0b3IuZXhlY3V0ZShEaXJlY3RFeGVjdXRvci5qYXZhOjMwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuZXhlY3V0ZUxpc3RlbmVyKEFic3RyYWN0RnV0dXJlLmphdmE6MTE0Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmNvbXBsZXRlKEFic3RyYWN0RnV0dXJlLmphdmE6OTYzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuc2V0KEFic3RyYWN0RnV0dXJlLmphdmE6NzMxKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRGlyZWN0RXhlY3V0b3IuZXhlY3V0ZShEaXJlY3RFeGVjdXRvci5qYXZhOjMwKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuZXhlY3V0ZUxpc3RlbmVyKEFic3RyYWN0RnV0dXJlLmphdmE6MTE0Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmNvbXBsZXRlKEFic3RyYWN0RnV0dXJlLmphdmE6OTYzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQWJzdHJhY3RGdXR1cmUuc2V0KEFic3RyYWN0RnV0dXJlLmphdmE6NzMxKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS51dGlsLkNhbGxhYmxlRnV0dXJlLnJ1bihDYWxsYWJsZUZ1dHVyZS5qYXZhOjYyKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIudGhyZWFkLlRocmVhZFRyYWNrZXJzJFRocmVhZFRyYWNraW5nUnVubmFibGUucnVuKFRocmVhZFRyYWNrZXJzLmphdmE6MTI2KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlLnJ1bkluQ29udGV4dChUcmFjZUNvbnRleHQuamF2YTo0NTMpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5zZXJ2ZXIuQ29tbW9uTW9kdWxlJENvbnRleHRDYXJyeWluZ0V4ZWN1dG9yU2VydmljZSQxLnJ1bkluQ29udGV4dChDb21tb25Nb2R1bGUuamF2YTo4MDIpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUkMS5ydW4oVHJhY2VDb250ZXh0LmphdmE6NDYwKVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkQWJzdHJhY3RUcmFjZUNvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHROb1VucmVmKFRyYWNlQ29udGV4dC5qYXZhOjMxOSlcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRBYnN0cmFjdFRyYWNlQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dChUcmFjZUNvbnRleHQuamF2YTozMTEpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkVHJhY2VDb250ZXh0UnVubmFibGUucnVuKFRyYWNlQ29udGV4dC5qYXZhOjQ1Nylcblx0YXQgY29tLmdvb2dsZS5nc2UuaW50ZXJuYWwuRGlzcGF0Y2hRdWV1ZUltcGwkV29ya2VyVGhyZWFkLnJ1bihEaXNwYXRjaFF1ZXVlSW1wbC5qYXZhOjQwMylcbiJ9XSwiY29kZSI6NDA0LCJtZXNzYWdlIjoiTm90IEZvdW5kIn19" } }, { "ID": "03b45b7eac939177", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/storage-library-test-bucket/Caf%C3%A9", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "public, max-age=3600" ], "Content-Length": [ "20" ], "Content-Type": [ "text/plain" ], "Date": [ "Thu, 02 May 2019 22:26:29 GMT" ], "Etag": [ "\"ade43306cb39336d630e101af5fb51b4\"" ], "Expires": [ "Thu, 02 May 2019 23:26:29 GMT" ], "Last-Modified": [ "Fri, 24 Mar 2017 20:04:38 GMT" ], "Server": [ "UploadServer" ], "X-Goog-Generation": [ "1490385878535828" ], "X-Goog-Hash": [ "crc32c=fN3yZg==", "md5=reQzBss5M21jDhAa9ftRtA==" ], "X-Goog-Metageneration": [ "2" ], "X-Goog-Storage-Class": [ "MULTI_REGIONAL" ], "X-Goog-Stored-Content-Encoding": [ "identity" ], "X-Goog-Stored-Content-Length": [ "20" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpFU2KyS5OA-bAy_MovHXHg5zJZ2kznc6tgTTrSjilrNHiw0NimPHZApcRXOS_ejrSSy8nIn02xipxUWxvHM3ru5IYhJRTeBZxhlq6_XQVsATkvink" ] }, "Body": "Tm9ybWFsaXphdGlvbiBGb3JtIEM=" } }, { "ID": "725883eeccd4b42c", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/upload/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "multipart/related", "BodyParts": [ "eyJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJuYW1lIjoiemVybyJ9Cg==", "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "3128" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:29 GMT" ], "Etag": [ "CKyp9oDy/eECEAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_single_post_uploads" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UruPh9tBADr1LSQWFlj1C4tjlS6uwlcy_MVRYaTGD4e_qEUlq0iXJx6ns3JHbH7I9olH7aSJpDW6VQcV5EdLwjQMecgA7qKhxzLoYFW4BZdEXbUrro" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS96ZXJvLzE1NTY4MzU5ODkyOTYzMDAiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby96ZXJvIiwibmFtZSI6Inplcm8iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk4OTI5NjMwMCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNjoyOS4yOTVaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjY6MjkuMjk1WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI2OjI5LjI5NVoiLCJzaXplIjoiMCIsIm1kNUhhc2giOiIxQjJNMlk4QXNnVHBnQW1ZN1BoQ2ZnPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vemVybz9nZW5lcmF0aW9uPTE1NTY4MzU5ODkyOTYzMDAmYWx0PW1lZGlhIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvemVyby8xNTU2ODM1OTg5Mjk2MzAwL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL3plcm8vYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Inplcm8iLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk4OTI5NjMwMCIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDS3lwOW9EeS9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvemVyby8xNTU2ODM1OTg5Mjk2MzAwL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby96ZXJvL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiemVybyIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTg5Mjk2MzAwIiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0t5cDlvRHkvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL3plcm8vMTU1NjgzNTk4OTI5NjMwMC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vemVyby9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Inplcm8iLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk4OTI5NjMwMCIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDS3lwOW9EeS9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvemVyby8xNTU2ODM1OTg5Mjk2MzAwL3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby96ZXJvL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiemVybyIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTg5Mjk2MzAwIiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ0t5cDlvRHkvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJBQUFBQUE9PSIsImV0YWciOiJDS3lwOW9EeS9lRUNFQUU9In0=" } }, { "ID": "036f06773f6d6306", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0021/o?alt=json\u0026delimiter=\u0026pageToken=\u0026prefix=\u0026prettyPrint=false\u0026projection=full\u0026versions=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 404, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "11821" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:29 GMT" ], "Expires": [ "Thu, 02 May 2019 22:26:29 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "agent_rejected" ], "X-Guploader-Upload-Result": [ "agent_rejected" ], "X-Guploader-Uploadid": [ "AEnB2Uqs9uKpqdPwYRv420tAk0KmBT6DS2POPsIj39ROT-r3ymrd2SB-oOJEXuaHGOfih1ckOqp-YrvHHAh7l7A-6rwlFjoBSb4qCtWzXGPjekN0pUBIok8" ] }, "Body": "eyJlcnJvciI6eyJlcnJvcnMiOlt7ImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6Im5vdEZvdW5kIiwibWVzc2FnZSI6Ik5vdCBGb3VuZCIsImRlYnVnSW5mbyI6ImNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpCVUNLRVRfTk9UX0ZPVU5EOiBObyBzdWNoIGJ1Y2tldDogZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIxXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkxpc3RPYmplY3RzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChMaXN0T2JqZWN0cy5qYXZhOjE3MSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkxpc3RPYmplY3RzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChMaXN0T2JqZWN0cy5qYXZhOjQxKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLmxpc3QoT2JqZWN0c0RlbGVnYXRvci5qYXZhOjg5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBObyBzdWNoIGJ1Y2tldDogZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIxXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUuRmF1bHQ6IEltbXV0YWJsZUVycm9yRGVmaW5pdGlvbntiYXNlPU5PVF9GT1VORCwgY2F0ZWdvcnk9VVNFUl9FUlJPUiwgY2F1c2U9bnVsbCwgZGVidWdJbmZvPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpCVUNLRVRfTk9UX0ZPVU5EOiBObyBzdWNoIGJ1Y2tldDogZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIxXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkxpc3RPYmplY3RzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChMaXN0T2JqZWN0cy5qYXZhOjE3MSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkxpc3RPYmplY3RzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChMaXN0T2JqZWN0cy5qYXZhOjQxKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLmxpc3QoT2JqZWN0c0RlbGVnYXRvci5qYXZhOjg5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBObyBzdWNoIGJ1Y2tldDogZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIxXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZG9tYWluPWdsb2JhbCwgZXh0ZW5kZWRIZWxwPW51bGwsIGh0dHBIZWFkZXJzPXt9LCBodHRwU3RhdHVzPW5vdEZvdW5kLCBpbnRlcm5hbFJlYXNvbj1SZWFzb257YXJndW1lbnRzPXt9LCBjYXVzZT1udWxsLCBjb2RlPWdkYXRhLkNvcmVFcnJvckRvbWFpbi5OT1RfRk9VTkQsIGNyZWF0ZWRCeUJhY2tlbmQ9dHJ1ZSwgZGVidWdNZXNzYWdlPWNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpCVUNLRVRfTk9UX0ZPVU5EOiBObyBzdWNoIGJ1Y2tldDogZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIxXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkxpc3RPYmplY3RzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChMaXN0T2JqZWN0cy5qYXZhOjE3MSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkxpc3RPYmplY3RzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChMaXN0T2JqZWN0cy5qYXZhOjQxKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLmxpc3QoT2JqZWN0c0RlbGVnYXRvci5qYXZhOjg5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBObyBzdWNoIGJ1Y2tldDogZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIxXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcbiwgZXJyb3JQcm90b0NvZGU9Tk9UX0ZPVU5ELCBlcnJvclByb3RvRG9tYWluPWdkYXRhLkNvcmVFcnJvckRvbWFpbiwgZmlsdGVyZWRNZXNzYWdlPW51bGwsIGxvY2F0aW9uPWVudGl0eS5idWNrZXQsIG1lc3NhZ2U9bnVsbCwgdW5uYW1lZEFyZ3VtZW50cz1bXX0sIGxvY2F0aW9uPWVudGl0eS5idWNrZXQsIG1lc3NhZ2U9Tm90IEZvdW5kLCByZWFzb249bm90Rm91bmQsIHJwY0NvZGU9NDA0fSBOb3QgRm91bmQ6IGNvbS5nb29nbGUubmV0LnJwYzMuUnBjRXhjZXB0aW9uOiBjbG91ZC5iaWdzdG9yZS5SZXNwb25zZUNvZGUuRXJyb3JDb2RlOjpCVUNLRVRfTk9UX0ZPVU5EOiBObyBzdWNoIGJ1Y2tldDogZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIxXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRvUnBjM0V4Y2VwdGlvbihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjE0Nylcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkxpc3RPYmplY3RzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChMaXN0T2JqZWN0cy5qYXZhOjE3MSlcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5oYW5kbGVycy5vYmplY3RzLkxpc3RPYmplY3RzLmhhbmRsZVJlcXVlc3RSZWNlaXZlZChMaXN0T2JqZWN0cy5qYXZhOjQxKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmFwaS5qc29uLmZyYW1ld29yay5SZXF1ZXN0SGFuZGxlci5oYW5kbGVSZXF1ZXN0UmVjZWl2ZWQoUmVxdWVzdEhhbmRsZXIuamF2YTozMTApXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuYXBpLmpzb24uZnJhbWV3b3JrLlJlcXVlc3RIYW5kbGVyLmhhbmRsZShSZXF1ZXN0SGFuZGxlci5qYXZhOjI1Nilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5hcGkuanNvbi5PYmplY3RzRGVsZWdhdG9yLmxpc3QoT2JqZWN0c0RlbGVnYXRvci5qYXZhOjg5KVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5ScGNSZWNlaXZlci5sYW1iZGEkcHJvY2Vzc1JlcXVlc3RBc3luYyQ0KFJwY1JlY2VpdmVyLmphdmE6MjAyKVxuXHRhdCBjb20uZ29vZ2xlLmNsb3VkLmJpZ3N0b3JlLmlzb2xhdGlvbi5Bc3luY0V4ZWN1dG9yLmxhbWJkYSRzdWJtaXQkMChBc3luY0V4ZWN1dG9yLmphdmE6MjUzKVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoQ29udGV4dFJ1bm5hYmxlLmphdmE6NTApXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLmNvbnRleHQuQ29udGV4dFJ1bm5hYmxlJDEucnVuKENvbnRleHRSdW5uYWJsZS5qYXZhOjM5KVxuXHRhdCBpby5ncnBjLkNvbnRleHQucnVuKENvbnRleHQuamF2YTo1NjUpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5DdXJyZW50Q29udGV4dC5ydW5JbkNvbnRleHQoQ3VycmVudENvbnRleHQuamF2YToyMDQpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5HZW5lcmljQ29udGV4dENhbGxiYWNrLnJ1bkluSW5oZXJpdGVkQ29udGV4dE5vVW5yZWYoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjcyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuR2VuZXJpY0NvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoR2VuZXJpY0NvbnRleHRDYWxsYmFjay5qYXZhOjY0KVxuXHRhdCBjb20uZ29vZ2xlLmNvbW1vbi5jb250ZXh0LkNvbnRleHRSdW5uYWJsZS5ydW4oQ29udGV4dFJ1bm5hYmxlLmphdmE6MzUpXG5cdGF0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvci5ydW5Xb3JrZXIoVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6MTE0OSlcblx0YXQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkUG9vbEV4ZWN1dG9yJFdvcmtlci5ydW4oVGhyZWFkUG9vbEV4ZWN1dG9yLmphdmE6NjI0KVxuXHRhdCBqYXZhLmxhbmcuVGhyZWFkLnJ1bihUaHJlYWQuamF2YTo3NDgpXG5DYXVzZWQgYnk6IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uOiBObyBzdWNoIGJ1Y2tldDogZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIxXG5cdGF0IGNvbS5nb29nbGUuY2xvdWQuYmlnc3RvcmUuY29tbW9uLkJpZ3N0b3JlRXhjZXB0aW9uLnRocm93T25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMxMilcblx0YXQgY29tLmdvb2dsZS5jbG91ZC5iaWdzdG9yZS5jb21tb24uQmlnc3RvcmVFeGNlcHRpb24udGhyb3dScGMzT25FcnJvcihCaWdzdG9yZUV4Y2VwdGlvbi5qYXZhOjMyMClcblx0Li4uIDE3IG1vcmVcblxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuY29yZS5FcnJvckNvbGxlY3Rvci50b0ZhdWx0KEVycm9yQ29sbGVjdG9yLmphdmE6NTQpXG5cdGF0IGNvbS5nb29nbGUuYXBpLnNlcnZlci5yZXN0LmFkYXB0ZXIucm9zeS5Sb3N5RXJyb3JDb252ZXJ0ZXIudG9GYXVsdChSb3N5RXJyb3JDb252ZXJ0ZXIuamF2YTo2Nylcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lIYW5kbGVyJDIuY2FsbChSb3N5SGFuZGxlci5qYXZhOjI1OSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnJlc3QuYWRhcHRlci5yb3N5LlJvc3lIYW5kbGVyJDIuY2FsbChSb3N5SGFuZGxlci5qYXZhOjIzOSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkRpcmVjdEV4ZWN1dG9yLmV4ZWN1dGUoRGlyZWN0RXhlY3V0b3IuamF2YTozMClcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmV4ZWN1dGVMaXN0ZW5lcihBYnN0cmFjdEZ1dHVyZS5qYXZhOjExNDMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5jb21wbGV0ZShBYnN0cmFjdEZ1dHVyZS5qYXZhOjk2Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLnNldChBYnN0cmFjdEZ1dHVyZS5qYXZhOjczMSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkRpcmVjdEV4ZWN1dG9yLmV4ZWN1dGUoRGlyZWN0RXhlY3V0b3IuamF2YTozMClcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLmV4ZWN1dGVMaXN0ZW5lcihBYnN0cmFjdEZ1dHVyZS5qYXZhOjExNDMpXG5cdGF0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5BYnN0cmFjdEZ1dHVyZS5jb21wbGV0ZShBYnN0cmFjdEZ1dHVyZS5qYXZhOjk2Mylcblx0YXQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFic3RyYWN0RnV0dXJlLnNldChBYnN0cmFjdEZ1dHVyZS5qYXZhOjczMSlcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLmNvcmUudXRpbC5DYWxsYWJsZUZ1dHVyZS5ydW4oQ2FsbGFibGVGdXR1cmUuamF2YTo2Milcblx0YXQgY29tLmdvb2dsZS5hcGkuc2VydmVyLnRocmVhZC5UaHJlYWRUcmFja2VycyRUaHJlYWRUcmFja2luZ1J1bm5hYmxlLnJ1bihUaHJlYWRUcmFja2Vycy5qYXZhOjEyNilcblx0YXQgY29tLmdvb2dsZS50cmFjaW5nLlRyYWNlQ29udGV4dCRUcmFjZUNvbnRleHRSdW5uYWJsZS5ydW5JbkNvbnRleHQoVHJhY2VDb250ZXh0LmphdmE6NDUzKVxuXHRhdCBjb20uZ29vZ2xlLmFwaS5zZXJ2ZXIuc2VydmVyLkNvbW1vbk1vZHVsZSRDb250ZXh0Q2FycnlpbmdFeGVjdXRvclNlcnZpY2UkMS5ydW5JbkNvbnRleHQoQ29tbW9uTW9kdWxlLmphdmE6ODAyKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlJDEucnVuKFRyYWNlQ29udGV4dC5qYXZhOjQ2MClcblx0YXQgaW8uZ3JwYy5Db250ZXh0LnJ1bihDb250ZXh0LmphdmE6NTY1KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuQ3VycmVudENvbnRleHQucnVuSW5Db250ZXh0KEN1cnJlbnRDb250ZXh0LmphdmE6MjA0KVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JEFic3RyYWN0VHJhY2VDb250ZXh0Q2FsbGJhY2sucnVuSW5Jbmhlcml0ZWRDb250ZXh0Tm9VbnJlZihUcmFjZUNvbnRleHQuamF2YTozMTkpXG5cdGF0IGNvbS5nb29nbGUudHJhY2luZy5UcmFjZUNvbnRleHQkQWJzdHJhY3RUcmFjZUNvbnRleHRDYWxsYmFjay5ydW5JbkluaGVyaXRlZENvbnRleHQoVHJhY2VDb250ZXh0LmphdmE6MzExKVxuXHRhdCBjb20uZ29vZ2xlLnRyYWNpbmcuVHJhY2VDb250ZXh0JFRyYWNlQ29udGV4dFJ1bm5hYmxlLnJ1bihUcmFjZUNvbnRleHQuamF2YTo0NTcpXG5cdGF0IGNvbS5nb29nbGUuZ3NlLmludGVybmFsLkRpc3BhdGNoUXVldWVJbXBsJFdvcmtlclRocmVhZC5ydW4oRGlzcGF0Y2hRdWV1ZUltcGwuamF2YTo0MDMpXG4ifV0sImNvZGUiOjQwNCwibWVzc2FnZSI6Ik5vdCBGb3VuZCJ9fQ==" } }, { "ID": "6b9dc540a02ed56f", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/storage-library-test-bucket/Cafe%CC%81", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "public, max-age=3600" ], "Content-Length": [ "20" ], "Content-Type": [ "text/plain" ], "Date": [ "Thu, 02 May 2019 22:26:29 GMT" ], "Etag": [ "\"df597679bac7c6150429ad80a1a05680\"" ], "Expires": [ "Thu, 02 May 2019 23:26:29 GMT" ], "Last-Modified": [ "Fri, 24 Mar 2017 20:04:37 GMT" ], "Server": [ "UploadServer" ], "X-Goog-Generation": [ "1490385877705600" ], "X-Goog-Hash": [ "crc32c=qBeWjQ==", "md5=31l2ebrHxhUEKa2AoaBWgA==" ], "X-Goog-Metageneration": [ "2" ], "X-Goog-Storage-Class": [ "MULTI_REGIONAL" ], "X-Goog-Stored-Content-Encoding": [ "identity" ], "X-Goog-Stored-Content-Length": [ "20" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrK69XFh4eDvl0RvSevMYIwMVs-nlDelMhoacS-4faSvuEateXMEqzdMvHClWdzkyqcEk7IQ1N0JMcv5uEPt6V98chYK-p9otm8puF4Uf846EBUEmg" ] }, "Body": "Tm9ybWFsaXphdGlvbiBGb3JtIEQ=" } }, { "ID": "09f71762da168c2f", "Request": { "Method": "GET", "URL": "https://storage.googleapis.com/go-integration-test-20190502-80633403432013-0001/zero", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "Go-http-client/1.1" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Accept-Ranges": [ "bytes" ], "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0" ], "Content-Length": [ "0" ], "Content-Type": [ "text/plain; charset=utf-8" ], "Date": [ "Thu, 02 May 2019 22:26:29 GMT" ], "Etag": [ "\"d41d8cd98f00b204e9800998ecf8427e\"" ], "Expires": [ "Thu, 02 May 2019 22:26:29 GMT" ], "Last-Modified": [ "Thu, 02 May 2019 22:26:29 GMT" ], "Server": [ "UploadServer" ], "X-Goog-Expiration": [ "Sat, 01 Jun 2019 22:26:29 GMT" ], "X-Goog-Generation": [ "1556835989296300" ], "X-Goog-Hash": [ "crc32c=AAAAAA==", "md5=1B2M2Y8AsgTpgAmY7PhCfg==" ], "X-Goog-Metageneration": [ "1" ], "X-Goog-Storage-Class": [ "STANDARD" ], "X-Goog-Stored-Content-Encoding": [ "identity" ], "X-Goog-Stored-Content-Length": [ "0" ], "X-Guploader-Customer": [ "cloud-storage" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrL3cJhuZXF-arxiYeo4MSf1to_dAoiyMisikOum5rqnrSnFa0OZ25Sl8hUU7lcIeW6P3-dwXK6qv0yHGFYMFnUB0VYpI9BRT16gMo8ikQ_L3gBmew" ] }, "Body": "" } }, { "ID": "681729281517b9c0", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/zero?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:26:29 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrKCNWRWyBsgMgWxsrSjXZMKW22GWVttfUWHw_UNSF7X7hnnz4h-cD7vFzaLO7OVWvnuMyW9qpJAA4eJaERT9hSjGfv41XVw_9ouvBOeIK9ykq-DrE" ] }, "Body": "" } }, { "ID": "39261fa7e6e9aede", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b?alt=json\u0026prettyPrint=false\u0026project=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "60" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIyIn0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "485" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:33 GMT" ], "Etag": [ "CAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpEt-jSVBZqHHBwfNkeP4NXxMdC1ISsFp2E_M6JiSw9rDj2gTnmTZhrvOn-bo_f9Lx_HMxMDgsXfO0ftWqvUjGwdmHAYNnYK5JSJozLfuosPNxv_S4" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAyMiIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAyMiIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIyIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI2OjMzLjU1N1oiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNjozMy41NTdaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiaWFtQ29uZmlndXJhdGlvbiI6eyJidWNrZXRQb2xpY3lPbmx5Ijp7ImVuYWJsZWQiOmZhbHNlfX0sImxvY2F0aW9uIjoiVVMiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsImV0YWciOiJDQUU9In0=" } }, { "ID": "3e70965b0aa1111b", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0022?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "2431" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:34 GMT" ], "Etag": [ "CAE=" ], "Expires": [ "Thu, 02 May 2019 22:26:34 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrB-4r560VjwZdR64GS_7_mZDefc-iM5ma_H8KjYfrdNXt-IlkgvzShsy7iNLseN6coOnkJwWT5tLbP54_M7nMUjord_jmpb1i19SBRA_3RQ_64yys" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAyMiIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAyMiIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIyIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI2OjMzLjU1N1oiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNjozMy41NTdaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjIvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIyL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjIiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIyL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjIvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjIiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjIvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAyMi9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAyMiIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUU9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBRT0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwiZXRhZyI6IkNBRT0ifQ==" } }, { "ID": "b80f9a99661cd572", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0022?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:26:34 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Ur4ItFRDN2_vB0_Ej095pAE061aywdVAoU_00t3fazm21R5ZLxUHpQL4ifTJ58218EkOeDBSWNaOaWuuzTnTM0DhXTe4l2X3pytOdfcZdIeyLV1rWA" ] }, "Body": "" } }, { "ID": "979ffb3f3450c3d5", "Request": { "Method": "POST", "URL": "https://www.googleapis.com/storage/v1/b?alt=json\u0026prettyPrint=false\u0026project=deklerk-sandbox", "Header": { "Accept-Encoding": [ "gzip" ], "Content-Length": [ "543" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "application/json", "BodyParts": [ "eyJsYWJlbHMiOnsiZW1wdHkiOiIiLCJsMSI6InYxIn0sImxpZmVjeWNsZSI6eyJydWxlIjpbeyJhY3Rpb24iOnsic3RvcmFnZUNsYXNzIjoiTkVBUkxJTkUiLCJ0eXBlIjoiU2V0U3RvcmFnZUNsYXNzIn0sImNvbmRpdGlvbiI6eyJhZ2UiOjEwLCJjcmVhdGVkQmVmb3JlIjoiMjAxNy0wMS0wMSIsImlzTGl2ZSI6ZmFsc2UsIm1hdGNoZXNTdG9yYWdlQ2xhc3MiOlsiTVVMVElfUkVHSU9OQUwiLCJTVEFOREFSRCJdLCJudW1OZXdlclZlcnNpb25zIjozfX0seyJhY3Rpb24iOnsidHlwZSI6IkRlbGV0ZSJ9LCJjb25kaXRpb24iOnsiYWdlIjozMCwiY3JlYXRlZEJlZm9yZSI6IjIwMTctMDEtMDEiLCJpc0xpdmUiOnRydWUsIm1hdGNoZXNTdG9yYWdlQ2xhc3MiOlsiTkVBUkxJTkUiXSwibnVtTmV3ZXJWZXJzaW9ucyI6MTB9fV19LCJsb2NhdGlvbiI6IlVTIiwibmFtZSI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAyMiIsInN0b3JhZ2VDbGFzcyI6Ik5FQVJMSU5FIiwidmVyc2lvbmluZyI6eyJlbmFibGVkIjp0cnVlfX0K" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "926" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:34 GMT" ], "Etag": [ "CAE=" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqM_YYHcsYolLFJJwWhO9AUYmnc3Vp3J6C5AydYOy-0RVAmBxObG8QpwZOsn28vDVllo_OZ1-4bASi_RGi4wdply2CPhzUOCVjP11XNzVYZ4_EiFb4" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAyMiIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAyMiIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIyIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI2OjM0LjU2M1oiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNjozNC41NjNaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiaWFtQ29uZmlndXJhdGlvbiI6eyJidWNrZXRQb2xpY3lPbmx5Ijp7ImVuYWJsZWQiOmZhbHNlfX0sImxvY2F0aW9uIjoiVVMiLCJ2ZXJzaW9uaW5nIjp7ImVuYWJsZWQiOnRydWV9LCJsaWZlY3ljbGUiOnsicnVsZSI6W3siYWN0aW9uIjp7InR5cGUiOiJTZXRTdG9yYWdlQ2xhc3MiLCJzdG9yYWdlQ2xhc3MiOiJORUFSTElORSJ9LCJjb25kaXRpb24iOnsiYWdlIjoxMCwiY3JlYXRlZEJlZm9yZSI6IjIwMTctMDEtMDEiLCJpc0xpdmUiOmZhbHNlLCJtYXRjaGVzU3RvcmFnZUNsYXNzIjpbIk1VTFRJX1JFR0lPTkFMIiwiU1RBTkRBUkQiXSwibnVtTmV3ZXJWZXJzaW9ucyI6M319LHsiYWN0aW9uIjp7InR5cGUiOiJEZWxldGUifSwiY29uZGl0aW9uIjp7ImFnZSI6MzAsImNyZWF0ZWRCZWZvcmUiOiIyMDE3LTAxLTAxIiwiaXNMaXZlIjp0cnVlLCJtYXRjaGVzU3RvcmFnZUNsYXNzIjpbIk5FQVJMSU5FIl0sIm51bU5ld2VyVmVyc2lvbnMiOjEwfX1dfSwibGFiZWxzIjp7ImwxIjoidjEiLCJlbXB0eSI6IiJ9LCJzdG9yYWdlQ2xhc3MiOiJORUFSTElORSIsImV0YWciOiJDQUU9In0=" } }, { "ID": "4931edd6fbd7e278", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0022?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "2872" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:34 GMT" ], "Etag": [ "CAE=" ], "Expires": [ "Thu, 02 May 2019 22:26:34 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpxOq-rTQ-0CFxAKezuPpbibtEmD_yASKzhW5dOiUdwVORx6a7_e1dmDnNCdamDPwLsBOpLueQD8iDbwlracb2uxGwwZ6yz92QD-t-JSKM-jSNp2xA" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAyMiIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAyMiIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIyIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI2OjM0LjU2M1oiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNjozNC41NjNaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjIvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIyL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjIiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDIyL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjIvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjIiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMjIvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAyMi9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAyMiIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUU9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBRT0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsInZlcnNpb25pbmciOnsiZW5hYmxlZCI6dHJ1ZX0sImxpZmVjeWNsZSI6eyJydWxlIjpbeyJhY3Rpb24iOnsidHlwZSI6IlNldFN0b3JhZ2VDbGFzcyIsInN0b3JhZ2VDbGFzcyI6Ik5FQVJMSU5FIn0sImNvbmRpdGlvbiI6eyJhZ2UiOjEwLCJjcmVhdGVkQmVmb3JlIjoiMjAxNy0wMS0wMSIsImlzTGl2ZSI6ZmFsc2UsIm1hdGNoZXNTdG9yYWdlQ2xhc3MiOlsiTVVMVElfUkVHSU9OQUwiLCJTVEFOREFSRCJdLCJudW1OZXdlclZlcnNpb25zIjozfX0seyJhY3Rpb24iOnsidHlwZSI6IkRlbGV0ZSJ9LCJjb25kaXRpb24iOnsiYWdlIjozMCwiY3JlYXRlZEJlZm9yZSI6IjIwMTctMDEtMDEiLCJpc0xpdmUiOnRydWUsIm1hdGNoZXNTdG9yYWdlQ2xhc3MiOlsiTkVBUkxJTkUiXSwibnVtTmV3ZXJWZXJzaW9ucyI6MTB9fV19LCJsYWJlbHMiOnsibDEiOiJ2MSIsImVtcHR5IjoiIn0sInN0b3JhZ2VDbGFzcyI6Ik5FQVJMSU5FIiwiZXRhZyI6IkNBRT0ifQ==" } }, { "ID": "12c06b5419a1fa81", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0022?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:26:35 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uoc24sLEBwU00YKpSYT4V6iJu3WxME2LgbyRWaYj4kX8s6Gjatzl0AWcCwPRhj_Bq0BOoUhKQzS8L0GJlhHC36eyEWEIs2rk2BcUyo0aE3U8XbuHuM" ] }, "Body": "" } }, { "ID": "bf24dffbe6cb8609", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001?alt=json\u0026prettyPrint=false\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "2571" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:35 GMT" ], "Etag": [ "CA0=" ], "Expires": [ "Thu, 02 May 2019 22:26:35 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqVkn03LSqmt8RiOPdW3JO4dpsS9vRp7VK8Qc0HwhmS3L9KDOgmyZIqLnvAwuAyvoIz1VsbqeoLwMMtz9pCIX216P4K3OpEs-x_bf_VSwMiFehgZiM" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjIzOjU0LjYxMFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNToyNS41MjdaIiwibWV0YWdlbmVyYXRpb24iOiIxMyIsImFjbCI6W3sia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQTA9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0EwPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0EwPSJ9XSwiZGVmYXVsdE9iamVjdEFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDQTA9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0EwPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQTA9In1dLCJpYW1Db25maWd1cmF0aW9uIjp7ImJ1Y2tldFBvbGljeU9ubHkiOnsiZW5hYmxlZCI6ZmFsc2V9fSwib3duZXIiOnsiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0In0sImxvY2F0aW9uIjoiVVMiLCJ2ZXJzaW9uaW5nIjp7ImVuYWJsZWQiOmZhbHNlfSwibGlmZWN5Y2xlIjp7InJ1bGUiOlt7ImFjdGlvbiI6eyJ0eXBlIjoiRGVsZXRlIn0sImNvbmRpdGlvbiI6eyJhZ2UiOjMwfX1dfSwibGFiZWxzIjp7ImwxIjoidjIiLCJuZXciOiJuZXcifSwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJldGFnIjoiQ0EwPSJ9" } }, { "ID": "2e41eac5e693f3e1", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o?alt=json\u0026delimiter=\u0026pageToken=\u0026prefix=\u0026prettyPrint=false\u0026projection=full\u0026versions=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "64746" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:35 GMT" ], "Expires": [ "Thu, 02 May 2019 22:26:35 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqgGJECa6hRJfdjE3ErHERxS3HPU_SALrzjf-HIDuv4lfxMvOwrkF2pfY2jUJ3b8TcIjWcnaa85Rs4LBucKffiSWfFXcfLZMF0EuiVRj9oH6Kp4tOg" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2FjbDEvMTU1NjgzNTg2NDI0ODE3MCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2FjbDEiLCJuYW1lIjoiYWNsMSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODY0MjQ4MTcwIiwibWV0YWdlbmVyYXRpb24iOiIyIiwiY29udGVudFR5cGUiOiJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MjQuMjQ3WiIsInVwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjI1LjYyOVoiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDoyNC4yNDdaIiwic2l6ZSI6IjE2IiwibWQ1SGFzaCI6IjBFOXRGTnBaajAvV0tPSjZmVjlwYXc9PSIsIm1lZGlhTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9hY2wxP2dlbmVyYXRpb249MTU1NjgzNTg2NDI0ODE3MCZhbHQ9bWVkaWEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9hY2wxLzE1NTY4MzU4NjQyNDgxNzAvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vYWNsMS9hY2wvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiYWNsMSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODY0MjQ4MTcwIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNPcitwY1h4L2VFQ0VBST0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9hY2wxLzE1NTY4MzU4NjQyNDgxNzAvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2FjbDEvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJhY2wxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NjQyNDgxNzAiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDT3IrcGNYeC9lRUNFQUk9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYWNsMS8xNTU2ODM1ODY0MjQ4MTcwL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9hY2wxL2FjbC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiYWNsMSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODY0MjQ4MTcwIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNPcitwY1h4L2VFQ0VBST0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9hY2wxLzE1NTY4MzU4NjQyNDgxNzAvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2FjbDEvYWNsL3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJhY2wxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NjQyNDgxNzAiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDT3IrcGNYeC9lRUNFQUk9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6IkZpRG1WZz09IiwiZXRhZyI6IkNPcitwY1h4L2VFQ0VBST0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2FjbDIvMTU1NjgzNTg2NDczNzk0NiIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2FjbDIiLCJuYW1lIjoiYWNsMiIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODY0NzM3OTQ2IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MjQuNzM3WiIsInVwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjI0LjczN1oiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDoyNC43MzdaIiwic2l6ZSI6IjE2IiwibWQ1SGFzaCI6ImM5K08vcmcyNEhURkJjK2V0V2plZmc9PSIsIm1lZGlhTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9hY2wyP2dlbmVyYXRpb249MTU1NjgzNTg2NDczNzk0NiZhbHQ9bWVkaWEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9hY2wyLzE1NTY4MzU4NjQ3Mzc5NDYvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vYWNsMi9hY2wvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiYWNsMiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODY0NzM3OTQ2IiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNKcnh3OFh4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9hY2wyLzE1NTY4MzU4NjQ3Mzc5NDYvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2FjbDIvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJhY2wyIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NjQ3Mzc5NDYiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDSnJ4dzhYeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYWNsMi8xNTU2ODM1ODY0NzM3OTQ2L3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9hY2wyL2FjbC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiYWNsMiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODY0NzM3OTQ2IiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNKcnh3OFh4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9hY2wyLzE1NTY4MzU4NjQ3Mzc5NDYvZG9tYWluLWdvb2dsZS5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9hY2wyL2FjbC9kb21haW4tZ29vZ2xlLmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImFjbDIiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg2NDczNzk0NiIsImVudGl0eSI6ImRvbWFpbi1nb29nbGUuY29tIiwicm9sZSI6IlJFQURFUiIsImRvbWFpbiI6Imdvb2dsZS5jb20iLCJldGFnIjoiQ0pyeHc4WHgvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2FjbDIvMTU1NjgzNTg2NDczNzk0Ni91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vYWNsMi9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImFjbDIiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg2NDczNzk0NiIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNKcnh3OFh4L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoiQXROUnRBPT0iLCJldGFnIjoiQ0pyeHc4WHgvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYnVja2V0SW5Db3B5QXR0cnMvMTU1NjgzNTg4MzY2Mzg1NiIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2J1Y2tldEluQ29weUF0dHJzIiwibmFtZSI6ImJ1Y2tldEluQ29weUF0dHJzIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4ODM2NjM4NTYiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6NDMuNjYzWiIsInVwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjQzLjY2M1oiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDo0My42NjNaIiwic2l6ZSI6IjMiLCJtZDVIYXNoIjoickwwWTIwekMrRnp0NzJWUHpNU2syQT09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2J1Y2tldEluQ29weUF0dHJzP2dlbmVyYXRpb249MTU1NjgzNTg4MzY2Mzg1NiZhbHQ9bWVkaWEiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9idWNrZXRJbkNvcHlBdHRycy8xNTU2ODM1ODgzNjYzODU2L3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2J1Y2tldEluQ29weUF0dHJzL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJidWNrZXRJbkNvcHlBdHRycyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODgzNjYzODU2IiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNQQ0R4ODd4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9idWNrZXRJbkNvcHlBdHRycy8xNTU2ODM1ODgzNjYzODU2L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9idWNrZXRJbkNvcHlBdHRycy9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImJ1Y2tldEluQ29weUF0dHJzIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4ODM2NjM4NTYiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDUENEeDg3eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvYnVja2V0SW5Db3B5QXR0cnMvMTU1NjgzNTg4MzY2Mzg1Ni9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vYnVja2V0SW5Db3B5QXR0cnMvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJidWNrZXRJbkNvcHlBdHRycyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODgzNjYzODU2IiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNQQ0R4ODd4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9idWNrZXRJbkNvcHlBdHRycy8xNTU2ODM1ODgzNjYzODU2L3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9idWNrZXRJbkNvcHlBdHRycy9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImJ1Y2tldEluQ29weUF0dHJzIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4ODM2NjM4NTYiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDUENEeDg3eC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6Ino4U3VIUT09IiwiZXRhZyI6IkNQQ0R4ODd4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NoZWNrc3VtLW9iamVjdC8xNTU2ODM1ODU1OTYyMjQxIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY2hlY2tzdW0tb2JqZWN0IiwibmFtZSI6ImNoZWNrc3VtLW9iamVjdCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODU1OTYyMjQxIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjE1Ljk2MVoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDoxNS45NjFaIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MTUuOTYxWiIsInNpemUiOiIxMCIsIm1kNUhhc2giOiIvRjREalRpbGNESUlWRUhuL25BUXNBPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY2hlY2tzdW0tb2JqZWN0P2dlbmVyYXRpb249MTU1NjgzNTg1NTk2MjI0MSZhbHQ9bWVkaWEiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jaGVja3N1bS1vYmplY3QvMTU1NjgzNTg1NTk2MjI0MS9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jaGVja3N1bS1vYmplY3QvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImNoZWNrc3VtLW9iamVjdCIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODU1OTYyMjQxIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNJR2hyTUh4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jaGVja3N1bS1vYmplY3QvMTU1NjgzNTg1NTk2MjI0MS9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY2hlY2tzdW0tb2JqZWN0L2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY2hlY2tzdW0tb2JqZWN0IiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NTU5NjIyNDEiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDSUdock1IeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY2hlY2tzdW0tb2JqZWN0LzE1NTY4MzU4NTU5NjIyNDEvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2NoZWNrc3VtLW9iamVjdC9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImNoZWNrc3VtLW9iamVjdCIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODU1OTYyMjQxIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNJR2hyTUh4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jaGVja3N1bS1vYmplY3QvMTU1NjgzNTg1NTk2MjI0MS91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY2hlY2tzdW0tb2JqZWN0L2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY2hlY2tzdW0tb2JqZWN0IiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NTU5NjIyNDEiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDSUdock1IeC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6IlZzdTBnQT09IiwiZXRhZyI6IkNJR2hyTUh4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NvbXBvc2VkMS8xNTU2ODM1ODU4OTYyOTU3Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY29tcG9zZWQxIiwibmFtZSI6ImNvbXBvc2VkMSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODU4OTYyOTU3IiwibWV0YWdlbmVyYXRpb24iOiIxIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjE4Ljk2MloiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDoxOC45NjJaIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MTguOTYyWiIsInNpemUiOiI0OCIsIm1lZGlhTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jb21wb3NlZDE/Z2VuZXJhdGlvbj0xNTU2ODM1ODU4OTYyOTU3JmFsdD1tZWRpYSIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NvbXBvc2VkMS8xNTU2ODM1ODU4OTYyOTU3L3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2NvbXBvc2VkMS9hY2wvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY29tcG9zZWQxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NTg5NjI5NTciLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0kyMDQ4THgvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NvbXBvc2VkMS8xNTU2ODM1ODU4OTYyOTU3L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jb21wb3NlZDEvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJjb21wb3NlZDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg1ODk2Mjk1NyIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNJMjA0OEx4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb21wb3NlZDEvMTU1NjgzNTg1ODk2Mjk1Ny9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY29tcG9zZWQxL2FjbC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY29tcG9zZWQxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NTg5NjI5NTciLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0kyMDQ4THgvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NvbXBvc2VkMS8xNTU2ODM1ODU4OTYyOTU3L3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jb21wb3NlZDEvYWNsL3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJjb21wb3NlZDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg1ODk2Mjk1NyIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNJMjA0OEx4L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoiQWJXQnlRPT0iLCJjb21wb25lbnRDb3VudCI6MywiZXRhZyI6IkNJMjA0OEx4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NvbXBvc2VkMi8xNTU2ODM1ODU5NTY0Nzk5Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY29tcG9zZWQyIiwibmFtZSI6ImNvbXBvc2VkMiIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODU5NTY0Nzk5IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L2pzb24iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MTkuNTY0WiIsInVwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjE5LjU2NFoiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDoxOS41NjRaIiwic2l6ZSI6IjQ4IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2NvbXBvc2VkMj9nZW5lcmF0aW9uPTE1NTY4MzU4NTk1NjQ3OTkmYWx0PW1lZGlhIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY29tcG9zZWQyLzE1NTY4MzU4NTk1NjQ3OTkvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY29tcG9zZWQyL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJjb21wb3NlZDIiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg1OTU2NDc5OSIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDUCtSaU1QeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY29tcG9zZWQyLzE1NTY4MzU4NTk1NjQ3OTkvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2NvbXBvc2VkMi9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImNvbXBvc2VkMiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODU5NTY0Nzk5IiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ1ArUmlNUHgvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2NvbXBvc2VkMi8xNTU2ODM1ODU5NTY0Nzk5L3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jb21wb3NlZDIvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJjb21wb3NlZDIiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg1OTU2NDc5OSIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDUCtSaU1QeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY29tcG9zZWQyLzE1NTY4MzU4NTk1NjQ3OTkvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2NvbXBvc2VkMi9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImNvbXBvc2VkMiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODU5NTY0Nzk5IiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ1ArUmlNUHgvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJBYldCeVE9PSIsImNvbXBvbmVudENvdW50IjozLCJldGFnIjoiQ1ArUmlNUHgvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY29udGVudC8xNTU2ODM1ODc0MzUyMjA3Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY29udGVudCIsIm5hbWUiOiJjb250ZW50IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NzQzNTIyMDciLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6ImltYWdlL2pwZWciLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MzQuMzUxWiIsInVwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjM0LjM1MVoiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDozNC4zNTFaIiwic2l6ZSI6IjU0IiwibWQ1SGFzaCI6Ik44cDgvczlGd2RBQW5sdnIvbEVBalE9PSIsIm1lZGlhTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jb250ZW50P2dlbmVyYXRpb249MTU1NjgzNTg3NDM1MjIwNyZhbHQ9bWVkaWEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb250ZW50LzE1NTY4MzU4NzQzNTIyMDcvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY29udGVudC9hY2wvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY29udGVudCIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODc0MzUyMjA3IiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNNL1lqc3J4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb250ZW50LzE1NTY4MzU4NzQzNTIyMDcvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2NvbnRlbnQvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJjb250ZW50IiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NzQzNTIyMDciLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDTS9ZanNyeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY29udGVudC8xNTU2ODM1ODc0MzUyMjA3L3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jb250ZW50L2FjbC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY29udGVudCIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODc0MzUyMjA3IiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNNL1lqc3J4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jb250ZW50LzE1NTY4MzU4NzQzNTIyMDcvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2NvbnRlbnQvYWNsL3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJjb250ZW50IiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NzQzNTIyMDciLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDTS9ZanNyeC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6IkdvVWJzUT09IiwiZXRhZyI6IkNNL1lqc3J4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2N1c3RvbWVyLWVuY3J5cHRpb24vMTU1NjgzNTg3NTA1ODY4MCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2N1c3RvbWVyLWVuY3J5cHRpb24iLCJuYW1lIjoiY3VzdG9tZXItZW5jcnlwdGlvbiIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODc1MDU4NjgwIiwibWV0YWdlbmVyYXRpb24iOiIzIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjM1LjA1OFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDozNi4yMjVaIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MzUuMDU4WiIsInNpemUiOiIxMSIsIm1lZGlhTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jdXN0b21lci1lbmNyeXB0aW9uP2dlbmVyYXRpb249MTU1NjgzNTg3NTA1ODY4MCZhbHQ9bWVkaWEiLCJjb250ZW50TGFuZ3VhZ2UiOiJlbiIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2N1c3RvbWVyLWVuY3J5cHRpb24vMTU1NjgzNTg3NTA1ODY4MC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jdXN0b21lci1lbmNyeXB0aW9uL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJjdXN0b21lci1lbmNyeXB0aW9uIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NzUwNTg2ODAiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ1BqbnVjcngvZUVDRUFNPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2N1c3RvbWVyLWVuY3J5cHRpb24vMTU1NjgzNTg3NTA1ODY4MC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY3VzdG9tZXItZW5jcnlwdGlvbi9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImN1c3RvbWVyLWVuY3J5cHRpb24iLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3NTA1ODY4MCIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNQam51Y3J4L2VFQ0VBTT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLzE1NTY4MzU4NzUwNTg2ODAvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2N1c3RvbWVyLWVuY3J5cHRpb24vYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJjdXN0b21lci1lbmNyeXB0aW9uIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NzUwNTg2ODAiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ1BqbnVjcngvZUVDRUFNPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2N1c3RvbWVyLWVuY3J5cHRpb24vMTU1NjgzNTg3NTA1ODY4MC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY3VzdG9tZXItZW5jcnlwdGlvbi9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImN1c3RvbWVyLWVuY3J5cHRpb24iLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3NTA1ODY4MCIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNQam51Y3J4L2VFQ0VBTT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiZXRhZyI6IkNQam51Y3J4L2VFQ0VBTT0iLCJjdXN0b21lckVuY3J5cHRpb24iOnsiZW5jcnlwdGlvbkFsZ29yaXRobSI6IkFFUzI1NiIsImtleVNoYTI1NiI6IkgrTG1uWGhSb2VJNlRNVzVic1Y2SHlVazZweUdjMklNYnFZYkFYQmNwczA9In19LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY3VzdG9tZXItZW5jcnlwdGlvbi0yLzE1NTY4MzU4ODA3MTc1MDYiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jdXN0b21lci1lbmNyeXB0aW9uLTIiLCJuYW1lIjoiY3VzdG9tZXItZW5jcnlwdGlvbi0yIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4ODA3MTc1MDYiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6NDAuNzE3WiIsInVwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjQwLjcxN1oiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDo0MC43MTdaIiwic2l6ZSI6IjExIiwibWQ1SGFzaCI6Inh3V05GYTBWZFhQbWxBd3JsY0FKY2c9PSIsIm1lZGlhTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jdXN0b21lci1lbmNyeXB0aW9uLTI/Z2VuZXJhdGlvbj0xNTU2ODM1ODgwNzE3NTA2JmFsdD1tZWRpYSIsImNvbnRlbnRMYW5ndWFnZSI6ImVuIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY3VzdG9tZXItZW5jcnlwdGlvbi0yLzE1NTY4MzU4ODA3MTc1MDYvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY3VzdG9tZXItZW5jcnlwdGlvbi0yL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJjdXN0b21lci1lbmNyeXB0aW9uLTIiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg4MDcxNzUwNiIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDTUtaazgzeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY3VzdG9tZXItZW5jcnlwdGlvbi0yLzE1NTY4MzU4ODA3MTc1MDYvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2N1c3RvbWVyLWVuY3J5cHRpb24tMi9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImN1c3RvbWVyLWVuY3J5cHRpb24tMiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODgwNzE3NTA2IiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ01LWms4M3gvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2N1c3RvbWVyLWVuY3J5cHRpb24tMi8xNTU2ODM1ODgwNzE3NTA2L3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jdXN0b21lci1lbmNyeXB0aW9uLTIvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJjdXN0b21lci1lbmNyeXB0aW9uLTIiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg4MDcxNzUwNiIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDTUtaazgzeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY3VzdG9tZXItZW5jcnlwdGlvbi0yLzE1NTY4MzU4ODA3MTc1MDYvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2N1c3RvbWVyLWVuY3J5cHRpb24tMi9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImN1c3RvbWVyLWVuY3J5cHRpb24tMiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODgwNzE3NTA2IiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ01LWms4M3gvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJyME5Hcmc9PSIsImV0YWciOiJDTUtaazgzeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLTMvMTU1NjgzNTg3OTg1OTQ0MCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2N1c3RvbWVyLWVuY3J5cHRpb24tMyIsIm5hbWUiOiJjdXN0b21lci1lbmNyeXB0aW9uLTMiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg3OTg1OTQ0MCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDozOS44NTlaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MzkuODU5WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjM5Ljg1OVoiLCJzaXplIjoiMjIiLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY3VzdG9tZXItZW5jcnlwdGlvbi0zP2dlbmVyYXRpb249MTU1NjgzNTg3OTg1OTQ0MCZhbHQ9bWVkaWEiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLTMvMTU1NjgzNTg3OTg1OTQ0MC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9jdXN0b21lci1lbmNyeXB0aW9uLTMvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImN1c3RvbWVyLWVuY3J5cHRpb24tMyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODc5ODU5NDQwIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNQRHAzc3p4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLTMvMTU1NjgzNTg3OTg1OTQ0MC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY3VzdG9tZXItZW5jcnlwdGlvbi0zL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY3VzdG9tZXItZW5jcnlwdGlvbi0zIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4Nzk4NTk0NDAiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDUERwM3N6eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvY3VzdG9tZXItZW5jcnlwdGlvbi0zLzE1NTY4MzU4Nzk4NTk0NDAvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2N1c3RvbWVyLWVuY3J5cHRpb24tMy9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6ImN1c3RvbWVyLWVuY3J5cHRpb24tMyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODc5ODU5NDQwIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNQRHAzc3p4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9jdXN0b21lci1lbmNyeXB0aW9uLTMvMTU1NjgzNTg3OTg1OTQ0MC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vY3VzdG9tZXItZW5jcnlwdGlvbi0zL2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0IjoiY3VzdG9tZXItZW5jcnlwdGlvbi0zIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4Nzk4NTk0NDAiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDUERwM3N6eC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNvbXBvbmVudENvdW50IjoyLCJldGFnIjoiQ1BEcDNzengvZUVDRUFFPSIsImN1c3RvbWVyRW5jcnlwdGlvbiI6eyJlbmNyeXB0aW9uQWxnb3JpdGhtIjoiQUVTMjU2Iiwia2V5U2hhMjU2IjoiSCtMbW5YaFJvZUk2VE1XNWJzVjZIeVVrNnB5R2MySU1icVliQVhCY3BzMD0ifX0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9nemlwLXRlc3QvMTU1NjgzNTg2MDI1MTg2NyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2d6aXAtdGVzdCIsIm5hbWUiOiJnemlwLXRlc3QiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg2MDI1MTg2NyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoiYXBwbGljYXRpb24veC1nemlwIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjIwLjI1MVoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDoyMC4yNTFaIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MjAuMjUxWiIsInNpemUiOiIyNyIsIm1kNUhhc2giOiJPdEN3K2FSUklScUtHRkFFT2F4K3F3PT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vZ3ppcC10ZXN0P2dlbmVyYXRpb249MTU1NjgzNTg2MDI1MTg2NyZhbHQ9bWVkaWEiLCJjb250ZW50RW5jb2RpbmciOiJnemlwIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvZ3ppcC10ZXN0LzE1NTY4MzU4NjAyNTE4NjcvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vZ3ppcC10ZXN0L2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJnemlwLXRlc3QiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg2MDI1MTg2NyIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDTnVKc3NQeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvZ3ppcC10ZXN0LzE1NTY4MzU4NjAyNTE4NjcvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2d6aXAtdGVzdC9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Imd6aXAtdGVzdCIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODYwMjUxODY3IiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ051SnNzUHgvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2d6aXAtdGVzdC8xNTU2ODM1ODYwMjUxODY3L3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9nemlwLXRlc3QvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJnemlwLXRlc3QiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg2MDI1MTg2NyIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDTnVKc3NQeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvZ3ppcC10ZXN0LzE1NTY4MzU4NjAyNTE4NjcvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2d6aXAtdGVzdC9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Imd6aXAtdGVzdCIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODYwMjUxODY3IiwiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInJvbGUiOiJPV05FUiIsImVtYWlsIjoiYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJldGFnIjoiQ051SnNzUHgvZUVDRUFFPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiI5RGh3QkE9PSIsImV0YWciOiJDTnVKc3NQeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9oYXNoZXNPblVwbG9hZC0xLzE1NTY4MzU4ODUwNTE2ODAiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9oYXNoZXNPblVwbG9hZC0xIiwibmFtZSI6Imhhc2hlc09uVXBsb2FkLTEiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg4NTA1MTY4MCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDo0NS4wNTFaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6NDUuMDUxWiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjQ1LjA1MVoiLCJzaXplIjoiMjciLCJtZDVIYXNoIjoib2ZaakdsY1hQSmlHT0FmS0ZiSmwxUT09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2hhc2hlc09uVXBsb2FkLTE/Z2VuZXJhdGlvbj0xNTU2ODM1ODg1MDUxNjgwJmFsdD1tZWRpYSIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2hhc2hlc09uVXBsb2FkLTEvMTU1NjgzNTg4NTA1MTY4MC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9oYXNoZXNPblVwbG9hZC0xL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJoYXNoZXNPblVwbG9hZC0xIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4ODUwNTE2ODAiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0tEZW04L3gvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2hhc2hlc09uVXBsb2FkLTEvMTU1NjgzNTg4NTA1MTY4MC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vaGFzaGVzT25VcGxvYWQtMS9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Imhhc2hlc09uVXBsb2FkLTEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg4NTA1MTY4MCIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNLRGVtOC94L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9oYXNoZXNPblVwbG9hZC0xLzE1NTY4MzU4ODUwNTE2ODAvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL2hhc2hlc09uVXBsb2FkLTEvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJoYXNoZXNPblVwbG9hZC0xIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4ODUwNTE2ODAiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0tEZW04L3gvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL2hhc2hlc09uVXBsb2FkLTEvMTU1NjgzNTg4NTA1MTY4MC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vaGFzaGVzT25VcGxvYWQtMS9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Imhhc2hlc09uVXBsb2FkLTEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg4NTA1MTY4MCIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNLRGVtOC94L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoiY0grQSt3PT0iLCJldGFnIjoiQ0tEZW04L3gvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqL3dpdGgvc2xhc2hlcy8xNTU2ODM1ODQ1NTExMDE4Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqJTJGd2l0aCUyRnNsYXNoZXMiLCJuYW1lIjoib2JqL3dpdGgvc2xhc2hlcyIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1NTExMDE4IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA1LjUxMFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowNS41MTBaIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDUuNTEwWiIsInNpemUiOiIxNiIsIm1kNUhhc2giOiJ1ZXovaEo2d0FyZURRbmNjRFVkeGZnPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqJTJGd2l0aCUyRnNsYXNoZXM/Z2VuZXJhdGlvbj0xNTU2ODM1ODQ1NTExMDE4JmFsdD1tZWRpYSIsImNhY2hlQ29udHJvbCI6InB1YmxpYywgbWF4LWFnZT02MCIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iai93aXRoL3NsYXNoZXMvMTU1NjgzNTg0NTUxMTAxOC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmolMkZ3aXRoJTJGc2xhc2hlcy9hY2wvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqL3dpdGgvc2xhc2hlcyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1NTExMDE4IiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNPcXVycnp4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmovd2l0aC9zbGFzaGVzLzE1NTY4MzU4NDU1MTEwMTgvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iaiUyRndpdGglMkZzbGFzaGVzL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoib2JqL3dpdGgvc2xhc2hlcyIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ1NTExMDE4IiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ09xdXJyengvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iai93aXRoL3NsYXNoZXMvMTU1NjgzNTg0NTUxMTAxOC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqJTJGd2l0aCUyRnNsYXNoZXMvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmovd2l0aC9zbGFzaGVzIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDU1MTEwMTgiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ09xdXJyengvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iai93aXRoL3NsYXNoZXMvMTU1NjgzNTg0NTUxMTAxOC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqJTJGd2l0aCUyRnNsYXNoZXMvYWNsL3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmovd2l0aC9zbGFzaGVzIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDU1MTEwMTgiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDT3F1cnJ6eC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6Im9lbytGQT09IiwiZXRhZyI6IkNPcXVycnp4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajEvMTU1NjgzNTg0NDY0NzIyNSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajEiLCJuYW1lIjoib2JqMSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODQ0NjQ3MjI1IiwibWV0YWdlbmVyYXRpb24iOiI0IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA0LjY0NloiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDoxNy4xMjFaIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDQuNjQ2WiIsInNpemUiOiIxNiIsIm1kNUhhc2giOiJTbmEvVVd2N21jWkkyM29FNXRVYWJRPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMT9nZW5lcmF0aW9uPTE1NTY4MzU4NDQ2NDcyMjUmYWx0PW1lZGlhIiwiY2FjaGVDb250cm9sIjoicHVibGljLCBtYXgtYWdlPTYwIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMS8xNTU2ODM1ODQ0NjQ3MjI1L2RvbWFpbi1nb29nbGUuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMS9hY2wvZG9tYWluLWdvb2dsZS5jb20iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDQ2NDcyMjUiLCJlbnRpdHkiOiJkb21haW4tZ29vZ2xlLmNvbSIsInJvbGUiOiJSRUFERVIiLCJkb21haW4iOiJnb29nbGUuY29tIiwiZXRhZyI6IkNMblMrYnZ4L2VFQ0VBUT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoxLzE1NTY4MzU4NDQ2NDcyMjUvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajEvYWNsL3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDQ2NDcyMjUiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDTG5TK2J2eC9lRUNFQVE9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvb2JqMS8xNTU2ODM1ODQ0NjQ3MjI1L2FsbFVzZXJzIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMS9hY2wvYWxsVXNlcnMiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDQ2NDcyMjUiLCJlbnRpdHkiOiJhbGxVc2VycyIsInJvbGUiOiJSRUFERVIiLCJldGFnIjoiQ0xuUytidngvZUVDRUFRPSJ9XSwib3duZXIiOnsiZW50aXR5IjoidXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSJ9LCJjcmMzMmMiOiJDVDZkVEE9PSIsImV0YWciOiJDTG5TK2J2eC9lRUNFQVE9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoyLzE1NTY4MzU4NDUwNDkyNDUiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoyIiwibmFtZSI6Im9iajIiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTA0OTI0NSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDowNS4wNDhaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MDUuMDQ4WiIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjA1LjA0OFoiLCJzaXplIjoiMTYiLCJtZDVIYXNoIjoiQ0Mxd2x3ck1PSXEwZHZNa015bFVoZz09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajI/Z2VuZXJhdGlvbj0xNTU2ODM1ODQ1MDQ5MjQ1JmFsdD1tZWRpYSIsImNhY2hlQ29udHJvbCI6InB1YmxpYywgbWF4LWFnZT02MCIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajIvMTU1NjgzNTg0NTA0OTI0NS9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9vYmoyL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoyIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDUwNDkyNDUiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0oyWGtyengvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajIvMTU1NjgzNTg0NTA0OTI0NS9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMi9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajIiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTA0OTI0NSIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNKMlhrcnp4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vYmoyLzE1NTY4MzU4NDUwNDkyNDUvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL29iajIvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJvYmoyIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NDUwNDkyNDUiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0oyWGtyengvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL29iajIvMTU1NjgzNTg0NTA0OTI0NS91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vb2JqMi9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Im9iajIiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg0NTA0OTI0NSIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNKMlhrcnp4L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoialY1QVZRPT0iLCJldGFnIjoiQ0oyWGtyengvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvcG9zYy8xNTU2ODM1ODgyNzYwNjA3Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vcG9zYyIsIm5hbWUiOiJwb3NjIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4ODI3NjA2MDciLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6NDIuNzYwWiIsInVwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjQyLjc2MFoiLCJzdG9yYWdlQ2xhc3MiOiJNVUxUSV9SRUdJT05BTCIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDo0Mi43NjBaIiwic2l6ZSI6IjMiLCJtZDVIYXNoIjoickwwWTIwekMrRnp0NzJWUHpNU2syQT09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL3Bvc2M/Z2VuZXJhdGlvbj0xNTU2ODM1ODgyNzYwNjA3JmFsdD1tZWRpYSIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL3Bvc2MvMTU1NjgzNTg4Mjc2MDYwNy9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9wb3NjL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJwb3NjIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4ODI3NjA2MDciLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0ovemo4N3gvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL3Bvc2MvMTU1NjgzNTg4Mjc2MDYwNy9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vcG9zYy9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6InBvc2MiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg4Mjc2MDYwNyIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNKL3pqODd4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9wb3NjLzE1NTY4MzU4ODI3NjA2MDcvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL3Bvc2MvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJwb3NjIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4ODI3NjA2MDciLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0ovemo4N3gvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL3Bvc2MvMTU1NjgzNTg4Mjc2MDYwNy91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vcG9zYy9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6InBvc2MiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTg4Mjc2MDYwNyIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNKL3pqODd4L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoiejhTdUhRPT0iLCJldGFnIjoiQ0ovemo4N3gvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvcG9zYzIvMTU1NjgzNTg4MzE1Mjc3MCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL3Bvc2MyIiwibmFtZSI6InBvc2MyIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4ODMxNTI3NzAiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6NDMuMTUyWiIsInVwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjQzLjE1MloiLCJzdG9yYWdlQ2xhc3MiOiJNVUxUSV9SRUdJT05BTCIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDo0My4xNTJaIiwic2l6ZSI6IjMiLCJtZDVIYXNoIjoiOVdHcTl1OEw4VTFDQ0x0R3BNeXpyUT09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL3Bvc2MyP2dlbmVyYXRpb249MTU1NjgzNTg4MzE1Mjc3MCZhbHQ9bWVkaWEiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9wb3NjMi8xNTU2ODM1ODgzMTUyNzcwL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL3Bvc2MyL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJwb3NjMiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODgzMTUyNzcwIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNJTHJwODd4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9wb3NjMi8xNTU2ODM1ODgzMTUyNzcwL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9wb3NjMi9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6InBvc2MyIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4ODMxNTI3NzAiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDSUxycDg3eC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvcG9zYzIvMTU1NjgzNTg4MzE1Mjc3MC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vcG9zYzIvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJwb3NjMiIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODgzMTUyNzcwIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNJTHJwODd4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9wb3NjMi8xNTU2ODM1ODgzMTUyNzcwL3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9wb3NjMi9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6InBvc2MyIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4ODMxNTI3NzAiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDSUxycDg3eC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6IjE3cUFCUT09IiwiZXRhZyI6IkNJTHJwODd4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL3NpZ25lZFVSTC8xNTU2ODM1ODYxMTQxMjA2Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vc2lnbmVkVVJMIiwibmFtZSI6InNpZ25lZFVSTCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODYxMTQxMjA2IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjIxLjE0MFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDoyMS4xNDBaIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MjEuMTQwWiIsInNpemUiOiIyOSIsIm1kNUhhc2giOiJKeXh2Z3dtOW4yTXNyR1RNUGJNZVlBPT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vc2lnbmVkVVJMP2dlbmVyYXRpb249MTU1NjgzNTg2MTE0MTIwNiZhbHQ9bWVkaWEiLCJjYWNoZUNvbnRyb2wiOiJwdWJsaWMsIG1heC1hZ2U9NjAiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9zaWduZWRVUkwvMTU1NjgzNTg2MTE0MTIwNi9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9zaWduZWRVUkwvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6InNpZ25lZFVSTCIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODYxMTQxMjA2IiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNOYXQ2TVB4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9zaWduZWRVUkwvMTU1NjgzNTg2MTE0MTIwNi9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vc2lnbmVkVVJML2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoic2lnbmVkVVJMIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NjExNDEyMDYiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDTmF0Nk1QeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvc2lnbmVkVVJMLzE1NTY4MzU4NjExNDEyMDYvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL3NpZ25lZFVSTC9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6InNpZ25lZFVSTCIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODYxMTQxMjA2IiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNOYXQ2TVB4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9zaWduZWRVUkwvMTU1NjgzNTg2MTE0MTIwNi91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vc2lnbmVkVVJML2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoic2lnbmVkVVJMIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NjExNDEyMDYiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDTmF0Nk1QeC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6IlpUcUFMdz09IiwiZXRhZyI6IkNOYXQ2TVB4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL3NvbWUtb2JqZWN0LzE1NTY4MzU5ODgyNzM1MzAiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9zb21lLW9iamVjdCIsIm5hbWUiOiJzb21lLW9iamVjdCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsImdlbmVyYXRpb24iOiIxNTU2ODM1OTg4MjczNTMwIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI2OjI4LjI3M1oiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNjoyOC4yNzNaIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjY6MjguMjczWiIsInNpemUiOiIxNiIsIm1kNUhhc2giOiJ0SGFjZlNLZkJ5QysvK2NsRzdxK2p3PT0iLCJtZWRpYUxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vc29tZS1vYmplY3Q/Z2VuZXJhdGlvbj0xNTU2ODM1OTg4MjczNTMwJmFsdD1tZWRpYSIsImNhY2hlQ29udHJvbCI6InB1YmxpYywgbWF4LWFnZT02MCIsImFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL3NvbWUtb2JqZWN0LzE1NTY4MzU5ODgyNzM1MzAvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vc29tZS1vYmplY3QvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6InNvbWUtb2JqZWN0IiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5ODgyNzM1MzAiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ1ByeXQ0RHkvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL3NvbWUtb2JqZWN0LzE1NTY4MzU5ODgyNzM1MzAvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL3NvbWUtb2JqZWN0L2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoic29tZS1vYmplY3QiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk4ODI3MzUzMCIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNQcnl0NER5L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9zb21lLW9iamVjdC8xNTU2ODM1OTg4MjczNTMwL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby9zb21lLW9iamVjdC9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6InNvbWUtb2JqZWN0IiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU5ODgyNzM1MzAiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ1ByeXQ0RHkvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL3NvbWUtb2JqZWN0LzE1NTY4MzU5ODgyNzM1MzAvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL3NvbWUtb2JqZWN0L2FjbC91c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwib2JqZWN0Ijoic29tZS1vYmplY3QiLCJnZW5lcmF0aW9uIjoiMTU1NjgzNTk4ODI3MzUzMCIsImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJyb2xlIjoiT1dORVIiLCJlbWFpbCI6ImFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwiZXRhZyI6IkNQcnl0NER5L2VFQ0VBRT0ifV0sIm93bmVyIjp7ImVudGl0eSI6InVzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20ifSwiY3JjMzJjIjoiU20xZ0t3PT0iLCJldGFnIjoiQ1ByeXQ0RHkvZUVDRUFFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvemVyby1vYmplY3QvMTU1NjgzNTg1NjUzNzAxNiIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL3plcm8tb2JqZWN0IiwibmFtZSI6Inplcm8tb2JqZWN0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxIiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NTY1MzcwMTYiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDUtMDJUMjI6MjQ6MTYuNTM2WiIsInVwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI0OjE2LjUzNloiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNDoxNi41MzZaIiwic2l6ZSI6IjAiLCJtZDVIYXNoIjoiMUIyTTJZOEFzZ1RwZ0FtWTdQaENmZz09IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL3plcm8tb2JqZWN0P2dlbmVyYXRpb249MTU1NjgzNTg1NjUzNzAxNiZhbHQ9bWVkaWEiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS96ZXJvLW9iamVjdC8xNTU2ODM1ODU2NTM3MDE2L3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS9vL3plcm8tb2JqZWN0L2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJ6ZXJvLW9iamVjdCIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODU2NTM3MDE2IiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNMaXJ6OEh4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS96ZXJvLW9iamVjdC8xNTU2ODM1ODU2NTM3MDE2L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby96ZXJvLW9iamVjdC9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Inplcm8tb2JqZWN0IiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NTY1MzcwMTYiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDTGlyejhIeC9lRUNFQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvemVyby1vYmplY3QvMTU1NjgzNTg1NjUzNzAxNi9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDAxL28vemVyby1vYmplY3QvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEiLCJvYmplY3QiOiJ6ZXJvLW9iamVjdCIsImdlbmVyYXRpb24iOiIxNTU2ODM1ODU2NTM3MDE2IiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNMaXJ6OEh4L2VFQ0VBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMS96ZXJvLW9iamVjdC8xNTU2ODM1ODU2NTM3MDE2L3VzZXItYW5vdGhlci10aGluZ0BkZWtsZXJrLXNhbmRib3guaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMDEvby96ZXJvLW9iamVjdC9hY2wvdXNlci1hbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAwMSIsIm9iamVjdCI6Inplcm8tb2JqZWN0IiwiZ2VuZXJhdGlvbiI6IjE1NTY4MzU4NTY1MzcwMTYiLCJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwicm9sZSI6Ik9XTkVSIiwiZW1haWwiOiJhbm90aGVyLXRoaW5nQGRla2xlcmstc2FuZGJveC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImV0YWciOiJDTGlyejhIeC9lRUNFQUU9In1dLCJvd25lciI6eyJlbnRpdHkiOiJ1c2VyLWFub3RoZXItdGhpbmdAZGVrbGVyay1zYW5kYm94LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0sImNyYzMyYyI6IkFBQUFBQT09IiwiZXRhZyI6IkNMaXJ6OEh4L2VFQ0VBRT0ifV19" } }, { "ID": "744cbe6970c9623b", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/acl1?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:26:35 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpfI-4jHQ7K_XJuo8cMIfOvPLKerfuQA1KlRDBi4Fq11Uc9i--oKNuFL_MbH0CCxK8PeI4r4fmZILF9hdSGAMMpMmyX0w67j7t84C4tRDx2LnbzG4I" ] }, "Body": "" } }, { "ID": "a2bea52380600211", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/acl2?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:26:35 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrzTcVhZWJuBZITVX_K6haiVlOGb5fEYRdiiH8ODa4XsVSPl4FCDs7zPpKMTfoZA1veIMd4ccdcj8rUqWDMcRfDU5l4cOGvNhGZV-h9S2AVJfl6GdE" ] }, "Body": "" } }, { "ID": "e187777c49170a6d", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/bucketInCopyAttrs?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:26:36 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UouPwITheFghtKlzs2vxoAGnEm_V7OZZnYkk_0pLhV8g5YN6TPRS2n1h0iAtzkuFXYtjovp3ifqt_351LO6-CobCar6VgRnJ-_EQ9WgOWhIC9DzYTs" ] }, "Body": "" } }, { "ID": "653fa745ed683364", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/checksum-object?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:26:36 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UoBLZLK-ePmvYxO2ByvMQ1dXb_4-5yhOR-1nYkxjkINZf5fY9ptO2H4RfRtbIrRQ-QQNZHqZGgCOGJakKLkNgVI2_ExobQLkJ-JaJ-ViDWL9GZCEgU" ] }, "Body": "" } }, { "ID": "91230665f80c46f7", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/composed1?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:26:36 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Upasg8dCwbL7dWntUy3O1t_wWVeDNNT3YCz1uVNL8QUNh4z75y0p9OfL57wFX4CUv3NV06Oi9f7a85m42BzgDZl-kqmv4com_INYmRYjKbwrTdFB8A" ] }, "Body": "" } }, { "ID": "dc68e1f94de4fa2a", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/composed2?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:26:36 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqXdUtFVSSFIrK72haTC8pKLogl9pB4lDLpARc8oDKdNt1yfbHj4VAQH0M_Doqj1mLY2LVmThFxvG_1mvtVBm-N4x_J-c5Izq46lZh_xx3wOQEYZKQ" ] }, "Body": "" } }, { "ID": "db5b5c31ef8e503e", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/content?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:26:36 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Ur2nVuDhUpL1-5n7rzvboeHuOBlvh-59eoy59Y5ZIyvUy6FXYj2eCphVTBFkaIPXK7XIS6DJXkPzZABjiFi4hMA7Ewdgp860sYu44qguzhTfOymXYY" ] }, "Body": "" } }, { "ID": "f44103066254972d", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/customer-encryption?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:26:36 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uqul73HMDr4p6XCqdfKz99RILwd68VT50DnynneOl5m5E_a7ky2mbMA8mdM6xyAWCQtiJm8dCxvIuKYtjLavA8JUlkGIqqCLGfLbB2EvWahd55Fw_A" ] }, "Body": "" } }, { "ID": "99aa9c86d4998414", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/customer-encryption-2?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:26:36 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uqfk5JfeEeFo80cy1Y-OxXgzSIbt_x7qDWML2yJopIrt9DsPmRq4cDVFqg6sUFStj6aMrjxP7iu_tbwZzS_3BtnwqfPrJZvHllZ7tdeFTXLmto742o" ] }, "Body": "" } }, { "ID": "24bd829460fb4df6", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/customer-encryption-3?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:26:37 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UprF0LO3CObAApP8iwUO6IvC-Yh-5whtr0F_mMzaj0rltEl4C-AZjNuBMGuQUue-v9oBqb-nQU2ykIenSZ3UYnK4XVV7moFIS43VyP7pByYqsHPkMo" ] }, "Body": "" } }, { "ID": "acdf7531eddfd72c", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/gzip-test?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:26:37 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqAEWwZD_lXrdbrjMg-PYbmLP1-zSzjESAs-osetXJrFTueJ6ufxVfA3xkMG5KjtEz-68YryfKl9gAGsgfseX6H5COwltvyW6pJSdxDdA-dTV_S8eU" ] }, "Body": "" } }, { "ID": "8facd7ede0dc71a6", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/hashesOnUpload-1?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:26:37 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrInkaBVPO1ip6mFSpF0Nihd1wYE9HNfIz8HfFsZkiEVG1mX7eKMItsbmNwWMehWZ0qaKAf081imDi7DmKqs6mEy7vyTokMNXVUp5LrFoQ-yDfVRuc" ] }, "Body": "" } }, { "ID": "6affac5f0a8dea5a", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/obj%2Fwith%2Fslashes?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:26:37 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqhbUYzZ-vUqGcyfzGFaQrr89Q05cXGCB0EbWA2Dy8dmQxB3uWJ7_FUwi6Ish-VMpOrZv78bT9qAHd5Tr5b3s8bTCX6QR9HlelvxkKdyrUv2G8QQuY" ] }, "Body": "" } }, { "ID": "8258a6e1b5dc73aa", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/obj1?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:26:37 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Upola6CIBa9ONjl53PxMpFGQkHvYEau96KG2mgCmUDWDhxZKCw0T58QQRx8OIJW5sisH_acrPcg2o-LLdJgOxCtlVSw-t6wGisVL2-TSopEuezgmu4" ] }, "Body": "" } }, { "ID": "12186a37ecd09333", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/obj2?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:26:37 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UpFxLaOTSsPe7hDbzBznGCoZvAUmeNgWBwS45X2j3rpLlk8_MIFFuCa-aBpAM83d23ixudKpklnhiqCcrQQotCUZhkrMLpWLHBJdmcM0d5rCKL6opY" ] }, "Body": "" } }, { "ID": "e7a92beca78e4ec6", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/posc?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:26:37 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrpITV4ogt1-_eCsp0KFz7tVeM2A4FzSevs8Q0BPZ36nEPrP9aAaB4nfWASzLZgi2hNM1l9eFkf5UbYYWDT5J-nQFCapVNcm_4Nr43yd94Ce95SVps" ] }, "Body": "" } }, { "ID": "5bb0506f3ca9135d", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/posc2?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:26:38 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqFBt86Wz7Oqelsb0pPpIskBYdMYLR3XuBmD2F5DwyXt84Q1AUyL0Q94YtqTJP1yzgohHCkJWSGibqUARgP8Ilv9v4lVipsdfjSdFHgIjFJ1H-vuU4" ] }, "Body": "" } }, { "ID": "3ea05ac204d7a112", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/signedURL?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:26:38 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Up2mLLaTTO-0iqVf4m8WXPEsP-mHlaS6hz_gavjGI5yzU0jCjBNDRw1gj6Wa_cQIBzfjytwP2XYhBIJeAglwa6Uqv87WhzeqgGXt4u820FuZKVgY-w" ] }, "Body": "" } }, { "ID": "bed8580dc40e850e", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/some-object?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:26:38 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UodR7nshMeihBskPB6loBZoNDRFEUxojhFCKhQ0NpiEMRHY0ZHU8ncI4Sr7FHUmIDXyK8xVg_I7Qt5ESrqnGmRzW0h1eM8OGfEM-3weHyzMqN-VMik" ] }, "Body": "" } }, { "ID": "57489f1d9de0ddb8", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001/o/zero-object?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:26:38 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UqxQ_NSeD-rrAbZXERIaDr3_1wDC_RZ4MyuFZnOhdDqLkn4qub7rAIamqSQKDD8-jbn0c3XmxvowTghxhq4tZaxxHTmYJtB_FPvJxRZtCt3Leugx4g" ] }, "Body": "" } }, { "ID": "006b3176688c0ac8", "Request": { "Method": "DELETE", "URL": "https://www.googleapis.com/storage/v1/b/go-integration-test-20190502-80633403432013-0001?alt=json\u0026prettyPrint=false", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 204, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "no-cache, no-store, max-age=0, must-revalidate" ], "Content-Length": [ "0" ], "Content-Type": [ "application/json" ], "Date": [ "Thu, 02 May 2019 22:26:38 GMT" ], "Expires": [ "Mon, 01 Jan 1990 00:00:00 GMT" ], "Pragma": [ "no-cache" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2Uo4l8LfaJI78MH37sa7nOmY2A8EB4paZccrewnIFFud-pwGLeVf067ZiRaBAOAPsPYlaxxtsr6gtECA6UY0xiUBHPTLFOe4VNnNQpniNWYJEfZ1-I8" ] }, "Body": "" } }, { "ID": "a853ce25e734dbfd", "Request": { "Method": "GET", "URL": "https://www.googleapis.com/storage/v1/b?alt=json\u0026pageToken=\u0026prefix=go-integration-test\u0026prettyPrint=false\u0026project=deklerk-sandbox\u0026projection=full", "Header": { "Accept-Encoding": [ "gzip" ], "User-Agent": [ "google-api-go-client/0.5" ] }, "MediaType": "", "BodyParts": [ "" ] }, "Response": { "StatusCode": 200, "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "Header": { "Alt-Svc": [ "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"" ], "Cache-Control": [ "private, max-age=0, must-revalidate, no-transform" ], "Content-Length": [ "47300" ], "Content-Type": [ "application/json; charset=UTF-8" ], "Date": [ "Thu, 02 May 2019 22:26:39 GMT" ], "Expires": [ "Thu, 02 May 2019 22:26:39 GMT" ], "Server": [ "UploadServer" ], "Vary": [ "Origin", "X-Origin" ], "X-Guploader-Customer": [ "apiary_cloudstorage_metadata" ], "X-Guploader-Request-Result": [ "success" ], "X-Guploader-Upload-Result": [ "success" ], "X-Guploader-Uploadid": [ "AEnB2UrnXhEY-kWgvl-XqP1kXnVDpQphHD9znE-EyBBlFT-kHZtXEsAW5QG5PuzlaJPfQUwZqnTHP0wxu6YDbRCgDMB31UR760_lfEiX88PtVKIdTgCWm5A" ] }, "Body": "eyJraW5kIjoic3RvcmFnZSNidWNrZXRzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI2J1Y2tldCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi02NjU5NzcwNTEzMzE0Ni0wMDAxIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi02NjU5NzcwNTEzMzE0Ni0wMDAxIiwicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsIm5hbWUiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTY2NTk3NzA1MTMzMTQ2LTAwMDEiLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDUtMDJUMTg6Mjk6NTguNjAxWiIsInVwZGF0ZWQiOiIyMDE5LTA1LTAyVDE4OjI5OjU4LjYwMVoiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI2J1Y2tldEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItNjY1OTc3MDUxMzMxNDYtMDAwMS9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTY2NTk3NzA1MTMzMTQ2LTAwMDEvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItNjY1OTc3MDUxMzMxNDYtMDAwMSIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTY2NTk3NzA1MTMzMTQ2LTAwMDEvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItNjY1OTc3MDUxMzMxNDYtMDAwMS9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItNjY1OTc3MDUxMzMxNDYtMDAwMSIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI2J1Y2tldEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItNjY1OTc3MDUxMzMxNDYtMDAwMS9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi02NjU5NzcwNTEzMzE0Ni0wMDAxL2FjbC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi02NjU5NzcwNTEzMzE0Ni0wMDAxIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBRT0ifV0sImRlZmF1bHRPYmplY3RBY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0FFPSJ9XSwiaWFtQ29uZmlndXJhdGlvbiI6eyJidWNrZXRQb2xpY3lPbmx5Ijp7ImVuYWJsZWQiOmZhbHNlfX0sIm93bmVyIjp7ImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCJ9LCJsb2NhdGlvbiI6IlVTIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0IiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTY2NjExNTA2OTA3NjAyLTAwMDEiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTY2NjExNTA2OTA3NjAyLTAwMDEiLCJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwibmFtZSI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItNjY2MTE1MDY5MDc2MDItMDAwMSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQxODozMDoxMi4yNjRaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMTg6MzA6MTIuMjY0WiIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImFjbCI6W3sia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi02NjYxMTUwNjkwNzYwMi0wMDAxL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItNjY2MTE1MDY5MDc2MDItMDAwMS9hY2wvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi02NjYxMTUwNjkwNzYwMi0wMDAxIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI2J1Y2tldEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItNjY2MTE1MDY5MDc2MDItMDAwMS9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi02NjYxMTUwNjkwNzYwMi0wMDAxL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi02NjYxMTUwNjkwNzYwMi0wMDAxIiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi02NjYxMTUwNjkwNzYwMi0wMDAxL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTY2NjExNTA2OTA3NjAyLTAwMDEvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTY2NjExNTA2OTA3NjAyLTAwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0FFPSJ9XSwiZGVmYXVsdE9iamVjdEFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUU9In1dLCJpYW1Db25maWd1cmF0aW9uIjp7ImJ1Y2tldFBvbGljeU9ubHkiOnsiZW5hYmxlZCI6ZmFsc2V9fSwib3duZXIiOnsiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0In0sImxvY2F0aW9uIjoiVVMiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItNjY2MzM5NjU0MjA4MTgtMDAwMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItNjY2MzM5NjU0MjA4MTgtMDAwMSIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi02NjYzMzk2NTQyMDgxOC0wMDAxIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDE4OjMwOjM0LjY2MloiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQxODozMDozNC42NjJaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTY2NjMzOTY1NDIwODE4LTAwMDEvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi02NjYzMzk2NTQyMDgxOC0wMDAxL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTY2NjMzOTY1NDIwODE4LTAwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi02NjYzMzk2NTQyMDgxOC0wMDAxL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTY2NjMzOTY1NDIwODE4LTAwMDEvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTY2NjMzOTY1NDIwODE4LTAwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTY2NjMzOTY1NDIwODE4LTAwMDEvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItNjY2MzM5NjU0MjA4MTgtMDAwMS9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItNjY2MzM5NjU0MjA4MTgtMDAwMSIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUU9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBRT0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwiZXRhZyI6IkNBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI2J1Y2tldCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi03ODI5NDExMzUxNDUxOS0wMDAxIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi03ODI5NDExMzUxNDUxOS0wMDAxIiwicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsIm5hbWUiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTc4Mjk0MTEzNTE0NTE5LTAwMDEiLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDUtMDJUMjE6NDQ6NTQuOTYwWiIsInVwZGF0ZWQiOiIyMDE5LTA1LTAyVDIxOjQ0OjU0Ljk2MFoiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI2J1Y2tldEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItNzgyOTQxMTM1MTQ1MTktMDAwMS9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTc4Mjk0MTEzNTE0NTE5LTAwMDEvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItNzgyOTQxMTM1MTQ1MTktMDAwMSIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTc4Mjk0MTEzNTE0NTE5LTAwMDEvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItNzgyOTQxMTM1MTQ1MTktMDAwMS9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItNzgyOTQxMTM1MTQ1MTktMDAwMSIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI2J1Y2tldEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItNzgyOTQxMTM1MTQ1MTktMDAwMS9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi03ODI5NDExMzUxNDUxOS0wMDAxL2FjbC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi03ODI5NDExMzUxNDUxOS0wMDAxIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBRT0ifV0sImRlZmF1bHRPYmplY3RBY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0FFPSJ9XSwiaWFtQ29uZmlndXJhdGlvbiI6eyJidWNrZXRQb2xpY3lPbmx5Ijp7ImVuYWJsZWQiOmZhbHNlfX0sIm93bmVyIjp7ImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCJ9LCJsb2NhdGlvbiI6IlVTIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0IiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTc5Mzg1MTMzMzgyODI1LTAwMTciLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTc5Mzg1MTMzMzgyODI1LTAwMTciLCJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwibmFtZSI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItNzkzODUxMzMzODI4MjUtMDAxNyIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjowNTozNC4zNzVaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MDU6MzYuMzQxWiIsIm1ldGFnZW5lcmF0aW9uIjoiMiIsImFjbCI6W3sia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi03OTM4NTEzMzM4MjgyNS0wMDE3L3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItNzkzODUxMzMzODI4MjUtMDAxNy9hY2wvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi03OTM4NTEzMzM4MjgyNS0wMDE3IiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBST0ifSx7ImtpbmQiOiJzdG9yYWdlI2J1Y2tldEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItNzkzODUxMzMzODI4MjUtMDAxNy9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi03OTM4NTEzMzM4MjgyNS0wMDE3L2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi03OTM4NTEzMzM4MjgyNS0wMDE3IiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0FJPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi03OTM4NTEzMzM4MjgyNS0wMDE3L3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTc5Mzg1MTMzMzgyODI1LTAwMTcvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTc5Mzg1MTMzMzgyODI1LTAwMTciLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0FJPSJ9XSwiZGVmYXVsdE9iamVjdEFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0FJPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUk9In1dLCJpYW1Db25maWd1cmF0aW9uIjp7ImJ1Y2tldFBvbGljeU9ubHkiOnsiZW5hYmxlZCI6ZmFsc2V9fSwib3duZXIiOnsiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0In0sImxvY2F0aW9uIjoiVVMiLCJyZXRlbnRpb25Qb2xpY3kiOnsicmV0ZW50aW9uUGVyaW9kIjoiOTAwMDAiLCJlZmZlY3RpdmVUaW1lIjoiMjAxOS0wNS0wMlQyMjowNTozNC4zNzVaIiwiaXNMb2NrZWQiOnRydWV9LCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItNzkzODUxMzMzODI4MjUtMDAxOCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItNzkzODUxMzMzODI4MjUtMDAxOCIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi03OTM4NTEzMzM4MjgyNS0wMDE4IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjA1OjM3LjczM1oiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjowNTozNy43MzNaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTc5Mzg1MTMzMzgyODI1LTAwMTgvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi03OTM4NTEzMzM4MjgyNS0wMDE4L2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTc5Mzg1MTMzMzgyODI1LTAwMTgiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi03OTM4NTEzMzM4MjgyNS0wMDE4L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTc5Mzg1MTMzMzgyODI1LTAwMTgvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTc5Mzg1MTMzMzgyODI1LTAwMTgiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTc5Mzg1MTMzMzgyODI1LTAwMTgvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItNzkzODUxMzMzODI4MjUtMDAxOC9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItNzkzODUxMzMzODI4MjUtMDAxOCIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUU9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBRT0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsInJldGVudGlvblBvbGljeSI6eyJyZXRlbnRpb25QZXJpb2QiOiI5MDAwMCIsImVmZmVjdGl2ZVRpbWUiOiIyMDE5LTA1LTAyVDIyOjA1OjM3LjczM1oifSwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0IiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTc5OTExNTk1OTI0OTAzLTAwMDEiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTc5OTExNTk1OTI0OTAzLTAwMDEiLCJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwibmFtZSI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItNzk5MTE1OTU5MjQ5MDMtMDAwMSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoxMTo1Mi4zNThaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MTE6NTIuMzU4WiIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImFjbCI6W3sia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi03OTkxMTU5NTkyNDkwMy0wMDAxL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItNzk5MTE1OTU5MjQ5MDMtMDAwMS9hY2wvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi03OTkxMTU5NTkyNDkwMy0wMDAxIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI2J1Y2tldEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItNzk5MTE1OTU5MjQ5MDMtMDAwMS9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi03OTkxMTU5NTkyNDkwMy0wMDAxL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi03OTkxMTU5NTkyNDkwMy0wMDAxIiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi03OTkxMTU5NTkyNDkwMy0wMDAxL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTc5OTExNTk1OTI0OTAzLTAwMDEvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTc5OTExNTk1OTI0OTAzLTAwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0FFPSJ9XSwiZGVmYXVsdE9iamVjdEFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUU9In1dLCJpYW1Db25maWd1cmF0aW9uIjp7ImJ1Y2tldFBvbGljeU9ubHkiOnsiZW5hYmxlZCI6ZmFsc2V9fSwib3duZXIiOnsiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0In0sImxvY2F0aW9uIjoiVVMiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItNzk5Mjg3Mjc5ODIzOTMtMDAwMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItNzk5Mjg3Mjc5ODIzOTMtMDAwMSIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi03OTkyODcyNzk4MjM5My0wMDAxIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjEyOjA5LjcwNloiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoxMzo0MS42MzRaIiwibWV0YWdlbmVyYXRpb24iOiIxMyIsImFjbCI6W3sia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi03OTkyODcyNzk4MjM5My0wMDAxL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTc5OTI4NzI3OTgyMzkzLTAwMDEvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTc5OTI4NzI3OTgyMzkzLTAwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQTA9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTc5OTI4NzI3OTgyMzkzLTAwMDEvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi03OTkyODcyNzk4MjM5My0wMDAxL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTc5OTI4NzI3OTgyMzkzLTAwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0EwPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi03OTkyODcyNzk4MjM5My0wMDAxL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTc5OTI4NzI3OTgyMzkzLTAwMDEvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTc5OTI4NzI3OTgyMzkzLTAwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0EwPSJ9XSwiZGVmYXVsdE9iamVjdEFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDQTA9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0EwPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQTA9In1dLCJpYW1Db25maWd1cmF0aW9uIjp7ImJ1Y2tldFBvbGljeU9ubHkiOnsiZW5hYmxlZCI6ZmFsc2V9fSwib3duZXIiOnsiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0In0sImxvY2F0aW9uIjoiVVMiLCJ2ZXJzaW9uaW5nIjp7ImVuYWJsZWQiOmZhbHNlfSwibGlmZWN5Y2xlIjp7InJ1bGUiOlt7ImFjdGlvbiI6eyJ0eXBlIjoiRGVsZXRlIn0sImNvbmRpdGlvbiI6eyJhZ2UiOjMwfX1dfSwibGFiZWxzIjp7ImwxIjoidjIiLCJuZXciOiJuZXcifSwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJldGFnIjoiQ0EwPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0IiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTc5OTI4NzI3OTgyMzkzLTAwMTciLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTc5OTI4NzI3OTgyMzkzLTAwMTciLCJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwibmFtZSI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItNzk5Mjg3Mjc5ODIzOTMtMDAxNyIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoxNDoxNy40ODZaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MTQ6MTguOTA1WiIsIm1ldGFnZW5lcmF0aW9uIjoiMiIsImFjbCI6W3sia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi03OTkyODcyNzk4MjM5My0wMDE3L3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItNzk5Mjg3Mjc5ODIzOTMtMDAxNy9hY2wvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi03OTkyODcyNzk4MjM5My0wMDE3IiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBST0ifSx7ImtpbmQiOiJzdG9yYWdlI2J1Y2tldEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItNzk5Mjg3Mjc5ODIzOTMtMDAxNy9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi03OTkyODcyNzk4MjM5My0wMDE3L2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi03OTkyODcyNzk4MjM5My0wMDE3IiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0FJPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi03OTkyODcyNzk4MjM5My0wMDE3L3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTc5OTI4NzI3OTgyMzkzLTAwMTcvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTc5OTI4NzI3OTgyMzkzLTAwMTciLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0FJPSJ9XSwiZGVmYXVsdE9iamVjdEFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0FJPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUk9In1dLCJpYW1Db25maWd1cmF0aW9uIjp7ImJ1Y2tldFBvbGljeU9ubHkiOnsiZW5hYmxlZCI6ZmFsc2V9fSwib3duZXIiOnsiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0In0sImxvY2F0aW9uIjoiVVMiLCJyZXRlbnRpb25Qb2xpY3kiOnsicmV0ZW50aW9uUGVyaW9kIjoiOTAwMDAiLCJlZmZlY3RpdmVUaW1lIjoiMjAxOS0wNS0wMlQyMjoxNDoxNy40ODZaIiwiaXNMb2NrZWQiOnRydWV9LCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItNzk5Mjg3Mjc5ODIzOTMtMDAxOCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItNzk5Mjg3Mjc5ODIzOTMtMDAxOCIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi03OTkyODcyNzk4MjM5My0wMDE4IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjE0OjIwLjEwNVoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoxNDoyMC4xMDVaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTc5OTI4NzI3OTgyMzkzLTAwMTgvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi03OTkyODcyNzk4MjM5My0wMDE4L2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTc5OTI4NzI3OTgyMzkzLTAwMTgiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi03OTkyODcyNzk4MjM5My0wMDE4L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTc5OTI4NzI3OTgyMzkzLTAwMTgvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTc5OTI4NzI3OTgyMzkzLTAwMTgiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTc5OTI4NzI3OTgyMzkzLTAwMTgvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItNzk5Mjg3Mjc5ODIzOTMtMDAxOC9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItNzk5Mjg3Mjc5ODIzOTMtMDAxOCIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUU9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBRT0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsInJldGVudGlvblBvbGljeSI6eyJyZXRlbnRpb25QZXJpb2QiOiI5MDAwMCIsImVmZmVjdGl2ZVRpbWUiOiIyMDE5LTA1LTAyVDIyOjE0OjIwLjEwNVoifSwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0IiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwMzI2NTg5NDAzNDQ2LTAwMDEiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwMzI2NTg5NDAzNDQ2LTAwMDEiLCJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwibmFtZSI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODAzMjY1ODk0MDM0NDYtMDAwMSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoxODo0Ny4zOThaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MTg6NDcuMzk4WiIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImFjbCI6W3sia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDMyNjU4OTQwMzQ0Ni0wMDAxL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODAzMjY1ODk0MDM0NDYtMDAwMS9hY2wvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDMyNjU4OTQwMzQ0Ni0wMDAxIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI2J1Y2tldEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODAzMjY1ODk0MDM0NDYtMDAwMS9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDMyNjU4OTQwMzQ0Ni0wMDAxL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDMyNjU4OTQwMzQ0Ni0wMDAxIiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDMyNjU4OTQwMzQ0Ni0wMDAxL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwMzI2NTg5NDAzNDQ2LTAwMDEvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwMzI2NTg5NDAzNDQ2LTAwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0FFPSJ9XSwiZGVmYXVsdE9iamVjdEFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUU9In1dLCJpYW1Db25maWd1cmF0aW9uIjp7ImJ1Y2tldFBvbGljeU9ubHkiOnsiZW5hYmxlZCI6ZmFsc2V9fSwib3duZXIiOnsiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0In0sImxvY2F0aW9uIjoiVVMiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODAzMjY1ODk0MDM0NDYtMDAwMiIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODAzMjY1ODk0MDM0NDYtMDAwMiIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDMyNjU4OTQwMzQ0Ni0wMDAyIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjE4OjQ4LjExNFoiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoxODo0OC4xMTRaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwMzI2NTg5NDAzNDQ2LTAwMDIvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDMyNjU4OTQwMzQ0Ni0wMDAyL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwMzI2NTg5NDAzNDQ2LTAwMDIiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDMyNjU4OTQwMzQ0Ni0wMDAyL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwMzI2NTg5NDAzNDQ2LTAwMDIvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwMzI2NTg5NDAzNDQ2LTAwMDIiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwMzI2NTg5NDAzNDQ2LTAwMDIvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODAzMjY1ODk0MDM0NDYtMDAwMi9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODAzMjY1ODk0MDM0NDYtMDAwMiIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUU9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBRT0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsInN0b3JhZ2VDbGFzcyI6IlNUQU5EQVJEIiwiZXRhZyI6IkNBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI2J1Y2tldCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDMzMzk1NTMwMzUzOS0wMDAxIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDMzMzk1NTMwMzUzOS0wMDAxIiwicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsIm5hbWUiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwMzMzOTU1MzAzNTM5LTAwMDEiLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDUtMDJUMjI6MTg6NTQuNzAxWiIsInVwZGF0ZWQiOiIyMDE5LTA1LTAyVDIyOjE4OjU0LjcwMVoiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJhY2wiOlt7ImtpbmQiOiJzdG9yYWdlI2J1Y2tldEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODAzMzM5NTUzMDM1MzktMDAwMS9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwMzMzOTU1MzAzNTM5LTAwMDEvYWNsL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODAzMzM5NTUzMDM1MzktMDAwMSIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwMzMzOTU1MzAzNTM5LTAwMDEvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODAzMzM5NTUzMDM1MzktMDAwMS9hY2wvcHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODAzMzM5NTUzMDM1MzktMDAwMSIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI2J1Y2tldEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODAzMzM5NTUzMDM1MzktMDAwMS9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDMzMzk1NTMwMzUzOS0wMDAxL2FjbC9wcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDMzMzk1NTMwMzUzOS0wMDAxIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBRT0ifV0sImRlZmF1bHRPYmplY3RBY2wiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImVudGl0eSI6InByb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6ImVkaXRvcnMifSwiZXRhZyI6IkNBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0FFPSJ9XSwiaWFtQ29uZmlndXJhdGlvbiI6eyJidWNrZXRQb2xpY3lPbmx5Ijp7ImVuYWJsZWQiOmZhbHNlfX0sIm93bmVyIjp7ImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCJ9LCJsb2NhdGlvbiI6IlVTIiwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0IiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwMzMzOTU1MzAzNTM5LTAwMDIiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwMzMzOTU1MzAzNTM5LTAwMDIiLCJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwibmFtZSI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODAzMzM5NTUzMDM1MzktMDAwMiIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoxODo1NS4yOTNaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MTg6NTUuMjkzWiIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImFjbCI6W3sia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDMzMzk1NTMwMzUzOS0wMDAyL3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODAzMzM5NTUzMDM1MzktMDAwMi9hY2wvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDMzMzk1NTMwMzUzOS0wMDAyIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI2J1Y2tldEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODAzMzM5NTUzMDM1MzktMDAwMi9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDMzMzk1NTMwMzUzOS0wMDAyL2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDMzMzk1NTMwMzUzOS0wMDAyIiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDMzMzk1NTMwMzUzOS0wMDAyL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwMzMzOTU1MzAzNTM5LTAwMDIvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwMzMzOTU1MzAzNTM5LTAwMDIiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0FFPSJ9XSwiZGVmYXVsdE9iamVjdEFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUU9In1dLCJpYW1Db25maWd1cmF0aW9uIjp7ImJ1Y2tldFBvbGljeU9ubHkiOnsiZW5hYmxlZCI6ZmFsc2V9fSwib3duZXIiOnsiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0In0sImxvY2F0aW9uIjoiVVMiLCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA0NDU4MzA0MzA4MDgtMDAwMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA0NDU4MzA0MzA4MDgtMDAwMSIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDQ0NTgzMDQzMDgwOC0wMDAxIiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjIwOjQ2Ljg5N1oiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyMjowNy40MjlaIiwibWV0YWdlbmVyYXRpb24iOiIxMyIsImFjbCI6W3sia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDQ0NTgzMDQzMDgwOC0wMDAxL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNDQ1ODMwNDMwODA4LTAwMDEvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNDQ1ODMwNDMwODA4LTAwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQTA9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNDQ1ODMwNDMwODA4LTAwMDEvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDQ0NTgzMDQzMDgwOC0wMDAxL2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNDQ1ODMwNDMwODA4LTAwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0EwPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDQ0NTgzMDQzMDgwOC0wMDAxL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNDQ1ODMwNDMwODA4LTAwMDEvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNDQ1ODMwNDMwODA4LTAwMDEiLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0EwPSJ9XSwiZGVmYXVsdE9iamVjdEFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDQTA9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0EwPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQTA9In1dLCJpYW1Db25maWd1cmF0aW9uIjp7ImJ1Y2tldFBvbGljeU9ubHkiOnsiZW5hYmxlZCI6ZmFsc2V9fSwib3duZXIiOnsiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0In0sImxvY2F0aW9uIjoiVVMiLCJ2ZXJzaW9uaW5nIjp7ImVuYWJsZWQiOmZhbHNlfSwibGlmZWN5Y2xlIjp7InJ1bGUiOlt7ImFjdGlvbiI6eyJ0eXBlIjoiRGVsZXRlIn0sImNvbmRpdGlvbiI6eyJhZ2UiOjMwfX1dfSwibGFiZWxzIjp7Im5ldyI6Im5ldyIsImwxIjoidjIifSwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJldGFnIjoiQ0EwPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0IiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNDQ1ODMwNDMwODA4LTAwMTciLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNDQ1ODMwNDMwODA4LTAwMTciLCJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwibmFtZSI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA0NDU4MzA0MzA4MDgtMDAxNyIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyMjo1MC40MjhaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjI6NTEuOTM1WiIsIm1ldGFnZW5lcmF0aW9uIjoiMiIsImFjbCI6W3sia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDQ0NTgzMDQzMDgwOC0wMDE3L3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA0NDU4MzA0MzA4MDgtMDAxNy9hY2wvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDQ0NTgzMDQzMDgwOC0wMDE3IiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBST0ifSx7ImtpbmQiOiJzdG9yYWdlI2J1Y2tldEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA0NDU4MzA0MzA4MDgtMDAxNy9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDQ0NTgzMDQzMDgwOC0wMDE3L2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDQ0NTgzMDQzMDgwOC0wMDE3IiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0FJPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDQ0NTgzMDQzMDgwOC0wMDE3L3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNDQ1ODMwNDMwODA4LTAwMTcvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNDQ1ODMwNDMwODA4LTAwMTciLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0FJPSJ9XSwiZGVmYXVsdE9iamVjdEFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0FJPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUk9In1dLCJpYW1Db25maWd1cmF0aW9uIjp7ImJ1Y2tldFBvbGljeU9ubHkiOnsiZW5hYmxlZCI6ZmFsc2V9fSwib3duZXIiOnsiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0In0sImxvY2F0aW9uIjoiVVMiLCJyZXRlbnRpb25Qb2xpY3kiOnsicmV0ZW50aW9uUGVyaW9kIjoiOTAwMDAiLCJlZmZlY3RpdmVUaW1lIjoiMjAxOS0wNS0wMlQyMjoyMjo1MC40MjhaIiwiaXNMb2NrZWQiOnRydWV9LCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA0NDU4MzA0MzA4MDgtMDAxOCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA0NDU4MzA0MzA4MDgtMDAxOCIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDQ0NTgzMDQzMDgwOC0wMDE4IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjIyOjUyLjk2MloiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyMjo1Mi45NjJaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNDQ1ODMwNDMwODA4LTAwMTgvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDQ0NTgzMDQzMDgwOC0wMDE4L2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNDQ1ODMwNDMwODA4LTAwMTgiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDQ0NTgzMDQzMDgwOC0wMDE4L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNDQ1ODMwNDMwODA4LTAwMTgvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNDQ1ODMwNDMwODA4LTAwMTgiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNDQ1ODMwNDMwODA4LTAwMTgvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA0NDU4MzA0MzA4MDgtMDAxOC9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA0NDU4MzA0MzA4MDgtMDAxOCIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUU9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBRT0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsInJldGVudGlvblBvbGljeSI6eyJyZXRlbnRpb25QZXJpb2QiOiI5MDAwMCIsImVmZmVjdGl2ZVRpbWUiOiIyMDE5LTA1LTAyVDIyOjIyOjUyLjk2MloifSwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0IiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTciLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTciLCJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwibmFtZSI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNyIsInRpbWVDcmVhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNjowMS45MDhaIiwidXBkYXRlZCI6IjIwMTktMDUtMDJUMjI6MjY6MDMuNTQ0WiIsIm1ldGFnZW5lcmF0aW9uIjoiMiIsImFjbCI6W3sia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE3L3Byb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNy9hY2wvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE3IiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBST0ifSx7ImtpbmQiOiJzdG9yYWdlI2J1Y2tldEFjY2Vzc0NvbnRyb2wiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxNy9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE3L2FjbC9wcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0IiwiYnVja2V0IjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE3IiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0FJPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE3L3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTcvYWNsL3Byb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTciLCJlbnRpdHkiOiJwcm9qZWN0LXZpZXdlcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6IlJFQURFUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoidmlld2VycyJ9LCJldGFnIjoiQ0FJPSJ9XSwiZGVmYXVsdE9iamVjdEFjbCI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImVudGl0eSI6InByb2plY3Qtb3duZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoib3duZXJzIn0sImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1lZGl0b3JzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJPV05FUiIsInByb2plY3RUZWFtIjp7InByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJ0ZWFtIjoiZWRpdG9ycyJ9LCJldGFnIjoiQ0FJPSJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0QWNjZXNzQ29udHJvbCIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUk9In1dLCJpYW1Db25maWd1cmF0aW9uIjp7ImJ1Y2tldFBvbGljeU9ubHkiOnsiZW5hYmxlZCI6ZmFsc2V9fSwib3duZXIiOnsiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0In0sImxvY2F0aW9uIjoiVVMiLCJyZXRlbnRpb25Qb2xpY3kiOnsicmV0ZW50aW9uUGVyaW9kIjoiOTAwMDAiLCJlZmZlY3RpdmVUaW1lIjoiMjAxOS0wNS0wMlQyMjoyNjowMS45MDhaIiwiaXNMb2NrZWQiOnRydWV9LCJzdG9yYWdlQ2xhc3MiOiJTVEFOREFSRCIsImV0YWciOiJDQUk9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXQiLCJpZCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOCIsInByb2plY3ROdW1iZXIiOiI0OTYxNjk2MDE3MTQiLCJuYW1lIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE4IiwidGltZUNyZWF0ZWQiOiIyMDE5LTA1LTAyVDIyOjI2OjE1LjA5N1oiLCJ1cGRhdGVkIjoiMjAxOS0wNS0wMlQyMjoyNjoxNS4wOTdaIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiYWNsIjpbeyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTgvcHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE4L2FjbC9wcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTgiLCJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiT1dORVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6Im93bmVycyJ9LCJldGFnIjoiQ0FFPSJ9LHsia2luZCI6InN0b3JhZ2UjYnVja2V0QWNjZXNzQ29udHJvbCIsImlkIjoiZ28taW50ZWdyYXRpb24tdGVzdC0yMDE5MDUwMi04MDYzMzQwMzQzMjAxMy0wMDE4L3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTgvYWNsL3Byb2plY3QtZWRpdG9ycy00OTYxNjk2MDE3MTQiLCJidWNrZXQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTgiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNidWNrZXRBY2Nlc3NDb250cm9sIiwiaWQiOiJnby1pbnRlZ3JhdGlvbi10ZXN0LTIwMTkwNTAyLTgwNjMzNDAzNDMyMDEzLTAwMTgvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOC9hY2wvcHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsImJ1Y2tldCI6ImdvLWludGVncmF0aW9uLXRlc3QtMjAxOTA1MDItODA2MzM0MDM0MzIwMTMtMDAxOCIsImVudGl0eSI6InByb2plY3Qtdmlld2Vycy00OTYxNjk2MDE3MTQiLCJyb2xlIjoiUkVBREVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJ2aWV3ZXJzIn0sImV0YWciOiJDQUU9In1dLCJkZWZhdWx0T2JqZWN0QWNsIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC1vd25lcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJvd25lcnMifSwiZXRhZyI6IkNBRT0ifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdEFjY2Vzc0NvbnRyb2wiLCJlbnRpdHkiOiJwcm9qZWN0LWVkaXRvcnMtNDk2MTY5NjAxNzE0Iiwicm9sZSI6Ik9XTkVSIiwicHJvamVjdFRlYW0iOnsicHJvamVjdE51bWJlciI6IjQ5NjE2OTYwMTcxNCIsInRlYW0iOiJlZGl0b3JzIn0sImV0YWciOiJDQUU9In0seyJraW5kIjoic3RvcmFnZSNvYmplY3RBY2Nlc3NDb250cm9sIiwiZW50aXR5IjoicHJvamVjdC12aWV3ZXJzLTQ5NjE2OTYwMTcxNCIsInJvbGUiOiJSRUFERVIiLCJwcm9qZWN0VGVhbSI6eyJwcm9qZWN0TnVtYmVyIjoiNDk2MTY5NjAxNzE0IiwidGVhbSI6InZpZXdlcnMifSwiZXRhZyI6IkNBRT0ifV0sImlhbUNvbmZpZ3VyYXRpb24iOnsiYnVja2V0UG9saWN5T25seSI6eyJlbmFibGVkIjpmYWxzZX19LCJvd25lciI6eyJlbnRpdHkiOiJwcm9qZWN0LW93bmVycy00OTYxNjk2MDE3MTQifSwibG9jYXRpb24iOiJVUyIsInJldGVudGlvblBvbGljeSI6eyJyZXRlbnRpb25QZXJpb2QiOiI5MDAwMCIsImVmZmVjdGl2ZVRpbWUiOiIyMDE5LTA1LTAyVDIyOjI2OjE1LjA5N1oifSwic3RvcmFnZUNsYXNzIjoiU1RBTkRBUkQiLCJldGFnIjoiQ0FFPSJ9XX0=" } } ] }google-cloud-go-0.49.0/storage/storage_test.go000066400000000000000000001052431356504100700212730ustar00rootroot00000000000000// Copyright 2014 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package storage import ( "context" "crypto/tls" "encoding/json" "fmt" "io" "io/ioutil" "log" "net" "net/http" "net/http/httptest" "net/url" "reflect" "regexp" "sort" "strings" "testing" "time" "cloud.google.com/go/iam" "cloud.google.com/go/internal/testutil" "google.golang.org/api/iterator" "google.golang.org/api/option" raw "google.golang.org/api/storage/v1" ) func TestV2HeaderSanitization(t *testing.T) { t.Parallel() var tests = []struct { desc string in []string want []string }{ { desc: "already sanitized headers should not be modified", in: []string{"x-goog-header1:true", "x-goog-header2:0"}, want: []string{"x-goog-header1:true", "x-goog-header2:0"}, }, { desc: "sanitized headers should be sorted", in: []string{"x-goog-header2:0", "x-goog-header1:true"}, want: []string{"x-goog-header1:true", "x-goog-header2:0"}, }, { desc: "non-canonical headers should be removed", in: []string{"x-goog-header1:true", "x-goog-no-value", "non-canonical-header:not-of-use"}, want: []string{"x-goog-header1:true"}, }, { desc: "excluded canonical headers should be removed", in: []string{"x-goog-header1:true", "x-goog-encryption-key:my_key", "x-goog-encryption-key-sha256:my_sha256"}, want: []string{"x-goog-header1:true"}, }, { desc: "dirty headers should be formatted correctly", in: []string{" x-goog-header1 : \textra-spaces ", "X-Goog-Header2:CamelCaseValue"}, want: []string{"x-goog-header1:extra-spaces", "x-goog-header2:CamelCaseValue"}, }, { desc: "duplicate headers should be merged", in: []string{"x-goog-header1:value1", "X-Goog-Header1:value2"}, want: []string{"x-goog-header1:value1,value2"}, }, } for _, test := range tests { got := v2SanitizeHeaders(test.in) if !testutil.Equal(got, test.want) { t.Errorf("%s: got %v, want %v", test.desc, got, test.want) } } } func TestV4HeaderSanitization(t *testing.T) { t.Parallel() var tests = []struct { desc string in []string want []string }{ { desc: "already sanitized headers should not be modified", in: []string{"x-goog-header1:true", "x-goog-header2:0"}, want: []string{"x-goog-header1:true", "x-goog-header2:0"}, }, { desc: "dirty headers should be formatted correctly", in: []string{" x-goog-header1 : \textra-spaces ", "X-Goog-Header2:CamelCaseValue"}, want: []string{"x-goog-header1:extra-spaces", "x-goog-header2:CamelCaseValue"}, }, { desc: "duplicate headers should be merged", in: []string{"x-goog-header1:value1", "X-Goog-Header1:value2"}, want: []string{"x-goog-header1:value1,value2"}, }, { desc: "multiple spaces in value are stripped down to one", in: []string{"foo:bar gaz"}, want: []string{"foo:bar gaz"}, }, } for _, test := range tests { got := v4SanitizeHeaders(test.in) sort.Strings(got) sort.Strings(test.want) if !testutil.Equal(got, test.want) { t.Errorf("%s: got %v, want %v", test.desc, got, test.want) } } } func TestSignedURLV2(t *testing.T) { expires, _ := time.Parse(time.RFC3339, "2002-10-02T10:00:00-05:00") tests := []struct { desc string objectName string opts *SignedURLOptions want string }{ { desc: "SignedURLV2 works", objectName: "object-name", opts: &SignedURLOptions{ GoogleAccessID: "xxx@clientid", PrivateKey: dummyKey("rsa"), Method: "GET", MD5: "ICy5YqxZB1uWSwcVLSNLcA==", Expires: expires, ContentType: "application/json", Headers: []string{"x-goog-header1:true", "x-goog-header2:false"}, }, want: "https://storage.googleapis.com/bucket-name/object-name?" + "Expires=1033570800&GoogleAccessId=xxx%40clientid&Signature=" + "RfsHlPtbB2JUYjzCgNr2Mi%2BjggdEuL1V7E6N9o6aaqwVLBDuTv3I0%2B9" + "x94E6rmmr%2FVgnmZigkIUxX%2Blfl7LgKf30uPGLt0mjKGH2p7r9ey1ONJ" + "%2BhVec23FnTRcSgopglvHPuCMWU2oNJE%2F1y8EwWE27baHrG1RhRHbLVF" + "bPpLZ9xTRFK20pluIkfHV00JGljB1imqQHXM%2B2XPWqBngLr%2FwqxLN7i" + "FcUiqR8xQEOHF%2F2e7fbkTHPNq4TazaLZ8X0eZ3eFdJ55A5QmNi8atlN4W" + "5q7Hvs0jcxElG3yqIbx439A995BkspLiAcA%2Fo4%2BxAwEMkGLICdbvakq" + "3eEprNCojw%3D%3D", }, { desc: "With a PEM Private Key", objectName: "object-name", opts: &SignedURLOptions{ GoogleAccessID: "xxx@clientid", PrivateKey: dummyKey("pem"), Method: "GET", MD5: "ICy5YqxZB1uWSwcVLSNLcA==", Expires: expires, ContentType: "application/json", Headers: []string{"x-goog-header1:true", "x-goog-header2:false"}, }, want: "https://storage.googleapis.com/bucket-name/object-name?" + "Expires=1033570800&GoogleAccessId=xxx%40clientid&Signature=" + "TiyKD%2FgGb6Kh0kkb2iF%2FfF%2BnTx7L0J4YiZua8AcTmnidutePEGIU5" + "NULYlrGl6l52gz4zqFb3VFfIRTcPXMdXnnFdMCDhz2QuJBUpsU1Ai9zlyTQ" + "dkb6ShG03xz9%2BEXWAUQO4GBybJw%2FULASuv37xA00SwLdkqj8YdyS5II" + "1lro%3D", }, { desc: "With custom SignBytes", objectName: "object-name", opts: &SignedURLOptions{ GoogleAccessID: "xxx@clientid", SignBytes: func(b []byte) ([]byte, error) { return []byte("signed"), nil }, Method: "GET", MD5: "ICy5YqxZB1uWSwcVLSNLcA==", Expires: expires, ContentType: "application/json", Headers: []string{"x-goog-header1:true", "x-goog-header2:false"}, }, want: "https://storage.googleapis.com/bucket-name/object-name?" + "Expires=1033570800&GoogleAccessId=xxx%40clientid&Signature=" + "c2lnbmVk", // base64('signed') == 'c2lnbmVk' }, { desc: "With unsafe object name", objectName: "object name界", opts: &SignedURLOptions{ GoogleAccessID: "xxx@clientid", PrivateKey: dummyKey("pem"), Method: "GET", MD5: "ICy5YqxZB1uWSwcVLSNLcA==", Expires: expires, ContentType: "application/json", Headers: []string{"x-goog-header1:true", "x-goog-header2:false"}, }, want: "https://storage.googleapis.com/bucket-name/object%20name%E7%95%8C?" + "Expires=1033570800&GoogleAccessId=xxx%40clientid&Signature=bxVH1%2Bl%2" + "BSxpnj3XuqKz6mOFk6M94Y%2B4w85J6FCmJan%2FNhGSpndP6fAw1uLHlOn%2F8xUaY%2F" + "SfZ5GzcQ%2BbxOL1WA37yIwZ7xgLYlO%2ByAi3GuqMUmHZiNCai28emODXQ8RtWHvgv6dE" + "SQ%2F0KpDMIWW7rYCaUa63UkUyeSQsKhrVqkIA%3D", }, } for _, test := range tests { u, err := SignedURL("bucket-name", test.objectName, test.opts) if err != nil { t.Fatalf("[%s] %v", test.desc, err) } if u != test.want { t.Fatalf("[%s] Unexpected signed URL; found %v", test.desc, u) } } } func TestSignedURLV4(t *testing.T) { expires, _ := time.Parse(time.RFC3339, "2002-10-02T10:00:00-05:00") tests := []struct { desc string objectName string now time.Time opts *SignedURLOptions // Note for future implementors: X-Goog-Signature generated by having // the client run through its algorithm with pre-defined input and copy // pasting the output. These tests are not great for testing whether // the right signature is calculated - instead we rely on the backend // and integration tests for that. want string }{ { desc: "SignURLV4 works", objectName: "object-name", now: expires.Add(-24 * time.Hour), opts: &SignedURLOptions{ GoogleAccessID: "xxx@clientid", PrivateKey: dummyKey("rsa"), Method: "POST", Expires: expires, Scheme: SigningSchemeV4, ContentType: "application/json", MD5: "ICy5YqxZB1uWSwcVLSNLcA==", Headers: []string{"x-goog-header1:true", "x-goog-header2:false"}, }, want: "https://storage.googleapis.com/bucket-name/object-name" + "?X-Goog-Algorithm=GOOG4-RSA-SHA256" + "&X-Goog-Credential=xxx%40clientid%2F20021001%2Fauto%2Fstorage%2Fgoog4_request" + "&X-Goog-Date=20021001T100000Z&X-Goog-Expires=86400" + "&X-Goog-Signature=774b11d89663d0562b0909131b8495e70d24e31f3417d3f8fd1438a72b620b256111a7221fecab14a6ebb7dc7eed7984316a794789beb4ecdda67a77407f6de1a68113e8fa2b885e330036a995c08f0f2a7d2c212a3d0a2fd1b392d40305d3fe31ab94c547a7541278f4a956ebb6565ebe4cb27f26e30b334adb7b065adc0d27f9eaa42ee76d75d673fc4523d023d9a636de0b5329f5dffbf80024cf21fdc6236e89aa41976572bfe4807be9a9a01f644ed9f546dcf1e0394665be7610f58c36b3d63379f4d1b64f646f7427f1fc55bb89d7fdd59017d007156c99e26440e828581cddf83faf03e739e5987c062d503f2b73f24049c25edc60ecbbc09f6ce945" + "&X-Goog-SignedHeaders=content-md5%3Bcontent-type%3Bhost%3Bx-goog-header1%3Bx-goog-header2", }, { desc: "With PEM Private Key", objectName: "object-name", now: expires.Add(-24 * time.Hour), opts: &SignedURLOptions{ GoogleAccessID: "xxx@clientid", PrivateKey: dummyKey("pem"), Method: "GET", Expires: expires, Scheme: SigningSchemeV4, }, want: "https://storage.googleapis.com/bucket-name/object-name" + "?X-Goog-Algorithm=GOOG4-RSA-SHA256" + "&X-Goog-Credential=xxx%40clientid%2F20021001%2Fauto%2Fstorage%2Fgoog4_request" + "&X-Goog-Date=20021001T100000Z&X-Goog-Expires=86400" + "&X-Goog-Signature=5592f4b8b2cae14025b619546d69bb463ca8f2caaab538a3cc6b5868c8c64b83a8b04b57d8a82c8696a192f62abddc8d99e0454b3fc33feac5bf87c353f0703aab6cfee60364aaeecec2edd37c1d6e6793d90812b5811b7936a014a3efad5d08477b4fbfaebf04fa61f1ca03f31bcdc46a161868cd2f4e98def6c82634a01454" + "&X-Goog-SignedHeaders=host", }, { desc: "Unsafe object name", objectName: "object name界", now: expires.Add(-24 * time.Hour), opts: &SignedURLOptions{ GoogleAccessID: "xxx@clientid", PrivateKey: dummyKey("pem"), Method: "GET", Expires: expires, Scheme: SigningSchemeV4, }, want: "https://storage.googleapis.com/bucket-name/object%20name%E7%95%8C" + "?X-Goog-Algorithm=GOOG4-RSA-SHA256" + "&X-Goog-Credential=xxx%40clientid%2F20021001%2Fauto%2Fstorage%2Fgoog4_request" + "&X-Goog-Date=20021001T100000Z&X-Goog-Expires=86400" + "&X-Goog-Signature=90fd455fb47725b45c08d65ddf99078184710ad30f09bc2a190c5416ba1596e4c58420e2e48744b03de2d1b85dc8679dcb4c36af6e7a1b2547cd62becaad72aebbbaf7c1686f1aa0fedf8a9b01cef20a8b8630d824a6f8b81bb9eb75f342a7d8a28457a4efd2baac93e37089b84b1506b2af72712187f638e0eafbac650b071a" + "&X-Goog-SignedHeaders=host", }, { desc: "With custom SignBytes", objectName: "object-name", now: expires.Add(-24 * time.Hour), opts: &SignedURLOptions{ GoogleAccessID: "xxx@clientid", SignBytes: func(b []byte) ([]byte, error) { return []byte("signed"), nil }, Method: "GET", Expires: expires, Scheme: SigningSchemeV4, }, want: "https://storage.googleapis.com/bucket-name/object-name" + "?X-Goog-Algorithm=GOOG4-RSA-SHA256" + "&X-Goog-Credential=xxx%40clientid%2F20021001%2Fauto%2Fstorage%2Fgoog4_request" + "&X-Goog-Date=20021001T100000Z&X-Goog-Expires=86400" + "&X-Goog-Signature=7369676e6564" + // hex('signed') = '7369676e6564' "&X-Goog-SignedHeaders=host", }, } oldUTCNow := utcNow defer func() { utcNow = oldUTCNow }() for _, test := range tests { t.Logf("Testcase: '%s'", test.desc) utcNow = func() time.Time { return test.now } got, err := SignedURL("bucket-name", test.objectName, test.opts) if err != nil { t.Fatal(err) } if got != test.want { t.Fatalf("\n\tgot:\t%v\n\twant:\t%v", got, test.want) } } } func TestSignedURL_MissingOptions(t *testing.T) { now, _ := time.Parse(time.RFC3339, "2002-10-01T00:00:00-05:00") expires, _ := time.Parse(time.RFC3339, "2002-10-15T00:00:00-05:00") pk := dummyKey("rsa") var tests = []struct { opts *SignedURLOptions errMsg string }{ { &SignedURLOptions{}, "missing required GoogleAccessID", }, { &SignedURLOptions{GoogleAccessID: "access_id"}, "exactly one of PrivateKey or SignedBytes must be set", }, { &SignedURLOptions{ GoogleAccessID: "access_id", SignBytes: func(b []byte) ([]byte, error) { return b, nil }, PrivateKey: pk, }, "exactly one of PrivateKey or SignedBytes must be set", }, { &SignedURLOptions{ GoogleAccessID: "access_id", PrivateKey: pk, }, "missing required method", }, { &SignedURLOptions{ GoogleAccessID: "access_id", SignBytes: func(b []byte) ([]byte, error) { return b, nil }, }, "missing required method", }, { &SignedURLOptions{ GoogleAccessID: "access_id", PrivateKey: pk, Method: "PUT", }, "missing required expires", }, { &SignedURLOptions{ GoogleAccessID: "access_id", PrivateKey: pk, Method: "PUT", Expires: expires, MD5: "invalid", }, "invalid MD5 checksum", }, // SigningSchemeV4 tests { &SignedURLOptions{ PrivateKey: pk, Method: "GET", Expires: expires, Scheme: SigningSchemeV4, }, "missing required GoogleAccessID", }, { &SignedURLOptions{ GoogleAccessID: "access_id", Method: "GET", Expires: expires, SignBytes: func(b []byte) ([]byte, error) { return b, nil }, PrivateKey: pk, Scheme: SigningSchemeV4, }, "exactly one of PrivateKey or SignedBytes must be set", }, { &SignedURLOptions{ GoogleAccessID: "access_id", PrivateKey: pk, Expires: expires, Scheme: SigningSchemeV4, }, "missing required method", }, { &SignedURLOptions{ GoogleAccessID: "access_id", PrivateKey: pk, Method: "PUT", Scheme: SigningSchemeV4, }, "missing required expires", }, { &SignedURLOptions{ GoogleAccessID: "access_id", PrivateKey: pk, Method: "PUT", Expires: now.Add(time.Hour), MD5: "invalid", Scheme: SigningSchemeV4, }, "invalid MD5 checksum", }, { &SignedURLOptions{ GoogleAccessID: "access_id", PrivateKey: pk, Method: "GET", Expires: expires, Scheme: SigningSchemeV4, }, "expires must be within seven days from now", }, } oldUTCNow := utcNow defer func() { utcNow = oldUTCNow }() utcNow = func() time.Time { return now } for _, test := range tests { _, err := SignedURL("bucket", "name", test.opts) if !strings.Contains(err.Error(), test.errMsg) { t.Errorf("expected err: %v, found: %v", test.errMsg, err) } } } func dummyKey(kind string) []byte { slurp, err := ioutil.ReadFile(fmt.Sprintf("./internal/test/dummy_%s", kind)) if err != nil { log.Fatal(err) } return slurp } func TestObjectNames(t *testing.T) { t.Parallel() // Naming requirements: https://cloud.google.com/storage/docs/bucket-naming const maxLegalLength = 1024 type testT struct { name, want string } tests := []testT{ // Embedded characters important in URLs. {"foo % bar", "foo%20%25%20bar"}, {"foo ? bar", "foo%20%3F%20bar"}, {"foo / bar", "foo%20/%20bar"}, {"foo %?/ bar", "foo%20%25%3F/%20bar"}, // Non-Roman scripts {"타코", "%ED%83%80%EC%BD%94"}, {"世界", "%E4%B8%96%E7%95%8C"}, // Longest legal name {strings.Repeat("a", maxLegalLength), strings.Repeat("a", maxLegalLength)}, // Line terminators besides CR and LF: https://en.wikipedia.org/wiki/Newline#Unicode {"foo \u000b bar", "foo%20%0B%20bar"}, {"foo \u000c bar", "foo%20%0C%20bar"}, {"foo \u0085 bar", "foo%20%C2%85%20bar"}, {"foo \u2028 bar", "foo%20%E2%80%A8%20bar"}, {"foo \u2029 bar", "foo%20%E2%80%A9%20bar"}, // Null byte. {"foo \u0000 bar", "foo%20%00%20bar"}, // Non-control characters that are discouraged, but not forbidden, according to the documentation. {"foo # bar", "foo%20%23%20bar"}, {"foo []*? bar", "foo%20%5B%5D%2A%3F%20bar"}, // Angstrom symbol singleton and normalized forms: http://unicode.org/reports/tr15/ {"foo \u212b bar", "foo%20%E2%84%AB%20bar"}, {"foo \u0041\u030a bar", "foo%20A%CC%8A%20bar"}, {"foo \u00c5 bar", "foo%20%C3%85%20bar"}, // Hangul separating jamo: http://www.unicode.org/versions/Unicode7.0.0/ch18.pdf (Table 18-10) {"foo \u3131\u314f bar", "foo%20%E3%84%B1%E3%85%8F%20bar"}, {"foo \u1100\u1161 bar", "foo%20%E1%84%80%E1%85%A1%20bar"}, {"foo \uac00 bar", "foo%20%EA%B0%80%20bar"}, } // C0 control characters not forbidden by the docs. var runes []rune for r := rune(0x01); r <= rune(0x1f); r++ { if r != '\u000a' && r != '\u000d' { runes = append(runes, r) } } tests = append(tests, testT{fmt.Sprintf("foo %s bar", string(runes)), "foo%20%01%02%03%04%05%06%07%08%09%0B%0C%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%20bar"}) // C1 control characters, plus DEL. runes = nil for r := rune(0x7f); r <= rune(0x9f); r++ { runes = append(runes, r) } tests = append(tests, testT{fmt.Sprintf("foo %s bar", string(runes)), "foo%20%7F%C2%80%C2%81%C2%82%C2%83%C2%84%C2%85%C2%86%C2%87%C2%88%C2%89%C2%8A%C2%8B%C2%8C%C2%8D%C2%8E%C2%8F%C2%90%C2%91%C2%92%C2%93%C2%94%C2%95%C2%96%C2%97%C2%98%C2%99%C2%9A%C2%9B%C2%9C%C2%9D%C2%9E%C2%9F%20bar"}) opts := &SignedURLOptions{ GoogleAccessID: "xxx@clientid", PrivateKey: dummyKey("rsa"), Method: "GET", MD5: "ICy5YqxZB1uWSwcVLSNLcA==", Expires: time.Date(2002, time.October, 2, 10, 0, 0, 0, time.UTC), ContentType: "application/json", Headers: []string{"x-goog-header1", "x-goog-header2"}, } for _, test := range tests { g, err := SignedURL("bucket-name", test.name, opts) if err != nil { t.Errorf("SignedURL(%q) err=%v, want nil", test.name, err) } if w := "/bucket-name/" + test.want; !strings.Contains(g, w) { t.Errorf("SignedURL(%q)=%q, want substring %q", test.name, g, w) } } } func TestCondition(t *testing.T) { t.Parallel() gotReq := make(chan *http.Request, 1) hc, close := newTestServer(func(w http.ResponseWriter, r *http.Request) { io.Copy(ioutil.Discard, r.Body) gotReq <- r w.WriteHeader(200) }) defer close() ctx := context.Background() c, err := NewClient(ctx, option.WithHTTPClient(hc)) if err != nil { t.Fatal(err) } obj := c.Bucket("buck").Object("obj") dst := c.Bucket("dstbuck").Object("dst") tests := []struct { fn func() error want string }{ { func() error { _, err := obj.Generation(1234).NewReader(ctx) return err }, "GET /buck/obj?generation=1234", }, { func() error { _, err := obj.If(Conditions{GenerationMatch: 1234}).NewReader(ctx) return err }, "GET /buck/obj?ifGenerationMatch=1234", }, { func() error { _, err := obj.If(Conditions{GenerationNotMatch: 1234}).NewReader(ctx) return err }, "GET /buck/obj?ifGenerationNotMatch=1234", }, { func() error { _, err := obj.If(Conditions{MetagenerationMatch: 1234}).NewReader(ctx) return err }, "GET /buck/obj?ifMetagenerationMatch=1234", }, { func() error { _, err := obj.If(Conditions{MetagenerationNotMatch: 1234}).NewReader(ctx) return err }, "GET /buck/obj?ifMetagenerationNotMatch=1234", }, { func() error { _, err := obj.If(Conditions{MetagenerationNotMatch: 1234}).Attrs(ctx) return err }, "GET /storage/v1/b/buck/o/obj?alt=json&ifMetagenerationNotMatch=1234&prettyPrint=false&projection=full", }, { func() error { _, err := obj.If(Conditions{MetagenerationMatch: 1234}).Update(ctx, ObjectAttrsToUpdate{}) return err }, "PATCH /storage/v1/b/buck/o/obj?alt=json&ifMetagenerationMatch=1234&prettyPrint=false&projection=full", }, { func() error { return obj.Generation(1234).Delete(ctx) }, "DELETE /storage/v1/b/buck/o/obj?alt=json&generation=1234&prettyPrint=false", }, { func() error { w := obj.If(Conditions{GenerationMatch: 1234}).NewWriter(ctx) w.ContentType = "text/plain" return w.Close() }, "POST /upload/storage/v1/b/buck/o?alt=json&ifGenerationMatch=1234&prettyPrint=false&projection=full&uploadType=multipart", }, { func() error { w := obj.If(Conditions{DoesNotExist: true}).NewWriter(ctx) w.ContentType = "text/plain" return w.Close() }, "POST /upload/storage/v1/b/buck/o?alt=json&ifGenerationMatch=0&prettyPrint=false&projection=full&uploadType=multipart", }, { func() error { _, err := dst.If(Conditions{MetagenerationMatch: 5678}).CopierFrom(obj.If(Conditions{GenerationMatch: 1234})).Run(ctx) return err }, "POST /storage/v1/b/buck/o/obj/rewriteTo/b/dstbuck/o/dst?alt=json&ifMetagenerationMatch=5678&ifSourceGenerationMatch=1234&prettyPrint=false&projection=full", }, } for i, tt := range tests { if err := tt.fn(); err != nil && err != io.EOF { t.Error(err) continue } select { case r := <-gotReq: got := r.Method + " " + r.RequestURI if got != tt.want { t.Errorf("%d. RequestURI = %q; want %q", i, got, tt.want) } case <-time.After(5 * time.Second): t.Fatalf("%d. timeout", i) } if err != nil { t.Fatal(err) } } // Test an error, too: err = obj.Generation(1234).NewWriter(ctx).Close() if err == nil || !strings.Contains(err.Error(), "NewWriter: generation not supported") { t.Errorf("want error about unsupported generation; got %v", err) } } func TestConditionErrors(t *testing.T) { t.Parallel() for _, conds := range []Conditions{ {GenerationMatch: 0}, {DoesNotExist: false}, // same as above, actually {GenerationMatch: 1, GenerationNotMatch: 2}, {GenerationNotMatch: 2, DoesNotExist: true}, {MetagenerationMatch: 1, MetagenerationNotMatch: 2}, } { if err := conds.validate(""); err == nil { t.Errorf("%+v: got nil, want error", conds) } } } // Test object compose. func TestObjectCompose(t *testing.T) { t.Parallel() gotURL := make(chan string, 1) gotBody := make(chan []byte, 1) hc, close := newTestServer(func(w http.ResponseWriter, r *http.Request) { body, _ := ioutil.ReadAll(r.Body) gotURL <- r.URL.String() gotBody <- body w.Write([]byte("{}")) }) defer close() ctx := context.Background() c, err := NewClient(ctx, option.WithHTTPClient(hc)) if err != nil { t.Fatal(err) } testCases := []struct { desc string dst *ObjectHandle srcs []*ObjectHandle attrs *ObjectAttrs wantReq raw.ComposeRequest wantURL string wantErr bool }{ { desc: "basic case", dst: c.Bucket("foo").Object("bar"), srcs: []*ObjectHandle{ c.Bucket("foo").Object("baz"), c.Bucket("foo").Object("quux"), }, wantURL: "/storage/v1/b/foo/o/bar/compose?alt=json&prettyPrint=false", wantReq: raw.ComposeRequest{ Destination: &raw.Object{Bucket: "foo"}, SourceObjects: []*raw.ComposeRequestSourceObjects{ {Name: "baz"}, {Name: "quux"}, }, }, }, { desc: "with object attrs", dst: c.Bucket("foo").Object("bar"), srcs: []*ObjectHandle{ c.Bucket("foo").Object("baz"), c.Bucket("foo").Object("quux"), }, attrs: &ObjectAttrs{ Name: "not-bar", ContentType: "application/json", }, wantURL: "/storage/v1/b/foo/o/bar/compose?alt=json&prettyPrint=false", wantReq: raw.ComposeRequest{ Destination: &raw.Object{ Bucket: "foo", Name: "not-bar", ContentType: "application/json", }, SourceObjects: []*raw.ComposeRequestSourceObjects{ {Name: "baz"}, {Name: "quux"}, }, }, }, { desc: "with conditions", dst: c.Bucket("foo").Object("bar").If(Conditions{ GenerationMatch: 12, MetagenerationMatch: 34, }), srcs: []*ObjectHandle{ c.Bucket("foo").Object("baz").Generation(56), c.Bucket("foo").Object("quux").If(Conditions{GenerationMatch: 78}), }, wantURL: "/storage/v1/b/foo/o/bar/compose?alt=json&ifGenerationMatch=12&ifMetagenerationMatch=34&prettyPrint=false", wantReq: raw.ComposeRequest{ Destination: &raw.Object{Bucket: "foo"}, SourceObjects: []*raw.ComposeRequestSourceObjects{ { Name: "baz", Generation: 56, }, { Name: "quux", ObjectPreconditions: &raw.ComposeRequestSourceObjectsObjectPreconditions{ IfGenerationMatch: 78, }, }, }, }, }, { desc: "no sources", dst: c.Bucket("foo").Object("bar"), wantErr: true, }, { desc: "destination, no bucket", dst: c.Bucket("").Object("bar"), srcs: []*ObjectHandle{ c.Bucket("foo").Object("baz"), }, wantErr: true, }, { desc: "destination, no object", dst: c.Bucket("foo").Object(""), srcs: []*ObjectHandle{ c.Bucket("foo").Object("baz"), }, wantErr: true, }, { desc: "source, different bucket", dst: c.Bucket("foo").Object("bar"), srcs: []*ObjectHandle{ c.Bucket("otherbucket").Object("baz"), }, wantErr: true, }, { desc: "source, no object", dst: c.Bucket("foo").Object("bar"), srcs: []*ObjectHandle{ c.Bucket("foo").Object(""), }, wantErr: true, }, { desc: "destination, bad condition", dst: c.Bucket("foo").Object("bar").Generation(12), srcs: []*ObjectHandle{ c.Bucket("foo").Object("baz"), }, wantErr: true, }, { desc: "source, bad condition", dst: c.Bucket("foo").Object("bar"), srcs: []*ObjectHandle{ c.Bucket("foo").Object("baz").If(Conditions{MetagenerationMatch: 12}), }, wantErr: true, }, } for _, tt := range testCases { composer := tt.dst.ComposerFrom(tt.srcs...) if tt.attrs != nil { composer.ObjectAttrs = *tt.attrs } _, err := composer.Run(ctx) if gotErr := err != nil; gotErr != tt.wantErr { t.Errorf("%s: got error %v; want err %t", tt.desc, err, tt.wantErr) continue } if tt.wantErr { continue } u, body := <-gotURL, <-gotBody if u != tt.wantURL { t.Errorf("%s: request URL\ngot %q\nwant %q", tt.desc, u, tt.wantURL) } var req raw.ComposeRequest if err := json.Unmarshal(body, &req); err != nil { t.Errorf("%s: json.Unmarshal %v (body %s)", tt.desc, err, body) } if !testutil.Equal(req, tt.wantReq) { // Print to JSON. wantReq, _ := json.Marshal(tt.wantReq) t.Errorf("%s: request body\ngot %s\nwant %s", tt.desc, body, wantReq) } } } // Test that ObjectIterator's Next and NextPage methods correctly terminate // if there is nothing to iterate over. func TestEmptyObjectIterator(t *testing.T) { t.Parallel() hClient, close := newTestServer(func(w http.ResponseWriter, r *http.Request) { io.Copy(ioutil.Discard, r.Body) fmt.Fprintf(w, "{}") }) defer close() ctx := context.Background() client, err := NewClient(ctx, option.WithHTTPClient(hClient)) if err != nil { t.Fatal(err) } it := client.Bucket("b").Objects(ctx, nil) _, err = it.Next() if err != iterator.Done { t.Errorf("got %v, want Done", err) } } // Test that BucketIterator's Next method correctly terminates if there is // nothing to iterate over. func TestEmptyBucketIterator(t *testing.T) { t.Parallel() hClient, close := newTestServer(func(w http.ResponseWriter, r *http.Request) { io.Copy(ioutil.Discard, r.Body) fmt.Fprintf(w, "{}") }) defer close() ctx := context.Background() client, err := NewClient(ctx, option.WithHTTPClient(hClient)) if err != nil { t.Fatal(err) } it := client.Buckets(ctx, "project") _, err = it.Next() if err != iterator.Done { t.Errorf("got %v, want Done", err) } } func TestCodecUint32(t *testing.T) { t.Parallel() for _, u := range []uint32{0, 1, 256, 0xFFFFFFFF} { s := encodeUint32(u) d, err := decodeUint32(s) if err != nil { t.Fatal(err) } if d != u { t.Errorf("got %d, want input %d", d, u) } } } func TestUserProject(t *testing.T) { // Verify that the userProject query param is sent. t.Parallel() ctx := context.Background() gotURL := make(chan *url.URL, 1) hClient, close := newTestServer(func(w http.ResponseWriter, r *http.Request) { io.Copy(ioutil.Discard, r.Body) gotURL <- r.URL if strings.Contains(r.URL.String(), "/rewriteTo/") { res := &raw.RewriteResponse{Done: true} bytes, err := res.MarshalJSON() if err != nil { t.Fatal(err) } w.Write(bytes) } else { fmt.Fprintf(w, "{}") } }) defer close() client, err := NewClient(ctx, option.WithHTTPClient(hClient)) if err != nil { t.Fatal(err) } re := regexp.MustCompile(`\buserProject=p\b`) b := client.Bucket("b").UserProject("p") o := b.Object("o") check := func(msg string, f func()) { f() select { case u := <-gotURL: if !re.MatchString(u.RawQuery) { t.Errorf("%s: query string %q does not contain userProject", msg, u.RawQuery) } case <-time.After(2 * time.Second): t.Errorf("%s: timed out", msg) } } check("buckets.delete", func() { b.Delete(ctx) }) check("buckets.get", func() { b.Attrs(ctx) }) check("buckets.patch", func() { b.Update(ctx, BucketAttrsToUpdate{}) }) check("storage.objects.compose", func() { o.ComposerFrom(b.Object("x")).Run(ctx) }) check("storage.objects.delete", func() { o.Delete(ctx) }) check("storage.objects.get", func() { o.Attrs(ctx) }) check("storage.objects.insert", func() { o.NewWriter(ctx).Close() }) check("storage.objects.list", func() { b.Objects(ctx, nil).Next() }) check("storage.objects.patch", func() { o.Update(ctx, ObjectAttrsToUpdate{}) }) check("storage.objects.rewrite", func() { o.CopierFrom(b.Object("x")).Run(ctx) }) check("storage.objectAccessControls.list", func() { o.ACL().List(ctx) }) check("storage.objectAccessControls.update", func() { o.ACL().Set(ctx, "", "") }) check("storage.objectAccessControls.delete", func() { o.ACL().Delete(ctx, "") }) check("storage.bucketAccessControls.list", func() { b.ACL().List(ctx) }) check("storage.bucketAccessControls.update", func() { b.ACL().Set(ctx, "", "") }) check("storage.bucketAccessControls.delete", func() { b.ACL().Delete(ctx, "") }) check("storage.defaultObjectAccessControls.list", func() { b.DefaultObjectACL().List(ctx) }) check("storage.defaultObjectAccessControls.update", func() { b.DefaultObjectACL().Set(ctx, "", "") }) check("storage.defaultObjectAccessControls.delete", func() { b.DefaultObjectACL().Delete(ctx, "") }) check("buckets.getIamPolicy", func() { b.IAM().Policy(ctx) }) check("buckets.setIamPolicy", func() { p := &iam.Policy{} p.Add("m", iam.Owner) b.IAM().SetPolicy(ctx, p) }) check("buckets.testIamPermissions", func() { b.IAM().TestPermissions(ctx, nil) }) check("storage.notifications.insert", func() { b.AddNotification(ctx, &Notification{TopicProjectID: "p", TopicID: "t"}) }) check("storage.notifications.delete", func() { b.DeleteNotification(ctx, "n") }) check("storage.notifications.list", func() { b.Notifications(ctx) }) } func newTestServer(handler func(w http.ResponseWriter, r *http.Request)) (*http.Client, func()) { ts := httptest.NewTLSServer(http.HandlerFunc(handler)) tlsConf := &tls.Config{InsecureSkipVerify: true} tr := &http.Transport{ TLSClientConfig: tlsConf, DialTLS: func(netw, addr string) (net.Conn, error) { return tls.Dial("tcp", ts.Listener.Addr().String(), tlsConf) }, } return &http.Client{Transport: tr}, func() { tr.CloseIdleConnections() ts.Close() } } func TestRawObjectToObjectAttrs(t *testing.T) { t.Parallel() tests := []struct { in *raw.Object want *ObjectAttrs }{ {in: nil, want: nil}, { in: &raw.Object{ Bucket: "Test", ContentLanguage: "en-us", ContentType: "video/mpeg", EventBasedHold: false, Etag: "Zkyw9ACJZUvcYmlFaKGChzhmtnE/dt1zHSfweiWpwzdGsqXwuJZqiD0", Generation: 7, Md5Hash: "MTQ2ODNjYmE0NDRkYmNjNmRiMjk3NjQ1ZTY4M2Y1YzE=", Name: "foo.mp4", RetentionExpirationTime: "2019-03-31T19:33:36Z", Size: 1 << 20, TimeCreated: "2019-03-31T19:32:10Z", TimeDeleted: "2019-03-31T19:33:39Z", TemporaryHold: true, }, want: &ObjectAttrs{ Bucket: "Test", Created: time.Date(2019, 3, 31, 19, 32, 10, 0, time.UTC), ContentLanguage: "en-us", ContentType: "video/mpeg", Deleted: time.Date(2019, 3, 31, 19, 33, 39, 0, time.UTC), EventBasedHold: false, Etag: "Zkyw9ACJZUvcYmlFaKGChzhmtnE/dt1zHSfweiWpwzdGsqXwuJZqiD0", Generation: 7, MD5: []byte("14683cba444dbcc6db297645e683f5c1"), Name: "foo.mp4", RetentionExpirationTime: time.Date(2019, 3, 31, 19, 33, 36, 0, time.UTC), Size: 1 << 20, TemporaryHold: true, }, }, } for i, tt := range tests { got := newObject(tt.in) if diff := testutil.Diff(got, tt.want); diff != "" { t.Errorf("#%d: newObject mismatches:\ngot=-, want=+:\n%s", i, diff) } } } func TestObjectAttrsToRawObject(t *testing.T) { t.Parallel() bucketName := "the-bucket" in := &ObjectAttrs{ Bucket: "Test", Created: time.Date(2019, 3, 31, 19, 32, 10, 0, time.UTC), ContentLanguage: "en-us", ContentType: "video/mpeg", Deleted: time.Date(2019, 3, 31, 19, 33, 39, 0, time.UTC), EventBasedHold: false, Etag: "Zkyw9ACJZUvcYmlFaKGChzhmtnE/dt1zHSfweiWpwzdGsqXwuJZqiD0", Generation: 7, MD5: []byte("14683cba444dbcc6db297645e683f5c1"), Name: "foo.mp4", RetentionExpirationTime: time.Date(2019, 3, 31, 19, 33, 36, 0, time.UTC), Size: 1 << 20, TemporaryHold: true, } want := &raw.Object{ Bucket: bucketName, ContentLanguage: "en-us", ContentType: "video/mpeg", EventBasedHold: false, Name: "foo.mp4", RetentionExpirationTime: "2019-03-31T19:33:36Z", TemporaryHold: true, } got := in.toRawObject(bucketName) if !testutil.Equal(got, want) { if diff := testutil.Diff(got, want); diff != "" { t.Errorf("toRawObject mismatches:\ngot=-, want=+:\n%s", diff) } } } func TestAttrToFieldMapCoverage(t *testing.T) { t.Parallel() oa := reflect.TypeOf((*ObjectAttrs)(nil)).Elem() oaFields := make(map[string]bool) for i := 0; i < oa.NumField(); i++ { fieldName := oa.Field(i).Name oaFields[fieldName] = true } // Check that all fields of attrToFieldMap exist in ObjectAttrs. for k := range attrToFieldMap { if _, ok := oaFields[k]; !ok { t.Errorf("%v is not an ObjectAttrs field", k) } } // Check that all fields of ObjectAttrs exist in attrToFieldMap, with // known exceptions which aren't sent over the wire but are settable by // the user. for k := range oaFields { if _, ok := attrToFieldMap[k]; !ok { if k != "Prefix" && k != "PredefinedACL" { t.Errorf("ObjectAttrs.%v is not in attrToFieldMap", k) } } } } google-cloud-go-0.49.0/storage/writer.go000066400000000000000000000171721356504100700201070ustar00rootroot00000000000000// Copyright 2014 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package storage import ( "context" "encoding/base64" "errors" "fmt" "io" "sync" "unicode/utf8" "google.golang.org/api/googleapi" raw "google.golang.org/api/storage/v1" ) // A Writer writes a Cloud Storage object. type Writer struct { // ObjectAttrs are optional attributes to set on the object. Any attributes // must be initialized before the first Write call. Nil or zero-valued // attributes are ignored. ObjectAttrs // SendCRC specifies whether to transmit a CRC32C field. It should be set // to true in addition to setting the Writer's CRC32C field, because zero // is a valid CRC and normally a zero would not be transmitted. // If a CRC32C is sent, and the data written does not match the checksum, // the write will be rejected. SendCRC32C bool // ChunkSize controls the maximum number of bytes of the object that the // Writer will attempt to send to the server in a single request. Objects // smaller than the size will be sent in a single request, while larger // objects will be split over multiple requests. The size will be rounded up // to the nearest multiple of 256K. If zero, chunking will be disabled and // the object will be uploaded in a single request. // // ChunkSize will default to a reasonable value. If you perform many concurrent // writes of small objects, you may wish set ChunkSize to a value that matches // your objects' sizes to avoid consuming large amounts of memory. // // ChunkSize must be set before the first Write call. ChunkSize int // ProgressFunc can be used to monitor the progress of a large write. // operation. If ProgressFunc is not nil and writing requires multiple // calls to the underlying service (see // https://cloud.google.com/storage/docs/json_api/v1/how-tos/resumable-upload), // then ProgressFunc will be invoked after each call with the number of bytes of // content copied so far. // // ProgressFunc should return quickly without blocking. ProgressFunc func(int64) ctx context.Context o *ObjectHandle opened bool pw *io.PipeWriter donec chan struct{} // closed after err and obj are set. obj *ObjectAttrs mu sync.Mutex err error } func (w *Writer) open() error { attrs := w.ObjectAttrs // Check the developer didn't change the object Name (this is unfortunate, but // we don't want to store an object under the wrong name). if attrs.Name != w.o.object { return fmt.Errorf("storage: Writer.Name %q does not match object name %q", attrs.Name, w.o.object) } if !utf8.ValidString(attrs.Name) { return fmt.Errorf("storage: object name %q is not valid UTF-8", attrs.Name) } if attrs.KMSKeyName != "" && w.o.encryptionKey != nil { return errors.New("storage: cannot use KMSKeyName with a customer-supplied encryption key") } pr, pw := io.Pipe() w.pw = pw w.opened = true go w.monitorCancel() if w.ChunkSize < 0 { return errors.New("storage: Writer.ChunkSize must be non-negative") } mediaOpts := []googleapi.MediaOption{ googleapi.ChunkSize(w.ChunkSize), } if c := attrs.ContentType; c != "" { mediaOpts = append(mediaOpts, googleapi.ContentType(c)) } go func() { defer close(w.donec) rawObj := attrs.toRawObject(w.o.bucket) if w.SendCRC32C { rawObj.Crc32c = encodeUint32(attrs.CRC32C) } if w.MD5 != nil { rawObj.Md5Hash = base64.StdEncoding.EncodeToString(w.MD5) } if w.o.c.envHost != "" { w.o.c.raw.BasePath = fmt.Sprintf("%s://%s", w.o.c.scheme, w.o.c.envHost) } call := w.o.c.raw.Objects.Insert(w.o.bucket, rawObj). Media(pr, mediaOpts...). Projection("full"). Context(w.ctx) if w.ProgressFunc != nil { call.ProgressUpdater(func(n, _ int64) { w.ProgressFunc(n) }) } if attrs.KMSKeyName != "" { call.KmsKeyName(attrs.KMSKeyName) } if attrs.PredefinedACL != "" { call.PredefinedAcl(attrs.PredefinedACL) } if err := setEncryptionHeaders(call.Header(), w.o.encryptionKey, false); err != nil { w.mu.Lock() w.err = err w.mu.Unlock() pr.CloseWithError(err) return } var resp *raw.Object err := applyConds("NewWriter", w.o.gen, w.o.conds, call) if err == nil { if w.o.userProject != "" { call.UserProject(w.o.userProject) } setClientHeader(call.Header()) // The internals that perform call.Do automatically retry // uploading chunks, hence no need to add retries here. // See issue https://github.com/googleapis/google-cloud-go/issues/1507. // // However, since this whole call's internals involve making the initial // resumable upload session, the first HTTP request is not retried. // TODO: Follow-up with google.golang.org/gensupport to solve // https://github.com/googleapis/google-api-go-client/issues/392. resp, err = call.Do() } if err != nil { w.mu.Lock() w.err = err w.mu.Unlock() pr.CloseWithError(err) return } w.obj = newObject(resp) }() return nil } // Write appends to w. It implements the io.Writer interface. // // Since writes happen asynchronously, Write may return a nil // error even though the write failed (or will fail). Always // use the error returned from Writer.Close to determine if // the upload was successful. func (w *Writer) Write(p []byte) (n int, err error) { w.mu.Lock() werr := w.err w.mu.Unlock() if werr != nil { return 0, werr } if !w.opened { if err := w.open(); err != nil { return 0, err } } n, err = w.pw.Write(p) if err != nil { w.mu.Lock() werr := w.err w.mu.Unlock() // Preserve existing functionality that when context is canceled, Write will return // context.Canceled instead of "io: read/write on closed pipe". This hides the // pipe implementation detail from users and makes Write seem as though it's an RPC. if werr == context.Canceled || werr == context.DeadlineExceeded { return n, werr } } return n, err } // Close completes the write operation and flushes any buffered data. // If Close doesn't return an error, metadata about the written object // can be retrieved by calling Attrs. func (w *Writer) Close() error { if !w.opened { if err := w.open(); err != nil { return err } } // Closing either the read or write causes the entire pipe to close. if err := w.pw.Close(); err != nil { return err } <-w.donec w.mu.Lock() defer w.mu.Unlock() return w.err } // monitorCancel is intended to be used as a background goroutine. It monitors the // context, and when it observes that the context has been canceled, it manually // closes things that do not take a context. func (w *Writer) monitorCancel() { select { case <-w.ctx.Done(): w.mu.Lock() werr := w.ctx.Err() w.err = werr w.mu.Unlock() // Closing either the read or write causes the entire pipe to close. w.CloseWithError(werr) case <-w.donec: } } // CloseWithError aborts the write operation with the provided error. // CloseWithError always returns nil. // // Deprecated: cancel the context passed to NewWriter instead. func (w *Writer) CloseWithError(err error) error { if !w.opened { return nil } return w.pw.CloseWithError(err) } // Attrs returns metadata about a successfully-written object. // It's only valid to call it after Close returns nil. func (w *Writer) Attrs() *ObjectAttrs { return w.obj } google-cloud-go-0.49.0/storage/writer_test.go000066400000000000000000000133271356504100700211440ustar00rootroot00000000000000// Copyright 2014 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package storage import ( "context" "crypto/sha256" "encoding/base64" "net/http" "strings" "testing" "cloud.google.com/go/internal/testutil" "google.golang.org/api/googleapi" "google.golang.org/api/option" ) var testEncryptionKey = []byte("secret-key-that-is-32-bytes-long") func TestErrorOnObjectsInsertCall(t *testing.T) { t.Skip("Skipping until https://github.com/googleapis/google-api-go-client/issues/392 is resolved") t.Parallel() ctx := context.Background() const contents = "hello world" doWrite := func(mt *mockTransport) *Writer { client := mockClient(t, mt) wc := client.Bucket("bucketname").Object("filename1").NewWriter(ctx) wc.ContentType = "text/plain" // We can't check that the Write fails, since it depends on the write to the // underling mockTransport failing which is racy. wc.Write([]byte(contents)) return wc } wc := doWrite(&mockTransport{}) // Close must always return an error though since it waits for the transport to // have closed. if err := wc.Close(); err == nil { t.Errorf("expected error on close, got nil") } // Retry on 5xx mt := &mockTransport{} mt.addResult(&http.Response{StatusCode: 503, Body: bodyReader("")}, nil) mt.addResult(&http.Response{StatusCode: 200, Body: bodyReader("{}")}, nil) wc = doWrite(mt) if err := wc.Close(); err != nil { t.Errorf("got %v, want nil", err) } got := string(mt.gotBody) if !strings.Contains(got, contents) { t.Errorf("got body %q, which does not contain %q", got, contents) } } func TestEncryption(t *testing.T) { t.Parallel() ctx := context.Background() mt := &mockTransport{} mt.addResult(&http.Response{StatusCode: 200, Body: bodyReader("{}")}, nil) client := mockClient(t, mt) obj := client.Bucket("bucketname").Object("filename1") wc := obj.Key(testEncryptionKey).NewWriter(ctx) if _, err := wc.Write([]byte("hello world")); err != nil { t.Fatal(err) } if err := wc.Close(); err != nil { t.Fatal(err) } if got, want := mt.gotReq.Header.Get("x-goog-encryption-algorithm"), "AES256"; got != want { t.Errorf("algorithm: got %q, want %q", got, want) } gotKey, err := base64.StdEncoding.DecodeString(mt.gotReq.Header.Get("x-goog-encryption-key")) if err != nil { t.Fatalf("decoding key: %v", err) } if !testutil.Equal(gotKey, testEncryptionKey) { t.Errorf("key: got %v, want %v", gotKey, testEncryptionKey) } wantHash := sha256.Sum256(testEncryptionKey) gotHash, err := base64.StdEncoding.DecodeString(mt.gotReq.Header.Get("x-goog-encryption-key-sha256")) if err != nil { t.Fatalf("decoding hash: %v", err) } if !testutil.Equal(gotHash, wantHash[:]) { // wantHash is an array t.Errorf("hash: got\n%v, want\n%v", gotHash, wantHash) } // Using a customer-supplied encryption key and a KMS key together is an error. checkKMSError := func(msg string, err error) { if err == nil { t.Errorf("%s: got nil, want error", msg) } else if !strings.Contains(err.Error(), "KMS") { t.Errorf(`%s: got %q, want it to contain "KMS"`, msg, err) } } wc = obj.Key(testEncryptionKey).NewWriter(ctx) wc.KMSKeyName = "key" _, err = wc.Write([]byte{}) checkKMSError("Write", err) checkKMSError("Close", wc.Close()) } // This test demonstrates the data race on Writer.err that can happen when the // Writer's context is cancelled. To see the race, comment out the w.mu.Lock/Unlock // lines in writer.go and run this test with -race. func TestRaceOnCancel(t *testing.T) { client := mockClient(t, &mockTransport{}) cctx, cancel := context.WithCancel(context.Background()) w := client.Bucket("b").Object("o").NewWriter(cctx) w.ChunkSize = googleapi.MinUploadChunkSize buf := make([]byte, w.ChunkSize) // This Write starts the goroutine in Writer.open. That reads the first chunk in its entirety // before sending the request (see google.golang.org/api/gensupport.PrepareUpload), // so to exhibit the race we must provide ChunkSize bytes. The goroutine then makes the RPC (L137). w.Write(buf) // Canceling the context causes the call to return context.Canceled, which makes the open goroutine // write to w.err (L151). cancel() // This call to Write concurrently reads w.err (L169). w.Write([]byte(nil)) } func TestCancelDoesNotLeak(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) const contents = "hello world" mt := mockTransport{} client, err := NewClient(ctx, option.WithHTTPClient(&http.Client{Transport: &mt})) if err != nil { t.Fatal(err) } wc := client.Bucket("bucketname").Object("filename1").NewWriter(ctx) wc.ContentType = "text/plain" // We can't check that the Write fails, since it depends on the write to the // underling mockTransport failing which is racy. wc.Write([]byte(contents)) cancel() } func TestCloseDoesNotLeak(t *testing.T) { ctx := context.Background() const contents = "hello world" mt := mockTransport{} client, err := NewClient(ctx, option.WithHTTPClient(&http.Client{Transport: &mt})) if err != nil { t.Fatal(err) } wc := client.Bucket("bucketname").Object("filename1").NewWriter(ctx) wc.ContentType = "text/plain" // We can't check that the Write fails, since it depends on the write to the // underling mockTransport failing which is racy. wc.Write([]byte(contents)) wc.Close() } google-cloud-go-0.49.0/talent/000077500000000000000000000000001356504100700160575ustar00rootroot00000000000000google-cloud-go-0.49.0/talent/apiv4beta1/000077500000000000000000000000001356504100700200175ustar00rootroot00000000000000google-cloud-go-0.49.0/talent/apiv4beta1/.repo-metadata.json000066400000000000000000000006411356504100700235140ustar00rootroot00000000000000{ "name": "talent", "name_pretty": "Cloud Talent Solution", "product_documentation": "https://cloud.google.com/talent-solution", "client_documentation": "https://godoc.org/cloud.google.com/go/talent/apiv4beta1", "release_level": "beta", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "jobs.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/talent/apiv4beta1/application_client.go000066400000000000000000000244331356504100700242150ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package talent import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" talentpb "google.golang.org/genproto/googleapis/cloud/talent/v4beta1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // ApplicationCallOptions contains the retry settings for each method of ApplicationClient. type ApplicationCallOptions struct { CreateApplication []gax.CallOption GetApplication []gax.CallOption UpdateApplication []gax.CallOption DeleteApplication []gax.CallOption ListApplications []gax.CallOption } func defaultApplicationClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("jobs.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultApplicationCallOptions() *ApplicationCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &ApplicationCallOptions{ CreateApplication: retry[[2]string{"default", "non_idempotent"}], GetApplication: retry[[2]string{"default", "idempotent"}], UpdateApplication: retry[[2]string{"default", "non_idempotent"}], DeleteApplication: retry[[2]string{"default", "idempotent"}], ListApplications: retry[[2]string{"default", "idempotent"}], } } // ApplicationClient is a client for interacting with Cloud Talent Solution API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type ApplicationClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. applicationClient talentpb.ApplicationServiceClient // The call options for this service. CallOptions *ApplicationCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewApplicationClient creates a new application service client. // // A service that handles application management, including CRUD and // enumeration. func NewApplicationClient(ctx context.Context, opts ...option.ClientOption) (*ApplicationClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultApplicationClientOptions(), opts...)...) if err != nil { return nil, err } c := &ApplicationClient{ conn: conn, CallOptions: defaultApplicationCallOptions(), applicationClient: talentpb.NewApplicationServiceClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *ApplicationClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *ApplicationClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *ApplicationClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // CreateApplication creates a new application entity. func (c *ApplicationClient) CreateApplication(ctx context.Context, req *talentpb.CreateApplicationRequest, opts ...gax.CallOption) (*talentpb.Application, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateApplication[0:len(c.CallOptions.CreateApplication):len(c.CallOptions.CreateApplication)], opts...) var resp *talentpb.Application err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.applicationClient.CreateApplication(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetApplication retrieves specified application. func (c *ApplicationClient) GetApplication(ctx context.Context, req *talentpb.GetApplicationRequest, opts ...gax.CallOption) (*talentpb.Application, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetApplication[0:len(c.CallOptions.GetApplication):len(c.CallOptions.GetApplication)], opts...) var resp *talentpb.Application err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.applicationClient.GetApplication(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateApplication updates specified application. func (c *ApplicationClient) UpdateApplication(ctx context.Context, req *talentpb.UpdateApplicationRequest, opts ...gax.CallOption) (*talentpb.Application, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "application.name", url.QueryEscape(req.GetApplication().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateApplication[0:len(c.CallOptions.UpdateApplication):len(c.CallOptions.UpdateApplication)], opts...) var resp *talentpb.Application err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.applicationClient.UpdateApplication(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteApplication deletes specified application. func (c *ApplicationClient) DeleteApplication(ctx context.Context, req *talentpb.DeleteApplicationRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteApplication[0:len(c.CallOptions.DeleteApplication):len(c.CallOptions.DeleteApplication)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.applicationClient.DeleteApplication(ctx, req, settings.GRPC...) return err }, opts...) return err } // ListApplications lists all applications associated with the profile. func (c *ApplicationClient) ListApplications(ctx context.Context, req *talentpb.ListApplicationsRequest, opts ...gax.CallOption) *ApplicationIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListApplications[0:len(c.CallOptions.ListApplications):len(c.CallOptions.ListApplications)], opts...) it := &ApplicationIterator{} req = proto.Clone(req).(*talentpb.ListApplicationsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*talentpb.Application, string, error) { var resp *talentpb.ListApplicationsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.applicationClient.ListApplications(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Applications, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // ApplicationIterator manages a stream of *talentpb.Application. type ApplicationIterator struct { items []*talentpb.Application pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*talentpb.Application, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *ApplicationIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *ApplicationIterator) Next() (*talentpb.Application, error) { var item *talentpb.Application if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *ApplicationIterator) bufLen() int { return len(it.items) } func (it *ApplicationIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/talent/apiv4beta1/application_client_example_test.go000066400000000000000000000056011356504100700267630ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package talent_test import ( "context" talent "cloud.google.com/go/talent/apiv4beta1" "google.golang.org/api/iterator" talentpb "google.golang.org/genproto/googleapis/cloud/talent/v4beta1" ) func ExampleNewApplicationClient() { ctx := context.Background() c, err := talent.NewApplicationClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleApplicationClient_CreateApplication() { ctx := context.Background() c, err := talent.NewApplicationClient(ctx) if err != nil { // TODO: Handle error. } req := &talentpb.CreateApplicationRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateApplication(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleApplicationClient_GetApplication() { ctx := context.Background() c, err := talent.NewApplicationClient(ctx) if err != nil { // TODO: Handle error. } req := &talentpb.GetApplicationRequest{ // TODO: Fill request struct fields. } resp, err := c.GetApplication(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleApplicationClient_UpdateApplication() { ctx := context.Background() c, err := talent.NewApplicationClient(ctx) if err != nil { // TODO: Handle error. } req := &talentpb.UpdateApplicationRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateApplication(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleApplicationClient_DeleteApplication() { ctx := context.Background() c, err := talent.NewApplicationClient(ctx) if err != nil { // TODO: Handle error. } req := &talentpb.DeleteApplicationRequest{ // TODO: Fill request struct fields. } err = c.DeleteApplication(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleApplicationClient_ListApplications() { ctx := context.Background() c, err := talent.NewApplicationClient(ctx) if err != nil { // TODO: Handle error. } req := &talentpb.ListApplicationsRequest{ // TODO: Fill request struct fields. } it := c.ListApplications(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } google-cloud-go-0.49.0/talent/apiv4beta1/company_client.go000066400000000000000000000236501356504100700233600ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package talent import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" talentpb "google.golang.org/genproto/googleapis/cloud/talent/v4beta1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // CompanyCallOptions contains the retry settings for each method of CompanyClient. type CompanyCallOptions struct { CreateCompany []gax.CallOption GetCompany []gax.CallOption UpdateCompany []gax.CallOption DeleteCompany []gax.CallOption ListCompanies []gax.CallOption } func defaultCompanyClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("jobs.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultCompanyCallOptions() *CompanyCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &CompanyCallOptions{ CreateCompany: retry[[2]string{"default", "non_idempotent"}], GetCompany: retry[[2]string{"default", "idempotent"}], UpdateCompany: retry[[2]string{"default", "non_idempotent"}], DeleteCompany: retry[[2]string{"default", "idempotent"}], ListCompanies: retry[[2]string{"default", "idempotent"}], } } // CompanyClient is a client for interacting with Cloud Talent Solution API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type CompanyClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. companyClient talentpb.CompanyServiceClient // The call options for this service. CallOptions *CompanyCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewCompanyClient creates a new company service client. // // A service that handles company management, including CRUD and enumeration. func NewCompanyClient(ctx context.Context, opts ...option.ClientOption) (*CompanyClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultCompanyClientOptions(), opts...)...) if err != nil { return nil, err } c := &CompanyClient{ conn: conn, CallOptions: defaultCompanyCallOptions(), companyClient: talentpb.NewCompanyServiceClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *CompanyClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *CompanyClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *CompanyClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // CreateCompany creates a new company entity. func (c *CompanyClient) CreateCompany(ctx context.Context, req *talentpb.CreateCompanyRequest, opts ...gax.CallOption) (*talentpb.Company, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateCompany[0:len(c.CallOptions.CreateCompany):len(c.CallOptions.CreateCompany)], opts...) var resp *talentpb.Company err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.companyClient.CreateCompany(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetCompany retrieves specified company. func (c *CompanyClient) GetCompany(ctx context.Context, req *talentpb.GetCompanyRequest, opts ...gax.CallOption) (*talentpb.Company, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetCompany[0:len(c.CallOptions.GetCompany):len(c.CallOptions.GetCompany)], opts...) var resp *talentpb.Company err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.companyClient.GetCompany(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateCompany updates specified company. func (c *CompanyClient) UpdateCompany(ctx context.Context, req *talentpb.UpdateCompanyRequest, opts ...gax.CallOption) (*talentpb.Company, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "company.name", url.QueryEscape(req.GetCompany().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateCompany[0:len(c.CallOptions.UpdateCompany):len(c.CallOptions.UpdateCompany)], opts...) var resp *talentpb.Company err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.companyClient.UpdateCompany(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteCompany deletes specified company. // Prerequisite: The company has no jobs associated with it. func (c *CompanyClient) DeleteCompany(ctx context.Context, req *talentpb.DeleteCompanyRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteCompany[0:len(c.CallOptions.DeleteCompany):len(c.CallOptions.DeleteCompany)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.companyClient.DeleteCompany(ctx, req, settings.GRPC...) return err }, opts...) return err } // ListCompanies lists all companies associated with the project. func (c *CompanyClient) ListCompanies(ctx context.Context, req *talentpb.ListCompaniesRequest, opts ...gax.CallOption) *CompanyIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListCompanies[0:len(c.CallOptions.ListCompanies):len(c.CallOptions.ListCompanies)], opts...) it := &CompanyIterator{} req = proto.Clone(req).(*talentpb.ListCompaniesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*talentpb.Company, string, error) { var resp *talentpb.ListCompaniesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.companyClient.ListCompanies(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Companies, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // CompanyIterator manages a stream of *talentpb.Company. type CompanyIterator struct { items []*talentpb.Company pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*talentpb.Company, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *CompanyIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *CompanyIterator) Next() (*talentpb.Company, error) { var item *talentpb.Company if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *CompanyIterator) bufLen() int { return len(it.items) } func (it *CompanyIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/talent/apiv4beta1/company_client_example_test.go000066400000000000000000000054301356504100700261260ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package talent_test import ( "context" talent "cloud.google.com/go/talent/apiv4beta1" "google.golang.org/api/iterator" talentpb "google.golang.org/genproto/googleapis/cloud/talent/v4beta1" ) func ExampleNewCompanyClient() { ctx := context.Background() c, err := talent.NewCompanyClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleCompanyClient_CreateCompany() { ctx := context.Background() c, err := talent.NewCompanyClient(ctx) if err != nil { // TODO: Handle error. } req := &talentpb.CreateCompanyRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateCompany(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleCompanyClient_GetCompany() { ctx := context.Background() c, err := talent.NewCompanyClient(ctx) if err != nil { // TODO: Handle error. } req := &talentpb.GetCompanyRequest{ // TODO: Fill request struct fields. } resp, err := c.GetCompany(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleCompanyClient_UpdateCompany() { ctx := context.Background() c, err := talent.NewCompanyClient(ctx) if err != nil { // TODO: Handle error. } req := &talentpb.UpdateCompanyRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateCompany(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleCompanyClient_DeleteCompany() { ctx := context.Background() c, err := talent.NewCompanyClient(ctx) if err != nil { // TODO: Handle error. } req := &talentpb.DeleteCompanyRequest{ // TODO: Fill request struct fields. } err = c.DeleteCompany(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleCompanyClient_ListCompanies() { ctx := context.Background() c, err := talent.NewCompanyClient(ctx) if err != nil { // TODO: Handle error. } req := &talentpb.ListCompaniesRequest{ // TODO: Fill request struct fields. } it := c.ListCompanies(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } google-cloud-go-0.49.0/talent/apiv4beta1/completion_client.go000066400000000000000000000111211356504100700240510ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package talent import ( "context" "fmt" "math" "net/url" "time" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" "google.golang.org/api/transport" talentpb "google.golang.org/genproto/googleapis/cloud/talent/v4beta1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // CompletionCallOptions contains the retry settings for each method of CompletionClient. type CompletionCallOptions struct { CompleteQuery []gax.CallOption } func defaultCompletionClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("jobs.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultCompletionCallOptions() *CompletionCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &CompletionCallOptions{ CompleteQuery: retry[[2]string{"default", "idempotent"}], } } // CompletionClient is a client for interacting with Cloud Talent Solution API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type CompletionClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. completionClient talentpb.CompletionClient // The call options for this service. CallOptions *CompletionCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewCompletionClient creates a new completion client. // // A service handles auto completion. func NewCompletionClient(ctx context.Context, opts ...option.ClientOption) (*CompletionClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultCompletionClientOptions(), opts...)...) if err != nil { return nil, err } c := &CompletionClient{ conn: conn, CallOptions: defaultCompletionCallOptions(), completionClient: talentpb.NewCompletionClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *CompletionClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *CompletionClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *CompletionClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // CompleteQuery completes the specified prefix with keyword suggestions. // Intended for use by a job search auto-complete search box. func (c *CompletionClient) CompleteQuery(ctx context.Context, req *talentpb.CompleteQueryRequest, opts ...gax.CallOption) (*talentpb.CompleteQueryResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CompleteQuery[0:len(c.CallOptions.CompleteQuery):len(c.CallOptions.CompleteQuery)], opts...) var resp *talentpb.CompleteQueryResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.completionClient.CompleteQuery(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } google-cloud-go-0.49.0/talent/apiv4beta1/completion_client_example_test.go000066400000000000000000000025121356504100700266270ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package talent_test import ( "context" talent "cloud.google.com/go/talent/apiv4beta1" talentpb "google.golang.org/genproto/googleapis/cloud/talent/v4beta1" ) func ExampleNewCompletionClient() { ctx := context.Background() c, err := talent.NewCompletionClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleCompletionClient_CompleteQuery() { ctx := context.Background() c, err := talent.NewCompletionClient(ctx) if err != nil { // TODO: Handle error. } req := &talentpb.CompleteQueryRequest{ // TODO: Fill request struct fields. } resp, err := c.CompleteQuery(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/talent/apiv4beta1/doc.go000066400000000000000000000055471356504100700211260ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package talent is an auto-generated package for the // Cloud Talent Solution API. // // NOTE: This package is in beta. It is not stable, and may be subject to changes. // // Cloud Talent Solution provides the capability to create, read, update, and // delete job postings, as well as search jobs based on keywords and filters. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package talent // import "cloud.google.com/go/talent/apiv4beta1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/jobs", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191115" google-cloud-go-0.49.0/talent/apiv4beta1/event_client.go000066400000000000000000000106121356504100700230250ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package talent import ( "context" "fmt" "math" "net/url" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" "google.golang.org/api/transport" talentpb "google.golang.org/genproto/googleapis/cloud/talent/v4beta1" "google.golang.org/grpc" "google.golang.org/grpc/metadata" ) // EventCallOptions contains the retry settings for each method of EventClient. type EventCallOptions struct { CreateClientEvent []gax.CallOption } func defaultEventClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("jobs.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultEventCallOptions() *EventCallOptions { retry := map[[2]string][]gax.CallOption{} return &EventCallOptions{ CreateClientEvent: retry[[2]string{"default", "non_idempotent"}], } } // EventClient is a client for interacting with Cloud Talent Solution API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type EventClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. eventClient talentpb.EventServiceClient // The call options for this service. CallOptions *EventCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewEventClient creates a new event service client. // // A service handles client event report. func NewEventClient(ctx context.Context, opts ...option.ClientOption) (*EventClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultEventClientOptions(), opts...)...) if err != nil { return nil, err } c := &EventClient{ conn: conn, CallOptions: defaultEventCallOptions(), eventClient: talentpb.NewEventServiceClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *EventClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *EventClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *EventClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // CreateClientEvent report events issued when end user interacts with customer's application // that uses Cloud Talent Solution. You may inspect the created events in // self service // tools (at https://console.cloud.google.com/talent-solution/overview). // Learn // more (at https://cloud.google.com/talent-solution/docs/management-tools) // about self service tools. func (c *EventClient) CreateClientEvent(ctx context.Context, req *talentpb.CreateClientEventRequest, opts ...gax.CallOption) (*talentpb.ClientEvent, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateClientEvent[0:len(c.CallOptions.CreateClientEvent):len(c.CallOptions.CreateClientEvent)], opts...) var resp *talentpb.ClientEvent err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.eventClient.CreateClientEvent(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } google-cloud-go-0.49.0/talent/apiv4beta1/event_client_example_test.go000066400000000000000000000025021356504100700255760ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package talent_test import ( "context" talent "cloud.google.com/go/talent/apiv4beta1" talentpb "google.golang.org/genproto/googleapis/cloud/talent/v4beta1" ) func ExampleNewEventClient() { ctx := context.Background() c, err := talent.NewEventClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleEventClient_CreateClientEvent() { ctx := context.Background() c, err := talent.NewEventClient(ctx) if err != nil { // TODO: Handle error. } req := &talentpb.CreateClientEventRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateClientEvent(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/talent/apiv4beta1/job_client.go000066400000000000000000000614751356504100700224730ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package talent import ( "context" "fmt" "math" "net/url" "time" "cloud.google.com/go/longrunning" lroauto "cloud.google.com/go/longrunning/autogen" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" talentpb "google.golang.org/genproto/googleapis/cloud/talent/v4beta1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // JobCallOptions contains the retry settings for each method of JobClient. type JobCallOptions struct { CreateJob []gax.CallOption GetJob []gax.CallOption UpdateJob []gax.CallOption DeleteJob []gax.CallOption ListJobs []gax.CallOption BatchDeleteJobs []gax.CallOption SearchJobs []gax.CallOption SearchJobsForAlert []gax.CallOption BatchCreateJobs []gax.CallOption BatchUpdateJobs []gax.CallOption } func defaultJobClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("jobs.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultJobCallOptions() *JobCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &JobCallOptions{ CreateJob: retry[[2]string{"default", "non_idempotent"}], GetJob: retry[[2]string{"default", "idempotent"}], UpdateJob: retry[[2]string{"default", "non_idempotent"}], DeleteJob: retry[[2]string{"default", "idempotent"}], ListJobs: retry[[2]string{"default", "idempotent"}], BatchDeleteJobs: retry[[2]string{"default", "non_idempotent"}], SearchJobs: retry[[2]string{"default", "non_idempotent"}], SearchJobsForAlert: retry[[2]string{"default", "non_idempotent"}], BatchCreateJobs: retry[[2]string{"default", "non_idempotent"}], BatchUpdateJobs: retry[[2]string{"default", "non_idempotent"}], } } // JobClient is a client for interacting with Cloud Talent Solution API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type JobClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. jobClient talentpb.JobServiceClient // LROClient is used internally to handle longrunning operations. // It is exposed so that its CallOptions can be modified if required. // Users should not Close this client. LROClient *lroauto.OperationsClient // The call options for this service. CallOptions *JobCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewJobClient creates a new job service client. // // A service handles job management, including job CRUD, enumeration and search. func NewJobClient(ctx context.Context, opts ...option.ClientOption) (*JobClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultJobClientOptions(), opts...)...) if err != nil { return nil, err } c := &JobClient{ conn: conn, CallOptions: defaultJobCallOptions(), jobClient: talentpb.NewJobServiceClient(conn), } c.setGoogleClientInfo() c.LROClient, err = lroauto.NewOperationsClient(ctx, option.WithGRPCConn(conn)) if err != nil { // This error "should not happen", since we are just reusing old connection // and never actually need to dial. // If this does happen, we could leak conn. However, we cannot close conn: // If the user invoked the function with option.WithGRPCConn, // we would close a connection that's still in use. // TODO(pongad): investigate error conditions. return nil, err } return c, nil } // Connection returns the client's connection to the API service. func (c *JobClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *JobClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *JobClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // CreateJob creates a new job. // // Typically, the job becomes searchable within 10 seconds, but it may take // up to 5 minutes. func (c *JobClient) CreateJob(ctx context.Context, req *talentpb.CreateJobRequest, opts ...gax.CallOption) (*talentpb.Job, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateJob[0:len(c.CallOptions.CreateJob):len(c.CallOptions.CreateJob)], opts...) var resp *talentpb.Job err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.jobClient.CreateJob(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetJob retrieves the specified job, whose status is OPEN or recently EXPIRED // within the last 90 days. func (c *JobClient) GetJob(ctx context.Context, req *talentpb.GetJobRequest, opts ...gax.CallOption) (*talentpb.Job, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetJob[0:len(c.CallOptions.GetJob):len(c.CallOptions.GetJob)], opts...) var resp *talentpb.Job err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.jobClient.GetJob(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateJob updates specified job. // // Typically, updated contents become visible in search results within 10 // seconds, but it may take up to 5 minutes. func (c *JobClient) UpdateJob(ctx context.Context, req *talentpb.UpdateJobRequest, opts ...gax.CallOption) (*talentpb.Job, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "job.name", url.QueryEscape(req.GetJob().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateJob[0:len(c.CallOptions.UpdateJob):len(c.CallOptions.UpdateJob)], opts...) var resp *talentpb.Job err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.jobClient.UpdateJob(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteJob deletes the specified job. // // Typically, the job becomes unsearchable within 10 seconds, but it may take // up to 5 minutes. func (c *JobClient) DeleteJob(ctx context.Context, req *talentpb.DeleteJobRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteJob[0:len(c.CallOptions.DeleteJob):len(c.CallOptions.DeleteJob)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.jobClient.DeleteJob(ctx, req, settings.GRPC...) return err }, opts...) return err } // ListJobs lists jobs by filter. func (c *JobClient) ListJobs(ctx context.Context, req *talentpb.ListJobsRequest, opts ...gax.CallOption) *JobIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListJobs[0:len(c.CallOptions.ListJobs):len(c.CallOptions.ListJobs)], opts...) it := &JobIterator{} req = proto.Clone(req).(*talentpb.ListJobsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*talentpb.Job, string, error) { var resp *talentpb.ListJobsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.jobClient.ListJobs(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Jobs, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // BatchDeleteJobs deletes a list of [Job][google.cloud.talent.v4beta1.Job]s by filter. func (c *JobClient) BatchDeleteJobs(ctx context.Context, req *talentpb.BatchDeleteJobsRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.BatchDeleteJobs[0:len(c.CallOptions.BatchDeleteJobs):len(c.CallOptions.BatchDeleteJobs)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.jobClient.BatchDeleteJobs(ctx, req, settings.GRPC...) return err }, opts...) return err } // SearchJobs searches for jobs using the provided // [SearchJobsRequest][google.cloud.talent.v4beta1.SearchJobsRequest]. // // This call constrains the // [visibility][google.cloud.talent.v4beta1.Job.visibility] of jobs present in // the database, and only returns jobs that the caller has permission to // search against. func (c *JobClient) SearchJobs(ctx context.Context, req *talentpb.SearchJobsRequest, opts ...gax.CallOption) *SearchJobsResponse_MatchingJobIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.SearchJobs[0:len(c.CallOptions.SearchJobs):len(c.CallOptions.SearchJobs)], opts...) it := &SearchJobsResponse_MatchingJobIterator{} req = proto.Clone(req).(*talentpb.SearchJobsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*talentpb.SearchJobsResponse_MatchingJob, string, error) { var resp *talentpb.SearchJobsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.jobClient.SearchJobs(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.MatchingJobs, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // SearchJobsForAlert searches for jobs using the provided // [SearchJobsRequest][google.cloud.talent.v4beta1.SearchJobsRequest]. // // This API call is intended for the use case of targeting passive job // seekers (for example, job seekers who have signed up to receive email // alerts about potential job opportunities), and has different algorithmic // adjustments that are targeted to passive job seekers. // // This call constrains the // [visibility][google.cloud.talent.v4beta1.Job.visibility] of jobs present in // the database, and only returns jobs the caller has permission to search // against. func (c *JobClient) SearchJobsForAlert(ctx context.Context, req *talentpb.SearchJobsRequest, opts ...gax.CallOption) *SearchJobsResponse_MatchingJobIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.SearchJobsForAlert[0:len(c.CallOptions.SearchJobsForAlert):len(c.CallOptions.SearchJobsForAlert)], opts...) it := &SearchJobsResponse_MatchingJobIterator{} req = proto.Clone(req).(*talentpb.SearchJobsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*talentpb.SearchJobsResponse_MatchingJob, string, error) { var resp *talentpb.SearchJobsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.jobClient.SearchJobsForAlert(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.MatchingJobs, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // BatchCreateJobs begins executing a batch create jobs operation. func (c *JobClient) BatchCreateJobs(ctx context.Context, req *talentpb.BatchCreateJobsRequest, opts ...gax.CallOption) (*BatchCreateJobsOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.BatchCreateJobs[0:len(c.CallOptions.BatchCreateJobs):len(c.CallOptions.BatchCreateJobs)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.jobClient.BatchCreateJobs(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &BatchCreateJobsOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // BatchUpdateJobs begins executing a batch update jobs operation. func (c *JobClient) BatchUpdateJobs(ctx context.Context, req *talentpb.BatchUpdateJobsRequest, opts ...gax.CallOption) (*BatchUpdateJobsOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.BatchUpdateJobs[0:len(c.CallOptions.BatchUpdateJobs):len(c.CallOptions.BatchUpdateJobs)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.jobClient.BatchUpdateJobs(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &BatchUpdateJobsOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // JobIterator manages a stream of *talentpb.Job. type JobIterator struct { items []*talentpb.Job pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*talentpb.Job, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *JobIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *JobIterator) Next() (*talentpb.Job, error) { var item *talentpb.Job if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *JobIterator) bufLen() int { return len(it.items) } func (it *JobIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // SearchJobsResponse_MatchingJobIterator manages a stream of *talentpb.SearchJobsResponse_MatchingJob. type SearchJobsResponse_MatchingJobIterator struct { items []*talentpb.SearchJobsResponse_MatchingJob pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*talentpb.SearchJobsResponse_MatchingJob, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *SearchJobsResponse_MatchingJobIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *SearchJobsResponse_MatchingJobIterator) Next() (*talentpb.SearchJobsResponse_MatchingJob, error) { var item *talentpb.SearchJobsResponse_MatchingJob if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *SearchJobsResponse_MatchingJobIterator) bufLen() int { return len(it.items) } func (it *SearchJobsResponse_MatchingJobIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // BatchCreateJobsOperation manages a long-running operation from BatchCreateJobs. type BatchCreateJobsOperation struct { lro *longrunning.Operation } // BatchCreateJobsOperation returns a new BatchCreateJobsOperation from a given name. // The name must be that of a previously created BatchCreateJobsOperation, possibly from a different process. func (c *JobClient) BatchCreateJobsOperation(name string) *BatchCreateJobsOperation { return &BatchCreateJobsOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *BatchCreateJobsOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*talentpb.JobOperationResult, error) { var resp talentpb.JobOperationResult if err := op.lro.WaitWithInterval(ctx, &resp, 5000*time.Millisecond, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *BatchCreateJobsOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*talentpb.JobOperationResult, error) { var resp talentpb.JobOperationResult if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *BatchCreateJobsOperation) Metadata() (*talentpb.BatchOperationMetadata, error) { var meta talentpb.BatchOperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *BatchCreateJobsOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *BatchCreateJobsOperation) Name() string { return op.lro.Name() } // BatchUpdateJobsOperation manages a long-running operation from BatchUpdateJobs. type BatchUpdateJobsOperation struct { lro *longrunning.Operation } // BatchUpdateJobsOperation returns a new BatchUpdateJobsOperation from a given name. // The name must be that of a previously created BatchUpdateJobsOperation, possibly from a different process. func (c *JobClient) BatchUpdateJobsOperation(name string) *BatchUpdateJobsOperation { return &BatchUpdateJobsOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *BatchUpdateJobsOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*talentpb.JobOperationResult, error) { var resp talentpb.JobOperationResult if err := op.lro.WaitWithInterval(ctx, &resp, 5000*time.Millisecond, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *BatchUpdateJobsOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*talentpb.JobOperationResult, error) { var resp talentpb.JobOperationResult if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *BatchUpdateJobsOperation) Metadata() (*talentpb.BatchOperationMetadata, error) { var meta talentpb.BatchOperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *BatchUpdateJobsOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *BatchUpdateJobsOperation) Name() string { return op.lro.Name() } google-cloud-go-0.49.0/talent/apiv4beta1/job_client_example_test.go000066400000000000000000000112211356504100700252250ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package talent_test import ( "context" talent "cloud.google.com/go/talent/apiv4beta1" "google.golang.org/api/iterator" talentpb "google.golang.org/genproto/googleapis/cloud/talent/v4beta1" ) func ExampleNewJobClient() { ctx := context.Background() c, err := talent.NewJobClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleJobClient_CreateJob() { ctx := context.Background() c, err := talent.NewJobClient(ctx) if err != nil { // TODO: Handle error. } req := &talentpb.CreateJobRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateJob(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleJobClient_GetJob() { ctx := context.Background() c, err := talent.NewJobClient(ctx) if err != nil { // TODO: Handle error. } req := &talentpb.GetJobRequest{ // TODO: Fill request struct fields. } resp, err := c.GetJob(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleJobClient_UpdateJob() { ctx := context.Background() c, err := talent.NewJobClient(ctx) if err != nil { // TODO: Handle error. } req := &talentpb.UpdateJobRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateJob(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleJobClient_DeleteJob() { ctx := context.Background() c, err := talent.NewJobClient(ctx) if err != nil { // TODO: Handle error. } req := &talentpb.DeleteJobRequest{ // TODO: Fill request struct fields. } err = c.DeleteJob(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleJobClient_ListJobs() { ctx := context.Background() c, err := talent.NewJobClient(ctx) if err != nil { // TODO: Handle error. } req := &talentpb.ListJobsRequest{ // TODO: Fill request struct fields. } it := c.ListJobs(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleJobClient_BatchDeleteJobs() { ctx := context.Background() c, err := talent.NewJobClient(ctx) if err != nil { // TODO: Handle error. } req := &talentpb.BatchDeleteJobsRequest{ // TODO: Fill request struct fields. } err = c.BatchDeleteJobs(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleJobClient_SearchJobs() { ctx := context.Background() c, err := talent.NewJobClient(ctx) if err != nil { // TODO: Handle error. } req := &talentpb.SearchJobsRequest{ // TODO: Fill request struct fields. } it := c.SearchJobs(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleJobClient_SearchJobsForAlert() { ctx := context.Background() c, err := talent.NewJobClient(ctx) if err != nil { // TODO: Handle error. } req := &talentpb.SearchJobsRequest{ // TODO: Fill request struct fields. } it := c.SearchJobsForAlert(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleJobClient_BatchCreateJobs() { ctx := context.Background() c, err := talent.NewJobClient(ctx) if err != nil { // TODO: Handle error. } req := &talentpb.BatchCreateJobsRequest{ // TODO: Fill request struct fields. } op, err := c.BatchCreateJobs(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleJobClient_BatchUpdateJobs() { ctx := context.Background() c, err := talent.NewJobClient(ctx) if err != nil { // TODO: Handle error. } req := &talentpb.BatchUpdateJobsRequest{ // TODO: Fill request struct fields. } op, err := c.BatchUpdateJobs(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/talent/apiv4beta1/mock_test.go000066400000000000000000002474051356504100700223520ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package talent import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" "google.golang.org/api/option" talentpb "google.golang.org/genproto/googleapis/cloud/talent/v4beta1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockApplicationServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. talentpb.ApplicationServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockApplicationServer) CreateApplication(ctx context.Context, req *talentpb.CreateApplicationRequest) (*talentpb.Application, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*talentpb.Application), nil } func (s *mockApplicationServer) GetApplication(ctx context.Context, req *talentpb.GetApplicationRequest) (*talentpb.Application, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*talentpb.Application), nil } func (s *mockApplicationServer) UpdateApplication(ctx context.Context, req *talentpb.UpdateApplicationRequest) (*talentpb.Application, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*talentpb.Application), nil } func (s *mockApplicationServer) DeleteApplication(ctx context.Context, req *talentpb.DeleteApplicationRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockApplicationServer) ListApplications(ctx context.Context, req *talentpb.ListApplicationsRequest) (*talentpb.ListApplicationsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*talentpb.ListApplicationsResponse), nil } type mockCompanyServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. talentpb.CompanyServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockCompanyServer) CreateCompany(ctx context.Context, req *talentpb.CreateCompanyRequest) (*talentpb.Company, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*talentpb.Company), nil } func (s *mockCompanyServer) GetCompany(ctx context.Context, req *talentpb.GetCompanyRequest) (*talentpb.Company, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*talentpb.Company), nil } func (s *mockCompanyServer) UpdateCompany(ctx context.Context, req *talentpb.UpdateCompanyRequest) (*talentpb.Company, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*talentpb.Company), nil } func (s *mockCompanyServer) DeleteCompany(ctx context.Context, req *talentpb.DeleteCompanyRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockCompanyServer) ListCompanies(ctx context.Context, req *talentpb.ListCompaniesRequest) (*talentpb.ListCompaniesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*talentpb.ListCompaniesResponse), nil } type mockCompletionServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. talentpb.CompletionServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockCompletionServer) CompleteQuery(ctx context.Context, req *talentpb.CompleteQueryRequest) (*talentpb.CompleteQueryResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*talentpb.CompleteQueryResponse), nil } type mockEventServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. talentpb.EventServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockEventServer) CreateClientEvent(ctx context.Context, req *talentpb.CreateClientEventRequest) (*talentpb.ClientEvent, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*talentpb.ClientEvent), nil } type mockJobServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. talentpb.JobServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockJobServer) CreateJob(ctx context.Context, req *talentpb.CreateJobRequest) (*talentpb.Job, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*talentpb.Job), nil } func (s *mockJobServer) BatchCreateJobs(ctx context.Context, req *talentpb.BatchCreateJobsRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockJobServer) GetJob(ctx context.Context, req *talentpb.GetJobRequest) (*talentpb.Job, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*talentpb.Job), nil } func (s *mockJobServer) UpdateJob(ctx context.Context, req *talentpb.UpdateJobRequest) (*talentpb.Job, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*talentpb.Job), nil } func (s *mockJobServer) BatchUpdateJobs(ctx context.Context, req *talentpb.BatchUpdateJobsRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockJobServer) DeleteJob(ctx context.Context, req *talentpb.DeleteJobRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockJobServer) BatchDeleteJobs(ctx context.Context, req *talentpb.BatchDeleteJobsRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockJobServer) ListJobs(ctx context.Context, req *talentpb.ListJobsRequest) (*talentpb.ListJobsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*talentpb.ListJobsResponse), nil } func (s *mockJobServer) SearchJobs(ctx context.Context, req *talentpb.SearchJobsRequest) (*talentpb.SearchJobsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*talentpb.SearchJobsResponse), nil } func (s *mockJobServer) SearchJobsForAlert(ctx context.Context, req *talentpb.SearchJobsRequest) (*talentpb.SearchJobsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*talentpb.SearchJobsResponse), nil } type mockProfileServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. talentpb.ProfileServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockProfileServer) ListProfiles(ctx context.Context, req *talentpb.ListProfilesRequest) (*talentpb.ListProfilesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*talentpb.ListProfilesResponse), nil } func (s *mockProfileServer) CreateProfile(ctx context.Context, req *talentpb.CreateProfileRequest) (*talentpb.Profile, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*talentpb.Profile), nil } func (s *mockProfileServer) GetProfile(ctx context.Context, req *talentpb.GetProfileRequest) (*talentpb.Profile, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*talentpb.Profile), nil } func (s *mockProfileServer) UpdateProfile(ctx context.Context, req *talentpb.UpdateProfileRequest) (*talentpb.Profile, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*talentpb.Profile), nil } func (s *mockProfileServer) DeleteProfile(ctx context.Context, req *talentpb.DeleteProfileRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockProfileServer) SearchProfiles(ctx context.Context, req *talentpb.SearchProfilesRequest) (*talentpb.SearchProfilesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*talentpb.SearchProfilesResponse), nil } type mockTenantServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. talentpb.TenantServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockTenantServer) CreateTenant(ctx context.Context, req *talentpb.CreateTenantRequest) (*talentpb.Tenant, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*talentpb.Tenant), nil } func (s *mockTenantServer) GetTenant(ctx context.Context, req *talentpb.GetTenantRequest) (*talentpb.Tenant, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*talentpb.Tenant), nil } func (s *mockTenantServer) UpdateTenant(ctx context.Context, req *talentpb.UpdateTenantRequest) (*talentpb.Tenant, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*talentpb.Tenant), nil } func (s *mockTenantServer) DeleteTenant(ctx context.Context, req *talentpb.DeleteTenantRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockTenantServer) ListTenants(ctx context.Context, req *talentpb.ListTenantsRequest) (*talentpb.ListTenantsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*talentpb.ListTenantsResponse), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockApplication mockApplicationServer mockCompany mockCompanyServer mockCompletion mockCompletionServer mockEvent mockEventServer mockJob mockJobServer mockProfile mockProfileServer mockTenant mockTenantServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() talentpb.RegisterApplicationServiceServer(serv, &mockApplication) talentpb.RegisterCompanyServiceServer(serv, &mockCompany) talentpb.RegisterCompletionServer(serv, &mockCompletion) talentpb.RegisterEventServiceServer(serv, &mockEvent) talentpb.RegisterJobServiceServer(serv, &mockJob) talentpb.RegisterProfileServiceServer(serv, &mockProfile) talentpb.RegisterTenantServiceServer(serv, &mockTenant) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestApplicationServiceCreateApplication(t *testing.T) { var name string = "name3373707" var externalId string = "externalId-1153075697" var profile string = "profile-309425751" var job string = "job105405" var company string = "company950484093" var outcomeNotes string = "outcomeNotes-355961964" var jobTitleSnippet string = "jobTitleSnippet-1100512972" var expectedResponse = &talentpb.Application{ Name: name, ExternalId: externalId, Profile: profile, Job: job, Company: company, OutcomeNotes: outcomeNotes, JobTitleSnippet: jobTitleSnippet, } mockApplication.err = nil mockApplication.reqs = nil mockApplication.resps = append(mockApplication.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s/profiles/%s", "[PROJECT]", "[TENANT]", "[PROFILE]") var application *talentpb.Application = &talentpb.Application{} var request = &talentpb.CreateApplicationRequest{ Parent: formattedParent, Application: application, } c, err := NewApplicationClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateApplication(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockApplication.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestApplicationServiceCreateApplicationError(t *testing.T) { errCode := codes.PermissionDenied mockApplication.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s/profiles/%s", "[PROJECT]", "[TENANT]", "[PROFILE]") var application *talentpb.Application = &talentpb.Application{} var request = &talentpb.CreateApplicationRequest{ Parent: formattedParent, Application: application, } c, err := NewApplicationClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateApplication(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestApplicationServiceGetApplication(t *testing.T) { var name2 string = "name2-1052831874" var externalId string = "externalId-1153075697" var profile string = "profile-309425751" var job string = "job105405" var company string = "company950484093" var outcomeNotes string = "outcomeNotes-355961964" var jobTitleSnippet string = "jobTitleSnippet-1100512972" var expectedResponse = &talentpb.Application{ Name: name2, ExternalId: externalId, Profile: profile, Job: job, Company: company, OutcomeNotes: outcomeNotes, JobTitleSnippet: jobTitleSnippet, } mockApplication.err = nil mockApplication.reqs = nil mockApplication.resps = append(mockApplication.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/tenants/%s/profiles/%s/applications/%s", "[PROJECT]", "[TENANT]", "[PROFILE]", "[APPLICATION]") var request = &talentpb.GetApplicationRequest{ Name: formattedName, } c, err := NewApplicationClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetApplication(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockApplication.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestApplicationServiceGetApplicationError(t *testing.T) { errCode := codes.PermissionDenied mockApplication.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/tenants/%s/profiles/%s/applications/%s", "[PROJECT]", "[TENANT]", "[PROFILE]", "[APPLICATION]") var request = &talentpb.GetApplicationRequest{ Name: formattedName, } c, err := NewApplicationClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetApplication(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestApplicationServiceUpdateApplication(t *testing.T) { var name string = "name3373707" var externalId string = "externalId-1153075697" var profile string = "profile-309425751" var job string = "job105405" var company string = "company950484093" var outcomeNotes string = "outcomeNotes-355961964" var jobTitleSnippet string = "jobTitleSnippet-1100512972" var expectedResponse = &talentpb.Application{ Name: name, ExternalId: externalId, Profile: profile, Job: job, Company: company, OutcomeNotes: outcomeNotes, JobTitleSnippet: jobTitleSnippet, } mockApplication.err = nil mockApplication.reqs = nil mockApplication.resps = append(mockApplication.resps[:0], expectedResponse) var application *talentpb.Application = &talentpb.Application{} var request = &talentpb.UpdateApplicationRequest{ Application: application, } c, err := NewApplicationClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateApplication(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockApplication.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestApplicationServiceUpdateApplicationError(t *testing.T) { errCode := codes.PermissionDenied mockApplication.err = gstatus.Error(errCode, "test error") var application *talentpb.Application = &talentpb.Application{} var request = &talentpb.UpdateApplicationRequest{ Application: application, } c, err := NewApplicationClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateApplication(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestApplicationServiceDeleteApplication(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockApplication.err = nil mockApplication.reqs = nil mockApplication.resps = append(mockApplication.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/tenants/%s/profiles/%s/applications/%s", "[PROJECT]", "[TENANT]", "[PROFILE]", "[APPLICATION]") var request = &talentpb.DeleteApplicationRequest{ Name: formattedName, } c, err := NewApplicationClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteApplication(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockApplication.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestApplicationServiceDeleteApplicationError(t *testing.T) { errCode := codes.PermissionDenied mockApplication.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/tenants/%s/profiles/%s/applications/%s", "[PROJECT]", "[TENANT]", "[PROFILE]", "[APPLICATION]") var request = &talentpb.DeleteApplicationRequest{ Name: formattedName, } c, err := NewApplicationClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteApplication(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestApplicationServiceListApplications(t *testing.T) { var nextPageToken string = "" var applicationsElement *talentpb.Application = &talentpb.Application{} var applications = []*talentpb.Application{applicationsElement} var expectedResponse = &talentpb.ListApplicationsResponse{ NextPageToken: nextPageToken, Applications: applications, } mockApplication.err = nil mockApplication.reqs = nil mockApplication.resps = append(mockApplication.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s/profiles/%s", "[PROJECT]", "[TENANT]", "[PROFILE]") var request = &talentpb.ListApplicationsRequest{ Parent: formattedParent, } c, err := NewApplicationClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListApplications(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockApplication.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Applications[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestApplicationServiceListApplicationsError(t *testing.T) { errCode := codes.PermissionDenied mockApplication.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s/profiles/%s", "[PROJECT]", "[TENANT]", "[PROFILE]") var request = &talentpb.ListApplicationsRequest{ Parent: formattedParent, } c, err := NewApplicationClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListApplications(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCompanyServiceCreateCompany(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var externalId string = "externalId-1153075697" var headquartersAddress string = "headquartersAddress-1879520036" var hiringAgency bool = false var eeoText string = "eeoText-1652097123" var websiteUri string = "websiteUri-2118185016" var careerSiteUri string = "careerSiteUri1223331861" var imageUri string = "imageUri-877823864" var suspended bool = false var expectedResponse = &talentpb.Company{ Name: name, DisplayName: displayName, ExternalId: externalId, HeadquartersAddress: headquartersAddress, HiringAgency: hiringAgency, EeoText: eeoText, WebsiteUri: websiteUri, CareerSiteUri: careerSiteUri, ImageUri: imageUri, Suspended: suspended, } mockCompany.err = nil mockCompany.reqs = nil mockCompany.resps = append(mockCompany.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]") var company *talentpb.Company = &talentpb.Company{} var request = &talentpb.CreateCompanyRequest{ Parent: formattedParent, Company: company, } c, err := NewCompanyClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateCompany(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCompany.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCompanyServiceCreateCompanyError(t *testing.T) { errCode := codes.PermissionDenied mockCompany.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]") var company *talentpb.Company = &talentpb.Company{} var request = &talentpb.CreateCompanyRequest{ Parent: formattedParent, Company: company, } c, err := NewCompanyClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateCompany(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCompanyServiceGetCompany(t *testing.T) { var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var externalId string = "externalId-1153075697" var headquartersAddress string = "headquartersAddress-1879520036" var hiringAgency bool = false var eeoText string = "eeoText-1652097123" var websiteUri string = "websiteUri-2118185016" var careerSiteUri string = "careerSiteUri1223331861" var imageUri string = "imageUri-877823864" var suspended bool = false var expectedResponse = &talentpb.Company{ Name: name2, DisplayName: displayName, ExternalId: externalId, HeadquartersAddress: headquartersAddress, HiringAgency: hiringAgency, EeoText: eeoText, WebsiteUri: websiteUri, CareerSiteUri: careerSiteUri, ImageUri: imageUri, Suspended: suspended, } mockCompany.err = nil mockCompany.reqs = nil mockCompany.resps = append(mockCompany.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/tenants/%s/companies/%s", "[PROJECT]", "[TENANT]", "[COMPANY]") var request = &talentpb.GetCompanyRequest{ Name: formattedName, } c, err := NewCompanyClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetCompany(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCompany.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCompanyServiceGetCompanyError(t *testing.T) { errCode := codes.PermissionDenied mockCompany.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/tenants/%s/companies/%s", "[PROJECT]", "[TENANT]", "[COMPANY]") var request = &talentpb.GetCompanyRequest{ Name: formattedName, } c, err := NewCompanyClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetCompany(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCompanyServiceUpdateCompany(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var externalId string = "externalId-1153075697" var headquartersAddress string = "headquartersAddress-1879520036" var hiringAgency bool = false var eeoText string = "eeoText-1652097123" var websiteUri string = "websiteUri-2118185016" var careerSiteUri string = "careerSiteUri1223331861" var imageUri string = "imageUri-877823864" var suspended bool = false var expectedResponse = &talentpb.Company{ Name: name, DisplayName: displayName, ExternalId: externalId, HeadquartersAddress: headquartersAddress, HiringAgency: hiringAgency, EeoText: eeoText, WebsiteUri: websiteUri, CareerSiteUri: careerSiteUri, ImageUri: imageUri, Suspended: suspended, } mockCompany.err = nil mockCompany.reqs = nil mockCompany.resps = append(mockCompany.resps[:0], expectedResponse) var company *talentpb.Company = &talentpb.Company{} var request = &talentpb.UpdateCompanyRequest{ Company: company, } c, err := NewCompanyClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateCompany(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCompany.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCompanyServiceUpdateCompanyError(t *testing.T) { errCode := codes.PermissionDenied mockCompany.err = gstatus.Error(errCode, "test error") var company *talentpb.Company = &talentpb.Company{} var request = &talentpb.UpdateCompanyRequest{ Company: company, } c, err := NewCompanyClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateCompany(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCompanyServiceDeleteCompany(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockCompany.err = nil mockCompany.reqs = nil mockCompany.resps = append(mockCompany.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/tenants/%s/companies/%s", "[PROJECT]", "[TENANT]", "[COMPANY]") var request = &talentpb.DeleteCompanyRequest{ Name: formattedName, } c, err := NewCompanyClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteCompany(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCompany.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestCompanyServiceDeleteCompanyError(t *testing.T) { errCode := codes.PermissionDenied mockCompany.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/tenants/%s/companies/%s", "[PROJECT]", "[TENANT]", "[COMPANY]") var request = &talentpb.DeleteCompanyRequest{ Name: formattedName, } c, err := NewCompanyClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteCompany(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestCompanyServiceListCompanies(t *testing.T) { var nextPageToken string = "" var companiesElement *talentpb.Company = &talentpb.Company{} var companies = []*talentpb.Company{companiesElement} var expectedResponse = &talentpb.ListCompaniesResponse{ NextPageToken: nextPageToken, Companies: companies, } mockCompany.err = nil mockCompany.reqs = nil mockCompany.resps = append(mockCompany.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]") var request = &talentpb.ListCompaniesRequest{ Parent: formattedParent, } c, err := NewCompanyClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListCompanies(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockCompany.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Companies[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCompanyServiceListCompaniesError(t *testing.T) { errCode := codes.PermissionDenied mockCompany.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]") var request = &talentpb.ListCompaniesRequest{ Parent: formattedParent, } c, err := NewCompanyClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListCompanies(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestCompletionCompleteQuery(t *testing.T) { var expectedResponse *talentpb.CompleteQueryResponse = &talentpb.CompleteQueryResponse{} mockCompletion.err = nil mockCompletion.reqs = nil mockCompletion.resps = append(mockCompletion.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]") var query string = "query107944136" var pageSize int32 = 883849137 var request = &talentpb.CompleteQueryRequest{ Parent: formattedParent, Query: query, PageSize: pageSize, } c, err := NewCompletionClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CompleteQuery(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockCompletion.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestCompletionCompleteQueryError(t *testing.T) { errCode := codes.PermissionDenied mockCompletion.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]") var query string = "query107944136" var pageSize int32 = 883849137 var request = &talentpb.CompleteQueryRequest{ Parent: formattedParent, Query: query, PageSize: pageSize, } c, err := NewCompletionClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CompleteQuery(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestEventServiceCreateClientEvent(t *testing.T) { var requestId string = "requestId37109963" var eventId string = "eventId278118624" var eventNotes string = "eventNotes445073628" var expectedResponse = &talentpb.ClientEvent{ RequestId: requestId, EventId: eventId, EventNotes: eventNotes, } mockEvent.err = nil mockEvent.reqs = nil mockEvent.resps = append(mockEvent.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]") var clientEvent *talentpb.ClientEvent = &talentpb.ClientEvent{} var request = &talentpb.CreateClientEventRequest{ Parent: formattedParent, ClientEvent: clientEvent, } c, err := NewEventClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateClientEvent(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockEvent.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestEventServiceCreateClientEventError(t *testing.T) { errCode := codes.PermissionDenied mockEvent.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]") var clientEvent *talentpb.ClientEvent = &talentpb.ClientEvent{} var request = &talentpb.CreateClientEventRequest{ Parent: formattedParent, ClientEvent: clientEvent, } c, err := NewEventClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateClientEvent(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestJobServiceCreateJob(t *testing.T) { var name string = "name3373707" var company string = "company950484093" var requisitionId string = "requisitionId980224926" var title string = "title110371416" var description string = "description-1724546052" var department string = "department848184146" var incentives string = "incentives-1262874520" var languageCode string = "languageCode-412800396" var promotionValue int32 = 353413845 var qualifications string = "qualifications1903501412" var responsibilities string = "responsibilities-926952660" var companyDisplayName string = "companyDisplayName1982424170" var expectedResponse = &talentpb.Job{ Name: name, Company: company, RequisitionId: requisitionId, Title: title, Description: description, Department: department, Incentives: incentives, LanguageCode: languageCode, PromotionValue: promotionValue, Qualifications: qualifications, Responsibilities: responsibilities, CompanyDisplayName: companyDisplayName, } mockJob.err = nil mockJob.reqs = nil mockJob.resps = append(mockJob.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]") var job *talentpb.Job = &talentpb.Job{} var request = &talentpb.CreateJobRequest{ Parent: formattedParent, Job: job, } c, err := NewJobClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateJob(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockJob.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestJobServiceCreateJobError(t *testing.T) { errCode := codes.PermissionDenied mockJob.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]") var job *talentpb.Job = &talentpb.Job{} var request = &talentpb.CreateJobRequest{ Parent: formattedParent, Job: job, } c, err := NewJobClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateJob(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestJobServiceGetJob(t *testing.T) { var name2 string = "name2-1052831874" var company string = "company950484093" var requisitionId string = "requisitionId980224926" var title string = "title110371416" var description string = "description-1724546052" var department string = "department848184146" var incentives string = "incentives-1262874520" var languageCode string = "languageCode-412800396" var promotionValue int32 = 353413845 var qualifications string = "qualifications1903501412" var responsibilities string = "responsibilities-926952660" var companyDisplayName string = "companyDisplayName1982424170" var expectedResponse = &talentpb.Job{ Name: name2, Company: company, RequisitionId: requisitionId, Title: title, Description: description, Department: department, Incentives: incentives, LanguageCode: languageCode, PromotionValue: promotionValue, Qualifications: qualifications, Responsibilities: responsibilities, CompanyDisplayName: companyDisplayName, } mockJob.err = nil mockJob.reqs = nil mockJob.resps = append(mockJob.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/tenants/%s/jobs/%s", "[PROJECT]", "[TENANT]", "[JOBS]") var request = &talentpb.GetJobRequest{ Name: formattedName, } c, err := NewJobClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetJob(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockJob.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestJobServiceGetJobError(t *testing.T) { errCode := codes.PermissionDenied mockJob.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/tenants/%s/jobs/%s", "[PROJECT]", "[TENANT]", "[JOBS]") var request = &talentpb.GetJobRequest{ Name: formattedName, } c, err := NewJobClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetJob(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestJobServiceUpdateJob(t *testing.T) { var name string = "name3373707" var company string = "company950484093" var requisitionId string = "requisitionId980224926" var title string = "title110371416" var description string = "description-1724546052" var department string = "department848184146" var incentives string = "incentives-1262874520" var languageCode string = "languageCode-412800396" var promotionValue int32 = 353413845 var qualifications string = "qualifications1903501412" var responsibilities string = "responsibilities-926952660" var companyDisplayName string = "companyDisplayName1982424170" var expectedResponse = &talentpb.Job{ Name: name, Company: company, RequisitionId: requisitionId, Title: title, Description: description, Department: department, Incentives: incentives, LanguageCode: languageCode, PromotionValue: promotionValue, Qualifications: qualifications, Responsibilities: responsibilities, CompanyDisplayName: companyDisplayName, } mockJob.err = nil mockJob.reqs = nil mockJob.resps = append(mockJob.resps[:0], expectedResponse) var job *talentpb.Job = &talentpb.Job{} var request = &talentpb.UpdateJobRequest{ Job: job, } c, err := NewJobClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateJob(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockJob.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestJobServiceUpdateJobError(t *testing.T) { errCode := codes.PermissionDenied mockJob.err = gstatus.Error(errCode, "test error") var job *talentpb.Job = &talentpb.Job{} var request = &talentpb.UpdateJobRequest{ Job: job, } c, err := NewJobClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateJob(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestJobServiceDeleteJob(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockJob.err = nil mockJob.reqs = nil mockJob.resps = append(mockJob.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/tenants/%s/jobs/%s", "[PROJECT]", "[TENANT]", "[JOBS]") var request = &talentpb.DeleteJobRequest{ Name: formattedName, } c, err := NewJobClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteJob(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockJob.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestJobServiceDeleteJobError(t *testing.T) { errCode := codes.PermissionDenied mockJob.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/tenants/%s/jobs/%s", "[PROJECT]", "[TENANT]", "[JOBS]") var request = &talentpb.DeleteJobRequest{ Name: formattedName, } c, err := NewJobClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteJob(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestJobServiceListJobs(t *testing.T) { var nextPageToken string = "" var jobsElement *talentpb.Job = &talentpb.Job{} var jobs = []*talentpb.Job{jobsElement} var expectedResponse = &talentpb.ListJobsResponse{ NextPageToken: nextPageToken, Jobs: jobs, } mockJob.err = nil mockJob.reqs = nil mockJob.resps = append(mockJob.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]") var filter string = "filter-1274492040" var request = &talentpb.ListJobsRequest{ Parent: formattedParent, Filter: filter, } c, err := NewJobClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListJobs(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockJob.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Jobs[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestJobServiceListJobsError(t *testing.T) { errCode := codes.PermissionDenied mockJob.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]") var filter string = "filter-1274492040" var request = &talentpb.ListJobsRequest{ Parent: formattedParent, Filter: filter, } c, err := NewJobClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListJobs(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestJobServiceBatchDeleteJobs(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockJob.err = nil mockJob.reqs = nil mockJob.resps = append(mockJob.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]") var filter string = "filter-1274492040" var request = &talentpb.BatchDeleteJobsRequest{ Parent: formattedParent, Filter: filter, } c, err := NewJobClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.BatchDeleteJobs(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockJob.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestJobServiceBatchDeleteJobsError(t *testing.T) { errCode := codes.PermissionDenied mockJob.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]") var filter string = "filter-1274492040" var request = &talentpb.BatchDeleteJobsRequest{ Parent: formattedParent, Filter: filter, } c, err := NewJobClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.BatchDeleteJobs(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestJobServiceSearchJobs(t *testing.T) { var nextPageToken string = "" var estimatedTotalSize int32 = 1882144769 var totalSize int32 = 705419236 var broadenedQueryJobsCount int32 = 1432104658 var matchingJobsElement *talentpb.SearchJobsResponse_MatchingJob = &talentpb.SearchJobsResponse_MatchingJob{} var matchingJobs = []*talentpb.SearchJobsResponse_MatchingJob{matchingJobsElement} var expectedResponse = &talentpb.SearchJobsResponse{ NextPageToken: nextPageToken, EstimatedTotalSize: estimatedTotalSize, TotalSize: totalSize, BroadenedQueryJobsCount: broadenedQueryJobsCount, MatchingJobs: matchingJobs, } mockJob.err = nil mockJob.reqs = nil mockJob.resps = append(mockJob.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]") var requestMetadata *talentpb.RequestMetadata = &talentpb.RequestMetadata{} var request = &talentpb.SearchJobsRequest{ Parent: formattedParent, RequestMetadata: requestMetadata, } c, err := NewJobClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SearchJobs(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockJob.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.MatchingJobs[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestJobServiceSearchJobsError(t *testing.T) { errCode := codes.PermissionDenied mockJob.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]") var requestMetadata *talentpb.RequestMetadata = &talentpb.RequestMetadata{} var request = &talentpb.SearchJobsRequest{ Parent: formattedParent, RequestMetadata: requestMetadata, } c, err := NewJobClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SearchJobs(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestJobServiceSearchJobsForAlert(t *testing.T) { var nextPageToken string = "" var estimatedTotalSize int32 = 1882144769 var totalSize int32 = 705419236 var broadenedQueryJobsCount int32 = 1432104658 var matchingJobsElement *talentpb.SearchJobsResponse_MatchingJob = &talentpb.SearchJobsResponse_MatchingJob{} var matchingJobs = []*talentpb.SearchJobsResponse_MatchingJob{matchingJobsElement} var expectedResponse = &talentpb.SearchJobsResponse{ NextPageToken: nextPageToken, EstimatedTotalSize: estimatedTotalSize, TotalSize: totalSize, BroadenedQueryJobsCount: broadenedQueryJobsCount, MatchingJobs: matchingJobs, } mockJob.err = nil mockJob.reqs = nil mockJob.resps = append(mockJob.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]") var requestMetadata *talentpb.RequestMetadata = &talentpb.RequestMetadata{} var request = &talentpb.SearchJobsRequest{ Parent: formattedParent, RequestMetadata: requestMetadata, } c, err := NewJobClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SearchJobsForAlert(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockJob.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.MatchingJobs[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestJobServiceSearchJobsForAlertError(t *testing.T) { errCode := codes.PermissionDenied mockJob.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]") var requestMetadata *talentpb.RequestMetadata = &talentpb.RequestMetadata{} var request = &talentpb.SearchJobsRequest{ Parent: formattedParent, RequestMetadata: requestMetadata, } c, err := NewJobClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SearchJobsForAlert(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestJobServiceBatchCreateJobs(t *testing.T) { var expectedResponse *talentpb.JobOperationResult = &talentpb.JobOperationResult{} mockJob.err = nil mockJob.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockJob.resps = append(mockJob.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]") var jobs []*talentpb.Job = nil var request = &talentpb.BatchCreateJobsRequest{ Parent: formattedParent, Jobs: jobs, } c, err := NewJobClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.BatchCreateJobs(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockJob.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestJobServiceBatchCreateJobsError(t *testing.T) { errCode := codes.PermissionDenied mockJob.err = nil mockJob.resps = append(mockJob.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]") var jobs []*talentpb.Job = nil var request = &talentpb.BatchCreateJobsRequest{ Parent: formattedParent, Jobs: jobs, } c, err := NewJobClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.BatchCreateJobs(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestJobServiceBatchUpdateJobs(t *testing.T) { var expectedResponse *talentpb.JobOperationResult = &talentpb.JobOperationResult{} mockJob.err = nil mockJob.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockJob.resps = append(mockJob.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]") var jobs []*talentpb.Job = nil var request = &talentpb.BatchUpdateJobsRequest{ Parent: formattedParent, Jobs: jobs, } c, err := NewJobClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.BatchUpdateJobs(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockJob.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestJobServiceBatchUpdateJobsError(t *testing.T) { errCode := codes.PermissionDenied mockJob.err = nil mockJob.resps = append(mockJob.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]") var jobs []*talentpb.Job = nil var request = &talentpb.BatchUpdateJobsRequest{ Parent: formattedParent, Jobs: jobs, } c, err := NewJobClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.BatchUpdateJobs(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestProfileServiceListProfiles(t *testing.T) { var nextPageToken string = "" var profilesElement *talentpb.Profile = &talentpb.Profile{} var profiles = []*talentpb.Profile{profilesElement} var expectedResponse = &talentpb.ListProfilesResponse{ NextPageToken: nextPageToken, Profiles: profiles, } mockProfile.err = nil mockProfile.reqs = nil mockProfile.resps = append(mockProfile.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]") var request = &talentpb.ListProfilesRequest{ Parent: formattedParent, } c, err := NewProfileClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListProfiles(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockProfile.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Profiles[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestProfileServiceListProfilesError(t *testing.T) { errCode := codes.PermissionDenied mockProfile.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]") var request = &talentpb.ListProfilesRequest{ Parent: formattedParent, } c, err := NewProfileClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListProfiles(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestProfileServiceCreateProfile(t *testing.T) { var name string = "name3373707" var externalId string = "externalId-1153075697" var source string = "source-896505829" var uri string = "uri116076" var groupId string = "groupId506361563" var processed bool = true var keywordSnippet string = "keywordSnippet1325317319" var expectedResponse = &talentpb.Profile{ Name: name, ExternalId: externalId, Source: source, Uri: uri, GroupId: groupId, Processed: processed, KeywordSnippet: keywordSnippet, } mockProfile.err = nil mockProfile.reqs = nil mockProfile.resps = append(mockProfile.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]") var profile *talentpb.Profile = &talentpb.Profile{} var request = &talentpb.CreateProfileRequest{ Parent: formattedParent, Profile: profile, } c, err := NewProfileClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateProfile(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockProfile.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestProfileServiceCreateProfileError(t *testing.T) { errCode := codes.PermissionDenied mockProfile.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]") var profile *talentpb.Profile = &talentpb.Profile{} var request = &talentpb.CreateProfileRequest{ Parent: formattedParent, Profile: profile, } c, err := NewProfileClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateProfile(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestProfileServiceGetProfile(t *testing.T) { var name2 string = "name2-1052831874" var externalId string = "externalId-1153075697" var source string = "source-896505829" var uri string = "uri116076" var groupId string = "groupId506361563" var processed bool = true var keywordSnippet string = "keywordSnippet1325317319" var expectedResponse = &talentpb.Profile{ Name: name2, ExternalId: externalId, Source: source, Uri: uri, GroupId: groupId, Processed: processed, KeywordSnippet: keywordSnippet, } mockProfile.err = nil mockProfile.reqs = nil mockProfile.resps = append(mockProfile.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/tenants/%s/profiles/%s", "[PROJECT]", "[TENANT]", "[PROFILE]") var request = &talentpb.GetProfileRequest{ Name: formattedName, } c, err := NewProfileClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetProfile(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockProfile.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestProfileServiceGetProfileError(t *testing.T) { errCode := codes.PermissionDenied mockProfile.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/tenants/%s/profiles/%s", "[PROJECT]", "[TENANT]", "[PROFILE]") var request = &talentpb.GetProfileRequest{ Name: formattedName, } c, err := NewProfileClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetProfile(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestProfileServiceUpdateProfile(t *testing.T) { var name string = "name3373707" var externalId string = "externalId-1153075697" var source string = "source-896505829" var uri string = "uri116076" var groupId string = "groupId506361563" var processed bool = true var keywordSnippet string = "keywordSnippet1325317319" var expectedResponse = &talentpb.Profile{ Name: name, ExternalId: externalId, Source: source, Uri: uri, GroupId: groupId, Processed: processed, KeywordSnippet: keywordSnippet, } mockProfile.err = nil mockProfile.reqs = nil mockProfile.resps = append(mockProfile.resps[:0], expectedResponse) var profile *talentpb.Profile = &talentpb.Profile{} var request = &talentpb.UpdateProfileRequest{ Profile: profile, } c, err := NewProfileClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateProfile(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockProfile.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestProfileServiceUpdateProfileError(t *testing.T) { errCode := codes.PermissionDenied mockProfile.err = gstatus.Error(errCode, "test error") var profile *talentpb.Profile = &talentpb.Profile{} var request = &talentpb.UpdateProfileRequest{ Profile: profile, } c, err := NewProfileClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateProfile(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestProfileServiceDeleteProfile(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockProfile.err = nil mockProfile.reqs = nil mockProfile.resps = append(mockProfile.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/tenants/%s/profiles/%s", "[PROJECT]", "[TENANT]", "[PROFILE]") var request = &talentpb.DeleteProfileRequest{ Name: formattedName, } c, err := NewProfileClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteProfile(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockProfile.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestProfileServiceDeleteProfileError(t *testing.T) { errCode := codes.PermissionDenied mockProfile.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/tenants/%s/profiles/%s", "[PROJECT]", "[TENANT]", "[PROFILE]") var request = &talentpb.DeleteProfileRequest{ Name: formattedName, } c, err := NewProfileClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteProfile(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestProfileServiceSearchProfiles(t *testing.T) { var estimatedTotalSize int64 = 1882144769 var nextPageToken string = "" var resultSetId string = "resultSetId-770306950" var summarizedProfilesElement *talentpb.SummarizedProfile = &talentpb.SummarizedProfile{} var summarizedProfiles = []*talentpb.SummarizedProfile{summarizedProfilesElement} var expectedResponse = &talentpb.SearchProfilesResponse{ EstimatedTotalSize: estimatedTotalSize, NextPageToken: nextPageToken, ResultSetId: resultSetId, SummarizedProfiles: summarizedProfiles, } mockProfile.err = nil mockProfile.reqs = nil mockProfile.resps = append(mockProfile.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]") var requestMetadata *talentpb.RequestMetadata = &talentpb.RequestMetadata{} var request = &talentpb.SearchProfilesRequest{ Parent: formattedParent, RequestMetadata: requestMetadata, } c, err := NewProfileClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SearchProfiles(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockProfile.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.SummarizedProfiles[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestProfileServiceSearchProfilesError(t *testing.T) { errCode := codes.PermissionDenied mockProfile.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]") var requestMetadata *talentpb.RequestMetadata = &talentpb.RequestMetadata{} var request = &talentpb.SearchProfilesRequest{ Parent: formattedParent, RequestMetadata: requestMetadata, } c, err := NewProfileClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SearchProfiles(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestTenantServiceCreateTenant(t *testing.T) { var name string = "name3373707" var externalId string = "externalId-1153075697" var expectedResponse = &talentpb.Tenant{ Name: name, ExternalId: externalId, } mockTenant.err = nil mockTenant.reqs = nil mockTenant.resps = append(mockTenant.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var tenant *talentpb.Tenant = &talentpb.Tenant{} var request = &talentpb.CreateTenantRequest{ Parent: formattedParent, Tenant: tenant, } c, err := NewTenantClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateTenant(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockTenant.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestTenantServiceCreateTenantError(t *testing.T) { errCode := codes.PermissionDenied mockTenant.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var tenant *talentpb.Tenant = &talentpb.Tenant{} var request = &talentpb.CreateTenantRequest{ Parent: formattedParent, Tenant: tenant, } c, err := NewTenantClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateTenant(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestTenantServiceGetTenant(t *testing.T) { var name2 string = "name2-1052831874" var externalId string = "externalId-1153075697" var expectedResponse = &talentpb.Tenant{ Name: name2, ExternalId: externalId, } mockTenant.err = nil mockTenant.reqs = nil mockTenant.resps = append(mockTenant.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]") var request = &talentpb.GetTenantRequest{ Name: formattedName, } c, err := NewTenantClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetTenant(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockTenant.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestTenantServiceGetTenantError(t *testing.T) { errCode := codes.PermissionDenied mockTenant.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]") var request = &talentpb.GetTenantRequest{ Name: formattedName, } c, err := NewTenantClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetTenant(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestTenantServiceUpdateTenant(t *testing.T) { var name string = "name3373707" var externalId string = "externalId-1153075697" var expectedResponse = &talentpb.Tenant{ Name: name, ExternalId: externalId, } mockTenant.err = nil mockTenant.reqs = nil mockTenant.resps = append(mockTenant.resps[:0], expectedResponse) var tenant *talentpb.Tenant = &talentpb.Tenant{} var request = &talentpb.UpdateTenantRequest{ Tenant: tenant, } c, err := NewTenantClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateTenant(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockTenant.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestTenantServiceUpdateTenantError(t *testing.T) { errCode := codes.PermissionDenied mockTenant.err = gstatus.Error(errCode, "test error") var tenant *talentpb.Tenant = &talentpb.Tenant{} var request = &talentpb.UpdateTenantRequest{ Tenant: tenant, } c, err := NewTenantClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateTenant(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestTenantServiceDeleteTenant(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockTenant.err = nil mockTenant.reqs = nil mockTenant.resps = append(mockTenant.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]") var request = &talentpb.DeleteTenantRequest{ Name: formattedName, } c, err := NewTenantClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteTenant(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockTenant.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestTenantServiceDeleteTenantError(t *testing.T) { errCode := codes.PermissionDenied mockTenant.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]") var request = &talentpb.DeleteTenantRequest{ Name: formattedName, } c, err := NewTenantClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteTenant(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestTenantServiceListTenants(t *testing.T) { var nextPageToken string = "" var tenantsElement *talentpb.Tenant = &talentpb.Tenant{} var tenants = []*talentpb.Tenant{tenantsElement} var expectedResponse = &talentpb.ListTenantsResponse{ NextPageToken: nextPageToken, Tenants: tenants, } mockTenant.err = nil mockTenant.reqs = nil mockTenant.resps = append(mockTenant.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &talentpb.ListTenantsRequest{ Parent: formattedParent, } c, err := NewTenantClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListTenants(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockTenant.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Tenants[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestTenantServiceListTenantsError(t *testing.T) { errCode := codes.PermissionDenied mockTenant.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]") var request = &talentpb.ListTenantsRequest{ Parent: formattedParent, } c, err := NewTenantClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListTenants(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/talent/apiv4beta1/profile_client.go000066400000000000000000000325511356504100700233520ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package talent import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" talentpb "google.golang.org/genproto/googleapis/cloud/talent/v4beta1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // ProfileCallOptions contains the retry settings for each method of ProfileClient. type ProfileCallOptions struct { ListProfiles []gax.CallOption CreateProfile []gax.CallOption GetProfile []gax.CallOption UpdateProfile []gax.CallOption DeleteProfile []gax.CallOption SearchProfiles []gax.CallOption } func defaultProfileClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("jobs.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultProfileCallOptions() *ProfileCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &ProfileCallOptions{ ListProfiles: retry[[2]string{"default", "idempotent"}], CreateProfile: retry[[2]string{"default", "non_idempotent"}], GetProfile: retry[[2]string{"default", "idempotent"}], UpdateProfile: retry[[2]string{"default", "non_idempotent"}], DeleteProfile: retry[[2]string{"default", "idempotent"}], SearchProfiles: retry[[2]string{"default", "non_idempotent"}], } } // ProfileClient is a client for interacting with Cloud Talent Solution API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type ProfileClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. profileClient talentpb.ProfileServiceClient // The call options for this service. CallOptions *ProfileCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewProfileClient creates a new profile service client. // // A service that handles profile management, including profile CRUD, // enumeration and search. func NewProfileClient(ctx context.Context, opts ...option.ClientOption) (*ProfileClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultProfileClientOptions(), opts...)...) if err != nil { return nil, err } c := &ProfileClient{ conn: conn, CallOptions: defaultProfileCallOptions(), profileClient: talentpb.NewProfileServiceClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *ProfileClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *ProfileClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *ProfileClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // ListProfiles lists profiles by filter. The order is unspecified. func (c *ProfileClient) ListProfiles(ctx context.Context, req *talentpb.ListProfilesRequest, opts ...gax.CallOption) *ProfileIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListProfiles[0:len(c.CallOptions.ListProfiles):len(c.CallOptions.ListProfiles)], opts...) it := &ProfileIterator{} req = proto.Clone(req).(*talentpb.ListProfilesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*talentpb.Profile, string, error) { var resp *talentpb.ListProfilesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.profileClient.ListProfiles(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Profiles, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // CreateProfile creates and returns a new profile. func (c *ProfileClient) CreateProfile(ctx context.Context, req *talentpb.CreateProfileRequest, opts ...gax.CallOption) (*talentpb.Profile, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateProfile[0:len(c.CallOptions.CreateProfile):len(c.CallOptions.CreateProfile)], opts...) var resp *talentpb.Profile err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.profileClient.CreateProfile(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetProfile gets the specified profile. func (c *ProfileClient) GetProfile(ctx context.Context, req *talentpb.GetProfileRequest, opts ...gax.CallOption) (*talentpb.Profile, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetProfile[0:len(c.CallOptions.GetProfile):len(c.CallOptions.GetProfile)], opts...) var resp *talentpb.Profile err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.profileClient.GetProfile(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateProfile updates the specified profile and returns the updated result. func (c *ProfileClient) UpdateProfile(ctx context.Context, req *talentpb.UpdateProfileRequest, opts ...gax.CallOption) (*talentpb.Profile, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "profile.name", url.QueryEscape(req.GetProfile().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateProfile[0:len(c.CallOptions.UpdateProfile):len(c.CallOptions.UpdateProfile)], opts...) var resp *talentpb.Profile err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.profileClient.UpdateProfile(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteProfile deletes the specified profile. // Prerequisite: The profile has no associated applications or assignments // associated. func (c *ProfileClient) DeleteProfile(ctx context.Context, req *talentpb.DeleteProfileRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteProfile[0:len(c.CallOptions.DeleteProfile):len(c.CallOptions.DeleteProfile)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.profileClient.DeleteProfile(ctx, req, settings.GRPC...) return err }, opts...) return err } // SearchProfiles searches for profiles within a tenant. // // For example, search by raw queries "software engineer in Mountain View" or // search by structured filters (location filter, education filter, etc.). // // See // [SearchProfilesRequest][google.cloud.talent.v4beta1.SearchProfilesRequest] // for more information. func (c *ProfileClient) SearchProfiles(ctx context.Context, req *talentpb.SearchProfilesRequest, opts ...gax.CallOption) *SummarizedProfileIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.SearchProfiles[0:len(c.CallOptions.SearchProfiles):len(c.CallOptions.SearchProfiles)], opts...) it := &SummarizedProfileIterator{} req = proto.Clone(req).(*talentpb.SearchProfilesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*talentpb.SummarizedProfile, string, error) { var resp *talentpb.SearchProfilesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.profileClient.SearchProfiles(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.SummarizedProfiles, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // ProfileIterator manages a stream of *talentpb.Profile. type ProfileIterator struct { items []*talentpb.Profile pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*talentpb.Profile, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *ProfileIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *ProfileIterator) Next() (*talentpb.Profile, error) { var item *talentpb.Profile if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *ProfileIterator) bufLen() int { return len(it.items) } func (it *ProfileIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // SummarizedProfileIterator manages a stream of *talentpb.SummarizedProfile. type SummarizedProfileIterator struct { items []*talentpb.SummarizedProfile pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*talentpb.SummarizedProfile, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *SummarizedProfileIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *SummarizedProfileIterator) Next() (*talentpb.SummarizedProfile, error) { var item *talentpb.SummarizedProfile if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *SummarizedProfileIterator) bufLen() int { return len(it.items) } func (it *SummarizedProfileIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/talent/apiv4beta1/profile_client_example_test.go000066400000000000000000000063111356504100700261170ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package talent_test import ( "context" talent "cloud.google.com/go/talent/apiv4beta1" "google.golang.org/api/iterator" talentpb "google.golang.org/genproto/googleapis/cloud/talent/v4beta1" ) func ExampleNewProfileClient() { ctx := context.Background() c, err := talent.NewProfileClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleProfileClient_ListProfiles() { ctx := context.Background() c, err := talent.NewProfileClient(ctx) if err != nil { // TODO: Handle error. } req := &talentpb.ListProfilesRequest{ // TODO: Fill request struct fields. } it := c.ListProfiles(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleProfileClient_CreateProfile() { ctx := context.Background() c, err := talent.NewProfileClient(ctx) if err != nil { // TODO: Handle error. } req := &talentpb.CreateProfileRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateProfile(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleProfileClient_GetProfile() { ctx := context.Background() c, err := talent.NewProfileClient(ctx) if err != nil { // TODO: Handle error. } req := &talentpb.GetProfileRequest{ // TODO: Fill request struct fields. } resp, err := c.GetProfile(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleProfileClient_UpdateProfile() { ctx := context.Background() c, err := talent.NewProfileClient(ctx) if err != nil { // TODO: Handle error. } req := &talentpb.UpdateProfileRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateProfile(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleProfileClient_DeleteProfile() { ctx := context.Background() c, err := talent.NewProfileClient(ctx) if err != nil { // TODO: Handle error. } req := &talentpb.DeleteProfileRequest{ // TODO: Fill request struct fields. } err = c.DeleteProfile(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleProfileClient_SearchProfiles() { ctx := context.Background() c, err := talent.NewProfileClient(ctx) if err != nil { // TODO: Handle error. } req := &talentpb.SearchProfilesRequest{ // TODO: Fill request struct fields. } it := c.SearchProfiles(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } google-cloud-go-0.49.0/talent/apiv4beta1/tenant_client.go000066400000000000000000000233621356504100700232030ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package talent import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" talentpb "google.golang.org/genproto/googleapis/cloud/talent/v4beta1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // TenantCallOptions contains the retry settings for each method of TenantClient. type TenantCallOptions struct { CreateTenant []gax.CallOption GetTenant []gax.CallOption UpdateTenant []gax.CallOption DeleteTenant []gax.CallOption ListTenants []gax.CallOption } func defaultTenantClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("jobs.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultTenantCallOptions() *TenantCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &TenantCallOptions{ CreateTenant: retry[[2]string{"default", "non_idempotent"}], GetTenant: retry[[2]string{"default", "idempotent"}], UpdateTenant: retry[[2]string{"default", "non_idempotent"}], DeleteTenant: retry[[2]string{"default", "idempotent"}], ListTenants: retry[[2]string{"default", "idempotent"}], } } // TenantClient is a client for interacting with Cloud Talent Solution API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type TenantClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. tenantClient talentpb.TenantServiceClient // The call options for this service. CallOptions *TenantCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewTenantClient creates a new tenant service client. // // A service that handles tenant management, including CRUD and enumeration. func NewTenantClient(ctx context.Context, opts ...option.ClientOption) (*TenantClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultTenantClientOptions(), opts...)...) if err != nil { return nil, err } c := &TenantClient{ conn: conn, CallOptions: defaultTenantCallOptions(), tenantClient: talentpb.NewTenantServiceClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *TenantClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *TenantClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *TenantClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // CreateTenant creates a new tenant entity. func (c *TenantClient) CreateTenant(ctx context.Context, req *talentpb.CreateTenantRequest, opts ...gax.CallOption) (*talentpb.Tenant, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateTenant[0:len(c.CallOptions.CreateTenant):len(c.CallOptions.CreateTenant)], opts...) var resp *talentpb.Tenant err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.tenantClient.CreateTenant(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetTenant retrieves specified tenant. func (c *TenantClient) GetTenant(ctx context.Context, req *talentpb.GetTenantRequest, opts ...gax.CallOption) (*talentpb.Tenant, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetTenant[0:len(c.CallOptions.GetTenant):len(c.CallOptions.GetTenant)], opts...) var resp *talentpb.Tenant err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.tenantClient.GetTenant(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateTenant updates specified tenant. func (c *TenantClient) UpdateTenant(ctx context.Context, req *talentpb.UpdateTenantRequest, opts ...gax.CallOption) (*talentpb.Tenant, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "tenant.name", url.QueryEscape(req.GetTenant().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateTenant[0:len(c.CallOptions.UpdateTenant):len(c.CallOptions.UpdateTenant)], opts...) var resp *talentpb.Tenant err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.tenantClient.UpdateTenant(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteTenant deletes specified tenant. func (c *TenantClient) DeleteTenant(ctx context.Context, req *talentpb.DeleteTenantRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteTenant[0:len(c.CallOptions.DeleteTenant):len(c.CallOptions.DeleteTenant)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.tenantClient.DeleteTenant(ctx, req, settings.GRPC...) return err }, opts...) return err } // ListTenants lists all tenants associated with the project. func (c *TenantClient) ListTenants(ctx context.Context, req *talentpb.ListTenantsRequest, opts ...gax.CallOption) *TenantIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListTenants[0:len(c.CallOptions.ListTenants):len(c.CallOptions.ListTenants)], opts...) it := &TenantIterator{} req = proto.Clone(req).(*talentpb.ListTenantsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*talentpb.Tenant, string, error) { var resp *talentpb.ListTenantsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.tenantClient.ListTenants(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Tenants, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // TenantIterator manages a stream of *talentpb.Tenant. type TenantIterator struct { items []*talentpb.Tenant pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*talentpb.Tenant, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *TenantIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *TenantIterator) Next() (*talentpb.Tenant, error) { var item *talentpb.Tenant if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *TenantIterator) bufLen() int { return len(it.items) } func (it *TenantIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/talent/apiv4beta1/tenant_client_example_test.go000066400000000000000000000053721356504100700257560ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package talent_test import ( "context" talent "cloud.google.com/go/talent/apiv4beta1" "google.golang.org/api/iterator" talentpb "google.golang.org/genproto/googleapis/cloud/talent/v4beta1" ) func ExampleNewTenantClient() { ctx := context.Background() c, err := talent.NewTenantClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleTenantClient_CreateTenant() { ctx := context.Background() c, err := talent.NewTenantClient(ctx) if err != nil { // TODO: Handle error. } req := &talentpb.CreateTenantRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateTenant(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleTenantClient_GetTenant() { ctx := context.Background() c, err := talent.NewTenantClient(ctx) if err != nil { // TODO: Handle error. } req := &talentpb.GetTenantRequest{ // TODO: Fill request struct fields. } resp, err := c.GetTenant(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleTenantClient_UpdateTenant() { ctx := context.Background() c, err := talent.NewTenantClient(ctx) if err != nil { // TODO: Handle error. } req := &talentpb.UpdateTenantRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateTenant(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleTenantClient_DeleteTenant() { ctx := context.Background() c, err := talent.NewTenantClient(ctx) if err != nil { // TODO: Handle error. } req := &talentpb.DeleteTenantRequest{ // TODO: Fill request struct fields. } err = c.DeleteTenant(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleTenantClient_ListTenants() { ctx := context.Background() c, err := talent.NewTenantClient(ctx) if err != nil { // TODO: Handle error. } req := &talentpb.ListTenantsRequest{ // TODO: Fill request struct fields. } it := c.ListTenants(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } google-cloud-go-0.49.0/texttospeech/000077500000000000000000000000001356504100700173075ustar00rootroot00000000000000google-cloud-go-0.49.0/texttospeech/apiv1/000077500000000000000000000000001356504100700203275ustar00rootroot00000000000000google-cloud-go-0.49.0/texttospeech/apiv1/.repo-metadata.json000066400000000000000000000006571356504100700240330ustar00rootroot00000000000000{ "name": "texttospeech", "name_pretty": "Cloud Text-to-Speech", "product_documentation": "https://cloud.google.com/text-to-speech", "client_documentation": "https://godoc.org/cloud.google.com/go/texttospeech/apiv1", "release_level": "alpha", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "texttospeech.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/texttospeech/apiv1/SynthesizeSpeech_smoke_test.go000066400000000000000000000040251356504100700264110ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package texttospeech import ( "context" "fmt" "strconv" "testing" "time" "cloud.google.com/go/internal/testutil" "google.golang.org/api/iterator" "google.golang.org/api/option" texttospeechpb "google.golang.org/genproto/googleapis/cloud/texttospeech/v1" ) var _ = fmt.Sprintf var _ = iterator.Done var _ = strconv.FormatUint var _ = time.Now func TestTextToSpeechSmoke(t *testing.T) { if testing.Short() { t.Skip("skipping smoke test in short mode") } ctx := context.Background() ts := testutil.TokenSource(ctx, DefaultAuthScopes()...) if ts == nil { t.Skip("Integration tests skipped. See CONTRIBUTING.md for details") } projectId := testutil.ProjID() _ = projectId c, err := NewClient(ctx, option.WithTokenSource(ts)) if err != nil { t.Fatal(err) } var text string = "test" var input = &texttospeechpb.SynthesisInput{ InputSource: &texttospeechpb.SynthesisInput_Text{ Text: text, }, } var languageCode string = "en-US" var voice = &texttospeechpb.VoiceSelectionParams{ LanguageCode: languageCode, } var audioEncoding texttospeechpb.AudioEncoding = texttospeechpb.AudioEncoding_MP3 var audioConfig = &texttospeechpb.AudioConfig{ AudioEncoding: audioEncoding, } var request = &texttospeechpb.SynthesizeSpeechRequest{ Input: input, Voice: voice, AudioConfig: audioConfig, } if _, err := c.SynthesizeSpeech(ctx, request); err != nil { t.Error(err) } } google-cloud-go-0.49.0/texttospeech/apiv1/doc.go000066400000000000000000000054031356504100700214250ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go_gapic. DO NOT EDIT. // Package texttospeech is an auto-generated package for the // Cloud Text-to-Speech API. // // Synthesizes natural-sounding speech by applying powerful neural network // models. // // NOTE: This package is in alpha. It is not stable, and is likely to change. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package texttospeech // import "cloud.google.com/go/texttospeech/apiv1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) const versionClient = "20191115" func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return !strings.ContainsRune("0123456789.", r) } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } google-cloud-go-0.49.0/texttospeech/apiv1/mock_test.go000066400000000000000000000146721356504100700226600ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package texttospeech import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" "google.golang.org/api/option" texttospeechpb "google.golang.org/genproto/googleapis/cloud/texttospeech/v1" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockTextToSpeechServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. texttospeechpb.TextToSpeechServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockTextToSpeechServer) ListVoices(ctx context.Context, req *texttospeechpb.ListVoicesRequest) (*texttospeechpb.ListVoicesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*texttospeechpb.ListVoicesResponse), nil } func (s *mockTextToSpeechServer) SynthesizeSpeech(ctx context.Context, req *texttospeechpb.SynthesizeSpeechRequest) (*texttospeechpb.SynthesizeSpeechResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*texttospeechpb.SynthesizeSpeechResponse), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockTextToSpeech mockTextToSpeechServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() texttospeechpb.RegisterTextToSpeechServer(serv, &mockTextToSpeech) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestTextToSpeechListVoices(t *testing.T) { var expectedResponse *texttospeechpb.ListVoicesResponse = &texttospeechpb.ListVoicesResponse{} mockTextToSpeech.err = nil mockTextToSpeech.reqs = nil mockTextToSpeech.resps = append(mockTextToSpeech.resps[:0], expectedResponse) var request *texttospeechpb.ListVoicesRequest = &texttospeechpb.ListVoicesRequest{} c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListVoices(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockTextToSpeech.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestTextToSpeechListVoicesError(t *testing.T) { errCode := codes.PermissionDenied mockTextToSpeech.err = gstatus.Error(errCode, "test error") var request *texttospeechpb.ListVoicesRequest = &texttospeechpb.ListVoicesRequest{} c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListVoices(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestTextToSpeechSynthesizeSpeech(t *testing.T) { var audioContent []byte = []byte("16") var expectedResponse = &texttospeechpb.SynthesizeSpeechResponse{ AudioContent: audioContent, } mockTextToSpeech.err = nil mockTextToSpeech.reqs = nil mockTextToSpeech.resps = append(mockTextToSpeech.resps[:0], expectedResponse) var input *texttospeechpb.SynthesisInput = &texttospeechpb.SynthesisInput{} var voice *texttospeechpb.VoiceSelectionParams = &texttospeechpb.VoiceSelectionParams{} var audioConfig *texttospeechpb.AudioConfig = &texttospeechpb.AudioConfig{} var request = &texttospeechpb.SynthesizeSpeechRequest{ Input: input, Voice: voice, AudioConfig: audioConfig, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SynthesizeSpeech(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockTextToSpeech.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestTextToSpeechSynthesizeSpeechError(t *testing.T) { errCode := codes.PermissionDenied mockTextToSpeech.err = gstatus.Error(errCode, "test error") var input *texttospeechpb.SynthesisInput = &texttospeechpb.SynthesisInput{} var voice *texttospeechpb.VoiceSelectionParams = &texttospeechpb.VoiceSelectionParams{} var audioConfig *texttospeechpb.AudioConfig = &texttospeechpb.AudioConfig{} var request = &texttospeechpb.SynthesizeSpeechRequest{ Input: input, Voice: voice, AudioConfig: audioConfig, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SynthesizeSpeech(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/texttospeech/apiv1/text_to_speech_client.go000066400000000000000000000124171356504100700252360ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go_gapic. DO NOT EDIT. package texttospeech import ( "context" "math" "time" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" "google.golang.org/api/transport" texttospeechpb "google.golang.org/genproto/googleapis/cloud/texttospeech/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // CallOptions contains the retry settings for each method of Client. type CallOptions struct { ListVoices []gax.CallOption SynthesizeSpeech []gax.CallOption } func defaultClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("texttospeech.googleapis.com:443"), option.WithGRPCDialOption(grpc.WithDisableServiceConfig()), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultCallOptions() *CallOptions { return &CallOptions{ ListVoices: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, codes.DeadlineExceeded, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, SynthesizeSpeech: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, codes.DeadlineExceeded, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, } } // Client is a client for interacting with Cloud Text-to-Speech API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. client texttospeechpb.TextToSpeechClient // The call options for this service. CallOptions *CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewClient creates a new text to speech client. // // Service that implements Google Cloud Text-to-Speech API. func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultClientOptions(), opts...)...) if err != nil { return nil, err } c := &Client{ conn: conn, CallOptions: defaultCallOptions(), client: texttospeechpb.NewTextToSpeechClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *Client) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *Client) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // ListVoices returns a list of Voice supported for synthesis. func (c *Client) ListVoices(ctx context.Context, req *texttospeechpb.ListVoicesRequest, opts ...gax.CallOption) (*texttospeechpb.ListVoicesResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.ListVoices[0:len(c.CallOptions.ListVoices):len(c.CallOptions.ListVoices)], opts...) var resp *texttospeechpb.ListVoicesResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListVoices(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // SynthesizeSpeech synthesizes speech synchronously: receive results after all text input // has been processed. func (c *Client) SynthesizeSpeech(ctx context.Context, req *texttospeechpb.SynthesizeSpeechRequest, opts ...gax.CallOption) (*texttospeechpb.SynthesizeSpeechResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.SynthesizeSpeech[0:len(c.CallOptions.SynthesizeSpeech):len(c.CallOptions.SynthesizeSpeech)], opts...) var resp *texttospeechpb.SynthesizeSpeechResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.SynthesizeSpeech(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } google-cloud-go-0.49.0/texttospeech/apiv1/text_to_speech_client_example_test.go000066400000000000000000000035431356504100700300100ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go_gapic. DO NOT EDIT. package texttospeech_test import ( "context" texttospeech "cloud.google.com/go/texttospeech/apiv1" texttospeechpb "google.golang.org/genproto/googleapis/cloud/texttospeech/v1" ) func ExampleNewClient() { ctx := context.Background() c, err := texttospeech.NewClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleClient_ListVoices() { // import texttospeechpb "google.golang.org/genproto/googleapis/cloud/texttospeech/v1" ctx := context.Background() c, err := texttospeech.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &texttospeechpb.ListVoicesRequest{ // TODO: Fill request struct fields. } resp, err := c.ListVoices(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_SynthesizeSpeech() { // import texttospeechpb "google.golang.org/genproto/googleapis/cloud/texttospeech/v1" ctx := context.Background() c, err := texttospeech.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &texttospeechpb.SynthesizeSpeechRequest{ // TODO: Fill request struct fields. } resp, err := c.SynthesizeSpeech(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/tidyall.sh000077500000000000000000000017151356504100700165750ustar00rootroot00000000000000#!/bin/bash # Copyright 2019 Google Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Run at repo root. go mod tidy for i in `find . -name go.mod`; do pushd `dirname $i`; # Update genproto and api to latest for every module (latest version is # always correct version). tidy will remove the dependencies if they're not # actually used by the client. go get -u google.golang.org/api go get -u google.golang.org/genproto go mod tidy; popd; done google-cloud-go-0.49.0/tools.go000066400000000000000000000023571356504100700162660ustar00rootroot00000000000000// +build tools // Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // This package exists to cause `go mod` and `go get` to believe these tools // are dependencies, even though they are not runtime dependencies of any // package (these are tools used by our CI builds). This means they will appear // in our `go.mod` file, but will not be a part of the build. Also, since the // build target is something non-existent, these should not be included in any // binaries. package cloud import ( _ "github.com/golang/protobuf/protoc-gen-go" _ "github.com/jstemmer/go-junit-report" _ "golang.org/x/exp/cmd/apidiff" _ "golang.org/x/lint/golint" _ "golang.org/x/tools/cmd/goimports" _ "honnef.co/go/tools/cmd/staticcheck" ) google-cloud-go-0.49.0/trace/000077500000000000000000000000001356504100700156665ustar00rootroot00000000000000google-cloud-go-0.49.0/trace/apiv1/000077500000000000000000000000001356504100700167065ustar00rootroot00000000000000google-cloud-go-0.49.0/trace/apiv1/.repo-metadata.json000066400000000000000000000006231356504100700224030ustar00rootroot00000000000000{ "name": "trace", "name_pretty": "Stackdriver Trace", "product_documentation": "https://cloud.google.com/trace", "client_documentation": "https://godoc.org/cloud.google.com/go/trace/apiv1", "release_level": "alpha", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "cloudtrace.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/trace/apiv1/ListTraces_smoke_test.go000066400000000000000000000031611356504100700235500ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package trace import ( "context" "fmt" "strconv" "testing" "time" "cloud.google.com/go/internal/testutil" "google.golang.org/api/iterator" "google.golang.org/api/option" cloudtracepb "google.golang.org/genproto/googleapis/devtools/cloudtrace/v1" ) var _ = fmt.Sprintf var _ = iterator.Done var _ = strconv.FormatUint var _ = time.Now func TestTraceServiceSmoke(t *testing.T) { if testing.Short() { t.Skip("skipping smoke test in short mode") } ctx := context.Background() ts := testutil.TokenSource(ctx, DefaultAuthScopes()...) if ts == nil { t.Skip("Integration tests skipped. See CONTRIBUTING.md for details") } projectId := testutil.ProjID() _ = projectId c, err := NewClient(ctx, option.WithTokenSource(ts)) if err != nil { t.Fatal(err) } var projectId2 string = projectId var request = &cloudtracepb.ListTracesRequest{ ProjectId: projectId2, } iter := c.ListTraces(ctx, request) if _, err := iter.Next(); err != nil && err != iterator.Done { t.Error(err) } } google-cloud-go-0.49.0/trace/apiv1/doc.go000066400000000000000000000060231356504100700200030ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package trace is an auto-generated package for the // Stackdriver Trace API. // // NOTE: This package is in alpha. It is not stable, and is likely to change. // // Sends application trace data to Stackdriver Trace for viewing. Trace data // is // collected for all App Engine applications by default. Trace data from // other // applications can be provided using this API. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. // // Use the client at cloud.google.com/go/trace in preference to this. package trace // import "cloud.google.com/go/trace/apiv1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/trace.append", "https://www.googleapis.com/auth/trace.readonly", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "UNKNOWN" google-cloud-go-0.49.0/trace/apiv1/mock_test.go000066400000000000000000000202411356504100700212240ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package trace import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" "google.golang.org/api/option" cloudtracepb "google.golang.org/genproto/googleapis/devtools/cloudtrace/v1" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockTraceServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. cloudtracepb.TraceServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockTraceServer) ListTraces(ctx context.Context, req *cloudtracepb.ListTracesRequest) (*cloudtracepb.ListTracesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*cloudtracepb.ListTracesResponse), nil } func (s *mockTraceServer) GetTrace(ctx context.Context, req *cloudtracepb.GetTraceRequest) (*cloudtracepb.Trace, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*cloudtracepb.Trace), nil } func (s *mockTraceServer) PatchTraces(ctx context.Context, req *cloudtracepb.PatchTracesRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockTrace mockTraceServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() cloudtracepb.RegisterTraceServiceServer(serv, &mockTrace) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestTraceServicePatchTraces(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockTrace.err = nil mockTrace.reqs = nil mockTrace.resps = append(mockTrace.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var traces *cloudtracepb.Traces = &cloudtracepb.Traces{} var request = &cloudtracepb.PatchTracesRequest{ ProjectId: projectId, Traces: traces, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.PatchTraces(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockTrace.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestTraceServicePatchTracesError(t *testing.T) { errCode := codes.PermissionDenied mockTrace.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var traces *cloudtracepb.Traces = &cloudtracepb.Traces{} var request = &cloudtracepb.PatchTracesRequest{ ProjectId: projectId, Traces: traces, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.PatchTraces(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestTraceServiceGetTrace(t *testing.T) { var projectId2 string = "projectId2939242356" var traceId2 string = "traceId2987826376" var expectedResponse = &cloudtracepb.Trace{ ProjectId: projectId2, TraceId: traceId2, } mockTrace.err = nil mockTrace.reqs = nil mockTrace.resps = append(mockTrace.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var traceId string = "traceId1270300245" var request = &cloudtracepb.GetTraceRequest{ ProjectId: projectId, TraceId: traceId, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetTrace(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockTrace.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestTraceServiceGetTraceError(t *testing.T) { errCode := codes.PermissionDenied mockTrace.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var traceId string = "traceId1270300245" var request = &cloudtracepb.GetTraceRequest{ ProjectId: projectId, TraceId: traceId, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetTrace(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestTraceServiceListTraces(t *testing.T) { var nextPageToken string = "" var tracesElement *cloudtracepb.Trace = &cloudtracepb.Trace{} var traces = []*cloudtracepb.Trace{tracesElement} var expectedResponse = &cloudtracepb.ListTracesResponse{ NextPageToken: nextPageToken, Traces: traces, } mockTrace.err = nil mockTrace.reqs = nil mockTrace.resps = append(mockTrace.resps[:0], expectedResponse) var projectId string = "projectId-1969970175" var request = &cloudtracepb.ListTracesRequest{ ProjectId: projectId, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListTraces(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockTrace.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Traces[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestTraceServiceListTracesError(t *testing.T) { errCode := codes.PermissionDenied mockTrace.err = gstatus.Error(errCode, "test error") var projectId string = "projectId-1969970175" var request = &cloudtracepb.ListTracesRequest{ ProjectId: projectId, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListTraces(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/trace/apiv1/trace_client.go000066400000000000000000000207051356504100700216750ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package trace import ( "context" "fmt" "math" "net/url" "time" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" cloudtracepb "google.golang.org/genproto/googleapis/devtools/cloudtrace/v1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // CallOptions contains the retry settings for each method of Client. type CallOptions struct { PatchTraces []gax.CallOption GetTrace []gax.CallOption ListTraces []gax.CallOption } func defaultClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("cloudtrace.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultCallOptions() *CallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 1000 * time.Millisecond, Multiplier: 1.2, }) }), }, } return &CallOptions{ PatchTraces: retry[[2]string{"default", "idempotent"}], GetTrace: retry[[2]string{"default", "idempotent"}], ListTraces: retry[[2]string{"default", "idempotent"}], } } // Client is a client for interacting with Stackdriver Trace API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. client cloudtracepb.TraceServiceClient // The call options for this service. CallOptions *CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewClient creates a new trace service client. // // This file describes an API for collecting and viewing traces and spans // within a trace. A Trace is a collection of spans corresponding to a single // operation or set of operations for an application. A span is an individual // timed event which forms a node of the trace tree. Spans for a single trace // may span multiple services. func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultClientOptions(), opts...)...) if err != nil { return nil, err } c := &Client{ conn: conn, CallOptions: defaultCallOptions(), client: cloudtracepb.NewTraceServiceClient(conn), } c.SetGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *Client) Close() error { return c.conn.Close() } // SetGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *Client) SetGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // PatchTraces sends new traces to Stackdriver Trace or updates existing traces. If the ID // of a trace that you send matches that of an existing trace, any fields // in the existing trace and its spans are overwritten by the provided values, // and any new fields provided are merged with the existing trace data. If the // ID does not match, a new trace is created. func (c *Client) PatchTraces(ctx context.Context, req *cloudtracepb.PatchTracesRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "project_id", url.QueryEscape(req.GetProjectId()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.PatchTraces[0:len(c.CallOptions.PatchTraces):len(c.CallOptions.PatchTraces)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.client.PatchTraces(ctx, req, settings.GRPC...) return err }, opts...) return err } // GetTrace gets a single trace by its ID. func (c *Client) GetTrace(ctx context.Context, req *cloudtracepb.GetTraceRequest, opts ...gax.CallOption) (*cloudtracepb.Trace, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.GetTrace[0:len(c.CallOptions.GetTrace):len(c.CallOptions.GetTrace)], opts...) var resp *cloudtracepb.Trace err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetTrace(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListTraces returns of a list of traces that match the specified filter conditions. func (c *Client) ListTraces(ctx context.Context, req *cloudtracepb.ListTracesRequest, opts ...gax.CallOption) *TraceIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "project_id", url.QueryEscape(req.GetProjectId()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListTraces[0:len(c.CallOptions.ListTraces):len(c.CallOptions.ListTraces)], opts...) it := &TraceIterator{} req = proto.Clone(req).(*cloudtracepb.ListTracesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*cloudtracepb.Trace, string, error) { var resp *cloudtracepb.ListTracesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListTraces(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Traces, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // TraceIterator manages a stream of *cloudtracepb.Trace. type TraceIterator struct { items []*cloudtracepb.Trace pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*cloudtracepb.Trace, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *TraceIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *TraceIterator) Next() (*cloudtracepb.Trace, error) { var item *cloudtracepb.Trace if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *TraceIterator) bufLen() int { return len(it.items) } func (it *TraceIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/trace/apiv1/trace_client_example_test.go000066400000000000000000000040031356504100700244400ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package trace_test import ( "context" trace "cloud.google.com/go/trace/apiv1" "google.golang.org/api/iterator" cloudtracepb "google.golang.org/genproto/googleapis/devtools/cloudtrace/v1" ) func ExampleNewClient() { ctx := context.Background() c, err := trace.NewClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleClient_PatchTraces() { ctx := context.Background() c, err := trace.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &cloudtracepb.PatchTracesRequest{ // TODO: Fill request struct fields. } err = c.PatchTraces(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleClient_GetTrace() { ctx := context.Background() c, err := trace.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &cloudtracepb.GetTraceRequest{ // TODO: Fill request struct fields. } resp, err := c.GetTrace(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleClient_ListTraces() { ctx := context.Background() c, err := trace.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &cloudtracepb.ListTracesRequest{ // TODO: Fill request struct fields. } it := c.ListTraces(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } google-cloud-go-0.49.0/trace/apiv2/000077500000000000000000000000001356504100700167075ustar00rootroot00000000000000google-cloud-go-0.49.0/trace/apiv2/.repo-metadata.json000066400000000000000000000006231356504100700224040ustar00rootroot00000000000000{ "name": "trace", "name_pretty": "Stackdriver Trace", "product_documentation": "https://cloud.google.com/trace", "client_documentation": "https://godoc.org/cloud.google.com/go/trace/apiv2", "release_level": "alpha", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "cloudtrace.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/trace/apiv2/BatchWriteSpans_smoke_test.go000066400000000000000000000031501356504100700245330ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package trace import ( "context" "fmt" "strconv" "testing" "time" "cloud.google.com/go/internal/testutil" "google.golang.org/api/iterator" "google.golang.org/api/option" cloudtracepb "google.golang.org/genproto/googleapis/devtools/cloudtrace/v2" ) var _ = fmt.Sprintf var _ = iterator.Done var _ = strconv.FormatUint var _ = time.Now func TestTraceServiceSmoke(t *testing.T) { if testing.Short() { t.Skip("skipping smoke test in short mode") } ctx := context.Background() ts := testutil.TokenSource(ctx, DefaultAuthScopes()...) if ts == nil { t.Skip("Integration tests skipped. See CONTRIBUTING.md for details") } projectId := testutil.ProjID() _ = projectId c, err := NewClient(ctx, option.WithTokenSource(ts)) if err != nil { t.Fatal(err) } var formattedName string = fmt.Sprintf("projects/%s", projectId) var request = &cloudtracepb.BatchWriteSpansRequest{ Name: formattedName, } if err := c.BatchWriteSpans(ctx, request); err != nil { t.Error(err) } } google-cloud-go-0.49.0/trace/apiv2/doc.go000066400000000000000000000060751356504100700200130ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package trace is an auto-generated package for the // Stackdriver Trace API. // // NOTE: This package is in alpha. It is not stable, and is likely to change. // // Sends application trace data to Stackdriver Trace for viewing. Trace data // is collected for all App Engine applications by default. Trace data from // other applications can be provided using this API. This library is used to // interact with the Trace API directly. If you are looking to instrument // your application for Stackdriver Trace, we recommend using OpenCensus. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package trace // import "cloud.google.com/go/trace/apiv2" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/trace.append", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191115" google-cloud-go-0.49.0/trace/apiv2/mock_test.go000066400000000000000000000154241356504100700212340ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package trace import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" timestamppb "github.com/golang/protobuf/ptypes/timestamp" "google.golang.org/api/option" cloudtracepb "google.golang.org/genproto/googleapis/devtools/cloudtrace/v2" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockTraceServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. cloudtracepb.TraceServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockTraceServer) BatchWriteSpans(ctx context.Context, req *cloudtracepb.BatchWriteSpansRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockTraceServer) CreateSpan(ctx context.Context, req *cloudtracepb.Span) (*cloudtracepb.Span, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*cloudtracepb.Span), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockTrace mockTraceServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() cloudtracepb.RegisterTraceServiceServer(serv, &mockTrace) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestTraceServiceBatchWriteSpans(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockTrace.err = nil mockTrace.reqs = nil mockTrace.resps = append(mockTrace.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s", "[PROJECT]") var spans []*cloudtracepb.Span = nil var request = &cloudtracepb.BatchWriteSpansRequest{ Name: formattedName, Spans: spans, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.BatchWriteSpans(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockTrace.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestTraceServiceBatchWriteSpansError(t *testing.T) { errCode := codes.PermissionDenied mockTrace.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s", "[PROJECT]") var spans []*cloudtracepb.Span = nil var request = &cloudtracepb.BatchWriteSpansRequest{ Name: formattedName, Spans: spans, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.BatchWriteSpans(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestTraceServiceCreateSpan(t *testing.T) { var name2 string = "name2-1052831874" var spanId2 string = "spanId2-643891741" var parentSpanId string = "parentSpanId-1757797477" var expectedResponse = &cloudtracepb.Span{ Name: name2, SpanId: spanId2, ParentSpanId: parentSpanId, } mockTrace.err = nil mockTrace.reqs = nil mockTrace.resps = append(mockTrace.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/traces/%s/spans/%s", "[PROJECT]", "[TRACE]", "[SPAN]") var spanId string = "spanId-2011840976" var displayName *cloudtracepb.TruncatableString = &cloudtracepb.TruncatableString{} var startTime *timestamppb.Timestamp = ×tamppb.Timestamp{} var endTime *timestamppb.Timestamp = ×tamppb.Timestamp{} var request = &cloudtracepb.Span{ Name: formattedName, SpanId: spanId, DisplayName: displayName, StartTime: startTime, EndTime: endTime, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateSpan(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockTrace.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestTraceServiceCreateSpanError(t *testing.T) { errCode := codes.PermissionDenied mockTrace.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/traces/%s/spans/%s", "[PROJECT]", "[TRACE]", "[SPAN]") var spanId string = "spanId-2011840976" var displayName *cloudtracepb.TruncatableString = &cloudtracepb.TruncatableString{} var startTime *timestamppb.Timestamp = ×tamppb.Timestamp{} var endTime *timestamppb.Timestamp = ×tamppb.Timestamp{} var request = &cloudtracepb.Span{ Name: formattedName, SpanId: spanId, DisplayName: displayName, StartTime: startTime, EndTime: endTime, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateSpan(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/trace/apiv2/path_funcs.go000066400000000000000000000021571356504100700213750ustar00rootroot00000000000000// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package trace // ProjectPath returns the path for the project resource. // // Deprecated: Use // fmt.Sprintf("projects/%s", project) // instead. func ProjectPath(project string) string { return "" + "projects/" + project + "" } // SpanPath returns the path for the span resource. // // Deprecated: Use // fmt.Sprintf("projects/%s/traces/%s/spans/%s", project, trace, span) // instead. func SpanPath(project, trace, span string) string { return "" + "projects/" + project + "/traces/" + trace + "/spans/" + span + "" } google-cloud-go-0.49.0/trace/apiv2/trace_client.go000066400000000000000000000125131356504100700216740ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package trace import ( "context" "fmt" "math" "net/url" "time" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" "google.golang.org/api/transport" cloudtracepb "google.golang.org/genproto/googleapis/devtools/cloudtrace/v2" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // CallOptions contains the retry settings for each method of Client. type CallOptions struct { BatchWriteSpans []gax.CallOption CreateSpan []gax.CallOption } func defaultClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("cloudtrace.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultCallOptions() *CallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 1000 * time.Millisecond, Multiplier: 1.2, }) }), }, } return &CallOptions{ BatchWriteSpans: retry[[2]string{"default", "non_idempotent"}], CreateSpan: retry[[2]string{"default", "idempotent"}], } } // Client is a client for interacting with Stackdriver Trace API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. client cloudtracepb.TraceServiceClient // The call options for this service. CallOptions *CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewClient creates a new trace service client. // // This file describes an API for collecting and viewing traces and spans // within a trace. A Trace is a collection of spans corresponding to a single // operation or set of operations for an application. A span is an individual // timed event which forms a node of the trace tree. A single trace may // contain span(s) from multiple services. func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultClientOptions(), opts...)...) if err != nil { return nil, err } c := &Client{ conn: conn, CallOptions: defaultCallOptions(), client: cloudtracepb.NewTraceServiceClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *Client) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *Client) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // BatchWriteSpans sends new spans to new or existing traces. You cannot update // existing spans. func (c *Client) BatchWriteSpans(ctx context.Context, req *cloudtracepb.BatchWriteSpansRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.BatchWriteSpans[0:len(c.CallOptions.BatchWriteSpans):len(c.CallOptions.BatchWriteSpans)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.client.BatchWriteSpans(ctx, req, settings.GRPC...) return err }, opts...) return err } // CreateSpan creates a new span. func (c *Client) CreateSpan(ctx context.Context, req *cloudtracepb.Span, opts ...gax.CallOption) (*cloudtracepb.Span, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateSpan[0:len(c.CallOptions.CreateSpan):len(c.CallOptions.CreateSpan)], opts...) var resp *cloudtracepb.Span err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CreateSpan(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } google-cloud-go-0.49.0/trace/apiv2/trace_client_example_test.go000066400000000000000000000031111356504100700244400ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package trace_test import ( "context" trace "cloud.google.com/go/trace/apiv2" cloudtracepb "google.golang.org/genproto/googleapis/devtools/cloudtrace/v2" ) func ExampleNewClient() { ctx := context.Background() c, err := trace.NewClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleClient_BatchWriteSpans() { ctx := context.Background() c, err := trace.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &cloudtracepb.BatchWriteSpansRequest{ // TODO: Fill request struct fields. } err = c.BatchWriteSpans(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleClient_CreateSpan() { ctx := context.Background() c, err := trace.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &cloudtracepb.Span{ // TODO: Fill request struct fields. } resp, err := c.CreateSpan(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/translate/000077500000000000000000000000001356504100700165655ustar00rootroot00000000000000google-cloud-go-0.49.0/translate/.repo-metadata.json000066400000000000000000000006351356504100700222650ustar00rootroot00000000000000{ "name": "translate", "name_pretty": "Translation API", "product_documentation": "https://cloud.google.com/translate", "client_documentation": "https://godoc.org/cloud.google.com/go/translate", "release_level": "ga", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go/translate", "api_id": "translate.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/translate/apiv3/000077500000000000000000000000001356504100700176075ustar00rootroot00000000000000google-cloud-go-0.49.0/translate/apiv3/doc.go000066400000000000000000000053061356504100700207070ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go_gapic. DO NOT EDIT. // Package translate is an auto-generated package for the // Cloud Translation API. // // Integrates text translation into your website or application. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package translate // import "cloud.google.com/go/translate/apiv3" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) const versionClient = "20191115" func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/cloud-translation", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return !strings.ContainsRune("0123456789.", r) } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } google-cloud-go-0.49.0/translate/apiv3/mock_test.go000066400000000000000000000553011356504100700221320ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package translate import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" "google.golang.org/api/option" translatepb "google.golang.org/genproto/googleapis/cloud/translate/v3" longrunningpb "google.golang.org/genproto/googleapis/longrunning" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockTranslationServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. translatepb.TranslationServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockTranslationServer) TranslateText(ctx context.Context, req *translatepb.TranslateTextRequest) (*translatepb.TranslateTextResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*translatepb.TranslateTextResponse), nil } func (s *mockTranslationServer) DetectLanguage(ctx context.Context, req *translatepb.DetectLanguageRequest) (*translatepb.DetectLanguageResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*translatepb.DetectLanguageResponse), nil } func (s *mockTranslationServer) GetSupportedLanguages(ctx context.Context, req *translatepb.GetSupportedLanguagesRequest) (*translatepb.SupportedLanguages, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*translatepb.SupportedLanguages), nil } func (s *mockTranslationServer) BatchTranslateText(ctx context.Context, req *translatepb.BatchTranslateTextRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockTranslationServer) CreateGlossary(ctx context.Context, req *translatepb.CreateGlossaryRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockTranslationServer) ListGlossaries(ctx context.Context, req *translatepb.ListGlossariesRequest) (*translatepb.ListGlossariesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*translatepb.ListGlossariesResponse), nil } func (s *mockTranslationServer) GetGlossary(ctx context.Context, req *translatepb.GetGlossaryRequest) (*translatepb.Glossary, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*translatepb.Glossary), nil } func (s *mockTranslationServer) DeleteGlossary(ctx context.Context, req *translatepb.DeleteGlossaryRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockTranslation mockTranslationServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() translatepb.RegisterTranslationServiceServer(serv, &mockTranslation) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestTranslationServiceTranslateText(t *testing.T) { var expectedResponse *translatepb.TranslateTextResponse = &translatepb.TranslateTextResponse{} mockTranslation.err = nil mockTranslation.reqs = nil mockTranslation.resps = append(mockTranslation.resps[:0], expectedResponse) var contents []string = nil var targetLanguageCode string = "targetLanguageCode1323228230" var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &translatepb.TranslateTextRequest{ Contents: contents, TargetLanguageCode: targetLanguageCode, Parent: formattedParent, } c, err := NewTranslationClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.TranslateText(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockTranslation.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestTranslationServiceTranslateTextError(t *testing.T) { errCode := codes.PermissionDenied mockTranslation.err = gstatus.Error(errCode, "test error") var contents []string = nil var targetLanguageCode string = "targetLanguageCode1323228230" var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &translatepb.TranslateTextRequest{ Contents: contents, TargetLanguageCode: targetLanguageCode, Parent: formattedParent, } c, err := NewTranslationClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.TranslateText(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestTranslationServiceDetectLanguage(t *testing.T) { var expectedResponse *translatepb.DetectLanguageResponse = &translatepb.DetectLanguageResponse{} mockTranslation.err = nil mockTranslation.reqs = nil mockTranslation.resps = append(mockTranslation.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &translatepb.DetectLanguageRequest{ Parent: formattedParent, } c, err := NewTranslationClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.DetectLanguage(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockTranslation.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestTranslationServiceDetectLanguageError(t *testing.T) { errCode := codes.PermissionDenied mockTranslation.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &translatepb.DetectLanguageRequest{ Parent: formattedParent, } c, err := NewTranslationClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.DetectLanguage(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestTranslationServiceGetSupportedLanguages(t *testing.T) { var expectedResponse *translatepb.SupportedLanguages = &translatepb.SupportedLanguages{} mockTranslation.err = nil mockTranslation.reqs = nil mockTranslation.resps = append(mockTranslation.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &translatepb.GetSupportedLanguagesRequest{ Parent: formattedParent, } c, err := NewTranslationClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetSupportedLanguages(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockTranslation.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestTranslationServiceGetSupportedLanguagesError(t *testing.T) { errCode := codes.PermissionDenied mockTranslation.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &translatepb.GetSupportedLanguagesRequest{ Parent: formattedParent, } c, err := NewTranslationClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetSupportedLanguages(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestTranslationServiceBatchTranslateText(t *testing.T) { var totalCharacters int64 = 1368640955 var translatedCharacters int64 = 1337326221 var failedCharacters int64 = 1723028396 var expectedResponse = &translatepb.BatchTranslateResponse{ TotalCharacters: totalCharacters, TranslatedCharacters: translatedCharacters, FailedCharacters: failedCharacters, } mockTranslation.err = nil mockTranslation.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockTranslation.resps = append(mockTranslation.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var sourceLanguageCode string = "sourceLanguageCode1687263568" var targetLanguageCodes []string = nil var inputConfigs []*translatepb.InputConfig = nil var outputConfig *translatepb.OutputConfig = &translatepb.OutputConfig{} var request = &translatepb.BatchTranslateTextRequest{ Parent: formattedParent, SourceLanguageCode: sourceLanguageCode, TargetLanguageCodes: targetLanguageCodes, InputConfigs: inputConfigs, OutputConfig: outputConfig, } c, err := NewTranslationClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.BatchTranslateText(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockTranslation.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestTranslationServiceBatchTranslateTextError(t *testing.T) { errCode := codes.PermissionDenied mockTranslation.err = nil mockTranslation.resps = append(mockTranslation.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var sourceLanguageCode string = "sourceLanguageCode1687263568" var targetLanguageCodes []string = nil var inputConfigs []*translatepb.InputConfig = nil var outputConfig *translatepb.OutputConfig = &translatepb.OutputConfig{} var request = &translatepb.BatchTranslateTextRequest{ Parent: formattedParent, SourceLanguageCode: sourceLanguageCode, TargetLanguageCodes: targetLanguageCodes, InputConfigs: inputConfigs, OutputConfig: outputConfig, } c, err := NewTranslationClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.BatchTranslateText(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestTranslationServiceCreateGlossary(t *testing.T) { var name string = "name3373707" var entryCount int32 = 811131134 var expectedResponse = &translatepb.Glossary{ Name: name, EntryCount: entryCount, } mockTranslation.err = nil mockTranslation.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockTranslation.resps = append(mockTranslation.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var glossary *translatepb.Glossary = &translatepb.Glossary{} var request = &translatepb.CreateGlossaryRequest{ Parent: formattedParent, Glossary: glossary, } c, err := NewTranslationClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.CreateGlossary(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockTranslation.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestTranslationServiceCreateGlossaryError(t *testing.T) { errCode := codes.PermissionDenied mockTranslation.err = nil mockTranslation.resps = append(mockTranslation.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var glossary *translatepb.Glossary = &translatepb.Glossary{} var request = &translatepb.CreateGlossaryRequest{ Parent: formattedParent, Glossary: glossary, } c, err := NewTranslationClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.CreateGlossary(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestTranslationServiceListGlossaries(t *testing.T) { var nextPageToken string = "" var glossariesElement *translatepb.Glossary = &translatepb.Glossary{} var glossaries = []*translatepb.Glossary{glossariesElement} var expectedResponse = &translatepb.ListGlossariesResponse{ NextPageToken: nextPageToken, Glossaries: glossaries, } mockTranslation.err = nil mockTranslation.reqs = nil mockTranslation.resps = append(mockTranslation.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &translatepb.ListGlossariesRequest{ Parent: formattedParent, } c, err := NewTranslationClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListGlossaries(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockTranslation.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Glossaries[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestTranslationServiceListGlossariesError(t *testing.T) { errCode := codes.PermissionDenied mockTranslation.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &translatepb.ListGlossariesRequest{ Parent: formattedParent, } c, err := NewTranslationClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListGlossaries(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestTranslationServiceGetGlossary(t *testing.T) { var name2 string = "name2-1052831874" var entryCount int32 = 811131134 var expectedResponse = &translatepb.Glossary{ Name: name2, EntryCount: entryCount, } mockTranslation.err = nil mockTranslation.reqs = nil mockTranslation.resps = append(mockTranslation.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/glossaries/%s", "[PROJECT]", "[LOCATION]", "[GLOSSARY]") var request = &translatepb.GetGlossaryRequest{ Name: formattedName, } c, err := NewTranslationClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetGlossary(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockTranslation.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestTranslationServiceGetGlossaryError(t *testing.T) { errCode := codes.PermissionDenied mockTranslation.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/glossaries/%s", "[PROJECT]", "[LOCATION]", "[GLOSSARY]") var request = &translatepb.GetGlossaryRequest{ Name: formattedName, } c, err := NewTranslationClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetGlossary(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestTranslationServiceDeleteGlossary(t *testing.T) { var name2 string = "name2-1052831874" var expectedResponse = &translatepb.DeleteGlossaryResponse{ Name: name2, } mockTranslation.err = nil mockTranslation.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockTranslation.resps = append(mockTranslation.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/glossaries/%s", "[PROJECT]", "[LOCATION]", "[GLOSSARY]") var request = &translatepb.DeleteGlossaryRequest{ Name: formattedName, } c, err := NewTranslationClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.DeleteGlossary(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockTranslation.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestTranslationServiceDeleteGlossaryError(t *testing.T) { errCode := codes.PermissionDenied mockTranslation.err = nil mockTranslation.resps = append(mockTranslation.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/glossaries/%s", "[PROJECT]", "[LOCATION]", "[GLOSSARY]") var request = &translatepb.DeleteGlossaryRequest{ Name: formattedName, } c, err := NewTranslationClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.DeleteGlossary(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/translate/apiv3/translation_client.go000066400000000000000000000602441356504100700240400ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go_gapic. DO NOT EDIT. package translate import ( "context" "fmt" "math" "net/url" "time" "cloud.google.com/go/longrunning" lroauto "cloud.google.com/go/longrunning/autogen" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" translatepb "google.golang.org/genproto/googleapis/cloud/translate/v3" longrunningpb "google.golang.org/genproto/googleapis/longrunning" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // TranslationCallOptions contains the retry settings for each method of TranslationClient. type TranslationCallOptions struct { TranslateText []gax.CallOption DetectLanguage []gax.CallOption GetSupportedLanguages []gax.CallOption BatchTranslateText []gax.CallOption CreateGlossary []gax.CallOption ListGlossaries []gax.CallOption GetGlossary []gax.CallOption DeleteGlossary []gax.CallOption } func defaultTranslationClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("translate.googleapis.com:443"), option.WithGRPCDialOption(grpc.WithDisableServiceConfig()), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultTranslationCallOptions() *TranslationCallOptions { return &TranslationCallOptions{ TranslateText: []gax.CallOption{}, DetectLanguage: []gax.CallOption{}, GetSupportedLanguages: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, BatchTranslateText: []gax.CallOption{}, CreateGlossary: []gax.CallOption{}, ListGlossaries: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, GetGlossary: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, DeleteGlossary: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, } } // TranslationClient is a client for interacting with Cloud Translation API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type TranslationClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. translationClient translatepb.TranslationServiceClient // LROClient is used internally to handle longrunning operations. // It is exposed so that its CallOptions can be modified if required. // Users should not Close this client. LROClient *lroauto.OperationsClient // The call options for this service. CallOptions *TranslationCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewTranslationClient creates a new translation service client. // // Provides natural language translation operations. func NewTranslationClient(ctx context.Context, opts ...option.ClientOption) (*TranslationClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultTranslationClientOptions(), opts...)...) if err != nil { return nil, err } c := &TranslationClient{ conn: conn, CallOptions: defaultTranslationCallOptions(), translationClient: translatepb.NewTranslationServiceClient(conn), } c.setGoogleClientInfo() c.LROClient, err = lroauto.NewOperationsClient(ctx, option.WithGRPCConn(conn)) if err != nil { // This error "should not happen", since we are just reusing old connection // and never actually need to dial. // If this does happen, we could leak conn. However, we cannot close conn: // If the user invoked the function with option.WithGRPCConn, // we would close a connection that's still in use. // TODO(pongad): investigate error conditions. return nil, err } return c, nil } // Connection returns the client's connection to the API service. func (c *TranslationClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *TranslationClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *TranslationClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // TranslateText translates input text and returns translated text. func (c *TranslationClient) TranslateText(ctx context.Context, req *translatepb.TranslateTextRequest, opts ...gax.CallOption) (*translatepb.TranslateTextResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.TranslateText[0:len(c.CallOptions.TranslateText):len(c.CallOptions.TranslateText)], opts...) var resp *translatepb.TranslateTextResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.translationClient.TranslateText(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DetectLanguage detects the language of text within a request. func (c *TranslationClient) DetectLanguage(ctx context.Context, req *translatepb.DetectLanguageRequest, opts ...gax.CallOption) (*translatepb.DetectLanguageResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DetectLanguage[0:len(c.CallOptions.DetectLanguage):len(c.CallOptions.DetectLanguage)], opts...) var resp *translatepb.DetectLanguageResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.translationClient.DetectLanguage(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // GetSupportedLanguages returns a list of supported languages for translation. func (c *TranslationClient) GetSupportedLanguages(ctx context.Context, req *translatepb.GetSupportedLanguagesRequest, opts ...gax.CallOption) (*translatepb.SupportedLanguages, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetSupportedLanguages[0:len(c.CallOptions.GetSupportedLanguages):len(c.CallOptions.GetSupportedLanguages)], opts...) var resp *translatepb.SupportedLanguages err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.translationClient.GetSupportedLanguages(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // BatchTranslateText translates a large volume of text in asynchronous batch mode. // This function provides real-time output as the inputs are being processed. // If caller cancels a request, the partial results (for an input file, it’s // all or nothing) may still be available on the specified output location. // // This call returns immediately and you can // use google.longrunning.Operation.name (at http://google.longrunning.Operation.name) to poll the status of the call. func (c *TranslationClient) BatchTranslateText(ctx context.Context, req *translatepb.BatchTranslateTextRequest, opts ...gax.CallOption) (*BatchTranslateTextOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.BatchTranslateText[0:len(c.CallOptions.BatchTranslateText):len(c.CallOptions.BatchTranslateText)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.translationClient.BatchTranslateText(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &BatchTranslateTextOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // CreateGlossary creates a glossary and returns the long-running operation. Returns // NOT_FOUND, if the project doesn’t exist. func (c *TranslationClient) CreateGlossary(ctx context.Context, req *translatepb.CreateGlossaryRequest, opts ...gax.CallOption) (*CreateGlossaryOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateGlossary[0:len(c.CallOptions.CreateGlossary):len(c.CallOptions.CreateGlossary)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.translationClient.CreateGlossary(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &CreateGlossaryOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // ListGlossaries lists glossaries in a project. Returns NOT_FOUND, if the project doesn’t // exist. func (c *TranslationClient) ListGlossaries(ctx context.Context, req *translatepb.ListGlossariesRequest, opts ...gax.CallOption) *GlossaryIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListGlossaries[0:len(c.CallOptions.ListGlossaries):len(c.CallOptions.ListGlossaries)], opts...) it := &GlossaryIterator{} req = proto.Clone(req).(*translatepb.ListGlossariesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*translatepb.Glossary, string, error) { var resp *translatepb.ListGlossariesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.translationClient.ListGlossaries(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } it.Response = resp return resp.Glossaries, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetGlossary gets a glossary. Returns NOT_FOUND, if the glossary doesn’t // exist. func (c *TranslationClient) GetGlossary(ctx context.Context, req *translatepb.GetGlossaryRequest, opts ...gax.CallOption) (*translatepb.Glossary, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetGlossary[0:len(c.CallOptions.GetGlossary):len(c.CallOptions.GetGlossary)], opts...) var resp *translatepb.Glossary err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.translationClient.GetGlossary(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteGlossary deletes a glossary, or cancels glossary construction // if the glossary isn’t created yet. // Returns NOT_FOUND, if the glossary doesn’t exist. func (c *TranslationClient) DeleteGlossary(ctx context.Context, req *translatepb.DeleteGlossaryRequest, opts ...gax.CallOption) (*DeleteGlossaryOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteGlossary[0:len(c.CallOptions.DeleteGlossary):len(c.CallOptions.DeleteGlossary)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.translationClient.DeleteGlossary(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &DeleteGlossaryOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // BatchTranslateTextOperation manages a long-running operation from BatchTranslateText. type BatchTranslateTextOperation struct { lro *longrunning.Operation } // BatchTranslateTextOperation returns a new BatchTranslateTextOperation from a given name. // The name must be that of a previously created BatchTranslateTextOperation, possibly from a different process. func (c *TranslationClient) BatchTranslateTextOperation(name string) *BatchTranslateTextOperation { return &BatchTranslateTextOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *BatchTranslateTextOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*translatepb.BatchTranslateResponse, error) { var resp translatepb.BatchTranslateResponse if err := op.lro.WaitWithInterval(ctx, &resp, time.Minute, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *BatchTranslateTextOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*translatepb.BatchTranslateResponse, error) { var resp translatepb.BatchTranslateResponse if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *BatchTranslateTextOperation) Metadata() (*translatepb.BatchTranslateMetadata, error) { var meta translatepb.BatchTranslateMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *BatchTranslateTextOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *BatchTranslateTextOperation) Name() string { return op.lro.Name() } // CreateGlossaryOperation manages a long-running operation from CreateGlossary. type CreateGlossaryOperation struct { lro *longrunning.Operation } // CreateGlossaryOperation returns a new CreateGlossaryOperation from a given name. // The name must be that of a previously created CreateGlossaryOperation, possibly from a different process. func (c *TranslationClient) CreateGlossaryOperation(name string) *CreateGlossaryOperation { return &CreateGlossaryOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *CreateGlossaryOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*translatepb.Glossary, error) { var resp translatepb.Glossary if err := op.lro.WaitWithInterval(ctx, &resp, time.Minute, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *CreateGlossaryOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*translatepb.Glossary, error) { var resp translatepb.Glossary if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *CreateGlossaryOperation) Metadata() (*translatepb.CreateGlossaryMetadata, error) { var meta translatepb.CreateGlossaryMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *CreateGlossaryOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *CreateGlossaryOperation) Name() string { return op.lro.Name() } // DeleteGlossaryOperation manages a long-running operation from DeleteGlossary. type DeleteGlossaryOperation struct { lro *longrunning.Operation } // DeleteGlossaryOperation returns a new DeleteGlossaryOperation from a given name. // The name must be that of a previously created DeleteGlossaryOperation, possibly from a different process. func (c *TranslationClient) DeleteGlossaryOperation(name string) *DeleteGlossaryOperation { return &DeleteGlossaryOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *DeleteGlossaryOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*translatepb.DeleteGlossaryResponse, error) { var resp translatepb.DeleteGlossaryResponse if err := op.lro.WaitWithInterval(ctx, &resp, time.Minute, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *DeleteGlossaryOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*translatepb.DeleteGlossaryResponse, error) { var resp translatepb.DeleteGlossaryResponse if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *DeleteGlossaryOperation) Metadata() (*translatepb.DeleteGlossaryMetadata, error) { var meta translatepb.DeleteGlossaryMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *DeleteGlossaryOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *DeleteGlossaryOperation) Name() string { return op.lro.Name() } // GlossaryIterator manages a stream of *translatepb.Glossary. type GlossaryIterator struct { items []*translatepb.Glossary pageInfo *iterator.PageInfo nextFunc func() error // Response is the raw response for the current page. // It must be cast to the RPC response type. // Calling Next() or InternalFetch() updates this value. Response interface{} // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*translatepb.Glossary, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *GlossaryIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *GlossaryIterator) Next() (*translatepb.Glossary, error) { var item *translatepb.Glossary if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *GlossaryIterator) bufLen() int { return len(it.items) } func (it *GlossaryIterator) takeBuf() interface{} { b := it.items it.items = nil return b } google-cloud-go-0.49.0/translate/apiv3/translation_client_example_test.go000066400000000000000000000117051356504100700266100ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go_gapic. DO NOT EDIT. package translate_test import ( "context" translate "cloud.google.com/go/translate/apiv3" "google.golang.org/api/iterator" translatepb "google.golang.org/genproto/googleapis/cloud/translate/v3" ) func ExampleNewTranslationClient() { ctx := context.Background() c, err := translate.NewTranslationClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleTranslationClient_TranslateText() { // import translatepb "google.golang.org/genproto/googleapis/cloud/translate/v3" ctx := context.Background() c, err := translate.NewTranslationClient(ctx) if err != nil { // TODO: Handle error. } req := &translatepb.TranslateTextRequest{ // TODO: Fill request struct fields. } resp, err := c.TranslateText(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleTranslationClient_DetectLanguage() { // import translatepb "google.golang.org/genproto/googleapis/cloud/translate/v3" ctx := context.Background() c, err := translate.NewTranslationClient(ctx) if err != nil { // TODO: Handle error. } req := &translatepb.DetectLanguageRequest{ // TODO: Fill request struct fields. } resp, err := c.DetectLanguage(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleTranslationClient_GetSupportedLanguages() { // import translatepb "google.golang.org/genproto/googleapis/cloud/translate/v3" ctx := context.Background() c, err := translate.NewTranslationClient(ctx) if err != nil { // TODO: Handle error. } req := &translatepb.GetSupportedLanguagesRequest{ // TODO: Fill request struct fields. } resp, err := c.GetSupportedLanguages(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleTranslationClient_BatchTranslateText() { // import translatepb "google.golang.org/genproto/googleapis/cloud/translate/v3" ctx := context.Background() c, err := translate.NewTranslationClient(ctx) if err != nil { // TODO: Handle error. } req := &translatepb.BatchTranslateTextRequest{ // TODO: Fill request struct fields. } op, err := c.BatchTranslateText(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleTranslationClient_CreateGlossary() { // import translatepb "google.golang.org/genproto/googleapis/cloud/translate/v3" ctx := context.Background() c, err := translate.NewTranslationClient(ctx) if err != nil { // TODO: Handle error. } req := &translatepb.CreateGlossaryRequest{ // TODO: Fill request struct fields. } op, err := c.CreateGlossary(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleTranslationClient_ListGlossaries() { // import translatepb "google.golang.org/genproto/googleapis/cloud/translate/v3" // import "google.golang.org/api/iterator" ctx := context.Background() c, err := translate.NewTranslationClient(ctx) if err != nil { // TODO: Handle error. } req := &translatepb.ListGlossariesRequest{ // TODO: Fill request struct fields. } it := c.ListGlossaries(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleTranslationClient_GetGlossary() { // import translatepb "google.golang.org/genproto/googleapis/cloud/translate/v3" ctx := context.Background() c, err := translate.NewTranslationClient(ctx) if err != nil { // TODO: Handle error. } req := &translatepb.GetGlossaryRequest{ // TODO: Fill request struct fields. } resp, err := c.GetGlossary(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleTranslationClient_DeleteGlossary() { // import translatepb "google.golang.org/genproto/googleapis/cloud/translate/v3" ctx := context.Background() c, err := translate.NewTranslationClient(ctx) if err != nil { // TODO: Handle error. } req := &translatepb.DeleteGlossaryRequest{ // TODO: Fill request struct fields. } op, err := c.DeleteGlossary(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/translate/examples_test.go000066400000000000000000000036371356504100700220020ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package translate_test import ( "context" "fmt" "cloud.google.com/go/translate" "golang.org/x/text/language" ) func Example_NewClient() { ctx := context.Background() client, err := translate.NewClient(ctx) if err != nil { // TODO: handle error. } // Use the client. // Close the client when finished. if err := client.Close(); err != nil { // TODO: handle error. } } func Example_Translate() { ctx := context.Background() client, err := translate.NewClient(ctx) if err != nil { // TODO: handle error. } translations, err := client.Translate(ctx, []string{"Le singe est sur la branche"}, language.English, &translate.Options{ Source: language.French, Format: translate.Text, }) if err != nil { // TODO: handle error. } fmt.Println(translations[0].Text) } func Example_DetectLanguage() { ctx := context.Background() client, err := translate.NewClient(ctx) if err != nil { // TODO: handle error. } ds, err := client.DetectLanguage(ctx, []string{"Today is Monday"}) if err != nil { // TODO: handle error. } fmt.Println(ds) } func Example_SupportedLanguages() { ctx := context.Background() client, err := translate.NewClient(ctx) if err != nil { // TODO: handle error. } langs, err := client.SupportedLanguages(ctx, language.English) if err != nil { // TODO: handle error. } fmt.Println(langs) } google-cloud-go-0.49.0/translate/translate.go000066400000000000000000000160751356504100700211220ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package translate is the v2 client for the Google Translation API. // // PLEASE NOTE: We recommend using the new v3 client for new projects: // https://cloud.google.com/go/translate/apiv3. // // See https://cloud.google.com/translation for details. package translate import ( "context" "fmt" "net/http" "cloud.google.com/go/internal/version" "golang.org/x/text/language" "google.golang.org/api/option" raw "google.golang.org/api/translate/v2" htransport "google.golang.org/api/transport/http" ) const userAgent = "gcloud-golang-translate/20161115" // Scope is the OAuth2 scope required by the Google Cloud Vision API. const Scope = raw.CloudPlatformScope // Client is a client for the translate API. type Client struct { raw *raw.Service } const prodAddr = "https://translation.googleapis.com/language/translate/" // NewClient constructs a new Client that can perform Translation operations. // // You can find or create API key for your project from the Credentials page of // the Developers Console (console.developers.google.com). func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { o := []option.ClientOption{ option.WithEndpoint(prodAddr), option.WithScopes(Scope), option.WithUserAgent(userAgent), } o = append(o, opts...) httpClient, endpoint, err := htransport.NewClient(ctx, o...) if err != nil { return nil, fmt.Errorf("dialing: %v", err) } rawService, err := raw.New(httpClient) if err != nil { return nil, fmt.Errorf("translate client: %v", err) } rawService.BasePath = endpoint return &Client{raw: rawService}, nil } // Close closes any resources held by the client. // Close should be called when the client is no longer needed. // It need not be called at program exit. func (c *Client) Close() error { return nil } // Translate one or more strings of text from a source language to a target // language. All inputs must be in the same language. // // The target parameter supplies the language to translate to. The supported // languages are listed at // https://cloud.google.com/translation/v2/translate-reference#supported_languages. // You can also call the SupportedLanguages method. // // The returned Translations appear in the same order as the inputs. func (c *Client) Translate(ctx context.Context, inputs []string, target language.Tag, opts *Options) ([]Translation, error) { call := c.raw.Translations.List(inputs, target.String()).Context(ctx) setClientHeader(call.Header()) if opts != nil { if s := opts.Source; s != language.Und { call.Source(s.String()) } if f := opts.Format; f != "" { call.Format(string(f)) } if m := opts.Model; m != "" { call.Model(m) } } res, err := call.Do() if err != nil { return nil, err } var ts []Translation for _, t := range res.Translations { var source language.Tag if t.DetectedSourceLanguage != "" { source, err = language.Parse(t.DetectedSourceLanguage) if err != nil { return nil, err } } ts = append(ts, Translation{ Text: t.TranslatedText, Source: source, Model: t.Model, }) } return ts, nil } // Options contains options for Translate. type Options struct { // Source is the language of the input strings. If empty, the service will // attempt to identify the source language automatically and return it within // the response. Source language.Tag // Format describes the format of the input texts. The choices are HTML or // Text. The default is HTML. Format Format // The model to use for translation. The choices are "nmt" or "base". The // default is "base". Model string } // Format is the format of the input text. Used in Options.Format. type Format string // Constants for Options.Format. const ( HTML Format = "html" Text Format = "text" ) // Translation contains the results of translating a piece of text. type Translation struct { // Text is the input text translated into the target language. Text string // Source is the detected language of the input text, if source was // not supplied to Client.Translate. If source was supplied, this field // will be empty. Source language.Tag // Model is the model that was used for translation. // It may not match the model provided as an option to Client.Translate. Model string } // DetectLanguage attempts to determine the language of the inputs. Each input // string may be in a different language. // // Each slice of Detections in the return value corresponds with one input // string. A slice of Detections holds multiple hypotheses for the language of // a single input string. func (c *Client) DetectLanguage(ctx context.Context, inputs []string) ([][]Detection, error) { call := c.raw.Detections.List(inputs).Context(ctx) setClientHeader(call.Header()) res, err := call.Do() if err != nil { return nil, err } var result [][]Detection for _, raws := range res.Detections { var ds []Detection for _, rd := range raws { tag, err := language.Parse(rd.Language) if err != nil { return nil, err } ds = append(ds, Detection{ Language: tag, Confidence: rd.Confidence, IsReliable: rd.IsReliable, }) } result = append(result, ds) } return result, nil } // Detection represents information about a language detected in an input. type Detection struct { // Language is the code of the language detected. Language language.Tag // Confidence is a number from 0 to 1, with higher numbers indicating more // confidence in the detection. Confidence float64 // IsReliable indicates whether the language detection result is reliable. IsReliable bool } // SupportedLanguages returns a list of supported languages for translation. // The target parameter is the language to use to return localized, human // readable names of supported languages. func (c *Client) SupportedLanguages(ctx context.Context, target language.Tag) ([]Language, error) { call := c.raw.Languages.List().Context(ctx).Target(target.String()) setClientHeader(call.Header()) res, err := call.Do() if err != nil { return nil, err } var ls []Language for _, l := range res.Languages { tag, err := language.Parse(l.Language) if err != nil { return nil, err } ls = append(ls, Language{ Name: l.Name, Tag: tag, }) } return ls, nil } // A Language describes a language supported for translation. type Language struct { // Name is the human-readable name of the language. Name string // Tag is a standard code for the language. Tag language.Tag } func setClientHeader(headers http.Header) { headers.Set("x-goog-api-client", fmt.Sprintf("gl-go/%s gccl/%s", version.Go(), version.Repo)) } google-cloud-go-0.49.0/translate/translate_test.go000066400000000000000000000222321356504100700221510ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package translate import ( "context" "fmt" "io/ioutil" "log" "net/http" "net/url" "os" "strings" "sync" "testing" "cloud.google.com/go/internal/testutil" "golang.org/x/text/language" "google.golang.org/api/option" ) var ( once sync.Once authOpt option.ClientOption ) func initTest(ctx context.Context, t *testing.T) *Client { if testing.Short() { t.Skip("integration tests skipped in short mode") } once.Do(func() { authOpt = authOption() }) if authOpt == nil { t.Skip("Integration tests skipped. See CONTRIBUTING.md for details") } client, err := NewClient(ctx, authOpt) if err != nil { t.Fatalf("NewClient: %v", err) } return client } func authOption() option.ClientOption { ts := testutil.TokenSource(context.Background(), Scope) if ts != nil { log.Println("authenticating via OAuth2") return option.WithTokenSource(ts) } apiKey := os.Getenv("GCLOUD_TESTS_API_KEY") if apiKey != "" { log.Println("authenticating with API key") return option.WithAPIKey(apiKey) } return nil } type fakeTransport struct { req *http.Request } func (t *fakeTransport) RoundTrip(req *http.Request) (*http.Response, error) { t.req = req return &http.Response{ Status: fmt.Sprintf("%d OK", http.StatusOK), StatusCode: http.StatusOK, Body: ioutil.NopCloser(strings.NewReader("{}")), }, nil } func TestTranslateURL(t *testing.T) { // The translate API has all inputs in the URL. // Make sure we generate the right one. ctx := context.Background() ft := &fakeTransport{} c, err := NewClient(ctx, option.WithHTTPClient(&http.Client{Transport: ft})) if err != nil { t.Fatal(err) } for _, test := range []struct { target language.Tag inputs []string opts *Options want url.Values }{ {language.Spanish, []string{"text"}, nil, url.Values{ "q": []string{"text"}, "target": []string{"es"}, "prettyPrint": []string{"false"}, }}, {language.English, []string{"text"}, &Options{}, url.Values{ "q": []string{"text"}, "target": []string{"en"}, "prettyPrint": []string{"false"}, }}, {language.Turkish, []string{"t1", "t2"}, nil, url.Values{ "q": []string{"t1", "t2"}, "target": []string{"tr"}, "prettyPrint": []string{"false"}, }}, {language.English, []string{"text"}, &Options{Source: language.French}, url.Values{ "q": []string{"text"}, "source": []string{"fr"}, "target": []string{"en"}, "prettyPrint": []string{"false"}, }, }, {language.English, []string{"text"}, &Options{Source: language.French, Format: HTML}, url.Values{ "q": []string{"text"}, "source": []string{"fr"}, "format": []string{"html"}, "target": []string{"en"}, "prettyPrint": []string{"false"}, }}, } { _, err = c.Translate(ctx, test.inputs, test.target, test.opts) if err != nil { t.Fatal(err) } got := ft.req.URL.Query() test.want.Add("alt", "json") if !testutil.Equal(got, test.want) { t.Errorf("Translate(%s, %v, %+v):\ngot %s\nwant %s", test.target, test.inputs, test.opts, got, test.want) } } } func TestTranslateOneInput(t *testing.T) { ctx := context.Background() c := initTest(ctx, t) defer c.Close() translate := func(input string, target language.Tag, opts *Options) Translation { ts, err := c.Translate(ctx, []string{input}, target, opts) if err != nil { t.Fatal(err) } if len(ts) != 1 { t.Fatalf("wanted one Translation, got %d", len(ts)) } return ts[0] } for _, test := range []struct { input string source language.Tag output string target language.Tag }{ // https://www.youtube.com/watch?v=x1sQkEfAdfY {"Le singe est sur la branche", language.French, "The monkey is on the branch", language.English}, {"The cat is on the chair", language.English, "Le chat est sur la chaise", language.French}, } { // Provide source and format. tr := translate(test.input, test.target, &Options{Source: test.source, Format: Text}) if got, want := tr.Source, language.Und; got != want { t.Errorf("source: got %q, wanted %q", got, want) continue } if got, want := tr.Text, test.output; got != want { t.Errorf("text: got %q, want %q", got, want) } // Omit source; it should be detected. tr = translate(test.input, test.target, &Options{Format: Text}) if got, want := tr.Source, test.source; got != want { t.Errorf("source: got %q, wanted %q", got, want) continue } if got, want := tr.Text, test.output; got != want { t.Errorf("text: got %q, want %q", got, want) } // Omit format. Defaults to HTML. Still works with plain text. tr = translate(test.input, test.target, nil) if got, want := tr.Source, test.source; got != want { t.Errorf("source: got %q, wanted %q", got, want) continue } if got, want := tr.Text, test.output; got != want { t.Errorf("text: got %q, want %q", got, want) } // Add HTML tags to input. They should be in output. htmlify := func(s string) string { return "" + s + "" } tr = translate(htmlify(test.input), test.target, nil) if got, want := tr.Text, htmlify(test.output); got != want { t.Errorf("html: got %q, want %q", got, want) } // Using the HTML format behaves the same. tr = translate(htmlify(test.input), test.target, &Options{Format: HTML}) if got, want := tr.Text, htmlify(test.output); got != want { t.Errorf("html: got %q, want %q", got, want) } } } // This tests the beta "nmt" model. func TestTranslateModel(t *testing.T) { ctx := context.Background() c := initTest(ctx, t) defer c.Close() trs, err := c.Translate(ctx, []string{"Thanks"}, language.French, &Options{Model: "nmt"}) if err != nil { t.Fatal(err) } if len(trs) != 1 { t.Fatalf("wanted one Translation, got %d", len(trs)) } tr := trs[0] if got, want := tr.Text, "Merci"; got != want { t.Errorf("text: got %q, want %q", got, want) } if got, want := tr.Model, "nmt"; got != want { t.Errorf("model: got %q, want %q", got, want) } } func TestTranslateMultipleInputs(t *testing.T) { ctx := context.Background() c := initTest(ctx, t) defer c.Close() inputs := []string{ "When you're a Jet, you're a Jet all the way", "From your first cigarette to your last dying day", "When you're a Jet if the spit hits the fan", "You got brothers around, you're a family man", } ts, err := c.Translate(ctx, inputs, language.French, nil) if err != nil { t.Fatal(err) } if got, want := len(ts), len(inputs); got != want { t.Fatalf("got %d Translations, wanted %d", got, want) } } func TestTranslateErrors(t *testing.T) { ctx := context.Background() c := initTest(ctx, t) defer c.Close() for _, test := range []struct { ctx context.Context target language.Tag inputs []string opts *Options }{ {ctx, language.English, nil, nil}, {ctx, language.Und, []string{"input"}, nil}, {ctx, language.English, []string{}, nil}, {ctx, language.English, []string{"input"}, &Options{Format: "random"}}, } { _, err := c.Translate(test.ctx, test.inputs, test.target, test.opts) if err == nil { t.Errorf("%+v: got nil, want error", test) } } } func TestDetectLanguage(t *testing.T) { ctx := context.Background() c := initTest(ctx, t) defer c.Close() ds, err := c.DetectLanguage(ctx, []string{ "Today is Monday", "Aujourd'hui est lundi", }) if err != nil { t.Fatal(err) } if len(ds) != 2 { t.Fatalf("got %d detection lists, want 2", len(ds)) } checkDetections(t, ds[0], language.English) checkDetections(t, ds[1], language.French) } func checkDetections(t *testing.T, ds []Detection, want language.Tag) { for _, d := range ds { if d.Language == want { return } } t.Errorf("%v: missing %s", ds, want) } // A small subset of the supported languages. var supportedLangs = []Language{ {Name: "Danish", Tag: language.Danish}, {Name: "English", Tag: language.English}, {Name: "French", Tag: language.French}, {Name: "German", Tag: language.German}, {Name: "Greek", Tag: language.Greek}, {Name: "Hindi", Tag: language.Hindi}, {Name: "Hungarian", Tag: language.Hungarian}, {Name: "Italian", Tag: language.Italian}, {Name: "Russian", Tag: language.Russian}, {Name: "Turkish", Tag: language.Turkish}, } func TestSupportedLanguages(t *testing.T) { ctx := context.Background() c := initTest(ctx, t) defer c.Close() got, err := c.SupportedLanguages(ctx, language.English) if err != nil { t.Fatal(err) } want := map[language.Tag]Language{} for _, sl := range supportedLangs { want[sl.Tag] = sl } for _, g := range got { w, ok := want[g.Tag] if !ok { continue } if g != w { t.Errorf("got %+v, want %+v", g, w) } delete(want, g.Tag) } if len(want) > 0 { t.Errorf("missing: %+v", want) } } google-cloud-go-0.49.0/videointelligence/000077500000000000000000000000001356504100700202615ustar00rootroot00000000000000google-cloud-go-0.49.0/videointelligence/apiv1/000077500000000000000000000000001356504100700213015ustar00rootroot00000000000000google-cloud-go-0.49.0/videointelligence/apiv1/.repo-metadata.json000066400000000000000000000006751356504100700250050ustar00rootroot00000000000000{ "name": "videointelligence", "name_pretty": "Translation API", "product_documentation": "https://cloud.google.com/video-intelligence", "client_documentation": "https://godoc.org/cloud.google.com/go/videointelligence/apiv1", "release_level": "alpha", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "videointelligence.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/videointelligence/apiv1/AnnotateVideo_smoke_test.go000066400000000000000000000035011356504100700266240ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package videointelligence import ( "context" "fmt" "strconv" "testing" "time" "cloud.google.com/go/internal/testutil" "google.golang.org/api/iterator" "google.golang.org/api/option" videointelligencepb "google.golang.org/genproto/googleapis/cloud/videointelligence/v1" ) var _ = fmt.Sprintf var _ = iterator.Done var _ = strconv.FormatUint var _ = time.Now func TestVideoIntelligenceServiceSmoke(t *testing.T) { if testing.Short() { t.Skip("skipping smoke test in short mode") } ctx := context.Background() ts := testutil.TokenSource(ctx, DefaultAuthScopes()...) if ts == nil { t.Skip("Integration tests skipped. See CONTRIBUTING.md for details") } projectId := testutil.ProjID() _ = projectId c, err := NewClient(ctx, option.WithTokenSource(ts)) if err != nil { t.Fatal(err) } var inputUri string = "gs://cloud-samples-data/video/cat.mp4" var featuresElement videointelligencepb.Feature = videointelligencepb.Feature_LABEL_DETECTION var features = []videointelligencepb.Feature{featuresElement} var request = &videointelligencepb.AnnotateVideoRequest{ InputUri: inputUri, Features: features, } if _, err := c.AnnotateVideo(ctx, request); err != nil { t.Error(err) } } google-cloud-go-0.49.0/videointelligence/apiv1/doc.go000066400000000000000000000056011356504100700223770ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package videointelligence is an auto-generated package for the // Cloud Video Intelligence API. // // NOTE: This package is in alpha. It is not stable, and is likely to change. // // Detects objects, explicit content, and scene changes in videos. It also // specifies the region for annotation and transcribes speech to text. // Supports both asynchronous API and streaming API. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package videointelligence // import "cloud.google.com/go/videointelligence/apiv1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "UNKNOWN" google-cloud-go-0.49.0/videointelligence/apiv1/mock_test.go000066400000000000000000000123251356504100700236230ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package videointelligence import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" "google.golang.org/api/option" videointelligencepb "google.golang.org/genproto/googleapis/cloud/videointelligence/v1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockVideoIntelligenceServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. videointelligencepb.VideoIntelligenceServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockVideoIntelligenceServer) AnnotateVideo(ctx context.Context, req *videointelligencepb.AnnotateVideoRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockVideoIntelligence mockVideoIntelligenceServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() videointelligencepb.RegisterVideoIntelligenceServiceServer(serv, &mockVideoIntelligence) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestVideoIntelligenceServiceAnnotateVideo(t *testing.T) { var expectedResponse *videointelligencepb.AnnotateVideoResponse = &videointelligencepb.AnnotateVideoResponse{} mockVideoIntelligence.err = nil mockVideoIntelligence.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockVideoIntelligence.resps = append(mockVideoIntelligence.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var featuresElement videointelligencepb.Feature = videointelligencepb.Feature_LABEL_DETECTION var features = []videointelligencepb.Feature{featuresElement} var inputUri string = "gs://cloud-samples-data/video/cat.mp4" var request = &videointelligencepb.AnnotateVideoRequest{ Features: features, InputUri: inputUri, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.AnnotateVideo(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockVideoIntelligence.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestVideoIntelligenceServiceAnnotateVideoError(t *testing.T) { errCode := codes.PermissionDenied mockVideoIntelligence.err = nil mockVideoIntelligence.resps = append(mockVideoIntelligence.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var featuresElement videointelligencepb.Feature = videointelligencepb.Feature_LABEL_DETECTION var features = []videointelligencepb.Feature{featuresElement} var inputUri string = "gs://cloud-samples-data/video/cat.mp4" var request = &videointelligencepb.AnnotateVideoRequest{ Features: features, InputUri: inputUri, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.AnnotateVideo(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/videointelligence/apiv1/video_intelligence_client.go000066400000000000000000000177061356504100700270310ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package videointelligence import ( "context" "math" "time" "cloud.google.com/go/longrunning" lroauto "cloud.google.com/go/longrunning/autogen" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" "google.golang.org/api/transport" videointelligencepb "google.golang.org/genproto/googleapis/cloud/videointelligence/v1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" "google.golang.org/grpc" "google.golang.org/grpc/metadata" ) // CallOptions contains the retry settings for each method of Client. type CallOptions struct { AnnotateVideo []gax.CallOption } func defaultClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("videointelligence.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultCallOptions() *CallOptions { retry := map[[2]string][]gax.CallOption{} return &CallOptions{ AnnotateVideo: retry[[2]string{"default", "non_idempotent"}], } } // Client is a client for interacting with Cloud Video Intelligence API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. client videointelligencepb.VideoIntelligenceServiceClient // LROClient is used internally to handle longrunning operations. // It is exposed so that its CallOptions can be modified if required. // Users should not Close this client. LROClient *lroauto.OperationsClient // The call options for this service. CallOptions *CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewClient creates a new video intelligence service client. // // Service that implements Google Cloud Video Intelligence API. func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultClientOptions(), opts...)...) if err != nil { return nil, err } c := &Client{ conn: conn, CallOptions: defaultCallOptions(), client: videointelligencepb.NewVideoIntelligenceServiceClient(conn), } c.setGoogleClientInfo() c.LROClient, err = lroauto.NewOperationsClient(ctx, option.WithGRPCConn(conn)) if err != nil { // This error "should not happen", since we are just reusing old connection // and never actually need to dial. // If this does happen, we could leak conn. However, we cannot close conn: // If the user invoked the function with option.WithGRPCConn, // we would close a connection that's still in use. // TODO(pongad): investigate error conditions. return nil, err } return c, nil } // Connection returns the client's connection to the API service. func (c *Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *Client) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *Client) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // AnnotateVideo performs asynchronous video annotation. Progress and results can be // retrieved through the google.longrunning.Operations interface. // Operation.metadata contains AnnotateVideoProgress (progress). // Operation.response contains AnnotateVideoResponse (results). func (c *Client) AnnotateVideo(ctx context.Context, req *videointelligencepb.AnnotateVideoRequest, opts ...gax.CallOption) (*AnnotateVideoOperation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.AnnotateVideo[0:len(c.CallOptions.AnnotateVideo):len(c.CallOptions.AnnotateVideo)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.AnnotateVideo(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &AnnotateVideoOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // AnnotateVideoOperation manages a long-running operation from AnnotateVideo. type AnnotateVideoOperation struct { lro *longrunning.Operation } // AnnotateVideoOperation returns a new AnnotateVideoOperation from a given name. // The name must be that of a previously created AnnotateVideoOperation, possibly from a different process. func (c *Client) AnnotateVideoOperation(name string) *AnnotateVideoOperation { return &AnnotateVideoOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *AnnotateVideoOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*videointelligencepb.AnnotateVideoResponse, error) { var resp videointelligencepb.AnnotateVideoResponse if err := op.lro.WaitWithInterval(ctx, &resp, 45000*time.Millisecond, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *AnnotateVideoOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*videointelligencepb.AnnotateVideoResponse, error) { var resp videointelligencepb.AnnotateVideoResponse if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *AnnotateVideoOperation) Metadata() (*videointelligencepb.AnnotateVideoProgress, error) { var meta videointelligencepb.AnnotateVideoProgress if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *AnnotateVideoOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *AnnotateVideoOperation) Name() string { return op.lro.Name() } google-cloud-go-0.49.0/videointelligence/apiv1/video_intelligence_client_example_test.go000066400000000000000000000026671356504100700316030ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package videointelligence_test import ( "context" videointelligence "cloud.google.com/go/videointelligence/apiv1" videointelligencepb "google.golang.org/genproto/googleapis/cloud/videointelligence/v1" ) func ExampleNewClient() { ctx := context.Background() c, err := videointelligence.NewClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleClient_AnnotateVideo() { ctx := context.Background() c, err := videointelligence.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &videointelligencepb.AnnotateVideoRequest{ // TODO: Fill request struct fields. } op, err := c.AnnotateVideo(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/videointelligence/apiv1beta2/000077500000000000000000000000001356504100700222175ustar00rootroot00000000000000google-cloud-go-0.49.0/videointelligence/apiv1beta2/.repo-metadata.json000066400000000000000000000007011356504100700257110ustar00rootroot00000000000000{ "name": "videointelligence", "name_pretty": "Translation API", "product_documentation": "https://cloud.google.com/video-intelligence", "client_documentation": "https://godoc.org/cloud.google.com/go/videointelligence/apiv1beta2", "release_level": "beta", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "videointelligence.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/videointelligence/apiv1beta2/doc.go000066400000000000000000000056231356504100700233210ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package videointelligence is an auto-generated package for the // Google Cloud Video Intelligence API. // // NOTE: This package is in beta. It is not stable, and may be subject to changes. // // Detects objects, explicit content, and scene changes in videos. It also // specifies the region for annotation and transcribes speech to text. // Supports both asynchronous API and streaming API. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package videointelligence // import "cloud.google.com/go/videointelligence/apiv1beta2" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191115" google-cloud-go-0.49.0/videointelligence/apiv1beta2/mock_test.go000066400000000000000000000123321356504100700245370ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package videointelligence import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" "google.golang.org/api/option" videointelligencepb "google.golang.org/genproto/googleapis/cloud/videointelligence/v1beta2" longrunningpb "google.golang.org/genproto/googleapis/longrunning" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockVideoIntelligenceServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. videointelligencepb.VideoIntelligenceServiceServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockVideoIntelligenceServer) AnnotateVideo(ctx context.Context, req *videointelligencepb.AnnotateVideoRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockVideoIntelligence mockVideoIntelligenceServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() videointelligencepb.RegisterVideoIntelligenceServiceServer(serv, &mockVideoIntelligence) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestVideoIntelligenceServiceAnnotateVideo(t *testing.T) { var expectedResponse *videointelligencepb.AnnotateVideoResponse = &videointelligencepb.AnnotateVideoResponse{} mockVideoIntelligence.err = nil mockVideoIntelligence.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockVideoIntelligence.resps = append(mockVideoIntelligence.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var inputUri string = "gs://cloud-samples-data/video/cat.mp4" var featuresElement videointelligencepb.Feature = videointelligencepb.Feature_LABEL_DETECTION var features = []videointelligencepb.Feature{featuresElement} var request = &videointelligencepb.AnnotateVideoRequest{ InputUri: inputUri, Features: features, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.AnnotateVideo(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockVideoIntelligence.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestVideoIntelligenceServiceAnnotateVideoError(t *testing.T) { errCode := codes.PermissionDenied mockVideoIntelligence.err = nil mockVideoIntelligence.resps = append(mockVideoIntelligence.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var inputUri string = "gs://cloud-samples-data/video/cat.mp4" var featuresElement videointelligencepb.Feature = videointelligencepb.Feature_LABEL_DETECTION var features = []videointelligencepb.Feature{featuresElement} var request = &videointelligencepb.AnnotateVideoRequest{ InputUri: inputUri, Features: features, } c, err := NewClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.AnnotateVideo(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/videointelligence/apiv1beta2/video_intelligence_client.go000066400000000000000000000204421356504100700277360ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package videointelligence import ( "context" "math" "time" "cloud.google.com/go/longrunning" lroauto "cloud.google.com/go/longrunning/autogen" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" "google.golang.org/api/transport" videointelligencepb "google.golang.org/genproto/googleapis/cloud/videointelligence/v1beta2" longrunningpb "google.golang.org/genproto/googleapis/longrunning" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // CallOptions contains the retry settings for each method of Client. type CallOptions struct { AnnotateVideo []gax.CallOption } func defaultClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("videointelligence.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultCallOptions() *CallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 1000 * time.Millisecond, Max: 120000 * time.Millisecond, Multiplier: 2.5, }) }), }, } return &CallOptions{ AnnotateVideo: retry[[2]string{"default", "idempotent"}], } } // Client is a client for interacting with Google Cloud Video Intelligence API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. client videointelligencepb.VideoIntelligenceServiceClient // LROClient is used internally to handle longrunning operations. // It is exposed so that its CallOptions can be modified if required. // Users should not Close this client. LROClient *lroauto.OperationsClient // The call options for this service. CallOptions *CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewClient creates a new video intelligence service client. // // Service that implements Google Cloud Video Intelligence API. func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultClientOptions(), opts...)...) if err != nil { return nil, err } c := &Client{ conn: conn, CallOptions: defaultCallOptions(), client: videointelligencepb.NewVideoIntelligenceServiceClient(conn), } c.setGoogleClientInfo() c.LROClient, err = lroauto.NewOperationsClient(ctx, option.WithGRPCConn(conn)) if err != nil { // This error "should not happen", since we are just reusing old connection // and never actually need to dial. // If this does happen, we could leak conn. However, we cannot close conn: // If the user invoked the function with option.WithGRPCConn, // we would close a connection that's still in use. // TODO(pongad): investigate error conditions. return nil, err } return c, nil } // Connection returns the client's connection to the API service. func (c *Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *Client) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *Client) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // AnnotateVideo performs asynchronous video annotation. Progress and results can be // retrieved through the google.longrunning.Operations interface. // Operation.metadata contains AnnotateVideoProgress (progress). // Operation.response contains AnnotateVideoResponse (results). func (c *Client) AnnotateVideo(ctx context.Context, req *videointelligencepb.AnnotateVideoRequest, opts ...gax.CallOption) (*AnnotateVideoOperation, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.AnnotateVideo[0:len(c.CallOptions.AnnotateVideo):len(c.CallOptions.AnnotateVideo)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.AnnotateVideo(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &AnnotateVideoOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // AnnotateVideoOperation manages a long-running operation from AnnotateVideo. type AnnotateVideoOperation struct { lro *longrunning.Operation } // AnnotateVideoOperation returns a new AnnotateVideoOperation from a given name. // The name must be that of a previously created AnnotateVideoOperation, possibly from a different process. func (c *Client) AnnotateVideoOperation(name string) *AnnotateVideoOperation { return &AnnotateVideoOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *AnnotateVideoOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*videointelligencepb.AnnotateVideoResponse, error) { var resp videointelligencepb.AnnotateVideoResponse if err := op.lro.WaitWithInterval(ctx, &resp, 45000*time.Millisecond, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *AnnotateVideoOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*videointelligencepb.AnnotateVideoResponse, error) { var resp videointelligencepb.AnnotateVideoResponse if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *AnnotateVideoOperation) Metadata() (*videointelligencepb.AnnotateVideoProgress, error) { var meta videointelligencepb.AnnotateVideoProgress if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *AnnotateVideoOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *AnnotateVideoOperation) Name() string { return op.lro.Name() } google-cloud-go-0.49.0/videointelligence/apiv1beta2/video_intelligence_client_example_test.go000066400000000000000000000027011356504100700325060ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package videointelligence_test import ( "context" videointelligence "cloud.google.com/go/videointelligence/apiv1beta2" videointelligencepb "google.golang.org/genproto/googleapis/cloud/videointelligence/v1beta2" ) func ExampleNewClient() { ctx := context.Background() c, err := videointelligence.NewClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleClient_AnnotateVideo() { ctx := context.Background() c, err := videointelligence.NewClient(ctx) if err != nil { // TODO: Handle error. } req := &videointelligencepb.AnnotateVideoRequest{ // TODO: Fill request struct fields. } op, err := c.AnnotateVideo(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/videointelligence/apiv1beta2/whitelist.go000066400000000000000000000012511356504100700245610ustar00rootroot00000000000000// Copyright 2017, Google Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // THIS API IS CURRENTLY UNDER WHITELIST. package videointelligence google-cloud-go-0.49.0/vision/000077500000000000000000000000001356504100700160775ustar00rootroot00000000000000google-cloud-go-0.49.0/vision/apiv1/000077500000000000000000000000001356504100700171175ustar00rootroot00000000000000google-cloud-go-0.49.0/vision/apiv1/.repo-metadata.json000066400000000000000000000006221356504100700226130ustar00rootroot00000000000000{ "name": "vision", "name_pretty": "Vision AI API", "product_documentation": "https://cloud.google.com/vision", "client_documentation": "https://godoc.org/cloud.google.com/go/vision/apiv1", "release_level": "ga", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go/vision", "api_id": "vision.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/vision/apiv1/BatchAnnotateImages_smoke_test.go000066400000000000000000000041551356504100700255510ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package vision import ( "context" "fmt" "strconv" "testing" "time" "cloud.google.com/go/internal/testutil" "google.golang.org/api/iterator" "google.golang.org/api/option" visionpb "google.golang.org/genproto/googleapis/cloud/vision/v1" ) var _ = fmt.Sprintf var _ = iterator.Done var _ = strconv.FormatUint var _ = time.Now func TestImageAnnotatorSmoke(t *testing.T) { if testing.Short() { t.Skip("skipping smoke test in short mode") } ctx := context.Background() ts := testutil.TokenSource(ctx, DefaultAuthScopes()...) if ts == nil { t.Skip("Integration tests skipped. See CONTRIBUTING.md for details") } projectId := testutil.ProjID() _ = projectId c, err := NewImageAnnotatorClient(ctx, option.WithTokenSource(ts)) if err != nil { t.Fatal(err) } var gcsImageUri string = "gs://cloud-samples-data/vision/face_detection/celebrity_recognition/sergey.jpg" var source = &visionpb.ImageSource{ GcsImageUri: gcsImageUri, } var image = &visionpb.Image{ Source: source, } var type_ visionpb.Feature_Type = visionpb.Feature_FACE_DETECTION var featuresElement = &visionpb.Feature{ Type: type_, } var features = []*visionpb.Feature{featuresElement} var requestsElement = &visionpb.AnnotateImageRequest{ Image: image, Features: features, } var requests = []*visionpb.AnnotateImageRequest{requestsElement} var request = &visionpb.BatchAnnotateImagesRequest{ Requests: requests, } if _, err := c.BatchAnnotateImages(ctx, request); err != nil { t.Error(err) } } google-cloud-go-0.49.0/vision/apiv1/README.md000066400000000000000000000004571356504100700204040ustar00rootroot00000000000000Auto-generated vision v1 clients ================================= This package includes auto-generated clients for the vision v1 API. Use the handwritten client (in the parent directory, cloud.google.com/go/vision) in preference to this. This code is EXPERIMENTAL and subject to CHANGE AT ANY TIME. google-cloud-go-0.49.0/vision/apiv1/client.go000066400000000000000000000156171356504100700207360ustar00rootroot00000000000000// Copyright 2017, Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package vision import ( "context" gax "github.com/googleapis/gax-go/v2" pb "google.golang.org/genproto/googleapis/cloud/vision/v1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) // AnnotateImage runs image detection and annotation for a single image. func (c *ImageAnnotatorClient) AnnotateImage(ctx context.Context, req *pb.AnnotateImageRequest, opts ...gax.CallOption) (*pb.AnnotateImageResponse, error) { res, err := c.BatchAnnotateImages(ctx, &pb.BatchAnnotateImagesRequest{ Requests: []*pb.AnnotateImageRequest{req}, }, opts...) if err != nil { return nil, err } return res.Responses[0], nil } // Called for a single image and a single feature. func (c *ImageAnnotatorClient) annotateOne(ctx context.Context, img *pb.Image, ictx *pb.ImageContext, ftype pb.Feature_Type, maxResults int, opts []gax.CallOption) (*pb.AnnotateImageResponse, error) { res, err := c.AnnotateImage(ctx, &pb.AnnotateImageRequest{ Image: img, ImageContext: ictx, Features: []*pb.Feature{{Type: ftype, MaxResults: int32(maxResults)}}, }, opts...) if err != nil { return nil, err } // When there is only one image and one feature, the response's Error field is // unambiguously about that one detection, so we "promote" it to the error return // value. // res.Error is a google.rpc.Status. Convert to a Go error. Use a gRPC // error because it preserves the code as a separate field. // TODO(jba): preserve the details field. if res.Error != nil { return nil, status.Errorf(codes.Code(res.Error.Code), "%s", res.Error.Message) } return res, nil } // DetectFaces performs face detection on the image. // At most maxResults results are returned. func (c *ImageAnnotatorClient) DetectFaces(ctx context.Context, img *pb.Image, ictx *pb.ImageContext, maxResults int, opts ...gax.CallOption) ([]*pb.FaceAnnotation, error) { res, err := c.annotateOne(ctx, img, ictx, pb.Feature_FACE_DETECTION, maxResults, opts) if err != nil { return nil, err } return res.FaceAnnotations, nil } // DetectLandmarks performs landmark detection on the image. // At most maxResults results are returned. func (c *ImageAnnotatorClient) DetectLandmarks(ctx context.Context, img *pb.Image, ictx *pb.ImageContext, maxResults int, opts ...gax.CallOption) ([]*pb.EntityAnnotation, error) { res, err := c.annotateOne(ctx, img, ictx, pb.Feature_LANDMARK_DETECTION, maxResults, opts) if err != nil { return nil, err } return res.LandmarkAnnotations, nil } // DetectLogos performs logo detection on the image. // At most maxResults results are returned. func (c *ImageAnnotatorClient) DetectLogos(ctx context.Context, img *pb.Image, ictx *pb.ImageContext, maxResults int, opts ...gax.CallOption) ([]*pb.EntityAnnotation, error) { res, err := c.annotateOne(ctx, img, ictx, pb.Feature_LOGO_DETECTION, maxResults, opts) if err != nil { return nil, err } return res.LogoAnnotations, nil } // DetectLabels performs label detection on the image. // At most maxResults results are returned. func (c *ImageAnnotatorClient) DetectLabels(ctx context.Context, img *pb.Image, ictx *pb.ImageContext, maxResults int, opts ...gax.CallOption) ([]*pb.EntityAnnotation, error) { res, err := c.annotateOne(ctx, img, ictx, pb.Feature_LABEL_DETECTION, maxResults, opts) if err != nil { return nil, err } return res.LabelAnnotations, nil } // DetectTexts performs text detection on the image. // At most maxResults results are returned. func (c *ImageAnnotatorClient) DetectTexts(ctx context.Context, img *pb.Image, ictx *pb.ImageContext, maxResults int, opts ...gax.CallOption) ([]*pb.EntityAnnotation, error) { res, err := c.annotateOne(ctx, img, ictx, pb.Feature_TEXT_DETECTION, maxResults, opts) if err != nil { return nil, err } return res.TextAnnotations, nil } // DetectDocumentText performs full text (OCR) detection on the image. func (c *ImageAnnotatorClient) DetectDocumentText(ctx context.Context, img *pb.Image, ictx *pb.ImageContext, opts ...gax.CallOption) (*pb.TextAnnotation, error) { res, err := c.annotateOne(ctx, img, ictx, pb.Feature_DOCUMENT_TEXT_DETECTION, 0, opts) if err != nil { return nil, err } return res.FullTextAnnotation, nil } // DetectSafeSearch performs safe-search detection on the image. func (c *ImageAnnotatorClient) DetectSafeSearch(ctx context.Context, img *pb.Image, ictx *pb.ImageContext, opts ...gax.CallOption) (*pb.SafeSearchAnnotation, error) { res, err := c.annotateOne(ctx, img, ictx, pb.Feature_SAFE_SEARCH_DETECTION, 0, opts) if err != nil { return nil, err } return res.SafeSearchAnnotation, nil } // DetectImageProperties computes properties of the image. func (c *ImageAnnotatorClient) DetectImageProperties(ctx context.Context, img *pb.Image, ictx *pb.ImageContext, opts ...gax.CallOption) (*pb.ImageProperties, error) { res, err := c.annotateOne(ctx, img, ictx, pb.Feature_IMAGE_PROPERTIES, 0, opts) if err != nil { return nil, err } return res.ImagePropertiesAnnotation, nil } // DetectWeb computes a web annotation on the image. func (c *ImageAnnotatorClient) DetectWeb(ctx context.Context, img *pb.Image, ictx *pb.ImageContext, opts ...gax.CallOption) (*pb.WebDetection, error) { res, err := c.annotateOne(ctx, img, ictx, pb.Feature_WEB_DETECTION, 0, opts) if err != nil { return nil, err } return res.WebDetection, nil } // CropHints computes crop hints for the image. func (c *ImageAnnotatorClient) CropHints(ctx context.Context, img *pb.Image, ictx *pb.ImageContext, opts ...gax.CallOption) (*pb.CropHintsAnnotation, error) { res, err := c.annotateOne(ctx, img, ictx, pb.Feature_CROP_HINTS, 0, opts) if err != nil { return nil, err } return res.CropHintsAnnotation, nil } // LocalizeObject runs the localizer for object detection. func (c *ImageAnnotatorClient) LocalizeObjects(ctx context.Context, img *pb.Image, ictx *pb.ImageContext, opts ...gax.CallOption) ([]*pb.LocalizedObjectAnnotation, error) { res, err := c.annotateOne(ctx, img, ictx, pb.Feature_OBJECT_LOCALIZATION, 0, opts) if err != nil { return nil, err } return res.LocalizedObjectAnnotations, nil } // ProductSearch searches the image for products. func (c *ImageAnnotatorClient) ProductSearch(ctx context.Context, img *pb.Image, ictx *pb.ImageContext, opts ...gax.CallOption) (*pb.ProductSearchResults, error) { res, err := c.annotateOne(ctx, img, ictx, pb.Feature_PRODUCT_SEARCH, 0, opts) if err != nil { return nil, err } return res.ProductSearchResults, nil } google-cloud-go-0.49.0/vision/apiv1/client_test.go000066400000000000000000000154411356504100700217700ustar00rootroot00000000000000// Copyright 2017, Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package vision import ( "context" "fmt" "reflect" "testing" "github.com/golang/protobuf/proto" pb "google.golang.org/genproto/googleapis/cloud/vision/v1" "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" ) var batchResponse = &pb.BatchAnnotateImagesResponse{ Responses: []*pb.AnnotateImageResponse{{ FaceAnnotations: []*pb.FaceAnnotation{ {RollAngle: 1}, {RollAngle: 2}}, LandmarkAnnotations: []*pb.EntityAnnotation{{Mid: "landmark"}}, LogoAnnotations: []*pb.EntityAnnotation{{Mid: "logo"}}, LabelAnnotations: []*pb.EntityAnnotation{{Mid: "label"}}, TextAnnotations: []*pb.EntityAnnotation{{Mid: "text"}}, FullTextAnnotation: &pb.TextAnnotation{Text: "full"}, SafeSearchAnnotation: &pb.SafeSearchAnnotation{Spoof: pb.Likelihood_POSSIBLE}, ImagePropertiesAnnotation: &pb.ImageProperties{DominantColors: &pb.DominantColorsAnnotation{}}, CropHintsAnnotation: &pb.CropHintsAnnotation{CropHints: []*pb.CropHint{{Confidence: 0.5}}}, WebDetection: &pb.WebDetection{WebEntities: []*pb.WebDetection_WebEntity{{EntityId: "web"}}}, }}, } // Verify that all the "shortcut" methods use the underlying // BatchAnnotateImages RPC correctly. func TestClientMethods(t *testing.T) { ctx := context.Background() c, err := NewImageAnnotatorClient(ctx, clientOpt) if err != nil { t.Fatal(err) } mockImageAnnotator.resps = []proto.Message{batchResponse} img := &pb.Image{Source: &pb.ImageSource{ImageUri: "http://foo.jpg"}} ictx := &pb.ImageContext{LanguageHints: []string{"en", "fr"}} req := &pb.AnnotateImageRequest{ Image: img, ImageContext: ictx, Features: []*pb.Feature{ {Type: pb.Feature_LABEL_DETECTION, MaxResults: 3}, {Type: pb.Feature_FACE_DETECTION, MaxResults: 4}, }, } for i, test := range []struct { call func() (interface{}, error) wantFeatures []*pb.Feature wantRes interface{} }{ { func() (interface{}, error) { return c.AnnotateImage(ctx, req) }, req.Features, batchResponse.Responses[0], }, { func() (interface{}, error) { return c.DetectFaces(ctx, img, ictx, 2) }, []*pb.Feature{{Type: pb.Feature_FACE_DETECTION, MaxResults: 2}}, batchResponse.Responses[0].FaceAnnotations, }, { func() (interface{}, error) { return c.DetectLandmarks(ctx, img, ictx, 2) }, []*pb.Feature{{Type: pb.Feature_LANDMARK_DETECTION, MaxResults: 2}}, batchResponse.Responses[0].LandmarkAnnotations, }, { func() (interface{}, error) { return c.DetectLogos(ctx, img, ictx, 2) }, []*pb.Feature{{Type: pb.Feature_LOGO_DETECTION, MaxResults: 2}}, batchResponse.Responses[0].LogoAnnotations, }, { func() (interface{}, error) { return c.DetectLabels(ctx, img, ictx, 2) }, []*pb.Feature{{Type: pb.Feature_LABEL_DETECTION, MaxResults: 2}}, batchResponse.Responses[0].LabelAnnotations, }, { func() (interface{}, error) { return c.DetectTexts(ctx, img, ictx, 2) }, []*pb.Feature{{Type: pb.Feature_TEXT_DETECTION, MaxResults: 2}}, batchResponse.Responses[0].TextAnnotations, }, { func() (interface{}, error) { return c.DetectDocumentText(ctx, img, ictx) }, []*pb.Feature{{Type: pb.Feature_DOCUMENT_TEXT_DETECTION, MaxResults: 0}}, batchResponse.Responses[0].FullTextAnnotation, }, { func() (interface{}, error) { return c.DetectSafeSearch(ctx, img, ictx) }, []*pb.Feature{{Type: pb.Feature_SAFE_SEARCH_DETECTION, MaxResults: 0}}, batchResponse.Responses[0].SafeSearchAnnotation, }, { func() (interface{}, error) { return c.DetectImageProperties(ctx, img, ictx) }, []*pb.Feature{{Type: pb.Feature_IMAGE_PROPERTIES, MaxResults: 0}}, batchResponse.Responses[0].ImagePropertiesAnnotation, }, { func() (interface{}, error) { return c.DetectWeb(ctx, img, ictx) }, []*pb.Feature{{Type: pb.Feature_WEB_DETECTION, MaxResults: 0}}, batchResponse.Responses[0].WebDetection, }, { func() (interface{}, error) { return c.CropHints(ctx, img, ictx) }, []*pb.Feature{{Type: pb.Feature_CROP_HINTS, MaxResults: 0}}, batchResponse.Responses[0].CropHintsAnnotation, }, { func() (interface{}, error) { return c.LocalizeObjects(ctx, img, ictx) }, []*pb.Feature{{Type: pb.Feature_OBJECT_LOCALIZATION, MaxResults: 0}}, batchResponse.Responses[0].LocalizedObjectAnnotations, }, { func() (interface{}, error) { return c.ProductSearch(ctx, img, ictx) }, []*pb.Feature{{Type: pb.Feature_PRODUCT_SEARCH, MaxResults: 0}}, batchResponse.Responses[0].ProductSearchResults, }, } { mockImageAnnotator.reqs = nil res, err := test.call() if err != nil { t.Fatal(err) } got := mockImageAnnotator.reqs[0] want := &pb.BatchAnnotateImagesRequest{ Requests: []*pb.AnnotateImageRequest{{ Image: img, ImageContext: ictx, Features: test.wantFeatures, }}, } if !testEqual(got, want) { t.Errorf("#%d:\ngot %v\nwant %v", i, got, want) } if got, want := res, test.wantRes; !testEqual(got, want) { t.Errorf("#%d:\ngot %v\nwant %v", i, got, want) } } } func testEqual(a, b interface{}) bool { if a == nil && b == nil { return true } if a == nil || b == nil { return false } t := reflect.TypeOf(a) if t != reflect.TypeOf(b) { return false } if am, ok := a.(proto.Message); ok { return proto.Equal(am, b.(proto.Message)) } if t.Kind() != reflect.Slice { panic(fmt.Sprintf("testEqual can only handle proto.Message and slices, got %s", t)) } va := reflect.ValueOf(a) vb := reflect.ValueOf(b) if va.Len() != vb.Len() { return false } for i := 0; i < va.Len(); i++ { if !testEqual(va.Index(i).Interface(), vb.Index(i).Interface()) { return false } } return true } func TestAnnotateOneError(t *testing.T) { ctx := context.Background() c, err := NewImageAnnotatorClient(ctx, clientOpt) if err != nil { t.Fatal(err) } mockImageAnnotator.resps = []proto.Message{ &pb.BatchAnnotateImagesResponse{ Responses: []*pb.AnnotateImageResponse{{ Error: &status.Status{Code: int32(codes.NotFound), Message: "not found"}, }}, }, } _, err = c.annotateOne(ctx, &pb.Image{Source: &pb.ImageSource{ImageUri: "http://foo.jpg"}}, nil, pb.Feature_LOGO_DETECTION, 1, nil) if c := grpc.Code(err); c != codes.NotFound { t.Errorf("got %v, want NotFound", c) } } google-cloud-go-0.49.0/vision/apiv1/doc.go000066400000000000000000000054631356504100700202230ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package vision is an auto-generated package for the // Cloud Vision API. // // Integrates Google Vision features, including image labeling, face, logo, // and landmark detection, optical character recognition (OCR), and detection // of explicit content, into applications. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package vision // import "cloud.google.com/go/vision/apiv1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/cloud-vision", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191108" google-cloud-go-0.49.0/vision/apiv1/examples_test.go000066400000000000000000000044521356504100700223300ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package vision_test import ( "context" "fmt" "os" vision "cloud.google.com/go/vision/apiv1" pb "google.golang.org/genproto/googleapis/cloud/vision/v1" ) func Example_NewImageFromReader() { f, err := os.Open("path/to/image.jpg") if err != nil { // TODO: handle error. } img, err := vision.NewImageFromReader(f) if err != nil { // TODO: handle error. } fmt.Println(img) } func Example_NewImageFromURI() { img := vision.NewImageFromURI("gs://my-bucket/my-image.png") fmt.Println(img) } func ExampleImageAnnotatorClient_AnnotateImage() { ctx := context.Background() c, err := vision.NewImageAnnotatorClient(ctx) if err != nil { // TODO: Handle error. } res, err := c.AnnotateImage(ctx, &pb.AnnotateImageRequest{ Image: vision.NewImageFromURI("gs://my-bucket/my-image.png"), Features: []*pb.Feature{ {Type: pb.Feature_LANDMARK_DETECTION, MaxResults: 5}, {Type: pb.Feature_LABEL_DETECTION, MaxResults: 3}, }, }) if err != nil { // TODO: Handle error. } // TODO: Use res. _ = res } func Example_FaceFromLandmarks() { ctx := context.Background() c, err := vision.NewImageAnnotatorClient(ctx) if err != nil { // TODO: Handle error. } resp, err := c.BatchAnnotateImages(ctx, &pb.BatchAnnotateImagesRequest{ Requests: []*pb.AnnotateImageRequest{ { Image: vision.NewImageFromURI("gs://bucket/image.jpg"), Features: []*pb.Feature{{ Type: pb.Feature_FACE_DETECTION, MaxResults: 5, }}, }, }, }) if err != nil { // TODO: Handle error. } res := resp.Responses[0] if res.Error != nil { // TODO: Handle error. } for _, a := range res.FaceAnnotations { face := vision.FaceFromLandmarks(a.Landmarks) fmt.Println(face.Nose.Tip) fmt.Println(face.Eyes.Left.Pupil) } } google-cloud-go-0.49.0/vision/apiv1/face.go000066400000000000000000000117561356504100700203560ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package vision import ( "log" pb "google.golang.org/genproto/googleapis/cloud/vision/v1" ) // FaceLandmarks contains the positions of facial features detected by the service. type FaceLandmarks struct { Eyebrows Eyebrows Eyes Eyes Ears Ears Nose Nose Mouth Mouth Chin Chin Forehead *pb.Position } // Eyebrows represents a face's eyebrows. type Eyebrows struct { Left, Right Eyebrow } // Eyebrow represents a face's eyebrow. type Eyebrow struct { Top, Left, Right *pb.Position } // Eyes represents a face's eyes. type Eyes struct { Left, Right Eye } // Eye represents a face's eye. type Eye struct { Left, Right, Top, Bottom, Center, Pupil *pb.Position } // Ears represents a face's ears. type Ears struct { Left, Right *pb.Position } // Nose represents a face's nose. type Nose struct { Left, Right, Top, Bottom, Tip *pb.Position } // Mouth represents a face's mouth. type Mouth struct { Left, Center, Right, UpperLip, LowerLip *pb.Position } // Chin represents a face's chin. type Chin struct { Left, Center, Right *pb.Position } // FaceFromLandmarks converts the list of face landmarks returned by the service // to a FaceLandmarks struct. func FaceFromLandmarks(landmarks []*pb.FaceAnnotation_Landmark) *FaceLandmarks { face := &FaceLandmarks{} for _, lm := range landmarks { switch lm.Type { case pb.FaceAnnotation_Landmark_LEFT_OF_LEFT_EYEBROW: face.Eyebrows.Left.Left = lm.Position case pb.FaceAnnotation_Landmark_RIGHT_OF_LEFT_EYEBROW: face.Eyebrows.Left.Right = lm.Position case pb.FaceAnnotation_Landmark_LEFT_OF_RIGHT_EYEBROW: face.Eyebrows.Right.Left = lm.Position case pb.FaceAnnotation_Landmark_RIGHT_OF_RIGHT_EYEBROW: face.Eyebrows.Right.Right = lm.Position case pb.FaceAnnotation_Landmark_LEFT_EYEBROW_UPPER_MIDPOINT: face.Eyebrows.Left.Top = lm.Position case pb.FaceAnnotation_Landmark_RIGHT_EYEBROW_UPPER_MIDPOINT: face.Eyebrows.Right.Top = lm.Position case pb.FaceAnnotation_Landmark_MIDPOINT_BETWEEN_EYES: face.Nose.Top = lm.Position case pb.FaceAnnotation_Landmark_NOSE_TIP: face.Nose.Tip = lm.Position case pb.FaceAnnotation_Landmark_UPPER_LIP: face.Mouth.UpperLip = lm.Position case pb.FaceAnnotation_Landmark_LOWER_LIP: face.Mouth.LowerLip = lm.Position case pb.FaceAnnotation_Landmark_MOUTH_LEFT: face.Mouth.Left = lm.Position case pb.FaceAnnotation_Landmark_MOUTH_RIGHT: face.Mouth.Right = lm.Position case pb.FaceAnnotation_Landmark_MOUTH_CENTER: face.Mouth.Center = lm.Position case pb.FaceAnnotation_Landmark_NOSE_BOTTOM_RIGHT: face.Nose.Right = lm.Position case pb.FaceAnnotation_Landmark_NOSE_BOTTOM_LEFT: face.Nose.Left = lm.Position case pb.FaceAnnotation_Landmark_NOSE_BOTTOM_CENTER: face.Nose.Bottom = lm.Position case pb.FaceAnnotation_Landmark_LEFT_EYE: face.Eyes.Left.Center = lm.Position case pb.FaceAnnotation_Landmark_RIGHT_EYE: face.Eyes.Right.Center = lm.Position case pb.FaceAnnotation_Landmark_LEFT_EYE_TOP_BOUNDARY: face.Eyes.Left.Top = lm.Position case pb.FaceAnnotation_Landmark_LEFT_EYE_RIGHT_CORNER: face.Eyes.Left.Right = lm.Position case pb.FaceAnnotation_Landmark_LEFT_EYE_BOTTOM_BOUNDARY: face.Eyes.Left.Bottom = lm.Position case pb.FaceAnnotation_Landmark_LEFT_EYE_LEFT_CORNER: face.Eyes.Left.Left = lm.Position case pb.FaceAnnotation_Landmark_RIGHT_EYE_TOP_BOUNDARY: face.Eyes.Right.Top = lm.Position case pb.FaceAnnotation_Landmark_RIGHT_EYE_RIGHT_CORNER: face.Eyes.Right.Right = lm.Position case pb.FaceAnnotation_Landmark_RIGHT_EYE_BOTTOM_BOUNDARY: face.Eyes.Right.Bottom = lm.Position case pb.FaceAnnotation_Landmark_RIGHT_EYE_LEFT_CORNER: face.Eyes.Right.Left = lm.Position case pb.FaceAnnotation_Landmark_LEFT_EYE_PUPIL: face.Eyes.Left.Pupil = lm.Position case pb.FaceAnnotation_Landmark_RIGHT_EYE_PUPIL: face.Eyes.Right.Pupil = lm.Position case pb.FaceAnnotation_Landmark_LEFT_EAR_TRAGION: face.Ears.Left = lm.Position case pb.FaceAnnotation_Landmark_RIGHT_EAR_TRAGION: face.Ears.Right = lm.Position case pb.FaceAnnotation_Landmark_FOREHEAD_GLABELLA: face.Forehead = lm.Position case pb.FaceAnnotation_Landmark_CHIN_GNATHION: face.Chin.Center = lm.Position case pb.FaceAnnotation_Landmark_CHIN_LEFT_GONION: face.Chin.Left = lm.Position case pb.FaceAnnotation_Landmark_CHIN_RIGHT_GONION: face.Chin.Right = lm.Position default: log.Printf("vision: ignoring unknown face annotation landmark %s", lm.Type) } } return face } google-cloud-go-0.49.0/vision/apiv1/face_test.go000066400000000000000000000154561356504100700214160ustar00rootroot00000000000000// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package vision import ( "testing" "cloud.google.com/go/internal/testutil" pb "google.golang.org/genproto/googleapis/cloud/vision/v1" ) func TestFaceFromLandmarks(t *testing.T) { landmarks := []*pb.FaceAnnotation_Landmark{ { Type: pb.FaceAnnotation_Landmark_LEFT_EYE, Position: &pb.Position{X: 1192, Y: 575, Z: 0}, }, { Type: pb.FaceAnnotation_Landmark_RIGHT_EYE, Position: &pb.Position{X: 1479, Y: 571, Z: -9}, }, { Type: pb.FaceAnnotation_Landmark_LEFT_OF_LEFT_EYEBROW, Position: &pb.Position{X: 1097, Y: 522, Z: 27}, }, { Type: pb.FaceAnnotation_Landmark_RIGHT_OF_LEFT_EYEBROW, Position: &pb.Position{X: 1266, Y: 521, Z: -61}, }, { Type: pb.FaceAnnotation_Landmark_LEFT_OF_RIGHT_EYEBROW, Position: &pb.Position{X: 1402, Y: 520, Z: -66}, }, { Type: pb.FaceAnnotation_Landmark_RIGHT_OF_RIGHT_EYEBROW, Position: &pb.Position{X: 1571, Y: 519, Z: 10}, }, { Type: pb.FaceAnnotation_Landmark_MIDPOINT_BETWEEN_EYES, Position: &pb.Position{X: 1331, Y: 566, Z: -66}, }, { Type: pb.FaceAnnotation_Landmark_NOSE_TIP, Position: &pb.Position{X: 1329, Y: 743, Z: -137}, }, { Type: pb.FaceAnnotation_Landmark_UPPER_LIP, Position: &pb.Position{X: 1330, Y: 836, Z: -66}, }, { Type: pb.FaceAnnotation_Landmark_LOWER_LIP, Position: &pb.Position{X: 1334, Y: 954, Z: -36}, }, { Type: pb.FaceAnnotation_Landmark_MOUTH_LEFT, Position: &pb.Position{X: 1186, Y: 867, Z: 27}, }, { Type: pb.FaceAnnotation_Landmark_MOUTH_RIGHT, Position: &pb.Position{X: 1484, Y: 857, Z: 19}, }, { Type: pb.FaceAnnotation_Landmark_MOUTH_CENTER, Position: &pb.Position{X: 1332, Y: 894, Z: -41}, }, { Type: pb.FaceAnnotation_Landmark_NOSE_BOTTOM_RIGHT, Position: &pb.Position{X: 1432, Y: 750, Z: -26}, }, { Type: pb.FaceAnnotation_Landmark_NOSE_BOTTOM_LEFT, Position: &pb.Position{X: 1236, Y: 755, Z: -20}, }, { Type: pb.FaceAnnotation_Landmark_NOSE_BOTTOM_CENTER, Position: &pb.Position{X: 1332, Y: 783, Z: -70}, }, { Type: pb.FaceAnnotation_Landmark_LEFT_EYE_TOP_BOUNDARY, Position: &pb.Position{X: 1193, Y: 561, Z: -20}, }, { Type: pb.FaceAnnotation_Landmark_LEFT_EYE_RIGHT_CORNER, Position: &pb.Position{X: 1252, Y: 581, Z: -1}, }, { Type: pb.FaceAnnotation_Landmark_LEFT_EYE_BOTTOM_BOUNDARY, Position: &pb.Position{X: 1190, Y: 593, Z: -1}, }, { Type: pb.FaceAnnotation_Landmark_LEFT_EYE_LEFT_CORNER, Position: &pb.Position{X: 1133, Y: 584, Z: 28}, }, { Type: pb.FaceAnnotation_Landmark_LEFT_EYE_PUPIL, Position: &pb.Position{X: 1189, Y: 580, Z: -8}, }, { Type: pb.FaceAnnotation_Landmark_RIGHT_EYE_TOP_BOUNDARY, Position: &pb.Position{X: 1474, Y: 561, Z: -30}, }, { Type: pb.FaceAnnotation_Landmark_RIGHT_EYE_RIGHT_CORNER, Position: &pb.Position{X: 1536, Y: 581, Z: 15}, }, { Type: pb.FaceAnnotation_Landmark_RIGHT_EYE_BOTTOM_BOUNDARY, Position: &pb.Position{X: 1481, Y: 590, Z: -11}, }, { Type: pb.FaceAnnotation_Landmark_RIGHT_EYE_LEFT_CORNER, Position: &pb.Position{X: 1424, Y: 579, Z: -6}, }, { Type: pb.FaceAnnotation_Landmark_RIGHT_EYE_PUPIL, Position: &pb.Position{X: 1478, Y: 580, Z: -18}, }, { Type: pb.FaceAnnotation_Landmark_LEFT_EYEBROW_UPPER_MIDPOINT, Position: &pb.Position{X: 1181, Y: 482, Z: -40}, }, { Type: pb.FaceAnnotation_Landmark_RIGHT_EYEBROW_UPPER_MIDPOINT, Position: &pb.Position{X: 1485, Y: 482, Z: -50}, }, { Type: pb.FaceAnnotation_Landmark_LEFT_EAR_TRAGION, Position: &pb.Position{X: 1027, Y: 696, Z: 361}, }, { Type: pb.FaceAnnotation_Landmark_RIGHT_EAR_TRAGION, Position: &pb.Position{X: 1666, Y: 695, Z: 339}, }, { Type: pb.FaceAnnotation_Landmark_FOREHEAD_GLABELLA, Position: &pb.Position{X: 1332, Y: 514, Z: -75}, }, { Type: pb.FaceAnnotation_Landmark_CHIN_GNATHION, Position: &pb.Position{X: 1335, Y: 1058, Z: 6}, }, { Type: pb.FaceAnnotation_Landmark_CHIN_LEFT_GONION, Position: &pb.Position{X: 1055, Y: 882, Z: 257}, }, { Type: pb.FaceAnnotation_Landmark_CHIN_RIGHT_GONION, Position: &pb.Position{X: 1631, Y: 881, Z: 238}, }, } want := &FaceLandmarks{ Eyebrows: Eyebrows{ Left: Eyebrow{ Top: &pb.Position{X: 1181, Y: 482, Z: -40}, Left: &pb.Position{X: 1097, Y: 522, Z: 27}, Right: &pb.Position{X: 1266, Y: 521, Z: -61}, }, Right: Eyebrow{ Top: &pb.Position{X: 1485, Y: 482, Z: -50}, Left: &pb.Position{X: 1402, Y: 520, Z: -66}, Right: &pb.Position{X: 1571, Y: 519, Z: 10}, }, }, Eyes: Eyes{ Left: Eye{ Left: &pb.Position{X: 1133, Y: 584, Z: 28}, Right: &pb.Position{X: 1252, Y: 581, Z: -1}, Top: &pb.Position{X: 1193, Y: 561, Z: -20}, Bottom: &pb.Position{X: 1190, Y: 593, Z: -1}, Center: &pb.Position{X: 1192, Y: 575, Z: 0}, Pupil: &pb.Position{X: 1189, Y: 580, Z: -8}, }, Right: Eye{ Left: &pb.Position{X: 1424, Y: 579, Z: -6}, Right: &pb.Position{X: 1536, Y: 581, Z: 15}, Top: &pb.Position{X: 1474, Y: 561, Z: -30}, Bottom: &pb.Position{X: 1481, Y: 590, Z: -11}, Center: &pb.Position{X: 1479, Y: 571, Z: -9}, Pupil: &pb.Position{X: 1478, Y: 580, Z: -18}, }, }, Ears: Ears{ Left: &pb.Position{X: 1027, Y: 696, Z: 361}, Right: &pb.Position{X: 1666, Y: 695, Z: 339}, }, Nose: Nose{ Left: &pb.Position{X: 1236, Y: 755, Z: -20}, Right: &pb.Position{X: 1432, Y: 750, Z: -26}, Top: &pb.Position{X: 1331, Y: 566, Z: -66}, Bottom: &pb.Position{X: 1332, Y: 783, Z: -70}, Tip: &pb.Position{X: 1329, Y: 743, Z: -137}, }, Mouth: Mouth{ Left: &pb.Position{X: 1186, Y: 867, Z: 27}, Center: &pb.Position{X: 1332, Y: 894, Z: -41}, Right: &pb.Position{X: 1484, Y: 857, Z: 19}, UpperLip: &pb.Position{X: 1330, Y: 836, Z: -66}, LowerLip: &pb.Position{X: 1334, Y: 954, Z: -36}, }, Chin: Chin{ Left: &pb.Position{X: 1055, Y: 882, Z: 257}, Center: &pb.Position{X: 1335, Y: 1058, Z: 6}, Right: &pb.Position{X: 1631, Y: 881, Z: 238}, }, Forehead: &pb.Position{X: 1332, Y: 514, Z: -75}, } got := FaceFromLandmarks(landmarks) if diff := testutil.Diff(got, want); diff != "" { t.Error(diff) } } google-cloud-go-0.49.0/vision/apiv1/image.go000066400000000000000000000022461356504100700205340ustar00rootroot00000000000000// Copyright 2017, Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package vision import ( "io" "io/ioutil" pb "google.golang.org/genproto/googleapis/cloud/vision/v1" ) // NewImageFromReader reads the bytes of an image from r. func NewImageFromReader(r io.Reader) (*pb.Image, error) { bytes, err := ioutil.ReadAll(r) if err != nil { return nil, err } return &pb.Image{Content: bytes}, nil } // NewImageFromURI returns an image that refers to an object in Google Cloud Storage // (when the uri is of the form "gs://BUCKET/OBJECT") or at a public URL. func NewImageFromURI(uri string) *pb.Image { return &pb.Image{Source: &pb.ImageSource{ImageUri: uri}} } google-cloud-go-0.49.0/vision/apiv1/image_annotator_client.go000066400000000000000000000375571356504100700241740ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package vision import ( "context" "fmt" "math" "net/url" "time" "cloud.google.com/go/longrunning" lroauto "cloud.google.com/go/longrunning/autogen" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" "google.golang.org/api/transport" visionpb "google.golang.org/genproto/googleapis/cloud/vision/v1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // ImageAnnotatorCallOptions contains the retry settings for each method of ImageAnnotatorClient. type ImageAnnotatorCallOptions struct { BatchAnnotateImages []gax.CallOption BatchAnnotateFiles []gax.CallOption AsyncBatchAnnotateImages []gax.CallOption AsyncBatchAnnotateFiles []gax.CallOption } func defaultImageAnnotatorClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("vision.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultImageAnnotatorCallOptions() *ImageAnnotatorCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &ImageAnnotatorCallOptions{ BatchAnnotateImages: retry[[2]string{"default", "idempotent"}], BatchAnnotateFiles: retry[[2]string{"default", "idempotent"}], AsyncBatchAnnotateImages: retry[[2]string{"default", "idempotent"}], AsyncBatchAnnotateFiles: retry[[2]string{"default", "idempotent"}], } } // ImageAnnotatorClient is a client for interacting with Cloud Vision API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type ImageAnnotatorClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. imageAnnotatorClient visionpb.ImageAnnotatorClient // LROClient is used internally to handle longrunning operations. // It is exposed so that its CallOptions can be modified if required. // Users should not Close this client. LROClient *lroauto.OperationsClient // The call options for this service. CallOptions *ImageAnnotatorCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewImageAnnotatorClient creates a new image annotator client. // // Service that performs Google Cloud Vision API detection tasks over client // images, such as face, landmark, logo, label, and text detection. The // ImageAnnotator service returns detected entities from the images. func NewImageAnnotatorClient(ctx context.Context, opts ...option.ClientOption) (*ImageAnnotatorClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultImageAnnotatorClientOptions(), opts...)...) if err != nil { return nil, err } c := &ImageAnnotatorClient{ conn: conn, CallOptions: defaultImageAnnotatorCallOptions(), imageAnnotatorClient: visionpb.NewImageAnnotatorClient(conn), } c.setGoogleClientInfo() c.LROClient, err = lroauto.NewOperationsClient(ctx, option.WithGRPCConn(conn)) if err != nil { // This error "should not happen", since we are just reusing old connection // and never actually need to dial. // If this does happen, we could leak conn. However, we cannot close conn: // If the user invoked the function with option.WithGRPCConn, // we would close a connection that's still in use. // TODO(pongad): investigate error conditions. return nil, err } return c, nil } // Connection returns the client's connection to the API service. func (c *ImageAnnotatorClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *ImageAnnotatorClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *ImageAnnotatorClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // BatchAnnotateImages run image detection and annotation for a batch of images. func (c *ImageAnnotatorClient) BatchAnnotateImages(ctx context.Context, req *visionpb.BatchAnnotateImagesRequest, opts ...gax.CallOption) (*visionpb.BatchAnnotateImagesResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.BatchAnnotateImages[0:len(c.CallOptions.BatchAnnotateImages):len(c.CallOptions.BatchAnnotateImages)], opts...) var resp *visionpb.BatchAnnotateImagesResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.imageAnnotatorClient.BatchAnnotateImages(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // BatchAnnotateFiles service that performs image detection and annotation for a batch of files. // Now only "application/pdf", "image/tiff" and "image/gif" are supported. // // This service will extract at most 5 (customers can specify which 5 in // AnnotateFileRequest.pages) frames (gif) or pages (pdf or tiff) from each // file provided and perform detection and annotation for each image // extracted. func (c *ImageAnnotatorClient) BatchAnnotateFiles(ctx context.Context, req *visionpb.BatchAnnotateFilesRequest, opts ...gax.CallOption) (*visionpb.BatchAnnotateFilesResponse, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.BatchAnnotateFiles[0:len(c.CallOptions.BatchAnnotateFiles):len(c.CallOptions.BatchAnnotateFiles)], opts...) var resp *visionpb.BatchAnnotateFilesResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.imageAnnotatorClient.BatchAnnotateFiles(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // AsyncBatchAnnotateImages run asynchronous image detection and annotation for a list of images. // // Progress and results can be retrieved through the // google.longrunning.Operations interface. // Operation.metadata contains OperationMetadata (metadata). // Operation.response contains AsyncBatchAnnotateImagesResponse (results). // // This service will write image annotation outputs to json files in customer // GCS bucket, each json file containing BatchAnnotateImagesResponse proto. func (c *ImageAnnotatorClient) AsyncBatchAnnotateImages(ctx context.Context, req *visionpb.AsyncBatchAnnotateImagesRequest, opts ...gax.CallOption) (*AsyncBatchAnnotateImagesOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.AsyncBatchAnnotateImages[0:len(c.CallOptions.AsyncBatchAnnotateImages):len(c.CallOptions.AsyncBatchAnnotateImages)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.imageAnnotatorClient.AsyncBatchAnnotateImages(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &AsyncBatchAnnotateImagesOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // AsyncBatchAnnotateFiles run asynchronous image detection and annotation for a list of generic // files, such as PDF files, which may contain multiple pages and multiple // images per page. Progress and results can be retrieved through the // google.longrunning.Operations interface. // Operation.metadata contains OperationMetadata (metadata). // Operation.response contains AsyncBatchAnnotateFilesResponse (results). func (c *ImageAnnotatorClient) AsyncBatchAnnotateFiles(ctx context.Context, req *visionpb.AsyncBatchAnnotateFilesRequest, opts ...gax.CallOption) (*AsyncBatchAnnotateFilesOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.AsyncBatchAnnotateFiles[0:len(c.CallOptions.AsyncBatchAnnotateFiles):len(c.CallOptions.AsyncBatchAnnotateFiles)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.imageAnnotatorClient.AsyncBatchAnnotateFiles(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &AsyncBatchAnnotateFilesOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // AsyncBatchAnnotateFilesOperation manages a long-running operation from AsyncBatchAnnotateFiles. type AsyncBatchAnnotateFilesOperation struct { lro *longrunning.Operation } // AsyncBatchAnnotateFilesOperation returns a new AsyncBatchAnnotateFilesOperation from a given name. // The name must be that of a previously created AsyncBatchAnnotateFilesOperation, possibly from a different process. func (c *ImageAnnotatorClient) AsyncBatchAnnotateFilesOperation(name string) *AsyncBatchAnnotateFilesOperation { return &AsyncBatchAnnotateFilesOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *AsyncBatchAnnotateFilesOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*visionpb.AsyncBatchAnnotateFilesResponse, error) { var resp visionpb.AsyncBatchAnnotateFilesResponse if err := op.lro.WaitWithInterval(ctx, &resp, 45000*time.Millisecond, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *AsyncBatchAnnotateFilesOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*visionpb.AsyncBatchAnnotateFilesResponse, error) { var resp visionpb.AsyncBatchAnnotateFilesResponse if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *AsyncBatchAnnotateFilesOperation) Metadata() (*visionpb.OperationMetadata, error) { var meta visionpb.OperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *AsyncBatchAnnotateFilesOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *AsyncBatchAnnotateFilesOperation) Name() string { return op.lro.Name() } // AsyncBatchAnnotateImagesOperation manages a long-running operation from AsyncBatchAnnotateImages. type AsyncBatchAnnotateImagesOperation struct { lro *longrunning.Operation } // AsyncBatchAnnotateImagesOperation returns a new AsyncBatchAnnotateImagesOperation from a given name. // The name must be that of a previously created AsyncBatchAnnotateImagesOperation, possibly from a different process. func (c *ImageAnnotatorClient) AsyncBatchAnnotateImagesOperation(name string) *AsyncBatchAnnotateImagesOperation { return &AsyncBatchAnnotateImagesOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *AsyncBatchAnnotateImagesOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*visionpb.AsyncBatchAnnotateImagesResponse, error) { var resp visionpb.AsyncBatchAnnotateImagesResponse if err := op.lro.WaitWithInterval(ctx, &resp, 45000*time.Millisecond, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *AsyncBatchAnnotateImagesOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*visionpb.AsyncBatchAnnotateImagesResponse, error) { var resp visionpb.AsyncBatchAnnotateImagesResponse if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *AsyncBatchAnnotateImagesOperation) Metadata() (*visionpb.OperationMetadata, error) { var meta visionpb.OperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *AsyncBatchAnnotateImagesOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *AsyncBatchAnnotateImagesOperation) Name() string { return op.lro.Name() } google-cloud-go-0.49.0/vision/apiv1/image_annotator_client_example_test.go000066400000000000000000000052351356504100700267320ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package vision_test import ( "context" vision "cloud.google.com/go/vision/apiv1" visionpb "google.golang.org/genproto/googleapis/cloud/vision/v1" ) func ExampleNewImageAnnotatorClient() { ctx := context.Background() c, err := vision.NewImageAnnotatorClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleImageAnnotatorClient_BatchAnnotateImages() { ctx := context.Background() c, err := vision.NewImageAnnotatorClient(ctx) if err != nil { // TODO: Handle error. } req := &visionpb.BatchAnnotateImagesRequest{ // TODO: Fill request struct fields. } resp, err := c.BatchAnnotateImages(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleImageAnnotatorClient_BatchAnnotateFiles() { ctx := context.Background() c, err := vision.NewImageAnnotatorClient(ctx) if err != nil { // TODO: Handle error. } req := &visionpb.BatchAnnotateFilesRequest{ // TODO: Fill request struct fields. } resp, err := c.BatchAnnotateFiles(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleImageAnnotatorClient_AsyncBatchAnnotateImages() { ctx := context.Background() c, err := vision.NewImageAnnotatorClient(ctx) if err != nil { // TODO: Handle error. } req := &visionpb.AsyncBatchAnnotateImagesRequest{ // TODO: Fill request struct fields. } op, err := c.AsyncBatchAnnotateImages(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleImageAnnotatorClient_AsyncBatchAnnotateFiles() { ctx := context.Background() c, err := vision.NewImageAnnotatorClient(ctx) if err != nil { // TODO: Handle error. } req := &visionpb.AsyncBatchAnnotateFilesRequest{ // TODO: Fill request struct fields. } op, err := c.AsyncBatchAnnotateFiles(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/vision/apiv1/mock_test.go000066400000000000000000001606751356504100700214550ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package vision import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" emptypb "github.com/golang/protobuf/ptypes/empty" "google.golang.org/api/option" visionpb "google.golang.org/genproto/googleapis/cloud/vision/v1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockImageAnnotatorServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. visionpb.ImageAnnotatorServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockImageAnnotatorServer) BatchAnnotateImages(ctx context.Context, req *visionpb.BatchAnnotateImagesRequest) (*visionpb.BatchAnnotateImagesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*visionpb.BatchAnnotateImagesResponse), nil } func (s *mockImageAnnotatorServer) BatchAnnotateFiles(ctx context.Context, req *visionpb.BatchAnnotateFilesRequest) (*visionpb.BatchAnnotateFilesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*visionpb.BatchAnnotateFilesResponse), nil } func (s *mockImageAnnotatorServer) AsyncBatchAnnotateImages(ctx context.Context, req *visionpb.AsyncBatchAnnotateImagesRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockImageAnnotatorServer) AsyncBatchAnnotateFiles(ctx context.Context, req *visionpb.AsyncBatchAnnotateFilesRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } type mockProductSearchServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. visionpb.ProductSearchServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockProductSearchServer) CreateProductSet(ctx context.Context, req *visionpb.CreateProductSetRequest) (*visionpb.ProductSet, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*visionpb.ProductSet), nil } func (s *mockProductSearchServer) ListProductSets(ctx context.Context, req *visionpb.ListProductSetsRequest) (*visionpb.ListProductSetsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*visionpb.ListProductSetsResponse), nil } func (s *mockProductSearchServer) GetProductSet(ctx context.Context, req *visionpb.GetProductSetRequest) (*visionpb.ProductSet, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*visionpb.ProductSet), nil } func (s *mockProductSearchServer) UpdateProductSet(ctx context.Context, req *visionpb.UpdateProductSetRequest) (*visionpb.ProductSet, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*visionpb.ProductSet), nil } func (s *mockProductSearchServer) DeleteProductSet(ctx context.Context, req *visionpb.DeleteProductSetRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockProductSearchServer) CreateProduct(ctx context.Context, req *visionpb.CreateProductRequest) (*visionpb.Product, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*visionpb.Product), nil } func (s *mockProductSearchServer) ListProducts(ctx context.Context, req *visionpb.ListProductsRequest) (*visionpb.ListProductsResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*visionpb.ListProductsResponse), nil } func (s *mockProductSearchServer) GetProduct(ctx context.Context, req *visionpb.GetProductRequest) (*visionpb.Product, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*visionpb.Product), nil } func (s *mockProductSearchServer) UpdateProduct(ctx context.Context, req *visionpb.UpdateProductRequest) (*visionpb.Product, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*visionpb.Product), nil } func (s *mockProductSearchServer) DeleteProduct(ctx context.Context, req *visionpb.DeleteProductRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockProductSearchServer) CreateReferenceImage(ctx context.Context, req *visionpb.CreateReferenceImageRequest) (*visionpb.ReferenceImage, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*visionpb.ReferenceImage), nil } func (s *mockProductSearchServer) DeleteReferenceImage(ctx context.Context, req *visionpb.DeleteReferenceImageRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockProductSearchServer) ListReferenceImages(ctx context.Context, req *visionpb.ListReferenceImagesRequest) (*visionpb.ListReferenceImagesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*visionpb.ListReferenceImagesResponse), nil } func (s *mockProductSearchServer) GetReferenceImage(ctx context.Context, req *visionpb.GetReferenceImageRequest) (*visionpb.ReferenceImage, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*visionpb.ReferenceImage), nil } func (s *mockProductSearchServer) AddProductToProductSet(ctx context.Context, req *visionpb.AddProductToProductSetRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockProductSearchServer) RemoveProductFromProductSet(ctx context.Context, req *visionpb.RemoveProductFromProductSetRequest) (*emptypb.Empty, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*emptypb.Empty), nil } func (s *mockProductSearchServer) ListProductsInProductSet(ctx context.Context, req *visionpb.ListProductsInProductSetRequest) (*visionpb.ListProductsInProductSetResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*visionpb.ListProductsInProductSetResponse), nil } func (s *mockProductSearchServer) ImportProductSets(ctx context.Context, req *visionpb.ImportProductSetsRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } func (s *mockProductSearchServer) PurgeProducts(ctx context.Context, req *visionpb.PurgeProductsRequest) (*longrunningpb.Operation, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*longrunningpb.Operation), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockImageAnnotator mockImageAnnotatorServer mockProductSearch mockProductSearchServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() visionpb.RegisterImageAnnotatorServer(serv, &mockImageAnnotator) visionpb.RegisterProductSearchServer(serv, &mockProductSearch) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestImageAnnotatorBatchAnnotateImages(t *testing.T) { var expectedResponse *visionpb.BatchAnnotateImagesResponse = &visionpb.BatchAnnotateImagesResponse{} mockImageAnnotator.err = nil mockImageAnnotator.reqs = nil mockImageAnnotator.resps = append(mockImageAnnotator.resps[:0], expectedResponse) var requests []*visionpb.AnnotateImageRequest = nil var request = &visionpb.BatchAnnotateImagesRequest{ Requests: requests, } c, err := NewImageAnnotatorClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.BatchAnnotateImages(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockImageAnnotator.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestImageAnnotatorBatchAnnotateImagesError(t *testing.T) { errCode := codes.PermissionDenied mockImageAnnotator.err = gstatus.Error(errCode, "test error") var requests []*visionpb.AnnotateImageRequest = nil var request = &visionpb.BatchAnnotateImagesRequest{ Requests: requests, } c, err := NewImageAnnotatorClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.BatchAnnotateImages(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestImageAnnotatorBatchAnnotateFiles(t *testing.T) { var expectedResponse *visionpb.BatchAnnotateFilesResponse = &visionpb.BatchAnnotateFilesResponse{} mockImageAnnotator.err = nil mockImageAnnotator.reqs = nil mockImageAnnotator.resps = append(mockImageAnnotator.resps[:0], expectedResponse) var requests []*visionpb.AnnotateFileRequest = nil var request = &visionpb.BatchAnnotateFilesRequest{ Requests: requests, } c, err := NewImageAnnotatorClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.BatchAnnotateFiles(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockImageAnnotator.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestImageAnnotatorBatchAnnotateFilesError(t *testing.T) { errCode := codes.PermissionDenied mockImageAnnotator.err = gstatus.Error(errCode, "test error") var requests []*visionpb.AnnotateFileRequest = nil var request = &visionpb.BatchAnnotateFilesRequest{ Requests: requests, } c, err := NewImageAnnotatorClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.BatchAnnotateFiles(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestImageAnnotatorAsyncBatchAnnotateImages(t *testing.T) { var expectedResponse *visionpb.AsyncBatchAnnotateImagesResponse = &visionpb.AsyncBatchAnnotateImagesResponse{} mockImageAnnotator.err = nil mockImageAnnotator.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockImageAnnotator.resps = append(mockImageAnnotator.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var requests []*visionpb.AnnotateImageRequest = nil var outputConfig *visionpb.OutputConfig = &visionpb.OutputConfig{} var request = &visionpb.AsyncBatchAnnotateImagesRequest{ Requests: requests, OutputConfig: outputConfig, } c, err := NewImageAnnotatorClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.AsyncBatchAnnotateImages(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockImageAnnotator.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestImageAnnotatorAsyncBatchAnnotateImagesError(t *testing.T) { errCode := codes.PermissionDenied mockImageAnnotator.err = nil mockImageAnnotator.resps = append(mockImageAnnotator.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var requests []*visionpb.AnnotateImageRequest = nil var outputConfig *visionpb.OutputConfig = &visionpb.OutputConfig{} var request = &visionpb.AsyncBatchAnnotateImagesRequest{ Requests: requests, OutputConfig: outputConfig, } c, err := NewImageAnnotatorClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.AsyncBatchAnnotateImages(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestImageAnnotatorAsyncBatchAnnotateFiles(t *testing.T) { var expectedResponse *visionpb.AsyncBatchAnnotateFilesResponse = &visionpb.AsyncBatchAnnotateFilesResponse{} mockImageAnnotator.err = nil mockImageAnnotator.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockImageAnnotator.resps = append(mockImageAnnotator.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var requests []*visionpb.AsyncAnnotateFileRequest = nil var request = &visionpb.AsyncBatchAnnotateFilesRequest{ Requests: requests, } c, err := NewImageAnnotatorClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.AsyncBatchAnnotateFiles(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockImageAnnotator.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestImageAnnotatorAsyncBatchAnnotateFilesError(t *testing.T) { errCode := codes.PermissionDenied mockImageAnnotator.err = nil mockImageAnnotator.resps = append(mockImageAnnotator.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var requests []*visionpb.AsyncAnnotateFileRequest = nil var request = &visionpb.AsyncBatchAnnotateFilesRequest{ Requests: requests, } c, err := NewImageAnnotatorClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.AsyncBatchAnnotateFiles(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestProductSearchCreateProductSet(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var expectedResponse = &visionpb.ProductSet{ Name: name, DisplayName: displayName, } mockProductSearch.err = nil mockProductSearch.reqs = nil mockProductSearch.resps = append(mockProductSearch.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var productSet *visionpb.ProductSet = &visionpb.ProductSet{} var request = &visionpb.CreateProductSetRequest{ Parent: formattedParent, ProductSet: productSet, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateProductSet(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestProductSearchCreateProductSetError(t *testing.T) { errCode := codes.PermissionDenied mockProductSearch.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var productSet *visionpb.ProductSet = &visionpb.ProductSet{} var request = &visionpb.CreateProductSetRequest{ Parent: formattedParent, ProductSet: productSet, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateProductSet(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestProductSearchListProductSets(t *testing.T) { var nextPageToken string = "" var productSetsElement *visionpb.ProductSet = &visionpb.ProductSet{} var productSets = []*visionpb.ProductSet{productSetsElement} var expectedResponse = &visionpb.ListProductSetsResponse{ NextPageToken: nextPageToken, ProductSets: productSets, } mockProductSearch.err = nil mockProductSearch.reqs = nil mockProductSearch.resps = append(mockProductSearch.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &visionpb.ListProductSetsRequest{ Parent: formattedParent, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListProductSets(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.ProductSets[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestProductSearchListProductSetsError(t *testing.T) { errCode := codes.PermissionDenied mockProductSearch.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &visionpb.ListProductSetsRequest{ Parent: formattedParent, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListProductSets(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestProductSearchGetProductSet(t *testing.T) { var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var expectedResponse = &visionpb.ProductSet{ Name: name2, DisplayName: displayName, } mockProductSearch.err = nil mockProductSearch.reqs = nil mockProductSearch.resps = append(mockProductSearch.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/productSets/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT_SET]") var request = &visionpb.GetProductSetRequest{ Name: formattedName, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetProductSet(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestProductSearchGetProductSetError(t *testing.T) { errCode := codes.PermissionDenied mockProductSearch.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/productSets/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT_SET]") var request = &visionpb.GetProductSetRequest{ Name: formattedName, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetProductSet(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestProductSearchUpdateProductSet(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var expectedResponse = &visionpb.ProductSet{ Name: name, DisplayName: displayName, } mockProductSearch.err = nil mockProductSearch.reqs = nil mockProductSearch.resps = append(mockProductSearch.resps[:0], expectedResponse) var productSet *visionpb.ProductSet = &visionpb.ProductSet{} var request = &visionpb.UpdateProductSetRequest{ ProductSet: productSet, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateProductSet(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestProductSearchUpdateProductSetError(t *testing.T) { errCode := codes.PermissionDenied mockProductSearch.err = gstatus.Error(errCode, "test error") var productSet *visionpb.ProductSet = &visionpb.ProductSet{} var request = &visionpb.UpdateProductSetRequest{ ProductSet: productSet, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateProductSet(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestProductSearchDeleteProductSet(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockProductSearch.err = nil mockProductSearch.reqs = nil mockProductSearch.resps = append(mockProductSearch.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/productSets/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT_SET]") var request = &visionpb.DeleteProductSetRequest{ Name: formattedName, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteProductSet(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestProductSearchDeleteProductSetError(t *testing.T) { errCode := codes.PermissionDenied mockProductSearch.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/productSets/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT_SET]") var request = &visionpb.DeleteProductSetRequest{ Name: formattedName, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteProductSet(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestProductSearchCreateProduct(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var description string = "description-1724546052" var productCategory string = "productCategory-1607451058" var expectedResponse = &visionpb.Product{ Name: name, DisplayName: displayName, Description: description, ProductCategory: productCategory, } mockProductSearch.err = nil mockProductSearch.reqs = nil mockProductSearch.resps = append(mockProductSearch.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var product *visionpb.Product = &visionpb.Product{} var request = &visionpb.CreateProductRequest{ Parent: formattedParent, Product: product, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateProduct(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestProductSearchCreateProductError(t *testing.T) { errCode := codes.PermissionDenied mockProductSearch.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var product *visionpb.Product = &visionpb.Product{} var request = &visionpb.CreateProductRequest{ Parent: formattedParent, Product: product, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateProduct(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestProductSearchListProducts(t *testing.T) { var nextPageToken string = "" var productsElement *visionpb.Product = &visionpb.Product{} var products = []*visionpb.Product{productsElement} var expectedResponse = &visionpb.ListProductsResponse{ NextPageToken: nextPageToken, Products: products, } mockProductSearch.err = nil mockProductSearch.reqs = nil mockProductSearch.resps = append(mockProductSearch.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &visionpb.ListProductsRequest{ Parent: formattedParent, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListProducts(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Products[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestProductSearchListProductsError(t *testing.T) { errCode := codes.PermissionDenied mockProductSearch.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &visionpb.ListProductsRequest{ Parent: formattedParent, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListProducts(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestProductSearchGetProduct(t *testing.T) { var name2 string = "name2-1052831874" var displayName string = "displayName1615086568" var description string = "description-1724546052" var productCategory string = "productCategory-1607451058" var expectedResponse = &visionpb.Product{ Name: name2, DisplayName: displayName, Description: description, ProductCategory: productCategory, } mockProductSearch.err = nil mockProductSearch.reqs = nil mockProductSearch.resps = append(mockProductSearch.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/products/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT]") var request = &visionpb.GetProductRequest{ Name: formattedName, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetProduct(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestProductSearchGetProductError(t *testing.T) { errCode := codes.PermissionDenied mockProductSearch.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/products/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT]") var request = &visionpb.GetProductRequest{ Name: formattedName, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetProduct(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestProductSearchUpdateProduct(t *testing.T) { var name string = "name3373707" var displayName string = "displayName1615086568" var description string = "description-1724546052" var productCategory string = "productCategory-1607451058" var expectedResponse = &visionpb.Product{ Name: name, DisplayName: displayName, Description: description, ProductCategory: productCategory, } mockProductSearch.err = nil mockProductSearch.reqs = nil mockProductSearch.resps = append(mockProductSearch.resps[:0], expectedResponse) var product *visionpb.Product = &visionpb.Product{} var request = &visionpb.UpdateProductRequest{ Product: product, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateProduct(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestProductSearchUpdateProductError(t *testing.T) { errCode := codes.PermissionDenied mockProductSearch.err = gstatus.Error(errCode, "test error") var product *visionpb.Product = &visionpb.Product{} var request = &visionpb.UpdateProductRequest{ Product: product, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.UpdateProduct(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestProductSearchDeleteProduct(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockProductSearch.err = nil mockProductSearch.reqs = nil mockProductSearch.resps = append(mockProductSearch.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/products/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT]") var request = &visionpb.DeleteProductRequest{ Name: formattedName, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteProduct(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestProductSearchDeleteProductError(t *testing.T) { errCode := codes.PermissionDenied mockProductSearch.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/products/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT]") var request = &visionpb.DeleteProductRequest{ Name: formattedName, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteProduct(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestProductSearchCreateReferenceImage(t *testing.T) { var name string = "name3373707" var uri string = "uri116076" var expectedResponse = &visionpb.ReferenceImage{ Name: name, Uri: uri, } mockProductSearch.err = nil mockProductSearch.reqs = nil mockProductSearch.resps = append(mockProductSearch.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/products/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT]") var referenceImage *visionpb.ReferenceImage = &visionpb.ReferenceImage{} var request = &visionpb.CreateReferenceImageRequest{ Parent: formattedParent, ReferenceImage: referenceImage, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateReferenceImage(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestProductSearchCreateReferenceImageError(t *testing.T) { errCode := codes.PermissionDenied mockProductSearch.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/products/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT]") var referenceImage *visionpb.ReferenceImage = &visionpb.ReferenceImage{} var request = &visionpb.CreateReferenceImageRequest{ Parent: formattedParent, ReferenceImage: referenceImage, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.CreateReferenceImage(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestProductSearchDeleteReferenceImage(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockProductSearch.err = nil mockProductSearch.reqs = nil mockProductSearch.resps = append(mockProductSearch.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/products/%s/referenceImages/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT]", "[REFERENCE_IMAGE]") var request = &visionpb.DeleteReferenceImageRequest{ Name: formattedName, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteReferenceImage(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestProductSearchDeleteReferenceImageError(t *testing.T) { errCode := codes.PermissionDenied mockProductSearch.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/products/%s/referenceImages/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT]", "[REFERENCE_IMAGE]") var request = &visionpb.DeleteReferenceImageRequest{ Name: formattedName, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.DeleteReferenceImage(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestProductSearchListReferenceImages(t *testing.T) { var pageSize int32 = 883849137 var nextPageToken string = "" var referenceImagesElement *visionpb.ReferenceImage = &visionpb.ReferenceImage{} var referenceImages = []*visionpb.ReferenceImage{referenceImagesElement} var expectedResponse = &visionpb.ListReferenceImagesResponse{ PageSize: pageSize, NextPageToken: nextPageToken, ReferenceImages: referenceImages, } mockProductSearch.err = nil mockProductSearch.reqs = nil mockProductSearch.resps = append(mockProductSearch.resps[:0], expectedResponse) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/products/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT]") var request = &visionpb.ListReferenceImagesRequest{ Parent: formattedParent, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListReferenceImages(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.ReferenceImages[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestProductSearchListReferenceImagesError(t *testing.T) { errCode := codes.PermissionDenied mockProductSearch.err = gstatus.Error(errCode, "test error") var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/products/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT]") var request = &visionpb.ListReferenceImagesRequest{ Parent: formattedParent, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListReferenceImages(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestProductSearchGetReferenceImage(t *testing.T) { var name2 string = "name2-1052831874" var uri string = "uri116076" var expectedResponse = &visionpb.ReferenceImage{ Name: name2, Uri: uri, } mockProductSearch.err = nil mockProductSearch.reqs = nil mockProductSearch.resps = append(mockProductSearch.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/products/%s/referenceImages/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT]", "[REFERENCE_IMAGE]") var request = &visionpb.GetReferenceImageRequest{ Name: formattedName, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetReferenceImage(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestProductSearchGetReferenceImageError(t *testing.T) { errCode := codes.PermissionDenied mockProductSearch.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/products/%s/referenceImages/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT]", "[REFERENCE_IMAGE]") var request = &visionpb.GetReferenceImageRequest{ Name: formattedName, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.GetReferenceImage(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestProductSearchAddProductToProductSet(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockProductSearch.err = nil mockProductSearch.reqs = nil mockProductSearch.resps = append(mockProductSearch.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/productSets/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT_SET]") var formattedProduct string = fmt.Sprintf("projects/%s/locations/%s/products/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT]") var request = &visionpb.AddProductToProductSetRequest{ Name: formattedName, Product: formattedProduct, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.AddProductToProductSet(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestProductSearchAddProductToProductSetError(t *testing.T) { errCode := codes.PermissionDenied mockProductSearch.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/productSets/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT_SET]") var formattedProduct string = fmt.Sprintf("projects/%s/locations/%s/products/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT]") var request = &visionpb.AddProductToProductSetRequest{ Name: formattedName, Product: formattedProduct, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.AddProductToProductSet(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestProductSearchRemoveProductFromProductSet(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockProductSearch.err = nil mockProductSearch.reqs = nil mockProductSearch.resps = append(mockProductSearch.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/productSets/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT_SET]") var formattedProduct string = fmt.Sprintf("projects/%s/locations/%s/products/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT]") var request = &visionpb.RemoveProductFromProductSetRequest{ Name: formattedName, Product: formattedProduct, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.RemoveProductFromProductSet(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestProductSearchRemoveProductFromProductSetError(t *testing.T) { errCode := codes.PermissionDenied mockProductSearch.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/productSets/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT_SET]") var formattedProduct string = fmt.Sprintf("projects/%s/locations/%s/products/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT]") var request = &visionpb.RemoveProductFromProductSetRequest{ Name: formattedName, Product: formattedProduct, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } err = c.RemoveProductFromProductSet(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } func TestProductSearchListProductsInProductSet(t *testing.T) { var nextPageToken string = "" var productsElement *visionpb.Product = &visionpb.Product{} var products = []*visionpb.Product{productsElement} var expectedResponse = &visionpb.ListProductsInProductSetResponse{ NextPageToken: nextPageToken, Products: products, } mockProductSearch.err = nil mockProductSearch.reqs = nil mockProductSearch.resps = append(mockProductSearch.resps[:0], expectedResponse) var formattedName string = fmt.Sprintf("projects/%s/locations/%s/productSets/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT_SET]") var request = &visionpb.ListProductsInProductSetRequest{ Name: formattedName, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListProductsInProductSet(context.Background(), request).Next() if err != nil { t.Fatal(err) } if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } want := (interface{})(expectedResponse.Products[0]) got := (interface{})(resp) var ok bool switch want := (want).(type) { case proto.Message: ok = proto.Equal(want, got.(proto.Message)) default: ok = want == got } if !ok { t.Errorf("wrong response %q, want %q)", got, want) } } func TestProductSearchListProductsInProductSetError(t *testing.T) { errCode := codes.PermissionDenied mockProductSearch.err = gstatus.Error(errCode, "test error") var formattedName string = fmt.Sprintf("projects/%s/locations/%s/productSets/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT_SET]") var request = &visionpb.ListProductsInProductSetRequest{ Name: formattedName, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ListProductsInProductSet(context.Background(), request).Next() if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestProductSearchImportProductSets(t *testing.T) { var expectedResponse *visionpb.ImportProductSetsResponse = &visionpb.ImportProductSetsResponse{} mockProductSearch.err = nil mockProductSearch.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockProductSearch.resps = append(mockProductSearch.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var inputConfig *visionpb.ImportProductSetsInputConfig = &visionpb.ImportProductSetsInputConfig{} var request = &visionpb.ImportProductSetsRequest{ Parent: formattedParent, InputConfig: inputConfig, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.ImportProductSets(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestProductSearchImportProductSetsError(t *testing.T) { errCode := codes.PermissionDenied mockProductSearch.err = nil mockProductSearch.resps = append(mockProductSearch.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var inputConfig *visionpb.ImportProductSetsInputConfig = &visionpb.ImportProductSetsInputConfig{} var request = &visionpb.ImportProductSetsRequest{ Parent: formattedParent, InputConfig: inputConfig, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.ImportProductSets(context.Background(), request) if err != nil { t.Fatal(err) } resp, err := respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestProductSearchPurgeProducts(t *testing.T) { var expectedResponse *emptypb.Empty = &emptypb.Empty{} mockProductSearch.err = nil mockProductSearch.reqs = nil any, err := ptypes.MarshalAny(expectedResponse) if err != nil { t.Fatal(err) } mockProductSearch.resps = append(mockProductSearch.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Response{Response: any}, }) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &visionpb.PurgeProductsRequest{ Parent: formattedParent, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.PurgeProducts(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if err != nil { t.Fatal(err) } if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } } func TestProductSearchPurgeProductsError(t *testing.T) { errCode := codes.PermissionDenied mockProductSearch.err = nil mockProductSearch.resps = append(mockProductSearch.resps[:0], &longrunningpb.Operation{ Name: "longrunning-test", Done: true, Result: &longrunningpb.Operation_Error{ Error: &status.Status{ Code: int32(errCode), Message: "test error", }, }, }) var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]") var request = &visionpb.PurgeProductsRequest{ Parent: formattedParent, } c, err := NewProductSearchClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } respLRO, err := c.PurgeProducts(context.Background(), request) if err != nil { t.Fatal(err) } err = respLRO.Wait(context.Background()) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } } google-cloud-go-0.49.0/vision/apiv1/product_search_client.go000066400000000000000000001204551356504100700240200ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package vision import ( "context" "fmt" "math" "net/url" "time" "cloud.google.com/go/longrunning" lroauto "cloud.google.com/go/longrunning/autogen" "github.com/golang/protobuf/proto" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/transport" visionpb "google.golang.org/genproto/googleapis/cloud/vision/v1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // ProductSearchCallOptions contains the retry settings for each method of ProductSearchClient. type ProductSearchCallOptions struct { CreateProductSet []gax.CallOption ListProductSets []gax.CallOption GetProductSet []gax.CallOption UpdateProductSet []gax.CallOption DeleteProductSet []gax.CallOption CreateProduct []gax.CallOption ListProducts []gax.CallOption GetProduct []gax.CallOption UpdateProduct []gax.CallOption DeleteProduct []gax.CallOption CreateReferenceImage []gax.CallOption DeleteReferenceImage []gax.CallOption ListReferenceImages []gax.CallOption GetReferenceImage []gax.CallOption AddProductToProductSet []gax.CallOption RemoveProductFromProductSet []gax.CallOption ListProductsInProductSet []gax.CallOption ImportProductSets []gax.CallOption PurgeProducts []gax.CallOption } func defaultProductSearchClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("vision.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultProductSearchCallOptions() *ProductSearchCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &ProductSearchCallOptions{ CreateProductSet: retry[[2]string{"default", "non_idempotent"}], ListProductSets: retry[[2]string{"default", "idempotent"}], GetProductSet: retry[[2]string{"default", "idempotent"}], UpdateProductSet: retry[[2]string{"default", "idempotent"}], DeleteProductSet: retry[[2]string{"default", "idempotent"}], CreateProduct: retry[[2]string{"default", "non_idempotent"}], ListProducts: retry[[2]string{"default", "idempotent"}], GetProduct: retry[[2]string{"default", "idempotent"}], UpdateProduct: retry[[2]string{"default", "idempotent"}], DeleteProduct: retry[[2]string{"default", "idempotent"}], CreateReferenceImage: retry[[2]string{"default", "non_idempotent"}], DeleteReferenceImage: retry[[2]string{"default", "idempotent"}], ListReferenceImages: retry[[2]string{"default", "idempotent"}], GetReferenceImage: retry[[2]string{"default", "idempotent"}], AddProductToProductSet: retry[[2]string{"default", "idempotent"}], RemoveProductFromProductSet: retry[[2]string{"default", "idempotent"}], ListProductsInProductSet: retry[[2]string{"default", "idempotent"}], ImportProductSets: retry[[2]string{"default", "non_idempotent"}], PurgeProducts: retry[[2]string{"default", "non_idempotent"}], } } // ProductSearchClient is a client for interacting with Cloud Vision API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type ProductSearchClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. productSearchClient visionpb.ProductSearchClient // LROClient is used internally to handle longrunning operations. // It is exposed so that its CallOptions can be modified if required. // Users should not Close this client. LROClient *lroauto.OperationsClient // The call options for this service. CallOptions *ProductSearchCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewProductSearchClient creates a new product search client. // // Manages Products and ProductSets of reference images for use in product // search. It uses the following resource model: // // The API has a collection of [ProductSet][google.cloud.vision.v1.ProductSet] resources, named // projects/*/locations/*/productSets/*, which acts as a way to put different // products into groups to limit identification. // // In parallel, // // The API has a collection of [Product][google.cloud.vision.v1.Product] resources, named // projects/*/locations/*/products/* // // Each [Product][google.cloud.vision.v1.Product] has a collection of [ReferenceImage][google.cloud.vision.v1.ReferenceImage] resources, named // projects/*/locations/*/products/*/referenceImages/* func NewProductSearchClient(ctx context.Context, opts ...option.ClientOption) (*ProductSearchClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultProductSearchClientOptions(), opts...)...) if err != nil { return nil, err } c := &ProductSearchClient{ conn: conn, CallOptions: defaultProductSearchCallOptions(), productSearchClient: visionpb.NewProductSearchClient(conn), } c.setGoogleClientInfo() c.LROClient, err = lroauto.NewOperationsClient(ctx, option.WithGRPCConn(conn)) if err != nil { // This error "should not happen", since we are just reusing old connection // and never actually need to dial. // If this does happen, we could leak conn. However, we cannot close conn: // If the user invoked the function with option.WithGRPCConn, // we would close a connection that's still in use. // TODO(pongad): investigate error conditions. return nil, err } return c, nil } // Connection returns the client's connection to the API service. func (c *ProductSearchClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *ProductSearchClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *ProductSearchClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // CreateProductSet creates and returns a new ProductSet resource. // // Possible errors: // // Returns INVALID_ARGUMENT if display_name is missing, or is longer than // 4096 characters. func (c *ProductSearchClient) CreateProductSet(ctx context.Context, req *visionpb.CreateProductSetRequest, opts ...gax.CallOption) (*visionpb.ProductSet, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateProductSet[0:len(c.CallOptions.CreateProductSet):len(c.CallOptions.CreateProductSet)], opts...) var resp *visionpb.ProductSet err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.productSearchClient.CreateProductSet(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListProductSets lists ProductSets in an unspecified order. // // Possible errors: // // Returns INVALID_ARGUMENT if page_size is greater than 100, or less // than 1. func (c *ProductSearchClient) ListProductSets(ctx context.Context, req *visionpb.ListProductSetsRequest, opts ...gax.CallOption) *ProductSetIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListProductSets[0:len(c.CallOptions.ListProductSets):len(c.CallOptions.ListProductSets)], opts...) it := &ProductSetIterator{} req = proto.Clone(req).(*visionpb.ListProductSetsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*visionpb.ProductSet, string, error) { var resp *visionpb.ListProductSetsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.productSearchClient.ListProductSets(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.ProductSets, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetProductSet gets information associated with a ProductSet. // // Possible errors: // // Returns NOT_FOUND if the ProductSet does not exist. func (c *ProductSearchClient) GetProductSet(ctx context.Context, req *visionpb.GetProductSetRequest, opts ...gax.CallOption) (*visionpb.ProductSet, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetProductSet[0:len(c.CallOptions.GetProductSet):len(c.CallOptions.GetProductSet)], opts...) var resp *visionpb.ProductSet err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.productSearchClient.GetProductSet(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateProductSet makes changes to a ProductSet resource. // Only display_name can be updated currently. // // Possible errors: // // Returns NOT_FOUND if the ProductSet does not exist. // // Returns INVALID_ARGUMENT if display_name is present in update_mask but // missing from the request or longer than 4096 characters. func (c *ProductSearchClient) UpdateProductSet(ctx context.Context, req *visionpb.UpdateProductSetRequest, opts ...gax.CallOption) (*visionpb.ProductSet, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "product_set.name", url.QueryEscape(req.GetProductSet().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateProductSet[0:len(c.CallOptions.UpdateProductSet):len(c.CallOptions.UpdateProductSet)], opts...) var resp *visionpb.ProductSet err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.productSearchClient.UpdateProductSet(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteProductSet permanently deletes a ProductSet. Products and ReferenceImages in the // ProductSet are not deleted. // // The actual image files are not deleted from Google Cloud Storage. func (c *ProductSearchClient) DeleteProductSet(ctx context.Context, req *visionpb.DeleteProductSetRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteProductSet[0:len(c.CallOptions.DeleteProductSet):len(c.CallOptions.DeleteProductSet)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.productSearchClient.DeleteProductSet(ctx, req, settings.GRPC...) return err }, opts...) return err } // CreateProduct creates and returns a new product resource. // // Possible errors: // // Returns INVALID_ARGUMENT if display_name is missing or longer than 4096 // characters. // // Returns INVALID_ARGUMENT if description is longer than 4096 characters. // // Returns INVALID_ARGUMENT if product_category is missing or invalid. func (c *ProductSearchClient) CreateProduct(ctx context.Context, req *visionpb.CreateProductRequest, opts ...gax.CallOption) (*visionpb.Product, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateProduct[0:len(c.CallOptions.CreateProduct):len(c.CallOptions.CreateProduct)], opts...) var resp *visionpb.Product err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.productSearchClient.CreateProduct(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // ListProducts lists products in an unspecified order. // // Possible errors: // // Returns INVALID_ARGUMENT if page_size is greater than 100 or less than 1. func (c *ProductSearchClient) ListProducts(ctx context.Context, req *visionpb.ListProductsRequest, opts ...gax.CallOption) *ProductIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListProducts[0:len(c.CallOptions.ListProducts):len(c.CallOptions.ListProducts)], opts...) it := &ProductIterator{} req = proto.Clone(req).(*visionpb.ListProductsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*visionpb.Product, string, error) { var resp *visionpb.ListProductsResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.productSearchClient.ListProducts(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Products, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetProduct gets information associated with a Product. // // Possible errors: // // Returns NOT_FOUND if the Product does not exist. func (c *ProductSearchClient) GetProduct(ctx context.Context, req *visionpb.GetProductRequest, opts ...gax.CallOption) (*visionpb.Product, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetProduct[0:len(c.CallOptions.GetProduct):len(c.CallOptions.GetProduct)], opts...) var resp *visionpb.Product err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.productSearchClient.GetProduct(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // UpdateProduct makes changes to a Product resource. // Only the display_name, description, and labels fields can be updated // right now. // // If labels are updated, the change will not be reflected in queries until // the next index time. // // Possible errors: // // Returns NOT_FOUND if the Product does not exist. // // Returns INVALID_ARGUMENT if display_name is present in update_mask but is // missing from the request or longer than 4096 characters. // // Returns INVALID_ARGUMENT if description is present in update_mask but is // longer than 4096 characters. // // Returns INVALID_ARGUMENT if product_category is present in update_mask. func (c *ProductSearchClient) UpdateProduct(ctx context.Context, req *visionpb.UpdateProductRequest, opts ...gax.CallOption) (*visionpb.Product, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "product.name", url.QueryEscape(req.GetProduct().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.UpdateProduct[0:len(c.CallOptions.UpdateProduct):len(c.CallOptions.UpdateProduct)], opts...) var resp *visionpb.Product err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.productSearchClient.UpdateProduct(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteProduct permanently deletes a product and its reference images. // // Metadata of the product and all its images will be deleted right away, but // search queries against ProductSets containing the product may still work // until all related caches are refreshed. func (c *ProductSearchClient) DeleteProduct(ctx context.Context, req *visionpb.DeleteProductRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteProduct[0:len(c.CallOptions.DeleteProduct):len(c.CallOptions.DeleteProduct)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.productSearchClient.DeleteProduct(ctx, req, settings.GRPC...) return err }, opts...) return err } // CreateReferenceImage creates and returns a new ReferenceImage resource. // // The bounding_poly field is optional. If bounding_poly is not specified, // the system will try to detect regions of interest in the image that are // compatible with the product_category on the parent product. If it is // specified, detection is ALWAYS skipped. The system converts polygons into // non-rotated rectangles. // // Note that the pipeline will resize the image if the image resolution is too // large to process (above 50MP). // // Possible errors: // // Returns INVALID_ARGUMENT if the image_uri is missing or longer than 4096 // characters. // // Returns INVALID_ARGUMENT if the product does not exist. // // Returns INVALID_ARGUMENT if bounding_poly is not provided, and nothing // compatible with the parent product's product_category is detected. // // Returns INVALID_ARGUMENT if bounding_poly contains more than 10 polygons. func (c *ProductSearchClient) CreateReferenceImage(ctx context.Context, req *visionpb.CreateReferenceImageRequest, opts ...gax.CallOption) (*visionpb.ReferenceImage, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.CreateReferenceImage[0:len(c.CallOptions.CreateReferenceImage):len(c.CallOptions.CreateReferenceImage)], opts...) var resp *visionpb.ReferenceImage err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.productSearchClient.CreateReferenceImage(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // DeleteReferenceImage permanently deletes a reference image. // // The image metadata will be deleted right away, but search queries // against ProductSets containing the image may still work until all related // caches are refreshed. // // The actual image files are not deleted from Google Cloud Storage. func (c *ProductSearchClient) DeleteReferenceImage(ctx context.Context, req *visionpb.DeleteReferenceImageRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.DeleteReferenceImage[0:len(c.CallOptions.DeleteReferenceImage):len(c.CallOptions.DeleteReferenceImage)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.productSearchClient.DeleteReferenceImage(ctx, req, settings.GRPC...) return err }, opts...) return err } // ListReferenceImages lists reference images. // // Possible errors: // // Returns NOT_FOUND if the parent product does not exist. // // Returns INVALID_ARGUMENT if the page_size is greater than 100, or less // than 1. func (c *ProductSearchClient) ListReferenceImages(ctx context.Context, req *visionpb.ListReferenceImagesRequest, opts ...gax.CallOption) *ReferenceImageIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListReferenceImages[0:len(c.CallOptions.ListReferenceImages):len(c.CallOptions.ListReferenceImages)], opts...) it := &ReferenceImageIterator{} req = proto.Clone(req).(*visionpb.ListReferenceImagesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*visionpb.ReferenceImage, string, error) { var resp *visionpb.ListReferenceImagesResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.productSearchClient.ListReferenceImages(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.ReferenceImages, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // GetReferenceImage gets information associated with a ReferenceImage. // // Possible errors: // // Returns NOT_FOUND if the specified image does not exist. func (c *ProductSearchClient) GetReferenceImage(ctx context.Context, req *visionpb.GetReferenceImageRequest, opts ...gax.CallOption) (*visionpb.ReferenceImage, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.GetReferenceImage[0:len(c.CallOptions.GetReferenceImage):len(c.CallOptions.GetReferenceImage)], opts...) var resp *visionpb.ReferenceImage err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.productSearchClient.GetReferenceImage(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // AddProductToProductSet adds a Product to the specified ProductSet. If the Product is already // present, no change is made. // // One Product can be added to at most 100 ProductSets. // // Possible errors: // // Returns NOT_FOUND if the Product or the ProductSet doesn't exist. func (c *ProductSearchClient) AddProductToProductSet(ctx context.Context, req *visionpb.AddProductToProductSetRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.AddProductToProductSet[0:len(c.CallOptions.AddProductToProductSet):len(c.CallOptions.AddProductToProductSet)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.productSearchClient.AddProductToProductSet(ctx, req, settings.GRPC...) return err }, opts...) return err } // RemoveProductFromProductSet removes a Product from the specified ProductSet. func (c *ProductSearchClient) RemoveProductFromProductSet(ctx context.Context, req *visionpb.RemoveProductFromProductSetRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.RemoveProductFromProductSet[0:len(c.CallOptions.RemoveProductFromProductSet):len(c.CallOptions.RemoveProductFromProductSet)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.productSearchClient.RemoveProductFromProductSet(ctx, req, settings.GRPC...) return err }, opts...) return err } // ListProductsInProductSet lists the Products in a ProductSet, in an unspecified order. If the // ProductSet does not exist, the products field of the response will be // empty. // // Possible errors: // // Returns INVALID_ARGUMENT if page_size is greater than 100 or less than 1. func (c *ProductSearchClient) ListProductsInProductSet(ctx context.Context, req *visionpb.ListProductsInProductSetRequest, opts ...gax.CallOption) *ProductIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ListProductsInProductSet[0:len(c.CallOptions.ListProductsInProductSet):len(c.CallOptions.ListProductsInProductSet)], opts...) it := &ProductIterator{} req = proto.Clone(req).(*visionpb.ListProductsInProductSetRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*visionpb.Product, string, error) { var resp *visionpb.ListProductsInProductSetResponse req.PageToken = pageToken if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.productSearchClient.ListProductsInProductSet(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } return resp.Products, resp.NextPageToken, nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.PageSize) it.pageInfo.Token = req.PageToken return it } // ImportProductSets asynchronous API that imports a list of reference images to specified // product sets based on a list of image information. // // The [google.longrunning.Operation][google.longrunning.Operation] API can be used to keep track of the // progress and results of the request. // Operation.metadata contains BatchOperationMetadata. (progress) // Operation.response contains ImportProductSetsResponse. (results) // // The input source of this method is a csv file on Google Cloud Storage. // For the format of the csv file please see // [ImportProductSetsGcsSource.csv_file_uri][google.cloud.vision.v1.ImportProductSetsGcsSource.csv_file_uri]. func (c *ProductSearchClient) ImportProductSets(ctx context.Context, req *visionpb.ImportProductSetsRequest, opts ...gax.CallOption) (*ImportProductSetsOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.ImportProductSets[0:len(c.CallOptions.ImportProductSets):len(c.CallOptions.ImportProductSets)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.productSearchClient.ImportProductSets(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &ImportProductSetsOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // PurgeProducts asynchronous API to delete all Products in a ProductSet or all Products // that are in no ProductSet. // // If a Product is a member of the specified ProductSet in addition to other // ProductSets, the Product will still be deleted. // // It is recommended to not delete the specified ProductSet until after this // operation has completed. It is also recommended to not add any of the // Products involved in the batch delete to a new ProductSet while this // operation is running because those Products may still end up deleted. // // It's not possible to undo the PurgeProducts operation. Therefore, it is // recommended to keep the csv files used in ImportProductSets (if that was // how you originally built the Product Set) before starting PurgeProducts, in // case you need to re-import the data after deletion. // // If the plan is to purge all of the Products from a ProductSet and then // re-use the empty ProductSet to re-import new Products into the empty // ProductSet, you must wait until the PurgeProducts operation has finished // for that ProductSet. // // The [google.longrunning.Operation][google.longrunning.Operation] API can be used to keep track of the // progress and results of the request. // Operation.metadata contains BatchOperationMetadata. (progress) func (c *ProductSearchClient) PurgeProducts(ctx context.Context, req *visionpb.PurgeProductsRequest, opts ...gax.CallOption) (*PurgeProductsOperation, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append(c.CallOptions.PurgeProducts[0:len(c.CallOptions.PurgeProducts):len(c.CallOptions.PurgeProducts)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.productSearchClient.PurgeProducts(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &PurgeProductsOperation{ lro: longrunning.InternalNewOperation(c.LROClient, resp), }, nil } // ProductIterator manages a stream of *visionpb.Product. type ProductIterator struct { items []*visionpb.Product pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*visionpb.Product, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *ProductIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *ProductIterator) Next() (*visionpb.Product, error) { var item *visionpb.Product if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *ProductIterator) bufLen() int { return len(it.items) } func (it *ProductIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // ProductSetIterator manages a stream of *visionpb.ProductSet. type ProductSetIterator struct { items []*visionpb.ProductSet pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*visionpb.ProductSet, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *ProductSetIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *ProductSetIterator) Next() (*visionpb.ProductSet, error) { var item *visionpb.ProductSet if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *ProductSetIterator) bufLen() int { return len(it.items) } func (it *ProductSetIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // ReferenceImageIterator manages a stream of *visionpb.ReferenceImage. type ReferenceImageIterator struct { items []*visionpb.ReferenceImage pageInfo *iterator.PageInfo nextFunc func() error // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*visionpb.ReferenceImage, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *ReferenceImageIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *ReferenceImageIterator) Next() (*visionpb.ReferenceImage, error) { var item *visionpb.ReferenceImage if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *ReferenceImageIterator) bufLen() int { return len(it.items) } func (it *ReferenceImageIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // ImportProductSetsOperation manages a long-running operation from ImportProductSets. type ImportProductSetsOperation struct { lro *longrunning.Operation } // ImportProductSetsOperation returns a new ImportProductSetsOperation from a given name. // The name must be that of a previously created ImportProductSetsOperation, possibly from a different process. func (c *ProductSearchClient) ImportProductSetsOperation(name string) *ImportProductSetsOperation { return &ImportProductSetsOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *ImportProductSetsOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*visionpb.ImportProductSetsResponse, error) { var resp visionpb.ImportProductSetsResponse if err := op.lro.WaitWithInterval(ctx, &resp, 45000*time.Millisecond, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *ImportProductSetsOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*visionpb.ImportProductSetsResponse, error) { var resp visionpb.ImportProductSetsResponse if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *ImportProductSetsOperation) Metadata() (*visionpb.BatchOperationMetadata, error) { var meta visionpb.BatchOperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *ImportProductSetsOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *ImportProductSetsOperation) Name() string { return op.lro.Name() } // PurgeProductsOperation manages a long-running operation from PurgeProducts. type PurgeProductsOperation struct { lro *longrunning.Operation } // PurgeProductsOperation returns a new PurgeProductsOperation from a given name. // The name must be that of a previously created PurgeProductsOperation, possibly from a different process. func (c *ProductSearchClient) PurgeProductsOperation(name string) *PurgeProductsOperation { return &PurgeProductsOperation{ lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning any error encountered. // // See documentation of Poll for error-handling information. func (op *PurgeProductsOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { return op.lro.WaitWithInterval(ctx, nil, 45000*time.Millisecond, opts...) } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, op.Done will return true. func (op *PurgeProductsOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Poll(ctx, nil, opts...) } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *PurgeProductsOperation) Metadata() (*visionpb.BatchOperationMetadata, error) { var meta visionpb.BatchOperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *PurgeProductsOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *PurgeProductsOperation) Name() string { return op.lro.Name() } google-cloud-go-0.49.0/vision/apiv1/product_search_client_example_test.go000066400000000000000000000204261356504100700265670ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package vision_test import ( "context" vision "cloud.google.com/go/vision/apiv1" "google.golang.org/api/iterator" visionpb "google.golang.org/genproto/googleapis/cloud/vision/v1" ) func ExampleNewProductSearchClient() { ctx := context.Background() c, err := vision.NewProductSearchClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleProductSearchClient_CreateProductSet() { ctx := context.Background() c, err := vision.NewProductSearchClient(ctx) if err != nil { // TODO: Handle error. } req := &visionpb.CreateProductSetRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateProductSet(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleProductSearchClient_ListProductSets() { ctx := context.Background() c, err := vision.NewProductSearchClient(ctx) if err != nil { // TODO: Handle error. } req := &visionpb.ListProductSetsRequest{ // TODO: Fill request struct fields. } it := c.ListProductSets(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleProductSearchClient_GetProductSet() { ctx := context.Background() c, err := vision.NewProductSearchClient(ctx) if err != nil { // TODO: Handle error. } req := &visionpb.GetProductSetRequest{ // TODO: Fill request struct fields. } resp, err := c.GetProductSet(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleProductSearchClient_UpdateProductSet() { ctx := context.Background() c, err := vision.NewProductSearchClient(ctx) if err != nil { // TODO: Handle error. } req := &visionpb.UpdateProductSetRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateProductSet(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleProductSearchClient_DeleteProductSet() { ctx := context.Background() c, err := vision.NewProductSearchClient(ctx) if err != nil { // TODO: Handle error. } req := &visionpb.DeleteProductSetRequest{ // TODO: Fill request struct fields. } err = c.DeleteProductSet(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleProductSearchClient_CreateProduct() { ctx := context.Background() c, err := vision.NewProductSearchClient(ctx) if err != nil { // TODO: Handle error. } req := &visionpb.CreateProductRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateProduct(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleProductSearchClient_ListProducts() { ctx := context.Background() c, err := vision.NewProductSearchClient(ctx) if err != nil { // TODO: Handle error. } req := &visionpb.ListProductsRequest{ // TODO: Fill request struct fields. } it := c.ListProducts(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleProductSearchClient_GetProduct() { ctx := context.Background() c, err := vision.NewProductSearchClient(ctx) if err != nil { // TODO: Handle error. } req := &visionpb.GetProductRequest{ // TODO: Fill request struct fields. } resp, err := c.GetProduct(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleProductSearchClient_UpdateProduct() { ctx := context.Background() c, err := vision.NewProductSearchClient(ctx) if err != nil { // TODO: Handle error. } req := &visionpb.UpdateProductRequest{ // TODO: Fill request struct fields. } resp, err := c.UpdateProduct(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleProductSearchClient_DeleteProduct() { ctx := context.Background() c, err := vision.NewProductSearchClient(ctx) if err != nil { // TODO: Handle error. } req := &visionpb.DeleteProductRequest{ // TODO: Fill request struct fields. } err = c.DeleteProduct(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleProductSearchClient_CreateReferenceImage() { ctx := context.Background() c, err := vision.NewProductSearchClient(ctx) if err != nil { // TODO: Handle error. } req := &visionpb.CreateReferenceImageRequest{ // TODO: Fill request struct fields. } resp, err := c.CreateReferenceImage(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleProductSearchClient_DeleteReferenceImage() { ctx := context.Background() c, err := vision.NewProductSearchClient(ctx) if err != nil { // TODO: Handle error. } req := &visionpb.DeleteReferenceImageRequest{ // TODO: Fill request struct fields. } err = c.DeleteReferenceImage(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleProductSearchClient_ListReferenceImages() { ctx := context.Background() c, err := vision.NewProductSearchClient(ctx) if err != nil { // TODO: Handle error. } req := &visionpb.ListReferenceImagesRequest{ // TODO: Fill request struct fields. } it := c.ListReferenceImages(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleProductSearchClient_GetReferenceImage() { ctx := context.Background() c, err := vision.NewProductSearchClient(ctx) if err != nil { // TODO: Handle error. } req := &visionpb.GetReferenceImageRequest{ // TODO: Fill request struct fields. } resp, err := c.GetReferenceImage(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleProductSearchClient_AddProductToProductSet() { ctx := context.Background() c, err := vision.NewProductSearchClient(ctx) if err != nil { // TODO: Handle error. } req := &visionpb.AddProductToProductSetRequest{ // TODO: Fill request struct fields. } err = c.AddProductToProductSet(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleProductSearchClient_RemoveProductFromProductSet() { ctx := context.Background() c, err := vision.NewProductSearchClient(ctx) if err != nil { // TODO: Handle error. } req := &visionpb.RemoveProductFromProductSetRequest{ // TODO: Fill request struct fields. } err = c.RemoveProductFromProductSet(ctx, req) if err != nil { // TODO: Handle error. } } func ExampleProductSearchClient_ListProductsInProductSet() { ctx := context.Background() c, err := vision.NewProductSearchClient(ctx) if err != nil { // TODO: Handle error. } req := &visionpb.ListProductsInProductSetRequest{ // TODO: Fill request struct fields. } it := c.ListProductsInProductSet(ctx, req) for { resp, err := it.Next() if err == iterator.Done { break } if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } } func ExampleProductSearchClient_ImportProductSets() { ctx := context.Background() c, err := vision.NewProductSearchClient(ctx) if err != nil { // TODO: Handle error. } req := &visionpb.ImportProductSetsRequest{ // TODO: Fill request struct fields. } op, err := c.ImportProductSets(ctx, req) if err != nil { // TODO: Handle error. } resp, err := op.Wait(ctx) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleProductSearchClient_PurgeProducts() { ctx := context.Background() c, err := vision.NewProductSearchClient(ctx) if err != nil { // TODO: Handle error. } req := &visionpb.PurgeProductsRequest{ // TODO: Fill request struct fields. } op, err := c.PurgeProducts(ctx, req) if err != nil { // TODO: Handle error. } err = op.Wait(ctx) // TODO: Handle error. } google-cloud-go-0.49.0/vision/apiv1p1beta1/000077500000000000000000000000001356504100700202755ustar00rootroot00000000000000google-cloud-go-0.49.0/vision/apiv1p1beta1/.repo-metadata.json000066400000000000000000000006241356504100700237730ustar00rootroot00000000000000{ "name": "vision", "name_pretty": "Vision AI API", "product_documentation": "https://cloud.google.com/vision", "client_documentation": "https://godoc.org/cloud.google.com/go/vision/apiv1p1beta1", "release_level": "beta", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "vision.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/vision/apiv1p1beta1/BatchAnnotateImages_smoke_test.go000066400000000000000000000041641356504100700267270ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package vision import ( "context" "fmt" "strconv" "testing" "time" "cloud.google.com/go/internal/testutil" "google.golang.org/api/iterator" "google.golang.org/api/option" visionpb "google.golang.org/genproto/googleapis/cloud/vision/v1p1beta1" ) var _ = fmt.Sprintf var _ = iterator.Done var _ = strconv.FormatUint var _ = time.Now func TestImageAnnotatorSmoke(t *testing.T) { if testing.Short() { t.Skip("skipping smoke test in short mode") } ctx := context.Background() ts := testutil.TokenSource(ctx, DefaultAuthScopes()...) if ts == nil { t.Skip("Integration tests skipped. See CONTRIBUTING.md for details") } projectId := testutil.ProjID() _ = projectId c, err := NewImageAnnotatorClient(ctx, option.WithTokenSource(ts)) if err != nil { t.Fatal(err) } var gcsImageUri string = "gs://cloud-samples-data/vision/face_detection/celebrity_recognition/sergey.jpg" var source = &visionpb.ImageSource{ GcsImageUri: gcsImageUri, } var image = &visionpb.Image{ Source: source, } var type_ visionpb.Feature_Type = visionpb.Feature_FACE_DETECTION var featuresElement = &visionpb.Feature{ Type: type_, } var features = []*visionpb.Feature{featuresElement} var requestsElement = &visionpb.AnnotateImageRequest{ Image: image, Features: features, } var requests = []*visionpb.AnnotateImageRequest{requestsElement} var request = &visionpb.BatchAnnotateImagesRequest{ Requests: requests, } if _, err := c.BatchAnnotateImages(ctx, request); err != nil { t.Error(err) } } google-cloud-go-0.49.0/vision/apiv1p1beta1/doc.go000066400000000000000000000056331356504100700214000ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package vision is an auto-generated package for the // Google Cloud Vision API. // // NOTE: This package is in beta. It is not stable, and may be subject to changes. // // Integrates Google Vision features, including image labeling, face, logo, // and // landmark detection, optical character recognition (OCR), and detection of // explicit content, into applications. // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package vision // import "cloud.google.com/go/vision/apiv1p1beta1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/cloud-vision", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191115" google-cloud-go-0.49.0/vision/apiv1p1beta1/image_annotator_client.go000066400000000000000000000113561356504100700253370ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package vision import ( "context" "math" "time" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" "google.golang.org/api/transport" visionpb "google.golang.org/genproto/googleapis/cloud/vision/v1p1beta1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // ImageAnnotatorCallOptions contains the retry settings for each method of ImageAnnotatorClient. type ImageAnnotatorCallOptions struct { BatchAnnotateImages []gax.CallOption } func defaultImageAnnotatorClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("vision.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultImageAnnotatorCallOptions() *ImageAnnotatorCallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &ImageAnnotatorCallOptions{ BatchAnnotateImages: retry[[2]string{"default", "idempotent"}], } } // ImageAnnotatorClient is a client for interacting with Google Cloud Vision API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type ImageAnnotatorClient struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. imageAnnotatorClient visionpb.ImageAnnotatorClient // The call options for this service. CallOptions *ImageAnnotatorCallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewImageAnnotatorClient creates a new image annotator client. // // Service that performs Google Cloud Vision API detection tasks over client // images, such as face, landmark, logo, label, and text detection. The // ImageAnnotator service returns detected entities from the images. func NewImageAnnotatorClient(ctx context.Context, opts ...option.ClientOption) (*ImageAnnotatorClient, error) { conn, err := transport.DialGRPC(ctx, append(defaultImageAnnotatorClientOptions(), opts...)...) if err != nil { return nil, err } c := &ImageAnnotatorClient{ conn: conn, CallOptions: defaultImageAnnotatorCallOptions(), imageAnnotatorClient: visionpb.NewImageAnnotatorClient(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *ImageAnnotatorClient) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *ImageAnnotatorClient) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *ImageAnnotatorClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // BatchAnnotateImages run image detection and annotation for a batch of images. func (c *ImageAnnotatorClient) BatchAnnotateImages(ctx context.Context, req *visionpb.BatchAnnotateImagesRequest, opts ...gax.CallOption) (*visionpb.BatchAnnotateImagesResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.BatchAnnotateImages[0:len(c.CallOptions.BatchAnnotateImages):len(c.CallOptions.BatchAnnotateImages)], opts...) var resp *visionpb.BatchAnnotateImagesResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.imageAnnotatorClient.BatchAnnotateImages(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } google-cloud-go-0.49.0/vision/apiv1p1beta1/image_annotator_client_example_test.go000066400000000000000000000025601356504100700301060ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package vision_test import ( "context" vision "cloud.google.com/go/vision/apiv1p1beta1" visionpb "google.golang.org/genproto/googleapis/cloud/vision/v1p1beta1" ) func ExampleNewImageAnnotatorClient() { ctx := context.Background() c, err := vision.NewImageAnnotatorClient(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleImageAnnotatorClient_BatchAnnotateImages() { ctx := context.Background() c, err := vision.NewImageAnnotatorClient(ctx) if err != nil { // TODO: Handle error. } req := &visionpb.BatchAnnotateImagesRequest{ // TODO: Fill request struct fields. } resp, err := c.BatchAnnotateImages(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } google-cloud-go-0.49.0/vision/apiv1p1beta1/mock_test.go000066400000000000000000000101531356504100700226140ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package vision import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" "google.golang.org/api/option" visionpb "google.golang.org/genproto/googleapis/cloud/vision/v1p1beta1" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockImageAnnotatorServer struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. visionpb.ImageAnnotatorServer reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockImageAnnotatorServer) BatchAnnotateImages(ctx context.Context, req *visionpb.BatchAnnotateImagesRequest) (*visionpb.BatchAnnotateImagesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*visionpb.BatchAnnotateImagesResponse), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockImageAnnotator mockImageAnnotatorServer ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() visionpb.RegisterImageAnnotatorServer(serv, &mockImageAnnotator) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestImageAnnotatorBatchAnnotateImages(t *testing.T) { var expectedResponse *visionpb.BatchAnnotateImagesResponse = &visionpb.BatchAnnotateImagesResponse{} mockImageAnnotator.err = nil mockImageAnnotator.reqs = nil mockImageAnnotator.resps = append(mockImageAnnotator.resps[:0], expectedResponse) var requests []*visionpb.AnnotateImageRequest = nil var request = &visionpb.BatchAnnotateImagesRequest{ Requests: requests, } c, err := NewImageAnnotatorClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.BatchAnnotateImages(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockImageAnnotator.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestImageAnnotatorBatchAnnotateImagesError(t *testing.T) { errCode := codes.PermissionDenied mockImageAnnotator.err = gstatus.Error(errCode, "test error") var requests []*visionpb.AnnotateImageRequest = nil var request = &visionpb.BatchAnnotateImagesRequest{ Requests: requests, } c, err := NewImageAnnotatorClient(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.BatchAnnotateImages(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/webrisk/000077500000000000000000000000001356504100700162365ustar00rootroot00000000000000google-cloud-go-0.49.0/webrisk/apiv1beta1/000077500000000000000000000000001356504100700201735ustar00rootroot00000000000000google-cloud-go-0.49.0/webrisk/apiv1beta1/.repo-metadata.json000066400000000000000000000006261356504100700236730ustar00rootroot00000000000000{ "name": "webrisk", "name_pretty": "Web Risk API", "product_documentation": "https://cloud.google.com/web-risk", "client_documentation": "https://godoc.org/cloud.google.com/go/webrisk/apiv1beta1", "release_level": "beta", "language": "go", "repo": "googleapis/google-cloud-go", "distribution_name": "cloud.google.com/go", "api_id": "webrisk.googleapis.com", "requires_billing": true } google-cloud-go-0.49.0/webrisk/apiv1beta1/doc.go000066400000000000000000000052271356504100700212750ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. // Package webrisk is an auto-generated package for the // Web Risk API. // // NOTE: This package is in beta. It is not stable, and may be subject to changes. // // // Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit godoc.org/cloud.google.com/go. package webrisk // import "cloud.google.com/go/webrisk/apiv1beta1" import ( "context" "runtime" "strings" "unicode" "google.golang.org/grpc/metadata" ) func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return strings.IndexRune("0123456789.", r) < 0 } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } const versionClient = "20191115" google-cloud-go-0.49.0/webrisk/apiv1beta1/mock_test.go000066400000000000000000000215251356504100700225170ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package webrisk import ( "context" "flag" "fmt" "io" "log" "net" "os" "strings" "testing" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" "google.golang.org/api/option" webriskpb "google.golang.org/genproto/googleapis/cloud/webrisk/v1beta1" status "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" gstatus "google.golang.org/grpc/status" ) var _ = io.EOF var _ = ptypes.MarshalAny var _ status.Status type mockWebRiskServiceV1Beta1Server struct { // Embed for forward compatibility. // Tests will keep working if more methods are added // in the future. webriskpb.WebRiskServiceV1Beta1Server reqs []proto.Message // If set, all calls return this error. err error // responses to return if err == nil resps []proto.Message } func (s *mockWebRiskServiceV1Beta1Server) ComputeThreatListDiff(ctx context.Context, req *webriskpb.ComputeThreatListDiffRequest) (*webriskpb.ComputeThreatListDiffResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*webriskpb.ComputeThreatListDiffResponse), nil } func (s *mockWebRiskServiceV1Beta1Server) SearchUris(ctx context.Context, req *webriskpb.SearchUrisRequest) (*webriskpb.SearchUrisResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*webriskpb.SearchUrisResponse), nil } func (s *mockWebRiskServiceV1Beta1Server) SearchHashes(ctx context.Context, req *webriskpb.SearchHashesRequest) (*webriskpb.SearchHashesResponse, error) { md, _ := metadata.FromIncomingContext(ctx) if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg) } s.reqs = append(s.reqs, req) if s.err != nil { return nil, s.err } return s.resps[0].(*webriskpb.SearchHashesResponse), nil } // clientOpt is the option tests should use to connect to the test server. // It is initialized by TestMain. var clientOpt option.ClientOption var ( mockWebRiskServiceV1Beta1 mockWebRiskServiceV1Beta1Server ) func TestMain(m *testing.M) { flag.Parse() serv := grpc.NewServer() webriskpb.RegisterWebRiskServiceV1Beta1Server(serv, &mockWebRiskServiceV1Beta1) lis, err := net.Listen("tcp", "localhost:0") if err != nil { log.Fatal(err) } go serv.Serve(lis) conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) if err != nil { log.Fatal(err) } clientOpt = option.WithGRPCConn(conn) os.Exit(m.Run()) } func TestWebRiskServiceV1Beta1ComputeThreatListDiff(t *testing.T) { var newVersionToken []byte = []byte("115") var expectedResponse = &webriskpb.ComputeThreatListDiffResponse{ NewVersionToken: newVersionToken, } mockWebRiskServiceV1Beta1.err = nil mockWebRiskServiceV1Beta1.reqs = nil mockWebRiskServiceV1Beta1.resps = append(mockWebRiskServiceV1Beta1.resps[:0], expectedResponse) var threatType webriskpb.ThreatType = webriskpb.ThreatType_THREAT_TYPE_UNSPECIFIED var constraints *webriskpb.ComputeThreatListDiffRequest_Constraints = &webriskpb.ComputeThreatListDiffRequest_Constraints{} var request = &webriskpb.ComputeThreatListDiffRequest{ ThreatType: threatType, Constraints: constraints, } c, err := NewWebRiskServiceV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ComputeThreatListDiff(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockWebRiskServiceV1Beta1.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestWebRiskServiceV1Beta1ComputeThreatListDiffError(t *testing.T) { errCode := codes.PermissionDenied mockWebRiskServiceV1Beta1.err = gstatus.Error(errCode, "test error") var threatType webriskpb.ThreatType = webriskpb.ThreatType_THREAT_TYPE_UNSPECIFIED var constraints *webriskpb.ComputeThreatListDiffRequest_Constraints = &webriskpb.ComputeThreatListDiffRequest_Constraints{} var request = &webriskpb.ComputeThreatListDiffRequest{ ThreatType: threatType, Constraints: constraints, } c, err := NewWebRiskServiceV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.ComputeThreatListDiff(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestWebRiskServiceV1Beta1SearchUris(t *testing.T) { var expectedResponse *webriskpb.SearchUrisResponse = &webriskpb.SearchUrisResponse{} mockWebRiskServiceV1Beta1.err = nil mockWebRiskServiceV1Beta1.reqs = nil mockWebRiskServiceV1Beta1.resps = append(mockWebRiskServiceV1Beta1.resps[:0], expectedResponse) var uri string = "uri116076" var threatTypes []webriskpb.ThreatType = nil var request = &webriskpb.SearchUrisRequest{ Uri: uri, ThreatTypes: threatTypes, } c, err := NewWebRiskServiceV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SearchUris(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockWebRiskServiceV1Beta1.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestWebRiskServiceV1Beta1SearchUrisError(t *testing.T) { errCode := codes.PermissionDenied mockWebRiskServiceV1Beta1.err = gstatus.Error(errCode, "test error") var uri string = "uri116076" var threatTypes []webriskpb.ThreatType = nil var request = &webriskpb.SearchUrisRequest{ Uri: uri, ThreatTypes: threatTypes, } c, err := NewWebRiskServiceV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SearchUris(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } func TestWebRiskServiceV1Beta1SearchHashes(t *testing.T) { var expectedResponse *webriskpb.SearchHashesResponse = &webriskpb.SearchHashesResponse{} mockWebRiskServiceV1Beta1.err = nil mockWebRiskServiceV1Beta1.reqs = nil mockWebRiskServiceV1Beta1.resps = append(mockWebRiskServiceV1Beta1.resps[:0], expectedResponse) var threatTypes []webriskpb.ThreatType = nil var request = &webriskpb.SearchHashesRequest{ ThreatTypes: threatTypes, } c, err := NewWebRiskServiceV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SearchHashes(context.Background(), request) if err != nil { t.Fatal(err) } if want, got := request, mockWebRiskServiceV1Beta1.reqs[0]; !proto.Equal(want, got) { t.Errorf("wrong request %q, want %q", got, want) } if want, got := expectedResponse, resp; !proto.Equal(want, got) { t.Errorf("wrong response %q, want %q)", got, want) } } func TestWebRiskServiceV1Beta1SearchHashesError(t *testing.T) { errCode := codes.PermissionDenied mockWebRiskServiceV1Beta1.err = gstatus.Error(errCode, "test error") var threatTypes []webriskpb.ThreatType = nil var request = &webriskpb.SearchHashesRequest{ ThreatTypes: threatTypes, } c, err := NewWebRiskServiceV1Beta1Client(context.Background(), clientOpt) if err != nil { t.Fatal(err) } resp, err := c.SearchHashes(context.Background(), request) if st, ok := gstatus.FromError(err); !ok { t.Errorf("got error %v, expected grpc error", err) } else if c := st.Code(); c != errCode { t.Errorf("got error code %q, want %q", c, errCode) } _ = resp } google-cloud-go-0.49.0/webrisk/apiv1beta1/web_risk_service_v1_beta1_client.go000066400000000000000000000152601356504100700270730ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package webrisk import ( "context" "math" "time" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/option" "google.golang.org/api/transport" webriskpb "google.golang.org/genproto/googleapis/cloud/webrisk/v1beta1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" ) // WebRiskServiceV1Beta1CallOptions contains the retry settings for each method of WebRiskServiceV1Beta1Client. type WebRiskServiceV1Beta1CallOptions struct { ComputeThreatListDiff []gax.CallOption SearchUris []gax.CallOption SearchHashes []gax.CallOption } func defaultWebRiskServiceV1Beta1ClientOptions() []option.ClientOption { return []option.ClientOption{ option.WithEndpoint("webrisk.googleapis.com:443"), option.WithScopes(DefaultAuthScopes()...), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultWebRiskServiceV1Beta1CallOptions() *WebRiskServiceV1Beta1CallOptions { retry := map[[2]string][]gax.CallOption{ {"default", "idempotent"}: { gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.DeadlineExceeded, codes.Unavailable, }, gax.Backoff{ Initial: 100 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.3, }) }), }, } return &WebRiskServiceV1Beta1CallOptions{ ComputeThreatListDiff: retry[[2]string{"default", "idempotent"}], SearchUris: retry[[2]string{"default", "idempotent"}], SearchHashes: retry[[2]string{"default", "idempotent"}], } } // WebRiskServiceV1Beta1Client is a client for interacting with Web Risk API. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type WebRiskServiceV1Beta1Client struct { // The connection to the service. conn *grpc.ClientConn // The gRPC API client. webRiskServiceV1Beta1Client webriskpb.WebRiskServiceV1Beta1Client // The call options for this service. CallOptions *WebRiskServiceV1Beta1CallOptions // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewWebRiskServiceV1Beta1Client creates a new web risk service v1 beta1 client. // // Web Risk v1beta1 API defines an interface to detect malicious URLs on your // website and in client applications. func NewWebRiskServiceV1Beta1Client(ctx context.Context, opts ...option.ClientOption) (*WebRiskServiceV1Beta1Client, error) { conn, err := transport.DialGRPC(ctx, append(defaultWebRiskServiceV1Beta1ClientOptions(), opts...)...) if err != nil { return nil, err } c := &WebRiskServiceV1Beta1Client{ conn: conn, CallOptions: defaultWebRiskServiceV1Beta1CallOptions(), webRiskServiceV1Beta1Client: webriskpb.NewWebRiskServiceV1Beta1Client(conn), } c.setGoogleClientInfo() return c, nil } // Connection returns the client's connection to the API service. func (c *WebRiskServiceV1Beta1Client) Connection() *grpc.ClientConn { return c.conn } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *WebRiskServiceV1Beta1Client) Close() error { return c.conn.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *WebRiskServiceV1Beta1Client) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // ComputeThreatListDiff gets the most recent threat list diffs. func (c *WebRiskServiceV1Beta1Client) ComputeThreatListDiff(ctx context.Context, req *webriskpb.ComputeThreatListDiffRequest, opts ...gax.CallOption) (*webriskpb.ComputeThreatListDiffResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.ComputeThreatListDiff[0:len(c.CallOptions.ComputeThreatListDiff):len(c.CallOptions.ComputeThreatListDiff)], opts...) var resp *webriskpb.ComputeThreatListDiffResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.webRiskServiceV1Beta1Client.ComputeThreatListDiff(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // SearchUris this method is used to check whether a URI is on a given threatList. func (c *WebRiskServiceV1Beta1Client) SearchUris(ctx context.Context, req *webriskpb.SearchUrisRequest, opts ...gax.CallOption) (*webriskpb.SearchUrisResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.SearchUris[0:len(c.CallOptions.SearchUris):len(c.CallOptions.SearchUris)], opts...) var resp *webriskpb.SearchUrisResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.webRiskServiceV1Beta1Client.SearchUris(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } // SearchHashes gets the full hashes that match the requested hash prefix. // This is used after a hash prefix is looked up in a threatList // and there is a match. The client side threatList only holds partial hashes // so the client must query this method to determine if there is a full // hash match of a threat. func (c *WebRiskServiceV1Beta1Client) SearchHashes(ctx context.Context, req *webriskpb.SearchHashesRequest, opts ...gax.CallOption) (*webriskpb.SearchHashesResponse, error) { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append(c.CallOptions.SearchHashes[0:len(c.CallOptions.SearchHashes):len(c.CallOptions.SearchHashes)], opts...) var resp *webriskpb.SearchHashesResponse err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.webRiskServiceV1Beta1Client.SearchHashes(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } google-cloud-go-0.49.0/webrisk/apiv1beta1/web_risk_service_v1_beta1_client_example_test.go000066400000000000000000000042241356504100700316430ustar00rootroot00000000000000// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by gapic-generator. DO NOT EDIT. package webrisk_test import ( "context" webrisk "cloud.google.com/go/webrisk/apiv1beta1" webriskpb "google.golang.org/genproto/googleapis/cloud/webrisk/v1beta1" ) func ExampleNewWebRiskServiceV1Beta1Client() { ctx := context.Background() c, err := webrisk.NewWebRiskServiceV1Beta1Client(ctx) if err != nil { // TODO: Handle error. } // TODO: Use client. _ = c } func ExampleWebRiskServiceV1Beta1Client_ComputeThreatListDiff() { ctx := context.Background() c, err := webrisk.NewWebRiskServiceV1Beta1Client(ctx) if err != nil { // TODO: Handle error. } req := &webriskpb.ComputeThreatListDiffRequest{ // TODO: Fill request struct fields. } resp, err := c.ComputeThreatListDiff(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleWebRiskServiceV1Beta1Client_SearchUris() { ctx := context.Background() c, err := webrisk.NewWebRiskServiceV1Beta1Client(ctx) if err != nil { // TODO: Handle error. } req := &webriskpb.SearchUrisRequest{ // TODO: Fill request struct fields. } resp, err := c.SearchUris(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp } func ExampleWebRiskServiceV1Beta1Client_SearchHashes() { ctx := context.Background() c, err := webrisk.NewWebRiskServiceV1Beta1Client(ctx) if err != nil { // TODO: Handle error. } req := &webriskpb.SearchHashesRequest{ // TODO: Fill request struct fields. } resp, err := c.SearchHashes(ctx, req) if err != nil { // TODO: Handle error. } // TODO: Use resp. _ = resp }